]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/dma/edma.c
Merge branch 'next' of git://git.infradead.org/users/vkoul/slave-dma
[karo-tx-linux.git] / drivers / dma / edma.c
index f424298f1ac5094513f6ac9f3e3a64cbaa681ba6..cd7e3280fadd121e9dfbd13fef93212c4b217435 100644 (file)
@@ -69,9 +69,7 @@ struct edma_chan {
        int                             ch_num;
        bool                            alloced;
        int                             slot[EDMA_MAX_SLOTS];
-       dma_addr_t                      addr;
-       int                             addr_width;
-       int                             maxburst;
+       struct dma_slave_config         cfg;
 };
 
 struct edma_cc {
@@ -178,29 +176,14 @@ static int edma_terminate_all(struct edma_chan *echan)
        return 0;
 }
 
-
 static int edma_slave_config(struct edma_chan *echan,
-       struct dma_slave_config *config)
+       struct dma_slave_config *cfg)
 {
-       if ((config->src_addr_width > DMA_SLAVE_BUSWIDTH_4_BYTES) ||
-           (config->dst_addr_width > DMA_SLAVE_BUSWIDTH_4_BYTES))
+       if (cfg->src_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES ||
+           cfg->dst_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES)
                return -EINVAL;
 
-       if (config->direction == DMA_MEM_TO_DEV) {
-               if (config->dst_addr)
-                       echan->addr = config->dst_addr;
-               if (config->dst_addr_width)
-                       echan->addr_width = config->dst_addr_width;
-               if (config->dst_maxburst)
-                       echan->maxburst = config->dst_maxburst;
-       } else if (config->direction == DMA_DEV_TO_MEM) {
-               if (config->src_addr)
-                       echan->addr = config->src_addr;
-               if (config->src_addr_width)
-                       echan->addr_width = config->src_addr_width;
-               if (config->src_maxburst)
-                       echan->maxburst = config->src_maxburst;
-       }
+       memcpy(&echan->cfg, cfg, sizeof(echan->cfg));
 
        return 0;
 }
@@ -235,6 +218,9 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
        struct edma_chan *echan = to_edma_chan(chan);
        struct device *dev = chan->device->dev;
        struct edma_desc *edesc;
+       dma_addr_t dev_addr;
+       enum dma_slave_buswidth dev_width;
+       u32 burst;
        struct scatterlist *sg;
        int i;
        int acnt, bcnt, ccnt, src, dst, cidx;
@@ -243,7 +229,20 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
        if (unlikely(!echan || !sgl || !sg_len))
                return NULL;
 
-       if (echan->addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) {
+       if (direction == DMA_DEV_TO_MEM) {
+               dev_addr = echan->cfg.src_addr;
+               dev_width = echan->cfg.src_addr_width;
+               burst = echan->cfg.src_maxburst;
+       } else if (direction == DMA_MEM_TO_DEV) {
+               dev_addr = echan->cfg.dst_addr;
+               dev_width = echan->cfg.dst_addr_width;
+               burst = echan->cfg.dst_maxburst;
+       } else {
+               dev_err(dev, "%s: bad direction?\n", __func__);
+               return NULL;
+       }
+
+       if (dev_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) {
                dev_err(dev, "Undefined slave buswidth\n");
                return NULL;
        }
@@ -275,14 +274,14 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
                        }
                }
 
-               acnt = echan->addr_width;
+               acnt = dev_width;
 
                /*
                 * If the maxburst is equal to the fifo width, use
                 * A-synced transfers. This allows for large contiguous
                 * buffer transfers using only one PaRAM set.
                 */
-               if (echan->maxburst == 1) {
+               if (burst == 1) {
                        edesc->absync = false;
                        ccnt = sg_dma_len(sg) / acnt / (SZ_64K - 1);
                        bcnt = sg_dma_len(sg) / acnt - ccnt * (SZ_64K - 1);
@@ -302,7 +301,7 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
                 */
                } else {
                        edesc->absync = true;
-                       bcnt = echan->maxburst;
+                       bcnt = burst;
                        ccnt = sg_dma_len(sg) / (acnt * bcnt);
                        if (ccnt > (SZ_64K - 1)) {
                                dev_err(dev, "Exceeded max SG segment size\n");
@@ -313,13 +312,13 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
 
                if (direction == DMA_MEM_TO_DEV) {
                        src = sg_dma_address(sg);
-                       dst = echan->addr;
+                       dst = dev_addr;
                        src_bidx = acnt;
                        src_cidx = cidx;
                        dst_bidx = 0;
                        dst_cidx = 0;
                } else {
-                       src = echan->addr;
+                       src = dev_addr;
                        dst = sg_dma_address(sg);
                        src_bidx = 0;
                        src_cidx = 0;
@@ -621,13 +620,11 @@ static struct platform_device *pdev0, *pdev1;
 static const struct platform_device_info edma_dev_info0 = {
        .name = "edma-dma-engine",
        .id = 0,
-       .dma_mask = DMA_BIT_MASK(32),
 };
 
 static const struct platform_device_info edma_dev_info1 = {
        .name = "edma-dma-engine",
        .id = 1,
-       .dma_mask = DMA_BIT_MASK(32),
 };
 
 static int edma_init(void)
@@ -641,6 +638,8 @@ static int edma_init(void)
                        ret = PTR_ERR(pdev0);
                        goto out;
                }
+               pdev0->dev.dma_mask = &pdev0->dev.coherent_dma_mask;
+               pdev0->dev.coherent_dma_mask = DMA_BIT_MASK(32);
        }
 
        if (EDMA_CTLRS == 2) {
@@ -650,6 +649,8 @@ static int edma_init(void)
                        platform_device_unregister(pdev0);
                        ret = PTR_ERR(pdev1);
                }
+               pdev1->dev.dma_mask = &pdev1->dev.coherent_dma_mask;
+               pdev1->dev.coherent_dma_mask = DMA_BIT_MASK(32);
        }
 
 out: