PM定义了一个notifier_chain:

27 static BLOCKING_NOTIFIER_HEAD(pm_chain_head);

PM在休眠和唤醒的过程中会发出一些EVENTS,

246 /* Hibernation and suspend events */
247 #define PM_HIBERNATION_PREPARE  0x0001 /* Going to hibernate */
248 #define PM_POST_HIBERNATION     0x0002 /* Hibernation finished */
249 #define PM_SUSPEND_PREPARE      0x0003 /* Going to suspend the system */
250 #define PM_POST_SUSPEND         0x0004 /* Suspend finished */
251 #define PM_RESTORE_PREPARE      0x0005 /* Going to restore a saved image */
252 #define PM_POST_RESTORE         0x0006 /* Restore failed */

如果哪个内核模块想得到这些EVENTS,就需要定义一个notifier_block, 并把它挂载到pm_chain_head上。为此,PM定义了挂载和卸载函数:

29 int register_pm_notifier(struct notifier_block *nb)
 30 {
 31         return blocking_notifier_chain_register(&pm_chain_head, nb);
 32 }
 33 EXPORT_SYMBOL_GPL(register_pm_notifier);
 34 
 35 int unregister_pm_notifier(struct notifier_block *nb)
 36 {
 37         return blocking_notifier_chain_unregister(&pm_chain_head, nb);
 38 }
 39 EXPORT_SYMBOL_GPL(unregister_pm_notifier);

在PM休眠或者唤醒进行到某个特定阶段时,PM就会使用下面这个函数向链上所有的内核模块发送一个EVENT。

41 int pm_notifier_call_chain(unsigned long val)
 42 {
 43         return (blocking_notifier_call_chain(&pm_chain_head, val, NULL)
 44                         == NOTIFY_BAD) ? -EINVAL : 0;
 45 }

比如, 我们可以在suspend_prepare()中发现这样的代码:

88         error = pm_notifier_call_chain(PM_SUSPEND_PREPARE);
 89         if (error)
 90                 goto Finish;
 91    
 
102  Finish:
103         pm_notifier_call_chain(PM_POST_SUSPEND);

我们可以在vmwatchdog.c中看到使用pm_chain的例子。

vmwatchdog想获得下面的四个EVENTS,

PM_POST_HIBERNATION
PM_POST_SUSPEND
PM_HIBERNATION_PREPARE
PM_SUSPEND_PREPARE:

并在这4个EVENTS发生时调用对应的函数。 于是它定义了vmwdt_power_event()函数:

272 /* 
273  * This function is called for suspend and resume.
274  */
275 static int vmwdt_power_event(struct notifier_block *this, unsigned long event,
276                              void *ptr)
277 {  
278         switch (event) {
279         case PM_POST_HIBERNATION:
280         case PM_POST_SUSPEND:       
281                 return vmwdt_resume();
282         case PM_HIBERNATION_PREPARE:
283         case PM_SUSPEND_PREPARE:
284                 return vmwdt_suspend();
285         default:
286                 return NOTIFY_DONE;
287         }
288 }

vmwatch定义了一个notifier_block结构,叫做vmwdt_power_notifier,

290 static struct notifier_block vmwdt_power_notifier = {
291         .notifier_call = vmwdt_power_event,
292 };

并把它挂载到pm_chain链上,

315         ret = register_pm_notifier(&vmwdt_power_notifier);

这样,每次PM通过pm_notifier_call_chain()发出一些EVENTS时,vmwatchdog就可以接收到这些EVENTS并执行相应的函数了。

PM notifier相关推荐

  1. linux 电源管理 Generic PM之Suspend功能

    Linux电源管理(6)_Generic PM之Suspend功能 作者:wowo 发布于:2014-8-22 21:40 分类:电源管理子系统 1. 前言 Linux内核提供了三种Suspend: ...

  2. Linux电源管理(6)_Generic PM之Suspend功能【重磅文章】-- wowo

    文章目录 1. 前言 2. Suspend功能有关的代码分布 1)PM Core 2)Device PM 3)Platform dependent PM 3. suspend&resume过程 ...

  3. 戴文的linux内核专题 24,戴文的Linux内核专题:26 配置内核 (22)

    你好!本篇我们将继续配置quot;kernel hacksquot;,接着我们会配置整个安全系统. Alpha和s390处理器需要配置下一个特性(Force weak per-cpu definiti ...

  4. 【Android】 android suspend/resume总结(2)

    上文中提到Android系统通过将 mem 写入 /sys/power/state 来发起系统挂起.这篇文章大部分内容来自蜗窝科技,我更新了code以及增加自己的理解 Suspend功能有关的代码分布 ...

  5. Linux电源管理_Generic PowerManager 之Suspend功能--(一)

    1. 前言 Linux内核提供了三种Suspend: Freeze.Standby和STR(Suspend to RAM),在用户空间向"/sys/power/state"文件分别 ...

  6. Linux运行时IO设备电源管理框架---PM

    1. 介绍 对I/O设备的运行时电源管理(运行时PM)的支持,是在电源管理的核心(PM core)下借助于以下方式实现的: 电源管理工作队列pm_wq,总线类型(bus types)和设备驱动(dev ...

  7. OpenResty中遇到Can't locate Time/HiRes.pm in @INC问题的解决方法

    今天在研究resty这个命令行工具时,执行 resty -h 出现下面的报错 Can't locate Time/HiRes.pm in @INC (@INC contains: /usr/local ...

  8. 我是村里唯一的PM,哈哈哈…

    文章来源:PM圈子(pm1178) 当我跟村里人提起我是一名PM时 他们内心是这样想的 ▼ 也有的朋友这样想 ▼ 爸爸问我,什么P? ▼ 妈妈问我,M什么? ▼ 我说PM,就是项目经理 爸妈说,孩子出 ...

  9. 在阿里当PM都需要做什么?

    作者 | Bella酱 有人说"一起在湖边吹过晚风的人,会记得更久一些吧",那一起住过院的人,是不是可以刻骨铭心了?之前就想写篇文章总结一下自己前段时间当PM的经历呢,奈何发布了这 ...

  10. 如果你是PM,想转PM,拿走

    欢迎使用Markdown编辑器写博客 陈医生发神功串烧26首流行曲目,勇夺金曲奖.小伙伴们若是能串烧26本PM好书,那还不得笑傲PM江湖!26本好多,我们可以慢慢来,这次小编给各位介绍10本PM超级相 ...

最新文章

  1. ResponsiveSlides.js——小于1k的轻量级幻灯片演示插件
  2. 二十六、深入HashCode与equals的区别(上篇)
  3. Python中异常(Exception)的总结
  4. php 判断 多组,请教怎么有效判断几组数据范围是否有交集
  5. 2016级算法第六次上机-A.Bamboo之寻找小金刚
  6. CPPUnit 测试宏
  7. 学hadoop需要什么基础
  8. html的版本适配,2.1.3 HTML 5确保了与之前HTML版本的兼容性
  9. CAN 报文编码学习笔记二:汽车CAN协议测试——发送与接收
  10. 埃隆·马斯克(Elon Musk)
  11. 网页中图片显示不出来,解决网页中图片不能显示的方法
  12. [Growth]Steve Jobs——Follow your heart and intuition, everything else is secondary.
  13. 数据解读为什么流量明星不灵了
  14. 银行资产业务和负债业务
  15. 工作经费的开支范围_经费支出范围
  16. HTTPS 中双向认证SSL 协议的具体过程
  17. ubuntu的一些安装设置
  18. nfdump分析netflow
  19. daemontools安装及使用技巧
  20. 咕咕机显示服务器请求异常,request:fail小程序客户端Bug反馈【如果有做错误检测大家应该都遇到】...

热门文章

  1. BF算法(暴力算法)
  2. 老年程序员的出路何在
  3. 服务器ubuntu系统调节亮度,Ubuntu系统下调节屏幕亮度的两种Linux命令
  4. ANSI/ISO C++ Professional Programmer's Handbook(7)
  5. OJ 2312 Problem B Peach
  6. 清华大学鲍橒计算机1999,《最强大脑》鲍橒:世界盲棋第一人的最强记忆
  7. Spring框架基础(上)
  8. Star Way To Heaven 二分 + 并查集 + Prime
  9. “凸现”三围的健身运动法(图)
  10. 欠款人署名故意签错,怎么维权