Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b8429f08 authored by Tejas Prajapati's avatar Tejas Prajapati
Browse files

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: default avatarTejas Prajapati <tpraja@codeaurora.org>
parent e12864cd
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <media/cam_req_mgr.h>
#include <media/cam_defs.h>
#include <media/cam_icp.h>
#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;
+40 −25
Original line number Diff line number Diff line
@@ -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;
	}
+0 −6
Original line number Diff line number Diff line
@@ -11,12 +11,6 @@
#include <media/cam_req_mgr.h>
#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,