Commit 2e0ef56d authored by Yunfei Dong's avatar Yunfei Dong Committed by Mauro Carvalho Chehab

media: mediatek: vcodec: making sure queue_work successfully

Putting core work to work queue using queue_work maybe fail, call
queue_work again when the count of core work in work queue is less
than core_list_cnt, making sure all the buffer in core list can be
scheduled.

Fixes: 365e4ba0 ("media: mtk-vcodec: Add work queue for core hardware decode")
Signed-off-by: default avatarYunfei Dong <yunfei.dong@mediatek.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent af50b13d
...@@ -71,6 +71,7 @@ static void vdec_msg_queue_dec(struct vdec_msg_queue *msg_queue, int hardware_in ...@@ -71,6 +71,7 @@ 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) int vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *msg_ctx, struct vdec_lat_buf *buf)
{ {
struct list_head *head; struct list_head *head;
int status;
head = vdec_get_buf_list(msg_ctx->hardware_index, buf); head = vdec_get_buf_list(msg_ctx->hardware_index, buf);
if (!head) { if (!head) {
...@@ -83,11 +84,17 @@ int vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *msg_ctx, struct vdec_lat_buf ...@@ -83,11 +84,17 @@ int vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *msg_ctx, struct vdec_lat_buf
msg_ctx->ready_num++; msg_ctx->ready_num++;
vdec_msg_queue_inc(&buf->ctx->msg_queue, msg_ctx->hardware_index); vdec_msg_queue_inc(&buf->ctx->msg_queue, msg_ctx->hardware_index);
if (msg_ctx->hardware_index != MTK_VDEC_CORE) if (msg_ctx->hardware_index != MTK_VDEC_CORE) {
wake_up_all(&msg_ctx->ready_to_use); wake_up_all(&msg_ctx->ready_to_use);
else } else {
queue_work(buf->ctx->dev->core_workqueue, 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); &buf->ctx->msg_queue.core_work);
if (status)
buf->ctx->msg_queue.core_work_cnt++;
}
}
mtk_v4l2_debug(3, "enqueue buf type: %d addr: 0x%p num: %d", mtk_v4l2_debug(3, "enqueue buf type: %d addr: 0x%p num: %d",
msg_ctx->hardware_index, buf, msg_ctx->ready_num); msg_ctx->hardware_index, buf, msg_ctx->ready_num);
...@@ -254,6 +261,7 @@ static void vdec_msg_queue_core_work(struct work_struct *work) ...@@ -254,6 +261,7 @@ static void vdec_msg_queue_core_work(struct work_struct *work)
container_of(msg_queue, struct mtk_vcodec_ctx, msg_queue); container_of(msg_queue, struct mtk_vcodec_ctx, msg_queue);
struct mtk_vcodec_dev *dev = ctx->dev; struct mtk_vcodec_dev *dev = ctx->dev;
struct vdec_lat_buf *lat_buf; struct vdec_lat_buf *lat_buf;
int status;
lat_buf = vdec_msg_queue_dqbuf(&dev->msg_queue_core_ctx); lat_buf = vdec_msg_queue_dqbuf(&dev->msg_queue_core_ctx);
if (!lat_buf) if (!lat_buf)
...@@ -270,11 +278,17 @@ static void vdec_msg_queue_core_work(struct work_struct *work) ...@@ -270,11 +278,17 @@ static void vdec_msg_queue_core_work(struct work_struct *work)
vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf); vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf);
wake_up_all(&ctx->msg_queue.core_dec_done); wake_up_all(&ctx->msg_queue.core_dec_done);
if (atomic_read(&lat_buf->ctx->msg_queue.core_list_cnt)) { spin_lock(&dev->msg_queue_core_ctx.ready_lock);
mtk_v4l2_debug(3, "re-schedule to decode for core: %d", lat_buf->ctx->msg_queue.core_work_cnt--;
dev->msg_queue_core_ctx.ready_num);
queue_work(dev->core_workqueue, &msg_queue->core_work); 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++;
} }
spin_unlock(&dev->msg_queue_core_ctx.ready_lock);
} }
int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue, int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue,
...@@ -289,6 +303,7 @@ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue, ...@@ -289,6 +303,7 @@ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue,
return 0; return 0;
msg_queue->ctx = ctx; msg_queue->ctx = ctx;
msg_queue->core_work_cnt = 0;
vdec_msg_queue_init_ctx(&msg_queue->lat_ctx, MTK_VDEC_LAT0); vdec_msg_queue_init_ctx(&msg_queue->lat_ctx, MTK_VDEC_LAT0);
INIT_WORK(&msg_queue->core_work, vdec_msg_queue_core_work); INIT_WORK(&msg_queue->core_work, vdec_msg_queue_core_work);
......
...@@ -77,6 +77,7 @@ struct vdec_lat_buf { ...@@ -77,6 +77,7 @@ struct vdec_lat_buf {
* @lat_list_cnt: used to record each instance lat list count * @lat_list_cnt: used to record each instance lat list count
* @core_list_cnt: used to record each instance core list count * @core_list_cnt: used to record each instance core list count
* @core_dec_done: core work queue decode done event * @core_dec_done: core work queue decode done event
* @core_work_cnt: the number of core work in work queue
*/ */
struct vdec_msg_queue { struct vdec_msg_queue {
struct vdec_lat_buf lat_buf[NUM_BUFFER_COUNT]; struct vdec_lat_buf lat_buf[NUM_BUFFER_COUNT];
...@@ -92,6 +93,7 @@ struct vdec_msg_queue { ...@@ -92,6 +93,7 @@ struct vdec_msg_queue {
atomic_t lat_list_cnt; atomic_t lat_list_cnt;
atomic_t core_list_cnt; atomic_t core_list_cnt;
wait_queue_head_t core_dec_done; wait_queue_head_t core_dec_done;
int core_work_cnt;
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment