diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2015-03-26 00:02:09 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-03-27 18:59:17 -0400 |
commit | 2f78dd7f40264697afed4c2ac0890df8f0588e49 (patch) | |
tree | 9d37d40fef4bbf1161f9d447def5273d242dbf93 /sound/soc/sh/rcar/dvc.c | |
parent | c517d838eb7d07bbe9507871fab3931deccff539 (diff) |
ASoC: rsnd: call clk_prepare/unprepare() in probe/remove
clk_prepare_enable()/clk_disable_unprepare() uses mutex inside,
in concretely clk_prepare()/clk_unprepare().And it uses __schedule().
Then, raw_spin_lock/unlock_irq() is called, and it breaks Renesas
sound driver's spin lock irq.
This patch separates thesse into clk_prepare()/clk_unprepare() and
clk_enable/clk_disable. And call clk_prepare()/clk_unprepare() from
probe/remove function. Special thanks to Das Biju.
Reported-by: Das Biju <biju.das@bp.renesas.com>
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sh/rcar/dvc.c')
-rw-r--r-- | sound/soc/sh/rcar/dvc.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index d7f9ed959c4e..261997a3f589 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c | |||
@@ -333,7 +333,7 @@ int rsnd_dvc_probe(struct platform_device *pdev, | |||
333 | struct rsnd_dvc *dvc; | 333 | struct rsnd_dvc *dvc; |
334 | struct clk *clk; | 334 | struct clk *clk; |
335 | char name[RSND_DVC_NAME_SIZE]; | 335 | char name[RSND_DVC_NAME_SIZE]; |
336 | int i, nr; | 336 | int i, nr, ret; |
337 | 337 | ||
338 | rsnd_of_parse_dvc(pdev, of_data, priv); | 338 | rsnd_of_parse_dvc(pdev, of_data, priv); |
339 | 339 | ||
@@ -366,11 +366,24 @@ int rsnd_dvc_probe(struct platform_device *pdev, | |||
366 | 366 | ||
367 | dvc->info = &info->dvc_info[i]; | 367 | dvc->info = &info->dvc_info[i]; |
368 | 368 | ||
369 | rsnd_mod_init(&dvc->mod, &rsnd_dvc_ops, | 369 | ret = rsnd_mod_init(&dvc->mod, &rsnd_dvc_ops, |
370 | clk, RSND_MOD_DVC, i); | 370 | clk, RSND_MOD_DVC, i); |
371 | if (ret) | ||
372 | return ret; | ||
371 | 373 | ||
372 | dev_dbg(dev, "CMD%d probed\n", i); | 374 | dev_dbg(dev, "CMD%d probed\n", i); |
373 | } | 375 | } |
374 | 376 | ||
375 | return 0; | 377 | return 0; |
376 | } | 378 | } |
379 | |||
380 | void rsnd_dvc_remove(struct platform_device *pdev, | ||
381 | struct rsnd_priv *priv) | ||
382 | { | ||
383 | struct rsnd_dvc *dvc; | ||
384 | int i; | ||
385 | |||
386 | for_each_rsnd_dvc(dvc, priv, i) { | ||
387 | rsnd_mod_quit(&dvc->mod); | ||
388 | } | ||
389 | } | ||