Base Linux RC5.0
echo mem > /sys/power/state
Suspend Resume
| |
call notifiers Turn On Power
| |
freeze tasks System core online
| |
devices suspend Nonboot cpu online
| |
.prepare Devices Resume
| |
.suspend .resume_noirq
| |
.suspend_late .resume_early
| |
.suspend_noir .resume
| |
nonboot cpu offline .comnplete
| |
system core offline thaw tasks
| |
turn off power call notifiers
autosleep_store /*节点调用的入口函数*/
decode_state /*解析对用state, pm_state的初始化在pm_state_init(pm init完成)*/
pm_autosleep_set_state
__pm_stay_awake(autosleep_ws);
__pm_relax(autosleep_ws);
pm_wakep_autosleep_enabled
pm_suspend (state < PM_SUSPEND_MAX) /*Externally visible function for suspending the system*/
enter_state /*Do common work needed to enter system sleep state*/
state_store
pm_autosleep_lock
pm_autosleep_state() > PM_SUSPEND_ON /*如果进入到suspend流程,返还出去*/
decode_state /*解析对用state, pm_state的初始化在pm_state_init(pm init完成)*/
if (state < PM_SUSPEND_MAX) {
if (state == PM_SUSPEND_MEM)
state = mem_sleep_current; /*mem_sleep_store 函数初始化 mem sleep current的值*/
error = pm_suspend(state); /*Externally visible function for suspending the system*/
enter_state() /*Do common work needed to enter system sleep state*/
if (state == PM_SUSPEND_TO_IDLE)
s2idle_begin(); /*s2idle_state = S2IDLE_STATE_NONE*/
pm_suspend_clear_flags /*设置pm_suspend_global_flags = 0*/
suspend_prepare() /*Prepare for entering system sleep state*/
pm_prepare_console() /*切换 控制台打印口*/
__pm_notifier_call_chain() /*运行suspend的notifylist*/
suspend_freeze_processes()
freeze_processes /*冻结用户进程, 失败则thaw_processes解冻进程*/
freeze_kernel_threads /*冻结内核进程吗,失败则thaw_processes解冻进*/
dpm_save_failed_step() /*what to do????*/
error go out:
__pm_notifier_call_chain /*notify PM_POST_SUSPEND*/
pm_restore_console /*恢复控制台*/
suspend_test() /*调试使用的api*/
suspend_devices_and_enter() /*设备驱动休眠与进系统休眠*/
sleep_state_supported() /*判断是否支持*/
platform_suspend_begin()
s2idle_ops->begin()
suspend_ops->begin(state) /*suspend_set_ops(&psci_suspend_ops); psci 没有begin这个api,所以return*/
suspend_console() /*Suspending console(s) (use no_console_suspend to debug)*/
suspend_test_start() /** what to do???/
dpm_suspend_start()
dpm_prepare()
wait_for_device_probe() /*清理workqueue, 等待wq完成,同步域中的所有异步函数*/
device_block_probing() /*sync with probes to avoid races*/
device_prepare() /*调用devices pm ops.prepare*/
dpm_suspend()
devfreq_suspend()
cpufreq_suspend()
device_suspend()
/*dpm_prepared_list),转移到dpm_suspended_list*/
async_synchronize_full()
suspend_enter()
platform_suspend_prepare() /*suspend_ops->prepare*/
dpm_suspend_late() /*与dpm suspend 差别, 父节点的devices suspend, suspend late suspend设备*/
platform_suspend_prepare_late() /*s2idle_ops->prepare()*/
s2idle_loop /*state = id or test level RETURN*/
dpm_suspend_noirq() /*要disable irq的设备suspend,noirq,是通过禁止所有的中断线的形式,而不是通过关全局中断的方式*/
platform_suspend_prepare_noirq()
/*suspend_ops->prepare_late(), suspend_ops的prepare_late回调, 通知平台代码,以便让其在最后关头,再做一些处理, 失败的话,需要跳至Platform_wake处,
如果是suspend to freeze,执行相应的操作,包括冻结进程、suspended devices(参数为PM_SUSPEND_FREEZE)、cpu进入idle
如果有任何事件使CPU从idle状态退出,跳至Platform_wake处,执行wake操作*/
disable_nonboot_cpus() /*offline 非boot cpu, 调用cpudown的接口*/
arch_suspend_disable_irqs() /*local_irq_disable*/
syscore_suspend()
pm_wakeup_pending /*检查wakeup状态, return error*/ /*用pm_wakeup_pending检查一下,这段时间内,是否有唤醒事件发生,如果有就要终止suspend*/
ops->suspend /*syscore_ops_list 上的suspend调用,exp: cpufreq_stop_governor*/
pm_wakeup_pending /*再次检查wakeup状态*/
suspend_ops->enter(state) /*调用到psci接口中*/
out path:
syscore_resume
arch_suspend_enable_irqs
enable_nonboot_cpus
platform_resume_noirq
dpm_resume_noirq
platform_resume_early
dpm_resume_early
platform_resume_finish
} else if (state == PM_SUSPEND_MAX) {
error = hibernate();
} else {
error = -EINVAL;
}