什么是链接IRQ? chained_irq_enter
和chained_irq_exit
做什么的,因为中断发生后,IRQ线被禁用,但chained_irq_enter
正在调用与屏蔽中断相关的function。 如果该行已被禁用,为什么要屏蔽该中断?
什么是链接irq?
有两种方法可以在父(中断控制器)设备的IRQ处理程序中调用子设备的中断处理程序。
链式中断:
generic_handle_irq()
用于中断链接 嵌套的中断
handle_nested_irq()
用于创建嵌套的中断 handle_nested_irq()
IRQ处理程序在由handle_nested_irq()
函数创建的新线程中被调用; 我们需要它们在进程环境中运行,以便我们可以调用睡眠总线函数(如可能睡眠的I2C函数) 说到上面讨论的驱动程序:
irq-gic
CHAINED GPIO irqchips
驱动程序使用CHAINED GPIO irqchips
方法处理具有多个GIC的系统; 这个提交添加了这个功能 gpio-omap
驱动程序(如上所述)使用GENERIC CHAINED GPIO irqchips
方法。 看到这个提交。 它从使用常规CHAINED GPIO irqchips
转换,以便在实时内核它将线程IRQ处理程序,但在非RT内核它将是硬IRQ处理程序 NESTED THREADED GPIO irqchips
方法
chained_irq_enter
和chained_irq_exit
做什么的
这些功能实现硬件中断流控制,即通知中断控制器芯片何时屏蔽和取消屏蔽当前中断。
对于FastEOI中断控制器(最现代的方式):
chained_irq_enter()
什么都不做 chained_irq_exit()
调用irq_eoi()
回调告诉中断控制器中断处理完成 对于具有mask / unmask / ack功能的中断控制器
chained_irq_enter()
屏蔽当前中断,并且如果ack回调被设置,则确认它 chained_irq_exit()
取消屏蔽中断 因为中断发生后,irq线被禁用,但是
chained_irq_enter
正在调用与屏蔽中断有关的函数,如果该行已被禁用,为什么要屏蔽中断?
IRQ线被禁用。 但是在中断处理结束后我们还是需要写入EOI寄存器。 或者针对边沿级中断发送ACK。
这就解释了为什么在中断处理程序中禁止中断。
阅读Linux内核文档以了解这些API:
https://www.kernel.org/doc/Documentation/gpio/driver.txt
CHAINED GPIO irqchips:这些通常是嵌入在SoC上的类型。 这意味着GPIO有一个快速的IRQ处理程序,可以从父IRQ处理程序(最典型的是系统中断控制器)中调用。 这意味着GPIO irqchip使用irq_set_chained_handler()或相应的gpiochip_set_chained_irqchip()辅助函数进行注册,并且在保持IRQ禁用的情况下,将立即从父irqchip调用GPIO irqchip处理程序。 然后,GPIO irqchip将在其中断处理程序中调用类似这样的序列:
static irqreturn_t tc3589x_gpio_irq(int irq, void *data) chained_irq_enter(...); generic_handle_irq(...); chained_irq_exit(...);