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

linux电源管理3

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

    [LV.1]初来乍到

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

    EDA365欢迎您登录!

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

    x
    linux电源管理3

    & E/ m; N$ o# Q( Y5 J  J$ t6 F/ V设备初始化流程:
    0 Y! }: t# L: w1 Udevice_register(dev)->device_initialize(dev)->device_pm_init(dev)->INIT_LIST_HEAD(&dev->power.entry);
      T8 i( _& a  J- ?# @0 d( N设备添加流程:1 `0 [8 `3 `! s9 n7 |5 X
    device_add(dev)->device_pm_add(dev)->list_add_tail(&dev->power.entry,&dpm_list);, {8 T+ t/ O: D6 B% {
    6 S- w6 k1 l3 |1 X7 U& T

    7 F$ C5 c9 P# i- x% l从设备初始化和添加到设备模型的流程可以看出,每个设备在注册和添加的过程中对应的device->power.entry被添加到了dpm_list链表中。3 D9 U. m/ \, C! s

    8 _- ?0 N5 ~8 j% O' K
    . O2 K0 e8 J! W; a6 j. F6 zdevicesuspend由suspend模块完成,suspend模块由CONFIG_SUSPEND宏开关控制& f* A4 Z# o5 W  x& F

    # B. B. }7 s; L8 N- v[cpp] view plaincopyprint?
    # n7 P; D: s3 R9 Q, D' Q* u- {1 c+ C8 b
    • obj-$(CONFIG_SUSPEND)       += suspend.o
      ' T5 v( ]8 M3 i& X4 s

    4 E0 z( F( B; K% |3 e7 r代码就在kernel/power/suspend.c中
    $ A/ `; Y- i+ ~/ C% F, j' y1 wsuspend模块对外导出了pm_suspend接口:
    ( C* W$ X' `6 f( `8 ^$ T- D# d
    $ O. a+ K5 ^' x9 C[cpp] view plaincopyprint?
    9 M8 I, i" |2 l* p; o& H% s8 i0 ~: H2 ^& _8 J2 b: a7 P2 c- g
    • 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);
      . F  y* R" j( N9 Q2 o
    * d! m7 `% J. N! T; }$ Y3 `+ a
    . B: _4 D; ~6 x- E4 @
    pm_suspend被用来控制系统的设备进入指定的状态。前面提到的Linux定义的四种电源状态会被传递到这个函数,pm_suspend会对电源状态做检查,如果传入的是非法之,直接返回EINVAL。
    ; [  c4 M( A+ x) G* @四种电源状态定在include/linux/suspend.h文件中
    " i( I( r3 D* L" a% G& k% j4 p# `5 U& X$ i$ _0 B, P: K4 v4 D
    [cpp] view plaincopyprint?
    , {4 v$ a+ S" R% S  [) m. x( Q% f# {6 G' {- y
    • 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)
      7 K* T" R  j' u' R2 e5 r7 \; J2 F6 w

    . D" u! H+ g" Y; W, @) }
    * H0 q" A; U: d' c
    7 V/ O0 L5 K6 Z针对具体设备休眠的操作都在针对设备休眠的驱动里面。相关的文件在driver/base/power/目录下。针对设备的休眠动作在driver/base/power/main.c文件中。该文件对外导出了三个接口,suspend模块用到了这些接口。
    7 W& u7 s6 F( U) L9 c[cpp] view plaincopyprint?7 L/ a* d; y" j6 {
    0 }" U3 a3 {* g* p" d% {- T
    • 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);* A0 u* S& O* Q  @. K" I

    # |3 G, r  b7 w, c# k+ N0 d, T+ O+ l
    3 l; {1 L, J; S3 n4 U
    $ J2 C0 \+ n2 F* f7 {! x- K
    3.3平台相关挂起操作(platform suspending)在设备挂起操作完成之后,会针对特定平台做状态转换操作。Linux内核电源管理模块也为此定义了一组标准函数接口。不同架构只需要实现相应接口即可。5 I; h9 t! ^1 ~) D- I3 `# x  ]* n
    [cpp] view plaincopyprint?
      y+ G9 R0 j" R: E1 c$ E6 E$ b; R" A3 O; A+ J  [/ A
    • 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);
    • };
      / C9 E  E% B+ r  S  l

    3 g3 z6 Q& p" |" I$ p* d7 L1 J- I  ]! T0 S  p1 B3 l) d! m
    这组函数功能如下:
    , o1 {$ @0 p" F% i6 ~; Q- z8 nstructplatform_suspend_ops定义了一组用于管理不同平台的下系统进入休眠状态的回调函数。这部分跟mcu关系非常紧密,涉及到时钟,PLL,电压域,频率,总线等系统级的物理模块进入休眠状态。每个具体的函数功能,在sourcecode中有详细的注释。  T0 p! P2 x* f' O/ K) o* F

    6 j% W# `8 H. E! T7 y4 Q5 d" V
    % h: q( q9 x* @' M  x1 O+ z$ X
    + s. T0 r% Q1 _2 R
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-8-4 13:40 , Processed in 0.109375 second(s), 23 queries , Gzip On.

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

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

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