Commit 69e32a58 authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Mark Brown

ASoC: rsnd: Don't stop HW even if a large number of errors occur

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: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent c2dc47d5
...@@ -690,6 +690,8 @@ static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod, ...@@ -690,6 +690,8 @@ static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod,
struct rsnd_dai_stream *io) struct rsnd_dai_stream *io)
{ {
struct rsnd_priv *priv = rsnd_mod_to_priv(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);
spin_lock(&priv->lock); spin_lock(&priv->lock);
...@@ -698,18 +700,19 @@ static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod, ...@@ -698,18 +700,19 @@ static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod,
goto rsnd_src_interrupt_gen2_out; goto rsnd_src_interrupt_gen2_out;
if (rsnd_src_error_record_gen2(mod)) { 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", dev_dbg(dev, "%s[%d] restart\n",
rsnd_mod_name(mod), rsnd_mod_id(mod)); rsnd_mod_name(mod), rsnd_mod_id(mod));
_rsnd_src_stop_gen2(mod); _rsnd_src_stop_gen2(mod);
if (src->err < 1024)
_rsnd_src_start_gen2(mod, io); _rsnd_src_start_gen2(mod, io);
else }
dev_warn(dev, "no more SRC restart\n");
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: rsnd_src_interrupt_gen2_out:
......
...@@ -456,6 +456,7 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, ...@@ -456,6 +456,7 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
{ {
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
struct rsnd_priv *priv = rsnd_mod_to_priv(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); int is_dma = rsnd_ssi_is_dma_mode(mod);
u32 status; u32 status;
bool elapsed = false; bool elapsed = false;
...@@ -489,8 +490,6 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, ...@@ -489,8 +490,6 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
/* DMA only */ /* DMA only */
if (is_dma && (status & (UIRQ | OIRQ))) { if (is_dma && (status & (UIRQ | OIRQ))) {
struct device *dev = rsnd_priv_to_dev(priv);
/* /*
* restart SSI * restart SSI
*/ */
...@@ -498,14 +497,18 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, ...@@ -498,14 +497,18 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
rsnd_mod_name(mod), rsnd_mod_id(mod)); rsnd_mod_name(mod), rsnd_mod_id(mod));
rsnd_ssi_stop(mod, io, priv); rsnd_ssi_stop(mod, io, priv);
if (ssi->err < 1024)
rsnd_ssi_start(mod, io, priv); rsnd_ssi_start(mod, io, priv);
else
dev_warn(dev, "no more SSI restart\n");
} }
rsnd_ssi_record_error(ssi, status); 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: rsnd_ssi_interrupt_out:
spin_unlock(&priv->lock); spin_unlock(&priv->lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment