接上一节:
static
{
int
device_pm_lock();
#ifdef
cpufreq_get_cpufreq_name(0);
strcpy(governor_name,
if(strnicmp(governor_name,
cpufreq_set_policy(0,
}
#endif
arch_suspend_disable_irqs();
BUG_ON(!irqs_disabled());
if
printk(KERN_ERR
goto
}
error
if
if
error
sysdev_resume();
}
device_power_up(PMSG_RESUME);
arch_suspend_enable_irqs();
#ifdef
if(strnicmp(governor_name,
cpufreq_set_policy(0,
}
#endif
BUG_ON(irqs_disabled());
device_pm_unlock();
return
}
然后回到suspend_devices_and_enter()函数中,使能休眠时候停止掉的非启动CPU,继续唤醒每个设备,使能终端。
int
{
int
if
return
if
error
if
goto
}
suspend_console();
suspend_test_start();
error
if
printk(KERN_ERR
goto
}
suspend_test_finish("suspend
if
goto
if
error
if
goto
}
if
goto
error
if
suspend_enter(state);
enable_nonboot_cpus();
if
suspend_ops->finish();
suspend_test_start();
device_resume(PMSG_RESUME);
suspend_test_finish("resume
resume_console();
if
suspend_ops->end();
return
if
suspend_ops->recover();
goto
}
当suspend_devices_and_enter()执行完成后,系统外设已经唤醒,但进程依然是冻结的状态,返回到enter_state函数中,调用suspend_finish()函数。
static
{
int
if
return
if
return
printk(KERN_INFO
sys_sync();
printk("done.\n");
pr_debug("PM:
error
if
goto
if
goto
pr_debug("PM:
error
pr_debug("PM:
suspend_finish();
mutex_unlock(&pm_mutex);
return
}
在suspend_finish()函数中,解冻进程和任务,使能用户空间helper进程,广播一个系统从suspend状态退出的notify,唤醒终端。
static
{
suspend_thaw_processes();
usermodehelper_enable();
pm_notifier_call_chain(PM_POST_SUSPEND);
pm_restore_console();
}
当所有的唤醒已经结束以后,用户进程都已经开始运行了,但没点亮屏幕,唤醒通常会是以下的几种原因:
如果是来电,那么Modem会通过发送命令给rild来让rild通知WindowManager有来电响应,这样就会远程调用PowerManagerService来写”on”到
用户按键事件会送到WindowManager中,WindowManager会处理这些按键事件,按键分为几种情况,如果按键不是唤醒键,那么WindowManager会主动放弃wakeLock来使系统进入再次休眠;如果按键是唤醒键,那么WindowManger就会调用PowerManagerService中的接口来执行late
当”on”被写入到/sys/power/state之后,同early_suspend过程,request_suspend_state()被调用,只是执行的工作队列变为late_resume_work。在late_resume函数中,唤醒调用了early_suspend的设备。
static
static
{
struct
unsigned
int
mutex_lock(&early_suspend_lock);
spin_lock_irqsave(&state_lock,
if
state
else
abort
spin_unlock_irqrestore(&state_lock,
if
if
pr_info("late_resume:
goto
}
if
pr_info("late_resume:
list_for_each_entry_reverse(pos,
if
pos->resume(pos);
if
pr_info("late_resume:
abort:
mutex_unlock(&early_suspend_lock);
}