ASoC: Intel: avs: DSP recovery and resume fixes

Merge series from Cezary Rojewski <cezary.rojewski@intel.com>:

Two fixes that are result of the recent discussions [1][2].

First adds missing locking around snd_pcm_stop() while the second fix
sets substream state to DISCONNECTED if any suspend/resume related
operation fails so that userspace has means to be aware that something
went wrong during said operation.
This commit is contained in:
Mark Brown 2022-11-23 12:22:12 +00:00
commit e9a45c8aca
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
2 changed files with 11 additions and 2 deletions

View File

@ -123,7 +123,10 @@ static void avs_dsp_recovery(struct avs_dev *adev)
if (!substream || !substream->runtime) if (!substream || !substream->runtime)
continue; continue;
/* No need for _irq() as we are in nonatomic context. */
snd_pcm_stream_lock(substream);
snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED); snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
snd_pcm_stream_unlock(substream);
} }
} }
} }

View File

@ -934,21 +934,27 @@ static int avs_component_pm_op(struct snd_soc_component *component, bool be,
rtd = snd_pcm_substream_chip(data->substream); rtd = snd_pcm_substream_chip(data->substream);
if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) { if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) {
ret = op(dai, data); ret = op(dai, data);
if (ret < 0) if (ret < 0) {
__snd_pcm_set_state(data->substream->runtime,
SNDRV_PCM_STATE_DISCONNECTED);
return ret; return ret;
} }
} }
}
data = dai->capture_dma_data; data = dai->capture_dma_data;
if (data) { if (data) {
rtd = snd_pcm_substream_chip(data->substream); rtd = snd_pcm_substream_chip(data->substream);
if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) { if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) {
ret = op(dai, data); ret = op(dai, data);
if (ret < 0) if (ret < 0) {
__snd_pcm_set_state(data->substream->runtime,
SNDRV_PCM_STATE_DISCONNECTED);
return ret; return ret;
} }
} }
} }
}
return 0; return 0;
} }