Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] m68k: convert atari 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>

authored by

Roman Zippel and committed by
Linus Torvalds
73408565 0aa78106

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