Merge tag 'LA.UM.9.15.r1-07500-KAMORTA.QSSI13.0' of https://git.codelinaro.org/clo/la/platform/vendor/opensource/camera-kernel into android13-4.19-kona

"LA.UM.9.15.r1-07500-KAMORTA.QSSI13.0"

* tag 'LA.UM.9.15.r1-07500-KAMORTA.QSSI13.0' of https://git.codelinaro.org/clo/la/platform/vendor/opensource/camera-kernel:
  msm: camera: mem_mgr: release buffers after usage
  msm: camera: sensor: Add changes to prevent unmap buffers
  msm: camera: mem_mgr: Add refcount to track in use buffers
  msm: camera: core: validation of session/device/link handle

Change-Id: I67d08de0f2d7d3855c5d0cebccb5a8c0a05e49ec
This commit is contained in:
Michael Bestas
2023-08-25 12:05:33 +03:00
32 changed files with 562 additions and 159 deletions

View File

@@ -860,6 +860,7 @@ static int cam_hw_cdm_arb_submit_bl(struct cam_hw_info *cdm_hw,
"CDM hw bl write failed tag=%d", "CDM hw bl write failed tag=%d",
core->bl_fifo[fifo_idx].bl_tag - core->bl_fifo[fifo_idx].bl_tag -
1); 1);
cam_mem_put_cpu_buf(cdm_cmd->cmd[i].bl_addr.mem_handle);
list_del_init(&node->entry); list_del_init(&node->entry);
kfree(node); kfree(node);
return -EIO; return -EIO;
@@ -871,11 +872,12 @@ static int cam_hw_cdm_arb_submit_bl(struct cam_hw_info *cdm_hw,
"CDM hw commit failed tag=%d", "CDM hw commit failed tag=%d",
core->bl_fifo[fifo_idx].bl_tag - core->bl_fifo[fifo_idx].bl_tag -
1); 1);
cam_mem_put_cpu_buf(cdm_cmd->cmd[i].bl_addr.mem_handle);
list_del_init(&node->entry); list_del_init(&node->entry);
kfree(node); kfree(node);
return -EIO; return -EIO;
} }
cam_mem_put_cpu_buf(cdm_cmd->cmd[i].bl_addr.mem_handle);
return 0; return 0;
} }

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/delay.h> #include <linux/delay.h>
@@ -120,7 +121,7 @@ int cam_virtual_cdm_submit_bl(struct cam_hw_info *cdm_hw,
cdm_cmd->cmd[i].len) { cdm_cmd->cmd[i].len) {
CAM_ERR(CAM_CDM, "Not enough buffer"); CAM_ERR(CAM_CDM, "Not enough buffer");
rc = -EINVAL; rc = -EINVAL;
break; goto end;
} }
CAM_DBG(CAM_CDM, CAM_DBG(CAM_CDM,
"hdl=%x vaddr=%pK offset=%d cmdlen=%d:%zu", "hdl=%x vaddr=%pK offset=%d cmdlen=%d:%zu",
@@ -138,7 +139,7 @@ int cam_virtual_cdm_submit_bl(struct cam_hw_info *cdm_hw,
"write failed for cnt=%d:%d len %u", "write failed for cnt=%d:%d len %u",
i, req->data->cmd_arrary_count, i, req->data->cmd_arrary_count,
cdm_cmd->cmd[i].len); cdm_cmd->cmd[i].len);
break; goto end;
} }
} else { } else {
CAM_ERR(CAM_CDM, CAM_ERR(CAM_CDM,
@@ -149,7 +150,7 @@ int cam_virtual_cdm_submit_bl(struct cam_hw_info *cdm_hw,
"Sanity check failed for cmd_count=%d cnt=%d", "Sanity check failed for cmd_count=%d cnt=%d",
i, req->data->cmd_arrary_count); i, req->data->cmd_arrary_count);
rc = -EINVAL; rc = -EINVAL;
break; goto end;
} }
if (!rc) { if (!rc) {
struct cam_cdm_work_payload *payload; struct cam_cdm_work_payload *payload;
@@ -166,7 +167,7 @@ int cam_virtual_cdm_submit_bl(struct cam_hw_info *cdm_hw,
GFP_KERNEL); GFP_KERNEL);
if (!node) { if (!node) {
rc = -ENOMEM; rc = -ENOMEM;
break; goto end;
} }
node->request_type = CAM_HW_CDM_BL_CB_CLIENT; node->request_type = CAM_HW_CDM_BL_CB_CLIENT;
node->client_hdl = req->handle; node->client_hdl = req->handle;
@@ -200,9 +201,20 @@ int cam_virtual_cdm_submit_bl(struct cam_hw_info *cdm_hw,
if (!rc && (core->bl_tag == 63)) if (!rc && (core->bl_tag == 63))
core->bl_tag = 0; core->bl_tag = 0;
} }
if (req->data->type == CAM_CDM_BL_CMD_TYPE_MEM_HANDLE)
cam_mem_put_cpu_buf(cdm_cmd->cmd[i].bl_addr.mem_handle);
} }
mutex_unlock(&client->lock); mutex_unlock(&client->lock);
return rc; return rc;
end:
if (req->data->type == CAM_CDM_BL_CMD_TYPE_MEM_HANDLE)
cam_mem_put_cpu_buf(cdm_cmd->cmd[i].bl_addr.mem_handle);
mutex_unlock(&client->lock);
return rc;
} }
int cam_virtual_cdm_probe(struct platform_device *pdev) int cam_virtual_cdm_probe(struct platform_device *pdev)

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/debugfs.h> #include <linux/debugfs.h>
@@ -314,6 +315,7 @@ int32_t cam_context_config_dev_to_hw(
rc = -EFAULT; rc = -EFAULT;
} }
cam_mem_put_cpu_buf((int32_t) cmd->packet_handle);
return rc; return rc;
} }
@@ -375,6 +377,7 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
if ((len < sizeof(struct cam_packet)) || if ((len < sizeof(struct cam_packet)) ||
(cmd->offset >= (len - sizeof(struct cam_packet)))) { (cmd->offset >= (len - sizeof(struct cam_packet)))) {
CAM_ERR(CAM_CTXT, "Not enough buf"); CAM_ERR(CAM_CTXT, "Not enough buf");
cam_mem_put_cpu_buf((int32_t) cmd->packet_handle);
return -EINVAL; return -EINVAL;
} }
@@ -490,7 +493,7 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
req->in_map_entries[j].sync_id, rc); req->in_map_entries[j].sync_id, rc);
} }
} }
cam_mem_put_cpu_buf((int32_t) cmd->packet_handle);
return rc; return rc;
put_ref: put_ref:
for (--i; i >= 0; i--) { for (--i; i >= 0; i--) {
@@ -504,6 +507,7 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
req->ctx = NULL; req->ctx = NULL;
spin_unlock(&ctx->lock); spin_unlock(&ctx->lock);
cam_mem_put_cpu_buf((int32_t) cmd->packet_handle);
return rc; return rc;
} }
@@ -1096,6 +1100,7 @@ static int cam_context_dump_context(struct cam_context *ctx,
if (dump_args->offset >= buf_len) { if (dump_args->offset >= buf_len) {
CAM_WARN(CAM_CTXT, "dump buffer overshoot offset %zu len %zu", CAM_WARN(CAM_CTXT, "dump buffer overshoot offset %zu len %zu",
dump_args->offset, buf_len); dump_args->offset, buf_len);
cam_mem_put_cpu_buf(dump_args->buf_handle);
return -ENOSPC; return -ENOSPC;
} }
@@ -1107,6 +1112,7 @@ static int cam_context_dump_context(struct cam_context *ctx,
if (remain_len < min_len) { if (remain_len < min_len) {
CAM_WARN(CAM_CTXT, "dump buffer exhaust remain %zu min %u", CAM_WARN(CAM_CTXT, "dump buffer exhaust remain %zu min %u",
remain_len, min_len); remain_len, min_len);
cam_mem_put_cpu_buf(dump_args->buf_handle);
return -ENOSPC; return -ENOSPC;
} }
dst = (uint8_t *)cpu_addr + dump_args->offset; dst = (uint8_t *)cpu_addr + dump_args->offset;
@@ -1131,7 +1137,8 @@ static int cam_context_dump_context(struct cam_context *ctx,
hdr->size = hdr->word_size * (addr - start); hdr->size = hdr->word_size * (addr - start);
dump_args->offset += hdr->size + dump_args->offset += hdr->size +
sizeof(struct cam_context_dump_header); sizeof(struct cam_context_dump_header);
return rc; cam_mem_put_cpu_buf(dump_args->buf_handle);
return 0;
} }
int32_t cam_context_dump_dev_to_hw(struct cam_context *ctx, int32_t cam_context_dump_dev_to_hw(struct cam_context *ctx,

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/slab.h> #include <linux/slab.h>
@@ -1129,6 +1130,7 @@ static int cam_custom_mgr_prepare_hw_update(void *hw_mgr_priv,
} }
cam_custom_add_io_buffers(hw_mgr->img_iommu_hdl, prepare); cam_custom_add_io_buffers(hw_mgr->img_iommu_hdl, prepare);
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
return 0; return 0;
} }

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/module.h> #include <linux/module.h>
@@ -524,6 +525,33 @@ static int cam_fd_mgr_util_get_buf_map_requirement(uint32_t direction,
return 0; return 0;
} }
static int cam_fd_mgr_put_cpu_buf(struct cam_hw_prepare_update_args *prepare)
{
int i, rc;
uint32_t plane;
bool need_io_map, need_cpu_map;
struct cam_buf_io_cfg *io_cfg;
io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *)
&prepare->packet->payload + prepare->packet->io_configs_offset);
if (!io_cfg)
return -EINVAL;
for (i = 0; i < prepare->packet->num_io_configs; i++) {
rc = cam_fd_mgr_util_get_buf_map_requirement(
io_cfg[i].direction, io_cfg[i].resource_type,
&need_io_map, &need_cpu_map);
if (rc || !need_cpu_map)
continue;
for (plane = 0; plane < CAM_PACKET_MAX_PLANES; plane++)
cam_mem_put_cpu_buf(io_cfg[i].mem_handle[plane]);
}
return 0;
}
static int cam_fd_mgr_util_prepare_io_buf_info(int32_t iommu_hdl, static int cam_fd_mgr_util_prepare_io_buf_info(int32_t iommu_hdl,
struct cam_hw_prepare_update_args *prepare, struct cam_hw_prepare_update_args *prepare,
struct cam_fd_hw_io_buffer *input_buf, struct cam_fd_hw_io_buffer *input_buf,
@@ -620,6 +648,8 @@ static int cam_fd_mgr_util_prepare_io_buf_info(int32_t iommu_hdl,
"Invalid cpu buf %d %d %d", "Invalid cpu buf %d %d %d",
io_cfg[i].direction, io_cfg[i].direction,
io_cfg[i].resource_type, plane); io_cfg[i].resource_type, plane);
cam_mem_put_cpu_buf(
io_cfg[i].mem_handle[plane]);
rc = -EINVAL; rc = -EINVAL;
return rc; return rc;
} }
@@ -1597,6 +1627,7 @@ static int cam_fd_mgr_hw_dump(
if (fd_dump_args.buf_len <= dump_args->offset) { if (fd_dump_args.buf_len <= dump_args->offset) {
CAM_WARN(CAM_FD, "dump offset overshoot len %zu offset %zu", CAM_WARN(CAM_FD, "dump offset overshoot len %zu offset %zu",
fd_dump_args.buf_len, dump_args->offset); fd_dump_args.buf_len, dump_args->offset);
cam_mem_put_cpu_buf(dump_args->buf_handle);
return -ENOSPC; return -ENOSPC;
} }
remain_len = fd_dump_args.buf_len - dump_args->offset; remain_len = fd_dump_args.buf_len - dump_args->offset;
@@ -1606,6 +1637,7 @@ static int cam_fd_mgr_hw_dump(
if (remain_len < min_len) { if (remain_len < min_len) {
CAM_WARN(CAM_FD, "dump buffer exhaust remain %zu min %u", CAM_WARN(CAM_FD, "dump buffer exhaust remain %zu min %u",
remain_len, min_len); remain_len, min_len);
cam_mem_put_cpu_buf(dump_args->buf_handle);
return -ENOSPC; return -ENOSPC;
} }
@@ -1637,12 +1669,14 @@ static int cam_fd_mgr_hw_dump(
if (rc) { if (rc) {
CAM_ERR(CAM_FD, "Hw Dump cmd fails req %lld rc %d", CAM_ERR(CAM_FD, "Hw Dump cmd fails req %lld rc %d",
frame_req->request_id, rc); frame_req->request_id, rc);
cam_mem_put_cpu_buf(dump_args->buf_handle);
return rc; return rc;
} }
} }
CAM_DBG(CAM_FD, "Offset before %zu after %zu", CAM_DBG(CAM_FD, "Offset before %zu after %zu",
dump_args->offset, fd_dump_args.offset); dump_args->offset, fd_dump_args.offset);
dump_args->offset = fd_dump_args.offset; dump_args->offset = fd_dump_args.offset;
cam_mem_put_cpu_buf(dump_args->buf_handle);
return rc; return rc;
} }
@@ -1776,7 +1810,7 @@ static int cam_fd_mgr_hw_prepare_update(void *hw_mgr_priv,
&prestart_args, &kmd_buf); &prestart_args, &kmd_buf);
if (rc) { if (rc) {
CAM_ERR(CAM_FD, "Error in hw update entries %d", rc); CAM_ERR(CAM_FD, "Error in hw update entries %d", rc);
goto error; goto put_cpu_buf;
} }
/* get a free frame req from free list */ /* get a free frame req from free list */
@@ -1785,7 +1819,8 @@ static int cam_fd_mgr_hw_prepare_update(void *hw_mgr_priv,
if (rc || !frame_req) { if (rc || !frame_req) {
CAM_ERR(CAM_FD, "Get frame_req failed, rc=%d, hw_ctx=%pK", CAM_ERR(CAM_FD, "Get frame_req failed, rc=%d, hw_ctx=%pK",
rc, hw_ctx); rc, hw_ctx);
return -ENOMEM; rc = -ENOMEM;
goto put_cpu_buf;
} }
/* Setup frame request info and queue to pending list */ /* Setup frame request info and queue to pending list */
@@ -1800,9 +1835,13 @@ static int cam_fd_mgr_hw_prepare_update(void *hw_mgr_priv,
*/ */
prepare->priv = frame_req; prepare->priv = frame_req;
cam_fd_mgr_put_cpu_buf(prepare);
CAM_DBG(CAM_FD, "FramePrepare : Frame[%lld]", frame_req->request_id); CAM_DBG(CAM_FD, "FramePrepare : Frame[%lld]", frame_req->request_id);
return 0; return 0;
put_cpu_buf:
cam_fd_mgr_put_cpu_buf(prepare);
error: error:
return rc; return rc;
} }

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/debugfs.h> #include <linux/debugfs.h>
@@ -156,6 +157,7 @@ static int __cam_icp_config_dev_in_ready(struct cam_context *ctx,
CAM_ERR(CAM_CTXT, CAM_ERR(CAM_CTXT,
"Invalid offset, len: %zu cmd offset: %llu sizeof packet: %zu", "Invalid offset, len: %zu cmd offset: %llu sizeof packet: %zu",
len, cmd->offset, sizeof(struct cam_packet)); len, cmd->offset, sizeof(struct cam_packet));
cam_mem_put_cpu_buf((int32_t) cmd->packet_handle);
return -EINVAL; return -EINVAL;
} }
@@ -167,6 +169,7 @@ static int __cam_icp_config_dev_in_ready(struct cam_context *ctx,
if (rc) { if (rc) {
CAM_ERR(CAM_CTXT, "Invalid packet params, remain length: %zu", CAM_ERR(CAM_CTXT, "Invalid packet params, remain length: %zu",
remain_len); remain_len);
cam_mem_put_cpu_buf((int32_t) cmd->packet_handle);
return rc; return rc;
} }
@@ -181,6 +184,7 @@ static int __cam_icp_config_dev_in_ready(struct cam_context *ctx,
if (rc) if (rc)
CAM_ERR(CAM_ICP, "Failed to prepare device"); CAM_ERR(CAM_ICP, "Failed to prepare device");
cam_mem_put_cpu_buf((int32_t) cmd->packet_handle);
return rc; return rc;
} }

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/uaccess.h> #include <linux/uaccess.h>
@@ -84,7 +85,7 @@ static int cam_icp_dump_io_cfg(struct cam_icp_hw_ctx_data *ctx_data,
used = 0; used = 0;
} }
} }
cam_mem_put_cpu_buf(buf_handle);
return rc; return rc;
} }
@@ -4177,6 +4178,7 @@ static int cam_icp_mgr_process_cmd_desc(struct cam_icp_hw_mgr *hw_mgr,
*fw_cmd_buf_iova_addr = *fw_cmd_buf_iova_addr =
(*fw_cmd_buf_iova_addr + cmd_desc[i].offset); (*fw_cmd_buf_iova_addr + cmd_desc[i].offset);
rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle, rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle,
&cpu_addr, &len); &cpu_addr, &len);
if (rc || !cpu_addr) { if (rc || !cpu_addr) {
@@ -4193,9 +4195,12 @@ static int cam_icp_mgr_process_cmd_desc(struct cam_icp_hw_mgr *hw_mgr,
((len - cmd_desc[i].offset) < ((len - cmd_desc[i].offset) <
cmd_desc[i].length)) { cmd_desc[i].length)) {
CAM_ERR(CAM_ICP, "Invalid offset or length"); CAM_ERR(CAM_ICP, "Invalid offset or length");
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
return -EINVAL; return -EINVAL;
} }
cpu_addr = cpu_addr + cmd_desc[i].offset; cpu_addr = cpu_addr + cmd_desc[i].offset;
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
} }
} }
@@ -5151,6 +5156,7 @@ static int cam_icp_mgr_hw_dump(void *hw_priv, void *hw_dump_args)
req_ts.tv_nsec/NSEC_PER_USEC, req_ts.tv_nsec/NSEC_PER_USEC,
cur_ts.tv_sec, cur_ts.tv_sec,
cur_ts.tv_nsec/NSEC_PER_USEC); cur_ts.tv_nsec/NSEC_PER_USEC);
rc = cam_mem_get_cpu_buf(dump_args->buf_handle, rc = cam_mem_get_cpu_buf(dump_args->buf_handle,
&icp_dump_args.cpu_addr, &icp_dump_args.buf_len); &icp_dump_args.cpu_addr, &icp_dump_args.buf_len);
if (rc) { if (rc) {
@@ -5161,6 +5167,7 @@ static int cam_icp_mgr_hw_dump(void *hw_priv, void *hw_dump_args)
if (icp_dump_args.buf_len <= dump_args->offset) { if (icp_dump_args.buf_len <= dump_args->offset) {
CAM_WARN(CAM_ICP, "dump buffer overshoot len %zu offset %zu", CAM_WARN(CAM_ICP, "dump buffer overshoot len %zu offset %zu",
icp_dump_args.buf_len, dump_args->offset); icp_dump_args.buf_len, dump_args->offset);
cam_mem_put_cpu_buf(dump_args->buf_handle);
return -ENOSPC; return -ENOSPC;
} }
@@ -5171,6 +5178,7 @@ static int cam_icp_mgr_hw_dump(void *hw_priv, void *hw_dump_args)
if (remain_len < min_len) { if (remain_len < min_len) {
CAM_WARN(CAM_ICP, "dump buffer exhaust remain %zu min %u", CAM_WARN(CAM_ICP, "dump buffer exhaust remain %zu min %u",
remain_len, min_len); remain_len, min_len);
cam_mem_put_cpu_buf(dump_args->buf_handle);
return -ENOSPC; return -ENOSPC;
} }
@@ -5197,6 +5205,8 @@ static int cam_icp_mgr_hw_dump(void *hw_priv, void *hw_dump_args)
CAM_DBG(CAM_ICP, "Offset before %zu after %zu", CAM_DBG(CAM_ICP, "Offset before %zu after %zu",
dump_args->offset, icp_dump_args.offset); dump_args->offset, icp_dump_args.offset);
dump_args->offset = icp_dump_args.offset; dump_args->offset = icp_dump_args.offset;
cam_mem_put_cpu_buf(dump_args->buf_handle);
return rc; return rc;
} }

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/debugfs.h> #include <linux/debugfs.h>
@@ -334,7 +335,8 @@ static int cam_isp_ctx_dump_req(
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"Invalid offset exp %u actual %u", "Invalid offset exp %u actual %u",
req_isp->cfg[i].offset, (uint32_t)len); req_isp->cfg[i].offset, (uint32_t)len);
return rc; cam_mem_put_cpu_buf(req_isp->cfg[i].handle);
return -EINVAL;
} }
remain_len = len - req_isp->cfg[i].offset; remain_len = len - req_isp->cfg[i].offset;
@@ -344,7 +346,8 @@ static int cam_isp_ctx_dump_req(
"Invalid len exp %u remain_len %u", "Invalid len exp %u remain_len %u",
req_isp->cfg[i].len, req_isp->cfg[i].len,
(uint32_t)remain_len); (uint32_t)remain_len);
return rc; cam_mem_put_cpu_buf(req_isp->cfg[i].handle);
return -EINVAL;
} }
buf_start = (uint32_t *)((uint8_t *) buf_addr + buf_start = (uint32_t *)((uint8_t *) buf_addr +
@@ -368,6 +371,7 @@ static int cam_isp_ctx_dump_req(
} else { } else {
cam_cdm_util_dump_cmd_buf(buf_start, buf_end); cam_cdm_util_dump_cmd_buf(buf_start, buf_end);
} }
cam_mem_put_cpu_buf(req_isp->cfg[i].handle);
} }
} }
return rc; return rc;
@@ -2537,6 +2541,7 @@ static int __cam_isp_ctx_dump_in_top_state(
spin_unlock_bh(&ctx->lock); spin_unlock_bh(&ctx->lock);
CAM_WARN(CAM_ISP, "Dump buffer overshoot len %zu offset %zu", CAM_WARN(CAM_ISP, "Dump buffer overshoot len %zu offset %zu",
buf_len, dump_info->offset); buf_len, dump_info->offset);
cam_mem_put_cpu_buf(dump_info->buf_handle);
return -ENOSPC; return -ENOSPC;
} }
@@ -2548,6 +2553,7 @@ static int __cam_isp_ctx_dump_in_top_state(
spin_unlock_bh(&ctx->lock); spin_unlock_bh(&ctx->lock);
CAM_WARN(CAM_ISP, "Dump buffer exhaust remain %zu min %u", CAM_WARN(CAM_ISP, "Dump buffer exhaust remain %zu min %u",
remain_len, min_len); remain_len, min_len);
cam_mem_put_cpu_buf(dump_info->buf_handle);
return -ENOSPC; return -ENOSPC;
} }
@@ -2587,20 +2593,17 @@ static int __cam_isp_ctx_dump_in_top_state(
if (rc) { if (rc) {
CAM_ERR(CAM_ISP, "Dump event fail %lld", CAM_ERR(CAM_ISP, "Dump event fail %lld",
req->request_id); req->request_id);
spin_unlock_bh(&ctx->lock); goto end;
return rc;
}
if (dump_only_event_record) {
spin_unlock_bh(&ctx->lock);
return rc;
} }
if (dump_only_event_record)
goto end;
rc = __cam_isp_ctx_dump_req_info(ctx, req, cpu_addr, rc = __cam_isp_ctx_dump_req_info(ctx, req, cpu_addr,
buf_len, &dump_info->offset); buf_len, &dump_info->offset);
if (rc) { if (rc) {
CAM_ERR(CAM_ISP, "Dump Req info fail %lld", CAM_ERR(CAM_ISP, "Dump Req info fail %lld",
req->request_id); req->request_id);
spin_unlock_bh(&ctx->lock); goto end;
return rc;
} }
spin_unlock_bh(&ctx->lock); spin_unlock_bh(&ctx->lock);
@@ -2614,6 +2617,12 @@ static int __cam_isp_ctx_dump_in_top_state(
&dump_args); &dump_args);
dump_info->offset = dump_args.offset; dump_info->offset = dump_args.offset;
} }
cam_mem_put_cpu_buf(dump_info->buf_handle);
return rc;
end:
spin_unlock_bh(&ctx->lock);
cam_mem_put_cpu_buf(dump_info->buf_handle);
return rc; return rc;
} }
@@ -3742,6 +3751,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
"Preprocessing Config req_id %lld successful on ctx %u", "Preprocessing Config req_id %lld successful on ctx %u",
req->request_id, ctx->ctx_id); req->request_id, ctx->ctx_id);
cam_mem_put_cpu_buf((int32_t) cmd->packet_handle);
return rc; return rc;
put_ref: put_ref:
@@ -3755,6 +3765,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
list_add_tail(&req->list, &ctx->free_req_list); list_add_tail(&req->list, &ctx->free_req_list);
spin_unlock_bh(&ctx->lock); spin_unlock_bh(&ctx->lock);
cam_mem_put_cpu_buf((int32_t) cmd->packet_handle);
return rc; return rc;
} }

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/slab.h> #include <linux/slab.h>
@@ -6092,6 +6093,7 @@ static int cam_ife_mgr_dump(void *hw_mgr_priv, void *args)
} }
} }
dump_args->offset = isp_hw_dump_args.offset; dump_args->offset = isp_hw_dump_args.offset;
cam_mem_put_cpu_buf(dump_args->buf_handle);
end: end:
CAM_DBG(CAM_ISP, "offset %u", dump_args->offset); CAM_DBG(CAM_ISP, "offset %u", dump_args->offset);
return rc; return rc;

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/slab.h> #include <linux/slab.h>
@@ -1765,6 +1766,8 @@ void cam_tfe_cam_cdm_callback(uint32_t handle, void *userdata,
ctx->last_submit_bl_cmd.cmd[i].input_len - 1); ctx->last_submit_bl_cmd.cmd[i].input_len - 1);
cam_cdm_util_dump_cmd_buf(buf_start, buf_end); cam_cdm_util_dump_cmd_buf(buf_start, buf_end);
cam_mem_put_cpu_buf(
ctx->last_submit_bl_cmd.cmd[i].mem_handle);
} }
if (ctx->packet != NULL) if (ctx->packet != NULL)
cam_packet_dump_patch_info(ctx->packet, cam_packet_dump_patch_info(ctx->packet,
@@ -3287,6 +3290,7 @@ static int cam_tfe_mgr_dump(void *hw_mgr_priv, void *args)
} }
dump_args->offset = isp_hw_dump_args.offset; dump_args->offset = isp_hw_dump_args.offset;
CAM_DBG(CAM_ISP, "offset %u", dump_args->offset); CAM_DBG(CAM_ISP, "offset %u", dump_args->offset);
cam_mem_put_cpu_buf(dump_args->buf_handle);
return rc; return rc;
} }
@@ -3892,6 +3896,7 @@ static int cam_tfe_update_dual_config(
(cmd_desc->offset >= (cmd_desc->offset >=
(len - sizeof(struct cam_isp_tfe_dual_config)))) { (len - sizeof(struct cam_isp_tfe_dual_config)))) {
CAM_ERR(CAM_ISP, "not enough buffer provided"); CAM_ERR(CAM_ISP, "not enough buffer provided");
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
return -EINVAL; return -EINVAL;
} }
@@ -3904,6 +3909,7 @@ static int cam_tfe_update_dual_config(
(remain_len - (remain_len -
offsetof(struct cam_isp_tfe_dual_config, stripes))) { offsetof(struct cam_isp_tfe_dual_config, stripes))) {
CAM_ERR(CAM_ISP, "not enough buffer for all the dual configs"); CAM_ERR(CAM_ISP, "not enough buffer for all the dual configs");
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
return -EINVAL; return -EINVAL;
} }
@@ -3965,6 +3971,7 @@ static int cam_tfe_update_dual_config(
} }
end: end:
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
return rc; return rc;
} }

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <media/cam_defs.h> #include <media/cam_defs.h>
@@ -117,6 +118,7 @@ static int cam_isp_update_dual_config(
(cmd_desc->offset >= (cmd_desc->offset >=
(len - sizeof(struct cam_isp_dual_config)))) { (len - sizeof(struct cam_isp_dual_config)))) {
CAM_ERR(CAM_ISP, "not enough buffer provided"); CAM_ERR(CAM_ISP, "not enough buffer provided");
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
return -EINVAL; return -EINVAL;
} }
remain_len = len - cmd_desc->offset; remain_len = len - cmd_desc->offset;
@@ -127,6 +129,7 @@ static int cam_isp_update_dual_config(
sizeof(struct cam_isp_dual_stripe_config)) > sizeof(struct cam_isp_dual_stripe_config)) >
(remain_len - offsetof(struct cam_isp_dual_config, stripes))) { (remain_len - offsetof(struct cam_isp_dual_config, stripes))) {
CAM_ERR(CAM_ISP, "not enough buffer for all the dual configs"); CAM_ERR(CAM_ISP, "not enough buffer for all the dual configs");
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
return -EINVAL; return -EINVAL;
} }
for (i = 0; i < dual_config->num_ports; i++) { for (i = 0; i < dual_config->num_ports; i++) {
@@ -184,6 +187,7 @@ static int cam_isp_update_dual_config(
} }
end: end:
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
return rc; return rc;
} }

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/uaccess.h> #include <linux/uaccess.h>
@@ -154,6 +155,7 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data)
CAM_ERR(CAM_JPEG, "Invalid offset: %u cmd buf len: %zu", CAM_ERR(CAM_JPEG, "Invalid offset: %u cmd buf len: %zu",
p_cfg_req->hw_cfg_args.hw_update_entries[ p_cfg_req->hw_cfg_args.hw_update_entries[
CAM_JPEG_PARAM].offset, cmd_buf_len); CAM_JPEG_PARAM].offset, cmd_buf_len);
cam_mem_put_cpu_buf(mem_hdl);
return -EINVAL; return -EINVAL;
} }
@@ -180,6 +182,7 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data)
mutex_lock(&g_jpeg_hw_mgr.hw_mgr_mutex); mutex_lock(&g_jpeg_hw_mgr.hw_mgr_mutex);
list_add_tail(&p_cfg_req->list, &hw_mgr->free_req_list); list_add_tail(&p_cfg_req->list, &hw_mgr->free_req_list);
mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex); mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex);
cam_mem_put_cpu_buf(mem_hdl);
return rc; return rc;
} }
@@ -280,7 +283,11 @@ static int cam_jpeg_insert_cdm_change_base(
if (config_args->hw_update_entries[CAM_JPEG_CHBASE].offset >= if (config_args->hw_update_entries[CAM_JPEG_CHBASE].offset >=
ch_base_len) { ch_base_len) {
CAM_ERR(CAM_JPEG, "Not enough buf"); CAM_ERR(CAM_JPEG, "Not enough buf offset %d len %d",
config_args->hw_update_entries[CAM_JPEG_CHBASE].offset,
ch_base_len);
cam_mem_put_cpu_buf(
config_args->hw_update_entries[CAM_JPEG_CHBASE].handle);
return -EINVAL; return -EINVAL;
} }
CAM_DBG(CAM_JPEG, "iova %pK len %zu offset %d", CAM_DBG(CAM_JPEG, "iova %pK len %zu offset %d",
@@ -312,6 +319,9 @@ static int cam_jpeg_insert_cdm_change_base(
ch_base_iova_addr += size; ch_base_iova_addr += size;
*ch_base_iova_addr = 0; *ch_base_iova_addr = 0;
cam_mem_put_cpu_buf(
config_args->hw_update_entries[CAM_JPEG_CHBASE].handle);
return rc; return rc;
} }
@@ -1586,6 +1596,7 @@ static int cam_jpeg_mgr_hw_dump(void *hw_mgr_priv, void *dump_hw_args)
CAM_WARN(CAM_JPEG, "dump offset overshoot len %zu offset %zu", CAM_WARN(CAM_JPEG, "dump offset overshoot len %zu offset %zu",
jpeg_dump_args.buf_len, dump_args->offset); jpeg_dump_args.buf_len, dump_args->offset);
mutex_unlock(&hw_mgr->hw_mgr_mutex); mutex_unlock(&hw_mgr->hw_mgr_mutex);
cam_mem_put_cpu_buf(dump_args->buf_handle);
return -ENOSPC; return -ENOSPC;
} }
@@ -1596,6 +1607,7 @@ static int cam_jpeg_mgr_hw_dump(void *hw_mgr_priv, void *dump_hw_args)
CAM_WARN(CAM_JPEG, "dump buffer exhaust remain %zu min %u", CAM_WARN(CAM_JPEG, "dump buffer exhaust remain %zu min %u",
remain_len, min_len); remain_len, min_len);
mutex_unlock(&hw_mgr->hw_mgr_mutex); mutex_unlock(&hw_mgr->hw_mgr_mutex);
cam_mem_put_cpu_buf(dump_args->buf_handle);
return -ENOSPC; return -ENOSPC;
} }
@@ -1628,6 +1640,7 @@ static int cam_jpeg_mgr_hw_dump(void *hw_mgr_priv, void *dump_hw_args)
CAM_DBG(CAM_JPEG, "Offset before %u after %u", CAM_DBG(CAM_JPEG, "Offset before %u after %u",
dump_args->offset, jpeg_dump_args.offset); dump_args->offset, jpeg_dump_args.offset);
dump_args->offset = jpeg_dump_args.offset; dump_args->offset = jpeg_dump_args.offset;
cam_mem_put_cpu_buf(dump_args->buf_handle);
return rc; return rc;
} }

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/module.h> #include <linux/module.h>
@@ -690,6 +691,7 @@ static int cam_lrme_mgr_hw_dump(void *hw_mgr_priv, void *hw_dump_args)
CAM_DBG(CAM_LRME, "Offset before %zu after %zu", CAM_DBG(CAM_LRME, "Offset before %zu after %zu",
dump_args->offset, lrme_dump_args.offset); dump_args->offset, lrme_dump_args.offset);
dump_args->offset = lrme_dump_args.offset; dump_args->offset = lrme_dump_args.offset;
cam_mem_put_cpu_buf(dump_args->buf_handle);
return rc; return rc;
} }

View File

@@ -155,6 +155,7 @@ static int __cam_ope_config_dev_in_ready(struct cam_context *ctx,
if (rc) if (rc)
CAM_ERR(CAM_OPE, "Failed to prepare device"); CAM_ERR(CAM_OPE, "Failed to prepare device");
cam_mem_put_cpu_buf((int32_t) cmd->packet_handle);
return rc; return rc;
} }

View File

@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/uaccess.h> #include <linux/uaccess.h>
@@ -425,6 +425,25 @@ static void cam_ope_dump_dmi(struct cam_ope_hang_dump *dump, uint32_t addr,
return; return;
} }
static int cam_ope_mgr_put_cmd_buf(struct cam_packet *packet)
{
int i = 0;
struct cam_cmd_buf_desc *cmd_desc = NULL;
cmd_desc = (struct cam_cmd_buf_desc *)
((uint32_t *) &packet->payload + packet->cmd_buf_offset/4);
for (i = 0; i < packet->num_cmd_buf; i++) {
if (cmd_desc[i].type != CAM_CMD_BUF_GENERIC ||
cmd_desc[i].meta_data == OPE_CMD_META_GENERIC_BLOB)
continue;
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
}
return 0;
}
static int cam_ope_dump_indirect(struct ope_cmd_buf_info *cmd_buf_info, static int cam_ope_dump_indirect(struct ope_cmd_buf_info *cmd_buf_info,
struct cam_ope_hang_dump *dump) struct cam_ope_hang_dump *dump)
{ {
@@ -454,6 +473,7 @@ static int cam_ope_dump_indirect(struct ope_cmd_buf_info *cmd_buf_info,
print_ptr += sizeof(struct cdm_dmi_cmd) / print_ptr += sizeof(struct cdm_dmi_cmd) /
sizeof(uint32_t); sizeof(uint32_t);
} }
cam_mem_put_cpu_buf((int32_t) cmd_buf_info->mem_handle);
return rc; return rc;
} }
@@ -556,6 +576,7 @@ static int cam_ope_dump_frame_process(struct cam_packet *packet,
cam_ope_mgr_dump_cmd_buf(cpu_addr, dump); cam_ope_mgr_dump_cmd_buf(cpu_addr, dump);
cam_ope_mgr_dump_frame_set(cpu_addr, dump); cam_ope_mgr_dump_frame_set(cpu_addr, dump);
cam_ope_mgr_put_cmd_buf(packet);
return rc; return rc;
} }
@@ -2175,6 +2196,8 @@ static int cam_ope_mgr_process_cmd_buf_req(struct cam_ope_hw_mgr *hw_mgr,
ope_request->ope_kmd_buf.cpu_addr, ope_request->ope_kmd_buf.cpu_addr,
ope_request->ope_kmd_buf.iova_addr, ope_request->ope_kmd_buf.iova_addr,
ope_request->ope_kmd_buf.iova_cdm_addr); ope_request->ope_kmd_buf.iova_cdm_addr);
cam_mem_put_cpu_buf(
cmd_buf->mem_handle);
break; break;
} else if (cmd_buf->cmd_buf_usage == } else if (cmd_buf->cmd_buf_usage ==
OPE_CMD_BUF_DEBUG) { OPE_CMD_BUF_DEBUG) {
@@ -2190,8 +2213,11 @@ static int cam_ope_mgr_process_cmd_buf_req(struct cam_ope_hw_mgr *hw_mgr,
cmd_buf->offset; cmd_buf->offset;
CAM_DBG(CAM_OPE, "dbg buf = %x", CAM_DBG(CAM_OPE, "dbg buf = %x",
ope_request->ope_debug_buf.cpu_addr); ope_request->ope_debug_buf.cpu_addr);
cam_mem_put_cpu_buf(
cmd_buf->mem_handle);
break; break;
} }
cam_mem_put_cpu_buf(cmd_buf->mem_handle);
break; break;
} }
case OPE_CMD_BUF_SCOPE_STRIPE: { case OPE_CMD_BUF_SCOPE_STRIPE: {
@@ -3038,6 +3064,7 @@ static int cam_ope_mgr_release_hw(void *hw_priv, void *hw_release_args)
return rc; return rc;
} }
static int cam_ope_packet_generic_blob_handler(void *user_data, static int cam_ope_packet_generic_blob_handler(void *user_data,
uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data) uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data)
{ {
@@ -3294,14 +3321,15 @@ static int cam_ope_mgr_prepare_hw_update(void *hw_priv,
ctx_data->last_req_time); ctx_data->last_req_time);
cam_ope_req_timer_modify(ctx_data, ctx_data->req_timer_timeout); cam_ope_req_timer_modify(ctx_data, ctx_data->req_timer_timeout);
set_bit(request_idx, ctx_data->bitmap); set_bit(request_idx, ctx_data->bitmap);
cam_ope_mgr_put_cmd_buf(packet);
mutex_unlock(&ctx_data->ctx_mutex); mutex_unlock(&ctx_data->ctx_mutex);
CAM_DBG(CAM_REQ, "Prepare Hw update Successful request_id: %d ctx: %d", CAM_DBG(CAM_REQ, "Prepare Hw update Successful request_id: %d ctx: %d",
packet->header.request_id, ctx_data->ctx_id); packet->header.request_id, ctx_data->ctx_id);
return rc; return rc;
end: end:
kzfree(ctx_data->req_list[request_idx]->cdm_cmd); kzfree(ctx_data->req_list[request_idx]->cdm_cmd);
cam_ope_mgr_put_cmd_buf(packet);
ctx_data->req_list[request_idx]->cdm_cmd = NULL; ctx_data->req_list[request_idx]->cdm_cmd = NULL;
req_cdm_mem_alloc_failed: req_cdm_mem_alloc_failed:
kzfree(ctx_data->req_list[request_idx]); kzfree(ctx_data->req_list[request_idx]);

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/of.h> #include <linux/of.h>
@@ -584,6 +585,8 @@ static uint32_t *ope_create_frame_cmd_batch(struct cam_ope_hw_mgr *hw_mgr,
dmi_cmd = (struct cdm_dmi_cmd *)temp; dmi_cmd = (struct cdm_dmi_cmd *)temp;
if (!dmi_cmd->addr) { if (!dmi_cmd->addr) {
CAM_ERR(CAM_OPE, "Null dmi cmd addr"); CAM_ERR(CAM_OPE, "Null dmi cmd addr");
cam_mem_put_cpu_buf(
frm_proc->cmd_buf[i][j].mem_handle);
return NULL; return NULL;
} }
@@ -604,6 +607,8 @@ static uint32_t *ope_create_frame_cmd_batch(struct cam_ope_hw_mgr *hw_mgr,
if (hw_mgr->frame_dump_enable) if (hw_mgr->frame_dump_enable)
dump_frame_cmd(frm_proc, i, j, dump_frame_cmd(frm_proc, i, j,
iova_addr, kmd_buf, buf_len); iova_addr, kmd_buf, buf_len);
cam_mem_put_cpu_buf(frm_proc->cmd_buf[i][j].mem_handle);
} }
return kmd_buf; return kmd_buf;
@@ -743,6 +748,8 @@ static uint32_t *ope_create_frame_cmd(struct cam_ope_hw_mgr *hw_mgr,
if (!dmi_cmd->addr) { if (!dmi_cmd->addr) {
CAM_ERR(CAM_OPE, CAM_ERR(CAM_OPE,
"Null dmi cmd addr"); "Null dmi cmd addr");
cam_mem_put_cpu_buf(
frm_proc->cmd_buf[i][j].mem_handle);
return NULL; return NULL;
} }
@@ -764,6 +771,8 @@ static uint32_t *ope_create_frame_cmd(struct cam_ope_hw_mgr *hw_mgr,
if (hw_mgr->frame_dump_enable) if (hw_mgr->frame_dump_enable)
dump_frame_cmd(frm_proc, i, j, dump_frame_cmd(frm_proc, i, j,
iova_addr, kmd_buf, buf_len); iova_addr, kmd_buf, buf_len);
cam_mem_put_cpu_buf(frm_proc->cmd_buf[i][j].mem_handle);
} }
} }
return kmd_buf; return kmd_buf;
@@ -859,6 +868,8 @@ static uint32_t *ope_create_stripe_cmd(struct cam_ope_hw_mgr *hw_mgr,
dmi_cmd = (struct cdm_dmi_cmd *)temp; dmi_cmd = (struct cdm_dmi_cmd *)temp;
if (!dmi_cmd->addr) { if (!dmi_cmd->addr) {
CAM_ERR(CAM_OPE, "Null dmi cmd addr"); CAM_ERR(CAM_OPE, "Null dmi cmd addr");
cam_mem_put_cpu_buf(
frm_proc->cmd_buf[i][k].mem_handle);
return NULL; return NULL;
} }
@@ -877,6 +888,8 @@ static uint32_t *ope_create_stripe_cmd(struct cam_ope_hw_mgr *hw_mgr,
if (hw_mgr->frame_dump_enable) if (hw_mgr->frame_dump_enable)
dump_stripe_cmd(frm_proc, stripe_idx, i, k, dump_stripe_cmd(frm_proc, stripe_idx, i, k,
iova_addr, kmd_buf, buf_len); iova_addr, kmd_buf, buf_len);
cam_mem_put_cpu_buf(frm_proc->cmd_buf[i][k].mem_handle);
} }
ope_dev = hw_mgr->ope_dev_intf[0]->hw_priv; ope_dev = hw_mgr->ope_dev_intf[0]->hw_priv;

View File

@@ -272,24 +272,33 @@ int cam_mem_get_cpu_buf(int32_t buf_handle, uintptr_t *vaddr_ptr, size_t *len)
return -EINVAL; return -EINVAL;
idx = CAM_MEM_MGR_GET_HDL_IDX(buf_handle); idx = CAM_MEM_MGR_GET_HDL_IDX(buf_handle);
if (idx >= CAM_MEM_BUFQ_MAX || idx <= 0) if (idx >= CAM_MEM_BUFQ_MAX || idx <= 0)
return -EINVAL; return -EINVAL;
if (!tbl.bufq[idx].active) if (!tbl.bufq[idx].active)
return -EPERM; return -EPERM;
if (buf_handle != tbl.bufq[idx].buf_handle) if (buf_handle != tbl.bufq[idx].buf_handle) {
CAM_ERR(CAM_MEM, "idx: %d Invalid buf handle %d",
idx, buf_handle);
return -EINVAL; return -EINVAL;
}
if (!(tbl.bufq[idx].flags & CAM_MEM_FLAG_KMD_ACCESS)) if (!(tbl.bufq[idx].flags & CAM_MEM_FLAG_KMD_ACCESS)) {
CAM_ERR(CAM_MEM, "idx: %d Invalid flag 0x%x",
idx, tbl.bufq[idx].flags);
return -EINVAL; return -EINVAL;
}
if (tbl.bufq[idx].kmdvaddr) { if (tbl.bufq[idx].kmdvaddr &&
kref_get_unless_zero(&tbl.bufq[idx].krefcount)) {
*vaddr_ptr = tbl.bufq[idx].kmdvaddr; *vaddr_ptr = tbl.bufq[idx].kmdvaddr;
*len = tbl.bufq[idx].len; *len = tbl.bufq[idx].len;
} else { } else {
CAM_ERR(CAM_MEM, "No KMD access was requested for 0x%x handle", CAM_ERR(CAM_MEM,
buf_handle); "No KMD access request, vddr= %p, idx= %d, handle= %d",
tbl.bufq[idx].kmdvaddr, idx, buf_handle);
return -EINVAL; return -EINVAL;
} }
@@ -709,6 +718,8 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd)
memcpy(tbl.bufq[idx].hdls, cmd->mmu_hdls, memcpy(tbl.bufq[idx].hdls, cmd->mmu_hdls,
sizeof(int32_t) * cmd->num_hdl); sizeof(int32_t) * cmd->num_hdl);
tbl.bufq[idx].is_imported = false; tbl.bufq[idx].is_imported = false;
kref_init(&tbl.bufq[idx].krefcount);
tbl.bufq[idx].smmu_mapping_client = CAM_SMMU_MAPPING_USER;
mutex_unlock(&tbl.bufq[idx].q_lock); mutex_unlock(&tbl.bufq[idx].q_lock);
cmd->out.buf_handle = tbl.bufq[idx].buf_handle; cmd->out.buf_handle = tbl.bufq[idx].buf_handle;
@@ -811,6 +822,8 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd)
memcpy(tbl.bufq[idx].hdls, cmd->mmu_hdls, memcpy(tbl.bufq[idx].hdls, cmd->mmu_hdls,
sizeof(int32_t) * cmd->num_hdl); sizeof(int32_t) * cmd->num_hdl);
tbl.bufq[idx].is_imported = true; tbl.bufq[idx].is_imported = true;
kref_init(&tbl.bufq[idx].krefcount);
tbl.bufq[idx].smmu_mapping_client = CAM_SMMU_MAPPING_USER;
mutex_unlock(&tbl.bufq[idx].q_lock); mutex_unlock(&tbl.bufq[idx].q_lock);
cmd->out.buf_handle = tbl.bufq[idx].buf_handle; cmd->out.buf_handle = tbl.bufq[idx].buf_handle;
@@ -962,17 +975,23 @@ void cam_mem_mgr_deinit(void)
mutex_destroy(&tbl.m_lock); mutex_destroy(&tbl.m_lock);
} }
static int cam_mem_util_unmap(int32_t idx, static void cam_mem_util_unmap(struct kref *kref)
enum cam_smmu_mapping_client client)
{ {
int rc = 0; int rc = 0;
int32_t idx;
enum cam_smmu_region_id region = CAM_SMMU_REGION_SHARED; enum cam_smmu_region_id region = CAM_SMMU_REGION_SHARED;
enum cam_smmu_mapping_client client;
struct cam_mem_buf_queue *bufq =
container_of(kref, typeof(*bufq), krefcount);
idx = CAM_MEM_MGR_GET_HDL_IDX(bufq->buf_handle);
if (idx >= CAM_MEM_BUFQ_MAX || idx <= 0) { if (idx >= CAM_MEM_BUFQ_MAX || idx <= 0) {
CAM_ERR(CAM_MEM, "Incorrect index"); CAM_ERR(CAM_MEM, "Incorrect index");
return -EINVAL; return;
} }
client = tbl.bufq[idx].smmu_mapping_client;
CAM_DBG(CAM_MEM, "Flags = %X idx %d", tbl.bufq[idx].flags, idx); CAM_DBG(CAM_MEM, "Flags = %X idx %d", tbl.bufq[idx].flags, idx);
mutex_lock(&tbl.m_lock); mutex_lock(&tbl.m_lock);
@@ -981,7 +1000,7 @@ static int cam_mem_util_unmap(int32_t idx,
CAM_WARN(CAM_MEM, "Buffer at idx=%d is already unmapped,", CAM_WARN(CAM_MEM, "Buffer at idx=%d is already unmapped,",
idx); idx);
mutex_unlock(&tbl.m_lock); mutex_unlock(&tbl.m_lock);
return 0; return;
} }
if (tbl.bufq[idx].flags & CAM_MEM_FLAG_KMD_ACCESS) { if (tbl.bufq[idx].flags & CAM_MEM_FLAG_KMD_ACCESS) {
@@ -1041,13 +1060,50 @@ static int cam_mem_util_unmap(int32_t idx,
clear_bit(idx, tbl.bitmap); clear_bit(idx, tbl.bitmap);
mutex_unlock(&tbl.m_lock); mutex_unlock(&tbl.m_lock);
return rc;
} }
void cam_mem_put_cpu_buf(int32_t buf_handle)
{
int rc = 0;
int idx;
if (!buf_handle) {
CAM_ERR(CAM_MEM, "Invalid buf_handle");
return;
}
idx = CAM_MEM_MGR_GET_HDL_IDX(buf_handle);
if (idx >= CAM_MEM_BUFQ_MAX || idx <= 0) {
CAM_ERR(CAM_MEM, "idx: %d not valid", idx);
return;
}
if (!tbl.bufq[idx].active) {
CAM_ERR(CAM_MEM, "idx: %d not active", idx);
rc = -EPERM;
return;
}
if (buf_handle != tbl.bufq[idx].buf_handle) {
CAM_ERR(CAM_MEM, "idx: %d Invalid buf handle %d",
idx, buf_handle);
rc = -EINVAL;
return;
}
if (kref_put(&tbl.bufq[idx].krefcount, cam_mem_util_unmap))
CAM_DBG(CAM_MEM,
"Called unmap from here, buf_handle: %u, idx: %d",
buf_handle, idx);
}
EXPORT_SYMBOL(cam_mem_put_cpu_buf);
int cam_mem_mgr_release(struct cam_mem_mgr_release_cmd *cmd) int cam_mem_mgr_release(struct cam_mem_mgr_release_cmd *cmd)
{ {
int idx; int idx;
int rc; int rc = 0;
if (!atomic_read(&cam_mem_mgr_state)) { if (!atomic_read(&cam_mem_mgr_state)) {
CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized");
@@ -1079,7 +1135,11 @@ int cam_mem_mgr_release(struct cam_mem_mgr_release_cmd *cmd)
} }
CAM_DBG(CAM_MEM, "Releasing hdl = %x, idx = %d", cmd->buf_handle, idx); CAM_DBG(CAM_MEM, "Releasing hdl = %x, idx = %d", cmd->buf_handle, idx);
rc = cam_mem_util_unmap(idx, CAM_SMMU_MAPPING_USER);
if (kref_put(&tbl.bufq[idx].krefcount, cam_mem_util_unmap))
CAM_DBG(CAM_MEM,
"Called unmap from here, buf_handle: %u, idx: %d",
cmd->buf_handle, idx);
return rc; return rc;
} }
@@ -1200,6 +1260,8 @@ int cam_mem_mgr_request_mem(struct cam_mem_mgr_request_desc *inp,
memcpy(tbl.bufq[idx].hdls, &smmu_hdl, memcpy(tbl.bufq[idx].hdls, &smmu_hdl,
sizeof(int32_t)); sizeof(int32_t));
tbl.bufq[idx].is_imported = false; tbl.bufq[idx].is_imported = false;
kref_init(&tbl.bufq[idx].krefcount);
tbl.bufq[idx].smmu_mapping_client = CAM_SMMU_MAPPING_KERNEL;
mutex_unlock(&tbl.bufq[idx].q_lock); mutex_unlock(&tbl.bufq[idx].q_lock);
out->kva = kvaddr; out->kva = kvaddr;
@@ -1225,7 +1287,7 @@ EXPORT_SYMBOL(cam_mem_mgr_request_mem);
int cam_mem_mgr_release_mem(struct cam_mem_mgr_memory_desc *inp) int cam_mem_mgr_release_mem(struct cam_mem_mgr_memory_desc *inp)
{ {
int32_t idx; int32_t idx;
int rc; int rc = 0;
if (!atomic_read(&cam_mem_mgr_state)) { if (!atomic_read(&cam_mem_mgr_state)) {
CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized");
@@ -1259,7 +1321,12 @@ int cam_mem_mgr_release_mem(struct cam_mem_mgr_memory_desc *inp)
} }
CAM_DBG(CAM_MEM, "Releasing hdl = %X", inp->mem_handle); CAM_DBG(CAM_MEM, "Releasing hdl = %X", inp->mem_handle);
rc = cam_mem_util_unmap(idx, CAM_SMMU_MAPPING_KERNEL); if (kref_put(&tbl.bufq[idx].krefcount, cam_mem_util_unmap))
CAM_DBG(CAM_MEM,
"Called unmap from here, buf_handle: %u, idx: %d",
tbl.bufq[idx].buf_handle, idx);
else
rc = -EINVAL;
return rc; return rc;
} }
@@ -1348,6 +1415,8 @@ int cam_mem_mgr_reserve_memory_region(struct cam_mem_mgr_request_desc *inp,
memcpy(tbl.bufq[idx].hdls, &smmu_hdl, memcpy(tbl.bufq[idx].hdls, &smmu_hdl,
sizeof(int32_t)); sizeof(int32_t));
tbl.bufq[idx].is_imported = false; tbl.bufq[idx].is_imported = false;
kref_init(&tbl.bufq[idx].krefcount);
tbl.bufq[idx].smmu_mapping_client = CAM_SMMU_MAPPING_KERNEL;
mutex_unlock(&tbl.bufq[idx].q_lock); mutex_unlock(&tbl.bufq[idx].q_lock);
out->kva = 0; out->kva = 0;
@@ -1432,9 +1501,12 @@ int cam_mem_mgr_free_memory_region(struct cam_mem_mgr_memory_desc *inp)
} }
CAM_DBG(CAM_MEM, "Releasing hdl = %X", inp->mem_handle); CAM_DBG(CAM_MEM, "Releasing hdl = %X", inp->mem_handle);
rc = cam_mem_util_unmap(idx, CAM_SMMU_MAPPING_KERNEL); if (kref_put(&tbl.bufq[idx].krefcount, cam_mem_util_unmap))
if (rc) CAM_DBG(CAM_MEM,
CAM_ERR(CAM_MEM, "unmapping secondary heap failed"); "Called unmap from here, buf_handle: %u, idx: %d",
inp->mem_handle, idx);
else
rc = -EINVAL;
return rc; return rc;
} }

View File

@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#ifndef _CAM_MEM_MGR_H_ #ifndef _CAM_MEM_MGR_H_
@@ -40,7 +41,11 @@ enum cam_smmu_mapping_client {
* @vaddr: IOVA of buffer * @vaddr: IOVA of buffer
* @kmdvaddr: Kernel virtual address * @kmdvaddr: Kernel virtual address
* @active: state of the buffer * @active: state of the buffer
* @is_imported: Flag indicating if buffer is imported from an FD in user space * @is_imported: Flag indicating if buffer is imported from an FD
* in user space
* @krefcount: Reference counter to track whether the buffer is
* mapped and in use
* @smmu_mapping_client: Client buffer (User or kernel)
*/ */
struct cam_mem_buf_queue { struct cam_mem_buf_queue {
struct dma_buf *dma_buf; struct dma_buf *dma_buf;
@@ -56,6 +61,8 @@ struct cam_mem_buf_queue {
uintptr_t kmdvaddr; uintptr_t kmdvaddr;
bool active; bool active;
bool is_imported; bool is_imported;
struct kref krefcount;
enum cam_smmu_mapping_client smmu_mapping_client;
}; };
/** /**

View File

@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#ifndef _CAM_MEM_MGR_API_H_ #ifndef _CAM_MEM_MGR_API_H_
@@ -90,6 +91,14 @@ int cam_mem_get_io_buf(int32_t buf_handle, int32_t mmu_handle,
int cam_mem_get_cpu_buf(int32_t buf_handle, uintptr_t *vaddr_ptr, int cam_mem_get_cpu_buf(int32_t buf_handle, uintptr_t *vaddr_ptr,
size_t *len); size_t *len);
/**
* @brief: This indicates end of CPU access
*
* @buf_handle: Handle for the buffer
*
*/
void cam_mem_put_cpu_buf(int32_t buf_handle);
static inline bool cam_mem_is_secure_buf(int32_t buf_handle) static inline bool cam_mem_is_secure_buf(int32_t buf_handle)
{ {
return CAM_MEM_MGR_IS_SECURE_HDL(buf_handle); return CAM_MEM_MGR_IS_SECURE_HDL(buf_handle);

View File

@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/module.h> #include <linux/module.h>
@@ -2681,9 +2681,7 @@ static int cam_req_mgr_cb_add_req(struct cam_req_mgr_add_request *add_req)
return -EINVAL; return -EINVAL;
} }
link = (struct cam_req_mgr_core_link *) link = cam_get_link_priv(add_req->link_hdl);
cam_get_device_priv(add_req->link_hdl);
if (!link) { if (!link) {
CAM_DBG(CAM_CRM, "link ptr NULL %x", add_req->link_hdl); CAM_DBG(CAM_CRM, "link ptr NULL %x", add_req->link_hdl);
return -EINVAL; return -EINVAL;
@@ -2760,8 +2758,7 @@ static int cam_req_mgr_cb_notify_err(
goto end; goto end;
} }
link = (struct cam_req_mgr_core_link *) link = cam_get_link_priv(err_info->link_hdl);
cam_get_device_priv(err_info->link_hdl);
if (!link) { if (!link) {
CAM_DBG(CAM_CRM, "link ptr NULL %x", err_info->link_hdl); CAM_DBG(CAM_CRM, "link ptr NULL %x", err_info->link_hdl);
rc = -EINVAL; rc = -EINVAL;
@@ -2820,8 +2817,7 @@ static int cam_req_mgr_cb_notify_timer(
goto end; goto end;
} }
link = (struct cam_req_mgr_core_link *) link = cam_get_link_priv(timer_data->link_hdl);
cam_get_device_priv(timer_data->link_hdl);
if (!link) { if (!link) {
CAM_DBG(CAM_CRM, "link ptr NULL %x", timer_data->link_hdl); CAM_DBG(CAM_CRM, "link ptr NULL %x", timer_data->link_hdl);
rc = -EINVAL; rc = -EINVAL;
@@ -2867,8 +2863,7 @@ static int cam_req_mgr_cb_notify_stop(
goto end; goto end;
} }
link = (struct cam_req_mgr_core_link *) link = cam_get_link_priv(stop_info->link_hdl);
cam_get_device_priv(stop_info->link_hdl);
if (!link) { if (!link) {
CAM_DBG(CAM_CRM, "link ptr NULL %x", stop_info->link_hdl); CAM_DBG(CAM_CRM, "link ptr NULL %x", stop_info->link_hdl);
rc = -EINVAL; rc = -EINVAL;
@@ -2929,8 +2924,7 @@ static int cam_req_mgr_cb_notify_trigger(
goto end; goto end;
} }
link = (struct cam_req_mgr_core_link *) link = cam_get_link_priv(trigger_data->link_hdl);
cam_get_device_priv(trigger_data->link_hdl);
if (!link) { if (!link) {
CAM_DBG(CAM_CRM, "link ptr NULL %x", trigger_data->link_hdl); CAM_DBG(CAM_CRM, "link ptr NULL %x", trigger_data->link_hdl);
rc = -EINVAL; rc = -EINVAL;
@@ -3245,7 +3239,7 @@ static int __cam_req_mgr_unlink(struct cam_req_mgr_core_link *link)
__cam_req_mgr_destroy_subdev(&link->l_dev); __cam_req_mgr_destroy_subdev(&link->l_dev);
/* Destroy the link handle */ /* Destroy the link handle */
rc = cam_destroy_device_hdl(link->link_hdl); rc = cam_destroy_link_hdl(link->link_hdl);
if (rc < 0) { if (rc < 0) {
CAM_ERR(CAM_CRM, "error destroying link hdl %x rc %d", CAM_ERR(CAM_CRM, "error destroying link hdl %x rc %d",
link->link_hdl, rc); link->link_hdl, rc);
@@ -3271,11 +3265,9 @@ int cam_req_mgr_destroy_session(
} }
mutex_lock(&g_crm_core_dev->crm_lock); mutex_lock(&g_crm_core_dev->crm_lock);
cam_session = (struct cam_req_mgr_core_session *) cam_session = cam_get_session_priv(ses_info->session_hdl);
cam_get_device_priv(ses_info->session_hdl); if (!cam_session || (cam_session->session_hdl != ses_info->session_hdl)) {
if (!cam_session || CAM_ERR(CAM_CRM, "session: %s, ses_info->ses_hdl:%x, session->ses_hdl:%x",
(cam_session->session_hdl != ses_info->session_hdl)) {
CAM_ERR(CAM_CRM, "ses:%s ses_info->ses_hdl:%x ses->ses_hdl:%x",
CAM_IS_NULL_TO_STR(cam_session), ses_info->session_hdl, CAM_IS_NULL_TO_STR(cam_session), ses_info->session_hdl,
(!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : (!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL :
cam_session->session_hdl); cam_session->session_hdl);
@@ -3336,15 +3328,11 @@ int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info)
mutex_lock(&g_crm_core_dev->crm_lock); mutex_lock(&g_crm_core_dev->crm_lock);
/* session hdl's priv data is cam session struct */ /* session hdl's priv data is cam session struct */
cam_session = (struct cam_req_mgr_core_session *) cam_session = cam_get_session_priv(link_info->u.link_info_v1.session_hdl);
cam_get_device_priv(link_info->u.link_info_v1.session_hdl); if (!cam_session || (cam_session->session_hdl != link_info->u.link_info_v1.session_hdl)) {
if (!cam_session || (cam_session->session_hdl != CAM_ERR(CAM_CRM, "session: %s, link_info->ses_hdl:%x, session->ses_hdl:%x",
link_info->u.link_info_v1.session_hdl)) { CAM_IS_NULL_TO_STR(cam_session), link_info->u.link_info_v1.session_hdl,
CAM_ERR(CAM_CRM, "ses:%s lnk_info->ses_hdl:%x ses->ses_hdl:%x", (!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl);
CAM_IS_NULL_TO_STR(cam_session),
link_info->u.link_info_v1.session_hdl,
(!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL :
cam_session->session_hdl);
mutex_unlock(&g_crm_core_dev->crm_lock); mutex_unlock(&g_crm_core_dev->crm_lock);
return -EINVAL; return -EINVAL;
} }
@@ -3363,8 +3351,8 @@ int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info)
root_dev.priv = (void *)link; root_dev.priv = (void *)link;
root_dev.dev_id = CAM_CRM; root_dev.dev_id = CAM_CRM;
mutex_lock(&link->lock); mutex_lock(&link->lock);
/* Create unique dev handle for link */ /* Create unique handle for link */
link->link_hdl = cam_create_device_hdl(&root_dev); link->link_hdl = cam_create_link_hdl(&root_dev);
if (link->link_hdl < 0) { if (link->link_hdl < 0) {
CAM_ERR(CAM_CRM, CAM_ERR(CAM_CRM,
"Insufficient memory to create new device handle"); "Insufficient memory to create new device handle");
@@ -3418,7 +3406,7 @@ int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info)
setup_failed: setup_failed:
__cam_req_mgr_destroy_subdev(&link->l_dev); __cam_req_mgr_destroy_subdev(&link->l_dev);
create_subdev_failed: create_subdev_failed:
cam_destroy_device_hdl(link->link_hdl); cam_destroy_link_hdl(link->link_hdl);
link_info->u.link_info_v1.link_hdl = -1; link_info->u.link_info_v1.link_hdl = -1;
link_hdl_fail: link_hdl_fail:
mutex_unlock(&link->lock); mutex_unlock(&link->lock);
@@ -3450,15 +3438,11 @@ int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info)
mutex_lock(&g_crm_core_dev->crm_lock); mutex_lock(&g_crm_core_dev->crm_lock);
/* session hdl's priv data is cam session struct */ /* session hdl's priv data is cam session struct */
cam_session = (struct cam_req_mgr_core_session *) cam_session = cam_get_session_priv(link_info->u.link_info_v2.session_hdl);
cam_get_device_priv(link_info->u.link_info_v2.session_hdl); if (!cam_session || (cam_session->session_hdl != link_info->u.link_info_v2.session_hdl)) {
if (!cam_session || (cam_session->session_hdl != CAM_ERR(CAM_CRM, "session: %s, link_info->ses_hdl:%x, session->ses_hdl:%x",
link_info->u.link_info_v2.session_hdl)) { CAM_IS_NULL_TO_STR(cam_session), link_info->u.link_info_v2.session_hdl,
CAM_ERR(CAM_CRM, "ses:%s lnk_info->ses_hdl:%x ses->ses_hdl:%x", (!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl);
CAM_IS_NULL_TO_STR(cam_session),
link_info->u.link_info_v2.session_hdl,
(!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL :
cam_session->session_hdl);
mutex_unlock(&g_crm_core_dev->crm_lock); mutex_unlock(&g_crm_core_dev->crm_lock);
return -EINVAL; return -EINVAL;
} }
@@ -3478,8 +3462,8 @@ int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info)
root_dev.dev_id = CAM_CRM; root_dev.dev_id = CAM_CRM;
mutex_lock(&link->lock); mutex_lock(&link->lock);
/* Create unique dev handle for link */ /* Create unique handle for link */
link->link_hdl = cam_create_device_hdl(&root_dev); link->link_hdl = cam_create_link_hdl(&root_dev);
if (link->link_hdl < 0) { if (link->link_hdl < 0) {
CAM_ERR(CAM_CRM, CAM_ERR(CAM_CRM,
"Insufficient memory to create new device handle"); "Insufficient memory to create new device handle");
@@ -3533,7 +3517,7 @@ int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info)
setup_failed: setup_failed:
__cam_req_mgr_destroy_subdev(&link->l_dev); __cam_req_mgr_destroy_subdev(&link->l_dev);
create_subdev_failed: create_subdev_failed:
cam_destroy_device_hdl(link->link_hdl); cam_destroy_link_hdl(link->link_hdl);
link_info->u.link_info_v2.link_hdl = -1; link_info->u.link_info_v2.link_hdl = -1;
link_hdl_fail: link_hdl_fail:
mutex_unlock(&link->lock); mutex_unlock(&link->lock);
@@ -3558,21 +3542,17 @@ int cam_req_mgr_unlink(struct cam_req_mgr_unlink_info *unlink_info)
CAM_DBG(CAM_CRM, "link_hdl %x", unlink_info->link_hdl); CAM_DBG(CAM_CRM, "link_hdl %x", unlink_info->link_hdl);
/* session hdl's priv data is cam session struct */ /* session hdl's priv data is cam session struct */
cam_session = (struct cam_req_mgr_core_session *) cam_session = cam_get_session_priv(unlink_info->session_hdl);
cam_get_device_priv(unlink_info->session_hdl); if (!cam_session || (cam_session->session_hdl != unlink_info->session_hdl)) {
if (!cam_session || (cam_session->session_hdl != CAM_ERR(CAM_CRM, "session: %s, unlink_info->ses_hdl:%x, cam_session->ses_hdl:%x",
unlink_info->session_hdl)) { CAM_IS_NULL_TO_STR(cam_session), unlink_info->session_hdl,
CAM_ERR(CAM_CRM, "ses:%s unlink->ses_hdl:%x ses->ses_hdl:%x", (!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl);
CAM_IS_NULL_TO_STR(cam_session),
unlink_info->session_hdl,
(!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL :
cam_session->session_hdl);
mutex_unlock(&g_crm_core_dev->crm_lock); mutex_unlock(&g_crm_core_dev->crm_lock);
return -EINVAL; return -EINVAL;
} }
/* link hdl's priv data is core_link struct */ /* link hdl's priv data is core_link struct */
link = cam_get_device_priv(unlink_info->link_hdl); link = cam_get_link_priv(unlink_info->link_hdl);
if (!link || (link->link_hdl != unlink_info->link_hdl)) { if (!link || (link->link_hdl != unlink_info->link_hdl)) {
CAM_ERR(CAM_CRM, "link:%s unlink->lnk_hdl:%x link->lnk_hdl:%x", CAM_ERR(CAM_CRM, "link:%s unlink->lnk_hdl:%x link->lnk_hdl:%x",
CAM_IS_NULL_TO_STR(link), unlink_info->link_hdl, CAM_IS_NULL_TO_STR(link), unlink_info->link_hdl,
@@ -3606,8 +3586,7 @@ int cam_req_mgr_schedule_request(
} }
mutex_lock(&g_crm_core_dev->crm_lock); mutex_lock(&g_crm_core_dev->crm_lock);
link = (struct cam_req_mgr_core_link *) link = cam_get_link_priv(sched_req->link_hdl);
cam_get_device_priv(sched_req->link_hdl);
if (!link || (link->link_hdl != sched_req->link_hdl)) { if (!link || (link->link_hdl != sched_req->link_hdl)) {
CAM_ERR(CAM_CRM, "link:%s sched->lnk_hdl:%x link->lnk_hdl:%x", CAM_ERR(CAM_CRM, "link:%s sched->lnk_hdl:%x link->lnk_hdl:%x",
CAM_IS_NULL_TO_STR(link), sched_req->link_hdl, CAM_IS_NULL_TO_STR(link), sched_req->link_hdl,
@@ -3720,11 +3699,9 @@ int cam_req_mgr_sync_config(
mutex_lock(&g_crm_core_dev->crm_lock); mutex_lock(&g_crm_core_dev->crm_lock);
/* session hdl's priv data is cam session struct */ /* session hdl's priv data is cam session struct */
cam_session = (struct cam_req_mgr_core_session *) cam_session = cam_get_session_priv(sync_info->session_hdl);
cam_get_device_priv(sync_info->session_hdl); if (!cam_session || (cam_session->session_hdl != sync_info->session_hdl)) {
if (!cam_session || CAM_ERR(CAM_CRM, "session: %s, sync_info->session_hdl:%x, session->ses_hdl:%x",
(cam_session->session_hdl != sync_info->session_hdl)) {
CAM_ERR(CAM_CRM, "ses:%s sync_info->ses_hdl:%x ses->ses_hdl:%x",
CAM_IS_NULL_TO_STR(cam_session), sync_info->session_hdl, CAM_IS_NULL_TO_STR(cam_session), sync_info->session_hdl,
(!cam_session) ? (!cam_session) ?
CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl); CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl);
@@ -3738,7 +3715,7 @@ int cam_req_mgr_sync_config(
sync_info->link_hdls[0], sync_info->link_hdls[1]); sync_info->link_hdls[0], sync_info->link_hdls[1]);
/* only two links existing per session in dual cam use case*/ /* only two links existing per session in dual cam use case*/
link1 = cam_get_device_priv(sync_info->link_hdls[0]); link1 = cam_get_link_priv(sync_info->link_hdls[0]);
if (!link1 || (link1->link_hdl != sync_info->link_hdls[0])) { if (!link1 || (link1->link_hdl != sync_info->link_hdls[0])) {
CAM_ERR(CAM_CRM, "lnk:%s sync_info->lnk_hdl[0]:%x lnk1_hdl:%x", CAM_ERR(CAM_CRM, "lnk:%s sync_info->lnk_hdl[0]:%x lnk1_hdl:%x",
CAM_IS_NULL_TO_STR(link1), sync_info->link_hdls[0], CAM_IS_NULL_TO_STR(link1), sync_info->link_hdls[0],
@@ -3748,7 +3725,7 @@ int cam_req_mgr_sync_config(
goto done; goto done;
} }
link2 = cam_get_device_priv(sync_info->link_hdls[1]); link2 = cam_get_link_priv(sync_info->link_hdls[1]);
if (!link2 || (link2->link_hdl != sync_info->link_hdls[1])) { if (!link2 || (link2->link_hdl != sync_info->link_hdls[1])) {
CAM_ERR(CAM_CRM, "lnk:%s sync_info->lnk_hdl[1]:%x lnk2_hdl:%x", CAM_ERR(CAM_CRM, "lnk:%s sync_info->lnk_hdl[1]:%x lnk2_hdl:%x",
CAM_IS_NULL_TO_STR(link2), sync_info->link_hdls[1], CAM_IS_NULL_TO_STR(link2), sync_info->link_hdls[1],
@@ -3820,9 +3797,9 @@ int cam_req_mgr_flush_requests(
} }
mutex_lock(&g_crm_core_dev->crm_lock); mutex_lock(&g_crm_core_dev->crm_lock);
/* session hdl's priv data is cam session struct */ /* session hdl's priv data is cam session struct */
session = (struct cam_req_mgr_core_session *) session = cam_get_session_priv(flush_info->session_hdl);
cam_get_device_priv(flush_info->session_hdl);
if (!session || (session->session_hdl != flush_info->session_hdl)) { if (!session || (session->session_hdl != flush_info->session_hdl)) {
CAM_ERR(CAM_CRM, "ses:%s flush->ses_hdl:%x ses->ses_hdl:%x", CAM_ERR(CAM_CRM, "ses:%s flush->ses_hdl:%x ses->ses_hdl:%x",
CAM_IS_NULL_TO_STR(session), flush_info->session_hdl, CAM_IS_NULL_TO_STR(session), flush_info->session_hdl,
@@ -3837,8 +3814,7 @@ int cam_req_mgr_flush_requests(
goto end; goto end;
} }
link = (struct cam_req_mgr_core_link *) link = cam_get_link_priv(flush_info->link_hdl);
cam_get_device_priv(flush_info->link_hdl);
if (!link || (link->link_hdl != flush_info->link_hdl)) { if (!link || (link->link_hdl != flush_info->link_hdl)) {
CAM_ERR(CAM_CRM, "link:%s flush->link_hdl:%x link->link_hdl:%x", CAM_ERR(CAM_CRM, "link:%s flush->link_hdl:%x link->link_hdl:%x",
CAM_IS_NULL_TO_STR(link), flush_info->link_hdl, CAM_IS_NULL_TO_STR(link), flush_info->link_hdl,
@@ -3897,8 +3873,7 @@ int cam_req_mgr_link_control(struct cam_req_mgr_link_control *control)
mutex_lock(&g_crm_core_dev->crm_lock); mutex_lock(&g_crm_core_dev->crm_lock);
for (i = 0; i < control->num_links; i++) { for (i = 0; i < control->num_links; i++) {
link = (struct cam_req_mgr_core_link *) link = cam_get_link_priv(control->link_hdls[i]);
cam_get_device_priv(control->link_hdls[i]);
if (!link || (link->link_hdl != control->link_hdls[i])) { if (!link || (link->link_hdl != control->link_hdls[i])) {
CAM_ERR(CAM_CRM, CAM_ERR(CAM_CRM,
"link:%s control->lnk_hdl:%x link->lnk_hdl:%x", "link:%s control->lnk_hdl:%x link->lnk_hdl:%x",
@@ -3977,8 +3952,7 @@ int cam_req_mgr_dump_request(struct cam_dump_req_cmd *dump_req)
mutex_lock(&g_crm_core_dev->crm_lock); mutex_lock(&g_crm_core_dev->crm_lock);
/* session hdl's priv data is cam session struct */ /* session hdl's priv data is cam session struct */
session = (struct cam_req_mgr_core_session *) session = cam_get_session_priv(dump_req->session_handle);
cam_get_device_priv(dump_req->session_handle);
if (!session || (session->session_hdl != dump_req->session_handle)) { if (!session || (session->session_hdl != dump_req->session_handle)) {
CAM_ERR(CAM_CRM, "ses:%s dump_req->ses_hdl:%x ses->ses_hdl:%x", CAM_ERR(CAM_CRM, "ses:%s dump_req->ses_hdl:%x ses->ses_hdl:%x",
CAM_IS_NULL_TO_STR(session), dump_req->session_handle, CAM_IS_NULL_TO_STR(session), dump_req->session_handle,
@@ -3993,8 +3967,7 @@ int cam_req_mgr_dump_request(struct cam_dump_req_cmd *dump_req)
goto end; goto end;
} }
link = (struct cam_req_mgr_core_link *) link = cam_get_link_priv(dump_req->link_hdl);
cam_get_device_priv(dump_req->link_hdl);
if (!link || (link->link_hdl != dump_req->link_hdl)) { if (!link || (link->link_hdl != dump_req->link_hdl)) {
CAM_ERR(CAM_CRM, "link:%s dump_rq->lnk_hdl:%x link->lnk_hdl:%x", CAM_ERR(CAM_CRM, "link:%s dump_rq->lnk_hdl:%x link->lnk_hdl:%x",
CAM_IS_NULL_TO_STR(link), dump_req->link_hdl, CAM_IS_NULL_TO_STR(link), dump_req->link_hdl,

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#define pr_fmt(fmt) "CAM-REQ-MGR_UTIL %s:%d " fmt, __func__, __LINE__ #define pr_fmt(fmt) "CAM-REQ-MGR_UTIL %s:%d " fmt, __func__, __LINE__
@@ -36,28 +37,29 @@ int cam_req_mgr_util_init(void)
rc = -ENOMEM; rc = -ENOMEM;
goto hdl_tbl_alloc_failed; goto hdl_tbl_alloc_failed;
} }
bitmap_size = BITS_TO_LONGS(CAM_REQ_MGR_MAX_HANDLES_V2) * sizeof(long);
hdl_tbl_local->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
if (!hdl_tbl_local->bitmap) {
rc = -ENOMEM;
goto bitmap_alloc_fail;
}
hdl_tbl_local->bits = bitmap_size * BITS_PER_BYTE;
spin_lock_bh(&hdl_tbl_lock); spin_lock_bh(&hdl_tbl_lock);
if (hdl_tbl) { if (hdl_tbl) {
spin_unlock_bh(&hdl_tbl_lock); spin_unlock_bh(&hdl_tbl_lock);
rc = -EEXIST; rc = -EEXIST;
kfree(hdl_tbl_local->bitmap);
kfree(hdl_tbl_local); kfree(hdl_tbl_local);
goto hdl_tbl_check_failed; goto hdl_tbl_check_failed;
} }
hdl_tbl = hdl_tbl_local; hdl_tbl = hdl_tbl_local;
spin_unlock_bh(&hdl_tbl_lock); spin_unlock_bh(&hdl_tbl_lock);
bitmap_size = BITS_TO_LONGS(CAM_REQ_MGR_MAX_HANDLES_V2) * sizeof(long);
hdl_tbl->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
if (!hdl_tbl->bitmap) {
rc = -ENOMEM;
goto bitmap_alloc_fail;
}
hdl_tbl->bits = bitmap_size * BITS_PER_BYTE;
return rc; return rc;
bitmap_alloc_fail: bitmap_alloc_fail:
kfree(hdl_tbl); kfree(hdl_tbl_local);
hdl_tbl = NULL; hdl_tbl = NULL;
hdl_tbl_alloc_failed: hdl_tbl_alloc_failed:
hdl_tbl_check_failed: hdl_tbl_check_failed:
@@ -124,6 +126,18 @@ static int32_t cam_get_free_handle_index(void)
return idx; return idx;
} }
static void cam_dump_tbl_info(void)
{
int i;
for (i = 0; i < CAM_REQ_MGR_MAX_HANDLES_V2; i++)
CAM_INFO_RATE_LIMIT_CUSTOM(CAM_CRM, CAM_RATE_LIMIT_INTERVAL_5SEC,
CAM_REQ_MGR_MAX_HANDLES_V2,
"session_hdl=%x hdl_value=%x type=%d state=%d dev_id=%lld",
hdl_tbl->hdl[i].session_hdl, hdl_tbl->hdl[i].hdl_value,
hdl_tbl->hdl[i].type, hdl_tbl->hdl[i].state, hdl_tbl->hdl[i].dev_id);
}
int32_t cam_create_session_hdl(void *priv) int32_t cam_create_session_hdl(void *priv)
{ {
int idx; int idx;
@@ -139,7 +153,8 @@ int32_t cam_create_session_hdl(void *priv)
idx = cam_get_free_handle_index(); idx = cam_get_free_handle_index();
if (idx < 0) { if (idx < 0) {
CAM_ERR(CAM_CRM, "Unable to create session handle"); CAM_ERR(CAM_CRM, "Unable to create session handle(idx = %d)", idx);
cam_dump_tbl_info();
spin_unlock_bh(&hdl_tbl_lock); spin_unlock_bh(&hdl_tbl_lock);
return idx; return idx;
} }
@@ -181,8 +196,8 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data)
idx = cam_get_free_handle_index(); idx = cam_get_free_handle_index();
if (idx < 0) { if (idx < 0) {
CAM_ERR(CAM_CRM, CAM_ERR(CAM_CRM, "Unable to create device handle(idx= %d)", idx);
"Unable to create device handle(idx= %d)", idx); cam_dump_tbl_info();
spin_unlock_bh(&hdl_tbl_lock); spin_unlock_bh(&hdl_tbl_lock);
return idx; return idx;
} }
@@ -202,7 +217,43 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data)
return handle; return handle;
} }
void *cam_get_device_priv(int32_t dev_hdl) int32_t cam_create_link_hdl(struct cam_create_dev_hdl *hdl_data)
{
int idx;
int rand = 0;
int32_t handle;
spin_lock_bh(&hdl_tbl_lock);
if (!hdl_tbl) {
CAM_ERR(CAM_CRM, "Hdl tbl is NULL");
spin_unlock_bh(&hdl_tbl_lock);
return -EINVAL;
}
idx = cam_get_free_handle_index();
if (idx < 0) {
CAM_ERR(CAM_CRM, "Unable to create link handle(idx = %d)", idx);
cam_dump_tbl_info();
spin_unlock_bh(&hdl_tbl_lock);
return idx;
}
get_random_bytes(&rand, CAM_REQ_MGR_RND1_BYTES);
handle = GET_DEV_HANDLE(rand, HDL_TYPE_LINK, idx);
hdl_tbl->hdl[idx].session_hdl = hdl_data->session_hdl;
hdl_tbl->hdl[idx].hdl_value = handle;
hdl_tbl->hdl[idx].type = HDL_TYPE_LINK;
hdl_tbl->hdl[idx].state = HDL_ACTIVE;
hdl_tbl->hdl[idx].priv = hdl_data->priv;
hdl_tbl->hdl[idx].ops = NULL;
hdl_tbl->hdl[idx].dev_id = hdl_data->dev_id;
spin_unlock_bh(&hdl_tbl_lock);
CAM_DBG(CAM_CRM, "handle = %x", handle);
return handle;
}
void *cam_get_priv(int32_t dev_hdl, int handle_type)
{ {
int idx; int idx;
int type; int type;
@@ -216,18 +267,18 @@ void *cam_get_device_priv(int32_t dev_hdl)
idx = CAM_REQ_MGR_GET_HDL_IDX(dev_hdl); idx = CAM_REQ_MGR_GET_HDL_IDX(dev_hdl);
if (idx >= CAM_REQ_MGR_MAX_HANDLES_V2) { if (idx >= CAM_REQ_MGR_MAX_HANDLES_V2) {
CAM_ERR_RATE_LIMIT(CAM_CRM, "Invalid idx"); CAM_ERR_RATE_LIMIT(CAM_CRM, "Invalid idx: %d", idx);
goto device_priv_fail; goto device_priv_fail;
} }
if (hdl_tbl->hdl[idx].state != HDL_ACTIVE) { if (hdl_tbl->hdl[idx].state != HDL_ACTIVE) {
CAM_ERR_RATE_LIMIT(CAM_CRM, "Invalid state"); CAM_ERR_RATE_LIMIT(CAM_CRM, "Invalid state: %d", hdl_tbl->hdl[idx].state);
goto device_priv_fail; goto device_priv_fail;
} }
type = CAM_REQ_MGR_GET_HDL_TYPE(dev_hdl); type = CAM_REQ_MGR_GET_HDL_TYPE(dev_hdl);
if (HDL_TYPE_DEV != type && HDL_TYPE_SESSION != type) { if (type != handle_type) {
CAM_ERR_RATE_LIMIT(CAM_CRM, "Invalid type"); CAM_ERR_RATE_LIMIT(CAM_CRM, "Invalid type:%d", type);
goto device_priv_fail; goto device_priv_fail;
} }
@@ -246,6 +297,34 @@ void *cam_get_device_priv(int32_t dev_hdl)
return NULL; return NULL;
} }
void *cam_get_device_priv(int32_t dev_hdl)
{
void *priv;
priv = cam_get_priv(dev_hdl, HDL_TYPE_DEV);
return priv;
}
struct cam_req_mgr_core_session *cam_get_session_priv(int32_t dev_hdl)
{
struct cam_req_mgr_core_session *priv;
priv = (struct cam_req_mgr_core_session *)
cam_get_priv(dev_hdl, HDL_TYPE_SESSION);
return priv;
}
struct cam_req_mgr_core_link *cam_get_link_priv(int32_t dev_hdl)
{
struct cam_req_mgr_core_link *priv;
priv = (struct cam_req_mgr_core_link *)
cam_get_priv(dev_hdl, HDL_TYPE_LINK);
return priv;
}
void *cam_get_device_ops(int32_t dev_hdl) void *cam_get_device_ops(int32_t dev_hdl)
{ {
int idx; int idx;
@@ -270,7 +349,7 @@ void *cam_get_device_ops(int32_t dev_hdl)
} }
type = CAM_REQ_MGR_GET_HDL_TYPE(dev_hdl); type = CAM_REQ_MGR_GET_HDL_TYPE(dev_hdl);
if (HDL_TYPE_DEV != type && HDL_TYPE_SESSION != type) { if (HDL_TYPE_DEV != type && HDL_TYPE_SESSION != type && HDL_TYPE_LINK != type) {
CAM_ERR(CAM_CRM, "Invalid type"); CAM_ERR(CAM_CRM, "Invalid type");
goto device_ops_fail; goto device_ops_fail;
} }
@@ -341,6 +420,12 @@ int cam_destroy_device_hdl(int32_t dev_hdl)
return cam_destroy_hdl(dev_hdl, HDL_TYPE_DEV); return cam_destroy_hdl(dev_hdl, HDL_TYPE_DEV);
} }
int cam_destroy_link_hdl(int32_t dev_hdl)
{
CAM_DBG(CAM_CRM, "handle = %x", dev_hdl);
return cam_destroy_hdl(dev_hdl, HDL_TYPE_LINK);
}
int cam_destroy_session_hdl(int32_t dev_hdl) int cam_destroy_session_hdl(int32_t dev_hdl)
{ {
return cam_destroy_hdl(dev_hdl, HDL_TYPE_SESSION); return cam_destroy_hdl(dev_hdl, HDL_TYPE_SESSION);

View File

@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#ifndef _CAM_REQ_MGR_UTIL_API_H_ #ifndef _CAM_REQ_MGR_UTIL_API_H_
@@ -9,6 +10,9 @@
#include <media/cam_req_mgr.h> #include <media/cam_req_mgr.h>
#include "cam_req_mgr_util_priv.h" #include "cam_req_mgr_util_priv.h"
/* Interval for cam_info_rate_limit_custom() */
#define CAM_RATE_LIMIT_INTERVAL_5SEC 5
/** /**
* state of a handle(session/device) * state of a handle(session/device)
* @HDL_FREE: free handle * @HDL_FREE: free handle
@@ -21,12 +25,14 @@ enum hdl_state {
/** /**
* handle type * handle type
* @HDL_TYPE_DEV: for device and link * @HDL_TYPE_DEV: for device
* @HDL_TYPE_SESSION: for session * @HDL_TYPE_SESSION: for session
* @HDL_TYPE_LINK: for link
*/ */
enum hdl_type { enum hdl_type {
HDL_TYPE_DEV = 1, HDL_TYPE_DEV = 1,
HDL_TYPE_SESSION HDL_TYPE_SESSION,
HDL_TYPE_LINK
}; };
/** /**
@@ -103,8 +109,19 @@ int32_t cam_create_session_hdl(void *priv);
int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data); int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data);
/** /**
* cam_get_device_priv() - get private data of a handle * cam_create_link_hdl() - create a link handle
* @dev_hdl: handle for a session/link/device * @hdl_data: session hdl, flags, ops and priv dara as input
*
* cam_req_mgr_core calls this function to get
* session and link handles
* KMD drivers calls this function to create
* a link handle. Returns a unique link handle
*/
int32_t cam_create_link_hdl(struct cam_create_dev_hdl *hdl_data);
/**
* cam_get_device_priv() - get private data of a device handle
* @dev_hdl: handle for a device
* *
* cam_req_mgr_core and KMD drivers use this function to * cam_req_mgr_core and KMD drivers use this function to
* get private data of a handle. Returns a private data * get private data of a handle. Returns a private data
@@ -112,6 +129,26 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data);
*/ */
void *cam_get_device_priv(int32_t dev_hdl); void *cam_get_device_priv(int32_t dev_hdl);
/**
* cam_get_session_priv() - get private data of a session handle
* @dev_hdl: handle for a session
*
* cam_req_mgr_core and KMD drivers use this function to
* get private data of a handle. Returns a private data
* structure pointer.
*/
struct cam_req_mgr_core_session *cam_get_session_priv(int32_t dev_hdl);
/**
* cam_get_link_priv() - get private data of a link handle
* @dev_hdl: handle for a link
*
* cam_req_mgr_core and KMD drivers use this function to
* get private data of a handle. Returns a private data
* structure pointer.
*/
struct cam_req_mgr_core_link *cam_get_link_priv(int32_t dev_hdl);
/** /**
* cam_get_device_ops() - get ops of a handle * cam_get_device_ops() - get ops of a handle
* @dev_hdl: handle for a session/link/device * @dev_hdl: handle for a session/link/device
@@ -123,12 +160,20 @@ void *cam_get_device_ops(int32_t dev_hdl);
/** /**
* cam_destroy_device_hdl() - destroy device handle * cam_destroy_device_hdl() - destroy device handle
* @dev_hdl: handle for a link/device. * @dev_hdl: handle for a device.
* *
* Returns success/failure * Returns success/failure
*/ */
int32_t cam_destroy_device_hdl(int32_t dev_hdl); int32_t cam_destroy_device_hdl(int32_t dev_hdl);
/**
* cam_destroy_link_hdl() - destroy link handle
* @dev_hdl: handle for a link.
*
* Returns success/failure
*/
int32_t cam_destroy_link_hdl(int32_t dev_hdl);
/** /**
* cam_destroy_session_hdl() - destroy device handle * cam_destroy_session_hdl() - destroy device handle
* @dev_hdl: handle for a session * @dev_hdl: handle for a session

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/module.h> #include <linux/module.h>
@@ -563,6 +564,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
} }
break; break;
} }
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
} }
if (a_ctrl->cam_act_state == CAM_ACTUATOR_ACQUIRE) { if (a_ctrl->cam_act_state == CAM_ACTUATOR_ACQUIRE) {
@@ -732,6 +734,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
} }
end: end:
cam_mem_put_cpu_buf(config.packet_handle);
return rc; return rc;
} }

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/module.h> #include <linux/module.h>
@@ -294,7 +295,10 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
csiphy_dev->csiphy_info.settle_time, csiphy_dev->csiphy_info.settle_time,
csiphy_dev->csiphy_info.data_rate); csiphy_dev->csiphy_info.data_rate);
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
cam_mem_put_cpu_buf(cfg_dev->packet_handle);
return rc; return rc;
} }
void cam_csiphy_cphy_irq_config(struct csiphy_device *csiphy_dev) void cam_csiphy_cphy_irq_config(struct csiphy_device *csiphy_dev)

View File

@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/module.h> #include <linux/module.h>
@@ -892,9 +892,12 @@ static int32_t cam_eeprom_parse_write_memory_packet(
break; break;
} }
} }
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
} }
return rc;
end: end:
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
return rc; return rc;
} }
@@ -1051,9 +1054,12 @@ static int32_t cam_eeprom_init_pkt_parser(struct cam_eeprom_ctrl_t *e_ctrl,
} }
} }
e_ctrl->cal_data.num_map = num_map + 1; e_ctrl->cal_data.num_map = num_map + 1;
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
} }
return rc;
end: end:
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
return rc; return rc;
} }
@@ -1123,6 +1129,7 @@ static int32_t cam_eeprom_get_cal_data(struct cam_eeprom_ctrl_t *e_ctrl,
e_ctrl->cal_data.num_data); e_ctrl->cal_data.num_data);
memcpy(read_buffer, e_ctrl->cal_data.mapdata, memcpy(read_buffer, e_ctrl->cal_data.mapdata,
e_ctrl->cal_data.num_data); e_ctrl->cal_data.num_data);
cam_mem_put_cpu_buf(io_cfg->mem_handle[0]);
} else { } else {
CAM_ERR(CAM_EEPROM, "Invalid direction"); CAM_ERR(CAM_EEPROM, "Invalid direction");
rc = -EINVAL; rc = -EINVAL;
@@ -1371,6 +1378,7 @@ static int32_t cam_eeprom_pkt_parse(struct cam_eeprom_ctrl_t *e_ctrl, void *arg)
break; break;
} }
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc; return rc;
power_down: power_down:
cam_eeprom_power_down(e_ctrl); cam_eeprom_power_down(e_ctrl);

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/module.h> #include <linux/module.h>
@@ -1187,6 +1188,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
break; break;
} }
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
} }
power_info = &fctrl->power_info; power_info = &fctrl->power_info;
if (!power_info) { if (!power_info) {
@@ -1377,6 +1379,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
fctrl->bridge_intf.crm_cb->add_req(&add_req); fctrl->bridge_intf.crm_cb->add_req(&add_req);
CAM_DBG(CAM_FLASH, "add req to req_mgr= %lld", add_req.req_id); CAM_DBG(CAM_FLASH, "add req to req_mgr= %lld", add_req.req_id);
} }
cam_mem_put_cpu_buf(config.packet_handle);
return rc; return rc;
} }
@@ -1560,6 +1563,8 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
rc = -EINVAL; rc = -EINVAL;
return rc; return rc;
} }
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
break; break;
} }
case CAM_FLASH_PACKET_OPCODE_SET_OPS: { case CAM_FLASH_PACKET_OPCODE_SET_OPS: {
@@ -1654,6 +1659,8 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
rc = -EINVAL; rc = -EINVAL;
return rc; return rc;
} }
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
break; break;
} }
case CAM_FLASH_PACKET_OPCODE_NON_REALTIME_SET_OPS: { case CAM_FLASH_PACKET_OPCODE_NON_REALTIME_SET_OPS: {
@@ -1803,6 +1810,7 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
return rc; return rc;
} }
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
break; break;
} }
case CAM_PKT_NOP_OPCODE: { case CAM_PKT_NOP_OPCODE: {
@@ -1851,6 +1859,7 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
CAM_DBG(CAM_FLASH, "add req to req_mgr= %lld", add_req.req_id); CAM_DBG(CAM_FLASH, "add req to req_mgr= %lld", add_req.req_id);
} }
cam_mem_put_cpu_buf(config.packet_handle);
return rc; return rc;
} }

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/module.h> #include <linux/module.h>
@@ -571,6 +572,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
} }
break; break;
} }
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
} }
if (o_ctrl->cam_ois_state != CAM_OIS_CONFIG) { if (o_ctrl->cam_ois_state != CAM_OIS_CONFIG) {
@@ -729,6 +731,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
(csl_packet->header.op_code & 0xFFFFFF)); (csl_packet->header.op_code & 0xFFFFFF));
return -EINVAL; return -EINVAL;
} }
cam_mem_put_cpu_buf(dev_config.packet_handle);
if (!rc) if (!rc)
return rc; return rc;

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023, The Linux Foundation. All rights reserved.
*/ */
#include <linux/module.h> #include <linux/module.h>
@@ -275,6 +276,7 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl,
} }
end: end:
cam_mem_put_cpu_buf(config.packet_handle);
return rc; return rc;
} }
@@ -525,9 +527,11 @@ int32_t cam_handle_mem_ptr(uint64_t handle, struct cam_sensor_ctrl_t *s_ctrl)
"Failed to parse the command Buffer Header"); "Failed to parse the command Buffer Header");
goto end; goto end;
} }
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
} }
end: end:
cam_mem_put_cpu_buf(handle);
return rc; return rc;
} }

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
@@ -274,6 +275,7 @@ static int32_t cam_sensor_get_io_buffer(
io_cfg->direction); io_cfg->direction);
rc = -EINVAL; rc = -EINVAL;
} }
cam_mem_put_cpu_buf(io_cfg->mem_handle[0]);
return rc; return rc;
} }
@@ -721,9 +723,12 @@ int cam_sensor_i2c_command_parser(
} }
} }
i2c_reg_settings->is_settings_valid = 1; i2c_reg_settings->is_settings_valid = 1;
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
} }
return rc;
end: end:
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
return rc; return rc;
} }

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/types.h> #include <linux/types.h>
@@ -127,14 +128,16 @@ int cam_packet_util_get_kmd_buffer(struct cam_packet *packet,
((size_t)cmd_desc->size > (len - (size_t)cmd_desc->offset))) { ((size_t)cmd_desc->size > (len - (size_t)cmd_desc->offset))) {
CAM_ERR(CAM_UTIL, "invalid memory len:%zd and cmd desc size:%d", CAM_ERR(CAM_UTIL, "invalid memory len:%zd and cmd desc size:%d",
len, cmd_desc->size); len, cmd_desc->size);
return -EINVAL; rc = -EINVAL;
goto rel_kmd_buf;
} }
remain_len -= (size_t)cmd_desc->offset; remain_len -= (size_t)cmd_desc->offset;
if ((size_t)packet->kmd_cmd_buf_offset >= remain_len) { if ((size_t)packet->kmd_cmd_buf_offset >= remain_len) {
CAM_ERR(CAM_UTIL, "Invalid kmd cmd buf offset: %zu", CAM_ERR(CAM_UTIL, "Invalid kmd cmd buf offset: %zu",
(size_t)packet->kmd_cmd_buf_offset); (size_t)packet->kmd_cmd_buf_offset);
return -EINVAL; rc = -EINVAL;
goto rel_kmd_buf;
} }
cpu_addr += (cmd_desc->offset / 4) + (packet->kmd_cmd_buf_offset / 4); cpu_addr += (cmd_desc->offset / 4) + (packet->kmd_cmd_buf_offset / 4);
@@ -151,6 +154,8 @@ int cam_packet_util_get_kmd_buffer(struct cam_packet *packet,
kmd_buf->size = cmd_desc->size - cmd_desc->length; kmd_buf->size = cmd_desc->size - cmd_desc->length;
kmd_buf->used_bytes = 0; kmd_buf->used_bytes = 0;
rel_kmd_buf:
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
return rc; return rc;
} }
@@ -207,6 +212,8 @@ void cam_packet_dump_patch_info(struct cam_packet *packet,
if (!(*dst_cpu_addr)) if (!(*dst_cpu_addr))
CAM_ERR(CAM_ICP, "Null at dst addr %p", dst_cpu_addr); CAM_ERR(CAM_ICP, "Null at dst addr %p", dst_cpu_addr);
cam_mem_put_cpu_buf(patch_desc[i].dst_buf_hdl);
} }
} }
@@ -268,6 +275,7 @@ int cam_packet_util_process_patches(struct cam_packet *packet,
(size_t)patch_desc[i].dst_offset)) { (size_t)patch_desc[i].dst_offset)) {
CAM_ERR(CAM_UTIL, CAM_ERR(CAM_UTIL,
"Invalid dst buf patch offset"); "Invalid dst buf patch offset");
cam_mem_put_cpu_buf((int32_t)patch_desc[i].dst_buf_hdl);
return -EINVAL; return -EINVAL;
} }
@@ -281,6 +289,7 @@ int cam_packet_util_process_patches(struct cam_packet *packet,
"patch is done for dst %pK with src %pK value %llx", "patch is done for dst %pK with src %pK value %llx",
dst_cpu_addr, src_buf_iova_addr, dst_cpu_addr, src_buf_iova_addr,
*((uint64_t *)dst_cpu_addr)); *((uint64_t *)dst_cpu_addr));
cam_mem_put_cpu_buf((int32_t)patch_desc[i].dst_buf_hdl);
} }
return rc; return rc;
@@ -321,14 +330,16 @@ int cam_packet_util_process_generic_cmd_buffer(
((size_t)cmd_buf->offset > (buf_size - sizeof(uint32_t)))) { ((size_t)cmd_buf->offset > (buf_size - sizeof(uint32_t)))) {
CAM_ERR(CAM_UTIL, "Invalid offset for cmd buf: %zu", CAM_ERR(CAM_UTIL, "Invalid offset for cmd buf: %zu",
(size_t)cmd_buf->offset); (size_t)cmd_buf->offset);
return -EINVAL; rc = -EINVAL;
goto end;
} }
remain_len -= (size_t)cmd_buf->offset; remain_len -= (size_t)cmd_buf->offset;
if (remain_len < (size_t)cmd_buf->length) { if (remain_len < (size_t)cmd_buf->length) {
CAM_ERR(CAM_UTIL, "Invalid length for cmd buf: %zu", CAM_ERR(CAM_UTIL, "Invalid length for cmd buf: %zu",
(size_t)cmd_buf->length); (size_t)cmd_buf->length);
return -EINVAL; rc = -EINVAL;
goto end;
} }
blob_ptr = (uint32_t *)(((uint8_t *)cpu_addr) + blob_ptr = (uint32_t *)(((uint8_t *)cpu_addr) +
@@ -378,5 +389,6 @@ int cam_packet_util_process_generic_cmd_buffer(
} }
end: end:
cam_mem_put_cpu_buf(cmd_buf->mem_handle);
return rc; return rc;
} }

View File

@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#ifndef _CAM_PACKET_UTIL_H_ #ifndef _CAM_PACKET_UTIL_H_

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/of.h> #include <linux/of.h>
@@ -2021,8 +2022,7 @@ static int cam_soc_util_dump_dmi_reg_range_user_buf(
CAM_ERR(CAM_UTIL, CAM_ERR(CAM_UTIL,
"Invalid input args soc_info: %pK, dump_args: %pK", "Invalid input args soc_info: %pK, dump_args: %pK",
soc_info, dump_args); soc_info, dump_args);
rc = -EINVAL; return -EINVAL;
goto end;
} }
if (dmi_read->num_pre_writes > CAM_REG_DUMP_DMI_CONFIG_MAX || if (dmi_read->num_pre_writes > CAM_REG_DUMP_DMI_CONFIG_MAX ||
@@ -2030,15 +2030,14 @@ static int cam_soc_util_dump_dmi_reg_range_user_buf(
CAM_ERR(CAM_UTIL, CAM_ERR(CAM_UTIL,
"Invalid number of requested writes, pre: %d post: %d", "Invalid number of requested writes, pre: %d post: %d",
dmi_read->num_pre_writes, dmi_read->num_post_writes); dmi_read->num_pre_writes, dmi_read->num_post_writes);
rc = -EINVAL; return -EINVAL;
goto end;
} }
rc = cam_mem_get_cpu_buf(dump_args->buf_handle, &cpu_addr, &buf_len); rc = cam_mem_get_cpu_buf(dump_args->buf_handle, &cpu_addr, &buf_len);
if (rc) { if (rc) {
CAM_ERR(CAM_UTIL, "Invalid handle %u rc %d", CAM_ERR(CAM_UTIL, "Invalid handle %u rc %d",
dump_args->buf_handle, rc); dump_args->buf_handle, rc);
goto end; return -EINVAL;
} }
if (buf_len <= dump_args->offset) { if (buf_len <= dump_args->offset) {
@@ -2124,6 +2123,8 @@ static int cam_soc_util_dump_dmi_reg_range_user_buf(
sizeof(struct cam_hw_soc_dump_header); sizeof(struct cam_hw_soc_dump_header);
end: end:
if (dump_args)
cam_mem_put_cpu_buf(dump_args->buf_handle);
return rc; return rc;
} }
@@ -2148,13 +2149,13 @@ static int cam_soc_util_dump_cont_reg_range_user_buf(
"Invalid input args soc_info: %pK, dump_out_buffer: %pK reg_read: %pK", "Invalid input args soc_info: %pK, dump_out_buffer: %pK reg_read: %pK",
soc_info, dump_args, reg_read); soc_info, dump_args, reg_read);
rc = -EINVAL; rc = -EINVAL;
goto end; return rc;
} }
rc = cam_mem_get_cpu_buf(dump_args->buf_handle, &cpu_addr, &buf_len); rc = cam_mem_get_cpu_buf(dump_args->buf_handle, &cpu_addr, &buf_len);
if (rc) { if (rc) {
CAM_ERR(CAM_UTIL, "Invalid handle %u rc %d", CAM_ERR(CAM_UTIL, "Invalid handle %u rc %d",
dump_args->buf_handle, rc); dump_args->buf_handle, rc);
goto end; return rc;
} }
if (buf_len <= dump_args->offset) { if (buf_len <= dump_args->offset) {
CAM_WARN(CAM_UTIL, "Dump offset overshoot %zu %zu", CAM_WARN(CAM_UTIL, "Dump offset overshoot %zu %zu",
@@ -2204,6 +2205,8 @@ static int cam_soc_util_dump_cont_reg_range_user_buf(
dump_args->offset += hdr->size + dump_args->offset += hdr->size +
sizeof(struct cam_hw_soc_dump_header); sizeof(struct cam_hw_soc_dump_header);
end: end:
if (dump_args)
cam_mem_put_cpu_buf(dump_args->buf_handle);
return rc; return rc;
} }
@@ -2295,6 +2298,8 @@ int cam_soc_util_reg_dump_to_cmd_buf(void *ctx,
if (rc || !cpu_addr || (buf_size == 0)) { if (rc || !cpu_addr || (buf_size == 0)) {
CAM_ERR(CAM_UTIL, "Failed in Get cpu addr, rc=%d, cpu_addr=%pK", CAM_ERR(CAM_UTIL, "Failed in Get cpu addr, rc=%d, cpu_addr=%pK",
rc, (void *)cpu_addr); rc, (void *)cpu_addr);
if (rc)
return rc;
goto end; goto end;
} }
@@ -2496,5 +2501,6 @@ int cam_soc_util_reg_dump_to_cmd_buf(void *ctx,
} }
end: end:
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
return rc; return rc;
} }