ASoC: rsnd: add nolock_start/stop callback
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Tue, 25 Oct 2016 00:37:35 +0000 (00:37 +0000)
committerMark Brown <broonie@kernel.org>
Tue, 25 Oct 2016 14:02:43 +0000 (15:02 +0100)
Current Renesas Sound driver requests DMA channel when .probe timing,
and release it when .remove timing. And use DMA on .start/.stop
But, Audio DMAC power ON was handled when request timing (= .probe),
and power OFF was when release timing (= .remove).
This means Audio DMAC power is always ON during driver was enabled.
To fixup this issue, it should request/release DMA channel on each
playback/recorde timing.
But, DMA channel request/release function uses mutex lock inside.
This means it will breaks current spinlock's interrupt protect.
To solve this issue, DMA channel request/release function needs to
be called from non-spinlock area. This patch adds its callback.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sh/rcar/core.c
sound/soc/sh/rcar/rsnd.h

index ea14a1470de26b9a379789224e4a6fd1a520f0ac..9ffa29941cebd6bd6f863a36b69123f3b6e947f9 100644 (file)
@@ -716,7 +716,33 @@ static int rsnd_soc_set_dai_tdm_slot(struct snd_soc_dai *dai,
        return 0;
 }
 
+static int rsnd_soc_dai_startup(struct snd_pcm_substream *substream,
+                               struct snd_soc_dai *dai)
+{
+       struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
+       struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);
+
+       /*
+        * call rsnd_dai_call without spinlock
+        */
+       return rsnd_dai_call(nolock_start, io, priv);
+}
+
+static void rsnd_soc_dai_shutdown(struct snd_pcm_substream *substream,
+                                 struct snd_soc_dai *dai)
+{
+       struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
+       struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);
+
+       /*
+        * call rsnd_dai_call without spinlock
+        */
+       rsnd_dai_call(nolock_stop, io, priv);
+}
+
 static const struct snd_soc_dai_ops rsnd_soc_dai_ops = {
+       .startup        = rsnd_soc_dai_startup,
+       .shutdown       = rsnd_soc_dai_shutdown,
        .trigger        = rsnd_soc_dai_trigger,
        .set_fmt        = rsnd_soc_dai_set_fmt,
        .set_tdm_slot   = rsnd_soc_set_dai_tdm_slot,
index c1cee1ab3e62b3eed671b362e8ea89557ddb31fa..422b5344b687e8a0007f8d2bac14d9eb3894eed3 100644 (file)
@@ -259,6 +259,12 @@ struct rsnd_mod_ops {
        int (*fallback)(struct rsnd_mod *mod,
                        struct rsnd_dai_stream *io,
                        struct rsnd_priv *priv);
+       int (*nolock_start)(struct rsnd_mod *mod,
+                   struct rsnd_dai_stream *io,
+                   struct rsnd_priv *priv);
+       int (*nolock_stop)(struct rsnd_mod *mod,
+                   struct rsnd_dai_stream *io,
+                   struct rsnd_priv *priv);
 };
 
 struct rsnd_dai_stream;
@@ -276,8 +282,9 @@ struct rsnd_mod {
 /*
  * status
  *
- * 0xH0000CB0
+ * 0xH0000CBA
  *
+ * A   0: nolock_start 1: nolock_stop
  * B   0: init         1: quit
  * C   0: start        1: stop
  *
@@ -287,6 +294,8 @@ struct rsnd_mod {
  * H   0: fallback
  * H   0: hw_params
  */
+#define __rsnd_mod_shift_nolock_start  0
+#define __rsnd_mod_shift_nolock_stop   0
 #define __rsnd_mod_shift_init          4
 #define __rsnd_mod_shift_quit          4
 #define __rsnd_mod_shift_start         8
@@ -300,6 +309,8 @@ struct rsnd_mod {
 
 #define __rsnd_mod_add_probe           0
 #define __rsnd_mod_add_remove          0
+#define __rsnd_mod_add_nolock_start     1
+#define __rsnd_mod_add_nolock_stop     -1
 #define __rsnd_mod_add_init             1
 #define __rsnd_mod_add_quit            -1
 #define __rsnd_mod_add_start            1
@@ -319,6 +330,8 @@ struct rsnd_mod {
 #define __rsnd_mod_call_pcm_new                0
 #define __rsnd_mod_call_fallback       0
 #define __rsnd_mod_call_hw_params      0
+#define __rsnd_mod_call_nolock_start   0
+#define __rsnd_mod_call_nolock_stop    1
 
 #define rsnd_mod_to_priv(mod) ((mod)->priv)
 #define rsnd_mod_id(mod) ((mod) ? (mod)->id : -1)