aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68k/mac/macints.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m68k/mac/macints.c')
-rw-r--r--arch/m68k/mac/macints.c197
1 files changed, 49 insertions, 148 deletions
diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c
index ba220b70ab8c..5c1a6b2ff0af 100644
--- a/arch/m68k/mac/macints.c
+++ b/arch/m68k/mac/macints.c
@@ -26,10 +26,6 @@
26 * - slot 6: timer 1 (not on IIci) 26 * - slot 6: timer 1 (not on IIci)
27 * - slot 7: status of IRQ; signals 'any enabled int.' 27 * - slot 7: status of IRQ; signals 'any enabled int.'
28 * 28 *
29 * 2 - OSS (IIfx only?)
30 * - slot 0: SCSI interrupt
31 * - slot 1: Sound interrupt
32 *
33 * Levels 3-6 vary by machine type. For VIA or RBV Macintoshes: 29 * Levels 3-6 vary by machine type. For VIA or RBV Macintoshes:
34 * 30 *
35 * 3 - unused (?) 31 * 3 - unused (?)
@@ -42,21 +38,30 @@
42 * 38 *
43 * 6 - off switch (?) 39 * 6 - off switch (?)
44 * 40 *
45 * For OSS Macintoshes (IIfx only at this point): 41 * Machines with Quadra-like VIA hardware, except PSC and PMU machines, support
42 * an alternate interrupt mapping, as used by A/UX. It spreads ethernet and
43 * sound out to their own autovector IRQs and gives VIA1 a higher priority:
46 * 44 *
47 * 3 - Nubus interrupt 45 * 1 - unused (?)
48 * - slot 0: Slot $9
49 * - slot 1: Slot $A
50 * - slot 2: Slot $B
51 * - slot 3: Slot $C
52 * - slot 4: Slot $D
53 * - slot 5: Slot $E
54 * 46 *
55 * 4 - SCC IOP 47 * 3 - on-board SONIC
48 *
49 * 5 - Apple Sound Chip (ASC)
50 *
51 * 6 - VIA1
52 *
53 * For OSS Macintoshes (IIfx only), we apply an interrupt mapping similar to
54 * the Quadra (A/UX) mapping:
55 *
56 * 1 - ISM IOP (ADB)
56 * 57 *
57 * 5 - ISM IOP (ADB?) 58 * 2 - SCSI
58 * 59 *
59 * 6 - unused 60 * 3 - NuBus
61 *
62 * 4 - SCC IOP
63 *
64 * 6 - VIA1
60 * 65 *
61 * For PSC Macintoshes (660AV, 840AV): 66 * For PSC Macintoshes (660AV, 840AV):
62 * 67 *
@@ -100,88 +105,29 @@
100 * case. They're hidden behind the Nubus slot $C interrupt thus adding a 105 * case. They're hidden behind the Nubus slot $C interrupt thus adding a
101 * third layer of indirection. Why oh why did the Apple engineers do that? 106 * third layer of indirection. Why oh why did the Apple engineers do that?
102 * 107 *
103 * - We support "fast" and "slow" handlers, just like the Amiga port. The
104 * fast handlers are called first and with all interrupts disabled. They
105 * are expected to execute quickly (hence the name). The slow handlers are
106 * called last with interrupts enabled and the interrupt level restored.
107 * They must therefore be reentrant.
108 *
109 * TODO:
110 *
111 */ 108 */
112 109
113#include <linux/module.h>
114#include <linux/types.h> 110#include <linux/types.h>
115#include <linux/kernel.h> 111#include <linux/kernel.h>
116#include <linux/sched.h> 112#include <linux/sched.h>
117#include <linux/kernel_stat.h> 113#include <linux/interrupt.h>
118#include <linux/interrupt.h> /* for intr_count */ 114#include <linux/irq.h>
119#include <linux/delay.h> 115#include <linux/delay.h>
120#include <linux/seq_file.h>
121 116
122#include <asm/system.h>
123#include <asm/irq.h> 117#include <asm/irq.h>
124#include <asm/traps.h>
125#include <asm/bootinfo.h>
126#include <asm/macintosh.h> 118#include <asm/macintosh.h>
119#include <asm/macints.h>
127#include <asm/mac_via.h> 120#include <asm/mac_via.h>
128#include <asm/mac_psc.h> 121#include <asm/mac_psc.h>
122#include <asm/mac_oss.h>
123#include <asm/mac_iop.h>
124#include <asm/mac_baboon.h>
129#include <asm/hwtest.h> 125#include <asm/hwtest.h>
130#include <asm/errno.h>
131#include <asm/macints.h>
132#include <asm/irq_regs.h> 126#include <asm/irq_regs.h>
133#include <asm/mac_oss.h>
134 127
135#define SHUTUP_SONIC 128#define SHUTUP_SONIC
136 129
137/* 130/*
138 * VIA/RBV hooks
139 */
140
141extern void via_register_interrupts(void);
142extern void via_irq_enable(int);
143extern void via_irq_disable(int);
144extern void via_irq_clear(int);
145extern int via_irq_pending(int);
146
147/*
148 * OSS hooks
149 */
150
151extern void oss_register_interrupts(void);
152extern void oss_irq_enable(int);
153extern void oss_irq_disable(int);
154extern void oss_irq_clear(int);
155extern int oss_irq_pending(int);
156
157/*
158 * PSC hooks
159 */
160
161extern void psc_register_interrupts(void);
162extern void psc_irq_enable(int);
163extern void psc_irq_disable(int);
164extern void psc_irq_clear(int);
165extern int psc_irq_pending(int);
166
167/*
168 * IOP hooks
169 */
170
171extern void iop_register_interrupts(void);
172
173/*
174 * Baboon hooks
175 */
176
177extern int baboon_present;
178
179extern void baboon_register_interrupts(void);
180extern void baboon_irq_enable(int);
181extern void baboon_irq_disable(int);
182extern void baboon_irq_clear(int);
183
184/*
185 * console_loglevel determines NMI handler function 131 * console_loglevel determines NMI handler function
186 */ 132 */
187 133
@@ -190,10 +136,15 @@ irqreturn_t mac_debug_handler(int, void *);
190 136
191/* #define DEBUG_MACINTS */ 137/* #define DEBUG_MACINTS */
192 138
139static unsigned int mac_irq_startup(struct irq_data *);
140static void mac_irq_shutdown(struct irq_data *);
141
193static struct irq_chip mac_irq_chip = { 142static struct irq_chip mac_irq_chip = {
194 .name = "mac", 143 .name = "mac",
195 .irq_enable = mac_irq_enable, 144 .irq_enable = mac_irq_enable,
196 .irq_disable = mac_irq_disable, 145 .irq_disable = mac_irq_disable,
146 .irq_startup = mac_irq_startup,
147 .irq_shutdown = mac_irq_shutdown,
197}; 148};
198 149
199void __init mac_init_IRQ(void) 150void __init mac_init_IRQ(void)
@@ -239,8 +190,6 @@ void __init mac_init_IRQ(void)
239/* 190/*
240 * mac_irq_enable - enable an interrupt source 191 * mac_irq_enable - enable an interrupt source
241 * mac_irq_disable - disable an interrupt source 192 * mac_irq_disable - disable an interrupt source
242 * mac_clear_irq - clears a pending interrupt
243 * mac_irq_pending - returns the pending status of an IRQ (nonzero = pending)
244 * 193 *
245 * These routines are just dispatchers to the VIA/OSS/PSC routines. 194 * These routines are just dispatchers to the VIA/OSS/PSC routines.
246 */ 195 */
@@ -252,8 +201,6 @@ void mac_irq_enable(struct irq_data *data)
252 201
253 switch(irq_src) { 202 switch(irq_src) {
254 case 1: 203 case 1:
255 via_irq_enable(irq);
256 break;
257 case 2: 204 case 2:
258 case 7: 205 case 7:
259 if (oss_present) 206 if (oss_present)
@@ -262,6 +209,7 @@ void mac_irq_enable(struct irq_data *data)
262 via_irq_enable(irq); 209 via_irq_enable(irq);
263 break; 210 break;
264 case 3: 211 case 3:
212 case 4:
265 case 5: 213 case 5:
266 case 6: 214 case 6:
267 if (psc_present) 215 if (psc_present)
@@ -269,10 +217,6 @@ void mac_irq_enable(struct irq_data *data)
269 else if (oss_present) 217 else if (oss_present)
270 oss_irq_enable(irq); 218 oss_irq_enable(irq);
271 break; 219 break;
272 case 4:
273 if (psc_present)
274 psc_irq_enable(irq);
275 break;
276 case 8: 220 case 8:
277 if (baboon_present) 221 if (baboon_present)
278 baboon_irq_enable(irq); 222 baboon_irq_enable(irq);
@@ -287,8 +231,6 @@ void mac_irq_disable(struct irq_data *data)
287 231
288 switch(irq_src) { 232 switch(irq_src) {
289 case 1: 233 case 1:
290 via_irq_disable(irq);
291 break;
292 case 2: 234 case 2:
293 case 7: 235 case 7:
294 if (oss_present) 236 if (oss_present)
@@ -297,6 +239,7 @@ void mac_irq_disable(struct irq_data *data)
297 via_irq_disable(irq); 239 via_irq_disable(irq);
298 break; 240 break;
299 case 3: 241 case 3:
242 case 4:
300 case 5: 243 case 5:
301 case 6: 244 case 6:
302 if (psc_present) 245 if (psc_present)
@@ -304,10 +247,6 @@ void mac_irq_disable(struct irq_data *data)
304 else if (oss_present) 247 else if (oss_present)
305 oss_irq_disable(irq); 248 oss_irq_disable(irq);
306 break; 249 break;
307 case 4:
308 if (psc_present)
309 psc_irq_disable(irq);
310 break;
311 case 8: 250 case 8:
312 if (baboon_present) 251 if (baboon_present)
313 baboon_irq_disable(irq); 252 baboon_irq_disable(irq);
@@ -315,65 +254,27 @@ void mac_irq_disable(struct irq_data *data)
315 } 254 }
316} 255}
317 256
318void mac_clear_irq(unsigned int irq) 257static unsigned int mac_irq_startup(struct irq_data *data)
319{ 258{
320 switch(IRQ_SRC(irq)) { 259 int irq = data->irq;
321 case 1: 260
322 via_irq_clear(irq); 261 if (IRQ_SRC(irq) == 7 && !oss_present)
323 break; 262 via_nubus_irq_startup(irq);
324 case 2: 263 else
325 case 7: 264 mac_irq_enable(data);
326 if (oss_present) 265
327 oss_irq_clear(irq); 266 return 0;
328 else
329 via_irq_clear(irq);
330 break;
331 case 3:
332 case 5:
333 case 6:
334 if (psc_present)
335 psc_irq_clear(irq);
336 else if (oss_present)
337 oss_irq_clear(irq);
338 break;
339 case 4:
340 if (psc_present)
341 psc_irq_clear(irq);
342 break;
343 case 8:
344 if (baboon_present)
345 baboon_irq_clear(irq);
346 break;
347 }
348} 267}
349 268
350int mac_irq_pending(unsigned int irq) 269static void mac_irq_shutdown(struct irq_data *data)
351{ 270{
352 switch(IRQ_SRC(irq)) { 271 int irq = data->irq;
353 case 1: 272
354 return via_irq_pending(irq); 273 if (IRQ_SRC(irq) == 7 && !oss_present)
355 case 2: 274 via_nubus_irq_shutdown(irq);
356 case 7: 275 else
357 if (oss_present) 276 mac_irq_disable(data);
358 return oss_irq_pending(irq);
359 else
360 return via_irq_pending(irq);
361 case 3:
362 case 5:
363 case 6:
364 if (psc_present)
365 return psc_irq_pending(irq);
366 else if (oss_present)
367 return oss_irq_pending(irq);
368 break;
369 case 4:
370 if (psc_present)
371 return psc_irq_pending(irq);
372 break;
373 }
374 return 0;
375} 277}
376EXPORT_SYMBOL(mac_irq_pending);
377 278
378static int num_debug[8]; 279static int num_debug[8];
379 280