From b8429f0813934c3c4351cf4ffb1b87a4b7c107fc Mon Sep 17 00:00:00 2001 From: Tejas Prajapati Date: Wed, 25 Aug 2021 15:14:42 +0530 Subject: [PATCH 1/6] msm: camera: memmgr: ref count for init and deinit Shared memory is initialized by CRM and used by ICP; with CRM not active the ICP would fail to access the shared memory if memory manager is deinit. Tracking open and close calls will help ICP driver to access the shared memory if CRM is not active. CRs-Fixed: 3019488 Change-Id: Ifdf198c2e3593050573c66aeba69d50d131435b9 Signed-off-by: Tejas Prajapati --- drivers/cam_icp/cam_icp_subdev.c | 10 +++++ drivers/cam_req_mgr/cam_mem_mgr.c | 65 +++++++++++++++++++------------ drivers/cam_req_mgr/cam_mem_mgr.h | 6 --- 3 files changed, 50 insertions(+), 31 deletions(-) diff --git a/drivers/cam_icp/cam_icp_subdev.c b/drivers/cam_icp/cam_icp_subdev.c index 1a3be9b64ad5..8a69ff7c1e8f 100644 --- a/drivers/cam_icp/cam_icp_subdev.c +++ b/drivers/cam_icp/cam_icp_subdev.c @@ -20,6 +20,7 @@ #include #include #include +#include "cam_mem_mgr.h" #include "cam_req_mgr_dev.h" #include "cam_subdev.h" #include "cam_node.h" @@ -86,10 +87,18 @@ static int cam_icp_subdev_open(struct v4l2_subdev *sd, goto end; } + + rc = cam_mem_mgr_init(); + if (rc) { + CAM_ERR(CAM_CRM, "mem mgr init failed"); + goto end; + } + hw_mgr_intf = &node->hw_mgr_intf; rc = hw_mgr_intf->hw_open(hw_mgr_intf->hw_mgr_priv, NULL); if (rc < 0) { CAM_ERR(CAM_ICP, "FW download failed"); + cam_mem_mgr_deinit(); goto end; } g_icp_dev.open_cnt++; @@ -130,6 +139,7 @@ int cam_icp_subdev_close_internal(struct v4l2_subdev *sd, goto end; } + cam_mem_mgr_deinit(); end: mutex_unlock(&g_icp_dev.icp_lock); return rc; diff --git a/drivers/cam_req_mgr/cam_mem_mgr.c b/drivers/cam_req_mgr/cam_mem_mgr.c index b928c7da46c7..9c8a404dbfe5 100644 --- a/drivers/cam_req_mgr/cam_mem_mgr.c +++ b/drivers/cam_req_mgr/cam_mem_mgr.c @@ -19,8 +19,11 @@ #include "cam_trace.h" #include "cam_common_util.h" -static struct cam_mem_table tbl; -static atomic_t cam_mem_mgr_state = ATOMIC_INIT(CAM_MEM_MGR_UNINITIALIZED); +static struct cam_mem_table tbl = { + .m_lock = __MUTEX_INITIALIZER(tbl.m_lock), +}; + +static atomic_t cam_mem_mgr_refcnt = ATOMIC_INIT(0); static void cam_mem_mgr_print_tbl(void) { @@ -164,6 +167,16 @@ int cam_mem_mgr_init(void) int i; int bitmap_size; + mutex_lock(&tbl.m_lock); + + if (atomic_inc_return(&cam_mem_mgr_refcnt) > 1) { + CAM_DBG(CAM_MEM, + "Mem mgr refcnt: %d", + atomic_read(&cam_mem_mgr_refcnt)); + mutex_unlock(&tbl.m_lock); + return 0; + } + memset(tbl.bufq, 0, sizeof(tbl.bufq)); if (cam_smmu_need_force_alloc_cached(&tbl.force_cache_allocs)) { @@ -173,8 +186,13 @@ int cam_mem_mgr_init(void) bitmap_size = BITS_TO_LONGS(CAM_MEM_BUFQ_MAX) * sizeof(long); tbl.bitmap = kzalloc(bitmap_size, GFP_KERNEL); - if (!tbl.bitmap) + if (!tbl.bitmap) { + atomic_dec(&cam_mem_mgr_refcnt); + CAM_DBG(CAM_MEM, "Mem mgr refcnt: %d", + atomic_read(&cam_mem_mgr_refcnt)); + mutex_unlock(&tbl.m_lock); return -ENOMEM; + } tbl.bits = bitmap_size * BITS_PER_BYTE; bitmap_zero(tbl.bitmap, tbl.bits); @@ -185,9 +203,8 @@ int cam_mem_mgr_init(void) tbl.bufq[i].fd = -1; tbl.bufq[i].buf_handle = -1; } - mutex_init(&tbl.m_lock); - atomic_set(&cam_mem_mgr_state, CAM_MEM_MGR_INITIALIZED); + mutex_unlock(&tbl.m_lock); cam_mem_mgr_create_debug_fs(); @@ -234,7 +251,7 @@ int cam_mem_get_io_buf(int32_t buf_handle, int32_t mmu_handle, *len_ptr = 0; - if (!atomic_read(&cam_mem_mgr_state)) { + if (!atomic_read(&cam_mem_mgr_refcnt)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); return -EINVAL; } @@ -285,12 +302,7 @@ int cam_mem_get_cpu_buf(int32_t buf_handle, uintptr_t *vaddr_ptr, size_t *len) { int idx; - if (!atomic_read(&cam_mem_mgr_state)) { - CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); - return -EINVAL; - } - - if (!atomic_read(&cam_mem_mgr_state)) { + if (!atomic_read(&cam_mem_mgr_refcnt)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); return -EINVAL; } @@ -333,7 +345,7 @@ int cam_mem_mgr_cache_ops(struct cam_mem_cache_ops_cmd *cmd) uint32_t cache_dir; unsigned long dmabuf_flag = 0; - if (!atomic_read(&cam_mem_mgr_state)) { + if (!atomic_read(&cam_mem_mgr_refcnt)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); return -EINVAL; } @@ -659,7 +671,7 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd) uintptr_t kvaddr = 0; size_t klen; - if (!atomic_read(&cam_mem_mgr_state)) { + if (!atomic_read(&cam_mem_mgr_refcnt)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); return -EINVAL; } @@ -811,7 +823,7 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd) size_t len = 0; bool is_internal = false; - if (!atomic_read(&cam_mem_mgr_state)) { + if (!atomic_read(&cam_mem_mgr_refcnt)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); return -EINVAL; } @@ -998,7 +1010,6 @@ static int cam_mem_mgr_cleanup_table(void) { int i; - mutex_lock(&tbl.m_lock); for (i = 1; i < CAM_MEM_BUFQ_MAX; i++) { if (!tbl.bufq[i].active) { CAM_DBG(CAM_MEM, @@ -1034,23 +1045,27 @@ static int cam_mem_mgr_cleanup_table(void) bitmap_zero(tbl.bitmap, tbl.bits); /* We need to reserve slot 0 because 0 is invalid */ set_bit(0, tbl.bitmap); - mutex_unlock(&tbl.m_lock); return 0; } void cam_mem_mgr_deinit(void) { - atomic_set(&cam_mem_mgr_state, CAM_MEM_MGR_UNINITIALIZED); + mutex_lock(&tbl.m_lock); + if (!atomic_dec_and_test(&cam_mem_mgr_refcnt)) { + CAM_DBG(CAM_MEM, "Mem mgr refcnt: %d", + atomic_read(&cam_mem_mgr_refcnt)); + mutex_unlock(&tbl.m_lock); + return; + } + cam_mem_mgr_cleanup_table(); debugfs_remove_recursive(tbl.dentry); - mutex_lock(&tbl.m_lock); bitmap_zero(tbl.bitmap, tbl.bits); kfree(tbl.bitmap); tbl.bitmap = NULL; tbl.dbg_buf_idx = -1; mutex_unlock(&tbl.m_lock); - mutex_destroy(&tbl.m_lock); } static int cam_mem_util_unmap(int32_t idx, @@ -1148,7 +1163,7 @@ int cam_mem_mgr_release(struct cam_mem_mgr_release_cmd *cmd) int idx; int rc; - if (!atomic_read(&cam_mem_mgr_state)) { + if (!atomic_read(&cam_mem_mgr_refcnt)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); return -EINVAL; } @@ -1201,7 +1216,7 @@ int cam_mem_mgr_request_mem(struct cam_mem_mgr_request_desc *inp, enum cam_smmu_region_id region = CAM_SMMU_REGION_SHARED; - if (!atomic_read(&cam_mem_mgr_state)) { + if (!atomic_read(&cam_mem_mgr_refcnt)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); return -EINVAL; } @@ -1327,7 +1342,7 @@ int cam_mem_mgr_release_mem(struct cam_mem_mgr_memory_desc *inp) int32_t idx; int rc; - if (!atomic_read(&cam_mem_mgr_state)) { + if (!atomic_read(&cam_mem_mgr_refcnt)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); return -EINVAL; } @@ -1380,7 +1395,7 @@ int cam_mem_mgr_reserve_memory_region(struct cam_mem_mgr_request_desc *inp, int32_t smmu_hdl = 0; int32_t num_hdl = 0; - if (!atomic_read(&cam_mem_mgr_state)) { + if (!atomic_read(&cam_mem_mgr_refcnt)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); return -EINVAL; } @@ -1475,7 +1490,7 @@ int cam_mem_mgr_free_memory_region(struct cam_mem_mgr_memory_desc *inp) int rc; int32_t smmu_hdl; - if (!atomic_read(&cam_mem_mgr_state)) { + if (!atomic_read(&cam_mem_mgr_refcnt)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); return -EINVAL; } diff --git a/drivers/cam_req_mgr/cam_mem_mgr.h b/drivers/cam_req_mgr/cam_mem_mgr.h index 26ab9cb75319..9cf7a74b07cf 100644 --- a/drivers/cam_req_mgr/cam_mem_mgr.h +++ b/drivers/cam_req_mgr/cam_mem_mgr.h @@ -11,12 +11,6 @@ #include #include "cam_mem_mgr_api.h" -/* Enum for possible mem mgr states */ -enum cam_mem_mgr_state { - CAM_MEM_MGR_UNINITIALIZED, - CAM_MEM_MGR_INITIALIZED, -}; - /*Enum for possible SMMU operations */ enum cam_smmu_mapping_client { CAM_SMMU_MAPPING_USER, From ed7d45ddc51e148bda5e67879a9df75d1fc94f83 Mon Sep 17 00:00:00 2001 From: Shravya Samala Date: Mon, 6 Sep 2021 21:12:00 +0530 Subject: [PATCH 2/6] msm: camera: jpeg: Ensure in/out map entries are within allowed range Added checks to make sure in_map /out_map entries of packet io configs are within expected maximum value. CRs-Fixed: 3007258 Change-Id: I7e5a652cd8f9ae104a10a2af551fe49930849b2d Signed-off-by: Shravya Samala --- drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c index 8078ee59dc20..fa86ad313541 100644 --- a/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c +++ b/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c @@ -743,10 +743,11 @@ static int cam_jpeg_mgr_prepare_hw_update(void *hw_mgr_priv, } if ((packet->num_cmd_buf > 5) || !packet->num_patches || - !packet->num_io_configs) { - CAM_ERR(CAM_JPEG, "wrong number of cmd/patch info: %u %u", - packet->num_cmd_buf, - packet->num_patches); + !packet->num_io_configs || + (packet->num_io_configs > CAM_JPEG_IMAGE_MAX)) { + CAM_ERR(CAM_JPEG, + "wrong number of cmd/patch/io_configs info: %u %u %u", + packet->num_cmd_buf, packet->num_patches, packet->num_io_configs); return -EINVAL; } From 77cf2e394fbf54752dac08b4de2735853c4b8d47 Mon Sep 17 00:00:00 2001 From: Vishal Verma Date: Sun, 15 Aug 2021 00:14:11 +0530 Subject: [PATCH 3/6] msm: camera: flash: Add support for qup i2c flash Add Support for qup i2c based flash. Update i2c driver probe function and added regulator init at power up and init for gpio pin control table. Since positive return values are not errors for qup i2c rx and tx data transfer, fix the return type for the APIs. Added check for null pointer in get flash dt data for device node. Correct the logging group in sensor util for regulator power up function. CRs-Fixed: 3047031 Change-Id: I70558fbb489b622da25278283015139b6d4fe2a6 Signed-off-by: Vishal Verma --- .../cam_flash/cam_flash_dev.c | 54 ++++++++++++++++--- .../cam_flash/cam_flash_soc.c | 9 +++- .../cam_sensor_io/cam_sensor_qup_i2c.c | 20 +++++-- .../cam_sensor_utils/cam_sensor_util.c | 4 +- 4 files changed, 73 insertions(+), 14 deletions(-) diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c b/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c index b2dd3265da69..197502ff5896 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c @@ -429,6 +429,7 @@ static int cam_flash_component_bind(struct device *dev, return -ENOMEM; fctrl->pdev = pdev; + fctrl->of_node = pdev->dev.of_node; fctrl->soc_info.pdev = pdev; fctrl->soc_info.dev = &pdev->dev; fctrl->soc_info.dev_name = pdev->name; @@ -600,13 +601,18 @@ static int32_t cam_flash_i2c_driver_probe(struct i2c_client *client, { int32_t rc = 0, i = 0; struct cam_flash_ctrl *fctrl; + struct cam_hw_soc_info *soc_info = NULL; - if (client == NULL || id == NULL) { - CAM_ERR(CAM_FLASH, "Invalid Args client: %pK id: %pK", - client, id); + if (client == NULL) { + CAM_ERR(CAM_FLASH, "Invalid Args client: %pK", + client); return -EINVAL; } + if (id == NULL) { + CAM_DBG(CAM_FLASH, "device id is Null"); + } + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { CAM_ERR(CAM_FLASH, "%s :: i2c_check_functionality failed", client->name); @@ -618,9 +624,9 @@ static int32_t cam_flash_i2c_driver_probe(struct i2c_client *client, if (!fctrl) return -ENOMEM; - i2c_set_clientdata(client, fctrl); - + client->dev.driver_data = fctrl; fctrl->io_master_info.client = client; + fctrl->of_node = client->dev.of_node; fctrl->soc_info.dev = &client->dev; fctrl->soc_info.dev_name = client->name; fctrl->io_master_info.master_type = I2C_MASTER; @@ -631,6 +637,40 @@ static int32_t cam_flash_i2c_driver_probe(struct i2c_client *client, goto free_ctrl; } + rc = cam_flash_init_default_params(fctrl); + if (rc) { + CAM_ERR(CAM_FLASH, + "failed: cam_flash_init_default_params rc %d", + rc); + goto free_ctrl; + } + + soc_info = &fctrl->soc_info; + rc = cam_sensor_util_regulator_powerup(soc_info); + if (rc < 0) { + CAM_ERR(CAM_FLASH, "regulator power up for flash failed %d", + rc); + goto free_ctrl; + } + + if (!soc_info->gpio_data) { + CAM_DBG(CAM_FLASH, "No GPIO found"); + rc = 0; + return rc; + } + + if (!soc_info->gpio_data->cam_gpio_common_tbl_size) { + CAM_DBG(CAM_FLASH, "No GPIO found"); + return -EINVAL; + } + + rc = cam_sensor_util_init_gpio_pin_tbl(soc_info, + &fctrl->power_info.gpio_num_info); + if ((rc < 0) || (!fctrl->power_info.gpio_num_info)) { + CAM_ERR(CAM_FLASH, "No/Error Flash GPIOs"); + goto free_ctrl; + } + rc = cam_flash_init_subdev(fctrl); if (rc) goto free_ctrl; @@ -699,6 +739,7 @@ static struct i2c_driver cam_flash_i2c_driver = { .remove = cam_flash_i2c_driver_remove, .driver = { .name = FLASH_DRIVER_I2C, + .of_match_table = cam_flash_dt_match, }, }; @@ -713,8 +754,9 @@ int32_t cam_flash_init_module(void) } rc = i2c_add_driver(&cam_flash_i2c_driver); - if (rc) + if (rc < 0) CAM_ERR(CAM_FLASH, "i2c_add_driver failed rc: %d", rc); + return rc; } diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_soc.c b/drivers/cam_sensor_module/cam_flash/cam_flash_soc.c index 9ec28e953f8b..9eac7a8b8aaf 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_soc.c +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_soc.c @@ -293,7 +293,14 @@ int cam_flash_get_dt_data(struct cam_flash_ctrl *fctrl, rc = -ENOMEM; goto release_soc_res; } - of_node = fctrl->pdev->dev.of_node; + + if (fctrl->of_node == NULL) { + CAM_ERR(CAM_FLASH, "device node is NULL"); + rc = -EINVAL; + goto free_soc_private; + } + + of_node = fctrl->of_node; rc = cam_soc_util_get_dt_properties(soc_info); if (rc) { diff --git a/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_qup_i2c.c b/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_qup_i2c.c index 38af4f74bedb..17bcb0867abb 100644 --- a/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_qup_i2c.c +++ b/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_qup_i2c.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ #include "cam_sensor_cmn_header.h" @@ -31,9 +31,14 @@ static int32_t cam_qup_i2c_rxdata( }, }; rc = i2c_transfer(dev_client->adapter, msgs, 2); - if (rc < 0) + if (rc < 0) { CAM_ERR(CAM_SENSOR, "failed 0x%x", saddr); - return rc; + return rc; + } + /* Returns negative errno */ + /* else the number of messages executed. */ + /* So positive values are not errors. */ + return 0; } @@ -52,9 +57,14 @@ static int32_t cam_qup_i2c_txdata( }, }; rc = i2c_transfer(dev_client->client->adapter, msg, 1); - if (rc < 0) + if (rc < 0) { CAM_ERR(CAM_SENSOR, "failed 0x%x", saddr); - return rc; + return rc; + } + /* Returns negative errno, */ + /* else the number of messages executed. */ + /* So positive values are not errors. */ + return 0; } int32_t cam_qup_i2c_read(struct i2c_client *client, diff --git a/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c b/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c index 771ca38fa6d8..a8bad02a0247 100644 --- a/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c +++ b/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c @@ -74,11 +74,11 @@ int32_t cam_sensor_util_regulator_powerup(struct cam_hw_soc_info *soc_info) if (IS_ERR_OR_NULL(soc_info->rgltr[i])) { rc = PTR_ERR(soc_info->rgltr[i]); rc = rc ? rc : -EINVAL; - CAM_ERR(CAM_ACTUATOR, "get failed for regulator %s %d", + CAM_ERR(CAM_SENSOR, "get failed for regulator %s %d", soc_info->rgltr_name[i], rc); return rc; } - CAM_DBG(CAM_ACTUATOR, "get for regulator %s", + CAM_DBG(CAM_SENSOR, "get for regulator %s", soc_info->rgltr_name[i]); } From 1f20f5bc62e02d8c5ad0f10491b533fbe75afdbb Mon Sep 17 00:00:00 2001 From: sokchetra eung Date: Tue, 17 Aug 2021 14:55:38 -0700 Subject: [PATCH 4/6] msm: camera: req_mgr: Table info dump removed Remove dump_tbl_info function and all of its invocations in CRM to prevent dumping all the handle info when holding the spin lock. CRs-Fixed: 3014074, 3014073 Change-Id: Ie98bafb489fc0d1f2d75cf0f3f08efb48d9b4062 Signed-off-by: sokchetra eung --- drivers/cam_req_mgr/cam_req_mgr_util.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/drivers/cam_req_mgr/cam_req_mgr_util.c b/drivers/cam_req_mgr/cam_req_mgr_util.c index 00b919fcec30..4faba1d006b6 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_util.c +++ b/drivers/cam_req_mgr/cam_req_mgr_util.c @@ -115,7 +115,7 @@ static int32_t cam_get_free_handle_index(void) idx = find_first_zero_bit(hdl_tbl->bitmap, hdl_tbl->bits); if (idx >= CAM_REQ_MGR_MAX_HANDLES_V2 || idx < 0) { - CAM_DBG(CAM_CRM, "idx: %d", idx); + CAM_ERR(CAM_CRM, "No free index found idx: %d", idx); return -ENOSR; } @@ -124,20 +124,6 @@ static int32_t cam_get_free_handle_index(void) return idx; } -void cam_dump_tbl_info(void) -{ - int i; - - for (i = 0; i < CAM_REQ_MGR_MAX_HANDLES_V2; i++) - CAM_INFO(CAM_CRM, - "i: %d session_hdl=0x%x hdl_value=0x%x type=%d state=%d dev_id=0x%llx", - i, 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) { int idx; @@ -154,7 +140,6 @@ int32_t cam_create_session_hdl(void *priv) idx = cam_get_free_handle_index(); if (idx < 0) { CAM_ERR(CAM_CRM, "Unable to create session handle"); - cam_dump_tbl_info(); spin_unlock_bh(&hdl_tbl_lock); return idx; } @@ -190,7 +175,6 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data) if (idx < 0) { CAM_ERR(CAM_CRM, "Unable to create device handle(idx= %d)", idx); - cam_dump_tbl_info(); spin_unlock_bh(&hdl_tbl_lock); return idx; } From 6e882932bd82a9ae993dc9941cafc03f26602127 Mon Sep 17 00:00:00 2001 From: Gaurav Jindal Date: Thu, 9 Apr 2020 14:42:44 +0530 Subject: [PATCH 5/6] msm: camera: core: Delete request from pending list in case of error While preparing hw for request, there is a possiblity of receiving invalid sync object. In this case, we need to return error. By this time, the request is already in pending list. While returning error, request is moved back to free list. But deleting from the pending list was missed. This commit deleted the request from the pending list if the sync object received is invalid. CRs-Fixed: 2660625 Change-Id: Id619452889476b0c2811c8560361205b0d89bcb9 Signed-off-by: Gaurav Jindal --- drivers/cam_core/cam_context_utils.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/cam_core/cam_context_utils.c b/drivers/cam_core/cam_context_utils.c index cfef68791326..eb1cfc581bb7 100644 --- a/drivers/cam_core/cam_context_utils.c +++ b/drivers/cam_core/cam_context_utils.c @@ -457,6 +457,9 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, rc = cam_sync_check_valid( req->in_map_entries[j].sync_id); if (rc) { + spin_lock(&ctx->lock); + list_del_init(&req->list); + spin_unlock(&ctx->lock); CAM_ERR(CAM_CTXT, "invalid in map sync object %d", req->in_map_entries[j].sync_id); From abee20f08a78c5b9441f2d8c4b6d50641d3d2dda Mon Sep 17 00:00:00 2001 From: Vikram Sharma Date: Tue, 28 Sep 2021 22:05:01 +0530 Subject: [PATCH 6/6] msm: camera: isp: Add handling for flush in flushed state This change handles race condition in which flush is handled in flushed state. CRs-Fixed: 3038297 Change-Id: I8be1f8c70431c77366f8846d8ccab3414f3ede3e Signed-off-by: Vikram Sharma --- drivers/cam_isp/cam_isp_context.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/cam_isp/cam_isp_context.c b/drivers/cam_isp/cam_isp_context.c index acd4c1acad93..87779aea1a16 100644 --- a/drivers/cam_isp/cam_isp_context.c +++ b/drivers/cam_isp/cam_isp_context.c @@ -3541,6 +3541,19 @@ hw_dump: return rc; } +static int __cam_isp_ctx_flush_req_in_flushed_state( + struct cam_context *ctx, + struct cam_req_mgr_flush_request *flush_req) +{ + if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_ALL) { + CAM_INFO(CAM_ISP, "Flush in flushed state req id %lld ctx_id:%d", + flush_req->req_id, ctx->ctx_id); + ctx->last_flush_req = flush_req->req_id; + } + + return 0; +} + static int __cam_isp_ctx_flush_req(struct cam_context *ctx, struct list_head *req_list, struct cam_req_mgr_flush_request *flush_req) { @@ -4637,6 +4650,14 @@ static int __cam_isp_ctx_config_dev_in_top_state( packet->header.request_id); rc = -EBADR; goto free_req; + } else if ((packet_opcode == CAM_ISP_PACKET_INIT_DEV) + && (packet->header.request_id <= ctx->last_flush_req) + && ctx->last_flush_req && packet->header.request_id) { + CAM_WARN(CAM_ISP, + "last flushed req is %lld, config dev(init) for req %lld", + ctx->last_flush_req, packet->header.request_id); + rc = -EBADR; + goto free_req; } cfg.packet = packet; @@ -5927,6 +5948,7 @@ static struct cam_ctx_ops .crm_ops = { .unlink = __cam_isp_ctx_unlink_in_ready, .process_evt = __cam_isp_ctx_process_evt, + .flush_req = __cam_isp_ctx_flush_req_in_flushed_state, }, .irq_ops = NULL, .pagefault_ops = cam_isp_context_dump_requests,