diff options
Diffstat (limited to 'drivers/mtd/ubi/wl.c')
-rw-r--r-- | drivers/mtd/ubi/wl.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index fbd399cf6503..4f6f339d8fb8 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -89,6 +89,7 @@ #include <linux/crc32.h> #include <linux/freezer.h> #include <linux/kthread.h> +#include <linux/reboot.h> #include "ubi.h" #include "wl.h" @@ -127,6 +128,8 @@ static int self_check_in_wl_tree(const struct ubi_device *ubi, struct ubi_wl_entry *e, struct rb_root *root); static int self_check_in_pq(const struct ubi_device *ubi, struct ubi_wl_entry *e); +static int ubi_wl_reboot_notifier(struct notifier_block *n, + unsigned long state, void *cmd); /** * wl_tree_add - add a wear-leveling entry to a WL RB-tree. @@ -1950,6 +1953,13 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) if (!ubi->ro_mode && !ubi->fm_disabled) ubi_ensure_anchor_pebs(ubi); #endif + + if (!ubi->wl_reboot_notifier.notifier_call) { + ubi->wl_reboot_notifier.notifier_call = ubi_wl_reboot_notifier; + ubi->wl_reboot_notifier.priority = 1; /* Higher than MTD */ + register_reboot_notifier(&ubi->wl_reboot_notifier); + } + return 0; out_free: @@ -1995,6 +2005,17 @@ void ubi_wl_close(struct ubi_device *ubi) kfree(ubi->lookuptbl); } +static int ubi_wl_reboot_notifier(struct notifier_block *n, + unsigned long state, void *cmd) +{ + struct ubi_device *ubi; + + ubi = container_of(n, struct ubi_device, wl_reboot_notifier); + ubi_wl_close(ubi); + + return NOTIFY_DONE; +} + /** * self_check_ec - make sure that the erase counter of a PEB is correct. * @ubi: UBI device description object |