From 9203dbec90a68103644ad9bf3ccf16461d67fcac Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jun 2018 00:53:33 +0000 Subject: dmaengine: rcar-dmac: don't use DMAC error interrupt rcar-dmac has 2 types of interrupt, 1) error IRQ (for all), 2) IRQ for each channels. If error happens on some channels, the error IRQ will be handled by 1), and "all" channels will be restarted. But in this design, error handling itself will be problem for non error channel users. This patch removes 1) handler, and handles error IRQ on 2) Signed-off-by: Magnus Damm [Kuninori: updated patch to adjust DMACHCR/DMAOR] Signed-off-by: Kuninori Morimoto Tested-by: Nguyen Viet Dung Reviewed-by: Geert Uytterhoeven Signed-off-by: Vinod Koul --- drivers/dma/sh/rcar-dmac.c | 72 ++++++++++++++-------------------------------- 1 file changed, 22 insertions(+), 50 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c index 2a2ccd9c78e4..279c930c4a76 100644 --- a/drivers/dma/sh/rcar-dmac.c +++ b/drivers/dma/sh/rcar-dmac.c @@ -431,7 +431,8 @@ static void rcar_dmac_chan_start_xfer(struct rcar_dmac_chan *chan) chcr |= RCAR_DMACHCR_DPM_DISABLED | RCAR_DMACHCR_IE; } - rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr | RCAR_DMACHCR_DE); + rcar_dmac_chan_write(chan, RCAR_DMACHCR, + chcr | RCAR_DMACHCR_DE | RCAR_DMACHCR_CAIE); } static int rcar_dmac_init(struct rcar_dmac *dmac) @@ -783,7 +784,8 @@ static void rcar_dmac_chan_halt(struct rcar_dmac_chan *chan) u32 chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR); chcr &= ~(RCAR_DMACHCR_DSE | RCAR_DMACHCR_DSIE | RCAR_DMACHCR_IE | - RCAR_DMACHCR_TE | RCAR_DMACHCR_DE); + RCAR_DMACHCR_TE | RCAR_DMACHCR_DE | + RCAR_DMACHCR_CAE | RCAR_DMACHCR_CAIE); rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr); rcar_dmac_chcr_de_barrier(chan); } @@ -812,12 +814,7 @@ static void rcar_dmac_chan_reinit(struct rcar_dmac_chan *chan) } } -static void rcar_dmac_stop(struct rcar_dmac *dmac) -{ - rcar_dmac_write(dmac, RCAR_DMAOR, 0); -} - -static void rcar_dmac_abort(struct rcar_dmac *dmac) +static void rcar_dmac_stop_all_chan(struct rcar_dmac *dmac) { unsigned int i; @@ -829,11 +826,10 @@ static void rcar_dmac_abort(struct rcar_dmac *dmac) spin_lock(&chan->lock); rcar_dmac_chan_halt(chan); spin_unlock(&chan->lock); - - rcar_dmac_chan_reinit(chan); } } + /* ----------------------------------------------------------------------------- * Descriptors preparation */ @@ -1522,11 +1518,18 @@ static irqreturn_t rcar_dmac_isr_channel(int irq, void *dev) u32 mask = RCAR_DMACHCR_DSE | RCAR_DMACHCR_TE; struct rcar_dmac_chan *chan = dev; irqreturn_t ret = IRQ_NONE; + bool reinit = false; u32 chcr; spin_lock(&chan->lock); chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR); + if (chcr & RCAR_DMACHCR_CAE) { + rcar_dmac_chan_halt(chan); + reinit = true; + goto spin_lock_end; + } + if (chcr & RCAR_DMACHCR_TE) mask |= RCAR_DMACHCR_DE; rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr & ~mask); @@ -1539,8 +1542,16 @@ static irqreturn_t rcar_dmac_isr_channel(int irq, void *dev) if (chcr & RCAR_DMACHCR_TE) ret |= rcar_dmac_isr_transfer_end(chan); +spin_lock_end: spin_unlock(&chan->lock); + if (reinit) { + dev_err(chan->chan.device->dev, "Channel Address Error\n"); + + rcar_dmac_chan_reinit(chan); + ret = IRQ_HANDLED; + } + return ret; } @@ -1597,24 +1608,6 @@ static irqreturn_t rcar_dmac_isr_channel_thread(int irq, void *dev) return IRQ_HANDLED; } -static irqreturn_t rcar_dmac_isr_error(int irq, void *data) -{ - struct rcar_dmac *dmac = data; - - if (!(rcar_dmac_read(dmac, RCAR_DMAOR) & RCAR_DMAOR_AE)) - return IRQ_NONE; - - /* - * An unrecoverable error occurred on an unknown channel. Halt the DMAC, - * abort transfers on all channels, and reinitialize the DMAC. - */ - rcar_dmac_stop(dmac); - rcar_dmac_abort(dmac); - rcar_dmac_init(dmac); - - return IRQ_HANDLED; -} - /* ----------------------------------------------------------------------------- * OF xlate and channel filter */ @@ -1784,8 +1777,6 @@ static int rcar_dmac_probe(struct platform_device *pdev) struct rcar_dmac *dmac; struct resource *mem; unsigned int i; - char *irqname; - int irq; int ret; dmac = devm_kzalloc(&pdev->dev, sizeof(*dmac), GFP_KERNEL); @@ -1824,17 +1815,6 @@ static int rcar_dmac_probe(struct platform_device *pdev) if (IS_ERR(dmac->iomem)) return PTR_ERR(dmac->iomem); - irq = platform_get_irq_byname(pdev, "error"); - if (irq < 0) { - dev_err(&pdev->dev, "no error IRQ specified\n"); - return -ENODEV; - } - - irqname = devm_kasprintf(dmac->dev, GFP_KERNEL, "%s:error", - dev_name(dmac->dev)); - if (!irqname) - return -ENOMEM; - /* Enable runtime PM and initialize the device. */ pm_runtime_enable(&pdev->dev); ret = pm_runtime_get_sync(&pdev->dev); @@ -1885,14 +1865,6 @@ static int rcar_dmac_probe(struct platform_device *pdev) goto error; } - ret = devm_request_irq(&pdev->dev, irq, rcar_dmac_isr_error, 0, - irqname, dmac); - if (ret) { - dev_err(&pdev->dev, "failed to request IRQ %u (%d)\n", - irq, ret); - return ret; - } - /* Register the DMAC as a DMA provider for DT. */ ret = of_dma_controller_register(pdev->dev.of_node, rcar_dmac_of_xlate, NULL); @@ -1932,7 +1904,7 @@ static void rcar_dmac_shutdown(struct platform_device *pdev) { struct rcar_dmac *dmac = platform_get_drvdata(pdev); - rcar_dmac_stop(dmac); + rcar_dmac_stop_all_chan(dmac); } static const struct of_device_id rcar_dmac_of_ids[] = { -- cgit v1.2.3 From b9b0a74aad1ca47544f875d6afac4d91e789f67c Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 4 Jul 2018 00:34:10 +0000 Subject: dmaengine: rcar-dmac: convert to SPDX identifiers This patch is using C++ comment style for SPDX line only, because driver author want it. Signed-off-by: Kuninori Morimoto Reviewed-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart Signed-off-by: Vinod Koul --- drivers/dma/sh/rcar-dmac.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c index 279c930c4a76..6b3cdb709287 100644 --- a/drivers/dma/sh/rcar-dmac.c +++ b/drivers/dma/sh/rcar-dmac.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Renesas R-Car Gen2 DMA Controller Driver * * Copyright (C) 2014 Renesas Electronics Inc. * * Author: Laurent Pinchart - * - * This is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. */ #include -- cgit v1.2.3 From 45c9a603a4dfde06f53446ce1db218958442849b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 2 Jul 2018 17:02:06 +0200 Subject: dmaengine: rcar-dmac: Disable interrupts while stopping channels During system reboot or halt, with lockdep enabled: ================================ WARNING: inconsistent lock state 4.18.0-rc1-salvator-x-00002-g9203dbec90a68103 #41 Tainted: G W -------------------------------- inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage. reboot/2779 [HC0[0]:SC0[0]:HE1:SE1] takes: 0000000098ae4ad3 (&(&rchan->lock)->rlock){?.-.}, at: rcar_dmac_shutdown+0x58/0x6c {IN-HARDIRQ-W} state was registered at: lock_acquire+0x208/0x238 _raw_spin_lock+0x40/0x54 rcar_dmac_isr_channel+0x28/0x200 __handle_irq_event_percpu+0x1c0/0x3c8 handle_irq_event_percpu+0x34/0x88 handle_irq_event+0x48/0x78 handle_fasteoi_irq+0xc4/0x12c generic_handle_irq+0x18/0x2c __handle_domain_irq+0xa8/0xac gic_handle_irq+0x78/0xbc el1_irq+0xec/0x1c0 arch_cpu_idle+0xe8/0x1bc default_idle_call+0x2c/0x30 do_idle+0x144/0x234 cpu_startup_entry+0x20/0x24 rest_init+0x27c/0x290 start_kernel+0x430/0x45c irq event stamp: 12177 hardirqs last enabled at (12177): [] _raw_spin_unlock_irq+0x2c/0x4c hardirqs last disabled at (12176): [] _raw_spin_lock_irq+0x1c/0x60 softirqs last enabled at (11948): [] __do_softirq+0x160/0x4ec softirqs last disabled at (11935): [] irq_exit+0xa0/0xfc other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&(&rchan->lock)->rlock); lock(&(&rchan->lock)->rlock); *** DEADLOCK *** 3 locks held by reboot/2779: #0: 00000000bfabfa74 (reboot_mutex){+.+.}, at: sys_reboot+0xdc/0x208 #1: 00000000c75d8c3a (&dev->mutex){....}, at: device_shutdown+0xc8/0x1c4 #2: 00000000ebec58ec (&dev->mutex){....}, at: device_shutdown+0xd8/0x1c4 stack backtrace: CPU: 6 PID: 2779 Comm: reboot Tainted: G W 4.18.0-rc1-salvator-x-00002-g9203dbec90a68103 #41 Hardware name: Renesas Salvator-X 2nd version board based on r8a7795 ES2.0+ (DT) Call trace: dump_backtrace+0x0/0x148 show_stack+0x14/0x1c dump_stack+0xb0/0xf0 print_usage_bug.part.26+0x1c4/0x27c mark_lock+0x38c/0x610 __lock_acquire+0x3fc/0x14d4 lock_acquire+0x208/0x238 _raw_spin_lock+0x40/0x54 rcar_dmac_shutdown+0x58/0x6c platform_drv_shutdown+0x20/0x2c device_shutdown+0x160/0x1c4 kernel_restart_prepare+0x34/0x3c kernel_restart+0x14/0x5c sys_reboot+0x160/0x208 el0_svc_naked+0x30/0x34 rcar_dmac_stop_all_chan() takes the channel lock while stopping a channel, but does not disable interrupts, leading to a deadlock when a DMAC interrupt comes in. Before, the same code block was called from an interrupt handler, hence taking the spinlock was sufficient. Fix this by disabling local interrupts while taking the spinlock. Fixes: 9203dbec90a68103 ("dmaengine: rcar-dmac: don't use DMAC error interrupt") Signed-off-by: Geert Uytterhoeven Signed-off-by: Vinod Koul --- drivers/dma/sh/rcar-dmac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c index 6b3cdb709287..af2f2639cec9 100644 --- a/drivers/dma/sh/rcar-dmac.c +++ b/drivers/dma/sh/rcar-dmac.c @@ -820,9 +820,9 @@ static void rcar_dmac_stop_all_chan(struct rcar_dmac *dmac) struct rcar_dmac_chan *chan = &dmac->channels[i]; /* Stop and reinitialize the channel. */ - spin_lock(&chan->lock); + spin_lock_irq(&chan->lock); rcar_dmac_chan_halt(chan); - spin_unlock(&chan->lock); + spin_unlock_irq(&chan->lock); } } -- cgit v1.2.3 From e919417bd6468b7f1b2899200a78f1ad078757d3 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 3 Jul 2018 00:29:29 +0000 Subject: dmaengine: rcar-dmac: clear channel register when error We need to clear channel register in error case as recovery. The channel is already stopped in such case, thus we don't need to call rcar_dmac_chan_halt() before clearing. rcar_dmac_chan_halt() will clear and confirm DE bit. But it will be failed because channel is already stopped in error case. In other words, we shouldn't call it then. Reported-by: Hiroki Negishi Signed-off-by: Kuninori Morimoto Reviewed-by: Hiroki Negishi Reviewed-by: Simon Horman Signed-off-by: Vinod Koul --- drivers/dma/sh/rcar-dmac.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/dma') diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c index af2f2639cec9..9dc73ac92359 100644 --- a/drivers/dma/sh/rcar-dmac.c +++ b/drivers/dma/sh/rcar-dmac.c @@ -1522,7 +1522,15 @@ static irqreturn_t rcar_dmac_isr_channel(int irq, void *dev) chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR); if (chcr & RCAR_DMACHCR_CAE) { - rcar_dmac_chan_halt(chan); + struct rcar_dmac *dmac = to_rcar_dmac(chan->chan.device); + + /* + * We don't need to call rcar_dmac_chan_halt() + * because channel is already stopped in error case. + * We need to clear register and check DE bit as recovery. + */ + rcar_dmac_write(dmac, RCAR_DMACHCLR, 1 << chan->index); + rcar_dmac_chcr_de_barrier(chan); reinit = true; goto spin_lock_end; } -- cgit v1.2.3 From 538603c6026ce769eec633bb79349f5f287519c7 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 2 Jul 2018 18:18:03 +0900 Subject: 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 Signed-off-by: Vinod Koul --- drivers/dma/sh/rcar-dmac.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/dma') 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) -- cgit v1.2.3 From 4de1247a9826cec0ba054479124bd9aa60fb71a5 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 11 Jul 2018 11:10:15 +0900 Subject: dmaengine: sh: rcar-dmac: add a new function to clear CHCR.DE with barrier This patch adds a new function rcar_dmac_clear_chcr_de() to simplify adding pause function later. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Vinod Koul --- drivers/dma/sh/rcar-dmac.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c index 9906a9c7220b..d3b7388645bc 100644 --- a/drivers/dma/sh/rcar-dmac.c +++ b/drivers/dma/sh/rcar-dmac.c @@ -759,18 +759,25 @@ static void rcar_dmac_chcr_de_barrier(struct rcar_dmac_chan *chan) dev_err(chan->chan.device->dev, "CHCR DE check error\n"); } -static void rcar_dmac_sync_tcr(struct rcar_dmac_chan *chan) +static void rcar_dmac_clear_chcr_de(struct rcar_dmac_chan *chan) { u32 chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR); - if (!(chcr & RCAR_DMACHCR_DE)) - return; - /* set DE=0 and flush remaining data */ rcar_dmac_chan_write(chan, RCAR_DMACHCR, (chcr & ~RCAR_DMACHCR_DE)); /* make sure all remaining data was flushed */ rcar_dmac_chcr_de_barrier(chan); +} + +static void rcar_dmac_sync_tcr(struct rcar_dmac_chan *chan) +{ + u32 chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR); + + if (!(chcr & RCAR_DMACHCR_DE)) + return; + + rcar_dmac_clear_chcr_de(chan); /* back DE if remain data exists */ if (rcar_dmac_chan_read(chan, RCAR_DMATCR)) -- cgit v1.2.3 From 8115ce745fa26ccffe7d1a542ab4322acf4a682d Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 11 Jul 2018 11:10:16 +0900 Subject: dmaengine: sh: rcar-dmac: Add dma_pause operation This patch adds dma_pause operation. This patch is based on Muhammad Hamza Farooq's patch. After this patch applied, an issue that the sh-sci driver with high baud rate might cause data lost disappeared because the DMAC is possible to transmit between [1] and [2] below, and then the residue of [1] is not true: In rx_timer_fn() of the sh-sci.c: dmaengine_pause(); ... dmaengine_tx_status(); /* [1] */ ... dmaengine_terminate_all(); /* [2] */ Signed-off-by: Yoshihiro Shimoda Signed-off-by: Vinod Koul --- drivers/dma/sh/rcar-dmac.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers/dma') diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c index d3b7388645bc..be82d6997a55 100644 --- a/drivers/dma/sh/rcar-dmac.c +++ b/drivers/dma/sh/rcar-dmac.c @@ -834,6 +834,17 @@ static void rcar_dmac_stop_all_chan(struct rcar_dmac *dmac) } } +static int rcar_dmac_chan_pause(struct dma_chan *chan) +{ + unsigned long flags; + struct rcar_dmac_chan *rchan = to_rcar_dmac_chan(chan); + + spin_lock_irqsave(&rchan->lock, flags); + rcar_dmac_clear_chcr_de(rchan); + spin_unlock_irqrestore(&rchan->lock, flags); + + return 0; +} /* ----------------------------------------------------------------------------- * Descriptors preparation @@ -1864,6 +1875,7 @@ static int rcar_dmac_probe(struct platform_device *pdev) engine->device_prep_slave_sg = rcar_dmac_prep_slave_sg; engine->device_prep_dma_cyclic = rcar_dmac_prep_dma_cyclic; engine->device_config = rcar_dmac_device_config; + engine->device_pause = rcar_dmac_chan_pause; engine->device_terminate_all = rcar_dmac_chan_terminate_all; engine->device_tx_status = rcar_dmac_tx_status; engine->device_issue_pending = rcar_dmac_issue_pending; -- cgit v1.2.3 From 218c21043d0037f616bd8af406de55a01e3fa381 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 25 Jul 2018 17:27:04 +0900 Subject: dmaengine: sh: rcar-dmac: Should not stop the DMAC by rcar_dmac_sync_tcr() rcar_dmac_chan_get_residue() should not stop the DMAC, because the commit 538603c6026c ("dmaengine: sh: rcar-dmac: avoid to write CHCR.TE to 1 if TCR is set to 0") had fixed unexpected re-transferring issue. But it had caused the next issue which might stop the cyclic mode transferring. Thus, for example R-Car sound might be stopped suddenly. According to the commit 73a47bd0da66 ("dmaengine: rcar-dmac: use TCRB instead of TCR for residue"), the purpose of clearing CHCR.DE bit is flushing buffered data to calculate the exact residue. Such the "exact" residue had been required by sh-sci driver. sh-sci driver is calling dmaengine_pause() to stop transferring, and get "exact" residue. Otherwise, it might receive extra data during getting residue without pausing. In rx_timer_fn() of sh-sci driver: dmaengine_tx_status(); /* For checking roughly */ dmaengine_pause(); dmaengine_tx_status(); /* For getting residue */ dmaengine_terminate_all(); But, unfortunately the rcar-dmac driver didn't support dmaengine_pause() at that time. So, the sh-sci driver cannot get the "exact" residue without stopping the transferring, because rcar-dmac is buffering data inside. Because of these backgrounds, rcar-dmac had been cleared/set CHCR.DE bit in rcar_dmac_chan_get_residue() to synchronizing data and getting "exact" residue. However, rcar-dmac driver has rcar_dmac_chan_pause() now, and clearing CHCR.DE bit in rcar_dmac_chan_get_residue() doesn't need anymore. So, this patch removes the rcar_dmac_sync_tcr(). Fixes: 73a47bd0da66 ("dmaengine: rcar-dmac: use TCRB instead of TCR for residue") Signed-off-by: Yoshihiro Shimoda Tested-by: Hiroyuki Yokoyama Reviewed-by: Geert Uytterhoeven Signed-off-by: Vinod Koul --- drivers/dma/sh/rcar-dmac.c | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c index be82d6997a55..48ee35e2bce6 100644 --- a/drivers/dma/sh/rcar-dmac.c +++ b/drivers/dma/sh/rcar-dmac.c @@ -770,20 +770,6 @@ static void rcar_dmac_clear_chcr_de(struct rcar_dmac_chan *chan) rcar_dmac_chcr_de_barrier(chan); } -static void rcar_dmac_sync_tcr(struct rcar_dmac_chan *chan) -{ - u32 chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR); - - if (!(chcr & RCAR_DMACHCR_DE)) - return; - - rcar_dmac_clear_chcr_de(chan); - - /* 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) { u32 chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR); @@ -1367,9 +1353,6 @@ static unsigned int rcar_dmac_chan_get_residue(struct rcar_dmac_chan *chan, residue += chunk->size; } - if (desc->direction == DMA_DEV_TO_MEM) - rcar_dmac_sync_tcr(chan); - /* Add the residue for the current chunk. */ residue += rcar_dmac_chan_read(chan, RCAR_DMATCRB) << desc->xfer_shift; -- cgit v1.2.3