Skip to content

Commit

Permalink
ARM: 6532/1: Allow machine to specify it's own IRQ handlers at run-time
Browse files Browse the repository at this point in the history
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 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.

The assembly code to invoke handle_arch_irq is optimized by Russell
King.

Signed-off-by: Eric Miao <eric.miao@canonical.com>
Acked-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
ericmiao authored and Russell King committed Dec 24, 2010
1 parent 4a50bfe commit 5210864
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 2 deletions.
5 changes: 5 additions & 0 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions arch/arm/include/asm/mach/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
};

/*
Expand Down
4 changes: 4 additions & 0 deletions arch/arm/include/asm/mach/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
17 changes: 15 additions & 2 deletions arch/arm/kernel/entry-armv.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -58,9 +66,8 @@
adrne lr, BSYM(1b)
bne do_local_timer
#endif
9997:
#endif

9997:
.endm

#ifdef CONFIG_KPROBES
Expand Down Expand Up @@ -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
3 changes: 3 additions & 0 deletions arch/arm/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 5210864

Please sign in to comment.