es failed to suspend
);
goto Recover_platform;
}
suspend_test_finish(suspend devices);
if (suspend_test(TEST_DEVICES))
goto Recover_platform;
do {
error = suspend_enter(state, &wakeup);
} while (!error && !wakeup
&& suspend_ops->suspend_again && suspend_ops->suspend_again());
Resume_devices:
suspend_test_start();
dpm_resume_end(PMSG_RESUME);
suspend_test_finish(resume devices);
resume_console();
//Add a timer to trigger wakelock debug
pr_info([PM]unattended_timer: mod_timer
);
mod_timer(&unattended_timer, jiffies + msecs_to_jiffies(PM_UNATTENDED_TIMEOUT));
Close:
if (suspend_ops->end)
suspend_ops->end();
trace_machine_suspend(PWR_EVENT_EXIT);
return error;
Recover_platform:
if (suspend_ops->recover)
suspend_ops->recover();
goto Resume_devices;
}
suspend_console(); //冻结终端
suspend_test_start//打出suspend 开始的时间
其中dpm_suspend_start 试下如下:
int dpm_suspend_start(pm_message_t state)
{
int error;
error = dpm_prepare(state); 为设备准备链表
if (error) {
suspend_stats.failed_prepare++;
dpm_save_failed_step(SUSPEND_PREPARE);
} else
error = dpm_suspend(state);将准备的设备进入suspend
return error;
}
EXPORT_SYMBOL_GPL(dpm_suspend_start);
在dpm_suspendl里面,我们会将while (!list_empty(&dpm_list)) {
struct device *dev = to_device(dpm_list.next); dpm_list 里面所有的设备都遍历出来,
最终哦将遍历出来的设备添加到另外一个链表里面去:list_move_tail(&dev->power.entry, &dpm_prepared_list.至于dpm_list 是如何来的,我们在另外一个章节进行讲解。
接下来dpm_suspend(state); 进行suspend 设备。
dpm_suspend 的函数实现如下:
int dpm_suspend(pm_message_t state)
{
ktime_t starttime = ktime_get();
int error = 0;
might_sleep();
mutex_lock(&dpm_list_mtx);
pm_transition = state;
async_error = 0;
while (!list_empty(&dpm_prepared_list)) {
struct device *dev = to_device(dpm_prepared_list.prev);
get_device(dev);
mutex_unlock(&dpm_list_mtx);
error = device_suspend(dev);
mutex_lock(&dpm_list_mtx);
if (error) {
pm_dev_err(dev, state, , error);
dpm_save_failed_dev(dev_name(dev));
put_device(dev);
break;
}
if (!list_empty(&dev->power.entry))
list_move(&dev->power.entry, &dpm_suspended_list);
put_device(dev);
if (async_error)
break;
}
mutex_unlock(&dpm_list_mtx);
async_synchronize_full();
if (!error)
error = async_error;
if (error) {
suspend_stats.failed_suspend++;
dpm_save_failed_step(SUSPEND_SUSPEND);
} else
dpm_show_time(starttime, state, NULL);
return error;
}
然后调用device_suspend 函数
-----》__device_suspend ------》if (dev->pm_domain) {
info = power domain ;
callback = pm_op(&dev->pm_domain->ops, state);
goto Run;
}
if (dev->type && dev->type->pm) {
info = type ;
callback = pm_op(dev->type->pm, state);
goto Run;
}
if (dev->class) {
if (dev->class->pm) {
info = class ;
callback = pm_op(dev->class->pm, state);
goto Run;
} else if (dev->class->suspend) {
pm_dev_dbg(dev, state, legacy class );
error = legacy_suspend(dev, state, dev->class->suspend);
goto End;
}
}
if (dev->bus) {
if (dev->bus->pm) {
info = bus ;
callback = pm_op(dev->bus->pm, state);
} else if (dev->bus->suspend) {
pm_dev_dbg(dev, state, legacy bus );
error = legacy_suspend(dev, state, dev->bus->suspend);
goto End;
}
}
调用pm_op函数调用设备、class、 bus 等的suspend函数,同样的resume 函数也是一样的流程。
dpm_suspend_start 函数执行完了之后。我们再次回到suspend_devices_and_enter 函数中来。
do {
error = suspend_enter(state, &wakeup);
} wh |