什么是链接irq在Linux中,他们什么时候需要使用?

什么是链接IRQ? chained_irq_enterchained_irq_exit做什么的,因为中断发生后,IRQ线被禁用,但chained_irq_enter正在调用与屏蔽中断相关的function。 如果该行已被禁用,为什么要屏蔽该中断?

什么是链接irq?

有两种方法可以在父(中断控制器)设备的IRQ处理程序中调用子设备的中断处理程序。

  1. 链式中断:

    • “链接”意味着这些中断只是函数调用的链接(例如SoC的GPIO模块中断处理程序正在从GIC中断处理程序中调用,就像函数调用一样)
    • generic_handle_irq()用于中断链接
    • 子IRQ处理程序在父HW RQ处理程序中被调用
    • 你不能调用可能睡在链式(子)中断处理程序中的函数,因为它们仍处于原子上下文 (HW中断)
    • 这种方法通常用于SoC内部GPIO模块的驱动程序
  2. 嵌套的中断

    • “嵌套”意味着这些中断可以被另一个中断中断; 但他们不是真正的硬件IRQ,而是线程化的IRQ
    • handle_nested_irq()用于创建嵌套的中断
    • handle_nested_irq() IRQ处理程序在由handle_nested_irq()函数创建的新线程中被调用; 我们需要它们在进程环境中运行,以便我们可以调用睡眠总线函数(如可能睡眠的I2C函数)
    • 您可以调用嵌套(子)中断处理程序中可能睡眠的函数
    • 这种方法通常用于外部芯片的驱动程序,如GPIO扩展器,因为它们通常通过I2C总线连接到SoC,I2C功能可能会睡眠

说到上面讨论的驱动程序:

  • irq-gic CHAINED GPIO irqchips驱动程序使用CHAINED GPIO irqchips方法处理具有多个GIC的系统; 这个提交添加了这个功能
  • gpio-omap驱动程序(如上所述)使用GENERIC CHAINED GPIO irqchips方法。 看到这个提交。 它从使用常规CHAINED GPIO irqchips转换,以便在实时内核它将线程IRQ处理程序,但在非RT内核它将是硬IRQ处理程序
  • 'gpio-max732x'驱动程序使用NESTED THREADED GPIO irqchips方法

chained_irq_enterchained_irq_exit做什么的

这些功能实现硬件中断流控制,即通知中断控制器芯片何时屏蔽和取消屏蔽当前中断。

  1. 对于FastEOI中断控制器(最现代的方式):

    • chained_irq_enter()什么都不做
    • chained_irq_exit()调用irq_eoi()回调告诉中断控制器中断处理完成
  2. 对于具有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(...);