| From 069b8f108d9d621dc3c8ea913af0194256cb1600 Mon Sep 17 00:00:00 2001 |
| From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> |
| Date: Mon, 2 Jul 2018 18:18:03 +0900 |
| Subject: [PATCH 1617/1795] dmaengine: sh: rcar-dmac: avoid to write CHCR.TE to |
| 1 if TCR is set to 0 |
| |
| This patch fixes an issue that unexpected retransfering happens |
| if TCR is set to 0 before rcar_dmac_sync_tcr() writes DE bit to |
| the CHCR register. For example, sh-sci driver can reproduce this |
| issue like below: |
| |
| In rx_timer_fn(): /* CHCR DE bit may be set to 1 */ |
| dmaengine_tx_status() |
| rcar_dmac_tx_status() |
| rcar_dmac_chan_get_residue() |
| rcar_dmac_sync_tcr() /* TCR is possible to be set to 0 */ |
| |
| According to the description of commit 73a47bd0da66 ("dmaengine: |
| rcar-dmac: use TCRB instead of TCR for residue"), "this buffered data |
| will be transferred if CHCR::DE bit was cleared". So, this patch |
| doesn't need to check TCRB register. |
| |
| Fixes: 73a47bd0da66 ("dmaengine: rcar-dmac: use TCRB instead of TCR for residue") |
| Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> |
| Signed-off-by: Vinod Koul <vkoul@kernel.org> |
| (cherry picked from commit 538603c6026ce769eec633bb79349f5f287519c7) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> |
| --- |
| drivers/dma/sh/rcar-dmac.c | 5 +++-- |
| 1 file changed, 3 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c |
| index 9dc73ac92359..9906a9c7220b 100644 |
| --- a/drivers/dma/sh/rcar-dmac.c |
| +++ b/drivers/dma/sh/rcar-dmac.c |
| @@ -772,8 +772,9 @@ static void rcar_dmac_sync_tcr(struct rcar_dmac_chan *chan) |
| /* make sure all remaining data was flushed */ |
| rcar_dmac_chcr_de_barrier(chan); |
| |
| - /* back DE */ |
| - rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr); |
| + /* back DE if remain data exists */ |
| + if (rcar_dmac_chan_read(chan, RCAR_DMATCR)) |
| + rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr); |
| } |
| |
| static void rcar_dmac_chan_halt(struct rcar_dmac_chan *chan) |
| -- |
| 2.19.0 |
| |