|
89 | 89 | #include <linux/crc32.h>
|
90 | 90 | #include <linux/freezer.h>
|
91 | 91 | #include <linux/kthread.h>
|
| 92 | +#include <linux/reboot.h> |
92 | 93 | #include "ubi.h"
|
93 | 94 | #include "wl.h"
|
94 | 95 |
|
@@ -127,6 +128,8 @@ static int self_check_in_wl_tree(const struct ubi_device *ubi,
|
127 | 128 | struct ubi_wl_entry *e, struct rb_root *root);
|
128 | 129 | static int self_check_in_pq(const struct ubi_device *ubi,
|
129 | 130 | struct ubi_wl_entry *e);
|
| 131 | +static int ubi_wl_reboot_notifier(struct notifier_block *n, |
| 132 | + unsigned long state, void *cmd); |
130 | 133 |
|
131 | 134 | /**
|
132 | 135 | * 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)
|
1950 | 1953 | if (!ubi->ro_mode && !ubi->fm_disabled)
|
1951 | 1954 | ubi_ensure_anchor_pebs(ubi);
|
1952 | 1955 | #endif
|
| 1956 | + |
| 1957 | + if (!ubi->wl_reboot_notifier.notifier_call) { |
| 1958 | + ubi->wl_reboot_notifier.notifier_call = ubi_wl_reboot_notifier; |
| 1959 | + ubi->wl_reboot_notifier.priority = 1; /* Higher than MTD */ |
| 1960 | + register_reboot_notifier(&ubi->wl_reboot_notifier); |
| 1961 | + } |
| 1962 | + |
1953 | 1963 | return 0;
|
1954 | 1964 |
|
1955 | 1965 | out_free:
|
@@ -1995,6 +2005,17 @@ void ubi_wl_close(struct ubi_device *ubi)
|
1995 | 2005 | kfree(ubi->lookuptbl);
|
1996 | 2006 | }
|
1997 | 2007 |
|
| 2008 | +static int ubi_wl_reboot_notifier(struct notifier_block *n, |
| 2009 | + unsigned long state, void *cmd) |
| 2010 | +{ |
| 2011 | + struct ubi_device *ubi; |
| 2012 | + |
| 2013 | + ubi = container_of(n, struct ubi_device, wl_reboot_notifier); |
| 2014 | + ubi_wl_close(ubi); |
| 2015 | + |
| 2016 | + return NOTIFY_DONE; |
| 2017 | +} |
| 2018 | + |
1998 | 2019 | /**
|
1999 | 2020 | * self_check_ec - make sure that the erase counter of a PEB is correct.
|
2000 | 2021 | * @ubi: UBI device description object
|
|
0 commit comments