Import 2.1.116pre2
[davej-history.git] / arch / m68k / mac / macints.c
blobd2ea26e05f1033364cf4354cbe36698efad6de53
1 /*
2 * Macintosh interrupts
4 * General design:
5 * In contrary to the Amiga and Atari platforms, the Mac hardware seems to
6 * exclusively use the autovector interrupts (the 'generic level0-level7'
7 * interrupts with exception vectors 0x19-0x1f). The following interrupt levels
8 * are used:
9 * 1 - VIA1
10 * - slot 0: one second interrupt
11 * - slot 1: VBlank
12 * - slot 2: ADB data ready (SR full)
13 * - slot 3: ADB data (CB2)
14 * - slot 4: ADB clock (CB1)
15 * - slot 5: timer 2
16 * - slot 6: timer 1
17 * - slot 7: status of IRQ; signals 'any enabled int.'
19 * 2 - VIA2, RBV or OSS
20 * - slot 0: SCSI DRQ
21 * - slot 1: NUBUS IRQ
22 * - slot 3: SCSI IRQ
24 * 4 - SCC
25 * - subdivided into Channel B and Channel A interrupts
27 * 6 - Off switch (??)
29 * 7 - Debug output
31 * AV Macs only, handled by PSC:
33 * 3 - MACE ethernet IRQ (DMA complete on level 4)
35 * 5 - DSP ??
37 * Using the autovector irq numbers for Linux/m68k hardware interrupts without
38 * the IRQ_MACHSPEC bit set would interfere with the general m68k interrupt
39 * handling in kernel versions 2.0.x, so the following strategy is used:
41 * - mac_init_IRQ installs the low-level entry points for the via1 and via2
42 * exception vectors and the corresponding handlers (C functions); these
43 * entry points just add the machspec bit and call the handlers proper.
44 * (in principle, the C functions can be installed as the exception vectors
45 * directly, as they are hardcoded anyway; that's the current method).
47 * - via[12]_irq determine what interrupt sources have triggered the interrupt,
48 * and call the corresponding device interrupt handlers.
49 * (currently, via1_irq and via2_irq just call via_irq, passing the via base
50 * address. RBV interrupts are handled by (you guessed it) rbv_irq).
51 * Some interrupt functions want to have the interrupt number passed, so
52 * via_irq and rbv_irq need to generate the 'fake' numbers from scratch.
54 * - for the request/free/enable/disable business, interrupt sources are
55 * numbered internally (suggestion: keep irq 0-7 unused :-). One bit in the
56 * irq number specifies the via# to use, i.e. via1 interrupts are 8-16,
57 * via2 interrupts 17-32, rbv interrupts ...
58 * The device interrupt table and the irq_enable bitmap is maintained by
59 * the machspec interrupt code; all device drivers should only use these
60 * functions !
62 * - For future porting to version 2.1 (and removing of the machspec bit) it
63 * should be sufficient to use the same numbers (everything > 7 is assumed
64 * to be machspec, according to Jes!).
66 * TODO:
67 * - integrate Nubus interrupts in request/free_irq
69 * -
72 #include <linux/config.h>
73 #include <linux/types.h>
74 #include <linux/kernel.h>
75 #include <linux/sched.h>
76 #include <linux/kernel_stat.h>
77 #include <linux/interrupt.h> /* for intr_count */
78 #include <linux/delay.h>
80 #include <asm/system.h>
81 #include <asm/irq.h>
82 #include <asm/traps.h>
83 #include <asm/machw.h>
84 #include <asm/macintosh.h>
85 #include "via6522.h"
87 #include <asm/macints.h>
90 * Interrupt handler and parameter types
92 struct irqhandler {
93 void (*handler)(int, void *, struct pt_regs *);
94 void *dev_id;
97 struct irqparam {
98 unsigned long flags;
99 const char *devname;
102 struct irqflags {
103 unsigned int disabled;
104 unsigned int pending;
108 * Array with irq's and their parameter data.
110 static struct irqhandler via1_handler[8];
111 static struct irqhandler via2_handler[8];
112 static struct irqhandler rbv_handler[8];
113 static struct irqhandler psc3_handler[8];
114 static struct irqhandler scc_handler[8];
115 static struct irqhandler psc5_handler[8];
116 static struct irqhandler psc6_handler[8];
117 static struct irqhandler nubus_handler[8];
119 static struct irqhandler *handler_table[8];
122 * This array hold the rest of parameters of int handlers: type
123 * (slow,fast,prio) and the name of the handler. These values are only
124 * accessed from C
126 static struct irqparam via1_param[8];
127 static struct irqparam via2_param[8];
128 static struct irqparam rbv_param[8];
129 static struct irqparam psc3_param[8];
130 static struct irqparam scc_param[8];
131 static struct irqparam psc5_param[8];
132 static struct irqparam psc6_param[8];
133 static struct irqparam nubus_param[8];
135 static struct irqparam *param_table[8];
138 * This array holds the 'disabled' and 'pending' software flags maintained
139 * by mac_{enable,disable}_irq and the generic via_irq function.
142 static struct irqflags irq_flags[8];
145 * This array holds the pointers to the various VIA or other interrupt
146 * controllers, indexed by interrupt level
149 static volatile unsigned char *via_table[8];
152 * Arrays with irq statistics
154 static unsigned long via1_irqs[8];
155 static unsigned long via2_irqs[8];
156 static unsigned long rbv_irqs[8];
157 static unsigned long psc3_irqs[8];
158 static unsigned long scc_irqs[8];
159 static unsigned long psc5_irqs[8];
160 static unsigned long psc6_irqs[8];
161 static unsigned long nubus_irqs[8];
163 static unsigned long *mac_irqs[8];
166 * VIA2 / RBV register base pointers
169 volatile unsigned char *via2_regp=(volatile unsigned char *)VIA2_BAS;
170 volatile unsigned char *rbv_regp=(volatile unsigned char *)VIA2_BAS_IIci;
171 volatile unsigned char *oss_regp=(volatile unsigned char *)OSS_BAS;
172 volatile unsigned char *psc_regp=(volatile unsigned char *)PSC_BAS;
175 * Flags to control via2 / rbv behaviour
178 static int via2_is_rbv = 0;
179 static int via2_is_oss = 0;
180 static int rbv_clear = 0;
182 /* fake VIA2 to OSS bit mapping */
183 static int oss_map[8] = {2, 7, 0, 1, 3, 4, 5};
185 void oss_irq(int irq, void *dev_id, struct pt_regs *regs);
186 static void oss_do_nubus(int irq, void *dev_id, struct pt_regs *regs);
188 /* PSC ints */
189 void psc_irq(int irq, void *dev_id, struct pt_regs *regs);
192 * PSC hooks
195 extern void psc_init(void);
198 * console_loglevel determines NMI handler function
201 extern int console_loglevel;
204 * ADB test hooks
206 extern int in_keybinit;
207 void adb_queue_poll(void);
209 /* Defined in entry.S; only increments 'num_spurious' */
210 asmlinkage void bad_interrupt(void);
212 void nubus_wtf(int slot, void *via, struct pt_regs *regs);
214 void mac_nmi_handler(int irq, void *dev_id, struct pt_regs *regs);
215 void mac_debug_handler(int irq, void *dev_id, struct pt_regs *regs);
217 static void via_do_nubus(int slot, void *via, struct pt_regs *regs);
219 /*#define DEBUG_VIA*/
221 void mac_init_IRQ(void)
223 int i;
225 #ifdef DEBUG_MACINTS
226 printk("Mac interrupt stuff initializing ...\n");
227 #endif
229 via2_regp = (unsigned char *)VIA2_BAS;
230 rbv_regp = (unsigned char *)VIA2_BAS_IIci;
232 /* initialize the hardwired (primary, autovector) IRQs */
234 /* level 1 IRQ: VIA1, always present */
235 sys_request_irq(1, via1_irq, IRQ_FLG_LOCK, "via1", via1_irq);
237 /* via2 or rbv?? */
238 if (macintosh_config->via_type == MAC_VIA_IIci) {
240 * A word of caution: the definitions here only affect interrupt
241 * handling, see via6522.c for yet another file to change
242 * base addresses and RBV flags
245 /* yes, this is messy - the IIfx deserves a class of his own */
246 if (macintosh_config->ident == MAC_MODEL_IIFX) {
247 /* no real VIA2, the OSS seems _very_different */
248 via2_is_oss = 1;
249 /* IIfx has OSS, at a different base address than RBV */
250 rbv_regp = (unsigned char *) OSS_BAS;
251 sys_request_irq(2, oss_irq, IRQ_FLG_LOCK, "oss", oss_irq);
252 } else {
253 /* VIA2 is part of the RBV: different base, other offsets */
254 via2_is_rbv = 1;
256 /* LC III weirdness: IFR seems to behave like VIA2 */
257 /* FIXME: maybe also for LC II ?? */
258 if (macintosh_config->ident == MAC_MODEL_LCIII) {
259 rbv_clear = 0x0;
260 } else {
261 rbv_clear = 0x80;
263 /* level 2 IRQ: RBV/OSS; we only care about RBV for now */
264 sys_request_irq(2, rbv_irq, IRQ_FLG_LOCK, "rbv", rbv_irq);
266 } else
267 /* level 2 IRQ: VIA2 */
268 sys_request_irq(2, via2_irq, IRQ_FLG_LOCK, "via2", via2_irq);
271 * level 4 IRQ: SCC - use 'master' interrupt routine that calls the
272 * registered channel-specific interrupts in turn.
273 * Currently, one interrupt per channel is used, solely
274 * to pass the correct async_info as parameter!
276 #if 0 /* want to install debug/SCC shutup routine until SCC init */
277 sys_request_irq(4, mac_SCC_handler, IRQ_FLG_STD, "INT4", mac_SCC_handler);
278 #else
279 sys_request_irq(4, mac_debug_handler, IRQ_FLG_STD, "INT4", mac_debug_handler);
280 #endif
281 /* Alan uses IRQ 5 for SCC ?? */
282 sys_request_irq(5, mac_debug_handler, IRQ_FLG_STD, "INT5", mac_debug_handler);
284 /* level 6 */
285 sys_request_irq(6, mac_bang, IRQ_FLG_LOCK, "offswitch", mac_bang);
287 /* level 7 (or NMI) : debug stuff */
288 sys_request_irq(7, mac_nmi_handler, IRQ_FLG_STD, "NMI", mac_nmi_handler);
290 /* initialize the handler tables for VIAs */
291 for (i = 0; i < 8; i++) {
292 via1_handler[i].handler = mac_default_handler;
293 via1_handler[i].dev_id = NULL;
294 via1_param[i].flags = IRQ_FLG_STD;
295 via1_param[i].devname = NULL;
297 via2_handler[i].handler = mac_default_handler;
298 via2_handler[i].dev_id = NULL;
299 via2_param[i].flags = IRQ_FLG_STD;
300 via2_param[i].devname = NULL;
302 rbv_handler[i].handler = mac_default_handler;
303 rbv_handler[i].dev_id = NULL;
304 rbv_param[i].flags = IRQ_FLG_STD;
305 rbv_param[i].devname = NULL;
307 scc_handler[i].handler = mac_default_handler;
308 scc_handler[i].dev_id = NULL;
309 scc_param[i].flags = IRQ_FLG_STD;
310 scc_param[i].devname = NULL;
312 /* NUBUS interrupts routed through VIA2 slot 2 - special */
313 nubus_handler[i].handler = nubus_wtf;
314 nubus_handler[i].dev_id = NULL;
315 nubus_param[i].flags = IRQ_FLG_STD;
316 nubus_param[i].devname = NULL;
320 /* initialize the handler tables (level 1 -> via_handler[0] !!!) */
321 via_table[0] = via1_regp;
322 handler_table[0] = &via1_handler[0];
323 param_table[0] = &via1_param[0];
324 mac_irqs[0] = &via1_irqs[0];
326 if (via2_is_rbv || via2_is_oss) {
327 via_table[1] = rbv_regp;
328 handler_table[1] = &rbv_handler[0];
329 param_table[1] = &rbv_param[0];
330 mac_irqs[1] = &rbv_irqs[0];
331 } else {
332 via_table[1] = via2_regp;
333 handler_table[1] = &via2_handler[0];
334 param_table[1] = &via2_param[0];
335 mac_irqs[1] = &via2_irqs[0];
337 via_table[2] = NULL;
338 via_table[3] = NULL;
340 handler_table[2] = &rbv_handler[0];
341 handler_table[3] = &scc_handler[0];
342 handler_table[4] = NULL;
343 handler_table[5] = NULL;
344 handler_table[6] = NULL;
345 handler_table[7] = &nubus_handler[0];
347 param_table[2] = &rbv_param[0];
348 param_table[3] = &scc_param[0];
349 param_table[7] = &nubus_param[0];
351 mac_irqs[2] = &rbv_irqs[0];
352 mac_irqs[3] = &scc_irqs[0];
353 mac_irqs[7] = &nubus_irqs[0];
356 * AV Macs: shutup the PSC ints
358 if (macintosh_config->ident == MAC_MODEL_C660
359 || macintosh_config->ident == MAC_MODEL_Q840) {
360 psc_init();
362 handler_table[2] = &psc3_handler[0];
363 /* handler_table[3] = &psc4_handler[0]; */
364 handler_table[4] = &psc5_handler[0];
365 handler_table[5] = &psc6_handler[0];
367 param_table[2] = &psc3_param[0];
368 /* param_table[3] = &psc4_param[0]; */
369 param_table[4] = &psc5_param[0];
370 param_table[5] = &psc6_param[0];
372 mac_irqs[2] = &psc3_irqs[0];
373 /* mac_irqs[3] = &psc4_irqs[0]; */
374 mac_irqs[4] = &psc5_irqs[0];
375 mac_irqs[5] = &psc6_irqs[0];
377 sys_request_irq(3, psc_irq, IRQ_FLG_STD, "PSC3", psc_irq);
378 sys_request_irq(4, psc_irq, IRQ_FLG_STD, "PSC4", psc_irq);
379 sys_request_irq(5, psc_irq, IRQ_FLG_STD, "PSC5", psc_irq);
380 sys_request_irq(6, psc_irq, IRQ_FLG_STD, "PSC6", psc_irq);
383 #ifdef DEBUG_MACINTS
384 printk("Mac interrupt init done!\n");
385 #endif
389 * We have no machine specific interrupts on a macintoy
390 * Yet, we need to register/unregister interrupts ... :-)
391 * Currently unimplemented: Test for valid irq number, chained irqs,
392 * Nubus interrupts (use nubus_request_irq!).
395 int mac_request_irq (unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
396 unsigned long flags, const char *devname, void *dev_id)
398 int srcidx = ((irq & IRQ_SRC_MASK)>>3) - 1;
399 int irqidx = (irq & IRQ_IDX_MASK);
400 struct irqhandler *via_handler;
401 struct irqparam *via_param;
402 volatile unsigned char *via;
404 #ifdef DEBUG_MACINTS
405 printk ("%s: IRQ %d on VIA%d[%d] requested from %s\n",
406 __FUNCTION__, irq, srcidx+1, irqidx, devname);
407 #endif
409 if (flags < IRQ_TYPE_SLOW || flags > IRQ_TYPE_PRIO) {
410 printk ("%s: Bad irq type %ld requested from %s\n",
411 __FUNCTION__, flags, devname);
412 return -EINVAL;
415 /* figure out what VIA is handling this irq */
416 if (irq < IRQ_IDX(IRQ_VIA1_1) || irq >= IRQ_IDX(IRQ_NUBUS_1)) {
417 /* non-via irqs unimplemented */
418 printk ("%s: Bad irq source %d on VIA %d requested from %s\n",
419 __FUNCTION__, irq, srcidx, devname);
420 return -EINVAL;
423 /* figure out if SCC pseudo-irq (redundant ??) */
424 if (irq >= IRQ_IDX(IRQ_SCC) && irq < IRQ_IDX(IRQ_PSC5_0)) {
425 /* set specific SCC handler */
426 scc_handler[irqidx].handler = handler;
427 scc_handler[irqidx].dev_id = dev_id;
428 scc_param[irqidx].flags = flags;
429 scc_param[irqidx].devname = devname;
430 /* and done! */
431 return 0;
434 /* add similar hack for Nubus pseudo-irq here - hide nubus_request_irq */
436 via = (volatile unsigned char *) via_table[srcidx];
437 if (!via)
438 return -EINVAL;
440 via_handler = handler_table[srcidx];
441 via_param = param_table[srcidx];
443 /* check for conflicts or possible replacement */
445 /* set the handler - no chained irqs yet !! */
446 via_handler[irqidx].handler = handler;
447 via_handler[irqidx].dev_id = dev_id;
448 via_param[irqidx].flags = flags;
449 via_param[irqidx].devname = devname;
451 /* and turn it on ... careful, that's VIA only ... */
452 if (srcidx == SRC_VIA2 && via2_is_rbv)
453 via_write(via, rIER, via_read(via, rIER)|0x80|(1<<(irqidx)));
454 else if (srcidx == SRC_VIA2 && via2_is_oss)
455 via_write(oss_regp, oss_map[irqidx]+8, 2);
456 else
457 via_write(via, vIER, via_read(via, vIER)|0x80|(1<<(irqidx)));
460 if (irq == IRQ_IDX(IRQ_MAC_SCSI)) {
462 * Set vPCR for SCSI interrupts. (what about RBV here?)
463 * 980429 MS: RBV is ok, OSS seems to be differentt
465 if (!via2_is_oss)
466 /* CB2 (IRQ) indep. interrupt input, positive edge */
467 /* CA2 (DRQ) indep. interrupt input, positive edge */
468 via_write(via, vPCR, 0x66);
469 #if 0
470 else
471 /* CB2 (IRQ) indep. interrupt input, negative edge */
472 /* CA2 (DRQ) indep. interrupt input, negative edge */
473 via_write(via, vPCR, 0x22);
474 #endif
477 return 0;
480 void mac_free_irq (unsigned int irq, void *dev_id)
482 unsigned long flags;
483 int srcidx = ((irq & IRQ_SRC_MASK)>>3) - 1;
484 int irqidx = (irq & IRQ_IDX_MASK);
485 struct irqhandler *via_handler;
486 struct irqparam *via_param;
487 volatile unsigned char *via;
489 #ifdef DEBUG_MACINTS
490 printk ("%s: IRQ %d on VIA%d[%d] freed\n",
491 __FUNCTION__, irq, srcidx+1, irqidx);
492 #endif
494 /* figure out what VIA is handling this irq */
495 if (irq < IRQ_IDX(IRQ_VIA1_1) || irq >= IRQ_IDX(IRQ_NUBUS_1)) {
496 /* non-via irqs unimplemented */
497 return;
500 save_flags(flags);
501 cli();
503 /* figure out if SCC pseudo-irq */
504 if (irq >= IRQ_IDX(IRQ_SCC) && irq < IRQ_IDX(IRQ_PSC5_0)) {
505 /* clear specific SCC handler */
506 scc_handler[irqidx].handler = mac_default_handler;
507 scc_handler[irqidx].dev_id = NULL;
508 scc_param[irqidx].flags = IRQ_FLG_STD;
509 scc_param[irqidx].devname = NULL;
510 /* and done! */
511 restore_flags(flags);
512 return;
515 via = (volatile unsigned char *) via_table[srcidx];
516 via_handler = handler_table[srcidx];
517 via_param = param_table[srcidx];
519 if ( !via || (via_handler[irqidx].dev_id != dev_id) ) {
520 restore_flags(flags);
521 goto not_found;
524 /* clear the handler - no chained irqs yet !! */
525 via_handler[irqidx].handler = mac_default_handler;
526 via_handler[irqidx].dev_id = NULL;
527 via_param[irqidx].flags = IRQ_FLG_STD;
528 via_param[irqidx].devname = NULL;
530 /* and turn it off */
531 if (srcidx == SRC_VIA2 && via2_is_rbv)
532 via_write(via, rIER, (via_read(via, rIER)&(1<<irqidx)));
533 else if (srcidx == SRC_VIA2 && via2_is_oss)
534 via_write(oss_regp, oss_map[irqidx]+8, 0);
535 else
536 via_write(via, vIER, (via_read(via, vIER)&(1<<irqidx)));
538 restore_flags(flags);
539 return;
541 not_found:
542 printk("%s: tried to remove invalid irq\n", __FUNCTION__);
543 return;
548 * {en,dis}able_irq have the usual semantics of temporary blocking the
549 * interrupt, but not loosing requests that happen between disabling and
550 * enabling. On Atari, this is done with the MFP mask registers.
552 * On the Mac, this isn't possible: there is no VIA mask register.
553 * Needs to be implemented in software, setting 'mask' bits in a separate
554 * struct for each interrupt controller. These mask bits need to be checked
555 * by the VIA interrupt routine which should ignore requests for masked IRQs
556 * (after possibly ack'ing them).
558 * On second thought: some of the IRQ sources _can_ be turned off via bits
559 * in the VIA output registers. Need to check this ...
561 * TBI: According to the VIA docs, clearing a bit in the IER has the effect of
562 * blocking generation of the interrupt, but the internal interrupt condition
563 * is preserved. So the IER might be used as mask register here, and turnon_irq
564 * would need to clear the interrupt bit in the IFR to prevent getting an
565 * interrupt at all.
567 * Implementation note: the irq no's here are the _machspec_ irqs, hence the
568 * hack with srcidx to figure out which VIA/RBV handles the interrupt.
569 * That's fundamentally different when it comes to the interrupt handlers
570 * proper: these get the interrupt level no. as argument, all information about
571 * which source triggered the int. is buried in the VIA IFR ... The int. level
572 * points us to the proper handler, so we could do a sanity check there ...
575 void mac_enable_irq (unsigned int irq)
577 int srcidx = ((irq & IRQ_SRC_MASK)>>3) - 1;
578 int irqidx = (irq & IRQ_IDX_MASK);
580 irq_flags[srcidx].disabled &= ~(1<<irqidx);
582 * Call handler here if irq_flags[srcidx].pending & 1<<irqidx ??
583 * The structure of via_irq prevents this, sort of: it warns if
584 * no true events are pending. Maybe that's being changed ...
585 * Other problem: is it always possible to call an interrupt handler,
586 * or should that depend on the current interrupt level?
590 void mac_disable_irq (unsigned int irq)
592 int srcidx = ((irq & IRQ_SRC_MASK)>>3) - 1;
593 int irqidx = (irq & IRQ_IDX_MASK);
595 irq_flags[srcidx].disabled |= (1<<irqidx);
599 * In opposite to {en,dis}able_irq, requests between turn{off,on}_irq are not
600 * "stored". This is done with the VIA interrupt enable register
603 void mac_turnon_irq( unsigned int irq )
605 int srcidx = ((irq & IRQ_SRC_MASK)>>3) - 1;
606 int irqidx = (irq & IRQ_IDX_MASK);
607 volatile unsigned char *via;
609 via = (volatile unsigned char *) via_table[srcidx];
610 if (!via)
611 return;
613 if (srcidx == SRC_VIA2 && via2_is_rbv)
614 via_write(via, rIER, via_read(via, rIER)|0x80|(1<<(irqidx)));
615 else if (srcidx == SRC_VIA2 && via2_is_oss)
616 via_write(oss_regp, oss_map[irqidx]+8, 2);
617 else if (srcidx >= SRC_VIA2)
618 via_write(via, (0x104 + 0x10*srcidx),
619 via_read(via, (0x104 + 0x10*srcidx))|0x80|(1<<(irqidx)));
620 else
621 via_write(via, vIER, via_read(via, vIER)|0x80|(1<<(irqidx)));
625 void mac_turnoff_irq( unsigned int irq )
627 int srcidx = ((irq & IRQ_SRC_MASK)>>3) - 1;
628 int irqidx = (irq & IRQ_IDX_MASK);
629 volatile unsigned char *via;
631 via = (volatile unsigned char *) via_table[srcidx];
632 if (!via)
633 return;
635 if (srcidx == SRC_VIA2 && via2_is_rbv)
636 via_write(via, rIER, (via_read(via, rIER)&(1<<irqidx)));
637 else if (srcidx == SRC_VIA2 && via2_is_oss)
638 via_write(oss_regp, oss_map[irqidx]+8, 0);
639 else if (srcidx >= SRC_VIA2)
640 via_write(via, (0x104 + 0x10*srcidx),
641 via_read(via, (0x104 + 0x10*srcidx))|(1<<(irqidx)));
642 else
643 via_write(via, vIER, (via_read(via, vIER)&(1<<irqidx)));
647 * These functions currently only handle the software-maintained irq pending
648 * list for disabled irqs - manipulating the actual irq flags in the via would
649 * require clearing single bits in the via, such as (probably)
650 * via_write(via, vIFR, (via_read(via, vIFR)&(1<<irqidx))); - don't know if
651 * this has side-effects ...
654 void mac_clear_pending_irq( unsigned int irq )
656 int srcidx = ((irq & IRQ_SRC_MASK)>>3) - 1;
657 int irqidx = (irq & IRQ_IDX_MASK);
659 irq_flags[srcidx].pending &= ~(1<<irqidx);
662 int mac_irq_pending( unsigned int irq )
664 int pending = 0;
665 volatile unsigned char *via;
667 int srcidx = ((irq & IRQ_SRC_MASK)>>3) - 1;
668 int irqidx = (irq & IRQ_IDX_MASK);
670 pending = irq_flags[srcidx].pending & (1<<irqidx);
672 via = (volatile unsigned char *) via_table[srcidx];
673 if (!via)
674 return (pending);
676 if (srcidx == SRC_VIA2 && via2_is_rbv)
677 pending |= via_read(via, rIFR)&(1<<irqidx);
678 else if (srcidx == SRC_VIA2 && via2_is_oss)
679 pending |= via_read(via, oIFR)&0x03&(1<<oss_map[irqidx]);
680 else if (srcidx >= SRC_VIA2)
681 pending |= via_read(via, (0x100 + 0x10*srcidx))&(1<<irqidx);
682 else
683 pending |= via_read(via, vIFR)&(1<<irqidx);
685 return (pending);
688 int mac_get_irq_list (char *buf)
690 int i, len = 0;
691 int srcidx, irqidx;
693 for (i = VIA1_SOURCE_BASE; i < NUM_MAC_SOURCES+8; ++i) {
694 srcidx = ((i & IRQ_SRC_MASK)>>3) - 1;
695 irqidx = (i & IRQ_IDX_MASK);
698 * Not present: skip
701 if (mac_irqs[srcidx] == NULL)
702 continue;
705 * never used by VIAs, unused by others so far, counts
706 * the magic 'nothing pending' cases ...
708 if (irqidx == 7 && mac_irqs[srcidx][irqidx]) {
709 len += sprintf(buf+len, "Level %01d: %10lu (spurious) \n",
710 srcidx,
711 mac_irqs[srcidx][irqidx]);
712 continue;
716 * Nothing registered for this IPL: skip
719 if (handler_table[srcidx] == NULL)
720 continue;
723 * No handler installed: skip
726 if (handler_table[srcidx][irqidx].handler == mac_default_handler ||
727 handler_table[srcidx][irqidx].handler == nubus_wtf)
728 continue;
731 if (i < VIA2_SOURCE_BASE)
732 len += sprintf(buf+len, "via1 %01d: %10lu ",
733 irqidx,
734 mac_irqs[srcidx][irqidx]);
735 else if (i < RBV_SOURCE_BASE)
736 len += sprintf(buf+len, "via2 %01d: %10lu ",
737 irqidx,
738 mac_irqs[srcidx][irqidx]);
739 else if (i < MAC_SCC_SOURCE_BASE)
740 len += sprintf(buf+len, "rbv %01d: %10lu ",
741 irqidx,
742 mac_irqs[srcidx][irqidx]);
743 else if (i < NUBUS_SOURCE_BASE)
744 len += sprintf(buf+len, "scc %01d: %10lu ",
745 irqidx,
746 mac_irqs[srcidx][irqidx]);
747 else /* Nubus */
748 len += sprintf(buf+len, "nubus %01d: %10lu ",
749 irqidx,
750 mac_irqs[srcidx][irqidx]);
752 len += sprintf(buf+len, "%s\n",
753 param_table[srcidx][irqidx].devname);
756 if (num_spurious)
757 len += sprintf(buf+len, "spurio.: %10u\n", num_spurious);
758 return len;
761 void via_scsi_clear(void)
763 volatile unsigned char deep_magic;
764 if (via2_is_rbv) {
765 via_write(rbv_regp, rIFR, (1<<3)|(1<<0)|0x80);
766 deep_magic = via_read(rbv_regp, rBufB);
767 } else if (via2_is_oss) {
768 /* nothing */
769 /* via_write(oss_regp, 9, 0) */;
770 } else
771 deep_magic = via_read(via2_regp, vBufB);
772 mac_enable_irq( IRQ_IDX(IRQ_MAC_SCSI) );
776 void mac_default_handler(int irq, void *dev_id, struct pt_regs *regs)
778 #ifdef DEBUG_VIA
779 printk("Unexpected IRQ %d\n", irq);
780 #endif
783 static int num_debug[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
785 void mac_debug_handler(int irq, void *dev_id, struct pt_regs *regs)
787 if (num_debug[irq] < 10) {
788 printk("DEBUG: Unexpected IRQ %d\n", irq);
789 num_debug[irq]++;
793 void scsi_mac_debug(void);
794 void scsi_mac_polled(void);
796 static int in_nmi = 0;
797 static volatile int nmi_hold = 0;
799 void mac_nmi_handler(int irq, void *dev_id, struct pt_regs *fp)
801 int i;
803 * generate debug output on NMI switch if 'debug' kernel option given
804 * (only works with Penguin!)
807 in_nmi++;
808 #if 0
809 scsi_mac_debug();
810 printk("PC: %08lx\nSR: %04x SP: %p\n", fp->pc, fp->sr, fp);
811 #endif
812 for (i=0; i<100; i++)
813 udelay(1000);
815 if (in_nmi == 1) {
816 nmi_hold = 1;
817 printk("... pausing, press NMI to resume ...");
818 } else {
819 printk(" ok!\n");
820 nmi_hold = 0;
823 barrier();
825 while (nmi_hold == 1)
826 udelay(1000);
828 #if 0
829 scsi_mac_polled();
830 #endif
832 if ( console_loglevel >= 8 ) {
833 #if 0
834 show_state();
835 printk("PC: %08lx\nSR: %04x SP: %p\n", fp->pc, fp->sr, fp);
836 printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",
837 fp->d0, fp->d1, fp->d2, fp->d3);
838 printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
839 fp->d4, fp->d5, fp->a0, fp->a1);
841 if (STACK_MAGIC != *(unsigned long *)current->kernel_stack_page)
842 printk("Corrupted stack page\n");
843 printk("Process %s (pid: %d, stackpage=%08lx)\n",
844 current->comm, current->pid, current->kernel_stack_page);
845 if (intr_count == 1)
846 dump_stack((struct frame *)fp);
847 #else
848 /* printk("NMI "); */
849 #endif
851 in_nmi--;
855 * The generic VIA interrupt routines (shamelessly stolen from Alan Cox's
856 * via6522.c :-), disable/pending masks added.
857 * The int *viaidx etc. is just to keep the prototype happy ...
860 static void via_irq(unsigned char *via, int *viaidx, struct pt_regs *regs)
862 unsigned char events=(via_read(via, vIFR)&via_read(via,vIER))&0x7F;
863 int i;
864 int ct = 0;
865 struct irqhandler *via_handler = handler_table[*viaidx];
866 struct irqparam *via_param = param_table[*viaidx];
867 unsigned long *via_irqs = mac_irqs[*viaidx];
869 /* to be changed, possibly: for each non'masked', enabled IRQ, read
870 * flag bit, ack and call handler ...
871 * Currently: all pending irqs ack'ed en bloc.
872 * If ack for masked IRQ required: keep 'pending' info separate.
875 /* shouldn't we disable interrupts here ?? */
879 * Shouldnt happen
882 if(events==0)
884 #ifdef DEBUG_VIA
885 /* should go away; mostly missing timer ticks and ADB events */
886 printk("via%d_irq: nothing pending, flags %x mask %x!\n",
887 *viaidx + 1, via_read(via, vIFR), via_read(via,vIER));
888 #endif
889 via_irqs[7]++;
890 return;
893 #ifdef DEBUG_VIA
895 * limited verbosity for VIA interrupts
897 #if 0
898 if ( (*viaidx == 0 && events != 1<<6) /* timer int */
899 || (*viaidx == 1 && events != 1<<3) ) /* SCSI IRQ */
900 #else
901 if ( *viaidx == 0 && (events & 1<<2) )
902 #endif
903 printk("via_irq: irq %d events %x !\n", (*viaidx)+1, events);
904 #endif
906 do {
908 * Clear the pending flag
911 via_write(via, vIFR, events);
914 * Now see what bits are raised
917 for(i=0;i<7;i++)
919 /* determine machspec. irq no. */
920 int irq = ((*viaidx)+1)* 8 + i;
921 /* call corresponding handlers */
922 if (events&(1<<i)) {
923 if (irq_flags[*viaidx].disabled & (1<<i)) {
924 if (!irq_flags[*viaidx].pending&(1<<i))
925 via_irqs[i]++;
926 /* irq disabled -> mark pending */
927 irq_flags[*viaidx].pending |= (1<<i);
928 } else {
929 via_irqs[i]++;
930 /* irq enabled -> call handler */
931 (via_handler[i].handler)(irq, via, regs);
934 /* and call handlers for pending irqs - first ?? */
935 if ( (irq_flags[*viaidx].pending & (1<<i))
936 && !(irq_flags[*viaidx].disabled & (1<<i)) ) {
937 /* call handler for re-enabled irq */
938 (via_handler[i].handler)(irq, via, regs);
939 /* and clear pending flag :-) */
940 irq_flags[*viaidx].pending &= ~(1<<i);
945 * And done ... check for more punishment!
948 events=(via_read(via, vIFR)&via_read(via,vIER))&0x7F;
949 ct++;
950 if(events && ct>8)
952 #ifdef DEBUG_VIA
953 printk("via%d: stuck events %x\n", (*viaidx)+1, events);
954 #endif
955 break;
958 while(events);
959 #if 0
960 scsi_mac_polled();
961 #endif
965 * Caution: the following stuff is called from process_int as _autovector_
966 * system interrupts. So irq is always in the range 0-7 :-( and the selection
967 * of the appropriate VIA is up to the irq handler here based on the autovec
968 * irq number. There's no information whatsoever about which source on the VIA
969 * triggered the int - and that's what the machspec irq no's are about.
970 * Broken design :-((((
974 * System interrupts
977 void via1_irq(int irq, void *dev_id, struct pt_regs *regs)
979 int srcidx = IRQ_IDX(irq) - 1;
980 via_irq((unsigned char *)via1_regp, &srcidx, regs);
985 * Nubus / SCSI interrupts, VIA style (could be wrapped into via1_irq or
986 * via_irq directly by selecting the regp based on the irq!)
989 void via2_irq(int irq, void *dev_id, struct pt_regs *regs)
991 int srcidx = IRQ_IDX(irq) - 1;
992 via_irq((unsigned char *)via2_regp, &srcidx, regs);
996 * Nubus / SCSI interrupts; RBV style
997 * The RBV is different. RBV appears to stand for randomly broken
998 * VIA (or even real broken VIA).
1001 void rbv_irq(int irq, void *dev_id, struct pt_regs *regs)
1003 int srcidx = IRQ_IDX(irq) - 1; /* MUST be 1 !! */
1004 volatile unsigned char *via = rbv_regp;
1005 unsigned char events=(via_read(via, rIFR)&via_read(via,rIER))&0x7F;
1006 int i;
1007 int ct = 0;
1008 struct irqhandler *via_handler = handler_table[srcidx];
1009 struct irqparam *via_param = param_table[srcidx];
1011 /* shouldn't we disable interrupts here ?? */
1015 * Shouldnt happen
1018 if(events==0)
1020 #ifdef DEBUG_VIA
1021 printk("rbv_irq: nothing pending, flags %x mask %x!\n",
1022 via_read(via, rIFR), via_read(via,rIER));
1023 #endif
1024 rbv_irqs[7]++;
1025 return;
1028 #ifdef DEBUG_VIA
1030 * limited verbosity for RBV interrupts (add more if needed)
1032 if ( srcidx == 1 && events != 1<<3 ) /* SCSI IRQ */
1033 printk("rbv_irq: irq %d (%d) events %x !\n", irq, srcidx+1, events);
1034 #endif
1036 /* to be changed, possibly: for each non'masked', enabled IRQ, read
1037 * flag bit, ack and call handler ...
1038 * Currently: all pending irqs ack'ed en bloc.
1039 * If ack for masked IRQ required: keep 'pending' info separate.
1042 do {
1044 * Clear the pending flag
1047 via_write(via, rIFR, events | rbv_clear);
1050 * Now see what bits are raised
1053 for(i=0;i<7;i++)
1055 /* determine machspec. irq no. */
1056 int irq = (srcidx+1)* 8 + i;
1057 /* call corresponding handlers */
1058 if (events&(1<<i)) {
1059 if (irq_flags[srcidx].disabled & (1<<i)) {
1060 if (!irq_flags[srcidx].pending&(1<<i))
1061 rbv_irqs[i]++;
1062 /* irq disabled -> mark pending */
1063 irq_flags[srcidx].pending |= (1<<i);
1064 } else {
1065 rbv_irqs[i]++;
1066 /* irq enabled -> call handler */
1067 (via_handler[i].handler)(irq, via, regs);
1070 /* and call handlers for pending irqs - first ?? */
1071 if ( (irq_flags[srcidx].pending & (1<<i))
1072 && !(irq_flags[srcidx].disabled & (1<<i)) ) {
1073 /* call handler for re-enabled irq */
1074 (via_handler[i].handler)(irq, via, regs);
1075 /* and clear pending flag :-) */
1076 irq_flags[srcidx].pending &= ~(1<<i);
1081 * And done ... check for more punishment!
1084 events=(via_read(via, rIFR)&via_read(via,rIER))&0x7F;
1085 ct++;
1086 if(events && ct>8)
1088 printk("rbv: stuck events %x\n",events);
1089 for(i=0;i<7;i++)
1091 if(events&(1<<i))
1093 printk("rbv - bashing source %d\n",
1095 via_write(via, rIER, 1<<i);
1096 via_write(via, rIFR, (1<<i) | rbv_clear);
1099 break;
1102 while(events);
1103 #if 0
1104 scsi_mac_polled();
1105 #endif
1109 * Unexpected via interrupt
1112 void via_wtf(int slot, void *via, struct pt_regs *regs)
1114 #ifdef DEBUG_VIA
1115 printk("Unexpected event %d on via %p\n",slot,via);
1116 #endif
1120 * Nubus / SCSI interrupts; OSS style
1121 * The OSS is even more different than the RBV. OSS appears to stand for
1122 * Obscenely Screwed Silicon ...
1124 * Latest NetBSD sources suggest the OSS should behave like a RBV, but
1125 * that's probably true for the 0x203 offset (Nubus/ADB-SWIM IOP) at best
1128 void oss_irq(int irq, void *dev_id, struct pt_regs *regs)
1130 int srcidx = IRQ_IDX(irq) - 1; /* MUST be 1 !! */
1131 volatile unsigned char *via = oss_regp;
1132 unsigned char events=(via_read(via, oIFR))&0x03;
1133 unsigned char nub_ev=(via_read(via, nIFR))&0x4F;
1134 unsigned char adb_ev;
1135 int i;
1136 int ct = 0;
1137 struct irqhandler *via_handler = handler_table[srcidx];
1138 struct irqparam *via_param = param_table[srcidx];
1140 /* shouldn't we disable interrupts here ?? */
1142 adb_ev = nub_ev & 0x40;
1143 nub_ev &= 0x3F;
1146 * Shouldnt happen
1149 if (events==0 && adb_ev==0 && nub_ev==0)
1151 printk("oss_irq: nothing pending, flags %x %x!\n",
1152 via_read(via, oIFR), via_read(via, nIFR));
1153 rbv_irqs[7]++;
1154 return;
1157 #ifdef DEBUG_VIA
1159 * limited verbosity for RBV interrupts (add more if needed)
1161 if ( events != 1<<3 ) /* SCSI IRQ */
1162 printk("oss_irq: irq %d events %x %x %x !\n", irq, srcidx+1,
1163 events, adb_ev, nub_ev);
1164 #endif
1167 * OSS priorities: call ADB handler first if registered, other events,
1168 * then Nubus
1169 * ADB: yet to be implemented!
1173 * ADB: try to shutup the IOP
1175 if (adb_ev) {
1176 printk("Hands off ! Don't press this button ever again !!!\n");
1177 via_write(via, 6, 0);
1180 do {
1182 * Clear the pending flags
1183 * How exactly is that supposed to work ??
1187 * Now see what bits are raised
1190 for(i=0;i<7;i++)
1192 /* HACK HACK: map to bit number in OSS register */
1193 int irqidx = oss_map[i];
1194 /* determine machspec. irq no. */
1195 int irq = (srcidx+1)* 8 + i;
1196 /* call corresponding handlers */
1197 if ( (events&(1<<irqidx)) && /* bit set*/
1198 (via_read(via, irqidx+8)&0x7) ) { /* irq enabled */
1199 if (irq_flags[srcidx].disabled & (1<<i)) {
1200 if (!irq_flags[srcidx].pending&(1<<i))
1201 rbv_irqs[i]++;
1202 /* irq disabled -> mark pending */
1203 irq_flags[srcidx].pending |= (1<<i);
1204 } else {
1205 rbv_irqs[i]++;
1206 /* irq enabled -> call handler */
1207 (via_handler[i].handler)(irq, via, regs);
1210 /* and call handlers for pending irqs - first ?? */
1211 if ( (irq_flags[srcidx].pending & (1<<i))
1212 && !(irq_flags[srcidx].disabled & (1<<i)) ) {
1213 /* call handler for re-enabled irq */
1214 (via_handler[i].handler)(irq, via, regs);
1215 /* and clear pending flag :-) */
1216 irq_flags[srcidx].pending &= ~(1<<i);
1221 * And done ... check for more punishment!
1224 events=(via_read(via, oIFR)/*&via_read(via,rIER)*/)&0x03;
1225 ct++;
1226 if(events && ct>8)
1228 printk("oss: stuck events %x\n",events);
1229 for(i=0;i<7;i++)
1231 if(events&(1<<i))
1233 printk("oss - bashing source %d\n",
1235 /* that should disable it */
1236 via_write(via, 8+i, 0);
1239 break;
1242 while(events);
1243 #if 0
1244 scsi_mac_polled();
1245 #endif
1247 if (nub_ev)
1248 oss_do_nubus(irq, via, regs);
1253 * Unexpected slot interrupt
1256 void nubus_wtf(int slot, void *via, struct pt_regs *regs)
1258 #ifdef DEBUG_VIA_NUBUS
1259 printk("Unexpected interrupt on nubus slot %d\n",slot);
1260 #endif
1264 * SCC master interrupt handler; sole purpose: pass the registered
1265 * async struct to the SCC handler proper.
1268 void mac_SCC_handler(int irq, void *dev_id, struct pt_regs *regs)
1270 int i;
1271 /* 1+2: compatibility with PSC ! */
1272 for (i = 1; i < 3; i++) /* currently only these two used */
1273 if (scc_handler[i].handler != mac_default_handler)
1274 (scc_handler[i].handler)(i, scc_handler[i].dev_id, regs);
1279 * PSC interrupt handler
1282 void psc_irq(int irq, void *dev_id, struct pt_regs *regs)
1284 int srcidx = IRQ_IDX(irq) - 1;
1285 volatile unsigned char *via = psc_regp;
1286 unsigned int pIFR = 0x100 + 0x10*srcidx;
1287 unsigned int pIER = 0x104 + 0x10*srcidx;
1288 unsigned char events=(via_read(via, pIFR)&via_read(via,pIER))&0xF;
1289 int i;
1290 int ct = 0;
1291 struct irqhandler *via_handler = handler_table[srcidx];
1292 struct irqparam *via_param = param_table[srcidx];
1294 /* shouldn't we disable interrupts here ?? */
1298 * Shouldnt happen
1301 if(events==0)
1303 #ifdef DEBUG_VIA
1304 printk("rbv_irq: nothing pending, flags %x mask %x!\n",
1305 via_read(via, pIFR), via_read(via,pIER));
1306 #endif
1307 mac_irqs[srcidx][7]++;
1308 return;
1311 #ifdef DEBUG_VIA
1313 * limited verbosity for RBV interrupts (add more if needed)
1315 if ( srcidx == 1 && events != 1<<3 && events != 1<<1 ) /* SCSI IRQ */
1316 printk("psc_irq: irq %d events %x !\n", irq, srcidx+1, events);
1317 #endif
1319 /* to be changed, possibly: for each non'masked', enabled IRQ, read
1320 * flag bit, ack and call handler ...
1321 * Currently: all pending irqs ack'ed en bloc.
1322 * If ack for masked IRQ required: keep 'pending' info separate.
1325 do {
1327 * Clear the pending flag
1330 /* via_write(via, pIFR, events); */
1333 * Now see what bits are raised
1336 for(i=0;i<7;i++)
1338 /* determine machspec. irq no. */
1339 int irq = (srcidx+1)* 8 + i;
1340 /* call corresponding handlers */
1341 if (events&(1<<i)) {
1342 if (irq_flags[srcidx].disabled & (1<<i)) {
1343 if (!irq_flags[srcidx].pending&(1<<i))
1344 mac_irqs[srcidx][i]++;
1345 /* irq disabled -> mark pending */
1346 irq_flags[srcidx].pending |= (1<<i);
1347 } else {
1348 mac_irqs[srcidx][i]++;
1349 /* irq enabled -> call handler */
1350 (via_handler[i].handler)(irq, via, regs);
1353 /* and call handlers for pending irqs - first ?? */
1354 if ( (irq_flags[srcidx].pending & (1<<i))
1355 && !(irq_flags[srcidx].disabled & (1<<i)) ) {
1356 /* call handler for re-enabled irq */
1357 (via_handler[i].handler)(irq, via, regs);
1358 /* and clear pending flag :-) */
1359 irq_flags[srcidx].pending &= ~(1<<i);
1364 * And done ... check for more punishment!
1367 events=(via_read(via,pIFR)&via_read(via,pIER))&0x7F;
1368 ct++;
1369 if(events && ct>8)
1371 printk("psc: stuck events %x\n",events);
1372 for(i=0;i<7;i++)
1374 if(events&(1<<i))
1376 printk("psc - bashing source %d\n",
1378 via_write(via, pIER, 1<<i);
1379 /* via_write(via, pIFR, (1<<i)); */
1382 break;
1385 while(events);
1390 * Nubus handling
1391 * Caution: slot numbers are currently 'hardcoded' to the range 9-15!
1392 * In general, the same request_irq() functions as above can be used if
1393 * the interrupt numbers specifed in macints.h are used.
1396 static int nubus_active=0;
1398 int nubus_request_irq(int slot, void *dev_id, void (*handler)(int,void *,struct pt_regs *))
1400 slot-=9;
1401 /* printk("Nubus request irq for slot %d\n",slot);*/
1402 if(nubus_handler[slot].handler!=nubus_wtf)
1403 return -EBUSY;
1404 nubus_handler[slot].handler=handler;
1405 nubus_handler[slot].dev_id =dev_id;
1406 nubus_param[slot].flags = IRQ_FLG_LOCK;
1407 nubus_param[slot].devname = "nubus slot";
1410 * if no nubus int. was active previously: register the main nubus irq
1411 * handler now!
1414 if (!nubus_active && !via2_is_oss) {
1415 request_irq(IRQ_MAC_NUBUS, via_do_nubus, IRQ_FLG_LOCK,
1416 "nubus dispatch", via_do_nubus);
1419 nubus_active|=1<<slot;
1420 /* printk("program slot %d\n",slot);*/
1421 /* printk("via2=%p\n",via2);*/
1422 #if 0
1423 via_write(via2, vDirA,
1424 via_read(via2, vDirA)|(1<<slot));
1425 via_write(via2, vBufA, 0);
1426 #endif
1427 if (via2_is_oss)
1428 via_write(oss_regp, slot, 2);
1429 else if (!via2_is_rbv) {
1430 /* Make sure the bit is an input */
1431 via_write(via2_regp, vDirA,
1432 via_read(via2_regp, vDirA)&~(1<<slot));
1434 /* printk("nubus irq on\n");*/
1435 return 0;
1438 int nubus_free_irq(int slot)
1440 slot-=9;
1441 nubus_active&=~(1<<slot);
1442 nubus_handler[slot].handler=nubus_wtf;
1443 nubus_handler[slot].dev_id = NULL;
1444 nubus_param[slot].flags = IRQ_FLG_STD;
1445 nubus_param[slot].devname = NULL;
1447 if (via2_is_rbv)
1448 via_write(rbv_regp, rBufA, 1<<slot);
1449 else if (via2_is_oss)
1450 via_write(oss_regp, slot, 0);
1451 else {
1452 via_write(via2_regp, vDirA,
1453 via_read(via2_regp, vDirA)|(1<<slot));
1454 via_write(via2_regp, vBufA, 1<<slot);
1455 via_write(via2_regp, vDirA,
1456 via_read(via2_regp, vDirA)&~(1<<slot));
1458 return 0;
1461 #ifdef CONFIG_BLK_DEV_MAC_IDE
1463 * IDE interrupt hook
1465 extern void (*mac_ide_intr_hook)(int, void *, struct pt_regs *);
1466 #endif
1469 * Nubus dispatch handler - VIA/RBV style
1471 static void via_do_nubus(int slot, void *via, struct pt_regs *regs)
1473 unsigned char map;
1474 int i;
1475 int ct=0;
1477 /* printk("nubus interrupt\n");*/
1479 /* lock the nubus interrupt */
1480 if (via2_is_rbv)
1481 via_write(rbv_regp, rIFR, 0x82);
1482 else
1483 via_write(via2_regp, vIFR, 0x82);
1485 #ifdef CONFIG_BLK_DEV_MAC_IDE
1486 /* IDE hack */
1487 if (mac_ide_intr_hook)
1488 /* 'slot' is lacking the machspec bit in 2.0 */
1489 /* need to pass proper dev_id = hwgroup here */
1490 mac_ide_intr_hook(IRQ_MAC_NUBUS, via, regs);
1491 #endif
1493 while(1)
1495 if (via2_is_rbv)
1496 map = ~via_read(rbv_regp, rBufA);
1497 else
1498 map = ~via_read(via2_regp, vBufA);
1500 if( (map = (map&nubus_active)) ==0 ) {
1501 #ifdef DEBUG_NUBUS_INT
1502 printk("nubus_irq: nothing pending, map %x mask %x\n",
1503 map, nubus_active);
1504 #endif
1505 nubus_irqs[7]++;
1506 break;
1508 #ifdef DEBUG_NUBUS_INT
1509 printk("nubus_irq: map %x mask %x\n", map, nubus_active);
1510 #endif
1512 if(ct++>2)
1514 #ifdef DEBUG_NUBUS_INT
1515 printk("nubus stuck events - %d/%d\n", map, nubus_active);
1516 #endif
1517 return;
1520 for(i=0;i<7;i++)
1522 if(map&(1<<i))
1524 nubus_irqs[i]++;
1525 (nubus_handler[i].handler)(i+9, nubus_handler[i].dev_id, regs);
1528 /* clear it */
1529 if (via2_is_rbv)
1530 via_write(rbv_regp, rIFR, 0x02);
1531 else
1532 via_write(via2_regp, vIFR, 0x02);
1536 /* And done */
1540 * Nubus dispatch handler - OSS style
1542 static void oss_do_nubus(int slot, void *via, struct pt_regs *regs)
1544 unsigned char map;
1545 int i;
1546 int ct=0;
1548 /* printk("nubus interrupt\n");*/
1550 #if 0
1551 /* lock the nubus interrupt */
1552 if (via2_is_rbv)
1553 via_write(rbv_regp, rIFR, 0x82);
1554 else
1555 via_write(via2_regp, vIFR, 0x82);
1556 #endif
1558 /* IDE hack for Quadra: uses Nubus interrupt without any slot bit set */
1559 #ifdef CONFIG_BLK_DEV_MAC_IDE
1560 if (mac_ide_intr_hook)
1561 mac_ide_intr_hook(IRQ_MAC_NUBUS, via, regs);
1562 #endif
1564 while(1)
1566 /* pending events */
1567 map=(via_read(via, nIFR))&0x3F;
1569 #ifdef DEBUG_VIA_NUBUS
1570 printk("nubus_irq: map %x mask %x\n", map, nubus_active);
1571 #endif
1572 if( (map = (map&nubus_active)) ==0 ) {
1573 #ifdef CONFIG_BLK_DEV_MAC_IDE
1574 if (!mac_ide_intr_hook)
1575 printk("nubus_irq: nothing pending, map %x mask %x\n",
1576 map, nubus_active);
1577 #endif
1578 nubus_irqs[7]++;
1579 break;
1582 if(ct++>2)
1584 #if 0
1585 printk("nubus stuck events - %d/%d\n", map, nubus_active);
1586 #endif
1587 return;
1590 for(i=0;i<7;i++)
1592 if(map&(1<<i))
1594 nubus_irqs[i]++;
1595 /* call handler */
1596 (nubus_handler[i].handler)((i+9), nubus_handler[i].dev_id, regs);
1597 /* clear interrupt ?? */
1598 #if 0
1599 via_write(oss_regp, i, 0);
1600 #endif
1603 /* clear it */
1604 #if 0
1605 via_write(oss_regp, nIFR, map);
1606 #endif
1609 /* And done */