什么是 linux 中的链式 irq,它们什么时候需要使用? [英] what is chained irq in linux, when are they need to used?

查看:30
本文介绍了什么是 linux 中的链式 irq,它们什么时候需要使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

解决方案

什么是链式 irq ?

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

  1. 链式中断:

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

    • 嵌套"意味着那些中断可以被另一个中断中断;但它们并不是真正的硬件 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_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.

解释了为什么在中断处理程序中禁用中断.

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.

  1. 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
  2. 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 uses CHAINED GPIO irqchips approach for handling systems with multiple GICs; this commit adds that functionality
  • gpio-omap driver (mentioned above) uses GENERIC CHAINED GPIO irqchips approach. See this commit. It was converted from using regular CHAINED 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 and chained_irq_exit do

Those functions implement hardware interrupt flow control, i.e. notifying interrupt controller chip when to mask and unmask current interrupt.

  1. For FastEOI interrupt controllers (most modern way):

    • chained_irq_enter() do nothing
    • chained_irq_exit() calls irq_eoi() callback to tell the interrupt controller that interrupt processing is finished
  2. For interrupt controllers with mask/unmask/ack capabilities

    • chained_irq_enter() masks current interrupt, and acknowledges it if ack callback is set as well
    • chained_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆