summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorStuart Henderson <stuarth@opensource.cirrus.com>2019-02-19 17:31:57 +0000
committerMark Brown <broonie@kernel.org>2019-02-20 12:00:28 +0000
commitf938f3485c385b9b5c796b2e93427c015a7d18fa (patch)
tree4e9d84d24e104f4a5f888b829bbbdbf4fe72aff8 /sound
parent05bd7fcdd06b19a10f069af1bea3ad9abac038d7 (diff)
downloadlinux-f938f3485c385b9b5c796b2e93427c015a7d18fa.tar.gz
linux-f938f3485c385b9b5c796b2e93427c015a7d18fa.tar.bz2
linux-f938f3485c385b9b5c796b2e93427c015a7d18fa.zip
ASoC: wm_adsp: Update cached error state on trigger
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> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/wm_adsp.c38
1 files changed, 21 insertions, 17 deletions
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 1dd291cebe67..d15cf6e42adc 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -3422,6 +3422,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;
@@ -3443,6 +3460,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 */
@@ -3518,23 +3539,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;