aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2005-08-17 09:44:26 -0400
committerRalf Baechle <ralf@linux-mips.org>2005-10-29 14:32:09 -0400
commitd03d0a57754cb820d318d2234c60b728eb38a94d (patch)
treec9feac8689e0081304382411592f3e074fe96502
parent533330bf7fa19854f3b4accd2b84ff58e3ee160f (diff)
MT bulletproofing.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/kernel/irq_cpu.c79
-rw-r--r--arch/mips/kernel/traps.c10
2 files changed, 75 insertions, 14 deletions
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c
index 31c38c4971c0..5db67e31ec1a 100644
--- a/arch/mips/kernel/irq_cpu.c
+++ b/arch/mips/kernel/irq_cpu.c
@@ -33,6 +33,7 @@
33 33
34#include <asm/irq_cpu.h> 34#include <asm/irq_cpu.h>
35#include <asm/mipsregs.h> 35#include <asm/mipsregs.h>
36#include <asm/mipsmtregs.h>
36#include <asm/system.h> 37#include <asm/system.h>
37 38
38static int mips_cpu_irq_base; 39static int mips_cpu_irq_base;
@@ -76,7 +77,7 @@ static unsigned int mips_cpu_irq_startup(unsigned int irq)
76 return 0; 77 return 0;
77} 78}
78 79
79#define mips_cpu_irq_shutdown mips_cpu_irq_disable 80#define mips_cpu_irq_shutdown mips_cpu_irq_disable
80 81
81/* 82/*
82 * While we ack the interrupt interrupts are disabled and thus we don't need 83 * While we ack the interrupt interrupts are disabled and thus we don't need
@@ -84,9 +85,6 @@ static unsigned int mips_cpu_irq_startup(unsigned int irq)
84 */ 85 */
85static void mips_cpu_irq_ack(unsigned int irq) 86static void mips_cpu_irq_ack(unsigned int irq)
86{ 87{
87 /* Only necessary for soft interrupts */
88 clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
89
90 mask_mips_irq(irq); 88 mask_mips_irq(irq);
91} 89}
92 90
@@ -97,15 +95,60 @@ static void mips_cpu_irq_end(unsigned int irq)
97} 95}
98 96
99static hw_irq_controller mips_cpu_irq_controller = { 97static hw_irq_controller mips_cpu_irq_controller = {
100 .typename = "MIPS", 98 .typename = "MIPS",
101 .startup = mips_cpu_irq_startup, 99 .startup = mips_cpu_irq_startup,
102 .shutdown = mips_cpu_irq_shutdown, 100 .shutdown = mips_cpu_irq_shutdown,
103 .enable = mips_cpu_irq_enable, 101 .enable = mips_cpu_irq_enable,
104 .disable = mips_cpu_irq_disable, 102 .disable = mips_cpu_irq_disable,
105 .ack = mips_cpu_irq_ack, 103 .ack = mips_cpu_irq_ack,
106 .end = mips_cpu_irq_end, 104 .end = mips_cpu_irq_end,
107}; 105};
108 106
107/*
108 * Basically the same as above but taking care of all the MT stuff
109 */
110
111#define unmask_mips_mt_irq unmask_mips_irq
112#define mask_mips_mt_irq mask_mips_irq
113#define mips_mt_cpu_irq_enable mips_cpu_irq_enable
114#define mips_mt_cpu_irq_disable mips_cpu_irq_disable
115
116static unsigned int mips_mt_cpu_irq_startup(unsigned int irq)
117{
118 unsigned int vpflags = dvpe();
119
120 clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
121 evpe(vpflags);
122 mips_mt_cpu_irq_enable(irq);
123
124 return 0;
125}
126
127#define mips_mt_cpu_irq_shutdown mips_mt_cpu_irq_disable
128
129/*
130 * While we ack the interrupt interrupts are disabled and thus we don't need
131 * to deal with concurrency issues. Same for mips_cpu_irq_end.
132 */
133static void mips_mt_cpu_irq_ack(unsigned int irq)
134{
135 unsigned int vpflags = dvpe();
136 clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
137 evpe(vpflags);
138 mask_mips_mt_irq(irq);
139}
140
141#define mips_mt_cpu_irq_end mips_cpu_irq_end
142
143static hw_irq_controller mips_mt_cpu_irq_controller = {
144 .typename = "MIPS",
145 .startup = mips_mt_cpu_irq_startup,
146 .shutdown = mips_mt_cpu_irq_shutdown,
147 .enable = mips_mt_cpu_irq_enable,
148 .disable = mips_mt_cpu_irq_disable,
149 .ack = mips_mt_cpu_irq_ack,
150 .end = mips_mt_cpu_irq_end,
151};
109 152
110void __init mips_cpu_irq_init(int irq_base) 153void __init mips_cpu_irq_init(int irq_base)
111{ 154{
@@ -115,7 +158,19 @@ void __init mips_cpu_irq_init(int irq_base)
115 clear_c0_status(ST0_IM); 158 clear_c0_status(ST0_IM);
116 clear_c0_cause(CAUSEF_IP); 159 clear_c0_cause(CAUSEF_IP);
117 160
118 for (i = irq_base; i < irq_base + 8; i++) { 161 /*
162 * Only MT is using the software interrupts currently, so we just
163 * leave them uninitialized for other processors.
164 */
165 if (cpu_has_mipsmt)
166 for (i = irq_base; i < irq_base + 2; i++) {
167 irq_desc[i].status = IRQ_DISABLED;
168 irq_desc[i].action = NULL;
169 irq_desc[i].depth = 1;
170 irq_desc[i].handler = &mips_mt_cpu_irq_controller;
171 }
172
173 for (i = irq_base + 2; i < irq_base + 8; i++) {
119 irq_desc[i].status = IRQ_DISABLED; 174 irq_desc[i].status = IRQ_DISABLED;
120 irq_desc[i].action = NULL; 175 irq_desc[i].action = NULL;
121 irq_desc[i].depth = 1; 176 irq_desc[i].depth = 1;
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 519b8f18eedf..876aff71cd2e 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1186,8 +1186,14 @@ void __init per_cpu_trap_init(void)
1186 /* Setting vector spacing enables EI/VI mode */ 1186 /* Setting vector spacing enables EI/VI mode */
1187 change_c0_intctl (0x3e0, VECTORSPACING); 1187 change_c0_intctl (0x3e0, VECTORSPACING);
1188 } 1188 }
1189 if (cpu_has_divec) 1189 if (cpu_has_divec) {
1190 set_c0_cause(CAUSEF_IV); 1190 if (cpu_has_mipsmt) {
1191 unsigned int vpflags = dvpe();
1192 set_c0_cause(CAUSEF_IV);
1193 evpe(vpflags);
1194 } else
1195 set_c0_cause(CAUSEF_IV);
1196 }
1191 1197
1192 cpu_data[cpu].asid_cache = ASID_FIRST_VERSION; 1198 cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
1193 TLBMISS_HANDLER_SETUP(); 1199 TLBMISS_HANDLER_SETUP();