ASoC: wm_adsp: Avoid calling snd_compr_stop_error from WDT expiry
It is unsafe to call snd_compr_stop_error from outside of the
compressed ops. Firstly the compressed device lock needs to be held
and secondly it queues error work to issue a trigger stop which
should not happen after the stream has been freed. To avoid these
issues use the same trick used for the IRQ handling, simply send a
snd_compr_fragment_elapsed to cause user-space to wake on the poll,
then report the error when user-space issues the pointer request
after it wakes.
Fixes: a2bcbc1b9a
("ASoC: wm_adsp: Shutdown any compressed streams on DSP watchdog timeout")
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Cc: stable@kernel.org
This commit is contained in:
parent
fdf34366d3
commit
aa612f2b00
|
@ -4092,7 +4092,7 @@ int wm_adsp_compr_pointer(struct snd_compr_stream *stream,
|
|||
|
||||
buf = compr->buf;
|
||||
|
||||
if (!buf || buf->error) {
|
||||
if (dsp->fatal_error || !buf || buf->error) {
|
||||
snd_compr_stop_error(stream, SNDRV_PCM_STATE_XRUN);
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
|
@ -4196,12 +4196,13 @@ static int wm_adsp_buffer_capture_block(struct wm_adsp_compr *compr, int target)
|
|||
static int wm_adsp_compr_read(struct wm_adsp_compr *compr,
|
||||
char __user *buf, size_t count)
|
||||
{
|
||||
struct wm_adsp *dsp = compr->dsp;
|
||||
int ntotal = 0;
|
||||
int nwords, nbytes;
|
||||
|
||||
compr_dbg(compr, "Requested read of %zu bytes\n", count);
|
||||
|
||||
if (!compr->buf || compr->buf->error) {
|
||||
if (dsp->fatal_error || !compr->buf || compr->buf->error) {
|
||||
snd_compr_stop_error(compr->stream, SNDRV_PCM_STATE_XRUN);
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -4262,11 +4263,8 @@ static void wm_adsp_fatal_error(struct wm_adsp *dsp)
|
|||
dsp->fatal_error = true;
|
||||
|
||||
list_for_each_entry(compr, &dsp->compr_list, list) {
|
||||
if (compr->stream) {
|
||||
snd_compr_stop_error(compr->stream,
|
||||
SNDRV_PCM_STATE_XRUN);
|
||||
if (compr->stream)
|
||||
snd_compr_fragment_elapsed(compr->stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue