amiints.c (1da177e4c3f41524e886b7f1b8a0c1fc7321cac2) | amiints.c (b4290a23cfa9040e2f0de5ab57d6ea65abaf053b) |
---|---|
1/* 2 * linux/arch/m68k/amiga/amiints.c -- Amiga Linux interrupt handling code 3 * 4 * This file is subject to the terms and conditions of the GNU General Public 5 * License. See the file COPYING in the main directory of this archive 6 * for more details. 7 * 8 * 11/07/96: rewritten interrupt handling, irq lists are exists now only for --- 112 unchanged lines hidden (view full) --- 121 for (i = 0; i < AMI_IRQS; i++) 122 ami_ablecount[i] = 0; 123 124 /* turn off PCMCIA interrupts */ 125 if (AMIGAHW_PRESENT(PCMCIA)) 126 gayle.inten = GAYLE_IRQ_IDE; 127 128 /* turn off all interrupts and enable the master interrupt bit */ | 1/* 2 * linux/arch/m68k/amiga/amiints.c -- Amiga Linux interrupt handling code 3 * 4 * This file is subject to the terms and conditions of the GNU General Public 5 * License. See the file COPYING in the main directory of this archive 6 * for more details. 7 * 8 * 11/07/96: rewritten interrupt handling, irq lists are exists now only for --- 112 unchanged lines hidden (view full) --- 121 for (i = 0; i < AMI_IRQS; i++) 122 ami_ablecount[i] = 0; 123 124 /* turn off PCMCIA interrupts */ 125 if (AMIGAHW_PRESENT(PCMCIA)) 126 gayle.inten = GAYLE_IRQ_IDE; 127 128 /* turn off all interrupts and enable the master interrupt bit */ |
129 custom.intena = 0x7fff; 130 custom.intreq = 0x7fff; 131 custom.intena = IF_SETCLR | IF_INTEN; | 129 amiga_custom.intena = 0x7fff; 130 amiga_custom.intreq = 0x7fff; 131 amiga_custom.intena = IF_SETCLR | IF_INTEN; |
132 133 cia_init_IRQ(&ciaa_base); 134 cia_init_IRQ(&ciab_base); 135} 136 137static inline int amiga_insert_irq(irq_node_t **list, irq_node_t *node) 138{ 139 unsigned long flags; --- 100 unchanged lines hidden (view full) --- 240 ami_irq_list[irq]->handler = handler; 241 ami_irq_list[irq]->flags = flags; 242 ami_irq_list[irq]->dev_id = dev_id; 243 ami_irq_list[irq]->devname = devname; 244 } 245 246 /* enable the interrupt */ 247 if (irq < IRQ_AMIGA_PORTS && !ami_ablecount[irq]) | 132 133 cia_init_IRQ(&ciaa_base); 134 cia_init_IRQ(&ciab_base); 135} 136 137static inline int amiga_insert_irq(irq_node_t **list, irq_node_t *node) 138{ 139 unsigned long flags; --- 100 unchanged lines hidden (view full) --- 240 ami_irq_list[irq]->handler = handler; 241 ami_irq_list[irq]->flags = flags; 242 ami_irq_list[irq]->dev_id = dev_id; 243 ami_irq_list[irq]->devname = devname; 244 } 245 246 /* enable the interrupt */ 247 if (irq < IRQ_AMIGA_PORTS && !ami_ablecount[irq]) |
248 custom.intena = IF_SETCLR | amiga_intena_vals[irq]; | 248 amiga_custom.intena = IF_SETCLR | amiga_intena_vals[irq]; |
249 250 return error; 251} 252 253void amiga_free_irq(unsigned int irq, void *dev_id) 254{ 255 if (irq >= AMI_IRQS) { 256 printk ("%s: Unknown IRQ %d\n", __FUNCTION__, irq); --- 12 unchanged lines hidden (view full) --- 269 cia_free_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA, dev_id); 270 return; 271 } 272 273 if (ami_servers[irq]) { 274 amiga_delete_irq(&ami_irq_list[irq], dev_id); 275 /* if server list empty, disable the interrupt */ 276 if (!ami_irq_list[irq] && irq < IRQ_AMIGA_PORTS) | 249 250 return error; 251} 252 253void amiga_free_irq(unsigned int irq, void *dev_id) 254{ 255 if (irq >= AMI_IRQS) { 256 printk ("%s: Unknown IRQ %d\n", __FUNCTION__, irq); --- 12 unchanged lines hidden (view full) --- 269 cia_free_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA, dev_id); 270 return; 271 } 272 273 if (ami_servers[irq]) { 274 amiga_delete_irq(&ami_irq_list[irq], dev_id); 275 /* if server list empty, disable the interrupt */ 276 if (!ami_irq_list[irq] && irq < IRQ_AMIGA_PORTS) |
277 custom.intena = amiga_intena_vals[irq]; | 277 amiga_custom.intena = amiga_intena_vals[irq]; |
278 } else { 279 if (ami_irq_list[irq]->dev_id != dev_id) 280 printk("%s: removing probably wrong IRQ %d from %s\n", 281 __FUNCTION__, irq, ami_irq_list[irq]->devname); 282 ami_irq_list[irq]->handler = ami_badint; 283 ami_irq_list[irq]->flags = 0; 284 ami_irq_list[irq]->dev_id = NULL; 285 ami_irq_list[irq]->devname = NULL; | 278 } else { 279 if (ami_irq_list[irq]->dev_id != dev_id) 280 printk("%s: removing probably wrong IRQ %d from %s\n", 281 __FUNCTION__, irq, ami_irq_list[irq]->devname); 282 ami_irq_list[irq]->handler = ami_badint; 283 ami_irq_list[irq]->flags = 0; 284 ami_irq_list[irq]->dev_id = NULL; 285 ami_irq_list[irq]->devname = NULL; |
286 custom.intena = amiga_intena_vals[irq]; | 286 amiga_custom.intena = amiga_intena_vals[irq]; |
287 } 288} 289 290/* 291 * Enable/disable a particular machine specific interrupt source. 292 * Note that this may affect other interrupts in case of a shared interrupt. 293 * This function should only be called for a _very_ short time to change some 294 * internal data, that may not be changed by the interrupt at the same time. --- 27 unchanged lines hidden (view full) --- 322 if (irq >= IRQ_AMIGA_CIAA) { 323 cia_set_irq(&ciaa_base, (1 << (irq - IRQ_AMIGA_CIAA))); 324 cia_able_irq(&ciaa_base, CIA_ICR_SETCLR | 325 (1 << (irq - IRQ_AMIGA_CIAA))); 326 return; 327 } 328 329 /* enable the interrupt */ | 287 } 288} 289 290/* 291 * Enable/disable a particular machine specific interrupt source. 292 * Note that this may affect other interrupts in case of a shared interrupt. 293 * This function should only be called for a _very_ short time to change some 294 * internal data, that may not be changed by the interrupt at the same time. --- 27 unchanged lines hidden (view full) --- 322 if (irq >= IRQ_AMIGA_CIAA) { 323 cia_set_irq(&ciaa_base, (1 << (irq - IRQ_AMIGA_CIAA))); 324 cia_able_irq(&ciaa_base, CIA_ICR_SETCLR | 325 (1 << (irq - IRQ_AMIGA_CIAA))); 326 return; 327 } 328 329 /* enable the interrupt */ |
330 custom.intena = IF_SETCLR | amiga_intena_vals[irq]; | 330 amiga_custom.intena = IF_SETCLR | amiga_intena_vals[irq]; |
331} 332 333void amiga_disable_irq(unsigned int irq) 334{ 335 if (irq >= AMI_IRQS) { 336 printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq); 337 return; 338 } --- 14 unchanged lines hidden (view full) --- 353 } 354 355 if (irq >= IRQ_AMIGA_CIAA) { 356 cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA)); 357 return; 358 } 359 360 /* disable the interrupt */ | 331} 332 333void amiga_disable_irq(unsigned int irq) 334{ 335 if (irq >= AMI_IRQS) { 336 printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq); 337 return; 338 } --- 14 unchanged lines hidden (view full) --- 353 } 354 355 if (irq >= IRQ_AMIGA_CIAA) { 356 cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA)); 357 return; 358 } 359 360 /* disable the interrupt */ |
361 custom.intena = amiga_intena_vals[irq]; | 361 amiga_custom.intena = amiga_intena_vals[irq]; |
362} 363 364inline void amiga_do_irq(int irq, struct pt_regs *fp) 365{ 366 kstat_cpu(0).irqs[SYS_IRQS + irq]++; 367 ami_irq_list[irq]->handler(irq, ami_irq_list[irq]->dev_id, fp); 368} 369 370void amiga_do_irq_list(int irq, struct pt_regs *fp) 371{ 372 irq_node_t *node; 373 374 kstat_cpu(0).irqs[SYS_IRQS + irq]++; 375 | 362} 363 364inline void amiga_do_irq(int irq, struct pt_regs *fp) 365{ 366 kstat_cpu(0).irqs[SYS_IRQS + irq]++; 367 ami_irq_list[irq]->handler(irq, ami_irq_list[irq]->dev_id, fp); 368} 369 370void amiga_do_irq_list(int irq, struct pt_regs *fp) 371{ 372 irq_node_t *node; 373 374 kstat_cpu(0).irqs[SYS_IRQS + irq]++; 375 |
376 custom.intreq = amiga_intena_vals[irq]; | 376 amiga_custom.intreq = amiga_intena_vals[irq]; |
377 378 for (node = ami_irq_list[irq]; node; node = node->next) 379 node->handler(irq, node->dev_id, fp); 380} 381 382/* 383 * The builtin Amiga hardware interrupt handlers. 384 */ 385 386static irqreturn_t ami_int1(int irq, void *dev_id, struct pt_regs *fp) 387{ | 377 378 for (node = ami_irq_list[irq]; node; node = node->next) 379 node->handler(irq, node->dev_id, fp); 380} 381 382/* 383 * The builtin Amiga hardware interrupt handlers. 384 */ 385 386static irqreturn_t ami_int1(int irq, void *dev_id, struct pt_regs *fp) 387{ |
388 unsigned short ints = custom.intreqr & custom.intenar; | 388 unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; |
389 390 /* if serial transmit buffer empty, interrupt */ 391 if (ints & IF_TBE) { | 389 390 /* if serial transmit buffer empty, interrupt */ 391 if (ints & IF_TBE) { |
392 custom.intreq = IF_TBE; | 392 amiga_custom.intreq = IF_TBE; |
393 amiga_do_irq(IRQ_AMIGA_TBE, fp); 394 } 395 396 /* if floppy disk transfer complete, interrupt */ 397 if (ints & IF_DSKBLK) { | 393 amiga_do_irq(IRQ_AMIGA_TBE, fp); 394 } 395 396 /* if floppy disk transfer complete, interrupt */ 397 if (ints & IF_DSKBLK) { |
398 custom.intreq = IF_DSKBLK; | 398 amiga_custom.intreq = IF_DSKBLK; |
399 amiga_do_irq(IRQ_AMIGA_DSKBLK, fp); 400 } 401 402 /* if software interrupt set, interrupt */ 403 if (ints & IF_SOFT) { | 399 amiga_do_irq(IRQ_AMIGA_DSKBLK, fp); 400 } 401 402 /* if software interrupt set, interrupt */ 403 if (ints & IF_SOFT) { |
404 custom.intreq = IF_SOFT; | 404 amiga_custom.intreq = IF_SOFT; |
405 amiga_do_irq(IRQ_AMIGA_SOFT, fp); 406 } 407 return IRQ_HANDLED; 408} 409 410static irqreturn_t ami_int3(int irq, void *dev_id, struct pt_regs *fp) 411{ | 405 amiga_do_irq(IRQ_AMIGA_SOFT, fp); 406 } 407 return IRQ_HANDLED; 408} 409 410static irqreturn_t ami_int3(int irq, void *dev_id, struct pt_regs *fp) 411{ |
412 unsigned short ints = custom.intreqr & custom.intenar; | 412 unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; |
413 414 /* if a blitter interrupt */ 415 if (ints & IF_BLIT) { | 413 414 /* if a blitter interrupt */ 415 if (ints & IF_BLIT) { |
416 custom.intreq = IF_BLIT; | 416 amiga_custom.intreq = IF_BLIT; |
417 amiga_do_irq(IRQ_AMIGA_BLIT, fp); 418 } 419 420 /* if a copper interrupt */ 421 if (ints & IF_COPER) { | 417 amiga_do_irq(IRQ_AMIGA_BLIT, fp); 418 } 419 420 /* if a copper interrupt */ 421 if (ints & IF_COPER) { |
422 custom.intreq = IF_COPER; | 422 amiga_custom.intreq = IF_COPER; |
423 amiga_do_irq(IRQ_AMIGA_COPPER, fp); 424 } 425 426 /* if a vertical blank interrupt */ 427 if (ints & IF_VERTB) 428 amiga_do_irq_list(IRQ_AMIGA_VERTB, fp); 429 return IRQ_HANDLED; 430} 431 432static irqreturn_t ami_int4(int irq, void *dev_id, struct pt_regs *fp) 433{ | 423 amiga_do_irq(IRQ_AMIGA_COPPER, fp); 424 } 425 426 /* if a vertical blank interrupt */ 427 if (ints & IF_VERTB) 428 amiga_do_irq_list(IRQ_AMIGA_VERTB, fp); 429 return IRQ_HANDLED; 430} 431 432static irqreturn_t ami_int4(int irq, void *dev_id, struct pt_regs *fp) 433{ |
434 unsigned short ints = custom.intreqr & custom.intenar; | 434 unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; |
435 436 /* if audio 0 interrupt */ 437 if (ints & IF_AUD0) { | 435 436 /* if audio 0 interrupt */ 437 if (ints & IF_AUD0) { |
438 custom.intreq = IF_AUD0; | 438 amiga_custom.intreq = IF_AUD0; |
439 amiga_do_irq(IRQ_AMIGA_AUD0, fp); 440 } 441 442 /* if audio 1 interrupt */ 443 if (ints & IF_AUD1) { | 439 amiga_do_irq(IRQ_AMIGA_AUD0, fp); 440 } 441 442 /* if audio 1 interrupt */ 443 if (ints & IF_AUD1) { |
444 custom.intreq = IF_AUD1; | 444 amiga_custom.intreq = IF_AUD1; |
445 amiga_do_irq(IRQ_AMIGA_AUD1, fp); 446 } 447 448 /* if audio 2 interrupt */ 449 if (ints & IF_AUD2) { | 445 amiga_do_irq(IRQ_AMIGA_AUD1, fp); 446 } 447 448 /* if audio 2 interrupt */ 449 if (ints & IF_AUD2) { |
450 custom.intreq = IF_AUD2; | 450 amiga_custom.intreq = IF_AUD2; |
451 amiga_do_irq(IRQ_AMIGA_AUD2, fp); 452 } 453 454 /* if audio 3 interrupt */ 455 if (ints & IF_AUD3) { | 451 amiga_do_irq(IRQ_AMIGA_AUD2, fp); 452 } 453 454 /* if audio 3 interrupt */ 455 if (ints & IF_AUD3) { |
456 custom.intreq = IF_AUD3; | 456 amiga_custom.intreq = IF_AUD3; |
457 amiga_do_irq(IRQ_AMIGA_AUD3, fp); 458 } 459 return IRQ_HANDLED; 460} 461 462static irqreturn_t ami_int5(int irq, void *dev_id, struct pt_regs *fp) 463{ | 457 amiga_do_irq(IRQ_AMIGA_AUD3, fp); 458 } 459 return IRQ_HANDLED; 460} 461 462static irqreturn_t ami_int5(int irq, void *dev_id, struct pt_regs *fp) 463{ |
464 unsigned short ints = custom.intreqr & custom.intenar; | 464 unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; |
465 466 /* if serial receive buffer full interrupt */ 467 if (ints & IF_RBF) { 468 /* acknowledge of IF_RBF must be done by the serial interrupt */ 469 amiga_do_irq(IRQ_AMIGA_RBF, fp); 470 } 471 472 /* if a disk sync interrupt */ 473 if (ints & IF_DSKSYN) { | 465 466 /* if serial receive buffer full interrupt */ 467 if (ints & IF_RBF) { 468 /* acknowledge of IF_RBF must be done by the serial interrupt */ 469 amiga_do_irq(IRQ_AMIGA_RBF, fp); 470 } 471 472 /* if a disk sync interrupt */ 473 if (ints & IF_DSKSYN) { |
474 custom.intreq = IF_DSKSYN; | 474 amiga_custom.intreq = IF_DSKSYN; |
475 amiga_do_irq(IRQ_AMIGA_DSKSYN, fp); 476 } 477 return IRQ_HANDLED; 478} 479 480static irqreturn_t ami_int7(int irq, void *dev_id, struct pt_regs *fp) 481{ 482 panic ("level 7 interrupt received\n"); --- 38 unchanged lines hidden --- | 475 amiga_do_irq(IRQ_AMIGA_DSKSYN, fp); 476 } 477 return IRQ_HANDLED; 478} 479 480static irqreturn_t ami_int7(int irq, void *dev_id, struct pt_regs *fp) 481{ 482 panic ("level 7 interrupt received\n"); --- 38 unchanged lines hidden --- |