diff options
Diffstat (limited to 'arch/m68k/mac/via.c')
-rw-r--r-- | arch/m68k/mac/via.c | 143 |
1 files changed, 117 insertions, 26 deletions
diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c index bde156caa46d..b8156ac496a0 100644 --- a/arch/m68k/mac/via.c +++ b/arch/m68k/mac/via.c | |||
@@ -80,9 +80,6 @@ static int gIER,gIFR,gBufA,gBufB; | |||
80 | static u8 nubus_disabled; | 80 | static u8 nubus_disabled; |
81 | 81 | ||
82 | void via_debug_dump(void); | 82 | void via_debug_dump(void); |
83 | irqreturn_t via1_irq(int, void *); | ||
84 | irqreturn_t via2_irq(int, void *); | ||
85 | irqreturn_t via_nubus_irq(int, void *); | ||
86 | void via_irq_enable(int irq); | 83 | void via_irq_enable(int irq); |
87 | void via_irq_disable(int irq); | 84 | void via_irq_disable(int irq); |
88 | void via_irq_clear(int irq); | 85 | void via_irq_clear(int irq); |
@@ -289,29 +286,6 @@ void __init via_init_clock(irq_handler_t func) | |||
289 | } | 286 | } |
290 | 287 | ||
291 | /* | 288 | /* |
292 | * Register the interrupt dispatchers for VIA or RBV machines only. | ||
293 | */ | ||
294 | |||
295 | void __init via_register_interrupts(void) | ||
296 | { | ||
297 | if (via_alt_mapping) { | ||
298 | if (request_irq(IRQ_AUTO_1, via1_irq, 0, "software", | ||
299 | (void *)via1)) | ||
300 | pr_err("Couldn't register %s interrupt\n", "software"); | ||
301 | if (request_irq(IRQ_AUTO_6, via1_irq, 0, "via1", (void *)via1)) | ||
302 | pr_err("Couldn't register %s interrupt\n", "via1"); | ||
303 | } else { | ||
304 | if (request_irq(IRQ_AUTO_1, via1_irq, 0, "via1", (void *)via1)) | ||
305 | pr_err("Couldn't register %s interrupt\n", "via1"); | ||
306 | } | ||
307 | if (request_irq(IRQ_AUTO_2, via2_irq, 0, "via2", (void *)via2)) | ||
308 | pr_err("Couldn't register %s interrupt\n", "via2"); | ||
309 | if (request_irq(IRQ_MAC_NUBUS, via_nubus_irq, 0, "nubus", | ||
310 | (void *)via2)) | ||
311 | pr_err("Couldn't register %s interrupt\n", "nubus"); | ||
312 | } | ||
313 | |||
314 | /* | ||
315 | * Debugging dump, used in various places to see what's going on. | 289 | * Debugging dump, used in various places to see what's going on. |
316 | */ | 290 | */ |
317 | 291 | ||
@@ -443,6 +417,49 @@ void __init via_nubus_init(void) | |||
443 | * via6522.c :-), disable/pending masks added. | 417 | * via6522.c :-), disable/pending masks added. |
444 | */ | 418 | */ |
445 | 419 | ||
420 | #ifdef CONFIG_GENERIC_HARDIRQS | ||
421 | void via1_irq(unsigned int irq, struct irq_desc *desc) | ||
422 | { | ||
423 | int irq_num; | ||
424 | unsigned char irq_bit, events; | ||
425 | |||
426 | events = via1[vIFR] & via1[vIER] & 0x7F; | ||
427 | if (!events) | ||
428 | return; | ||
429 | |||
430 | irq_num = VIA1_SOURCE_BASE; | ||
431 | irq_bit = 1; | ||
432 | do { | ||
433 | if (events & irq_bit) { | ||
434 | via1[vIFR] = irq_bit; | ||
435 | generic_handle_irq(irq_num); | ||
436 | } | ||
437 | ++irq_num; | ||
438 | irq_bit <<= 1; | ||
439 | } while (events >= irq_bit); | ||
440 | } | ||
441 | |||
442 | static void via2_irq(unsigned int irq, struct irq_desc *desc) | ||
443 | { | ||
444 | int irq_num; | ||
445 | unsigned char irq_bit, events; | ||
446 | |||
447 | events = via2[gIFR] & via2[gIER] & 0x7F; | ||
448 | if (!events) | ||
449 | return; | ||
450 | |||
451 | irq_num = VIA2_SOURCE_BASE; | ||
452 | irq_bit = 1; | ||
453 | do { | ||
454 | if (events & irq_bit) { | ||
455 | via2[gIFR] = irq_bit | rbv_clear; | ||
456 | generic_handle_irq(irq_num); | ||
457 | } | ||
458 | ++irq_num; | ||
459 | irq_bit <<= 1; | ||
460 | } while (events >= irq_bit); | ||
461 | } | ||
462 | #else | ||
446 | irqreturn_t via1_irq(int irq, void *dev_id) | 463 | irqreturn_t via1_irq(int irq, void *dev_id) |
447 | { | 464 | { |
448 | int irq_num; | 465 | int irq_num; |
@@ -486,12 +503,49 @@ irqreturn_t via2_irq(int irq, void *dev_id) | |||
486 | } while (events >= irq_bit); | 503 | } while (events >= irq_bit); |
487 | return IRQ_HANDLED; | 504 | return IRQ_HANDLED; |
488 | } | 505 | } |
506 | #endif | ||
489 | 507 | ||
490 | /* | 508 | /* |
491 | * Dispatch Nubus interrupts. We are called as a secondary dispatch by the | 509 | * Dispatch Nubus interrupts. We are called as a secondary dispatch by the |
492 | * VIA2 dispatcher as a fast interrupt handler. | 510 | * VIA2 dispatcher as a fast interrupt handler. |
493 | */ | 511 | */ |
494 | 512 | ||
513 | #ifdef CONFIG_GENERIC_HARDIRQS | ||
514 | void via_nubus_irq(unsigned int irq, struct irq_desc *desc) | ||
515 | { | ||
516 | int slot_irq; | ||
517 | unsigned char slot_bit, events; | ||
518 | |||
519 | events = ~via2[gBufA] & 0x7F; | ||
520 | if (rbv_present) | ||
521 | events &= via2[rSIER]; | ||
522 | else | ||
523 | events &= ~via2[vDirA]; | ||
524 | if (!events) | ||
525 | return; | ||
526 | |||
527 | do { | ||
528 | slot_irq = IRQ_NUBUS_F; | ||
529 | slot_bit = 0x40; | ||
530 | do { | ||
531 | if (events & slot_bit) { | ||
532 | events &= ~slot_bit; | ||
533 | generic_handle_irq(slot_irq); | ||
534 | } | ||
535 | --slot_irq; | ||
536 | slot_bit >>= 1; | ||
537 | } while (events); | ||
538 | |||
539 | /* clear the CA1 interrupt and make certain there's no more. */ | ||
540 | via2[gIFR] = 0x02 | rbv_clear; | ||
541 | events = ~via2[gBufA] & 0x7F; | ||
542 | if (rbv_present) | ||
543 | events &= via2[rSIER]; | ||
544 | else | ||
545 | events &= ~via2[vDirA]; | ||
546 | } while (events); | ||
547 | } | ||
548 | #else | ||
495 | irqreturn_t via_nubus_irq(int irq, void *dev_id) | 549 | irqreturn_t via_nubus_irq(int irq, void *dev_id) |
496 | { | 550 | { |
497 | int slot_irq; | 551 | int slot_irq; |
@@ -527,6 +581,43 @@ irqreturn_t via_nubus_irq(int irq, void *dev_id) | |||
527 | } while (events); | 581 | } while (events); |
528 | return IRQ_HANDLED; | 582 | return IRQ_HANDLED; |
529 | } | 583 | } |
584 | #endif | ||
585 | |||
586 | /* | ||
587 | * Register the interrupt dispatchers for VIA or RBV machines only. | ||
588 | */ | ||
589 | |||
590 | void __init via_register_interrupts(void) | ||
591 | { | ||
592 | #ifdef CONFIG_GENERIC_HARDIRQS | ||
593 | if (via_alt_mapping) { | ||
594 | /* software interrupt */ | ||
595 | irq_set_chained_handler(IRQ_AUTO_1, via1_irq); | ||
596 | /* via1 interrupt */ | ||
597 | irq_set_chained_handler(IRQ_AUTO_6, via1_irq); | ||
598 | } else { | ||
599 | irq_set_chained_handler(IRQ_AUTO_1, via1_irq); | ||
600 | } | ||
601 | irq_set_chained_handler(IRQ_AUTO_2, via2_irq); | ||
602 | irq_set_chained_handler(IRQ_MAC_NUBUS, via_nubus_irq); | ||
603 | #else | ||
604 | if (via_alt_mapping) { | ||
605 | if (request_irq(IRQ_AUTO_1, via1_irq, 0, "software", | ||
606 | (void *)via1)) | ||
607 | pr_err("Couldn't register %s interrupt\n", "software"); | ||
608 | if (request_irq(IRQ_AUTO_6, via1_irq, 0, "via1", (void *)via1)) | ||
609 | pr_err("Couldn't register %s interrupt\n", "via1"); | ||
610 | } else { | ||
611 | if (request_irq(IRQ_AUTO_1, via1_irq, 0, "via1", (void *)via1)) | ||
612 | pr_err("Couldn't register %s interrupt\n", "via1"); | ||
613 | } | ||
614 | if (request_irq(IRQ_AUTO_2, via2_irq, 0, "via2", (void *)via2)) | ||
615 | pr_err("Couldn't register %s interrupt\n", "via2"); | ||
616 | if (request_irq(IRQ_MAC_NUBUS, via_nubus_irq, 0, "nubus", | ||
617 | (void *)via2)) | ||
618 | pr_err("Couldn't register %s interrupt\n", "nubus"); | ||
619 | #endif | ||
620 | } | ||
530 | 621 | ||
531 | void via_irq_enable(int irq) { | 622 | void via_irq_enable(int irq) { |
532 | int irq_src = IRQ_SRC(irq); | 623 | int irq_src = IRQ_SRC(irq); |