]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
dma: xilinx: Fix race conditions in the driver for cdma
authorKedareswara rao Appana <appana.durga.rao@xilinx.com>
Mon, 16 Oct 2017 08:52:39 +0000 (14:22 +0530)
committerMichal Simek <michal.simek@xilinx.com>
Tue, 17 Oct 2017 10:54:52 +0000 (12:54 +0200)
This patch fixes the below issues
--> when hardware is idle we need to toggle the SG bit
inorder to update new value to the current descriptor
register other wise undefined results will occur.
--> Halt bit is not valid for cdma case add checks
for the same.

Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
drivers/dma/xilinx/xilinx_dma.c

index 209fa97e6b260cb73b4dfcdecce8993839dad03f..54d009f98837fe062aeea2117091b6a95dbe1f88 100644 (file)
@@ -1179,6 +1179,12 @@ static void xilinx_cdma_start_transfer(struct xilinx_dma_chan *chan)
        }
 
        if (chan->has_sg) {
+               dma_ctrl_clr(chan, XILINX_DMA_REG_DMACR,
+                            XILINX_CDMA_CR_SGMODE);
+
+               dma_ctrl_set(chan, XILINX_DMA_REG_DMACR,
+                            XILINX_CDMA_CR_SGMODE);
+
                xilinx_write(chan, XILINX_DMA_REG_CURDESC,
                             head_desc->async_tx.phys);
 
@@ -2128,8 +2134,10 @@ static int xilinx_dma_terminate_all(struct dma_chan *dchan)
        if (chan->cyclic)
                xilinx_dma_chan_reset(chan);
 
-       /* Halt the DMA engine */
-       xilinx_dma_halt(chan);
+       if (!(chan->xdev->dma_config->dmatype == XDMA_TYPE_CDMA)) {
+               /* Halt the DMA engine */
+               xilinx_dma_halt(chan);
+       }
 
        /* Remove and free all of the descriptors in the lists */
        xilinx_dma_free_descriptors(chan);
@@ -2141,6 +2149,10 @@ static int xilinx_dma_terminate_all(struct dma_chan *dchan)
                chan->cyclic = false;
        }
 
+       if ((chan->xdev->dma_config->dmatype == XDMA_TYPE_CDMA) && chan->has_sg)
+               dma_ctrl_clr(chan, XILINX_DMA_REG_DMACR,
+                            XILINX_CDMA_CR_SGMODE);
+
        return 0;
 }