diff options
author | Ralf Baechle | 2006-04-03 17:56:36 +0100 |
---|---|---|
committer | Ralf Baechle | 2006-04-19 04:14:21 +0200 |
commit | e4ac58afdfac792c0583af30dbd9eae53e24c78b (patch) | |
tree | 7517bef2c515fc630e4d3d238867b91cde96f558 /arch/mips/gt64120 | |
parent | d35d473c25d43d7db3e5e18b66d558d2a631cca8 (diff) |
[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/gt64120')
-rw-r--r-- | arch/mips/gt64120/ev64120/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/gt64120/ev64120/int-handler.S | 114 | ||||
-rw-r--r-- | arch/mips/gt64120/ev64120/irq.c | 27 | ||||
-rw-r--r-- | arch/mips/gt64120/momenco_ocelot/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/gt64120/momenco_ocelot/int-handler.S | 131 | ||||
-rw-r--r-- | arch/mips/gt64120/momenco_ocelot/irq.c | 36 |
6 files changed, 49 insertions, 263 deletions
diff --git a/arch/mips/gt64120/ev64120/Makefile b/arch/mips/gt64120/ev64120/Makefile index ebe91c57e173..b2c53a8f8718 100644 --- a/arch/mips/gt64120/ev64120/Makefile +++ b/arch/mips/gt64120/ev64120/Makefile @@ -6,6 +6,6 @@ # Makefile for the Galileo EV64120 board. # -obj-y += int-handler.o irq.o promcon.o reset.o serialGT.o setup.o +obj-y += irq.o promcon.o reset.o serialGT.o setup.o EXTRA_AFLAGS := $(CFLAGS) diff --git a/arch/mips/gt64120/ev64120/int-handler.S b/arch/mips/gt64120/ev64120/int-handler.S deleted file mode 100644 index 9dda5b449522..000000000000 --- a/arch/mips/gt64120/ev64120/int-handler.S +++ /dev/null @@ -1,114 +0,0 @@ -/* - * int-handler.S - * - * Based on the cobalt handler. - */ -#include <asm/asm.h> -#include <asm/mipsregs.h> -#include <asm/addrspace.h> -#include <asm/regdef.h> -#include <asm/stackframe.h> - -/* - * galileo_handle_int - - * We check for the timer first, then check PCI ints A and D. - * Then check for serial IRQ and fall through. - */ - .align 5 - .set reorder - .set noat - NESTED(galileo_handle_int, PT_SIZE, sp) - SAVE_ALL - CLI - .set at - mfc0 t0,CP0_CAUSE - mfc0 t2,CP0_STATUS - - and t0,t2 - - andi t1,t0,STATUSF_IP4 /* int2 hardware line (timer) */ - bnez t1,ll_gt64120_irq - andi t1,t0,STATUSF_IP2 /* int0 hardware line */ - bnez t1,ll_pci_intA - andi t1,t0,STATUSF_IP5 /* int3 hardware line */ - bnez t1,ll_pci_intD - andi t1,t0,STATUSF_IP6 /* int4 hardware line */ - bnez t1,ll_serial_irq - andi t1,t0,STATUSF_IP7 /* compare int */ - bnez t1,ll_compare_irq - nop - - /* wrong alarm or masked ... */ - jal spurious_interrupt - nop - j ret_from_irq - END(galileo_handle_int) - - - .align 5 - .set reorder -ll_gt64120_irq: - li a0,4 - move a1,sp - jal do_IRQ - nop - j ret_from_irq - nop - - .align 5 - .set reorder -ll_compare_irq: - li a0,7 - move a1,sp - jal do_IRQ - nop - j ret_from_irq - nop - - .align 5 - .set reorder -ll_pci_intA: - move a0,sp - jal pci_intA - nop - j ret_from_irq - nop - -#if 0 - .align 5 - .set reorder -ll_pci_intB: - move a0,sp - jal pci_intB - nop - j ret_from_irq - nop - - .align 5 - .set reorder -ll_pci_intC: - move a0,sp - jal pci_intC - nop - j ret_from_irq - nop -#endif - - .align 5 - .set reorder -ll_pci_intD: - move a0,sp - jal pci_intD - nop - j ret_from_irq - nop - - .align 5 - .set reorder -ll_serial_irq: - li a0,6 - move a1,sp - jal do_IRQ - nop - j ret_from_irq - nop diff --git a/arch/mips/gt64120/ev64120/irq.c b/arch/mips/gt64120/ev64120/irq.c index 3b186159b21a..46c468b26b30 100644 --- a/arch/mips/gt64120/ev64120/irq.c +++ b/arch/mips/gt64120/ev64120/irq.c @@ -46,14 +46,22 @@ #include <asm/system.h> #include <asm/gt64120.h> -asmlinkage inline void pci_intA(struct pt_regs *regs) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { - do_IRQ(GT_INTA, regs); -} - -asmlinkage inline void pci_intD(struct pt_regs *regs) -{ - do_IRQ(GT_INTD, regs); + unsigned int pending = read_c0_status() & read_c0_cause(); + + if (pending & STATUSF_IP4) /* int2 hardware line (timer) */ + do_IRQ(4, regs); + else if (pending & STATUSF_IP2) /* int0 hardware line */ + do_IRQ(GT_INTA, regs); + else if (pending & STATUSF_IP5) /* int3 hardware line */ + do_IRQ(GT_INTD, regs); + else if (pending & STATUSF_IP6) /* int4 hardware line */ + do_IRQ(6, regs); + else if (pending & STATUSF_IP7) /* compare int */ + do_IRQ(7, regs); + else + spurious_interrupt(regs); } static void disable_ev64120_irq(unsigned int irq_nr) @@ -109,16 +117,11 @@ static struct hw_interrupt_type ev64120_irq_type = { void gt64120_irq_setup(void) { - extern asmlinkage void galileo_handle_int(void); - /* * Clear all of the interrupts while we change the able around a bit. */ clear_c0_status(ST0_IM); - /* Sets the exception_handler array. */ - set_except_vector(0, galileo_handle_int); - local_irq_disable(); /* diff --git a/arch/mips/gt64120/momenco_ocelot/Makefile b/arch/mips/gt64120/momenco_ocelot/Makefile index 7b59c6567c79..6f708df8373b 100644 --- a/arch/mips/gt64120/momenco_ocelot/Makefile +++ b/arch/mips/gt64120/momenco_ocelot/Makefile @@ -2,7 +2,7 @@ # Makefile for Momentum's Ocelot board. # -obj-y += int-handler.o irq.o prom.o reset.o setup.o +obj-y += irq.o prom.o reset.o setup.o obj-$(CONFIG_KGDB) += dbg_io.o diff --git a/arch/mips/gt64120/momenco_ocelot/int-handler.S b/arch/mips/gt64120/momenco_ocelot/int-handler.S deleted file mode 100644 index 808acef248cc..000000000000 --- a/arch/mips/gt64120/momenco_ocelot/int-handler.S +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2001 MontaVista Software Inc. - * Author: jsun@mvista.com or jsun@junsun.net - * - * First-level interrupt dispatcher for ocelot board. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include <asm/asm.h> -#include <asm/mipsregs.h> -#include <asm/addrspace.h> -#include <asm/regdef.h> -#include <asm/stackframe.h> - -/* - * first level interrupt dispatcher for ocelot board - - * We check for the timer first, then check PCI ints A and D. - * Then check for serial IRQ and fall through. - */ - .align 5 - NESTED(ocelot_handle_int, PT_SIZE, sp) - SAVE_ALL - CLI - .set at - mfc0 t0, CP0_CAUSE - mfc0 t2, CP0_STATUS - - and t0, t2 - - andi t1, t0, STATUSF_IP2 /* int0 hardware line */ - bnez t1, ll_pri_enet_irq - andi t1, t0, STATUSF_IP3 /* int1 hardware line */ - bnez t1, ll_sec_enet_irq - andi t1, t0, STATUSF_IP4 /* int2 hardware line */ - bnez t1, ll_uart1_irq - andi t1, t0, STATUSF_IP5 /* int3 hardware line */ - bnez t1, ll_cpci_irq - andi t1, t0, STATUSF_IP6 /* int4 hardware line */ - bnez t1, ll_galileo_irq - andi t1, t0, STATUSF_IP7 /* cpu timer */ - bnez t1, ll_cputimer_irq - - /* now look at the extended interrupts */ - mfc0 t0, CP0_CAUSE - cfc0 t1, CP0_S1_INTCONTROL - - /* shift the mask 8 bits left to line up the bits */ - sll t2, t1, 8 - - and t0, t2 - srl t0, t0, 16 - - andi t1, t0, STATUSF_IP8 /* int6 hardware line */ - bnez t1, ll_pmc1_irq - andi t1, t0, STATUSF_IP9 /* int7 hardware line */ - bnez t1, ll_pmc2_irq - andi t1, t0, STATUSF_IP10 /* int8 hardware line */ - bnez t1, ll_cpci_abcd_irq - andi t1, t0, STATUSF_IP11 /* int9 hardware line */ - bnez t1, ll_uart2_irq - - .set reorder - - /* wrong alarm or masked ... */ - j spurious_interrupt - nop - END(ocelot_handle_int) - - .align 5 -ll_pri_enet_irq: - li a0, 2 - move a1, sp - jal do_IRQ - j ret_from_irq - -ll_sec_enet_irq: - li a0, 3 - move a1, sp - jal do_IRQ - j ret_from_irq - -ll_uart1_irq: - li a0, 4 - move a1, sp - jal do_IRQ - j ret_from_irq - -ll_cpci_irq: - li a0, 5 - move a1, sp - jal do_IRQ - j ret_from_irq - -ll_galileo_irq: - li a0, 6 - move a1, sp - jal do_IRQ - j ret_from_irq - -ll_cputimer_irq: - li a0, 7 - move a1, sp - jal do_IRQ - j ret_from_irq - -ll_pmc1_irq: - li a0, 8 - move a1, sp - jal do_IRQ - j ret_from_irq - -ll_pmc2_irq: - li a0, 9 - move a1, sp - jal do_IRQ - j ret_from_irq - -ll_cpci_abcd_irq: - li a0, 10 - move a1, sp - jal do_IRQ - j ret_from_irq - -ll_uart2_irq: - li a0, 11 - move a1, sp - jal do_IRQ - j ret_from_irq diff --git a/arch/mips/gt64120/momenco_ocelot/irq.c b/arch/mips/gt64120/momenco_ocelot/irq.c index 4f108da71b23..885f67f32ea3 100644 --- a/arch/mips/gt64120/momenco_ocelot/irq.c +++ b/arch/mips/gt64120/momenco_ocelot/irq.c @@ -48,7 +48,38 @@ #include <asm/mipsregs.h> #include <asm/system.h> -extern asmlinkage void ocelot_handle_int(void); +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) +{ + unsigned int pending = read_c0_status() & read_c0_cause(); + + if (pending & STATUSF_IP2) /* int0 hardware line */ + do_IRQ(2, regs); + else if (pending & STATUSF_IP3) /* int1 hardware line */ + do_IRQ(3, regs); + else if (pending & STATUSF_IP4) /* int2 hardware line */ + do_IRQ(4, regs); + else if (pending & STATUSF_IP5) /* int3 hardware line */ + do_IRQ(5, regs); + else if (pending & STATUSF_IP6) /* int4 hardware line */ + do_IRQ(6, regs); + else if (pending & STATUSF_IP7) /* cpu timer */ + do_IRQ(7, regs); + else { + /* + * Now look at the extended interrupts + */ + pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16; + + if (pending & STATUSF_IP8) /* int6 hardware line */ + do_IRQ(8, regs); + else if (pending & STATUSF_IP9) /* int7 hardware line */ + do_IRQ(9, regs); + else if (pending & STATUSF_IP10) /* int8 hardware line */ + do_IRQ(10, regs); + else if (pending & STATUSF_IP11) /* int9 hardware line */ + do_IRQ(11, regs); + } +} void __init arch_init_irq(void) { @@ -59,9 +90,6 @@ void __init arch_init_irq(void) clear_c0_status(ST0_IM); local_irq_disable(); - /* Sets the first-level interrupt dispatcher. */ - set_except_vector(0, ocelot_handle_int); - mips_cpu_irq_init(0); rm7k_cpu_irq_init(8); } |