]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ide/pci/ns87415.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6
[linux-2.6-omap-h63xx.git] / drivers / ide / pci / ns87415.c
index b9bb8428b35e71d99210479ad587db8b64980ebe..53bd645736d965b73eeee8f8ffaeacc12a193cce 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
-#include <linux/hdreg.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/ide.h>
@@ -19,6 +18,8 @@
 
 #include <asm/io.h>
 
+#define DRV_NAME "ns87415"
+
 #ifdef CONFIG_SUPERIO
 /* SUPERIO 87560 is a PoS chip that NatSem denies exists.
  * Unfortunately, it's built-in on all Astro-based PA-RISC workstations
  */
 #include <asm/superio.h>
 
-static unsigned long superio_ide_status[2];
-static unsigned long superio_ide_select[2];
-static unsigned long superio_ide_dma_status[2];
-
 #define SUPERIO_IDE_MAX_RETRIES 25
 
 /* Because of a defect in Super I/O, all reads of the PCI DMA status 
@@ -40,27 +37,18 @@ static unsigned long superio_ide_dma_status[2];
  */
 static u8 superio_ide_inb (unsigned long port)
 {
-       if (port == superio_ide_status[0] ||
-           port == superio_ide_status[1] ||
-           port == superio_ide_select[0] ||
-           port == superio_ide_select[1] ||
-           port == superio_ide_dma_status[0] ||
-           port == superio_ide_dma_status[1]) {
-               u8 tmp;
-               int retries = SUPERIO_IDE_MAX_RETRIES;
+       u8 tmp;
+       int retries = SUPERIO_IDE_MAX_RETRIES;
 
-               /* printk(" [ reading port 0x%x with retry ] ", port); */
-
-               do {
-                       tmp = inb(port);
-                       if (tmp == 0)
-                               udelay(50);
-               } while (tmp == 0 && retries-- > 0);
+       /* printk(" [ reading port 0x%x with retry ] ", port); */
 
-               return tmp;
-       }
+       do {
+               tmp = inb(port);
+               if (tmp == 0)
+                       udelay(50);
+       } while (tmp == 0 && retries-- > 0);
 
-       return inb(port);
+       return tmp;
 }
 
 static u8 superio_read_status(ide_hwif_t *hwif)
@@ -117,39 +105,32 @@ static void superio_tf_read(ide_drive_t *drive, ide_task_t *task)
        }
 }
 
-static void __devinit superio_ide_init_iops (struct hwif_s *hwif)
-{
-       struct pci_dev *pdev = to_pci_dev(hwif->dev);
-       u32 base, dmabase;
-       u8 port = hwif->channel, tmp;
-
-       base = pci_resource_start(pdev, port * 2) & ~3;
-       dmabase = pci_resource_start(pdev, 4) & ~3;
-
-       superio_ide_status[port] = base + 7;
-       superio_ide_select[port] = base + 6;
-       superio_ide_dma_status[port] = dmabase + (!port ? 2 : 0xa);
-
-       /* Clear error/interrupt, enable dma */
-       tmp = superio_ide_inb(superio_ide_dma_status[port]);
-       outb(tmp | 0x66, superio_ide_dma_status[port]);
+static const struct ide_tp_ops superio_tp_ops = {
+       .exec_command           = ide_exec_command,
+       .read_status            = superio_read_status,
+       .read_altstatus         = ide_read_altstatus,
+       .read_sff_dma_status    = superio_read_sff_dma_status,
 
-       hwif->read_status         = superio_read_status;
-       hwif->read_sff_dma_status = superio_read_sff_dma_status;
+       .set_irq                = ide_set_irq,
 
-       hwif->tf_read = superio_tf_read;
+       .tf_load                = ide_tf_load,
+       .tf_read                = superio_tf_read,
 
-       /* We need to override inb to workaround a SuperIO errata */
-       hwif->INB = superio_ide_inb;
-}
+       .input_data             = ide_input_data,
+       .output_data            = ide_output_data,
+};
 
-static void __devinit init_iops_ns87415(ide_hwif_t *hwif)
+static void __devinit superio_init_iops(struct hwif_s *hwif)
 {
-       struct pci_dev *dev = to_pci_dev(hwif->dev);
+       struct pci_dev *pdev = to_pci_dev(hwif->dev);
+       u32 dma_stat;
+       u8 port = hwif->channel, tmp;
 
-       if (PCI_SLOT(dev->devfn) == 0xE)
-               /* Built-in - assume it's under superio. */
-               superio_ide_init_iops(hwif);
+       dma_stat = (pci_resource_start(pdev, 4) & ~3) + (!port ? 2 : 0xa);
+
+       /* Clear error/interrupt, enable dma */
+       tmp = superio_ide_inb(dma_stat);
+       outb(tmp | 0x66, dma_stat);
 }
 #endif
 
@@ -215,7 +196,7 @@ static int ns87415_dma_end(ide_drive_t *drive)
        u8 dma_stat = 0, dma_cmd = 0;
 
        drive->waiting_for_dma = 0;
-       dma_stat = hwif->read_sff_dma_status(hwif);
+       dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
        /* get DMA command mode */
        dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
        /* stop DMA */
@@ -291,10 +272,10 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
                outb(8, hwif->io_ports.ctl_addr);
                do {
                        udelay(50);
-                       stat = hwif->read_status(hwif);
-                       if (stat == 0xff)
-                               break;
-               } while ((stat & BUSY_STAT) && --timeout);
+                       stat = hwif->tp_ops->read_status(hwif);
+                       if (stat == 0xff)
+                               break;
+               } while ((stat & ATA_BUSY) && --timeout);
 #endif
        }
 
@@ -325,10 +306,7 @@ static const struct ide_dma_ops ns87415_dma_ops = {
 };
 
 static const struct ide_port_info ns87415_chipset __devinitdata = {
-       .name           = "NS87415",
-#ifdef CONFIG_SUPERIO
-       .init_iops      = init_iops_ns87415,
-#endif
+       .name           = DRV_NAME,
        .init_hwif      = init_hwif_ns87415,
        .port_ops       = &ns87415_port_ops,
        .dma_ops        = &ns87415_dma_ops,
@@ -338,7 +316,16 @@ static const struct ide_port_info ns87415_chipset __devinitdata = {
 
 static int __devinit ns87415_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       return ide_setup_pci_device(dev, &ns87415_chipset);
+       struct ide_port_info d = ns87415_chipset;
+
+#ifdef CONFIG_SUPERIO
+       if (PCI_SLOT(dev->devfn) == 0xE) {
+               /* Built-in - assume it's under superio. */
+               d.init_iops = superio_init_iops;
+               d.tp_ops = &superio_tp_ops;
+       }
+#endif
+       return ide_pci_init_one(dev, &d, NULL);
 }
 
 static const struct pci_device_id ns87415_pci_tbl[] = {
@@ -351,6 +338,9 @@ static struct pci_driver driver = {
        .name           = "NS87415_IDE",
        .id_table       = ns87415_pci_tbl,
        .probe          = ns87415_init_one,
+       .remove         = ide_pci_remove,
+       .suspend        = ide_pci_suspend,
+       .resume         = ide_pci_resume,
 };
 
 static int __init ns87415_ide_init(void)
@@ -358,7 +348,13 @@ static int __init ns87415_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
+static void __exit ns87415_ide_exit(void)
+{
+       pci_unregister_driver(&driver);
+}
+
 module_init(ns87415_ide_init);
+module_exit(ns87415_ide_exit);
 
 MODULE_AUTHOR("Mark Lord, Eddie Dost, Andre Hedrick");
 MODULE_DESCRIPTION("PCI driver module for NS87415 IDE");