diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index fd0e21be5e4401c70259a5076260d7b805ba9c6d..47694865018c445cf47109ecedf0b10b32048474 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1022,6 +1022,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 d97a964207fa15693c011f88f27dc64f4c7c3f16..7d55356110d48264270b72362d915b7d4078c645 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 ce3eee9fe26cbb055cbea6ab0d5567af4964b29a..6ecdad9a5c42a4eb453ff086ec8f95e4edada8e0 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 35f3f20d6731892300d6417f08d4a14b869720d0..caa6c396ec78433733da3db0c9e47bdc623959ae 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -30,6 +30,14 @@ * Interrupt handling. Preserves r7, r8, r9 */ .macro irq_handler +#ifdef CONFIG_MULTI_IRQ_HANDLER + ldr r5, =handle_arch_irq + mov r0, sp + ldr r5, [r5] + adr lr, BSYM(9997f) + teq r5, #0 + movne pc, r5 +#endif get_irqnr_preamble r5, lr 1: get_irqnr_and_base r0, r6, r5, lr movne r1, sp @@ -58,9 +66,8 @@ adrne lr, BSYM(1b) bne do_local_timer #endif -9997: #endif - +9997: .endm #ifdef CONFIG_KPROBES @@ -1245,3 +1252,9 @@ cr_alignment: .space 4 cr_no_alignment: .space 4 + +#ifdef CONFIG_MULTI_IRQ_HANDLER + .globl handle_arch_irq +handle_arch_irq: + .space 4 +#endif diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 8075e592f902ff6f0def0546d85fe34783ae0b53..0826f36330c463f5bbe99c0065f58f903a7a833d 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -875,6 +875,9 @@ void __init setup_arch(char **cmdline_p) init_arch_irq = mdesc->init_irq; system_timer = mdesc->timer; init_machine = mdesc->init_machine; +#ifdef CONFIG_MULTI_IRQ_HANDLER + handle_arch_irq = mdesc->handle_irq; +#endif #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE)