Messages in this thread Patch in this message | | | Subject | [PATCH] ASoC: dapm: Fix the unpaired runtime_get/put cases | From | Chuansheng Liu <> | Date | Wed, 19 Dec 2012 18:36:37 +0800 |
| |
Commit f1aac484f7(Take a pm_runtime reference on DAPM devices that are enabled) introduced runtime_get/put calling when devices are in off/non-off bias.
It is based on: 1/ device from off to non-off bias is called thru dapm_pre_sequence_async; 2/ device from non-off to off bias is called thru dapm_post_sequence_async;
There are the above conditions which then make sure runtime_get/put() are pairs.
But some devices has been set to STANDY bias directly during device probing, such as cs42l73_probe(): cs42l73_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
Then it will cause runtime_get() not be called but laterly runtime_put() will be called. Also found some other uppaired cases.
So here add new flag get_runtime, and the logic will be: 1/ when device is from off to non-off bias, runtime_get() will be called if not yet; 2/ When device is off bias, runtime_put() will be called if runtime_get() has been called;
Signed-off-by: liu chuansheng <chuansheng.liu@intel.com> --- include/sound/soc-dapm.h | 1 + sound/soc/soc-dapm.c | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index e1ef63d..e52fdcc 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -586,6 +586,7 @@ struct snd_soc_dapm_context { struct list_head list; int (*stream_event)(struct snd_soc_dapm_context *dapm, int event); + bool get_runtime; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_dapm; diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 1e36bc8..e6d030a 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1460,12 +1460,15 @@ static void dapm_pre_sequence_async(void *data, async_cookie_t cookie) struct snd_soc_dapm_context *d = data; int ret; + if ((d->target_bias_level != SND_SOC_BIAS_OFF) && + (d->dev) && !(d->get_runtime)) { + pm_runtime_get_sync(d->dev); + d->get_runtime = true; + } + /* If we're off and we're not supposed to be go into STANDBY */ if (d->bias_level == SND_SOC_BIAS_OFF && d->target_bias_level != SND_SOC_BIAS_OFF) { - if (d->dev) - pm_runtime_get_sync(d->dev); - ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY); if (ret != 0) dev_err(d->dev, @@ -1506,9 +1509,6 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie) if (ret != 0) dev_err(d->dev, "ASoC: Failed to turn off bias: %d\n", ret); - - if (d->dev) - pm_runtime_put(d->dev); } /* If we just powered up then move to active bias */ @@ -1519,6 +1519,12 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie) dev_err(d->dev, "ASoC: Failed to apply active bias: %d\n", ret); } + + if ((d->bias_level == SND_SOC_BIAS_OFF) && + (d->dev) && (d->get_runtime)) { + pm_runtime_put(d->dev); + d->get_runtime = false; + } } static void dapm_widget_set_peer_power(struct snd_soc_dapm_widget *peer, -- 1.7.0.4
| |