diff options
-rw-r--r-- | drivers/media/platform/coda/coda-common.c | 3 | ||||
-rw-r--r-- | drivers/media/platform/coda/coda-jpeg.c | 8 |
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)" : ""); |