linux中链接的irq是什么,什么时候需要使用



什么是链式IRQ?chained_irq_enterchained_irq_exit的作用是什么,因为在出现中断后,IRQ线被禁用,但chained_irq_enter正在调用与屏蔽中断相关的函数。如果线路已经被禁用,为什么要屏蔽中断?

什么是连锁irq?

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

  1. 链式中断:

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

    • "嵌套"意味着这些中断可以被另一个中断中断;但它们并不是真正的硬件IRQ,而是线程IRQ
    • handle_nested_irq()用于创建嵌套中断
    • handle_nested_irq()函数创建的新线程内部调用子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_enterchained_irq_exit做什么

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

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

    • chained_irq_enter()什么都不做
    • chained_irq_exit()调用irq_eoi()回调通知中断控制器中断处理完成
  2. 对于具有屏蔽/取消屏蔽/确认功能的中断控制器

    • 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 irq芯片:这些通常是嵌入在SoC。这意味着有一个用于GPIO的快速IRQ处理程序在链中从父IRQ处理程序调用,最典型的是系统中断控制器。这意味着GPIO irq芯片已注册使用irq_set_chained_handler()或相应的gpiochip_set_chained_irqchip()辅助函数和GPIO irqchip处理程序将立即从父irqchip调用,而保持IRQ被禁用。GPIO irq芯片将最终调用它的中断处理程序中有这样的序列:

    static irqreturn_t tc3589x_gpio_irq(int irq, void *data)
        chained_irq_enter(...);
        generic_handle_irq(...);
        chained_irq_exit(...);
    

最新更新