diff options
| -rw-r--r-- | arch/m68k/atari/ataints.c | 278 | ||||
| -rw-r--r-- | arch/m68k/atari/config.c | 11 |
2 files changed, 42 insertions, 247 deletions
diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c index bb54741dd6cd..ece13cbf9950 100644 --- a/arch/m68k/atari/ataints.c +++ b/arch/m68k/atari/ataints.c | |||
| @@ -104,6 +104,7 @@ | |||
| 104 | * the sr copy in the frame. | 104 | * the sr copy in the frame. |
| 105 | */ | 105 | */ |
| 106 | 106 | ||
| 107 | #if 0 | ||
| 107 | 108 | ||
| 108 | #define NUM_INT_SOURCES (8 + NUM_ATARI_SOURCES) | 109 | #define NUM_INT_SOURCES (8 + NUM_ATARI_SOURCES) |
| 109 | 110 | ||
| @@ -133,13 +134,6 @@ static struct irqhandler irq_handler[NUM_INT_SOURCES]; | |||
| 133 | */ | 134 | */ |
| 134 | static struct irqparam irq_param[NUM_INT_SOURCES]; | 135 | static struct irqparam irq_param[NUM_INT_SOURCES]; |
| 135 | 136 | ||
| 136 | /* | ||
| 137 | * Bitmap for free interrupt vector numbers | ||
| 138 | * (new vectors starting from 0x70 can be allocated by | ||
| 139 | * atari_register_vme_int()) | ||
| 140 | */ | ||
| 141 | static int free_vme_vec_bitmap; | ||
| 142 | |||
| 143 | /* check for valid int number (complex, sigh...) */ | 137 | /* check for valid int number (complex, sigh...) */ |
| 144 | #define IS_VALID_INTNO(n) \ | 138 | #define IS_VALID_INTNO(n) \ |
| 145 | ((n) > 0 && \ | 139 | ((n) > 0 && \ |
| @@ -301,6 +295,14 @@ __asm__ (__ALIGN_STR "\n" | |||
| 301 | ); | 295 | ); |
| 302 | for (;;); | 296 | for (;;); |
| 303 | } | 297 | } |
| 298 | #endif | ||
| 299 | |||
| 300 | /* | ||
| 301 | * Bitmap for free interrupt vector numbers | ||
| 302 | * (new vectors starting from 0x70 can be allocated by | ||
| 303 | * atari_register_vme_int()) | ||
| 304 | */ | ||
| 305 | static int free_vme_vec_bitmap; | ||
| 304 | 306 | ||
| 305 | /* GK: | 307 | /* GK: |
| 306 | * HBL IRQ handler for Falcon. Nobody needs it :-) | 308 | * HBL IRQ handler for Falcon. Nobody needs it :-) |
| @@ -313,13 +315,34 @@ __ALIGN_STR "\n\t" | |||
| 313 | "orw #0x200,%sp@\n\t" /* set saved ipl to 2 */ | 315 | "orw #0x200,%sp@\n\t" /* set saved ipl to 2 */ |
| 314 | "rte"); | 316 | "rte"); |
| 315 | 317 | ||
| 316 | /* Defined in entry.S; only increments 'num_spurious' */ | 318 | extern void atari_microwire_cmd(int cmd); |
| 317 | asmlinkage void bad_inthandler(void); | ||
| 318 | |||
| 319 | extern void atari_microwire_cmd( int cmd ); | ||
| 320 | 319 | ||
| 321 | extern int atari_SCC_reset_done; | 320 | extern int atari_SCC_reset_done; |
| 322 | 321 | ||
| 322 | static int atari_startup_irq(unsigned int irq) | ||
| 323 | { | ||
| 324 | m68k_irq_startup(irq); | ||
| 325 | atari_turnon_irq(irq); | ||
| 326 | atari_enable_irq(irq); | ||
| 327 | return 0; | ||
| 328 | } | ||
| 329 | |||
| 330 | static void atari_shutdown_irq(unsigned int irq) | ||
| 331 | { | ||
| 332 | atari_disable_irq(irq); | ||
| 333 | atari_turnoff_irq(irq); | ||
| 334 | m68k_irq_shutdown(irq); | ||
| 335 | } | ||
| 336 | |||
| 337 | static struct irq_controller atari_irq_controller = { | ||
| 338 | .name = "atari", | ||
| 339 | .lock = SPIN_LOCK_UNLOCKED, | ||
| 340 | .startup = atari_startup_irq, | ||
| 341 | .shutdown = atari_shutdown_irq, | ||
| 342 | .enable = atari_enable_irq, | ||
| 343 | .disable = atari_disable_irq, | ||
| 344 | }; | ||
| 345 | |||
| 323 | /* | 346 | /* |
| 324 | * void atari_init_IRQ (void) | 347 | * void atari_init_IRQ (void) |
| 325 | * | 348 | * |
| @@ -333,12 +356,8 @@ extern int atari_SCC_reset_done; | |||
| 333 | 356 | ||
| 334 | void __init atari_init_IRQ(void) | 357 | void __init atari_init_IRQ(void) |
| 335 | { | 358 | { |
| 336 | int i; | 359 | m68k_setup_user_interrupt(VEC_USER, 192, NULL); |
| 337 | 360 | m68k_setup_irq_controller(&atari_irq_controller, 1, NUM_ATARI_SOURCES - 1); | |
| 338 | /* initialize the vector table */ | ||
| 339 | for (i = 0; i < NUM_INT_SOURCES; ++i) { | ||
| 340 | vectors[IRQ_SOURCE_TO_VECTOR(i)] = bad_inthandler; | ||
| 341 | } | ||
| 342 | 361 | ||
| 343 | /* Initialize the MFP(s) */ | 362 | /* Initialize the MFP(s) */ |
| 344 | 363 | ||
| @@ -378,8 +397,7 @@ void __init atari_init_IRQ(void) | |||
| 378 | * enabled in VME mask | 397 | * enabled in VME mask |
| 379 | */ | 398 | */ |
| 380 | tt_scu.vme_mask = 0x60; /* enable MFP and SCC ints */ | 399 | tt_scu.vme_mask = 0x60; /* enable MFP and SCC ints */ |
| 381 | } | 400 | } else { |
| 382 | else { | ||
| 383 | /* If no SCU and no Hades, the HSYNC interrupt needs to be | 401 | /* If no SCU and no Hades, the HSYNC interrupt needs to be |
| 384 | * disabled this way. (Else _inthandler in kernel/sys_call.S | 402 | * disabled this way. (Else _inthandler in kernel/sys_call.S |
| 385 | * gets overruns) | 403 | * gets overruns) |
| @@ -404,184 +422,6 @@ void __init atari_init_IRQ(void) | |||
| 404 | } | 422 | } |
| 405 | 423 | ||
| 406 | 424 | ||
| 407 | static irqreturn_t atari_call_irq_list( int irq, void *dev_id, struct pt_regs *fp ) | ||
| 408 | { | ||
| 409 | irq_node_t *node; | ||
| 410 | |||
| 411 | for (node = (irq_node_t *)dev_id; node; node = node->next) | ||
| 412 | node->handler(irq, node->dev_id, fp); | ||
| 413 | return IRQ_HANDLED; | ||
| 414 | } | ||
| 415 | |||
| 416 | |||
| 417 | /* | ||
| 418 | * atari_request_irq : add an interrupt service routine for a particular | ||
| 419 | * machine specific interrupt source. | ||
| 420 | * If the addition was successful, it returns 0. | ||
| 421 | */ | ||
| 422 | |||
| 423 | int atari_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), | ||
| 424 | unsigned long flags, const char *devname, void *dev_id) | ||
| 425 | { | ||
| 426 | int vector; | ||
| 427 | unsigned long oflags = flags; | ||
| 428 | |||
| 429 | /* | ||
| 430 | * The following is a hack to make some PCI card drivers work, | ||
| 431 | * which set the SA_SHIRQ flag. | ||
| 432 | */ | ||
| 433 | |||
| 434 | flags &= ~SA_SHIRQ; | ||
| 435 | |||
| 436 | if (flags == SA_INTERRUPT) { | ||
| 437 | printk ("%s: SA_INTERRUPT changed to IRQ_TYPE_SLOW for %s\n", | ||
| 438 | __FUNCTION__, devname); | ||
| 439 | flags = IRQ_TYPE_SLOW; | ||
| 440 | } | ||
| 441 | if (flags < IRQ_TYPE_SLOW || flags > IRQ_TYPE_PRIO) { | ||
| 442 | printk ("%s: Bad irq type 0x%lx <0x%lx> requested from %s\n", | ||
| 443 | __FUNCTION__, flags, oflags, devname); | ||
| 444 | return -EINVAL; | ||
| 445 | } | ||
| 446 | if (!IS_VALID_INTNO(irq)) { | ||
| 447 | printk ("%s: Unknown irq %d requested from %s\n", | ||
| 448 | __FUNCTION__, irq, devname); | ||
| 449 | return -ENXIO; | ||
| 450 | } | ||
| 451 | vector = IRQ_SOURCE_TO_VECTOR(irq); | ||
| 452 | |||
| 453 | /* | ||
| 454 | * Check type/source combination: slow ints are (currently) | ||
| 455 | * only possible for MFP-interrupts. | ||
| 456 | */ | ||
| 457 | if (flags == IRQ_TYPE_SLOW && | ||
| 458 | (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE)) { | ||
| 459 | printk ("%s: Slow irq requested for non-MFP source %d from %s\n", | ||
| 460 | __FUNCTION__, irq, devname); | ||
| 461 | return -EINVAL; | ||
| 462 | } | ||
| 463 | |||
| 464 | if (vectors[vector] == bad_inthandler) { | ||
| 465 | /* int has no handler yet */ | ||
| 466 | irq_handler[irq].handler = handler; | ||
| 467 | irq_handler[irq].dev_id = dev_id; | ||
| 468 | irq_param[irq].flags = flags; | ||
| 469 | irq_param[irq].devname = devname; | ||
| 470 | vectors[vector] = | ||
| 471 | (flags == IRQ_TYPE_SLOW) ? slow_handlers[irq-STMFP_SOURCE_BASE] : | ||
| 472 | (flags == IRQ_TYPE_FAST) ? atari_fast_irq_handler : | ||
| 473 | atari_prio_irq_handler; | ||
| 474 | /* If MFP int, also enable and umask it */ | ||
| 475 | atari_turnon_irq(irq); | ||
| 476 | atari_enable_irq(irq); | ||
| 477 | |||
| 478 | return 0; | ||
| 479 | } | ||
| 480 | else if (irq_param[irq].flags == flags) { | ||
| 481 | /* old handler is of same type -> handlers can be chained */ | ||
| 482 | irq_node_t *node; | ||
| 483 | unsigned long flags; | ||
| 484 | |||
| 485 | local_irq_save(flags); | ||
| 486 | |||
| 487 | if (irq_handler[irq].handler != atari_call_irq_list) { | ||
| 488 | /* Only one handler yet, make a node for this first one */ | ||
| 489 | if (!(node = new_irq_node())) | ||
| 490 | return -ENOMEM; | ||
| 491 | node->handler = irq_handler[irq].handler; | ||
| 492 | node->dev_id = irq_handler[irq].dev_id; | ||
| 493 | node->devname = irq_param[irq].devname; | ||
| 494 | node->next = NULL; | ||
| 495 | |||
| 496 | irq_handler[irq].handler = atari_call_irq_list; | ||
| 497 | irq_handler[irq].dev_id = node; | ||
| 498 | irq_param[irq].devname = "chained"; | ||
| 499 | } | ||
| 500 | |||
| 501 | if (!(node = new_irq_node())) | ||
| 502 | return -ENOMEM; | ||
| 503 | node->handler = handler; | ||
| 504 | node->dev_id = dev_id; | ||
| 505 | node->devname = devname; | ||
| 506 | /* new handlers are put in front of the queue */ | ||
| 507 | node->next = irq_handler[irq].dev_id; | ||
| 508 | irq_handler[irq].dev_id = node; | ||
| 509 | |||
| 510 | local_irq_restore(flags); | ||
| 511 | return 0; | ||
| 512 | } else { | ||
| 513 | printk ("%s: Irq %d allocated by other type int (call from %s)\n", | ||
| 514 | __FUNCTION__, irq, devname); | ||
| 515 | return -EBUSY; | ||
| 516 | } | ||
| 517 | } | ||
| 518 | |||
| 519 | void atari_free_irq(unsigned int irq, void *dev_id) | ||
| 520 | { | ||
| 521 | unsigned long flags; | ||
| 522 | int vector; | ||
| 523 | irq_node_t **list, *node; | ||
| 524 | |||
| 525 | if (!IS_VALID_INTNO(irq)) { | ||
| 526 | printk("%s: Unknown irq %d\n", __FUNCTION__, irq); | ||
| 527 | return; | ||
| 528 | } | ||
| 529 | |||
| 530 | vector = IRQ_SOURCE_TO_VECTOR(irq); | ||
| 531 | if (vectors[vector] == bad_inthandler) | ||
| 532 | goto not_found; | ||
| 533 | |||
| 534 | local_irq_save(flags); | ||
| 535 | |||
| 536 | if (irq_handler[irq].handler != atari_call_irq_list) { | ||
| 537 | /* It's the only handler for the interrupt */ | ||
| 538 | if (irq_handler[irq].dev_id != dev_id) { | ||
| 539 | local_irq_restore(flags); | ||
| 540 | goto not_found; | ||
| 541 | } | ||
| 542 | irq_handler[irq].handler = NULL; | ||
| 543 | irq_handler[irq].dev_id = NULL; | ||
| 544 | irq_param[irq].devname = NULL; | ||
| 545 | vectors[vector] = bad_inthandler; | ||
| 546 | /* If MFP int, also disable it */ | ||
| 547 | atari_disable_irq(irq); | ||
| 548 | atari_turnoff_irq(irq); | ||
| 549 | |||
| 550 | local_irq_restore(flags); | ||
| 551 | return; | ||
| 552 | } | ||
| 553 | |||
| 554 | /* The interrupt is chained, find the irq on the list */ | ||
| 555 | for(list = (irq_node_t **)&irq_handler[irq].dev_id; *list; list = &(*list)->next) { | ||
| 556 | if ((*list)->dev_id == dev_id) break; | ||
| 557 | } | ||
| 558 | if (!*list) { | ||
| 559 | local_irq_restore(flags); | ||
| 560 | goto not_found; | ||
| 561 | } | ||
| 562 | |||
| 563 | (*list)->handler = NULL; /* Mark it as free for reallocation */ | ||
| 564 | *list = (*list)->next; | ||
| 565 | |||
| 566 | /* If there's now only one handler, unchain the interrupt, i.e. plug in | ||
| 567 | * the handler directly again and omit atari_call_irq_list */ | ||
| 568 | node = (irq_node_t *)irq_handler[irq].dev_id; | ||
| 569 | if (node && !node->next) { | ||
| 570 | irq_handler[irq].handler = node->handler; | ||
| 571 | irq_handler[irq].dev_id = node->dev_id; | ||
| 572 | irq_param[irq].devname = node->devname; | ||
| 573 | node->handler = NULL; /* Mark it as free for reallocation */ | ||
| 574 | } | ||
| 575 | |||
| 576 | local_irq_restore(flags); | ||
| 577 | return; | ||
| 578 | |||
| 579 | not_found: | ||
| 580 | printk("%s: tried to remove invalid irq\n", __FUNCTION__); | ||
| 581 | return; | ||
| 582 | } | ||
| 583 | |||
| 584 | |||
| 585 | /* | 425 | /* |
| 586 | * atari_register_vme_int() returns the number of a free interrupt vector for | 426 | * atari_register_vme_int() returns the number of a free interrupt vector for |
| 587 | * hardware with a programmable int vector (probably a VME board). | 427 | * hardware with a programmable int vector (probably a VME board). |
| @@ -591,58 +431,24 @@ unsigned long atari_register_vme_int(void) | |||
| 591 | { | 431 | { |
| 592 | int i; | 432 | int i; |
| 593 | 433 | ||
| 594 | for(i = 0; i < 32; i++) | 434 | for (i = 0; i < 32; i++) |
| 595 | if((free_vme_vec_bitmap & (1 << i)) == 0) | 435 | if ((free_vme_vec_bitmap & (1 << i)) == 0) |
| 596 | break; | 436 | break; |
| 597 | 437 | ||
| 598 | if(i == 16) | 438 | if (i == 16) |
| 599 | return 0; | 439 | return 0; |
| 600 | 440 | ||
| 601 | free_vme_vec_bitmap |= 1 << i; | 441 | free_vme_vec_bitmap |= 1 << i; |
| 602 | return (VME_SOURCE_BASE + i); | 442 | return VME_SOURCE_BASE + i; |
| 603 | } | 443 | } |
| 604 | 444 | ||
| 605 | 445 | ||
| 606 | void atari_unregister_vme_int(unsigned long irq) | 446 | void atari_unregister_vme_int(unsigned long irq) |
| 607 | { | 447 | { |
| 608 | if(irq >= VME_SOURCE_BASE && irq < VME_SOURCE_BASE + VME_MAX_SOURCES) { | 448 | if (irq >= VME_SOURCE_BASE && irq < VME_SOURCE_BASE + VME_MAX_SOURCES) { |
| 609 | irq -= VME_SOURCE_BASE; | 449 | irq -= VME_SOURCE_BASE; |
| 610 | free_vme_vec_bitmap &= ~(1 << irq); | 450 | free_vme_vec_bitmap &= ~(1 << irq); |
| 611 | } | 451 | } |
| 612 | } | 452 | } |
| 613 | 453 | ||
| 614 | 454 | ||
| 615 | int show_atari_interrupts(struct seq_file *p, void *v) | ||
| 616 | { | ||
| 617 | int i; | ||
| 618 | |||
| 619 | for (i = 0; i < NUM_INT_SOURCES; ++i) { | ||
| 620 | if (vectors[IRQ_SOURCE_TO_VECTOR(i)] == bad_inthandler) | ||
| 621 | continue; | ||
| 622 | if (i < STMFP_SOURCE_BASE) | ||
| 623 | seq_printf(p, "auto %2d: %10u ", | ||
| 624 | i, kstat_cpu(0).irqs[i]); | ||
| 625 | else | ||
| 626 | seq_printf(p, "vec $%02x: %10u ", | ||
| 627 | IRQ_SOURCE_TO_VECTOR(i), | ||
| 628 | kstat_cpu(0).irqs[i]); | ||
| 629 | |||
| 630 | if (irq_handler[i].handler != atari_call_irq_list) { | ||
| 631 | seq_printf(p, "%s\n", irq_param[i].devname); | ||
| 632 | } | ||
| 633 | else { | ||
| 634 | irq_node_t *n; | ||
| 635 | for( n = (irq_node_t *)irq_handler[i].dev_id; n; n = n->next ) { | ||
| 636 | seq_printf(p, "%s\n", n->devname); | ||
| 637 | if (n->next) | ||
| 638 | seq_puts(p, " " ); | ||
| 639 | } | ||
| 640 | } | ||
| 641 | } | ||
| 642 | if (num_spurious) | ||
| 643 | seq_printf(p, "spurio.: %10u\n", num_spurious); | ||
| 644 | |||
| 645 | return 0; | ||
| 646 | } | ||
| 647 | |||
| 648 | |||
diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c index 1012b08e5522..727289acad7e 100644 --- a/arch/m68k/atari/config.c +++ b/arch/m68k/atari/config.c | |||
| @@ -57,12 +57,6 @@ static int atari_get_hardware_list(char *buffer); | |||
| 57 | 57 | ||
| 58 | /* atari specific irq functions */ | 58 | /* atari specific irq functions */ |
| 59 | extern void atari_init_IRQ (void); | 59 | extern void atari_init_IRQ (void); |
| 60 | extern int atari_request_irq (unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), | ||
| 61 | unsigned long flags, const char *devname, void *dev_id); | ||
| 62 | extern void atari_free_irq (unsigned int irq, void *dev_id); | ||
| 63 | extern void atari_enable_irq (unsigned int); | ||
| 64 | extern void atari_disable_irq (unsigned int); | ||
| 65 | extern int show_atari_interrupts (struct seq_file *, void *); | ||
| 66 | extern void atari_mksound( unsigned int count, unsigned int ticks ); | 60 | extern void atari_mksound( unsigned int count, unsigned int ticks ); |
| 67 | #ifdef CONFIG_HEARTBEAT | 61 | #ifdef CONFIG_HEARTBEAT |
| 68 | static void atari_heartbeat( int on ); | 62 | static void atari_heartbeat( int on ); |
| @@ -232,13 +226,8 @@ void __init config_atari(void) | |||
| 232 | 226 | ||
| 233 | mach_sched_init = atari_sched_init; | 227 | mach_sched_init = atari_sched_init; |
| 234 | mach_init_IRQ = atari_init_IRQ; | 228 | mach_init_IRQ = atari_init_IRQ; |
| 235 | mach_request_irq = atari_request_irq; | ||
| 236 | mach_free_irq = atari_free_irq; | ||
| 237 | enable_irq = atari_enable_irq; | ||
| 238 | disable_irq = atari_disable_irq; | ||
| 239 | mach_get_model = atari_get_model; | 229 | mach_get_model = atari_get_model; |
| 240 | mach_get_hardware_list = atari_get_hardware_list; | 230 | mach_get_hardware_list = atari_get_hardware_list; |
| 241 | mach_get_irq_list = show_atari_interrupts; | ||
| 242 | mach_gettimeoffset = atari_gettimeoffset; | 231 | mach_gettimeoffset = atari_gettimeoffset; |
| 243 | mach_reset = atari_reset; | 232 | mach_reset = atari_reset; |
| 244 | mach_max_dma_address = 0xffffff; | 233 | mach_max_dma_address = 0xffffff; |
