Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / Atom feed
From: Philipp Puschmann <philipp.puschmann@emlix.com>
To: linux-kernel@vger.kernel.org
Cc: fugang.duan@nxp.com,
	Philipp Puschmann <philipp.puschmann@emlix.com>,
	festevam@gmail.com, s.hauer@pengutronix.de, vkoul@kernel.org,
	linux-imx@nxp.com, kernel@pengutronix.de,
	dan.j.williams@intel.com, yibin.gong@nxp.com,
	shawnguo@kernel.org, dmaengine@vger.kernel.or,
	linux-arm-kernel@lists.infradead.org, l.stach@pengutronix.de
Subject: [PATCH v2 2/3] dmaengine: imx-sdma: fix dma freezes
Date: Thu, 19 Sep 2019 12:23:18 +0200
Message-ID: <20190919102319.23368-3-philipp.puschmann@emlix.com> (raw)
In-Reply-To: <20190919102319.23368-1-philipp.puschmann@emlix.com>

For some years and since many kernel versions there are reports that the
RX UART SDMA channel stops working at some point. The workaround was to
disable DMA for RX. This commit tries to fix the problem itself.

Due to its license i wasn't able to debug the sdma script itself but it
somehow leads to blocking the scheduling of the channel script when a
running sdma script does not find any free descriptor in the ring to put
its data into.

If we detect such a potential case we manually restart the channel.

As sdmac->desc is constant we can move desc out of the loop.

Signed-off-by: Philipp Puschmann <philipp.puschmann@emlix.com>
Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
---

Changelog v2:
 - clarify comment and commit description

 drivers/dma/imx-sdma.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index e029a2443cfc..a32b5962630e 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -775,21 +775,23 @@ static void sdma_start_desc(struct sdma_channel *sdmac)
 static void sdma_update_channel_loop(struct sdma_channel *sdmac)
 {
 	struct sdma_buffer_descriptor *bd;
-	int error = 0;
-	enum dma_status	old_status = sdmac->status;
+	struct sdma_desc *desc = sdmac->desc;
+	int error = 0, cnt = 0;
+	enum dma_status old_status = sdmac->status;
 
 	/*
 	 * loop mode. Iterate over descriptors, re-setup them and
 	 * call callback function.
 	 */
-	while (sdmac->desc) {
-		struct sdma_desc *desc = sdmac->desc;
+	while (desc) {
 
 		bd = &desc->bd[desc->buf_tail];
 
 		if (bd->mode.status & BD_DONE)
 			break;
 
+		cnt++;
+
 		if (bd->mode.status & BD_RROR) {
 			bd->mode.status &= ~BD_RROR;
 			sdmac->status = DMA_ERROR;
@@ -822,6 +824,17 @@ static void sdma_update_channel_loop(struct sdma_channel *sdmac)
 		if (error)
 			sdmac->status = old_status;
 	}
+
+	/* In some situations it may happen that the sdma does not found any
+	 * usable descriptor in the ring to put data into. The channel is
+	 * stopped then. While there is no specific error condition we can
+	 * check for, a necessary condition is that all available buffers for
+	 * the current channel have been written to by the sdma script. In
+	 * this case and after we have made the buffers available again,
+	 * we restart the channel.
+	 */
+	if (cnt >= desc->num_bd)
+		sdma_enable_channel(sdmac->sdma, sdmac->channel);
 }
 
 static void mxc_sdma_handle_channel_normal(struct sdma_channel *data)
-- 
2.23.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply index

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-11 14:49 [PATCH 0/4] Fix UART DMA freezes for iMX6 Philipp Puschmann
2019-09-11 14:49 ` [PATCH 1/4] dmaengine: imx-sdma: fix buffer ownership Philipp Puschmann
2019-09-16 14:17   ` Lucas Stach
2019-09-19  9:20     ` Philipp Puschmann
2019-09-11 14:49 ` [PATCH 2/4] dmaengine: imx-sdma: fix dma freezes Philipp Puschmann
2019-09-16 14:22   ` Lucas Stach
2019-09-11 14:49 ` [PATCH 3/4] serial: imx: adapt rx buffer and dma periods Philipp Puschmann
2019-09-16 14:24   ` Lucas Stach
2019-09-11 14:49 ` [PATCH 4/4] dmaengine: imx-sdma: drop redundant variable Philipp Puschmann
2019-09-16 14:30   ` Lucas Stach
2019-09-12 15:31 ` [PATCH 0/4] Fix UART DMA freezes for iMX6 Fabio Estevam
2019-09-12 18:23 ` Fabio Estevam
2019-09-16 13:55   ` Philipp Puschmann
2019-09-16 14:00     ` Fabio Estevam
2019-09-16 14:10     ` [EXT] " Andy Duan
2019-09-16  8:02 ` Robin Gong
2019-09-16 13:41   ` Philipp Puschmann
2019-09-19 10:23 ` [PATCH v2 0/3] Fix UART DMA freezes for i.MX SOCs Philipp Puschmann
2019-09-19 10:23   ` [PATCH v2 1/3] dmaengine: imx-sdma: fix buffer ownership Philipp Puschmann
2019-09-19 10:27     ` Lucas Stach
2019-09-19 10:34       ` Philipp Puschmann
2019-09-19 10:23   ` Philipp Puschmann [this message]
2019-09-19 10:23   ` [PATCH v2 3/3] dmaengine: imx-sdma: drop redundant variable Philipp Puschmann
2019-09-19 10:33   ` [PATCH v2 0/3] Fix UART DMA freezes for i.MX SOCs Fabio Estevam
2019-09-19 10:45   ` [PATCH v3 " Philipp Puschmann
2019-09-19 10:45     ` [PATCH v3 1/3] dmaengine: imx-sdma: fix buffer ownership Philipp Puschmann
2019-09-19 11:37       ` Fabio Estevam
2019-09-19 11:42         ` Philipp Puschmann
2019-09-19 10:45     ` [PATCH v3 2/3] dmaengine: imx-sdma: fix dma freezes Philipp Puschmann
2019-09-19 10:45     ` [PATCH v3 3/3] dmaengine: imx-sdma: drop redundant variable Philipp Puschmann

Reply instructions:

You may reply publically to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190919102319.23368-3-philipp.puschmann@emlix.com \
    --to=philipp.puschmann@emlix.com \
    --cc=dan.j.williams@intel.com \
    --cc=dmaengine@vger.kernel.or \
    --cc=festevam@gmail.com \
    --cc=fugang.duan@nxp.com \
    --cc=kernel@pengutronix.de \
    --cc=l.stach@pengutronix.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-imx@nxp.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=s.hauer@pengutronix.de \
    --cc=shawnguo@kernel.org \
    --cc=vkoul@kernel.org \
    --cc=yibin.gong@nxp.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Linux-ARM-Kernel Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-arm-kernel/0 linux-arm-kernel/git/0.git
	git clone --mirror https://lore.kernel.org/linux-arm-kernel/1 linux-arm-kernel/git/1.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-arm-kernel linux-arm-kernel/ https://lore.kernel.org/linux-arm-kernel \
		linux-arm-kernel@lists.infradead.org
	public-inbox-index linux-arm-kernel

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.infradead.lists.linux-arm-kernel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git