summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/dma/at_xdmac.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index fcecbaddb351..fa9d75adf4d7 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -879,7 +879,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
struct list_head *descs_list;
enum dma_status ret;
int residue;
- u32 cur_nda;
+ u32 cur_nda, mask, value;
u8 dwidth = at_xdmac_get_dwidth(atchan->cfg[AT_XDMAC_CUR_CFG]);
ret = dma_cookie_status(chan, cookie, txstate);
@@ -903,10 +903,17 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
}
residue = desc->xfer_size;
- /* Flush FIFO. */
- at_xdmac_write(atxdmac, AT_XDMAC_GSWF, atchan->mask);
- while (!(at_xdmac_chan_read(atchan, AT_XDMAC_CIS) & AT_XDMAC_CIS_FIS))
- cpu_relax();
+ /*
+ * Flush FIFO: only relevant when the transfer is source peripheral
+ * synchronized.
+ */
+ mask = AT_XDMAC_CC_TYPE | AT_XDMAC_CC_DSYNC;
+ value = AT_XDMAC_CC_TYPE_PER_TRAN | AT_XDMAC_CC_DSYNC_PER2MEM;
+ if ((atchan->cfg[AT_XDMAC_CUR_CFG] & mask) == value) {
+ at_xdmac_write(atxdmac, AT_XDMAC_GSWF, atchan->mask);
+ while (!(at_xdmac_chan_read(atchan, AT_XDMAC_CIS) & AT_XDMAC_CIS_FIS))
+ cpu_relax();
+ }
cur_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc;
/*