]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - include/asm-sparc64/floppy.h
Merge branch 'linus' into x86/gart
[linux-2.6-omap-h63xx.git] / include / asm-sparc64 / floppy.h
index 07ccd6f04b52e64cbec01e82ac8c239fc6ecc7fd..ca19f80a9b7d96bab4494525abb248cd88e3c7a1 100644 (file)
@@ -1,7 +1,6 @@
-/* $Id: floppy.h,v 1.32 2001/10/26 17:59:36 davem Exp $
- * asm-sparc64/floppy.h: Sparc specific parts of the Floppy driver.
+/* floppy.h: Sparc specific parts of the Floppy driver.
  *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996, 2007 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  *
  * Ultra/PCI support added: Sep 1997  Eddie C. Dost  (ecd@skynet.be)
@@ -11,6 +10,7 @@
 #define __ASM_SPARC64_FLOPPY_H
 
 #include <linux/init.h>
+#include <linux/pci.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -84,8 +84,6 @@ static struct sun_floppy_ops sun_fdops;
 #define fd_free_irq()             sun_fdops.fd_free_irq()
 #define fd_eject(drive)           sun_fdops.fd_eject(drive)
 
-static int FLOPPY_MOTOR_MASK = 0x10;
-
 /* Super paranoid... */
 #undef HAVE_DISABLE_HLT
 
@@ -208,7 +206,55 @@ static void sun_fd_enable_dma(void)
        pdma_areasize = pdma_size;
 }
 
-extern irqreturn_t sparc_floppy_irq(int, void *, struct pt_regs *);
+irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie)
+{
+       if (likely(doing_pdma)) {
+               void __iomem *stat = (void __iomem *) fdc_status;
+               unsigned char *vaddr = pdma_vaddr;
+               unsigned long size = pdma_size;
+               u8 val;
+
+               while (size) {
+                       val = readb(stat);
+                       if (unlikely(!(val & 0x80))) {
+                               pdma_vaddr = vaddr;
+                               pdma_size = size;
+                               return IRQ_HANDLED;
+                       }
+                       if (unlikely(!(val & 0x20))) {
+                               pdma_vaddr = vaddr;
+                               pdma_size = size;
+                               doing_pdma = 0;
+                               goto main_interrupt;
+                       }
+                       if (val & 0x40) {
+                               /* read */
+                               *vaddr++ = readb(stat + 1);
+                       } else {
+                               unsigned char data = *vaddr++;
+
+                               /* write */
+                               writeb(data, stat + 1);
+                       }
+                       size--;
+               }
+
+               pdma_vaddr = vaddr;
+               pdma_size = size;
+
+               /* Send Terminal Count pulse to floppy controller. */
+               val = readb(auxio_register);
+               val |= AUXIO_AUX1_FTCNT;
+               writeb(val, auxio_register);
+               val &= ~AUXIO_AUX1_FTCNT;
+               writeb(val, auxio_register);
+
+               doing_pdma = 0;
+       }
+
+main_interrupt:
+       return floppy_interrupt(irq, dev_cookie);
+}
 
 static int sun_fd_request_irq(void)
 {
@@ -219,7 +265,7 @@ static int sun_fd_request_irq(void)
                once = 1;
 
                error = request_irq(FLOPPY_IRQ, sparc_floppy_irq, 
-                                   SA_INTERRUPT, "floppy", NULL);
+                                   IRQF_DISABLED, "floppy", NULL);
 
                return ((error == 0) ? 0 : -1);
        }
@@ -247,7 +293,6 @@ static int sun_fd_eject(int drive)
 
 #ifdef CONFIG_PCI
 #include <asm/ebus.h>
-#include <asm/isa.h>
 #include <asm/ns87303.h>
 
 static struct ebus_dma_info sun_pci_fd_ebus_dma;
@@ -263,7 +308,7 @@ struct sun_pci_dma_op {
 static struct sun_pci_dma_op sun_pci_dma_current = { -1U, 0, 0, NULL};
 static struct sun_pci_dma_op sun_pci_dma_pending = { -1U, 0, 0, NULL};
 
-extern irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+extern irqreturn_t floppy_interrupt(int irq, void *dev_id);
 
 static unsigned char sun_pci_fd_inb(unsigned long port)
 {
@@ -398,7 +443,7 @@ static int sun_pci_fd_eject(int drive)
 
 void sun_pci_fd_dma_callback(struct ebus_dma_info *p, int event, void *cookie)
 {
-       floppy_interrupt(0, NULL, NULL);
+       floppy_interrupt(0, NULL);
 }
 
 /*
@@ -498,98 +543,20 @@ static int sun_pci_fd_test_drive(unsigned long port, int drive)
 #ifdef CONFIG_PCI
 static int __init ebus_fdthree_p(struct linux_ebus_device *edev)
 {
-       if (!strcmp(edev->prom_name, "fdthree"))
+       if (!strcmp(edev->prom_node->name, "fdthree"))
                return 1;
-       if (!strcmp(edev->prom_name, "floppy")) {
-               char compat[16];
-               prom_getstring(edev->prom_node,
-                              "compatible",
-                              compat, sizeof(compat));
-               compat[15] = '\0';
-               if (!strcmp(compat, "fdthree"))
+       if (!strcmp(edev->prom_node->name, "floppy")) {
+               const char *compat;
+
+               compat = of_get_property(edev->prom_node,
+                                        "compatible", NULL);
+               if (compat && !strcmp(compat, "fdthree"))
                        return 1;
        }
        return 0;
 }
 #endif
 
-#ifdef CONFIG_PCI
-#undef ISA_FLOPPY_WORKS
-
-#ifdef ISA_FLOPPY_WORKS
-static unsigned long __init isa_floppy_init(void)
-{
-       struct sparc_isa_bridge *isa_br;
-       struct sparc_isa_device *isa_dev = NULL;
-
-       for_each_isa(isa_br) {
-               for_each_isadev(isa_dev, isa_br) {
-                       if (!strcmp(isa_dev->prom_name, "dma")) {
-                               struct sparc_isa_device *child =
-                                       isa_dev->child;
-
-                               while (child) {
-                                       if (!strcmp(child->prom_name,
-                                                   "floppy")) {
-                                               isa_dev = child;
-                                               goto isa_done;
-                                       }
-                                       child = child->next;
-                               }
-                       }
-               }
-       }
-isa_done:
-       if (!isa_dev)
-               return 0;
-
-       /* We could use DMA on devices behind the ISA bridge, but...
-        *
-        * There is a slight problem.  Normally on x86 kit the x86 processor
-        * delays I/O port instructions when the ISA bus "dma in progress"
-        * signal is active.  Well, sparc64 systems do not monitor this
-        * signal thus we would need to block all I/O port accesses in software
-        * when a dma transfer is active for some device.
-        */
-
-       sun_fdc = (struct sun_flpy_controller *)isa_dev->resource.start;
-       FLOPPY_IRQ = isa_dev->irq;
-
-       sun_fdops.fd_inb = sun_pci_fd_inb;
-       sun_fdops.fd_outb = sun_pci_fd_outb;
-
-       can_use_virtual_dma = use_virtual_dma = 1;
-       sun_fdops.fd_enable_dma = sun_fd_enable_dma;
-       sun_fdops.fd_disable_dma = sun_fd_disable_dma;
-       sun_fdops.fd_set_dma_mode = sun_fd_set_dma_mode;
-       sun_fdops.fd_set_dma_addr = sun_fd_set_dma_addr;
-       sun_fdops.fd_set_dma_count = sun_fd_set_dma_count;
-       sun_fdops.get_dma_residue = sun_get_dma_residue;
-
-       sun_fdops.fd_request_irq = sun_fd_request_irq;
-       sun_fdops.fd_free_irq = sun_fd_free_irq;
-
-       /* Floppy eject is manual.   Actually, could determine this
-        * via presence of 'manual' property in OBP node.
-        */
-       sun_fdops.fd_eject = sun_pci_fd_eject;
-
-        fdc_status = (unsigned long) &sun_fdc->status_82077;
-       FLOPPY_MOTOR_MASK = 0xf0;
-
-       allowed_drive_mask = 0;
-       sun_floppy_types[0] = 0;
-       sun_floppy_types[1] = 4;
-
-       sun_pci_broken_drive = 1;
-       sun_fdops.fd_outb = sun_pci_fd_broken_outb;
-
-       return sun_floppy_types[0];
-}
-#endif /* ISA_FLOPPY_WORKS */
-
-#endif
-
 static unsigned long __init sun_floppy_init(void)
 {
        char state[128];
@@ -614,6 +581,7 @@ static unsigned long __init sun_floppy_init(void)
                struct linux_ebus_device *edev = NULL;
                unsigned long config = 0;
                void __iomem *auxio_reg;
+               const char *state_prop;
 
                for_each_ebus(ebus) {
                        for_each_ebusdev(edev, ebus) {
@@ -622,17 +590,11 @@ static unsigned long __init sun_floppy_init(void)
                        }
                }
        ebus_done:
-               if (!edev) {
-#ifdef ISA_FLOPPY_WORKS
-                       return isa_floppy_init();
-#else
+               if (!edev)
                        return 0;
-#endif
-               }
 
-               prom_getproperty(edev->prom_node, "status",
-                                state, sizeof(state));
-               if (!strncmp(state, "disabled", 8))
+               state_prop = of_get_property(edev->prom_node, "status", NULL);
+               if (state_prop && !strncmp(state_prop, "disabled", 8))
                        return 0;
                        
                FLOPPY_IRQ = edev->irqs[0];
@@ -682,7 +644,6 @@ static unsigned long __init sun_floppy_init(void)
                sun_fdops.fd_eject = sun_pci_fd_eject;
 
                fdc_status = (unsigned long) &sun_fdc->status_82077;
-               FLOPPY_MOTOR_MASK = 0xf0;
 
                /*
                 * XXX: Find out on which machines this is really needed.
@@ -703,7 +664,7 @@ static unsigned long __init sun_floppy_init(void)
                 */
                for_each_ebus(ebus) {
                        for_each_ebusdev(edev, ebus) {
-                               if (!strcmp(edev->prom_name, "ecpp")) {
+                               if (!strcmp(edev->prom_node->name, "ecpp")) {
                                        config = edev->resource[1].start;
                                        goto config_done;
                                }
@@ -807,4 +768,15 @@ static unsigned long __init sun_floppy_init(void)
 
 #define EXTRA_FLOPPY_PARAMS
 
+static DEFINE_SPINLOCK(dma_spin_lock);
+
+#define claim_dma_lock() \
+({     unsigned long flags; \
+       spin_lock_irqsave(&dma_spin_lock, flags); \
+       flags; \
+})
+
+#define release_dma_lock(__flags) \
+       spin_unlock_irqrestore(&dma_spin_lock, __flags);
+
 #endif /* !(__ASM_SPARC64_FLOPPY_H) */