linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 00/10] *** imx-sdma: misc fix ***
@ 2016-05-17  3:47 Jiada Wang
  2016-05-17  3:47 ` [PATCH 01/10] dma: imx-sdma: use chn_real_count to report residue for UART Jiada Wang
                   ` (10 more replies)
  0 siblings, 11 replies; 20+ messages in thread
From: Jiada Wang @ 2016-05-17  3:47 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams
  Cc: dmaengine, linux-kernel, shawnguo, kernel, george_davis, jiada_wang

this patch set contains the following changes
1. fix issues in cyclic dma
2. add support to SYNC DMA termination
3. avoid system hang, when SDMA channel 0 timeouts
4. add lock to prevent race condition

Jiada Wang (10):
  dma: imx-sdma: use chn_real_count to report residue for UART
  dma: imx-sdma: don't update BD in isr routine
  dma: imx-sdma: clear BD_RROR flag before pass it to sdma script
  dma: imx-sdma: update sdma channel status for cyclic dma
  dma: imx-sdma: add flag to indicate SDMA channel state
  dma: imx-sdma: add terminate_all support
  dma: imx-sdma: Add synchronization support
  dma: imx-sdma: abort updating channel when it has been terminated
  dma: imx-sdma: disable channel 0 when it timeouts
  dma: imx-sdma: clear channel0 interrupt bit in irq routine

 drivers/dma/imx-sdma.c | 113 +++++++++++++++++++++++++++++++++++--------------
 1 file changed, 82 insertions(+), 31 deletions(-)

-- 
2.4.5

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 01/10] dma: imx-sdma: use chn_real_count to report residue for UART
  2016-05-17  3:47 [PATCH v1 00/10] *** imx-sdma: misc fix *** Jiada Wang
@ 2016-05-17  3:47 ` Jiada Wang
  2016-05-17  3:47 ` [PATCH 02/10] dma: imx-sdma: don't update BD in isr routine Jiada Wang
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Jiada Wang @ 2016-05-17  3:47 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams
  Cc: dmaengine, linux-kernel, shawnguo, kernel, george_davis, jiada_wang

For uart rx dma data may not receive fully, so the number
of data read by sdma script once isn't always equal to period_len,
thus residue returned from sdma_tx_status() isn't valid for uart rx
dma. The old way to use chn_real_count to report residue should be
used for uart rx dma.

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

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 0f6fd42..1f1b64b 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -680,6 +680,11 @@ static void sdma_update_channel_loop(struct sdma_channel *sdmac)
 		bd->mode.status |= BD_DONE;
 		sdmac->buf_tail++;
 		sdmac->buf_tail %= sdmac->num_bd;
+		if (sdmac->peripheral_type == IMX_DMATYPE_UART) {
+			/* restore mode.count after counter readed */
+			sdmac->chn_real_count = bd->mode.count;
+			bd->mode.count = sdmac->chn_count;
+		}
 	}
 }
 
@@ -1285,6 +1290,9 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
 		goto err_out;
 	}
 
+	if (sdmac->peripheral_type == IMX_DMATYPE_UART)
+		sdmac->chn_count = period_len;
+
 	while (buf < buf_len) {
 		struct sdma_buffer_descriptor *bd = &sdmac->bd[i];
 		int param;
@@ -1361,7 +1369,8 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan,
 	struct sdma_channel *sdmac = to_sdma_chan(chan);
 	u32 residue;
 
-	if (sdmac->flags & IMX_DMA_SG_LOOP)
+	if ((sdmac->flags & IMX_DMA_SG_LOOP) &&
+	    (sdmac->peripheral_type != IMX_DMATYPE_UART))
 		residue = (sdmac->num_bd - sdmac->buf_tail) * sdmac->period_len;
 	else
 		residue = sdmac->chn_count - sdmac->chn_real_count;
-- 
2.4.5

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 02/10] dma: imx-sdma: don't update BD in isr routine
  2016-05-17  3:47 [PATCH v1 00/10] *** imx-sdma: misc fix *** Jiada Wang
  2016-05-17  3:47 ` [PATCH 01/10] dma: imx-sdma: use chn_real_count to report residue for UART Jiada Wang
@ 2016-05-17  3:47 ` Jiada Wang
  2016-05-17  3:47 ` [PATCH 03/10] dma: imx-sdma: clear BD_RROR flag before pass it to sdma script Jiada Wang
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Jiada Wang @ 2016-05-17  3:47 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams
  Cc: dmaengine, linux-kernel, shawnguo, kernel, george_davis, jiada_wang

commit d1a792f3b407 ("Update imx-sdma cyclic handling to report residue")
moves updating of BD to isr routine, to avoid stop
of cyclic dma, but there is chance 'new' isr comes before the 'old'
tasklet can be fired, thus cause data loss due to missing of one
tasklet. So move updating of BD back to tasklet.

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

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 1f1b64b..887e4e5 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -656,12 +656,6 @@ static void sdma_event_disable(struct sdma_channel *sdmac, unsigned int event)
 
 static void sdma_handle_channel_loop(struct sdma_channel *sdmac)
 {
-	if (sdmac->desc.callback)
-		sdmac->desc.callback(sdmac->desc.callback_param);
-}
-
-static void sdma_update_channel_loop(struct sdma_channel *sdmac)
-{
 	struct sdma_buffer_descriptor *bd;
 
 	/*
@@ -685,6 +679,9 @@ static void sdma_update_channel_loop(struct sdma_channel *sdmac)
 			sdmac->chn_real_count = bd->mode.count;
 			bd->mode.count = sdmac->chn_count;
 		}
+
+		if (sdmac->desc.callback)
+			sdmac->desc.callback(sdmac->desc.callback_param);
 	}
 }
 
@@ -740,9 +737,6 @@ static irqreturn_t sdma_int_handler(int irq, void *dev_id)
 		int channel = fls(stat) - 1;
 		struct sdma_channel *sdmac = &sdma->channel[channel];
 
-		if (sdmac->flags & IMX_DMA_SG_LOOP)
-			sdma_update_channel_loop(sdmac);
-
 		tasklet_schedule(&sdmac->tasklet);
 
 		__clear_bit(channel, &stat);
-- 
2.4.5

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 03/10] dma: imx-sdma: clear BD_RROR flag before pass it to sdma script
  2016-05-17  3:47 [PATCH v1 00/10] *** imx-sdma: misc fix *** Jiada Wang
  2016-05-17  3:47 ` [PATCH 01/10] dma: imx-sdma: use chn_real_count to report residue for UART Jiada Wang
  2016-05-17  3:47 ` [PATCH 02/10] dma: imx-sdma: don't update BD in isr routine Jiada Wang
@ 2016-05-17  3:47 ` Jiada Wang
  2016-05-17  3:47 ` [PATCH 04/10] dma: imx-sdma: update sdma channel status for cyclic dma Jiada Wang
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Jiada Wang @ 2016-05-17  3:47 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams
  Cc: dmaengine, linux-kernel, shawnguo, kernel, george_davis, jiada_wang

Previously in cyclic dma mode when sdma transfer fails for one buffer,
it will mask BD_RROR flag for that buffer descriptor (BD). This flag
won't be cleared unless a new cyclic dma transfer is prepared, so if
sdma script next time iterates to the same BD, even this time the
transfer is successful, but as BD_RROR flag is set, client side
will still think the transfer failed.

This patch clears BD_RROR flag before pass it to sdma script.

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

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 887e4e5..1489de0 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -671,6 +671,7 @@ static void sdma_handle_channel_loop(struct sdma_channel *sdmac)
 		if (bd->mode.status & BD_RROR)
 			sdmac->status = DMA_ERROR;
 
+		bd->mode.status &= ~BD_RROR;
 		bd->mode.status |= BD_DONE;
 		sdmac->buf_tail++;
 		sdmac->buf_tail %= sdmac->num_bd;
-- 
2.4.5

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 04/10] dma: imx-sdma: update sdma channel status for cyclic dma
  2016-05-17  3:47 [PATCH v1 00/10] *** imx-sdma: misc fix *** Jiada Wang
                   ` (2 preceding siblings ...)
  2016-05-17  3:47 ` [PATCH 03/10] dma: imx-sdma: clear BD_RROR flag before pass it to sdma script Jiada Wang
@ 2016-05-17  3:47 ` Jiada Wang
  2016-05-17  3:47 ` [PATCH 05/10] dma: imx-sdma: add flag to indicate SDMA channel state Jiada Wang
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Jiada Wang @ 2016-05-17  3:47 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams
  Cc: dmaengine, linux-kernel, shawnguo, kernel, george_davis, jiada_wang

Previously for cyclic dma mode, once sdma fails sdma channel status will
be set to DMA_ERROR, unless the transfer is prepared again, sdmac status
will always be kept to DMA_ERROR, even the transfer for following buffers
is successful.

This patch updates sdmac status to the status of current buffer descriptor.

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

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 1489de0..36f5e39 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -670,6 +670,8 @@ static void sdma_handle_channel_loop(struct sdma_channel *sdmac)
 
 		if (bd->mode.status & BD_RROR)
 			sdmac->status = DMA_ERROR;
+		else
+			sdmac->status = DMA_IN_PROGRESS;
 
 		bd->mode.status &= ~BD_RROR;
 		bd->mode.status |= BD_DONE;
-- 
2.4.5

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 05/10] dma: imx-sdma: add flag to indicate SDMA channel state
  2016-05-17  3:47 [PATCH v1 00/10] *** imx-sdma: misc fix *** Jiada Wang
                   ` (3 preceding siblings ...)
  2016-05-17  3:47 ` [PATCH 04/10] dma: imx-sdma: update sdma channel status for cyclic dma Jiada Wang
@ 2016-05-17  3:47 ` Jiada Wang
  2016-05-17  3:47 ` [PATCH 06/10] dma: imx-sdma: add terminate_all support Jiada Wang
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Jiada Wang @ 2016-05-17  3:47 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams
  Cc: dmaengine, linux-kernel, shawnguo, kernel, george_davis, jiada_wang

There is race between STOP of SDMA channel and finish of
SDMA transfer, so some times, even after sdma_disable_channel()
is called, the bit of 'terminated channel' in INTR may still get
asserted, thus cause an extra sdma tasklet be called.
Add flag 'enabled' to each sdma channel to indicate its state.
only when SDMA channel is in its enabled state, irq handler
can schedule a sdma tasklet for it.

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

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 36f5e39..ef5d37c 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -327,6 +327,7 @@ struct sdma_channel {
 	unsigned int			chn_real_count;
 	struct tasklet_struct		tasklet;
 	struct imx_dma_data		data;
+	bool				enabled;
 };
 
 #define IMX_DMA_SG_LOOP		BIT(0)
@@ -562,7 +563,13 @@ static int sdma_config_ownership(struct sdma_channel *sdmac,
 
 static void sdma_enable_channel(struct sdma_engine *sdma, int channel)
 {
+	struct sdma_channel *sdmac = &sdma->channel[channel];
+	unsigned long flags;
+
+	spin_lock_irqsave(&sdmac->lock, flags);
+	sdmac->enabled = true;
 	writel(BIT(channel), sdma->regs + SDMA_H_START);
+	spin_unlock_irqrestore(&sdmac->lock, flags);
 }
 
 /*
@@ -740,9 +747,12 @@ static irqreturn_t sdma_int_handler(int irq, void *dev_id)
 		int channel = fls(stat) - 1;
 		struct sdma_channel *sdmac = &sdma->channel[channel];
 
-		tasklet_schedule(&sdmac->tasklet);
+		spin_lock(&sdmac->lock);
+		if (sdmac->enabled)
+			tasklet_schedule(&sdmac->tasklet);
 
 		__clear_bit(channel, &stat);
+		spin_unlock(&sdmac->lock);
 	}
 
 	return IRQ_HANDLED;
@@ -906,9 +916,13 @@ static int sdma_disable_channel(struct dma_chan *chan)
 	struct sdma_channel *sdmac = to_sdma_chan(chan);
 	struct sdma_engine *sdma = sdmac->sdma;
 	int channel = sdmac->channel;
+	unsigned long flags;
 
+	spin_lock_irqsave(&sdmac->lock, flags);
+	sdmac->enabled = false;
 	writel_relaxed(BIT(channel), sdma->regs + SDMA_H_STATSTOP);
 	sdmac->status = DMA_ERROR;
+	spin_unlock_irqrestore(&sdmac->lock, flags);
 
 	return 0;
 }
-- 
2.4.5

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 06/10] dma: imx-sdma: add terminate_all support
  2016-05-17  3:47 [PATCH v1 00/10] *** imx-sdma: misc fix *** Jiada Wang
                   ` (4 preceding siblings ...)
  2016-05-17  3:47 ` [PATCH 05/10] dma: imx-sdma: add flag to indicate SDMA channel state Jiada Wang
@ 2016-05-17  3:47 ` Jiada Wang
  2016-05-17  3:47 ` [PATCH 07/10] dma: imx-sdma: Add synchronization support Jiada Wang
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Jiada Wang @ 2016-05-17  3:47 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams
  Cc: dmaengine, linux-kernel, shawnguo, kernel, george_davis, jiada_wang

Implement device_terminate_all(), so that dmaengine_terminate_async()
can work.

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

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index ef5d37c..040cbf2 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -1401,6 +1401,13 @@ static void sdma_issue_pending(struct dma_chan *chan)
 		sdma_enable_channel(sdma, sdmac->channel);
 }
 
+static int sdma_terminate_all(struct dma_chan *chan)
+{
+	sdma_disable_channel(chan);
+
+	return 0;
+}
+
 #define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1	34
 #define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2	38
 #define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V3	41
@@ -1819,6 +1826,7 @@ static int sdma_probe(struct platform_device *pdev)
 	sdma->dma_device.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
 	sdma->dma_device.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
 	sdma->dma_device.device_issue_pending = sdma_issue_pending;
+	sdma->dma_device.device_terminate_all = sdma_terminate_all;
 	sdma->dma_device.dev->dma_parms = &sdma->dma_parms;
 	dma_set_max_seg_size(sdma->dma_device.dev, 65535);
 
-- 
2.4.5

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 07/10] dma: imx-sdma: Add synchronization support
  2016-05-17  3:47 [PATCH v1 00/10] *** imx-sdma: misc fix *** Jiada Wang
                   ` (5 preceding siblings ...)
  2016-05-17  3:47 ` [PATCH 06/10] dma: imx-sdma: add terminate_all support Jiada Wang
@ 2016-05-17  3:47 ` Jiada Wang
  2016-05-17  3:47 ` [PATCH 08/10] dma: imx-sdma: abort updating channel when it has been terminated Jiada Wang
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Jiada Wang @ 2016-05-17  3:47 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams
  Cc: dmaengine, linux-kernel, shawnguo, kernel, george_davis, jiada_wang

Implement the new device_synchronize() callback to allow proper
synchronization when stopping a channel. Since the driver already makes
sure that no new complete callbacks are scheduled after the
device_terminate_all() has been called, all left to do in the
device_synchronize() callback is to wait for all currently running complete
callbacks to finish.

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

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 040cbf2..0b23407 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -1408,6 +1408,13 @@ static int sdma_terminate_all(struct dma_chan *chan)
 	return 0;
 }
 
+static void sdma_synchronize(struct dma_chan *chan)
+{
+	struct sdma_channel *sdmac = to_sdma_chan(chan);
+
+	tasklet_kill(&sdmac->tasklet);
+}
+
 #define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1	34
 #define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2	38
 #define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V3	41
@@ -1827,6 +1834,7 @@ static int sdma_probe(struct platform_device *pdev)
 	sdma->dma_device.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
 	sdma->dma_device.device_issue_pending = sdma_issue_pending;
 	sdma->dma_device.device_terminate_all = sdma_terminate_all;
+	sdma->dma_device.device_synchronize = sdma_synchronize;
 	sdma->dma_device.dev->dma_parms = &sdma->dma_parms;
 	dma_set_max_seg_size(sdma->dma_device.dev, 65535);
 
-- 
2.4.5

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 08/10] dma: imx-sdma: abort updating channel when it has been terminated
  2016-05-17  3:47 [PATCH v1 00/10] *** imx-sdma: misc fix *** Jiada Wang
                   ` (6 preceding siblings ...)
  2016-05-17  3:47 ` [PATCH 07/10] dma: imx-sdma: Add synchronization support Jiada Wang
@ 2016-05-17  3:47 ` Jiada Wang
  2016-05-17  3:47 ` [PATCH 09/10] dma: imx-sdma: disable channel 0 when it timeouts Jiada Wang
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Jiada Wang @ 2016-05-17  3:47 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams
  Cc: dmaengine, linux-kernel, shawnguo, kernel, george_davis, jiada_wang

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

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 09/10] dma: imx-sdma: disable channel 0 when it timeouts
  2016-05-17  3:47 [PATCH v1 00/10] *** imx-sdma: misc fix *** Jiada Wang
                   ` (7 preceding siblings ...)
  2016-05-17  3:47 ` [PATCH 08/10] dma: imx-sdma: abort updating channel when it has been terminated Jiada Wang
@ 2016-05-17  3:47 ` Jiada Wang
  2016-05-17  3:47 ` [PATCH 10/10] dma: imx-sdma: clear channel0 interrupt bit in irq routine Jiada Wang
  2016-05-17 10:04 ` [PATCH v1 00/10] *** imx-sdma: misc fix *** Vinod Koul
  10 siblings, 0 replies; 20+ messages in thread
From: Jiada Wang @ 2016-05-17  3:47 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams
  Cc: dmaengine, linux-kernel, shawnguo, kernel, george_davis, jiada_wang

Previously when channel0 timeouts to finish its task,
sdma_run_channel0() just returns without disable channel0,
this will cause continuous interrupt later when channel0
finishs its task and set channel0 interrupt bit.

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

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index bc867e5..8b20bf4 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -572,6 +572,27 @@ static void sdma_enable_channel(struct sdma_engine *sdma, int channel)
 	spin_unlock_irqrestore(&sdmac->lock, flags);
 }
 
+static struct sdma_channel *to_sdma_chan(struct dma_chan *chan)
+{
+	return container_of(chan, struct sdma_channel, chan);
+}
+
+static int sdma_disable_channel(struct dma_chan *chan)
+{
+	struct sdma_channel *sdmac = to_sdma_chan(chan);
+	struct sdma_engine *sdma = sdmac->sdma;
+	int channel = sdmac->channel;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sdmac->lock, flags);
+	sdmac->enabled = false;
+	writel_relaxed(BIT(channel), sdma->regs + SDMA_H_STATSTOP);
+	sdmac->status = DMA_ERROR;
+	spin_unlock_irqrestore(&sdmac->lock, flags);
+
+	return 0;
+}
+
 /*
  * sdma_run_channel0 - run a channel and wait till it's done
  */
@@ -592,6 +613,7 @@ static int sdma_run_channel0(struct sdma_engine *sdma)
 		/* Clear the interrupt status */
 		writel_relaxed(ret, sdma->regs + SDMA_H_INTR);
 	} else {
+		sdma_disable_channel(&sdma->channel[0].chan);
 		dev_err(sdma->dev, "Timeout waiting for CH0 ready\n");
 	}
 
@@ -916,27 +938,6 @@ static int sdma_load_context(struct sdma_channel *sdmac)
 	return ret;
 }
 
-static struct sdma_channel *to_sdma_chan(struct dma_chan *chan)
-{
-	return container_of(chan, struct sdma_channel, chan);
-}
-
-static int sdma_disable_channel(struct dma_chan *chan)
-{
-	struct sdma_channel *sdmac = to_sdma_chan(chan);
-	struct sdma_engine *sdma = sdmac->sdma;
-	int channel = sdmac->channel;
-	unsigned long flags;
-
-	spin_lock_irqsave(&sdmac->lock, flags);
-	sdmac->enabled = false;
-	writel_relaxed(BIT(channel), sdma->regs + SDMA_H_STATSTOP);
-	sdmac->status = DMA_ERROR;
-	spin_unlock_irqrestore(&sdmac->lock, flags);
-
-	return 0;
-}
-
 static void sdma_set_watermarklevel_for_p2p(struct sdma_channel *sdmac)
 {
 	struct sdma_engine *sdma = sdmac->sdma;
-- 
2.4.5

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 10/10] dma: imx-sdma: clear channel0 interrupt bit in irq routine
  2016-05-17  3:47 [PATCH v1 00/10] *** imx-sdma: misc fix *** Jiada Wang
                   ` (8 preceding siblings ...)
  2016-05-17  3:47 ` [PATCH 09/10] dma: imx-sdma: disable channel 0 when it timeouts Jiada Wang
@ 2016-05-17  3:47 ` Jiada Wang
  2016-05-17 10:04 ` [PATCH v1 00/10] *** imx-sdma: misc fix *** Vinod Koul
  10 siblings, 0 replies; 20+ messages in thread
From: Jiada Wang @ 2016-05-17  3:47 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams
  Cc: dmaengine, linux-kernel, shawnguo, kernel, george_davis, jiada_wang

When SDMA channel0 timeouts, even it's disabled in error path,
but sometimes we still see its interrupt bit be asserted,
which causes irq routine be triggered continuously because
no one else clears this bit.

This commit clears channel0 interrupt as well in irq routine,
so that even channel0 timeouts, it won't cause irq storm,
also adds lock to prevent irq routine to clear this bit when
sdma_run_channel0() is busy checking it.

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

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 8b20bf4..ca1c984 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -768,12 +768,16 @@ static void sdma_tasklet(unsigned long data)
 static irqreturn_t sdma_int_handler(int irq, void *dev_id)
 {
 	struct sdma_engine *sdma = dev_id;
-	unsigned long stat;
+	unsigned long stat, flags;
+
+	spin_lock_irqsave(&sdma->channel_0_lock, flags);
 
 	stat = readl_relaxed(sdma->regs + SDMA_H_INTR);
+	writel_relaxed(stat, sdma->regs + SDMA_H_INTR);
 	/* not interested in channel 0 interrupts */
 	stat &= ~1;
-	writel_relaxed(stat, sdma->regs + SDMA_H_INTR);
+
+	spin_unlock_irqrestore(&sdma->channel_0_lock, flags);
 
 	while (stat) {
 		int channel = fls(stat) - 1;
-- 
2.4.5

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 00/10] *** imx-sdma: misc fix ***
  2016-05-17  3:47 [PATCH v1 00/10] *** imx-sdma: misc fix *** Jiada Wang
                   ` (9 preceding siblings ...)
  2016-05-17  3:47 ` [PATCH 10/10] dma: imx-sdma: clear channel0 interrupt bit in irq routine Jiada Wang
@ 2016-05-17 10:04 ` Vinod Koul
  2016-05-25  7:57   ` Jiada Wang
  10 siblings, 1 reply; 20+ messages in thread
From: Vinod Koul @ 2016-05-17 10:04 UTC (permalink / raw)
  To: Jiada Wang
  Cc: dan.j.williams, dmaengine, linux-kernel, shawnguo, kernel, george_davis

On Tue, May 17, 2016 at 12:47:46PM +0900, Jiada Wang wrote:
> this patch set contains the following changes
> 1. fix issues in cyclic dma
> 2. add support to SYNC DMA termination
> 3. avoid system hang, when SDMA channel 0 timeouts
> 4. add lock to prevent race condition

I have three series in my inbox with same title and version. whats going on?

> 
> Jiada Wang (10):
>   dma: imx-sdma: use chn_real_count to report residue for UART
>   dma: imx-sdma: don't update BD in isr routine
>   dma: imx-sdma: clear BD_RROR flag before pass it to sdma script
>   dma: imx-sdma: update sdma channel status for cyclic dma
>   dma: imx-sdma: add flag to indicate SDMA channel state
>   dma: imx-sdma: add terminate_all support
>   dma: imx-sdma: Add synchronization support
>   dma: imx-sdma: abort updating channel when it has been terminated
>   dma: imx-sdma: disable channel 0 when it timeouts
>   dma: imx-sdma: clear channel0 interrupt bit in irq routine
> 
>  drivers/dma/imx-sdma.c | 113 +++++++++++++++++++++++++++++++++++--------------
>  1 file changed, 82 insertions(+), 31 deletions(-)
> 
> -- 
> 2.4.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe dmaengine" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
~Vinod

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 00/10] *** imx-sdma: misc fix ***
  2016-05-17 10:04 ` [PATCH v1 00/10] *** imx-sdma: misc fix *** Vinod Koul
@ 2016-05-25  7:57   ` Jiada Wang
  0 siblings, 0 replies; 20+ messages in thread
From: Jiada Wang @ 2016-05-25  7:57 UTC (permalink / raw)
  To: Vinod Koul
  Cc: dan.j.williams, dmaengine, linux-kernel, shawnguo, kernel, george_davis

Hello

On 05/17/2016 07:04 PM, Vinod Koul wrote:
> On Tue, May 17, 2016 at 12:47:46PM +0900, Jiada Wang wrote:
>> this patch set contains the following changes
>> 1. fix issues in cyclic dma
>> 2. add support to SYNC DMA termination
>> 3. avoid system hang, when SDMA channel 0 timeouts
>> 4. add lock to prevent race condition
>
> I have three series in my inbox with same title and version. whats going on?
>
Sorry for the confusion,
attempted to loop Shawn, but used wrong email address.

Thanks,
Jiada

>>
>> Jiada Wang (10):
>>    dma: imx-sdma: use chn_real_count to report residue for UART
>>    dma: imx-sdma: don't update BD in isr routine
>>    dma: imx-sdma: clear BD_RROR flag before pass it to sdma script
>>    dma: imx-sdma: update sdma channel status for cyclic dma
>>    dma: imx-sdma: add flag to indicate SDMA channel state
>>    dma: imx-sdma: add terminate_all support
>>    dma: imx-sdma: Add synchronization support
>>    dma: imx-sdma: abort updating channel when it has been terminated
>>    dma: imx-sdma: disable channel 0 when it timeouts
>>    dma: imx-sdma: clear channel0 interrupt bit in irq routine
>>
>>   drivers/dma/imx-sdma.c | 113 +++++++++++++++++++++++++++++++++++--------------
>>   1 file changed, 82 insertions(+), 31 deletions(-)
>>
>> --
>> 2.4.5
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe dmaengine" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 00/10] *** imx-sdma: misc fix ***
  2016-10-17  5:34   ` Vinod Koul
@ 2016-10-17  7:39     ` Jiada Wang
  0 siblings, 0 replies; 20+ messages in thread
From: Jiada Wang @ 2016-10-17  7:39 UTC (permalink / raw)
  To: Vinod Koul
  Cc: dan.j.williams, dmaengine, linux-kernel, shawnguo, kernel, george_davis

Hello Vinod

On 10/17/2016 02:34 PM, Vinod Koul wrote:
> On Mon, Oct 17, 2016 at 01:51:26PM +0900, Jiada Wang wrote:
>> Hello community
>>
>> Is there any comment regarding this patch set?
>
> I dont seem to have this, can you please rebase this and resend..
>
I found upstream already has similar fix/feature to several of my 
commits in this patch set.
I will update this patch set after review of latest sdma driver.

Thanks,
Jiada

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 00/10] *** imx-sdma: misc fix ***
  2016-10-17  4:51 ` Jiada Wang
@ 2016-10-17  5:34   ` Vinod Koul
  2016-10-17  7:39     ` Jiada Wang
  0 siblings, 1 reply; 20+ messages in thread
From: Vinod Koul @ 2016-10-17  5:34 UTC (permalink / raw)
  To: Jiada Wang
  Cc: dan.j.williams, dmaengine, linux-kernel, shawnguo, kernel, george_davis

On Mon, Oct 17, 2016 at 01:51:26PM +0900, Jiada Wang wrote:
> Hello community
> 
> Is there any comment regarding this patch set?

I dont seem to have this, can you please rebase this and resend..

-- 
~Vinod

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 00/10] *** imx-sdma: misc fix ***
  2016-05-17  3:48 Jiada Wang
  2016-10-12  5:54 ` Jiada Wang
@ 2016-10-17  4:51 ` Jiada Wang
  2016-10-17  5:34   ` Vinod Koul
  1 sibling, 1 reply; 20+ messages in thread
From: Jiada Wang @ 2016-10-17  4:51 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams
  Cc: dmaengine, linux-kernel, shawnguo, kernel, george_davis

Hello community

Is there any comment regarding this patch set?

Thanks,
Jiada

On 05/17/2016 12:48 PM, Jiada Wang wrote:
> this patch set contains the following changes
> 1. fix issues in cyclic dma
> 2. add support to SYNC DMA termination
> 3. avoid system hang, when SDMA channel 0 timeouts
> 4. add lock to prevent race condition
>
> Jiada Wang (10):
>   dma: imx-sdma: use chn_real_count to report residue for UART
>   dma: imx-sdma: don't update BD in isr routine
>   dma: imx-sdma: clear BD_RROR flag before pass it to sdma script
>   dma: imx-sdma: update sdma channel status for cyclic dma
>   dma: imx-sdma: add flag to indicate SDMA channel state
>   dma: imx-sdma: add terminate_all support
>   dma: imx-sdma: Add synchronization support
>   dma: imx-sdma: abort updating channel when it has been terminated
>   dma: imx-sdma: disable channel 0 when it timeouts
>   dma: imx-sdma: clear channel0 interrupt bit in irq routine
>
>  drivers/dma/imx-sdma.c | 113 +++++++++++++++++++++++++++++++++++--------------
>  1 file changed, 82 insertions(+), 31 deletions(-)
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 00/10] *** imx-sdma: misc fix ***
  2016-05-17  3:48 Jiada Wang
@ 2016-10-12  5:54 ` Jiada Wang
  2016-10-17  4:51 ` Jiada Wang
  1 sibling, 0 replies; 20+ messages in thread
From: Jiada Wang @ 2016-10-12  5:54 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams
  Cc: dmaengine, linux-kernel, shawnguo, kernel, george_davis

Hello

Are there any comments for this patch set?

Thanks,
Jiada

On 05/17/2016 12:48 PM, Jiada Wang wrote:
> this patch set contains the following changes
> 1. fix issues in cyclic dma
> 2. add support to SYNC DMA termination
> 3. avoid system hang, when SDMA channel 0 timeouts
> 4. add lock to prevent race condition
>
> Jiada Wang (10):
>   dma: imx-sdma: use chn_real_count to report residue for UART
>   dma: imx-sdma: don't update BD in isr routine
>   dma: imx-sdma: clear BD_RROR flag before pass it to sdma script
>   dma: imx-sdma: update sdma channel status for cyclic dma
>   dma: imx-sdma: add flag to indicate SDMA channel state
>   dma: imx-sdma: add terminate_all support
>   dma: imx-sdma: Add synchronization support
>   dma: imx-sdma: abort updating channel when it has been terminated
>   dma: imx-sdma: disable channel 0 when it timeouts
>   dma: imx-sdma: clear channel0 interrupt bit in irq routine
>
>  drivers/dma/imx-sdma.c | 113 +++++++++++++++++++++++++++++++++++--------------
>  1 file changed, 82 insertions(+), 31 deletions(-)
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v1 00/10] *** imx-sdma: misc fix ***
@ 2016-05-17  3:48 Jiada Wang
  2016-10-12  5:54 ` Jiada Wang
  2016-10-17  4:51 ` Jiada Wang
  0 siblings, 2 replies; 20+ messages in thread
From: Jiada Wang @ 2016-05-17  3:48 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams
  Cc: dmaengine, linux-kernel, shawnguo, kernel, george_davis, jiada_wang

this patch set contains the following changes
1. fix issues in cyclic dma
2. add support to SYNC DMA termination
3. avoid system hang, when SDMA channel 0 timeouts
4. add lock to prevent race condition

Jiada Wang (10):
  dma: imx-sdma: use chn_real_count to report residue for UART
  dma: imx-sdma: don't update BD in isr routine
  dma: imx-sdma: clear BD_RROR flag before pass it to sdma script
  dma: imx-sdma: update sdma channel status for cyclic dma
  dma: imx-sdma: add flag to indicate SDMA channel state
  dma: imx-sdma: add terminate_all support
  dma: imx-sdma: Add synchronization support
  dma: imx-sdma: abort updating channel when it has been terminated
  dma: imx-sdma: disable channel 0 when it timeouts
  dma: imx-sdma: clear channel0 interrupt bit in irq routine

 drivers/dma/imx-sdma.c | 113 +++++++++++++++++++++++++++++++++++--------------
 1 file changed, 82 insertions(+), 31 deletions(-)

-- 
2.4.5

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 00/10] *** imx-sdma: misc fix ***
  2016-05-16  8:37 Jiada Wang
@ 2016-05-16 11:00 ` Vladimir Zapolskiy
  0 siblings, 0 replies; 20+ messages in thread
From: Vladimir Zapolskiy @ 2016-05-16 11:00 UTC (permalink / raw)
  To: Jiada Wang, Shawn Guo, Sascha Hauer
  Cc: vinod.koul, dan.j.williams, dmaengine, linux-kernel, george_davis

Hi Jiada,

On 16.05.2016 11:37, Jiada Wang wrote:
> this patch set contains the following changes
> 1. fix issues in cyclic dma
> 2. add support to SYNC DMA termination
> 3. avoid system hang, when SDMA channel 0 timeouts
> 4. add lock to prevent race condition
> 
> Jiada Wang (10):
>   dma: imx-sdma: use chn_real_count to report residue for UART
>   dma: imx-sdma: don't update BD in isr routine
>   dma: imx-sdma: clear BD_RROR flag before pass it to sdma script
>   dma: imx-sdma: update sdma channel status for cyclic dma
>   dma: imx-sdma: add flag to indicate SDMA channel state
>   dma: imx-sdma: add terminate_all support
>   dma: imx-sdma: Add synchronization support
>   dma: imx-sdma: abort updating channel when it has been terminated
>   dma: imx-sdma: disable channel 0 when it timeouts
>   dma: imx-sdma: clear channel0 interrupt bit in irq routine
> 
>  drivers/dma/imx-sdma.c | 113 +++++++++++++++++++++++++++++++++++--------------
>  1 file changed, 82 insertions(+), 31 deletions(-)
> 

I think it's worth to add Sascha and Shawn to Cc to let them know
about the change.

--
With best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v1 00/10] *** imx-sdma: misc fix ***
@ 2016-05-16  8:37 Jiada Wang
  2016-05-16 11:00 ` Vladimir Zapolskiy
  0 siblings, 1 reply; 20+ messages in thread
From: Jiada Wang @ 2016-05-16  8:37 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams
  Cc: dmaengine, linux-kernel, george_davis, jiada_wang

this patch set contains the following changes
1. fix issues in cyclic dma
2. add support to SYNC DMA termination
3. avoid system hang, when SDMA channel 0 timeouts
4. add lock to prevent race condition

Jiada Wang (10):
  dma: imx-sdma: use chn_real_count to report residue for UART
  dma: imx-sdma: don't update BD in isr routine
  dma: imx-sdma: clear BD_RROR flag before pass it to sdma script
  dma: imx-sdma: update sdma channel status for cyclic dma
  dma: imx-sdma: add flag to indicate SDMA channel state
  dma: imx-sdma: add terminate_all support
  dma: imx-sdma: Add synchronization support
  dma: imx-sdma: abort updating channel when it has been terminated
  dma: imx-sdma: disable channel 0 when it timeouts
  dma: imx-sdma: clear channel0 interrupt bit in irq routine

 drivers/dma/imx-sdma.c | 113 +++++++++++++++++++++++++++++++++++--------------
 1 file changed, 82 insertions(+), 31 deletions(-)

-- 
2.4.5

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2016-10-17  7:39 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-17  3:47 [PATCH v1 00/10] *** imx-sdma: misc fix *** Jiada Wang
2016-05-17  3:47 ` [PATCH 01/10] dma: imx-sdma: use chn_real_count to report residue for UART Jiada Wang
2016-05-17  3:47 ` [PATCH 02/10] dma: imx-sdma: don't update BD in isr routine Jiada Wang
2016-05-17  3:47 ` [PATCH 03/10] dma: imx-sdma: clear BD_RROR flag before pass it to sdma script Jiada Wang
2016-05-17  3:47 ` [PATCH 04/10] dma: imx-sdma: update sdma channel status for cyclic dma Jiada Wang
2016-05-17  3:47 ` [PATCH 05/10] dma: imx-sdma: add flag to indicate SDMA channel state Jiada Wang
2016-05-17  3:47 ` [PATCH 06/10] dma: imx-sdma: add terminate_all support Jiada Wang
2016-05-17  3:47 ` [PATCH 07/10] dma: imx-sdma: Add synchronization support Jiada Wang
2016-05-17  3:47 ` [PATCH 08/10] dma: imx-sdma: abort updating channel when it has been terminated Jiada Wang
2016-05-17  3:47 ` [PATCH 09/10] dma: imx-sdma: disable channel 0 when it timeouts Jiada Wang
2016-05-17  3:47 ` [PATCH 10/10] dma: imx-sdma: clear channel0 interrupt bit in irq routine Jiada Wang
2016-05-17 10:04 ` [PATCH v1 00/10] *** imx-sdma: misc fix *** Vinod Koul
2016-05-25  7:57   ` Jiada Wang
  -- strict thread matches above, loose matches on Subject: below --
2016-05-17  3:48 Jiada Wang
2016-10-12  5:54 ` Jiada Wang
2016-10-17  4:51 ` Jiada Wang
2016-10-17  5:34   ` Vinod Koul
2016-10-17  7:39     ` Jiada Wang
2016-05-16  8:37 Jiada Wang
2016-05-16 11:00 ` Vladimir Zapolskiy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).