Commit e300486a authored by Rander Wang's avatar Rander Wang Committed by Mark Brown

ASoC: Intel: tgl_max98373: fix a runtime pm issue in multi-thread case

When the playback & capture streams are stopped simultaneously, the
SOF PCI device will remain pm_runtime active. The root-cause is a race
condition with two threads reaching the trigger function at the same
time. They see another stream is active so the dapm pin is not
disabled, so the codec remains active as well as the parent PCI
device.

For max98373, the capture stream provides feedback when playback is
working and it is unused when playback is stopped. So the dapm pin
should be set only when playback is active.
Reviewed-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: default avatarRander Wang <rander.wang@intel.com>
Signed-off-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20200821195603.215535-7-pierre-louis.bossart@linux.intel.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 44751fc5
...@@ -66,6 +66,10 @@ int max98373_trigger(struct snd_pcm_substream *substream, int cmd) ...@@ -66,6 +66,10 @@ int max98373_trigger(struct snd_pcm_substream *substream, int cmd)
int j; int j;
int ret = 0; int ret = 0;
/* set spk pin by playback only */
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
return 0;
for_each_rtd_codec_dais(rtd, j, codec_dai) { for_each_rtd_codec_dais(rtd, j, codec_dai) {
struct snd_soc_component *component = codec_dai->component; struct snd_soc_component *component = codec_dai->component;
struct snd_soc_dapm_context *dapm = struct snd_soc_dapm_context *dapm =
...@@ -86,9 +90,6 @@ int max98373_trigger(struct snd_pcm_substream *substream, int cmd) ...@@ -86,9 +90,6 @@ int max98373_trigger(struct snd_pcm_substream *substream, int cmd)
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
/* Make sure no streams are active before disable pin */
if (snd_soc_dai_active(codec_dai) != 1)
break;
ret = snd_soc_dapm_disable_pin(dapm, pin_name); ret = snd_soc_dapm_disable_pin(dapm, pin_name);
if (!ret) if (!ret)
snd_soc_dapm_sync(dapm); snd_soc_dapm_sync(dapm);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment