什么是 linux 中的链式 irq,它们什么时候需要使用? [英] what is chained irq in linux, when are they need to used?
问题描述
什么是链式 IRQ?chained_irq_enter
和 chained_irq_exit
是做什么的,因为在中断发生后,IRQ 线被禁用,但是 chained_irq_enter
正在调用与屏蔽中断相关的函数.如果线路已经禁用为什么要屏蔽中断?
什么是链式 irq ?
如何在父(中断控制器)设备的 IRQ 处理程序中调用子设备的中断处理程序有两种方法.
链式中断:
- 链式"意味着这些中断只是函数调用链(例如,SoC 的 GPIO 模块中断处理程序正在从 GIC 中断处理程序中调用,就像函数调用一样)
generic_handle_irq()
用于中断链- 在父硬件 IRQ 处理程序内部调用子 IRQ 处理程序
- 您不能调用可能在链式(子)中断处理程序中休眠的函数,因为它们仍处于原子上下文(硬件中断)
- 这种方法通常用于 SoC 内部 GPIO 模块的驱动程序
嵌套中断
- 嵌套"意味着那些中断可以被另一个中断中断;但它们并不是真正的硬件 IRQ,而是线程 IRQ
handle_nested_irq()
用于创建嵌套中断- 子 IRQ 处理程序在由
handle_nested_irq()
函数创建的新线程 内被调用;我们需要它们在进程上下文中运行,以便我们可以调用休眠总线函数(如可能休眠的 I2C 函数) - 您可以调用可能在嵌套(子)中断处理程序中休眠的函数
- 这种方法通常用于外部芯片的驱动程序,例如 GPIO 扩展器,因为它们通常通过 I2C 总线连接到 SoC,并且 I2C 功能可能会休眠
谈到上面讨论的驱动程序:
irq-gic
驱动程序使用CHAINED GPIO irqchips
方法来处理具有多个 GIC 的系统;这个提交补充说功能gpio-omap
驱动程序(如上所述)使用GENERIC CHAINED GPIO irqchips
方法.请参阅此提交.它是从使用常规CHAINED GPIO irqchips
转换而来的,因此在实时内核上它将线程化 IRQ 处理程序,但在非 RT 内核上它将是硬 IRQ 处理程序- 'gpio-max732x' 驱动程序使用
NESTED THREADED GPIO irqchips
方法
chained_irq_enter
和 chained_irq_exit
做什么
这些函数实现了硬件中断流程控制,即通知中断控制器芯片何时屏蔽和取消屏蔽当前中断.
对于 FastEOI 中断控制器(最现代的方式):
chained_irq_enter()
什么都不做chained_irq_exit()
调用irq_eoi()
回调告诉中断控制器中断处理完成
对于具有屏蔽/取消屏蔽/确认功能的中断控制器
chained_irq_enter()
屏蔽当前中断,如果也设置了 ack 回调,则确认它chained_irq_exit()
取消屏蔽中断
<块引用>
因为中断产生后irq线被禁用,但是chained_irq_enter
正在调用与屏蔽中断相关的函数,如果该线已经被禁用,为什么要屏蔽中断?
IRQ 线路被禁用.但是我们还是需要在中断处理结束时写入EOI寄存器.或者为边缘级中断发送ACK.
这 解释了为什么在中断处理程序中禁用中断.
What is chained IRQ ? What does chained_irq_enter
and chained_irq_exit
do, because after an interrupt is arised the IRQ line is disabled, but chained_irq_enter
is calling functions related to masking interrupts. If the line is already disabled why to mask the interrupt ?
what is chained irq ?
There are two approaches how to call interrupt handlers for child devices in IRQ handler of parent (interrupt controller) device.
Chained interrupts:
- "chained" means that those interrupts are just chain of function calls (for example, SoC's GPIO module interrupt handler is being called from GIC interrupt handler, just as a function call)
generic_handle_irq()
is used for interrupts chaining- child IRQ handlers are being called inside of parent HW IRQ handler
- you can't call functions that may sleep in chained (child) interrupt handlers, because they are still in atomic context (HW interrupt)
- this approach is commonly used in drivers for SoC's internal GPIO modules
Nested interrupts
- "nested" means that those interrupts can be interrupted by another interrupt; but they are not really HW IRQs, but rather threaded IRQs
handle_nested_irq()
is used for creating nested interrupts- child IRQ handlers are being called inside of new thread created by
handle_nested_irq()
function; we need them to be run in process context, so that we can call sleeping bus functions (like I2C functions that may sleep) - you are able to call functions that may sleep inside of nested (child) interrupt handlers
- this approach is commonly used in drivers for external chips, like GPIO expanders, because they are usually connected to SoC via I2C bus, and I2C functions may sleep
Speaking of drivers discussed above:
irq-gic
driver usesCHAINED GPIO irqchips
approach for handling systems with multiple GICs; this commit adds that functionalitygpio-omap
driver (mentioned above) usesGENERIC CHAINED GPIO irqchips
approach. See this commit. It was converted from using regularCHAINED GPIO irqchips
so that on real-time kernel it will threaded IRQ handler, but on non-RT kernel it will be hard IRQ handler- 'gpio-max732x' driver uses
NESTED THREADED GPIO irqchips
approach
what does
chained_irq_enter
andchained_irq_exit
do
Those functions implement hardware interrupt flow control, i.e. notifying interrupt controller chip when to mask and unmask current interrupt.
For FastEOI interrupt controllers (most modern way):
chained_irq_enter()
do nothingchained_irq_exit()
callsirq_eoi()
callback to tell the interrupt controller that interrupt processing is finished
For interrupt controllers with mask/unmask/ack capabilities
chained_irq_enter()
masks current interrupt, and acknowledges it if ack callback is set as wellchained_irq_exit()
unmasks interrupt
because after an interrupt is arised the irq line is disabled, but
chained_irq_enter
is calling functions related to masking interrupts if the line is already disabled why to mask the interrupt ?
IRQ line is disabled. But we still need to write to EOI register in the end of interrupt processing. Or send ACK for edge-level interrupts.
This explains why interrupts are disabled in interrupt handler.
这篇关于什么是 linux 中的链式 irq,它们什么时候需要使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!