diff options
Diffstat (limited to 'arch/m68k/amiga/amiints.c')
-rw-r--r-- | arch/m68k/amiga/amiints.c | 382 |
1 files changed, 36 insertions, 346 deletions
diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c index e2d47b7bdfc1..f9403f4640a1 100644 --- a/arch/m68k/amiga/amiints.c +++ b/arch/m68k/amiga/amiints.c | |||
@@ -35,62 +35,30 @@ | |||
35 | * /Jes | 35 | * /Jes |
36 | */ | 36 | */ |
37 | 37 | ||
38 | #include <linux/types.h> | ||
39 | #include <linux/kernel.h> | ||
40 | #include <linux/sched.h> | ||
41 | #include <linux/kernel_stat.h> | ||
42 | #include <linux/init.h> | 38 | #include <linux/init.h> |
43 | #include <linux/interrupt.h> | 39 | #include <linux/interrupt.h> |
44 | #include <linux/errno.h> | 40 | #include <linux/errno.h> |
45 | #include <linux/seq_file.h> | ||
46 | 41 | ||
47 | #include <asm/system.h> | ||
48 | #include <asm/irq.h> | 42 | #include <asm/irq.h> |
49 | #include <asm/traps.h> | 43 | #include <asm/traps.h> |
50 | #include <asm/amigahw.h> | 44 | #include <asm/amigahw.h> |
51 | #include <asm/amigaints.h> | 45 | #include <asm/amigaints.h> |
52 | #include <asm/amipcmcia.h> | 46 | #include <asm/amipcmcia.h> |
53 | 47 | ||
54 | extern int cia_request_irq(struct ciabase *base,int irq, | 48 | static void amiga_enable_irq(unsigned int irq); |
55 | irqreturn_t (*handler)(int, void *, struct pt_regs *), | 49 | static void amiga_disable_irq(unsigned int irq); |
56 | unsigned long flags, const char *devname, void *dev_id); | 50 | static irqreturn_t ami_int1(int irq, void *dev_id, struct pt_regs *fp); |
57 | extern void cia_free_irq(struct ciabase *base, unsigned int irq, void *dev_id); | 51 | static irqreturn_t ami_int3(int irq, void *dev_id, struct pt_regs *fp); |
58 | extern void cia_init_IRQ(struct ciabase *base); | 52 | static irqreturn_t ami_int4(int irq, void *dev_id, struct pt_regs *fp); |
59 | extern int cia_get_irq_list(struct ciabase *base, struct seq_file *p); | 53 | static irqreturn_t ami_int5(int irq, void *dev_id, struct pt_regs *fp); |
60 | 54 | ||
61 | /* irq node variables for amiga interrupt sources */ | 55 | static struct irq_controller amiga_irq_controller = { |
62 | static irq_node_t *ami_irq_list[AMI_STD_IRQS]; | 56 | .name = "amiga", |
63 | 57 | .lock = SPIN_LOCK_UNLOCKED, | |
64 | static unsigned short amiga_intena_vals[AMI_STD_IRQS] = { | 58 | .enable = amiga_enable_irq, |
65 | [IRQ_AMIGA_VERTB-IRQ_USER] = IF_VERTB, | 59 | .disable = amiga_disable_irq, |
66 | [IRQ_AMIGA_COPPER-IRQ_USER] = IF_COPER, | ||
67 | [IRQ_AMIGA_AUD0-IRQ_USER] = IF_AUD0, | ||
68 | [IRQ_AMIGA_AUD1-IRQ_USER] = IF_AUD1, | ||
69 | [IRQ_AMIGA_AUD2-IRQ_USER] = IF_AUD2, | ||
70 | [IRQ_AMIGA_AUD3-IRQ_USER] = IF_AUD3, | ||
71 | [IRQ_AMIGA_BLIT-IRQ_USER] = IF_BLIT, | ||
72 | [IRQ_AMIGA_DSKSYN-IRQ_USER] = IF_DSKSYN, | ||
73 | [IRQ_AMIGA_DSKBLK-IRQ_USER] = IF_DSKBLK, | ||
74 | [IRQ_AMIGA_RBF-IRQ_USER] = IF_RBF, | ||
75 | [IRQ_AMIGA_TBE-IRQ_USER] = IF_TBE, | ||
76 | [IRQ_AMIGA_SOFT-IRQ_USER] = IF_SOFT, | ||
77 | [IRQ_AMIGA_PORTS-IRQ_USER] = IF_PORTS, | ||
78 | [IRQ_AMIGA_EXTER-IRQ_USER] = IF_EXTER | ||
79 | }; | ||
80 | static const unsigned char ami_servers[AMI_STD_IRQS] = { | ||
81 | [IRQ_AMIGA_VERTB-IRQ_USER] = 1, | ||
82 | [IRQ_AMIGA_PORTS-IRQ_USER] = 1, | ||
83 | [IRQ_AMIGA_EXTER-IRQ_USER] = 1 | ||
84 | }; | 60 | }; |
85 | 61 | ||
86 | static short ami_ablecount[AMI_IRQS]; | ||
87 | |||
88 | static irqreturn_t ami_badint(int irq, void *dev_id, struct pt_regs *fp) | ||
89 | { | ||
90 | num_spurious += 1; | ||
91 | return IRQ_NONE; | ||
92 | } | ||
93 | |||
94 | /* | 62 | /* |
95 | * void amiga_init_IRQ(void) | 63 | * void amiga_init_IRQ(void) |
96 | * | 64 | * |
@@ -104,23 +72,12 @@ static irqreturn_t ami_badint(int irq, void *dev_id, struct pt_regs *fp) | |||
104 | 72 | ||
105 | void __init amiga_init_IRQ(void) | 73 | void __init amiga_init_IRQ(void) |
106 | { | 74 | { |
107 | int i; | 75 | request_irq(IRQ_AUTO_1, ami_int1, 0, "int1", NULL); |
76 | request_irq(IRQ_AUTO_3, ami_int3, 0, "int3", NULL); | ||
77 | request_irq(IRQ_AUTO_4, ami_int4, 0, "int4", NULL); | ||
78 | request_irq(IRQ_AUTO_5, ami_int5, 0, "int5", NULL); | ||
108 | 79 | ||
109 | /* initialize handlers */ | 80 | m68k_setup_irq_controller(&amiga_irq_controller, IRQ_USER, AMI_STD_IRQS); |
110 | for (i = 0; i < AMI_STD_IRQS; i++) { | ||
111 | if (ami_servers[i]) { | ||
112 | ami_irq_list[i] = NULL; | ||
113 | } else { | ||
114 | ami_irq_list[i] = new_irq_node(); | ||
115 | ami_irq_list[i]->handler = ami_badint; | ||
116 | ami_irq_list[i]->flags = 0; | ||
117 | ami_irq_list[i]->dev_id = NULL; | ||
118 | ami_irq_list[i]->devname = NULL; | ||
119 | ami_irq_list[i]->next = NULL; | ||
120 | } | ||
121 | } | ||
122 | for (i = 0; i < AMI_IRQS; i++) | ||
123 | ami_ablecount[i] = 0; | ||
124 | 81 | ||
125 | /* turn off PCMCIA interrupts */ | 82 | /* turn off PCMCIA interrupts */ |
126 | if (AMIGAHW_PRESENT(PCMCIA)) | 83 | if (AMIGAHW_PRESENT(PCMCIA)) |
@@ -135,250 +92,21 @@ void __init amiga_init_IRQ(void) | |||
135 | cia_init_IRQ(&ciab_base); | 92 | cia_init_IRQ(&ciab_base); |
136 | } | 93 | } |
137 | 94 | ||
138 | static inline int amiga_insert_irq(irq_node_t **list, irq_node_t *node) | ||
139 | { | ||
140 | unsigned long flags; | ||
141 | irq_node_t *cur; | ||
142 | |||
143 | if (!node->dev_id) | ||
144 | printk("%s: Warning: dev_id of %s is zero\n", | ||
145 | __FUNCTION__, node->devname); | ||
146 | |||
147 | local_irq_save(flags); | ||
148 | |||
149 | cur = *list; | ||
150 | |||
151 | if (node->flags & SA_INTERRUPT) { | ||
152 | if (node->flags & SA_SHIRQ) | ||
153 | return -EBUSY; | ||
154 | /* | ||
155 | * There should never be more than one | ||
156 | */ | ||
157 | while (cur && cur->flags & SA_INTERRUPT) { | ||
158 | list = &cur->next; | ||
159 | cur = cur->next; | ||
160 | } | ||
161 | } else { | ||
162 | while (cur) { | ||
163 | list = &cur->next; | ||
164 | cur = cur->next; | ||
165 | } | ||
166 | } | ||
167 | |||
168 | node->next = cur; | ||
169 | *list = node; | ||
170 | |||
171 | local_irq_restore(flags); | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static inline void amiga_delete_irq(irq_node_t **list, void *dev_id) | ||
176 | { | ||
177 | unsigned long flags; | ||
178 | irq_node_t *node; | ||
179 | |||
180 | local_irq_save(flags); | ||
181 | |||
182 | for (node = *list; node; list = &node->next, node = *list) { | ||
183 | if (node->dev_id == dev_id) { | ||
184 | *list = node->next; | ||
185 | /* Mark it as free. */ | ||
186 | node->handler = NULL; | ||
187 | local_irq_restore(flags); | ||
188 | return; | ||
189 | } | ||
190 | } | ||
191 | local_irq_restore(flags); | ||
192 | printk ("%s: tried to remove invalid irq\n", __FUNCTION__); | ||
193 | } | ||
194 | |||
195 | /* | ||
196 | * amiga_request_irq : add an interrupt service routine for a particular | ||
197 | * machine specific interrupt source. | ||
198 | * If the addition was successful, it returns 0. | ||
199 | */ | ||
200 | |||
201 | int amiga_request_irq(unsigned int irq, | ||
202 | irqreturn_t (*handler)(int, void *, struct pt_regs *), | ||
203 | unsigned long flags, const char *devname, void *dev_id) | ||
204 | { | ||
205 | irq_node_t *node; | ||
206 | int error = 0; | ||
207 | |||
208 | if (irq >= AMI_IRQS) { | ||
209 | printk ("%s: Unknown IRQ %d from %s\n", __FUNCTION__, | ||
210 | irq, devname); | ||
211 | return -ENXIO; | ||
212 | } | ||
213 | |||
214 | if (irq < IRQ_USER) | ||
215 | return cpu_request_irq(irq, handler, flags, devname, dev_id); | ||
216 | |||
217 | if (irq >= IRQ_AMIGA_CIAB) | ||
218 | return cia_request_irq(&ciab_base, irq - IRQ_AMIGA_CIAB, | ||
219 | handler, flags, devname, dev_id); | ||
220 | |||
221 | if (irq >= IRQ_AMIGA_CIAA) | ||
222 | return cia_request_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA, | ||
223 | handler, flags, devname, dev_id); | ||
224 | |||
225 | irq -= IRQ_USER; | ||
226 | /* | ||
227 | * IRQ_AMIGA_PORTS & IRQ_AMIGA_EXTER defaults to shared, | ||
228 | * we could add a check here for the SA_SHIRQ flag but all drivers | ||
229 | * should be aware of sharing anyway. | ||
230 | */ | ||
231 | if (ami_servers[irq]) { | ||
232 | if (!(node = new_irq_node())) | ||
233 | return -ENOMEM; | ||
234 | node->handler = handler; | ||
235 | node->flags = flags; | ||
236 | node->dev_id = dev_id; | ||
237 | node->devname = devname; | ||
238 | node->next = NULL; | ||
239 | error = amiga_insert_irq(&ami_irq_list[irq], node); | ||
240 | } else { | ||
241 | ami_irq_list[irq]->handler = handler; | ||
242 | ami_irq_list[irq]->flags = flags; | ||
243 | ami_irq_list[irq]->dev_id = dev_id; | ||
244 | ami_irq_list[irq]->devname = devname; | ||
245 | } | ||
246 | |||
247 | /* enable the interrupt */ | ||
248 | if (irq < IRQ_AMIGA_PORTS && !ami_ablecount[irq]) | ||
249 | amiga_custom.intena = IF_SETCLR | amiga_intena_vals[irq]; | ||
250 | |||
251 | return error; | ||
252 | } | ||
253 | |||
254 | void amiga_free_irq(unsigned int irq, void *dev_id) | ||
255 | { | ||
256 | if (irq >= AMI_IRQS) { | ||
257 | printk ("%s: Unknown IRQ %d\n", __FUNCTION__, irq); | ||
258 | return; | ||
259 | } | ||
260 | |||
261 | if (irq < IRQ_USER) | ||
262 | cpu_free_irq(irq, dev_id); | ||
263 | |||
264 | if (irq >= IRQ_AMIGA_CIAB) { | ||
265 | cia_free_irq(&ciab_base, irq - IRQ_AMIGA_CIAB, dev_id); | ||
266 | return; | ||
267 | } | ||
268 | |||
269 | if (irq >= IRQ_AMIGA_CIAA) { | ||
270 | cia_free_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA, dev_id); | ||
271 | return; | ||
272 | } | ||
273 | |||
274 | irq -= IRQ_USER; | ||
275 | if (ami_servers[irq]) { | ||
276 | amiga_delete_irq(&ami_irq_list[irq], dev_id); | ||
277 | /* if server list empty, disable the interrupt */ | ||
278 | if (!ami_irq_list[irq] && irq < IRQ_AMIGA_PORTS) | ||
279 | amiga_custom.intena = amiga_intena_vals[irq]; | ||
280 | } else { | ||
281 | if (ami_irq_list[irq]->dev_id != dev_id) | ||
282 | printk("%s: removing probably wrong IRQ %d from %s\n", | ||
283 | __FUNCTION__, irq, ami_irq_list[irq]->devname); | ||
284 | ami_irq_list[irq]->handler = ami_badint; | ||
285 | ami_irq_list[irq]->flags = 0; | ||
286 | ami_irq_list[irq]->dev_id = NULL; | ||
287 | ami_irq_list[irq]->devname = NULL; | ||
288 | amiga_custom.intena = amiga_intena_vals[irq]; | ||
289 | } | ||
290 | } | ||
291 | |||
292 | /* | 95 | /* |
293 | * Enable/disable a particular machine specific interrupt source. | 96 | * Enable/disable a particular machine specific interrupt source. |
294 | * Note that this may affect other interrupts in case of a shared interrupt. | 97 | * Note that this may affect other interrupts in case of a shared interrupt. |
295 | * This function should only be called for a _very_ short time to change some | 98 | * This function should only be called for a _very_ short time to change some |
296 | * internal data, that may not be changed by the interrupt at the same time. | 99 | * internal data, that may not be changed by the interrupt at the same time. |
297 | * ami_(enable|disable)_irq calls may also be nested. | ||
298 | */ | 100 | */ |
299 | 101 | ||
300 | void amiga_enable_irq(unsigned int irq) | 102 | static void amiga_enable_irq(unsigned int irq) |
301 | { | ||
302 | if (irq >= AMI_IRQS) { | ||
303 | printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq); | ||
304 | return; | ||
305 | } | ||
306 | |||
307 | if (--ami_ablecount[irq]) | ||
308 | return; | ||
309 | |||
310 | /* No action for auto-vector interrupts */ | ||
311 | if (irq < IRQ_USER) { | ||
312 | printk("%s: Trying to enable auto-vector IRQ %i\n", | ||
313 | __FUNCTION__, irq); | ||
314 | return; | ||
315 | } | ||
316 | |||
317 | if (irq >= IRQ_AMIGA_CIAB) { | ||
318 | cia_set_irq(&ciab_base, (1 << (irq - IRQ_AMIGA_CIAB))); | ||
319 | cia_able_irq(&ciab_base, CIA_ICR_SETCLR | | ||
320 | (1 << (irq - IRQ_AMIGA_CIAB))); | ||
321 | return; | ||
322 | } | ||
323 | |||
324 | if (irq >= IRQ_AMIGA_CIAA) { | ||
325 | cia_set_irq(&ciaa_base, (1 << (irq - IRQ_AMIGA_CIAA))); | ||
326 | cia_able_irq(&ciaa_base, CIA_ICR_SETCLR | | ||
327 | (1 << (irq - IRQ_AMIGA_CIAA))); | ||
328 | return; | ||
329 | } | ||
330 | |||
331 | /* enable the interrupt */ | ||
332 | amiga_custom.intena = IF_SETCLR | amiga_intena_vals[irq-IRQ_USER]; | ||
333 | } | ||
334 | |||
335 | void amiga_disable_irq(unsigned int irq) | ||
336 | { | ||
337 | if (irq >= AMI_IRQS) { | ||
338 | printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq); | ||
339 | return; | ||
340 | } | ||
341 | |||
342 | if (ami_ablecount[irq]++) | ||
343 | return; | ||
344 | |||
345 | /* No action for auto-vector interrupts */ | ||
346 | if (irq < IRQ_USER) { | ||
347 | printk("%s: Trying to disable auto-vector IRQ %i\n", | ||
348 | __FUNCTION__, irq); | ||
349 | return; | ||
350 | } | ||
351 | |||
352 | if (irq >= IRQ_AMIGA_CIAB) { | ||
353 | cia_able_irq(&ciab_base, 1 << (irq - IRQ_AMIGA_CIAB)); | ||
354 | return; | ||
355 | } | ||
356 | |||
357 | if (irq >= IRQ_AMIGA_CIAA) { | ||
358 | cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA)); | ||
359 | return; | ||
360 | } | ||
361 | |||
362 | /* disable the interrupt */ | ||
363 | amiga_custom.intena = amiga_intena_vals[irq-IRQ_USER]; | ||
364 | } | ||
365 | |||
366 | inline void amiga_do_irq(int irq, struct pt_regs *fp) | ||
367 | { | 103 | { |
368 | kstat_cpu(0).irqs[irq]++; | 104 | amiga_custom.intena = IF_SETCLR | (1 << (irq - IRQ_USER)); |
369 | ami_irq_list[irq-IRQ_USER]->handler(irq, ami_irq_list[irq-IRQ_USER]->dev_id, fp); | ||
370 | } | 105 | } |
371 | 106 | ||
372 | void amiga_do_irq_list(int irq, struct pt_regs *fp) | 107 | static void amiga_disable_irq(unsigned int irq) |
373 | { | 108 | { |
374 | irq_node_t *node; | 109 | amiga_custom.intena = 1 << (irq - IRQ_USER); |
375 | |||
376 | kstat_cpu(0).irqs[irq]++; | ||
377 | |||
378 | amiga_custom.intreq = amiga_intena_vals[irq-IRQ_USER]; | ||
379 | |||
380 | for (node = ami_irq_list[irq-IRQ_USER]; node; node = node->next) | ||
381 | node->handler(irq, node->dev_id, fp); | ||
382 | } | 110 | } |
383 | 111 | ||
384 | /* | 112 | /* |
@@ -392,19 +120,19 @@ static irqreturn_t ami_int1(int irq, void *dev_id, struct pt_regs *fp) | |||
392 | /* if serial transmit buffer empty, interrupt */ | 120 | /* if serial transmit buffer empty, interrupt */ |
393 | if (ints & IF_TBE) { | 121 | if (ints & IF_TBE) { |
394 | amiga_custom.intreq = IF_TBE; | 122 | amiga_custom.intreq = IF_TBE; |
395 | amiga_do_irq(IRQ_AMIGA_TBE, fp); | 123 | m68k_handle_int(IRQ_AMIGA_TBE, fp); |
396 | } | 124 | } |
397 | 125 | ||
398 | /* if floppy disk transfer complete, interrupt */ | 126 | /* if floppy disk transfer complete, interrupt */ |
399 | if (ints & IF_DSKBLK) { | 127 | if (ints & IF_DSKBLK) { |
400 | amiga_custom.intreq = IF_DSKBLK; | 128 | amiga_custom.intreq = IF_DSKBLK; |
401 | amiga_do_irq(IRQ_AMIGA_DSKBLK, fp); | 129 | m68k_handle_int(IRQ_AMIGA_DSKBLK, fp); |
402 | } | 130 | } |
403 | 131 | ||
404 | /* if software interrupt set, interrupt */ | 132 | /* if software interrupt set, interrupt */ |
405 | if (ints & IF_SOFT) { | 133 | if (ints & IF_SOFT) { |
406 | amiga_custom.intreq = IF_SOFT; | 134 | amiga_custom.intreq = IF_SOFT; |
407 | amiga_do_irq(IRQ_AMIGA_SOFT, fp); | 135 | m68k_handle_int(IRQ_AMIGA_SOFT, fp); |
408 | } | 136 | } |
409 | return IRQ_HANDLED; | 137 | return IRQ_HANDLED; |
410 | } | 138 | } |
@@ -416,18 +144,20 @@ static irqreturn_t ami_int3(int irq, void *dev_id, struct pt_regs *fp) | |||
416 | /* if a blitter interrupt */ | 144 | /* if a blitter interrupt */ |
417 | if (ints & IF_BLIT) { | 145 | if (ints & IF_BLIT) { |
418 | amiga_custom.intreq = IF_BLIT; | 146 | amiga_custom.intreq = IF_BLIT; |
419 | amiga_do_irq(IRQ_AMIGA_BLIT, fp); | 147 | m68k_handle_int(IRQ_AMIGA_BLIT, fp); |
420 | } | 148 | } |
421 | 149 | ||
422 | /* if a copper interrupt */ | 150 | /* if a copper interrupt */ |
423 | if (ints & IF_COPER) { | 151 | if (ints & IF_COPER) { |
424 | amiga_custom.intreq = IF_COPER; | 152 | amiga_custom.intreq = IF_COPER; |
425 | amiga_do_irq(IRQ_AMIGA_COPPER, fp); | 153 | m68k_handle_int(IRQ_AMIGA_COPPER, fp); |
426 | } | 154 | } |
427 | 155 | ||
428 | /* if a vertical blank interrupt */ | 156 | /* if a vertical blank interrupt */ |
429 | if (ints & IF_VERTB) | 157 | if (ints & IF_VERTB) { |
430 | amiga_do_irq_list(IRQ_AMIGA_VERTB, fp); | 158 | amiga_custom.intreq = IF_VERTB; |
159 | m68k_handle_int(IRQ_AMIGA_VERTB, fp); | ||
160 | } | ||
431 | return IRQ_HANDLED; | 161 | return IRQ_HANDLED; |
432 | } | 162 | } |
433 | 163 | ||
@@ -438,25 +168,25 @@ static irqreturn_t ami_int4(int irq, void *dev_id, struct pt_regs *fp) | |||
438 | /* if audio 0 interrupt */ | 168 | /* if audio 0 interrupt */ |
439 | if (ints & IF_AUD0) { | 169 | if (ints & IF_AUD0) { |
440 | amiga_custom.intreq = IF_AUD0; | 170 | amiga_custom.intreq = IF_AUD0; |
441 | amiga_do_irq(IRQ_AMIGA_AUD0, fp); | 171 | m68k_handle_int(IRQ_AMIGA_AUD0, fp); |
442 | } | 172 | } |
443 | 173 | ||
444 | /* if audio 1 interrupt */ | 174 | /* if audio 1 interrupt */ |
445 | if (ints & IF_AUD1) { | 175 | if (ints & IF_AUD1) { |
446 | amiga_custom.intreq = IF_AUD1; | 176 | amiga_custom.intreq = IF_AUD1; |
447 | amiga_do_irq(IRQ_AMIGA_AUD1, fp); | 177 | m68k_handle_int(IRQ_AMIGA_AUD1, fp); |
448 | } | 178 | } |
449 | 179 | ||
450 | /* if audio 2 interrupt */ | 180 | /* if audio 2 interrupt */ |
451 | if (ints & IF_AUD2) { | 181 | if (ints & IF_AUD2) { |
452 | amiga_custom.intreq = IF_AUD2; | 182 | amiga_custom.intreq = IF_AUD2; |
453 | amiga_do_irq(IRQ_AMIGA_AUD2, fp); | 183 | m68k_handle_int(IRQ_AMIGA_AUD2, fp); |
454 | } | 184 | } |
455 | 185 | ||
456 | /* if audio 3 interrupt */ | 186 | /* if audio 3 interrupt */ |
457 | if (ints & IF_AUD3) { | 187 | if (ints & IF_AUD3) { |
458 | amiga_custom.intreq = IF_AUD3; | 188 | amiga_custom.intreq = IF_AUD3; |
459 | amiga_do_irq(IRQ_AMIGA_AUD3, fp); | 189 | m68k_handle_int(IRQ_AMIGA_AUD3, fp); |
460 | } | 190 | } |
461 | return IRQ_HANDLED; | 191 | return IRQ_HANDLED; |
462 | } | 192 | } |
@@ -468,53 +198,13 @@ static irqreturn_t ami_int5(int irq, void *dev_id, struct pt_regs *fp) | |||
468 | /* if serial receive buffer full interrupt */ | 198 | /* if serial receive buffer full interrupt */ |
469 | if (ints & IF_RBF) { | 199 | if (ints & IF_RBF) { |
470 | /* acknowledge of IF_RBF must be done by the serial interrupt */ | 200 | /* acknowledge of IF_RBF must be done by the serial interrupt */ |
471 | amiga_do_irq(IRQ_AMIGA_RBF, fp); | 201 | m68k_handle_int(IRQ_AMIGA_RBF, fp); |
472 | } | 202 | } |
473 | 203 | ||
474 | /* if a disk sync interrupt */ | 204 | /* if a disk sync interrupt */ |
475 | if (ints & IF_DSKSYN) { | 205 | if (ints & IF_DSKSYN) { |
476 | amiga_custom.intreq = IF_DSKSYN; | 206 | amiga_custom.intreq = IF_DSKSYN; |
477 | amiga_do_irq(IRQ_AMIGA_DSKSYN, fp); | 207 | m68k_handle_int(IRQ_AMIGA_DSKSYN, fp); |
478 | } | 208 | } |
479 | return IRQ_HANDLED; | 209 | return IRQ_HANDLED; |
480 | } | 210 | } |
481 | |||
482 | static irqreturn_t ami_int7(int irq, void *dev_id, struct pt_regs *fp) | ||
483 | { | ||
484 | panic ("level 7 interrupt received\n"); | ||
485 | } | ||
486 | |||
487 | irqreturn_t (*amiga_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = { | ||
488 | [1] = ami_int1, | ||
489 | [3] = ami_int3, | ||
490 | [4] = ami_int4, | ||
491 | [5] = ami_int5, | ||
492 | [7] = ami_int7 | ||
493 | }; | ||
494 | |||
495 | int show_amiga_interrupts(struct seq_file *p, void *v) | ||
496 | { | ||
497 | int i; | ||
498 | irq_node_t *node; | ||
499 | |||
500 | for (i = IRQ_USER; i < IRQ_AMIGA_CIAA; i++) { | ||
501 | node = ami_irq_list[i - IRQ_USER]; | ||
502 | if (!node) | ||
503 | continue; | ||
504 | seq_printf(p, "ami %2d: %10u ", i, | ||
505 | kstat_cpu(0).irqs[i]); | ||
506 | do { | ||
507 | if (node->flags & SA_INTERRUPT) | ||
508 | seq_puts(p, "F "); | ||
509 | else | ||
510 | seq_puts(p, " "); | ||
511 | seq_printf(p, "%s\n", node->devname); | ||
512 | if ((node = node->next)) | ||
513 | seq_puts(p, " "); | ||
514 | } while (node); | ||
515 | } | ||
516 | |||
517 | cia_get_irq_list(&ciaa_base, p); | ||
518 | cia_get_irq_list(&ciab_base, p); | ||
519 | return 0; | ||
520 | } | ||