aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoman Zippel <zippel@linux-m68k.org>2006-06-25 08:47:03 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-25 13:00:57 -0400
commit734085651c9b80aa3f9e6027b156102de214a0b2 (patch)
treea3f8c691b0c0298307784fc7e55b6c3c68812a0b
parent0aa78106c661cf6c251fd56e92f0c76a7459d244 (diff)
[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>
-rw-r--r--arch/m68k/atari/ataints.c278
-rw-r--r--arch/m68k/atari/config.c11
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 */
134static struct irqparam irq_param[NUM_INT_SOURCES]; 135static 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 */
141static 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 */
305static 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' */ 318extern void atari_microwire_cmd(int cmd);
317asmlinkage void bad_inthandler(void);
318
319extern void atari_microwire_cmd( int cmd );
320 319
321extern int atari_SCC_reset_done; 320extern int atari_SCC_reset_done;
322 321
322static 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
330static 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
337static 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
334void __init atari_init_IRQ(void) 357void __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
407static 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
423int 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
519void 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
579not_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
606void atari_unregister_vme_int(unsigned long irq) 446void 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
615int 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 */
59extern void atari_init_IRQ (void); 59extern void atari_init_IRQ (void);
60extern 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);
62extern void atari_free_irq (unsigned int irq, void *dev_id);
63extern void atari_enable_irq (unsigned int);
64extern void atari_disable_irq (unsigned int);
65extern int show_atari_interrupts (struct seq_file *, void *);
66extern void atari_mksound( unsigned int count, unsigned int ticks ); 60extern void atari_mksound( unsigned int count, unsigned int ticks );
67#ifdef CONFIG_HEARTBEAT 61#ifdef CONFIG_HEARTBEAT
68static void atari_heartbeat( int on ); 62static 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;