summary refs log tree commit diff
path: root/arch/mips/gt64120
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2006-04-03 17:56:36 +0100
committerRalf Baechle <ralf@linux-mips.org>2006-04-19 04:14:21 +0200
commite4ac58afdfac792c0583af30dbd9eae53e24c78b (patch)
tree7517bef2c515fc630e4d3d238867b91cde96f558 /arch/mips/gt64120
parentd35d473c25d43d7db3e5e18b66d558d2a631cca8 (diff)
downloadlinux-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/gt64120')
-rw-r--r--arch/mips/gt64120/ev64120/Makefile2
-rw-r--r--arch/mips/gt64120/ev64120/int-handler.S114
-rw-r--r--arch/mips/gt64120/ev64120/irq.c27
-rw-r--r--arch/mips/gt64120/momenco_ocelot/Makefile2
-rw-r--r--arch/mips/gt64120/momenco_ocelot/int-handler.S131
-rw-r--r--arch/mips/gt64120/momenco_ocelot/irq.c36
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);
 }