summaryrefslogtreecommitdiff
path: root/sound/soc/soc-compress.c
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@ti.com>2019-08-13 13:45:32 +0300
committerMark Brown <broonie@kernel.org>2019-08-15 17:07:43 +0300
commit72b745e3ad65deac94ea4eb83262c52ba3ffdb5b (patch)
treea5850d63c1e97e8fc8d4a6e1f29b8d6e181b112a /sound/soc/soc-compress.c
parent12f0bfadf69bb154052722e7e4e5cd1639044c76 (diff)
downloadlinux-72b745e3ad65deac94ea4eb83262c52ba3ffdb5b.tar.xz
ASoC: core: Move pcm_mutex up to card level from snd_soc_pcm_runtime
The pcm_mutex is used to prevent concurrent execution of snd_pcm_ops callbacks. This works fine most of the cases but it can not handle setups when the same DAI is used by different rtd, for example: pcm3168a have two DAIs: one for Playback and one for Capture. If the codec is connected to a single CPU DAI we need to have two dai_link to support both playback and capture. In this case the snd_pcm_ops callbacks can be executed in parallel causing unexpected races in DAI drivers. By moving the pcm_mutex up to card level this can be solved while - hopefully - not breaking other setups. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Tested-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://lore.kernel.org/r/20190813104532.16669-1-peter.ujfalusi@ti.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/soc-compress.c')
-rw-r--r--sound/soc/soc-compress.c48
1 files changed, 24 insertions, 24 deletions
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 289211069a1e..9e54d8ae6d2c 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -80,7 +80,7 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int ret;
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+ mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
@@ -108,7 +108,7 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
snd_soc_runtime_activate(rtd, cstream->direction);
- mutex_unlock(&rtd->pcm_mutex);
+ mutex_unlock(&rtd->card->pcm_mutex);
return 0;
@@ -118,7 +118,7 @@ machine_err:
if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
out:
- mutex_unlock(&rtd->pcm_mutex);
+ mutex_unlock(&rtd->card->pcm_mutex);
return ret;
}
@@ -224,7 +224,7 @@ static void close_delayed_work(struct work_struct *work)
container_of(work, struct snd_soc_pcm_runtime, delayed_work.work);
struct snd_soc_dai *codec_dai = rtd->codec_dai;
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+ 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",
@@ -239,7 +239,7 @@ static void close_delayed_work(struct work_struct *work)
SND_SOC_DAPM_STREAM_STOP);
}
- mutex_unlock(&rtd->pcm_mutex);
+ mutex_unlock(&rtd->card->pcm_mutex);
}
static int soc_compr_free(struct snd_compr_stream *cstream)
@@ -249,7 +249,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
struct snd_soc_dai *codec_dai = rtd->codec_dai;
int stream;
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+ mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
if (cstream->direction == SND_COMPRESS_PLAYBACK)
stream = SNDRV_PCM_STREAM_PLAYBACK;
@@ -292,7 +292,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
SND_SOC_DAPM_STREAM_STOP);
}
- mutex_unlock(&rtd->pcm_mutex);
+ mutex_unlock(&rtd->card->pcm_mutex);
return 0;
}
@@ -375,7 +375,7 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int ret;
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+ mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
ret = soc_compr_components_trigger(cstream, cmd);
if (ret < 0)
@@ -394,7 +394,7 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
}
out:
- mutex_unlock(&rtd->pcm_mutex);
+ mutex_unlock(&rtd->card->pcm_mutex);
return ret;
}
@@ -480,7 +480,7 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int ret;
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+ mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
/*
* First we call set_params for the CPU DAI, then the component
@@ -514,14 +514,14 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
/* cancel any delayed stream shutdown that is pending */
rtd->pop_wait = 0;
- mutex_unlock(&rtd->pcm_mutex);
+ mutex_unlock(&rtd->card->pcm_mutex);
cancel_delayed_work_sync(&rtd->delayed_work);
return 0;
err:
- mutex_unlock(&rtd->pcm_mutex);
+ mutex_unlock(&rtd->card->pcm_mutex);
return ret;
}
@@ -593,7 +593,7 @@ static int soc_compr_get_params(struct snd_compr_stream *cstream,
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int ret = 0;
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+ mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_params) {
ret = cpu_dai->driver->cops->get_params(cstream, params, cpu_dai);
@@ -613,7 +613,7 @@ static int soc_compr_get_params(struct snd_compr_stream *cstream,
}
err:
- mutex_unlock(&rtd->pcm_mutex);
+ mutex_unlock(&rtd->card->pcm_mutex);
return ret;
}
@@ -625,7 +625,7 @@ static int soc_compr_get_caps(struct snd_compr_stream *cstream,
struct snd_soc_rtdcom_list *rtdcom;
int ret = 0;
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+ mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
for_each_rtdcom(rtd, rtdcom) {
component = rtdcom->component;
@@ -638,7 +638,7 @@ static int soc_compr_get_caps(struct snd_compr_stream *cstream,
break;
}
- mutex_unlock(&rtd->pcm_mutex);
+ mutex_unlock(&rtd->card->pcm_mutex);
return ret;
}
@@ -650,7 +650,7 @@ static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
struct snd_soc_rtdcom_list *rtdcom;
int ret = 0;
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+ mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
for_each_rtdcom(rtd, rtdcom) {
component = rtdcom->component;
@@ -664,7 +664,7 @@ static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
break;
}
- mutex_unlock(&rtd->pcm_mutex);
+ mutex_unlock(&rtd->card->pcm_mutex);
return ret;
}
@@ -676,7 +676,7 @@ static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int ret = 0;
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+ mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
if (cpu_dai->driver->cops && cpu_dai->driver->cops->ack) {
ret = cpu_dai->driver->cops->ack(cstream, bytes, cpu_dai);
@@ -697,7 +697,7 @@ static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
}
err:
- mutex_unlock(&rtd->pcm_mutex);
+ mutex_unlock(&rtd->card->pcm_mutex);
return ret;
}
@@ -710,7 +710,7 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream,
int ret = 0;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+ mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
if (cpu_dai->driver->cops && cpu_dai->driver->cops->pointer)
cpu_dai->driver->cops->pointer(cstream, tstamp, cpu_dai);
@@ -726,7 +726,7 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream,
break;
}
- mutex_unlock(&rtd->pcm_mutex);
+ mutex_unlock(&rtd->card->pcm_mutex);
return ret;
}
@@ -738,7 +738,7 @@ static int soc_compr_copy(struct snd_compr_stream *cstream,
struct snd_soc_rtdcom_list *rtdcom;
int ret = 0;
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+ mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
for_each_rtdcom(rtd, rtdcom) {
component = rtdcom->component;
@@ -751,7 +751,7 @@ static int soc_compr_copy(struct snd_compr_stream *cstream,
break;
}
- mutex_unlock(&rtd->pcm_mutex);
+ mutex_unlock(&rtd->card->pcm_mutex);
return ret;
}