alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/11] ASoC: rsnd: tidyup and fixup rare MIXer issue
@ 2021-05-27  2:39 Kuninori Morimoto
  2021-05-27  2:40 ` [PATCH v2 01/11] ASoC: rsnd: call unregister for null_hw when removed Kuninori Morimoto
                   ` (11 more replies)
  0 siblings, 12 replies; 13+ messages in thread
From: Kuninori Morimoto @ 2021-05-27  2:39 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux-ALSA


Hi Mark

These are v2 of tidyup patch, and rare MIXer issue fixup patch for
Renesas Sound driver.

1 - 6 : tidyup for rsnd driver
7     : add debugfs support
8     : fixup rare MIXer issue
9 - 11: tidyup for rsnd driver

v1 -> v2
	- add adg.c fixup patch (= [01/11])
	- tidyup compile error when CONFIG_DEBUG_FS was not selected (= [07/11])

Link: https://lore.kernel.org/r/87mtsjof3w.wl-kuninori.morimoto.gx@renesas.com

Kuninori Morimoto (11):
   1 ASoC: rsnd: call unregister for null_hw when removed
   2 ASoC: rsnd: ignore runtime NULL case at rsnd_runtime_channel_original_with_params()
   3 ASoC: rsnd: attach SSIU when SSI was DMA mode
   4 ASoC: rsnd: check BUIF error everytime
   5 ASoC: rsnd: indicate unknown error at rsnd_dai_call()
   6 ASoC: rsnd: incidate irq error message
   7 ASoC: rsnd: add debugfs support
   8 ASoC: rsnd: protect mod->status
   9 ASoC: rsnd: implement BUSIF related code in ssiu.c
  10 ASoC: rsnd: tidyup rsnd_ssiu_busif_err_status_clear()
  11 ASoC: rsnd: tidyup rsnd_ssiu_busif_err_irq_ctrl()

 sound/soc/sh/rcar/Makefile  |   2 +-
 sound/soc/sh/rcar/adg.c     |  44 +++++++----
 sound/soc/sh/rcar/cmd.c     |  14 ++++
 sound/soc/sh/rcar/core.c    |  65 +++++++++-------
 sound/soc/sh/rcar/ctu.c     |  14 ++++
 sound/soc/sh/rcar/debugfs.c |  96 +++++++++++++++++++++++
 sound/soc/sh/rcar/dma.c     |  31 ++++++--
 sound/soc/sh/rcar/dvc.c     |  14 ++++
 sound/soc/sh/rcar/gen.c     |   9 +++
 sound/soc/sh/rcar/mix.c     |  14 ++++
 sound/soc/sh/rcar/rsnd.h    |  40 ++++++++--
 sound/soc/sh/rcar/src.c     |  26 ++++++-
 sound/soc/sh/rcar/ssi.c     | 148 +++++++++---------------------------
 sound/soc/sh/rcar/ssiu.c    | 134 ++++++++++++++++++++++++++++----
 14 files changed, 465 insertions(+), 186 deletions(-)
 create mode 100644 sound/soc/sh/rcar/debugfs.c

-- 
2.25.1


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

* [PATCH v2 01/11] ASoC: rsnd: call unregister for null_hw when removed
  2021-05-27  2:39 [PATCH v2 00/11] ASoC: rsnd: tidyup and fixup rare MIXer issue Kuninori Morimoto
@ 2021-05-27  2:40 ` Kuninori Morimoto
  2021-05-27  2:40 ` [PATCH v2 02/11] ASoC: rsnd: ignore runtime NULL case at rsnd_runtime_channel_original_with_params() Kuninori Morimoto
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Kuninori Morimoto @ 2021-05-27  2:40 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux-ALSA


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

commit d6956a7dde6fb ("ASoC: rsnd: add null CLOCKIN support")
added null_clk, but it is using local static valuable.
It will be leaked if rsnd driver was removed.
This patch moves it to priv, and call unregister when removing.

Fixes: d6956a7dde6fb ("ASoC: rsnd: add null CLOCKIN support")
Link: https://lore.kernel.org/r/87tumsoe2p.wl-kuninori.morimoto.gx@renesas.com
Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v1 -> v2
	- new patch

 sound/soc/sh/rcar/adg.c  | 9 +++++----
 sound/soc/sh/rcar/rsnd.h | 1 +
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index e13eb201d550..774a72a7b6a2 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -392,10 +392,9 @@ void rsnd_adg_clk_control(struct rsnd_priv *priv, int enable)
 #define NULL_CLK "rsnd_adg_null"
 static struct clk *rsnd_adg_null_clk_get(struct rsnd_priv *priv)
 {
-	static struct clk_hw *hw;
 	struct device *dev = rsnd_priv_to_dev(priv);
 
-	if (!hw) {
+	if (!priv->null_hw) {
 		struct clk_hw *_hw;
 		int ret;
 
@@ -407,10 +406,10 @@ static struct clk *rsnd_adg_null_clk_get(struct rsnd_priv *priv)
 		if (ret < 0)
 			clk_hw_unregister_fixed_rate(_hw);
 
-		hw = _hw;
+		priv->null_hw = _hw;
 	}
 
-	return clk_hw_get_clk(hw, NULL_CLK);
+	return clk_hw_get_clk(priv->null_hw, NULL_CLK);
 }
 
 static void rsnd_adg_get_clkin(struct rsnd_priv *priv,
@@ -649,6 +648,8 @@ void rsnd_adg_remove(struct rsnd_priv *priv)
 	for_each_rsnd_clkout(clk, adg, i)
 		if (adg->clkout[i])
 			clk_unregister_fixed_rate(adg->clkout[i]);
+	if (priv->null_hw)
+		clk_hw_unregister_fixed_rate(priv->null_hw);
 
 	of_clk_del_provider(np);
 
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 1255a85151db..19e73a1ddb16 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -635,6 +635,7 @@ struct rsnd_priv {
 	 * below value will be filled on rsnd_adg_probe()
 	 */
 	void *adg;
+	struct clk_hw *null_hw;
 
 	/*
 	 * below value will be filled on rsnd_dma_probe()
-- 
2.25.1


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

* [PATCH v2 02/11] ASoC: rsnd: ignore runtime NULL case at rsnd_runtime_channel_original_with_params()
  2021-05-27  2:39 [PATCH v2 00/11] ASoC: rsnd: tidyup and fixup rare MIXer issue Kuninori Morimoto
  2021-05-27  2:40 ` [PATCH v2 01/11] ASoC: rsnd: call unregister for null_hw when removed Kuninori Morimoto
@ 2021-05-27  2:40 ` Kuninori Morimoto
  2021-05-27  2:40 ` [PATCH v2 03/11] ASoC: rsnd: attach SSIU when SSI was DMA mode Kuninori Morimoto
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Kuninori Morimoto @ 2021-05-27  2:40 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux-ALSA

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

runtime might be NULL. Let's ignore such case.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 sound/soc/sh/rcar/core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 83c815008472..0d54c09c3c96 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -267,8 +267,9 @@ int rsnd_runtime_channel_original_with_params(struct rsnd_dai_stream *io,
 	 */
 	if (params)
 		return params_channels(params);
-	else
+	else if (runtime)
 		return runtime->channels;
+	return 0;
 }
 
 int rsnd_runtime_channel_after_ctu_with_params(struct rsnd_dai_stream *io,
-- 
2.25.1


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

* [PATCH v2 03/11] ASoC: rsnd: attach SSIU when SSI was DMA mode
  2021-05-27  2:39 [PATCH v2 00/11] ASoC: rsnd: tidyup and fixup rare MIXer issue Kuninori Morimoto
  2021-05-27  2:40 ` [PATCH v2 01/11] ASoC: rsnd: call unregister for null_hw when removed Kuninori Morimoto
  2021-05-27  2:40 ` [PATCH v2 02/11] ASoC: rsnd: ignore runtime NULL case at rsnd_runtime_channel_original_with_params() Kuninori Morimoto
@ 2021-05-27  2:40 ` Kuninori Morimoto
  2021-05-27  2:41 ` [PATCH v2 04/11] ASoC: rsnd: check BUIF error everytime Kuninori Morimoto
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Kuninori Morimoto @ 2021-05-27  2:40 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux-ALSA


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

SSIU is not needed if SSI was PIO mode.
This patch ignores such case.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 sound/soc/sh/rcar/rsnd.h | 1 +
 sound/soc/sh/rcar/ssi.c  | 4 +---
 sound/soc/sh/rcar/ssiu.c | 6 +++++-
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 19e73a1ddb16..aec54552474d 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -777,6 +777,7 @@ void rsnd_ssi_remove(struct rsnd_priv *priv);
 struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
 int rsnd_ssi_use_busif(struct rsnd_dai_stream *io);
 u32 rsnd_ssi_multi_secondaries_runtime(struct rsnd_dai_stream *io);
+int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod);
 
 #define rsnd_ssi_is_pin_sharing(io)	\
 	__rsnd_ssi_is_pin_sharing(rsnd_io_to_mod_ssi(io))
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index e29482c26d6a..bd479714b22e 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -117,8 +117,6 @@ struct rsnd_ssi {
 	(rsnd_ssi_run_mods(io) & (1 << rsnd_mod_id(mod)))
 #define rsnd_ssi_can_output_clk(mod) (!__rsnd_ssi_is_pin_sharing(mod))
 
-static int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod);
-
 int rsnd_ssi_use_busif(struct rsnd_dai_stream *io)
 {
 	struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io);
@@ -1147,7 +1145,7 @@ static struct rsnd_mod_ops rsnd_ssi_dma_ops = {
 	.get_status	= rsnd_ssi_get_status,
 };
 
-static int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod)
+int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod)
 {
 	return mod->ops == &rsnd_ssi_dma_ops;
 }
diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c
index 852cdeedf7e9..6896ff0bc89d 100644
--- a/sound/soc/sh/rcar/ssiu.c
+++ b/sound/soc/sh/rcar/ssiu.c
@@ -336,16 +336,20 @@ static void rsnd_parse_connect_ssiu_compatible(struct rsnd_priv *priv,
 {
 	struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
 	struct rsnd_ssiu *ssiu;
+	int is_dma_mode;
 	int i;
 
 	if (!ssi_mod)
 		return;
 
+	is_dma_mode = rsnd_ssi_is_dma_mode(ssi_mod);
+
 	/* select BUSIF0 */
 	for_each_rsnd_ssiu(ssiu, priv, i) {
 		struct rsnd_mod *mod = rsnd_mod_get(ssiu);
 
-		if ((rsnd_mod_id(ssi_mod) == rsnd_mod_id(mod)) &&
+		if (is_dma_mode &&
+		    (rsnd_mod_id(ssi_mod) == rsnd_mod_id(mod)) &&
 		    (rsnd_mod_id_sub(mod) == 0)) {
 			rsnd_dai_connect(mod, io, mod->type);
 			return;
-- 
2.25.1


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

* [PATCH v2 04/11] ASoC: rsnd: check BUIF error everytime
  2021-05-27  2:39 [PATCH v2 00/11] ASoC: rsnd: tidyup and fixup rare MIXer issue Kuninori Morimoto
                   ` (2 preceding siblings ...)
  2021-05-27  2:40 ` [PATCH v2 03/11] ASoC: rsnd: attach SSIU when SSI was DMA mode Kuninori Morimoto
@ 2021-05-27  2:41 ` Kuninori Morimoto
  2021-05-27  2:41 ` [PATCH v2 05/11] ASoC: rsnd: indicate unknown error at rsnd_dai_call() Kuninori Morimoto
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Kuninori Morimoto @ 2021-05-27  2:41 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux-ALSA


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

Current ssi.c checks BUSIF when TDM mode, but it should be checked
everytime.
This patch do it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 sound/soc/sh/rcar/ssi.c | 17 +++--------------
 1 file changed, 3 insertions(+), 14 deletions(-)

diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index bd479714b22e..2dceac994b37 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -535,8 +535,7 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod,
 	}
 
 	/* enable busif buffer over/under run interrupt. */
-	if (is_tdm || is_tdm_split)
-		rsnd_ssi_busif_err_irq_enable(mod);
+	rsnd_ssi_busif_err_irq_enable(mod);
 
 init_end:
 	ssi->cr_own	= cr_own;
@@ -592,10 +591,6 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod,
 {
 	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
 	struct device *dev = rsnd_priv_to_dev(priv);
-	int is_tdm, is_tdm_split;
-
-	is_tdm		= rsnd_runtime_is_tdm(io);
-	is_tdm_split	= rsnd_runtime_is_tdm_split(io);
 
 	if (!rsnd_ssi_is_run_mods(mod, io))
 		return 0;
@@ -618,8 +613,7 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod,
 	}
 
 	/* disable busif buffer over/under run interrupt. */
-	if (is_tdm || is_tdm_split)
-		rsnd_ssi_busif_err_irq_disable(mod);
+	rsnd_ssi_busif_err_irq_disable(mod);
 
 	return 0;
 }
@@ -773,10 +767,6 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
 	u32 status;
 	bool elapsed = false;
 	bool stop = false;
-	int is_tdm, is_tdm_split;
-
-	is_tdm		= rsnd_runtime_is_tdm(io);
-	is_tdm_split	= rsnd_runtime_is_tdm_split(io);
 
 	spin_lock(&priv->lock);
 
@@ -798,8 +788,7 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
 		stop = true;
 	}
 
-	if (is_tdm || is_tdm_split)
-		stop |= rsnd_ssi_busif_err_status_clear(mod);
+	stop |= rsnd_ssi_busif_err_status_clear(mod);
 
 	rsnd_ssi_status_clear(mod);
 rsnd_ssi_interrupt_out:
-- 
2.25.1


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

* [PATCH v2 05/11] ASoC: rsnd: indicate unknown error at rsnd_dai_call()
  2021-05-27  2:39 [PATCH v2 00/11] ASoC: rsnd: tidyup and fixup rare MIXer issue Kuninori Morimoto
                   ` (3 preceding siblings ...)
  2021-05-27  2:41 ` [PATCH v2 04/11] ASoC: rsnd: check BUIF error everytime Kuninori Morimoto
@ 2021-05-27  2:41 ` Kuninori Morimoto
  2021-05-27  2:41 ` [PATCH v2 06/11] ASoC: rsnd: incidate irq error message Kuninori Morimoto
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Kuninori Morimoto @ 2021-05-27  2:41 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux-ALSA


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

Current rsnd_dai_call() doesn't indicate error message,
thus it is very difficult to know the issue
when strange things happen.
This patch indicates error for it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 sound/soc/sh/rcar/core.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 0d54c09c3c96..3de04a25e357 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -543,7 +543,7 @@ static int rsnd_status_update(u32 *status,
 	int func_call	= (val == timing);
 
 	if (next_val == 0xF) /* underflow case */
-		func_call = 0;
+		func_call = -1;
 	else
 		*status = (*status & ~mask) + (next_val << shift);
 
@@ -567,11 +567,12 @@ static int rsnd_status_update(u32 *status,
 		rsnd_dbg_dai_call(dev, "%s\t0x%08x %s\n",		\
 			rsnd_mod_name(mod), *status,	\
 			(func_call && (mod)->ops->fn) ? #fn : "");	\
-		if (func_call && (mod)->ops->fn)			\
+		if (func_call > 0 && (mod)->ops->fn)			\
 			tmp = (mod)->ops->fn(mod, io, param);		\
-		if (tmp && (tmp != -EPROBE_DEFER))			\
-			dev_err(dev, "%s : %s error %d\n",		\
-				rsnd_mod_name(mod), #fn, tmp);		\
+		if (unlikely(func_call < 0) ||				\
+		    unlikely(tmp && (tmp != -EPROBE_DEFER)))		\
+			dev_err(dev, "%s : %s error (%d, %d)\n",	\
+				rsnd_mod_name(mod), #fn, tmp, func_call);\
 		ret |= tmp;						\
 	}								\
 	ret;								\
-- 
2.25.1


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

* [PATCH v2 06/11] ASoC: rsnd: incidate irq error message
  2021-05-27  2:39 [PATCH v2 00/11] ASoC: rsnd: tidyup and fixup rare MIXer issue Kuninori Morimoto
                   ` (4 preceding siblings ...)
  2021-05-27  2:41 ` [PATCH v2 05/11] ASoC: rsnd: indicate unknown error at rsnd_dai_call() Kuninori Morimoto
@ 2021-05-27  2:41 ` Kuninori Morimoto
  2021-05-27  2:41 ` [PATCH v2 07/11] ASoC: rsnd: add debugfs support Kuninori Morimoto
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Kuninori Morimoto @ 2021-05-27  2:41 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux-ALSA


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

Current rsnd is using dev_dbg() if irq error happen,
but it makes debug very difficult if some strange things happen.
This patch uses dev_info() for it, and rename the macro name.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 sound/soc/sh/rcar/rsnd.h |  5 +++--
 sound/soc/sh/rcar/src.c  |  6 +++---
 sound/soc/sh/rcar/ssi.c  | 14 +++++++-------
 3 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index aec54552474d..9736a94b9c39 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -881,9 +881,10 @@ void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type);
  *
  * #define RSND_DEBUG_NO_IRQ_STATUS 1
  */
-#define rsnd_dbg_irq_status(dev, param...)		\
+#define rsnd_print_irq_status(dev, param...) do {	\
 	if (!IS_BUILTIN(RSND_DEBUG_NO_IRQ_STATUS))	\
-		dev_dbg(dev, param)
+		dev_info(dev, param);			\
+} while (0)
 
 /*
  * If you don't need rsnd_dai_call debug message,
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index 628af8f3920d..7a7d6dc335a4 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -17,7 +17,7 @@
 /*
  * you can enable below define if you don't need
  * SSI interrupt status debug message when debugging
- * see rsnd_dbg_irq_status()
+ * see rsnd_print_irq_status()
  *
  * #define RSND_DEBUG_NO_IRQ_STATUS 1
  */
@@ -421,8 +421,8 @@ static bool rsnd_src_error_occurred(struct rsnd_mod *mod)
 	status0 = rsnd_mod_read(mod, SCU_SYS_STATUS0);
 	status1 = rsnd_mod_read(mod, SCU_SYS_STATUS1);
 	if ((status0 & val0) || (status1 & val1)) {
-		rsnd_dbg_irq_status(dev, "%s err status : 0x%08x, 0x%08x\n",
-			rsnd_mod_name(mod), status0, status1);
+		rsnd_print_irq_status(dev, "%s err status : 0x%08x, 0x%08x\n",
+				      rsnd_mod_name(mod), status0, status1);
 
 		ret = true;
 	}
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 2dceac994b37..ac920800af37 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -11,7 +11,7 @@
 /*
  * you can enable below define if you don't need
  * SSI interrupt status debug message when debugging
- * see rsnd_dbg_irq_status()
+ * see rsnd_print_irq_status()
  *
  * #define RSND_DEBUG_NO_IRQ_STATUS 1
  */
@@ -418,8 +418,8 @@ static bool rsnd_ssi_busif_err_status_clear(struct rsnd_mod *mod)
 			status &= 0xf << (id * 4);
 
 			if (status) {
-				rsnd_dbg_irq_status(dev, "%s err status : 0x%08x\n",
-						    rsnd_mod_name(mod), status);
+				rsnd_print_irq_status(dev, "%s err status : 0x%08x\n",
+						      rsnd_mod_name(mod), status);
 				rsnd_mod_write(mod,
 					       SSI_SYS_STATUS(i * 2),
 					       0xf << (id * 4));
@@ -433,8 +433,8 @@ static bool rsnd_ssi_busif_err_status_clear(struct rsnd_mod *mod)
 			status &= 0xf << 4;
 
 			if (status) {
-				rsnd_dbg_irq_status(dev, "%s err status : 0x%08x\n",
-						    rsnd_mod_name(mod), status);
+				rsnd_print_irq_status(dev, "%s err status : 0x%08x\n",
+						      rsnd_mod_name(mod), status);
 				rsnd_mod_write(mod,
 					       SSI_SYS_STATUS((i * 2) + 1),
 					       0xf << 4);
@@ -782,8 +782,8 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
 
 	/* DMA only */
 	if (is_dma && (status & (UIRQ | OIRQ))) {
-		rsnd_dbg_irq_status(dev, "%s err status : 0x%08x\n",
-			rsnd_mod_name(mod), status);
+		rsnd_print_irq_status(dev, "%s err status : 0x%08x\n",
+				      rsnd_mod_name(mod), status);
 
 		stop = true;
 	}
-- 
2.25.1


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

* [PATCH v2 07/11] ASoC: rsnd: add debugfs support
  2021-05-27  2:39 [PATCH v2 00/11] ASoC: rsnd: tidyup and fixup rare MIXer issue Kuninori Morimoto
                   ` (5 preceding siblings ...)
  2021-05-27  2:41 ` [PATCH v2 06/11] ASoC: rsnd: incidate irq error message Kuninori Morimoto
@ 2021-05-27  2:41 ` Kuninori Morimoto
  2021-05-27  2:41 ` [PATCH v2 08/11] ASoC: rsnd: protect mod->status Kuninori Morimoto
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Kuninori Morimoto @ 2021-05-27  2:41 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux-ALSA


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

Current rsnd supports #define DEBUG, but it is not helpful
if issue happen after 4-5 hours.
This patch adds debugfs support for it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 sound/soc/sh/rcar/Makefile  |  2 +-
 sound/soc/sh/rcar/adg.c     | 35 ++++++++++----
 sound/soc/sh/rcar/cmd.c     | 14 ++++++
 sound/soc/sh/rcar/core.c    |  1 +
 sound/soc/sh/rcar/ctu.c     | 14 ++++++
 sound/soc/sh/rcar/debugfs.c | 96 +++++++++++++++++++++++++++++++++++++
 sound/soc/sh/rcar/dma.c     | 31 ++++++++++--
 sound/soc/sh/rcar/dvc.c     | 14 ++++++
 sound/soc/sh/rcar/gen.c     |  9 ++++
 sound/soc/sh/rcar/mix.c     | 14 ++++++
 sound/soc/sh/rcar/rsnd.h    | 20 ++++++++
 sound/soc/sh/rcar/src.c     | 20 ++++++++
 sound/soc/sh/rcar/ssi.c     | 29 +++++++++++
 sound/soc/sh/rcar/ssiu.c    | 14 ++++++
 14 files changed, 298 insertions(+), 15 deletions(-)
 create mode 100644 sound/soc/sh/rcar/debugfs.c

diff --git a/sound/soc/sh/rcar/Makefile b/sound/soc/sh/rcar/Makefile
index 5d1ff8ef26f9..d07eccfa3ac2 100644
--- a/sound/soc/sh/rcar/Makefile
+++ b/sound/soc/sh/rcar/Makefile
@@ -1,3 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
-snd-soc-rcar-objs	:= core.o gen.o dma.o adg.o ssi.o ssiu.o src.o ctu.o mix.o dvc.o cmd.o
+snd-soc-rcar-objs	:= core.o gen.o dma.o adg.o ssi.o ssiu.o src.o ctu.o mix.o dvc.o cmd.o debugfs.o
 obj-$(CONFIG_SND_SOC_RCAR)	+= snd-soc-rcar.o
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 774a72a7b6a2..78916332c22f 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -583,32 +583,49 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
 	adg->rbgb = rbgb;
 }
 
-#ifdef DEBUG
-static void rsnd_adg_clk_dbg_info(struct rsnd_priv *priv, struct rsnd_adg *adg)
+#if defined(DEBUG) || defined(CONFIG_DEBUG_FS)
+static void dbg_msg(struct device *dev, struct seq_file *m,
+				   const char *fmt, ...)
 {
+	char msg[128];
+	va_list args;
+
+	va_start(args, fmt);
+	vsnprintf(msg, sizeof(msg), fmt, args);
+	va_end(args);
+
+	if (m)
+		seq_puts(m, msg);
+	else
+		dev_dbg(dev, "%s", msg);
+}
+
+void rsnd_adg_clk_dbg_info(struct rsnd_priv *priv, struct seq_file *m)
+{
+	struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
 	struct device *dev = rsnd_priv_to_dev(priv);
 	struct clk *clk;
 	int i;
 
 	for_each_rsnd_clk(clk, adg, i)
-		dev_dbg(dev, "%s    : %pa : %ld\n",
+		dbg_msg(dev, m, "%s    : %pa : %ld\n",
 			clk_name[i], clk, clk_get_rate(clk));
 
-	dev_dbg(dev, "BRGCKR = 0x%08x, BRRA/BRRB = 0x%x/0x%x\n",
+	dbg_msg(dev, m, "BRGCKR = 0x%08x, BRRA/BRRB = 0x%x/0x%x\n",
 		adg->ckr, adg->rbga, adg->rbgb);
-	dev_dbg(dev, "BRGA (for 44100 base) = %d\n", adg->rbga_rate_for_441khz);
-	dev_dbg(dev, "BRGB (for 48000 base) = %d\n", adg->rbgb_rate_for_48khz);
+	dbg_msg(dev, m, "BRGA (for 44100 base) = %d\n", adg->rbga_rate_for_441khz);
+	dbg_msg(dev, m, "BRGB (for 48000 base) = %d\n", adg->rbgb_rate_for_48khz);
 
 	/*
 	 * Actual CLKOUT will be exchanged in rsnd_adg_ssi_clk_try_start()
 	 * by BRGCKR::BRGCKR_31
 	 */
 	for_each_rsnd_clkout(clk, adg, i)
-		dev_dbg(dev, "clkout %d : %pa : %ld\n", i,
+		dbg_msg(dev, m, "clkout %d : %pa : %ld\n", i,
 			clk, clk_get_rate(clk));
 }
 #else
-#define rsnd_adg_clk_dbg_info(priv, adg)
+#define rsnd_adg_clk_dbg_info(priv, m)
 #endif
 
 int rsnd_adg_probe(struct rsnd_priv *priv)
@@ -628,11 +645,11 @@ int rsnd_adg_probe(struct rsnd_priv *priv)
 
 	rsnd_adg_get_clkin(priv, adg);
 	rsnd_adg_get_clkout(priv, adg);
-	rsnd_adg_clk_dbg_info(priv, adg);
 
 	priv->adg = adg;
 
 	rsnd_adg_clk_enable(priv);
+	rsnd_adg_clk_dbg_info(priv, NULL);
 
 	return 0;
 }
diff --git a/sound/soc/sh/rcar/cmd.c b/sound/soc/sh/rcar/cmd.c
index 9fdb37c2cbc2..329e6ab1b222 100644
--- a/sound/soc/sh/rcar/cmd.c
+++ b/sound/soc/sh/rcar/cmd.c
@@ -114,12 +114,26 @@ static int rsnd_cmd_stop(struct rsnd_mod *mod,
 	return 0;
 }
 
+#ifdef CONFIG_DEBUG_FS
+static void rsnd_cmd_debug_info(struct seq_file *m,
+				struct rsnd_dai_stream *io,
+				struct rsnd_mod *mod)
+{
+	rsnd_debugfs_mod_reg_show(m, mod, RSND_GEN2_SCU,
+				  0x180 + rsnd_mod_id_raw(mod) * 0x20, 0x30);
+}
+#define DEBUG_INFO .debug_info = rsnd_cmd_debug_info
+#else
+#define DEBUG_INFO
+#endif
+
 static struct rsnd_mod_ops rsnd_cmd_ops = {
 	.name		= CMD_NAME,
 	.init		= rsnd_cmd_init,
 	.start		= rsnd_cmd_start,
 	.stop		= rsnd_cmd_stop,
 	.get_status	= rsnd_mod_get_status,
+	DEBUG_INFO
 };
 
 static struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id)
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 3de04a25e357..385d202146c6 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -1744,6 +1744,7 @@ int rsnd_kctrl_new(struct rsnd_mod *mod,
  */
 static const struct snd_soc_component_driver rsnd_soc_component = {
 	.name		= "rsnd",
+	.probe		= rsnd_debugfs_probe,
 	.hw_params	= rsnd_hw_params,
 	.hw_free	= rsnd_hw_free,
 	.pointer	= rsnd_pointer,
diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c
index 20eecd088d13..6156445bcb69 100644
--- a/sound/soc/sh/rcar/ctu.c
+++ b/sound/soc/sh/rcar/ctu.c
@@ -275,6 +275,19 @@ static int rsnd_ctu_id_sub(struct rsnd_mod *mod)
 	return mod->id % 4;
 }
 
+#ifdef CONFIG_DEBUG_FS
+static void rsnd_ctu_debug_info(struct seq_file *m,
+				struct rsnd_dai_stream *io,
+				struct rsnd_mod *mod)
+{
+	rsnd_debugfs_mod_reg_show(m, mod, RSND_GEN2_SCU,
+				  0x500 + rsnd_mod_id_raw(mod) * 0x100, 0x100);
+}
+#define DEBUG_INFO .debug_info = rsnd_ctu_debug_info
+#else
+#define DEBUG_INFO
+#endif
+
 static struct rsnd_mod_ops rsnd_ctu_ops = {
 	.name		= CTU_NAME,
 	.probe		= rsnd_ctu_probe_,
@@ -285,6 +298,7 @@ static struct rsnd_mod_ops rsnd_ctu_ops = {
 	.id		= rsnd_ctu_id,
 	.id_sub		= rsnd_ctu_id_sub,
 	.id_cmd		= rsnd_mod_id_raw,
+	DEBUG_INFO
 };
 
 struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id)
diff --git a/sound/soc/sh/rcar/debugfs.c b/sound/soc/sh/rcar/debugfs.c
new file mode 100644
index 000000000000..26d3b310b9db
--- /dev/null
+++ b/sound/soc/sh/rcar/debugfs.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// // Renesas R-Car debugfs support
+//
+// Copyright (c) 2021 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+//
+//	> mount -t debugfs none /sys/kernel/debug
+//	> cd /sys/kernel/debug/asoc/rcar-sound/ec500000.sound/rdai{N}/
+//	> cat playback/xxx
+//	> cat capture/xxx
+//
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/debugfs.h>
+#include "rsnd.h"
+
+static int rsnd_debugfs_show(struct seq_file *m, void *v)
+{
+	struct rsnd_dai_stream *io = m->private;
+	struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io);
+	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
+	int i;
+
+	/* adg is out of mods */
+	rsnd_adg_clk_dbg_info(priv, m);
+
+	for_each_rsnd_mod(i, mod, io) {
+		u32 *status = mod->ops->get_status(mod, io, mod->type);
+
+		seq_printf(m, "name: %s\n", rsnd_mod_name(mod));
+		seq_printf(m, "status: %08x\n", *status);
+
+		if (mod->ops->debug_info)
+			mod->ops->debug_info(m, io, mod);
+	}
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(rsnd_debugfs);
+
+void rsnd_debugfs_reg_show(struct seq_file *m, phys_addr_t _addr,
+			   void __iomem *base, int offset, int size)
+{
+	int i, j;
+
+	for (i = 0; i < size; i += 0x10) {
+		phys_addr_t addr = _addr + offset + i;
+
+		seq_printf(m, "%pa:", &addr);
+		for (j = 0; j < 0x10; j += 0x4)
+			seq_printf(m, " %08x", __raw_readl(base + offset + i + j));
+		seq_puts(m, "\n");
+	}
+}
+
+void rsnd_debugfs_mod_reg_show(struct seq_file *m, struct rsnd_mod *mod,
+			       int reg_id, int offset, int size)
+{
+	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
+
+	rsnd_debugfs_reg_show(m,
+			      rsnd_gen_get_phy_addr(priv, reg_id),
+			      rsnd_gen_get_base_addr(priv, reg_id),
+			      offset, size);
+}
+
+int rsnd_debugfs_probe(struct snd_soc_component *component)
+{
+	struct rsnd_priv *priv = dev_get_drvdata(component->dev);
+	struct rsnd_dai *rdai;
+	struct dentry *dir;
+	char name[64];
+	int i;
+
+	/* Gen1 is not supported */
+	if (rsnd_is_gen1(priv))
+		return 0;
+
+	for_each_rsnd_dai(rdai, priv, i) {
+		/*
+		 * created debugfs will be automatically
+		 * removed, nothing to do for _remove.
+		 * see
+		 *	soc_cleanup_component_debugfs()
+		 */
+		snprintf(name, sizeof(name), "rdai%d", i);
+		dir = debugfs_create_dir(name, component->debugfs_root);
+
+		debugfs_create_file("playback", 0444, dir, &rdai->playback, &rsnd_debugfs_fops);
+		debugfs_create_file("capture",  0444, dir, &rdai->capture,  &rsnd_debugfs_fops);
+	}
+
+	return 0;
+}
+
+#endif /* CONFIG_DEBUG_FS */
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
index 95aa26d62e4f..44519929a28b 100644
--- a/sound/soc/sh/rcar/dma.c
+++ b/sound/soc/sh/rcar/dma.c
@@ -44,7 +44,8 @@ struct rsnd_dma {
 };
 
 struct rsnd_dma_ctrl {
-	void __iomem *base;
+	void __iomem *ppbase;
+	phys_addr_t ppres;
 	int dmaen_num;
 	int dmapp_num;
 };
@@ -415,7 +416,7 @@ static u32 rsnd_dmapp_get_chcr(struct rsnd_dai_stream *io,
 }
 
 #define rsnd_dmapp_addr(dmac, dma, reg) \
-	(dmac->base + 0x20 + reg + \
+	(dmac->ppbase + 0x20 + reg + \
 	 (0x10 * rsnd_dma_to_dmapp(dma)->dmapp_id))
 static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg)
 {
@@ -504,12 +505,31 @@ static int rsnd_dmapp_attach(struct rsnd_dai_stream *io,
 	return 0;
 }
 
+#ifdef CONFIG_DEBUG_FS
+static void rsnd_dmapp_debug_info(struct seq_file *m,
+				  struct rsnd_dai_stream *io,
+				  struct rsnd_mod *mod)
+{
+	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
+	struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
+	struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
+	struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
+
+	rsnd_debugfs_reg_show(m, dmac->ppres, dmac->ppbase,
+			      0x20 + 0x10 * dmapp->dmapp_id, 0x10);
+}
+#define DEBUG_INFO .debug_info = rsnd_dmapp_debug_info
+#else
+#define DEBUG_INFO
+#endif
+
 static struct rsnd_mod_ops rsnd_dmapp_ops = {
 	.name		= "audmac-pp",
 	.start		= rsnd_dmapp_start,
 	.stop		= rsnd_dmapp_stop,
 	.quit		= rsnd_dmapp_stop,
 	.get_status	= rsnd_mod_get_status,
+	DEBUG_INFO
 };
 
 /*
@@ -864,9 +884,10 @@ int rsnd_dma_probe(struct rsnd_priv *priv)
 	}
 
 	dmac->dmapp_num = 0;
-	dmac->base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(dmac->base))
-		return PTR_ERR(dmac->base);
+	dmac->ppres  = res->start;
+	dmac->ppbase = devm_ioremap_resource(dev, res);
+	if (IS_ERR(dmac->ppbase))
+		return PTR_ERR(dmac->ppbase);
 
 	priv->dma = dmac;
 
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c
index 8d91c0eb0880..1943ac1ff803 100644
--- a/sound/soc/sh/rcar/dvc.c
+++ b/sound/soc/sh/rcar/dvc.c
@@ -285,6 +285,19 @@ static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_dai_stream *io,
 					mod, "tx");
 }
 
+#ifdef CONFIG_DEBUG_FS
+static void rsnd_dvc_debug_info(struct seq_file *m,
+				struct rsnd_dai_stream *io,
+				struct rsnd_mod *mod)
+{
+	rsnd_debugfs_mod_reg_show(m, mod, RSND_GEN2_SCU,
+				  0xe00 + rsnd_mod_id(mod) * 0x100, 0x60);
+}
+#define DEBUG_INFO .debug_info = rsnd_dvc_debug_info
+#else
+#define DEBUG_INFO
+#endif
+
 static struct rsnd_mod_ops rsnd_dvc_ops = {
 	.name		= DVC_NAME,
 	.dma_req	= rsnd_dvc_dma_req,
@@ -293,6 +306,7 @@ static struct rsnd_mod_ops rsnd_dvc_ops = {
 	.quit		= rsnd_dvc_quit,
 	.pcm_new	= rsnd_dvc_pcm_new,
 	.get_status	= rsnd_mod_get_status,
+	DEBUG_INFO
 };
 
 struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id)
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index 8bd49c8a9517..925565baaa41 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -141,6 +141,15 @@ phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id)
 	return	gen->res[reg_id];
 }
 
+#ifdef CONFIG_DEBUG_FS
+void __iomem *rsnd_gen_get_base_addr(struct rsnd_priv *priv, int reg_id)
+{
+	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
+
+	return	gen->base[reg_id];
+}
+#endif
+
 #define rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf)		\
 	_rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf, ARRAY_SIZE(conf))
 static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c
index a3e0370f5704..3572c2c5686c 100644
--- a/sound/soc/sh/rcar/mix.c
+++ b/sound/soc/sh/rcar/mix.c
@@ -250,6 +250,19 @@ static int rsnd_mix_pcm_new(struct rsnd_mod *mod,
 	return ret;
 }
 
+#ifdef CONFIG_DEBUG_FS
+static void rsnd_mix_debug_info(struct seq_file *m,
+				struct rsnd_dai_stream *io,
+				struct rsnd_mod *mod)
+{
+	rsnd_debugfs_mod_reg_show(m, mod, RSND_GEN2_SCU,
+				  0xd00 + rsnd_mod_id(mod) * 0x40, 0x30);
+}
+#define DEBUG_INFO .debug_info = rsnd_mix_debug_info
+#else
+#define DEBUG_INFO
+#endif
+
 static struct rsnd_mod_ops rsnd_mix_ops = {
 	.name		= MIX_NAME,
 	.probe		= rsnd_mix_probe_,
@@ -257,6 +270,7 @@ static struct rsnd_mod_ops rsnd_mix_ops = {
 	.quit		= rsnd_mix_quit,
 	.pcm_new	= rsnd_mix_pcm_new,
 	.get_status	= rsnd_mod_get_status,
+	DEBUG_INFO
 };
 
 struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id)
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 9736a94b9c39..0527aa8e139c 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -345,6 +345,11 @@ struct rsnd_mod_ops {
 	int (*id)(struct rsnd_mod *mod);
 	int (*id_sub)(struct rsnd_mod *mod);
 	int (*id_cmd)(struct rsnd_mod *mod);
+
+#ifdef CONFIG_DEBUG_FS
+	void (*debug_info)(struct seq_file *m,
+			   struct rsnd_dai_stream *io, struct rsnd_mod *mod);
+#endif
 };
 
 struct rsnd_dai_stream;
@@ -592,6 +597,9 @@ void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
 			       struct rsnd_mod *mod,
 			       enum rsnd_reg reg);
 phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id);
+#ifdef CONFIG_DEBUG_FS
+void __iomem *rsnd_gen_get_base_addr(struct rsnd_priv *priv, int reg_id);
+#endif
 
 /*
  *	R-Car ADG
@@ -610,6 +618,7 @@ int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *cmd_mod,
 #define rsnd_adg_clk_enable(priv)	rsnd_adg_clk_control(priv, 1)
 #define rsnd_adg_clk_disable(priv)	rsnd_adg_clk_control(priv, 0)
 void rsnd_adg_clk_control(struct rsnd_priv *priv, int enable);
+void rsnd_adg_clk_dbg_info(struct rsnd_priv *priv, struct seq_file *m);
 
 /*
  *	R-Car sound priv
@@ -897,3 +906,14 @@ void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type);
 		dev_dbg(dev, param)
 
 #endif
+
+#ifdef CONFIG_DEBUG_FS
+int rsnd_debugfs_probe(struct snd_soc_component *component);
+void rsnd_debugfs_reg_show(struct seq_file *m, phys_addr_t _addr,
+			   void __iomem *base, int offset, int size);
+void rsnd_debugfs_mod_reg_show(struct seq_file *m, struct rsnd_mod *mod,
+			       int reg_id, int offset, int size);
+
+#else
+#define rsnd_debugfs_probe  NULL
+#endif
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index 7a7d6dc335a4..8f7af3e3a1cd 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -597,6 +597,25 @@ static int rsnd_src_pcm_new(struct rsnd_mod *mod,
 	return ret;
 }
 
+#ifdef CONFIG_DEBUG_FS
+static void rsnd_src_debug_info(struct seq_file *m,
+				struct rsnd_dai_stream *io,
+				struct rsnd_mod *mod)
+{
+	rsnd_debugfs_mod_reg_show(m, mod, RSND_GEN2_SCU,
+				  rsnd_mod_id(mod) * 0x20, 0x20);
+	seq_puts(m, "\n");
+	rsnd_debugfs_mod_reg_show(m, mod, RSND_GEN2_SCU,
+				  0x1c0, 0x20);
+	seq_puts(m, "\n");
+	rsnd_debugfs_mod_reg_show(m, mod, RSND_GEN2_SCU,
+				  0x200 + rsnd_mod_id(mod) * 0x40, 0x40);
+}
+#define DEBUG_INFO .debug_info = rsnd_src_debug_info
+#else
+#define DEBUG_INFO
+#endif
+
 static struct rsnd_mod_ops rsnd_src_ops = {
 	.name		= SRC_NAME,
 	.dma_req	= rsnd_src_dma_req,
@@ -608,6 +627,7 @@ static struct rsnd_mod_ops rsnd_src_ops = {
 	.irq		= rsnd_src_irq,
 	.pcm_new	= rsnd_src_pcm_new,
 	.get_status	= rsnd_mod_get_status,
+	DEBUG_INFO
 };
 
 struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index ac920800af37..551c78f47da9 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -1118,6 +1118,34 @@ static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_dai_stream *io,
 					mod, name);
 }
 
+#ifdef CONFIG_DEBUG_FS
+static void rsnd_ssi_debug_info(struct seq_file *m,
+				struct rsnd_dai_stream *io,
+				struct rsnd_mod *mod)
+{
+	struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
+	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
+
+	seq_printf(m, "clock:           %s\n",		rsnd_rdai_is_clk_master(rdai) ?
+								"provider" : "consumer");
+	seq_printf(m, "bit_clk_inv:     %d\n",		rdai->bit_clk_inv);
+	seq_printf(m, "frm_clk_inv:     %d\n",		rdai->frm_clk_inv);
+	seq_printf(m, "pin share:       %d\n",		__rsnd_ssi_is_pin_sharing(mod));
+	seq_printf(m, "can out clk:     %d\n",		rsnd_ssi_can_output_clk(mod));
+	seq_printf(m, "multi secondary: %d\n",		rsnd_ssi_is_multi_secondary(mod, io));
+	seq_printf(m, "tdm:             %d, %d\n",	rsnd_runtime_is_tdm(io),
+							rsnd_runtime_is_tdm_split(io));
+	seq_printf(m, "chan:            %d\n",		ssi->chan);
+	seq_printf(m, "user:            %d\n",		ssi->usrcnt);
+
+	rsnd_debugfs_mod_reg_show(m, mod, RSND_GEN2_SSI,
+				  rsnd_mod_id(mod) * 0x40, 0x40);
+}
+#define DEBUG_INFO .debug_info = rsnd_ssi_debug_info
+#else
+#define DEBUG_INFO
+#endif
+
 static struct rsnd_mod_ops rsnd_ssi_dma_ops = {
 	.name		= SSI_NAME,
 	.dma_req	= rsnd_ssi_dma_req,
@@ -1132,6 +1160,7 @@ static struct rsnd_mod_ops rsnd_ssi_dma_ops = {
 	.fallback	= rsnd_ssi_fallback,
 	.hw_params	= rsnd_ssi_hw_params,
 	.get_status	= rsnd_ssi_get_status,
+	DEBUG_INFO
 };
 
 int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod)
diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c
index 6896ff0bc89d..cb2071cbe3c6 100644
--- a/sound/soc/sh/rcar/ssiu.c
+++ b/sound/soc/sh/rcar/ssiu.c
@@ -314,6 +314,19 @@ static struct dma_chan *rsnd_ssiu_dma_req(struct rsnd_dai_stream *io,
 					mod, name);
 }
 
+#ifdef CONFIG_DEBUG_FS
+static void rsnd_ssiu_debug_info(struct seq_file *m,
+				 struct rsnd_dai_stream *io,
+				struct rsnd_mod *mod)
+{
+	rsnd_debugfs_mod_reg_show(m, mod, RSND_GEN2_SSIU,
+				  rsnd_mod_id(mod) * 0x80, 0x80);
+}
+#define DEBUG_INFO .debug_info = rsnd_ssiu_debug_info
+#else
+#define DEBUG_INFO
+#endif
+
 static struct rsnd_mod_ops rsnd_ssiu_ops_gen2 = {
 	.name		= SSIU_NAME,
 	.dma_req	= rsnd_ssiu_dma_req,
@@ -321,6 +334,7 @@ static struct rsnd_mod_ops rsnd_ssiu_ops_gen2 = {
 	.start		= rsnd_ssiu_start_gen2,
 	.stop		= rsnd_ssiu_stop_gen2,
 	.get_status	= rsnd_ssiu_get_status,
+	DEBUG_INFO
 };
 
 static struct rsnd_mod *rsnd_ssiu_mod_get(struct rsnd_priv *priv, int id)
-- 
2.25.1


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

* [PATCH v2 08/11] ASoC: rsnd: protect mod->status
  2021-05-27  2:39 [PATCH v2 00/11] ASoC: rsnd: tidyup and fixup rare MIXer issue Kuninori Morimoto
                   ` (6 preceding siblings ...)
  2021-05-27  2:41 ` [PATCH v2 07/11] ASoC: rsnd: add debugfs support Kuninori Morimoto
@ 2021-05-27  2:41 ` Kuninori Morimoto
  2021-05-27  2:41 ` [PATCH v2 09/11] ASoC: rsnd: implement BUSIF related code in ssiu.c Kuninori Morimoto
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Kuninori Morimoto @ 2021-05-27  2:41 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux-ALSA


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

Renesas Sound uses many modules (SSI/SSIU/SRC/CTU/MIX/DVC/DMA),
and supports complex connections/path.
Thus each modules needs to save its status to correctly control it.
This status is updated when by .trigger, and .hw_params/.hw_free.

Renesas Sound is protecting modules by using lock when .trigger,
but it was not enough to protecting each modules "status" if it was
used from many paths.

1) .hw_params/.hw_free update status
2) another doesn't update status, but overwrites by same value

This patch do
1) protects .hw_params/.hw_free by lock
2) do nothing if no status update

Without this patch, protected mod->status (= .trigger) might be
overwrote by non protected mod->status (= .hw_params / .hw_free),
and in such case, CTU/MIX/DVC/SSIU/SSI which are used from
many paths might get damage.

If above issue happens, Renesas Sound will be hung (= silence)
and never be recoverd.
I could reproduce this issue by continue playing very short sound
with loop very long term (3-4 hours) through 2 inputs (= MIXer).

For updating rsnd_status_update(), this patch removes rsnd_dai_call()
debug message. Because we already have debugfs support, and is not
good match to new code.

Reported-by: Linh Phung T. Y <linh.phung.jy@renesas.com>
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 sound/soc/sh/rcar/core.c | 50 ++++++++++++++++++++++++----------------
 sound/soc/sh/rcar/rsnd.h | 12 +++++-----
 2 files changed, 36 insertions(+), 26 deletions(-)

diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 385d202146c6..a5d13b801492 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -90,14 +90,6 @@
  *
  */
 
-/*
- * you can enable below define if you don't need
- * DAI status debug message when debugging
- * see rsnd_dbg_dai_call()
- *
- * #define RSND_DEBUG_NO_DAI_CALL 1
- */
-
 #include <linux/pm_runtime.h>
 #include "rsnd.h"
 
@@ -534,14 +526,20 @@ static enum rsnd_mod_type rsnd_mod_sequence[][RSND_MOD_MAX] = {
 	},
 };
 
-static int rsnd_status_update(u32 *status,
+static int rsnd_status_update(struct rsnd_dai_stream *io,
+			      struct rsnd_mod *mod, enum rsnd_mod_type type,
 			      int shift, int add, int timing)
 {
+	u32 *status	= mod->ops->get_status(mod, io, type);
 	u32 mask	= 0xF << shift;
 	u8 val		= (*status >> shift) & 0xF;
 	u8 next_val	= (val + add) & 0xF;
 	int func_call	= (val == timing);
 
+	/* no status update */
+	if (add == 0 || shift == 28)
+		return 1;
+
 	if (next_val == 0xF) /* underflow case */
 		func_call = -1;
 	else
@@ -559,14 +557,10 @@ static int rsnd_status_update(u32 *status,
 	enum rsnd_mod_type *types = rsnd_mod_sequence[is_play];		\
 	for_each_rsnd_mod_arrays(i, mod, io, types, RSND_MOD_MAX) {	\
 		int tmp = 0;						\
-		u32 *status = mod->ops->get_status(mod, io, types[i]);	\
-		int func_call = rsnd_status_update(status,		\
+		int func_call = rsnd_status_update(io, mod, types[i],	\
 						__rsnd_mod_shift_##fn,	\
 						__rsnd_mod_add_##fn,	\
 						__rsnd_mod_call_##fn);	\
-		rsnd_dbg_dai_call(dev, "%s\t0x%08x %s\n",		\
-			rsnd_mod_name(mod), *status,	\
-			(func_call && (mod)->ops->fn) ? #fn : "");	\
 		if (func_call > 0 && (mod)->ops->fn)			\
 			tmp = (mod)->ops->fn(mod, io, param);		\
 		if (unlikely(func_call < 0) ||				\
@@ -1417,6 +1411,26 @@ static int rsnd_dai_probe(struct rsnd_priv *priv)
 /*
  *		pcm ops
  */
+static int rsnd_hw_update(struct snd_pcm_substream *substream,
+			  struct snd_pcm_hw_params *hw_params)
+{
+	struct snd_soc_dai *dai = rsnd_substream_to_dai(substream);
+	struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
+	struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);
+	struct rsnd_priv *priv = rsnd_io_to_priv(io);
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	if (hw_params)
+		ret = rsnd_dai_call(hw_params, io, substream, hw_params);
+	else
+		ret = rsnd_dai_call(hw_free, io, substream);
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return ret;
+}
+
 static int rsnd_hw_params(struct snd_soc_component *component,
 			  struct snd_pcm_substream *substream,
 			  struct snd_pcm_hw_params *hw_params)
@@ -1524,17 +1538,13 @@ static int rsnd_hw_params(struct snd_soc_component *component,
 		}
 	}
 
-	return rsnd_dai_call(hw_params, io, substream, hw_params);
+	return rsnd_hw_update(substream, hw_params);
 }
 
 static int rsnd_hw_free(struct snd_soc_component *component,
 			struct snd_pcm_substream *substream)
 {
-	struct snd_soc_dai *dai = rsnd_substream_to_dai(substream);
-	struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
-	struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);
-
-	return rsnd_dai_call(hw_free, io, substream);
+	return rsnd_hw_update(substream, NULL);
 }
 
 static snd_pcm_uframes_t rsnd_pointer(struct snd_soc_component *component,
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 0527aa8e139c..159754b7bb53 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -397,12 +397,12 @@ struct rsnd_mod {
 #define __rsnd_mod_add_remove		0
 #define __rsnd_mod_add_prepare		0
 #define __rsnd_mod_add_cleanup		0
-#define __rsnd_mod_add_init		 1
-#define __rsnd_mod_add_quit		-1
-#define __rsnd_mod_add_start		 1
-#define __rsnd_mod_add_stop		-1
-#define __rsnd_mod_add_hw_params	1
-#define __rsnd_mod_add_hw_free		-1
+#define __rsnd_mod_add_init		 1 /* needs protect */
+#define __rsnd_mod_add_quit		-1 /* needs protect */
+#define __rsnd_mod_add_start		 1 /* needs protect */
+#define __rsnd_mod_add_stop		-1 /* needs protect */
+#define __rsnd_mod_add_hw_params	 1 /* needs protect */
+#define __rsnd_mod_add_hw_free		-1 /* needs protect */
 #define __rsnd_mod_add_irq		0
 #define __rsnd_mod_add_pcm_new		0
 #define __rsnd_mod_add_fallback		0
-- 
2.25.1


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

* [PATCH v2 09/11] ASoC: rsnd: implement BUSIF related code in ssiu.c
  2021-05-27  2:39 [PATCH v2 00/11] ASoC: rsnd: tidyup and fixup rare MIXer issue Kuninori Morimoto
                   ` (7 preceding siblings ...)
  2021-05-27  2:41 ` [PATCH v2 08/11] ASoC: rsnd: protect mod->status Kuninori Morimoto
@ 2021-05-27  2:41 ` Kuninori Morimoto
  2021-05-27  2:41 ` [PATCH v2 10/11] ASoC: rsnd: tidyup rsnd_ssiu_busif_err_status_clear() Kuninori Morimoto
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Kuninori Morimoto @ 2021-05-27  2:41 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux-ALSA


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

BUSIF is SSIU feature, but its related code is
implemented at ssi.c today.
This patch moves it to ssiu.c

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 sound/soc/sh/rcar/rsnd.h |   1 +
 sound/soc/sh/rcar/ssi.c  |  98 +------------------------------
 sound/soc/sh/rcar/ssiu.c | 121 ++++++++++++++++++++++++++++++++++-----
 3 files changed, 108 insertions(+), 112 deletions(-)

diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 159754b7bb53..d712615c9c9f 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -810,6 +810,7 @@ void rsnd_parse_connect_ssiu(struct rsnd_dai *rdai,
 			     struct device_node *playback,
 			     struct device_node *capture);
 #define rsnd_ssiu_of_node(priv) rsnd_parse_of_node(priv, RSND_NODE_SSIU)
+bool rsnd_ssiu_busif_err_status_clear(struct rsnd_mod *mod);
 
 /*
  *	R-Car SRC
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 551c78f47da9..facdd8c0d419 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -357,96 +357,6 @@ static void rsnd_ssi_master_clk_stop(struct rsnd_mod *mod,
 	rsnd_adg_ssi_clk_stop(mod);
 }
 
-/* enable busif buffer over/under run interrupt. */
-#define rsnd_ssi_busif_err_irq_enable(mod)  rsnd_ssi_busif_err_irq_ctrl(mod, 1)
-#define rsnd_ssi_busif_err_irq_disable(mod) rsnd_ssi_busif_err_irq_ctrl(mod, 0)
-static void rsnd_ssi_busif_err_irq_ctrl(struct rsnd_mod *mod, int enable)
-{
-	u32 sys_int_enable = 0;
-	int id = rsnd_mod_id(mod);
-	int i;
-
-	switch (id) {
-	case 0:
-	case 1:
-	case 2:
-	case 3:
-	case 4:
-		for (i = 0; i < 4; i++) {
-			sys_int_enable = rsnd_mod_read(mod, SSI_SYS_INT_ENABLE(i * 2));
-			if (enable)
-				sys_int_enable |= 0xf << (id * 4);
-			else
-				sys_int_enable &= ~(0xf << (id * 4));
-			rsnd_mod_write(mod,
-				       SSI_SYS_INT_ENABLE(i * 2),
-				       sys_int_enable);
-		}
-		break;
-	case 9:
-		for (i = 0; i < 4; i++) {
-			sys_int_enable = rsnd_mod_read(mod, SSI_SYS_INT_ENABLE((i * 2) + 1));
-			if (enable)
-				sys_int_enable |= 0xf << 4;
-			else
-				sys_int_enable &= ~(0xf << 4);
-			rsnd_mod_write(mod,
-				       SSI_SYS_INT_ENABLE((i * 2) + 1),
-				       sys_int_enable);
-		}
-		break;
-	}
-}
-
-static bool rsnd_ssi_busif_err_status_clear(struct rsnd_mod *mod)
-{
-	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
-	struct device *dev = rsnd_priv_to_dev(priv);
-	u32 status;
-	bool stop = false;
-	int id = rsnd_mod_id(mod);
-	int i;
-
-	switch (id) {
-	case 0:
-	case 1:
-	case 2:
-	case 3:
-	case 4:
-		for (i = 0; i < 4; i++) {
-			status = rsnd_mod_read(mod, SSI_SYS_STATUS(i * 2));
-			status &= 0xf << (id * 4);
-
-			if (status) {
-				rsnd_print_irq_status(dev, "%s err status : 0x%08x\n",
-						      rsnd_mod_name(mod), status);
-				rsnd_mod_write(mod,
-					       SSI_SYS_STATUS(i * 2),
-					       0xf << (id * 4));
-				stop = true;
-			}
-		}
-		break;
-	case 9:
-		for (i = 0; i < 4; i++) {
-			status = rsnd_mod_read(mod, SSI_SYS_STATUS((i * 2) + 1));
-			status &= 0xf << 4;
-
-			if (status) {
-				rsnd_print_irq_status(dev, "%s err status : 0x%08x\n",
-						      rsnd_mod_name(mod), status);
-				rsnd_mod_write(mod,
-					       SSI_SYS_STATUS((i * 2) + 1),
-					       0xf << 4);
-				stop = true;
-			}
-		}
-		break;
-	}
-
-	return stop;
-}
-
 static void rsnd_ssi_config_init(struct rsnd_mod *mod,
 				struct rsnd_dai_stream *io)
 {
@@ -534,9 +444,6 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod,
 		cr_mode = DIEN;		/* PIO : enable Data interrupt */
 	}
 
-	/* enable busif buffer over/under run interrupt. */
-	rsnd_ssi_busif_err_irq_enable(mod);
-
 init_end:
 	ssi->cr_own	= cr_own;
 	ssi->cr_mode	= cr_mode;
@@ -612,9 +519,6 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod,
 		ssi->wsr	= 0;
 	}
 
-	/* disable busif buffer over/under run interrupt. */
-	rsnd_ssi_busif_err_irq_disable(mod);
-
 	return 0;
 }
 
@@ -788,7 +692,7 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
 		stop = true;
 	}
 
-	stop |= rsnd_ssi_busif_err_status_clear(mod);
+	stop |= rsnd_ssiu_busif_err_status_clear(mod);
 
 	rsnd_ssi_status_clear(mod);
 rsnd_ssi_interrupt_out:
diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c
index cb2071cbe3c6..3a98ec2066bc 100644
--- a/sound/soc/sh/rcar/ssiu.c
+++ b/sound/soc/sh/rcar/ssiu.c
@@ -45,6 +45,92 @@ struct rsnd_ssiu {
 static const int gen2_id[] = { 0, 4,  8, 12, 13, 14, 15, 16, 17, 18 };
 static const int gen3_id[] = { 0, 8, 16, 24, 32, 40, 41, 42, 43, 44 };
 
+/* enable busif buffer over/under run interrupt. */
+#define rsnd_ssiu_busif_err_irq_enable(mod)  rsnd_ssiu_busif_err_irq_ctrl(mod, 1)
+#define rsnd_ssiu_busif_err_irq_disable(mod) rsnd_ssiu_busif_err_irq_ctrl(mod, 0)
+static void rsnd_ssiu_busif_err_irq_ctrl(struct rsnd_mod *mod, int enable)
+{
+	u32 sys_int_enable = 0;
+	int id = rsnd_mod_id(mod);
+	int i;
+
+	switch (id) {
+	case 0:
+	case 1:
+	case 2:
+	case 3:
+	case 4:
+		for (i = 0; i < 4; i++) {
+			sys_int_enable = rsnd_mod_read(mod, SSI_SYS_INT_ENABLE(i * 2));
+			if (enable)
+				sys_int_enable |= 0xf << (id * 4);
+			else
+				sys_int_enable &= ~(0xf << (id * 4));
+			rsnd_mod_write(mod,
+				       SSI_SYS_INT_ENABLE(i * 2),
+				       sys_int_enable);
+		}
+		break;
+	case 9:
+		for (i = 0; i < 4; i++) {
+			sys_int_enable = rsnd_mod_read(mod, SSI_SYS_INT_ENABLE((i * 2) + 1));
+			if (enable)
+				sys_int_enable |= 0xf << 4;
+			else
+				sys_int_enable &= ~(0xf << 4);
+			rsnd_mod_write(mod,
+				       SSI_SYS_INT_ENABLE((i * 2) + 1),
+				       sys_int_enable);
+		}
+		break;
+	}
+}
+
+bool rsnd_ssiu_busif_err_status_clear(struct rsnd_mod *mod)
+{
+	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
+	struct device *dev = rsnd_priv_to_dev(priv);
+	u32 status;
+	bool error = false;
+	int id = rsnd_mod_id(mod);
+	int i;
+
+	switch (id) {
+	case 0:
+	case 1:
+	case 2:
+	case 3:
+	case 4:
+		for (i = 0; i < 4; i++) {
+			status = rsnd_mod_read(mod, SSI_SYS_STATUS(i * 2));
+			status &= 0xf << (id * 4);
+
+			if (status) {
+				rsnd_print_irq_status(dev, "%s err status : 0x%08x\n",
+						      rsnd_mod_name(mod), status);
+				error = true;
+			}
+			rsnd_mod_write(mod, SSI_SYS_STATUS(i * 2), 0xf << (id * 4));
+		}
+		break;
+	case 9:
+		for (i = 0; i < 4; i++) {
+			status = rsnd_mod_read(mod, SSI_SYS_STATUS((i * 2) + 1));
+			status &= 0xf << 4;
+
+			if (status) {
+				rsnd_print_irq_status(dev, "%s err status : 0x%08x\n",
+						      rsnd_mod_name(mod), status);
+				error = true;
+			}
+			rsnd_mod_write(mod, SSI_SYS_STATUS((i * 2) + 1), 0xf << 4);
+		}
+		break;
+	}
+
+	return error;
+}
+
 static u32 *rsnd_ssiu_get_status(struct rsnd_mod *mod,
 				 struct rsnd_dai_stream *io,
 				 enum rsnd_mod_type type)
@@ -65,23 +151,9 @@ static int rsnd_ssiu_init(struct rsnd_mod *mod,
 	int id = rsnd_mod_id(mod);
 	int is_clk_master = rsnd_rdai_is_clk_master(rdai);
 	u32 val1, val2;
-	int i;
 
 	/* clear status */
-	switch (id) {
-	case 0:
-	case 1:
-	case 2:
-	case 3:
-	case 4:
-		for (i = 0; i < 4; i++)
-			rsnd_mod_write(mod, SSI_SYS_STATUS(i * 2), 0xf << (id * 4));
-		break;
-	case 9:
-		for (i = 0; i < 4; i++)
-			rsnd_mod_write(mod, SSI_SYS_STATUS((i * 2) + 1), 0xf << 4);
-		break;
-	}
+	rsnd_ssiu_busif_err_status_clear(mod);
 
 	/*
 	 * SSI_MODE0
@@ -137,12 +209,31 @@ static int rsnd_ssiu_init(struct rsnd_mod *mod,
 	rsnd_mod_bset(mod, SSI_MODE1, 0x0013001f, val1);
 	rsnd_mod_bset(mod, SSI_MODE2, 0x00000017, val2);
 
+	/*
+	 * Enable busif buffer over/under run interrupt.
+	 * It will be handled from ssi.c
+	 * see
+	 *	__rsnd_ssi_interrupt()
+	 */
+	rsnd_ssiu_busif_err_irq_enable(mod);
+
+	return 0;
+}
+
+static int rsnd_ssiu_quit(struct rsnd_mod *mod,
+			  struct rsnd_dai_stream *io,
+			  struct rsnd_priv *priv)
+{
+	/* disable busif buffer over/under run interrupt. */
+	rsnd_ssiu_busif_err_irq_disable(mod);
+
 	return 0;
 }
 
 static struct rsnd_mod_ops rsnd_ssiu_ops_gen1 = {
 	.name		= SSIU_NAME,
 	.init		= rsnd_ssiu_init,
+	.quit		= rsnd_ssiu_quit,
 	.get_status	= rsnd_ssiu_get_status,
 };
 
-- 
2.25.1


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

* [PATCH v2 10/11] ASoC: rsnd: tidyup rsnd_ssiu_busif_err_status_clear()
  2021-05-27  2:39 [PATCH v2 00/11] ASoC: rsnd: tidyup and fixup rare MIXer issue Kuninori Morimoto
                   ` (8 preceding siblings ...)
  2021-05-27  2:41 ` [PATCH v2 09/11] ASoC: rsnd: implement BUSIF related code in ssiu.c Kuninori Morimoto
@ 2021-05-27  2:41 ` Kuninori Morimoto
  2021-05-27  2:42 ` [PATCH v2 11/11] ASoC: rsnd: tidyup rsnd_ssiu_busif_err_irq_ctrl() Kuninori Morimoto
  2021-05-28 16:04 ` [PATCH v2 00/11] ASoC: rsnd: tidyup and fixup rare MIXer issue Mark Brown
  11 siblings, 0 replies; 13+ messages in thread
From: Kuninori Morimoto @ 2021-05-27  2:41 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux-ALSA


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

rsnd_ssiu_busif_err_status_clear() has very similar duplicated code.
This patch merge and tidyup the code.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 sound/soc/sh/rcar/ssiu.c | 45 +++++++++++++++++++---------------------
 1 file changed, 21 insertions(+), 24 deletions(-)

diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c
index 3a98ec2066bc..b79628761167 100644
--- a/sound/soc/sh/rcar/ssiu.c
+++ b/sound/soc/sh/rcar/ssiu.c
@@ -88,11 +88,9 @@ static void rsnd_ssiu_busif_err_irq_ctrl(struct rsnd_mod *mod, int enable)
 
 bool rsnd_ssiu_busif_err_status_clear(struct rsnd_mod *mod)
 {
-	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
-	struct device *dev = rsnd_priv_to_dev(priv);
-	u32 status;
 	bool error = false;
 	int id = rsnd_mod_id(mod);
+	int shift, offset;
 	int i;
 
 	switch (id) {
@@ -101,31 +99,30 @@ bool rsnd_ssiu_busif_err_status_clear(struct rsnd_mod *mod)
 	case 2:
 	case 3:
 	case 4:
-		for (i = 0; i < 4; i++) {
-			status = rsnd_mod_read(mod, SSI_SYS_STATUS(i * 2));
-			status &= 0xf << (id * 4);
-
-			if (status) {
-				rsnd_print_irq_status(dev, "%s err status : 0x%08x\n",
-						      rsnd_mod_name(mod), status);
-				error = true;
-			}
-			rsnd_mod_write(mod, SSI_SYS_STATUS(i * 2), 0xf << (id * 4));
-		}
+		shift  = id;
+		offset = 0;
 		break;
 	case 9:
-		for (i = 0; i < 4; i++) {
-			status = rsnd_mod_read(mod, SSI_SYS_STATUS((i * 2) + 1));
-			status &= 0xf << 4;
+		shift  = 1;
+		offset = 1;
+		break;
+	}
 
-			if (status) {
-				rsnd_print_irq_status(dev, "%s err status : 0x%08x\n",
-						      rsnd_mod_name(mod), status);
-				error = true;
-			}
-			rsnd_mod_write(mod, SSI_SYS_STATUS((i * 2) + 1), 0xf << 4);
+	for (i = 0; i < 4; i++) {
+		u32 reg = SSI_SYS_STATUS(i * 2) + offset;
+		u32 status = rsnd_mod_read(mod, reg);
+		u32 val = 0xf << (shift * 4);
+
+		status &= val;
+		if (status) {
+			struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
+			struct device *dev = rsnd_priv_to_dev(priv);
+
+			rsnd_print_irq_status(dev, "%s err status : 0x%08x\n",
+					      rsnd_mod_name(mod), status);
+			error = true;
 		}
-		break;
+		rsnd_mod_write(mod, reg, val);
 	}
 
 	return error;
-- 
2.25.1


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

* [PATCH v2 11/11] ASoC: rsnd: tidyup rsnd_ssiu_busif_err_irq_ctrl()
  2021-05-27  2:39 [PATCH v2 00/11] ASoC: rsnd: tidyup and fixup rare MIXer issue Kuninori Morimoto
                   ` (9 preceding siblings ...)
  2021-05-27  2:41 ` [PATCH v2 10/11] ASoC: rsnd: tidyup rsnd_ssiu_busif_err_status_clear() Kuninori Morimoto
@ 2021-05-27  2:42 ` Kuninori Morimoto
  2021-05-28 16:04 ` [PATCH v2 00/11] ASoC: rsnd: tidyup and fixup rare MIXer issue Mark Brown
  11 siblings, 0 replies; 13+ messages in thread
From: Kuninori Morimoto @ 2021-05-27  2:42 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux-ALSA


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

rsnd_ssiu_busif_err_irq_ctrl() has very similar duplicated code.
This patch merge and tidyup the code.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 sound/soc/sh/rcar/ssiu.c | 38 +++++++++++++++++---------------------
 1 file changed, 17 insertions(+), 21 deletions(-)

diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c
index b79628761167..4363508e8250 100644
--- a/sound/soc/sh/rcar/ssiu.c
+++ b/sound/soc/sh/rcar/ssiu.c
@@ -50,8 +50,8 @@ static const int gen3_id[] = { 0, 8, 16, 24, 32, 40, 41, 42, 43, 44 };
 #define rsnd_ssiu_busif_err_irq_disable(mod) rsnd_ssiu_busif_err_irq_ctrl(mod, 0)
 static void rsnd_ssiu_busif_err_irq_ctrl(struct rsnd_mod *mod, int enable)
 {
-	u32 sys_int_enable = 0;
 	int id = rsnd_mod_id(mod);
+	int shift, offset;
 	int i;
 
 	switch (id) {
@@ -60,30 +60,26 @@ static void rsnd_ssiu_busif_err_irq_ctrl(struct rsnd_mod *mod, int enable)
 	case 2:
 	case 3:
 	case 4:
-		for (i = 0; i < 4; i++) {
-			sys_int_enable = rsnd_mod_read(mod, SSI_SYS_INT_ENABLE(i * 2));
-			if (enable)
-				sys_int_enable |= 0xf << (id * 4);
-			else
-				sys_int_enable &= ~(0xf << (id * 4));
-			rsnd_mod_write(mod,
-				       SSI_SYS_INT_ENABLE(i * 2),
-				       sys_int_enable);
-		}
+		shift  = id;
+		offset = 0;
 		break;
 	case 9:
-		for (i = 0; i < 4; i++) {
-			sys_int_enable = rsnd_mod_read(mod, SSI_SYS_INT_ENABLE((i * 2) + 1));
-			if (enable)
-				sys_int_enable |= 0xf << 4;
-			else
-				sys_int_enable &= ~(0xf << 4);
-			rsnd_mod_write(mod,
-				       SSI_SYS_INT_ENABLE((i * 2) + 1),
-				       sys_int_enable);
-		}
+		shift  = 1;
+		offset = 1;
 		break;
 	}
+
+	for (i = 0; i < 4; i++) {
+		enum rsnd_reg reg = SSI_SYS_INT_ENABLE((i * 2) + offset);
+		u32 val = 0xf << (shift * 4);
+		u32 sys_int_enable = rsnd_mod_read(mod, reg);
+
+		if (enable)
+			sys_int_enable |= val;
+		else
+			sys_int_enable &= ~val;
+		rsnd_mod_write(mod, reg, sys_int_enable);
+	}
 }
 
 bool rsnd_ssiu_busif_err_status_clear(struct rsnd_mod *mod)
-- 
2.25.1


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

* Re: [PATCH v2 00/11] ASoC: rsnd: tidyup and fixup rare MIXer issue
  2021-05-27  2:39 [PATCH v2 00/11] ASoC: rsnd: tidyup and fixup rare MIXer issue Kuninori Morimoto
                   ` (10 preceding siblings ...)
  2021-05-27  2:42 ` [PATCH v2 11/11] ASoC: rsnd: tidyup rsnd_ssiu_busif_err_irq_ctrl() Kuninori Morimoto
@ 2021-05-28 16:04 ` Mark Brown
  11 siblings, 0 replies; 13+ messages in thread
From: Mark Brown @ 2021-05-28 16:04 UTC (permalink / raw)
  To: Kuninori Morimoto; +Cc: broonie, Mark, Brown, Linux-ALSA

From: Mark Brown,,, <broonie@kernel.org>

On 27 May 2021 11:39:39 +0900, Kuninori Morimoto wrote:
> These are v2 of tidyup patch, and rare MIXer issue fixup patch for
> Renesas Sound driver.
> 
> 1 - 6 : tidyup for rsnd driver
> 7     : add debugfs support
> 8     : fixup rare MIXer issue
> 9 - 11: tidyup for rsnd driver
> 
> [...]

Applied, thanks!

[01/11] ASoC: rsnd: call unregister for null_hw when removed
        commit: 965386c97616c401b34cba4e9e3bfc9c6b215359
[02/11] ASoC: rsnd: ignore runtime NULL case at rsnd_runtime_channel_original_with_params()
        commit: 6da8f00e7ac277ddfc72e255328dc5ff0378c3ee
[03/11] ASoC: rsnd: attach SSIU when SSI was DMA mode
        commit: ab62e8a8bce1cc3b730462a7a462107db634bd5c
[04/11] ASoC: rsnd: check BUIF error everytime
        commit: 54e81e9446377c36fdcb952ca7db43e59857e0d7
[05/11] ASoC: rsnd: indicate unknown error at rsnd_dai_call()
        commit: 9ff07d19fb28ce8544d3ee4755673020b00487e6
[06/11] ASoC: rsnd: incidate irq error message
        commit: 1788a1520185e69f62e56dd23b33a0992e8187aa
[07/11] ASoC: rsnd: add debugfs support
        commit: 1f9c82b5ab83ff24f5c2b62bf9a912e4aef8905e
[08/11] ASoC: rsnd: protect mod->status
        commit: b43b8ae87c8e0a8b81a26cfc39bd157c5f53ae14
[09/11] ASoC: rsnd: implement BUSIF related code in ssiu.c
        commit: 83b220cf8eb2aa9dbe0007bcf43c5e305fe1986d
[10/11] ASoC: rsnd: tidyup rsnd_ssiu_busif_err_status_clear()
        commit: cfb7b8bf1e2d660583dd91d870cec2f6728cbdbc
[11/11] ASoC: rsnd: tidyup rsnd_ssiu_busif_err_irq_ctrl()
        commit: 0ab000e5e57e6dcb34605fbdee92a1b0947606e0

Best regards,
-- 
Mark Brown,,, <broonie@kernel.org>

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

end of thread, other threads:[~2021-05-28 16:06 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-27  2:39 [PATCH v2 00/11] ASoC: rsnd: tidyup and fixup rare MIXer issue Kuninori Morimoto
2021-05-27  2:40 ` [PATCH v2 01/11] ASoC: rsnd: call unregister for null_hw when removed Kuninori Morimoto
2021-05-27  2:40 ` [PATCH v2 02/11] ASoC: rsnd: ignore runtime NULL case at rsnd_runtime_channel_original_with_params() Kuninori Morimoto
2021-05-27  2:40 ` [PATCH v2 03/11] ASoC: rsnd: attach SSIU when SSI was DMA mode Kuninori Morimoto
2021-05-27  2:41 ` [PATCH v2 04/11] ASoC: rsnd: check BUIF error everytime Kuninori Morimoto
2021-05-27  2:41 ` [PATCH v2 05/11] ASoC: rsnd: indicate unknown error at rsnd_dai_call() Kuninori Morimoto
2021-05-27  2:41 ` [PATCH v2 06/11] ASoC: rsnd: incidate irq error message Kuninori Morimoto
2021-05-27  2:41 ` [PATCH v2 07/11] ASoC: rsnd: add debugfs support Kuninori Morimoto
2021-05-27  2:41 ` [PATCH v2 08/11] ASoC: rsnd: protect mod->status Kuninori Morimoto
2021-05-27  2:41 ` [PATCH v2 09/11] ASoC: rsnd: implement BUSIF related code in ssiu.c Kuninori Morimoto
2021-05-27  2:41 ` [PATCH v2 10/11] ASoC: rsnd: tidyup rsnd_ssiu_busif_err_status_clear() Kuninori Morimoto
2021-05-27  2:42 ` [PATCH v2 11/11] ASoC: rsnd: tidyup rsnd_ssiu_busif_err_irq_ctrl() Kuninori Morimoto
2021-05-28 16:04 ` [PATCH v2 00/11] ASoC: rsnd: tidyup and fixup rare MIXer issue Mark Brown

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