[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <cc3a85a3-2105-40c6-9761-a3d5bb843d69@xs4all.nl>
Date: Fri, 29 Nov 2024 10:03:03 +0100
From: Hans Verkuil <hverkuil@...all.nl>
To: Dikshita Agarwal <quic_dikshita@...cinc.com>,
Vikash Garodia <quic_vgarodia@...cinc.com>,
Abhinav Kumar <quic_abhinavk@...cinc.com>,
Mauro Carvalho Chehab <mchehab@...nel.org>, Rob Herring <robh@...nel.org>,
Krzysztof Kozlowski <krzk+dt@...nel.org>, Conor Dooley
<conor+dt@...nel.org>, Philipp Zabel <p.zabel@...gutronix.de>
Cc: Sebastian Fricke <sebastian.fricke@...labora.com>,
Bryan O'Donoghue <bryan.odonoghue@...aro.org>,
Dmitry Baryshkov <dmitry.baryshkov@...aro.org>,
Neil Armstrong <neil.armstrong@...aro.org>,
Nicolas Dufresne <nicolas@...fresne.ca>,
Uwe Kleine-König <u.kleine-koenig@...libre.com>,
Jianhua Lu <lujianhua000@...il.com>, linux-media@...r.kernel.org,
linux-arm-msm@...r.kernel.org, devicetree@...r.kernel.org,
linux-kernel@...r.kernel.org, Vedang Nagar <quic_vnagar@...cinc.com>
Subject: Re: [PATCH v6 14/28] media: iris: implement iris v4l2_ctrl_ops
On 20/11/2024 15:46, Dikshita Agarwal wrote:
> Initialize ctrl handler by reading platform specific firmware
> capabilities. Capabilities are features supported by a specific platform
> (SOC). Each capability is defined with min, max, range, default value
> and corresponding HFI. Implement s_ctrl and g_volatile_ctrl ctrl ops.
>
> Co-developed-by: Vedang Nagar <quic_vnagar@...cinc.com>
> Signed-off-by: Vedang Nagar <quic_vnagar@...cinc.com>
> Signed-off-by: Dikshita Agarwal <quic_dikshita@...cinc.com>
Reviewed-by: Hans Verkuil <hverkuil@...all.nl>
Regards,
Hans
> ---
> drivers/media/platform/qcom/iris/Makefile | 1 +
> drivers/media/platform/qcom/iris/iris_core.h | 2 +
> drivers/media/platform/qcom/iris/iris_ctrls.c | 161 +++++++++++++++++++++
> drivers/media/platform/qcom/iris/iris_ctrls.h | 17 +++
> .../platform/qcom/iris/iris_hfi_gen2_defines.h | 2 +
> drivers/media/platform/qcom/iris/iris_instance.h | 4 +
> .../platform/qcom/iris/iris_platform_common.h | 29 ++++
> .../platform/qcom/iris/iris_platform_sm8550.c | 47 ++++++
> drivers/media/platform/qcom/iris/iris_probe.c | 3 +
> drivers/media/platform/qcom/iris/iris_vdec.c | 9 +-
> drivers/media/platform/qcom/iris/iris_vdec.h | 2 +-
> drivers/media/platform/qcom/iris/iris_vidc.c | 9 +-
> 12 files changed, 283 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile
> index 48ab264b7906..f685d76c2f79 100644
> --- a/drivers/media/platform/qcom/iris/Makefile
> +++ b/drivers/media/platform/qcom/iris/Makefile
> @@ -1,5 +1,6 @@
> iris-objs += iris_buffer.o \
> iris_core.o \
> + iris_ctrls.o \
> iris_firmware.o \
> iris_hfi_common.o \
> iris_hfi_gen1_command.o \
> diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h
> index 1ddcb8793172..37fb4919fecc 100644
> --- a/drivers/media/platform/qcom/iris/iris_core.h
> +++ b/drivers/media/platform/qcom/iris/iris_core.h
> @@ -63,6 +63,7 @@ struct icc_info {
> * @intr_status: interrupt status
> * @sys_error_handler: a delayed work for handling system fatal error
> * @instances: a list_head of all instances
> + * @inst_fw_caps: an array of supported instance capabilities
> */
>
> struct iris_core {
> @@ -101,6 +102,7 @@ struct iris_core {
> u32 intr_status;
> struct delayed_work sys_error_handler;
> struct list_head instances;
> + struct platform_inst_fw_cap inst_fw_caps[INST_FW_CAP_MAX];
> };
>
> int iris_core_init(struct iris_core *core);
> diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c
> new file mode 100644
> index 000000000000..a204e2e1edf7
> --- /dev/null
> +++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
> @@ -0,0 +1,161 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +#include <media/v4l2-mem2mem.h>
> +#include "iris_ctrls.h"
> +#include "iris_instance.h"
> +
> +static inline bool iris_valid_cap_id(enum platform_inst_fw_cap_type cap_id)
> +{
> + return cap_id >= 1 && cap_id < INST_FW_CAP_MAX;
> +}
> +
> +static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
> +{
> + switch (id) {
> + case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
> + return PROFILE;
> + case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
> + return LEVEL;
> + default:
> + return INST_FW_CAP_MAX;
> + }
> +}
> +
> +static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
> +{
> + if (!iris_valid_cap_id(cap_id))
> + return 0;
> +
> + switch (cap_id) {
> + case PROFILE:
> + return V4L2_CID_MPEG_VIDEO_H264_PROFILE;
> + case LEVEL:
> + return V4L2_CID_MPEG_VIDEO_H264_LEVEL;
> + default:
> + return 0;
> + }
> +}
> +
> +static int iris_vdec_op_s_ctrl(struct v4l2_ctrl *ctrl)
> +{
> + struct iris_inst *inst = container_of(ctrl->handler, struct iris_inst, ctrl_handler);
> + enum platform_inst_fw_cap_type cap_id;
> + struct platform_inst_fw_cap *cap;
> + struct vb2_queue *q;
> +
> + cap = &inst->fw_caps[0];
> + cap_id = iris_get_cap_id(ctrl->id);
> + if (!iris_valid_cap_id(cap_id))
> + return -EINVAL;
> +
> + q = v4l2_m2m_get_src_vq(inst->m2m_ctx);
> + if (vb2_is_streaming(q) &&
> + (!(inst->fw_caps[cap_id].flags & CAP_FLAG_DYNAMIC_ALLOWED)))
> + return -EINVAL;
> +
> + cap[cap_id].flags |= CAP_FLAG_CLIENT_SET;
> +
> + inst->fw_caps[cap_id].value = ctrl->val;
> +
> + return 0;
> +}
> +
> +static const struct v4l2_ctrl_ops iris_ctrl_ops = {
> + .s_ctrl = iris_vdec_op_s_ctrl,
> +};
> +
> +int iris_ctrls_init(struct iris_inst *inst)
> +{
> + struct platform_inst_fw_cap *cap = &inst->fw_caps[0];
> + u32 num_ctrls = 0, ctrl_idx = 0, idx = 0;
> + u32 v4l2_id;
> + int ret;
> +
> + for (idx = 1; idx < INST_FW_CAP_MAX; idx++) {
> + if (iris_get_v4l2_id(cap[idx].cap_id))
> + num_ctrls++;
> + }
> + if (!num_ctrls)
> + return -EINVAL;
> +
> + /* Adding 1 to num_ctrls to include V4L2_CID_MIN_BUFFERS_FOR_CAPTURE */
> +
> + ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, num_ctrls + 1);
> + if (ret)
> + return ret;
> +
> + for (idx = 1; idx < INST_FW_CAP_MAX; idx++) {
> + struct v4l2_ctrl *ctrl;
> +
> + v4l2_id = iris_get_v4l2_id(cap[idx].cap_id);
> + if (!v4l2_id)
> + continue;
> +
> + if (ctrl_idx >= num_ctrls) {
> + ret = -EINVAL;
> + goto error;
> + }
> +
> + if (cap[idx].flags & CAP_FLAG_MENU) {
> + ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler,
> + &iris_ctrl_ops,
> + v4l2_id,
> + cap[idx].max,
> + ~(cap[idx].step_or_mask),
> + cap[idx].value);
> + } else {
> + ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler,
> + &iris_ctrl_ops,
> + v4l2_id,
> + cap[idx].min,
> + cap[idx].max,
> + cap[idx].step_or_mask,
> + cap[idx].value);
> + }
> + if (!ctrl) {
> + ret = -EINVAL;
> + goto error;
> + }
> +
> + ctrl_idx++;
> + }
> +
> + v4l2_ctrl_new_std(&inst->ctrl_handler, NULL,
> + V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 4);
> +
> + ret = inst->ctrl_handler.error;
> + if (ret)
> + goto error;
> +
> + return 0;
> +error:
> + v4l2_ctrl_handler_free(&inst->ctrl_handler);
> +
> + return ret;
> +}
> +
> +void iris_session_init_caps(struct iris_core *core)
> +{
> + struct platform_inst_fw_cap *caps;
> + u32 i, num_cap, cap_id;
> +
> + caps = core->iris_platform_data->inst_fw_caps;
> + num_cap = core->iris_platform_data->inst_fw_caps_size;
> +
> + for (i = 0; i < num_cap; i++) {
> + cap_id = caps[i].cap_id;
> + if (!iris_valid_cap_id(cap_id))
> + continue;
> +
> + core->inst_fw_caps[cap_id].cap_id = caps[i].cap_id;
> + core->inst_fw_caps[cap_id].min = caps[i].min;
> + core->inst_fw_caps[cap_id].max = caps[i].max;
> + core->inst_fw_caps[cap_id].step_or_mask = caps[i].step_or_mask;
> + core->inst_fw_caps[cap_id].value = caps[i].value;
> + core->inst_fw_caps[cap_id].flags = caps[i].flags;
> + core->inst_fw_caps[cap_id].hfi_id = caps[i].hfi_id;
> + }
> +}
> diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.h b/drivers/media/platform/qcom/iris/iris_ctrls.h
> new file mode 100644
> index 000000000000..fe65a772e6dd
> --- /dev/null
> +++ b/drivers/media/platform/qcom/iris/iris_ctrls.h
> @@ -0,0 +1,17 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +#ifndef __IRIS_CTRLS_H__
> +#define __IRIS_CTRLS_H__
> +
> +#include "iris_platform_common.h"
> +
> +struct iris_core;
> +struct iris_inst;
> +
> +int iris_ctrls_init(struct iris_inst *inst);
> +void iris_session_init_caps(struct iris_core *core);
> +
> +#endif
> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
> index b95a34379ea1..6be8a6ff7924 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
> @@ -28,6 +28,8 @@
> #define HFI_PROP_UBWC_BANK_SWZL_LEVEL3 0x03000008
> #define HFI_PROP_UBWC_BANK_SPREADING 0x03000009
> #define HFI_PROP_CODEC 0x03000100
> +#define HFI_PROP_PROFILE 0x03000107
> +#define HFI_PROP_LEVEL 0x03000108
> #define HFI_PROP_DEC_DEFAULT_HEADER 0x03000168
> #define HFI_PROP_END 0x03FFFFFF
>
> diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/media/platform/qcom/iris/iris_instance.h
> index ef4515d2086c..16b463cec4f4 100644
> --- a/drivers/media/platform/qcom/iris/iris_instance.h
> +++ b/drivers/media/platform/qcom/iris/iris_instance.h
> @@ -23,8 +23,10 @@
> * @fh: reference of v4l2 file handler
> * @fmt_src: structure of v4l2_format for source
> * @fmt_dst: structure of v4l2_format for destination
> + * @ctrl_handler: reference of v4l2 ctrl handler
> * @crop: structure of crop info
> * @completions: structure of signal completions
> + * @fw_caps: array of supported instance firmware capabilities
> * @buffers: array of different iris buffers
> * @fw_min_count: minimnum count of buffers needed by fw
> * @once_per_session_set: boolean to set once per session property
> @@ -42,8 +44,10 @@ struct iris_inst {
> struct v4l2_fh fh;
> struct v4l2_format *fmt_src;
> struct v4l2_format *fmt_dst;
> + struct v4l2_ctrl_handler ctrl_handler;
> struct iris_hfi_rect_desc crop;
> struct completion completion;
> + struct platform_inst_fw_cap fw_caps[INST_FW_CAP_MAX];
> struct iris_buffers buffers[BUF_TYPE_MAX];
> u32 fw_min_count;
> bool once_per_session_set;
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
> index 75d4932df910..a96475535aeb 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_common.h
> +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
> @@ -49,6 +49,33 @@ struct platform_inst_caps {
> u32 max_frame_height;
> u32 max_mbpf;
> };
> +
> +enum platform_inst_fw_cap_type {
> + PROFILE = 1,
> + LEVEL,
> + INST_FW_CAP_MAX,
> +};
> +
> +enum platform_inst_fw_cap_flags {
> + CAP_FLAG_DYNAMIC_ALLOWED = BIT(0),
> + CAP_FLAG_MENU = BIT(1),
> + CAP_FLAG_INPUT_PORT = BIT(2),
> + CAP_FLAG_OUTPUT_PORT = BIT(3),
> + CAP_FLAG_CLIENT_SET = BIT(4),
> + CAP_FLAG_BITMASK = BIT(5),
> + CAP_FLAG_VOLATILE = BIT(6),
> +};
> +
> +struct platform_inst_fw_cap {
> + enum platform_inst_fw_cap_type cap_id;
> + s64 min;
> + s64 max;
> + s64 step_or_mask;
> + s64 value;
> + u32 hfi_id;
> + enum platform_inst_fw_cap_flags flags;
> +};
> +
> struct iris_core_power {
> u64 clk_freq;
> u64 icc_bw;
> @@ -79,6 +106,8 @@ struct iris_platform_data {
> const char *fwname;
> u32 pas_id;
> struct platform_inst_caps *inst_caps;
> + struct platform_inst_fw_cap *inst_fw_caps;
> + u32 inst_fw_caps_size;
> struct tz_cp_config *tz_cp_config_data;
> u32 core_arch;
> u32 hw_response_timeout;
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
> index 37c0130d7059..7e3703adb5b3 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
> +++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
> @@ -5,11 +5,56 @@
>
> #include "iris_core.h"
> #include "iris_hfi_gen2.h"
> +#include "iris_hfi_gen2_defines.h"
> #include "iris_platform_common.h"
> #include "iris_vpu_common.h"
>
> #define VIDEO_ARCH_LX 1
>
> +static struct platform_inst_fw_cap inst_fw_cap_sm8550[] = {
> + {
> + .cap_id = PROFILE,
> + .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
> + .max = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,
> + .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH) |
> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH),
> + .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
> + .hfi_id = HFI_PROP_PROFILE,
> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> + },
> + {
> + .cap_id = LEVEL,
> + .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
> + .max = V4L2_MPEG_VIDEO_H264_LEVEL_6_2,
> + .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_0) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_1) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_2),
> + .value = V4L2_MPEG_VIDEO_H264_LEVEL_6_1,
> + .hfi_id = HFI_PROP_LEVEL,
> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> + },
> +};
> +
> static struct platform_inst_caps platform_inst_cap_sm8550 = {
> .min_frame_width = 96,
> .max_frame_width = 8192,
> @@ -77,6 +122,8 @@ struct iris_platform_data sm8550_data = {
> .fwname = "qcom/vpu/vpu30_p4.mbn",
> .pas_id = IRIS_PAS_ID,
> .inst_caps = &platform_inst_cap_sm8550,
> + .inst_fw_caps = inst_fw_cap_sm8550,
> + .inst_fw_caps_size = ARRAY_SIZE(inst_fw_cap_sm8550),
> .tz_cp_config_data = &tz_cp_config_sm8550,
> .core_arch = VIDEO_ARCH_LX,
> .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE,
> diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c
> index a9162be5f9f6..954cc7c0cc97 100644
> --- a/drivers/media/platform/qcom/iris/iris_probe.c
> +++ b/drivers/media/platform/qcom/iris/iris_probe.c
> @@ -12,6 +12,7 @@
> #include <linux/reset.h>
>
> #include "iris_core.h"
> +#include "iris_ctrls.h"
> #include "iris_vidc.h"
>
> static int iris_init_icc(struct iris_core *core)
> @@ -236,6 +237,8 @@ static int iris_probe(struct platform_device *pdev)
> if (ret)
> return ret;
>
> + iris_session_init_caps(core);
> +
> ret = v4l2_device_register(dev, &core->v4l2_dev);
> if (ret)
> return ret;
> diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c
> index 9afeb681b7a7..5571c24a7417 100644
> --- a/drivers/media/platform/qcom/iris/iris_vdec.c
> +++ b/drivers/media/platform/qcom/iris/iris_vdec.c
> @@ -7,6 +7,7 @@
> #include <media/v4l2-mem2mem.h>
>
> #include "iris_buffer.h"
> +#include "iris_ctrls.h"
> #include "iris_instance.h"
> #include "iris_vdec.h"
> #include "iris_vpu_buffer.h"
> @@ -15,8 +16,9 @@
> #define DEFAULT_HEIGHT 240
> #define DEFAULT_CODEC_ALIGNMENT 16
>
> -void iris_vdec_inst_init(struct iris_inst *inst)
> +int iris_vdec_inst_init(struct iris_inst *inst)
> {
> + struct iris_core *core = inst->core;
> struct v4l2_format *f;
>
> inst->fmt_src = kzalloc(sizeof(*inst->fmt_src), GFP_KERNEL);
> @@ -51,6 +53,11 @@ void iris_vdec_inst_init(struct iris_inst *inst)
> f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
> inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT);
> inst->buffers[BUF_OUTPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
> +
> + memcpy(&inst->fw_caps[0], &core->inst_fw_caps[0],
> + INST_FW_CAP_MAX * sizeof(struct platform_inst_fw_cap));
> +
> + return iris_ctrls_init(inst);
> }
>
> void iris_vdec_inst_deinit(struct iris_inst *inst)
> diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/platform/qcom/iris/iris_vdec.h
> index f64ce3234e6a..9f08a13cb6bb 100644
> --- a/drivers/media/platform/qcom/iris/iris_vdec.h
> +++ b/drivers/media/platform/qcom/iris/iris_vdec.h
> @@ -8,7 +8,7 @@
>
> struct iris_inst;
>
> -void iris_vdec_inst_init(struct iris_inst *inst);
> +int iris_vdec_inst_init(struct iris_inst *inst);
> void iris_vdec_inst_deinit(struct iris_inst *inst);
> int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f);
> int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f);
> diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c
> index 3a138172e674..820d98da3190 100644
> --- a/drivers/media/platform/qcom/iris/iris_vidc.c
> +++ b/drivers/media/platform/qcom/iris/iris_vidc.c
> @@ -23,12 +23,14 @@
> static void iris_v4l2_fh_init(struct iris_inst *inst)
> {
> v4l2_fh_init(&inst->fh, inst->core->vdev_dec);
> + inst->fh.ctrl_handler = &inst->ctrl_handler;
> v4l2_fh_add(&inst->fh);
> }
>
> static void iris_v4l2_fh_deinit(struct iris_inst *inst)
> {
> v4l2_fh_del(&inst->fh);
> + inst->fh.ctrl_handler = NULL;
> v4l2_fh_exit(&inst->fh);
> }
>
> @@ -162,7 +164,9 @@ int iris_open(struct file *filp)
> goto fail_m2m_release;
> }
>
> - iris_vdec_inst_init(inst);
> + ret = iris_vdec_inst_init(inst);
> + if (ret)
> + goto fail_m2m_ctx_release;
>
> iris_add_session(inst);
>
> @@ -171,6 +175,8 @@ int iris_open(struct file *filp)
>
> return 0;
>
> +fail_m2m_ctx_release:
> + v4l2_m2m_ctx_release(inst->m2m_ctx);
> fail_m2m_release:
> v4l2_m2m_release(inst->m2m_dev);
> fail_v4l2_fh_deinit:
> @@ -202,6 +208,7 @@ int iris_close(struct file *filp)
> {
> struct iris_inst *inst = iris_get_inst(filp, NULL);
>
> + v4l2_ctrl_handler_free(&inst->ctrl_handler);
> v4l2_m2m_ctx_release(inst->m2m_ctx);
> v4l2_m2m_release(inst->m2m_dev);
> mutex_lock(&inst->lock);
>
Powered by blists - more mailing lists