什么是Linux中的链式中断,它们何时需要使用?

8

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


这是 此问题 的延续。 - Sam Protsenko
下一部分在这里 - Sam Protsenko
2个回答

11
什么是链接中断? 有两种方法可以在父级(中断控制器)设备的IRQ处理程序中调用子设备的中断处理程序。 1. 链式中断: - “链式”意味着这些中断只是一系列函数调用(例如,SoC的GPIO模块中断处理程序从GIC中断处理程序中被调用,就像一个函数调用) - 使用generic_handle_irq()进行中断链接 - 子IRQ处理程序在父HW IRQ处理程序内部被调用 - 无法在链式(子)中断处理程序中调用可能休眠的函数,因为它们仍处于原子上下文(HW中断)中 - 这种方法通常用于SoC内部GPIO模块的驱动程序中 2. 嵌套中断: - “嵌套”意味着这些中断可以被另一个中断打断;但它们并不是真正的HW IRQs,而是线程化的IRQs - 使用handle_nested_irq()创建嵌套中断 - 子IRQ处理程序在由handle_nested_irq()函数创建的新线程内部被调用;我们需要它们在进程上下文中运行,以便我们可以调用休眠总线函数(如可能休眠的I2C函数) - 可以在嵌套(子)中断处理程序中调用可能休眠的函数 - 这种方法通常用于外部芯片的驱动程序,例如GPIO扩展器,因为它们通常通过I2C总线连接到SoC,而I2C函数可能会休眠。 关于上述驱动程序: - 链式中断通常用于SoC内部GPIO模块的驱动程序 - 嵌套中断通常用于外部芯片的驱动程序,例如GPIO扩展器,因为它们通常通过I2C总线连接到SoC,而I2C函数可能会休眠。
  • irq-gic驱动程序使用CHAINED GPIO irqchips方法来处理具有多个GIC的系统; 这个提交增加了这个功能。
  • gpio-omap驱动程序(上述提到)使用GENERIC CHAINED GPIO irqchips方法。 请参见提交。 它从常规的CHAINED GPIO irqchips转换而来,因此在实时内核上,它将是线程化的IRQ处理程序,但在非实时内核上,它将是硬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()屏蔽当前中断,并在设置确认回调时确认它
      • chained_irq_exit()取消屏蔽中断
    3. 因为在中断产生后,irq线路被禁用,但是 "chained_irq_enter" 在调用与掩码中断相关的函数。如果线路已经被禁用,为什么还要屏蔽中断?
      IRQ线路被禁用。但我们仍然需要在中断处理结束时写入EOI寄存器。或者对于边缘级别中断发送ACK。
      这里解释了为什么在中断处理程序中禁用中断:This

    2

    阅读Linux内核文档,以理解这些API:

    https://www.kernel.org/doc/Documentation/gpio/driver.txt

    • CHAINED GPIO irqchips: these are usually the type that is embedded on an SoC. This means that there is a fast IRQ handler for the GPIOs that gets called in a chain from the parent IRQ handler, most typically the system interrupt controller. This means the GPIO irqchip is registered using irq_set_chained_handler() or the corresponding gpiochip_set_chained_irqchip() helper function, and the GPIO irqchip handler will be called immediately from the parent irqchip, while holding the IRQs disabled. The GPIO irqchip will then end up calling something like this sequence in its interrupt handler:

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

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接