Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only
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
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 : :
24 : 234 : void lock_system_sleep(void)
25 : : {
26 : 234 : current->flags |= PF_FREEZER_SKIP;
27 : 234 : mutex_lock(&system_transition_mutex);
28 : 234 : }
29 : : EXPORT_SYMBOL_GPL(lock_system_sleep);
30 : :
31 : 234 : void unlock_system_sleep(void)
32 : : {
33 : : /*
34 : : * Don't use freezer_count() because we don't want the call to
35 : : * try_to_freeze() here.
36 : : *
37 : : * Reason:
38 : : * Fundamentally, we just don't need it, because freezing condition
39 : : * doesn't come into effect until we release the
40 : : * system_transition_mutex lock, since the freezer always works with
41 : : * system_transition_mutex held.
42 : : *
43 : : * More importantly, in the case of hibernation,
44 : : * unlock_system_sleep() gets called in snapshot_read() and
45 : : * snapshot_write() when the freezing condition is still in effect.
46 : : * Which means, if we use try_to_freeze() here, it would make them
47 : : * enter the refrigerator, thus causing hibernation to lockup.
48 : : */
49 : 234 : current->flags &= ~PF_FREEZER_SKIP;
50 : 234 : mutex_unlock(&system_transition_mutex);
51 : 234 : }
52 : : EXPORT_SYMBOL_GPL(unlock_system_sleep);
53 : :
54 : 0 : void ksys_sync_helper(void)
55 : : {
56 : 0 : ktime_t start;
57 : 0 : long elapsed_msecs;
58 : :
59 : 0 : start = ktime_get();
60 : 0 : ksys_sync();
61 : 0 : elapsed_msecs = ktime_to_ms(ktime_sub(ktime_get(), start));
62 : 0 : pr_info("Filesystems sync: %ld.%03ld seconds\n",
63 : : elapsed_msecs / MSEC_PER_SEC, elapsed_msecs % MSEC_PER_SEC);
64 : 0 : }
65 : : EXPORT_SYMBOL_GPL(ksys_sync_helper);
66 : :
67 : : /* Routines for PM-transition notifications */
68 : :
69 : : static BLOCKING_NOTIFIER_HEAD(pm_chain_head);
70 : :
71 : 468 : int register_pm_notifier(struct notifier_block *nb)
72 : : {
73 : 468 : return blocking_notifier_chain_register(&pm_chain_head, nb);
74 : : }
75 : : EXPORT_SYMBOL_GPL(register_pm_notifier);
76 : :
77 : 0 : int unregister_pm_notifier(struct notifier_block *nb)
78 : : {
79 : 0 : return blocking_notifier_chain_unregister(&pm_chain_head, nb);
80 : : }
81 : : EXPORT_SYMBOL_GPL(unregister_pm_notifier);
82 : :
83 : 0 : int __pm_notifier_call_chain(unsigned long val, int nr_to_call, int *nr_calls)
84 : : {
85 : 0 : int ret;
86 : :
87 : 0 : ret = __blocking_notifier_call_chain(&pm_chain_head, val, NULL,
88 : : nr_to_call, nr_calls);
89 : :
90 [ # # # # ]: 0 : return notifier_to_errno(ret);
91 : : }
92 : 0 : int pm_notifier_call_chain(unsigned long val)
93 : : {
94 : 0 : return __pm_notifier_call_chain(val, -1, NULL);
95 : : }
96 : :
97 : : /* If set, devices may be suspended and resumed asynchronously. */
98 : : int pm_async_enabled = 1;
99 : :
100 : 0 : static ssize_t pm_async_show(struct kobject *kobj, struct kobj_attribute *attr,
101 : : char *buf)
102 : : {
103 : 0 : return sprintf(buf, "%d\n", pm_async_enabled);
104 : : }
105 : :
106 : 0 : static ssize_t pm_async_store(struct kobject *kobj, struct kobj_attribute *attr,
107 : : const char *buf, size_t n)
108 : : {
109 : 0 : unsigned long val;
110 : :
111 [ # # ]: 0 : if (kstrtoul(buf, 10, &val))
112 : : return -EINVAL;
113 : :
114 [ # # ]: 0 : if (val > 1)
115 : : return -EINVAL;
116 : :
117 : 0 : pm_async_enabled = val;
118 : 0 : return n;
119 : : }
120 : :
121 : : power_attr(pm_async);
122 : :
123 : : #ifdef CONFIG_SUSPEND
124 : 0 : static ssize_t mem_sleep_show(struct kobject *kobj, struct kobj_attribute *attr,
125 : : char *buf)
126 : : {
127 : 0 : char *s = buf;
128 : 0 : suspend_state_t i;
129 : :
130 [ # # ]: 0 : for (i = PM_SUSPEND_MIN; i < PM_SUSPEND_MAX; i++)
131 [ # # ]: 0 : if (mem_sleep_states[i]) {
132 : 0 : const char *label = mem_sleep_states[i];
133 : :
134 [ # # ]: 0 : if (mem_sleep_current == i)
135 : 0 : s += sprintf(s, "[%s] ", label);
136 : : else
137 : 0 : s += sprintf(s, "%s ", label);
138 : : }
139 : :
140 : : /* Convert the last space to a newline if needed. */
141 [ # # ]: 0 : if (s != buf)
142 : 0 : *(s-1) = '\n';
143 : :
144 : 0 : return (s - buf);
145 : : }
146 : :
147 : 0 : static suspend_state_t decode_suspend_state(const char *buf, size_t n)
148 : : {
149 : 0 : suspend_state_t state;
150 : 0 : char *p;
151 : 0 : int len;
152 : :
153 : 0 : p = memchr(buf, '\n', n);
154 [ # # ]: 0 : len = p ? p - buf : n;
155 : :
156 [ # # ]: 0 : for (state = PM_SUSPEND_MIN; state < PM_SUSPEND_MAX; state++) {
157 : 0 : const char *label = mem_sleep_states[state];
158 : :
159 [ # # # # : 0 : if (label && len == strlen(label) && !strncmp(buf, label, len))
# # ]
160 : 0 : return state;
161 : : }
162 : :
163 : : return PM_SUSPEND_ON;
164 : : }
165 : :
166 : 0 : static ssize_t mem_sleep_store(struct kobject *kobj, struct kobj_attribute *attr,
167 : : const char *buf, size_t n)
168 : : {
169 : 0 : suspend_state_t state;
170 : 0 : int error;
171 : :
172 [ # # ]: 0 : error = pm_autosleep_lock();
173 : 0 : if (error)
174 : : return error;
175 : :
176 [ # # ]: 0 : if (pm_autosleep_state() > PM_SUSPEND_ON) {
177 : : error = -EBUSY;
178 : : goto out;
179 : : }
180 : :
181 : 0 : state = decode_suspend_state(buf, n);
182 [ # # ]: 0 : if (state < PM_SUSPEND_MAX && state > PM_SUSPEND_ON)
183 : 0 : mem_sleep_current = state;
184 : : else
185 : : error = -EINVAL;
186 : :
187 : : out:
188 : 0 : pm_autosleep_unlock();
189 : 0 : return error ? error : n;
190 : : }
191 : :
192 : : power_attr(mem_sleep);
193 : :
194 : : /*
195 : : * sync_on_suspend: invoke ksys_sync_helper() before suspend.
196 : : *
197 : : * show() returns whether ksys_sync_helper() is invoked before suspend.
198 : : * store() accepts 0 or 1. 0 disables ksys_sync_helper() and 1 enables it.
199 : : */
200 : : bool sync_on_suspend_enabled = !IS_ENABLED(CONFIG_SUSPEND_SKIP_SYNC);
201 : :
202 : 0 : static ssize_t sync_on_suspend_show(struct kobject *kobj,
203 : : struct kobj_attribute *attr, char *buf)
204 : : {
205 : 0 : return sprintf(buf, "%d\n", sync_on_suspend_enabled);
206 : : }
207 : :
208 : 0 : static ssize_t sync_on_suspend_store(struct kobject *kobj,
209 : : struct kobj_attribute *attr,
210 : : const char *buf, size_t n)
211 : : {
212 : 0 : unsigned long val;
213 : :
214 [ # # ]: 0 : if (kstrtoul(buf, 10, &val))
215 : : return -EINVAL;
216 : :
217 [ # # ]: 0 : if (val > 1)
218 : : return -EINVAL;
219 : :
220 : 0 : sync_on_suspend_enabled = !!val;
221 : 0 : return n;
222 : : }
223 : :
224 : : power_attr(sync_on_suspend);
225 : : #endif /* CONFIG_SUSPEND */
226 : :
227 : : #ifdef CONFIG_PM_SLEEP_DEBUG
228 : : int pm_test_level = TEST_NONE;
229 : :
230 : : static 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 : :
239 : 0 : static ssize_t pm_test_show(struct kobject *kobj, struct kobj_attribute *attr,
240 : : char *buf)
241 : : {
242 : 0 : char *s = buf;
243 : 0 : int level;
244 : :
245 [ # # ]: 0 : for (level = TEST_FIRST; level <= TEST_MAX; level++)
246 [ # # ]: 0 : if (pm_tests[level]) {
247 [ # # ]: 0 : if (level == pm_test_level)
248 : 0 : s += sprintf(s, "[%s] ", pm_tests[level]);
249 : : else
250 : 0 : s += sprintf(s, "%s ", pm_tests[level]);
251 : : }
252 : :
253 [ # # ]: 0 : if (s != buf)
254 : : /* convert the last space to a newline */
255 : 0 : *(s-1) = '\n';
256 : :
257 : 0 : return (s - buf);
258 : : }
259 : :
260 : 0 : static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr,
261 : : const char *buf, size_t n)
262 : : {
263 : 0 : const char * const *s;
264 : 0 : int level;
265 : 0 : char *p;
266 : 0 : int len;
267 : 0 : int error = -EINVAL;
268 : :
269 : 0 : p = memchr(buf, '\n', n);
270 [ # # ]: 0 : len = p ? p - buf : n;
271 : :
272 : 0 : lock_system_sleep();
273 : :
274 : 0 : level = TEST_FIRST;
275 [ # # ]: 0 : for (s = &pm_tests[level]; level <= TEST_MAX; s++, level++)
276 [ # # # # : 0 : if (*s && len == strlen(*s) && !strncmp(buf, *s, len)) {
# # ]
277 : 0 : pm_test_level = level;
278 : 0 : error = 0;
279 : 0 : break;
280 : : }
281 : :
282 : 0 : unlock_system_sleep();
283 : :
284 [ # # ]: 0 : return error ? error : n;
285 : : }
286 : :
287 : : power_attr(pm_test);
288 : : #endif /* CONFIG_PM_SLEEP_DEBUG */
289 : :
290 : 0 : static char *suspend_step_name(enum suspend_stat_step step)
291 : : {
292 : 0 : 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) \
311 : : static 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 : : } \
316 : : static struct kobj_attribute _name = __ATTR_RO(_name)
317 : :
318 : 0 : suspend_attr(success);
319 : 0 : suspend_attr(fail);
320 : 0 : suspend_attr(failed_freeze);
321 : 0 : suspend_attr(failed_prepare);
322 : 0 : suspend_attr(failed_suspend);
323 : 0 : suspend_attr(failed_suspend_late);
324 : 0 : suspend_attr(failed_suspend_noirq);
325 : 0 : suspend_attr(failed_resume);
326 : 0 : suspend_attr(failed_resume_early);
327 : 0 : suspend_attr(failed_resume_noirq);
328 : :
329 : 0 : static ssize_t last_failed_dev_show(struct kobject *kobj,
330 : : struct kobj_attribute *attr, char *buf)
331 : : {
332 : 0 : int index;
333 : 0 : char *last_failed_dev = NULL;
334 : :
335 : 0 : index = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1;
336 : 0 : index %= REC_FAILED_NUM;
337 : 0 : last_failed_dev = suspend_stats.failed_devs[index];
338 : :
339 : 0 : return sprintf(buf, "%s\n", last_failed_dev);
340 : : }
341 : : static struct kobj_attribute last_failed_dev = __ATTR_RO(last_failed_dev);
342 : :
343 : 0 : static ssize_t last_failed_errno_show(struct kobject *kobj,
344 : : struct kobj_attribute *attr, char *buf)
345 : : {
346 : 0 : int index;
347 : 0 : int last_failed_errno;
348 : :
349 : 0 : index = suspend_stats.last_failed_errno + REC_FAILED_NUM - 1;
350 : 0 : index %= REC_FAILED_NUM;
351 : 0 : last_failed_errno = suspend_stats.errno[index];
352 : :
353 : 0 : return sprintf(buf, "%d\n", last_failed_errno);
354 : : }
355 : : static struct kobj_attribute last_failed_errno = __ATTR_RO(last_failed_errno);
356 : :
357 : 0 : static ssize_t last_failed_step_show(struct kobject *kobj,
358 : : struct kobj_attribute *attr, char *buf)
359 : : {
360 : 0 : int index;
361 : 0 : enum suspend_stat_step step;
362 : 0 : char *last_failed_step = NULL;
363 : :
364 : 0 : index = suspend_stats.last_failed_step + REC_FAILED_NUM - 1;
365 : 0 : index %= REC_FAILED_NUM;
366 : 0 : step = suspend_stats.failed_steps[index];
367 [ # # ]: 0 : last_failed_step = suspend_step_name(step);
368 : :
369 : 0 : return sprintf(buf, "%s\n", last_failed_step);
370 : : }
371 : : static struct kobj_attribute last_failed_step = __ATTR_RO(last_failed_step);
372 : :
373 : : static 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 : :
390 : : static struct attribute_group suspend_attr_group = {
391 : : .name = "suspend_stats",
392 : : .attrs = suspend_attrs,
393 : : };
394 : :
395 : : #ifdef CONFIG_DEBUG_FS
396 : 0 : static int suspend_stats_show(struct seq_file *s, void *unused)
397 : : {
398 : 0 : int i, index, last_dev, last_errno, last_step;
399 : :
400 : 0 : last_dev = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1;
401 : 0 : last_dev %= REC_FAILED_NUM;
402 : 0 : last_errno = suspend_stats.last_failed_errno + REC_FAILED_NUM - 1;
403 : 0 : last_errno %= REC_FAILED_NUM;
404 : 0 : last_step = suspend_stats.last_failed_step + REC_FAILED_NUM - 1;
405 : 0 : last_step %= REC_FAILED_NUM;
406 : 0 : 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 : 0 : seq_printf(s, "failures:\n last_failed_dev:\t%-s\n",
423 : 0 : suspend_stats.failed_devs[last_dev]);
424 [ # # ]: 0 : for (i = 1; i < REC_FAILED_NUM; i++) {
425 : 0 : index = last_dev + REC_FAILED_NUM - i;
426 : 0 : index %= REC_FAILED_NUM;
427 : 0 : seq_printf(s, "\t\t\t%-s\n",
428 : 0 : suspend_stats.failed_devs[index]);
429 : : }
430 : 0 : seq_printf(s, " last_failed_errno:\t%-d\n",
431 : : suspend_stats.errno[last_errno]);
432 [ # # ]: 0 : for (i = 1; i < REC_FAILED_NUM; i++) {
433 : 0 : index = last_errno + REC_FAILED_NUM - i;
434 : 0 : index %= REC_FAILED_NUM;
435 : 0 : seq_printf(s, "\t\t\t%-d\n",
436 : : suspend_stats.errno[index]);
437 : : }
438 [ # # ]: 0 : seq_printf(s, " last_failed_step:\t%-s\n",
439 : : suspend_step_name(
440 : : suspend_stats.failed_steps[last_step]));
441 [ # # ]: 0 : for (i = 1; i < REC_FAILED_NUM; i++) {
442 : 0 : index = last_step + REC_FAILED_NUM - i;
443 : 0 : index %= REC_FAILED_NUM;
444 [ # # ]: 0 : seq_printf(s, "\t\t\t%-s\n",
445 : : suspend_step_name(
446 : : suspend_stats.failed_steps[index]));
447 : : }
448 : :
449 : 0 : return 0;
450 : : }
451 : 0 : DEFINE_SHOW_ATTRIBUTE(suspend_stats);
452 : :
453 : 78 : static int __init pm_debugfs_init(void)
454 : : {
455 : 78 : debugfs_create_file("suspend_stats", S_IFREG | S_IRUGO,
456 : : NULL, NULL, &suspend_stats_fops);
457 : 78 : return 0;
458 : : }
459 : :
460 : : late_initcall(pm_debugfs_init);
461 : : #endif /* CONFIG_DEBUG_FS */
462 : :
463 : : #endif /* CONFIG_PM_SLEEP */
464 : :
465 : : #ifdef CONFIG_PM_SLEEP_DEBUG
466 : : /*
467 : : * pm_print_times: print time taken by devices to suspend and resume.
468 : : *
469 : : * show() returns whether printing of suspend and resume times is enabled.
470 : : * store() accepts 0 or 1. 0 disables printing and 1 enables it.
471 : : */
472 : : bool pm_print_times_enabled;
473 : :
474 : 0 : static ssize_t pm_print_times_show(struct kobject *kobj,
475 : : struct kobj_attribute *attr, char *buf)
476 : : {
477 : 0 : return sprintf(buf, "%d\n", pm_print_times_enabled);
478 : : }
479 : :
480 : 0 : static ssize_t pm_print_times_store(struct kobject *kobj,
481 : : struct kobj_attribute *attr,
482 : : const char *buf, size_t n)
483 : : {
484 : 0 : unsigned long val;
485 : :
486 [ # # ]: 0 : if (kstrtoul(buf, 10, &val))
487 : : return -EINVAL;
488 : :
489 [ # # ]: 0 : if (val > 1)
490 : : return -EINVAL;
491 : :
492 : 0 : pm_print_times_enabled = !!val;
493 : 0 : return n;
494 : : }
495 : :
496 : : power_attr(pm_print_times);
497 : :
498 : 78 : static inline void pm_print_times_init(void)
499 : : {
500 : 78 : pm_print_times_enabled = !!initcall_debug;
501 : : }
502 : :
503 : 0 : static ssize_t pm_wakeup_irq_show(struct kobject *kobj,
504 : : struct kobj_attribute *attr,
505 : : char *buf)
506 : : {
507 [ # # ]: 0 : return pm_wakeup_irq ? sprintf(buf, "%u\n", pm_wakeup_irq) : -ENODATA;
508 : : }
509 : :
510 : : power_attr_ro(pm_wakeup_irq);
511 : :
512 : : bool pm_debug_messages_on __read_mostly;
513 : :
514 : 0 : static ssize_t pm_debug_messages_show(struct kobject *kobj,
515 : : struct kobj_attribute *attr, char *buf)
516 : : {
517 : 0 : return sprintf(buf, "%d\n", pm_debug_messages_on);
518 : : }
519 : :
520 : 0 : static ssize_t pm_debug_messages_store(struct kobject *kobj,
521 : : struct kobj_attribute *attr,
522 : : const char *buf, size_t n)
523 : : {
524 : 0 : unsigned long val;
525 : :
526 [ # # ]: 0 : if (kstrtoul(buf, 10, &val))
527 : : return -EINVAL;
528 : :
529 [ # # ]: 0 : if (val > 1)
530 : : return -EINVAL;
531 : :
532 : 0 : pm_debug_messages_on = !!val;
533 : 0 : return n;
534 : : }
535 : :
536 : : power_attr(pm_debug_messages);
537 : :
538 : : /**
539 : : * __pm_pr_dbg - Print a suspend debug message to the kernel log.
540 : : * @defer: Whether or not to use printk_deferred() to print the message.
541 : : * @fmt: Message format.
542 : : *
543 : : * The message will be emitted if enabled through the pm_debug_messages
544 : : * sysfs attribute.
545 : : */
546 : 78 : void __pm_pr_dbg(bool defer, const char *fmt, ...)
547 : : {
548 : 78 : struct va_format vaf;
549 : 78 : va_list args;
550 : :
551 [ + - ]: 78 : if (!pm_debug_messages_on)
552 : 78 : return;
553 : :
554 : 0 : va_start(args, fmt);
555 : :
556 : 0 : vaf.fmt = fmt;
557 : 0 : vaf.va = &args;
558 : :
559 [ # # ]: 0 : if (defer)
560 : 0 : printk_deferred(KERN_DEBUG "PM: %pV", &vaf);
561 : : else
562 : 0 : printk(KERN_DEBUG "PM: %pV", &vaf);
563 : :
564 : 0 : va_end(args);
565 : : }
566 : :
567 : : #else /* !CONFIG_PM_SLEEP_DEBUG */
568 : : static inline void pm_print_times_init(void) {}
569 : : #endif /* CONFIG_PM_SLEEP_DEBUG */
570 : :
571 : : struct kobject *power_kobj;
572 : :
573 : : /**
574 : : * state - control system sleep states.
575 : : *
576 : : * show() returns available sleep state labels, which may be "mem", "standby",
577 : : * "freeze" and "disk" (hibernation).
578 : : * See Documentation/admin-guide/pm/sleep-states.rst for a description of
579 : : * what they mean.
580 : : *
581 : : * store() accepts one of those strings, translates it into the proper
582 : : * enumerated value, and initiates a suspend transition.
583 : : */
584 : 0 : static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr,
585 : : char *buf)
586 : : {
587 : 0 : char *s = buf;
588 : : #ifdef CONFIG_SUSPEND
589 : 0 : suspend_state_t i;
590 : :
591 [ # # ]: 0 : for (i = PM_SUSPEND_MIN; i < PM_SUSPEND_MAX; i++)
592 [ # # ]: 0 : if (pm_states[i])
593 : 0 : s += sprintf(s,"%s ", pm_states[i]);
594 : :
595 : : #endif
596 [ # # ]: 0 : if (hibernation_available())
597 : 0 : s += sprintf(s, "disk ");
598 [ # # ]: 0 : if (s != buf)
599 : : /* convert the last space to a newline */
600 : 0 : *(s-1) = '\n';
601 : 0 : return (s - buf);
602 : : }
603 : :
604 : 0 : static suspend_state_t decode_state(const char *buf, size_t n)
605 : : {
606 : : #ifdef CONFIG_SUSPEND
607 : 0 : suspend_state_t state;
608 : : #endif
609 : 0 : char *p;
610 : 0 : int len;
611 : :
612 : 0 : p = memchr(buf, '\n', n);
613 [ # # ]: 0 : len = p ? p - buf : n;
614 : :
615 : : /* Check hibernation first. */
616 [ # # ]: 0 : if (len == 4 && str_has_prefix(buf, "disk"))
617 : : return PM_SUSPEND_MAX;
618 : :
619 : : #ifdef CONFIG_SUSPEND
620 [ # # ]: 0 : for (state = PM_SUSPEND_MIN; state < PM_SUSPEND_MAX; state++) {
621 : 0 : const char *label = pm_states[state];
622 : :
623 [ # # # # : 0 : if (label && len == strlen(label) && !strncmp(buf, label, len))
# # ]
624 : 0 : return state;
625 : : }
626 : : #endif
627 : :
628 : : return PM_SUSPEND_ON;
629 : : }
630 : :
631 : 0 : static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
632 : : const char *buf, size_t n)
633 : : {
634 : 0 : suspend_state_t state;
635 : 0 : int error;
636 : :
637 [ # # ]: 0 : error = pm_autosleep_lock();
638 : 0 : if (error)
639 : : return error;
640 : :
641 [ # # ]: 0 : if (pm_autosleep_state() > PM_SUSPEND_ON) {
642 : : error = -EBUSY;
643 : : goto out;
644 : : }
645 : :
646 : 0 : state = decode_state(buf, n);
647 [ # # ]: 0 : if (state < PM_SUSPEND_MAX) {
648 [ # # ]: 0 : if (state == PM_SUSPEND_MEM)
649 : 0 : state = mem_sleep_current;
650 : :
651 : 0 : error = pm_suspend(state);
652 [ # # ]: 0 : } else if (state == PM_SUSPEND_MAX) {
653 : 0 : error = hibernate();
654 : : } else {
655 : : error = -EINVAL;
656 : : }
657 : :
658 : 0 : out:
659 [ # # ]: 0 : pm_autosleep_unlock();
660 [ # # ]: 0 : return error ? error : n;
661 : : }
662 : :
663 : : power_attr(state);
664 : :
665 : : #ifdef CONFIG_PM_SLEEP
666 : : /*
667 : : * The 'wakeup_count' attribute, along with the functions defined in
668 : : * drivers/base/power/wakeup.c, provides a means by which wakeup events can be
669 : : * handled in a non-racy way.
670 : : *
671 : : * If a wakeup event occurs when the system is in a sleep state, it simply is
672 : : * woken up. In turn, if an event that would wake the system up from a sleep
673 : : * state occurs when it is undergoing a transition to that sleep state, the
674 : : * transition should be aborted. Moreover, if such an event occurs when the
675 : : * system is in the working state, an attempt to start a transition to the
676 : : * given sleep state should fail during certain period after the detection of
677 : : * the event. Using the 'state' attribute alone is not sufficient to satisfy
678 : : * these requirements, because a wakeup event may occur exactly when 'state'
679 : : * is being written to and may be delivered to user space right before it is
680 : : * frozen, so the event will remain only partially processed until the system is
681 : : * woken up by another event. In particular, it won't cause the transition to
682 : : * a sleep state to be aborted.
683 : : *
684 : : * This difficulty may be overcome if user space uses 'wakeup_count' before
685 : : * writing to 'state'. It first should read from 'wakeup_count' and store
686 : : * the read value. Then, after carrying out its own preparations for the system
687 : : * transition to a sleep state, it should write the stored value to
688 : : * 'wakeup_count'. If that fails, at least one wakeup event has occurred since
689 : : * 'wakeup_count' was read and 'state' should not be written to. Otherwise, it
690 : : * is allowed to write to 'state', but the transition will be aborted if there
691 : : * are any wakeup events detected after 'wakeup_count' was written to.
692 : : */
693 : :
694 : 0 : static ssize_t wakeup_count_show(struct kobject *kobj,
695 : : struct kobj_attribute *attr,
696 : : char *buf)
697 : : {
698 : 0 : unsigned int val;
699 : :
700 : 0 : return pm_get_wakeup_count(&val, true) ?
701 [ # # ]: 0 : sprintf(buf, "%u\n", val) : -EINTR;
702 : : }
703 : :
704 : 0 : static ssize_t wakeup_count_store(struct kobject *kobj,
705 : : struct kobj_attribute *attr,
706 : : const char *buf, size_t n)
707 : : {
708 : 0 : unsigned int val;
709 : 0 : int error;
710 : :
711 [ # # ]: 0 : error = pm_autosleep_lock();
712 : 0 : if (error)
713 : : return error;
714 : :
715 [ # # ]: 0 : if (pm_autosleep_state() > PM_SUSPEND_ON) {
716 : : error = -EBUSY;
717 : : goto out;
718 : : }
719 : :
720 : 0 : error = -EINVAL;
721 [ # # ]: 0 : if (sscanf(buf, "%u", &val) == 1) {
722 [ # # ]: 0 : if (pm_save_wakeup_count(val))
723 : 0 : error = n;
724 : : else
725 : 0 : pm_print_active_wakeup_sources();
726 : : }
727 : :
728 : 0 : out:
729 : 0 : pm_autosleep_unlock();
730 : 0 : return error;
731 : : }
732 : :
733 : : power_attr(wakeup_count);
734 : :
735 : : #ifdef CONFIG_PM_AUTOSLEEP
736 : : static ssize_t autosleep_show(struct kobject *kobj,
737 : : struct kobj_attribute *attr,
738 : : char *buf)
739 : : {
740 : : suspend_state_t state = pm_autosleep_state();
741 : :
742 : : if (state == PM_SUSPEND_ON)
743 : : return sprintf(buf, "off\n");
744 : :
745 : : #ifdef CONFIG_SUSPEND
746 : : if (state < PM_SUSPEND_MAX)
747 : : return sprintf(buf, "%s\n", pm_states[state] ?
748 : : pm_states[state] : "error");
749 : : #endif
750 : : #ifdef CONFIG_HIBERNATION
751 : : return sprintf(buf, "disk\n");
752 : : #else
753 : : return sprintf(buf, "error");
754 : : #endif
755 : : }
756 : :
757 : : static ssize_t autosleep_store(struct kobject *kobj,
758 : : struct kobj_attribute *attr,
759 : : const char *buf, size_t n)
760 : : {
761 : : suspend_state_t state = decode_state(buf, n);
762 : : int error;
763 : :
764 : : if (state == PM_SUSPEND_ON
765 : : && strcmp(buf, "off") && strcmp(buf, "off\n"))
766 : : return -EINVAL;
767 : :
768 : : if (state == PM_SUSPEND_MEM)
769 : : state = mem_sleep_current;
770 : :
771 : : error = pm_autosleep_set_state(state);
772 : : return error ? error : n;
773 : : }
774 : :
775 : : power_attr(autosleep);
776 : : #endif /* CONFIG_PM_AUTOSLEEP */
777 : :
778 : : #ifdef CONFIG_PM_WAKELOCKS
779 : : static ssize_t wake_lock_show(struct kobject *kobj,
780 : : struct kobj_attribute *attr,
781 : : char *buf)
782 : : {
783 : : return pm_show_wakelocks(buf, true);
784 : : }
785 : :
786 : : static ssize_t wake_lock_store(struct kobject *kobj,
787 : : struct kobj_attribute *attr,
788 : : const char *buf, size_t n)
789 : : {
790 : : int error = pm_wake_lock(buf);
791 : : return error ? error : n;
792 : : }
793 : :
794 : : power_attr(wake_lock);
795 : :
796 : : static ssize_t wake_unlock_show(struct kobject *kobj,
797 : : struct kobj_attribute *attr,
798 : : char *buf)
799 : : {
800 : : return pm_show_wakelocks(buf, false);
801 : : }
802 : :
803 : : static ssize_t wake_unlock_store(struct kobject *kobj,
804 : : struct kobj_attribute *attr,
805 : : const char *buf, size_t n)
806 : : {
807 : : int error = pm_wake_unlock(buf);
808 : : return error ? error : n;
809 : : }
810 : :
811 : : power_attr(wake_unlock);
812 : :
813 : : #endif /* CONFIG_PM_WAKELOCKS */
814 : : #endif /* CONFIG_PM_SLEEP */
815 : :
816 : : #ifdef CONFIG_PM_TRACE
817 : : int pm_trace_enabled;
818 : :
819 : 0 : static ssize_t pm_trace_show(struct kobject *kobj, struct kobj_attribute *attr,
820 : : char *buf)
821 : : {
822 : 0 : return sprintf(buf, "%d\n", pm_trace_enabled);
823 : : }
824 : :
825 : : static ssize_t
826 : 0 : pm_trace_store(struct kobject *kobj, struct kobj_attribute *attr,
827 : : const char *buf, size_t n)
828 : : {
829 : 0 : int val;
830 : :
831 [ # # ]: 0 : if (sscanf(buf, "%d", &val) == 1) {
832 : 0 : pm_trace_enabled = !!val;
833 [ # # ]: 0 : if (pm_trace_enabled) {
834 : 0 : pr_warn("PM: Enabling pm_trace changes system date and time during resume.\n"
835 : : "PM: Correct system time has to be restored manually after resume.\n");
836 : : }
837 : 0 : return n;
838 : : }
839 : : return -EINVAL;
840 : : }
841 : :
842 : : power_attr(pm_trace);
843 : :
844 : 0 : static ssize_t pm_trace_dev_match_show(struct kobject *kobj,
845 : : struct kobj_attribute *attr,
846 : : char *buf)
847 : : {
848 : 0 : return show_trace_dev_match(buf, PAGE_SIZE);
849 : : }
850 : :
851 : : power_attr_ro(pm_trace_dev_match);
852 : :
853 : : #endif /* CONFIG_PM_TRACE */
854 : :
855 : : #ifdef CONFIG_FREEZER
856 : 0 : static ssize_t pm_freeze_timeout_show(struct kobject *kobj,
857 : : struct kobj_attribute *attr, char *buf)
858 : : {
859 : 0 : return sprintf(buf, "%u\n", freeze_timeout_msecs);
860 : : }
861 : :
862 : 0 : static ssize_t pm_freeze_timeout_store(struct kobject *kobj,
863 : : struct kobj_attribute *attr,
864 : : const char *buf, size_t n)
865 : : {
866 : 0 : unsigned long val;
867 : :
868 [ # # ]: 0 : if (kstrtoul(buf, 10, &val))
869 : : return -EINVAL;
870 : :
871 : 0 : freeze_timeout_msecs = val;
872 : 0 : return n;
873 : : }
874 : :
875 : : power_attr(pm_freeze_timeout);
876 : :
877 : : #endif /* CONFIG_FREEZER*/
878 : :
879 : : static struct attribute * g[] = {
880 : : &state_attr.attr,
881 : : #ifdef CONFIG_PM_TRACE
882 : : &pm_trace_attr.attr,
883 : : &pm_trace_dev_match_attr.attr,
884 : : #endif
885 : : #ifdef CONFIG_PM_SLEEP
886 : : &pm_async_attr.attr,
887 : : &wakeup_count_attr.attr,
888 : : #ifdef CONFIG_SUSPEND
889 : : &mem_sleep_attr.attr,
890 : : &sync_on_suspend_attr.attr,
891 : : #endif
892 : : #ifdef CONFIG_PM_AUTOSLEEP
893 : : &autosleep_attr.attr,
894 : : #endif
895 : : #ifdef CONFIG_PM_WAKELOCKS
896 : : &wake_lock_attr.attr,
897 : : &wake_unlock_attr.attr,
898 : : #endif
899 : : #ifdef CONFIG_PM_SLEEP_DEBUG
900 : : &pm_test_attr.attr,
901 : : &pm_print_times_attr.attr,
902 : : &pm_wakeup_irq_attr.attr,
903 : : &pm_debug_messages_attr.attr,
904 : : #endif
905 : : #endif
906 : : #ifdef CONFIG_FREEZER
907 : : &pm_freeze_timeout_attr.attr,
908 : : #endif
909 : : NULL,
910 : : };
911 : :
912 : : static const struct attribute_group attr_group = {
913 : : .attrs = g,
914 : : };
915 : :
916 : : static const struct attribute_group *attr_groups[] = {
917 : : &attr_group,
918 : : #ifdef CONFIG_PM_SLEEP
919 : : &suspend_attr_group,
920 : : #endif
921 : : NULL,
922 : : };
923 : :
924 : : struct workqueue_struct *pm_wq;
925 : : EXPORT_SYMBOL_GPL(pm_wq);
926 : :
927 : 78 : static int __init pm_start_workqueue(void)
928 : : {
929 : 78 : pm_wq = alloc_workqueue("pm", WQ_FREEZABLE, 0);
930 : :
931 [ - + ]: 78 : return pm_wq ? 0 : -ENOMEM;
932 : : }
933 : :
934 : 78 : static int __init pm_init(void)
935 : : {
936 : 78 : int error = pm_start_workqueue();
937 [ + - ]: 78 : if (error)
938 : : return error;
939 : 78 : hibernate_image_size_init();
940 : 78 : hibernate_reserved_size_init();
941 : 78 : pm_states_init();
942 : 78 : power_kobj = kobject_create_and_add("power", NULL);
943 [ + - ]: 78 : if (!power_kobj)
944 : : return -ENOMEM;
945 : 78 : error = sysfs_create_groups(power_kobj, attr_groups);
946 [ + - ]: 78 : if (error)
947 : : return error;
948 : 78 : pm_print_times_init();
949 : 78 : return pm_autosleep_init();
950 : : }
951 : :
952 : : core_initcall(pm_init);
|