FAILED: patch "[PATCH] ASoC: wm_adsp: Avoid calling snd_compr_stop_error from WDT" failed to apply to 5.1-stable tree
Subsystems (4)
[email protected]
maintainerThe patch below does not apply to the 5.1-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From aa612f2b006aa3552871dabcd6a8e90e33f65e09 Mon Sep 17 00:00:00 2001
From: Charles Keepax <[email protected]>
Date: Thu, 4 Apr 2019 13:56:01 +0100
Subject: [PATCH] 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.
sound/soc/codecs/wm_adsp.c +4 -6
@@ -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); - } } }