[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <7d446316-efb8-83b9-78c3-149e1378a9f9@quicinc.com>
Date: Fri, 25 Oct 2024 14:51:57 +0530
From: Dikshita Agarwal <quic_dikshita@...cinc.com>
To: Hans Verkuil <hverkuil@...all.nl>,
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>,
<linux-arm-msm@...r.kernel.org>, <linux-media@...r.kernel.org>,
<devicetree@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
Vedang Nagar
<quic_vnagar@...cinc.com>
Subject: Re: [PATCH v4 14/28] media: iris: implement iris v4l2_ctrl_ops
On 10/23/2024 4:32 PM, Hans Verkuil wrote:
> On 14/10/2024 11:07, 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>
>> ---
>> drivers/media/platform/qcom/iris/Makefile | 1 +
>> drivers/media/platform/qcom/iris/iris_core.h | 2 +
>> drivers/media/platform/qcom/iris/iris_ctrls.c | 186 +++++++++++++++++++++
>> 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, 308 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 578166d196f6..70e0dbc7c457 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..4b991145dbad
>> --- /dev/null
>> +++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
>> @@ -0,0 +1,186 @@
>> +// 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_g_volatile_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;
>> +
>> + switch (ctrl->id) {
>> + case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
>> + ctrl->val = inst->buffers[BUF_OUTPUT].min_count;
>> + break;
>> + case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
>> + ctrl->val = inst->buffers[BUF_INPUT].min_count;
>> + break;
>
> This is NOT volatile. It is just a regular read-only control. If the min_count
> changes, then just call v4l2_ctrl_s_ctrl for it in the driver to update the
> value of this control.
>
>> + default:
>> + cap_id = iris_get_cap_id(ctrl->id);
>> + if (iris_valid_cap_id(cap_id))
>> + ctrl->val = inst->fw_caps[cap_id].value;
>
> Looking at this code, this is almost certainly not volatile either.
> I.e. whenever the driver updates inst->fw_caps[cap_id].value, it can
> update this control at the same time.
>
> A volatile control typically reads from the hardware register that is
> automatically modified by the hardware. An example is the gain value if
> the hardware is in autogain mode and changes the gain value autonomously.
>
Sure, will remove iris_vdec_op_g_volatile_ctrl and update the value fro
thesse controls as per your suggestions.
>> + else
>> + return -EINVAL;
>> + }
>> +
>> + 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,
>> + .g_volatile_ctrl = iris_vdec_op_g_volatile_ctrl,
>
> So g_volatile_ctrl isn't needed.
>
Sure.
>> +};
>> +
>> +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;
>> +
>> + ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, num_ctrls);
>> + 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;
>> + }
>> +
>> + ret = inst->ctrl_handler.error;
>> + if (ret)
>> + goto error;
>
> Move this out of the loop, you can check the result at the end.
>
Ok.
>> +
>> + if ((cap[idx].flags & CAP_FLAG_VOLATILE) ||
>> + (ctrl->id == V4L2_CID_MIN_BUFFERS_FOR_CAPTURE ||
>> + ctrl->id == V4L2_CID_MIN_BUFFERS_FOR_OUTPUT))
>> + ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
>> +
>> + ctrl->flags |= V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
>
> Do you really need this? It certainly does not make sense for
> V4L2_CID_MIN_BUFFERS_FOR_CAPTURE/OUTPUT.
>
> If a control needs this, then set it in cap[idx].flags and don't add
> it for all. It is rarely needed.
>
Checked it more, and seems it's not needed if above controls shouldn't be
treated as volatile contrils, so will remove this.
Thanks,
Dikshita
>> + ctrl_idx++;
>> + }
>> +
>> + 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..3e4dd46e7a26
>> --- /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 18cc9365ab75..457ab1887793 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 d28b8fd7ec2f..43ced6ece289 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 54a2d723797b..c45928a6c4fe 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 15463a07ae59..86ef2e5c488e 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)
>> @@ -237,6 +238,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 c4eeba5ed6da..66a54771b9e8 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"
>> @@ -16,8 +17,9 @@
>> #define DEFAULT_CODEC_ALIGNMENT 16
>> #define MAX_EVENTS 30
>>
>> -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);
>> @@ -54,6 +56,11 @@ void iris_vdec_inst_init(struct iris_inst *inst)
>> inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT);
>> inst->buffers[BUF_OUTPUT].actual_count = inst->buffers[BUF_OUTPUT].min_count;
>> 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 707fff34bf4d..d7b8a0ad6fa8 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 8068c06c1f11..93d2be118a81 100644
>> --- a/drivers/media/platform/qcom/iris/iris_vidc.c
>> +++ b/drivers/media/platform/qcom/iris/iris_vidc.c
>> @@ -22,12 +22,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);
>> }
>>
>> @@ -159,7 +161,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);
>>
>> @@ -168,6 +172,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:
>> @@ -199,6 +205,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