diff options
| author | Roman Zippel <zippel@linux-m68k.org> | 2006-06-25 08:47:01 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-25 13:00:57 -0400 |
| commit | 74be8d0835f91f0f77a2f1554dfa7242f1f7b652 (patch) | |
| tree | 8a761fdba6a921bad34a9f87ed4af4e336c05e55 | |
| parent | 68387c448b7f2b3e2bfa0f606391cd3b602b1997 (diff) | |
[PATCH] m68k: convert amiga irq code
Signed-off-by: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
| -rw-r--r-- | arch/m68k/amiga/amiga_ksyms.c | 2 | ||||
| -rw-r--r-- | arch/m68k/amiga/amiints.c | 382 | ||||
| -rw-r--r-- | arch/m68k/amiga/cia.c | 155 | ||||
| -rw-r--r-- | arch/m68k/amiga/config.c | 15 | ||||
| -rw-r--r-- | include/asm-m68k/amigaints.h | 8 |
5 files changed, 117 insertions, 445 deletions
diff --git a/arch/m68k/amiga/amiga_ksyms.c b/arch/m68k/amiga/amiga_ksyms.c index b7bd84c73ea7..8f2e0587ae2f 100644 --- a/arch/m68k/amiga/amiga_ksyms.c +++ b/arch/m68k/amiga/amiga_ksyms.c | |||
| @@ -23,8 +23,6 @@ EXPORT_SYMBOL(amiga_chip_avail); | |||
| 23 | EXPORT_SYMBOL(amiga_chip_size); | 23 | EXPORT_SYMBOL(amiga_chip_size); |
| 24 | EXPORT_SYMBOL(amiga_audio_period); | 24 | EXPORT_SYMBOL(amiga_audio_period); |
| 25 | EXPORT_SYMBOL(amiga_audio_min_period); | 25 | EXPORT_SYMBOL(amiga_audio_min_period); |
| 26 | EXPORT_SYMBOL(amiga_do_irq); | ||
| 27 | EXPORT_SYMBOL(amiga_do_irq_list); | ||
| 28 | 26 | ||
| 29 | #ifdef CONFIG_AMIGA_PCMCIA | 27 | #ifdef CONFIG_AMIGA_PCMCIA |
| 30 | EXPORT_SYMBOL(pcmcia_reset); | 28 | EXPORT_SYMBOL(pcmcia_reset); |
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 | } | ||
diff --git a/arch/m68k/amiga/cia.c b/arch/m68k/amiga/cia.c index 4a003d87f98d..0956e45399e5 100644 --- a/arch/m68k/amiga/cia.c +++ b/arch/m68k/amiga/cia.c | |||
| @@ -29,21 +29,18 @@ struct ciabase { | |||
| 29 | unsigned short int_mask; | 29 | unsigned short int_mask; |
| 30 | int handler_irq, cia_irq, server_irq; | 30 | int handler_irq, cia_irq, server_irq; |
| 31 | char *name; | 31 | char *name; |
| 32 | irq_handler_t irq_list[CIA_IRQS]; | ||
| 33 | } ciaa_base = { | 32 | } ciaa_base = { |
| 34 | .cia = &ciaa, | 33 | .cia = &ciaa, |
| 35 | .int_mask = IF_PORTS, | 34 | .int_mask = IF_PORTS, |
| 36 | .handler_irq = IRQ_AUTO_2, | 35 | .handler_irq = IRQ_AMIGA_PORTS, |
| 37 | .cia_irq = IRQ_AMIGA_CIAA, | 36 | .cia_irq = IRQ_AMIGA_CIAA, |
| 38 | .server_irq = IRQ_AMIGA_PORTS, | 37 | .name = "CIAA" |
| 39 | .name = "CIAA handler" | ||
| 40 | }, ciab_base = { | 38 | }, ciab_base = { |
| 41 | .cia = &ciab, | 39 | .cia = &ciab, |
| 42 | .int_mask = IF_EXTER, | 40 | .int_mask = IF_EXTER, |
| 43 | .handler_irq = IRQ_AUTO_6, | 41 | .handler_irq = IRQ_AMIGA_EXTER, |
| 44 | .cia_irq = IRQ_AMIGA_CIAB, | 42 | .cia_irq = IRQ_AMIGA_CIAB, |
| 45 | .server_irq = IRQ_AMIGA_EXTER, | 43 | .name = "CIAB" |
| 46 | .name = "CIAB handler" | ||
| 47 | }; | 44 | }; |
| 48 | 45 | ||
| 49 | /* | 46 | /* |
| @@ -66,13 +63,11 @@ unsigned char cia_set_irq(struct ciabase *base, unsigned char mask) | |||
| 66 | 63 | ||
| 67 | /* | 64 | /* |
| 68 | * Enable or disable CIA interrupts, return old interrupt mask, | 65 | * Enable or disable CIA interrupts, return old interrupt mask, |
| 69 | * interrupts will only be enabled if a handler exists | ||
| 70 | */ | 66 | */ |
| 71 | 67 | ||
| 72 | unsigned char cia_able_irq(struct ciabase *base, unsigned char mask) | 68 | unsigned char cia_able_irq(struct ciabase *base, unsigned char mask) |
| 73 | { | 69 | { |
| 74 | unsigned char old, tmp; | 70 | unsigned char old; |
| 75 | int i; | ||
| 76 | 71 | ||
| 77 | old = base->icr_mask; | 72 | old = base->icr_mask; |
| 78 | base->icr_data |= base->cia->icr; | 73 | base->icr_data |= base->cia->icr; |
| @@ -82,98 +77,104 @@ unsigned char cia_able_irq(struct ciabase *base, unsigned char mask) | |||
| 82 | else | 77 | else |
| 83 | base->icr_mask &= ~mask; | 78 | base->icr_mask &= ~mask; |
| 84 | base->icr_mask &= CIA_ICR_ALL; | 79 | base->icr_mask &= CIA_ICR_ALL; |
| 85 | for (i = 0, tmp = 1; i < CIA_IRQS; i++, tmp <<= 1) { | ||
| 86 | if ((tmp & base->icr_mask) && !base->irq_list[i].handler) { | ||
| 87 | base->icr_mask &= ~tmp; | ||
| 88 | base->cia->icr = tmp; | ||
| 89 | } | ||
| 90 | } | ||
| 91 | if (base->icr_data & base->icr_mask) | 80 | if (base->icr_data & base->icr_mask) |
| 92 | amiga_custom.intreq = IF_SETCLR | base->int_mask; | 81 | amiga_custom.intreq = IF_SETCLR | base->int_mask; |
| 93 | return old; | 82 | return old; |
| 94 | } | 83 | } |
| 95 | 84 | ||
| 96 | int cia_request_irq(struct ciabase *base, unsigned int irq, | ||
| 97 | irqreturn_t (*handler)(int, void *, struct pt_regs *), | ||
| 98 | unsigned long flags, const char *devname, void *dev_id) | ||
| 99 | { | ||
| 100 | unsigned char mask; | ||
| 101 | |||
| 102 | base->irq_list[irq].handler = handler; | ||
| 103 | base->irq_list[irq].flags = flags; | ||
| 104 | base->irq_list[irq].dev_id = dev_id; | ||
| 105 | base->irq_list[irq].devname = devname; | ||
| 106 | |||
| 107 | /* enable the interrupt */ | ||
| 108 | mask = 1 << irq; | ||
| 109 | cia_set_irq(base, mask); | ||
| 110 | cia_able_irq(base, CIA_ICR_SETCLR | mask); | ||
| 111 | return 0; | ||
| 112 | } | ||
| 113 | |||
| 114 | void cia_free_irq(struct ciabase *base, unsigned int irq, void *dev_id) | ||
| 115 | { | ||
| 116 | if (base->irq_list[irq].dev_id != dev_id) | ||
| 117 | printk("%s: removing probably wrong IRQ %i from %s\n", | ||
| 118 | __FUNCTION__, base->cia_irq + irq, | ||
| 119 | base->irq_list[irq].devname); | ||
| 120 | |||
| 121 | base->irq_list[irq].handler = NULL; | ||
| 122 | base->irq_list[irq].flags = 0; | ||
| 123 | |||
| 124 | cia_able_irq(base, 1 << irq); | ||
| 125 | } | ||
| 126 | |||
| 127 | static irqreturn_t cia_handler(int irq, void *dev_id, struct pt_regs *fp) | 85 | static irqreturn_t cia_handler(int irq, void *dev_id, struct pt_regs *fp) |
| 128 | { | 86 | { |
| 129 | struct ciabase *base = (struct ciabase *)dev_id; | 87 | struct ciabase *base = (struct ciabase *)dev_id; |
| 130 | int mach_irq, i; | 88 | int mach_irq; |
| 131 | unsigned char ints; | 89 | unsigned char ints; |
| 132 | 90 | ||
| 133 | mach_irq = base->cia_irq; | 91 | mach_irq = base->cia_irq; |
| 134 | ints = cia_set_irq(base, CIA_ICR_ALL); | 92 | ints = cia_set_irq(base, CIA_ICR_ALL); |
| 135 | amiga_custom.intreq = base->int_mask; | 93 | amiga_custom.intreq = base->int_mask; |
| 136 | for (i = 0; i < CIA_IRQS; i++, mach_irq++) { | 94 | for (; ints; mach_irq++, ints >>= 1) { |
| 137 | if (ints & 1) { | 95 | if (ints & 1) |
| 138 | kstat_cpu(0).irqs[mach_irq]++; | 96 | m68k_handle_int(mach_irq, fp); |
| 139 | base->irq_list[i].handler(mach_irq, base->irq_list[i].dev_id, fp); | ||
| 140 | } | ||
| 141 | ints >>= 1; | ||
| 142 | } | 97 | } |
| 143 | amiga_do_irq_list(base->server_irq, fp); | ||
| 144 | return IRQ_HANDLED; | 98 | return IRQ_HANDLED; |
| 145 | } | 99 | } |
| 146 | 100 | ||
| 147 | void __init cia_init_IRQ(struct ciabase *base) | 101 | static void cia_enable_irq(unsigned int irq) |
| 148 | { | 102 | { |
| 149 | int i; | 103 | unsigned char mask; |
| 150 | 104 | ||
| 151 | /* init isr handlers */ | 105 | if (irq >= IRQ_AMIGA_CIAB) { |
| 152 | for (i = 0; i < CIA_IRQS; i++) { | 106 | mask = 1 << (irq - IRQ_AMIGA_CIAB); |
| 153 | base->irq_list[i].handler = NULL; | 107 | cia_set_irq(&ciab_base, mask); |
| 154 | base->irq_list[i].flags = 0; | 108 | cia_able_irq(&ciab_base, CIA_ICR_SETCLR | mask); |
| 109 | } else { | ||
| 110 | mask = 1 << (irq - IRQ_AMIGA_CIAA); | ||
| 111 | cia_set_irq(&ciaa_base, mask); | ||
| 112 | cia_able_irq(&ciaa_base, CIA_ICR_SETCLR | mask); | ||
| 155 | } | 113 | } |
| 114 | } | ||
| 156 | 115 | ||
| 157 | /* clear any pending interrupt and turn off all interrupts */ | 116 | static void cia_disable_irq(unsigned int irq) |
| 158 | cia_set_irq(base, CIA_ICR_ALL); | 117 | { |
| 159 | cia_able_irq(base, CIA_ICR_ALL); | 118 | if (irq >= IRQ_AMIGA_CIAB) |
| 119 | cia_able_irq(&ciab_base, 1 << (irq - IRQ_AMIGA_CIAB)); | ||
| 120 | else | ||
| 121 | cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA)); | ||
| 122 | } | ||
| 160 | 123 | ||
| 161 | /* install CIA handler */ | 124 | static struct irq_controller cia_irq_controller = { |
| 162 | request_irq(base->handler_irq, cia_handler, 0, base->name, base); | 125 | .name = "cia", |
| 126 | .lock = SPIN_LOCK_UNLOCKED, | ||
| 127 | .enable = cia_enable_irq, | ||
| 128 | .disable = cia_disable_irq, | ||
| 129 | }; | ||
| 130 | |||
| 131 | /* | ||
| 132 | * Override auto irq 2 & 6 and use them as general chain | ||
| 133 | * for external interrupts, we link the CIA interrupt sources | ||
| 134 | * into this chain. | ||
| 135 | */ | ||
| 163 | 136 | ||
| 164 | amiga_custom.intena = IF_SETCLR | base->int_mask; | 137 | static void auto_enable_irq(unsigned int irq) |
| 138 | { | ||
| 139 | switch (irq) { | ||
| 140 | case IRQ_AUTO_2: | ||
| 141 | amiga_custom.intena = IF_SETCLR | IF_PORTS; | ||
| 142 | break; | ||
| 143 | case IRQ_AUTO_6: | ||
| 144 | amiga_custom.intena = IF_SETCLR | IF_EXTER; | ||
| 145 | break; | ||
| 146 | } | ||
| 165 | } | 147 | } |
| 166 | 148 | ||
| 167 | int cia_get_irq_list(struct ciabase *base, struct seq_file *p) | 149 | static void auto_disable_irq(unsigned int irq) |
| 168 | { | 150 | { |
| 169 | int i, j; | 151 | switch (irq) { |
| 170 | 152 | case IRQ_AUTO_2: | |
| 171 | j = base->cia_irq; | 153 | amiga_custom.intena = IF_PORTS; |
| 172 | for (i = 0; i < CIA_IRQS; i++) { | 154 | break; |
| 173 | seq_printf(p, "cia %2d: %10d ", j + i, | 155 | case IRQ_AUTO_6: |
| 174 | kstat_cpu(0).irqs[j + i]); | 156 | amiga_custom.intena = IF_EXTER; |
| 175 | seq_puts(p, " "); | 157 | break; |
| 176 | seq_printf(p, "%s\n", base->irq_list[i].devname); | ||
| 177 | } | 158 | } |
| 178 | return 0; | 159 | } |
| 160 | |||
| 161 | static struct irq_controller auto_irq_controller = { | ||
| 162 | .name = "auto", | ||
| 163 | .lock = SPIN_LOCK_UNLOCKED, | ||
| 164 | .enable = auto_enable_irq, | ||
| 165 | .disable = auto_disable_irq, | ||
| 166 | }; | ||
| 167 | |||
| 168 | void __init cia_init_IRQ(struct ciabase *base) | ||
| 169 | { | ||
| 170 | m68k_setup_irq_controller(&cia_irq_controller, base->cia_irq, CIA_IRQS); | ||
| 171 | |||
| 172 | /* clear any pending interrupt and turn off all interrupts */ | ||
| 173 | cia_set_irq(base, CIA_ICR_ALL); | ||
| 174 | cia_able_irq(base, CIA_ICR_ALL); | ||
| 175 | |||
| 176 | /* override auto int and install CIA handler */ | ||
| 177 | m68k_setup_irq_controller(&auto_irq_controller, base->handler_irq, 1); | ||
| 178 | m68k_irq_startup(base->handler_irq); | ||
| 179 | request_irq(base->handler_irq, cia_handler, SA_SHIRQ, base->name, base); | ||
| 179 | } | 180 | } |
diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c index 12e3706fe02c..b5b8a416a07a 100644 --- a/arch/m68k/amiga/config.c +++ b/arch/m68k/amiga/config.c | |||
| @@ -87,17 +87,8 @@ extern char m68k_debug_device[]; | |||
| 87 | static void amiga_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); | 87 | static void amiga_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); |
| 88 | /* amiga specific irq functions */ | 88 | /* amiga specific irq functions */ |
| 89 | extern void amiga_init_IRQ (void); | 89 | extern void amiga_init_IRQ (void); |
| 90 | extern irqreturn_t (*amiga_default_handler[]) (int, void *, struct pt_regs *); | ||
| 91 | extern int amiga_request_irq (unsigned int irq, | ||
| 92 | irqreturn_t (*handler)(int, void *, struct pt_regs *), | ||
| 93 | unsigned long flags, const char *devname, | ||
| 94 | void *dev_id); | ||
| 95 | extern void amiga_free_irq (unsigned int irq, void *dev_id); | ||
| 96 | extern void amiga_enable_irq (unsigned int); | ||
| 97 | extern void amiga_disable_irq (unsigned int); | ||
| 98 | static void amiga_get_model(char *model); | 90 | static void amiga_get_model(char *model); |
| 99 | static int amiga_get_hardware_list(char *buffer); | 91 | static int amiga_get_hardware_list(char *buffer); |
| 100 | extern int show_amiga_interrupts (struct seq_file *, void *); | ||
| 101 | /* amiga specific timer functions */ | 92 | /* amiga specific timer functions */ |
| 102 | static unsigned long amiga_gettimeoffset (void); | 93 | static unsigned long amiga_gettimeoffset (void); |
| 103 | static int a3000_hwclk (int, struct rtc_time *); | 94 | static int a3000_hwclk (int, struct rtc_time *); |
| @@ -392,14 +383,8 @@ void __init config_amiga(void) | |||
| 392 | 383 | ||
| 393 | mach_sched_init = amiga_sched_init; | 384 | mach_sched_init = amiga_sched_init; |
| 394 | mach_init_IRQ = amiga_init_IRQ; | 385 | mach_init_IRQ = amiga_init_IRQ; |
| 395 | mach_default_handler = &amiga_default_handler; | ||
| 396 | mach_request_irq = amiga_request_irq; | ||
| 397 | mach_free_irq = amiga_free_irq; | ||
| 398 | enable_irq = amiga_enable_irq; | ||
| 399 | disable_irq = amiga_disable_irq; | ||
| 400 | mach_get_model = amiga_get_model; | 386 | mach_get_model = amiga_get_model; |
| 401 | mach_get_hardware_list = amiga_get_hardware_list; | 387 | mach_get_hardware_list = amiga_get_hardware_list; |
| 402 | mach_get_irq_list = show_amiga_interrupts; | ||
| 403 | mach_gettimeoffset = amiga_gettimeoffset; | 388 | mach_gettimeoffset = amiga_gettimeoffset; |
| 404 | if (AMIGAHW_PRESENT(A3000_CLK)){ | 389 | if (AMIGAHW_PRESENT(A3000_CLK)){ |
| 405 | mach_hwclk = a3000_hwclk; | 390 | mach_hwclk = a3000_hwclk; |
diff --git a/include/asm-m68k/amigaints.h b/include/asm-m68k/amigaints.h index 576f5d1b5706..7c8713468fd2 100644 --- a/include/asm-m68k/amigaints.h +++ b/include/asm-m68k/amigaints.h | |||
| @@ -37,8 +37,8 @@ | |||
| 37 | #define IRQ_AMIGA_SOFT (IRQ_USER+2) | 37 | #define IRQ_AMIGA_SOFT (IRQ_USER+2) |
| 38 | 38 | ||
| 39 | /* interrupts from external hardware */ | 39 | /* interrupts from external hardware */ |
| 40 | #define IRQ_AMIGA_PORTS (IRQ_USER+3) | 40 | #define IRQ_AMIGA_PORTS IRQ_AUTO_2 |
| 41 | #define IRQ_AMIGA_EXTER (IRQ_USER+13) | 41 | #define IRQ_AMIGA_EXTER IRQ_AUTO_6 |
| 42 | 42 | ||
| 43 | /* copper interrupt */ | 43 | /* copper interrupt */ |
| 44 | #define IRQ_AMIGA_COPPER (IRQ_USER+4) | 44 | #define IRQ_AMIGA_COPPER (IRQ_USER+4) |
| @@ -88,9 +88,6 @@ | |||
| 88 | #define IF_DSKBLK 0x0002 /* diskblock DMA finished */ | 88 | #define IF_DSKBLK 0x0002 /* diskblock DMA finished */ |
| 89 | #define IF_TBE 0x0001 /* serial transmit buffer empty interrupt */ | 89 | #define IF_TBE 0x0001 /* serial transmit buffer empty interrupt */ |
| 90 | 90 | ||
| 91 | extern void amiga_do_irq(int irq, struct pt_regs *fp); | ||
| 92 | extern void amiga_do_irq_list(int irq, struct pt_regs *fp); | ||
| 93 | |||
| 94 | /* CIA interrupt control register bits */ | 91 | /* CIA interrupt control register bits */ |
| 95 | 92 | ||
| 96 | #define CIA_ICR_TA 0x01 | 93 | #define CIA_ICR_TA 0x01 |
| @@ -107,6 +104,7 @@ extern void amiga_do_irq_list(int irq, struct pt_regs *fp); | |||
| 107 | 104 | ||
| 108 | extern struct ciabase ciaa_base, ciab_base; | 105 | extern struct ciabase ciaa_base, ciab_base; |
| 109 | 106 | ||
| 107 | extern void cia_init_IRQ(struct ciabase *base); | ||
| 110 | extern unsigned char cia_set_irq(struct ciabase *base, unsigned char mask); | 108 | extern unsigned char cia_set_irq(struct ciabase *base, unsigned char mask); |
| 111 | extern unsigned char cia_able_irq(struct ciabase *base, unsigned char mask); | 109 | extern unsigned char cia_able_irq(struct ciabase *base, unsigned char mask); |
| 112 | 110 | ||
