0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/export.h>
0010 #include <linux/kobject.h>
0011 #include <linux/string.h>
0012 #include <linux/pm-trace.h>
0013 #include <linux/workqueue.h>
0014 #include <linux/debugfs.h>
0015 #include <linux/seq_file.h>
0016 #include <linux/suspend.h>
0017 #include <linux/syscalls.h>
0018 #include <linux/pm_runtime.h>
0019
0020 #include "power.h"
0021
0022 #ifdef CONFIG_PM_SLEEP
0023
0024 void lock_system_sleep(void)
0025 {
0026 current->flags |= PF_FREEZER_SKIP;
0027 mutex_lock(&system_transition_mutex);
0028 }
0029 EXPORT_SYMBOL_GPL(lock_system_sleep);
0030
0031 void unlock_system_sleep(void)
0032 {
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 current->flags &= ~PF_FREEZER_SKIP;
0050 mutex_unlock(&system_transition_mutex);
0051 }
0052 EXPORT_SYMBOL_GPL(unlock_system_sleep);
0053
0054 void ksys_sync_helper(void)
0055 {
0056 ktime_t start;
0057 long elapsed_msecs;
0058
0059 start = ktime_get();
0060 ksys_sync();
0061 elapsed_msecs = ktime_to_ms(ktime_sub(ktime_get(), start));
0062 pr_info("Filesystems sync: %ld.%03ld seconds\n",
0063 elapsed_msecs / MSEC_PER_SEC, elapsed_msecs % MSEC_PER_SEC);
0064 }
0065 EXPORT_SYMBOL_GPL(ksys_sync_helper);
0066
0067
0068
0069 static BLOCKING_NOTIFIER_HEAD(pm_chain_head);
0070
0071 int register_pm_notifier(struct notifier_block *nb)
0072 {
0073 return blocking_notifier_chain_register(&pm_chain_head, nb);
0074 }
0075 EXPORT_SYMBOL_GPL(register_pm_notifier);
0076
0077 int unregister_pm_notifier(struct notifier_block *nb)
0078 {
0079 return blocking_notifier_chain_unregister(&pm_chain_head, nb);
0080 }
0081 EXPORT_SYMBOL_GPL(unregister_pm_notifier);
0082
0083 int pm_notifier_call_chain_robust(unsigned long val_up, unsigned long val_down)
0084 {
0085 int ret;
0086
0087 ret = blocking_notifier_call_chain_robust(&pm_chain_head, val_up, val_down, NULL);
0088
0089 return notifier_to_errno(ret);
0090 }
0091
0092 int pm_notifier_call_chain(unsigned long val)
0093 {
0094 return blocking_notifier_call_chain(&pm_chain_head, val, NULL);
0095 }
0096
0097
0098 int pm_async_enabled = 1;
0099
0100 static ssize_t pm_async_show(struct kobject *kobj, struct kobj_attribute *attr,
0101 char *buf)
0102 {
0103 return sprintf(buf, "%d\n", pm_async_enabled);
0104 }
0105
0106 static ssize_t pm_async_store(struct kobject *kobj, struct kobj_attribute *attr,
0107 const char *buf, size_t n)
0108 {
0109 unsigned long val;
0110
0111 if (kstrtoul(buf, 10, &val))
0112 return -EINVAL;
0113
0114 if (val > 1)
0115 return -EINVAL;
0116
0117 pm_async_enabled = val;
0118 return n;
0119 }
0120
0121 power_attr(pm_async);
0122
0123 #ifdef CONFIG_SUSPEND
0124 static ssize_t mem_sleep_show(struct kobject *kobj, struct kobj_attribute *attr,
0125 char *buf)
0126 {
0127 char *s = buf;
0128 suspend_state_t i;
0129
0130 for (i = PM_SUSPEND_MIN; i < PM_SUSPEND_MAX; i++) {
0131 if (i >= PM_SUSPEND_MEM && cxl_mem_active())
0132 continue;
0133 if (mem_sleep_states[i]) {
0134 const char *label = mem_sleep_states[i];
0135
0136 if (mem_sleep_current == i)
0137 s += sprintf(s, "[%s] ", label);
0138 else
0139 s += sprintf(s, "%s ", label);
0140 }
0141 }
0142
0143
0144 if (s != buf)
0145 *(s-1) = '\n';
0146
0147 return (s - buf);
0148 }
0149
0150 static suspend_state_t decode_suspend_state(const char *buf, size_t n)
0151 {
0152 suspend_state_t state;
0153 char *p;
0154 int len;
0155
0156 p = memchr(buf, '\n', n);
0157 len = p ? p - buf : n;
0158
0159 for (state = PM_SUSPEND_MIN; state < PM_SUSPEND_MAX; state++) {
0160 const char *label = mem_sleep_states[state];
0161
0162 if (label && len == strlen(label) && !strncmp(buf, label, len))
0163 return state;
0164 }
0165
0166 return PM_SUSPEND_ON;
0167 }
0168
0169 static ssize_t mem_sleep_store(struct kobject *kobj, struct kobj_attribute *attr,
0170 const char *buf, size_t n)
0171 {
0172 suspend_state_t state;
0173 int error;
0174
0175 error = pm_autosleep_lock();
0176 if (error)
0177 return error;
0178
0179 if (pm_autosleep_state() > PM_SUSPEND_ON) {
0180 error = -EBUSY;
0181 goto out;
0182 }
0183
0184 state = decode_suspend_state(buf, n);
0185 if (state < PM_SUSPEND_MAX && state > PM_SUSPEND_ON)
0186 mem_sleep_current = state;
0187 else
0188 error = -EINVAL;
0189
0190 out:
0191 pm_autosleep_unlock();
0192 return error ? error : n;
0193 }
0194
0195 power_attr(mem_sleep);
0196
0197
0198
0199
0200
0201
0202
0203 bool sync_on_suspend_enabled = !IS_ENABLED(CONFIG_SUSPEND_SKIP_SYNC);
0204
0205 static ssize_t sync_on_suspend_show(struct kobject *kobj,
0206 struct kobj_attribute *attr, char *buf)
0207 {
0208 return sprintf(buf, "%d\n", sync_on_suspend_enabled);
0209 }
0210
0211 static ssize_t sync_on_suspend_store(struct kobject *kobj,
0212 struct kobj_attribute *attr,
0213 const char *buf, size_t n)
0214 {
0215 unsigned long val;
0216
0217 if (kstrtoul(buf, 10, &val))
0218 return -EINVAL;
0219
0220 if (val > 1)
0221 return -EINVAL;
0222
0223 sync_on_suspend_enabled = !!val;
0224 return n;
0225 }
0226
0227 power_attr(sync_on_suspend);
0228 #endif
0229
0230 #ifdef CONFIG_PM_SLEEP_DEBUG
0231 int pm_test_level = TEST_NONE;
0232
0233 static const char * const pm_tests[__TEST_AFTER_LAST] = {
0234 [TEST_NONE] = "none",
0235 [TEST_CORE] = "core",
0236 [TEST_CPUS] = "processors",
0237 [TEST_PLATFORM] = "platform",
0238 [TEST_DEVICES] = "devices",
0239 [TEST_FREEZER] = "freezer",
0240 };
0241
0242 static ssize_t pm_test_show(struct kobject *kobj, struct kobj_attribute *attr,
0243 char *buf)
0244 {
0245 char *s = buf;
0246 int level;
0247
0248 for (level = TEST_FIRST; level <= TEST_MAX; level++)
0249 if (pm_tests[level]) {
0250 if (level == pm_test_level)
0251 s += sprintf(s, "[%s] ", pm_tests[level]);
0252 else
0253 s += sprintf(s, "%s ", pm_tests[level]);
0254 }
0255
0256 if (s != buf)
0257
0258 *(s-1) = '\n';
0259
0260 return (s - buf);
0261 }
0262
0263 static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr,
0264 const char *buf, size_t n)
0265 {
0266 const char * const *s;
0267 int level;
0268 char *p;
0269 int len;
0270 int error = -EINVAL;
0271
0272 p = memchr(buf, '\n', n);
0273 len = p ? p - buf : n;
0274
0275 lock_system_sleep();
0276
0277 level = TEST_FIRST;
0278 for (s = &pm_tests[level]; level <= TEST_MAX; s++, level++)
0279 if (*s && len == strlen(*s) && !strncmp(buf, *s, len)) {
0280 pm_test_level = level;
0281 error = 0;
0282 break;
0283 }
0284
0285 unlock_system_sleep();
0286
0287 return error ? error : n;
0288 }
0289
0290 power_attr(pm_test);
0291 #endif
0292
0293 static char *suspend_step_name(enum suspend_stat_step step)
0294 {
0295 switch (step) {
0296 case SUSPEND_FREEZE:
0297 return "freeze";
0298 case SUSPEND_PREPARE:
0299 return "prepare";
0300 case SUSPEND_SUSPEND:
0301 return "suspend";
0302 case SUSPEND_SUSPEND_NOIRQ:
0303 return "suspend_noirq";
0304 case SUSPEND_RESUME_NOIRQ:
0305 return "resume_noirq";
0306 case SUSPEND_RESUME:
0307 return "resume";
0308 default:
0309 return "";
0310 }
0311 }
0312
0313 #define suspend_attr(_name) \
0314 static ssize_t _name##_show(struct kobject *kobj, \
0315 struct kobj_attribute *attr, char *buf) \
0316 { \
0317 return sprintf(buf, "%d\n", suspend_stats._name); \
0318 } \
0319 static struct kobj_attribute _name = __ATTR_RO(_name)
0320
0321 suspend_attr(success);
0322 suspend_attr(fail);
0323 suspend_attr(failed_freeze);
0324 suspend_attr(failed_prepare);
0325 suspend_attr(failed_suspend);
0326 suspend_attr(failed_suspend_late);
0327 suspend_attr(failed_suspend_noirq);
0328 suspend_attr(failed_resume);
0329 suspend_attr(failed_resume_early);
0330 suspend_attr(failed_resume_noirq);
0331
0332 static ssize_t last_failed_dev_show(struct kobject *kobj,
0333 struct kobj_attribute *attr, char *buf)
0334 {
0335 int index;
0336 char *last_failed_dev = NULL;
0337
0338 index = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1;
0339 index %= REC_FAILED_NUM;
0340 last_failed_dev = suspend_stats.failed_devs[index];
0341
0342 return sprintf(buf, "%s\n", last_failed_dev);
0343 }
0344 static struct kobj_attribute last_failed_dev = __ATTR_RO(last_failed_dev);
0345
0346 static ssize_t last_failed_errno_show(struct kobject *kobj,
0347 struct kobj_attribute *attr, char *buf)
0348 {
0349 int index;
0350 int last_failed_errno;
0351
0352 index = suspend_stats.last_failed_errno + REC_FAILED_NUM - 1;
0353 index %= REC_FAILED_NUM;
0354 last_failed_errno = suspend_stats.errno[index];
0355
0356 return sprintf(buf, "%d\n", last_failed_errno);
0357 }
0358 static struct kobj_attribute last_failed_errno = __ATTR_RO(last_failed_errno);
0359
0360 static ssize_t last_failed_step_show(struct kobject *kobj,
0361 struct kobj_attribute *attr, char *buf)
0362 {
0363 int index;
0364 enum suspend_stat_step step;
0365 char *last_failed_step = NULL;
0366
0367 index = suspend_stats.last_failed_step + REC_FAILED_NUM - 1;
0368 index %= REC_FAILED_NUM;
0369 step = suspend_stats.failed_steps[index];
0370 last_failed_step = suspend_step_name(step);
0371
0372 return sprintf(buf, "%s\n", last_failed_step);
0373 }
0374 static struct kobj_attribute last_failed_step = __ATTR_RO(last_failed_step);
0375
0376 static struct attribute *suspend_attrs[] = {
0377 &success.attr,
0378 &fail.attr,
0379 &failed_freeze.attr,
0380 &failed_prepare.attr,
0381 &failed_suspend.attr,
0382 &failed_suspend_late.attr,
0383 &failed_suspend_noirq.attr,
0384 &failed_resume.attr,
0385 &failed_resume_early.attr,
0386 &failed_resume_noirq.attr,
0387 &last_failed_dev.attr,
0388 &last_failed_errno.attr,
0389 &last_failed_step.attr,
0390 NULL,
0391 };
0392
0393 static const struct attribute_group suspend_attr_group = {
0394 .name = "suspend_stats",
0395 .attrs = suspend_attrs,
0396 };
0397
0398 #ifdef CONFIG_DEBUG_FS
0399 static int suspend_stats_show(struct seq_file *s, void *unused)
0400 {
0401 int i, index, last_dev, last_errno, last_step;
0402
0403 last_dev = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1;
0404 last_dev %= REC_FAILED_NUM;
0405 last_errno = suspend_stats.last_failed_errno + REC_FAILED_NUM - 1;
0406 last_errno %= REC_FAILED_NUM;
0407 last_step = suspend_stats.last_failed_step + REC_FAILED_NUM - 1;
0408 last_step %= REC_FAILED_NUM;
0409 seq_printf(s, "%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n"
0410 "%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n",
0411 "success", suspend_stats.success,
0412 "fail", suspend_stats.fail,
0413 "failed_freeze", suspend_stats.failed_freeze,
0414 "failed_prepare", suspend_stats.failed_prepare,
0415 "failed_suspend", suspend_stats.failed_suspend,
0416 "failed_suspend_late",
0417 suspend_stats.failed_suspend_late,
0418 "failed_suspend_noirq",
0419 suspend_stats.failed_suspend_noirq,
0420 "failed_resume", suspend_stats.failed_resume,
0421 "failed_resume_early",
0422 suspend_stats.failed_resume_early,
0423 "failed_resume_noirq",
0424 suspend_stats.failed_resume_noirq);
0425 seq_printf(s, "failures:\n last_failed_dev:\t%-s\n",
0426 suspend_stats.failed_devs[last_dev]);
0427 for (i = 1; i < REC_FAILED_NUM; i++) {
0428 index = last_dev + REC_FAILED_NUM - i;
0429 index %= REC_FAILED_NUM;
0430 seq_printf(s, "\t\t\t%-s\n",
0431 suspend_stats.failed_devs[index]);
0432 }
0433 seq_printf(s, " last_failed_errno:\t%-d\n",
0434 suspend_stats.errno[last_errno]);
0435 for (i = 1; i < REC_FAILED_NUM; i++) {
0436 index = last_errno + REC_FAILED_NUM - i;
0437 index %= REC_FAILED_NUM;
0438 seq_printf(s, "\t\t\t%-d\n",
0439 suspend_stats.errno[index]);
0440 }
0441 seq_printf(s, " last_failed_step:\t%-s\n",
0442 suspend_step_name(
0443 suspend_stats.failed_steps[last_step]));
0444 for (i = 1; i < REC_FAILED_NUM; i++) {
0445 index = last_step + REC_FAILED_NUM - i;
0446 index %= REC_FAILED_NUM;
0447 seq_printf(s, "\t\t\t%-s\n",
0448 suspend_step_name(
0449 suspend_stats.failed_steps[index]));
0450 }
0451
0452 return 0;
0453 }
0454 DEFINE_SHOW_ATTRIBUTE(suspend_stats);
0455
0456 static int __init pm_debugfs_init(void)
0457 {
0458 debugfs_create_file("suspend_stats", S_IFREG | S_IRUGO,
0459 NULL, NULL, &suspend_stats_fops);
0460 return 0;
0461 }
0462
0463 late_initcall(pm_debugfs_init);
0464 #endif
0465
0466 #endif
0467
0468 #ifdef CONFIG_PM_SLEEP_DEBUG
0469
0470
0471
0472
0473
0474
0475 bool pm_print_times_enabled;
0476
0477 static ssize_t pm_print_times_show(struct kobject *kobj,
0478 struct kobj_attribute *attr, char *buf)
0479 {
0480 return sprintf(buf, "%d\n", pm_print_times_enabled);
0481 }
0482
0483 static ssize_t pm_print_times_store(struct kobject *kobj,
0484 struct kobj_attribute *attr,
0485 const char *buf, size_t n)
0486 {
0487 unsigned long val;
0488
0489 if (kstrtoul(buf, 10, &val))
0490 return -EINVAL;
0491
0492 if (val > 1)
0493 return -EINVAL;
0494
0495 pm_print_times_enabled = !!val;
0496 return n;
0497 }
0498
0499 power_attr(pm_print_times);
0500
0501 static inline void pm_print_times_init(void)
0502 {
0503 pm_print_times_enabled = !!initcall_debug;
0504 }
0505
0506 static ssize_t pm_wakeup_irq_show(struct kobject *kobj,
0507 struct kobj_attribute *attr,
0508 char *buf)
0509 {
0510 if (!pm_wakeup_irq())
0511 return -ENODATA;
0512
0513 return sprintf(buf, "%u\n", pm_wakeup_irq());
0514 }
0515
0516 power_attr_ro(pm_wakeup_irq);
0517
0518 bool pm_debug_messages_on __read_mostly;
0519
0520 static ssize_t pm_debug_messages_show(struct kobject *kobj,
0521 struct kobj_attribute *attr, char *buf)
0522 {
0523 return sprintf(buf, "%d\n", pm_debug_messages_on);
0524 }
0525
0526 static ssize_t pm_debug_messages_store(struct kobject *kobj,
0527 struct kobj_attribute *attr,
0528 const char *buf, size_t n)
0529 {
0530 unsigned long val;
0531
0532 if (kstrtoul(buf, 10, &val))
0533 return -EINVAL;
0534
0535 if (val > 1)
0536 return -EINVAL;
0537
0538 pm_debug_messages_on = !!val;
0539 return n;
0540 }
0541
0542 power_attr(pm_debug_messages);
0543
0544 static int __init pm_debug_messages_setup(char *str)
0545 {
0546 pm_debug_messages_on = true;
0547 return 1;
0548 }
0549 __setup("pm_debug_messages", pm_debug_messages_setup);
0550
0551 #else
0552 static inline void pm_print_times_init(void) {}
0553 #endif
0554
0555 struct kobject *power_kobj;
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568 static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr,
0569 char *buf)
0570 {
0571 char *s = buf;
0572 #ifdef CONFIG_SUSPEND
0573 suspend_state_t i;
0574
0575 for (i = PM_SUSPEND_MIN; i < PM_SUSPEND_MAX; i++)
0576 if (pm_states[i])
0577 s += sprintf(s,"%s ", pm_states[i]);
0578
0579 #endif
0580 if (hibernation_available())
0581 s += sprintf(s, "disk ");
0582 if (s != buf)
0583
0584 *(s-1) = '\n';
0585 return (s - buf);
0586 }
0587
0588 static suspend_state_t decode_state(const char *buf, size_t n)
0589 {
0590 #ifdef CONFIG_SUSPEND
0591 suspend_state_t state;
0592 #endif
0593 char *p;
0594 int len;
0595
0596 p = memchr(buf, '\n', n);
0597 len = p ? p - buf : n;
0598
0599
0600 if (len == 4 && str_has_prefix(buf, "disk"))
0601 return PM_SUSPEND_MAX;
0602
0603 #ifdef CONFIG_SUSPEND
0604 for (state = PM_SUSPEND_MIN; state < PM_SUSPEND_MAX; state++) {
0605 const char *label = pm_states[state];
0606
0607 if (label && len == strlen(label) && !strncmp(buf, label, len))
0608 return state;
0609 }
0610 #endif
0611
0612 return PM_SUSPEND_ON;
0613 }
0614
0615 static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
0616 const char *buf, size_t n)
0617 {
0618 suspend_state_t state;
0619 int error;
0620
0621 error = pm_autosleep_lock();
0622 if (error)
0623 return error;
0624
0625 if (pm_autosleep_state() > PM_SUSPEND_ON) {
0626 error = -EBUSY;
0627 goto out;
0628 }
0629
0630 state = decode_state(buf, n);
0631 if (state < PM_SUSPEND_MAX) {
0632 if (state == PM_SUSPEND_MEM)
0633 state = mem_sleep_current;
0634
0635 error = pm_suspend(state);
0636 } else if (state == PM_SUSPEND_MAX) {
0637 error = hibernate();
0638 } else {
0639 error = -EINVAL;
0640 }
0641
0642 out:
0643 pm_autosleep_unlock();
0644 return error ? error : n;
0645 }
0646
0647 power_attr(state);
0648
0649 #ifdef CONFIG_PM_SLEEP
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678 static ssize_t wakeup_count_show(struct kobject *kobj,
0679 struct kobj_attribute *attr,
0680 char *buf)
0681 {
0682 unsigned int val;
0683
0684 return pm_get_wakeup_count(&val, true) ?
0685 sprintf(buf, "%u\n", val) : -EINTR;
0686 }
0687
0688 static ssize_t wakeup_count_store(struct kobject *kobj,
0689 struct kobj_attribute *attr,
0690 const char *buf, size_t n)
0691 {
0692 unsigned int val;
0693 int error;
0694
0695 error = pm_autosleep_lock();
0696 if (error)
0697 return error;
0698
0699 if (pm_autosleep_state() > PM_SUSPEND_ON) {
0700 error = -EBUSY;
0701 goto out;
0702 }
0703
0704 error = -EINVAL;
0705 if (sscanf(buf, "%u", &val) == 1) {
0706 if (pm_save_wakeup_count(val))
0707 error = n;
0708 else
0709 pm_print_active_wakeup_sources();
0710 }
0711
0712 out:
0713 pm_autosleep_unlock();
0714 return error;
0715 }
0716
0717 power_attr(wakeup_count);
0718
0719 #ifdef CONFIG_PM_AUTOSLEEP
0720 static ssize_t autosleep_show(struct kobject *kobj,
0721 struct kobj_attribute *attr,
0722 char *buf)
0723 {
0724 suspend_state_t state = pm_autosleep_state();
0725
0726 if (state == PM_SUSPEND_ON)
0727 return sprintf(buf, "off\n");
0728
0729 #ifdef CONFIG_SUSPEND
0730 if (state < PM_SUSPEND_MAX)
0731 return sprintf(buf, "%s\n", pm_states[state] ?
0732 pm_states[state] : "error");
0733 #endif
0734 #ifdef CONFIG_HIBERNATION
0735 return sprintf(buf, "disk\n");
0736 #else
0737 return sprintf(buf, "error");
0738 #endif
0739 }
0740
0741 static ssize_t autosleep_store(struct kobject *kobj,
0742 struct kobj_attribute *attr,
0743 const char *buf, size_t n)
0744 {
0745 suspend_state_t state = decode_state(buf, n);
0746 int error;
0747
0748 if (state == PM_SUSPEND_ON
0749 && strcmp(buf, "off") && strcmp(buf, "off\n"))
0750 return -EINVAL;
0751
0752 if (state == PM_SUSPEND_MEM)
0753 state = mem_sleep_current;
0754
0755 error = pm_autosleep_set_state(state);
0756 return error ? error : n;
0757 }
0758
0759 power_attr(autosleep);
0760 #endif
0761
0762 #ifdef CONFIG_PM_WAKELOCKS
0763 static ssize_t wake_lock_show(struct kobject *kobj,
0764 struct kobj_attribute *attr,
0765 char *buf)
0766 {
0767 return pm_show_wakelocks(buf, true);
0768 }
0769
0770 static ssize_t wake_lock_store(struct kobject *kobj,
0771 struct kobj_attribute *attr,
0772 const char *buf, size_t n)
0773 {
0774 int error = pm_wake_lock(buf);
0775 return error ? error : n;
0776 }
0777
0778 power_attr(wake_lock);
0779
0780 static ssize_t wake_unlock_show(struct kobject *kobj,
0781 struct kobj_attribute *attr,
0782 char *buf)
0783 {
0784 return pm_show_wakelocks(buf, false);
0785 }
0786
0787 static ssize_t wake_unlock_store(struct kobject *kobj,
0788 struct kobj_attribute *attr,
0789 const char *buf, size_t n)
0790 {
0791 int error = pm_wake_unlock(buf);
0792 return error ? error : n;
0793 }
0794
0795 power_attr(wake_unlock);
0796
0797 #endif
0798 #endif
0799
0800 #ifdef CONFIG_PM_TRACE
0801 int pm_trace_enabled;
0802
0803 static ssize_t pm_trace_show(struct kobject *kobj, struct kobj_attribute *attr,
0804 char *buf)
0805 {
0806 return sprintf(buf, "%d\n", pm_trace_enabled);
0807 }
0808
0809 static ssize_t
0810 pm_trace_store(struct kobject *kobj, struct kobj_attribute *attr,
0811 const char *buf, size_t n)
0812 {
0813 int val;
0814
0815 if (sscanf(buf, "%d", &val) == 1) {
0816 pm_trace_enabled = !!val;
0817 if (pm_trace_enabled) {
0818 pr_warn("PM: Enabling pm_trace changes system date and time during resume.\n"
0819 "PM: Correct system time has to be restored manually after resume.\n");
0820 }
0821 return n;
0822 }
0823 return -EINVAL;
0824 }
0825
0826 power_attr(pm_trace);
0827
0828 static ssize_t pm_trace_dev_match_show(struct kobject *kobj,
0829 struct kobj_attribute *attr,
0830 char *buf)
0831 {
0832 return show_trace_dev_match(buf, PAGE_SIZE);
0833 }
0834
0835 power_attr_ro(pm_trace_dev_match);
0836
0837 #endif
0838
0839 #ifdef CONFIG_FREEZER
0840 static ssize_t pm_freeze_timeout_show(struct kobject *kobj,
0841 struct kobj_attribute *attr, char *buf)
0842 {
0843 return sprintf(buf, "%u\n", freeze_timeout_msecs);
0844 }
0845
0846 static ssize_t pm_freeze_timeout_store(struct kobject *kobj,
0847 struct kobj_attribute *attr,
0848 const char *buf, size_t n)
0849 {
0850 unsigned long val;
0851
0852 if (kstrtoul(buf, 10, &val))
0853 return -EINVAL;
0854
0855 freeze_timeout_msecs = val;
0856 return n;
0857 }
0858
0859 power_attr(pm_freeze_timeout);
0860
0861 #endif
0862
0863 static struct attribute * g[] = {
0864 &state_attr.attr,
0865 #ifdef CONFIG_PM_TRACE
0866 &pm_trace_attr.attr,
0867 &pm_trace_dev_match_attr.attr,
0868 #endif
0869 #ifdef CONFIG_PM_SLEEP
0870 &pm_async_attr.attr,
0871 &wakeup_count_attr.attr,
0872 #ifdef CONFIG_SUSPEND
0873 &mem_sleep_attr.attr,
0874 &sync_on_suspend_attr.attr,
0875 #endif
0876 #ifdef CONFIG_PM_AUTOSLEEP
0877 &autosleep_attr.attr,
0878 #endif
0879 #ifdef CONFIG_PM_WAKELOCKS
0880 &wake_lock_attr.attr,
0881 &wake_unlock_attr.attr,
0882 #endif
0883 #ifdef CONFIG_PM_SLEEP_DEBUG
0884 &pm_test_attr.attr,
0885 &pm_print_times_attr.attr,
0886 &pm_wakeup_irq_attr.attr,
0887 &pm_debug_messages_attr.attr,
0888 #endif
0889 #endif
0890 #ifdef CONFIG_FREEZER
0891 &pm_freeze_timeout_attr.attr,
0892 #endif
0893 NULL,
0894 };
0895
0896 static const struct attribute_group attr_group = {
0897 .attrs = g,
0898 };
0899
0900 static const struct attribute_group *attr_groups[] = {
0901 &attr_group,
0902 #ifdef CONFIG_PM_SLEEP
0903 &suspend_attr_group,
0904 #endif
0905 NULL,
0906 };
0907
0908 struct workqueue_struct *pm_wq;
0909 EXPORT_SYMBOL_GPL(pm_wq);
0910
0911 static int __init pm_start_workqueue(void)
0912 {
0913 pm_wq = alloc_workqueue("pm", WQ_FREEZABLE, 0);
0914
0915 return pm_wq ? 0 : -ENOMEM;
0916 }
0917
0918 static int __init pm_init(void)
0919 {
0920 int error = pm_start_workqueue();
0921 if (error)
0922 return error;
0923 hibernate_image_size_init();
0924 hibernate_reserved_size_init();
0925 pm_states_init();
0926 power_kobj = kobject_create_and_add("power", NULL);
0927 if (!power_kobj)
0928 return -ENOMEM;
0929 error = sysfs_create_groups(power_kobj, attr_groups);
0930 if (error)
0931 return error;
0932 pm_print_times_init();
0933 return pm_autosleep_init();
0934 }
0935
0936 core_initcall(pm_init);