Jelajahi Sumber

msm: camera: custom: Add support for acquire_hw_v1

Split the acquire in custom node to acquire device and
acquire hw to be in line with IFE for multicamera usecases.

CRs-Fixed: 2524308
Change-Id: I7be7d5227dcd304d095d7e3d7fac32800fecc199
Signed-off-by: Karthik Anantha Ram <[email protected]>
Karthik Anantha Ram 5 tahun lalu
induk
melakukan
a27592f01b

+ 211 - 20
drivers/cam_cust/cam_custom_context.c

@@ -19,7 +19,7 @@
 #include "cam_custom_context.h"
 #include "cam_common_util.h"
 
-static const char custom_dev_name[] = "custom hw";
+static const char custom_dev_name[] = "cam-custom";
 
 static int __cam_custom_ctx_handle_irq_in_activated(
 	void *context, uint32_t evt_id, void *evt_data);
@@ -275,6 +275,67 @@ static int __cam_custom_stop_dev_in_activated(struct cam_context *ctx,
 	return 0;
 }
 
+static int __cam_custom_ctx_release_hw_in_top_state(
+	struct cam_context *ctx, void *cmd)
+{
+	int rc = 0;
+	struct cam_hw_release_args        rel_arg;
+	struct cam_req_mgr_flush_request  flush_req;
+	struct cam_custom_context        *custom_ctx =
+		(struct cam_custom_context *) ctx->ctx_priv;
+
+	if (custom_ctx->hw_ctx) {
+		rel_arg.ctxt_to_hw_map = custom_ctx->hw_ctx;
+		rc = ctx->hw_mgr_intf->hw_release(ctx->hw_mgr_intf->hw_mgr_priv,
+			&rel_arg);
+		custom_ctx->hw_ctx = NULL;
+		if (rc)
+			CAM_ERR(CAM_CUSTOM,
+				"Failed to release HW for ctx:%u", ctx->ctx_id);
+	} else {
+		CAM_ERR(CAM_CUSTOM, "No HW resources acquired for this ctx");
+	}
+
+	ctx->last_flush_req = 0;
+	custom_ctx->frame_id = 0;
+	custom_ctx->active_req_cnt = 0;
+	custom_ctx->hw_acquired = false;
+	custom_ctx->init_received = false;
+
+	/* check for active requests as well */
+	flush_req.type = CAM_REQ_MGR_FLUSH_TYPE_ALL;
+	flush_req.link_hdl = ctx->link_hdl;
+	flush_req.dev_hdl = ctx->dev_hdl;
+
+	CAM_DBG(CAM_CUSTOM, "try to flush pending list");
+	spin_lock_bh(&ctx->lock);
+	rc = __cam_custom_ctx_flush_req(ctx, &ctx->pending_req_list,
+		&flush_req);
+	spin_unlock_bh(&ctx->lock);
+	ctx->state = CAM_CTX_ACQUIRED;
+
+	CAM_DBG(CAM_CUSTOM, "Release HW success[%u] next state %d",
+		ctx->ctx_id, ctx->state);
+
+	return rc;
+}
+
+static int __cam_custom_ctx_release_hw_in_activated_state(
+	struct cam_context *ctx, void *cmd)
+{
+	int rc = 0;
+
+	rc = __cam_custom_stop_dev_in_activated(ctx, NULL);
+	if (rc)
+		CAM_ERR(CAM_CUSTOM, "Stop device failed rc=%d", rc);
+
+	rc = __cam_custom_ctx_release_hw_in_top_state(ctx, cmd);
+	if (rc)
+		CAM_ERR(CAM_CUSTOM, "Release hw failed rc=%d", rc);
+
+	return rc;
+}
+
 static int __cam_custom_release_dev_in_acquired(struct cam_context *ctx,
 	struct cam_release_dev_cmd *cmd)
 {
@@ -283,14 +344,16 @@ static int __cam_custom_release_dev_in_acquired(struct cam_context *ctx,
 		(struct cam_custom_context *) ctx->ctx_priv;
 	struct cam_req_mgr_flush_request flush_req;
 
-	rc = cam_context_release_dev_to_hw(ctx, cmd);
-	if (rc)
-		CAM_ERR(CAM_CUSTOM, "Unable to release device");
+	if (cmd && ctx_custom->hw_ctx) {
+		CAM_ERR(CAM_CUSTOM, "releasing hw");
+		__cam_custom_ctx_release_hw_in_top_state(ctx, NULL);
+	}
 
 	ctx->ctx_crm_intf = NULL;
 	ctx->last_flush_req = 0;
 	ctx_custom->frame_id = 0;
 	ctx_custom->active_req_cnt = 0;
+	ctx_custom->hw_acquired = false;
 	ctx_custom->init_received = false;
 
 	if (!list_empty(&ctx->active_req_list))
@@ -381,33 +444,128 @@ end:
 	return rc;
 }
 
-static int __cam_custom_ctx_acquire_dev_in_available(struct cam_context *ctx,
-	struct cam_acquire_dev_cmd *cmd)
+static int __cam_custom_ctx_acquire_hw_v1(
+	struct cam_context *ctx, void *args)
 {
-	int rc;
-	struct cam_custom_context *custom_ctx;
+	int rc = 0;
+	struct cam_acquire_hw_cmd_v1 *cmd =
+		(struct cam_acquire_hw_cmd_v1 *)args;
+	struct cam_hw_acquire_args         param;
+	struct cam_custom_context         *ctx_custom =
+		(struct cam_custom_context *)  ctx->ctx_priv;
+	struct cam_custom_acquire_hw_info *acquire_hw_info = NULL;
+
+	if (!ctx->hw_mgr_intf) {
+		CAM_ERR(CAM_CUSTOM, "HW interface is not ready");
+		rc = -EFAULT;
+		goto end;
+	}
 
-	custom_ctx = (struct cam_custom_context *) ctx->ctx_priv;
+	CAM_DBG(CAM_CUSTOM,
+		"session_hdl 0x%x, hdl type %d, res %lld",
+		cmd->session_handle, cmd->handle_type, cmd->resource_hdl);
 
-	if (cmd->num_resources > CAM_CUSTOM_DEV_CTX_RES_MAX) {
-		CAM_ERR(CAM_CUSTOM, "Too much resources in the acquire");
+	if (cmd->handle_type != 1)  {
+		CAM_ERR(CAM_CUSTOM, "Only user pointer is supported");
+		rc = -EINVAL;
+		goto end;
+	}
+
+	if (cmd->data_size < sizeof(*acquire_hw_info)) {
+		CAM_ERR(CAM_CUSTOM, "data_size is not a valid value");
+		goto end;
+	}
+
+	acquire_hw_info = kzalloc(cmd->data_size, GFP_KERNEL);
+	if (!acquire_hw_info) {
 		rc = -ENOMEM;
-		return rc;
+		goto end;
 	}
 
-	if (cmd->handle_type != 1)	{
-		CAM_ERR(CAM_CUSTOM, "Only user pointer is supported");
-		rc = -EINVAL;
+	CAM_DBG(CAM_CUSTOM, "start copy resources from user");
+
+	if (copy_from_user(acquire_hw_info, (void __user *)cmd->resource_hdl,
+		cmd->data_size)) {
+		rc = -EFAULT;
+		goto free_res;
+	}
+
+	memset(&param, 0, sizeof(param));
+	param.context_data = ctx;
+	param.event_cb = ctx->irq_cb_intf;
+	param.acquire_info_size = cmd->data_size;
+	param.acquire_info = (uint64_t) acquire_hw_info;
+
+	/* call HW manager to reserve the resource */
+	rc = ctx->hw_mgr_intf->hw_acquire(ctx->hw_mgr_intf->hw_mgr_priv,
+		&param);
+	if (rc != 0) {
+		CAM_ERR(CAM_CUSTOM, "Acquire HW failed");
+		goto free_res;
+	}
+
+	ctx_custom->hw_ctx = param.ctxt_to_hw_map;
+	ctx_custom->hw_acquired = true;
+	ctx->ctxt_to_hw_map = param.ctxt_to_hw_map;
+
+	CAM_DBG(CAM_CUSTOM,
+		"Acquire HW success on session_hdl 0x%xs for ctx_id %u",
+		ctx->session_hdl, ctx->ctx_id);
+
+	kfree(acquire_hw_info);
+	return rc;
+
+free_res:
+	kfree(acquire_hw_info);
+end:
+	return rc;
+}
+
+static int __cam_custom_ctx_acquire_dev_in_available(
+	struct cam_context *ctx, struct cam_acquire_dev_cmd *cmd)
+{
+	int rc = 0;
+	struct cam_create_dev_hdl  req_hdl_param;
+
+	if (!ctx->hw_mgr_intf) {
+		CAM_ERR(CAM_CUSTOM, "HW interface is not ready");
+		rc = -EFAULT;
 		return rc;
 	}
 
-	rc = cam_context_acquire_dev_to_hw(ctx, cmd);
-	if (!rc) {
-		ctx->state = CAM_CTX_ACQUIRED;
-		custom_ctx->hw_ctx = ctx->ctxt_to_hw_map;
+	CAM_DBG(CAM_CUSTOM,
+		"session_hdl 0x%x, num_resources %d, hdl type %d, res %lld",
+		cmd->session_handle, cmd->num_resources,
+		cmd->handle_type, cmd->resource_hdl);
+
+	if (cmd->num_resources != CAM_API_COMPAT_CONSTANT) {
+		CAM_ERR(CAM_CUSTOM, "Invalid num_resources 0x%x",
+			cmd->num_resources);
+		return -EINVAL;
 	}
 
-	CAM_DBG(CAM_CUSTOM, "Acquire done %d", ctx->ctx_id);
+	req_hdl_param.session_hdl = cmd->session_handle;
+	req_hdl_param.v4l2_sub_dev_flag = 0;
+	req_hdl_param.media_entity_flag = 0;
+	req_hdl_param.ops = ctx->crm_ctx_intf;
+	req_hdl_param.priv = ctx;
+
+	CAM_DBG(CAM_CUSTOM, "get device handle from bridge");
+	ctx->dev_hdl = cam_create_device_hdl(&req_hdl_param);
+	if (ctx->dev_hdl <= 0) {
+		rc = -EFAULT;
+		CAM_ERR(CAM_CUSTOM, "Can not create device handle");
+		return rc;
+	}
+
+	cmd->dev_handle = ctx->dev_hdl;
+	ctx->session_hdl = cmd->session_handle;
+	ctx->state = CAM_CTX_ACQUIRED;
+
+	CAM_DBG(CAM_CUSTOM,
+		"Acquire dev success on session_hdl 0x%x for ctx %u",
+		cmd->session_handle, ctx->ctx_id);
+
 	return rc;
 }
 
@@ -642,6 +800,13 @@ static int __cam_custom_ctx_config_dev_in_acquired(struct cam_context *ctx,
 	struct cam_config_dev_cmd *cmd)
 {
 	int rc = 0;
+	struct cam_custom_context        *ctx_custom =
+		(struct cam_custom_context *) ctx->ctx_priv;
+
+	if (!ctx_custom->hw_acquired) {
+		CAM_ERR(CAM_CUSTOM, "HW not acquired, reject config packet");
+		return -EAGAIN;
+	}
 
 	rc = __cam_custom_ctx_config_dev(ctx, cmd);
 
@@ -826,6 +991,27 @@ static int __cam_custom_ctx_handle_irq_in_activated(void *context,
 	return rc;
 }
 
+static int __cam_custom_ctx_acquire_hw_in_acquired(
+	struct cam_context *ctx, void *args)
+{
+	int rc = -EINVAL;
+	uint32_t api_version;
+
+	if (!ctx || !args) {
+		CAM_ERR(CAM_CUSTOM, "Invalid input pointer");
+		return rc;
+	}
+
+	api_version = *((uint32_t *)args);
+	if (api_version == 1)
+		rc = __cam_custom_ctx_acquire_hw_v1(ctx, args);
+	else
+		CAM_ERR(CAM_CUSTOM, "Unsupported api version %d",
+			api_version);
+
+	return rc;
+}
+
 /* top state machine */
 static struct cam_ctx_ops
 	cam_custom_dev_ctx_top_state_machine[CAM_CTX_STATE_MAX] = {
@@ -847,8 +1033,10 @@ static struct cam_ctx_ops
 	/* Acquired */
 	{
 		.ioctl_ops = {
+			.acquire_hw = __cam_custom_ctx_acquire_hw_in_acquired,
 			.release_dev = __cam_custom_release_dev_in_acquired,
 			.config_dev = __cam_custom_ctx_config_dev_in_acquired,
+			.release_hw = __cam_custom_ctx_release_hw_in_top_state,
 		},
 		.crm_ops = {
 			.link = __cam_custom_ctx_link_in_acquired,
@@ -866,6 +1054,7 @@ static struct cam_ctx_ops
 			.start_dev = __cam_custom_ctx_start_dev_in_ready,
 			.release_dev = __cam_custom_release_dev_in_acquired,
 			.config_dev = __cam_custom_ctx_config_dev,
+			.release_hw = __cam_custom_ctx_release_hw_in_top_state,
 		},
 		.crm_ops = {
 			.unlink = __cam_custom_ctx_unlink_in_ready,
@@ -883,6 +1072,8 @@ static struct cam_ctx_ops
 			.release_dev =
 				__cam_custom_ctx_release_dev_in_activated,
 			.config_dev = __cam_custom_ctx_config_dev,
+			.release_hw =
+				__cam_custom_ctx_release_hw_in_activated_state,
 		},
 		.crm_ops = {
 			.unlink = __cam_custom_ctx_unlink_in_activated,

+ 2 - 0
drivers/cam_cust/cam_custom_context.h

@@ -67,6 +67,7 @@ struct cam_custom_dev_ctx_req {
  *                   custom HW will invoke CRM cb at those event.
  * @active_req_cnt: Counter for the active request
  * @frame_id: Frame id tracking for the custom context
+ * @hw_acquired: Flag to indicate if HW is acquired for this context
  * @req_base: common request structure
  * @req_custom: custom request structure
  *
@@ -80,6 +81,7 @@ struct cam_custom_context {
 	uint32_t                      subscribe_event;
 	uint32_t                      active_req_cnt;
 	int64_t                       frame_id;
+	bool                          hw_acquired;
 	struct cam_ctx_request        req_base[CAM_CTX_REQ_MAX];
 	struct cam_custom_dev_ctx_req req_custom[CAM_CTX_REQ_MAX];
 };

+ 104 - 145
drivers/cam_cust/cam_custom_hw_mgr/cam_custom_hw_mgr.c

@@ -380,7 +380,7 @@ static int cam_custom_mgr_start_hw(void *hw_mgr_priv,
 		&ctx->res_list_custom_cid, list) {
 		rc = cam_custom_hw_mgr_init_hw_res(hw_mgr_res);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "Can not INIT CID(id :%d)",
+			CAM_ERR(CAM_CUSTOM, "Can not INIT CID(id :%d)",
 				hw_mgr_res->res_id);
 			goto deinit_hw;
 		}
@@ -391,7 +391,7 @@ static int cam_custom_mgr_start_hw(void *hw_mgr_priv,
 		&ctx->res_list_custom_csid, list) {
 		rc = cam_custom_hw_mgr_init_hw_res(hw_mgr_res);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "Can not INIT CSID(id :%d)",
+			CAM_ERR(CAM_CUSTOM, "Can not INIT CSID(id :%d)",
 				hw_mgr_res->res_id);
 			goto deinit_hw;
 		}
@@ -411,7 +411,7 @@ static int cam_custom_mgr_start_hw(void *hw_mgr_priv,
 		&ctx->res_list_custom_csid, list) {
 		rc = cam_custom_hw_mgr_start_hw_res(hw_mgr_res);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "Can not START CSID(id :%d)",
+			CAM_ERR(CAM_CUSTOM, "Can not START CSID(id :%d)",
 				hw_mgr_res->res_id);
 			goto err;
 		}
@@ -422,7 +422,7 @@ static int cam_custom_mgr_start_hw(void *hw_mgr_priv,
 		&ctx->res_list_custom_cid, list) {
 		rc = cam_custom_hw_mgr_start_hw_res(hw_mgr_res);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "Can not START CID(id :%d)",
+			CAM_ERR(CAM_CUSTOM, "Can not START CID(id :%d)",
 				hw_mgr_res->res_id);
 			goto err;
 		}
@@ -760,7 +760,7 @@ static int cam_custom_hw_mgr_release_hw_for_ctx(
 		&custom_ctx->res_list_custom_cid, list) {
 		rc = cam_custom_hw_mgr_free_hw_res(hw_mgr_res);
 		if (rc)
-			CAM_ERR(CAM_ISP, "Can not release CID(id :%d)",
+			CAM_ERR(CAM_CUSTOM, "Can not release CID(id :%d)",
 				hw_mgr_res->res_id);
 		cam_custom_hw_mgr_put_res(
 			&custom_ctx->free_res_list, &hw_mgr_res);
@@ -771,7 +771,7 @@ static int cam_custom_hw_mgr_release_hw_for_ctx(
 		&custom_ctx->res_list_custom_csid, list) {
 		rc = cam_custom_hw_mgr_free_hw_res(hw_mgr_res);
 		if (rc)
-			CAM_ERR(CAM_ISP, "Can not release CSID(id :%d)",
+			CAM_ERR(CAM_CUSTOM, "Can not release CSID(id :%d)",
 				hw_mgr_res->res_id);
 		cam_custom_hw_mgr_put_res(
 			&custom_ctx->free_res_list, &hw_mgr_res);
@@ -811,41 +811,82 @@ static int cam_custom_mgr_release_hw(void *hw_mgr_priv,
 	return rc;
 }
 
-static void cam_custom_hw_mgr_acquire_get_unified_dev_str(
-	struct cam_custom_in_port_info *in,
-	struct cam_isp_in_port_generic_info *gen_port_info)
+static int cam_custom_hw_mgr_acquire_get_unified_dev_str(
+	struct cam_custom_acquire_hw_info *acquire_hw_info,
+	uint32_t *input_size,
+	struct cam_isp_in_port_generic_info **gen_port_info)
 {
-	int i;
+	int32_t rc = 0, i;
+	uint32_t in_port_length = 0;
+	struct cam_custom_in_port_info *in = NULL;
+	struct cam_isp_in_port_generic_info *port_info = NULL;
+
+	in = (struct cam_custom_in_port_info *)
+		((uint8_t *)&acquire_hw_info->data +
+		 acquire_hw_info->input_info_offset + *input_size);
+
+	in_port_length = sizeof(struct cam_custom_in_port_info) +
+		(in->num_out_res - 1) *
+		sizeof(struct cam_custom_out_port_info);
+
+	*input_size += in_port_length;
+
+	if ((*input_size) > acquire_hw_info->input_info_size) {
+		CAM_ERR(CAM_CUSTOM, "Input is not proper");
+		rc = -EINVAL;
+		return rc;
+	}
+
+	port_info = kzalloc(
+		sizeof(struct cam_isp_in_port_generic_info), GFP_KERNEL);
+
+	if (!port_info)
+		return -ENOMEM;
 
-	gen_port_info->res_type        =  in->res_type +
+	port_info->res_type        =  in->res_type +
 		CAM_ISP_IFE_IN_RES_BASE - CAM_CUSTOM_IN_RES_BASE;
-	gen_port_info->lane_type       =  in->lane_type;
-	gen_port_info->lane_num        =  in->lane_num;
-	gen_port_info->lane_cfg        =  in->lane_cfg;
-	gen_port_info->vc[0]           =  in->vc[0];
-	gen_port_info->dt[0]           =  in->dt[0];
-	gen_port_info->num_valid_vc_dt =  in->num_valid_vc_dt;
-	gen_port_info->format          =  in->format;
-	gen_port_info->test_pattern    =  in->test_pattern;
-	gen_port_info->usage_type      =  in->usage_type;
-	gen_port_info->left_start      =  in->left_start;
-	gen_port_info->left_stop       =  in->left_stop;
-	gen_port_info->left_width      =  in->left_width;
-	gen_port_info->right_start     =  in->right_start;
-	gen_port_info->right_stop      =  in->right_stop;
-	gen_port_info->right_width     =  in->right_width;
-	gen_port_info->line_start      =  in->line_start;
-	gen_port_info->line_stop       =  in->line_stop;
-	gen_port_info->height          =  in->height;
-	gen_port_info->pixel_clk       =  in->pixel_clk;
-	gen_port_info->cust_node       =  1;
-	gen_port_info->num_out_res     =  in->num_out_res;
-	gen_port_info->num_bytes_out   =  in->num_bytes_out;
+	port_info->lane_type       =  in->lane_type;
+	port_info->lane_num        =  in->lane_num;
+	port_info->lane_cfg        =  in->lane_cfg;
+	port_info->vc[0]           =  in->vc[0];
+	port_info->dt[0]           =  in->dt[0];
+	port_info->num_valid_vc_dt =  in->num_valid_vc_dt;
+	port_info->format          =  in->format;
+	port_info->test_pattern    =  in->test_pattern;
+	port_info->usage_type      =  in->usage_type;
+	port_info->left_start      =  in->left_start;
+	port_info->left_stop       =  in->left_stop;
+	port_info->left_width      =  in->left_width;
+	port_info->right_start     =  in->right_start;
+	port_info->right_stop      =  in->right_stop;
+	port_info->right_width     =  in->right_width;
+	port_info->line_start      =  in->line_start;
+	port_info->line_stop       =  in->line_stop;
+	port_info->height          =  in->height;
+	port_info->pixel_clk       =  in->pixel_clk;
+	port_info->cust_node       =  1;
+	port_info->num_out_res     =  in->num_out_res;
+	port_info->num_bytes_out   =  in->num_bytes_out;
+
+	port_info->data = kcalloc(in->num_out_res,
+		sizeof(struct cam_isp_out_port_generic_info),
+		GFP_KERNEL);
+	if (port_info->data == NULL) {
+		rc = -ENOMEM;
+		goto release_port_mem;
+	}
 
 	for (i = 0; i < in->num_out_res; i++) {
-		gen_port_info->data[i].res_type     = in->data[i].res_type;
-		gen_port_info->data[i].format       = in->data[i].format;
+		port_info->data[i].res_type     = in->data[i].res_type;
+		port_info->data[i].format       = in->data[i].format;
 	}
+
+	*gen_port_info = port_info;
+	return 0;
+
+release_port_mem:
+	kfree(port_info);
+	return rc;
 }
 
 static int cam_custom_mgr_acquire_hw_for_ctx(
@@ -896,18 +937,16 @@ static int cam_custom_mgr_acquire_hw(
 	void *hw_mgr_priv,
 	void *acquire_hw_args)
 {
-	int rc = -1;
-	int32_t i;
-	uint32_t                             in_port_length;
+	int rc = -1, i;
+	uint32_t                             input_size = 0;
 	struct cam_custom_hw_mgr_ctx        *custom_ctx;
 	struct cam_custom_hw_mgr            *custom_hw_mgr;
-	struct cam_hw_acquire_args          *acquire_args =
-		(struct cam_hw_acquire_args *)  acquire_hw_args;
-	struct cam_custom_in_port_info      *in_port_info;
-	struct cam_custom_resource          *custom_rsrc;
+	struct cam_custom_acquire_hw_info   *acquire_hw_info = NULL;
 	struct cam_isp_in_port_generic_info *gen_port_info = NULL;
+	struct cam_hw_acquire_args          *acquire_args =
+		(struct cam_hw_acquire_args *)acquire_hw_args;
 
-	if (!hw_mgr_priv || !acquire_args || (acquire_args->num_acq <= 0)) {
+	if (!hw_mgr_priv || !acquire_args) {
 		CAM_ERR(CAM_CUSTOM, "Invalid params");
 		return -EINVAL;
 	}
@@ -923,127 +962,47 @@ static int cam_custom_mgr_acquire_hw(
 	}
 	mutex_unlock(&g_custom_hw_mgr.ctx_mutex);
 
-	/* Handle Acquire Here */
 	custom_ctx->hw_mgr = custom_hw_mgr;
 	custom_ctx->cb_priv = acquire_args->context_data;
 	custom_ctx->event_cb = acquire_args->event_cb;
 
-	custom_rsrc = kcalloc(acquire_args->num_acq,
-		sizeof(*custom_rsrc), GFP_KERNEL);
-	if (!custom_rsrc) {
-		rc = -ENOMEM;
-		goto free_ctx;
-	}
-
-	CAM_DBG(CAM_CUSTOM, "start copy %d resources from user",
-		acquire_args->num_acq);
+	acquire_hw_info =
+		(struct cam_custom_acquire_hw_info *)acquire_args->acquire_info;
 
-	if (copy_from_user(custom_rsrc,
-		(void __user *)acquire_args->acquire_info,
-		((sizeof(*custom_rsrc)) * acquire_args->num_acq))) {
-		rc = -EFAULT;
-		goto free_ctx;
-	}
+	for (i = 0; i < acquire_hw_info->num_inputs; i++) {
+		rc = cam_custom_hw_mgr_acquire_get_unified_dev_str(
+			acquire_hw_info, &input_size, &gen_port_info);
 
-	for (i = 0; i < acquire_args->num_acq; i++) {
-		if (custom_rsrc[i].resource_id != CAM_CUSTOM_RES_ID_PORT)
-			continue;
-
-		CAM_DBG(CAM_CUSTOM, "acquire no = %d total = %d", i,
-			acquire_args->num_acq);
-
-		CAM_DBG(CAM_CUSTOM,
-			"start copy from user handle %lld with len = %d",
-			custom_rsrc[i].res_hdl,
-			custom_rsrc[i].length);
-
-		in_port_length = sizeof(struct cam_custom_in_port_info);
-		if (in_port_length > custom_rsrc[i].length) {
-			CAM_ERR(CAM_CUSTOM, "buffer size is not enough");
-			rc = -EINVAL;
+		if (rc < 0) {
+			CAM_ERR(CAM_CUSTOM, "Failed in parsing: %d", rc);
 			goto free_res;
 		}
 
-		in_port_info = memdup_user(
-			u64_to_user_ptr(custom_rsrc[i].res_hdl),
-			custom_rsrc[i].length);
-
-		if (!IS_ERR(in_port_info)) {
-			if (in_port_info->num_out_res >
-				CAM_CUSTOM_HW_OUT_RES_MAX) {
-				CAM_ERR(CAM_CUSTOM, "too many output res %d",
-					in_port_info->num_out_res);
-				rc = -EINVAL;
-				kfree(in_port_info);
-				goto free_res;
-			}
-
-			in_port_length =
-				sizeof(struct cam_custom_in_port_info) +
-				(in_port_info->num_out_res - 1) *
-				sizeof(struct cam_custom_out_port_info);
-
-			if (in_port_length > custom_rsrc[i].length) {
-				CAM_ERR(CAM_CUSTOM,
-					"buffer size is not enough");
-				rc = -EINVAL;
-				kfree(in_port_info);
-				goto free_res;
-			}
-
-			gen_port_info = kzalloc(
-				sizeof(struct cam_isp_in_port_generic_info),
-				GFP_KERNEL);
-			if (gen_port_info == NULL) {
-				rc = -ENOMEM;
-				goto free_res;
-			}
-
-			gen_port_info->data = kcalloc(
-				sizeof(struct cam_isp_out_port_generic_info),
-				in_port_info->num_out_res, GFP_KERNEL);
-			if (gen_port_info->data == NULL) {
-				kfree(gen_port_info);
-				gen_port_info = NULL;
-				rc = -ENOMEM;
-				goto free_res;
-			}
-
-			cam_custom_hw_mgr_acquire_get_unified_dev_str(
-				in_port_info, gen_port_info);
-
-			rc = cam_custom_mgr_acquire_hw_for_ctx(custom_ctx,
-				gen_port_info, &acquire_args->acquired_hw_id[i],
-				acquire_args->acquired_hw_path[i]);
-
-			kfree(in_port_info);
-			if (gen_port_info != NULL) {
-				kfree(gen_port_info->data);
-				kfree(gen_port_info);
-				gen_port_info = NULL;
-			}
-
-			if (rc) {
-				CAM_ERR(CAM_CUSTOM, "can not acquire resource");
-				goto free_res;
-			}
-	} else {
-		CAM_ERR(CAM_CUSTOM,
-			"Copy from user failed with in_port = %pK",
-			in_port_info);
-			rc = -EFAULT;
-			goto free_res;
+		CAM_DBG(CAM_CUSTOM, "in_res_type %x", gen_port_info->res_type);
+		rc = cam_custom_mgr_acquire_hw_for_ctx(custom_ctx,
+			gen_port_info, &acquire_args->acquired_hw_id[i],
+			acquire_args->acquired_hw_path[i]);
+		if (rc) {
+			CAM_ERR(CAM_CUSTOM, "can not acquire resource");
+			goto free_mem;
 		}
+
+		kfree(gen_port_info->data);
+		kfree(gen_port_info);
+		gen_port_info = NULL;
 	}
 
 	custom_ctx->ctx_in_use = 1;
 	acquire_args->ctxt_to_hw_map = custom_ctx;
+	cam_custom_hw_mgr_put_ctx(&custom_hw_mgr->used_ctx_list, &custom_ctx);
 	CAM_DBG(CAM_CUSTOM, "Exit...(success)");
 	return 0;
 
+free_mem:
+	kfree(gen_port_info->data);
+	kfree(gen_port_info);
 free_res:
 	cam_custom_hw_mgr_release_hw_for_ctx(custom_ctx);
-free_ctx:
 	cam_custom_hw_mgr_put_ctx(&custom_hw_mgr->free_ctx_list, &custom_ctx);
 err:
 	CAM_DBG(CAM_CUSTOM, "Exit...(rc=%d)", rc);

+ 17 - 0
include/uapi/media/cam_custom.h

@@ -170,6 +170,23 @@ struct cam_custom_resource {
 	uint64_t                       res_hdl;
 };
 
+/**
+ * struct cam_custom_acquire_hw_info - Custom acquire HW params
+ *
+ * @num_inputs           : Number of inputs
+ * @input_info_size      : Size of input info struct used
+ * @input_info_offset    : Offset of input info from start of data
+ * @reserved             : reserved
+ * @data                 : Start of data region
+ */
+struct cam_custom_acquire_hw_info {
+	uint32_t                num_inputs;
+	uint32_t                input_info_size;
+	uint32_t                input_info_offset;
+	uint32_t                reserved;
+	uint64_t                data;
+};
+
 /**
  * struct cam_custom_cmd_buf_type_1 - cmd buf type 1
  *