video_device and vb2_queue locks are now both
mandatory. Add them, remove driver ad-hoc locking,
and implement wait_{prepare, finish}.

To stay on the safe side, this commit uses a single mutex
for both locks. Better latency can be obtained by separating
these if needed.

Signed-off-by: Ezequiel Garcia <ezequ...@collabora.com>
---
 drivers/media/platform/qcom/venus/core.h    |  4 +++-
 drivers/media/platform/qcom/venus/helpers.c | 16 ++++++++--------
 drivers/media/platform/qcom/venus/vdec.c    | 25 ++++++++++---------------
 drivers/media/platform/qcom/venus/venc.c    | 19 +++++++++----------
 4 files changed, 30 insertions(+), 34 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/core.h 
b/drivers/media/platform/qcom/venus/core.h
index 0360d295f4c8..5617d0af990f 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -102,6 +102,8 @@ struct venus_core {
        struct device *dev_dec;
        struct device *dev_enc;
        struct mutex lock;
+       struct mutex dec_lock;
+       struct mutex enc_lock;
        struct list_head instances;
        atomic_t insts_count;
        unsigned int state;
@@ -243,7 +245,7 @@ struct venus_buffer {
  */
 struct venus_inst {
        struct list_head list;
-       struct mutex lock;
+       struct mutex *lock;
        struct venus_core *core;
        struct list_head internalbufs;
        struct list_head registeredbufs;
diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 0ce9559a2924..5a2dda6fb984 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -512,7 +512,7 @@ static void delayed_process_buf_func(struct work_struct 
*work)
 
        inst = container_of(work, struct venus_inst, delayed_process_work);
 
-       mutex_lock(&inst->lock);
+       mutex_lock(inst->lock);
 
        if (!(inst->streamon_out & inst->streamon_cap))
                goto unlock;
@@ -528,7 +528,7 @@ static void delayed_process_buf_func(struct work_struct 
*work)
                list_del_init(&buf->ref_list);
        }
 unlock:
-       mutex_unlock(&inst->lock);
+       mutex_unlock(inst->lock);
 }
 
 void venus_helper_release_buf_ref(struct venus_inst *inst, unsigned int idx)
@@ -621,7 +621,7 @@ void venus_helper_vb2_buf_queue(struct vb2_buffer *vb)
        struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
        int ret;
 
-       mutex_lock(&inst->lock);
+       mutex_lock(inst->lock);
 
        v4l2_m2m_buf_queue(m2m_ctx, vbuf);
 
@@ -637,7 +637,7 @@ void venus_helper_vb2_buf_queue(struct vb2_buffer *vb)
                return_buf_error(inst, vbuf);
 
 unlock:
-       mutex_unlock(&inst->lock);
+       mutex_unlock(inst->lock);
 }
 EXPORT_SYMBOL_GPL(venus_helper_vb2_buf_queue);
 
@@ -659,7 +659,7 @@ void venus_helper_vb2_stop_streaming(struct vb2_queue *q)
        struct venus_core *core = inst->core;
        int ret;
 
-       mutex_lock(&inst->lock);
+       mutex_lock(inst->lock);
 
        if (inst->streamon_out & inst->streamon_cap) {
                ret = hfi_session_stop(inst);
@@ -685,7 +685,7 @@ void venus_helper_vb2_stop_streaming(struct vb2_queue *q)
        else
                inst->streamon_cap = 0;
 
-       mutex_unlock(&inst->lock);
+       mutex_unlock(inst->lock);
 }
 EXPORT_SYMBOL_GPL(venus_helper_vb2_stop_streaming);
 
@@ -731,7 +731,7 @@ void venus_helper_m2m_device_run(void *priv)
        struct v4l2_m2m_buffer *buf, *n;
        int ret;
 
-       mutex_lock(&inst->lock);
+       mutex_lock(inst->lock);
 
        v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buf, n) {
                ret = session_process_buf(inst, &buf->vb);
@@ -745,7 +745,7 @@ void venus_helper_m2m_device_run(void *priv)
                        return_buf_error(inst, &buf->vb);
        }
 
-       mutex_unlock(&inst->lock);
+       mutex_unlock(inst->lock);
 }
 EXPORT_SYMBOL_GPL(venus_helper_m2m_device_run);
 
diff --git a/drivers/media/platform/qcom/venus/vdec.c 
b/drivers/media/platform/qcom/venus/vdec.c
index 49bbd1861d3a..41d14df46f5d 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -493,14 +493,12 @@ vdec_decoder_cmd(struct file *file, void *fh, struct 
v4l2_decoder_cmd *cmd)
        if (ret)
                return ret;
 
-       mutex_lock(&inst->lock);
-
        /*
         * Implement V4L2_DEC_CMD_STOP by enqueue an empty buffer on decoder
         * input to signal EOS.
         */
        if (!(inst->streamon_out & inst->streamon_cap))
-               goto unlock;
+               return 0;
 
        fdata.buffer_type = HFI_BUFFER_INPUT;
        fdata.flags |= HFI_BUFFERFLAG_EOS;
@@ -508,8 +506,6 @@ vdec_decoder_cmd(struct file *file, void *fh, struct 
v4l2_decoder_cmd *cmd)
 
        ret = hfi_session_process_buf(inst, &fdata);
 
-unlock:
-       mutex_unlock(&inst->lock);
        return ret;
 }
 
@@ -720,17 +716,13 @@ static int vdec_start_streaming(struct vb2_queue *q, 
unsigned int count)
        u32 ptype;
        int ret;
 
-       mutex_lock(&inst->lock);
-
        if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
                inst->streamon_out = 1;
        else
                inst->streamon_cap = 1;
 
-       if (!(inst->streamon_out & inst->streamon_cap)) {
-               mutex_unlock(&inst->lock);
+       if (!(inst->streamon_out & inst->streamon_cap))
                return 0;
-       }
 
        venus_helper_init_instance(inst);
 
@@ -771,8 +763,6 @@ static int vdec_start_streaming(struct vb2_queue *q, 
unsigned int count)
        if (ret)
                goto deinit_sess;
 
-       mutex_unlock(&inst->lock);
-
        return 0;
 
 deinit_sess:
@@ -783,7 +773,6 @@ static int vdec_start_streaming(struct vb2_queue *q, 
unsigned int count)
                inst->streamon_out = 0;
        else
                inst->streamon_cap = 0;
-       mutex_unlock(&inst->lock);
        return ret;
 }
 
@@ -794,6 +783,8 @@ static const struct vb2_ops vdec_vb2_ops = {
        .start_streaming = vdec_start_streaming,
        .stop_streaming = venus_helper_vb2_stop_streaming,
        .buf_queue = venus_helper_vb2_buf_queue,
+       .wait_prepare = vb2_ops_wait_prepare,
+       .wait_finish = vb2_ops_wait_finish,
 };
 
 static void vdec_buf_done(struct venus_inst *inst, unsigned int buf_type,
@@ -940,6 +931,7 @@ static int m2m_queue_init(void *priv, struct vb2_queue 
*src_vq,
        src_vq->allow_zero_bytesused = 1;
        src_vq->min_buffers_needed = 1;
        src_vq->dev = inst->core->dev;
+       src_vq->lock = &inst->core->dec_lock;
        ret = vb2_queue_init(src_vq);
        if (ret)
                return ret;
@@ -954,6 +946,7 @@ static int m2m_queue_init(void *priv, struct vb2_queue 
*src_vq,
        dst_vq->allow_zero_bytesused = 1;
        dst_vq->min_buffers_needed = 1;
        dst_vq->dev = inst->core->dev;
+       dst_vq->lock = &inst->core->dec_lock;
        ret = vb2_queue_init(dst_vq);
        if (ret) {
                vb2_queue_release(src_vq);
@@ -976,9 +969,9 @@ static int vdec_open(struct file *file)
        INIT_LIST_HEAD(&inst->registeredbufs);
        INIT_LIST_HEAD(&inst->internalbufs);
        INIT_LIST_HEAD(&inst->list);
-       mutex_init(&inst->lock);
 
        inst->core = core;
+       inst->lock = &core->dec_lock;
        inst->session_type = VIDC_SESSION_TYPE_DEC;
        inst->num_output_bufs = 1;
 
@@ -1044,7 +1037,6 @@ static int vdec_close(struct file *file)
        v4l2_m2m_release(inst->m2m_dev);
        vdec_ctrl_deinit(inst);
        hfi_session_destroy(inst);
-       mutex_destroy(&inst->lock);
        v4l2_fh_del(&inst->fh);
        v4l2_fh_exit(&inst->fh);
 
@@ -1092,12 +1084,14 @@ static int vdec_probe(struct platform_device *pdev)
        if (!vdev)
                return -ENOMEM;
 
+       mutex_init(&core->dec_lock);
        strlcpy(vdev->name, "qcom-venus-decoder", sizeof(vdev->name));
        vdev->release = video_device_release;
        vdev->fops = &vdec_fops;
        vdev->ioctl_ops = &vdec_ioctl_ops;
        vdev->vfl_dir = VFL_DIR_M2M;
        vdev->v4l2_dev = &core->v4l2_dev;
+       vdev->lock = &core->dec_lock;
        vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
 
        ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
@@ -1123,6 +1117,7 @@ static int vdec_remove(struct platform_device *pdev)
 
        video_unregister_device(core->vdev_dec);
        pm_runtime_disable(core->dev_dec);
+       mutex_destroy(&core->dec_lock);
 
        return 0;
 }
diff --git a/drivers/media/platform/qcom/venus/venc.c 
b/drivers/media/platform/qcom/venus/venc.c
index 6b2ce479584e..016af21abf5d 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -922,17 +922,13 @@ static int venc_start_streaming(struct vb2_queue *q, 
unsigned int count)
        struct venus_inst *inst = vb2_get_drv_priv(q);
        int ret;
 
-       mutex_lock(&inst->lock);
-
        if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
                inst->streamon_out = 1;
        else
                inst->streamon_cap = 1;
 
-       if (!(inst->streamon_out & inst->streamon_cap)) {
-               mutex_unlock(&inst->lock);
+       if (!(inst->streamon_out & inst->streamon_cap))
                return 0;
-       }
 
        venus_helper_init_instance(inst);
 
@@ -960,8 +956,6 @@ static int venc_start_streaming(struct vb2_queue *q, 
unsigned int count)
        if (ret)
                goto deinit_sess;
 
-       mutex_unlock(&inst->lock);
-
        return 0;
 
 deinit_sess:
@@ -972,7 +966,6 @@ static int venc_start_streaming(struct vb2_queue *q, 
unsigned int count)
                inst->streamon_out = 0;
        else
                inst->streamon_cap = 0;
-       mutex_unlock(&inst->lock);
        return ret;
 }
 
@@ -983,6 +976,8 @@ static const struct vb2_ops venc_vb2_ops = {
        .start_streaming = venc_start_streaming,
        .stop_streaming = venus_helper_vb2_stop_streaming,
        .buf_queue = venus_helper_vb2_buf_queue,
+       .wait_prepare = vb2_ops_wait_prepare,
+       .wait_finish = vb2_ops_wait_finish,
 };
 
 static void venc_buf_done(struct venus_inst *inst, unsigned int buf_type,
@@ -1054,6 +1049,7 @@ static int m2m_queue_init(void *priv, struct vb2_queue 
*src_vq,
        src_vq->allow_zero_bytesused = 1;
        src_vq->min_buffers_needed = 1;
        src_vq->dev = inst->core->dev;
+       src_vq->lock = &inst->core->enc_lock;
        if (inst->core->res->hfi_version == HFI_VERSION_1XX)
                src_vq->bidirectional = 1;
        ret = vb2_queue_init(src_vq);
@@ -1070,6 +1066,7 @@ static int m2m_queue_init(void *priv, struct vb2_queue 
*src_vq,
        dst_vq->allow_zero_bytesused = 1;
        dst_vq->min_buffers_needed = 1;
        dst_vq->dev = inst->core->dev;
+       dst_vq->lock = &inst->core->enc_lock;
        ret = vb2_queue_init(dst_vq);
        if (ret) {
                vb2_queue_release(src_vq);
@@ -1121,9 +1118,9 @@ static int venc_open(struct file *file)
        INIT_LIST_HEAD(&inst->registeredbufs);
        INIT_LIST_HEAD(&inst->internalbufs);
        INIT_LIST_HEAD(&inst->list);
-       mutex_init(&inst->lock);
 
        inst->core = core;
+       inst->lock = &core->enc_lock;
        inst->session_type = VIDC_SESSION_TYPE_ENC;
 
        venus_helper_init_instance(inst);
@@ -1188,7 +1185,6 @@ static int venc_close(struct file *file)
        v4l2_m2m_release(inst->m2m_dev);
        venc_ctrl_deinit(inst);
        hfi_session_destroy(inst);
-       mutex_destroy(&inst->lock);
        v4l2_fh_del(&inst->fh);
        v4l2_fh_exit(&inst->fh);
 
@@ -1237,11 +1233,13 @@ static int venc_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        strlcpy(vdev->name, "qcom-venus-encoder", sizeof(vdev->name));
+       mutex_init(&core->enc_lock);
        vdev->release = video_device_release;
        vdev->fops = &venc_fops;
        vdev->ioctl_ops = &venc_ioctl_ops;
        vdev->vfl_dir = VFL_DIR_M2M;
        vdev->v4l2_dev = &core->v4l2_dev;
+       vdev->lock = &core->enc_lock;
        vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
 
        ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
@@ -1267,6 +1265,7 @@ static int venc_remove(struct platform_device *pdev)
 
        video_unregister_device(core->vdev_enc);
        pm_runtime_disable(core->dev_enc);
+       mutex_destroy(&core->enc_lock);
 
        return 0;
 }
-- 
2.16.3

Reply via email to