linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3] dmaengine: rcar-dmac: don't use DMAC error interrupt
@ 2018-06-15  0:53 Kuninori Morimoto
  2018-06-15  6:20 ` Geert Uytterhoeven
  2018-06-28  4:21 ` Vinod
  0 siblings, 2 replies; 4+ messages in thread
From: Kuninori Morimoto @ 2018-06-15  0:53 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: vkoul, Dan Williams, Magnus Damm, Linux-Renesas,
	Linux Kernel Mailing List, Laurent Pinchart, Kieran Bingham,
	Geert Uytterhoeven, dmaengine,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS


From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

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 <damm+renesas@opensource.se>
[Kuninori: updated patch to adjust DMACHCR/DMAOR]
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Tested-by: Nguyen Viet Dung <nv-dung@jinso.co.jp>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v2 -> v3

 - don't touch to DT binding text
 - tidyup git log
 - added Reviewed-by from Geert

 drivers/dma/sh/rcar-dmac.c | 72 ++++++++++++++--------------------------------
 1 file changed, 22 insertions(+), 50 deletions(-)

diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c
index 2a2ccd9..279c930 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[] = {
-- 
1.9.1


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

* Re: [PATCH v3] dmaengine: rcar-dmac: don't use DMAC error interrupt
  2018-06-15  0:53 [PATCH v3] dmaengine: rcar-dmac: don't use DMAC error interrupt Kuninori Morimoto
@ 2018-06-15  6:20 ` Geert Uytterhoeven
  2018-06-15  7:15   ` Kuninori Morimoto
  2018-06-28  4:21 ` Vinod
  1 sibling, 1 reply; 4+ messages in thread
From: Geert Uytterhoeven @ 2018-06-15  6:20 UTC (permalink / raw)
  To: Kuninori Morimoto
  Cc: vkoul, Dan Williams, Magnus Damm, Linux-Renesas,
	Linux Kernel Mailing List, Laurent Pinchart, Kieran Bingham,
	Geert Uytterhoeven, dmaengine,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS

Hi Morimoto-san,

On Fri, Jun 15, 2018 at 2:53 AM Kuninori Morimoto
<kuninori.morimoto.gx@renesas.com> wrote:
> From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
>
> 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)

Thank you, that explains the rationale!

BTW, how can you trigger an error, for testing?

Thanks again!

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v3] dmaengine: rcar-dmac: don't use DMAC error interrupt
  2018-06-15  6:20 ` Geert Uytterhoeven
@ 2018-06-15  7:15   ` Kuninori Morimoto
  0 siblings, 0 replies; 4+ messages in thread
From: Kuninori Morimoto @ 2018-06-15  7:15 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: vkoul, Dan Williams, Magnus Damm, Linux-Renesas,
	Linux Kernel Mailing List, Laurent Pinchart, Kieran Bingham,
	Geert Uytterhoeven, dmaengine,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS


Hi Geert

> > 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)
> 
> Thank you, that explains the rationale!

Thanks

> BTW, how can you trigger an error, for testing?

We created local patch to break address alignment.

Best regards
---
Kuninori Morimoto

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

* Re: [PATCH v3] dmaengine: rcar-dmac: don't use DMAC error interrupt
  2018-06-15  0:53 [PATCH v3] dmaengine: rcar-dmac: don't use DMAC error interrupt Kuninori Morimoto
  2018-06-15  6:20 ` Geert Uytterhoeven
@ 2018-06-28  4:21 ` Vinod
  1 sibling, 0 replies; 4+ messages in thread
From: Vinod @ 2018-06-28  4:21 UTC (permalink / raw)
  To: Kuninori Morimoto
  Cc: Geert Uytterhoeven, Dan Williams, Magnus Damm, Linux-Renesas,
	Linux Kernel Mailing List, Laurent Pinchart, Kieran Bingham,
	Geert Uytterhoeven, dmaengine,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS

On 15-06-18, 00:53, Kuninori Morimoto wrote:
> 
> From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> 
> 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 <damm+renesas@opensource.se>
> [Kuninori: updated patch to adjust DMACHCR/DMAOR]
> Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> Tested-by: Nguyen Viet Dung <nv-dung@jinso.co.jp>
> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Applied, thanks

-- 
~Vinod

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

end of thread, other threads:[~2018-06-28  4:21 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-15  0:53 [PATCH v3] dmaengine: rcar-dmac: don't use DMAC error interrupt Kuninori Morimoto
2018-06-15  6:20 ` Geert Uytterhoeven
2018-06-15  7:15   ` Kuninori Morimoto
2018-06-28  4:21 ` Vinod

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).