[PATCH] ARM: Allow machine to specify it's own IRQ handlers at run-time
Eric Miao
eric.y.miao at gmail.com
Mon Dec 6 01:12:54 EST 2010
On Sun, Dec 5, 2010 at 5:23 PM, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Mon, Nov 22, 2010 at 04:26:50PM +0800, Eric Miao wrote:
>> I wonder if it's still acceptable for a patch like below to have a dynamic IRQ
>> handler at run-time. There is some changes to the irq_handler, esp. some
>> SMP changes.
>>
>> Magnus had some similar patches to have a run-time irq_handler, which is
>> a bit more complicated, but I'm also very happy with.
>
> I'd prefer a simple but efficient approach. I am worried about
> unnecessarily increasing the IRQ latency - and IRQ latency is something
> that we should be concerned about. It has the ability to make platforms
> useless.
>
> Eg, we know that SMC91x net interfaces are sensitive to IRQ latency, and
> the same is true of serial ports with small FIFOs.
>
> Any attempt to support multiple IRQ handlers is going to increase IRQ
> handling latency - I don't think that's something which can be avoided,
> and I'm wondering what effect this and the recent genirq changes is going
> to have. Has anyone been keeping an eye on IRQ handling latency?
>
> Lastly, this patch is dependent on your machine class patches, which makes
> it unsuitable as-is for mainline.
>
This one isn't. I've rebased this on top of v2.6.37-rc1.
>> commit d57e464929c9b2b50cda07e8683679583adf0fee
>> Author: Eric Miao <eric.y.miao at gmail.com>
>> Date: Mon Nov 22 16:13:51 2010 +0800
>>
>> ARM: Allow machine to specify it's own IRQ handlers at run-time
>>
>> Normally different ARM platform has different way to decode the IRQ
>> hardware status and demultiplex to the corresponding IRQ handler.
>> This is highly optimized by macro irq_handler in entry-armv.S, and
>> each machine class defines their own macro to decode the IRQ number.
>> However, this prevents multiple machine classes to be built into a
>> single kernel.
>>
>> By allowing each machine to specify thier own handler, and making
>> function pointer 'handle_arch_irq' to point to it at run time, this
>> can be solved. And introduce CONFIG_MULTI_IRQ_HANDLER to allow both
>> solutions to work.
>>
>> Comparing with the highly optimized macro of irq_handler, the new
>> function must be written with care not to lose too much performance.
>> And the IPI stuff on SMP is expected to move to the provided arch
>> IRQ handler as well.
>>
>> Signed-off-by: Eric Miao <eric.miao at canonical.com>
>> Acked-by: Nicolas Pitre <nicolas.pitre at linaro.org>
>>
>> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
>> index a19a526..c2c9838 100644
>> --- a/arch/arm/Kconfig
>> +++ b/arch/arm/Kconfig
>> @@ -1017,6 +1017,11 @@ config CPU_HAS_PMU
>> default y
>> bool
>>
>> +config MULTI_IRQ_HANDLER
>> + bool
>> + help
>> + Allow each machine to specify it's own IRQ handler at run time.
>> +
>> if !MMU
>> source "arch/arm/Kconfig-nommu"
>> endif
>> diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
>> index d97a964..7d55356 100644
>> --- a/arch/arm/include/asm/mach/arch.h
>> +++ b/arch/arm/include/asm/mach/arch.h
>> @@ -40,6 +40,9 @@ struct machine_desc {
>> void (*init_irq)(void);
>> struct sys_timer *timer; /* system tick timer */
>> void (*init_machine)(void);
>> +#ifdef CONFIG_MULTI_IRQ_HANDLER
>> + void (*handle_irq)(struct pt_regs *);
>> +#endif
>> };
>>
>> /*
>> diff --git a/arch/arm/include/asm/mach/irq.h b/arch/arm/include/asm/mach/irq.h
>> index ce3eee9..6ecdad9 100644
>> --- a/arch/arm/include/asm/mach/irq.h
>> +++ b/arch/arm/include/asm/mach/irq.h
>> @@ -22,6 +22,10 @@ extern void (*init_arch_irq)(void);
>> extern void init_FIQ(void);
>> extern int show_fiq_list(struct seq_file *, void *);
>>
>> +#ifdef CONFIG_MULTI_IRQ_HANDLER
>> +extern void (*handle_arch_irq)(struct pt_regs *);
>> +#endif
>> +
>> /*
>> * This is for easy migration, but should be changed in the source
>> */
>> diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
>> index c09e357..8ed4f7c 100644
>> --- a/arch/arm/kernel/entry-armv.S
>> +++ b/arch/arm/kernel/entry-armv.S
>> @@ -29,6 +29,7 @@
>> /*
>> * Interrupt handling. Preserves r7, r8, r9
>> */
>> +#ifndef CONFIG_MULTI_IRQ_HANDLER
>> .macro irq_handler
>> get_irqnr_preamble r5, lr
>> 1: get_irqnr_and_base r0, r6, r5, lr
>> @@ -62,6 +63,14 @@
>> #endif
>>
>> .endm
>> +#else
>> + .macro irq_handler
>> + ldr r4, =handle_arch_irq
>> + mov r0, sp
>> + mov lr, pc
>> + ldr pc, [r4]
>> + .endm
>> +#endif /* CONFIG_MULTI_IRQ_HANDLER */
>>
>> #ifdef CONFIG_KPROBES
>> .section .kprobes.text,"ax",%progbits
>> @@ -1245,3 +1254,9 @@ cr_alignment:
>> .space 4
>> cr_no_alignment:
>> .space 4
>> +
>> +#ifdef CONFIG_MULTI_IRQ_HANDLER
>> + .globl handle_arch_irq
>> +handle_arch_irq:
>> + .long 0
>> +#endif
>> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
>> index 336f14e..a834c6c 100644
>> --- a/arch/arm/kernel/setup.c
>> +++ b/arch/arm/kernel/setup.c
>> @@ -876,6 +876,12 @@ void __init setup_arch(char **cmdline_p)
>> system_timer = mdesc->timer;
>> init_machine = mdesc->init_machine;
>>
>> +#ifdef CONFIG_MULTI_IRQ_HANDLER
>> + handle_arch_irq = class ? class->handle_irq : NULL;
>> + if (!handle_arch_irq)
>> + panic("No machine class specific IRQ handler defined\n");
>> +#endif
>> +
>> #ifdef CONFIG_VT
>> #if defined(CONFIG_VGA_CONSOLE)
>> conswitchp = &vga_con;
>
More information about the linux-arm-kernel
mailing list