diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2006-04-03 17:56:36 +0100 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2006-04-19 04:14:21 +0200 |
commit | e4ac58afdfac792c0583af30dbd9eae53e24c78b (patch) | |
tree | 7517bef2c515fc630e4d3d238867b91cde96f558 /arch/mips/sgi-ip32 | |
parent | d35d473c25d43d7db3e5e18b66d558d2a631cca8 (diff) | |
download | op-kernel-dev-e4ac58afdfac792c0583af30dbd9eae53e24c78b.zip op-kernel-dev-e4ac58afdfac792c0583af30dbd9eae53e24c78b.tar.gz |
[MIPS] Rewrite all the assembler interrupt handlers to C.
Saves like 1,600 lines of code, is way easier to debug, compilers
frequently do a better job than the cut and paste type of handlers many
boards had. And finally having all the stuff done in a single place
also means alot of bug potencial for the MT ASE is gone.
The only surviving handler in assembler is the DECstation one; I hope
Maciej will rewrite it.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/sgi-ip32')
-rw-r--r-- | arch/mips/sgi-ip32/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/sgi-ip32/ip32-irq-glue.S | 86 | ||||
-rw-r--r-- | arch/mips/sgi-ip32/ip32-irq.c | 33 |
3 files changed, 25 insertions, 96 deletions
diff --git a/arch/mips/sgi-ip32/Makefile b/arch/mips/sgi-ip32/Makefile index 470898f..530bf84 100644 --- a/arch/mips/sgi-ip32/Makefile +++ b/arch/mips/sgi-ip32/Makefile @@ -3,7 +3,7 @@ # under Linux. # -obj-y += ip32-berr.o ip32-irq.o ip32-irq-glue.o ip32-setup.o ip32-reset.o \ +obj-y += ip32-berr.o ip32-irq.o ip32-setup.o ip32-reset.o \ crime.o ip32-memory.o EXTRA_AFLAGS := $(CFLAGS) diff --git a/arch/mips/sgi-ip32/ip32-irq-glue.S b/arch/mips/sgi-ip32/ip32-irq-glue.S deleted file mode 100644 index 200924e..0000000 --- a/arch/mips/sgi-ip32/ip32-irq-glue.S +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Low level interrupt handler for the SGI O2 aka IP32 aka Moosehead - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000 Harald Koerfgen - * Copyright (C) 2001 Keith M Wesolowski - */ -#include <asm/asm.h> -#include <asm/regdef.h> -#include <asm/mipsregs.h> -#include <asm/stackframe.h> -#include <asm/addrspace.h> - - .text - .set noreorder - .set noat - .align 5 - NESTED(ip32_handle_int, PT_SIZE, ra) - .set noat - SAVE_ALL - CLI # TEST: interrupts should be off - .set at - .set noreorder - - mfc0 s0,CP0_CAUSE - - andi t1, s0, IE_IRQ0 - bnez t1, handle_irq0 - andi t1, s0, IE_IRQ1 - bnez t1, handle_irq1 - andi t1, s0, IE_IRQ2 - bnez t1, handle_irq2 - andi t1, s0, IE_IRQ3 - bnez t1, handle_irq3 - andi t1, s0, IE_IRQ4 - bnez t1, handle_irq4 - andi t1, s0, IE_IRQ5 - bnez t1, handle_irq5 - nop - - /* Either someone has triggered the "software interrupts" - * or we lost an interrupt somehow. Ignore it. - */ - j ret_from_irq - nop - -handle_irq0: - jal ip32_irq0 - move a0, sp - j ret_from_irq - nop - -handle_irq1: - jal ip32_irq1 - move a0, sp - j ret_from_irq - nop - -handle_irq2: - jal ip32_irq2 - move a0, sp - j ret_from_irq - nop - -handle_irq3: - jal ip32_irq3 - move a0, sp - j ret_from_irq - nop - -handle_irq4: - jal ip32_irq4 - move a0, sp - j ret_from_irq - nop - -handle_irq5: - jal ip32_irq5 - move a0, sp - j ret_from_irq - nop - - END(ip32_handle_int) diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index 2eb22d69..22a6df9 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c @@ -130,8 +130,6 @@ struct irqaction memerr_irq = { crime_memerr_intr, SA_INTERRUPT, struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT, CPU_MASK_NONE, "CRIME CPU error", NULL, NULL }; -extern void ip32_handle_int(void); - /* * For interrupts wired from a single device to the CPU. Only the clock * uses this it seems, which is IRQ 0 and IP7. @@ -503,7 +501,7 @@ static void ip32_unknown_interrupt(struct pt_regs *regs) /* CRIME 1.1 appears to deliver all interrupts to this one pin. */ /* change this to loop over all edge-triggered irqs, exception masked out ones */ -void ip32_irq0(struct pt_regs *regs) +static void ip32_irq0(struct pt_regs *regs) { uint64_t crime_int; int irq = 0; @@ -520,31 +518,49 @@ void ip32_irq0(struct pt_regs *regs) do_IRQ(irq, regs); } -void ip32_irq1(struct pt_regs *regs) +static void ip32_irq1(struct pt_regs *regs) { ip32_unknown_interrupt(regs); } -void ip32_irq2(struct pt_regs *regs) +static void ip32_irq2(struct pt_regs *regs) { ip32_unknown_interrupt(regs); } -void ip32_irq3(struct pt_regs *regs) +static void ip32_irq3(struct pt_regs *regs) { ip32_unknown_interrupt(regs); } -void ip32_irq4(struct pt_regs *regs) +static void ip32_irq4(struct pt_regs *regs) { ip32_unknown_interrupt(regs); } -void ip32_irq5(struct pt_regs *regs) +static void ip32_irq5(struct pt_regs *regs) { ll_timer_interrupt(IP32_R4K_TIMER_IRQ, regs); } +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) +{ + unsigned int pending = read_c0_cause(); + + if (likely(pending & IE_IRQ0)) + ip32_irq0(regs); + else if (unlikely(pending & IE_IRQ1)) + ip32_irq1(regs); + else if (unlikely(pending & IE_IRQ2)) + ip32_irq2(regs); + else if (unlikely(pending & IE_IRQ3)) + ip32_irq3(regs); + else if (unlikely(pending & IE_IRQ4)) + ip32_irq4(regs); + else if (likely(pending & IE_IRQ5)) + ip32_irq5(regs); +} + void __init arch_init_irq(void) { unsigned int irq; @@ -556,7 +572,6 @@ void __init arch_init_irq(void) crime->soft_int = 0; mace->perif.ctrl.istat = 0; mace->perif.ctrl.imask = 0; - set_except_vector(0, ip32_handle_int); for (irq = 0; irq <= IP32_IRQ_MAX; irq++) { hw_irq_controller *controller; |