spi: rspi: Extract rspi_request_dma_chan()
authorGeert Uytterhoeven <geert+renesas@glider.be>
Mon, 2 Jun 2014 13:38:09 +0000 (15:38 +0200)
committerMark Brown <broonie@linaro.org>
Mon, 2 Jun 2014 14:49:33 +0000 (15:49 +0100)
Setup of the receive and transmit DMA channels is very similar, so let's
consolidate.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Mark Brown <broonie@linaro.org>
drivers/spi/spi-rspi.c

index 94a99ec7d989d682e3fe2424184f779aa97c8842..0a7a2d618f0f7860f8875375ae58b515b0a4ff44 100644 (file)
@@ -942,52 +942,73 @@ static irqreturn_t rspi_irq_tx(int irq, void *_sr)
        return 0;
 }
 
-static int rspi_request_dma(struct rspi_data *rspi,
-                                     struct platform_device *pdev)
+static struct dma_chan *rspi_request_dma_chan(struct device *dev,
+                                             enum dma_transfer_direction dir,
+                                             unsigned int id,
+                                             dma_addr_t port_addr)
 {
-       const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev);
-       struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        dma_cap_mask_t mask;
+       struct dma_chan *chan;
        struct dma_slave_config cfg;
        int ret;
 
+       dma_cap_zero(mask);
+       dma_cap_set(DMA_SLAVE, mask);
+
+       chan = dma_request_channel(mask, shdma_chan_filter,
+                                  (void *)(unsigned long)id);
+       if (!chan) {
+               dev_warn(dev, "dma_request_channel failed\n");
+               return NULL;
+       }
+
+       memset(&cfg, 0, sizeof(cfg));
+       cfg.slave_id = id;
+       cfg.direction = dir;
+       if (dir == DMA_MEM_TO_DEV)
+               cfg.dst_addr = port_addr;
+       else
+               cfg.src_addr = port_addr;
+
+       ret = dmaengine_slave_config(chan, &cfg);
+       if (ret) {
+               dev_warn(dev, "dmaengine_slave_config failed %d\n", ret);
+               dma_release_channel(chan);
+               return NULL;
+       }
+
+       return chan;
+}
+
+static int rspi_request_dma(struct rspi_data *rspi,
+                           struct platform_device *pdev)
+{
+       const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev);
+       struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
        if (!res || !rspi_pd)
                return 0;       /* The driver assumes no error. */
 
        /* If the module receives data by DMAC, it also needs TX DMAC */
        if (rspi_pd->dma_rx_id && rspi_pd->dma_tx_id) {
-               dma_cap_zero(mask);
-               dma_cap_set(DMA_SLAVE, mask);
-               rspi->chan_rx = dma_request_channel(mask, shdma_chan_filter,
-                                                   (void *)rspi_pd->dma_rx_id);
-               if (rspi->chan_rx) {
-                       cfg.slave_id = rspi_pd->dma_rx_id;
-                       cfg.direction = DMA_DEV_TO_MEM;
-                       cfg.dst_addr = 0;
-                       cfg.src_addr = res->start + RSPI_SPDR;
-                       ret = dmaengine_slave_config(rspi->chan_rx, &cfg);
-                       if (!ret)
-                               dev_info(&pdev->dev, "Use DMA when rx.\n");
-                       else
-                               return ret;
-               }
+               rspi->chan_rx = rspi_request_dma_chan(&pdev->dev,
+                                                     DMA_DEV_TO_MEM,
+                                                     rspi_pd->dma_rx_id,
+                                                     res->start + RSPI_SPDR);
+               if (!rspi->chan_rx)
+                       return -ENODEV;
+
+               dev_info(&pdev->dev, "Use DMA when rx.\n");
        }
        if (rspi_pd->dma_tx_id) {
-               dma_cap_zero(mask);
-               dma_cap_set(DMA_SLAVE, mask);
-               rspi->chan_tx = dma_request_channel(mask, shdma_chan_filter,
-                                                   (void *)rspi_pd->dma_tx_id);
-               if (rspi->chan_tx) {
-                       cfg.slave_id = rspi_pd->dma_tx_id;
-                       cfg.direction = DMA_MEM_TO_DEV;
-                       cfg.dst_addr = res->start + RSPI_SPDR;
-                       cfg.src_addr = 0;
-                       ret = dmaengine_slave_config(rspi->chan_tx, &cfg);
-                       if (!ret)
-                               dev_info(&pdev->dev, "Use DMA when tx\n");
-                       else
-                               return ret;
-               }
+               rspi->chan_tx = rspi_request_dma_chan(&pdev->dev,
+                                                     DMA_MEM_TO_DEV,
+                                                     rspi_pd->dma_tx_id,
+                                                     res->start + RSPI_SPDR);
+               if (!rspi->chan_tx)
+                       return -ENODEV;
+
+               dev_info(&pdev->dev, "Use DMA when tx\n");
        }
 
        return 0;