lkml.org 
[lkml]   [2016]   [May]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 08/10] dma: imx-sdma: abort updating channel when it has been terminated
Date
In case the corresponding channel has already been terminated,
then instead of go on updating channel status, driver should abort from
sdma_handle_channel_loop(), otherwise channel status will be updated
incorrecly.

This patch also adds lock to avoid race between terminate of channel,
and updaing of channel status in sdma_handle_channel_loop().

Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
---
drivers/dma/imx-sdma.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 0b23407..bc867e5 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -664,16 +664,25 @@ static void sdma_event_disable(struct sdma_channel *sdmac, unsigned int event)
static void sdma_handle_channel_loop(struct sdma_channel *sdmac)
{
struct sdma_buffer_descriptor *bd;
+ unsigned long flags;

/*
* loop mode. Iterate over descriptors, re-setup them and
* call callback function.
*/
while (1) {
+ spin_lock_irqsave(&sdmac->lock, flags);
+ if (!sdmac->enabled) {
+ spin_unlock_irqrestore(&sdmac->lock, flags);
+ break;
+ }
+
bd = &sdmac->bd[sdmac->buf_tail];

- if (bd->mode.status & BD_DONE)
+ if (bd->mode.status & BD_DONE) {
+ spin_unlock_irqrestore(&sdmac->lock, flags);
break;
+ }

if (bd->mode.status & BD_RROR)
sdmac->status = DMA_ERROR;
@@ -690,6 +699,7 @@ static void sdma_handle_channel_loop(struct sdma_channel *sdmac)
bd->mode.count = sdmac->chn_count;
}

+ spin_unlock_irqrestore(&sdmac->lock, flags);
if (sdmac->desc.callback)
sdmac->desc.callback(sdmac->desc.callback_param);
}
--
2.4.5
\
 
 \ /
  Last update: 2016-05-17 06:41    [W:0.033 / U:0.340 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site