diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2006-04-03 12:56:36 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2006-04-18 22:14:21 -0400 |
commit | e4ac58afdfac792c0583af30dbd9eae53e24c78b (patch) | |
tree | 7517bef2c515fc630e4d3d238867b91cde96f558 /arch/mips/ddb5xxx | |
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/ddb5xxx')
-rw-r--r-- | arch/mips/ddb5xxx/ddb5074/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/ddb5xxx/ddb5074/int-handler.S | 120 | ||||
-rw-r--r-- | arch/mips/ddb5xxx/ddb5074/irq.c | 26 | ||||
-rw-r--r-- | arch/mips/ddb5xxx/ddb5476/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/ddb5xxx/ddb5476/int-handler.S | 113 | ||||
-rw-r--r-- | arch/mips/ddb5xxx/ddb5476/irq.c | 30 | ||||
-rw-r--r-- | arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c | 2 | ||||
-rw-r--r-- | arch/mips/ddb5xxx/ddb5477/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/ddb5xxx/ddb5477/int-handler.S | 75 | ||||
-rw-r--r-- | arch/mips/ddb5xxx/ddb5477/irq.c | 24 |
10 files changed, 67 insertions, 329 deletions
diff --git a/arch/mips/ddb5xxx/ddb5074/Makefile b/arch/mips/ddb5xxx/ddb5074/Makefile index 488206b8d94e..304c02107b46 100644 --- a/arch/mips/ddb5xxx/ddb5074/Makefile +++ b/arch/mips/ddb5xxx/ddb5074/Makefile | |||
@@ -3,6 +3,6 @@ | |||
3 | # under Linux. | 3 | # under Linux. |
4 | # | 4 | # |
5 | 5 | ||
6 | obj-y += setup.o irq.o int-handler.o nile4_pic.o | 6 | obj-y += setup.o irq.o nile4_pic.o |
7 | 7 | ||
8 | EXTRA_AFLAGS := $(CFLAGS) | 8 | EXTRA_AFLAGS := $(CFLAGS) |
diff --git a/arch/mips/ddb5xxx/ddb5074/int-handler.S b/arch/mips/ddb5xxx/ddb5074/int-handler.S deleted file mode 100644 index a78644150b37..000000000000 --- a/arch/mips/ddb5xxx/ddb5074/int-handler.S +++ /dev/null | |||
@@ -1,120 +0,0 @@ | |||
1 | /* | ||
2 | * arch/mips/ddb5074/int-handler.S -- NEC DDB Vrc-5074 interrupt handler | ||
3 | * | ||
4 | * Based on arch/mips/sgi/kernel/indyIRQ.S | ||
5 | * | ||
6 | * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) | ||
7 | * | ||
8 | * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> | ||
9 | * Sony Software Development Center Europe (SDCE), Brussels | ||
10 | */ | ||
11 | #include <asm/asm.h> | ||
12 | #include <asm/mipsregs.h> | ||
13 | #include <asm/regdef.h> | ||
14 | #include <asm/stackframe.h> | ||
15 | |||
16 | /* A lot of complication here is taken away because: | ||
17 | * | ||
18 | * 1) We handle one interrupt and return, sitting in a loop and moving across | ||
19 | * all the pending IRQ bits in the cause register is _NOT_ the answer, the | ||
20 | * common case is one pending IRQ so optimize in that direction. | ||
21 | * | ||
22 | * 2) We need not check against bits in the status register IRQ mask, that | ||
23 | * would make this routine slow as hell. | ||
24 | * | ||
25 | * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in | ||
26 | * between like BSD spl() brain-damage. | ||
27 | * | ||
28 | * Furthermore, the IRQs on the INDY look basically (barring software IRQs | ||
29 | * which we don't use at all) like: | ||
30 | * | ||
31 | * MIPS IRQ Source | ||
32 | * -------- ------ | ||
33 | * 0 Software (ignored) | ||
34 | * 1 Software (ignored) | ||
35 | * 2 Local IRQ level zero | ||
36 | * 3 Local IRQ level one | ||
37 | * 4 8254 Timer zero | ||
38 | * 5 8254 Timer one | ||
39 | * 6 Bus Error | ||
40 | * 7 R4k timer (what we use) | ||
41 | * | ||
42 | * We handle the IRQ according to _our_ priority which is: | ||
43 | * | ||
44 | * Highest ---- R4k Timer | ||
45 | * Local IRQ zero | ||
46 | * Local IRQ one | ||
47 | * Bus Error | ||
48 | * 8254 Timer zero | ||
49 | * Lowest ---- 8254 Timer one | ||
50 | * | ||
51 | * then we just return, if multiple IRQs are pending then we will just take | ||
52 | * another exception, big deal. | ||
53 | */ | ||
54 | |||
55 | .text | ||
56 | .set noreorder | ||
57 | .set noat | ||
58 | .align 5 | ||
59 | NESTED(ddbIRQ, PT_SIZE, sp) | ||
60 | SAVE_ALL | ||
61 | CLI | ||
62 | .set at | ||
63 | mfc0 s0, CP0_CAUSE # get irq mask | ||
64 | |||
65 | #if 1 | ||
66 | mfc0 t2,CP0_STATUS # get enabled interrupts | ||
67 | and s0,t2 # isolate allowed ones | ||
68 | #endif | ||
69 | /* First we check for r4k counter/timer IRQ. */ | ||
70 | andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero | ||
71 | beq a0, zero, 1f | ||
72 | andi a0, s0, CAUSEF_IP3 # delay slot, check local level one | ||
73 | |||
74 | /* Wheee, local level zero interrupt. */ | ||
75 | jal ddb_local0_irqdispatch | ||
76 | move a0, sp # delay slot | ||
77 | |||
78 | j ret_from_irq | ||
79 | nop # delay slot | ||
80 | |||
81 | 1: | ||
82 | beq a0, zero, 1f | ||
83 | andi a0, s0, CAUSEF_IP6 # delay slot, check bus error | ||
84 | |||
85 | /* Wheee, local level one interrupt. */ | ||
86 | move a0, sp | ||
87 | jal ddb_local1_irqdispatch | ||
88 | nop | ||
89 | |||
90 | j ret_from_irq | ||
91 | nop | ||
92 | |||
93 | 1: | ||
94 | beq a0, zero, 1f | ||
95 | nop | ||
96 | |||
97 | /* Wheee, an asynchronous bus error... */ | ||
98 | move a0, sp | ||
99 | jal ddb_buserror_irq | ||
100 | nop | ||
101 | |||
102 | j ret_from_irq | ||
103 | nop | ||
104 | |||
105 | 1: | ||
106 | /* Here by mistake? This is possible, what can happen | ||
107 | * is that by the time we take the exception the IRQ | ||
108 | * pin goes low, so just leave if this is the case. | ||
109 | */ | ||
110 | andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5) | ||
111 | beq a0, zero, 1f | ||
112 | |||
113 | /* Must be one of the 8254 timers... */ | ||
114 | move a0, sp | ||
115 | jal ddb_8254timer_irq | ||
116 | nop | ||
117 | 1: | ||
118 | j ret_from_irq | ||
119 | nop | ||
120 | END(ddbIRQ) | ||
diff --git a/arch/mips/ddb5xxx/ddb5074/irq.c b/arch/mips/ddb5xxx/ddb5074/irq.c index 45088a1be414..60c087b7738c 100644 --- a/arch/mips/ddb5xxx/ddb5074/irq.c +++ b/arch/mips/ddb5xxx/ddb5074/irq.c | |||
@@ -21,8 +21,6 @@ | |||
21 | #include <asm/ddb5xxx/ddb5074.h> | 21 | #include <asm/ddb5xxx/ddb5074.h> |
22 | 22 | ||
23 | 23 | ||
24 | extern asmlinkage void ddbIRQ(void); | ||
25 | |||
26 | static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; | 24 | static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; |
27 | 25 | ||
28 | #define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */ | 26 | #define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */ |
@@ -90,7 +88,7 @@ static void m1543_irq_setup(void) | |||
90 | 88 | ||
91 | } | 89 | } |
92 | 90 | ||
93 | void ddb_local0_irqdispatch(struct pt_regs *regs) | 91 | static void ddb_local0_irqdispatch(struct pt_regs *regs) |
94 | { | 92 | { |
95 | u32 mask; | 93 | u32 mask; |
96 | int nile4_irq; | 94 | int nile4_irq; |
@@ -118,29 +116,41 @@ void ddb_local0_irqdispatch(struct pt_regs *regs) | |||
118 | } | 116 | } |
119 | } | 117 | } |
120 | 118 | ||
121 | void ddb_local1_irqdispatch(void) | 119 | static void ddb_local1_irqdispatch(void) |
122 | { | 120 | { |
123 | printk("ddb_local1_irqdispatch called\n"); | 121 | printk("ddb_local1_irqdispatch called\n"); |
124 | } | 122 | } |
125 | 123 | ||
126 | void ddb_buserror_irq(void) | 124 | static void ddb_buserror_irq(void) |
127 | { | 125 | { |
128 | printk("ddb_buserror_irq called\n"); | 126 | printk("ddb_buserror_irq called\n"); |
129 | } | 127 | } |
130 | 128 | ||
131 | void ddb_8254timer_irq(void) | 129 | static void ddb_8254timer_irq(void) |
132 | { | 130 | { |
133 | printk("ddb_8254timer_irq called\n"); | 131 | printk("ddb_8254timer_irq called\n"); |
134 | } | 132 | } |
135 | 133 | ||
134 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
135 | { | ||
136 | unsigned int pending = read_c0_cause() & read_c0_status(); | ||
137 | |||
138 | if (pending & CAUSEF_IP2) | ||
139 | ddb_local0_irqdispatch(regs); | ||
140 | else if (pending & CAUSEF_IP3) | ||
141 | ddb_local1_irqdispatch(); | ||
142 | else if (pending & CAUSEF_IP6) | ||
143 | ddb_buserror_irq(); | ||
144 | else if (pending & (CAUSEF_IP4 | CAUSEF_IP5)) | ||
145 | ddb_8254timer_irq(); | ||
146 | } | ||
147 | |||
136 | void __init arch_init_irq(void) | 148 | void __init arch_init_irq(void) |
137 | { | 149 | { |
138 | /* setup cascade interrupts */ | 150 | /* setup cascade interrupts */ |
139 | setup_irq(NILE4_IRQ_BASE + NILE4_INT_INTE, &irq_cascade); | 151 | setup_irq(NILE4_IRQ_BASE + NILE4_INT_INTE, &irq_cascade); |
140 | setup_irq(CPU_IRQ_BASE + CPU_NILE4_CASCADE, &irq_cascade); | 152 | setup_irq(CPU_IRQ_BASE + CPU_NILE4_CASCADE, &irq_cascade); |
141 | 153 | ||
142 | set_except_vector(0, ddbIRQ); | ||
143 | |||
144 | nile4_irq_setup(NILE4_IRQ_BASE); | 154 | nile4_irq_setup(NILE4_IRQ_BASE); |
145 | m1543_irq_setup(); | 155 | m1543_irq_setup(); |
146 | init_i8259_irqs(); | 156 | init_i8259_irqs(); |
diff --git a/arch/mips/ddb5xxx/ddb5476/Makefile b/arch/mips/ddb5xxx/ddb5476/Makefile index 61eec363cb02..ab0312cb47b4 100644 --- a/arch/mips/ddb5xxx/ddb5476/Makefile +++ b/arch/mips/ddb5xxx/ddb5476/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # under Linux. | 3 | # under Linux. |
4 | # | 4 | # |
5 | 5 | ||
6 | obj-y += setup.o irq.o int-handler.o nile4_pic.o vrc5476_irq.o | 6 | obj-y += setup.o irq.o nile4_pic.o vrc5476_irq.o |
7 | obj-$(CONFIG_KGDB) += dbg_io.o | 7 | obj-$(CONFIG_KGDB) += dbg_io.o |
8 | 8 | ||
9 | EXTRA_AFLAGS := $(CFLAGS) | 9 | EXTRA_AFLAGS := $(CFLAGS) |
diff --git a/arch/mips/ddb5xxx/ddb5476/int-handler.S b/arch/mips/ddb5xxx/ddb5476/int-handler.S deleted file mode 100644 index 0c2bdae96bb1..000000000000 --- a/arch/mips/ddb5xxx/ddb5476/int-handler.S +++ /dev/null | |||
@@ -1,113 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2001 MontaVista Software Inc. | ||
3 | * Author: jsun@mvista.com or jsun@junsun.net | ||
4 | * | ||
5 | * First-level interrupt dispatcher for ddb5476 | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | #include <asm/asm.h> | ||
13 | #include <asm/mipsregs.h> | ||
14 | #include <asm/addrspace.h> | ||
15 | #include <asm/regdef.h> | ||
16 | #include <asm/stackframe.h> | ||
17 | |||
18 | #include <asm/ddb5xxx/ddb5476.h> | ||
19 | |||
20 | /* | ||
21 | * first level interrupt dispatcher for ocelot board - | ||
22 | * We check for the timer first, then check PCI ints A and D. | ||
23 | * Then check for serial IRQ and fall through. | ||
24 | */ | ||
25 | .align 5 | ||
26 | NESTED(ddb5476_handle_int, PT_SIZE, sp) | ||
27 | SAVE_ALL | ||
28 | CLI | ||
29 | .set at | ||
30 | .set noreorder | ||
31 | mfc0 t0, CP0_CAUSE | ||
32 | mfc0 t2, CP0_STATUS | ||
33 | |||
34 | and t0, t2 | ||
35 | |||
36 | andi t1, t0, STATUSF_IP7 /* cpu timer */ | ||
37 | bnez t1, ll_cpu_ip7 | ||
38 | andi t1, t0, STATUSF_IP2 /* vrc5476 & i8259 */ | ||
39 | bnez t1, ll_cpu_ip2 | ||
40 | andi t1, t0, STATUSF_IP3 | ||
41 | bnez t1, ll_cpu_ip3 | ||
42 | andi t1, t0, STATUSF_IP4 | ||
43 | bnez t1, ll_cpu_ip4 | ||
44 | andi t1, t0, STATUSF_IP5 | ||
45 | bnez t1, ll_cpu_ip5 | ||
46 | andi t1, t0, STATUSF_IP6 | ||
47 | bnez t1, ll_cpu_ip6 | ||
48 | andi t1, t0, STATUSF_IP0 /* software int 0 */ | ||
49 | bnez t1, ll_cpu_ip0 | ||
50 | andi t1, t0, STATUSF_IP1 /* software int 1 */ | ||
51 | bnez t1, ll_cpu_ip1 | ||
52 | nop | ||
53 | |||
54 | .set reorder | ||
55 | |||
56 | /* wrong alarm or masked ... */ | ||
57 | // jal spurious_interrupt | ||
58 | // j ret_from_irq | ||
59 | move a0, sp | ||
60 | jal vrc5476_irq_dispatch | ||
61 | j ret_from_irq | ||
62 | nop | ||
63 | |||
64 | .align 5 | ||
65 | |||
66 | ll_cpu_ip0: | ||
67 | li a0, CPU_IRQ_BASE + 0 | ||
68 | move a1, sp | ||
69 | jal do_IRQ | ||
70 | j ret_from_irq | ||
71 | |||
72 | ll_cpu_ip1: | ||
73 | li a0, CPU_IRQ_BASE + 1 | ||
74 | move a1, sp | ||
75 | jal do_IRQ | ||
76 | j ret_from_irq | ||
77 | |||
78 | ll_cpu_ip2: /* jump to second-level dispatching */ | ||
79 | move a0, sp | ||
80 | jal vrc5476_irq_dispatch | ||
81 | j ret_from_irq | ||
82 | |||
83 | ll_cpu_ip3: | ||
84 | li a0, CPU_IRQ_BASE + 3 | ||
85 | move a1, sp | ||
86 | jal do_IRQ | ||
87 | j ret_from_irq | ||
88 | |||
89 | ll_cpu_ip4: | ||
90 | li a0, CPU_IRQ_BASE + 4 | ||
91 | move a1, sp | ||
92 | jal do_IRQ | ||
93 | j ret_from_irq | ||
94 | |||
95 | ll_cpu_ip5: | ||
96 | li a0, CPU_IRQ_BASE + 5 | ||
97 | move a1, sp | ||
98 | jal do_IRQ | ||
99 | j ret_from_irq | ||
100 | |||
101 | ll_cpu_ip6: | ||
102 | li a0, CPU_IRQ_BASE + 6 | ||
103 | move a1, sp | ||
104 | jal do_IRQ | ||
105 | j ret_from_irq | ||
106 | |||
107 | ll_cpu_ip7: | ||
108 | li a0, CPU_IRQ_BASE + 7 | ||
109 | move a1, sp | ||
110 | jal do_IRQ | ||
111 | j ret_from_irq | ||
112 | |||
113 | END(ddb5476_handle_int) | ||
diff --git a/arch/mips/ddb5xxx/ddb5476/irq.c b/arch/mips/ddb5xxx/ddb5476/irq.c index 5388b5868c4a..7583a1f30711 100644 --- a/arch/mips/ddb5xxx/ddb5476/irq.c +++ b/arch/mips/ddb5xxx/ddb5476/irq.c | |||
@@ -110,11 +110,36 @@ static void nile4_irq_setup(void) | |||
110 | static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; | 110 | static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; |
111 | static struct irqaction irq_error = { no_action, 0, CPU_MASK_NONE, "error", NULL, NULL }; | 111 | static struct irqaction irq_error = { no_action, 0, CPU_MASK_NONE, "error", NULL, NULL }; |
112 | 112 | ||
113 | extern asmlinkage void ddb5476_handle_int(void); | ||
114 | extern int setup_irq(unsigned int irq, struct irqaction *irqaction); | 113 | extern int setup_irq(unsigned int irq, struct irqaction *irqaction); |
115 | extern void mips_cpu_irq_init(u32 irq_base); | 114 | extern void mips_cpu_irq_init(u32 irq_base); |
116 | extern void vrc5476_irq_init(u32 irq_base); | 115 | extern void vrc5476_irq_init(u32 irq_base); |
117 | 116 | ||
117 | extern void vrc5476_irq_dispatch(struct pt_regs *regs); | ||
118 | |||
119 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
120 | { | ||
121 | unsigned int pending = read_c0_cause() & read_c0_status(); | ||
122 | |||
123 | if (pending & STATUSF_IP7) | ||
124 | do_IRQ(CPU_IRQ_BASE + 7, regs); | ||
125 | else if (pending & STATUSF_IP2) | ||
126 | vrc5476_irq_dispatch(regs); | ||
127 | else if (pending & STATUSF_IP3) | ||
128 | do_IRQ(CPU_IRQ_BASE + 3, regs); | ||
129 | else if (pending & STATUSF_IP4) | ||
130 | do_IRQ(CPU_IRQ_BASE + 4, regs); | ||
131 | else if (pending & STATUSF_IP5) | ||
132 | do_IRQ(CPU_IRQ_BASE + 5, regs); | ||
133 | else if (pending & STATUSF_IP6) | ||
134 | do_IRQ(CPU_IRQ_BASE + 6, regs); | ||
135 | else if (pending & STATUSF_IP0) | ||
136 | do_IRQ(CPU_IRQ_BASE, regs); | ||
137 | else if (pending & STATUSF_IP1) | ||
138 | do_IRQ(CPU_IRQ_BASE + 1, regs); | ||
139 | |||
140 | vrc5476_irq_dispatch(regs); | ||
141 | } | ||
142 | |||
118 | void __init arch_init_irq(void) | 143 | void __init arch_init_irq(void) |
119 | { | 144 | { |
120 | /* hardware initialization */ | 145 | /* hardware initialization */ |
@@ -137,7 +162,4 @@ void __init arch_init_irq(void) | |||
137 | setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_LBRT, &irq_error); | 162 | setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_LBRT, &irq_error); |
138 | setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCIS, &irq_error); | 163 | setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCIS, &irq_error); |
139 | setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCI, &irq_error); | 164 | setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCI, &irq_error); |
140 | |||
141 | /* setup the grandpa intr vector */ | ||
142 | set_except_vector(0, ddb5476_handle_int); | ||
143 | } | 165 | } |
diff --git a/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c b/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c index 581eabad5f82..a3c5e7b18018 100644 --- a/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c +++ b/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c | |||
@@ -77,7 +77,7 @@ vrc5476_irq_init(u32 base) | |||
77 | } | 77 | } |
78 | 78 | ||
79 | 79 | ||
80 | asmlinkage void | 80 | void |
81 | vrc5476_irq_dispatch(struct pt_regs *regs) | 81 | vrc5476_irq_dispatch(struct pt_regs *regs) |
82 | { | 82 | { |
83 | u32 mask; | 83 | u32 mask; |
diff --git a/arch/mips/ddb5xxx/ddb5477/Makefile b/arch/mips/ddb5xxx/ddb5477/Makefile index b79b43c9f93b..ea68815ad17a 100644 --- a/arch/mips/ddb5xxx/ddb5477/Makefile +++ b/arch/mips/ddb5xxx/ddb5477/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for NEC DDB-Vrc5477 board | 2 | # Makefile for NEC DDB-Vrc5477 board |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += int-handler.o irq.o irq_5477.o setup.o lcd44780.o | 5 | obj-y += irq.o irq_5477.o setup.o lcd44780.o |
6 | 6 | ||
7 | obj-$(CONFIG_RUNTIME_DEBUG) += debug.o | 7 | obj-$(CONFIG_RUNTIME_DEBUG) += debug.o |
8 | obj-$(CONFIG_KGDB) += kgdb_io.o | 8 | obj-$(CONFIG_KGDB) += kgdb_io.o |
diff --git a/arch/mips/ddb5xxx/ddb5477/int-handler.S b/arch/mips/ddb5xxx/ddb5477/int-handler.S deleted file mode 100644 index 9884874dbeb5..000000000000 --- a/arch/mips/ddb5xxx/ddb5477/int-handler.S +++ /dev/null | |||
@@ -1,75 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2001 MontaVista Software Inc. | ||
3 | * Author: jsun@mvista.com or jsun@junsun.net | ||
4 | * | ||
5 | * First-level interrupt dispatcher for ddb5477 | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | #include <asm/asm.h> | ||
13 | #include <asm/mipsregs.h> | ||
14 | #include <asm/addrspace.h> | ||
15 | #include <asm/regdef.h> | ||
16 | #include <asm/stackframe.h> | ||
17 | #include <asm/ddb5xxx/ddb5477.h> | ||
18 | |||
19 | /* | ||
20 | * first level interrupt dispatcher for ocelot board - | ||
21 | * We check for the timer first, then check PCI ints A and D. | ||
22 | * Then check for serial IRQ and fall through. | ||
23 | */ | ||
24 | .align 5 | ||
25 | NESTED(ddb5477_handle_int, PT_SIZE, sp) | ||
26 | SAVE_ALL | ||
27 | CLI | ||
28 | .set at | ||
29 | .set noreorder | ||
30 | mfc0 t0, CP0_CAUSE | ||
31 | mfc0 t2, CP0_STATUS | ||
32 | |||
33 | and t0, t2 | ||
34 | |||
35 | andi t1, t0, STATUSF_IP7 /* cpu timer */ | ||
36 | bnez t1, ll_cputimer_irq | ||
37 | andi t1, t0, (STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP5 | STATUSF_IP6 ) | ||
38 | bnez t1, ll_vrc5477_irq | ||
39 | andi t1, t0, STATUSF_IP0 /* software int 0 */ | ||
40 | bnez t1, ll_cpu_ip0 | ||
41 | andi t1, t0, STATUSF_IP1 /* software int 1 */ | ||
42 | bnez t1, ll_cpu_ip1 | ||
43 | nop | ||
44 | .set reorder | ||
45 | |||
46 | /* wrong alarm or masked ... */ | ||
47 | jal spurious_interrupt | ||
48 | j ret_from_irq | ||
49 | END(ddb5477_handle_int) | ||
50 | |||
51 | .align 5 | ||
52 | |||
53 | ll_vrc5477_irq: | ||
54 | move a0, sp | ||
55 | jal vrc5477_irq_dispatch | ||
56 | j ret_from_irq | ||
57 | |||
58 | ll_cputimer_irq: | ||
59 | li a0, CPU_IRQ_BASE + 7 | ||
60 | move a1, sp | ||
61 | jal do_IRQ | ||
62 | j ret_from_irq | ||
63 | |||
64 | |||
65 | ll_cpu_ip0: | ||
66 | li a0, CPU_IRQ_BASE + 0 | ||
67 | move a1, sp | ||
68 | jal do_IRQ | ||
69 | j ret_from_irq | ||
70 | |||
71 | ll_cpu_ip1: | ||
72 | li a0, CPU_IRQ_BASE + 1 | ||
73 | move a1, sp | ||
74 | jal do_IRQ | ||
75 | j ret_from_irq | ||
diff --git a/arch/mips/ddb5xxx/ddb5477/irq.c b/arch/mips/ddb5xxx/ddb5477/irq.c index 9ffe1a9142ca..de433cf9fb50 100644 --- a/arch/mips/ddb5xxx/ddb5477/irq.c +++ b/arch/mips/ddb5xxx/ddb5477/irq.c | |||
@@ -75,7 +75,6 @@ set_pci_int_attr(u32 pci, u32 intn, u32 active, u32 trigger) | |||
75 | 75 | ||
76 | extern void vrc5477_irq_init(u32 base); | 76 | extern void vrc5477_irq_init(u32 base); |
77 | extern void mips_cpu_irq_init(u32 base); | 77 | extern void mips_cpu_irq_init(u32 base); |
78 | extern asmlinkage void ddb5477_handle_int(void); | ||
79 | extern int setup_irq(unsigned int irq, struct irqaction *irqaction); | 78 | extern int setup_irq(unsigned int irq, struct irqaction *irqaction); |
80 | static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; | 79 | static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; |
81 | 80 | ||
@@ -135,9 +134,6 @@ void __init arch_init_irq(void) | |||
135 | /* setup cascade interrupts */ | 134 | /* setup cascade interrupts */ |
136 | setup_irq(VRC5477_IRQ_BASE + VRC5477_I8259_CASCADE, &irq_cascade); | 135 | setup_irq(VRC5477_IRQ_BASE + VRC5477_I8259_CASCADE, &irq_cascade); |
137 | setup_irq(CPU_IRQ_BASE + CPU_VRC5477_CASCADE, &irq_cascade); | 136 | setup_irq(CPU_IRQ_BASE + CPU_VRC5477_CASCADE, &irq_cascade); |
138 | |||
139 | /* hook up the first-level interrupt handler */ | ||
140 | set_except_vector(0, ddb5477_handle_int); | ||
141 | } | 137 | } |
142 | 138 | ||
143 | u8 i8259_interrupt_ack(void) | 139 | u8 i8259_interrupt_ack(void) |
@@ -159,7 +155,7 @@ u8 i8259_interrupt_ack(void) | |||
159 | * the first level int-handler will jump here if it is a vrc5477 irq | 155 | * the first level int-handler will jump here if it is a vrc5477 irq |
160 | */ | 156 | */ |
161 | #define NUM_5477_IRQS 32 | 157 | #define NUM_5477_IRQS 32 |
162 | asmlinkage void | 158 | static void |
163 | vrc5477_irq_dispatch(struct pt_regs *regs) | 159 | vrc5477_irq_dispatch(struct pt_regs *regs) |
164 | { | 160 | { |
165 | u32 intStatus; | 161 | u32 intStatus; |
@@ -197,3 +193,21 @@ vrc5477_irq_dispatch(struct pt_regs *regs) | |||
197 | } | 193 | } |
198 | } | 194 | } |
199 | } | 195 | } |
196 | |||
197 | #define VR5477INTS (STATUSF_IP2|STATUSF_IP3|STATUSF_IP4|STATUSF_IP5|STATUSF_IP6) | ||
198 | |||
199 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
200 | { | ||
201 | unsigned int pending = read_c0_cause() & read_c0_status(); | ||
202 | |||
203 | if (pending & STATUSF_IP7) | ||
204 | do_IRQ(CPU_IRQ_BASE + 7, regs); | ||
205 | else if (pending & VR5477INTS) | ||
206 | vrc5477_irq_dispatch(regs); | ||
207 | else if (pending & STATUSF_IP0) | ||
208 | do_IRQ(CPU_IRQ_BASE, regs); | ||
209 | else if (pending & STATUSF_IP1) | ||
210 | do_IRQ(CPU_IRQ_BASE + 1, regs); | ||
211 | else | ||
212 | spurious_interrupt(regs); | ||
213 | } | ||