aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68k/mac/via.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m68k/mac/via.c')
-rw-r--r--arch/m68k/mac/via.c143
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;
80static u8 nubus_disabled; 80static u8 nubus_disabled;
81 81
82void via_debug_dump(void); 82void via_debug_dump(void);
83irqreturn_t via1_irq(int, void *);
84irqreturn_t via2_irq(int, void *);
85irqreturn_t via_nubus_irq(int, void *);
86void via_irq_enable(int irq); 83void via_irq_enable(int irq);
87void via_irq_disable(int irq); 84void via_irq_disable(int irq);
88void via_irq_clear(int irq); 85void 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
295void __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
421void 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
442static 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
446irqreturn_t via1_irq(int irq, void *dev_id) 463irqreturn_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
514void 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
495irqreturn_t via_nubus_irq(int irq, void *dev_id) 549irqreturn_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
590void __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
531void via_irq_enable(int irq) { 622void via_irq_enable(int irq) {
532 int irq_src = IRQ_SRC(irq); 623 int irq_src = IRQ_SRC(irq);