1
2
3
4
5
6
7
8
9
10
11#include <linux/export.h>
12#include <linux/kobject.h>
13#include <linux/string.h>
14#include <linux/pm-trace.h>
15#include <linux/workqueue.h>
16#include <linux/debugfs.h>
17#include <linux/seq_file.h>
18
19#include "power.h"
20
21DEFINE_MUTEX(pm_mutex);
22
23#ifdef CONFIG_PM_SLEEP
24
25
26
27static BLOCKING_NOTIFIER_HEAD(pm_chain_head);
28
29int register_pm_notifier(struct notifier_block *nb)
30{
31 return blocking_notifier_chain_register(&pm_chain_head, nb);
32}
33EXPORT_SYMBOL_GPL(register_pm_notifier);
34
35int unregister_pm_notifier(struct notifier_block *nb)
36{
37 return blocking_notifier_chain_unregister(&pm_chain_head, nb);
38}
39EXPORT_SYMBOL_GPL(unregister_pm_notifier);
40
41int __pm_notifier_call_chain(unsigned long val, int nr_to_call, int *nr_calls)
42{
43 int ret;
44
45 ret = __blocking_notifier_call_chain(&pm_chain_head, val, NULL,
46 nr_to_call, nr_calls);
47
48 return notifier_to_errno(ret);
49}
50int pm_notifier_call_chain(unsigned long val)
51{
52 return __pm_notifier_call_chain(val, -1, NULL);
53}
54
55
56int pm_async_enabled = 1;
57
58static ssize_t pm_async_show(struct kobject *kobj, struct kobj_attribute *attr,
59 char *buf)
60{
61 return sprintf(buf, "%d\n", pm_async_enabled);
62}
63
64static ssize_t pm_async_store(struct kobject *kobj, struct kobj_attribute *attr,
65 const char *buf, size_t n)
66{
67 unsigned long val;
68
69 if (kstrtoul(buf, 10, &val))
70 return -EINVAL;
71
72 if (val > 1)
73 return -EINVAL;
74
75 pm_async_enabled = val;
76 return n;
77}
78
79power_attr(pm_async);
80
81#ifdef CONFIG_SUSPEND
82static ssize_t mem_sleep_show(struct kobject *kobj, struct kobj_attribute *attr,
83 char *buf)
84{
85 char *s = buf;
86 suspend_state_t i;
87
88 for (i = PM_SUSPEND_MIN; i < PM_SUSPEND_MAX; i++)
89 if (mem_sleep_states[i]) {
90 const char *label = mem_sleep_states[i];
91
92 if (mem_sleep_current == i)
93 s += sprintf(s, "[%s] ", label);
94 else
95 s += sprintf(s, "%s ", label);
96 }
97
98
99 if (s != buf)
100 *(s-1) = '\n';
101
102 return (s - buf);
103}
104
105static suspend_state_t decode_suspend_state(const char *buf, size_t n)
106{
107 suspend_state_t state;
108 char *p;
109 int len;
110
111 p = memchr(buf, '\n', n);
112 len = p ? p - buf : n;
113
114 for (state = PM_SUSPEND_MIN; state < PM_SUSPEND_MAX; state++) {
115 const char *label = mem_sleep_states[state];
116
117 if (label && len == strlen(label) && !strncmp(buf, label, len))
118 return state;
119 }
120
121 return PM_SUSPEND_ON;
122}
123
124static ssize_t mem_sleep_store(struct kobject *kobj, struct kobj_attribute *attr,
125 const char *buf, size_t n)
126{
127 suspend_state_t state;
128 int error;
129
130 error = pm_autosleep_lock();
131 if (error)
132 return error;
133
134 if (pm_autosleep_state() > PM_SUSPEND_ON) {
135 error = -EBUSY;
136 goto out;
137 }
138
139 state = decode_suspend_state(buf, n);
140 if (state < PM_SUSPEND_MAX && state > PM_SUSPEND_ON)
141 mem_sleep_current = state;
142 else
143 error = -EINVAL;
144
145 out:
146 pm_autosleep_unlock();
147 return error ? error : n;
148}
149
150power_attr(mem_sleep);
151#endif
152
153#ifdef CONFIG_PM_SLEEP_DEBUG
154int pm_test_level = TEST_NONE;
155
156static const char * const pm_tests[__TEST_AFTER_LAST] = {
157 [TEST_NONE] = "none",
158 [TEST_CORE] = "core",
159 [TEST_CPUS] = "processors",
160 [TEST_PLATFORM] = "platform",
161 [TEST_DEVICES] = "devices",
162 [TEST_FREEZER] = "freezer",
163};
164
165static ssize_t pm_test_show(struct kobject *kobj, struct kobj_attribute *attr,
166 char *buf)
167{
168 char *s = buf;
169 int level;
170
171 for (level = TEST_FIRST; level <= TEST_MAX; level++)
172 if (pm_tests[level]) {
173 if (level == pm_test_level)
174 s += sprintf(s, "[%s] ", pm_tests[level]);
175 else
176 s += sprintf(s, "%s ", pm_tests[level]);
177 }
178
179 if (s != buf)
180
181 *(s-1) = '\n';
182
183 return (s - buf);
184}
185
186static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr,
187 const char *buf, size_t n)
188{
189 const char * const *s;
190 int level;
191 char *p;
192 int len;
193 int error = -EINVAL;
194
195 p = memchr(buf, '\n', n);
196 len = p ? p - buf : n;
197
198 lock_system_sleep();
199
200 level = TEST_FIRST;
201 for (s = &pm_tests[level]; level <= TEST_MAX; s++, level++)
202 if (*s && len == strlen(*s) && !strncmp(buf, *s, len)) {
203 pm_test_level = level;
204 error = 0;
205 break;
206 }
207
208 unlock_system_sleep();
209
210 return error ? error : n;
211}
212
213power_attr(pm_test);
214#endif
215
216#ifdef CONFIG_DEBUG_FS
217static char *suspend_step_name(enum suspend_stat_step step)
218{
219 switch (step) {
220 case SUSPEND_FREEZE:
221 return "freeze";
222 case SUSPEND_PREPARE:
223 return "prepare";
224 case SUSPEND_SUSPEND:
225 return "suspend";
226 case SUSPEND_SUSPEND_NOIRQ:
227 return "suspend_noirq";
228 case SUSPEND_RESUME_NOIRQ:
229 return "resume_noirq";
230 case SUSPEND_RESUME:
231 return "resume";
232 default:
233 return "";
234 }
235}
236
237static int suspend_stats_show(struct seq_file *s, void *unused)
238{
239 int i, index, last_dev, last_errno, last_step;
240
241 last_dev = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1;
242 last_dev %= REC_FAILED_NUM;
243 last_errno = suspend_stats.last_failed_errno + REC_FAILED_NUM - 1;
244 last_errno %= REC_FAILED_NUM;
245 last_step = suspend_stats.last_failed_step + REC_FAILED_NUM - 1;
246 last_step %= REC_FAILED_NUM;
247 seq_printf(s, "%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n"
248 "%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n",
249 "success", suspend_stats.success,
250 "fail", suspend_stats.fail,
251 "failed_freeze", suspend_stats.failed_freeze,
252 "failed_prepare", suspend_stats.failed_prepare,
253 "failed_suspend", suspend_stats.failed_suspend,
254 "failed_suspend_late",
255 suspend_stats.failed_suspend_late,
256 "failed_suspend_noirq",
257 suspend_stats.failed_suspend_noirq,
258 "failed_resume", suspend_stats.failed_resume,
259 "failed_resume_early",
260 suspend_stats.failed_resume_early,
261 "failed_resume_noirq",
262 suspend_stats.failed_resume_noirq);
263 seq_printf(s, "failures:\n last_failed_dev:\t%-s\n",
264 suspend_stats.failed_devs[last_dev]);
265 for (i = 1; i < REC_FAILED_NUM; i++) {
266 index = last_dev + REC_FAILED_NUM - i;
267 index %= REC_FAILED_NUM;
268 seq_printf(s, "\t\t\t%-s\n",
269 suspend_stats.failed_devs[index]);
270 }
271 seq_printf(s, " last_failed_errno:\t%-d\n",
272 suspend_stats.errno[last_errno]);
273 for (i = 1; i < REC_FAILED_NUM; i++) {
274 index = last_errno + REC_FAILED_NUM - i;
275 index %= REC_FAILED_NUM;
276 seq_printf(s, "\t\t\t%-d\n",
277 suspend_stats.errno[index]);
278 }
279 seq_printf(s, " last_failed_step:\t%-s\n",
280 suspend_step_name(
281 suspend_stats.failed_steps[last_step]));
282 for (i = 1; i < REC_FAILED_NUM; i++) {
283 index = last_step + REC_FAILED_NUM - i;
284 index %= REC_FAILED_NUM;
285 seq_printf(s, "\t\t\t%-s\n",
286 suspend_step_name(
287 suspend_stats.failed_steps[index]));
288 }
289
290 return 0;
291}
292
293static int suspend_stats_open(struct inode *inode, struct file *file)
294{
295 return single_open(file, suspend_stats_show, NULL);
296}
297
298static const struct file_operations suspend_stats_operations = {
299 .open = suspend_stats_open,
300 .read = seq_read,
301 .llseek = seq_lseek,
302 .release = single_release,
303};
304
305static int __init pm_debugfs_init(void)
306{
307 debugfs_create_file("suspend_stats", S_IFREG | S_IRUGO,
308 NULL, NULL, &suspend_stats_operations);
309 return 0;
310}
311
312late_initcall(pm_debugfs_init);
313#endif
314
315#endif
316
317#ifdef CONFIG_PM_SLEEP_DEBUG
318
319
320
321
322
323
324bool pm_print_times_enabled;
325
326static ssize_t pm_print_times_show(struct kobject *kobj,
327 struct kobj_attribute *attr, char *buf)
328{
329 return sprintf(buf, "%d\n", pm_print_times_enabled);
330}
331
332static ssize_t pm_print_times_store(struct kobject *kobj,
333 struct kobj_attribute *attr,
334 const char *buf, size_t n)
335{
336 unsigned long val;
337
338 if (kstrtoul(buf, 10, &val))
339 return -EINVAL;
340
341 if (val > 1)
342 return -EINVAL;
343
344 pm_print_times_enabled = !!val;
345 return n;
346}
347
348power_attr(pm_print_times);
349
350static inline void pm_print_times_init(void)
351{
352 pm_print_times_enabled = !!initcall_debug;
353}
354
355static ssize_t pm_wakeup_irq_show(struct kobject *kobj,
356 struct kobj_attribute *attr,
357 char *buf)
358{
359 return pm_wakeup_irq ? sprintf(buf, "%u\n", pm_wakeup_irq) : -ENODATA;
360}
361
362power_attr_ro(pm_wakeup_irq);
363
364bool pm_debug_messages_on __read_mostly;
365
366static ssize_t pm_debug_messages_show(struct kobject *kobj,
367 struct kobj_attribute *attr, char *buf)
368{
369 return sprintf(buf, "%d\n", pm_debug_messages_on);
370}
371
372static ssize_t pm_debug_messages_store(struct kobject *kobj,
373 struct kobj_attribute *attr,
374 const char *buf, size_t n)
375{
376 unsigned long val;
377
378 if (kstrtoul(buf, 10, &val))
379 return -EINVAL;
380
381 if (val > 1)
382 return -EINVAL;
383
384 pm_debug_messages_on = !!val;
385 return n;
386}
387
388power_attr(pm_debug_messages);
389
390
391
392
393
394
395
396
397
398void __pm_pr_dbg(bool defer, const char *fmt, ...)
399{
400 struct va_format vaf;
401 va_list args;
402
403 if (!pm_debug_messages_on)
404 return;
405
406 va_start(args, fmt);
407
408 vaf.fmt = fmt;
409 vaf.va = &args;
410
411 if (defer)
412 printk_deferred(KERN_DEBUG "PM: %pV", &vaf);
413 else
414 printk(KERN_DEBUG "PM: %pV", &vaf);
415
416 va_end(args);
417}
418
419#else
420static inline void pm_print_times_init(void) {}
421#endif
422
423struct kobject *power_kobj;
424
425
426
427
428
429
430
431
432
433
434
435static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr,
436 char *buf)
437{
438 char *s = buf;
439#ifdef CONFIG_SUSPEND
440 suspend_state_t i;
441
442 for (i = PM_SUSPEND_MIN; i < PM_SUSPEND_MAX; i++)
443 if (pm_states[i])
444 s += sprintf(s,"%s ", pm_states[i]);
445
446#endif
447 if (hibernation_available())
448 s += sprintf(s, "disk ");
449 if (s != buf)
450
451 *(s-1) = '\n';
452 return (s - buf);
453}
454
455static suspend_state_t decode_state(const char *buf, size_t n)
456{
457#ifdef CONFIG_SUSPEND
458 suspend_state_t state;
459#endif
460 char *p;
461 int len;
462
463 p = memchr(buf, '\n', n);
464 len = p ? p - buf : n;
465
466
467 if (len == 4 && !strncmp(buf, "disk", len))
468 return PM_SUSPEND_MAX;
469
470#ifdef CONFIG_SUSPEND
471 for (state = PM_SUSPEND_MIN; state < PM_SUSPEND_MAX; state++) {
472 const char *label = pm_states[state];
473
474 if (label && len == strlen(label) && !strncmp(buf, label, len))
475 return state;
476 }
477#endif
478
479 return PM_SUSPEND_ON;
480}
481
482static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
483 const char *buf, size_t n)
484{
485 suspend_state_t state;
486 int error;
487
488 error = pm_autosleep_lock();
489 if (error)
490 return error;
491
492 if (pm_autosleep_state() > PM_SUSPEND_ON) {
493 error = -EBUSY;
494 goto out;
495 }
496
497 state = decode_state(buf, n);
498 if (state < PM_SUSPEND_MAX) {
499 if (state == PM_SUSPEND_MEM)
500 state = mem_sleep_current;
501
502 error = pm_suspend(state);
503 } else if (state == PM_SUSPEND_MAX) {
504 error = hibernate();
505 } else {
506 error = -EINVAL;
507 }
508
509 out:
510 pm_autosleep_unlock();
511 return error ? error : n;
512}
513
514power_attr(state);
515
516#ifdef CONFIG_PM_SLEEP
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545static ssize_t wakeup_count_show(struct kobject *kobj,
546 struct kobj_attribute *attr,
547 char *buf)
548{
549 unsigned int val;
550
551 return pm_get_wakeup_count(&val, true) ?
552 sprintf(buf, "%u\n", val) : -EINTR;
553}
554
555static ssize_t wakeup_count_store(struct kobject *kobj,
556 struct kobj_attribute *attr,
557 const char *buf, size_t n)
558{
559 unsigned int val;
560 int error;
561
562 error = pm_autosleep_lock();
563 if (error)
564 return error;
565
566 if (pm_autosleep_state() > PM_SUSPEND_ON) {
567 error = -EBUSY;
568 goto out;
569 }
570
571 error = -EINVAL;
572 if (sscanf(buf, "%u", &val) == 1) {
573 if (pm_save_wakeup_count(val))
574 error = n;
575 else
576 pm_print_active_wakeup_sources();
577 }
578
579 out:
580 pm_autosleep_unlock();
581 return error;
582}
583
584power_attr(wakeup_count);
585
586#ifdef CONFIG_PM_AUTOSLEEP
587static ssize_t autosleep_show(struct kobject *kobj,
588 struct kobj_attribute *attr,
589 char *buf)
590{
591 suspend_state_t state = pm_autosleep_state();
592
593 if (state == PM_SUSPEND_ON)
594 return sprintf(buf, "off\n");
595
596#ifdef CONFIG_SUSPEND
597 if (state < PM_SUSPEND_MAX)
598 return sprintf(buf, "%s\n", pm_states[state] ?
599 pm_states[state] : "error");
600#endif
601#ifdef CONFIG_HIBERNATION
602 return sprintf(buf, "disk\n");
603#else
604 return sprintf(buf, "error");
605#endif
606}
607
608static ssize_t autosleep_store(struct kobject *kobj,
609 struct kobj_attribute *attr,
610 const char *buf, size_t n)
611{
612 suspend_state_t state = decode_state(buf, n);
613 int error;
614
615 if (state == PM_SUSPEND_ON
616 && strcmp(buf, "off") && strcmp(buf, "off\n"))
617 return -EINVAL;
618
619 if (state == PM_SUSPEND_MEM)
620 state = mem_sleep_current;
621
622 error = pm_autosleep_set_state(state);
623 return error ? error : n;
624}
625
626power_attr(autosleep);
627#endif
628
629#ifdef CONFIG_PM_WAKELOCKS
630static ssize_t wake_lock_show(struct kobject *kobj,
631 struct kobj_attribute *attr,
632 char *buf)
633{
634 return pm_show_wakelocks(buf, true);
635}
636
637static ssize_t wake_lock_store(struct kobject *kobj,
638 struct kobj_attribute *attr,
639 const char *buf, size_t n)
640{
641 int error = pm_wake_lock(buf);
642 return error ? error : n;
643}
644
645power_attr(wake_lock);
646
647static ssize_t wake_unlock_show(struct kobject *kobj,
648 struct kobj_attribute *attr,
649 char *buf)
650{
651 return pm_show_wakelocks(buf, false);
652}
653
654static ssize_t wake_unlock_store(struct kobject *kobj,
655 struct kobj_attribute *attr,
656 const char *buf, size_t n)
657{
658 int error = pm_wake_unlock(buf);
659 return error ? error : n;
660}
661
662power_attr(wake_unlock);
663
664#endif
665#endif
666
667#ifdef CONFIG_PM_TRACE
668int pm_trace_enabled;
669
670static ssize_t pm_trace_show(struct kobject *kobj, struct kobj_attribute *attr,
671 char *buf)
672{
673 return sprintf(buf, "%d\n", pm_trace_enabled);
674}
675
676static ssize_t
677pm_trace_store(struct kobject *kobj, struct kobj_attribute *attr,
678 const char *buf, size_t n)
679{
680 int val;
681
682 if (sscanf(buf, "%d", &val) == 1) {
683 pm_trace_enabled = !!val;
684 if (pm_trace_enabled) {
685 pr_warn("PM: Enabling pm_trace changes system date and time during resume.\n"
686 "PM: Correct system time has to be restored manually after resume.\n");
687 }
688 return n;
689 }
690 return -EINVAL;
691}
692
693power_attr(pm_trace);
694
695static ssize_t pm_trace_dev_match_show(struct kobject *kobj,
696 struct kobj_attribute *attr,
697 char *buf)
698{
699 return show_trace_dev_match(buf, PAGE_SIZE);
700}
701
702power_attr_ro(pm_trace_dev_match);
703
704#endif
705
706#ifdef CONFIG_FREEZER
707static ssize_t pm_freeze_timeout_show(struct kobject *kobj,
708 struct kobj_attribute *attr, char *buf)
709{
710 return sprintf(buf, "%u\n", freeze_timeout_msecs);
711}
712
713static ssize_t pm_freeze_timeout_store(struct kobject *kobj,
714 struct kobj_attribute *attr,
715 const char *buf, size_t n)
716{
717 unsigned long val;
718
719 if (kstrtoul(buf, 10, &val))
720 return -EINVAL;
721
722 freeze_timeout_msecs = val;
723 return n;
724}
725
726power_attr(pm_freeze_timeout);
727
728#endif
729
730static struct attribute * g[] = {
731 &state_attr.attr,
732#ifdef CONFIG_PM_TRACE
733 &pm_trace_attr.attr,
734 &pm_trace_dev_match_attr.attr,
735#endif
736#ifdef CONFIG_PM_SLEEP
737 &pm_async_attr.attr,
738 &wakeup_count_attr.attr,
739#ifdef CONFIG_SUSPEND
740 &mem_sleep_attr.attr,
741#endif
742#ifdef CONFIG_PM_AUTOSLEEP
743 &autosleep_attr.attr,
744#endif
745#ifdef CONFIG_PM_WAKELOCKS
746 &wake_lock_attr.attr,
747 &wake_unlock_attr.attr,
748#endif
749#ifdef CONFIG_PM_SLEEP_DEBUG
750 &pm_test_attr.attr,
751 &pm_print_times_attr.attr,
752 &pm_wakeup_irq_attr.attr,
753 &pm_debug_messages_attr.attr,
754#endif
755#endif
756#ifdef CONFIG_FREEZER
757 &pm_freeze_timeout_attr.attr,
758#endif
759 NULL,
760};
761
762static const struct attribute_group attr_group = {
763 .attrs = g,
764};
765
766struct workqueue_struct *pm_wq;
767EXPORT_SYMBOL_GPL(pm_wq);
768
769static int __init pm_start_workqueue(void)
770{
771 pm_wq = alloc_workqueue("pm", WQ_FREEZABLE, 0);
772
773 return pm_wq ? 0 : -ENOMEM;
774}
775
776static int __init pm_init(void)
777{
778 int error = pm_start_workqueue();
779 if (error)
780 return error;
781 hibernate_image_size_init();
782 hibernate_reserved_size_init();
783 pm_states_init();
784 power_kobj = kobject_create_and_add("power", NULL);
785 if (!power_kobj)
786 return -ENOMEM;
787 error = sysfs_create_group(power_kobj, &attr_group);
788 if (error)
789 return error;
790 pm_print_times_init();
791 return pm_autosleep_init();
792}
793
794core_initcall(pm_init);
795