]> git.baikalelectronics.ru Git - kernel.git/commitdiff
ASoC: compress: Add pm_runtime support
authorCezary Rojewski <cezary.rojewski@intel.com>
Tue, 17 Dec 2019 09:58:50 +0000 (10:58 +0100)
committerMark Brown <broonie@kernel.org>
Tue, 17 Dec 2019 12:35:02 +0000 (12:35 +0000)
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 <cezary.rojewski@intel.com>
Link: https://lore.kernel.org/r/20191217095851.19629-7-cezary.rojewski@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/soc-compress.c

index 6615ef64c7f55ad1c7bd94f186babaa64feab966..b2a5351b1a11a9c0b8ac4b08da502e6db965dcc3 100644 (file)
@@ -19,6 +19,7 @@
 #include <sound/soc.h>
 #include <sound/initval.h>
 #include <sound/soc-dpcm.h>
+#include <linux/pm_runtime.h>
 
 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;
 }