From 4137f4b65df7608e52f307f4aa9792b984bad7de Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Tue, 17 Dec 2019 10:58:50 +0100 Subject: [PATCH] ASoC: compress: Add pm_runtime support For some devices, components need to be powered-up before stream startup sequence commences. Update soc_compr_open to provide such functionality. Based on soc_pcm_open. Adjust soc_compr_free accordingly to power down components once compress stream is closed. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20191217095851.19629-7-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/soc-compress.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index 6615ef64c7f5..b2a5351b1a11 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -19,6 +19,7 @@ #include #include #include +#include static int soc_compr_components_open(struct snd_compr_stream *cstream, struct snd_soc_component **last) @@ -72,10 +73,20 @@ static int soc_compr_components_free(struct snd_compr_stream *cstream, static int soc_compr_open(struct snd_compr_stream *cstream) { struct snd_soc_pcm_runtime *rtd = cstream->private_data; - struct snd_soc_component *component; + struct snd_soc_component *component, *save = NULL; + struct snd_soc_rtdcom_list *rtdcom; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int ret; + for_each_rtd_components(rtd, rtdcom, component) { + ret = pm_runtime_get_sync(component->dev); + if (ret < 0 && ret != -EACCES) { + pm_runtime_put_noidle(component->dev); + save = component; + goto pm_err; + } + } + mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) { @@ -115,6 +126,14 @@ machine_err: cpu_dai->driver->cops->shutdown(cstream, cpu_dai); out: mutex_unlock(&rtd->card->pcm_mutex); +pm_err: + for_each_rtd_components(rtd, rtdcom, component) { + if (component == save) + break; + pm_runtime_mark_last_busy(component->dev); + pm_runtime_put_autosuspend(component->dev); + } + return ret; } @@ -239,6 +258,8 @@ static void close_delayed_work(struct snd_soc_pcm_runtime *rtd) static int soc_compr_free(struct snd_compr_stream *cstream) { struct snd_soc_pcm_runtime *rtd = cstream->private_data; + struct snd_soc_component *component; + struct snd_soc_rtdcom_list *rtdcom; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai; int stream; @@ -287,6 +308,12 @@ static int soc_compr_free(struct snd_compr_stream *cstream) } mutex_unlock(&rtd->card->pcm_mutex); + + for_each_rtd_components(rtd, rtdcom, component) { + pm_runtime_mark_last_busy(component->dev); + pm_runtime_put_autosuspend(component->dev); + } + return 0; } -- 2.11.0