pm_suspend代碼分析
v0.01 20190903 Init
1. /sys/power/state
/sys/power/state是Linux進入睡眠模式的入口。 比如:echo freeze > /sys/power/state
共支持4種模式,具體請參考: TODO
該接口是在kernel/power/main.c中實現的,從中可以看出,除了_hibernation模式是hibernate(),
其餘模式都是在pm_suspend()實現的。
#kernel/power/main.c
power_attr(state);
513 static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
514 const char *buf, size_t n)
515 {
...
529 if (state < PM_SUSPEND_MAX) {
530 if (state == PM_SUSPEND_MEM)
531 state = mem_sleep_current;
532
533 error = pm_suspend(state);
534 } else if (state == PM_SUSPEND_MAX) {
535 error = hibernate();
536 } else {
537 error = -EINVAL;
538 }
...
543 }
對應的命令如下:
# _hibernation
echo disk > /sys/power/state
# _standby
echo mem > /sys/power/state
# _s2idle
echo freeze > /sys/power/state
2. pm_suspend()分析
pm_suspend(kernel/power/suspend.c)
enter_state()
suspend_prepare() //console、通知鏈、並suspend所有進程線程
suspend_devices_and_enter()
platform_suspend_begin()
dpm_suspend_start() //調用dpm_prepare和dpm_suspend, 即所有devices做suspend
suspend_enter() //suspend_late, suspend_noirq,關從核,關中斷,syscore_suspend
suspend_ops->enter()
說明一下,syscore_suspend存在的原因是,有些子系統執行suspend/resume/shutdown操作,要求只有一個CPU在線,且要關閉中斷。比如acpi, clk,cpufreq,gpio,iommu,irqchip,irq,time,所以增加了syscore,等suspend的最後階段調用。
這部分代碼在drivers/base/syscore.c實現的。