For last few days i am studying a lot about linux chapter 10 book ldd3. I have some doubt please clarify them. Some are my analysis please suggest if they are wrong.
For ARM there is one interrupt vector table address for -- IRQ interrupt -- 0x00000018 Then a chip manufacturer can have a separate interrupt line for there hardware like USART, SPI, I2C, External Interrupt -- and multiplex them to a single IRQ line of ARM. and have registers (of their choice) to determine which one fired the interrupt.
Also if example there is an single interrupt line available for GPIO pin level change interrupt. As per below link's single interrupt lines can be shared by many handlers of different device drivers.
fiq & irq handler -- arm Usually the interrupt controller is a hardware unit that multiplexes many interrupt lines together, generating single line to the CPU. When an interrupt occurs, the controller asserts the IRQ line. The CPU stops executing and jumps through the IRQ vector (location varies) to the interrupt handler. The interrupt handlers reads a register on interrupt controller to determine the interrupt line and, invokes the correct interrupt handler and then clears the interrupt - allowing another to occur.
http://www.makelinux.net/ldd3/chp-10-sect-2 How to register an interrupt handler is described in this link.
https://unix.stackexchange.com/questions/47306/how-does-the-linux-kernel-handle-shared-irqs Linux calls all the intruppt handler for the same shared line.
My question is as an device driver programmer i am only calling .... request_irq().
Who is providing for the code of generic -- IRQ interrupt @0x00000018 address -- which is reading the vendor specific register to determine which interrupt line raised the IRQ. And then telling linux functionality -- to call all the shared interrupt handler's registered for that IRQ line ?
Is it GCC compiler startup code for chipset doing this work for us ?
The actual interrupt handling is set up by linux/arch/arm/kernel/entry-armv.S. There is then a long chain of code involved in decoding and running interrupt handlers.
The actual request_irq is generic code, which sets up a "descriptor", irq_desc, defined in linux/include/linux/irqdesc.h.
The actual handling of "which interrupt is which" is configured in the specific setup for the board. I'm giving an example of an omap2/omap3 board here (randomly chosen because I have worked with those boards, but not in Linux): linux/arch/arm/mach-omap2/irq.c
I hope this helps.
In entry-armv.S file, you can locate the code for filling IRQ line as folows:
/*
* Interrupt handling. Preserves r7, r8, r9
*/
.macro irq_handler
get_irqnr_preamble r5, lr
1: get_irqnr_and_base r0, r6, r5, lr
movne r1, sp
@
@ routine called with r0 = irq number, r1 = struct pt_regs *
@
adrne lr, BSYM(1b)
bne asm_do_IRQ
Macro get_irqnr_and_base
is suposed to be machine specific, and hence contained in file arch/arm/mach_/include/entry-macro.S.
You can see that this macro is implemented different way for differnet arm-based machines. So that's how identification of IRQ lines are done based on differnet HWs.
User contributions licensed under CC BY-SA 3.0