diff options
Diffstat (limited to 'arch/m68k/mac/macints.c')
-rw-r--r-- | arch/m68k/mac/macints.c | 197 |
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 | |||
141 | extern void via_register_interrupts(void); | ||
142 | extern void via_irq_enable(int); | ||
143 | extern void via_irq_disable(int); | ||
144 | extern void via_irq_clear(int); | ||
145 | extern int via_irq_pending(int); | ||
146 | |||
147 | /* | ||
148 | * OSS hooks | ||
149 | */ | ||
150 | |||
151 | extern void oss_register_interrupts(void); | ||
152 | extern void oss_irq_enable(int); | ||
153 | extern void oss_irq_disable(int); | ||
154 | extern void oss_irq_clear(int); | ||
155 | extern int oss_irq_pending(int); | ||
156 | |||
157 | /* | ||
158 | * PSC hooks | ||
159 | */ | ||
160 | |||
161 | extern void psc_register_interrupts(void); | ||
162 | extern void psc_irq_enable(int); | ||
163 | extern void psc_irq_disable(int); | ||
164 | extern void psc_irq_clear(int); | ||
165 | extern int psc_irq_pending(int); | ||
166 | |||
167 | /* | ||
168 | * IOP hooks | ||
169 | */ | ||
170 | |||
171 | extern void iop_register_interrupts(void); | ||
172 | |||
173 | /* | ||
174 | * Baboon hooks | ||
175 | */ | ||
176 | |||
177 | extern int baboon_present; | ||
178 | |||
179 | extern void baboon_register_interrupts(void); | ||
180 | extern void baboon_irq_enable(int); | ||
181 | extern void baboon_irq_disable(int); | ||
182 | extern 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 | ||
139 | static unsigned int mac_irq_startup(struct irq_data *); | ||
140 | static void mac_irq_shutdown(struct irq_data *); | ||
141 | |||
193 | static struct irq_chip mac_irq_chip = { | 142 | static 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 | ||
199 | void __init mac_init_IRQ(void) | 150 | void __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 | ||
318 | void mac_clear_irq(unsigned int irq) | 257 | static 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 | ||
350 | int mac_irq_pending(unsigned int irq) | 269 | static 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 | } |
376 | EXPORT_SYMBOL(mac_irq_pending); | ||
377 | 278 | ||
378 | static int num_debug[8]; | 279 | static int num_debug[8]; |
379 | 280 | ||