VIC 中断 与 gpio 中断 的硬件拓扑图描述
以下是 s3c6410a 的 irq 拓扑 描述, 着重凸显了 gpio irq
以下 每个颜色 的gpio 共享一个vic 的中断线, 共 5 个 中断线
-- -- -- -- -- -
注意 : 在linux 里面, 将每个 gpx 注册为了一个domain! ! !
pinctrl0: pinctrl@7f 008000 {
compatible = "samsung,s3c64xx-pinctrl" ;
reg = < 0x7f008000 0x1000 > ;
interrupt- parent = < & vic1> ;
interrupts = < 21 > ;
pctrl_int_map: pinctrl- interrupt- map {
interrupt- map = < 0 & vic0 0 > ,
< 1 & vic0 1 > ,
< 2 & vic1 0 > ,
< 3 & vic1 1 > ;
# address - cells = < 0 > ;
# size - cells = < 0 > ;
# interrupt - cells = < 1 > ;
} ;
wakeup- interrupt- controller {
compatible = "samsung,s3c64xx-wakeup-eint" ;
interrupts = < 0 > , < 1 > , < 2 > , < 3 > ;
interrupt- parent = < & pctrl_int_map> ;
} ;
} ;
linux cascaded irq domain
这个配置没有使用 Hierarchy IRQ domain , 即 CONFIG_IRQ_DOMAIN_HIERARCHY= n, 但是使用了级联中断
是怎么实现的呢?
在 gpio irq domain 初始化过程中 直接 做了 父domain ( vic) 中的 hwirq& irq 的申请.
并做好了对应的多合一的中断处理函数( 三星专用的)
如果实现了 CONFIG_IRQ_DOMAIN_HIERARCHY= y
则会在 使用gpio ( gpn3) 中断的模块驱动中, request_irq , 如果是第一个, 则 会 做了 父domain ( vic0) 中的 hwirq ( 1 ) & irq 的申请
并 设置 多合一( vic0 hwirq0) 的中断处理函数( 这应该是通用函数gpio_handle_irq_cascaded)
然后申请自己的中断处理函数( gpn3)
使用 irq_set_chained_handler_and_data ( d-> irq, s3c64xx_eint_gpio_irq, data) ; 和 父domain ( vic) 建立了联系
这个函数做了以下事情
1. 由vic 21 对应的 irq 申请了desc
2. 申请了中断处理函数 s3c64xx_eint_gpio_irq
3. 设置了中断处理函数 能够获取的数据 data
当中断发生时, 调用s3c64xx_eint_gpio_irq, 这个函数做以下事情
0. 知道是gpio domain 中哪个硬件中断号
1. 获取data中的domain
3. 利用 irq_linear_revmap 和 domain 和 硬件中断号 获取 软件中断号
4. 调用软件中断号对应的中断处理函数, 即该GPIO的中断处理函数
irq domain 初始化时
s3c64xx_eint_eint0_init
for ( i = 0 ; i < NUM_EINT0_IRQ; ++ i) {
irq = irq_of_parse_and_map ( eint0_np, i) ;
irq_set_chained_handler_and_data ( irq, s3c64xx_eint0_handlers[ i] , data) ;
}
for ( i = 0 ; i < d-> nr_banks; ++ i, ++ bank)
bank-> irq_domain = irq_domain_add_linear ( bank-> of_node, nr_eints, & s3c64xx_eint0_irqd_ops, ddata) ;
获取 IRQ number(软件中断号) 时
使用domain 映射号码
irq_create_mapping/ irq_create_mapping_affinity
virq = irq_find_mapping ( domain, hwirq) ;
virq = irq_domain_alloc_descs ( - 1 , 1 , hwirq, of_node_to_nid ( of_node) , affinity) ;
irq_domain_associate ( domain, virq, hwirq)
irq_set_chip_and_handler ( virq, & s3c64xx_eint0_irq_chip, handle_level_irq) ;
中断发生时
一旦发生硬件中断,经过CPU architecture相关的中断代码之后,会调用irq handler,该函数的一般过程如下:
(1 )首先找到root interrupt controller对应的irq domain。
(2 )根据HW 寄存器信息和irq domain信息获取HW interrupt ID
(3 )调用irq_find_mapping找到HW interrupt ID对应的irq number
(4 )调用handle_IRQ(对于ARM平台)来处理该irq number
按照当前 gpio 级联到 vic
假设 vic0 是 A, GPN0- 3 的domain 是 B
假设 GPN0 发生了中断
A. 1 首先找到root interrupt controller ( 在这里是vic) 对应的irq domain
A. 2 根据VIC HW 寄存器信息和irq domain信息获取HW interrupt ID
A. 3 调用irq_find_mapping找到HW interrupt ID ( 在这里是0 ) 对应的irq number
A. 4 调用irq domain B 注册 的 handler ( irq_set_chained_handler 设定的gpio_handle_irq_cascaded)
B. 1 gpio_handle_irq_cascaded找到gpio对应的irq domain
B. 2 根据GPIO HW 寄存器信息和irq domain信息获取HW interrupt ID
B. 3 调用irq_find_mapping找到HW interrupt ID对应的irq number
B. 4 调用 驱动 注册 的 handler ( request_irq 设定的)
如何调试
CONFIG_DYNAMIC_DEBUG= y
CONFIG_DEBUG_FS= y
CONFIG_GENERIC_IRQ_DEBUGFS= y
-- -- -- -- -- -- -- --
kernel/ irq/ Makefile
@@ - 1 , 5 + 1 , 6 @@
# SPDX- License- Identifier: GPL- 2.0
+ ccflags- y += - DDEBUG - DVERBOSE_DEBUG
# pwd
/ sys/ kernel/ debug/ irq
# ls
domains irqs
# ls - l
total 0
drwxr- xr- x 2 root root 0 Jan 1 00 : 00 domains
drwxr- xr- x 2 root root 0 Jan 1 00 : 00 irqs
以下的文件都可以读
. / domains:
: soc: interrupt- controller@71200000 : soc: pinctrl@7f 008000 : gph
: soc: interrupt- controller@71300000 : soc: pinctrl@7f 008000 : gpl
: soc: pinctrl@7f 008000 : gpa : soc: pinctrl@7f 008000 : gpm
: soc: pinctrl@7f 008000 : gpb : soc: pinctrl@7f 008000 : gpn
: soc: pinctrl@7f 008000 : gpc : soc: pinctrl@7f 008000 : gpo
: soc: pinctrl@7f 008000 : gpd : soc: pinctrl@7f 008000 : gpp
: soc: pinctrl@7f 008000 : gpf : soc: pinctrl@7f 008000 : gpq
: soc: pinctrl@7f 008000 : gpg default
. / irqs:
0 10 12 14 16 18 2 21 23 25 27 29 30 32 4 6 8
1 11 13 15 17 19 20 22 24 26 28 3 31 33 5 7 9
linux irq domain 实例
irq: Added domain : soc: interrupt- controller@71200000
irq: Added domain : soc: interrupt- controller@71300000
irq: Added domain : soc: pinctrl@7f 008000 : gpa
irq: Added domain : soc: pinctrl@7f 008000 : gpb
irq: Added domain : soc: pinctrl@7f 008000 : gpc
irq: Added domain : soc: pinctrl@7f 008000 : gpd
irq: Added domain : soc: pinctrl@7f 008000 : gpf
irq: Added domain : soc: pinctrl@7f 008000 : gpg
irq: Added domain : soc: pinctrl@7f 008000 : gph
irq: Added domain : soc: pinctrl@7f 008000 : gpo
irq: Added domain : soc: pinctrl@7f 008000 : gpp
irq: Added domain : soc: pinctrl@7f 008000 : gpq
irq: Added domain : soc: pinctrl@7f 008000 : gpl
irq: Added domain : soc: pinctrl@7f 008000 : gpm
irq: Added domain : soc: pinctrl@7f 008000 : gpn
irq: Added domain : soc: pinctrl@7f 008000 : gpn
irq: -> using domain @c0889d80
SUD File: kernel/ irq/ irqdomain. c, Line: 00557 : irq_domain_associate, domain: c0889d80, virq: 33 , hwirq: 7
SUD File: kernel/ irq/ irqdomain. c, Line: 00559 : irq_domain_associate, c024afa8
SUD File: kernel/ irq/ irqdomain. c, Line: 00499 : irq_domain_set_mapping, 7 , 16
irq: irq 7 on domain gpn mapped to virtual irq 33
VIC domain 与 gpio domain 的硬件拓扑语言描述
VIC 与 INT_EINTx 的关系
Int. No. Sources Description Group 53 INT_EINT4 External interrupt Group 1 ~ Group 9 VIC1 33 INT_EINT3 External interrupt Group 0 20 ~ 27 VIC1 32 INT_EINT2 External interrupt Group 0 12 ~ 19 VIC1 1 INT_EINT1 External interrupt Group 0 4 ~ 11 VIC0 0 INT_EINT0 External interrupt Group 0 0 ~ 3 VIC0
INT_EINTx 与 GPIO的关系
INT_EINT0
External interrupt Group 0 0 - 15 <= == > GPN0- GPN15
GPN0- 3 : 0
GPN4- 11 : 1
GPN12- 15 & GPL8- GPL11 : 32
External interrupt Group 0 16 - 22 <= == > GPL8- GPL14
GPL12- GPL14 & GPM0- GPM4 : 33
External interrupt Group 0 23 - 27 <= == > GPM0- GPM4
INT_EINT1
External interrupt Group 0 0 - 15 <= == > GPN0- GPN15
External interrupt Group 0 16 - 22 <= == > GPL8- GPL14
External interrupt Group 0 23 - 27 <= == > GPM0- GPM4
INT_EINT2
External interrupt Group 0 0 - 15 <= == > GPN0- GPN15
External interrupt Group 0 16 - 22 <= == > GPL8- GPL14
External interrupt Group 0 23 - 27 <= == > GPM0- GPM4
INT_EINT3
External interrupt Group 0 0 - 15 <= == > GPN0- GPN15
External interrupt Group 0 16 - 22 <= == > GPL8- GPL14
External interrupt Group 0 23 - 27 <= == > GPM0- GPM4
INT_EINT4
INT_EINT4 与 External interrupt Group1-9 的关系
External interrupt Group1
EINT1 0 - 7 <= == > GPA 0 - 7
EINT1 8 - 14 <= == > GPB 0 - 6
External interrupt Group2
EINT2 0 - 7 <= == > GPC 0 - 7
External interrupt Group3
EINT3 0 - 4 <= == > GPD 0 - 4
External interrupt Group4
EINT4 0 - 13 <= == > GPF 0 - 13
External interrupt Group5
EINT5 0 - 6 <= == > GPG 0 - 6
External interrupt Group6
EINT6 0 - 9 <= == > GPH 0 - 9
External interrupt Group7
EINT7 0 - 15 <= == > GPO 0 - 7
External interrupt Group8
EINT8 0 - 14 <= == > GPP 0 - 7
External interrupt Group9
EINT9 0 - 8 <= == > GPQ 0 - 8