转自: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机制分析(上)【转】的更多相关文章

  1. linux dpm机制分析(下)【转】

    转自:http://blog.csdn.net/lixiaojie1012/article/details/23707901 1      设备注册到dpm_list路径 (Platform_devi ...

  2. 【原创】Linux信号量机制分析

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  3. 【转】Linux Writeback机制分析

    1. bdi是什么? bdi,即是backing device info的缩写,顾名思义它描述备用存储设备相关描述信息,这在内核代码里用一个结构体backing_dev_info来表示. bdi,备用 ...

  4. 【原创】Linux Mutex机制分析

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  5. 仿照linux dpm机制,实现自己的dpm【转】

    转自:http://blog.csdn.net/lixiaojie1012/article/details/23788713 前边我们讨论分析了linux 内核的dpm实现,分析的目的在于学以致用:在 ...

  6. JAVA异常处理机制分析(上)

    过去曾有一段时间关于java的异常处理机制曾经让我吃尽苦头,异常机制看似简单,原理,用法也仅仅如此,但是,用起来或是在使用一些框架的时候总会因为使用不当,造成灾难性后果. jdk异常处理机制     ...

  7. Linux mips64r2 PCI中断路由机制分析

    Linux mips64r2 PCI中断路由机制分析 本文主要分析mips64r2 PCI设备中断路由原理和irq号分配实现方法,并尝试回答如下问题: PCI设备驱动中断注册(request_irq) ...

  8. [转载]Linux 线程实现机制分析

    本文转自http://www.ibm.com/developerworks/cn/linux/kernel/l-thread/ 支持原创.尊重原创,分享知识! 自从多线程编程的概念出现在 Linux ...

  9. Linux信号(signal) 机制分析

    Linux信号(signal) 机制分析 [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核 ...

随机推荐

  1. BZOJ 2306 幸福路径(DP)

    题解来源:http://www.cnblogs.com/jianglangcaijin/p/3799494.html 最后必然是走了一条链,或者是一个环(一直绕),或者是一条链加一个环.设f[i][j ...

  2. BZOJ 1786 配对(DP)

    如果我们直接令dp[i][j]为前i个位置第i个位置填j所产生的逆序对的最少数.这样是不满足无后效性的. 但是如果发现对于两个-1,如果前面的-1填的数要大于后面的-1填的数.容易证明把他们两交换结果 ...

  3. [Leetcode] single number 找单个数

    Given an array of integers, every element appears twice except for one. Find that single one. Note:  ...

  4. 内存和cpu

    http://www.blogjava.net/fjzag/articles/317773.html ubuntu@ubuntu-vm:/work/sv-g5-application/projects ...

  5. JavaScript是如何实现继承的

    JavaScript中的function是万能的,除了用于的函数定义,也可以用于类的定义.JavaScript的继承,说起来也是有点怪,没有public,private等访问控制修饰,也没有imple ...

  6. HDU2841 (队列容斥)

    Visible TreesTime Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot ...

  7. Saddle Point ZOJ - 3955 题意题

    Chiaki has an n × m matrix A. Rows are numbered from 1 to n from top to bottom and columns are numbe ...

  8. Git版本管理1-安装配置和同步

    原文载于youdaonote,有图片: http://note.youdao.com/share/?id=79a2d4cae937a97785bda7b93cbfc489&type=note ...

  9. 疯狂java学习笔记

    面向对象: 从现实世界中客观存在的事物(对象)出发构造软件系统,并在软件系统构造中运用人类的自然思维方式,强调直接以现实世界中的事物为中心来思考,认识问题,并根据这些事务的本质特点,将他们抽象为系统中 ...

  10. c# 定时执行任务

    在Global.asax文件中加上 void Application_Start(object sender, EventArgs e) { // Code that runs on applicat ...