基于设备树的TQ2440的中断(2)
下面以按键中断为例看看基于设备数的中断的用法:
设备树:
tq2440_key {
compatible = "tq2440,key";
interrupt-parent = <&gpf>;
interrupts = < IRQ_TYPE_EDGE_FALLING>, < IRQ_TYPE_EDGE_FALLING>;
key_3 = <&gpf GPIO_ACTIVE_HIGH>;
key_4 = <&gpf GPIO_ACTIVE_HIGH>;
key_8 = <&gpg GPIO_ACTIVE_HIGH>;
};
驱动:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/interrupt.h> static irqreturn_t tq2440_key_isr(int irq, void *dev_id)
{
printk("%s enter, irq: %d, %s\n", __func__, irq, (char *)dev_id);
return IRQ_HANDLED;
} static int tq2440_key_probe(struct platform_device *pdev) {
struct device *dev = &pdev->dev;
int irq_gpio = -;
int irq = -; printk("%s enter.\n", __func__); if (!dev->of_node) {
dev_err(dev, "no platform data.\n");
return -EINVAL;
} irq = platform_get_irq(pdev, );
printk("%s: get irq %d\n", __func__, irq);
devm_request_any_context_irq(dev, irq,
tq2440_key_isr, IRQF_TRIGGER_FALLING, "key-1", "key-1"); irq = platform_get_irq(pdev, );
printk("%s: get irq %d\n", __func__, irq);
devm_request_any_context_irq(dev, irq,
tq2440_key_isr, IRQF_TRIGGER_FALLING, "key-2", "key-2"); irq_gpio = of_get_named_gpio(dev->of_node, "key_3", );
irq = gpio_to_irq(irq_gpio);
printk("%s: gpio: %d ---> irq (%d)\n", __func__, irq_gpio, irq);
devm_request_any_context_irq(dev, irq,
tq2440_key_isr, IRQF_TRIGGER_FALLING, "key-3", "key-3"); irq_gpio = of_get_named_gpio(dev->of_node, "key_4", );
irq = gpio_to_irq(irq_gpio);
printk("%s: gpio: %d ---> irq (%d)\n", __func__, irq_gpio, irq);
devm_request_any_context_irq(dev, irq,
tq2440_key_isr, IRQF_TRIGGER_FALLING, "key-4", "key-4"); irq_gpio = of_get_named_gpio(dev->of_node, "key_8", );
irq = gpio_to_irq(irq_gpio);
printk("%s: gpio: %d ---> irq (%d)\n", __func__, irq_gpio, irq);
devm_request_any_context_irq(dev, irq,
tq2440_key_isr, IRQF_TRIGGER_FALLING, "key-8", "key-8"); return ;
} static int tq2440_key_remove(struct platform_device *pdev) { printk("%s enter.\n", __func__); return ;
} static const struct of_device_id tq2440_key_dt_ids[] = {
{ .compatible = "tq2440,key", },
{},
}; MODULE_DEVICE_TABLE(of, tq2440_key_dt_ids); static struct platform_driver tq2440_key_driver = {
.driver = {
.name = "tq2440_key",
.of_match_table = of_match_ptr(tq2440_key_dt_ids),
},
.probe = tq2440_key_probe,
.remove = tq2440_key_remove,
}; static int __init tq2440_key_init(void)
{
int ret; ret = platform_driver_register(&tq2440_key_driver);
if (ret)
printk(KERN_ERR "tq2440_key: probe failed: %d\n", ret); return ret;
}
module_init(tq2440_key_init); static void __exit tq2440_key_exit(void)
{
platform_driver_unregister(&tq2440_key_driver);
}
module_exit(tq2440_key_exit); MODULE_LICENSE("GPL");
启动后,加载驱动,可以看看/proc/interrupts:
[root@tq2440 mnt]# cat /proc/interrupts
CPU0
: s3c-eint Edge eth0
: s3c Edge s3c2410-rtc tick
: s3c Edge samsung_time_irq
15: s3c2410-eint0_3 Edge key-
: s3c2410-eint0_3 Edge key-
: s3c2410-eint0_3 Edge key-
: s3c-eint Edge key-
: s3c-eint Edge key-
: s3c Edge ohci_hcd:usb1
: s3c Edge .i2c
: s3c Edge s3c2410-rtc alarm
: s3c-level Level .serial
: s3c-level Level .serial
: s3c-level Edge .watchdog
下面是加载驱动的时候时的log:
<7>[ 29.155953] tq2440_key_probe enter.
<7>[ 29.156100] tq2440_key_probe: get irq 15
<7>[ 29.156350] tq2440_key_probe: get irq 17
<7>[ 29.156546] tq2440_key_probe: gpio: 86 ---> irq (18)
<7>[ 29.156803] tq2440_key_probe: gpio: 88 ---> irq (19)
<7>[ 29.157061] tq2440_key_probe: gpio: 92 ---> irq (20)
按键的时候会看到下面的log:
<7>[ 350.161506] tq2440_key_isr enter, irq: 17, key-2
<7>[ 354.624168] tq2440_key_isr enter, irq: 18, key-3
<7>[ 355.301634] tq2440_key_isr enter, irq: 19, key-4
<7>[ 357.053889] tq2440_key_isr enter, irq: 15, key-1
<7>[ 368.231196] tq2440_key_isr enter, irq: 20, key-8
可以在中断处理函数中将调用栈打印出来:
EINT0_3中断对应的log:
<7>[ 483.595441] [<bf008044>] (tq2440_key_isr [interrupts_demo]) from [<c00447d8>] (__handle_irq_event_percpu+0x3c/0x130)
<7>[ 483.595481] [<c00447d8>] (__handle_irq_event_percpu) from [<c00448e8>] (handle_irq_event_percpu+0x1c/0x54)
<7>[ 483.595521] [<c00448e8>] (handle_irq_event_percpu) from [<c0044948>] (handle_irq_event+0x28/0x3c)
<7>[ 483.595558] [<c0044948>] (handle_irq_event) from [<c00476a8>] (handle_edge_irq+0xbc/0x190)
<7>[ 483.595586] [<c00476a8>] (handle_edge_irq) from [<c0043fd8>] (generic_handle_irq+0x2c/0x40)
<7>[ 483.595621] [<c0043fd8>] (generic_handle_irq) from [<c00441ac>] (__handle_domain_irq+0x6c/0xcc)
<7>[ 483.595653] [<c00441ac>] (__handle_domain_irq) from [<c0009444>] (s3c24xx_handle_irq+0x6c/0x12c)
<7>[ 483.595681] [<c0009444>] (s3c24xx_handle_irq) from [<c000e5fc>] (__irq_svc+0x5c/0x78)
EINT4:
<7>[ 594.735684] [<bf008044>] (tq2440_key_isr [interrupts_demo]) from [<c00447d8>] (__handle_irq_event_percpu+0x3c/0x130)
<7>[ 594.735725] [<c00447d8>] (__handle_irq_event_percpu) from [<c00448e8>] (handle_irq_event_percpu+0x1c/0x54)
<7>[ 594.735764] [<c00448e8>] (handle_irq_event_percpu) from [<c0044948>] (handle_irq_event+0x28/0x3c)
<7>[ 594.735801] [<c0044948>] (handle_irq_event) from [<c00476a8>] (handle_edge_irq+0xbc/0x190)
<7>[ 594.735832] [<c00476a8>] (handle_edge_irq) from [<c0043fd8>] (generic_handle_irq+0x2c/0x40)
<7>[ 594.735878] [<c0043fd8>] (generic_handle_irq) from [<c02490f4>] (s3c24xx_demux_eint4_7+0xa4/0x120)
<7>[ 594.735916] [<c02490f4>] (s3c24xx_demux_eint4_7) from [<c00441ac>] (__handle_domain_irq+0x6c/0xcc)
<7>[ 594.735946] [<c00441ac>] (__handle_domain_irq) from [<c0009444>] (s3c24xx_handle_irq+0x6c/0x12c)
<7>[ 594.735975] [<c0009444>] (s3c24xx_handle_irq) from [<c000e5fc>] (__irq_svc+0x5c/0x78)
EINT8:
<7>[ 652.506024] [<bf008044>] (tq2440_key_isr [interrupts_demo]) from [<c00447d8>] (__handle_irq_event_percpu+0x3c/0x130)
<7>[ 652.506065] [<c00447d8>] (__handle_irq_event_percpu) from [<c00448e8>] (handle_irq_event_percpu+0x1c/0x54)
<7>[ 652.506106] [<c00448e8>] (handle_irq_event_percpu) from [<c0044948>] (handle_irq_event+0x28/0x3c)
<7>[ 652.506142] [<c0044948>] (handle_irq_event) from [<c00476a8>] (handle_edge_irq+0xbc/0x190)
<7>[ 652.506171] [<c00476a8>] (handle_edge_irq) from [<c0043fd8>] (generic_handle_irq+0x2c/0x40)
<7>[ 652.506219] [<c0043fd8>] (generic_handle_irq) from [<c0249224>] (s3c24xx_demux_eint8_23+0xb4/0x130)
<7>[ 652.506258] [<c0249224>] (s3c24xx_demux_eint8_23) from [<c00441ac>] (__handle_domain_irq+0x6c/0xcc)
<7>[ 652.506287] [<c00441ac>] (__handle_domain_irq) from [<c0009444>] (s3c24xx_handle_irq+0x6c/0x12c)
<7>[ 652.506316] [<c0009444>] (s3c24xx_handle_irq) from [<c000e5fc>] (__irq_svc+0x5c/0x78)
完。
基于设备树的TQ2440的中断(2)的更多相关文章
- 基于设备树的TQ2440的中断(1)
作者 姓名:彭东林 E-mail:pengdonglin137@163.com QQ:405728433 平台 板子:TQ2440 内核:Linux-4.9 u-boot: 2015.04 工具链: ...
- 基于设备树的TQ2440触摸屏驱动移植
平台 开发板:tq2440 内核:Linux-4.9 u-boot:u-boot-2015.04 概述 之前移植了LCD驱动,下面继续移植触摸屏驱动,然后将tslib也移植上去. 正文 一.移植触 ...
- 基于设备树的TQ2440 DMA学习(3)—— DMA控制器驱动
作者 彭东林pengdonglin137@163.com 平台 TQ2440Linux-4.9 概述 上一篇直接操作DMA控制器实现了一个mem2mem的DMA传输,但是这样不符合linux driv ...
- 基于设备树的TQ2440 DMA学习(4)—— client驱动
作者 彭东林pengdonglin137@163.com 平台 TQ2440Linux-4.9 概述 前面分析了DMA控制器驱动,下面我们调用DMAENGINE的API写一个MEM2MEM的驱动 正文 ...
- 基于设备树的TQ2440 DMA学习(2)—— 简单的DMA传输
作者 彭东林 pengdonglin137@163.com 平台 TQ2440 Linux-4.9 概述 上一篇博客分析了DMA控制器的寄存器,循序渐进,下面我们直接操作DMA控制器的寄存器实 ...
- 基于设备树的TQ2440 DMA学习(1)—— 芯片手册
作者 彭东林pengdonglin137@163.com 平台 TQ2440内核Linux4.9 概述 一直想抽时间学习一下DMA驱动,今天就以S3C2440为例,这款芯片的DMA控制器足够简单,也比 ...
- 基于设备树的controller学习(2)
作者 彭东林 pengdonglin137@163.com 平台 TQ2440 Linux-4.10.17 概述 上一篇大概介绍了一下demo-controller的结构,下面结合驱动分析. 正文 ...
- 基于设备树的controller学习(1)
作者 彭东林pengdonglin137@163.com 平台 TQ2440Linux-4.10.17 概述 在设备树中我们经常见到诸如"#clock-cells"."# ...
- 基于设备树的led驱动程序
#include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include ...
随机推荐
- 【源码阅读】Mimikatz一键获取远程终端凭据与获取明文密码修改方法
1.前言 mimikatz框架是非常精妙的,粗浅讲一下修改的思路. 它的模块主要由各个结构体数组组成,根据传入的命令搜索执行相应命令的模块 mimikatz.c 部分代码: NTSTATUS mimi ...
- jquery.validate动态更改校验规则
有时候表单中有多个字段是相互关联的,以下遇到的就是证件类型和证件号码的关联,在下拉框中选择不同的证件类型,证件号码的值的格式都是不同的,这就需要动态的改变校验规则. 点击(此处)折叠或打开 <! ...
- reportng之测试报告升级美化
背景:偶然看到一个人的自动化框架的测试报告好漂亮,心痒痒,今天弄了一下午,还是不行,结果到现在就现在,我特么成功了,不为什么 Mark一下: 本地化修改 获取源码,修改reportng.propert ...
- PowerMockRunner和ActiveObjectsJUnitRunner
Jira的二次开发,需要作单元测试. 测试跟数据库连接的类,比如service类,需要在类上加@RunWith(ActiveObjectsJUnitRunner.class). 有时需要搭配mocki ...
- POJ 3281 Dining(最大流+拆点)
题目链接:http://poj.org/problem?id=3281 题目大意:农夫为他的 N (1 ≤ N ≤ 100) 牛准备了 F (1 ≤ F ≤ 100)种食物和 D (1 ≤ D ≤ 1 ...
- Android Studio一直 Fetching Documentation...
Android查看私有库android-spport-v4.jar & android-support-v7-appcompat.jar源码 https://www.cnblogs.com/s ...
- .NetCore 中扩展ExceptionLess 实现链式方法添加操作日志
在使用ExceptionLess添加日志的时候,发现还是有一些写法上的个人觉得不爽的地方,比如添加Info日志 ExceptionlessClient.Default.CreateLog(source ...
- 使用prometheus抓取k8s的metrics作监控时,cAdvisor和kubelet配置有何差别?
按网上说法: 目前cAdvisor集成到了kubelet组件内,可以在kubernetes集群中每个启动了kubelet的节点使用cAdvisor提供的metrics接口获取该节点所有容器相关的性能指 ...
- PHP函数之trigger_error
在程序开发中,如果我们编码不规范,比如调用不存在的变量.语法错误.少了个逗号,这些都会引起系统报错并进行提示,但是今天,突然发现PHP还有这样一个函数,用于自动触发一个报错提示,并且会将报错信息写入p ...
- 002.iSCSI服务端配置
一 iSCSI target的磁盘种类 大型文件 单一分区(partition) 磁盘 数组 RAID LVM 二 iSCSI创建步骤 建立用于共享的磁盘设备(分区/磁盘/文件) 创建后备磁盘 创建相 ...