找回密码
 注册
关于网站域名变更的通知
查看: 318|回复: 1
打印 上一主题 下一主题

linux电源管理3

[复制链接]
  • TA的每日心情
    开心
    2019-11-20 15:00
  • 签到天数: 2 天

    [LV.1]初来乍到

    跳转到指定楼层
    1#
    发表于 2019-6-27 10:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

    EDA365欢迎您登录!

    您需要 登录 才可以下载或查看,没有帐号?注册

    x
    linux电源管理3
    & ]* [1 R' k  m& v' ^* @
    设备初始化流程:
    5 p% O7 h& X6 \" `" _" adevice_register(dev)->device_initialize(dev)->device_pm_init(dev)->INIT_LIST_HEAD(&dev->power.entry);, \1 G  ~  G+ w9 k1 X2 p3 u
    设备添加流程:. Z4 P( N, e; F3 Z  g/ n! |
    device_add(dev)->device_pm_add(dev)->list_add_tail(&dev->power.entry,&dpm_list);% t3 H( }+ r3 |7 j6 E) g( H
    4 N$ x0 O7 k! M5 o7 ]
    8 v6 `& ?3 h3 n. B3 n, }- r
    从设备初始化和添加到设备模型的流程可以看出,每个设备在注册和添加的过程中对应的device->power.entry被添加到了dpm_list链表中。6 V9 B. _. d+ D. v+ d! |+ P4 R/ S" Q
    : w8 H- P, G3 N+ x* \. L1 T+ o: l; N! j

    & D2 J1 a+ H$ u9 {+ P0 Cdevicesuspend由suspend模块完成,suspend模块由CONFIG_SUSPEND宏开关控制
      @) _2 `) S+ f4 ~! b5 X4 N0 ^8 h; m$ }0 I  W
    [cpp] view plaincopyprint?
    + M: j  Z: e5 s) c' y" y" N! \8 c$ I. G8 Q& q
    • obj-$(CONFIG_SUSPEND)       += suspend.o
      / U# S% \0 w6 x5 g/ s1 q8 H# o2 D
    1 T  z2 [4 ~- h! v5 v4 v! P0 w
    代码就在kernel/power/suspend.c中
    5 Z8 o- e) e& \  g! n* {8 osuspend模块对外导出了pm_suspend接口:
    ( I% ^2 L3 N1 s( ~# K
    5 {: ~) \5 r$ U9 ^& g' ~( u9 z[cpp] view plaincopyprint?( _9 B; W" ?- S) B. c! V  d

    ( o# m. M+ ?4 {, ]" k: E6 e
    • 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);) G) V$ d4 d* C

    & i% g# a5 }, S! q# c% I8 U1 B) ]  P- }+ g" v0 s
    pm_suspend被用来控制系统的设备进入指定的状态。前面提到的Linux定义的四种电源状态会被传递到这个函数,pm_suspend会对电源状态做检查,如果传入的是非法之,直接返回EINVAL。
      c+ v9 n" E8 V( @! {四种电源状态定在include/linux/suspend.h文件中0 S/ W' d' I. C5 B0 H2 ^
    0 {, ^* ^5 f) T% ~/ j5 r
    [cpp] view plaincopyprint?* X6 w! s2 ?9 v5 W

    " F: N& ]0 K& T! s$ o" f
    • 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)
      & x  \/ m4 N8 o4 u# ~# P' n
    $ J+ T5 b" n$ y

    : r7 X! N& i0 F8 N: [
    & m; S, @' g2 M: ~/ C2 J1 u针对具体设备休眠的操作都在针对设备休眠的驱动里面。相关的文件在driver/base/power/目录下。针对设备的休眠动作在driver/base/power/main.c文件中。该文件对外导出了三个接口,suspend模块用到了这些接口。. b2 ^& |  K: Z# z  h
    [cpp] view plaincopyprint?! w. }; q+ |, m1 g* o
    : P, C$ U4 }$ p" C
    • 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);
      7 w# ]( L- H6 \

    ; {( a* j/ I* N0 K  E$ E3 |. f* Y6 M
    $ c! s5 w9 ]3 Y2 C% _7 D( x

    % |% }( W. v+ I0 O6 W3.3平台相关挂起操作(platform suspending)在设备挂起操作完成之后,会针对特定平台做状态转换操作。Linux内核电源管理模块也为此定义了一组标准函数接口。不同架构只需要实现相应接口即可。
    3 {* S' v2 l( g3 f8 _7 \7 D[cpp] view plaincopyprint?
    * u7 v- r8 |7 \6 T+ G+ g4 B! S# R& k% I6 q* }! h% o7 q
    • 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);
    • };0 N% ?% K; Z1 ]/ |- F3 j
    , b: o: j: C: O

    8 A- D! c- y3 s9 l这组函数功能如下:. {$ d3 N/ M" V+ ]
    structplatform_suspend_ops定义了一组用于管理不同平台的下系统进入休眠状态的回调函数。这部分跟mcu关系非常紧密,涉及到时钟,PLL,电压域,频率,总线等系统级的物理模块进入休眠状态。每个具体的函数功能,在sourcecode中有详细的注释。# U, w% S* M* x# _% ?
    5 H" S* V4 `! n- F4 ^- z2 D

    7 T9 F2 P0 T+ u( D0 S2 o* ~' w( S5 `, u4 X0 e' o
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-10-10 05:01 , Processed in 0.156250 second(s), 23 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表