diff options
Diffstat (limited to 'arch/mips/sgi-ip32/ip32-irq.c')
-rw-r--r-- | arch/mips/sgi-ip32/ip32-irq.c | 133 |
1 files changed, 20 insertions, 113 deletions
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index c9acadd0846b..ae063864c026 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c | |||
@@ -113,12 +113,6 @@ static void inline flush_mace_bus(void) | |||
113 | * is quite different anyway. | 113 | * is quite different anyway. |
114 | */ | 114 | */ |
115 | 115 | ||
116 | /* | ||
117 | * IRQ spinlock - Ralf says not to disable CPU interrupts, | ||
118 | * and I think he knows better. | ||
119 | */ | ||
120 | static DEFINE_SPINLOCK(ip32_irq_lock); | ||
121 | |||
122 | /* Some initial interrupts to set up */ | 116 | /* Some initial interrupts to set up */ |
123 | extern irqreturn_t crime_memerr_intr(int irq, void *dev_id); | 117 | extern irqreturn_t crime_memerr_intr(int irq, void *dev_id); |
124 | extern irqreturn_t crime_cpuerr_intr(int irq, void *dev_id); | 118 | extern irqreturn_t crime_cpuerr_intr(int irq, void *dev_id); |
@@ -138,12 +132,6 @@ static void enable_cpu_irq(unsigned int irq) | |||
138 | set_c0_status(STATUSF_IP7); | 132 | set_c0_status(STATUSF_IP7); |
139 | } | 133 | } |
140 | 134 | ||
141 | static unsigned int startup_cpu_irq(unsigned int irq) | ||
142 | { | ||
143 | enable_cpu_irq(irq); | ||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | static void disable_cpu_irq(unsigned int irq) | 135 | static void disable_cpu_irq(unsigned int irq) |
148 | { | 136 | { |
149 | clear_c0_status(STATUSF_IP7); | 137 | clear_c0_status(STATUSF_IP7); |
@@ -155,16 +143,12 @@ static void end_cpu_irq(unsigned int irq) | |||
155 | enable_cpu_irq (irq); | 143 | enable_cpu_irq (irq); |
156 | } | 144 | } |
157 | 145 | ||
158 | #define shutdown_cpu_irq disable_cpu_irq | ||
159 | #define mask_and_ack_cpu_irq disable_cpu_irq | ||
160 | |||
161 | static struct irq_chip ip32_cpu_interrupt = { | 146 | static struct irq_chip ip32_cpu_interrupt = { |
162 | .typename = "IP32 CPU", | 147 | .typename = "IP32 CPU", |
163 | .startup = startup_cpu_irq, | 148 | .ack = disable_cpu_irq, |
164 | .shutdown = shutdown_cpu_irq, | 149 | .mask = disable_cpu_irq, |
165 | .enable = enable_cpu_irq, | 150 | .mask_ack = disable_cpu_irq, |
166 | .disable = disable_cpu_irq, | 151 | .unmask = enable_cpu_irq, |
167 | .ack = mask_and_ack_cpu_irq, | ||
168 | .end = end_cpu_irq, | 152 | .end = end_cpu_irq, |
169 | }; | 153 | }; |
170 | 154 | ||
@@ -177,45 +161,27 @@ static uint64_t crime_mask; | |||
177 | 161 | ||
178 | static void enable_crime_irq(unsigned int irq) | 162 | static void enable_crime_irq(unsigned int irq) |
179 | { | 163 | { |
180 | unsigned long flags; | ||
181 | |||
182 | spin_lock_irqsave(&ip32_irq_lock, flags); | ||
183 | crime_mask |= 1 << (irq - 1); | 164 | crime_mask |= 1 << (irq - 1); |
184 | crime->imask = crime_mask; | 165 | crime->imask = crime_mask; |
185 | spin_unlock_irqrestore(&ip32_irq_lock, flags); | ||
186 | } | ||
187 | |||
188 | static unsigned int startup_crime_irq(unsigned int irq) | ||
189 | { | ||
190 | enable_crime_irq(irq); | ||
191 | return 0; /* This is probably not right; we could have pending irqs */ | ||
192 | } | 166 | } |
193 | 167 | ||
194 | static void disable_crime_irq(unsigned int irq) | 168 | static void disable_crime_irq(unsigned int irq) |
195 | { | 169 | { |
196 | unsigned long flags; | ||
197 | |||
198 | spin_lock_irqsave(&ip32_irq_lock, flags); | ||
199 | crime_mask &= ~(1 << (irq - 1)); | 170 | crime_mask &= ~(1 << (irq - 1)); |
200 | crime->imask = crime_mask; | 171 | crime->imask = crime_mask; |
201 | flush_crime_bus(); | 172 | flush_crime_bus(); |
202 | spin_unlock_irqrestore(&ip32_irq_lock, flags); | ||
203 | } | 173 | } |
204 | 174 | ||
205 | static void mask_and_ack_crime_irq(unsigned int irq) | 175 | static void mask_and_ack_crime_irq(unsigned int irq) |
206 | { | 176 | { |
207 | unsigned long flags; | ||
208 | |||
209 | /* Edge triggered interrupts must be cleared. */ | 177 | /* Edge triggered interrupts must be cleared. */ |
210 | if ((irq >= CRIME_GBE0_IRQ && irq <= CRIME_GBE3_IRQ) | 178 | if ((irq >= CRIME_GBE0_IRQ && irq <= CRIME_GBE3_IRQ) |
211 | || (irq >= CRIME_RE_EMPTY_E_IRQ && irq <= CRIME_RE_IDLE_E_IRQ) | 179 | || (irq >= CRIME_RE_EMPTY_E_IRQ && irq <= CRIME_RE_IDLE_E_IRQ) |
212 | || (irq >= CRIME_SOFT0_IRQ && irq <= CRIME_SOFT2_IRQ)) { | 180 | || (irq >= CRIME_SOFT0_IRQ && irq <= CRIME_SOFT2_IRQ)) { |
213 | uint64_t crime_int; | 181 | uint64_t crime_int; |
214 | spin_lock_irqsave(&ip32_irq_lock, flags); | ||
215 | crime_int = crime->hard_int; | 182 | crime_int = crime->hard_int; |
216 | crime_int &= ~(1 << (irq - 1)); | 183 | crime_int &= ~(1 << (irq - 1)); |
217 | crime->hard_int = crime_int; | 184 | crime->hard_int = crime_int; |
218 | spin_unlock_irqrestore(&ip32_irq_lock, flags); | ||
219 | } | 185 | } |
220 | disable_crime_irq(irq); | 186 | disable_crime_irq(irq); |
221 | } | 187 | } |
@@ -226,15 +192,12 @@ static void end_crime_irq(unsigned int irq) | |||
226 | enable_crime_irq(irq); | 192 | enable_crime_irq(irq); |
227 | } | 193 | } |
228 | 194 | ||
229 | #define shutdown_crime_irq disable_crime_irq | ||
230 | |||
231 | static struct irq_chip ip32_crime_interrupt = { | 195 | static struct irq_chip ip32_crime_interrupt = { |
232 | .typename = "IP32 CRIME", | 196 | .typename = "IP32 CRIME", |
233 | .startup = startup_crime_irq, | ||
234 | .shutdown = shutdown_crime_irq, | ||
235 | .enable = enable_crime_irq, | ||
236 | .disable = disable_crime_irq, | ||
237 | .ack = mask_and_ack_crime_irq, | 197 | .ack = mask_and_ack_crime_irq, |
198 | .mask = disable_crime_irq, | ||
199 | .mask_ack = mask_and_ack_crime_irq, | ||
200 | .unmask = enable_crime_irq, | ||
238 | .end = end_crime_irq, | 201 | .end = end_crime_irq, |
239 | }; | 202 | }; |
240 | 203 | ||
@@ -248,34 +211,20 @@ static unsigned long macepci_mask; | |||
248 | 211 | ||
249 | static void enable_macepci_irq(unsigned int irq) | 212 | static void enable_macepci_irq(unsigned int irq) |
250 | { | 213 | { |
251 | unsigned long flags; | ||
252 | |||
253 | spin_lock_irqsave(&ip32_irq_lock, flags); | ||
254 | macepci_mask |= MACEPCI_CONTROL_INT(irq - 9); | 214 | macepci_mask |= MACEPCI_CONTROL_INT(irq - 9); |
255 | mace->pci.control = macepci_mask; | 215 | mace->pci.control = macepci_mask; |
256 | crime_mask |= 1 << (irq - 1); | 216 | crime_mask |= 1 << (irq - 1); |
257 | crime->imask = crime_mask; | 217 | crime->imask = crime_mask; |
258 | spin_unlock_irqrestore(&ip32_irq_lock, flags); | ||
259 | } | ||
260 | |||
261 | static unsigned int startup_macepci_irq(unsigned int irq) | ||
262 | { | ||
263 | enable_macepci_irq (irq); | ||
264 | return 0; | ||
265 | } | 218 | } |
266 | 219 | ||
267 | static void disable_macepci_irq(unsigned int irq) | 220 | static void disable_macepci_irq(unsigned int irq) |
268 | { | 221 | { |
269 | unsigned long flags; | ||
270 | |||
271 | spin_lock_irqsave(&ip32_irq_lock, flags); | ||
272 | crime_mask &= ~(1 << (irq - 1)); | 222 | crime_mask &= ~(1 << (irq - 1)); |
273 | crime->imask = crime_mask; | 223 | crime->imask = crime_mask; |
274 | flush_crime_bus(); | 224 | flush_crime_bus(); |
275 | macepci_mask &= ~MACEPCI_CONTROL_INT(irq - 9); | 225 | macepci_mask &= ~MACEPCI_CONTROL_INT(irq - 9); |
276 | mace->pci.control = macepci_mask; | 226 | mace->pci.control = macepci_mask; |
277 | flush_mace_bus(); | 227 | flush_mace_bus(); |
278 | spin_unlock_irqrestore(&ip32_irq_lock, flags); | ||
279 | } | 228 | } |
280 | 229 | ||
281 | static void end_macepci_irq(unsigned int irq) | 230 | static void end_macepci_irq(unsigned int irq) |
@@ -284,16 +233,12 @@ static void end_macepci_irq(unsigned int irq) | |||
284 | enable_macepci_irq(irq); | 233 | enable_macepci_irq(irq); |
285 | } | 234 | } |
286 | 235 | ||
287 | #define shutdown_macepci_irq disable_macepci_irq | ||
288 | #define mask_and_ack_macepci_irq disable_macepci_irq | ||
289 | |||
290 | static struct irq_chip ip32_macepci_interrupt = { | 236 | static struct irq_chip ip32_macepci_interrupt = { |
291 | .typename = "IP32 MACE PCI", | 237 | .typename = "IP32 MACE PCI", |
292 | .startup = startup_macepci_irq, | 238 | .ack = disable_macepci_irq, |
293 | .shutdown = shutdown_macepci_irq, | 239 | .mask = disable_macepci_irq, |
294 | .enable = enable_macepci_irq, | 240 | .mask_ack = disable_macepci_irq, |
295 | .disable = disable_macepci_irq, | 241 | .unmask = enable_macepci_irq, |
296 | .ack = mask_and_ack_macepci_irq, | ||
297 | .end = end_macepci_irq, | 242 | .end = end_macepci_irq, |
298 | }; | 243 | }; |
299 | 244 | ||
@@ -339,7 +284,6 @@ static unsigned long maceisa_mask; | |||
339 | static void enable_maceisa_irq (unsigned int irq) | 284 | static void enable_maceisa_irq (unsigned int irq) |
340 | { | 285 | { |
341 | unsigned int crime_int = 0; | 286 | unsigned int crime_int = 0; |
342 | unsigned long flags; | ||
343 | 287 | ||
344 | DBG ("maceisa enable: %u\n", irq); | 288 | DBG ("maceisa enable: %u\n", irq); |
345 | 289 | ||
@@ -355,26 +299,16 @@ static void enable_maceisa_irq (unsigned int irq) | |||
355 | break; | 299 | break; |
356 | } | 300 | } |
357 | DBG ("crime_int %08x enabled\n", crime_int); | 301 | DBG ("crime_int %08x enabled\n", crime_int); |
358 | spin_lock_irqsave(&ip32_irq_lock, flags); | ||
359 | crime_mask |= crime_int; | 302 | crime_mask |= crime_int; |
360 | crime->imask = crime_mask; | 303 | crime->imask = crime_mask; |
361 | maceisa_mask |= 1 << (irq - 33); | 304 | maceisa_mask |= 1 << (irq - 33); |
362 | mace->perif.ctrl.imask = maceisa_mask; | 305 | mace->perif.ctrl.imask = maceisa_mask; |
363 | spin_unlock_irqrestore(&ip32_irq_lock, flags); | ||
364 | } | ||
365 | |||
366 | static unsigned int startup_maceisa_irq(unsigned int irq) | ||
367 | { | ||
368 | enable_maceisa_irq(irq); | ||
369 | return 0; | ||
370 | } | 306 | } |
371 | 307 | ||
372 | static void disable_maceisa_irq(unsigned int irq) | 308 | static void disable_maceisa_irq(unsigned int irq) |
373 | { | 309 | { |
374 | unsigned int crime_int = 0; | 310 | unsigned int crime_int = 0; |
375 | unsigned long flags; | ||
376 | 311 | ||
377 | spin_lock_irqsave(&ip32_irq_lock, flags); | ||
378 | maceisa_mask &= ~(1 << (irq - 33)); | 312 | maceisa_mask &= ~(1 << (irq - 33)); |
379 | if(!(maceisa_mask & MACEISA_AUDIO_INT)) | 313 | if(!(maceisa_mask & MACEISA_AUDIO_INT)) |
380 | crime_int |= MACE_AUDIO_INT; | 314 | crime_int |= MACE_AUDIO_INT; |
@@ -387,23 +321,20 @@ static void disable_maceisa_irq(unsigned int irq) | |||
387 | flush_crime_bus(); | 321 | flush_crime_bus(); |
388 | mace->perif.ctrl.imask = maceisa_mask; | 322 | mace->perif.ctrl.imask = maceisa_mask; |
389 | flush_mace_bus(); | 323 | flush_mace_bus(); |
390 | spin_unlock_irqrestore(&ip32_irq_lock, flags); | ||
391 | } | 324 | } |
392 | 325 | ||
393 | static void mask_and_ack_maceisa_irq(unsigned int irq) | 326 | static void mask_and_ack_maceisa_irq(unsigned int irq) |
394 | { | 327 | { |
395 | unsigned long mace_int, flags; | 328 | unsigned long mace_int; |
396 | 329 | ||
397 | switch (irq) { | 330 | switch (irq) { |
398 | case MACEISA_PARALLEL_IRQ: | 331 | case MACEISA_PARALLEL_IRQ: |
399 | case MACEISA_SERIAL1_TDMAPR_IRQ: | 332 | case MACEISA_SERIAL1_TDMAPR_IRQ: |
400 | case MACEISA_SERIAL2_TDMAPR_IRQ: | 333 | case MACEISA_SERIAL2_TDMAPR_IRQ: |
401 | /* edge triggered */ | 334 | /* edge triggered */ |
402 | spin_lock_irqsave(&ip32_irq_lock, flags); | ||
403 | mace_int = mace->perif.ctrl.istat; | 335 | mace_int = mace->perif.ctrl.istat; |
404 | mace_int &= ~(1 << (irq - 33)); | 336 | mace_int &= ~(1 << (irq - 33)); |
405 | mace->perif.ctrl.istat = mace_int; | 337 | mace->perif.ctrl.istat = mace_int; |
406 | spin_unlock_irqrestore(&ip32_irq_lock, flags); | ||
407 | break; | 338 | break; |
408 | } | 339 | } |
409 | disable_maceisa_irq(irq); | 340 | disable_maceisa_irq(irq); |
@@ -415,15 +346,12 @@ static void end_maceisa_irq(unsigned irq) | |||
415 | enable_maceisa_irq(irq); | 346 | enable_maceisa_irq(irq); |
416 | } | 347 | } |
417 | 348 | ||
418 | #define shutdown_maceisa_irq disable_maceisa_irq | ||
419 | |||
420 | static struct irq_chip ip32_maceisa_interrupt = { | 349 | static struct irq_chip ip32_maceisa_interrupt = { |
421 | .typename = "IP32 MACE ISA", | 350 | .typename = "IP32 MACE ISA", |
422 | .startup = startup_maceisa_irq, | ||
423 | .shutdown = shutdown_maceisa_irq, | ||
424 | .enable = enable_maceisa_irq, | ||
425 | .disable = disable_maceisa_irq, | ||
426 | .ack = mask_and_ack_maceisa_irq, | 351 | .ack = mask_and_ack_maceisa_irq, |
352 | .mask = disable_maceisa_irq, | ||
353 | .mask_ack = mask_and_ack_maceisa_irq, | ||
354 | .unmask = enable_maceisa_irq, | ||
427 | .end = end_maceisa_irq, | 355 | .end = end_maceisa_irq, |
428 | }; | 356 | }; |
429 | 357 | ||
@@ -433,29 +361,15 @@ static struct irq_chip ip32_maceisa_interrupt = { | |||
433 | 361 | ||
434 | static void enable_mace_irq(unsigned int irq) | 362 | static void enable_mace_irq(unsigned int irq) |
435 | { | 363 | { |
436 | unsigned long flags; | ||
437 | |||
438 | spin_lock_irqsave(&ip32_irq_lock, flags); | ||
439 | crime_mask |= 1 << (irq - 1); | 364 | crime_mask |= 1 << (irq - 1); |
440 | crime->imask = crime_mask; | 365 | crime->imask = crime_mask; |
441 | spin_unlock_irqrestore(&ip32_irq_lock, flags); | ||
442 | } | ||
443 | |||
444 | static unsigned int startup_mace_irq(unsigned int irq) | ||
445 | { | ||
446 | enable_mace_irq(irq); | ||
447 | return 0; | ||
448 | } | 366 | } |
449 | 367 | ||
450 | static void disable_mace_irq(unsigned int irq) | 368 | static void disable_mace_irq(unsigned int irq) |
451 | { | 369 | { |
452 | unsigned long flags; | ||
453 | |||
454 | spin_lock_irqsave(&ip32_irq_lock, flags); | ||
455 | crime_mask &= ~(1 << (irq - 1)); | 370 | crime_mask &= ~(1 << (irq - 1)); |
456 | crime->imask = crime_mask; | 371 | crime->imask = crime_mask; |
457 | flush_crime_bus(); | 372 | flush_crime_bus(); |
458 | spin_unlock_irqrestore(&ip32_irq_lock, flags); | ||
459 | } | 373 | } |
460 | 374 | ||
461 | static void end_mace_irq(unsigned int irq) | 375 | static void end_mace_irq(unsigned int irq) |
@@ -464,16 +378,12 @@ static void end_mace_irq(unsigned int irq) | |||
464 | enable_mace_irq(irq); | 378 | enable_mace_irq(irq); |
465 | } | 379 | } |
466 | 380 | ||
467 | #define shutdown_mace_irq disable_mace_irq | ||
468 | #define mask_and_ack_mace_irq disable_mace_irq | ||
469 | |||
470 | static struct irq_chip ip32_mace_interrupt = { | 381 | static struct irq_chip ip32_mace_interrupt = { |
471 | .typename = "IP32 MACE", | 382 | .typename = "IP32 MACE", |
472 | .startup = startup_mace_irq, | 383 | .ack = disable_mace_irq, |
473 | .shutdown = shutdown_mace_irq, | 384 | .mask = disable_mace_irq, |
474 | .enable = enable_mace_irq, | 385 | .mask_ack = disable_mace_irq, |
475 | .disable = disable_mace_irq, | 386 | .unmask = enable_mace_irq, |
476 | .ack = mask_and_ack_mace_irq, | ||
477 | .end = end_mace_irq, | 387 | .end = end_mace_irq, |
478 | }; | 388 | }; |
479 | 389 | ||
@@ -586,10 +496,7 @@ void __init arch_init_irq(void) | |||
586 | else | 496 | else |
587 | controller = &ip32_maceisa_interrupt; | 497 | controller = &ip32_maceisa_interrupt; |
588 | 498 | ||
589 | irq_desc[irq].status = IRQ_DISABLED; | 499 | set_irq_chip(irq, controller); |
590 | irq_desc[irq].action = 0; | ||
591 | irq_desc[irq].depth = 0; | ||
592 | irq_desc[irq].chip = controller; | ||
593 | } | 500 | } |
594 | setup_irq(CRIME_MEMERR_IRQ, &memerr_irq); | 501 | setup_irq(CRIME_MEMERR_IRQ, &memerr_irq); |
595 | setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq); | 502 | setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq); |