Lines Matching +full:suspend +full:- +full:to +full:- +full:idle
1 // SPDX-License-Identifier: GPL-2.0-only
3 * kernel/power/suspend.c - Suspend to RAM and standby functionality.
26 #include <linux/suspend.h>
66 * pm_suspend_default_s2idle - Check if suspend-to-idle is the default suspend.
68 * Return 'true' if suspend-to-idle has been selected as the default system
69 * suspend method.
100 * The s2idle_lock must be acquired before the pending wakeup check to in s2idle_enter()
112 /* Push all the CPUs into the idle loop. */ in s2idle_enter()
114 /* Make the current CPU wait so it can enter the idle loop too. */ in s2idle_enter()
119 * Kick all CPUs to ensure that they resume their timers and restore in s2idle_enter()
135 pm_pr_dbg("suspend-to-idle\n"); in s2idle_loop()
138 * Suspend-to-idle equals: in s2idle_loop()
139 * frozen processes + suspended devices + idle processors. in s2idle_loop()
143 * Wakeups during the noirq suspend of devices may be spurious, so try in s2idle_loop()
144 * to avoid them upfront. in s2idle_loop()
147 if (s2idle_ops && s2idle_ops->wake) { in s2idle_loop()
148 if (s2idle_ops->wake()) in s2idle_loop()
154 if (s2idle_ops && s2idle_ops->check) in s2idle_loop()
155 s2idle_ops->check(); in s2idle_loop()
160 pm_pr_dbg("resume from suspend-to-idle\n"); in s2idle_loop()
179 * The PM_SUSPEND_STANDBY and PM_SUSPEND_MEM states require low-level in valid_state()
180 * support and need to be valid to the low-level implementation. in valid_state()
182 * No ->valid() or ->enter() callback implies that none are valid. in valid_state()
184 return suspend_ops && suspend_ops->valid && suspend_ops->valid(state) && in valid_state()
185 suspend_ops->enter; in valid_state()
194 * Suspend-to-idle should be supported even without any suspend_ops, in pm_states_init()
217 * suspend_set_ops - Set the global suspend method table.
218 * @ops: Suspend operations to use.
245 * suspend_valid_only_mem - Generic memory-only valid callback.
248 * Platform drivers that implement mem suspend only and only need to check for
266 return state != PM_SUSPEND_TO_IDLE && suspend_ops->prepare ? in platform_suspend_prepare()
267 suspend_ops->prepare() : 0; in platform_suspend_prepare()
272 return state == PM_SUSPEND_TO_IDLE && s2idle_ops && s2idle_ops->prepare ? in platform_suspend_prepare_late()
273 s2idle_ops->prepare() : 0; in platform_suspend_prepare_late()
279 return s2idle_ops && s2idle_ops->prepare_late ? in platform_suspend_prepare_noirq()
280 s2idle_ops->prepare_late() : 0; in platform_suspend_prepare_noirq()
282 return suspend_ops->prepare_late ? suspend_ops->prepare_late() : 0; in platform_suspend_prepare_noirq()
288 if (s2idle_ops && s2idle_ops->restore_early) in platform_resume_noirq()
289 s2idle_ops->restore_early(); in platform_resume_noirq()
290 } else if (suspend_ops->wake) { in platform_resume_noirq()
291 suspend_ops->wake(); in platform_resume_noirq()
297 if (state == PM_SUSPEND_TO_IDLE && s2idle_ops && s2idle_ops->restore) in platform_resume_early()
298 s2idle_ops->restore(); in platform_resume_early()
303 if (state != PM_SUSPEND_TO_IDLE && suspend_ops->finish) in platform_resume_finish()
304 suspend_ops->finish(); in platform_resume_finish()
309 if (state == PM_SUSPEND_TO_IDLE && s2idle_ops && s2idle_ops->begin) in platform_suspend_begin()
310 return s2idle_ops->begin(); in platform_suspend_begin()
311 else if (suspend_ops && suspend_ops->begin) in platform_suspend_begin()
312 return suspend_ops->begin(state); in platform_suspend_begin()
319 if (state == PM_SUSPEND_TO_IDLE && s2idle_ops && s2idle_ops->end) in platform_resume_end()
320 s2idle_ops->end(); in platform_resume_end()
321 else if (suspend_ops && suspend_ops->end) in platform_resume_end()
322 suspend_ops->end(); in platform_resume_end()
327 if (state != PM_SUSPEND_TO_IDLE && suspend_ops->recover) in platform_recover()
328 suspend_ops->recover(); in platform_recover()
333 return state != PM_SUSPEND_TO_IDLE && suspend_ops->suspend_again ? in platform_suspend_again()
334 suspend_ops->suspend_again() : false; in platform_suspend_again()
341 "Number of seconds to wait before resuming from suspend test");
348 pr_info("suspend debug: Waiting for %d second(s).\n", in suspend_test()
358 * suspend_prepare - Prepare for entering system sleep state.
362 * hibernation). Run suspend notifiers, allocate the "suspend" console and
370 return -EPERM; in suspend_prepare()
407 * suspend_enter - Make the system enter the given sleep state.
408 * @state: System sleep state to enter.
409 * @wakeup: Returns information that the sleep state should not be re-entered.
423 pr_err("late suspend of devices failed\n"); in suspend_enter()
432 pr_err("noirq suspend of devices failed\n"); in suspend_enter()
462 error = suspend_ops->enter(state); in suspend_enter()
466 error = -EBUSY; in suspend_enter()
495 * suspend_devices_and_enter - Suspend devices and enter system sleep state.
496 * @state: System sleep state to enter.
504 return -ENOSYS; in suspend_devices_and_enter()
519 pr_err("Some devices failed to suspend, or early wake event detected\n"); in suspend_devices_and_enter()
522 suspend_test_finish("suspend devices"); in suspend_devices_and_enter()
549 * suspend_finish - Clean up before finishing the suspend sequence.
551 * Call platform code to clean up, restart processes, and free the console that
563 * enter_state - Do common work needed to enter system sleep state.
564 * @state: System sleep state to enter.
566 * Make sure that no one else is trying to put the system into a sleep state.
567 * Fail if that's not the case. Otherwise, prepare for system suspend, make the
578 …pr_warn("Unsupported test mode for suspend to idle, please choose none/freezer/devices/platform.\n… in enter_state()
579 return -EAGAIN; in enter_state()
583 return -EINVAL; in enter_state()
586 return -EBUSY; in enter_state()
620 * pm_suspend - Externally visible function for suspending the system.
621 * @state: System sleep state to enter.
624 * execute enter_state() and update system suspend statistics.
631 return -EINVAL; in pm_suspend()
633 pr_info("suspend entry (%s)\n", mem_sleep_labels[state]); in pm_suspend()
636 pr_info("suspend exit\n"); in pm_suspend()