diff options
author | James Hogan <james@albanarts.com> | 2010-10-11 18:00:25 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2010-10-16 19:57:50 -0400 |
commit | d33ac60beaf2c7dee5cd90aba7c1eb385dd70937 (patch) | |
tree | 7393c5f323433f39d2c64e7d9990aa7565397214 /drivers/base/power/trace.c | |
parent | 2ac21c6bc4249ee6d922f18dbec7266377592c32 (diff) |
PM: Add sysfs attr for rechecking dev hash from PM trace
If the device which fails to resume is part of a loadable kernel module
it won't be checked at startup against the magic number stored in the
RTC.
Add a read-only sysfs attribute /sys/power/pm_trace_dev_match which
contains a list of newline separated devices (usually just the one)
which currently match the last magic number. This allows the device
which is failing to resume to be found after the modules are loaded
again.
Signed-off-by: James Hogan <james@albanarts.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'drivers/base/power/trace.c')
-rw-r--r-- | drivers/base/power/trace.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/base/power/trace.c b/drivers/base/power/trace.c index 17e24e3f4422..9f4258df4cfd 100644 --- a/drivers/base/power/trace.c +++ b/drivers/base/power/trace.c | |||
@@ -207,6 +207,37 @@ static int show_dev_hash(unsigned int value) | |||
207 | 207 | ||
208 | static unsigned int hash_value_early_read; | 208 | static unsigned int hash_value_early_read; |
209 | 209 | ||
210 | int show_trace_dev_match(char *buf, size_t size) | ||
211 | { | ||
212 | unsigned int value = hash_value_early_read / (USERHASH * FILEHASH); | ||
213 | int ret = 0; | ||
214 | struct list_head *entry; | ||
215 | |||
216 | /* | ||
217 | * It's possible that multiple devices will match the hash and we can't | ||
218 | * tell which is the culprit, so it's best to output them all. | ||
219 | */ | ||
220 | device_pm_lock(); | ||
221 | entry = dpm_list.prev; | ||
222 | while (size && entry != &dpm_list) { | ||
223 | struct device *dev = to_device(entry); | ||
224 | unsigned int hash = hash_string(DEVSEED, dev_name(dev), | ||
225 | DEVHASH); | ||
226 | if (hash == value) { | ||
227 | int len = snprintf(buf, size, "%s\n", | ||
228 | dev_driver_string(dev)); | ||
229 | if (len > size) | ||
230 | len = size; | ||
231 | buf += len; | ||
232 | ret += len; | ||
233 | size -= len; | ||
234 | } | ||
235 | entry = entry->prev; | ||
236 | } | ||
237 | device_pm_unlock(); | ||
238 | return ret; | ||
239 | } | ||
240 | |||
210 | static int early_resume_init(void) | 241 | static int early_resume_init(void) |
211 | { | 242 | { |
212 | hash_value_early_read = read_magic_time(); | 243 | hash_value_early_read = read_magic_time(); |