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/sgi-ip22/ip22-int.c | |
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/sgi-ip22/ip22-int.c')
-rw-r--r-- | arch/mips/sgi-ip22/ip22-int.c | 59 |
1 files changed, 53 insertions, 6 deletions
diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c index d16fb43b1a93..fc6a7e2b189c 100644 --- a/arch/mips/sgi-ip22/ip22-int.c +++ b/arch/mips/sgi-ip22/ip22-int.c | |||
@@ -37,7 +37,6 @@ static char lc1msk_to_irqnr[256]; | |||
37 | static char lc2msk_to_irqnr[256]; | 37 | static char lc2msk_to_irqnr[256]; |
38 | static char lc3msk_to_irqnr[256]; | 38 | static char lc3msk_to_irqnr[256]; |
39 | 39 | ||
40 | extern asmlinkage void indyIRQ(void); | ||
41 | extern int ip22_eisa_init(void); | 40 | extern int ip22_eisa_init(void); |
42 | 41 | ||
43 | static void enable_local0_irq(unsigned int irq) | 42 | static void enable_local0_irq(unsigned int irq) |
@@ -224,7 +223,7 @@ static struct hw_interrupt_type ip22_local3_irq_type = { | |||
224 | .end = end_local3_irq, | 223 | .end = end_local3_irq, |
225 | }; | 224 | }; |
226 | 225 | ||
227 | void indy_local0_irqdispatch(struct pt_regs *regs) | 226 | static void indy_local0_irqdispatch(struct pt_regs *regs) |
228 | { | 227 | { |
229 | u8 mask = sgint->istat0 & sgint->imask0; | 228 | u8 mask = sgint->istat0 & sgint->imask0; |
230 | u8 mask2; | 229 | u8 mask2; |
@@ -242,7 +241,7 @@ void indy_local0_irqdispatch(struct pt_regs *regs) | |||
242 | return; | 241 | return; |
243 | } | 242 | } |
244 | 243 | ||
245 | void indy_local1_irqdispatch(struct pt_regs *regs) | 244 | static void indy_local1_irqdispatch(struct pt_regs *regs) |
246 | { | 245 | { |
247 | u8 mask = sgint->istat1 & sgint->imask1; | 246 | u8 mask = sgint->istat1 & sgint->imask1; |
248 | u8 mask2; | 247 | u8 mask2; |
@@ -262,7 +261,7 @@ void indy_local1_irqdispatch(struct pt_regs *regs) | |||
262 | 261 | ||
263 | extern void ip22_be_interrupt(int irq, struct pt_regs *regs); | 262 | extern void ip22_be_interrupt(int irq, struct pt_regs *regs); |
264 | 263 | ||
265 | void indy_buserror_irq(struct pt_regs *regs) | 264 | static void indy_buserror_irq(struct pt_regs *regs) |
266 | { | 265 | { |
267 | int irq = SGI_BUSERR_IRQ; | 266 | int irq = SGI_BUSERR_IRQ; |
268 | 267 | ||
@@ -307,6 +306,56 @@ static struct irqaction map1_cascade = { | |||
307 | #define SGI_INTERRUPTS SGINT_LOCAL3 | 306 | #define SGI_INTERRUPTS SGINT_LOCAL3 |
308 | #endif | 307 | #endif |
309 | 308 | ||
309 | extern void indy_r4k_timer_interrupt(struct pt_regs *regs); | ||
310 | extern void indy_8254timer_irq(struct pt_regs *regs); | ||
311 | |||
312 | /* | ||
313 | * IRQs on the INDY look basically (barring software IRQs which we don't use | ||
314 | * at all) like: | ||
315 | * | ||
316 | * MIPS IRQ Source | ||
317 | * -------- ------ | ||
318 | * 0 Software (ignored) | ||
319 | * 1 Software (ignored) | ||
320 | * 2 Local IRQ level zero | ||
321 | * 3 Local IRQ level one | ||
322 | * 4 8254 Timer zero | ||
323 | * 5 8254 Timer one | ||
324 | * 6 Bus Error | ||
325 | * 7 R4k timer (what we use) | ||
326 | * | ||
327 | * We handle the IRQ according to _our_ priority which is: | ||
328 | * | ||
329 | * Highest ---- R4k Timer | ||
330 | * Local IRQ zero | ||
331 | * Local IRQ one | ||
332 | * Bus Error | ||
333 | * 8254 Timer zero | ||
334 | * Lowest ---- 8254 Timer one | ||
335 | * | ||
336 | * then we just return, if multiple IRQs are pending then we will just take | ||
337 | * another exception, big deal. | ||
338 | */ | ||
339 | |||
340 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
341 | { | ||
342 | unsigned int pending = read_c0_cause(); | ||
343 | |||
344 | /* | ||
345 | * First we check for r4k counter/timer IRQ. | ||
346 | */ | ||
347 | if (pending & CAUSEF_IP7) | ||
348 | indy_r4k_timer_interrupt(regs); | ||
349 | else if (pending & CAUSEF_IP2) | ||
350 | indy_local0_irqdispatch(regs); | ||
351 | else if (pending & CAUSEF_IP3) | ||
352 | indy_local1_irqdispatch(regs); | ||
353 | else if (pending & CAUSEF_IP6) | ||
354 | indy_buserror_irq(regs); | ||
355 | else if (pending & (CAUSEF_IP4 | CAUSEF_IP5)) | ||
356 | indy_8254timer_irq(regs); | ||
357 | } | ||
358 | |||
310 | extern void mips_cpu_irq_init(unsigned int irq_base); | 359 | extern void mips_cpu_irq_init(unsigned int irq_base); |
311 | 360 | ||
312 | void __init arch_init_irq(void) | 361 | void __init arch_init_irq(void) |
@@ -369,8 +418,6 @@ void __init arch_init_irq(void) | |||
369 | sgint->cmeimask0 = 0; | 418 | sgint->cmeimask0 = 0; |
370 | sgint->cmeimask1 = 0; | 419 | sgint->cmeimask1 = 0; |
371 | 420 | ||
372 | set_except_vector(0, indyIRQ); | ||
373 | |||
374 | /* init CPU irqs */ | 421 | /* init CPU irqs */ |
375 | mips_cpu_irq_init(SGINT_CPU); | 422 | mips_cpu_irq_init(SGINT_CPU); |
376 | 423 | ||