dmaengine: xdmac: Add function to align width
authorMaxime Ripard <maxime.ripard@free-electrons.com>
Thu, 7 May 2015 15:38:09 +0000 (17:38 +0200)
committerVinod Koul <vinod.koul@intel.com>
Mon, 18 May 2015 05:29:34 +0000 (10:59 +0530)
The code has some logic to compute the burst width according to the alignment
of the address we're using.

Move that in a function of its own to reduce code duplication.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Acked-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
drivers/dma/at_xdmac.c

index 2d039512ecb3c483d933fab62b322c136e45194d..cbeadeeed9c08e268d6331c24e0551cbfb9b6a0f 100644 (file)
@@ -749,6 +749,35 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr,
        return &first->tx_dma_desc;
 }
 
+static inline u32 at_xdmac_align_width(struct dma_chan *chan, dma_addr_t addr)
+{
+       u32 width;
+
+       /*
+        * Check address alignment to select the greater data width we
+        * can use.
+        *
+        * Some XDMAC implementations don't provide dword transfer, in
+        * this case selecting dword has the same behavior as
+        * selecting word transfers.
+        */
+       if (!(addr & 7)) {
+               width = AT_XDMAC_CC_DWIDTH_DWORD;
+               dev_dbg(chan2dev(chan), "%s: dwidth: double word\n", __func__);
+       } else if (!(addr & 3)) {
+               width = AT_XDMAC_CC_DWIDTH_WORD;
+               dev_dbg(chan2dev(chan), "%s: dwidth: word\n", __func__);
+       } else if (!(addr & 1)) {
+               width = AT_XDMAC_CC_DWIDTH_HALFWORD;
+               dev_dbg(chan2dev(chan), "%s: dwidth: half word\n", __func__);
+       } else {
+               width = AT_XDMAC_CC_DWIDTH_BYTE;
+               dev_dbg(chan2dev(chan), "%s: dwidth: byte\n", __func__);
+       }
+
+       return width;
+}
+
 static struct dma_async_tx_descriptor *
 at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
                         size_t len, unsigned long flags)
@@ -779,24 +808,7 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
        if (unlikely(!len))
                return NULL;
 
-       /*
-        * Check address alignment to select the greater data width we can use.
-        * Some XDMAC implementations don't provide dword transfer, in this
-        * case selecting dword has the same behavior as selecting word transfers.
-        */
-       if (!((src_addr | dst_addr) & 7)) {
-               dwidth = AT_XDMAC_CC_DWIDTH_DWORD;
-               dev_dbg(chan2dev(chan), "%s: dwidth: double word\n", __func__);
-       } else if (!((src_addr | dst_addr)  & 3)) {
-               dwidth = AT_XDMAC_CC_DWIDTH_WORD;
-               dev_dbg(chan2dev(chan), "%s: dwidth: word\n", __func__);
-       } else if (!((src_addr | dst_addr) & 1)) {
-               dwidth = AT_XDMAC_CC_DWIDTH_HALFWORD;
-               dev_dbg(chan2dev(chan), "%s: dwidth: half word\n", __func__);
-       } else {
-               dwidth = AT_XDMAC_CC_DWIDTH_BYTE;
-               dev_dbg(chan2dev(chan), "%s: dwidth: byte\n", __func__);
-       }
+       dwidth = at_xdmac_align_width(chan, src_addr | dst_addr);
 
        /* Prepare descriptors. */
        while (remaining_size) {
@@ -826,19 +838,8 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
                dev_dbg(chan2dev(chan), "%s: xfer_size=%zu\n", __func__, xfer_size);
 
                /* Check remaining length and change data width if needed. */
-               if (!((src_addr | dst_addr | xfer_size) & 7)) {
-                       dwidth = AT_XDMAC_CC_DWIDTH_DWORD;
-                       dev_dbg(chan2dev(chan), "%s: dwidth: double word\n", __func__);
-               } else if (!((src_addr | dst_addr | xfer_size)  & 3)) {
-                       dwidth = AT_XDMAC_CC_DWIDTH_WORD;
-                       dev_dbg(chan2dev(chan), "%s: dwidth: word\n", __func__);
-               } else if (!((src_addr | dst_addr | xfer_size) & 1)) {
-                       dwidth = AT_XDMAC_CC_DWIDTH_HALFWORD;
-                       dev_dbg(chan2dev(chan), "%s: dwidth: half word\n", __func__);
-               } else if ((src_addr | dst_addr | xfer_size) & 1) {
-                       dwidth = AT_XDMAC_CC_DWIDTH_BYTE;
-                       dev_dbg(chan2dev(chan), "%s: dwidth: byte\n", __func__);
-               }
+               dwidth = at_xdmac_align_width(chan,
+                                             src_addr | dst_addr | xfer_size);
                chan_cc |= AT_XDMAC_CC_DWIDTH(dwidth);
 
                ublen = xfer_size >> dwidth;