Exynos4412的外部中断是如何安排的?
作者
平台
概述
正文



res = platform_get_resource(pdev, IORESOURCE_IRQ, );
if (res)
drvdata->irq = res->start;
ret = devm_request_irq(dev, d->irq, exynos_eint_gpio_irq,
, dev_name(dev), d);
也就是当GIC上的SPI-47这个中断被触发后,中断处理函数exynos_eint_gpio_irq会被调用。
bank = d->pin_banks;
for (i = ; i < d->nr_banks; ++i, ++bank) {
if (bank->eint_type != EINT_TYPE_GPIO)
continue; bank->irq_domain = irq_domain_add_linear(bank->of_node,
bank->nr_pins, &exynos_eint_irqd_ops, bank); bank->irq_chip = &exynos_gpio_irq_chip;
}
也就是图3中的每一组GPIO都可以是一个中断控制器,bank->nr_pins是该组GPIO有几个引脚,每一个引脚对应一个中断,所以也就表示该irq_domain可以最大支持的中断个数。第9行设置了irq_chip,用户控制每一个引脚中断的打开、关闭、清除等。
static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
{
struct samsung_pinctrl_drv_data *d = data;
struct samsung_pin_bank *bank = d->pin_banks;
unsigned int svc, group, pin, virq; svc = readl(d->virt_base + EXYNOS_SVC_OFFSET);
group = EXYNOS_SVC_GROUP(svc);
pin = svc & EXYNOS_SVC_NUM_MASK; if (!group)
return IRQ_HANDLED;
bank += (group - ); virq = irq_linear_revmap(bank->irq_domain, pin);
if (!virq)
return IRQ_NONE;
generic_handle_irq(virq);
return IRQ_HANDLED;
}
第7行的宏EXYNOS_SVC_OFFSET是0xB08,这个需要结合Exynos4412的用户手册看:




for (i = ; i < d->nr_banks; ++i, ++bank) {
if (bank->eint_type != EINT_TYPE_WKUP)
continue; bank->irq_domain = irq_domain_add_linear(bank->of_node,
bank->nr_pins, &exynos_eint_irqd_ops, bank); bank->irq_chip = irq_chip; if (!of_find_property(bank->of_node, "interrupts", NULL)) {
bank->eint_type = EINT_TYPE_WKUP_MUX;
++muxed_banks;
continue;
} weint_data = devm_kzalloc(dev, bank->nr_pins
* sizeof(*weint_data), GFP_KERNEL); for (idx = ; idx < bank->nr_pins; ++idx) {
irq = irq_of_parse_and_map(bank->of_node, idx); weint_data[idx].irq = idx;
weint_data[idx].bank = bank;
irq_set_chained_handler_and_data(irq,
exynos_irq_eint0_15,
&weint_data[idx]);
}
}
在设备树中GPX0和GPX1设置interupts属性,而GPX2和GPX3没有。所以执行完上面的逻辑,muxed_banks为2,就是GPX2和GPX3,而其bank->eint_type被设置为了EINT_TYPE_WKUP_MUX。
static void exynos_irq_eint0_15(struct irq_desc *desc)
{
struct exynos_weint_data *eintd = irq_desc_get_handler_data(desc);
struct samsung_pin_bank *bank = eintd->bank;
struct irq_chip *chip = irq_desc_get_chip(desc);
int eint_irq; chained_irq_enter(chip, desc); eint_irq = irq_linear_revmap(bank->irq_domain, eintd->irq);
generic_handle_irq(eint_irq); chained_irq_exit(chip, desc);
}
irq = irq_of_parse_and_map(wkup_np, ); muxed_data = devm_kzalloc(dev, sizeof(*muxed_data)
+ muxed_banks*sizeof(struct samsung_pin_bank *), GFP_KERNEL); irq_set_chained_handler_and_data(irq, exynos_irq_demux_eint16_31,
muxed_data); bank = d->pin_banks;
idx = ;
for (i = ; i < d->nr_banks; ++i, ++bank) {
if (bank->eint_type != EINT_TYPE_WKUP_MUX)
continue; muxed_data->banks[idx++] = bank;
}
muxed_data->nr_banks = muxed_banks;
第1行解析设备树里"wakeup-interrupt-controller"节点的interrupts属性,映射获得对应的virq
第6行设置级联
static void exynos_irq_demux_eint16_31(struct irq_desc *desc)
{
struct irq_chip *chip = irq_desc_get_chip(desc);
struct exynos_muxed_weint_data *eintd = irq_desc_get_handler_data(desc);
struct samsung_pinctrl_drv_data *d = eintd->banks[]->drvdata;
unsigned long pend;
unsigned long mask;
int i; chained_irq_enter(chip, desc); for (i = ; i < eintd->nr_banks; ++i) {
struct samsung_pin_bank *b = eintd->banks[i];
pend = readl(d->virt_base + b->irq_chip->eint_pend
+ b->eint_offset);
mask = readl(d->virt_base + b->irq_chip->eint_mask
+ b->eint_offset);
exynos_irq_demux_eint(pend & ~mask, b->irq_domain);
} chained_irq_exit(chip, desc);
}
第12行的for循环依次处理GPX2和GPX3,主要就是看是不是有那个引脚的中断处于pengding中,如果有的话,函数exynos_irq_demux_eint会进行处理。
static inline void exynos_irq_demux_eint(unsigned long pend,
struct irq_domain *domain)
{
unsigned int irq; while (pend) {
irq = fls(pend) - ;
generic_handle_irq(irq_find_mapping(domain, irq));
pend &= ~( << irq);
}
}

static void __init combiner_init(void __iomem *combiner_base,
struct device_node *np)
{
int i, irq;
unsigned int nr_irq; nr_irq = max_nr * IRQ_IN_COMBINER; combiner_data = kcalloc(max_nr, sizeof (*combiner_data), GFP_KERNEL); combiner_irq_domain = irq_domain_add_linear(np, nr_irq,
&combiner_irq_domain_ops, combiner_data); for (i = ; i < max_nr; i++) {
irq = irq_of_parse_and_map(np, i); combiner_init_one(&combiner_data[i], i,
combiner_base + (i >> ) * 0x10, irq);
combiner_cascade_irq(&combiner_data[i], irq);
}
}
第15行解析interrupt combiner节点的interrupts属性,获得对应的virq
第19行设置级联
Exynos4412的外部中断是如何安排的?的更多相关文章
- 单片微机原理P2:80C51外部中断与定时器系统
0. 外部中断 书上的废话当然是很多的了,对于中断我想大家应该早就有一个很直观的认识,就是"设置断点,执行外部外码,然后返回断点"这样的三个过程.中断给系统提供了一个良好的响应模式 ...
- STM32f103之外部中断
一.背景 有个需求,IO口检测上升沿,然后做相应的动作.在此记录STM32F103的外部中断结构及配置方法, 以备下次快速上手使用. 有许多不太明白,又是老司机(:-D)帮忙,真的是站在别人的肩膀上会 ...
- STM32之EXTI——外部中断
互联网的广大网友,大家早上中午晚上好.EXTI...故名思义..EX表外,出..I表示Intrrupt..所以合起来就是外部中断...说到这..我觉得我最近的六级水平(背单词)又进了一步,稍微自夸了下 ...
- 转别人的 STM32外部中断使用注意事项
前言:这些问题都是我之前在工作中遇到的,后来觉得需要总结,自己记忆不好,所以在这个给自己打个mark. 一:触发方式 STM32 的外部中断是通过边沿来触发的,不支持电平触发: 二:外部中断分组 ST ...
- STM32外部中断初理解
PA0,PB0...PG0--->EXTI0 PA1,PB1...PG1--->EXTI1 ....... PA15,PB15...PG15--->EXTI15 以上为GPIO和中断 ...
- STM32——外部中断EXIT实现
外部中断实现步骤: 一.初始化,包括:1.AFIO时钟中断和GPIO时钟使能: 2.GPIO初始化 ...
- STM32 GPIO外部中断总结
一.STM32中断分组: STM32 的每一个GPIO都能配置成一个外部中断触发源,这点也是 STM32 的强大之处.STM32 通过根据引脚的序号不同将众多中断触发源分成不同的组,比如:PA0,PB ...
- 向linux内核中添加外部中断驱动模块
本文主要介绍外部中断驱动模块的编写,包括:1.linux模块的框架及混杂设备的注册.卸载.操作函数集.2.中断的申请及释放.3.等待队列的使用.4.工作队列的使用.5.定时器的使用.6.向linux内 ...
- STM32学习笔记(九) 外部中断,待机模式和事件唤醒
学会知识只需要不段的积累和提高,但是如何将知识系统的讲解出来就需要深入的认知和系统的了解.外部中断和事件学习难度并不高,不过涉及到STM32的电源控制部分,还是值得认真了解的,在本文中我将以实际代码为 ...
随机推荐
- android 通用 Intent
通用 Intent 本文内容显示详细信息 闹钟 日历 相机 联系人/人员应用 电子邮件 文件存储 本地操作 地图 音乐或视频 新笔记 电话 搜索 设置 发送短信 网络浏览器 使用 Android 调试 ...
- 1.网站应用程序 - 《APS.NET本质论》
1.1.HTTP协议 浏览器与WEB服务器的协议是应用层协议,当前遵循HTTP/1.1,HTTP协议是无状态的协议 客户机与服务器通过请求和响应完成一次会话(Session),每次会话中,双方发送的数 ...
- T-SQL语句2
一.修改表 1.alter table 语句 alter table database_name,table_name,column_name,type_name//database_name指数据库 ...
- synchronized和lock
Synchronized 同步代码块 使用 monitorenter 和 moniterexit 指令实现, monitorenter指令插入到同步代码块的开始位置, moniterexit 指令插 ...
- 一份可以发布jar包到MAVEN中央仓库的POM
[2017-01-03 更新]将基础的pom抽离成一个项目无关的parent pom,euler-framework的pom继承这个parent pom 今天在家折腾了一下怎么把Jar包发布到Mave ...
- fstab文件详解
挂载分区的位置 挂载点 分区格式 设置 备份自检 UUID=94e4e... / ext4 defaults,barrier=0 1 1 tmpfs /dev/shm tmpfs defaults 0 ...
- 用python实现一个无界面的2048
转载请注明出处http://www.cnblogs.com/Wxtrkbc/p/5519453.html 以前游戏2048火的时候,正好用其他的语言编写了一个,现在学习python,正好想起来,便决定 ...
- 001.etcd简介及单节点使用
一 etcd简介 1.1 概述 etcd 是 CoreOS 团队发起的开源项目,是一个管理配置信息和服务发现(service discovery)的项目,它的目标是构建一个高可用的分布式键值(key- ...
- css细节:尖角处理
在各种网站里面,我们会经常看到类似于这样的尖角:(示例:新浪微博) 它实现的方式有多种,哪种才是最简单的?哪种才是最优秀的?首先我声明一下,我还不清楚这个东西具体叫什么名字(哪位知道还望告知),暂且叫 ...
- Xtreme8.0 - Play with GCD dp
Play with GCD 题目连接: https://www.hackerrank.com/contests/ieeextreme-challenges/challenges/play-with-g ...