aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/m68k/mac/baboon.c12
-rw-r--r--arch/m68k/mac/oss.c8
-rw-r--r--arch/m68k/mac/psc.c19
-rw-r--r--arch/m68k/mac/via.c141
4 files changed, 111 insertions, 69 deletions
diff --git a/arch/m68k/mac/baboon.c b/arch/m68k/mac/baboon.c
index 303a3b56c51c..8ea7498cec37 100644
--- a/arch/m68k/mac/baboon.c
+++ b/arch/m68k/mac/baboon.c
@@ -66,7 +66,7 @@ void __init baboon_register_interrupts(void)
66 66
67irqreturn_t baboon_irq(int irq, void *dev_id) 67irqreturn_t baboon_irq(int irq, void *dev_id)
68{ 68{
69 int irq_bit,i; 69 int irq_bit, irq_num;
70 unsigned char events; 70 unsigned char events;
71 71
72#ifdef DEBUG_IRQS 72#ifdef DEBUG_IRQS
@@ -78,14 +78,18 @@ irqreturn_t baboon_irq(int irq, void *dev_id)
78 if (!(events = baboon->mb_ifr & 0x07)) 78 if (!(events = baboon->mb_ifr & 0x07))
79 return IRQ_NONE; 79 return IRQ_NONE;
80 80
81 for (i = 0, irq_bit = 1 ; i < 3 ; i++, irq_bit <<= 1) { 81 irq_num = IRQ_BABOON_0;
82 irq_bit = 1;
83 do {
82 if (events & irq_bit/* & baboon_active*/) { 84 if (events & irq_bit/* & baboon_active*/) {
83 baboon_active &= ~irq_bit; 85 baboon_active &= ~irq_bit;
84 baboon->mb_ifr &= ~irq_bit; 86 baboon->mb_ifr &= ~irq_bit;
85 m68k_handle_int(IRQ_BABOON_0 + i); 87 m68k_handle_int(irq_num);
86 baboon_active |= irq_bit; 88 baboon_active |= irq_bit;
87 } 89 }
88 } 90 irq_bit <<= 1;
91 irq_num++;
92 } while(events >= irq_bit);
89#if 0 93#if 0
90 if (baboon->mb_ifr & 0x02) macide_ack_intr(NULL); 94 if (baboon->mb_ifr & 0x02) macide_ack_intr(NULL);
91 /* for now we need to smash all interrupts */ 95 /* for now we need to smash all interrupts */
diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c
index 603d5cb72891..6399883ae742 100644
--- a/arch/m68k/mac/oss.c
+++ b/arch/m68k/mac/oss.c
@@ -143,14 +143,18 @@ irqreturn_t oss_nubus_irq(int irq, void *dev_id)
143#endif 143#endif
144 /* There are only six slots on the OSS, not seven */ 144 /* There are only six slots on the OSS, not seven */
145 145
146 for (i = 0, irq_bit = 1 ; i < 6 ; i++, irq_bit <<= 1) { 146 i = 6;
147 irq_bit = 0x40;
148 do {
149 --i;
150 irq_bit >>= 1;
147 if (events & irq_bit) { 151 if (events & irq_bit) {
148 oss->irq_level[i] = OSS_IRQLEV_DISABLED; 152 oss->irq_level[i] = OSS_IRQLEV_DISABLED;
149 oss->irq_pending &= ~irq_bit; 153 oss->irq_pending &= ~irq_bit;
150 m68k_handle_int(NUBUS_SOURCE_BASE + i); 154 m68k_handle_int(NUBUS_SOURCE_BASE + i);
151 oss->irq_level[i] = OSS_IRQLEV_NUBUS; 155 oss->irq_level[i] = OSS_IRQLEV_NUBUS;
152 } 156 }
153 } 157 } while(events & (irq_bit - 1));
154 return IRQ_HANDLED; 158 return IRQ_HANDLED;
155} 159}
156 160
diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c
index 401147985a96..1dba88247c6f 100644
--- a/arch/m68k/mac/psc.c
+++ b/arch/m68k/mac/psc.c
@@ -131,11 +131,8 @@ irqreturn_t psc_irq(int irq, void *dev_id)
131{ 131{
132 int pIFR = pIFRbase + ((int) dev_id); 132 int pIFR = pIFRbase + ((int) dev_id);
133 int pIER = pIERbase + ((int) dev_id); 133 int pIER = pIERbase + ((int) dev_id);
134 int base_irq; 134 int irq_num;
135 int irq_bit,i; 135 unsigned char irq_bit, events;
136 unsigned char events;
137
138 base_irq = irq << 3;
139 136
140#ifdef DEBUG_IRQS 137#ifdef DEBUG_IRQS
141 printk("psc_irq: irq %d pIFR = 0x%02X pIER = 0x%02X\n", 138 printk("psc_irq: irq %d pIFR = 0x%02X pIER = 0x%02X\n",
@@ -146,14 +143,18 @@ irqreturn_t psc_irq(int irq, void *dev_id)
146 if (!events) 143 if (!events)
147 return IRQ_NONE; 144 return IRQ_NONE;
148 145
149 for (i = 0, irq_bit = 1 ; i < 4 ; i++, irq_bit <<= 1) { 146 irq_num = irq << 3;
150 if (events & irq_bit) { 147 irq_bit = 1;
148 do {
149 if (events & irq_bit) {
151 psc_write_byte(pIER, irq_bit); 150 psc_write_byte(pIER, irq_bit);
152 psc_write_byte(pIFR, irq_bit); 151 psc_write_byte(pIFR, irq_bit);
153 m68k_handle_int(base_irq + i); 152 m68k_handle_int(irq_num);
154 psc_write_byte(pIER, irq_bit | 0x80); 153 psc_write_byte(pIER, irq_bit | 0x80);
155 } 154 }
156 } 155 irq_num++;
156 irq_bit <<= 1;
157 } while (events >= irq_bit);
157 return IRQ_HANDLED; 158 return IRQ_HANDLED;
158} 159}
159 160
diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c
index 21b03180d9f4..0c1cc45c570d 100644
--- a/arch/m68k/mac/via.c
+++ b/arch/m68k/mac/via.c
@@ -13,6 +13,10 @@
13 * for info. A full-text web search on 6522 AND VIA will probably also 13 * for info. A full-text web search on 6522 AND VIA will probably also
14 * net some usefulness. <cananian@alumni.princeton.edu> 20apr1999 14 * net some usefulness. <cananian@alumni.princeton.edu> 20apr1999
15 * 15 *
16 * Additional data is here (the SY6522 was used in the Mac II etc):
17 * http://www.6502.org/documents/datasheets/synertek/synertek_sy6522.pdf
18 * http://www.6502.org/documents/datasheets/synertek/synertek_sy6522_programming_reference.pdf
19 *
16 * PRAM/RTC access algorithms are from the NetBSD RTC toolkit version 1.08b 20 * PRAM/RTC access algorithms are from the NetBSD RTC toolkit version 1.08b
17 * by Erik Vogan and adapted to Linux by Joshua M. Thompson (funaho@jurai.org) 21 * by Erik Vogan and adapted to Linux by Joshua M. Thompson (funaho@jurai.org)
18 * 22 *
@@ -37,7 +41,7 @@ volatile __u8 *via1, *via2;
37/* See note in mac_via.h about how this is possibly not useful */ 41/* See note in mac_via.h about how this is possibly not useful */
38volatile long *via_memory_bogon=(long *)&via_memory_bogon; 42volatile long *via_memory_bogon=(long *)&via_memory_bogon;
39#endif 43#endif
40int rbv_present,via_alt_mapping; 44int rbv_present, via_alt_mapping;
41__u8 rbv_clear; 45__u8 rbv_clear;
42 46
43/* 47/*
@@ -138,11 +142,11 @@ void __init via_init(void)
138 142
139 printk(KERN_INFO "VIA2 at %p is ", via2); 143 printk(KERN_INFO "VIA2 at %p is ", via2);
140 if (rbv_present) { 144 if (rbv_present) {
141 printk(KERN_INFO "an RBV\n"); 145 printk("an RBV\n");
142 } else if (oss_present) { 146 } else if (oss_present) {
143 printk(KERN_INFO "an OSS\n"); 147 printk("an OSS\n");
144 } else { 148 } else {
145 printk(KERN_INFO "a 6522 or clone\n"); 149 printk("a 6522 or clone\n");
146 } 150 }
147 151
148#ifdef DEBUG_VIA 152#ifdef DEBUG_VIA
@@ -163,6 +167,7 @@ void __init via_init(void)
163 via1[vT2CL] = 0; 167 via1[vT2CL] = 0;
164 via1[vT2CH] = 0; 168 via1[vT2CH] = 0;
165 via1[vACR] &= 0x3F; 169 via1[vACR] &= 0x3F;
170 via1[vACR] &= ~0x03; /* disable port A & B latches */
166 171
167 /* 172 /*
168 * SE/30: disable video IRQ 173 * SE/30: disable video IRQ
@@ -234,6 +239,22 @@ void __init via_init(void)
234 via2[vT2CL] = 0; 239 via2[vT2CL] = 0;
235 via2[vT2CH] = 0; 240 via2[vT2CH] = 0;
236 via2[vACR] &= 0x3F; 241 via2[vACR] &= 0x3F;
242 via2[vACR] &= ~0x03; /* disable port A & B latches */
243 }
244
245 /*
246 * Set vPCR for SCSI interrupts (but not on RBV)
247 */
248 if (!rbv_present) {
249 if (macintosh_config->scsi_type == MAC_SCSI_OLD) {
250 /* CB2 (IRQ) indep. input, positive edge */
251 /* CA2 (DRQ) indep. input, positive edge */
252 via2[vPCR] = 0x66;
253 } else {
254 /* CB2 (IRQ) indep. input, negative edge */
255 /* CA2 (DRQ) indep. input, negative edge */
256 via2[vPCR] = 0x22;
257 }
237 } 258 }
238} 259}
239 260
@@ -367,19 +388,14 @@ void __init via_nubus_init(void)
367 388
368 /* unlock nubus transactions */ 389 /* unlock nubus transactions */
369 390
370 if (!rbv_present) { 391 if ((macintosh_config->adb_type != MAC_ADB_PB1) &&
392 (macintosh_config->adb_type != MAC_ADB_PB2)) {
371 /* set the line to be an output on non-RBV machines */ 393 /* set the line to be an output on non-RBV machines */
372 if ((macintosh_config->adb_type != MAC_ADB_PB1) && 394 if (!rbv_present)
373 (macintosh_config->adb_type != MAC_ADB_PB2)) {
374 via2[vDirB] |= 0x02; 395 via2[vDirB] |= 0x02;
375 }
376 }
377
378 /* this seems to be an ADB bit on PMU machines */
379 /* according to MkLinux. -- jmt */
380 396
381 if ((macintosh_config->adb_type != MAC_ADB_PB1) && 397 /* this seems to be an ADB bit on PMU machines */
382 (macintosh_config->adb_type != MAC_ADB_PB2)) { 398 /* according to MkLinux. -- jmt */
383 via2[gBufB] |= 0x02; 399 via2[gBufB] |= 0x02;
384 } 400 }
385 401
@@ -420,20 +436,25 @@ void __init via_nubus_init(void)
420 436
421irqreturn_t via1_irq(int irq, void *dev_id) 437irqreturn_t via1_irq(int irq, void *dev_id)
422{ 438{
423 int irq_bit, i; 439 int irq_num;
424 unsigned char events, mask; 440 unsigned char irq_bit, events;
425 441
426 mask = via1[vIER] & 0x7F; 442 events = via1[vIFR] & via1[vIER] & 0x7F;
427 if (!(events = via1[vIFR] & mask)) 443 if (!events)
428 return IRQ_NONE; 444 return IRQ_NONE;
429 445
430 for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) 446 irq_num = VIA1_SOURCE_BASE;
447 irq_bit = 1;
448 do {
431 if (events & irq_bit) { 449 if (events & irq_bit) {
432 via1[vIER] = irq_bit; 450 via1[vIER] = irq_bit;
433 via1[vIFR] = irq_bit; 451 via1[vIFR] = irq_bit;
434 m68k_handle_int(VIA1_SOURCE_BASE + i); 452 m68k_handle_int(irq_num);
435 via1[vIER] = irq_bit | 0x80; 453 via1[vIER] = irq_bit | 0x80;
436 } 454 }
455 ++irq_num;
456 irq_bit <<= 1;
457 } while (events >= irq_bit);
437 458
438#if 0 /* freakin' pmu is doing weird stuff */ 459#if 0 /* freakin' pmu is doing weird stuff */
439 if (!oss_present) { 460 if (!oss_present) {
@@ -454,20 +475,25 @@ irqreturn_t via1_irq(int irq, void *dev_id)
454 475
455irqreturn_t via2_irq(int irq, void *dev_id) 476irqreturn_t via2_irq(int irq, void *dev_id)
456{ 477{
457 int irq_bit, i; 478 int irq_num;
458 unsigned char events, mask; 479 unsigned char irq_bit, events;
459 480
460 mask = via2[gIER] & 0x7F; 481 events = via2[gIFR] & via2[gIER] & 0x7F;
461 if (!(events = via2[gIFR] & mask)) 482 if (!events)
462 return IRQ_NONE; 483 return IRQ_NONE;
463 484
464 for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) 485 irq_num = VIA2_SOURCE_BASE;
486 irq_bit = 1;
487 do {
465 if (events & irq_bit) { 488 if (events & irq_bit) {
466 via2[gIER] = irq_bit; 489 via2[gIER] = irq_bit;
467 via2[gIFR] = irq_bit | rbv_clear; 490 via2[gIFR] = irq_bit | rbv_clear;
468 m68k_handle_int(VIA2_SOURCE_BASE + i); 491 m68k_handle_int(irq_num);
469 via2[gIER] = irq_bit | 0x80; 492 via2[gIER] = irq_bit | 0x80;
470 } 493 }
494 ++irq_num;
495 irq_bit <<= 1;
496 } while (events >= irq_bit);
471 return IRQ_HANDLED; 497 return IRQ_HANDLED;
472} 498}
473 499
@@ -478,19 +504,37 @@ irqreturn_t via2_irq(int irq, void *dev_id)
478 504
479irqreturn_t via_nubus_irq(int irq, void *dev_id) 505irqreturn_t via_nubus_irq(int irq, void *dev_id)
480{ 506{
481 int irq_bit, i; 507 int slot_irq;
482 unsigned char events; 508 unsigned char slot_bit, events;
483 509
484 if (!(events = ~via2[gBufA] & nubus_active)) 510 events = ~via2[gBufA] & 0x7F;
511 if (rbv_present)
512 events &= via2[rSIER];
513 else
514 events &= nubus_active;
515 if (!events)
485 return IRQ_NONE; 516 return IRQ_NONE;
486 517
487 for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) { 518 do {
488 if (events & irq_bit) { 519 slot_irq = IRQ_NUBUS_F;
489 via_irq_disable(NUBUS_SOURCE_BASE + i); 520 slot_bit = 0x40;
490 m68k_handle_int(NUBUS_SOURCE_BASE + i); 521 do {
491 via_irq_enable(NUBUS_SOURCE_BASE + i); 522 if (events & slot_bit) {
492 } 523 events &= ~slot_bit;
493 } 524 m68k_handle_int(slot_irq);
525 }
526 --slot_irq;
527 slot_bit >>= 1;
528 } while (events);
529
530 /* clear the CA1 interrupt and make certain there's no more. */
531 via2[gIFR] = 0x02 | rbv_clear;
532 events = ~via2[gBufA] & 0x7F;
533 if (rbv_present)
534 events &= via2[rSIER];
535 else
536 events &= nubus_active;
537 } while (events);
494 return IRQ_HANDLED; 538 return IRQ_HANDLED;
495} 539}
496 540
@@ -506,20 +550,6 @@ void via_irq_enable(int irq) {
506 if (irq_src == 1) { 550 if (irq_src == 1) {
507 via1[vIER] = irq_bit | 0x80; 551 via1[vIER] = irq_bit | 0x80;
508 } else if (irq_src == 2) { 552 } else if (irq_src == 2) {
509 /*
510 * Set vPCR for SCSI interrupts (but not on RBV)
511 */
512 if ((irq_idx == 0) && !rbv_present) {
513 if (macintosh_config->scsi_type == MAC_SCSI_OLD) {
514 /* CB2 (IRQ) indep. input, positive edge */
515 /* CA2 (DRQ) indep. input, positive edge */
516 via2[vPCR] = 0x66;
517 } else {
518 /* CB2 (IRQ) indep. input, negative edge */
519 /* CA2 (DRQ) indep. input, negative edge */
520 via2[vPCR] = 0x22;
521 }
522 }
523 via2[gIER] = irq_bit | 0x80; 553 via2[gIER] = irq_bit | 0x80;
524 } else if (irq_src == 7) { 554 } else if (irq_src == 7) {
525 nubus_active |= irq_bit; 555 nubus_active |= irq_bit;
@@ -557,9 +587,9 @@ void via_irq_disable(int irq) {
557#endif 587#endif
558 588
559 if (irq_src == 1) { 589 if (irq_src == 1) {
560 via1[vIER] = irq_bit; 590 via1[vIER] = irq_bit & 0x7F;
561 } else if (irq_src == 2) { 591 } else if (irq_src == 2) {
562 via2[gIER] = irq_bit; 592 via2[gIER] = irq_bit & 0x7F;
563 } else if (irq_src == 7) { 593 } else if (irq_src == 7) {
564 if (rbv_present) { 594 if (rbv_present) {
565 /* disable the slot interrupt. SIER works like IER. */ 595 /* disable the slot interrupt. SIER works like IER. */
@@ -586,7 +616,9 @@ void via_irq_clear(int irq) {
586 } else if (irq_src == 2) { 616 } else if (irq_src == 2) {
587 via2[gIFR] = irq_bit | rbv_clear; 617 via2[gIFR] = irq_bit | rbv_clear;
588 } else if (irq_src == 7) { 618 } else if (irq_src == 7) {
589 /* FIXME: hmm.. */ 619 /* FIXME: There is no way to clear an individual nubus slot
620 * IRQ flag, other than getting the device to do it.
621 */
590 } 622 }
591} 623}
592 624
@@ -606,6 +638,7 @@ int via_irq_pending(int irq)
606 } else if (irq_src == 2) { 638 } else if (irq_src == 2) {
607 return via2[gIFR] & irq_bit; 639 return via2[gIFR] & irq_bit;
608 } else if (irq_src == 7) { 640 } else if (irq_src == 7) {
641 /* FIXME: this can't work while a slot irq is disabled! */
609 return ~via2[gBufA] & irq_bit; 642 return ~via2[gBufA] & irq_bit;
610 } 643 }
611 return 0; 644 return 0;