Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Generic PXA PATA driver
0004  *
0005  * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com>
0006  */
0007 
0008 #include <linux/kernel.h>
0009 #include <linux/module.h>
0010 #include <linux/blkdev.h>
0011 #include <linux/ata.h>
0012 #include <linux/libata.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/dmaengine.h>
0015 #include <linux/slab.h>
0016 #include <linux/completion.h>
0017 
0018 #include <scsi/scsi_host.h>
0019 
0020 #include <linux/platform_data/ata-pxa.h>
0021 
0022 #define DRV_NAME    "pata_pxa"
0023 #define DRV_VERSION "0.1"
0024 
0025 struct pata_pxa_data {
0026     struct dma_chan     *dma_chan;
0027     dma_cookie_t        dma_cookie;
0028     struct completion   dma_done;
0029 };
0030 
0031 /*
0032  * DMA interrupt handler.
0033  */
0034 static void pxa_ata_dma_irq(void *d)
0035 {
0036     struct pata_pxa_data *pd = d;
0037     enum dma_status status;
0038 
0039     status = dmaengine_tx_status(pd->dma_chan, pd->dma_cookie, NULL);
0040     if (status == DMA_ERROR || status == DMA_COMPLETE)
0041         complete(&pd->dma_done);
0042 }
0043 
0044 /*
0045  * Prepare taskfile for submission.
0046  */
0047 static enum ata_completion_errors pxa_qc_prep(struct ata_queued_cmd *qc)
0048 {
0049     struct pata_pxa_data *pd = qc->ap->private_data;
0050     struct dma_async_tx_descriptor *tx;
0051     enum dma_transfer_direction dir;
0052 
0053     if (!(qc->flags & ATA_QCFLAG_DMAMAP))
0054         return AC_ERR_OK;
0055 
0056     dir = (qc->dma_dir == DMA_TO_DEVICE ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM);
0057     tx = dmaengine_prep_slave_sg(pd->dma_chan, qc->sg, qc->n_elem, dir,
0058                      DMA_PREP_INTERRUPT);
0059     if (!tx) {
0060         ata_dev_err(qc->dev, "prep_slave_sg() failed\n");
0061         return AC_ERR_OK;
0062     }
0063     tx->callback = pxa_ata_dma_irq;
0064     tx->callback_param = pd;
0065     pd->dma_cookie = dmaengine_submit(tx);
0066 
0067     return AC_ERR_OK;
0068 }
0069 
0070 /*
0071  * Configure the DMA controller, load the DMA descriptors, but don't start the
0072  * DMA controller yet. Only issue the ATA command.
0073  */
0074 static void pxa_bmdma_setup(struct ata_queued_cmd *qc)
0075 {
0076     qc->ap->ops->sff_exec_command(qc->ap, &qc->tf);
0077 }
0078 
0079 /*
0080  * Execute the DMA transfer.
0081  */
0082 static void pxa_bmdma_start(struct ata_queued_cmd *qc)
0083 {
0084     struct pata_pxa_data *pd = qc->ap->private_data;
0085     init_completion(&pd->dma_done);
0086     dma_async_issue_pending(pd->dma_chan);
0087 }
0088 
0089 /*
0090  * Wait until the DMA transfer completes, then stop the DMA controller.
0091  */
0092 static void pxa_bmdma_stop(struct ata_queued_cmd *qc)
0093 {
0094     struct pata_pxa_data *pd = qc->ap->private_data;
0095     enum dma_status status;
0096 
0097     status = dmaengine_tx_status(pd->dma_chan, pd->dma_cookie, NULL);
0098     if (status != DMA_ERROR && status != DMA_COMPLETE &&
0099         wait_for_completion_timeout(&pd->dma_done, HZ))
0100         ata_dev_err(qc->dev, "Timeout waiting for DMA completion!");
0101 
0102     dmaengine_terminate_all(pd->dma_chan);
0103 }
0104 
0105 /*
0106  * Read DMA status. The bmdma_stop() will take care of properly finishing the
0107  * DMA transfer so we always have DMA-complete interrupt here.
0108  */
0109 static unsigned char pxa_bmdma_status(struct ata_port *ap)
0110 {
0111     struct pata_pxa_data *pd = ap->private_data;
0112     unsigned char ret = ATA_DMA_INTR;
0113     struct dma_tx_state state;
0114     enum dma_status status;
0115 
0116     status = dmaengine_tx_status(pd->dma_chan, pd->dma_cookie, &state);
0117     if (status != DMA_COMPLETE)
0118         ret |= ATA_DMA_ERR;
0119 
0120     return ret;
0121 }
0122 
0123 /*
0124  * No IRQ register present so we do nothing.
0125  */
0126 static void pxa_irq_clear(struct ata_port *ap)
0127 {
0128 }
0129 
0130 /*
0131  * Check for ATAPI DMA. ATAPI DMA is unsupported by this driver. It's still
0132  * unclear why ATAPI has DMA issues.
0133  */
0134 static int pxa_check_atapi_dma(struct ata_queued_cmd *qc)
0135 {
0136     return -EOPNOTSUPP;
0137 }
0138 
0139 static struct scsi_host_template pxa_ata_sht = {
0140     ATA_BMDMA_SHT(DRV_NAME),
0141 };
0142 
0143 static struct ata_port_operations pxa_ata_port_ops = {
0144     .inherits       = &ata_bmdma_port_ops,
0145     .cable_detect       = ata_cable_40wire,
0146 
0147     .bmdma_setup        = pxa_bmdma_setup,
0148     .bmdma_start        = pxa_bmdma_start,
0149     .bmdma_stop     = pxa_bmdma_stop,
0150     .bmdma_status       = pxa_bmdma_status,
0151 
0152     .check_atapi_dma    = pxa_check_atapi_dma,
0153 
0154     .sff_irq_clear      = pxa_irq_clear,
0155 
0156     .qc_prep        = pxa_qc_prep,
0157 };
0158 
0159 static int pxa_ata_probe(struct platform_device *pdev)
0160 {
0161     struct ata_host *host;
0162     struct ata_port *ap;
0163     struct pata_pxa_data *data;
0164     struct resource *cmd_res;
0165     struct resource *ctl_res;
0166     struct resource *dma_res;
0167     struct pata_pxa_pdata *pdata = dev_get_platdata(&pdev->dev);
0168     struct dma_slave_config config;
0169     int ret = 0;
0170     int irq;
0171 
0172     /*
0173      * Resource validation, three resources are needed:
0174      *  - CMD port base address
0175      *  - CTL port base address
0176      *  - DMA port base address
0177      *  - IRQ pin
0178      */
0179     if (pdev->num_resources != 4) {
0180         dev_err(&pdev->dev, "invalid number of resources\n");
0181         return -EINVAL;
0182     }
0183 
0184     /*
0185      * CMD port base address
0186      */
0187     cmd_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0188     if (unlikely(cmd_res == NULL))
0189         return -EINVAL;
0190 
0191     /*
0192      * CTL port base address
0193      */
0194     ctl_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
0195     if (unlikely(ctl_res == NULL))
0196         return -EINVAL;
0197 
0198     /*
0199      * DMA port base address
0200      */
0201     dma_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
0202     if (unlikely(dma_res == NULL))
0203         return -EINVAL;
0204 
0205     /*
0206      * IRQ pin
0207      */
0208     irq = platform_get_irq(pdev, 0);
0209     if (irq < 0)
0210         return irq;
0211 
0212     /*
0213      * Allocate the host
0214      */
0215     host = ata_host_alloc(&pdev->dev, 1);
0216     if (!host)
0217         return -ENOMEM;
0218 
0219     ap      = host->ports[0];
0220     ap->ops     = &pxa_ata_port_ops;
0221     ap->pio_mask    = ATA_PIO4;
0222     ap->mwdma_mask  = ATA_MWDMA2;
0223 
0224     ap->ioaddr.cmd_addr = devm_ioremap(&pdev->dev, cmd_res->start,
0225                         resource_size(cmd_res));
0226     ap->ioaddr.ctl_addr = devm_ioremap(&pdev->dev, ctl_res->start,
0227                         resource_size(ctl_res));
0228     ap->ioaddr.bmdma_addr   = devm_ioremap(&pdev->dev, dma_res->start,
0229                         resource_size(dma_res));
0230 
0231     /*
0232      * Adjust register offsets
0233      */
0234     ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr;
0235     ap->ioaddr.data_addr    = ap->ioaddr.cmd_addr +
0236                     (ATA_REG_DATA << pdata->reg_shift);
0237     ap->ioaddr.error_addr   = ap->ioaddr.cmd_addr +
0238                     (ATA_REG_ERR << pdata->reg_shift);
0239     ap->ioaddr.feature_addr = ap->ioaddr.cmd_addr +
0240                     (ATA_REG_FEATURE << pdata->reg_shift);
0241     ap->ioaddr.nsect_addr   = ap->ioaddr.cmd_addr +
0242                     (ATA_REG_NSECT << pdata->reg_shift);
0243     ap->ioaddr.lbal_addr    = ap->ioaddr.cmd_addr +
0244                     (ATA_REG_LBAL << pdata->reg_shift);
0245     ap->ioaddr.lbam_addr    = ap->ioaddr.cmd_addr +
0246                     (ATA_REG_LBAM << pdata->reg_shift);
0247     ap->ioaddr.lbah_addr    = ap->ioaddr.cmd_addr +
0248                     (ATA_REG_LBAH << pdata->reg_shift);
0249     ap->ioaddr.device_addr  = ap->ioaddr.cmd_addr +
0250                     (ATA_REG_DEVICE << pdata->reg_shift);
0251     ap->ioaddr.status_addr  = ap->ioaddr.cmd_addr +
0252                     (ATA_REG_STATUS << pdata->reg_shift);
0253     ap->ioaddr.command_addr = ap->ioaddr.cmd_addr +
0254                     (ATA_REG_CMD << pdata->reg_shift);
0255 
0256     /*
0257      * Allocate and load driver's internal data structure
0258      */
0259     data = devm_kzalloc(&pdev->dev, sizeof(struct pata_pxa_data),
0260                                 GFP_KERNEL);
0261     if (!data)
0262         return -ENOMEM;
0263 
0264     ap->private_data = data;
0265 
0266     memset(&config, 0, sizeof(config));
0267     config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
0268     config.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
0269     config.src_addr = dma_res->start;
0270     config.dst_addr = dma_res->start;
0271     config.src_maxburst = 32;
0272     config.dst_maxburst = 32;
0273 
0274     /*
0275      * Request the DMA channel
0276      */
0277     data->dma_chan =
0278         dma_request_slave_channel(&pdev->dev, "data");
0279     if (!data->dma_chan)
0280         return -EBUSY;
0281     ret = dmaengine_slave_config(data->dma_chan, &config);
0282     if (ret < 0) {
0283         dev_err(&pdev->dev, "dma configuration failed: %d\n", ret);
0284         return ret;
0285     }
0286 
0287     /*
0288      * Activate the ATA host
0289      */
0290     ret = ata_host_activate(host, irq, ata_sff_interrupt,
0291                 pdata->irq_flags, &pxa_ata_sht);
0292     if (ret)
0293         dma_release_channel(data->dma_chan);
0294 
0295     return ret;
0296 }
0297 
0298 static int pxa_ata_remove(struct platform_device *pdev)
0299 {
0300     struct ata_host *host = platform_get_drvdata(pdev);
0301     struct pata_pxa_data *data = host->ports[0]->private_data;
0302 
0303     dma_release_channel(data->dma_chan);
0304 
0305     ata_host_detach(host);
0306 
0307     return 0;
0308 }
0309 
0310 static struct platform_driver pxa_ata_driver = {
0311     .probe      = pxa_ata_probe,
0312     .remove     = pxa_ata_remove,
0313     .driver     = {
0314         .name       = DRV_NAME,
0315     },
0316 };
0317 
0318 module_platform_driver(pxa_ata_driver);
0319 
0320 MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
0321 MODULE_DESCRIPTION("DMA-capable driver for PATA on PXA CPU");
0322 MODULE_LICENSE("GPL");
0323 MODULE_VERSION(DRV_VERSION);
0324 MODULE_ALIAS("platform:" DRV_NAME);