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/sni | |
parent | d35d473c25d43d7db3e5e18b66d558d2a631cca8 (diff) | |
download | linux-e4ac58afdfac792c0583af30dbd9eae53e24c78b.tar.gz linux-e4ac58afdfac792c0583af30dbd9eae53e24c78b.tar.bz2 linux-e4ac58afdfac792c0583af30dbd9eae53e24c78b.zip |
[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/sni')
-rw-r--r-- | arch/mips/sni/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/sni/int-handler.S | 106 | ||||
-rw-r--r-- | arch/mips/sni/irq.c | 37 |
3 files changed, 28 insertions, 117 deletions
diff --git a/arch/mips/sni/Makefile b/arch/mips/sni/Makefile index 1e5676e4be86..9c7eaa5fb210 100644 --- a/arch/mips/sni/Makefile +++ b/arch/mips/sni/Makefile @@ -2,6 +2,6 @@ # Makefile for the SNI specific part of the kernel # -obj-y += int-handler.o irq.o pcimt_scache.o reset.o setup.o +obj-y += irq.o pcimt_scache.o reset.o setup.o EXTRA_AFLAGS := $(CFLAGS) diff --git a/arch/mips/sni/int-handler.S b/arch/mips/sni/int-handler.S deleted file mode 100644 index 2cdc09f55f18..000000000000 --- a/arch/mips/sni/int-handler.S +++ /dev/null @@ -1,106 +0,0 @@ -/* - * SNI RM200 PCI specific interrupt handler code. - * - * Copyright (C) 1994, 95, 96, 97, 98, 1999, 2000, 01 by Ralf Baechle - */ -#include <asm/asm.h> -#include <asm/mipsregs.h> -#include <asm/regdef.h> -#include <asm/sni.h> -#include <asm/stackframe.h> - -/* - * The PCI ASIC has the nasty property that it may delay writes if it is busy. - * As a consequence from writes that have not graduated when we exit from the - * interrupt handler we might catch a spurious interrupt. To avoid this we - * force the PCI ASIC to graduate all writes by executing a read from the - * PCI bus. - */ - .set noreorder - .set noat - .align 5 - NESTED(sni_rm200_pci_handle_int, PT_SIZE, sp) - SAVE_ALL - CLI - .set at - - /* Blinken light ... */ - lb t0, led_cache - addiu t0, 1 - sb t0, led_cache - sb t0, PCIMT_CSLED # write only register - .data -led_cache: .byte 0 - .text - - mfc0 t0, CP0_STATUS - mfc0 t1, CP0_CAUSE - and t0, t1 - - andi t1, t0, 0x0800 # hardware interrupt 1 - bnez t1, _hwint1 - andi t1, t0, 0x4000 # hardware interrupt 4 - bnez t1, _hwint4 - andi t1, t0, 0x2000 # hardware interrupt 3 - bnez t1, _hwint3 - andi t1, t0, 0x1000 # hardware interrupt 2 - bnez t1, _hwint2 - andi t1, t0, 0x8000 # hardware interrupt 5 - bnez t1, _hwint5 - andi t1, t0, 0x0400 # hardware interrupt 0 - bnez t1, _hwint0 - nop - - j restore_all # spurious interrupt - nop - - ############################################################################## - -/* hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug - button interrupts. */ -_hwint0: jal pciasic_hwint0 - move a0, sp - j ret_from_irq - nop - -/* - * hwint 1 deals with EISA and SCSI interrupts - */ -_hwint1: jal pciasic_hwint1 - move a0, sp - j ret_from_irq - nop - - -/* - * This interrupt was used for the com1 console on the first prototypes; - * it's unsed otherwise - */ -_hwint2: jal pciasic_hwint2 - move a0, sp - j ret_from_irq - nop - -/* - * hwint 3 are the PCI interrupts A - D - */ -_hwint3: jal pciasic_hwint3 - move a0, sp - j ret_from_irq - nop - -/* - * hwint 4 is used for only the onboard PCnet 32. - */ -_hwint4: jal pciasic_hwint4 - move a0, sp - j ret_from_irq - nop - -/* hwint5 is the r4k count / compare interrupt */ -_hwint5: jal pciasic_hwint5 - move a0, sp - j ret_from_irq - nop - - END(sni_rm200_pci_handle_int) diff --git a/arch/mips/sni/irq.c b/arch/mips/sni/irq.c index 952038aa4b90..7365b4853ddb 100644 --- a/arch/mips/sni/irq.c +++ b/arch/mips/sni/irq.c @@ -19,8 +19,6 @@ DEFINE_SPINLOCK(pciasic_lock); -extern asmlinkage void sni_rm200_pci_handle_int(void); - static void enable_pciasic_irq(unsigned int irq) { unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2); @@ -71,20 +69,20 @@ static struct hw_interrupt_type pciasic_irq_type = { * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug * button interrupts. Later ... */ -void pciasic_hwint0(struct pt_regs *regs) +static void pciasic_hwint0(struct pt_regs *regs) { panic("Received int0 but no handler yet ..."); } /* This interrupt was used for the com1 console on the first prototypes. */ -void pciasic_hwint2(struct pt_regs *regs) +static void pciasic_hwint2(struct pt_regs *regs) { /* I think this shouldn't happen on production machines. */ panic("hwint2 and no handler yet"); } /* hwint5 is the r4k count / compare interrupt */ -void pciasic_hwint5(struct pt_regs *regs) +static void pciasic_hwint5(struct pt_regs *regs) { panic("hwint5 and no handler yet"); } @@ -105,7 +103,7 @@ static unsigned int ls1bit8(unsigned int x) * * The EISA_INT bit in CSITPEND is high active, all others are low active. */ -void pciasic_hwint1(struct pt_regs *regs) +static void pciasic_hwint1(struct pt_regs *regs) { u8 pend = *(volatile char *)PCIMT_CSITPEND; unsigned long flags; @@ -135,7 +133,7 @@ void pciasic_hwint1(struct pt_regs *regs) /* * hwint 3 should deal with the PCI A - D interrupts, */ -void pciasic_hwint3(struct pt_regs *regs) +static void pciasic_hwint3(struct pt_regs *regs) { u8 pend = *(volatile char *)PCIMT_CSITPEND; int irq; @@ -150,13 +148,34 @@ void pciasic_hwint3(struct pt_regs *regs) /* * hwint 4 is used for only the onboard PCnet 32. */ -void pciasic_hwint4(struct pt_regs *regs) +static void pciasic_hwint4(struct pt_regs *regs) { clear_c0_status(IE_IRQ4); do_IRQ(PCIMT_IRQ_ETHERNET, regs); set_c0_status(IE_IRQ4); } +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) +{ + unsigned int pending = read_c0_status() & read_c0_cause(); + static unsigned char led_cache; + + *(volatile unsigned char *) PCIMT_CSLED = ++led_cache; + + if (pending & 0x0800) + pciasic_hwint1(regs); + else if (pending & 0x4000) + pciasic_hwint4(regs); + else if (pending & 0x2000) + pciasic_hwint3(regs); + else if (pending & 0x1000) + pciasic_hwint2(regs); + else if (pending & 0x8000) + pciasic_hwint5(regs); + else if (pending & 0x0400) + pciasic_hwint0(regs); +} + void __init init_pciasic(void) { unsigned long flags; @@ -176,8 +195,6 @@ void __init arch_init_irq(void) { int i; - set_except_vector(0, sni_rm200_pci_handle_int); - init_i8259_irqs(); /* Integrated i8259 */ init_pciasic(); |