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