m68k: merge mmu and non-mmu versions of processor.h
[linux-2.6.git] / arch / m68k / atari / ataints.c
index bb54741..39478dd 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/init.h>
 #include <linux/seq_file.h>
+#include <linux/module.h>
 
 #include <asm/system.h>
 #include <asm/traps.h>
  * the sr copy in the frame.
  */
 
+#if 0
 
 #define        NUM_INT_SOURCES (8 + NUM_ATARI_SOURCES)
 
@@ -133,13 +135,6 @@ static struct irqhandler irq_handler[NUM_INT_SOURCES];
  */
 static struct irqparam irq_param[NUM_INT_SOURCES];
 
-/*
- * Bitmap for free interrupt vector numbers
- * (new vectors starting from 0x70 can be allocated by
- * atari_register_vme_int())
- */
-static int free_vme_vec_bitmap;
-
 /* check for valid int number (complex, sigh...) */
 #define        IS_VALID_INTNO(n)                                                                                       \
        ((n) > 0 &&                                                                                                             \
@@ -192,8 +187,8 @@ __asm__ (__ALIGN_STR "\n"                                              \
 "      jbra    ret_from_interrupt\n"                                      \
         : : "i" (&kstat_cpu(0).irqs[n+8]), "i" (&irq_handler[n+8]),       \
             "n" (PT_OFF_SR), "n" (n),                                     \
-            "i" (n & 8 ? (n & 16 ? &tt_mfp.int_mk_a : &mfp.int_mk_a)      \
-                       : (n & 16 ? &tt_mfp.int_mk_b : &mfp.int_mk_b)),    \
+            "i" (n & 8 ? (n & 16 ? &tt_mfp.int_mk_a : &st_mfp.int_mk_a)   \
+                       : (n & 16 ? &tt_mfp.int_mk_b : &st_mfp.int_mk_b)), \
             "m" (preempt_count()), "di" (HARDIRQ_OFFSET)                  \
 );                                                                        \
        for (;;);                       /* fake noreturn */                \
@@ -301,6 +296,14 @@ __asm__ (__ALIGN_STR "\n"
 );
        for (;;);
 }
+#endif
+
+/*
+ * Bitmap for free interrupt vector numbers
+ * (new vectors starting from 0x70 can be allocated by
+ * atari_register_vme_int())
+ */
+static int free_vme_vec_bitmap;
 
 /* GK:
  * HBL IRQ handler for Falcon. Nobody needs it :-)
@@ -313,13 +316,37 @@ __ALIGN_STR "\n\t"
        "orw    #0x200,%sp@\n\t"        /* set saved ipl to 2 */
        "rte");
 
-/* Defined in entry.S; only increments 'num_spurious' */
-asmlinkage void bad_inthandler(void);
-
-extern void atari_microwire_cmd( int cmd );
+extern void atari_microwire_cmd(int cmd);
 
 extern int atari_SCC_reset_done;
 
+static int atari_startup_irq(unsigned int irq)
+{
+       m68k_irq_startup(irq);
+       atari_turnon_irq(irq);
+       atari_enable_irq(irq);
+       return 0;
+}
+
+static void atari_shutdown_irq(unsigned int irq)
+{
+       atari_disable_irq(irq);
+       atari_turnoff_irq(irq);
+       m68k_irq_shutdown(irq);
+
+       if (irq == IRQ_AUTO_4)
+           vectors[VEC_INT4] = falcon_hblhandler;
+}
+
+static struct irq_controller atari_irq_controller = {
+       .name           = "atari",
+       .lock           = __SPIN_LOCK_UNLOCKED(atari_irq_controller.lock),
+       .startup        = atari_startup_irq,
+       .shutdown       = atari_shutdown_irq,
+       .enable         = atari_enable_irq,
+       .disable        = atari_disable_irq,
+};
+
 /*
  * void atari_init_IRQ (void)
  *
@@ -333,24 +360,20 @@ extern int atari_SCC_reset_done;
 
 void __init atari_init_IRQ(void)
 {
-       int i;
-
-       /* initialize the vector table */
-       for (i = 0; i < NUM_INT_SOURCES; ++i) {
-               vectors[IRQ_SOURCE_TO_VECTOR(i)] = bad_inthandler;
-       }
+       m68k_setup_user_interrupt(VEC_USER, NUM_ATARI_SOURCES - IRQ_USER, NULL);
+       m68k_setup_irq_controller(&atari_irq_controller, 1, NUM_ATARI_SOURCES - 1);
 
        /* Initialize the MFP(s) */
 
 #ifdef ATARI_USE_SOFTWARE_EOI
-       mfp.vec_adr  = 0x48;    /* Software EOI-Mode */
+       st_mfp.vec_adr  = 0x48; /* Software EOI-Mode */
 #else
-       mfp.vec_adr  = 0x40;    /* Automatic EOI-Mode */
+       st_mfp.vec_adr  = 0x40; /* Automatic EOI-Mode */
 #endif
-       mfp.int_en_a = 0x00;    /* turn off MFP-Ints */
-       mfp.int_en_b = 0x00;
-       mfp.int_mk_a = 0xff;    /* no Masking */
-       mfp.int_mk_b = 0xff;
+       st_mfp.int_en_a = 0x00; /* turn off MFP-Ints */
+       st_mfp.int_en_b = 0x00;
+       st_mfp.int_mk_a = 0xff; /* no Masking */
+       st_mfp.int_mk_b = 0xff;
 
        if (ATARIHW_PRESENT(TT_MFP)) {
 #ifdef ATARI_USE_SOFTWARE_EOI
@@ -378,15 +401,14 @@ void __init atari_init_IRQ(void)
                                                                         * enabled in VME mask
                                                                         */
                tt_scu.vme_mask = 0x60;         /* enable MFP and SCC ints */
-       }
-       else {
+       } else {
                /* If no SCU and no Hades, the HSYNC interrupt needs to be
                 * disabled this way. (Else _inthandler in kernel/sys_call.S
                 * gets overruns)
                 */
 
-               if (!MACH_IS_HADES)
-                       vectors[VEC_INT2] = falcon_hblhandler;
+               vectors[VEC_INT2] = falcon_hblhandler;
+               vectors[VEC_INT4] = falcon_hblhandler;
        }
 
        if (ATARIHW_PRESENT(PCM_8BIT) && ATARIHW_PRESENT(MICROWIRE)) {
@@ -404,184 +426,6 @@ void __init atari_init_IRQ(void)
 }
 
 
-static irqreturn_t atari_call_irq_list( int irq, void *dev_id, struct pt_regs *fp )
-{
-       irq_node_t *node;
-
-       for (node = (irq_node_t *)dev_id; node; node = node->next)
-               node->handler(irq, node->dev_id, fp);
-       return IRQ_HANDLED;
-}
-
-
-/*
- * atari_request_irq : add an interrupt service routine for a particular
- *                     machine specific interrupt source.
- *                     If the addition was successful, it returns 0.
- */
-
-int atari_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),
-                      unsigned long flags, const char *devname, void *dev_id)
-{
-       int vector;
-       unsigned long oflags = flags;
-
-       /*
-        * The following is a hack to make some PCI card drivers work,
-        * which set the SA_SHIRQ flag.
-        */
-
-       flags &= ~SA_SHIRQ;
-
-       if (flags == SA_INTERRUPT) {
-               printk ("%s: SA_INTERRUPT changed to IRQ_TYPE_SLOW for %s\n",
-                       __FUNCTION__, devname);
-               flags = IRQ_TYPE_SLOW;
-       }
-       if (flags < IRQ_TYPE_SLOW || flags > IRQ_TYPE_PRIO) {
-               printk ("%s: Bad irq type 0x%lx <0x%lx> requested from %s\n",
-                       __FUNCTION__, flags, oflags, devname);
-               return -EINVAL;
-       }
-       if (!IS_VALID_INTNO(irq)) {
-               printk ("%s: Unknown irq %d requested from %s\n",
-                       __FUNCTION__, irq, devname);
-               return -ENXIO;
-       }
-       vector = IRQ_SOURCE_TO_VECTOR(irq);
-
-       /*
-        * Check type/source combination: slow ints are (currently)
-        * only possible for MFP-interrupts.
-        */
-       if (flags == IRQ_TYPE_SLOW &&
-               (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE)) {
-               printk ("%s: Slow irq requested for non-MFP source %d from %s\n",
-                       __FUNCTION__, irq, devname);
-               return -EINVAL;
-       }
-
-       if (vectors[vector] == bad_inthandler) {
-               /* int has no handler yet */
-               irq_handler[irq].handler = handler;
-               irq_handler[irq].dev_id  = dev_id;
-               irq_param[irq].flags   = flags;
-               irq_param[irq].devname = devname;
-               vectors[vector] =
-                       (flags == IRQ_TYPE_SLOW) ? slow_handlers[irq-STMFP_SOURCE_BASE] :
-                       (flags == IRQ_TYPE_FAST) ? atari_fast_irq_handler :
-                                                 atari_prio_irq_handler;
-               /* If MFP int, also enable and umask it */
-               atari_turnon_irq(irq);
-               atari_enable_irq(irq);
-
-               return 0;
-       }
-       else if (irq_param[irq].flags == flags) {
-               /* old handler is of same type -> handlers can be chained */
-               irq_node_t *node;
-               unsigned long flags;
-
-               local_irq_save(flags);
-
-               if (irq_handler[irq].handler != atari_call_irq_list) {
-                       /* Only one handler yet, make a node for this first one */
-                       if (!(node = new_irq_node()))
-                               return -ENOMEM;
-                       node->handler = irq_handler[irq].handler;
-                       node->dev_id  = irq_handler[irq].dev_id;
-                       node->devname = irq_param[irq].devname;
-                       node->next = NULL;
-
-                       irq_handler[irq].handler = atari_call_irq_list;
-                       irq_handler[irq].dev_id  = node;
-                       irq_param[irq].devname   = "chained";
-               }
-
-               if (!(node = new_irq_node()))
-                       return -ENOMEM;
-               node->handler = handler;
-               node->dev_id  = dev_id;
-               node->devname = devname;
-               /* new handlers are put in front of the queue */
-               node->next = irq_handler[irq].dev_id;
-               irq_handler[irq].dev_id = node;
-
-               local_irq_restore(flags);
-               return 0;
-       } else {
-               printk ("%s: Irq %d allocated by other type int (call from %s)\n",
-                       __FUNCTION__, irq, devname);
-               return -EBUSY;
-       }
-}
-
-void atari_free_irq(unsigned int irq, void *dev_id)
-{
-       unsigned long flags;
-       int vector;
-       irq_node_t **list, *node;
-
-       if (!IS_VALID_INTNO(irq)) {
-               printk("%s: Unknown irq %d\n", __FUNCTION__, irq);
-               return;
-       }
-
-       vector = IRQ_SOURCE_TO_VECTOR(irq);
-       if (vectors[vector] == bad_inthandler)
-               goto not_found;
-
-       local_irq_save(flags);
-
-       if (irq_handler[irq].handler != atari_call_irq_list) {
-               /* It's the only handler for the interrupt */
-               if (irq_handler[irq].dev_id != dev_id) {
-                       local_irq_restore(flags);
-                       goto not_found;
-               }
-               irq_handler[irq].handler = NULL;
-               irq_handler[irq].dev_id  = NULL;
-               irq_param[irq].devname   = NULL;
-               vectors[vector] = bad_inthandler;
-               /* If MFP int, also disable it */
-               atari_disable_irq(irq);
-               atari_turnoff_irq(irq);
-
-               local_irq_restore(flags);
-               return;
-       }
-
-       /* The interrupt is chained, find the irq on the list */
-       for(list = (irq_node_t **)&irq_handler[irq].dev_id; *list; list = &(*list)->next) {
-               if ((*list)->dev_id == dev_id) break;
-       }
-       if (!*list) {
-               local_irq_restore(flags);
-               goto not_found;
-       }
-
-       (*list)->handler = NULL; /* Mark it as free for reallocation */
-       *list = (*list)->next;
-
-       /* If there's now only one handler, unchain the interrupt, i.e. plug in
-        * the handler directly again and omit atari_call_irq_list */
-       node = (irq_node_t *)irq_handler[irq].dev_id;
-       if (node && !node->next) {
-               irq_handler[irq].handler = node->handler;
-               irq_handler[irq].dev_id  = node->dev_id;
-               irq_param[irq].devname   = node->devname;
-               node->handler = NULL; /* Mark it as free for reallocation */
-       }
-
-       local_irq_restore(flags);
-       return;
-
-not_found:
-       printk("%s: tried to remove invalid irq\n", __FUNCTION__);
-       return;
-}
-
-
 /*
  * atari_register_vme_int() returns the number of a free interrupt vector for
  * hardware with a programmable int vector (probably a VME board).
@@ -591,58 +435,26 @@ unsigned long atari_register_vme_int(void)
 {
        int i;
 
-       for(i = 0; i < 32; i++)
-               if((free_vme_vec_bitmap & (1 << i)) == 0)
+       for (i = 0; i < 32; i++)
+               if ((free_vme_vec_bitmap & (1 << i)) == 0)
                        break;
 
-       if(i == 16)
+       if (i == 16)
                return 0;
 
        free_vme_vec_bitmap |= 1 << i;
-       return (VME_SOURCE_BASE + i);
+       return VME_SOURCE_BASE + i;
 }
+EXPORT_SYMBOL(atari_register_vme_int);
 
 
 void atari_unregister_vme_int(unsigned long irq)
 {
-       if(irq >= VME_SOURCE_BASE && irq < VME_SOURCE_BASE + VME_MAX_SOURCES) {
+       if (irq >= VME_SOURCE_BASE && irq < VME_SOURCE_BASE + VME_MAX_SOURCES) {
                irq -= VME_SOURCE_BASE;
                free_vme_vec_bitmap &= ~(1 << irq);
        }
 }
-
-
-int show_atari_interrupts(struct seq_file *p, void *v)
-{
-       int i;
-
-       for (i = 0; i < NUM_INT_SOURCES; ++i) {
-               if (vectors[IRQ_SOURCE_TO_VECTOR(i)] == bad_inthandler)
-                       continue;
-               if (i < STMFP_SOURCE_BASE)
-                       seq_printf(p, "auto %2d: %10u ",
-                                      i, kstat_cpu(0).irqs[i]);
-               else
-                       seq_printf(p, "vec $%02x: %10u ",
-                                      IRQ_SOURCE_TO_VECTOR(i),
-                                      kstat_cpu(0).irqs[i]);
-
-               if (irq_handler[i].handler != atari_call_irq_list) {
-                       seq_printf(p, "%s\n", irq_param[i].devname);
-               }
-               else {
-                       irq_node_t *n;
-                       for( n = (irq_node_t *)irq_handler[i].dev_id; n; n = n->next ) {
-                               seq_printf(p, "%s\n", n->devname);
-                               if (n->next)
-                                       seq_puts(p, "                    " );
-                       }
-               }
-       }
-       if (num_spurious)
-               seq_printf(p, "spurio.: %10u\n", num_spurious);
-
-       return 0;
-}
+EXPORT_SYMBOL(atari_unregister_vme_int);