summaryrefslogtreecommitdiffstats
path: root/kernel/power/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/power/main.c')
-rw-r--r--kernel/power/main.c99
1 files changed, 96 insertions, 3 deletions
diff --git a/kernel/power/main.c b/kernel/power/main.c
index bdbd605c4215..e8710d179b35 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -254,7 +254,6 @@ static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr,
254power_attr(pm_test); 254power_attr(pm_test);
255#endif /* CONFIG_PM_SLEEP_DEBUG */ 255#endif /* CONFIG_PM_SLEEP_DEBUG */
256 256
257#ifdef CONFIG_DEBUG_FS
258static char *suspend_step_name(enum suspend_stat_step step) 257static char *suspend_step_name(enum suspend_stat_step step)
259{ 258{
260 switch (step) { 259 switch (step) {
@@ -275,6 +274,92 @@ static char *suspend_step_name(enum suspend_stat_step step)
275 } 274 }
276} 275}
277 276
277#define suspend_attr(_name) \
278static ssize_t _name##_show(struct kobject *kobj, \
279 struct kobj_attribute *attr, char *buf) \
280{ \
281 return sprintf(buf, "%d\n", suspend_stats._name); \
282} \
283static struct kobj_attribute _name = __ATTR_RO(_name)
284
285suspend_attr(success);
286suspend_attr(fail);
287suspend_attr(failed_freeze);
288suspend_attr(failed_prepare);
289suspend_attr(failed_suspend);
290suspend_attr(failed_suspend_late);
291suspend_attr(failed_suspend_noirq);
292suspend_attr(failed_resume);
293suspend_attr(failed_resume_early);
294suspend_attr(failed_resume_noirq);
295
296static ssize_t last_failed_dev_show(struct kobject *kobj,
297 struct kobj_attribute *attr, char *buf)
298{
299 int index;
300 char *last_failed_dev = NULL;
301
302 index = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1;
303 index %= REC_FAILED_NUM;
304 last_failed_dev = suspend_stats.failed_devs[index];
305
306 return sprintf(buf, "%s\n", last_failed_dev);
307}
308static struct kobj_attribute last_failed_dev = __ATTR_RO(last_failed_dev);
309
310static ssize_t last_failed_errno_show(struct kobject *kobj,
311 struct kobj_attribute *attr, char *buf)
312{
313 int index;
314 int last_failed_errno;
315
316 index = suspend_stats.last_failed_errno + REC_FAILED_NUM - 1;
317 index %= REC_FAILED_NUM;
318 last_failed_errno = suspend_stats.errno[index];
319
320 return sprintf(buf, "%d\n", last_failed_errno);
321}
322static struct kobj_attribute last_failed_errno = __ATTR_RO(last_failed_errno);
323
324static ssize_t last_failed_step_show(struct kobject *kobj,
325 struct kobj_attribute *attr, char *buf)
326{
327 int index;
328 enum suspend_stat_step step;
329 char *last_failed_step = NULL;
330
331 index = suspend_stats.last_failed_step + REC_FAILED_NUM - 1;
332 index %= REC_FAILED_NUM;
333 step = suspend_stats.failed_steps[index];
334 last_failed_step = suspend_step_name(step);
335
336 return sprintf(buf, "%s\n", last_failed_step);
337}
338static struct kobj_attribute last_failed_step = __ATTR_RO(last_failed_step);
339
340static struct attribute *suspend_attrs[] = {
341 &success.attr,
342 &fail.attr,
343 &failed_freeze.attr,
344 &failed_prepare.attr,
345 &failed_suspend.attr,
346 &failed_suspend_late.attr,
347 &failed_suspend_noirq.attr,
348 &failed_resume.attr,
349 &failed_resume_early.attr,
350 &failed_resume_noirq.attr,
351 &last_failed_dev.attr,
352 &last_failed_errno.attr,
353 &last_failed_step.attr,
354 NULL,
355};
356
357static struct attribute_group suspend_attr_group = {
358 .name = "suspend_stats",
359 .attrs = suspend_attrs,
360};
361
362#ifdef CONFIG_DEBUG_FS
278static int suspend_stats_show(struct seq_file *s, void *unused) 363static int suspend_stats_show(struct seq_file *s, void *unused)
279{ 364{
280 int i, index, last_dev, last_errno, last_step; 365 int i, index, last_dev, last_errno, last_step;
@@ -495,7 +580,7 @@ static suspend_state_t decode_state(const char *buf, size_t n)
495 len = p ? p - buf : n; 580 len = p ? p - buf : n;
496 581
497 /* Check hibernation first. */ 582 /* Check hibernation first. */
498 if (len == 4 && !strncmp(buf, "disk", len)) 583 if (len == 4 && str_has_prefix(buf, "disk"))
499 return PM_SUSPEND_MAX; 584 return PM_SUSPEND_MAX;
500 585
501#ifdef CONFIG_SUSPEND 586#ifdef CONFIG_SUSPEND
@@ -794,6 +879,14 @@ static const struct attribute_group attr_group = {
794 .attrs = g, 879 .attrs = g,
795}; 880};
796 881
882static const struct attribute_group *attr_groups[] = {
883 &attr_group,
884#ifdef CONFIG_PM_SLEEP
885 &suspend_attr_group,
886#endif
887 NULL,
888};
889
797struct workqueue_struct *pm_wq; 890struct workqueue_struct *pm_wq;
798EXPORT_SYMBOL_GPL(pm_wq); 891EXPORT_SYMBOL_GPL(pm_wq);
799 892
@@ -815,7 +908,7 @@ static int __init pm_init(void)
815 power_kobj = kobject_create_and_add("power", NULL); 908 power_kobj = kobject_create_and_add("power", NULL);
816 if (!power_kobj) 909 if (!power_kobj)
817 return -ENOMEM; 910 return -ENOMEM;
818 error = sysfs_create_group(power_kobj, &attr_group); 911 error = sysfs_create_groups(power_kobj, attr_groups);
819 if (error) 912 if (error)
820 return error; 913 return error;
821 pm_print_times_init(); 914 pm_print_times_init();