Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[safe/jmp/linux-2.6] / arch / m68knommu / platform / 68360 / ints.c
index ba184db..6f22970 100644 (file)
  * Copyright (c) 1999 D. Jeff Dionne <jeff@uclinux.org>
  */
 
-#include <linux/config.h>
-#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 <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>
 #include <asm/m68360.h>
 
 /* from quicc/commproc.c: */
@@ -36,25 +29,40 @@ extern void cpm_interrupt_init(void);
 asmlinkage void system_call(void);
 asmlinkage void buserr(void);
 asmlinkage void trap(void);
-asmlinkage irqreturn_t bad_interrupt(void);
-asmlinkage irqreturn_t inthandler(void);
+asmlinkage void bad_interrupt(void);
+asmlinkage void inthandler(void);
 
 extern void *_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[INTERNAL_IRQS];
+static void intc_irq_unmask(unsigned int irq)
+{
+       pquicc->intr_cimr |= (1 << irq);
+}
+
+static void intc_irq_mask(unsigned int irq)
+{
+       pquicc->intr_cimr &= ~(1 << irq);
+}
+
+static void intc_irq_ack(unsigned int irq)
+{
+       pquicc->intr_cisr = (1 << irq);
+}
 
-static short int_irq_ablecount[INTERNAL_IRQS];
+static struct irq_chip intc_irq_chip = {
+       .name           = "M68K-INTC",
+       .mask           = intc_irq_mask,
+       .unmask         = intc_irq_unmask,
+       .ack            = intc_irq_ack,
+};
 
 /*
  * This function should be called during kernel startup to initialize
- * IRQ handling routines.
+ * the vector table.
  */
-
 void init_IRQ(void)
 {
        int i;
@@ -79,7 +87,6 @@ void init_IRQ(void)
        _ramvec[32] = system_call;
        _ramvec[33] = trap;
 
-
        cpm_interrupt_init();
 
        /* set up CICR for vector base address and irq level */
@@ -100,7 +107,6 @@ void init_IRQ(void)
        _ramvec[vba+CPMVEC_PIO_PC7]     = inthandler;  /* pio - pc7 */
        _ramvec[vba+CPMVEC_PIO_PC6]     = inthandler;  /* pio - pc6 */
        _ramvec[vba+CPMVEC_TIMER3]      = inthandler;  /* timer 3 */
-       _ramvec[vba+CPMVEC_RISCTIMER]   = inthandler;  /* reserved */
        _ramvec[vba+CPMVEC_PIO_PC5]     = inthandler;  /* pio - pc5 */
        _ramvec[vba+CPMVEC_PIO_PC4]     = inthandler;  /* pio - pc4 */
        _ramvec[vba+CPMVEC_RESERVED2]   = inthandler;  /* reserved */
@@ -125,211 +131,11 @@ void init_IRQ(void)
        /* turn off all CPM interrupts */
        pquicc->intr_cimr = 0x00000000;
 
-       /* initialize handlers */
-       for (i = 0; i < INTERNAL_IRQS; i++) {
-               int_irq_list[i].handler = NULL;
-               int_irq_list[i].flags   = IRQ_FLG_STD;
-               int_irq_list[i].dev_id  = NULL;
-               int_irq_list[i].devname = NULL;
-       }
-}
-
-#if 0
-void M68360_insert_irq(irq_node_t **list, irq_node_t *node)
-{
-       unsigned long flags;
-       irq_node_t *cur;
-
-       if (!node->dev_id)
-               printk(KERN_INFO "%s: Warning: dev_id of %s is zero\n",
-                      __FUNCTION__, node->devname);
-
-       local_irq_save(flags);
-
-       cur = *list;
-
-       while (cur) {
-               list = &cur->next;
-               cur = cur->next;
-       }
-
-       node->next = cur;
-       *list = node;
-
-       local_irq_restore(flags);
-}
-
-void M68360_delete_irq(irq_node_t **list, void *dev_id)
-{
-       unsigned long flags;
-       irq_node_t *node;
-
-       local_irq_save(flags);
-
-       for (node = *list; node; list = &node->next, node = *list) {
-               if (node->dev_id == dev_id) {
-                       *list = node->next;
-                       /* Mark it as free. */
-                       node->handler = NULL;
-                       local_irq_restore(flags);
-                       return;
-               }
-       }
-       local_irq_restore(flags);
-       printk (KERN_INFO "%s: tried to remove invalid irq\n", __FUNCTION__);
-}
-#endif
-
-int request_irq(
-       unsigned int irq,
-       irqreturn_t (*handler)(int, void *, struct pt_regs *),
-       unsigned long flags,
-       const char *devname,
-       void *dev_id)
-{
-       int mask = (1<<irq);
-
-       irq += (CPM_VECTOR_BASE<<4);
-
-       if (irq >= INTERNAL_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;
-
-       /* enable in the CIMR */
-       if (!int_irq_ablecount[irq])
-               pquicc->intr_cimr |= mask;
-       /*      *(volatile unsigned long *)0xfffff304 &= ~(1<<irq); */
-
-       return 0;
-}
-
-EXPORT_SYMBOL(request_irq);
-
-void free_irq(unsigned int irq, void *dev_id)
-{
-       if (irq >= INTERNAL_IRQS) {
-               printk (KERN_ERR "%s: Unknown IRQ %d\n", __FUNCTION__, irq);
-               return;
+       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;
        }
-
-       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 = NULL;
-       int_irq_list[irq].flags   = IRQ_FLG_STD;
-       int_irq_list[irq].dev_id  = NULL;
-       int_irq_list[irq].devname = NULL;
-
-       *(volatile unsigned long *)0xfffff304 |= 1<<irq;
 }
 
-EXPORT_SYMBOL(free_irq);
-
-#if 0
-/*
- * Enable/disable a particular machine specific interrupt source.
- * Note that this may affect other interrupts in case of a shared interrupt.
- * This function should only be called for a _very_ short time to change some
- * internal data, that may not be changed by the interrupt at the same time.
- * int_(enable|disable)_irq calls may also be nested.
- */
-void M68360_enable_irq(unsigned int irq)
-{
-       if (irq >= INTERNAL_IRQS) {
-               printk(KERN_ERR "%s: Unknown IRQ %d\n", __FUNCTION__, irq);
-               return;
-       }
-
-       if (--int_irq_ablecount[irq])
-               return;
-
-       /* enable the interrupt */
-       *(volatile unsigned long *)0xfffff304 &= ~(1<<irq);
-}
-
-void M68360_disable_irq(unsigned int irq)
-{
-       if (irq >= INTERNAL_IRQS) {
-               printk(KERN_ERR "%s: Unknown IRQ %d\n", __FUNCTION__, irq);
-               return;
-       }
-
-       if (int_irq_ablecount[irq]++)
-               return;
-
-       /* disable the interrupt */
-       *(volatile unsigned long *)0xfffff304 |= 1<<irq;
-}
-#endif
-
-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
- * not provide the vector number on the stack, we vector everything
- * into one vector and look in the blasted mask register...
- * This code is designed to be fast, almost constant time, not clean!
- */
-void process_int(int vec, struct pt_regs *fp)
-{
-       int irq;
-       int mask;
-
-       /* unsigned long pend = *(volatile unsigned long *)0xfffff30c; */
-
-       /* irq = vec + (CPM_VECTOR_BASE<<4); */
-       irq = vec;
-
-       /* unsigned long pend = *(volatile unsigned long *)pquicc->intr_cipr; */
-
-       /* Bugger all that weirdness. For the moment, I seem to know where I came from;
-        * vec is passed from a specific ISR, so I'll use it. */
-
-       if (int_irq_list[irq].handler) {
-               int_irq_list[irq].handler(irq , int_irq_list[irq].dev_id, fp);
-               kstat_cpu(0).irqs[irq]++;
-               pquicc->intr_cisr = (1 << vec); /* indicate that irq has been serviced */
-       } else {
-               printk(KERN_ERR "unregistered interrupt %d!\nTurning it off in the CIMR...\n", irq);
-               /* *(volatile unsigned long *)0xfffff304 |= mask; */
-               pquicc->intr_cimr &= ~(1 << vec);
-               num_spurious += 1;
-       }
-       return(IRQ_HANDLED);
-}