ASoC: rsnd: amend .probe/.remove call for DPCM
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Wed, 19 Oct 2016 03:56:26 +0000 (03:56 +0000)
committerMark Brown <broonie@kernel.org>
Mon, 24 Oct 2016 17:23:29 +0000 (18:23 +0100)
commit 1a5658c2131 ("ASoC: rsnd: count .probe/.remove for
rsnd_mod_call()") solved multi-resource-free issue, by putting
.probe/.remove under count control. But,it breaks sound mixing case
(if it was used under DPCM). In such case, it uses MIXn/DVCn/SSIn,
and these should be always probed.
This patch reverted above patch, and solved the same issue by
modifing _rsnd_kctrl_remove() function.

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/dma.c
sound/soc/sh/rcar/rsnd.h
sound/soc/sh/rcar/ssi.c

index f18141098b50184231bc7a12b8fa41f881435740..209e7363bfdd893bcfa227256f4f5dea4a8a299c 100644 (file)
@@ -993,7 +993,11 @@ static int __rsnd_kctrl_new(struct rsnd_mod *mod,
 
 void _rsnd_kctrl_remove(struct rsnd_kctrl_cfg *cfg)
 {
-       snd_ctl_remove(cfg->card, cfg->kctrl);
+       if (cfg->card && cfg->kctrl)
+               snd_ctl_remove(cfg->card, cfg->kctrl);
+
+       cfg->card = NULL;
+       cfg->kctrl = NULL;
 }
 
 int rsnd_kctrl_new_m(struct rsnd_mod *mod,
index 6bc93cbb3049a823f8b33b559478f2d1175a9052..b3bdd362a5112905176484ec1ba3f9f4604fb582 100644 (file)
@@ -707,6 +707,17 @@ int rsnd_dma_attach(struct rsnd_dai_stream *io, struct rsnd_mod *mod,
        return 0;
 }
 
+void rsnd_dma_detach(struct rsnd_mod *mod, struct rsnd_mod **dma_mod)
+{
+       if (*dma_mod) {
+               struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
+               struct device *dev = rsnd_priv_to_dev(priv);
+
+               devm_kfree(dev, *dma_mod);
+               *dma_mod = NULL;
+       }
+}
+
 int rsnd_dma_probe(struct rsnd_priv *priv)
 {
        struct platform_device *pdev = rsnd_priv_to_pdev(priv);
index a8f61d79333b5071c8fb6785458c4e87aca3158b..901095cb5139415abd0715590d3b9992d0536303 100644 (file)
@@ -200,6 +200,7 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
  */
 int rsnd_dma_attach(struct rsnd_dai_stream *io,
                    struct rsnd_mod *mod, struct rsnd_mod **dma_mod, int id);
+void rsnd_dma_detach(struct rsnd_mod *mod, struct rsnd_mod **dma_mod);
 int rsnd_dma_probe(struct rsnd_priv *priv);
 struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
                                          struct rsnd_mod *mod, char *name);
@@ -276,9 +277,8 @@ struct rsnd_mod {
 /*
  * status
  *
- * 0xH0000CBA
+ * 0xH0000CB0
  *
- * A   0: probe        1: remove
  * B   0: init         1: quit
  * C   0: start        1: stop
  *
@@ -288,19 +288,19 @@ struct rsnd_mod {
  * H   0: fallback
  * H   0: hw_params
  */
-#define __rsnd_mod_shift_probe         0
-#define __rsnd_mod_shift_remove                0
 #define __rsnd_mod_shift_init          4
 #define __rsnd_mod_shift_quit          4
 #define __rsnd_mod_shift_start         8
 #define __rsnd_mod_shift_stop          8
+#define __rsnd_mod_shift_probe         28 /* always called */
+#define __rsnd_mod_shift_remove                28 /* always called */
 #define __rsnd_mod_shift_irq           28 /* always called */
 #define __rsnd_mod_shift_pcm_new       28 /* always called */
 #define __rsnd_mod_shift_fallback      28 /* always called */
 #define __rsnd_mod_shift_hw_params     28 /* always called */
 
-#define __rsnd_mod_add_probe            1
-#define __rsnd_mod_add_remove          -1
+#define __rsnd_mod_add_probe           0
+#define __rsnd_mod_add_remove          0
 #define __rsnd_mod_add_init             1
 #define __rsnd_mod_add_quit            -1
 #define __rsnd_mod_add_start            1
@@ -311,7 +311,7 @@ struct rsnd_mod {
 #define __rsnd_mod_add_hw_params       0
 
 #define __rsnd_mod_call_probe          0
-#define __rsnd_mod_call_remove         1
+#define __rsnd_mod_call_remove         0
 #define __rsnd_mod_call_init           0
 #define __rsnd_mod_call_quit           1
 #define __rsnd_mod_call_start          0
index 6cb6db005fc45dd3e562fe480c0e353db7a6116a..94a19f975fa29ea9e1127f3158ecd70981887d2f 100644 (file)
@@ -698,7 +698,10 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
        int irq = ssi->irq;
 
        /* PIO will request IRQ again */
-       devm_free_irq(dev, irq, mod);
+       if (ssi->dma)
+               devm_free_irq(dev, irq, mod);
+
+       rsnd_dma_detach(mod, &ssi->dma);
 
        return 0;
 }