赞
踩
前面我们分析了休眠的第一个阶段即浅度休眠,现在我们继续看休眠的第二个阶段 — 深度休眠。在深度休眠的过程中系统会首先冻结所有可以冻结的进程,然后依次挂起所有设备的电源,挂起顺序与设备注册的顺序相反,这样保证了设备之间电源的依赖性;直至最后进入省电模式,等待用户或者RTC唤醒;在唤醒过程中则会按照设备注册的顺序依次恢复每个设备的电源进入正常工作状态,解冻相关的进程,然后再进行浅度休眠的唤醒流程。
1、深度休眠入口
根据wake_lock一节的分析我们知道driver层进入深度休眠的入口有4个,分别为expire_timer、wake_lock、wake_lock_timeout、wake_unlock,这几个入口函数将根据相应的条件启动suspend_work里面的pm_suspend()函数进入深度休眠流程,代码在linux/kernel/power/suspend.c中:
在enter_state()中首先进入状态的判断,根据平台的特性判断是否支持此状态;然后再同步缓存;接着调用suspend_prepare()冻结大部分进程;然后再通过suspend_devices_and_enter()开始挂起设备。
2、冻结进程
这里有一个notifier机制后面要专门分析下。
3、挂起设备
函数将设备按照注册顺序反向挂起,挂起执行的流程如下:
在这个阶段首先看处理器是否需要做一些准备,接下来执行非sysdev的late suspend函数,然后处理器做休眠前最后的准备、关闭非启动cpu、挂起中断,再挂起sysdev,最后进入处理器的挂起函数,至此休眠流程结束,处理器等待用户或者RTC唤醒。
附1、late suspend
在这里我们看到了一种新的suspend机制 — late suspend,是在所有的suspend执行完后再开始执行,接口为dev->bus->pm->suspend_noirq;这样early_suspend、suspend以及late suspend构成了suspend的三部曲,late suspend是在中断关闭的情况下进行的;前面我们分析的wake_lock就有用到,用于检测在suspend阶段是否有锁被激活。late suspend的实现如下:
附2、中断关闭流程
在late suspend机制中我们看到了休眠流程中关闭系统中断的地方:
附3、dpm_list链表
dpm_list是内核中用于设备电源管理的链表,设备注册时通过一系列的调用 device_register() -> device_add() -> device_pm_add() 最后在device_pm_add()中将设备加入dpm_list链表中:
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。