linux dpm机制分析(上)【转】
转自:http://blog.csdn.net/lixiaojie1012/article/details/23707681
1 DPM介绍
1.1 Dpm:
设备电源管理,device power management
主要功能:系统在对外设下电前,需要做一些准备工作,保存一些设备的必要信息,以便在系统退出低功耗状态时能够恢复这些信息,使本设备在上电后能像睡眠前那样正常工作。驱动程序作为一部分,跟随系统级别的低功耗状态。
1.2 系统睡眠模式System Sleep model:
Suspend:保存到ram中,suspend-to-RAM,也就是我们使用并关注的睡眠模式
Hibernation:保存到硬盘中,suspend-to-disk
2 设备电源管理操作
子系统和驱动程序的设备电源管理操作,都定义在dev_pm_ops结构中,这个结构在include/linux/pm.h中定义:
struct dev_pm_ops {
int (*prepare)(struct device *dev);
void (*complete)(struct device *dev);
int (*suspend)(struct device *dev);
int (*resume)(struct device *dev);
int (*freeze)(struct device *dev);
int (*thaw)(struct device *dev);
int (*poweroff)(struct device *dev);
int (*restore)(struct device *dev);
int (*suspend_late)(struct device *dev);
int (*resume_early)(struct device *dev);
int (*freeze_late)(struct device *dev);
int (*thaw_early)(struct device *dev);
int (*poweroff_late)(struct device *dev);
int (*restore_early)(struct device *dev);
int (*suspend_noirq)(struct device *dev);
int (*resume_noirq)(struct device *dev);
int (*freeze_noirq)(struct device *dev);
int (*thaw_noirq)(struct device *dev);
int (*poweroff_noirq)(struct device *dev);
int (*restore_noirq)(struct device *dev);
int (*runtime_suspend)(struct device *dev);
int (*runtime_resume)(struct device *dev);
int (*runtime_idle)(struct device *dev);
};
驱动程序使用的主要由以下8种:
Prepare:做suspend前的准备工作,返回后本设备下不能再注册子设备,后续可跟@suspend(), @freeze(), @poweroff()中的一种回调;其作为dpm众多回调函数中的一个,在执行保存操作时最先执行,优先级最高;
Complete:执行prepare的逆操作,
Suspend:回调各设备的suspend回调函数,保存各设备必要信息,在系统唤醒时能恢复这些信息使该设备能实现睡眠前的功能。
suspend_late:晚于其他设备进行suspend操作,还可以保存suspend阶段没有保存的一些信息;
suspend_noirq: 阶段发生在IRQ被禁止之后,这意味着该回调运行期间,驱动程序的中断处理代码不会被调用。回调方法可以保存上一阶段没有保存的寄存器并最终让设备进入相应的低功耗状态;该回调函数优先级最低,最后执行保存工作,
Resume:回调各设备的resume回调函数,恢复suspend保存的一些必要信息
resume_early:先于其他设备进行恢复操作;对应suspend_late
resume_noirq:唤醒阶段的第一阶段,执行suspend_noirq的逆操作
设备进入suspend和resume的关键方法在bus_type结构、device_type结构和class结构的pm成员中,他是一个dev_pm_ops结构的指针。 1 系统电源管理的各个阶段
suspend和resume是分阶段完成的。在进入下一个阶段之前,都需要为每个设备调用属于本阶段的回调函数。不是所有的总线和设备类都会支持所有这些回调,也不是所有的驱动程序都要使用这些回调。有些阶段需要冻结进程后,解冻进程前执行。此外,*_noirq阶段需要在IRQ被关闭的情况下执行。
2.1 系统挂起(suspend)
当系统进入standby或sleep状态时,需要经历以下阶段:
prepare,suspend,suspend_late, suspend_noirq。
(1) prepare阶段主要是通过阻止新设备注册来防止竟态的发生; prepare回调返回后,该设备的下面将不可以注册新的子设备。回调方法也会让设备或驱动为将要到来的系统电源状态迁移做出准备。
(2) suspend阶段由suspend回调实现,它停止设备的一切I/O操作。它同时也可以保存设备的寄存器,依据设备所属的总线类型,让设备进入合适的低功耗状态。
以上两个回调主要由低功耗接口dpm_suspend_start()来实现。
(3) Suspend_late顾名思义,是在其他设备suspend之后,再进行suspend操作,也就是说如果设备注册了本回调意味着本设备的suspend要晚于其他设备的suspend操作
(4) suspend_noirq阶段发生在IRQ被禁止之后,这意味着该回调运行期间,驱动程序的中断处理代码不会被调用。回调方法可以保存上一阶段没有保存的寄存器并最终让设备进入相应的低功耗状态。大多数子系统(subsystem)和驱动程序不需要实现这一回调。不过,某些允许设备共享中断向量的总线类型,例如PCI,通常需要这一回调;否则,当本设备已经进入低功耗时另一个与他共享中断的设备感知中断的发生,驱动程序将会发生错误。
以上两个回调主要由低功耗接口dpm_suspend_end()来实现。
这些阶段结束后,驱动程序必须停止所有的I/O事务(DMA,IRQs),保存足够的状态信息以便它们能被重新初始化或回复之前的状态(按应将的需要而定),然后让设备进入低功耗状态。很多平台上,它们会关闭某些时钟(只在一个核上使用的设备需要在回调函数中添加关钟和开钟操作);有时还会关闭电源或者是降低电压,V7R2由M3来统一执行下电操作。
只要这些回调中的一个返回错误,系统不会进入所述的低功耗状态,而是由pm的核心对已经suspend的设备发起resume动作进行回退。
2.2 唤醒(resume)
当系统退出standby或sleep状态时,需要经历以下阶段:
resume_noirq,resume_early,resume,complete。
(1) resume_noirq回调方法应该执行所有在中断处理程序被调用前的必须动作。这通常意味着撤销suspend_noirq阶段所做的动作。如果总线类型允许共享中断向量,例如PCI,该回调方法应该使设备和驱动能够识别自身是否是中断源,如果是,还要能正确地处理。例如,对于PCI总线,bus->pm.resume_noirq()让设备进入全电源状态(PCI中称作D0),并回复设备的标准配置寄存器。然后,调用设备驱动程序的 ->pm.resume_noirq()方法来执行特定于设备的动作。
(2) resume_early执行在其他设备恢复信息之前,早于其他设备的恢复,suspend_late的逆操作
以上两个回调主要由低功耗接口dpm_resume_start()来实现。
(3) resume回调方法让设备回到他的工作状态,以便它能执行正常的I/O。这通常等同于执行suspend阶段的撤销工作。
(4) complete阶段撤销prepare阶段所做出的动作。不过请注意,新设备可能在resume回调返回后立刻被注册,而不必等到complete阶段完成。
以上两个回调主要由低功耗接口dpm_resume_end()来实现。
这些阶段结束后,驱动应该和suspend之前一样:I/O能通过DMA或IRQs执行,相应的时钟被打开。
多数阶段使用bus、type和class的回调(也就是定义在dev->bus->pm,dev->type->pm和dev->class->pm中)。
当然也可以直接使用device结构体中的ops。
linux dpm机制分析(上)【转】的更多相关文章
- linux dpm机制分析(下)【转】
转自:http://blog.csdn.net/lixiaojie1012/article/details/23707901 1 设备注册到dpm_list路径 (Platform_devi ...
- 【原创】Linux信号量机制分析
背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...
- 【转】Linux Writeback机制分析
1. bdi是什么? bdi,即是backing device info的缩写,顾名思义它描述备用存储设备相关描述信息,这在内核代码里用一个结构体backing_dev_info来表示. bdi,备用 ...
- 【原创】Linux Mutex机制分析
背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...
- 仿照linux dpm机制,实现自己的dpm【转】
转自:http://blog.csdn.net/lixiaojie1012/article/details/23788713 前边我们讨论分析了linux 内核的dpm实现,分析的目的在于学以致用:在 ...
- JAVA异常处理机制分析(上)
过去曾有一段时间关于java的异常处理机制曾经让我吃尽苦头,异常机制看似简单,原理,用法也仅仅如此,但是,用起来或是在使用一些框架的时候总会因为使用不当,造成灾难性后果. jdk异常处理机制 ...
- Linux mips64r2 PCI中断路由机制分析
Linux mips64r2 PCI中断路由机制分析 本文主要分析mips64r2 PCI设备中断路由原理和irq号分配实现方法,并尝试回答如下问题: PCI设备驱动中断注册(request_irq) ...
- [转载]Linux 线程实现机制分析
本文转自http://www.ibm.com/developerworks/cn/linux/kernel/l-thread/ 支持原创.尊重原创,分享知识! 自从多线程编程的概念出现在 Linux ...
- Linux信号(signal) 机制分析
Linux信号(signal) 机制分析 [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核 ...
随机推荐
- 【python】如何查看已经安装的python软件包和版本
pip 是一个安装和管理 Python 包的工具 , 是 easy_install 的一个替换品. pip freeze可以查看已经安装的python软件包和版本 pip list 也可以
- codeforces 987 D. Fair
D. Fair time limit per test 2 seconds memory limit per test 512 megabytes input standard input outpu ...
- iOS-开发中的时间处理
做App避免不了要和时间打交道,关于时间的处理,里面有不少门道,远不是一行API调用,获取当前系统时间这么简单.我们需要了解与时间相关的各种API之间的差别,再因场景而异去设计相应的机制. 时间的形式 ...
- Go语言【第十一篇】:Go数据结构之:结构体
Go语言结构体 Go语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型,结构体是由一系列具有相同类型或不同类型数据构成的集合.结构体表示一项记录,比如:保存图书馆的书籍记 ...
- 转:Scipy入门
Scipy入门 转:http://notes.yeshiwei.com/scipy/getting_started.html 本章节主要内容来自 Getting Started .翻译的其中一部分,并 ...
- POJ3977:Subset——题解(三分+折半搜索)
http://poj.org/problem?id=3977 题目大意:有一堆数,取出一些数,记他们和的绝对值为w,取的个数为n,求在w最小的情况下,n最小,并输出w,n. ————————————— ...
- 洛谷 P4597 序列sequence 解题报告
P4597 序列sequence 题目背景 原题\(\tt{cf13c}\)数据加强版 题目描述 给定一个序列,每次操作可以把某个数\(+1\)或\(-1\).要求把序列变成非降数列.而且要求修改后的 ...
- lightoj 1341
lightoj 1341 Aladdin and the Flying Carpet 链接:http://lightoj.com/volume_showproblem.php?problem=134 ...
- Git版本管理1-安装配置和同步
原文载于youdaonote,有图片: http://note.youdao.com/share/?id=79a2d4cae937a97785bda7b93cbfc489&type=note ...
- SQL Server 代理(已禁用代理 XP)
sp_configure 'show advanced options', 1; GO RECONFIGURE WITH OVERRIDE; GO sp_configure 'Agent XPs', ...