What is the irq chain in linux when should they be used?

What is an IRQ chain? What do chained_irq_enter and chained_irq_exit , because after interruption, the IRQ line is disabled, but chained_irq_enter calls the functions associated with masking interruptions. If the row is already disabled, why mask the interrupt?

+6
source share
2 answers

what is irq encoded?

There are two ways to call interrupt handlers for child devices in the parent's IRQ handler (interrupt controller).

  • Associated Interrupts:

    • a โ€œhairpinโ€ means that these interrupts are just chains of function calls (for example, the GPIO SoC module interrupt handler is called from the GIC interrupt handler, like a function call)
    • generic_handle_irq() used for interrupt chains
    • child IRQ handlers are called inside the parent HW IRQ handler
    • you cannot call functions that can sleep in chain (child) interrupt handlers because they are still in the atomic context (HW interrupt)
    • this approach is commonly used in drivers for internal GPIO SoC modules.
  • Nested Interrupts

    • "nested" means that these interrupts can be interrupted by another interrupt; but they are not really HW IRQs, but rather streamed IRQs
    • handle_nested_irq() used to create nested interrupts
    • child IRQ handlers are called inside the new thread created by the handle_nested_irq() function; we need them to run in the context of the process so that we can call the sleeping bus functions (for example, I2C functions that can sleep)
    • you can call functions that can sleep inside nested (child) interrupt handlers
    • This approach is commonly used in external chip drivers, such as GPIO extenders, as they usually connect to the SoC via the I2C bus, and I2C functions can sleep

Speaking of the drivers mentioned above:

  • Driver
  • irq-gic uses the CHAINED GPIO irqchips to process systems with multiple GICs; this commit adds driver functionality
  • gpio-omap (mentioned above) uses the GENERIC CHAINED GPIO irqchips . See this commit. It was converted from the usual CHAINED GPIO irqchips , so in the real-time kernel it will process the IRQ processor, but on the non-RT core it will be a difficult IRQ processor
  • "gpio-max732x" uses the NESTED THREADED GPIO irqchips

what does chained_irq_enter and chained_irq_exit do

These functions implement hardware interrupt flow control, that is, notify the interrupt controller chip when they mask and expose the current interrupt.

  • For FastEOI interrupt controllers (the most modern way):

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

    • chained_irq_enter() masks the current interrupt and confirms it if callback call is also set
    • chained_irq_exit() interrupt interrupt

because after the interruption, the irq line appears, but chained_irq_enter calls the functions related to masking interrupts, if the line is already disconnected, why mask the interrupt?

IRQ string is disabled. But at the end of interrupt processing, we still need to write to the EOI register. Or send an ACK for edge level interrupts.

This explains why interrupts are disabled in the interrupt handler.

+7
source

Check out the Linux kernel documentation itself to understand these APIs:

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

  • CHAINED GPIO irqchips: This is usually the type that is built into SoC. This means that for GPIO there is a fast IRQ handler that receives a call in the chain from the parent IRQ handler, most typically a system interrupt. This means that the GPIO irqchip is registered using irq_set_chained_handler () or the corresponding gpiochip_set_chained_irqchip (), as well as the GPIO irqchip handler, will be called immediately from the parent irqchip, while IRQ hold is disabled. Then GPIO irqchip will eventually call something like this sequence in the interrupt handler:

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

All Articles