summaryrefslogtreecommitdiff
path: root/drivers/cam_req_mgr/cam_req_mgr_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cam_req_mgr/cam_req_mgr_util.c')
-rw-r--r--drivers/cam_req_mgr/cam_req_mgr_util.c126
1 files changed, 110 insertions, 16 deletions
diff --git a/drivers/cam_req_mgr/cam_req_mgr_util.c b/drivers/cam_req_mgr/cam_req_mgr_util.c
index a1a5da3..9fded8d 100644
--- a/drivers/cam_req_mgr/cam_req_mgr_util.c
+++ b/drivers/cam_req_mgr/cam_req_mgr_util.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#define pr_fmt(fmt) "CAM-REQ-MGR_UTIL %s:%d " fmt, __func__, __LINE__
@@ -35,28 +36,29 @@ int cam_req_mgr_util_init(void)
rc = -ENOMEM;
goto hdl_tbl_alloc_failed;
}
+ bitmap_size = BITS_TO_LONGS(CAM_REQ_MGR_MAX_HANDLES_V2) * sizeof(long);
+ hdl_tbl_local->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
+ if (!hdl_tbl_local->bitmap) {
+ rc = -ENOMEM;
+ goto bitmap_alloc_fail;
+ }
+ hdl_tbl_local->bits = bitmap_size * BITS_PER_BYTE;
+
spin_lock_bh(&hdl_tbl_lock);
if (hdl_tbl) {
spin_unlock_bh(&hdl_tbl_lock);
rc = -EEXIST;
+ kfree(hdl_tbl_local->bitmap);
kfree(hdl_tbl_local);
goto hdl_tbl_check_failed;
}
hdl_tbl = hdl_tbl_local;
spin_unlock_bh(&hdl_tbl_lock);
- bitmap_size = BITS_TO_LONGS(CAM_REQ_MGR_MAX_HANDLES_V2) * sizeof(long);
- hdl_tbl->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
- if (!hdl_tbl->bitmap) {
- rc = -ENOMEM;
- goto bitmap_alloc_fail;
- }
- hdl_tbl->bits = bitmap_size * BITS_PER_BYTE;
-
return rc;
bitmap_alloc_fail:
- kfree(hdl_tbl);
+ kfree(hdl_tbl_local);
hdl_tbl = NULL;
hdl_tbl_alloc_failed:
hdl_tbl_check_failed:
@@ -121,6 +123,19 @@ static int32_t cam_get_free_handle_index(void)
return idx;
}
+static void cam_dump_tbl_info(void)
+{
+ int i;
+
+ for (i = 0; i < CAM_REQ_MGR_MAX_HANDLES_V2; i++)
+ CAM_INFO_RATE_LIMIT_CUSTOM(CAM_CRM,
+ CAM_RATE_LIMIT_INTERVAL_5SEC,
+ CAM_REQ_MGR_MAX_HANDLES_V2,
+ "ses_hdl=%x hdl_value=%x type=%d state=%d",
+ hdl_tbl->hdl[i].session_hdl, hdl_tbl->hdl[i].hdl_value,
+ hdl_tbl->hdl[i].type, hdl_tbl->hdl[i].state);
+}
+
int32_t cam_create_session_hdl(void *priv)
{
int idx;
@@ -136,7 +151,9 @@ 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_ERR(CAM_CRM, "Unable to create session handle(idx = %d)",
+ idx);
+ cam_dump_tbl_info();
spin_unlock_bh(&hdl_tbl_lock);
return idx;
}
@@ -169,7 +186,9 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data)
idx = cam_get_free_handle_index();
if (idx < 0) {
- CAM_ERR(CAM_CRM, "Unable to create device handle");
+ CAM_ERR(CAM_CRM, "Unable to create device handle(idx= %d)",
+ idx);
+ cam_dump_tbl_info();
spin_unlock_bh(&hdl_tbl_lock);
return idx;
}
@@ -189,7 +208,43 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data)
}
EXPORT_SYMBOL_GPL(cam_create_device_hdl);
-void *cam_get_device_priv(int32_t dev_hdl)
+int32_t cam_create_link_hdl(struct cam_create_dev_hdl *hdl_data)
+{
+ int idx;
+ int rand = 0;
+ int32_t handle;
+
+ spin_lock_bh(&hdl_tbl_lock);
+ if (!hdl_tbl) {
+ CAM_ERR(CAM_CRM, "Hdl tbl is NULL");
+ spin_unlock_bh(&hdl_tbl_lock);
+ return -EINVAL;
+ }
+
+ idx = cam_get_free_handle_index();
+ if (idx < 0) {
+ CAM_ERR(CAM_CRM, "Unable to create link handle(idx = %d)", idx);
+ cam_dump_tbl_info();
+ spin_unlock_bh(&hdl_tbl_lock);
+ return idx;
+ }
+
+ get_random_bytes(&rand, CAM_REQ_MGR_RND1_BYTES);
+ handle = GET_DEV_HANDLE(rand, HDL_TYPE_LINK, idx);
+ hdl_tbl->hdl[idx].session_hdl = hdl_data->session_hdl;
+ hdl_tbl->hdl[idx].hdl_value = handle;
+ hdl_tbl->hdl[idx].type = HDL_TYPE_LINK;
+ hdl_tbl->hdl[idx].state = HDL_ACTIVE;
+ hdl_tbl->hdl[idx].priv = hdl_data->priv;
+ hdl_tbl->hdl[idx].ops = NULL;
+ spin_unlock_bh(&hdl_tbl_lock);
+
+ CAM_DBG(CAM_CRM, "handle = %x", handle);
+ return handle;
+}
+EXPORT_SYMBOL_GPL(cam_create_link_hdl);
+
+void *cam_get_priv(int32_t dev_hdl, int handle_type)
{
int idx;
int type;
@@ -203,17 +258,18 @@ void *cam_get_device_priv(int32_t dev_hdl)
idx = CAM_REQ_MGR_GET_HDL_IDX(dev_hdl);
if (idx >= CAM_REQ_MGR_MAX_HANDLES_V2) {
- CAM_ERR_RATE_LIMIT(CAM_CRM, "Invalid idx");
+ CAM_ERR_RATE_LIMIT(CAM_CRM, "Invalid idx: %d", idx);
goto device_priv_fail;
}
if (hdl_tbl->hdl[idx].state != HDL_ACTIVE) {
- CAM_ERR_RATE_LIMIT(CAM_CRM, "Invalid state");
+ CAM_ERR_RATE_LIMIT(CAM_CRM, "Invalid state: %d",
+ hdl_tbl->hdl[idx].state);
goto device_priv_fail;
}
type = CAM_REQ_MGR_GET_HDL_TYPE(dev_hdl);
- if (HDL_TYPE_DEV != type && HDL_TYPE_SESSION != type) {
+ if (HDL_TYPE_DEV != type && HDL_TYPE_SESSION != type && HDL_TYPE_LINK != type) {
CAM_ERR_RATE_LIMIT(CAM_CRM, "Invalid type");
goto device_priv_fail;
}
@@ -232,8 +288,38 @@ device_priv_fail:
spin_unlock_bh(&hdl_tbl_lock);
return NULL;
}
+
+void *cam_get_device_priv(int32_t dev_hdl)
+{
+ void *priv;
+
+ priv = cam_get_priv(dev_hdl, HDL_TYPE_DEV);
+ return priv;
+}
EXPORT_SYMBOL_GPL(cam_get_device_priv);
+struct cam_req_mgr_core_session *cam_get_session_priv(int32_t dev_hdl)
+{
+ struct cam_req_mgr_core_session *priv;
+
+ priv = (struct cam_req_mgr_core_session *)
+ cam_get_priv(dev_hdl, HDL_TYPE_SESSION);
+
+ return priv;
+}
+EXPORT_SYMBOL_GPL(cam_get_session_priv);
+
+struct cam_req_mgr_core_link *cam_get_link_priv(int32_t dev_hdl)
+{
+ struct cam_req_mgr_core_link *priv;
+
+ priv = (struct cam_req_mgr_core_link *)
+ cam_get_priv(dev_hdl, HDL_TYPE_LINK);
+
+ return priv;
+}
+EXPORT_SYMBOL_GPL(cam_get_link_priv);
+
void *cam_get_device_ops(int32_t dev_hdl)
{
int idx;
@@ -258,7 +344,8 @@ void *cam_get_device_ops(int32_t dev_hdl)
}
type = CAM_REQ_MGR_GET_HDL_TYPE(dev_hdl);
- if (HDL_TYPE_DEV != type && HDL_TYPE_SESSION != type) {
+ if (type != HDL_TYPE_DEV && type != HDL_TYPE_SESSION &&
+ type != HDL_TYPE_LINK) {
CAM_ERR(CAM_CRM, "Invalid type");
goto device_ops_fail;
}
@@ -330,6 +417,13 @@ int cam_destroy_device_hdl(int32_t dev_hdl)
}
EXPORT_SYMBOL_GPL(cam_destroy_device_hdl);
+int cam_destroy_link_hdl(int32_t dev_hdl)
+{
+ CAM_DBG(CAM_CRM, "handle = %x", dev_hdl);
+ return cam_destroy_hdl(dev_hdl, HDL_TYPE_LINK);
+}
+EXPORT_SYMBOL_GPL(cam_destroy_link_hdl);
+
int cam_destroy_session_hdl(int32_t dev_hdl)
{
return cam_destroy_hdl(dev_hdl, HDL_TYPE_SESSION);