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.
Chained interrupts:
generic_handle_irq()
is used for interrupts chainingNested interrupts
handle_nested_irq()
is used for creating nested interruptshandle_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)Speaking of drivers discussed above:
irq-gic
driver uses CHAINED GPIO irqchips
approach for handling systems with multiple GICs; this commit adds that functionalitygpio-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 handlerNESTED THREADED GPIO irqchips
approachwhat does
chained_irq_enter
andchained_irq_exit
do
Those functions implement hardware interrupt flow control, i.e. notifying interrupt controller chip when to mask and unmask current interrupt.
For FastEOI interrupt controllers (most modern way):
chained_irq_enter()
do nothingchained_irq_exit()
calls irq_eoi()
callback to tell the interrupt controller that interrupt processing is finishedFor interrupt controllers with mask/unmask/ack capabilities
chained_irq_enter()
masks current interrupt, and acknowledges it if ack callback is set as wellchained_irq_exit()
unmasks interruptbecause 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.
Read Linux kernel documentation itself for understanding these APIs:
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(...);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With