标题:
linux电源管理3
[打印本页]
作者:
look_w
时间:
2017-10-19 13:59
标题:
linux电源管理3
设备初始化流程:
device_register(dev)->device_initialize(dev)->device_pm_init(dev)->INIT_LIST_HEAD(&dev->power.entry);
设备添加流程:
device_add(dev)->device_pm_add(dev)->list_add_tail(&dev->power.entry,&dpm_list);
从设备初始化和添加到设备模型的流程可以看出,每个设备在注册和添加的过程中对应的device->power.entry被添加到了dpm_list链表中。
devicesuspend由suspend模块完成,suspend模块由CONFIG_SUSPEND宏开关控制
[cpp]
view plain
copy
print
?
obj-$(CONFIG_SUSPEND) += suspend.o
代码就在kernel/power/suspend.c中
suspend模块对外导出了pm_suspend接口:
[cpp]
view plain
copy
print
?
int
pm_suspend(suspend_state_t state)
{
int
error;
if
(state <= PM_SUSPEND_ON || state >= PM_SUSPEND_MAX)
return
-EINVAL;
error = enter_state(state);
if
(error) {
suspend_stats.fail++;
dpm_save_failed_errno(error);
}
else
{
suspend_stats.success++;
}
return
error;
}
EXPORT_SYMBOL(pm_suspend);
pm_suspend被用来控制系统的设备进入指定的状态。前面提到的Linux定义的四种电源状态会被传递到这个函数,pm_suspend会对电源状态做检查,如果传入的是非法之,直接返回EINVAL。
四种电源状态定在include/linux/suspend.h文件中
[cpp]
view plain
copy
print
?
typedef
int
__bitwise suspend_state_t;
#define PM_SUSPEND_ON ((__force suspend_state_t) 0)
#define PM_SUSPEND_STANDBY ((__force suspend_state_t) 1)
#define PM_SUSPEND_MEM ((__force suspend_state_t) 3)
#define PM_SUSPEND_MAX ((__force suspend_state_t) 4)
针对具体设备休眠的操作都在针对设备休眠的驱动里面。相关的文件在driver/base/power/目录下。针对设备的休眠动作在driver/base/power/main.c文件中。该文件对外导出了三个接口,suspend模块用到了这些接口。
[cpp]
view plain
copy
print
?
int
dpm_suspend_start(pm_message_t state)
{
int
error;
error = dpm_prepare(state);
if
(error) {
suspend_stats.failed_prepare++;
dpm_save_failed_step(SUSPEND_PREPARE);
}
else
error = dpm_suspend(state);
return
error;
}
EXPORT_SYMBOL_GPL(dpm_suspend_start);
void
__suspend_report_result(
const
char
*function,
void
*fn,
int
ret)
{
if
(ret)
printk(KERN_ERR "%s(): %pF returns %d\n", function, fn, ret);
}
EXPORT_SYMBOL_GPL(__suspend_report_result);
int
device_pm_wait_for_dev(
struct
device *subordinate,
struct
device *dev)
{
dpm_wait(dev, subordinate->power.async_suspend);
return
async_error;
}
EXPORT_SYMBOL_GPL(device_pm_wait_for_dev);
3.3平台相关挂起操作(platform suspending)在设备挂起操作完成之后,会针对特定平台做状态转换操作。Linux内核电源管理模块也为此定义了一组标准函数接口。不同架构只需要实现相应接口即可。
[cpp]
view plain
copy
print
?
struct
platform_suspend_ops {
int
(*valid)(suspend_state_t state);
int
(*begin)(suspend_state_t state);
int
(*prepare)(
void
);
int
(*prepare_late)(
void
);
int
(*enter)(suspend_state_t state);
void
(*wake)(
void
);
void
(*finish)(
void
);
bool
(*suspend_again)(
void
);
void
(*end)(
void
);
void
(*recover)(
void
);
};
这组函数功能如下:
structplatform_suspend_ops定义了一组用于管理不同平台的下系统进入休眠状态的回调函数。这部分跟MCU关系非常紧密,涉及到时钟,PLL,电压域,频率,总线等系统级的物理模块进入休眠状态。每个具体的函数功能,在sourcecode中有详细的注释。
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0