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

linux电源管理3

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

    [LV.1]初来乍到

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

    EDA365欢迎您登录!

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

    x
    linux电源管理3

    9 f+ c& [4 z( M* r  A, ~设备初始化流程:
    7 g! Y. i3 e# E; T; tdevice_register(dev)->device_initialize(dev)->device_pm_init(dev)->INIT_LIST_HEAD(&dev->power.entry);; Y9 v; R; y0 l+ ?% u
    设备添加流程:
    7 i( X- t, H) ydevice_add(dev)->device_pm_add(dev)->list_add_tail(&dev->power.entry,&dpm_list);$ F  i7 V0 C/ |2 f4 |; O

    8 n% I- ^* S- |+ N. q% M3 q6 x0 h& w9 i7 g, t. h  t
    从设备初始化和添加到设备模型的流程可以看出,每个设备在注册和添加的过程中对应的device->power.entry被添加到了dpm_list链表中。
    3 E" `  i+ A9 C" z
    / ^0 j1 l+ [1 q" v+ B; F4 L( l: Q# C% J" n5 ^
    devicesuspend由suspend模块完成,suspend模块由CONFIG_SUSPEND宏开关控制& B8 T& T( u* F( |) K1 ~

    5 V5 @% \7 j# @5 W' @[cpp] view plaincopyprint?" Y/ X" E$ k2 n

    0 G0 E6 ^, {% ?8 l: C: H5 p# [
    • obj-$(CONFIG_SUSPEND)       += suspend.o
      5 f. K  `8 X& Q( R* T
    ! Z2 E/ ]" h4 L# C" x
    代码就在kernel/power/suspend.c中
    " D3 x) v/ W% Z# ~2 Q' `% Q" |suspend模块对外导出了pm_suspend接口:% p* W7 r- r" G5 E

    . t1 ]) [* |+ I  V4 E[cpp] view plaincopyprint?% i! g( d* e. o
      ^4 h6 |& v9 \8 }
    • 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);4 s+ D" z2 B. e4 `3 w7 l6 }
    4 i) ~" @0 p9 E2 g5 ]! v1 c) p
    & D; k0 i" x& }! m; I: h; c: g
    pm_suspend被用来控制系统的设备进入指定的状态。前面提到的Linux定义的四种电源状态会被传递到这个函数,pm_suspend会对电源状态做检查,如果传入的是非法之,直接返回EINVAL。; w. Q2 Z+ G( b7 e  _
    四种电源状态定在include/linux/suspend.h文件中
    " F2 J6 @9 J& ^
    5 U( K: c" m% K[cpp] view plaincopyprint?
    ! L, [7 F5 F" E9 p3 d& y7 {7 X- {
    • 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)2 k$ ~! j$ V8 @
    + t5 `, s- a4 J+ \5 L) |
    9 p7 _3 V* {% t
    $ i: F+ s- p. m
    针对具体设备休眠的操作都在针对设备休眠的驱动里面。相关的文件在driver/base/power/目录下。针对设备的休眠动作在driver/base/power/main.c文件中。该文件对外导出了三个接口,suspend模块用到了这些接口。
    : I6 b" B4 w7 g7 T4 s, X[cpp] view plaincopyprint?2 B- V4 ~/ g% v4 Z% Q$ s- Z* Q

    % M. G6 ~# U! A8 q1 X
    • 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);
      1 b) q4 Y% E# i* ^

    ' M3 I: K# g6 u5 ?5 q, N( T9 i: M
    * l7 Q( d5 A; R! h9 Y
    6 m' u4 v; u( J6 u
    % d* o: z+ b6 C& p# @3.3平台相关挂起操作(platform suspending)在设备挂起操作完成之后,会针对特定平台做状态转换操作。Linux内核电源管理模块也为此定义了一组标准函数接口。不同架构只需要实现相应接口即可。" @$ R) m( }5 n  \8 ^* X' V
    [cpp] view plaincopyprint?
    2 ]# Q( E3 ^2 v+ l0 x, X% L- ]
      d. N  B" V3 F$ Y/ C) e  }
    • 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);
    • };" `( B/ L8 S8 C' T( x
    : j8 v/ X. b! H* V$ n

    2 ^2 O" H5 \- e4 U) F- z. V这组函数功能如下:
    + o/ _5 A: G' J. Z/ X+ Rstructplatform_suspend_ops定义了一组用于管理不同平台的下系统进入休眠状态的回调函数。这部分跟mcu关系非常紧密,涉及到时钟,PLL,电压域,频率,总线等系统级的物理模块进入休眠状态。每个具体的函数功能,在sourcecode中有详细的注释。# M- i$ v+ W/ ^& r$ {# w5 @; u
    * B$ P/ A+ M/ T1 }" [
    + w6 k' y& }( n3 i

    - D% j( {& {- E: }2 o6 L3 i
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-7-23 03:33 , Processed in 0.109375 second(s), 23 queries , Gzip On.

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

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

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