diff options
Diffstat (limited to 'arch/mips/sgi-ip22')
-rw-r--r-- | arch/mips/sgi-ip22/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/sgi-ip22/ip22-int.c | 59 | ||||
-rw-r--r-- | arch/mips/sgi-ip22/ip22-irq.S | 118 |
3 files changed, 54 insertions, 125 deletions
diff --git a/arch/mips/sgi-ip22/Makefile b/arch/mips/sgi-ip22/Makefile index eb0820fe50bd..6aa4c0cd169c 100644 --- a/arch/mips/sgi-ip22/Makefile +++ b/arch/mips/sgi-ip22/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # under Linux. | 3 | # under Linux. |
4 | # | 4 | # |
5 | 5 | ||
6 | obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-irq.o ip22-berr.o \ | 6 | obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-berr.o \ |
7 | ip22-time.o ip22-nvram.o ip22-reset.o ip22-setup.o | 7 | ip22-time.o ip22-nvram.o ip22-reset.o ip22-setup.o |
8 | 8 | ||
9 | obj-$(CONFIG_EISA) += ip22-eisa.o | 9 | obj-$(CONFIG_EISA) += ip22-eisa.o |
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 | ||
diff --git a/arch/mips/sgi-ip22/ip22-irq.S b/arch/mips/sgi-ip22/ip22-irq.S deleted file mode 100644 index 6ccbd9e1d967..000000000000 --- a/arch/mips/sgi-ip22/ip22-irq.S +++ /dev/null | |||
@@ -1,118 +0,0 @@ | |||
1 | /* | ||
2 | * ip22-irq.S: Interrupt exception dispatch code for FullHouse and | ||
3 | * Guiness. | ||
4 | * | ||
5 | * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) | ||
6 | */ | ||
7 | |||
8 | #include <asm/asm.h> | ||
9 | #include <asm/mipsregs.h> | ||
10 | #include <asm/regdef.h> | ||
11 | #include <asm/stackframe.h> | ||
12 | |||
13 | /* A lot of complication here is taken away because: | ||
14 | * | ||
15 | * 1) We handle one interrupt and return, sitting in a loop and moving across | ||
16 | * all the pending IRQ bits in the cause register is _NOT_ the answer, the | ||
17 | * common case is one pending IRQ so optimize in that direction. | ||
18 | * | ||
19 | * 2) We need not check against bits in the status register IRQ mask, that | ||
20 | * would make this routine slow as hell. | ||
21 | * | ||
22 | * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in | ||
23 | * between like BSD spl() brain-damage. | ||
24 | * | ||
25 | * Furthermore, the IRQs on the INDY look basically (barring software IRQs | ||
26 | * which we don't use at all) like: | ||
27 | * | ||
28 | * MIPS IRQ Source | ||
29 | * -------- ------ | ||
30 | * 0 Software (ignored) | ||
31 | * 1 Software (ignored) | ||
32 | * 2 Local IRQ level zero | ||
33 | * 3 Local IRQ level one | ||
34 | * 4 8254 Timer zero | ||
35 | * 5 8254 Timer one | ||
36 | * 6 Bus Error | ||
37 | * 7 R4k timer (what we use) | ||
38 | * | ||
39 | * We handle the IRQ according to _our_ priority which is: | ||
40 | * | ||
41 | * Highest ---- R4k Timer | ||
42 | * Local IRQ zero | ||
43 | * Local IRQ one | ||
44 | * Bus Error | ||
45 | * 8254 Timer zero | ||
46 | * Lowest ---- 8254 Timer one | ||
47 | * | ||
48 | * then we just return, if multiple IRQs are pending then we will just take | ||
49 | * another exception, big deal. | ||
50 | */ | ||
51 | |||
52 | .text | ||
53 | .set noreorder | ||
54 | .set noat | ||
55 | .align 5 | ||
56 | NESTED(indyIRQ, PT_SIZE, sp) | ||
57 | SAVE_ALL | ||
58 | CLI | ||
59 | .set at | ||
60 | mfc0 s0, CP0_CAUSE # get irq mask | ||
61 | |||
62 | /* First we check for r4k counter/timer IRQ. */ | ||
63 | andi a0, s0, CAUSEF_IP7 | ||
64 | beq a0, zero, 1f | ||
65 | andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero | ||
66 | |||
67 | /* Wheee, a timer interrupt. */ | ||
68 | jal indy_r4k_timer_interrupt | ||
69 | move a0, sp # delay slot | ||
70 | j ret_from_irq | ||
71 | nop # delay slot | ||
72 | |||
73 | 1: | ||
74 | beq a0, zero, 1f | ||
75 | andi a0, s0, CAUSEF_IP3 # delay slot, check local level one | ||
76 | |||
77 | /* Wheee, local level zero interrupt. */ | ||
78 | jal indy_local0_irqdispatch | ||
79 | move a0, sp # delay slot | ||
80 | |||
81 | j ret_from_irq | ||
82 | nop # delay slot | ||
83 | |||
84 | 1: | ||
85 | beq a0, zero, 1f | ||
86 | andi a0, s0, CAUSEF_IP6 # delay slot, check bus error | ||
87 | |||
88 | /* Wheee, local level one interrupt. */ | ||
89 | jal indy_local1_irqdispatch | ||
90 | move a0, sp # delay slot | ||
91 | j ret_from_irq | ||
92 | nop # delay slot | ||
93 | |||
94 | 1: | ||
95 | beq a0, zero, 1f | ||
96 | andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5) # delay slot | ||
97 | |||
98 | /* Wheee, an asynchronous bus error... */ | ||
99 | jal indy_buserror_irq | ||
100 | move a0, sp # delay slot | ||
101 | j ret_from_irq | ||
102 | nop # delay slot | ||
103 | |||
104 | 1: | ||
105 | /* Here by mistake? It is possible, that by the time we take | ||
106 | * the exception the IRQ pin goes low, so just leave if this | ||
107 | * is the case. | ||
108 | */ | ||
109 | beq a0, zero, 1f | ||
110 | nop # delay slot | ||
111 | |||
112 | /* Must be one of the 8254 timers... */ | ||
113 | jal indy_8254timer_irq | ||
114 | move a0, sp # delay slot | ||
115 | 1: | ||
116 | j ret_from_irq | ||
117 | nop # delay slot | ||
118 | END(indyIRQ) | ||