最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 正文

Linux电源管理架构

来源:动视网 责编:小OO 时间:2025-10-04 11:05:27
文档

Linux电源管理架构

LK设备驱动模型之电源管理2013年1月14日※要点区:※设计思想:※数据结构关系图:表示用来描述request的work,work将被放置在workqueue中pm_message_tpower_stateunsignedintcan_wakeup表示设备物理上是否支持唤醒事件unsignedintshould_wakeup表示设备是否启用它的唤醒机制unsignedasync_suspend表示suspend操作的同步信号enumdpm_statestatusDPM_INVALIDDPM_
推荐度:
导读LK设备驱动模型之电源管理2013年1月14日※要点区:※设计思想:※数据结构关系图:表示用来描述request的work,work将被放置在workqueue中pm_message_tpower_stateunsignedintcan_wakeup表示设备物理上是否支持唤醒事件unsignedintshould_wakeup表示设备是否启用它的唤醒机制unsignedasync_suspend表示suspend操作的同步信号enumdpm_statestatusDPM_INVALIDDPM_
LK 设备驱动模型之电源管理

2013年1月14日

※要点区:

※设计思想:

※数据结构关系图:

表示用来描述request 的work ,work 将被放置在workqueue 中 pm_message_t power_state unsigned int can_wakeup 表示设备物理上是否支持唤醒事件 unsigned int

should_wakeup 表示设备是否启用它的唤醒机制 unsigned

async_suspend

表示suspend 操作的同步信号

enum dpm_state status DPM_INVALID DPM_ON

DPM_PREPARING DPM_RESUMING DPM_SUSPENDING DPM_OFF DPM_OFF_IRQ

dev_pm_info

dpm_state

struct list_head entry

struct completion completion struct timer_list suspend_timer unsigned long timer_expires; struct work_struct work enum rpm_request request atomic_t

usage_count 设置定时器的定时时间

表示设备使用计数器

atomic_t child_count 表示处于“active ”状态的子设备的个数 unsigned int

disable_depth unsigned int

ignore_children unsigned int

idle_notification 若被置位,runtime_idle()将被执行 unsigned int

request_pending 若存在未处理的请求,标志位将置1

unsigned int deferred_resume 若被置位,设备在执行完suspend 操作后立即执行resume unsigned int runtime_auto 若被置位,设备属于runtime 电源管理模式 spin_lock_t

lock

enum rpm_status runtime_status int

runtime_error

若回调函数执行失败,标志位将置1

表示设备的run-time PM 状态,但不能反映真实的电源状态 RPM_REQ_NONE = 0

RPM_REQ_IDLE

RPM_REQ_SUSPEND

RPM_REQ_RESUME

rpm_request

RPM_ACTIVE = 0 RPM_RESUMING RPM_SUSPENDED RPM_SUSPENDING

rpm_status

若被置位,忽略处于“active ”状态的子设备的个数若被设置为非0,关闭runtime PM 功能

表示用于对suspend 请求进行调度的timer 表示与PM 核操作相关的设备当前状态

struct dev_pm_info power device

... ...

表示未处理请求的类型表示同步锁

※电源管理代码流程分析:

步骤一:初始化

device_register()→device_initialize()→device_pm_init(dev)→pm_runtime_init ()

device_register()

device_initialize()

device_pm_init()

pm_runtime_init()

INIT_WORK(&dev->power.work,pm_runtime_work)

setup_timer(&dev->power.suspend_timer,pm_suspend_timer_fn,…)

init_waitqueue_head(&dev->power.wait_queue)

__pm_runtime_idle()

dev->power.request = RPM_REQ_IDLE?

Y

__pm_runtime_suspend()

dev->power.request = RPM_REQ_SUSPEND?

Y

__pm_runtime_resume()

dev->power.request = RPM_REQ_RESUME?

Y

expires > 0 &&

!time_after(expires,jiffies)?

Y

__pm_request_suspend()

dev->power.request = RPM_REQ_SUSPEND queue_work(pm_wq,&dev->power.work)

core_initcall(pm_init)

pm_init()

pm_wq = create_freezeable_workqueue(“pm ”)

void pm_runtime_init (struct device *dev) { ... ... ;

//确定工作任务对应的处理函数 INIT_WORK(&dev->power.work, pm_runtime_work );

//设置用于安排挂起请求的定时器,定时器时间到将执行pm_suspend_timer_fn 函数

setup_timer(&dev->power.suspend_timer, pm_suspend_timer_fn ,(unsigned long)dev); init_waitqueue_head(&dev->power.wait_queue);

}

{

struct device *dev = container_of(work, struct device, power.work);

enum rpm_request req;

... ... ;

req = dev->power.request;

//设置未处理请求的类型为RPM_REQ_NONE

dev->power.request = RPM_REQ_NONE;

//设置不存在未处理的请求

dev->power.request_pending = false;

//根据未处理请求的类型执行相应操作

switch (req) {

case RPM_REQ_NONE:

break;

case RPM_REQ_IDLE:

__pm_runtime_idle(dev);

break;

case RPM_REQ_SUSPEND:

__pm_runtime_suspend(dev, true);

break;

case RPM_REQ_RESUME:

__pm_runtime_resume(dev, true);

break;

}

}

static int __pm_runtime_idle(struct device *dev)

{

dev->power.idle_notification = true;

if (dev->bus->pm->runtime_idle)

dev->bus->pm->runtime_idle(dev);

else if (dev->type->pm->runtime_idle)

dev->type->pm->runtime_idle(dev);

if ( dev->class->pm->runtime_idle)

dev->class->pm->runtime_idle(dev);

dev->power.idle_notification = false;

//唤醒等待队列

wake_up_all(&dev->power.wait_queue);}

int __pm_runtime_suspend(struct device *dev, bool from_wq)

{

//取消还未处理的suspend请求

pm_runtime_cancel_pending(dev);

//判定设备是否正处于suspend操作

if (dev->power.runtime_status == RPM_SUSPENDING) {

DEFINE_WAIT(wait);

//等待已经进入处理状态的suspend请求处理完毕

for (;;) {

prepare_to_wait(&dev->power.wait_queue, &wait,TASK_UNINTERRUPTIBLE);

schedule();

... ... ;

}

finish_wait(&dev->power.wait_queue, &wait);

}

//设置设备电源管理的操作状态为RPM_SUSPENDING,即正处于挂起中

dev->power.runtime_status = RPM_SUSPENDING;

//设置在执行完suspend操作后不会立即执行resume

dev->power.deferred_resume = false;

if (dev->bus->pm->runtime_suspend)

dev->bus->pm->runtime_suspend(dev);

else if (dev->type->pm->runtime_suspend)

dev->type->pm->runtime_suspend(dev);

else if ( dev->class->pm->runtime_suspend)

dev->class->pm->runtime_suspend(dev);

//设置设备电源管理的操作状态为RPM_SUSPENDED,即已完成挂起操作

dev->power.runtime_status = RPM_SUSPENDED;

//使suspend 定时器无效

pm_runtime_deactivate_timer(dev);

//唤醒等待队列

wake_up_all(&dev->power.wait_queue);

//确定是否应该执行resume

if (dev->power.deferred_resume)__pm_runtime_resume(dev, false);

}

int __pm_runtime_resume(struct device *dev, bool from_wq)

{

//取消还未处理的suspend请求

pm_runtime_cancel_pending(dev);

//判定是否存在设备正处于suspend操作或resume操作

if (dev->power.runtime_status == RPM_RESUMING ||

dev->power.runtime_status == RPM_SUSPENDING) {

DEFINE_WAIT(wait);

for (;;) {

prepare_to_wait(&dev->power.wait_queue, &wait,TASK_UNINTERRUPTIBLE);

schedule();

finish_wait(&dev->power.wait_queue, &wait);

}

}

//设置设备电源管理的操作状态为RPM_RESUMING,即正处于恢复过程中

dev->power.runtime_status = RPM_RESUMING;

if (dev->bus->pm->runtime_resume)

dev->bus->pm->runtime_resume(dev);

else if (dev->type->pm->runtime_resume)

dev->type->pm->runtime_resume(dev);

else if (dev->class->pm->runtime_resume)

dev->class->pm->runtime_resume(dev);

//设置设备电源管理的操作状态为RPM_ACTIVE,即设备已激活

dev->power.runtime_status = RPM_ACTIVE;

wake_up_all(&dev->power.wait_queue);

}

static void pm_suspend_timer_fn(unsigned long data)

{

if (expires > 0 && !time_after(expires, jiffies))

__pm_request_suspend(dev);

... ... ;

}

static int __pm_request_suspend(struct device *dev)

{//设置电源管理请求类型为suspend

dev->power.request = RPM_REQ_SUSPEND;

//添加工作到pm_wq工作队列

queue_work(pm_wq, &dev->power.work);

... ... ;

}

static int __init pm_init(void)←core_initcall(pm_init)

{

pm_wq = create_freezeable_workqueue("pm");

//在/sys/目录下创建名为power的目录

power_kobj = kobject_create_and_add("power

//在/sys/power/目录下创建

sysfs_create_group(power_kobj, &attr_group);

}

static struct attribute_group attr_group = {

.attrs = g,

};

static struct attribute * g[] = {

&state_attr.attr,

&pm_async_attr.attr,

&wake_lock_attr.attr,

&wake_unlock_attr.attr,

};

步骤二:

? ? ?

dpm_suspend_start() dpm_suspend_end()

dpm_prepare() dpm_suspend() dpm_resume() dpm_complete() dpm_suspend_noirq() dpm_resume_noirq()

文档

Linux电源管理架构

LK设备驱动模型之电源管理2013年1月14日※要点区:※设计思想:※数据结构关系图:表示用来描述request的work,work将被放置在workqueue中pm_message_tpower_stateunsignedintcan_wakeup表示设备物理上是否支持唤醒事件unsignedintshould_wakeup表示设备是否启用它的唤醒机制unsignedasync_suspend表示suspend操作的同步信号enumdpm_statestatusDPM_INVALIDDPM_
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top