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,