aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-pcm.c
diff options
context:
space:
mode:
authorLiam Girdwood <lrg@ti.com>2011-06-09 12:04:39 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-06-09 14:29:29 -0400
commitb8c0dab9bf3373010e857a8d3f1b594c60a348dd (patch)
tree9ea917827ed56fc655c3528431dfb234e8231660 /sound/soc/soc-pcm.c
parent2c36c2ce00987a416bf75681742617a0f85335eb (diff)
ASoC: core - PCM mutex per rtd
In preparation for the new ASoC Dynamic PCM support (AKA DSP support). The new ASoC Dynamic PCM core allows DAIs to be dynamically re-routed at runtime between the PCM device end (or Frontend - FE) and the physical DAI (Backend - BE) using regular kcontrols (just like a hardware CODEC routes audio in the analog domain). The Dynamic PCM core therefore must be able to call PCM operations for both the Frontend and Backend(s) DAIs at the same time. Currently we have a global pcm_mutex that is used to serialise the ASoC PCM operations. This patch removes the global mutex and adds a mutex per RTD allowing the PCM operations to be reentrant and allow control of more than one DAI at at time. e.g. a frontend PCM hw_params() could configure multiple backend DAI hw_params() with similar or different hw parameters at the same time. Signed-off-by: Liam Girdwood <lrg@ti.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/soc-pcm.c')
-rw-r--r--sound/soc/soc-pcm.c28
1 files changed, 14 insertions, 14 deletions
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 9bebee82bc1..f4864b088d2 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -81,7 +81,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
81 struct snd_soc_dai_driver *codec_dai_drv = codec_dai->driver; 81 struct snd_soc_dai_driver *codec_dai_drv = codec_dai->driver;
82 int ret = 0; 82 int ret = 0;
83 83
84 mutex_lock(&pcm_mutex); 84 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
85 85
86 /* startup the audio subsystem */ 86 /* startup the audio subsystem */
87 if (cpu_dai->driver->ops->startup) { 87 if (cpu_dai->driver->ops->startup) {
@@ -211,7 +211,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
211 cpu_dai->active++; 211 cpu_dai->active++;
212 codec_dai->active++; 212 codec_dai->active++;
213 rtd->codec->active++; 213 rtd->codec->active++;
214 mutex_unlock(&pcm_mutex); 214 mutex_unlock(&rtd->pcm_mutex);
215 return 0; 215 return 0;
216 216
217config_err: 217config_err:
@@ -230,7 +230,7 @@ platform_err:
230 if (cpu_dai->driver->ops->shutdown) 230 if (cpu_dai->driver->ops->shutdown)
231 cpu_dai->driver->ops->shutdown(substream, cpu_dai); 231 cpu_dai->driver->ops->shutdown(substream, cpu_dai);
232out: 232out:
233 mutex_unlock(&pcm_mutex); 233 mutex_unlock(&rtd->pcm_mutex);
234 return ret; 234 return ret;
235} 235}
236 236
@@ -245,7 +245,7 @@ static void close_delayed_work(struct work_struct *work)
245 container_of(work, struct snd_soc_pcm_runtime, delayed_work.work); 245 container_of(work, struct snd_soc_pcm_runtime, delayed_work.work);
246 struct snd_soc_dai *codec_dai = rtd->codec_dai; 246 struct snd_soc_dai *codec_dai = rtd->codec_dai;
247 247
248 mutex_lock(&pcm_mutex); 248 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
249 249
250 pr_debug("pop wq checking: %s status: %s waiting: %s\n", 250 pr_debug("pop wq checking: %s status: %s waiting: %s\n",
251 codec_dai->driver->playback.stream_name, 251 codec_dai->driver->playback.stream_name,
@@ -260,7 +260,7 @@ static void close_delayed_work(struct work_struct *work)
260 SND_SOC_DAPM_STREAM_STOP); 260 SND_SOC_DAPM_STREAM_STOP);
261 } 261 }
262 262
263 mutex_unlock(&pcm_mutex); 263 mutex_unlock(&rtd->pcm_mutex);
264} 264}
265 265
266/* 266/*
@@ -276,7 +276,7 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
276 struct snd_soc_dai *codec_dai = rtd->codec_dai; 276 struct snd_soc_dai *codec_dai = rtd->codec_dai;
277 struct snd_soc_codec *codec = rtd->codec; 277 struct snd_soc_codec *codec = rtd->codec;
278 278
279 mutex_lock(&pcm_mutex); 279 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
280 280
281 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 281 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
282 cpu_dai->playback_active--; 282 cpu_dai->playback_active--;
@@ -321,7 +321,7 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
321 SND_SOC_DAPM_STREAM_STOP); 321 SND_SOC_DAPM_STREAM_STOP);
322 } 322 }
323 323
324 mutex_unlock(&pcm_mutex); 324 mutex_unlock(&rtd->pcm_mutex);
325 return 0; 325 return 0;
326} 326}
327 327
@@ -338,7 +338,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
338 struct snd_soc_dai *codec_dai = rtd->codec_dai; 338 struct snd_soc_dai *codec_dai = rtd->codec_dai;
339 int ret = 0; 339 int ret = 0;
340 340
341 mutex_lock(&pcm_mutex); 341 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
342 342
343 if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) { 343 if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) {
344 ret = rtd->dai_link->ops->prepare(substream); 344 ret = rtd->dai_link->ops->prepare(substream);
@@ -391,7 +391,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
391 snd_soc_dai_digital_mute(codec_dai, 0); 391 snd_soc_dai_digital_mute(codec_dai, 0);
392 392
393out: 393out:
394 mutex_unlock(&pcm_mutex); 394 mutex_unlock(&rtd->pcm_mutex);
395 return ret; 395 return ret;
396} 396}
397 397
@@ -409,7 +409,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
409 struct snd_soc_dai *codec_dai = rtd->codec_dai; 409 struct snd_soc_dai *codec_dai = rtd->codec_dai;
410 int ret = 0; 410 int ret = 0;
411 411
412 mutex_lock(&pcm_mutex); 412 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
413 413
414 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) { 414 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) {
415 ret = rtd->dai_link->ops->hw_params(substream, params); 415 ret = rtd->dai_link->ops->hw_params(substream, params);
@@ -449,7 +449,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
449 rtd->rate = params_rate(params); 449 rtd->rate = params_rate(params);
450 450
451out: 451out:
452 mutex_unlock(&pcm_mutex); 452 mutex_unlock(&rtd->pcm_mutex);
453 return ret; 453 return ret;
454 454
455platform_err: 455platform_err:
@@ -464,7 +464,7 @@ codec_err:
464 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free) 464 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free)
465 rtd->dai_link->ops->hw_free(substream); 465 rtd->dai_link->ops->hw_free(substream);
466 466
467 mutex_unlock(&pcm_mutex); 467 mutex_unlock(&rtd->pcm_mutex);
468 return ret; 468 return ret;
469} 469}
470 470
@@ -479,7 +479,7 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
479 struct snd_soc_dai *codec_dai = rtd->codec_dai; 479 struct snd_soc_dai *codec_dai = rtd->codec_dai;
480 struct snd_soc_codec *codec = rtd->codec; 480 struct snd_soc_codec *codec = rtd->codec;
481 481
482 mutex_lock(&pcm_mutex); 482 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
483 483
484 /* apply codec digital mute */ 484 /* apply codec digital mute */
485 if (!codec->active) 485 if (!codec->active)
@@ -500,7 +500,7 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
500 if (cpu_dai->driver->ops->hw_free) 500 if (cpu_dai->driver->ops->hw_free)
501 cpu_dai->driver->ops->hw_free(substream, cpu_dai); 501 cpu_dai->driver->ops->hw_free(substream, cpu_dai);
502 502
503 mutex_unlock(&pcm_mutex); 503 mutex_unlock(&rtd->pcm_mutex);
504 return 0; 504 return 0;
505} 505}
506 506