| From e1719d6d8a1696f0c7bbbb30195978da484b16b5 Mon Sep 17 00:00:00 2001 |
| From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
| Date: Wed, 19 Oct 2016 03:56:26 +0000 |
| Subject: [PATCH 061/299] ASoC: rsnd: amend .probe/.remove call for DPCM |
| |
| 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> |
| (cherry picked from commit 0af5c01a79ade438698af683511803fc11291360) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| sound/soc/sh/rcar/core.c | 6 +++++- |
| sound/soc/sh/rcar/dma.c | 11 +++++++++++ |
| sound/soc/sh/rcar/rsnd.h | 14 +++++++------- |
| sound/soc/sh/rcar/ssi.c | 5 ++++- |
| 4 files changed, 27 insertions(+), 9 deletions(-) |
| |
| --- a/sound/soc/sh/rcar/core.c |
| +++ b/sound/soc/sh/rcar/core.c |
| @@ -993,7 +993,11 @@ static int __rsnd_kctrl_new(struct rsnd_ |
| |
| 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, |
| --- a/sound/soc/sh/rcar/dma.c |
| +++ b/sound/soc/sh/rcar/dma.c |
| @@ -707,6 +707,17 @@ int rsnd_dma_attach(struct rsnd_dai_stre |
| 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); |
| --- a/sound/soc/sh/rcar/rsnd.h |
| +++ b/sound/soc/sh/rcar/rsnd.h |
| @@ -200,6 +200,7 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod |
| */ |
| 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 |
| --- a/sound/soc/sh/rcar/ssi.c |
| +++ b/sound/soc/sh/rcar/ssi.c |
| @@ -698,7 +698,10 @@ static int rsnd_ssi_dma_remove(struct rs |
| 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; |
| } |