mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-25 14:13:01 -04:00
msm: camera: mem_mgr: Add refcount to track in use buffers
The function cam_mem_mgr_release can unmap the buffers when in use. This change prevents unmapping the buffers when in use. CRs-Fixed: 3489559 Change-Id: I2e72e795d39ac15abfa56c19043c419a03686966 Signed-off-by: Shivakumar Malke <quic_smalke@quicinc.com> Signed-off-by: Gaurav Jindal <quic_gjindal@quicinc.com>
This commit is contained in:
parent
217ebc5e61
commit
575f20ea96
21 changed files with 312 additions and 65 deletions
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
|
@ -123,7 +124,7 @@ int cam_virtual_cdm_submit_bl(struct cam_hw_info *cdm_hw,
|
|||
cdm_cmd->cmd[i].len) {
|
||||
CAM_ERR(CAM_CDM, "Not enough buffer");
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
goto end;
|
||||
}
|
||||
CAM_DBG(CAM_CDM,
|
||||
"hdl=%x vaddr=%pK offset=%d cmdlen=%d:%zu",
|
||||
|
|
@ -141,7 +142,7 @@ int cam_virtual_cdm_submit_bl(struct cam_hw_info *cdm_hw,
|
|||
"write failed for cnt=%d:%d len %u",
|
||||
i, req->data->cmd_arrary_count,
|
||||
cdm_cmd->cmd[i].len);
|
||||
break;
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
CAM_ERR(CAM_CDM,
|
||||
|
|
@ -152,7 +153,7 @@ int cam_virtual_cdm_submit_bl(struct cam_hw_info *cdm_hw,
|
|||
"Sanity check failed for cmd_count=%d cnt=%d",
|
||||
i, req->data->cmd_arrary_count);
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
goto end;
|
||||
}
|
||||
if (!rc) {
|
||||
struct cam_cdm_work_payload *payload;
|
||||
|
|
@ -169,7 +170,7 @@ int cam_virtual_cdm_submit_bl(struct cam_hw_info *cdm_hw,
|
|||
GFP_KERNEL);
|
||||
if (!node) {
|
||||
rc = -ENOMEM;
|
||||
break;
|
||||
goto end;
|
||||
}
|
||||
node->request_type = CAM_HW_CDM_BL_CB_CLIENT;
|
||||
node->client_hdl = req->handle;
|
||||
|
|
@ -203,9 +204,20 @@ int cam_virtual_cdm_submit_bl(struct cam_hw_info *cdm_hw,
|
|||
if (!rc && (core->bl_tag == 63))
|
||||
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);
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
|
|
@ -316,6 +317,7 @@ int32_t cam_context_config_dev_to_hw(
|
|||
rc = -EFAULT;
|
||||
}
|
||||
|
||||
cam_mem_put_cpu_buf((int32_t) cmd->packet_handle);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -1109,6 +1111,7 @@ static int cam_context_dump_context(struct cam_context *ctx,
|
|||
if (dump_args->offset >= buf_len) {
|
||||
CAM_WARN(CAM_CTXT, "dump buffer overshoot offset %zu len %zu",
|
||||
dump_args->offset, buf_len);
|
||||
cam_mem_put_cpu_buf(dump_args->buf_handle);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
|
|
@ -1120,6 +1123,7 @@ static int cam_context_dump_context(struct cam_context *ctx,
|
|||
if (remain_len < min_len) {
|
||||
CAM_WARN(CAM_CTXT, "dump buffer exhaust remain %zu min %u",
|
||||
remain_len, min_len);
|
||||
cam_mem_put_cpu_buf(dump_args->buf_handle);
|
||||
return -ENOSPC;
|
||||
}
|
||||
dst = (uint8_t *)cpu_addr + dump_args->offset;
|
||||
|
|
@ -1144,7 +1148,8 @@ static int cam_context_dump_context(struct cam_context *ctx,
|
|||
hdr->size = hdr->word_size * (addr - start);
|
||||
dump_args->offset += hdr->size +
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
|
@ -1275,6 +1276,7 @@ static int cam_custom_mgr_prepare_hw_update(void *hw_mgr_priv,
|
|||
ctx->scratch_buffer_addr = 0x0;
|
||||
prepare_hw_data->num_cfg = 0;
|
||||
cam_custom_add_io_buffers(hw_mgr->img_iommu_hdl, prepare);
|
||||
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* 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>
|
||||
|
|
@ -542,6 +542,33 @@ static int cam_fd_mgr_util_get_buf_map_requirement(uint32_t direction,
|
|||
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,
|
||||
struct cam_hw_prepare_update_args *prepare,
|
||||
struct cam_fd_hw_io_buffer *input_buf,
|
||||
|
|
@ -638,6 +665,7 @@ static int cam_fd_mgr_util_prepare_io_buf_info(int32_t iommu_hdl,
|
|||
"Invalid cpu buf %d %d %d",
|
||||
io_cfg[i].direction,
|
||||
io_cfg[i].resource_type, plane);
|
||||
cam_mem_put_cpu_buf(io_cfg[i].mem_handle[plane];
|
||||
rc = -EINVAL;
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -1619,6 +1647,7 @@ hw_dump:
|
|||
if (fd_dump_args.buf_len <= dump_args->offset) {
|
||||
CAM_WARN(CAM_FD, "dump offset overshoot len %zu offset %zu",
|
||||
fd_dump_args.buf_len, dump_args->offset);
|
||||
cam_mem_put_cpu_buf(dump_args->buf_handle);
|
||||
return -ENOSPC;
|
||||
}
|
||||
remain_len = fd_dump_args.buf_len - dump_args->offset;
|
||||
|
|
@ -1628,6 +1657,7 @@ hw_dump:
|
|||
if (remain_len < min_len) {
|
||||
CAM_WARN(CAM_FD, "dump buffer exhaust remain %zu min %u",
|
||||
remain_len, min_len);
|
||||
cam_mem_put_cpu_buf(dump_args->buf_handle);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
|
|
@ -1659,12 +1689,14 @@ hw_dump:
|
|||
if (rc) {
|
||||
CAM_ERR(CAM_FD, "Hw Dump cmd fails req %lld rc %d",
|
||||
frame_req->request_id, rc);
|
||||
cam_mem_put_cpu_buf(dump_args->buf_handle);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
CAM_DBG(CAM_FD, "Offset before %zu after %zu",
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -1798,7 +1830,7 @@ static int cam_fd_mgr_hw_prepare_update(void *hw_mgr_priv,
|
|||
&prestart_args, &kmd_buf);
|
||||
if (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 */
|
||||
|
|
@ -1807,7 +1839,8 @@ static int cam_fd_mgr_hw_prepare_update(void *hw_mgr_priv,
|
|||
if (rc || !frame_req) {
|
||||
CAM_ERR(CAM_FD, "Get frame_req failed, rc=%d, hw_ctx=%pK",
|
||||
rc, hw_ctx);
|
||||
return -ENOMEM;
|
||||
rc = -ENOMEM;
|
||||
goto put_cpu_buf;
|
||||
}
|
||||
|
||||
/* Setup frame request info and queue to pending list */
|
||||
|
|
@ -1822,9 +1855,13 @@ static int cam_fd_mgr_hw_prepare_update(void *hw_mgr_priv,
|
|||
*/
|
||||
prepare->priv = frame_req;
|
||||
|
||||
cam_fd_mgr_put_cpu_buf(prepare);
|
||||
CAM_DBG(CAM_FD, "FramePrepare : Frame[%lld]", frame_req->request_id);
|
||||
|
||||
return 0;
|
||||
|
||||
put_cpu_buf:
|
||||
cam_fd_mgr_put_cpu_buf(prepare);
|
||||
error:
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
|
|
@ -157,6 +158,7 @@ static int __cam_icp_config_dev_in_ready(struct cam_context *ctx,
|
|||
CAM_ERR(CAM_CTXT,
|
||||
"Invalid offset, len: %zu cmd offset: %llu sizeof packet: %zu",
|
||||
len, cmd->offset, sizeof(struct cam_packet));
|
||||
cam_mem_put_cpu_buf((int32_t) cmd->packet_handle);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -168,6 +170,7 @@ static int __cam_icp_config_dev_in_ready(struct cam_context *ctx,
|
|||
if (rc) {
|
||||
CAM_ERR(CAM_CTXT, "Invalid packet params, remain length: %zu",
|
||||
remain_len);
|
||||
cam_mem_put_cpu_buf((int32_t) cmd->packet_handle);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -182,6 +185,7 @@ static int __cam_icp_config_dev_in_ready(struct cam_context *ctx,
|
|||
if (rc)
|
||||
CAM_ERR(CAM_ICP, "Failed to prepare device");
|
||||
|
||||
cam_mem_put_cpu_buf((int32_t) cmd->packet_handle);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
|
|
@ -91,7 +92,7 @@ static int cam_icp_dump_io_cfg(struct cam_icp_hw_ctx_data *ctx_data,
|
|||
used = 0;
|
||||
}
|
||||
}
|
||||
|
||||
cam_mem_put_cpu_buf(buf_handle);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -4258,6 +4259,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 + cmd_desc[i].offset);
|
||||
|
||||
rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle,
|
||||
&cpu_addr, &len);
|
||||
if (rc || !cpu_addr) {
|
||||
|
|
@ -4274,9 +4276,12 @@ static int cam_icp_mgr_process_cmd_desc(struct cam_icp_hw_mgr *hw_mgr,
|
|||
((len - cmd_desc[i].offset) <
|
||||
cmd_desc[i].length)) {
|
||||
CAM_ERR(CAM_ICP, "Invalid offset or length");
|
||||
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
|
||||
return -EINVAL;
|
||||
}
|
||||
cpu_addr = cpu_addr + cmd_desc[i].offset;
|
||||
|
||||
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5233,6 +5238,7 @@ hw_dump:
|
|||
req_ts.tv_nsec/NSEC_PER_USEC,
|
||||
cur_ts.tv_sec,
|
||||
cur_ts.tv_nsec/NSEC_PER_USEC);
|
||||
|
||||
rc = cam_mem_get_cpu_buf(dump_args->buf_handle,
|
||||
&icp_dump_args.cpu_addr, &icp_dump_args.buf_len);
|
||||
if (rc) {
|
||||
|
|
@ -5243,6 +5249,7 @@ hw_dump:
|
|||
if (icp_dump_args.buf_len <= dump_args->offset) {
|
||||
CAM_WARN(CAM_ICP, "dump buffer overshoot len %zu offset %zu",
|
||||
icp_dump_args.buf_len, dump_args->offset);
|
||||
cam_mem_put_cpu_buf(dump_args->buf_handle);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
|
|
@ -5253,6 +5260,7 @@ hw_dump:
|
|||
if (remain_len < min_len) {
|
||||
CAM_WARN(CAM_ICP, "dump buffer exhaust remain %zu min %u",
|
||||
remain_len, min_len);
|
||||
cam_mem_put_cpu_buf(dump_args->buf_handle);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
|
|
@ -5272,6 +5280,13 @@ hw_dump:
|
|||
/* Dumping the fw image*/
|
||||
icp_dump_args.offset = dump_args->offset;
|
||||
icp_dev_intf = hw_mgr->icp_dev_intf;
|
||||
|
||||
if (!icp_dev_intf) {
|
||||
CAM_ERR(CAM_ICP, "ICP device interface is NULL");
|
||||
cam_mem_put_cpu_buf(dump_args->buf_handle);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = icp_dev_intf->hw_ops.process_cmd(
|
||||
icp_dev_intf->hw_priv,
|
||||
CAM_ICP_CMD_HW_DUMP, &icp_dump_args,
|
||||
|
|
@ -5279,6 +5294,8 @@ hw_dump:
|
|||
CAM_DBG(CAM_ICP, "Offset before %zu after %zu",
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
|
|
@ -339,6 +340,7 @@ static int cam_isp_ctx_dump_req(
|
|||
CAM_ERR(CAM_ISP,
|
||||
"Invalid offset exp %u actual %u",
|
||||
req_isp->cfg[i].offset, (uint32_t)len);
|
||||
cam_mem_put_cpu_buf(req_isp->cfg[i].handle);
|
||||
return -EINVAL;
|
||||
}
|
||||
remain_len = len - req_isp->cfg[i].offset;
|
||||
|
|
@ -349,6 +351,7 @@ static int cam_isp_ctx_dump_req(
|
|||
"Invalid len exp %u remain_len %u",
|
||||
req_isp->cfg[i].len,
|
||||
(uint32_t)remain_len);
|
||||
cam_mem_put_cpu_buf(req_isp->cfg[i].handle);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -374,6 +377,7 @@ static int cam_isp_ctx_dump_req(
|
|||
return rc;
|
||||
} else
|
||||
cam_cdm_util_dump_cmd_buf(buf_start, buf_end);
|
||||
cam_mem_put_cpu_buf(req_isp->cfg[i].handle);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
|
|
@ -3560,6 +3564,7 @@ hw_dump:
|
|||
spin_unlock_bh(&ctx->lock);
|
||||
CAM_WARN(CAM_ISP, "Dump buffer overshoot len %zu offset %zu",
|
||||
buf_len, dump_info->offset);
|
||||
cam_mem_put_cpu_buf(dump_info->buf_handle);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
|
|
@ -3571,6 +3576,7 @@ hw_dump:
|
|||
spin_unlock_bh(&ctx->lock);
|
||||
CAM_WARN(CAM_ISP, "Dump buffer exhaust remain %zu min %u",
|
||||
remain_len, min_len);
|
||||
cam_mem_put_cpu_buf(dump_info->buf_handle);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
|
|
@ -3610,20 +3616,17 @@ hw_dump:
|
|||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "Dump event fail %lld",
|
||||
req->request_id);
|
||||
spin_unlock_bh(&ctx->lock);
|
||||
return rc;
|
||||
}
|
||||
if (dump_only_event_record) {
|
||||
spin_unlock_bh(&ctx->lock);
|
||||
return rc;
|
||||
goto end;
|
||||
}
|
||||
if (dump_only_event_record)
|
||||
goto end;
|
||||
|
||||
rc = __cam_isp_ctx_dump_req_info(ctx, req, cpu_addr,
|
||||
buf_len, &dump_info->offset);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "Dump Req info fail %lld",
|
||||
req->request_id);
|
||||
spin_unlock_bh(&ctx->lock);
|
||||
return rc;
|
||||
goto end;
|
||||
}
|
||||
spin_unlock_bh(&ctx->lock);
|
||||
|
||||
|
|
@ -3637,6 +3640,12 @@ hw_dump:
|
|||
&dump_args);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
|
@ -7293,6 +7294,7 @@ static int cam_ife_mgr_dump(void *hw_mgr_priv, void *args)
|
|||
}
|
||||
}
|
||||
dump_args->offset = isp_hw_dump_args.offset;
|
||||
cam_mem_put_cpu_buf(dump_args->buf_handle);
|
||||
end:
|
||||
CAM_DBG(CAM_ISP, "offset %u", dump_args->offset);
|
||||
return rc;
|
||||
|
|
|
|||
|
|
@ -1893,6 +1893,7 @@ void cam_tfe_cam_cdm_callback(uint32_t handle, void *userdata,
|
|||
ctx->last_submit_bl_cmd.cmd[i].input_len - 1);
|
||||
|
||||
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)
|
||||
cam_packet_dump_patch_info(ctx->packet,
|
||||
|
|
@ -3585,6 +3586,7 @@ static int cam_tfe_mgr_dump(void *hw_mgr_priv, void *args)
|
|||
}
|
||||
dump_args->offset = isp_hw_dump_args.offset;
|
||||
CAM_DBG(CAM_ISP, "offset %u", dump_args->offset);
|
||||
cam_mem_put_cpu_buf(dump_args->buf_handle);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -4183,6 +4185,7 @@ static int cam_tfe_update_dual_config(
|
|||
(cmd_desc->offset >=
|
||||
(len - sizeof(struct cam_isp_tfe_dual_config)))) {
|
||||
CAM_ERR(CAM_ISP, "not enough buffer provided");
|
||||
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -4195,6 +4198,7 @@ static int cam_tfe_update_dual_config(
|
|||
(remain_len -
|
||||
offsetof(struct cam_isp_tfe_dual_config, stripes))) {
|
||||
CAM_ERR(CAM_ISP, "not enough buffer for all the dual configs");
|
||||
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -4256,6 +4260,7 @@ static int cam_tfe_update_dual_config(
|
|||
}
|
||||
|
||||
end:
|
||||
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -4910,7 +4915,6 @@ outportlog:
|
|||
cam_tfe_mgr_print_io_bufs(hw_mgr, *resource_type, packet,
|
||||
ctx_found, ctx);
|
||||
|
||||
|
||||
}
|
||||
|
||||
static int cam_tfe_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* 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>
|
||||
|
|
@ -118,6 +119,7 @@ static int cam_isp_update_dual_config(
|
|||
(cmd_desc->offset >=
|
||||
(len - sizeof(struct cam_isp_dual_config)))) {
|
||||
CAM_ERR(CAM_ISP, "not enough buffer provided");
|
||||
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
|
||||
return -EINVAL;
|
||||
}
|
||||
remain_len = len - cmd_desc->offset;
|
||||
|
|
@ -134,6 +136,7 @@ static int cam_isp_update_dual_config(
|
|||
sizeof(struct cam_isp_dual_stripe_config)) >
|
||||
(remain_len - offsetof(struct cam_isp_dual_config, stripes))) {
|
||||
CAM_ERR(CAM_ISP, "not enough buffer for all the dual configs");
|
||||
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
|
||||
return -EINVAL;
|
||||
}
|
||||
for (i = 0; i < dual_config->num_ports; i++) {
|
||||
|
|
@ -184,6 +187,7 @@ static int cam_isp_update_dual_config(
|
|||
}
|
||||
|
||||
end:
|
||||
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* 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>
|
||||
|
|
@ -444,6 +444,8 @@ static int cam_jpeg_insert_cdm_change_base(
|
|||
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;
|
||||
}
|
||||
CAM_DBG(CAM_JPEG, "iova %pK len %zu offset %d",
|
||||
|
|
@ -475,6 +477,9 @@ static int cam_jpeg_insert_cdm_change_base(
|
|||
ch_base_iova_addr += size;
|
||||
*ch_base_iova_addr = 0;
|
||||
|
||||
cam_mem_put_cpu_buf(
|
||||
config_args->hw_update_entries[CAM_JPEG_CHBASE].handle);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -1649,6 +1654,7 @@ hw_dump:
|
|||
CAM_WARN(CAM_JPEG, "dump offset overshoot len %zu offset %zu",
|
||||
jpeg_dump_args.buf_len, dump_args->offset);
|
||||
mutex_unlock(&hw_mgr->hw_mgr_mutex);
|
||||
cam_mem_put_cpu_buf(dump_args->buf_handle);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
|
|
@ -1659,6 +1665,7 @@ hw_dump:
|
|||
CAM_WARN(CAM_JPEG, "dump buffer exhaust remain %zu min %u",
|
||||
remain_len, min_len);
|
||||
mutex_unlock(&hw_mgr->hw_mgr_mutex);
|
||||
cam_mem_put_cpu_buf(dump_args->buf_handle);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
|
|
@ -1691,6 +1698,7 @@ hw_dump:
|
|||
CAM_DBG(CAM_JPEG, "Offset before %u after %u",
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* 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>
|
||||
|
|
@ -704,6 +704,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",
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -155,6 +155,7 @@ static int __cam_ope_config_dev_in_ready(struct cam_context *ctx,
|
|||
if (rc)
|
||||
CAM_ERR(CAM_OPE, "Failed to prepare device");
|
||||
|
||||
cam_mem_put_cpu_buf((int32_t) cmd->packet_handle);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2022, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
|
|
@ -427,6 +428,25 @@ end:
|
|||
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,
|
||||
struct cam_ope_hang_dump *dump)
|
||||
{
|
||||
|
|
@ -456,6 +476,7 @@ static int cam_ope_dump_indirect(struct ope_cmd_buf_info *cmd_buf_info,
|
|||
print_ptr += sizeof(struct cdm_dmi_cmd) /
|
||||
sizeof(uint32_t);
|
||||
}
|
||||
cam_mem_put_cpu_buf((int32_t) cmd_buf_info->mem_handle);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -558,6 +579,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_frame_set(cpu_addr, dump);
|
||||
cam_ope_mgr_put_cmd_buf(packet);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2187,6 +2209,7 @@ 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.iova_addr,
|
||||
ope_request->ope_kmd_buf.iova_cdm_addr);
|
||||
cam_mem_put_cpu_buf(cmd_buf->mem_handle);
|
||||
break;
|
||||
} else if (cmd_buf->cmd_buf_usage ==
|
||||
OPE_CMD_BUF_DEBUG) {
|
||||
|
|
@ -2202,8 +2225,10 @@ static int cam_ope_mgr_process_cmd_buf_req(struct cam_ope_hw_mgr *hw_mgr,
|
|||
cmd_buf->offset;
|
||||
CAM_DBG(CAM_OPE, "dbg buf = %x",
|
||||
ope_request->ope_debug_buf.cpu_addr);
|
||||
cam_mem_put_cpu_buf(cmd_buf->mem_handle);
|
||||
break;
|
||||
}
|
||||
cam_mem_put_cpu_buf(cmd_buf->mem_handle);
|
||||
break;
|
||||
}
|
||||
case OPE_CMD_BUF_SCOPE_STRIPE: {
|
||||
|
|
@ -3050,6 +3075,7 @@ static int cam_ope_mgr_release_hw(void *hw_priv, void *hw_release_args)
|
|||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int cam_ope_packet_generic_blob_handler(void *user_data,
|
||||
uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data)
|
||||
{
|
||||
|
|
@ -3309,14 +3335,15 @@ static int cam_ope_mgr_prepare_hw_update(void *hw_priv,
|
|||
ctx_data->last_req_time);
|
||||
cam_ope_req_timer_modify(ctx_data, ctx_data->req_timer_timeout);
|
||||
set_bit(request_idx, ctx_data->bitmap);
|
||||
cam_ope_mgr_put_cmd_buf(packet);
|
||||
mutex_unlock(&ctx_data->ctx_mutex);
|
||||
|
||||
CAM_DBG(CAM_REQ, "Prepare Hw update Successful request_id: %d ctx: %d",
|
||||
packet->header.request_id, ctx_data->ctx_id);
|
||||
return rc;
|
||||
|
||||
end:
|
||||
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;
|
||||
req_cdm_mem_alloc_failed:
|
||||
kzfree(ctx_data->req_list[request_idx]);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
|
|
@ -584,6 +585,7 @@ static uint32_t *ope_create_frame_cmd_batch(struct cam_ope_hw_mgr *hw_mgr,
|
|||
dmi_cmd = (struct cdm_dmi_cmd *)temp;
|
||||
if (!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;
|
||||
}
|
||||
|
||||
|
|
@ -604,6 +606,8 @@ static uint32_t *ope_create_frame_cmd_batch(struct cam_ope_hw_mgr *hw_mgr,
|
|||
if (hw_mgr->frame_dump_enable)
|
||||
dump_frame_cmd(frm_proc, i, j,
|
||||
iova_addr, kmd_buf, buf_len);
|
||||
|
||||
cam_mem_put_cpu_buf(frm_proc->cmd_buf[i][j].mem_handle);
|
||||
}
|
||||
return kmd_buf;
|
||||
|
||||
|
|
@ -743,6 +747,8 @@ static uint32_t *ope_create_frame_cmd(struct cam_ope_hw_mgr *hw_mgr,
|
|||
if (!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;
|
||||
}
|
||||
|
||||
|
|
@ -764,6 +770,8 @@ static uint32_t *ope_create_frame_cmd(struct cam_ope_hw_mgr *hw_mgr,
|
|||
if (hw_mgr->frame_dump_enable)
|
||||
dump_frame_cmd(frm_proc, i, j,
|
||||
iova_addr, kmd_buf, buf_len);
|
||||
|
||||
cam_mem_put_cpu_buf(frm_proc->cmd_buf[i][j].mem_handle);
|
||||
}
|
||||
}
|
||||
return kmd_buf;
|
||||
|
|
@ -859,6 +867,7 @@ static uint32_t *ope_create_stripe_cmd(struct cam_ope_hw_mgr *hw_mgr,
|
|||
dmi_cmd = (struct cdm_dmi_cmd *)temp;
|
||||
if (!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;
|
||||
}
|
||||
|
||||
|
|
@ -877,6 +886,8 @@ static uint32_t *ope_create_stripe_cmd(struct cam_ope_hw_mgr *hw_mgr,
|
|||
if (hw_mgr->frame_dump_enable)
|
||||
dump_stripe_cmd(frm_proc, stripe_idx, i, k,
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -300,6 +300,7 @@ int cam_mem_get_cpu_buf(int32_t buf_handle, uintptr_t *vaddr_ptr, size_t *len)
|
|||
return -EINVAL;
|
||||
|
||||
idx = CAM_MEM_MGR_GET_HDL_IDX(buf_handle);
|
||||
|
||||
if (idx >= CAM_MEM_BUFQ_MAX || idx <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -309,18 +310,24 @@ int cam_mem_get_cpu_buf(int32_t buf_handle, uintptr_t *vaddr_ptr, size_t *len)
|
|||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (tbl.bufq[idx].kmdvaddr) {
|
||||
if (tbl.bufq[idx].kmdvaddr && kref_get_unless_zero(&tbl.bufq[idx].krefcount)) {
|
||||
*vaddr_ptr = tbl.bufq[idx].kmdvaddr;
|
||||
*len = tbl.bufq[idx].len;
|
||||
} else {
|
||||
CAM_ERR(CAM_MEM, "No KMD access was requested for 0x%x handle",
|
||||
buf_handle);
|
||||
CAM_ERR(CAM_MEM, "No KMD access requested, kmdvddr= %p, idx= %d, buf_handle= %d",
|
||||
tbl.bufq[idx].kmdvaddr, idx, buf_handle);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -761,6 +768,8 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd)
|
|||
memcpy(tbl.bufq[idx].hdls, cmd->mmu_hdls,
|
||||
sizeof(int32_t) * cmd->num_hdl);
|
||||
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);
|
||||
|
||||
cmd->out.buf_handle = tbl.bufq[idx].buf_handle;
|
||||
|
|
@ -894,6 +903,8 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd)
|
|||
sizeof(int32_t) * cmd->num_hdl);
|
||||
tbl.bufq[idx].is_imported = true;
|
||||
tbl.bufq[idx].is_internal = is_internal;
|
||||
kref_init(&tbl.bufq[idx].krefcount);
|
||||
tbl.bufq[idx].smmu_mapping_client = CAM_SMMU_MAPPING_USER;
|
||||
mutex_unlock(&tbl.bufq[idx].q_lock);
|
||||
|
||||
cmd->out.buf_handle = tbl.bufq[idx].buf_handle;
|
||||
|
|
@ -1052,17 +1063,23 @@ void cam_mem_mgr_deinit(void)
|
|||
mutex_destroy(&tbl.m_lock);
|
||||
}
|
||||
|
||||
static int cam_mem_util_unmap(int32_t idx,
|
||||
enum cam_smmu_mapping_client client)
|
||||
static void cam_mem_util_unmap(struct kref *kref)
|
||||
{
|
||||
int rc = 0;
|
||||
int32_t idx;
|
||||
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) {
|
||||
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);
|
||||
|
||||
mutex_lock(&tbl.m_lock);
|
||||
|
|
@ -1071,7 +1088,7 @@ static int cam_mem_util_unmap(int32_t idx,
|
|||
CAM_WARN(CAM_MEM, "Buffer at idx=%d is already unmapped,",
|
||||
idx);
|
||||
mutex_unlock(&tbl.m_lock);
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Deactivate the buffer queue to prevent multiple unmap */
|
||||
|
|
@ -1136,13 +1153,50 @@ static int cam_mem_util_unmap(int32_t idx,
|
|||
clear_bit(idx, tbl.bitmap);
|
||||
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 idx;
|
||||
int rc;
|
||||
int rc = 0;
|
||||
|
||||
if (!atomic_read(&cam_mem_mgr_state)) {
|
||||
CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized");
|
||||
|
|
@ -1174,7 +1228,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);
|
||||
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;
|
||||
}
|
||||
|
|
@ -1296,6 +1354,8 @@ int cam_mem_mgr_request_mem(struct cam_mem_mgr_request_desc *inp,
|
|||
memcpy(tbl.bufq[idx].hdls, &smmu_hdl,
|
||||
sizeof(int32_t));
|
||||
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);
|
||||
|
||||
out->kva = kvaddr;
|
||||
|
|
@ -1321,7 +1381,7 @@ EXPORT_SYMBOL(cam_mem_mgr_request_mem);
|
|||
int cam_mem_mgr_release_mem(struct cam_mem_mgr_memory_desc *inp)
|
||||
{
|
||||
int32_t idx;
|
||||
int rc;
|
||||
int rc = 0;
|
||||
|
||||
if (!atomic_read(&cam_mem_mgr_state)) {
|
||||
CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized");
|
||||
|
|
@ -1355,7 +1415,12 @@ int cam_mem_mgr_release_mem(struct cam_mem_mgr_memory_desc *inp)
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -1445,6 +1510,8 @@ int cam_mem_mgr_reserve_memory_region(struct cam_mem_mgr_request_desc *inp,
|
|||
memcpy(tbl.bufq[idx].hdls, &smmu_hdl,
|
||||
sizeof(int32_t));
|
||||
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);
|
||||
|
||||
out->kva = 0;
|
||||
|
|
@ -1529,9 +1596,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);
|
||||
rc = cam_mem_util_unmap(idx, CAM_SMMU_MAPPING_KERNEL);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_MEM, "unmapping secondary heap failed");
|
||||
if (kref_put(&tbl.bufq[idx].krefcount, cam_mem_util_unmap))
|
||||
CAM_DBG(CAM_MEM,
|
||||
"Called unmap from here, buf_handle: %u, idx: %d",
|
||||
inp->mem_handle, idx);
|
||||
else
|
||||
rc = -EINVAL;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_MEM_MGR_H_
|
||||
|
|
@ -26,21 +27,24 @@ enum cam_smmu_mapping_client {
|
|||
/**
|
||||
* struct cam_mem_buf_queue
|
||||
*
|
||||
* @dma_buf: pointer to the allocated dma_buf in the table
|
||||
* @q_lock: mutex lock for buffer
|
||||
* @hdls: list of mapped handles
|
||||
* @num_hdl: number of handles
|
||||
* @fd: file descriptor of buffer
|
||||
* @buf_handle: unique handle for buffer
|
||||
* @align: alignment for allocation
|
||||
* @len: size of buffer
|
||||
* @flags: attributes of buffer
|
||||
* @vaddr: IOVA of buffer
|
||||
* @kmdvaddr: Kernel virtual address
|
||||
* @active: state of the buffer
|
||||
* @is_imported: Flag indicating if buffer is imported from an FD in user space
|
||||
* @is_internal: Flag indicating kernel allocated buffer
|
||||
* @timestamp: Timestamp at which this entry in tbl was made
|
||||
* @dma_buf: pointer to the allocated dma_buf in the table
|
||||
* @q_lock: mutex lock for buffer
|
||||
* @hdls: list of mapped handles
|
||||
* @num_hdl: number of handles
|
||||
* @fd: file descriptor of buffer
|
||||
* @buf_handle: unique handle for buffer
|
||||
* @align: alignment for allocation
|
||||
* @len: size of buffer
|
||||
* @flags: attributes of buffer
|
||||
* @vaddr: IOVA of buffer
|
||||
* @kmdvaddr: Kernel virtual address
|
||||
* @active: state of the buffer
|
||||
* @is_imported: Flag indicating if buffer is imported from an FD in user space
|
||||
* @is_internal: Flag indicating kernel allocated buffer
|
||||
* @timestamp: Timestamp at which this entry in tbl was made
|
||||
* @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 dma_buf *dma_buf;
|
||||
|
|
@ -58,6 +62,8 @@ struct cam_mem_buf_queue {
|
|||
bool is_imported;
|
||||
bool is_internal;
|
||||
struct timespec64 timestamp;
|
||||
struct kref krefcount;
|
||||
enum cam_smmu_mapping_client smmu_mapping_client;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_MEM_MGR_API_H_
|
||||
|
|
@ -89,6 +90,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,
|
||||
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)
|
||||
{
|
||||
return CAM_MEM_MGR_IS_SECURE_HDL(buf_handle);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* 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/types.h>
|
||||
|
|
@ -148,14 +148,16 @@ int cam_packet_util_get_kmd_buffer(struct cam_packet *packet,
|
|||
((size_t)cmd_desc->size > (len - (size_t)cmd_desc->offset))) {
|
||||
CAM_ERR(CAM_UTIL, "invalid memory len:%zd and cmd desc size:%d",
|
||||
len, cmd_desc->size);
|
||||
return -EINVAL;
|
||||
rc = -EINVAL;
|
||||
goto rel_kmd_buf;
|
||||
}
|
||||
|
||||
remain_len -= (size_t)cmd_desc->offset;
|
||||
if ((size_t)packet->kmd_cmd_buf_offset >= remain_len) {
|
||||
CAM_ERR(CAM_UTIL, "Invalid kmd cmd buf offset: %zu",
|
||||
(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);
|
||||
|
|
@ -172,6 +174,8 @@ int cam_packet_util_get_kmd_buffer(struct cam_packet *packet,
|
|||
kmd_buf->size = cmd_desc->size - cmd_desc->length;
|
||||
kmd_buf->used_bytes = 0;
|
||||
|
||||
rel_kmd_buf:
|
||||
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -228,6 +232,8 @@ void cam_packet_dump_patch_info(struct cam_packet *packet,
|
|||
|
||||
if (!(*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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -356,6 +362,7 @@ int cam_packet_util_process_patches(struct cam_packet *packet,
|
|||
(size_t)patch_desc[i].dst_offset)) {
|
||||
CAM_ERR(CAM_UTIL,
|
||||
"Invalid dst buf patch offset");
|
||||
cam_mem_put_cpu_buf((int32_t)patch_desc[i].dst_buf_hdl);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -369,6 +376,7 @@ int cam_packet_util_process_patches(struct cam_packet *packet,
|
|||
"patch is done for dst %pK with src %pK value %llx",
|
||||
dst_cpu_addr, src_buf_iova_addr,
|
||||
*((uint64_t *)dst_cpu_addr));
|
||||
cam_mem_put_cpu_buf((int32_t)patch_desc[i].dst_buf_hdl);
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
|
@ -409,14 +417,16 @@ int cam_packet_util_process_generic_cmd_buffer(
|
|||
((size_t)cmd_buf->offset > (buf_size - sizeof(uint32_t)))) {
|
||||
CAM_ERR(CAM_UTIL, "Invalid offset for cmd buf: %zu",
|
||||
(size_t)cmd_buf->offset);
|
||||
return -EINVAL;
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
remain_len -= (size_t)cmd_buf->offset;
|
||||
|
||||
if (remain_len < (size_t)cmd_buf->length) {
|
||||
CAM_ERR(CAM_UTIL, "Invalid length for cmd buf: %zu",
|
||||
(size_t)cmd_buf->length);
|
||||
return -EINVAL;
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
blob_ptr = (uint32_t *)(((uint8_t *)cpu_addr) +
|
||||
|
|
@ -466,5 +476,6 @@ int cam_packet_util_process_generic_cmd_buffer(
|
|||
}
|
||||
|
||||
end:
|
||||
cam_mem_put_cpu_buf(cmd_buf->mem_handle);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* 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_
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
|
|
@ -2082,8 +2083,7 @@ static int cam_soc_util_dump_dmi_reg_range_user_buf(
|
|||
CAM_ERR(CAM_UTIL,
|
||||
"Invalid input args soc_info: %pK, dump_args: %pK",
|
||||
soc_info, dump_args);
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (dmi_read->num_pre_writes > CAM_REG_DUMP_DMI_CONFIG_MAX ||
|
||||
|
|
@ -2091,15 +2091,14 @@ static int cam_soc_util_dump_dmi_reg_range_user_buf(
|
|||
CAM_ERR(CAM_UTIL,
|
||||
"Invalid number of requested writes, pre: %d post: %d",
|
||||
dmi_read->num_pre_writes, dmi_read->num_post_writes);
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = cam_mem_get_cpu_buf(dump_args->buf_handle, &cpu_addr, &buf_len);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_UTIL, "Invalid handle %u rc %d",
|
||||
dump_args->buf_handle, rc);
|
||||
goto end;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (buf_len <= dump_args->offset) {
|
||||
|
|
@ -2185,6 +2184,8 @@ static int cam_soc_util_dump_dmi_reg_range_user_buf(
|
|||
sizeof(struct cam_hw_soc_dump_header);
|
||||
|
||||
end:
|
||||
if (dump_args)
|
||||
cam_mem_put_cpu_buf(dump_args->buf_handle);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2209,13 +2210,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",
|
||||
soc_info, dump_args, reg_read);
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
return rc;
|
||||
}
|
||||
rc = cam_mem_get_cpu_buf(dump_args->buf_handle, &cpu_addr, &buf_len);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_UTIL, "Invalid handle %u rc %d",
|
||||
dump_args->buf_handle, rc);
|
||||
goto end;
|
||||
return rc;
|
||||
}
|
||||
if (buf_len <= dump_args->offset) {
|
||||
CAM_WARN(CAM_UTIL, "Dump offset overshoot %zu %zu",
|
||||
|
|
@ -2265,6 +2266,8 @@ static int cam_soc_util_dump_cont_reg_range_user_buf(
|
|||
dump_args->offset += hdr->size +
|
||||
sizeof(struct cam_hw_soc_dump_header);
|
||||
end:
|
||||
if (dump_args)
|
||||
cam_mem_put_cpu_buf(dump_args->buf_handle);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2356,6 +2359,8 @@ int cam_soc_util_reg_dump_to_cmd_buf(void *ctx,
|
|||
if (rc || !cpu_addr || (buf_size == 0)) {
|
||||
CAM_ERR(CAM_UTIL, "Failed in Get cpu addr, rc=%d, cpu_addr=%pK",
|
||||
rc, (void *)cpu_addr);
|
||||
if (rc)
|
||||
return rc;
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
|
@ -2557,6 +2562,7 @@ int cam_soc_util_reg_dump_to_cmd_buf(void *ctx,
|
|||
}
|
||||
|
||||
end:
|
||||
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue