PM: sleep: stats: Use unsigned int for success and failure counters
[linux-2.6-block.git] / kernel / power / main.c
CommitLineData
55716d26 1// SPDX-License-Identifier: GPL-2.0-only
1da177e4
LT
2/*
3 * kernel/power/main.c - PM subsystem core functionality.
4 *
5 * Copyright (c) 2003 Patrick Mochel
6 * Copyright (c) 2003 Open Source Development Lab
1da177e4
LT
7 */
8
b52124a7 9#include <linux/acpi.h>
6e5fdeed 10#include <linux/export.h>
1da177e4
LT
11#include <linux/kobject.h>
12#include <linux/string.h>
431d452a 13#include <linux/pm-trace.h>
5e928f77 14#include <linux/workqueue.h>
2a77c46d
SL
15#include <linux/debugfs.h>
16#include <linux/seq_file.h>
55f2503c 17#include <linux/suspend.h>
b5dee313 18#include <linux/syscalls.h>
f49249d5 19#include <linux/pm_runtime.h>
1da177e4
LT
20
21#include "power.h"
22
cd51e61c 23#ifdef CONFIG_PM_SLEEP
07f44ac3
KW
24/*
25 * The following functions are used by the suspend/hibernate code to temporarily
26 * change gfp_allowed_mask in order to avoid using I/O during memory allocations
27 * while devices are suspended. To avoid races with the suspend/hibernate code,
28 * they should always be called with system_transition_mutex held
29 * (gfp_allowed_mask also should only be modified with system_transition_mutex
30 * held, unless the suspend/hibernate code is guaranteed not to run in parallel
31 * with that modification).
32 */
33static gfp_t saved_gfp_mask;
34
35void pm_restore_gfp_mask(void)
36{
37 WARN_ON(!mutex_is_locked(&system_transition_mutex));
38 if (saved_gfp_mask) {
39 gfp_allowed_mask = saved_gfp_mask;
40 saved_gfp_mask = 0;
41 }
42}
43
44void pm_restrict_gfp_mask(void)
45{
46 WARN_ON(!mutex_is_locked(&system_transition_mutex));
47 WARN_ON(saved_gfp_mask);
48 saved_gfp_mask = gfp_allowed_mask;
49 gfp_allowed_mask &= ~(__GFP_IO | __GFP_FS);
50}
cd51e61c 51
5950e5d5 52unsigned int lock_system_sleep(void)
4bf236a3 53{
5950e5d5 54 unsigned int flags = current->flags;
f5d39b02 55 current->flags |= PF_NOFREEZE;
55f2503c 56 mutex_lock(&system_transition_mutex);
5950e5d5 57 return flags;
4bf236a3
BVA
58}
59EXPORT_SYMBOL_GPL(lock_system_sleep);
60
5950e5d5 61void unlock_system_sleep(unsigned int flags)
4bf236a3 62{
f5d39b02
PZ
63 if (!(flags & PF_NOFREEZE))
64 current->flags &= ~PF_NOFREEZE;
55f2503c 65 mutex_unlock(&system_transition_mutex);
4bf236a3
BVA
66}
67EXPORT_SYMBOL_GPL(unlock_system_sleep);
68
b5dee313
HP
69void ksys_sync_helper(void)
70{
c64546b1
HP
71 ktime_t start;
72 long elapsed_msecs;
73
74 start = ktime_get();
b5dee313 75 ksys_sync();
c64546b1
HP
76 elapsed_msecs = ktime_to_ms(ktime_sub(ktime_get(), start));
77 pr_info("Filesystems sync: %ld.%03ld seconds\n",
78 elapsed_msecs / MSEC_PER_SEC, elapsed_msecs % MSEC_PER_SEC);
b5dee313
HP
79}
80EXPORT_SYMBOL_GPL(ksys_sync_helper);
81
82525756
AS
82/* Routines for PM-transition notifications */
83
84static BLOCKING_NOTIFIER_HEAD(pm_chain_head);
85
86int register_pm_notifier(struct notifier_block *nb)
87{
88 return blocking_notifier_chain_register(&pm_chain_head, nb);
89}
90EXPORT_SYMBOL_GPL(register_pm_notifier);
91
92int unregister_pm_notifier(struct notifier_block *nb)
93{
94 return blocking_notifier_chain_unregister(&pm_chain_head, nb);
95}
96EXPORT_SYMBOL_GPL(unregister_pm_notifier);
97
b52124a7
ML
98void pm_report_hw_sleep_time(u64 t)
99{
100 suspend_stats.last_hw_sleep = t;
101 suspend_stats.total_hw_sleep += t;
102}
103EXPORT_SYMBOL_GPL(pm_report_hw_sleep_time);
104
105void pm_report_max_hw_sleep(u64 t)
106{
107 suspend_stats.max_hw_sleep = t;
108}
109EXPORT_SYMBOL_GPL(pm_report_max_hw_sleep);
110
70d93298 111int pm_notifier_call_chain_robust(unsigned long val_up, unsigned long val_down)
82525756 112{
ea00f4f4
LW
113 int ret;
114
70d93298 115 ret = blocking_notifier_call_chain_robust(&pm_chain_head, val_up, val_down, NULL);
f0c077a8
AM
116
117 return notifier_to_errno(ret);
82525756 118}
70d93298 119
ea00f4f4
LW
120int pm_notifier_call_chain(unsigned long val)
121{
70d93298 122 return blocking_notifier_call_chain(&pm_chain_head, val, NULL);
ea00f4f4 123}
82525756 124
0e06b4a8
RW
125/* If set, devices may be suspended and resumed asynchronously. */
126int pm_async_enabled = 1;
127
128static ssize_t pm_async_show(struct kobject *kobj, struct kobj_attribute *attr,
129 char *buf)
130{
131 return sprintf(buf, "%d\n", pm_async_enabled);
132}
133
134static ssize_t pm_async_store(struct kobject *kobj, struct kobj_attribute *attr,
135 const char *buf, size_t n)
136{
137 unsigned long val;
138
883ee4f7 139 if (kstrtoul(buf, 10, &val))
0e06b4a8
RW
140 return -EINVAL;
141
142 if (val > 1)
143 return -EINVAL;
144
145 pm_async_enabled = val;
146 return n;
147}
148
149power_attr(pm_async);
150
406e7938
RW
151#ifdef CONFIG_SUSPEND
152static ssize_t mem_sleep_show(struct kobject *kobj, struct kobj_attribute *attr,
153 char *buf)
154{
155 char *s = buf;
156 suspend_state_t i;
157
9ea4dcf4
DW
158 for (i = PM_SUSPEND_MIN; i < PM_SUSPEND_MAX; i++) {
159 if (i >= PM_SUSPEND_MEM && cxl_mem_active())
160 continue;
406e7938
RW
161 if (mem_sleep_states[i]) {
162 const char *label = mem_sleep_states[i];
163
164 if (mem_sleep_current == i)
165 s += sprintf(s, "[%s] ", label);
166 else
167 s += sprintf(s, "%s ", label);
168 }
9ea4dcf4 169 }
406e7938
RW
170
171 /* Convert the last space to a newline if needed. */
172 if (s != buf)
173 *(s-1) = '\n';
174
175 return (s - buf);
176}
177
178static suspend_state_t decode_suspend_state(const char *buf, size_t n)
179{
180 suspend_state_t state;
181 char *p;
182 int len;
183
184 p = memchr(buf, '\n', n);
185 len = p ? p - buf : n;
186
187 for (state = PM_SUSPEND_MIN; state < PM_SUSPEND_MAX; state++) {
188 const char *label = mem_sleep_states[state];
189
190 if (label && len == strlen(label) && !strncmp(buf, label, len))
191 return state;
192 }
193
194 return PM_SUSPEND_ON;
195}
196
197static ssize_t mem_sleep_store(struct kobject *kobj, struct kobj_attribute *attr,
198 const char *buf, size_t n)
199{
200 suspend_state_t state;
201 int error;
202
203 error = pm_autosleep_lock();
204 if (error)
205 return error;
206
207 if (pm_autosleep_state() > PM_SUSPEND_ON) {
208 error = -EBUSY;
209 goto out;
210 }
211
212 state = decode_suspend_state(buf, n);
213 if (state < PM_SUSPEND_MAX && state > PM_SUSPEND_ON)
214 mem_sleep_current = state;
215 else
216 error = -EINVAL;
217
218 out:
219 pm_autosleep_unlock();
220 return error ? error : n;
221}
222
223power_attr(mem_sleep);
c052bf82
JM
224
225/*
226 * sync_on_suspend: invoke ksys_sync_helper() before suspend.
227 *
228 * show() returns whether ksys_sync_helper() is invoked before suspend.
229 * store() accepts 0 or 1. 0 disables ksys_sync_helper() and 1 enables it.
230 */
231bool sync_on_suspend_enabled = !IS_ENABLED(CONFIG_SUSPEND_SKIP_SYNC);
232
233static ssize_t sync_on_suspend_show(struct kobject *kobj,
234 struct kobj_attribute *attr, char *buf)
235{
236 return sprintf(buf, "%d\n", sync_on_suspend_enabled);
237}
238
239static ssize_t sync_on_suspend_store(struct kobject *kobj,
240 struct kobj_attribute *attr,
241 const char *buf, size_t n)
242{
243 unsigned long val;
244
245 if (kstrtoul(buf, 10, &val))
246 return -EINVAL;
247
248 if (val > 1)
249 return -EINVAL;
250
251 sync_on_suspend_enabled = !!val;
252 return n;
253}
254
255power_attr(sync_on_suspend);
406e7938
RW
256#endif /* CONFIG_SUSPEND */
257
e516a1db 258#ifdef CONFIG_PM_SLEEP_DEBUG
0e7d56e3
RW
259int pm_test_level = TEST_NONE;
260
0e7d56e3
RW
261static const char * const pm_tests[__TEST_AFTER_LAST] = {
262 [TEST_NONE] = "none",
263 [TEST_CORE] = "core",
264 [TEST_CPUS] = "processors",
265 [TEST_PLATFORM] = "platform",
266 [TEST_DEVICES] = "devices",
267 [TEST_FREEZER] = "freezer",
268};
269
039a75c6
RW
270static ssize_t pm_test_show(struct kobject *kobj, struct kobj_attribute *attr,
271 char *buf)
0e7d56e3
RW
272{
273 char *s = buf;
274 int level;
275
276 for (level = TEST_FIRST; level <= TEST_MAX; level++)
277 if (pm_tests[level]) {
278 if (level == pm_test_level)
279 s += sprintf(s, "[%s] ", pm_tests[level]);
280 else
281 s += sprintf(s, "%s ", pm_tests[level]);
282 }
283
284 if (s != buf)
285 /* convert the last space to a newline */
286 *(s-1) = '\n';
287
288 return (s - buf);
289}
290
039a75c6
RW
291static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr,
292 const char *buf, size_t n)
0e7d56e3 293{
5950e5d5 294 unsigned int sleep_flags;
0e7d56e3 295 const char * const *s;
5950e5d5 296 int error = -EINVAL;
0e7d56e3
RW
297 int level;
298 char *p;
299 int len;
0e7d56e3
RW
300
301 p = memchr(buf, '\n', n);
302 len = p ? p - buf : n;
303
5950e5d5 304 sleep_flags = lock_system_sleep();
0e7d56e3
RW
305
306 level = TEST_FIRST;
307 for (s = &pm_tests[level]; level <= TEST_MAX; s++, level++)
308 if (*s && len == strlen(*s) && !strncmp(buf, *s, len)) {
309 pm_test_level = level;
310 error = 0;
311 break;
312 }
313
5950e5d5 314 unlock_system_sleep(sleep_flags);
0e7d56e3
RW
315
316 return error ? error : n;
317}
318
319power_attr(pm_test);
e516a1db 320#endif /* CONFIG_PM_SLEEP_DEBUG */
0e7d56e3 321
bc88528c
RW
322static const char * const suspend_step_names[] = {
323 [SUSPEND_WORKING] = "",
324 [SUSPEND_FREEZE] = "freeze",
325 [SUSPEND_PREPARE] = "prepare",
326 [SUSPEND_SUSPEND] = "suspend",
327 [SUSPEND_SUSPEND_LATE] = "suspend_late",
328 [SUSPEND_SUSPEND_NOIRQ] = "suspend_noirq",
329 [SUSPEND_RESUME_NOIRQ] = "resume_noirq",
330 [SUSPEND_RESUME_EARLY] = "resume_early",
331 [SUSPEND_RESUME] = "resume",
332};
2a77c46d 333
b52124a7 334#define suspend_attr(_name, format_str) \
2c8db5be
KS
335static ssize_t _name##_show(struct kobject *kobj, \
336 struct kobj_attribute *attr, char *buf) \
337{ \
b52124a7 338 return sprintf(buf, format_str, suspend_stats._name); \
2c8db5be
KS
339} \
340static struct kobj_attribute _name = __ATTR_RO(_name)
341
2231f78d
RW
342suspend_attr(success, "%u\n");
343suspend_attr(fail, "%u\n");
b52124a7
ML
344suspend_attr(last_hw_sleep, "%llu\n");
345suspend_attr(total_hw_sleep, "%llu\n");
346suspend_attr(max_hw_sleep, "%llu\n");
2c8db5be 347
b730bab0
RW
348#define suspend_step_attr(_name, step) \
349static ssize_t _name##_show(struct kobject *kobj, \
350 struct kobj_attribute *attr, char *buf) \
351{ \
352 return sprintf(buf, "%u\n", \
353 suspend_stats.step_failures[step-1]); \
354} \
355static struct kobj_attribute _name = __ATTR_RO(_name)
356
357suspend_step_attr(failed_freeze, SUSPEND_FREEZE);
358suspend_step_attr(failed_prepare, SUSPEND_PREPARE);
359suspend_step_attr(failed_suspend, SUSPEND_SUSPEND);
360suspend_step_attr(failed_suspend_late, SUSPEND_SUSPEND_LATE);
361suspend_step_attr(failed_suspend_noirq, SUSPEND_SUSPEND_NOIRQ);
362suspend_step_attr(failed_resume, SUSPEND_RESUME);
363suspend_step_attr(failed_resume_early, SUSPEND_RESUME_EARLY);
364suspend_step_attr(failed_resume_noirq, SUSPEND_RESUME_NOIRQ);
365
2c8db5be
KS
366static ssize_t last_failed_dev_show(struct kobject *kobj,
367 struct kobj_attribute *attr, char *buf)
368{
369 int index;
370 char *last_failed_dev = NULL;
371
372 index = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1;
373 index %= REC_FAILED_NUM;
374 last_failed_dev = suspend_stats.failed_devs[index];
375
376 return sprintf(buf, "%s\n", last_failed_dev);
377}
378static struct kobj_attribute last_failed_dev = __ATTR_RO(last_failed_dev);
379
380static ssize_t last_failed_errno_show(struct kobject *kobj,
381 struct kobj_attribute *attr, char *buf)
382{
383 int index;
384 int last_failed_errno;
385
386 index = suspend_stats.last_failed_errno + REC_FAILED_NUM - 1;
387 index %= REC_FAILED_NUM;
388 last_failed_errno = suspend_stats.errno[index];
389
390 return sprintf(buf, "%d\n", last_failed_errno);
391}
392static struct kobj_attribute last_failed_errno = __ATTR_RO(last_failed_errno);
393
394static ssize_t last_failed_step_show(struct kobject *kobj,
395 struct kobj_attribute *attr, char *buf)
396{
2c8db5be 397 enum suspend_stat_step step;
bc88528c 398 int index;
2c8db5be
KS
399
400 index = suspend_stats.last_failed_step + REC_FAILED_NUM - 1;
401 index %= REC_FAILED_NUM;
402 step = suspend_stats.failed_steps[index];
2c8db5be 403
bc88528c 404 return sprintf(buf, "%s\n", suspend_step_names[step]);
2c8db5be
KS
405}
406static struct kobj_attribute last_failed_step = __ATTR_RO(last_failed_step);
407
408static struct attribute *suspend_attrs[] = {
409 &success.attr,
410 &fail.attr,
411 &failed_freeze.attr,
412 &failed_prepare.attr,
413 &failed_suspend.attr,
414 &failed_suspend_late.attr,
415 &failed_suspend_noirq.attr,
416 &failed_resume.attr,
417 &failed_resume_early.attr,
418 &failed_resume_noirq.attr,
419 &last_failed_dev.attr,
420 &last_failed_errno.attr,
421 &last_failed_step.attr,
b52124a7
ML
422 &last_hw_sleep.attr,
423 &total_hw_sleep.attr,
424 &max_hw_sleep.attr,
2c8db5be
KS
425 NULL,
426};
427
b52124a7
ML
428static umode_t suspend_attr_is_visible(struct kobject *kobj, struct attribute *attr, int idx)
429{
430 if (attr != &last_hw_sleep.attr &&
431 attr != &total_hw_sleep.attr &&
432 attr != &max_hw_sleep.attr)
433 return 0444;
434
435#ifdef CONFIG_ACPI
436 if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)
437 return 0444;
438#endif
439 return 0;
440}
441
15560574 442static const struct attribute_group suspend_attr_group = {
2c8db5be
KS
443 .name = "suspend_stats",
444 .attrs = suspend_attrs,
b52124a7 445 .is_visible = suspend_attr_is_visible,
2c8db5be
KS
446};
447
448#ifdef CONFIG_DEBUG_FS
2a77c46d
SL
449static int suspend_stats_show(struct seq_file *s, void *unused)
450{
451 int i, index, last_dev, last_errno, last_step;
b730bab0 452 enum suspend_stat_step step;
2a77c46d
SL
453
454 last_dev = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1;
455 last_dev %= REC_FAILED_NUM;
456 last_errno = suspend_stats.last_failed_errno + REC_FAILED_NUM - 1;
457 last_errno %= REC_FAILED_NUM;
458 last_step = suspend_stats.last_failed_step + REC_FAILED_NUM - 1;
459 last_step %= REC_FAILED_NUM;
b730bab0 460
2231f78d 461 seq_printf(s, "success: %u\nfail: %u\n",
b730bab0
RW
462 suspend_stats.success, suspend_stats.fail);
463
464 for (step = SUSPEND_FREEZE; step <= SUSPEND_NR_STEPS; step++)
465 seq_printf(s, "failed_%s: %u\n", suspend_step_names[step],
466 suspend_stats.step_failures[step-1]);
467
2a77c46d 468 seq_printf(s, "failures:\n last_failed_dev:\t%-s\n",
bc88528c 469 suspend_stats.failed_devs[last_dev]);
2a77c46d
SL
470 for (i = 1; i < REC_FAILED_NUM; i++) {
471 index = last_dev + REC_FAILED_NUM - i;
472 index %= REC_FAILED_NUM;
bc88528c 473 seq_printf(s, "\t\t\t%-s\n", suspend_stats.failed_devs[index]);
2a77c46d
SL
474 }
475 seq_printf(s, " last_failed_errno:\t%-d\n",
476 suspend_stats.errno[last_errno]);
477 for (i = 1; i < REC_FAILED_NUM; i++) {
478 index = last_errno + REC_FAILED_NUM - i;
479 index %= REC_FAILED_NUM;
bc88528c 480 seq_printf(s, "\t\t\t%-d\n", suspend_stats.errno[index]);
2a77c46d
SL
481 }
482 seq_printf(s, " last_failed_step:\t%-s\n",
bc88528c 483 suspend_step_names[suspend_stats.failed_steps[last_step]]);
2a77c46d
SL
484 for (i = 1; i < REC_FAILED_NUM; i++) {
485 index = last_step + REC_FAILED_NUM - i;
486 index %= REC_FAILED_NUM;
487 seq_printf(s, "\t\t\t%-s\n",
bc88528c 488 suspend_step_names[suspend_stats.failed_steps[index]]);
2a77c46d
SL
489 }
490
491 return 0;
492}
943a10f8 493DEFINE_SHOW_ATTRIBUTE(suspend_stats);
2a77c46d
SL
494
495static int __init pm_debugfs_init(void)
496{
497 debugfs_create_file("suspend_stats", S_IFREG | S_IRUGO,
943a10f8 498 NULL, NULL, &suspend_stats_fops);
2a77c46d
SL
499 return 0;
500}
501
502late_initcall(pm_debugfs_init);
503#endif /* CONFIG_DEBUG_FS */
504
ca123102
RW
505#endif /* CONFIG_PM_SLEEP */
506
b2df1d4f
RW
507#ifdef CONFIG_PM_SLEEP_DEBUG
508/*
509 * pm_print_times: print time taken by devices to suspend and resume.
510 *
511 * show() returns whether printing of suspend and resume times is enabled.
512 * store() accepts 0 or 1. 0 disables printing and 1 enables it.
513 */
514bool pm_print_times_enabled;
515
516static ssize_t pm_print_times_show(struct kobject *kobj,
517 struct kobj_attribute *attr, char *buf)
518{
519 return sprintf(buf, "%d\n", pm_print_times_enabled);
520}
521
522static ssize_t pm_print_times_store(struct kobject *kobj,
523 struct kobj_attribute *attr,
524 const char *buf, size_t n)
525{
526 unsigned long val;
527
528 if (kstrtoul(buf, 10, &val))
529 return -EINVAL;
530
531 if (val > 1)
532 return -EINVAL;
533
534 pm_print_times_enabled = !!val;
535 return n;
536}
537
538power_attr(pm_print_times);
539
540static inline void pm_print_times_init(void)
541{
542 pm_print_times_enabled = !!initcall_debug;
543}
a6f5f0dd
AY
544
545static ssize_t pm_wakeup_irq_show(struct kobject *kobj,
546 struct kobj_attribute *attr,
547 char *buf)
548{
cb1f65c1
RW
549 if (!pm_wakeup_irq())
550 return -ENODATA;
551
552 return sprintf(buf, "%u\n", pm_wakeup_irq());
a6f5f0dd
AY
553}
554
a1e9ca69 555power_attr_ro(pm_wakeup_irq);
a6f5f0dd 556
726fb6b4 557bool pm_debug_messages_on __read_mostly;
8d8b2441 558
cdb8c100
ML
559bool pm_debug_messages_should_print(void)
560{
561 return pm_debug_messages_on && pm_suspend_target_state != PM_SUSPEND_ON;
562}
563EXPORT_SYMBOL_GPL(pm_debug_messages_should_print);
564
8d8b2441
RW
565static ssize_t pm_debug_messages_show(struct kobject *kobj,
566 struct kobj_attribute *attr, char *buf)
567{
568 return sprintf(buf, "%d\n", pm_debug_messages_on);
569}
570
571static ssize_t pm_debug_messages_store(struct kobject *kobj,
572 struct kobj_attribute *attr,
573 const char *buf, size_t n)
574{
575 unsigned long val;
576
577 if (kstrtoul(buf, 10, &val))
578 return -EINVAL;
579
580 if (val > 1)
581 return -EINVAL;
582
583 pm_debug_messages_on = !!val;
584 return n;
585}
586
587power_attr(pm_debug_messages);
588
db96a759
CY
589static int __init pm_debug_messages_setup(char *str)
590{
591 pm_debug_messages_on = true;
592 return 1;
593}
594__setup("pm_debug_messages", pm_debug_messages_setup);
595
819b1bb3 596#else /* !CONFIG_PM_SLEEP_DEBUG */
b2df1d4f
RW
597static inline void pm_print_times_init(void) {}
598#endif /* CONFIG_PM_SLEEP_DEBUG */
599
d76e15fb 600struct kobject *power_kobj;
1da177e4 601
dbcfa715 602/*
0399d4db 603 * state - control system sleep states.
1da177e4 604 *
0399d4db 605 * show() returns available sleep state labels, which may be "mem", "standby",
44348e8a
MCC
606 * "freeze" and "disk" (hibernation).
607 * See Documentation/admin-guide/pm/sleep-states.rst for a description of
608 * what they mean.
1da177e4 609 *
0399d4db
RW
610 * store() accepts one of those strings, translates it into the proper
611 * enumerated value, and initiates a suspend transition.
1da177e4 612 */
386f275f
KS
613static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr,
614 char *buf)
1da177e4 615{
296699de
RW
616 char *s = buf;
617#ifdef CONFIG_SUSPEND
27ddcc65
RW
618 suspend_state_t i;
619
620 for (i = PM_SUSPEND_MIN; i < PM_SUSPEND_MAX; i++)
d431cbc5
RW
621 if (pm_states[i])
622 s += sprintf(s,"%s ", pm_states[i]);
1da177e4 623
296699de 624#endif
a6e15a39
KC
625 if (hibernation_available())
626 s += sprintf(s, "disk ");
a3d25c27
RW
627 if (s != buf)
628 /* convert the last space to a newline */
629 *(s-1) = '\n';
1da177e4
LT
630 return (s - buf);
631}
632
7483b4a4 633static suspend_state_t decode_state(const char *buf, size_t n)
1da177e4 634{
296699de 635#ifdef CONFIG_SUSPEND
d431cbc5 636 suspend_state_t state;
296699de 637#endif
1da177e4 638 char *p;
1da177e4
LT
639 int len;
640
641 p = memchr(buf, '\n', n);
642 len = p ? p - buf : n;
643
7483b4a4 644 /* Check hibernation first. */
d30bdfc0 645 if (len == 4 && str_has_prefix(buf, "disk"))
7483b4a4 646 return PM_SUSPEND_MAX;
a3d25c27 647
296699de 648#ifdef CONFIG_SUSPEND
d431cbc5
RW
649 for (state = PM_SUSPEND_MIN; state < PM_SUSPEND_MAX; state++) {
650 const char *label = pm_states[state];
651
652 if (label && len == strlen(label) && !strncmp(buf, label, len))
653 return state;
654 }
296699de
RW
655#endif
656
7483b4a4
RW
657 return PM_SUSPEND_ON;
658}
659
660static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
661 const char *buf, size_t n)
662{
663 suspend_state_t state;
664 int error;
665
666 error = pm_autosleep_lock();
667 if (error)
668 return error;
669
670 if (pm_autosleep_state() > PM_SUSPEND_ON) {
671 error = -EBUSY;
672 goto out;
673 }
674
675 state = decode_state(buf, n);
406e7938
RW
676 if (state < PM_SUSPEND_MAX) {
677 if (state == PM_SUSPEND_MEM)
678 state = mem_sleep_current;
679
7483b4a4 680 error = pm_suspend(state);
406e7938 681 } else if (state == PM_SUSPEND_MAX) {
7483b4a4 682 error = hibernate();
406e7938 683 } else {
7483b4a4 684 error = -EINVAL;
406e7938 685 }
7483b4a4
RW
686
687 out:
688 pm_autosleep_unlock();
1da177e4
LT
689 return error ? error : n;
690}
691
692power_attr(state);
693
c125e96f
RW
694#ifdef CONFIG_PM_SLEEP
695/*
696 * The 'wakeup_count' attribute, along with the functions defined in
697 * drivers/base/power/wakeup.c, provides a means by which wakeup events can be
698 * handled in a non-racy way.
699 *
700 * If a wakeup event occurs when the system is in a sleep state, it simply is
701 * woken up. In turn, if an event that would wake the system up from a sleep
702 * state occurs when it is undergoing a transition to that sleep state, the
703 * transition should be aborted. Moreover, if such an event occurs when the
704 * system is in the working state, an attempt to start a transition to the
705 * given sleep state should fail during certain period after the detection of
706 * the event. Using the 'state' attribute alone is not sufficient to satisfy
707 * these requirements, because a wakeup event may occur exactly when 'state'
708 * is being written to and may be delivered to user space right before it is
709 * frozen, so the event will remain only partially processed until the system is
710 * woken up by another event. In particular, it won't cause the transition to
711 * a sleep state to be aborted.
712 *
713 * This difficulty may be overcome if user space uses 'wakeup_count' before
714 * writing to 'state'. It first should read from 'wakeup_count' and store
715 * the read value. Then, after carrying out its own preparations for the system
716 * transition to a sleep state, it should write the stored value to
25985edc 717 * 'wakeup_count'. If that fails, at least one wakeup event has occurred since
c125e96f
RW
718 * 'wakeup_count' was read and 'state' should not be written to. Otherwise, it
719 * is allowed to write to 'state', but the transition will be aborted if there
720 * are any wakeup events detected after 'wakeup_count' was written to.
721 */
722
723static ssize_t wakeup_count_show(struct kobject *kobj,
724 struct kobj_attribute *attr,
725 char *buf)
726{
074037ec 727 unsigned int val;
c125e96f 728
7483b4a4
RW
729 return pm_get_wakeup_count(&val, true) ?
730 sprintf(buf, "%u\n", val) : -EINTR;
c125e96f
RW
731}
732
733static ssize_t wakeup_count_store(struct kobject *kobj,
734 struct kobj_attribute *attr,
735 const char *buf, size_t n)
736{
074037ec 737 unsigned int val;
7483b4a4
RW
738 int error;
739
740 error = pm_autosleep_lock();
741 if (error)
742 return error;
c125e96f 743
7483b4a4
RW
744 if (pm_autosleep_state() > PM_SUSPEND_ON) {
745 error = -EBUSY;
746 goto out;
747 }
748
749 error = -EINVAL;
074037ec 750 if (sscanf(buf, "%u", &val) == 1) {
c125e96f 751 if (pm_save_wakeup_count(val))
7483b4a4 752 error = n;
bb177fed
JW
753 else
754 pm_print_active_wakeup_sources();
c125e96f 755 }
7483b4a4
RW
756
757 out:
758 pm_autosleep_unlock();
759 return error;
c125e96f
RW
760}
761
762power_attr(wakeup_count);
7483b4a4
RW
763
764#ifdef CONFIG_PM_AUTOSLEEP
765static ssize_t autosleep_show(struct kobject *kobj,
766 struct kobj_attribute *attr,
767 char *buf)
768{
769 suspend_state_t state = pm_autosleep_state();
770
771 if (state == PM_SUSPEND_ON)
772 return sprintf(buf, "off\n");
773
774#ifdef CONFIG_SUSPEND
775 if (state < PM_SUSPEND_MAX)
d431cbc5
RW
776 return sprintf(buf, "%s\n", pm_states[state] ?
777 pm_states[state] : "error");
7483b4a4
RW
778#endif
779#ifdef CONFIG_HIBERNATION
780 return sprintf(buf, "disk\n");
781#else
782 return sprintf(buf, "error");
783#endif
784}
785
786static ssize_t autosleep_store(struct kobject *kobj,
787 struct kobj_attribute *attr,
788 const char *buf, size_t n)
789{
790 suspend_state_t state = decode_state(buf, n);
791 int error;
792
793 if (state == PM_SUSPEND_ON
040e5bf6 794 && strcmp(buf, "off") && strcmp(buf, "off\n"))
7483b4a4
RW
795 return -EINVAL;
796
406e7938
RW
797 if (state == PM_SUSPEND_MEM)
798 state = mem_sleep_current;
799
7483b4a4
RW
800 error = pm_autosleep_set_state(state);
801 return error ? error : n;
802}
803
804power_attr(autosleep);
805#endif /* CONFIG_PM_AUTOSLEEP */
b86ff982
RW
806
807#ifdef CONFIG_PM_WAKELOCKS
808static ssize_t wake_lock_show(struct kobject *kobj,
809 struct kobj_attribute *attr,
810 char *buf)
811{
812 return pm_show_wakelocks(buf, true);
813}
814
815static ssize_t wake_lock_store(struct kobject *kobj,
816 struct kobj_attribute *attr,
817 const char *buf, size_t n)
818{
819 int error = pm_wake_lock(buf);
820 return error ? error : n;
821}
822
823power_attr(wake_lock);
824
825static ssize_t wake_unlock_show(struct kobject *kobj,
826 struct kobj_attribute *attr,
827 char *buf)
828{
829 return pm_show_wakelocks(buf, false);
830}
831
832static ssize_t wake_unlock_store(struct kobject *kobj,
833 struct kobj_attribute *attr,
834 const char *buf, size_t n)
835{
836 int error = pm_wake_unlock(buf);
837 return error ? error : n;
838}
839
840power_attr(wake_unlock);
841
842#endif /* CONFIG_PM_WAKELOCKS */
c125e96f
RW
843#endif /* CONFIG_PM_SLEEP */
844
c5c6ba4e
RW
845#ifdef CONFIG_PM_TRACE
846int pm_trace_enabled;
847
386f275f
KS
848static ssize_t pm_trace_show(struct kobject *kobj, struct kobj_attribute *attr,
849 char *buf)
c5c6ba4e
RW
850{
851 return sprintf(buf, "%d\n", pm_trace_enabled);
852}
853
854static ssize_t
386f275f
KS
855pm_trace_store(struct kobject *kobj, struct kobj_attribute *attr,
856 const char *buf, size_t n)
c5c6ba4e
RW
857{
858 int val;
859
860 if (sscanf(buf, "%d", &val) == 1) {
861 pm_trace_enabled = !!val;
9dceefe4
SK
862 if (pm_trace_enabled) {
863 pr_warn("PM: Enabling pm_trace changes system date and time during resume.\n"
864 "PM: Correct system time has to be restored manually after resume.\n");
865 }
c5c6ba4e
RW
866 return n;
867 }
868 return -EINVAL;
869}
870
871power_attr(pm_trace);
d33ac60b
JH
872
873static ssize_t pm_trace_dev_match_show(struct kobject *kobj,
874 struct kobj_attribute *attr,
875 char *buf)
876{
877 return show_trace_dev_match(buf, PAGE_SIZE);
878}
879
a1e9ca69 880power_attr_ro(pm_trace_dev_match);
d33ac60b 881
0e7d56e3 882#endif /* CONFIG_PM_TRACE */
c5c6ba4e 883
957d1282
LF
884#ifdef CONFIG_FREEZER
885static ssize_t pm_freeze_timeout_show(struct kobject *kobj,
886 struct kobj_attribute *attr, char *buf)
887{
888 return sprintf(buf, "%u\n", freeze_timeout_msecs);
889}
890
891static ssize_t pm_freeze_timeout_store(struct kobject *kobj,
892 struct kobj_attribute *attr,
893 const char *buf, size_t n)
894{
895 unsigned long val;
896
897 if (kstrtoul(buf, 10, &val))
898 return -EINVAL;
899
900 freeze_timeout_msecs = val;
901 return n;
902}
903
904power_attr(pm_freeze_timeout);
905
906#endif /* CONFIG_FREEZER*/
907
c5c6ba4e
RW
908static struct attribute * g[] = {
909 &state_attr.attr,
0e7d56e3 910#ifdef CONFIG_PM_TRACE
c5c6ba4e 911 &pm_trace_attr.attr,
d33ac60b 912 &pm_trace_dev_match_attr.attr,
0e7d56e3 913#endif
0e06b4a8
RW
914#ifdef CONFIG_PM_SLEEP
915 &pm_async_attr.attr,
c125e96f 916 &wakeup_count_attr.attr,
406e7938
RW
917#ifdef CONFIG_SUSPEND
918 &mem_sleep_attr.attr,
c052bf82 919 &sync_on_suspend_attr.attr,
406e7938 920#endif
7483b4a4
RW
921#ifdef CONFIG_PM_AUTOSLEEP
922 &autosleep_attr.attr,
923#endif
b86ff982
RW
924#ifdef CONFIG_PM_WAKELOCKS
925 &wake_lock_attr.attr,
926 &wake_unlock_attr.attr,
927#endif
b2df1d4f 928#ifdef CONFIG_PM_SLEEP_DEBUG
e516a1db 929 &pm_test_attr.attr,
4b7760ba 930 &pm_print_times_attr.attr,
a6f5f0dd 931 &pm_wakeup_irq_attr.attr,
8d8b2441 932 &pm_debug_messages_attr.attr,
0e06b4a8 933#endif
957d1282
LF
934#endif
935#ifdef CONFIG_FREEZER
936 &pm_freeze_timeout_attr.attr,
0e7d56e3 937#endif
c5c6ba4e
RW
938 NULL,
939};
1da177e4 940
1d0c6e59 941static const struct attribute_group attr_group = {
1da177e4
LT
942 .attrs = g,
943};
944
2c8db5be
KS
945static const struct attribute_group *attr_groups[] = {
946 &attr_group,
947#ifdef CONFIG_PM_SLEEP
948 &suspend_attr_group,
949#endif
950 NULL,
951};
952
5e928f77 953struct workqueue_struct *pm_wq;
7b199ca2 954EXPORT_SYMBOL_GPL(pm_wq);
5e928f77
RW
955
956static int __init pm_start_workqueue(void)
957{
58a69cb4 958 pm_wq = alloc_workqueue("pm", WQ_FREEZABLE, 0);
5e928f77
RW
959
960 return pm_wq ? 0 : -ENOMEM;
961}
5e928f77 962
1da177e4
LT
963static int __init pm_init(void)
964{
5e928f77
RW
965 int error = pm_start_workqueue();
966 if (error)
967 return error;
ac5c24ec 968 hibernate_image_size_init();
ddeb6487 969 hibernate_reserved_size_init();
fa7fd6fa 970 pm_states_init();
d76e15fb
GKH
971 power_kobj = kobject_create_and_add("power", NULL);
972 if (!power_kobj)
039a5dcd 973 return -ENOMEM;
2c8db5be 974 error = sysfs_create_groups(power_kobj, attr_groups);
7483b4a4
RW
975 if (error)
976 return error;
b2df1d4f 977 pm_print_times_init();
7483b4a4 978 return pm_autosleep_init();
1da177e4
LT
979}
980
981core_initcall(pm_init);