2014/09/09

Linux Interrupt on ARM

Question:
How interrupt information get initialized?

Answers:
Usually, in place like arch/arm/mach-xxx/some_file.c, resource of tyep IORESOURCE_IRQ is defined and get registered by calling platform_device_register(struct platform_device).
platform_device.name is used to map device and  device driver.

Device driver registration by usually happens when device module is loaded, by calling platform_driver_register(struct platform_driver).
platform_driver.driver.name is used map the device and device driver.



Question:
How driver register interrupt handler?

Answer:
In implementation of function platform_driver.probe(),
irq = platform_get_irq(plat_dev, num) // get an IRQ for a device
request_irq(irq, my_driver_irq_handler, IRQF_TRIGGER_RISING, ... )

Then my_driver_irq_handler() will be called when irq with index "num" is raised.



Question:
ARM CPU has only one IRQ input pin, how could it find out which peripheral raised the interrupt?
How driver interrupt handler get called?

Answer:
The Interrupt could be handled in two ways, call stack below:

1. CONFIG_MULTI_IRQ_HANDLER on
/* Macro in entry-armV.S */
irq_handler
/* This is a function pointer set by set_handle_irq, usually it got set during platform initialization, ex, like in function s3c2410_init_irq(), the pointer points to s3c24xx_handle_irq().
The pointer could also be set in setup_arch(), /arch/arm/kernel/setup.c, as mdesc->handle_irq.
mdesc->handle_irq is initialized in macro MACHINE_START, MACHINE_END,
mdesc->handle_irq could be set as gic_handle_irq(). */
handle_arch_irq
/* Here finds the actually irq number!!! */
s3c24xx_handle_irq
handle_IRQ
/* the kernel irq API, which will invoke actually irq handler. */
generic_handle_irq

2. CONFIG_MULTI_IRQ_HANDLER off
/* Macro in entry-armV.S */
irq_handler
/* get_irqnr_and_base() is called, which is a platform specific macro to query irq controller to find out which irq line is raised. */
arch_irq_handler_default
asm_do_IRQ
handle_IRQ
/* the kernel irq API, which will invoke actually irq handler. */
generic_handle_irq



Question:
When ARM's GIC ( General Interrupt Controller) hardware is used, how IRQ number is retrieved?

Answer:
In file arch/arm/common/gic.c, function gic_handle_irq() reads the interrupt controller's CPU interface register ICCIAR ( interrupt acknowledge register ) to get the IRQ number.  The register has 0x08 offset relative to "CPU interface base address".
Code:
irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK);
Reference:
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ihi0048b/index.html


Reference:
http://lxr.free-electrons.com/source/Documentation/blockdev/mflash.txt
http://pankaj-techstuff.blogspot.jp/2007/11/story-interrupt-handling-in-linux-2611.html
http://hi.baidu.com/sun_yfs/blog/item/e2531ecbf2cde989c9176806.html
http://lxr.linux.no/#linux+v2.6.32.59/drivers/video/s3c2410fb.c
http://lxr.linux.no/#linux+v2.6.32.59/arch/arm/plat-s3c24xx/irq.c
http://code.metager.de/source/xref/denx/u-boot/doc/README.SPL
http://code.metager.de/source/xref/denx/u-boot/doc/README.arm-relocation

No comments:

Post a Comment

Post Code on Blogger

Simplest way to post code to blogger for me: <pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black;overflow-x:...