[alsa-devel] [PATCH 10/18] ASoC: rsnd: Don't stop HW even if a large number of errors occur

Kuninori Morimoto kuninori.morimoto.gx at renesas.com
Mon Oct 26 09:41:36 CET 2015


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

Current SSI/SRC restarts HW if under/over flow happened to avoid L/R
invert issue. But it will stop HW if too many error happen.
But if it stops on HW, other side under/over flow happen. OTHA, it will
be forever loop interrupt if something strange error happen on
HW/driver without escape route of large number error.

To avoid this issue, it indicates error message if large number error
occur, and disables error interrupt.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
---
 sound/soc/sh/rcar/src.c | 17 ++++++++++-------
 sound/soc/sh/rcar/ssi.c | 15 +++++++++------
 2 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index 3f6993f..0d96ce5 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -690,6 +690,8 @@ static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod,
 				      struct rsnd_dai_stream *io)
 {
 	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
+	struct rsnd_src *src = rsnd_mod_to_src(mod);
+	struct device *dev = rsnd_priv_to_dev(priv);
 
 	spin_lock(&priv->lock);
 
@@ -698,18 +700,19 @@ static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod,
 		goto rsnd_src_interrupt_gen2_out;
 
 	if (rsnd_src_error_record_gen2(mod)) {
-		struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
-		struct rsnd_src *src = rsnd_mod_to_src(mod);
-		struct device *dev = rsnd_priv_to_dev(priv);
 
 		dev_dbg(dev, "%s[%d] restart\n",
 			rsnd_mod_name(mod), rsnd_mod_id(mod));
 
 		_rsnd_src_stop_gen2(mod);
-		if (src->err < 1024)
-			_rsnd_src_start_gen2(mod, io);
-		else
-			dev_warn(dev, "no more SRC restart\n");
+		_rsnd_src_start_gen2(mod, io);
+	}
+
+	if (src->err > 1024) {
+		rsnd_src_irq_disable_gen2(mod);
+
+		dev_warn(dev, "no more %s[%d] restart\n",
+			 rsnd_mod_name(mod), rsnd_mod_id(mod));
 	}
 
 rsnd_src_interrupt_gen2_out:
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index c7d9434..86e51ce 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -456,6 +456,7 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
 {
 	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
 	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
+	struct device *dev = rsnd_priv_to_dev(priv);
 	int is_dma = rsnd_ssi_is_dma_mode(mod);
 	u32 status;
 	bool elapsed = false;
@@ -489,8 +490,6 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
 
 	/* DMA only */
 	if (is_dma && (status & (UIRQ | OIRQ))) {
-		struct device *dev = rsnd_priv_to_dev(priv);
-
 		/*
 		 * restart SSI
 		 */
@@ -498,14 +497,18 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
 			rsnd_mod_name(mod), rsnd_mod_id(mod));
 
 		rsnd_ssi_stop(mod, io, priv);
-		if (ssi->err < 1024)
-			rsnd_ssi_start(mod, io, priv);
-		else
-			dev_warn(dev, "no more SSI restart\n");
+		rsnd_ssi_start(mod, io, priv);
 	}
 
 	rsnd_ssi_record_error(ssi, status);
 
+	if (ssi->err > 1024) {
+		rsnd_ssi_irq_disable(mod);
+
+		dev_warn(dev, "no more %s[%d] restart\n",
+			 rsnd_mod_name(mod), rsnd_mod_id(mod));
+	}
+
 rsnd_ssi_interrupt_out:
 	spin_unlock(&priv->lock);
 
-- 
1.9.1



More information about the Alsa-devel mailing list