summaryrefslogtreecommitdiff
path: root/sound/soc/soc-pcm.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 15:07:43 +0100
commit72b745e3ad65deac94ea4eb83262c52ba3ffdb5b (patch)
treea5850d63c1e97e8fc8d4a6e1f29b8d6e181b112a /sound/soc/soc-pcm.c
parent12f0bfadf69bb154052722e7e4e5cd1639044c76 (diff)
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-pcm.c')
-rw-r--r--sound/soc/soc-pcm.c36
1 files changed, 18 insertions, 18 deletions
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index da657c8179cc..e163dde5eab1 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -36,7 +36,7 @@
* Increments the active count for all the DAIs and components attached to a PCM
* runtime. Should typically be called when a stream is opened.
*
- * Must be called with the rtd->pcm_mutex being held
+ * Must be called with the rtd->card->pcm_mutex being held
*/
void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream)
{
@@ -44,7 +44,7 @@ void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream)
struct snd_soc_dai *codec_dai;
int i;
- lockdep_assert_held(&rtd->pcm_mutex);
+ lockdep_assert_held(&rtd->card->pcm_mutex);
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
cpu_dai->playback_active++;
@@ -72,7 +72,7 @@ void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream)
* Decrements the active count for all the DAIs and components attached to a PCM
* runtime. Should typically be called when a stream is closed.
*
- * Must be called with the rtd->pcm_mutex being held
+ * Must be called with the rtd->card->pcm_mutex being held
*/
void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream)
{
@@ -80,7 +80,7 @@ void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream)
struct snd_soc_dai *codec_dai;
int i;
- lockdep_assert_held(&rtd->pcm_mutex);
+ lockdep_assert_held(&rtd->card->pcm_mutex);
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
cpu_dai->playback_active--;
@@ -506,7 +506,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
pm_runtime_get_sync(component->dev);
}
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+ mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
/* startup the audio subsystem */
ret = snd_soc_dai_startup(cpu_dai, substream);
@@ -604,7 +604,7 @@ dynamic:
snd_soc_runtime_activate(rtd, substream->stream);
- mutex_unlock(&rtd->pcm_mutex);
+ mutex_unlock(&rtd->card->pcm_mutex);
return 0;
config_err:
@@ -623,7 +623,7 @@ component_err:
snd_soc_dai_shutdown(cpu_dai, substream);
out:
- mutex_unlock(&rtd->pcm_mutex);
+ mutex_unlock(&rtd->card->pcm_mutex);
for_each_rtdcom(rtd, rtdcom) {
component = rtdcom->component;
@@ -653,7 +653,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_dais[0];
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+ mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
dev_dbg(rtd->dev, "ASoC: pop wq checking: %s status: %s waiting: %s\n",
codec_dai->driver->playback.stream_name,
@@ -667,7 +667,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 void codec2codec_close_delayed_work(struct work_struct *work)
@@ -694,7 +694,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
struct snd_soc_dai *codec_dai;
int i;
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+ mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
snd_soc_runtime_deactivate(rtd, substream->stream);
@@ -738,7 +738,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
SND_SOC_DAPM_STREAM_STOP);
}
- mutex_unlock(&rtd->pcm_mutex);
+ mutex_unlock(&rtd->card->pcm_mutex);
for_each_rtdcom(rtd, rtdcom) {
component = rtdcom->component;
@@ -771,7 +771,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
struct snd_soc_dai *codec_dai;
int i, ret = 0;
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+ mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
if (rtd->dai_link->ops->prepare) {
ret = rtd->dai_link->ops->prepare(substream);
@@ -826,7 +826,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
snd_soc_dai_digital_mute(cpu_dai, 0, substream->stream);
out:
- mutex_unlock(&rtd->pcm_mutex);
+ mutex_unlock(&rtd->card->pcm_mutex);
return ret;
}
@@ -876,7 +876,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *codec_dai;
int i, ret = 0;
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+ mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
if (rtd->dai_link->ops->hw_params) {
ret = rtd->dai_link->ops->hw_params(substream, params);
if (ret < 0) {
@@ -962,7 +962,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
if (ret)
goto component_err;
out:
- mutex_unlock(&rtd->pcm_mutex);
+ mutex_unlock(&rtd->card->pcm_mutex);
return ret;
component_err:
@@ -986,7 +986,7 @@ codec_err:
if (rtd->dai_link->ops->hw_free)
rtd->dai_link->ops->hw_free(substream);
- mutex_unlock(&rtd->pcm_mutex);
+ mutex_unlock(&rtd->card->pcm_mutex);
return ret;
}
@@ -1001,7 +1001,7 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
bool playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
int i;
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+ mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
/* clear the corresponding DAIs parameters when going to be inactive */
if (cpu_dai->active == 1) {
@@ -1043,7 +1043,7 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
snd_soc_dai_hw_free(cpu_dai, substream);
- mutex_unlock(&rtd->pcm_mutex);
+ mutex_unlock(&rtd->card->pcm_mutex);
return 0;
}