m68knommu: complete interrupt controller code for the 68328 CPU's
[linux-2.6.git] / arch / m68knommu / platform / 68328 / ints.c
index 2dda733..b91ee85 100644 (file)
@@ -9,20 +9,14 @@
  * Copyright 1999 D. Jeff Dionne <jeff@rt-control.com>
  */
 
-#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/kernel_stat.h>
-#include <linux/errno.h>
-
-#include <asm/system.h>
-#include <asm/irq.h>
-#include <asm/irqnode.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <asm/traps.h>
 #include <asm/io.h>
 #include <asm/machdep.h>
-#include <asm/setup.h>
 
 #if defined(CONFIG_M68328)
 #include <asm/MC68328.h>
@@ -64,7 +58,7 @@ asmlinkage void trap44(void);
 asmlinkage void trap45(void);
 asmlinkage void trap46(void);
 asmlinkage void trap47(void);
-asmlinkage irqreturn_t bad_interrupt(int, void *, struct pt_regs *);
+asmlinkage irqreturn_t bad_interrupt(int, void *);
 asmlinkage irqreturn_t inthandler(void);
 asmlinkage irqreturn_t inthandler1(void);
 asmlinkage irqreturn_t inthandler2(void);
@@ -78,124 +72,6 @@ extern e_vector *_ramvec;
 
 /* The number of spurious interrupts */
 volatile unsigned int num_spurious;
-unsigned int local_irq_count[NR_CPUS];
-
-/* irq node variables for the 32 (potential) on chip sources */
-static irq_node_t int_irq_list[NR_IRQS];
-
-/*
- * This function should be called during kernel startup to initialize
- * the IRQ handling routines.
- */
-void init_IRQ(void)
-{
-       int i;
-
-       /* set up the vectors */
-       for (i = 72; i < 256; ++i)
-               _ramvec[i] = (e_vector) bad_interrupt;
-
-       _ramvec[32] = system_call;
-
-       _ramvec[65] = (e_vector) inthandler1;
-       _ramvec[66] = (e_vector) inthandler2;
-       _ramvec[67] = (e_vector) inthandler3;
-       _ramvec[68] = (e_vector) inthandler4;
-       _ramvec[69] = (e_vector) inthandler5;
-       _ramvec[70] = (e_vector) inthandler6;
-       _ramvec[71] = (e_vector) inthandler7;
-       IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */
-
-       /* initialize handlers */
-       for (i = 0; i < NR_IRQS; i++) {
-               int_irq_list[i].handler = bad_interrupt;
-               int_irq_list[i].flags   = IRQ_FLG_STD;
-               int_irq_list[i].dev_id  = NULL;
-               int_irq_list[i].devname = NULL;
-       }
-
-       /* turn off all interrupts */
-       IMR = ~0;
-}
-
-int request_irq(
-       unsigned int irq,
-       irqreturn_t (*handler)(int, void *, struct pt_regs *),
-       unsigned long flags,
-       const char *devname,
-       void *dev_id)
-{
-       if (irq >= NR_IRQS) {
-               printk (KERN_ERR "%s: Unknown IRQ %d from %s\n", __FUNCTION__, irq, devname);
-               return -ENXIO;
-       }
-
-       if (!(int_irq_list[irq].flags & IRQ_FLG_STD)) {
-               if (int_irq_list[irq].flags & IRQ_FLG_LOCK) {
-                       printk(KERN_ERR "%s: IRQ %d from %s is not replaceable\n",
-                              __FUNCTION__, irq, int_irq_list[irq].devname);
-                       return -EBUSY;
-               }
-               if (flags & IRQ_FLG_REPLACE) {
-                       printk(KERN_ERR "%s: %s can't replace IRQ %d from %s\n",
-                              __FUNCTION__, devname, irq, int_irq_list[irq].devname);
-                       return -EBUSY;
-               }
-       }
-
-       int_irq_list[irq].handler = handler;
-       int_irq_list[irq].flags   = flags;
-       int_irq_list[irq].dev_id  = dev_id;
-       int_irq_list[irq].devname = devname;
-
-       IMR &= ~(1<<irq);
-
-       return 0;
-}
-
-EXPORT_SYMBOL(request_irq);
-
-void free_irq(unsigned int irq, void *dev_id)
-{
-       if (irq >= NR_IRQS) {
-               printk (KERN_ERR "%s: Unknown IRQ %d\n", __FUNCTION__, irq);
-               return;
-       }
-
-       if (int_irq_list[irq].dev_id != dev_id)
-               printk(KERN_INFO "%s: removing probably wrong IRQ %d from %s\n",
-                      __FUNCTION__, irq, int_irq_list[irq].devname);
-
-       int_irq_list[irq].handler = bad_interrupt;
-       int_irq_list[irq].flags   = IRQ_FLG_STD;
-       int_irq_list[irq].dev_id  = NULL;
-       int_irq_list[irq].devname = NULL;
-
-       IMR |= 1<<irq;
-}
-
-EXPORT_SYMBOL(free_irq);
-
-int show_interrupts(struct seq_file *p, void *v)
-{
-       int i = *(loff_t *) v;
-
-       if (i < NR_IRQS) {
-               if (int_irq_list[i].devname) {
-                       seq_printf(p, "%3d: %10u ", i, kstat_cpu(0).irqs[i]);
-                       if (int_irq_list[i].flags & IRQ_FLG_LOCK)
-                               seq_printf(p, "L ");
-                       else
-                               seq_printf(p, "  ");
-                       seq_printf(p, "%s\n", int_irq_list[i].devname);
-               }
-       }
-       if (i == NR_IRQS)
-               seq_printf(p, "   : %10u   spurious\n", num_spurious);
-
-       return 0;
-}
 
 /* The 68k family did not have a good way to determine the source
  * of interrupts until later in the family.  The EC000 core does
@@ -254,14 +130,59 @@ void process_int(int vec, struct pt_regs *fp)
                        irq++;
                }
 
-               kstat_cpu(0).irqs[irq]++;
-
-               if (int_irq_list[irq].handler) {
-                       int_irq_list[irq].handler(irq, int_irq_list[irq].dev_id, fp);
-               } else {
-                       printk(KERN_ERR "unregistered interrupt %d!\nTurning it off in the IMR...\n", irq);
-                       IMR |= mask;
-               }
+               do_IRQ(irq, fp);
                pend &= ~mask;
        }
 }
+
+static void intc_irq_unmask(unsigned int irq)
+{
+       IMR &= ~(1<<irq);
+}
+
+static void intc_irq_mask(unsigned int irq)
+{
+       IMR |= (1<<irq);
+}
+
+static struct irq_chip intc_irq_chip = {
+       .name           = "M68K-INTC",
+       .mask           = intc_irq_mask,
+       .unmask         = intc_irq_unmask,
+};
+
+/*
+ * This function should be called during kernel startup to initialize
+ * the machine vector table.
+ */
+void __init init_IRQ(void)
+{
+       int i;
+
+       /* set up the vectors */
+       for (i = 72; i < 256; ++i)
+               _ramvec[i] = (e_vector) bad_interrupt;
+
+       _ramvec[32] = system_call;
+
+       _ramvec[65] = (e_vector) inthandler1;
+       _ramvec[66] = (e_vector) inthandler2;
+       _ramvec[67] = (e_vector) inthandler3;
+       _ramvec[68] = (e_vector) inthandler4;
+       _ramvec[69] = (e_vector) inthandler5;
+       _ramvec[70] = (e_vector) inthandler6;
+       _ramvec[71] = (e_vector) inthandler7;
+
+       IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */
+
+       /* turn off all interrupts */
+       IMR = ~0;
+
+       for (i = 0; (i < NR_IRQS); i++) {
+               irq_desc[i].status = IRQ_DISABLED;
+               irq_desc[i].action = NULL;
+               irq_desc[i].depth = 1;
+               irq_desc[i].chip = &intc_irq_chip;
+       }
+}
+