首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

linux电源管理3

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 plaincopyprint?

  • obj-$(CONFIG_SUSPEND)       += suspend.o  

代码就在kernel/power/suspend.c中
suspend模块对外导出了pm_suspend接口:

[cpp] view plaincopyprint?

  •   
  • 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 plaincopyprint?

  • 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 plaincopyprint?

  •   
  • 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 plaincopyprint?

  • 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中有详细的注释。
返回列表