在linux内核系统中,各个模块、子系统之间是相互独立的。Linux内核可以通过通知链机制来获取由其它模块或子系统产生的它感兴趣的某些事件。

notifier_block结构体在include/linux/notifier.h中定义:

struct notifier_block {
notifier_fn_t notifier_call;
struct notifier_block __rcu *next;
int priority;
};

priority用来定义优先级,高优先级的处理例程将被优先执行,数值越大,优先级越高。

回到函数的原型定义:

typedef    int (*notifier_fn_t)(struct notifier_block *nb,
unsigned long action, void *data);

TP属于输入子系统,可以通过获取framebuffer子系统来实现亮屏和灭屏时触发相应的事件。

fb_register_client和fb_unregister_client函数定义在drivers/video/fb_notify.c:

/**
* fb_register_client - register a client notifier
* @nb: notifier block to callback on events
*/
int fb_register_client(struct notifier_block *nb)
{
return blocking_notifier_chain_register(&fb_notifier_list, nb);
} /**
 *    fb_unregister_client - unregister a client notifier
 *    @nb: notifier block to callback on events
 */
int fb_unregister_client(struct notifier_block *nb)
{
    return blocking_notifier_chain_unregister(&fb_notifier_list, nb);
}

当framebuffer子系统发生事件时,调用notifier_call_chain()来触发相应的处理函数。

/**
* fb_notifier_call_chain - notify clients of fb_events
*
*/
int fb_notifier_call_chain(unsigned long val, void *v)
{
return blocking_notifier_call_chain(&fb_notifier_list, val, v);
}

下面是一个实例:

struct msg21xx_ts_data {
struct input_dev *input;
struct hrtimer timer;
struct work_struct work;
int irq;
struct dentry *dir;
char *ts_info;
u8 addr;
int fw_major;
int fw_minor;
#ifdef CONFIG_FB
struct notifier_block fb_notif;
#endif
bool suspended;
struct i2c_client *client;
struct regulator *vdd;
struct regulator *vcc_i2c;
struct msg21xx_platform_data *pdata;
struct workqueue_struct *msg21xx_wq;
struct mutex msg21xx_mutex;
};

probe函数中与notifier相关部分实现:

struct msg21xx_ts_data *data;

data = kzalloc(sizeof(struct msg21xx_ts_data), GFP_KERNEL);
if (!data) {
    dev_err(&client->dev, "%s: Alloc mem fail!", __func__);
    err = -ENOMEM;
    goto exit;
} #ifdef CONFIG_FB
data->fb_notif.notifier_call = fb_notifier_callback;
err = fb_register_client(&data->fb_notif);
if (err)
dev_err(&client->dev, "Unable to register fb_notifier: %d\n",
        err);
#endif

fb_notifier_callback实现:


#ifdef CONFIG_FB
static int fb_notifier_callback(struct notifier_block *self,
unsigned long event, void *data)
{
struct fb_event *evdata = data;
int *blank;
struct msg21xx_ts_data *msg21xx_data =
container_of(self, struct msg21xx_ts_data, fb_notif); if (evdata && evdata->data && event == FB_EVENT_BLANK &&
msg21xx_data && msg21xx_data->client) {
blank = evdata->data;
if (*blank == FB_BLANK_UNBLANK)
msg21xx_ts_resume(&msg21xx_data->client->dev);
else if (*blank == FB_BLANK_POWERDOWN)
msg21xx_ts_suspend(&msg21xx_data->client->dev);
} return 0;
}
#endif

msg21xx_ts_suspend和msg21xx_ts_resume实现如下,主要是操作TP的电源和RST脚,LCD灭屏时,为了降低系统的功耗,需要将TP的power关闭,同时将TP的复位脚拉低,让TP自身进入低功耗模式。

#if defined(CONFIG_PM) || defined(CONFIG_PM_RUNTIME)
static int msg21xx_ts_suspend(struct device *dev)
{
struct msg21xx_ts_data *data = dev_get_drvdata(dev);
int err; if (data->suspended) {
dev_info(dev, "Already in suspend state\n");
return 0;
} disable_irq(data->client->irq); err = msg21xx_power_on(data, false);
if (err)
dev_err(dev, "power off failed"); gpio_set_value_cansleep(data->pdata->reset_gpio, 0); data->suspended = true;
return 0;
} static int msg21xx_ts_resume(struct device *dev)
{
struct msg21xx_ts_data *data = dev_get_drvdata(dev);
int err; if (!data->suspended) {
dev_dbg(dev, "Already in awake state\n");
return 0;
} err = msg21xx_power_on(data, true);
if (err) {
dev_err(dev, "power on failed");
return err;
} enable_irq(data->client->irq);
gpio_set_value_cansleep(data->pdata->reset_gpio, 1);
data->suspended = false;
return 0;
}
#endif

Linux的notifier机制的应用的更多相关文章

  1. Linux的notifier机制在TP中的应用【转】

    转自:https://blog.csdn.net/armfpga123/article/details/51771666 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog ...

  2. 浅谈Linux内存管理机制

    经常遇到一些刚接触Linux的新手会问内存占用怎么那么多?在Linux中经常发现空闲内存很少,似乎所有的内存都被系统占用了,表面感觉是内存不够用了,其实不然.这是Linux内存管理的一个优秀特性,在这 ...

  3. Linux的io机制

    Linux的io机制 Buffered-IO 和Direct-IO Linux磁盘I/O分为Buffered IO和Direct IO,这两者有何区别呢? 对于Buffered IO: 当应用程序尝试 ...

  4. [内核同步]浅析Linux内核同步机制

    转自:http://blog.csdn.net/fzubbsc/article/details/37736683?utm_source=tuicool&utm_medium=referral ...

  5. Linux内核同步机制--转发自蜗窝科技

    Linux内核同步机制之(一):原子操作 http://www.wowotech.net/linux_kenrel/atomic.html 一.源由 我们的程序逻辑经常遇到这样的操作序列: 1.读一个 ...

  6. 了解linux内存管理机制(转)

    今天了解了下linux内存管理机制,在这里记录下,原文在这里http://ixdba.blog.51cto.com/2895551/541355 根据自己的理解画了张图: 下面是转载的内容: 一 物理 ...

  7. 【Linux下进程机制】从一道面试题谈linux下fork的运行机制

    今天一位朋友去一个不错的外企面试linux开发职位,面试官出了一个如下的题目: 给出如下C程序,在linux下使用gcc编译: #include "stdio.h" #includ ...

  8. Linux内核同步机制

    http://blog.csdn.net/bullbat/article/details/7376424 Linux内核同步控制方法有很多,信号量.锁.原子量.RCU等等,不同的实现方法应用于不同的环 ...

  9. Linux内核OOM机制的详细分析(转)

    Linux 内核 有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了 防止内存耗尽而内核会把该进程杀掉.典 ...

随机推荐

  1. Perl的特殊代码块:BEGIN、CHECK、INIT、END和UNITCHECK

    这是5个特殊的代码块.要理解这几个块,关键在于几个时间点: (1).程序编译期间 (2).程序执行期间 (3).程序执行结束但还未退出期间 BEGIN块 BEGIN块是在程序编译期间执行的,也就是上面 ...

  2. iconfont图标应用

    一.什么是iconfont? 我们现在通常所指的iconfont,是用字体文件取代图片文件,来展示图标.特殊字体等元素的方法.iconfont是阿里巴巴矢量图标库是由阿里巴巴体验团队倾力打造的中国第一 ...

  3. mvc 中合并两个list集合

    有时候,在进行查询操作的时候需要将从数据库中查询的两张表进行合并,成为一张表然后返回给前端.或者在原有的一张表基础上面加几个新的字段. 这个时候可以新建一个.class[model类],在这个新建的m ...

  4. [转]centos7指定yum安装软件路径

    本文转自:https://www.cnblogs.com/pyyu/p/9814062.html 网上的命令都是垃圾 yum -c /etc/yum.conf --installroot=/opt/a ...

  5. pycharm破解

    链接: https://share.weiyun.com/5DGGG3J (密码:hQq6) 将JetbrainsCrack-2.6.10-release-enc.jar放D盘1.pycharm下bi ...

  6. [android] 采用断点调试的方式观察pull解析的流程

    当程序出现错误的时候,界面出不来,这个时候就需要调试技巧,描述这个程序在哪个地方出现的问题.在你认为可能出错的代码部分,左侧的行号栏点击打断点,在项目目录右键 ==>debug as ==> ...

  7. python学习笔记(三)、字典

    字典是一种映射类型的数据类型.辣么什么是映射呢?如果看过<数据结构与算法>这一本书的小伙伴应该有印象(我也只是大学学习过,嘻嘻). 映射:就是将两个集合一 一对应起来,通过集合a的值,集合 ...

  8. python_文件操作

    说明:如有转载,请标明出处!! 一.文件操作 1.文件常用操作方法 open() f=open('文件名','r',encoding='utf-8') #三个参数,第一个文件详细路径,需要写明文件格式 ...

  9. Spring Boot Docker 实战

    Spring Boot Docker 开发环境 开发工具: Intellij IDEA 2018.2.6 springboot: 2.0.6.RELEASE jdk: 1.8.0_192 maven: ...

  10. Java学习笔记之——Object类

    所有类的祖先 如果一个类没有显式继承,则继承Object 每一个类都直接或间接的是Object的子类 相关API: protected Objectclone() 创建并返回此对象的副本. boole ...