aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/soc.h8
-rw-r--r--sound/soc/soc-core.c1
-rw-r--r--sound/soc/soc-pcm.c28
3 files changed, 23 insertions, 14 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index d5db87e82c6..4334ab25c5d 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -269,6 +269,11 @@ enum snd_soc_compress_type {
269 SND_SOC_RBTREE_COMPRESSION 269 SND_SOC_RBTREE_COMPRESSION
270}; 270};
271 271
272enum snd_soc_pcm_subclass {
273 SND_SOC_PCM_CLASS_PCM = 0,
274 SND_SOC_PCM_CLASS_BE = 1,
275};
276
272int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id, 277int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
273 unsigned int freq, int dir); 278 unsigned int freq, int dir);
274int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source, 279int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
@@ -809,6 +814,9 @@ struct snd_soc_pcm_runtime {
809 struct device dev; 814 struct device dev;
810 struct snd_soc_card *card; 815 struct snd_soc_card *card;
811 struct snd_soc_dai_link *dai_link; 816 struct snd_soc_dai_link *dai_link;
817 struct mutex pcm_mutex;
818 enum snd_soc_pcm_subclass pcm_subclass;
819 struct snd_pcm_ops ops;
812 820
813 unsigned int complete:1; 821 unsigned int complete:1;
814 unsigned int dev_registered:1; 822 unsigned int dev_registered:1;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 32d7d2f8147..32bc50387f6 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1032,6 +1032,7 @@ static int soc_post_component_init(struct snd_soc_card *card,
1032 rtd->dev.parent = card->dev; 1032 rtd->dev.parent = card->dev;
1033 rtd->dev.release = rtd_release; 1033 rtd->dev.release = rtd_release;
1034 rtd->dev.init_name = name; 1034 rtd->dev.init_name = name;
1035 mutex_init(&rtd->pcm_mutex);
1035 ret = device_register(&rtd->dev); 1036 ret = device_register(&rtd->dev);
1036 if (ret < 0) { 1037 if (ret < 0) {
1037 dev_err(card->dev, 1038 dev_err(card->dev,
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