| From a34733d7e91c1defeb73b851cb78e76db67a5e48 Mon Sep 17 00:00:00 2001 |
| From: Mark Brown <broonie@opensource.wolfsonmicro.com> |
| Date: Sat, 3 Dec 2011 20:14:31 +0000 |
| Subject: ASoC: Hold runtime PM references to components of active DAIs |
| |
| Every device that implements runtime power management for DAIs is doing |
| it in pretty much the same way: in the startup callback they take a |
| runtime PM reference and then in the shutdown callback they release that |
| reference, keeping the device active while the DAI is active. Given the |
| frequency with which this is done and the obviousness of the need to keep |
| the device active in this period factor the code out into the core, taking |
| references on the device for each CPU DAI, CODEC DAI and DMA device in the |
| core. |
| |
| As runtime PM is reference counted this shouldn't interfere with any |
| other reference holding by the drivers, and since (in common with the |
| existing implementations) we don't check for errors on enabling it |
| shouldn't matter if the device actually has runtime PM enabled or not. |
| |
| Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> |
| Tested-by: Peter Ujfalusi <peter.ujfalusi@ti.com> |
| (cherry picked from commit d6652ef8229e9953543f41d8e081c23e653f0044) |
| |
| Signed-off-by: Simon Horman <horms@verge.net.au> |
| --- |
| sound/soc/soc-pcm.c | 15 +++++++++++++++ |
| 1 file changed, 15 insertions(+) |
| |
| diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c |
| index f4864b0..3047db8 100644 |
| --- a/sound/soc/soc-pcm.c |
| +++ b/sound/soc/soc-pcm.c |
| @@ -19,6 +19,7 @@ |
| #include <linux/kernel.h> |
| #include <linux/init.h> |
| #include <linux/delay.h> |
| +#include <linux/pm_runtime.h> |
| #include <linux/slab.h> |
| #include <linux/workqueue.h> |
| #include <sound/core.h> |
| @@ -81,6 +82,10 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) |
| struct snd_soc_dai_driver *codec_dai_drv = codec_dai->driver; |
| int ret = 0; |
| |
| + pm_runtime_get_sync(cpu_dai->dev); |
| + pm_runtime_get_sync(codec_dai->dev); |
| + pm_runtime_get_sync(platform->dev); |
| + |
| mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); |
| |
| /* startup the audio subsystem */ |
| @@ -231,6 +236,11 @@ platform_err: |
| cpu_dai->driver->ops->shutdown(substream, cpu_dai); |
| out: |
| mutex_unlock(&rtd->pcm_mutex); |
| + |
| + pm_runtime_put(platform->dev); |
| + pm_runtime_put(codec_dai->dev); |
| + pm_runtime_put(cpu_dai->dev); |
| + |
| return ret; |
| } |
| |
| @@ -322,6 +332,11 @@ static int soc_codec_close(struct snd_pcm_substream *substream) |
| } |
| |
| mutex_unlock(&rtd->pcm_mutex); |
| + |
| + pm_runtime_put(platform->dev); |
| + pm_runtime_put(codec_dai->dev); |
| + pm_runtime_put(cpu_dai->dev); |
| + |
| return 0; |
| } |
| |
| -- |
| 1.7.10.2.565.gbd578b5 |
| |