diff options
Diffstat (limited to 'arch/m68k')
-rw-r--r-- | arch/m68k/mac/baboon.c | 12 | ||||
-rw-r--r-- | arch/m68k/mac/oss.c | 8 | ||||
-rw-r--r-- | arch/m68k/mac/psc.c | 19 | ||||
-rw-r--r-- | arch/m68k/mac/via.c | 141 |
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 | ||
67 | irqreturn_t baboon_irq(int irq, void *dev_id) | 67 | irqreturn_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 */ |
38 | volatile long *via_memory_bogon=(long *)&via_memory_bogon; | 42 | volatile long *via_memory_bogon=(long *)&via_memory_bogon; |
39 | #endif | 43 | #endif |
40 | int rbv_present,via_alt_mapping; | 44 | int 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 | ||
421 | irqreturn_t via1_irq(int irq, void *dev_id) | 437 | irqreturn_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 | ||
455 | irqreturn_t via2_irq(int irq, void *dev_id) | 476 | irqreturn_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 | ||
479 | irqreturn_t via_nubus_irq(int irq, void *dev_id) | 505 | irqreturn_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; |