Merge master.kernel.org:/pub/scm/linux/kernel/git/davej/agpgart
[linux-drm-fsl-dcu.git] / drivers / ata / sata_sx4.c
index ae7992de4b08ff44c0b668899ca3f5fce3f2aee2..0ebd77b080d68396b4bc37987b45037004374a8e 100644 (file)
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
-#include <linux/sched.h>
 #include <linux/device.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_cmnd.h>
 #include <linux/libata.h>
-#include <asm/io.h>
 #include "sata_promise.h"
 
 #define DRV_NAME       "sata_sx4"
@@ -50,6 +48,9 @@
 
 
 enum {
+       PDC_MMIO_BAR            = 3,
+       PDC_DIMM_BAR            = 4,
+
        PDC_PRD_TBL             = 0x44, /* Direct command DMA table addr */
 
        PDC_PKT_SUBMIT          = 0x40, /* Command packet pointer addr */
@@ -138,8 +139,6 @@ struct pdc_port_priv {
 };
 
 struct pdc_host_priv {
-       void                    __iomem *dimm_mmio;
-
        unsigned int            doing_hdma;
        unsigned int            hdma_prod;
        unsigned int            hdma_cons;
@@ -156,11 +155,9 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance);
 static void pdc_eng_timeout(struct ata_port *ap);
 static void pdc_20621_phy_reset (struct ata_port *ap);
 static int pdc_port_start(struct ata_port *ap);
-static void pdc_port_stop(struct ata_port *ap);
 static void pdc20621_qc_prep(struct ata_queued_cmd *qc);
 static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
 static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
-static void pdc20621_host_stop(struct ata_host *host);
 static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe);
 static int pdc20621_detect_dimm(struct ata_probe_ent *pe);
 static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe,
@@ -205,13 +202,13 @@ static const struct ata_port_operations pdc_20621_ops = {
        .phy_reset              = pdc_20621_phy_reset,
        .qc_prep                = pdc20621_qc_prep,
        .qc_issue               = pdc20621_qc_issue_prot,
-       .data_xfer              = ata_mmio_data_xfer,
+       .data_xfer              = ata_data_xfer,
        .eng_timeout            = pdc_eng_timeout,
        .irq_handler            = pdc20621_interrupt,
        .irq_clear              = pdc20621_irq_clear,
+       .irq_on                 = ata_irq_on,
+       .irq_ack                = ata_irq_ack,
        .port_start             = pdc_port_start,
-       .port_stop              = pdc_port_stop,
-       .host_stop              = pdc20621_host_stop,
 };
 
 static const struct ata_port_info pdc_port_info[] = {
@@ -243,18 +240,6 @@ static struct pci_driver pdc_sata_pci_driver = {
 };
 
 
-static void pdc20621_host_stop(struct ata_host *host)
-{
-       struct pci_dev *pdev = to_pci_dev(host->dev);
-       struct pdc_host_priv *hpriv = host->private_data;
-       void __iomem *dimm_mmio = hpriv->dimm_mmio;
-
-       pci_iounmap(pdev, dimm_mmio);
-       kfree(hpriv);
-
-       pci_iounmap(pdev, host->mmio_base);
-}
-
 static int pdc_port_start(struct ata_port *ap)
 {
        struct device *dev = ap->host->dev;
@@ -265,43 +250,19 @@ static int pdc_port_start(struct ata_port *ap)
        if (rc)
                return rc;
 
-       pp = kmalloc(sizeof(*pp), GFP_KERNEL);
-       if (!pp) {
-               rc = -ENOMEM;
-               goto err_out;
-       }
-       memset(pp, 0, sizeof(*pp));
+       pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
+       if (!pp)
+               return -ENOMEM;
 
-       pp->pkt = dma_alloc_coherent(dev, 128, &pp->pkt_dma, GFP_KERNEL);
-       if (!pp->pkt) {
-               rc = -ENOMEM;
-               goto err_out_kfree;
-       }
+       pp->pkt = dmam_alloc_coherent(dev, 128, &pp->pkt_dma, GFP_KERNEL);
+       if (!pp->pkt)
+               return -ENOMEM;
 
        ap->private_data = pp;
 
        return 0;
-
-err_out_kfree:
-       kfree(pp);
-err_out:
-       ata_port_stop(ap);
-       return rc;
-}
-
-
-static void pdc_port_stop(struct ata_port *ap)
-{
-       struct device *dev = ap->host->dev;
-       struct pdc_port_priv *pp = ap->private_data;
-
-       ap->private_data = NULL;
-       dma_free_coherent(dev, 128, pp->pkt, pp->pkt_dma);
-       kfree(pp);
-       ata_port_stop(ap);
 }
 
-
 static void pdc_20621_phy_reset (struct ata_port *ap)
 {
        VPRINTK("ENTER\n");
@@ -452,9 +413,8 @@ static void pdc20621_dma_prep(struct ata_queued_cmd *qc)
        struct scatterlist *sg;
        struct ata_port *ap = qc->ap;
        struct pdc_port_priv *pp = ap->private_data;
-       void __iomem *mmio = ap->host->mmio_base;
-       struct pdc_host_priv *hpriv = ap->host->private_data;
-       void __iomem *dimm_mmio = hpriv->dimm_mmio;
+       void __iomem *mmio = ap->host->iomap[PDC_MMIO_BAR];
+       void __iomem *dimm_mmio = ap->host->iomap[PDC_DIMM_BAR];
        unsigned int portno = ap->port_no;
        unsigned int i, idx, total_len = 0, sgt_len;
        u32 *buf = (u32 *) &pp->dimm_buf[PDC_DIMM_HEADER_SZ];
@@ -513,9 +473,8 @@ static void pdc20621_nodata_prep(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
        struct pdc_port_priv *pp = ap->private_data;
-       void __iomem *mmio = ap->host->mmio_base;
-       struct pdc_host_priv *hpriv = ap->host->private_data;
-       void __iomem *dimm_mmio = hpriv->dimm_mmio;
+       void __iomem *mmio = ap->host->iomap[PDC_MMIO_BAR];
+       void __iomem *dimm_mmio = ap->host->iomap[PDC_DIMM_BAR];
        unsigned int portno = ap->port_no;
        unsigned int i;
 
@@ -565,7 +524,7 @@ static void __pdc20621_push_hdma(struct ata_queued_cmd *qc,
 {
        struct ata_port *ap = qc->ap;
        struct ata_host *host = ap->host;
-       void __iomem *mmio = host->mmio_base;
+       void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
 
        /* hard-code chip #0 */
        mmio += PDC_CHIP0_OFS;
@@ -619,8 +578,7 @@ static void pdc20621_dump_hdma(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
        unsigned int port_no = ap->port_no;
-       struct pdc_host_priv *hpriv = ap->host->private_data;
-       void *dimm_mmio = hpriv->dimm_mmio;
+       void __iomem *dimm_mmio = ap->host->iomap[PDC_DIMM_BAR];
 
        dimm_mmio += (port_no * PDC_DIMM_WINDOW_STEP);
        dimm_mmio += PDC_DIMM_HOST_PKT;
@@ -639,7 +597,7 @@ static void pdc20621_packet_start(struct ata_queued_cmd *qc)
        struct ata_port *ap = qc->ap;
        struct ata_host *host = ap->host;
        unsigned int port_no = ap->port_no;
-       void __iomem *mmio = host->mmio_base;
+       void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
        unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
        u8 seq = (u8) (port_no + 1);
        unsigned int port_ofs;
@@ -668,8 +626,8 @@ static void pdc20621_packet_start(struct ata_queued_cmd *qc)
                readl(mmio + PDC_20621_SEQCTL + (seq * 4));     /* flush */
 
                writel(port_ofs + PDC_DIMM_ATA_PKT,
-                      (void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
-               readl((void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+                      ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+               readl(ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
                VPRINTK("submitted ofs 0x%x (%u), seq %u\n",
                        port_ofs + PDC_DIMM_ATA_PKT,
                        port_ofs + PDC_DIMM_ATA_PKT,
@@ -747,8 +705,8 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
                        writel(0x00000001, mmio + PDC_20621_SEQCTL + (seq * 4));
                        readl(mmio + PDC_20621_SEQCTL + (seq * 4));
                        writel(port_ofs + PDC_DIMM_ATA_PKT,
-                              (void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
-                       readl((void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+                              ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+                       readl(ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
                }
 
                /* step two - execute ATA command */
@@ -781,7 +739,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
 static void pdc20621_irq_clear(struct ata_port *ap)
 {
        struct ata_host *host = ap->host;
-       void __iomem *mmio = host->mmio_base;
+       void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
 
        mmio += PDC_CHIP0_OFS;
 
@@ -799,12 +757,12 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance)
 
        VPRINTK("ENTER\n");
 
-       if (!host || !host->mmio_base) {
+       if (!host || !host->iomap[PDC_MMIO_BAR]) {
                VPRINTK("QUICK EXIT\n");
                return IRQ_NONE;
        }
 
-       mmio_base = host->mmio_base;
+       mmio_base = host->iomap[PDC_MMIO_BAR];
 
        /* reading should also clear interrupts */
        mmio_base += PDC_CHIP0_OFS;
@@ -905,7 +863,7 @@ static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile
 }
 
 
-static void pdc_sata_setup_port(struct ata_ioports *port, unsigned long base)
+static void pdc_sata_setup_port(struct ata_ioports *port, void __iomem *base)
 {
        port->cmd_addr          = base;
        port->data_addr         = base;
@@ -931,9 +889,8 @@ static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, void *psource,
        u16 idx;
        u8 page_mask;
        long dist;
-       void __iomem *mmio = pe->mmio_base;
-       struct pdc_host_priv *hpriv = pe->private_data;
-       void __iomem *dimm_mmio = hpriv->dimm_mmio;
+       void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
+       void __iomem *dimm_mmio = pe->iomap[PDC_DIMM_BAR];
 
        /* hard-code chip #0 */
        mmio += PDC_CHIP0_OFS;
@@ -987,9 +944,8 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource,
        u16 idx;
        u8 page_mask;
        long dist;
-       void __iomem *mmio = pe->mmio_base;
-       struct pdc_host_priv *hpriv = pe->private_data;
-       void __iomem *dimm_mmio = hpriv->dimm_mmio;
+       void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
+       void __iomem *dimm_mmio = pe->iomap[PDC_DIMM_BAR];
 
        /* hard-code chip #0 */
        mmio += PDC_CHIP0_OFS;
@@ -1034,7 +990,7 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource,
 static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, u32 device,
                                      u32 subaddr, u32 *pdata)
 {
-       void __iomem *mmio = pe->mmio_base;
+       void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
        u32 i2creg  = 0;
        u32 status;
        u32 count =0;
@@ -1093,7 +1049,7 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe)
        u32 data = 0;
        int size, i;
        u8 bdimmsize;
-       void __iomem *mmio = pe->mmio_base;
+       void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
        static const struct {
                unsigned int reg;
                unsigned int ofs;
@@ -1155,8 +1111,8 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe)
 static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe)
 {
        u32 data, spd0;
-       int error, i;
-       void __iomem *mmio = pe->mmio_base;
+       int error, i;
+       void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
 
        /* hard-code chip #0 */
        mmio += PDC_CHIP0_OFS;
@@ -1210,7 +1166,7 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
        u32 ticks=0;
        u32 clock=0;
        u32 fparam=0;
-       void __iomem *mmio = pe->mmio_base;
+       void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
 
        /* hard-code chip #0 */
        mmio += PDC_CHIP0_OFS;
@@ -1334,7 +1290,7 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
 static void pdc_20621_init(struct ata_probe_ent *pe)
 {
        u32 tmp;
-       void __iomem *mmio = pe->mmio_base;
+       void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
 
        /* hard-code chip #0 */
        mmio += PDC_CHIP0_OFS;
@@ -1365,67 +1321,43 @@ static void pdc_20621_init(struct ata_probe_ent *pe)
 static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       struct ata_probe_ent *probe_ent = NULL;
-       unsigned long base;
-       void __iomem *mmio_base;
-       void __iomem *dimm_mmio = NULL;
-       struct pdc_host_priv *hpriv = NULL;
+       struct ata_probe_ent *probe_ent;
+       void __iomem *base;
+       struct pdc_host_priv *hpriv;
        unsigned int board_idx = (unsigned int) ent->driver_data;
-       int pci_dev_busy = 0;
        int rc;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
-       rc = pci_enable_device(pdev);
+       rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
 
-       rc = pci_request_regions(pdev, DRV_NAME);
-       if (rc) {
-               pci_dev_busy = 1;
-               goto err_out;
-       }
+       rc = pcim_iomap_regions(pdev, (1 << PDC_MMIO_BAR) | (1 << PDC_DIMM_BAR),
+                               DRV_NAME);
+       if (rc == -EBUSY)
+               pcim_pin_device(pdev);
+       if (rc)
+               return rc;
 
        rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
        if (rc)
-               goto err_out_regions;
+               return rc;
        rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
        if (rc)
-               goto err_out_regions;
+               return rc;
 
-       probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
-       if (probe_ent == NULL) {
-               rc = -ENOMEM;
-               goto err_out_regions;
-       }
+       probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
+       if (probe_ent == NULL)
+               return -ENOMEM;
 
-       memset(probe_ent, 0, sizeof(*probe_ent));
        probe_ent->dev = pci_dev_to_dev(pdev);
        INIT_LIST_HEAD(&probe_ent->node);
 
-       mmio_base = pci_iomap(pdev, 3, 0);
-       if (mmio_base == NULL) {
-               rc = -ENOMEM;
-               goto err_out_free_ent;
-       }
-       base = (unsigned long) mmio_base;
-
-       hpriv = kmalloc(sizeof(*hpriv), GFP_KERNEL);
-       if (!hpriv) {
-               rc = -ENOMEM;
-               goto err_out_iounmap;
-       }
-       memset(hpriv, 0, sizeof(*hpriv));
-
-       dimm_mmio = pci_iomap(pdev, 4, 0);
-       if (!dimm_mmio) {
-               kfree(hpriv);
-               rc = -ENOMEM;
-               goto err_out_iounmap;
-       }
-
-       hpriv->dimm_mmio = dimm_mmio;
+       hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
+       if (!hpriv)
+               return -ENOMEM;
 
        probe_ent->sht          = pdc_port_info[board_idx].sht;
        probe_ent->port_flags   = pdc_port_info[board_idx].flags;
@@ -1436,10 +1368,10 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
 
                probe_ent->irq = pdev->irq;
                probe_ent->irq_flags = IRQF_SHARED;
-       probe_ent->mmio_base = mmio_base;
+       probe_ent->iomap = pcim_iomap_table(pdev);
 
        probe_ent->private_data = hpriv;
-       base += PDC_CHIP0_OFS;
+       base = probe_ent->iomap[PDC_MMIO_BAR] + PDC_CHIP0_OFS;
 
        probe_ent->n_ports = 4;
        pdc_sata_setup_port(&probe_ent->port[0], base + 0x200);
@@ -1451,31 +1383,15 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
 
        /* initialize adapter */
        /* initialize local dimm */
-       if (pdc20621_dimm_init(probe_ent)) {
-               rc = -ENOMEM;
-               goto err_out_iounmap_dimm;
-       }
+       if (pdc20621_dimm_init(probe_ent))
+               return -ENOMEM;
        pdc_20621_init(probe_ent);
 
-       /* FIXME: check ata_device_add return value */
-       ata_device_add(probe_ent);
-       kfree(probe_ent);
+       if (!ata_device_add(probe_ent))
+               return -ENODEV;
 
+       devm_kfree(&pdev->dev, probe_ent);
        return 0;
-
-err_out_iounmap_dimm:          /* only get to this label if 20621 */
-       kfree(hpriv);
-       pci_iounmap(pdev, dimm_mmio);
-err_out_iounmap:
-       pci_iounmap(pdev, mmio_base);
-err_out_free_ent:
-       kfree(probe_ent);
-err_out_regions:
-       pci_release_regions(pdev);
-err_out:
-       if (!pci_dev_busy)
-               pci_disable_device(pdev);
-       return rc;
 }