Merge changes I185381f8,I26ee4c58 into camera-kernel-iot.lnx.4.1

* changes:
  msm: camera: ois: Copy packet header in kernel
  msm: camera: common: Add missing put_cpu_buf calls
This commit is contained in:
Linux Build Service Account 2026-03-03 21:50:18 -08:00 • committed by Gerrit - the friendly Code Review server
commit bd44a374ed
9 changed files with 148 additions and 76 deletions

View file

@ -4791,8 +4791,10 @@ static int __cam_isp_ctx_config_dev_in_top_state(
if ((len < sizeof(struct cam_packet)) ||
((size_t)cmd->offset >= len - sizeof(struct cam_packet))) {
CAM_ERR(CAM_ISP, "invalid buff length: %zu or offset", len);
rc = -EINVAL;
goto free_req;
spin_lock_bh(&ctx->lock);
list_add_tail(&req->list, &ctx->free_req_list);
spin_unlock_bh(&ctx->lock);
return -EINVAL;
}
remain_len -= (size_t)cmd->offset;

View file

@ -507,8 +507,10 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
/* Loop through multiple command buffers */
for (i = 0; i < csl_packet->num_cmd_buf; i++) {
rc = cam_packet_util_validate_cmd_desc(&cmd_desc[i]);
if (rc)
if (rc) {
cam_mem_put_cpu_buf(config.packet_handle);
return rc;
}
total_cmd_buf_in_bytes = cmd_desc[i].length;
if (!total_cmd_buf_in_bytes)

View file

@ -379,6 +379,7 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
CAM_ERR(CAM_CSIPHY,
"Inval cam_packet strut size: %zu, len_of_buff: %zu",
sizeof(struct cam_packet), len);
cam_mem_put_cpu_buf((int32_t)cfg_dev->packet_handle);
rc = -EINVAL;
return rc;
}
@ -390,6 +391,7 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
if (cam_packet_util_validate_packet(csl_packet,
remain_len)) {
CAM_ERR(CAM_CSIPHY, "Invalid packet params");
cam_mem_put_cpu_buf((int32_t)cfg_dev->packet_handle);
rc = -EINVAL;
return rc;
}
@ -400,6 +402,7 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
csl_packet->cmd_buf_offset / 4);
else {
CAM_ERR(CAM_CSIPHY, "num_cmd_buffers = %d", csl_packet->num_cmd_buf);
cam_mem_put_cpu_buf((int32_t)cfg_dev->packet_handle);
rc = -EINVAL;
return rc;
}
@ -407,6 +410,7 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
rc = cam_packet_util_validate_cmd_desc(cmd_desc);
if (rc) {
CAM_ERR(CAM_CSIPHY, "Invalid cmd desc ret: %d", rc);
cam_mem_put_cpu_buf((int32_t)cfg_dev->packet_handle);
return rc;
}
@ -415,6 +419,7 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
if (rc < 0) {
CAM_ERR(CAM_CSIPHY,
"Failed to get cmd buf Mem address : %d", rc);
cam_mem_put_cpu_buf((int32_t)cfg_dev->packet_handle);
return rc;
}
@ -422,6 +427,8 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
(cmd_desc->offset > (len - sizeof(struct cam_csiphy_info)))) {
CAM_ERR(CAM_CSIPHY,
"Not enough buffer provided for cam_cisphy_info");
cam_mem_put_cpu_buf((int32_t)cfg_dev->packet_handle);
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
rc = -EINVAL;
return rc;
}
@ -433,6 +440,7 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
index = cam_csiphy_get_instance_offset(csiphy_dev, cfg_dev->dev_handle);
if (index < 0 || index >= csiphy_dev->session_max_device_support) {
CAM_ERR(CAM_CSIPHY, "index in invalid: %d", index);
cam_mem_put_cpu_buf((int32_t)cfg_dev->packet_handle);
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
return -EINVAL;
}
@ -443,6 +451,7 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
CAM_ERR(CAM_CSIPHY,
"Wrong configuration lane_cnt: %u",
cam_cmd_csiphy_info->lane_cnt);
cam_mem_put_cpu_buf((int32_t)cfg_dev->packet_handle);
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
return rc;
}

View file

@ -1065,9 +1065,10 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
/* Loop through multiple command buffers */
for (i = 1; i < csl_packet->num_cmd_buf; i++) {
rc = cam_packet_util_validate_cmd_desc(&cmd_desc[i]);
if (rc)
if (rc) {
cam_mem_put_cpu_buf(config.packet_handle);
return rc;
}
total_cmd_buf_in_bytes = cmd_desc[i].length;
processed_cmd_buf_in_bytes = 0;
if (!total_cmd_buf_in_bytes)
@ -1278,8 +1279,8 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
rc = fctrl->func_tbl.apply_setting(fctrl, 1);
if (rc) {
CAM_ERR(CAM_FLASH, "cannot apply fire settings rc = %d", rc);
return rc;
}
cam_mem_put_cpu_buf(config.packet_handle);
return rc;
}
break;
@ -1344,8 +1345,10 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
goto update_req_mgr;
}
case CAM_FLASH_PACKET_OPCODE_STREAM_OFF: {
if (fctrl->streamoff_count > 0)
if (fctrl->streamoff_count > 0) {
cam_mem_put_cpu_buf(config.packet_handle);
return rc;
}
CAM_DBG(CAM_FLASH, "Received Stream off Settings");
i2c_data = &(fctrl->i2c_data);
@ -1362,6 +1365,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
if (rc) {
CAM_ERR(CAM_FLASH,
"Failed in parsing i2c Stream off packets");
cam_mem_put_cpu_buf(config.packet_handle);
return rc;
}
break;
@ -1638,6 +1642,8 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
cmd_buf = (uint32_t *)((uint8_t *)cmd_buf_ptr +
cmd_desc->offset);
if (!cmd_buf) {
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
cam_mem_put_cpu_buf(config.packet_handle);
rc = -EINVAL;
return rc;
}
@ -1654,6 +1660,8 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
CAM_WARN(CAM_FLASH,
"Rxed Flash fire ops without linking");
flash_data->cmn_attr.is_settings_valid = false;
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
cam_mem_put_cpu_buf(config.packet_handle);
return -EINVAL;
}
if (remain_len < sizeof(struct cam_flash_set_on_off)) {

View file

@ -493,11 +493,13 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
size_t pkt_len;
size_t remain_len = 0;
struct cam_packet *csl_packet = NULL;
struct cam_packet *csl_packet_u = NULL;
size_t len_of_buff = 0;
uint32_t *offset = NULL, *cmd_buf;
struct cam_ois_soc_private *soc_private =
(struct cam_ois_soc_private *)o_ctrl->soc_info.soc_private;
struct cam_sensor_power_ctrl_t *power_info = &soc_private->power_info;
size_t packet_size = 0;
ioctl_ctrl = (struct cam_control *)arg;
if (copy_from_user(&dev_config,
@ -519,22 +521,36 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
CAM_ERR(CAM_OIS,
"Inval cam_packet strut size: %zu, len_of_buff: %zu",
sizeof(struct cam_packet), pkt_len);
cam_mem_put_cpu_buf(dev_config.packet_handle);
return -EINVAL;
rc = -EINVAL;
goto put_ref;
}
remain_len -= (size_t)dev_config.offset;
csl_packet = (struct cam_packet *)
csl_packet_u = (struct cam_packet *)
(generic_pkt_addr + (uint32_t)dev_config.offset);
packet_size = csl_packet_u->header.size;
if (packet_size <= remain_len) {
rc = cam_common_mem_kdup((void **)&csl_packet,
csl_packet_u, packet_size);
if (rc) {
CAM_ERR(CAM_OIS, "Alloc and copy request %lld packet fail",
csl_packet_u->header.request_id);
goto put_ref;
}
} else {
CAM_ERR(CAM_OIS, "Invalid packet header size %u",
packet_size);
rc = -EINVAL;
goto put_ref;
}
if (cam_packet_util_validate_packet(csl_packet,
remain_len)) {
CAM_ERR(CAM_OIS, "Invalid packet params");
cam_mem_put_cpu_buf(dev_config.packet_handle);
return -EINVAL;
rc = -EINVAL;
goto end;
}
switch (csl_packet->header.op_code & 0xFFFFFF) {
case CAM_OIS_PACKET_OPCODE_INIT:
offset = (uint32_t *)&csl_packet->payload;
@ -544,8 +560,10 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
/* Loop through multiple command buffers */
for (i = 0; i < csl_packet->num_cmd_buf; i++) {
rc = cam_packet_util_validate_cmd_desc(&cmd_desc[i]);
if (rc)
return rc;
if (rc) {
CAM_ERR(CAM_OIS, "Invalid cmd desc");
goto end;
}
total_cmd_buf_in_bytes = cmd_desc[i].length;
if (!total_cmd_buf_in_bytes)
@ -556,15 +574,14 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
if (rc < 0) {
CAM_ERR(CAM_OIS, "Failed to get cpu buf : 0x%x",
cmd_desc[i].mem_handle);
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
goto end;
}
cmd_buf = (uint32_t *)generic_ptr;
if (!cmd_buf) {
CAM_ERR(CAM_OIS, "invalid cmd buf");
rc = -EINVAL;
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
cam_mem_put_cpu_buf(dev_config.packet_handle);
return -EINVAL;
goto end;
}
if ((len_of_buff < sizeof(struct common_header)) ||
@ -572,9 +589,9 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
sizeof(struct common_header)))) {
CAM_ERR(CAM_OIS,
"Invalid length for sensor cmd");
rc = -EINVAL;
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
cam_mem_put_cpu_buf(dev_config.packet_handle);
return -EINVAL;
goto end;
}
remain_len = len_of_buff - cmd_desc[i].offset;
cmd_buf += cmd_desc[i].offset / sizeof(uint32_t);
@ -587,9 +604,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
if (rc < 0) {
CAM_ERR(CAM_OIS,
"Failed in parsing slave info");
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
break;
}
break;
case CAMERA_SENSOR_CMD_TYPE_PWR_UP:
@ -603,9 +618,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
if (rc) {
CAM_ERR(CAM_OIS,
"Failed: parse power settings");
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
break;
}
break;
default:
@ -623,9 +636,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
if (rc < 0) {
CAM_ERR(CAM_OIS,
"init parsing failed: %d", rc);
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
break;
}
} else if ((o_ctrl->is_ois_calib != 0) &&
(o_ctrl->i2c_calib_data.is_settings_valid ==
@ -642,22 +653,22 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
if (rc < 0) {
CAM_ERR(CAM_OIS,
"Calib parsing failed: %d", rc);
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
break;
}
}
break;
}
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
if (rc < 0)
goto end;
}
if (o_ctrl->cam_ois_state != CAM_OIS_CONFIG) {
rc = cam_ois_power_up(o_ctrl);
if (rc) {
CAM_ERR(CAM_OIS, " OIS Power up failed");
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
goto end;
}
o_ctrl->cam_ois_state = CAM_OIS_CONFIG;
}
@ -714,8 +725,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
CAM_WARN(CAM_OIS,
"Not in right state to control OIS: %d",
o_ctrl->cam_ois_state);
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
goto end;
}
offset = (uint32_t *)&csl_packet->payload;
offset += (csl_packet->cmd_buf_offset / sizeof(uint32_t));
@ -728,23 +738,20 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
cmd_desc, 1, NULL);
if (rc < 0) {
CAM_ERR(CAM_OIS, "OIS pkt parsing failed: %d", rc);
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
goto end;
}
rc = cam_ois_apply_settings(o_ctrl, i2c_reg_settings);
if (rc < 0) {
CAM_ERR(CAM_OIS, "Cannot apply mode settings");
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
goto end;
}
rc = delete_request(i2c_reg_settings);
if (rc < 0) {
CAM_ERR(CAM_OIS,
"Fail deleting Mode data: rc: %d", rc);
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
goto end;
}
break;
case CAM_OIS_PACKET_OPCODE_READ: {
@ -756,16 +763,14 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
CAM_WARN(CAM_OIS,
"Not in right state to read OIS: %d",
o_ctrl->cam_ois_state);
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
goto end;
}
CAM_DBG(CAM_OIS, "number of I/O configs: %d:",
csl_packet->num_io_configs);
if (csl_packet->num_io_configs == 0) {
CAM_ERR(CAM_OIS, "No I/O configs to process");
rc = -EINVAL;
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
goto end;
}
INIT_LIST_HEAD(&(i2c_read_settings.list_head));
@ -778,8 +783,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
if (io_cfg == NULL) {
CAM_ERR(CAM_OIS, "I/O config is invalid(NULL)");
rc = -EINVAL;
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
goto end;
}
offset = (uint32_t *)&csl_packet->payload;
@ -792,8 +796,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
cmd_desc, 1, &io_cfg[0]);
if (rc < 0) {
CAM_ERR(CAM_OIS, "OIS read pkt parsing failed: %d", rc);
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
goto end;
}
rc = cam_sensor_i2c_read_data(
@ -802,8 +805,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
if (rc < 0) {
CAM_ERR(CAM_OIS, "cannot read data rc: %d", rc);
delete_request(&i2c_read_settings);
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
goto end;
}
if (csl_packet->num_io_configs > 1) {
@ -813,8 +815,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
CAM_ERR(CAM_OIS,
"write qtimer failed rc: %d", rc);
delete_request(&i2c_read_settings);
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
goto end;
}
}
@ -822,8 +823,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
if (rc < 0) {
CAM_ERR(CAM_OIS,
"Failed in deleting the read settings");
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
goto end;
}
break;
}
@ -833,8 +833,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
CAM_ERR(CAM_OIS,
"Not in right state to write time to OIS: %d",
o_ctrl->cam_ois_state);
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
goto end;
}
offset = (uint32_t *)&csl_packet->payload;
offset += (csl_packet->cmd_buf_offset / sizeof(uint32_t));
@ -847,47 +846,45 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
cmd_desc, 1, NULL);
if (rc < 0) {
CAM_ERR(CAM_OIS, "OIS pkt parsing failed: %d", rc);
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
goto end;
}
rc = cam_ois_update_time(i2c_reg_settings);
if (rc < 0) {
CAM_ERR(CAM_OIS, "Cannot update time");
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
goto end;
}
rc = cam_ois_apply_settings(o_ctrl, i2c_reg_settings);
if (rc < 0) {
CAM_ERR(CAM_OIS, "Cannot apply mode settings");
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
goto end;
}
rc = delete_request(i2c_reg_settings);
if (rc < 0) {
CAM_ERR(CAM_OIS,
"Fail deleting Mode data: rc: %d", rc);
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
goto end;
}
break;
}
default:
CAM_ERR(CAM_OIS, "Invalid Opcode: %d",
(csl_packet->header.op_code & 0xFFFFFF));
cam_mem_put_cpu_buf(dev_config.packet_handle);
return -EINVAL;
rc = -EINVAL;
goto end;
}
if (!rc) {
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
}
if (!rc)
goto end;
pwr_dwn:
cam_mem_put_cpu_buf(dev_config.packet_handle);
cam_ois_power_down(o_ctrl);
end:
cam_common_mem_free(csl_packet);
put_ref:
cam_mem_put_cpu_buf(dev_config.packet_handle);
return rc;
}

View file

@ -556,8 +556,10 @@ int32_t cam_handle_mem_ptr(uint64_t handle, struct cam_sensor_ctrl_t *s_ctrl)
for (i = 0; i < pkt->num_cmd_buf; i++) {
rc = cam_packet_util_validate_cmd_desc(&cmd_desc[i]);
if (rc)
if (rc) {
cam_mem_put_cpu_buf(handle);
return rc;
}
if (!(cmd_desc[i].length))
continue;

View file

@ -316,12 +316,12 @@ static int32_t cam_sensor_get_io_buffer(
(uint8_t *)buf_addr + io_cfg->offsets[0];
i2c_settings->read_buff_len =
buf_size - io_cfg->offsets[0];
cam_mem_put_cpu_buf(io_cfg->mem_handle[0]);
} else {
CAM_ERR(CAM_SENSOR, "Invalid direction: %d",
io_cfg->direction);
rc = -EINVAL;
}
cam_mem_put_cpu_buf(io_cfg->mem_handle[0]);
return rc;
}

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2019, 2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/string.h>
@ -72,3 +73,36 @@ void cam_common_util_thread_switch_delay_detect(
}
}
int cam_common_mem_kdup(void **dst,
void *src, size_t size)
{
gfp_t flag = GFP_KERNEL;
if (!src || !dst || !size) {
CAM_ERR(CAM_UTIL, "Invalid params src: %pK dst: %pK size: %u",
src, dst, size);
return -EINVAL;
}
if (!in_task())
flag = GFP_ATOMIC;
*dst = kzalloc(size, flag);
if (!*dst) {
CAM_ERR(CAM_UTIL, "Failed to allocate memory with size: %u", size);
return -ENOMEM;
}
memcpy(*dst, src, size);
CAM_DBG(CAM_UTIL, "Allocate and copy memory with size: %u", size);
return 0;
}
EXPORT_SYMBOL(cam_common_mem_kdup);
void cam_common_mem_free(void *memory)
{
kfree(memory);
}
EXPORT_SYMBOL(cam_common_mem_free);

View file

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_COMMON_UTIL_H_
@ -85,4 +86,21 @@ uint32_t cam_common_util_remove_duplicate_arr(int32_t *array,
void cam_common_util_thread_switch_delay_detect(const char *token,
ktime_t scheduled_time, uint32_t threshold);
/**
* @brief: Memory alloc and copy
*
* @dst: Address of destination address of memory
* @src: Source address of memory
* @size: Length of memory
*
* @return 0 if success in register non-zero if failes
*/
int cam_common_mem_kdup(void **dst, void *src, size_t size);
/**
* @brief: Free the memory
*
* @memory: Address of memory
*/
void cam_common_mem_free(void *memory);
#endif /* _CAM_COMMON_UTIL_H_ */