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>
This commit is contained in:
parent
12f0bfadf6
commit
72b745e3ad
|
@ -988,6 +988,10 @@ struct snd_soc_card {
|
||||||
struct mutex mutex;
|
struct mutex mutex;
|
||||||
struct mutex dapm_mutex;
|
struct mutex dapm_mutex;
|
||||||
|
|
||||||
|
/* Mutex for PCM operations */
|
||||||
|
struct mutex pcm_mutex;
|
||||||
|
enum snd_soc_pcm_subclass pcm_subclass;
|
||||||
|
|
||||||
spinlock_t dpcm_lock;
|
spinlock_t dpcm_lock;
|
||||||
|
|
||||||
bool instantiated;
|
bool instantiated;
|
||||||
|
@ -1116,8 +1120,6 @@ struct snd_soc_pcm_runtime {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct snd_soc_card *card;
|
struct snd_soc_card *card;
|
||||||
struct snd_soc_dai_link *dai_link;
|
struct snd_soc_dai_link *dai_link;
|
||||||
struct mutex pcm_mutex;
|
|
||||||
enum snd_soc_pcm_subclass pcm_subclass;
|
|
||||||
struct snd_pcm_ops ops;
|
struct snd_pcm_ops ops;
|
||||||
|
|
||||||
unsigned int params_select; /* currently selected param for dai link */
|
unsigned int params_select; /* currently selected param for dai link */
|
||||||
|
|
|
@ -80,7 +80,7 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
|
||||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||||
int ret;
|
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) {
|
if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
|
||||||
ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
|
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);
|
snd_soc_runtime_activate(rtd, cstream->direction);
|
||||||
|
|
||||||
mutex_unlock(&rtd->pcm_mutex);
|
mutex_unlock(&rtd->card->pcm_mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ machine_err:
|
||||||
if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
|
if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
|
||||||
cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
|
cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&rtd->pcm_mutex);
|
mutex_unlock(&rtd->card->pcm_mutex);
|
||||||
return ret;
|
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);
|
container_of(work, struct snd_soc_pcm_runtime, delayed_work.work);
|
||||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
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,
|
dev_dbg(rtd->dev,
|
||||||
"Compress ASoC: pop wq checking: %s status: %s waiting: %s\n",
|
"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);
|
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)
|
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;
|
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||||
int stream;
|
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)
|
if (cstream->direction == SND_COMPRESS_PLAYBACK)
|
||||||
stream = SNDRV_PCM_STREAM_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);
|
SND_SOC_DAPM_STREAM_STOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&rtd->pcm_mutex);
|
mutex_unlock(&rtd->card->pcm_mutex);
|
||||||
return 0;
|
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;
|
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||||
int ret;
|
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);
|
ret = soc_compr_components_trigger(cstream, cmd);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -394,7 +394,7 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&rtd->pcm_mutex);
|
mutex_unlock(&rtd->card->pcm_mutex);
|
||||||
return ret;
|
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;
|
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||||
int ret;
|
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
|
* 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 */
|
/* cancel any delayed stream shutdown that is pending */
|
||||||
rtd->pop_wait = 0;
|
rtd->pop_wait = 0;
|
||||||
mutex_unlock(&rtd->pcm_mutex);
|
mutex_unlock(&rtd->card->pcm_mutex);
|
||||||
|
|
||||||
cancel_delayed_work_sync(&rtd->delayed_work);
|
cancel_delayed_work_sync(&rtd->delayed_work);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
mutex_unlock(&rtd->pcm_mutex);
|
mutex_unlock(&rtd->card->pcm_mutex);
|
||||||
return ret;
|
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;
|
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||||
int ret = 0;
|
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) {
|
if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_params) {
|
||||||
ret = cpu_dai->driver->cops->get_params(cstream, params, cpu_dai);
|
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:
|
err:
|
||||||
mutex_unlock(&rtd->pcm_mutex);
|
mutex_unlock(&rtd->card->pcm_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -625,7 +625,7 @@ static int soc_compr_get_caps(struct snd_compr_stream *cstream,
|
||||||
struct snd_soc_rtdcom_list *rtdcom;
|
struct snd_soc_rtdcom_list *rtdcom;
|
||||||
int ret = 0;
|
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) {
|
for_each_rtdcom(rtd, rtdcom) {
|
||||||
component = rtdcom->component;
|
component = rtdcom->component;
|
||||||
|
@ -638,7 +638,7 @@ static int soc_compr_get_caps(struct snd_compr_stream *cstream,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&rtd->pcm_mutex);
|
mutex_unlock(&rtd->card->pcm_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,7 +650,7 @@ static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
|
||||||
struct snd_soc_rtdcom_list *rtdcom;
|
struct snd_soc_rtdcom_list *rtdcom;
|
||||||
int ret = 0;
|
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) {
|
for_each_rtdcom(rtd, rtdcom) {
|
||||||
component = rtdcom->component;
|
component = rtdcom->component;
|
||||||
|
@ -664,7 +664,7 @@ static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&rtd->pcm_mutex);
|
mutex_unlock(&rtd->card->pcm_mutex);
|
||||||
return ret;
|
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;
|
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||||
int ret = 0;
|
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) {
|
if (cpu_dai->driver->cops && cpu_dai->driver->cops->ack) {
|
||||||
ret = cpu_dai->driver->cops->ack(cstream, bytes, cpu_dai);
|
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:
|
err:
|
||||||
mutex_unlock(&rtd->pcm_mutex);
|
mutex_unlock(&rtd->card->pcm_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -710,7 +710,7 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream,
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
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)
|
if (cpu_dai->driver->cops && cpu_dai->driver->cops->pointer)
|
||||||
cpu_dai->driver->cops->pointer(cstream, tstamp, cpu_dai);
|
cpu_dai->driver->cops->pointer(cstream, tstamp, cpu_dai);
|
||||||
|
@ -726,7 +726,7 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&rtd->pcm_mutex);
|
mutex_unlock(&rtd->card->pcm_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -738,7 +738,7 @@ static int soc_compr_copy(struct snd_compr_stream *cstream,
|
||||||
struct snd_soc_rtdcom_list *rtdcom;
|
struct snd_soc_rtdcom_list *rtdcom;
|
||||||
int ret = 0;
|
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) {
|
for_each_rtdcom(rtd, rtdcom) {
|
||||||
component = rtdcom->component;
|
component = rtdcom->component;
|
||||||
|
@ -751,7 +751,7 @@ static int soc_compr_copy(struct snd_compr_stream *cstream,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&rtd->pcm_mutex);
|
mutex_unlock(&rtd->card->pcm_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1360,7 +1360,6 @@ static int soc_post_component_init(struct snd_soc_pcm_runtime *rtd,
|
||||||
rtd->dev->groups = soc_dev_attr_groups;
|
rtd->dev->groups = soc_dev_attr_groups;
|
||||||
dev_set_name(rtd->dev, "%s", name);
|
dev_set_name(rtd->dev, "%s", name);
|
||||||
dev_set_drvdata(rtd->dev, rtd);
|
dev_set_drvdata(rtd->dev, rtd);
|
||||||
mutex_init(&rtd->pcm_mutex);
|
|
||||||
INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients);
|
INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients);
|
||||||
INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].be_clients);
|
INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].be_clients);
|
||||||
INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].fe_clients);
|
INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].fe_clients);
|
||||||
|
@ -2383,6 +2382,7 @@ int snd_soc_register_card(struct snd_soc_card *card)
|
||||||
card->instantiated = 0;
|
card->instantiated = 0;
|
||||||
mutex_init(&card->mutex);
|
mutex_init(&card->mutex);
|
||||||
mutex_init(&card->dapm_mutex);
|
mutex_init(&card->dapm_mutex);
|
||||||
|
mutex_init(&card->pcm_mutex);
|
||||||
spin_lock_init(&card->dpcm_lock);
|
spin_lock_init(&card->dpcm_lock);
|
||||||
|
|
||||||
return snd_soc_bind_card(card);
|
return snd_soc_bind_card(card);
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
* Increments the active count for all the DAIs and components attached to a PCM
|
* Increments the active count for all the DAIs and components attached to a PCM
|
||||||
* runtime. Should typically be called when a stream is opened.
|
* 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)
|
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;
|
struct snd_soc_dai *codec_dai;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
lockdep_assert_held(&rtd->pcm_mutex);
|
lockdep_assert_held(&rtd->card->pcm_mutex);
|
||||||
|
|
||||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||||
cpu_dai->playback_active++;
|
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
|
* Decrements the active count for all the DAIs and components attached to a PCM
|
||||||
* runtime. Should typically be called when a stream is closed.
|
* 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)
|
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;
|
struct snd_soc_dai *codec_dai;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
lockdep_assert_held(&rtd->pcm_mutex);
|
lockdep_assert_held(&rtd->card->pcm_mutex);
|
||||||
|
|
||||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||||
cpu_dai->playback_active--;
|
cpu_dai->playback_active--;
|
||||||
|
@ -506,7 +506,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
|
||||||
pm_runtime_get_sync(component->dev);
|
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 */
|
/* startup the audio subsystem */
|
||||||
ret = snd_soc_dai_startup(cpu_dai, substream);
|
ret = snd_soc_dai_startup(cpu_dai, substream);
|
||||||
|
@ -604,7 +604,7 @@ dynamic:
|
||||||
|
|
||||||
snd_soc_runtime_activate(rtd, substream->stream);
|
snd_soc_runtime_activate(rtd, substream->stream);
|
||||||
|
|
||||||
mutex_unlock(&rtd->pcm_mutex);
|
mutex_unlock(&rtd->card->pcm_mutex);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
config_err:
|
config_err:
|
||||||
|
@ -623,7 +623,7 @@ component_err:
|
||||||
|
|
||||||
snd_soc_dai_shutdown(cpu_dai, substream);
|
snd_soc_dai_shutdown(cpu_dai, substream);
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&rtd->pcm_mutex);
|
mutex_unlock(&rtd->card->pcm_mutex);
|
||||||
|
|
||||||
for_each_rtdcom(rtd, rtdcom) {
|
for_each_rtdcom(rtd, rtdcom) {
|
||||||
component = rtdcom->component;
|
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);
|
container_of(work, struct snd_soc_pcm_runtime, delayed_work.work);
|
||||||
struct snd_soc_dai *codec_dai = rtd->codec_dais[0];
|
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",
|
dev_dbg(rtd->dev, "ASoC: pop wq checking: %s status: %s waiting: %s\n",
|
||||||
codec_dai->driver->playback.stream_name,
|
codec_dai->driver->playback.stream_name,
|
||||||
|
@ -667,7 +667,7 @@ static void close_delayed_work(struct work_struct *work)
|
||||||
SND_SOC_DAPM_STREAM_STOP);
|
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)
|
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;
|
struct snd_soc_dai *codec_dai;
|
||||||
int i;
|
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);
|
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);
|
SND_SOC_DAPM_STREAM_STOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&rtd->pcm_mutex);
|
mutex_unlock(&rtd->card->pcm_mutex);
|
||||||
|
|
||||||
for_each_rtdcom(rtd, rtdcom) {
|
for_each_rtdcom(rtd, rtdcom) {
|
||||||
component = rtdcom->component;
|
component = rtdcom->component;
|
||||||
|
@ -771,7 +771,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
|
||||||
struct snd_soc_dai *codec_dai;
|
struct snd_soc_dai *codec_dai;
|
||||||
int i, ret = 0;
|
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) {
|
if (rtd->dai_link->ops->prepare) {
|
||||||
ret = rtd->dai_link->ops->prepare(substream);
|
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);
|
snd_soc_dai_digital_mute(cpu_dai, 0, substream->stream);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&rtd->pcm_mutex);
|
mutex_unlock(&rtd->card->pcm_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -876,7 +876,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||||
struct snd_soc_dai *codec_dai;
|
struct snd_soc_dai *codec_dai;
|
||||||
int i, ret = 0;
|
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) {
|
if (rtd->dai_link->ops->hw_params) {
|
||||||
ret = rtd->dai_link->ops->hw_params(substream, params);
|
ret = rtd->dai_link->ops->hw_params(substream, params);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -962,7 +962,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||||
if (ret)
|
if (ret)
|
||||||
goto component_err;
|
goto component_err;
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&rtd->pcm_mutex);
|
mutex_unlock(&rtd->card->pcm_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
component_err:
|
component_err:
|
||||||
|
@ -986,7 +986,7 @@ codec_err:
|
||||||
if (rtd->dai_link->ops->hw_free)
|
if (rtd->dai_link->ops->hw_free)
|
||||||
rtd->dai_link->ops->hw_free(substream);
|
rtd->dai_link->ops->hw_free(substream);
|
||||||
|
|
||||||
mutex_unlock(&rtd->pcm_mutex);
|
mutex_unlock(&rtd->card->pcm_mutex);
|
||||||
return ret;
|
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;
|
bool playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
|
||||||
int i;
|
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 */
|
/* clear the corresponding DAIs parameters when going to be inactive */
|
||||||
if (cpu_dai->active == 1) {
|
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);
|
snd_soc_dai_hw_free(cpu_dai, substream);
|
||||||
|
|
||||||
mutex_unlock(&rtd->pcm_mutex);
|
mutex_unlock(&rtd->card->pcm_mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue