diff mbox series

[2/2] ASoC: wm_adsp: Update cached error state on trigger

Message ID 20190219173157.14611-2-ckeepax@opensource.cirrus.com (mailing list archive)
State Accepted
Commit f938f3485c385b9b5c796b2e93427c015a7d18fa
Headers show
Series [1/2] ASoC: wm_adsp: Allow compressed buffers in any memory region | expand

Commit Message

Charles Keepax Feb. 19, 2019, 5:31 p.m. UTC
From: Stuart Henderson <stuarth@opensource.cirrus.com>

If a compressed stream is restarted after getting an error, the cached
error value will still be used on the next pointer request, preventing
the stream from starting.  Resolve this by ensuring the error status is
updated on trigger start.

Signed-off-by: Stuart Henderson <stuarth@opensource.cirrus.com>
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
 sound/soc/codecs/wm_adsp.c | 38 +++++++++++++++++++++-----------------
 1 file changed, 21 insertions(+), 17 deletions(-)

Comments

Mark Brown Feb. 20, 2019, 11:54 a.m. UTC | #1
On Tue, Feb 19, 2019 at 05:31:57PM +0000, Charles Keepax wrote:
> From: Stuart Henderson <stuarth@opensource.cirrus.com>
> 
> If a compressed stream is restarted after getting an error, the cached
> error value will still be used on the next pointer request, preventing
> the stream from starting.  Resolve this by ensuring the error status is
> updated on trigger start.

It's better to send fixes at the start of the series as this makes it
easier to apply them on a fixes branch for sending to Linus early.
diff mbox series

Patch

diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 12ef85e85c29..8d16a14cd226 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -3426,6 +3426,23 @@  static int wm_adsp_buffer_free(struct wm_adsp *dsp)
 	return 0;
 }
 
+static int wm_adsp_buffer_get_error(struct wm_adsp_compr_buf *buf)
+{
+	int ret;
+
+	ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(error), &buf->error);
+	if (ret < 0) {
+		adsp_err(buf->dsp, "Failed to check buffer error: %d\n", ret);
+		return ret;
+	}
+	if (buf->error != 0) {
+		adsp_err(buf->dsp, "Buffer error occurred: %d\n", buf->error);
+		return -EIO;
+	}
+
+	return 0;
+}
+
 int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd)
 {
 	struct wm_adsp_compr *compr = stream->runtime->private_data;
@@ -3447,6 +3464,10 @@  int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd)
 			}
 		}
 
+		ret = wm_adsp_buffer_get_error(compr->buf);
+		if (ret < 0)
+			break;
+
 		wm_adsp_buffer_clear(compr->buf);
 
 		/* Trigger the IRQ at one fragment of data */
@@ -3522,23 +3543,6 @@  static int wm_adsp_buffer_update_avail(struct wm_adsp_compr_buf *buf)
 	return 0;
 }
 
-static int wm_adsp_buffer_get_error(struct wm_adsp_compr_buf *buf)
-{
-	int ret;
-
-	ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(error), &buf->error);
-	if (ret < 0) {
-		adsp_err(buf->dsp, "Failed to check buffer error: %d\n", ret);
-		return ret;
-	}
-	if (buf->error != 0) {
-		adsp_err(buf->dsp, "Buffer error occurred: %d\n", buf->error);
-		return -EIO;
-	}
-
-	return 0;
-}
-
 int wm_adsp_compr_handle_irq(struct wm_adsp *dsp)
 {
 	struct wm_adsp_compr_buf *buf;