aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-compress.c
diff options
context:
space:
mode:
authorRodrigo Vivi <rodrigo.vivi@intel.com>2020-02-25 09:29:58 -0800
committerRodrigo Vivi <rodrigo.vivi@intel.com>2020-02-25 09:39:23 -0800
commitff36e78fdb251b9fa65028554689806961e011eb (patch)
treef5af925d509224e06a10936196be6c06bcbdc6ae /sound/soc/soc-compress.c
parentdrm/i915: Drop assertion that active->fence is unchanged (diff)
parentMerge tag 'drm-misc-next-2020-02-10' of git://anongit.freedesktop.org/drm/drm-misc into drm-next (diff)
downloadlinux-dev-ff36e78fdb251b9fa65028554689806961e011eb.tar.xz
linux-dev-ff36e78fdb251b9fa65028554689806961e011eb.zip
Merge drm/drm-next into drm-intel-next-queued
Some DSI and VBT pending patches from Hans will apply cleanly and with less ugly conflicts if they are rebuilt on top of other patches that recently landed on drm-next. Reference: https://patchwork.freedesktop.org/series/70952/ Cc: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com
Diffstat (limited to 'sound/soc/soc-compress.c')
-rw-r--r--sound/soc/soc-compress.c143
1 files changed, 57 insertions, 86 deletions
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 6615ef64c7f5..223cd045719e 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -19,16 +19,16 @@
#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)
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_component *component;
- struct snd_soc_rtdcom_list *rtdcom;
- int ret;
+ int i, ret;
- for_each_rtd_components(rtd, rtdcom, component) {
+ for_each_rtd_components(rtd, i, component) {
if (!component->driver->compr_ops ||
!component->driver->compr_ops->open)
continue;
@@ -53,9 +53,9 @@ static int soc_compr_components_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;
+ int i;
- for_each_rtd_components(rtd, rtdcom, component) {
+ for_each_rtd_components(rtd, i, component) {
if (component == last)
break;
@@ -72,9 +72,18 @@ 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_dai *cpu_dai = rtd->cpu_dai;
- int ret;
+ int ret, i;
+
+ for_each_rtd_components(rtd, i, 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);
@@ -115,6 +124,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, i, component) {
+ if (component == save)
+ break;
+ pm_runtime_mark_last_busy(component->dev);
+ pm_runtime_put_autosuspend(component->dev);
+ }
+
return ret;
}
@@ -209,39 +226,13 @@ be_err:
return ret;
}
-/*
- * Power down the audio subsystem pmdown_time msecs after close is called.
- * This is to ensure there are no pops or clicks in between any music tracks
- * due to DAPM power cycling.
- */
-static void close_delayed_work(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
-
- mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
-
- dev_dbg(rtd->dev,
- "Compress ASoC: pop wq checking: %s status: %s waiting: %s\n",
- codec_dai->driver->playback.stream_name,
- codec_dai->playback_active ? "active" : "inactive",
- rtd->pop_wait ? "yes" : "no");
-
- /* are we waiting on this codec DAI stream */
- if (rtd->pop_wait == 1) {
- rtd->pop_wait = 0;
- snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
- SND_SOC_DAPM_STREAM_STOP);
- }
-
- mutex_unlock(&rtd->card->pcm_mutex);
-}
-
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_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int stream;
+ int stream, i;
mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
@@ -268,25 +259,15 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
- if (cstream->direction == SND_COMPRESS_PLAYBACK) {
- if (snd_soc_runtime_ignore_pmdown_time(rtd)) {
- snd_soc_dapm_stream_event(rtd,
- SNDRV_PCM_STREAM_PLAYBACK,
- SND_SOC_DAPM_STREAM_STOP);
- } else {
- rtd->pop_wait = 1;
- queue_delayed_work(system_power_efficient_wq,
- &rtd->delayed_work,
- msecs_to_jiffies(rtd->pmdown_time));
- }
- } else {
- /* capture streams can be powered down now */
- snd_soc_dapm_stream_event(rtd,
- SNDRV_PCM_STREAM_CAPTURE,
- SND_SOC_DAPM_STREAM_STOP);
- }
+ snd_soc_dapm_stream_stop(rtd, stream);
mutex_unlock(&rtd->card->pcm_mutex);
+
+ for_each_rtd_components(rtd, i, component) {
+ pm_runtime_mark_last_busy(component->dev);
+ pm_runtime_put_autosuspend(component->dev);
+ }
+
return 0;
}
@@ -318,7 +299,7 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream)
for_each_dpcm_be(fe, stream, dpcm)
dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
- dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
+ snd_soc_dapm_stream_stop(fe, stream);
fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
@@ -344,10 +325,9 @@ static int soc_compr_components_trigger(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;
- int ret;
+ int i, ret;
- for_each_rtd_components(rtd, rtdcom, component) {
+ for_each_rtd_components(rtd, i, component) {
if (!component->driver->compr_ops ||
!component->driver->compr_ops->trigger)
continue;
@@ -447,10 +427,9 @@ static int soc_compr_components_set_params(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;
- int ret;
+ int i, ret;
- for_each_rtd_components(rtd, rtdcom, component) {
+ for_each_rtd_components(rtd, i, component) {
if (!component->driver->compr_ops ||
!component->driver->compr_ops->set_params)
continue;
@@ -579,9 +558,8 @@ static int soc_compr_get_params(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;
- int ret = 0;
+ int i, ret = 0;
mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
@@ -591,7 +569,7 @@ static int soc_compr_get_params(struct snd_compr_stream *cstream,
goto err;
}
- for_each_rtd_components(rtd, rtdcom, component) {
+ for_each_rtd_components(rtd, i, component) {
if (!component->driver->compr_ops ||
!component->driver->compr_ops->get_params)
continue;
@@ -610,12 +588,11 @@ static int soc_compr_get_caps(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;
- int ret = 0;
+ int i, ret = 0;
mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
- for_each_rtd_components(rtd, rtdcom, component) {
+ for_each_rtd_components(rtd, i, component) {
if (!component->driver->compr_ops ||
!component->driver->compr_ops->get_caps)
continue;
@@ -633,12 +610,11 @@ static int soc_compr_get_codec_caps(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;
- int ret = 0;
+ int i, ret = 0;
mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
- for_each_rtd_components(rtd, rtdcom, component) {
+ for_each_rtd_components(rtd, i, component) {
if (!component->driver->compr_ops ||
!component->driver->compr_ops->get_codec_caps)
continue;
@@ -656,9 +632,8 @@ static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
{
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;
- int ret = 0;
+ int i, ret = 0;
mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
@@ -668,7 +643,7 @@ static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
goto err;
}
- for_each_rtd_components(rtd, rtdcom, component) {
+ for_each_rtd_components(rtd, i, component) {
if (!component->driver->compr_ops ||
!component->driver->compr_ops->ack)
continue;
@@ -688,8 +663,7 @@ static int soc_compr_pointer(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;
- int ret = 0;
+ int i, ret = 0;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
@@ -697,7 +671,7 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream,
if (cpu_dai->driver->cops && cpu_dai->driver->cops->pointer)
cpu_dai->driver->cops->pointer(cstream, tstamp, cpu_dai);
- for_each_rtd_components(rtd, rtdcom, component) {
+ for_each_rtd_components(rtd, i, component) {
if (!component->driver->compr_ops ||
!component->driver->compr_ops->pointer)
continue;
@@ -715,12 +689,11 @@ static int soc_compr_copy(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;
- int ret = 0;
+ int i, ret = 0;
mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
- for_each_rtd_components(rtd, rtdcom, component) {
+ for_each_rtd_components(rtd, i, component) {
if (!component->driver->compr_ops ||
!component->driver->compr_ops->copy)
continue;
@@ -738,9 +711,8 @@ static int soc_compr_set_metadata(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;
- int ret;
+ int i, ret;
if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_metadata) {
ret = cpu_dai->driver->cops->set_metadata(cstream, metadata, cpu_dai);
@@ -748,7 +720,7 @@ static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
return ret;
}
- for_each_rtd_components(rtd, rtdcom, component) {
+ for_each_rtd_components(rtd, i, component) {
if (!component->driver->compr_ops ||
!component->driver->compr_ops->set_metadata)
continue;
@@ -767,9 +739,8 @@ static int soc_compr_get_metadata(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;
- int ret;
+ int i, ret;
if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_metadata) {
ret = cpu_dai->driver->cops->get_metadata(cstream, metadata, cpu_dai);
@@ -777,7 +748,7 @@ static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
return ret;
}
- for_each_rtd_components(rtd, rtdcom, component) {
+ for_each_rtd_components(rtd, i, component) {
if (!component->driver->compr_ops ||
!component->driver->compr_ops->get_metadata)
continue;
@@ -830,7 +801,6 @@ static struct snd_compr_ops soc_compr_dyn_ops = {
int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
{
struct snd_soc_component *component;
- struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_compr *compr;
@@ -838,6 +808,7 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
char new_name[64];
int ret = 0, direction = 0;
int playback = 0, capture = 0;
+ int i;
if (rtd->num_codecs > 1) {
dev_err(rtd->card->dev,
@@ -906,7 +877,7 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));
}
- for_each_rtd_components(rtd, rtdcom, component) {
+ for_each_rtd_components(rtd, i, component) {
if (!component->driver->compr_ops ||
!component->driver->compr_ops->copy)
continue;
@@ -927,7 +898,7 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
}
/* DAPM dai link stream work */
- rtd->close_delayed_work_func = close_delayed_work;
+ rtd->close_delayed_work_func = snd_soc_close_delayed_work;
rtd->compr = compr;
compr->private_data = rtd;