diff options
| -rw-r--r-- | drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c | 33 | ||||
| -rw-r--r-- | drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h | 16 |
2 files changed, 28 insertions, 21 deletions
diff --git a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c index f3073d1e7f42..03f8d7cd8edd 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c +++ b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c @@ -71,7 +71,6 @@ static void vdec_msg_queue_dec(struct vdec_msg_queue *msg_queue, int hardware_in int vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *msg_ctx, struct vdec_lat_buf *buf) { struct list_head *head; - int status; head = vdec_get_buf_list(msg_ctx->hardware_index, buf); if (!head) { @@ -87,12 +86,9 @@ int vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *msg_ctx, struct vdec_lat_buf if (msg_ctx->hardware_index != MTK_VDEC_CORE) { wake_up_all(&msg_ctx->ready_to_use); } else { - if (buf->ctx->msg_queue.core_work_cnt < - atomic_read(&buf->ctx->msg_queue.core_list_cnt)) { - status = queue_work(buf->ctx->dev->core_workqueue, - &buf->ctx->msg_queue.core_work); - if (status) - buf->ctx->msg_queue.core_work_cnt++; + if (!(buf->ctx->msg_queue.status & CONTEXT_LIST_QUEUED)) { + queue_work(buf->ctx->dev->core_workqueue, &buf->ctx->msg_queue.core_work); + buf->ctx->msg_queue.status |= CONTEXT_LIST_QUEUED; } } @@ -261,7 +257,10 @@ static void vdec_msg_queue_core_work(struct work_struct *work) container_of(msg_queue, struct mtk_vcodec_ctx, msg_queue); struct mtk_vcodec_dev *dev = ctx->dev; struct vdec_lat_buf *lat_buf; - int status; + + spin_lock(&ctx->dev->msg_queue_core_ctx.ready_lock); + ctx->msg_queue.status &= ~CONTEXT_LIST_QUEUED; + spin_unlock(&ctx->dev->msg_queue_core_ctx.ready_lock); lat_buf = vdec_msg_queue_dqbuf(&dev->msg_queue_core_ctx); if (!lat_buf) @@ -278,17 +277,13 @@ static void vdec_msg_queue_core_work(struct work_struct *work) vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf); wake_up_all(&ctx->msg_queue.core_dec_done); - spin_lock(&dev->msg_queue_core_ctx.ready_lock); - lat_buf->ctx->msg_queue.core_work_cnt--; - - if (lat_buf->ctx->msg_queue.core_work_cnt < - atomic_read(&lat_buf->ctx->msg_queue.core_list_cnt)) { - status = queue_work(lat_buf->ctx->dev->core_workqueue, - &lat_buf->ctx->msg_queue.core_work); - if (status) - lat_buf->ctx->msg_queue.core_work_cnt++; + if (!(ctx->msg_queue.status & CONTEXT_LIST_QUEUED) && + atomic_read(&msg_queue->core_list_cnt)) { + spin_lock(&ctx->dev->msg_queue_core_ctx.ready_lock); + ctx->msg_queue.status |= CONTEXT_LIST_QUEUED; + spin_unlock(&ctx->dev->msg_queue_core_ctx.ready_lock); + queue_work(ctx->dev->core_workqueue, &msg_queue->core_work); } - spin_unlock(&dev->msg_queue_core_ctx.ready_lock); } int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue, @@ -303,13 +298,13 @@ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue, return 0; msg_queue->ctx = ctx; - msg_queue->core_work_cnt = 0; vdec_msg_queue_init_ctx(&msg_queue->lat_ctx, MTK_VDEC_LAT0); INIT_WORK(&msg_queue->core_work, vdec_msg_queue_core_work); atomic_set(&msg_queue->lat_list_cnt, 0); atomic_set(&msg_queue->core_list_cnt, 0); init_waitqueue_head(&msg_queue->core_dec_done); + msg_queue->status = CONTEXT_LIST_EMPTY; msg_queue->wdma_addr.size = vde_msg_queue_get_trans_size(ctx->picinfo.buf_w, diff --git a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h index a5d44bc97c16..8f82d1484772 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h +++ b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h @@ -22,6 +22,18 @@ struct mtk_vcodec_dev; typedef int (*core_decode_cb_t)(struct vdec_lat_buf *lat_buf); /** + * enum core_ctx_status - Context decode status for core hardwre. + * @CONTEXT_LIST_EMPTY: No buffer queued on core hardware(must always be 0) + * @CONTEXT_LIST_QUEUED: Buffer queued to core work list + * @CONTEXT_LIST_DEC_DONE: context decode done + */ +enum core_ctx_status { + CONTEXT_LIST_EMPTY = 0, + CONTEXT_LIST_QUEUED, + CONTEXT_LIST_DEC_DONE, +}; + +/** * struct vdec_msg_queue_ctx - represents a queue for buffers ready to be processed * @ready_to_use: ready used queue used to signalize when get a job queue * @ready_queue: list of ready lat buffer queues @@ -77,7 +89,7 @@ struct vdec_lat_buf { * @lat_list_cnt: used to record each instance lat list count * @core_list_cnt: used to record each instance core list count * @core_dec_done: core work queue decode done event - * @core_work_cnt: the number of core work in work queue + * @status: current context decode status for core hardware */ struct vdec_msg_queue { struct vdec_lat_buf lat_buf[NUM_BUFFER_COUNT]; @@ -93,7 +105,7 @@ struct vdec_msg_queue { atomic_t lat_list_cnt; atomic_t core_list_cnt; wait_queue_head_t core_dec_done; - int core_work_cnt; + int status; }; /** |
