]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/sparc/kernel/irq.c
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6-omap-h63xx.git] / arch / sparc / kernel / irq.c
index c8cb211b90728741877f0326a96803c37ba07527..b76dc03fc3187fa50c6d80213bc8609e28fc72a3 100644 (file)
@@ -1,6 +1,6 @@
 /*  $Id: irq.c,v 1.114 2001/12/11 04:55:51 davem Exp $
  *  arch/sparc/kernel/irq.c:  Interrupt request handling routines. On the
- *                            Sparc the IRQ's are basically 'cast in stone'
+ *                            Sparc the IRQs are basically 'cast in stone'
  *                            and you are supposed to probe the prom's device
  *                            node trees to find out who's got which IRQ.
  *
@@ -24,7 +24,6 @@
 #include <linux/random.h>
 #include <linux/init.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/delay.h>
 #include <linux/threads.h>
 #include <linux/spinlock.h>
@@ -48,6 +47,8 @@
 #include <asm/cacheflush.h>
 #include <asm/irq_regs.h>
 
+#include "irq.h"
+
 #ifdef CONFIG_SMP
 #define SMP_NOP2 "nop; nop;\n\t"
 #define SMP_NOP3 "nop; nop; nop;\n\t"
@@ -269,7 +270,7 @@ void free_irq(unsigned int irq, void *dev_id)
        kfree(action);
 
        if (!sparc_irq[cpu_irq].action)
-               disable_irq(irq);
+               __disable_irq(irq);
 
 out_unlock:
        spin_unlock_irqrestore(&irq_action_lock, flags);
@@ -331,7 +332,7 @@ void handler_irq(int irq, struct pt_regs * regs)
        irq_enter();
        disable_pil_irq(irq);
 #ifdef CONFIG_SMP
-       /* Only rotate on lower priority IRQ's (scsi, ethernet, etc.). */
+       /* Only rotate on lower priority IRQs (scsi, ethernet, etc.). */
        if((sparc_cpu_model==sun4m) && (irq < 10))
                smp4m_irq_rotate(cpu);
 #endif
@@ -350,34 +351,14 @@ void handler_irq(int irq, struct pt_regs * regs)
        set_irq_regs(old_regs);
 }
 
-#ifdef CONFIG_BLK_DEV_FD
-extern void floppy_interrupt(int irq, void *dev_id);
-
-void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs)
-{
-       struct pt_regs *old_regs;
-       int cpu = smp_processor_id();
+#if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE)
 
-       old_regs = set_irq_regs(regs);
-       disable_pil_irq(irq);
-       irq_enter();
-       kstat_cpu(cpu).irqs[irq]++;
-       floppy_interrupt(irq, dev_id);
-       irq_exit();
-       enable_pil_irq(irq);
-       set_irq_regs(old_regs);
-       // XXX Eek, it's totally changed with preempt_count() and such
-       // if (softirq_pending(cpu))
-       //      do_softirq();
-}
-#endif
-
-/* Fast IRQ's on the Sparc can only have one routine attached to them,
+/* Fast IRQs on the Sparc can only have one routine attached to them,
  * thus no sharing possible.
  */
-int request_fast_irq(unsigned int irq,
-                    irq_handler_t handler,
-                    unsigned long irqflags, const char *devname)
+static int request_fast_irq(unsigned int irq,
+                           void (*handler)(void),
+                           unsigned long irqflags, const char *devname)
 {
        struct irqaction *action;
        unsigned long flags;
@@ -425,7 +406,7 @@ int request_fast_irq(unsigned int irq,
        }
        
        if (action == NULL)
-           action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
+           action = kmalloc(sizeof(struct irqaction),
                                                 GFP_ATOMIC);
        
        if (!action) { 
@@ -456,7 +437,6 @@ int request_fast_irq(unsigned int irq,
         */
        flush_cache_all();
 
-       action->handler = handler;
        action->flags = irqflags;
        cpus_clear(action->mask);
        action->name = devname;
@@ -465,7 +445,7 @@ int request_fast_irq(unsigned int irq,
 
        sparc_irq[cpu_irq].action = action;
 
-       enable_irq(irq);
+       __enable_irq(irq);
 
        ret = 0;
 out_unlock:
@@ -474,6 +454,61 @@ out:
        return ret;
 }
 
+/* These variables are used to access state from the assembler
+ * interrupt handler, floppy_hardint, so we cannot put these in
+ * the floppy driver image because that would not work in the
+ * modular case.
+ */
+volatile unsigned char *fdc_status;
+EXPORT_SYMBOL(fdc_status);
+
+char *pdma_vaddr;
+EXPORT_SYMBOL(pdma_vaddr);
+
+unsigned long pdma_size;
+EXPORT_SYMBOL(pdma_size);
+
+volatile int doing_pdma;
+EXPORT_SYMBOL(doing_pdma);
+
+char *pdma_base;
+EXPORT_SYMBOL(pdma_base);
+
+unsigned long pdma_areasize;
+EXPORT_SYMBOL(pdma_areasize);
+
+extern void floppy_hardint(void);
+
+static irqreturn_t (*floppy_irq_handler)(int irq, void *dev_id);
+
+void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+       struct pt_regs *old_regs;
+       int cpu = smp_processor_id();
+
+       old_regs = set_irq_regs(regs);
+       disable_pil_irq(irq);
+       irq_enter();
+       kstat_cpu(cpu).irqs[irq]++;
+       floppy_irq_handler(irq, dev_id);
+       irq_exit();
+       enable_pil_irq(irq);
+       set_irq_regs(old_regs);
+       // XXX Eek, it's totally changed with preempt_count() and such
+       // if (softirq_pending(cpu))
+       //      do_softirq();
+}
+
+int sparc_floppy_request_irq(int irq, unsigned long flags,
+                            irqreturn_t (*irq_handler)(int irq, void *))
+{
+       floppy_irq_handler = irq_handler;
+       return request_fast_irq(irq, floppy_hardint, flags, "floppy");
+}
+EXPORT_SYMBOL(sparc_floppy_request_irq);
+
+#endif
+
 int request_irq(unsigned int irq,
                irq_handler_t handler,
                unsigned long irqflags, const char * devname, void *dev_id)
@@ -528,7 +563,7 @@ int request_irq(unsigned int irq,
        }
        
        if (action == NULL)
-               action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
+               action = kmalloc(sizeof(struct irqaction),
                                                     GFP_ATOMIC);
        
        if (!action) { 
@@ -545,7 +580,7 @@ int request_irq(unsigned int irq,
 
        *actionp = action;
 
-       enable_irq(irq);
+       __enable_irq(irq);
 
        ret = 0;
 out_unlock:
@@ -556,6 +591,25 @@ out:
 
 EXPORT_SYMBOL(request_irq);
 
+void disable_irq_nosync(unsigned int irq)
+{
+       return __disable_irq(irq);
+}
+EXPORT_SYMBOL(disable_irq_nosync);
+
+void disable_irq(unsigned int irq)
+{
+       return __disable_irq(irq);
+}
+EXPORT_SYMBOL(disable_irq);
+
+void enable_irq(unsigned int irq)
+{
+       return __enable_irq(irq);
+}
+
+EXPORT_SYMBOL(enable_irq);
+
 /* We really don't need these at all on the Sparc.  We only have
  * stubs here because they are exported to modules.
  */
@@ -609,7 +663,7 @@ void __init init_IRQ(void)
                break;
 
        default:
-               prom_printf("Cannot initialize IRQ's on this Sun machine...");
+               prom_printf("Cannot initialize IRQs on this Sun machine...");
                break;
        }
        btfixup();