summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/media/platform/coda/coda-common.c3
-rw-r--r--drivers/media/platform/coda/coda-jpeg.c8
2 files changed, 11 insertions, 0 deletions
diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c
index 55bbd2a4c77f..80ad2db3e9c9 100644
--- a/drivers/media/platform/coda/coda-common.c
+++ b/drivers/media/platform/coda/coda-common.c
@@ -1230,6 +1230,8 @@ static int coda_decoder_cmd(struct file *file, void *fh,
stream_end = false;
wakeup = false;
+ mutex_lock(&ctx->wakeup_mutex);
+
buf = v4l2_m2m_last_src_buf(ctx->fh.m2m_ctx);
if (buf) {
coda_dbg(1, ctx, "marking last pending buffer\n");
@@ -1266,6 +1268,7 @@ static int coda_decoder_cmd(struct file *file, void *fh,
coda_wake_up_capture_queue(ctx);
}
+ mutex_unlock(&ctx->wakeup_mutex);
break;
default:
return -EINVAL;
diff --git a/drivers/media/platform/coda/coda-jpeg.c b/drivers/media/platform/coda/coda-jpeg.c
index c1407a677667..4512b2569b6b 100644
--- a/drivers/media/platform/coda/coda-jpeg.c
+++ b/drivers/media/platform/coda/coda-jpeg.c
@@ -1428,6 +1428,12 @@ static void coda9_jpeg_finish_decode(struct coda_ctx *ctx)
coda_write(dev, 0, CODA9_REG_JPEG_BBC_FLUSH_CMD);
+ /*
+ * Lock to make sure that a decoder stop command running in parallel
+ * will either already have marked src_buf as last, or it will wake up
+ * the capture queue after the buffers are returned.
+ */
+ mutex_lock(&ctx->wakeup_mutex);
src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
dst_buf->sequence = ctx->osequence++;
@@ -1447,6 +1453,8 @@ static void coda9_jpeg_finish_decode(struct coda_ctx *ctx)
coda_m2m_buf_done(ctx, dst_buf, err_mb ? VB2_BUF_STATE_ERROR :
VB2_BUF_STATE_DONE);
+ mutex_unlock(&ctx->wakeup_mutex);
+
coda_dbg(1, ctx, "job finished: decoded frame (%u)%s\n",
dst_buf->sequence,
(dst_buf->flags & V4L2_BUF_FLAG_LAST) ? " (last)" : "");