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

linux电源管理3

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

    [LV.1]初来乍到

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

    EDA365欢迎您登录!

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

    x
    linux电源管理3

    ! z$ P8 A6 X' A7 ~% o设备初始化流程:5 p, y% W* G8 E7 b( B& M" M
    device_register(dev)->device_initialize(dev)->device_pm_init(dev)->INIT_LIST_HEAD(&dev->power.entry);
    6 s5 k% X, N3 K设备添加流程:
    ) [" p2 g+ o5 X% X6 M5 o9 q1 Rdevice_add(dev)->device_pm_add(dev)->list_add_tail(&dev->power.entry,&dpm_list);
    * e8 W5 _3 N9 n6 N$ \, t( A: N: T8 T% E3 y: X
    ) ^% t: F% y% ^' b3 I8 R
    从设备初始化和添加到设备模型的流程可以看出,每个设备在注册和添加的过程中对应的device->power.entry被添加到了dpm_list链表中。3 V7 y; Y; O6 q* w6 V2 \9 I

    : |# f: e& \7 D8 u* ?9 v1 T+ l/ P7 s
    devicesuspend由suspend模块完成,suspend模块由CONFIG_SUSPEND宏开关控制  f: k: ^, N! B1 g3 Z( X7 [. E

    * c! o9 h" H6 J$ [[cpp] view plaincopyprint?9 ]# M1 H# f6 ?! `, O2 b

    : [* A( l- y" \8 u7 d9 c! f( H7 m4 b
    • obj-$(CONFIG_SUSPEND)       += suspend.o7 L+ @; e( O5 T6 c% Y/ z3 A* X

    ! k( \" I7 v  @代码就在kernel/power/suspend.c中
    0 q3 C) |6 i. o* j$ X5 K; [suspend模块对外导出了pm_suspend接口:
    " q) r* m; Q: E- u
      r* l* d. M: c[cpp] view plaincopyprint?) Z3 z1 w  [2 K" y
    6 x& \  m5 ~. o9 W, J0 a: K; f
    • 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);. {1 u  n* S. j! P1 `- l
    , y# m  K; c! ?/ m" b8 A
    ( A) X3 M: m! R) K
    pm_suspend被用来控制系统的设备进入指定的状态。前面提到的Linux定义的四种电源状态会被传递到这个函数,pm_suspend会对电源状态做检查,如果传入的是非法之,直接返回EINVAL。
    : k  J+ J6 N( G' q四种电源状态定在include/linux/suspend.h文件中) P5 B0 M5 |; D4 h* W" J. W

    ; [/ z$ g5 J; N. T[cpp] view plaincopyprint?  o9 s5 N8 H. S/ p& U
    2 [% o. J7 ~- P: J+ A! k
    • 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)! z7 R% H0 S- o/ V8 `

    # A- {" g+ D# b) g; e" I$ j1 _9 X2 G) p! U) J$ Z

    / F" B. p1 A3 ?6 Q% P针对具体设备休眠的操作都在针对设备休眠的驱动里面。相关的文件在driver/base/power/目录下。针对设备的休眠动作在driver/base/power/main.c文件中。该文件对外导出了三个接口,suspend模块用到了这些接口。
    % ^$ K/ s1 D) ]4 G! m- d" u[cpp] view plaincopyprint?
    / H! d1 l( p2 n1 h' P4 h
    ( ~! w% E. `! _) ^
    • 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);
      2 i# `  w+ K' G0 h6 n/ D( H( }' K
      `  s3 x- d, }. \
    1 q' ~& i2 u) r/ I
    : O8 z6 K/ M: x5 Z

    : t) @  X+ _+ S: K0 r4 k+ a3.3平台相关挂起操作(platform suspending)在设备挂起操作完成之后,会针对特定平台做状态转换操作。Linux内核电源管理模块也为此定义了一组标准函数接口。不同架构只需要实现相应接口即可。
    + r0 i9 [+ a( ?% a6 P[cpp] view plaincopyprint?, }7 D3 v" d) l( b: U+ |
    ) ]5 F0 e; L. a4 x0 J' L
    • 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);
    • };
      # G( s; g# l' v/ \* ^
    $ E% E# Z' w, b" f9 y' ]% W

    5 H3 x# D9 H! r& {$ f# _: H" M这组函数功能如下:, I: k# I% D8 z9 ]0 j7 A/ {
    structplatform_suspend_ops定义了一组用于管理不同平台的下系统进入休眠状态的回调函数。这部分跟mcu关系非常紧密,涉及到时钟,PLL,电压域,频率,总线等系统级的物理模块进入休眠状态。每个具体的函数功能,在sourcecode中有详细的注释。0 u: ~+ l4 B, J$ l* e9 s
    ! u( f8 D( [5 c+ B( S
    2 M+ M: j5 A& n; d
    * h! l' I- `' E: J$ Z7 f. `
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-8-21 23:17 , Processed in 0.140625 second(s), 23 queries , Gzip On.

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

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

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