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

Commit d2c3c181 authored by Trishansh Bhardwaj's avatar Trishansh Bhardwaj
Browse files

msm: camera: isp: Release HW during shutdown



On userspace crash release device is called without release HW.
In this case release device is failed and HW instance is leaked.

Fix this by releasing HW if not already released.

Change-Id: I88c8df1e08a10d474caef2638c56250e88021bbf
Signed-off-by: default avatarTrishansh Bhardwaj <tbhardwa@codeaurora.org>
parent ce75eabb
Loading
Loading
Loading
Loading
+26 −26
Original line number Diff line number Diff line
@@ -2078,9 +2078,8 @@ static struct cam_ctx_ops
	},
};

/* top level state machine */
static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx,
	struct cam_release_dev_cmd *cmd)
static int __cam_isp_ctx_release_hw_in_top_state(struct cam_context *ctx,
	void *cmd)
{
	int rc = 0;
	struct cam_hw_release_args       rel_arg;
@@ -2088,28 +2087,15 @@ static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx,
		(struct cam_isp_context *) ctx->ctx_priv;
	struct cam_req_mgr_flush_request flush_req;

	if (ctx->link_hdl != -1) {
		CAM_ERR(CAM_ISP, "ctx expects release dev after unlink");
		rc =  -EAGAIN;
		return rc;
	}

	if (cmd && ctx_isp->hw_ctx && ctx_isp->split_acquire) {
		CAM_ERR(CAM_ISP, "ctx expects release HW before release dev");
		return rc;
	}

	if (ctx_isp->hw_ctx) {
		rel_arg.ctxt_to_hw_map = ctx_isp->hw_ctx;
		ctx->hw_mgr_intf->hw_release(ctx->hw_mgr_intf->hw_mgr_priv,
			&rel_arg);
		ctx_isp->hw_ctx = NULL;
	} else {
		CAM_ERR(CAM_ISP, "No hw resources acquired for this ctx");
	}

	ctx->session_hdl = -1;
	ctx->dev_hdl = -1;
	ctx->link_hdl = -1;
	ctx->ctx_crm_intf = NULL;
	ctx_isp->frame_id = 0;
	ctx_isp->active_req_cnt = 0;
	ctx_isp->reported_req_id = 0;
@@ -2121,7 +2107,7 @@ static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx,
	 * But we still add some sanity check code here to help the debug
	 */
	if (!list_empty(&ctx->active_req_list))
		CAM_ERR(CAM_ISP, "Active list is not empty");
		CAM_WARN(CAM_ISP, "Active list is not empty");

	/* Flush all the pending request list  */
	flush_req.type = CAM_REQ_MGR_FLUSH_TYPE_ALL;
@@ -2132,7 +2118,7 @@ static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx,
	spin_lock_bh(&ctx->lock);
	rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, &flush_req);
	spin_unlock_bh(&ctx->lock);
	ctx->state = CAM_CTX_AVAILABLE;
	ctx->state = CAM_CTX_ACQUIRED;

	trace_cam_context_state("ISP", ctx);
	CAM_DBG(CAM_ISP, "Release device success[%u] next state %d",
@@ -2140,8 +2126,9 @@ static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx,
	return rc;
}

static int __cam_isp_ctx_release_hw_in_top_state(struct cam_context *ctx,
	void *cmd)
/* top level state machine */
static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx,
	struct cam_release_dev_cmd *cmd)
{
	int rc = 0;
	struct cam_hw_release_args       rel_arg;
@@ -2149,15 +2136,22 @@ static int __cam_isp_ctx_release_hw_in_top_state(struct cam_context *ctx,
		(struct cam_isp_context *) ctx->ctx_priv;
	struct cam_req_mgr_flush_request flush_req;

	if (cmd && ctx_isp->hw_ctx) {
		CAM_ERR(CAM_ISP, "releasing hw");
		__cam_isp_ctx_release_hw_in_top_state(ctx, NULL);
	}

	if (ctx_isp->hw_ctx) {
		rel_arg.ctxt_to_hw_map = ctx_isp->hw_ctx;
		ctx->hw_mgr_intf->hw_release(ctx->hw_mgr_intf->hw_mgr_priv,
			&rel_arg);
		ctx_isp->hw_ctx = NULL;
	} else {
		CAM_ERR(CAM_ISP, "No hw resources acquired for this ctx");
	}

	ctx->session_hdl = -1;
	ctx->dev_hdl = -1;
	ctx->link_hdl = -1;
	ctx->ctx_crm_intf = NULL;
	ctx_isp->frame_id = 0;
	ctx_isp->active_req_cnt = 0;
	ctx_isp->reported_req_id = 0;
@@ -2169,7 +2163,7 @@ static int __cam_isp_ctx_release_hw_in_top_state(struct cam_context *ctx,
	 * But we still add some sanity check code here to help the debug
	 */
	if (!list_empty(&ctx->active_req_list))
		CAM_WARN(CAM_ISP, "Active list is not empty");
		CAM_ERR(CAM_ISP, "Active list is not empty");

	/* Flush all the pending request list  */
	flush_req.type = CAM_REQ_MGR_FLUSH_TYPE_ALL;
@@ -2180,7 +2174,7 @@ static int __cam_isp_ctx_release_hw_in_top_state(struct cam_context *ctx,
	spin_lock_bh(&ctx->lock);
	rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, &flush_req);
	spin_unlock_bh(&ctx->lock);
	ctx->state = CAM_CTX_ACQUIRED;
	ctx->state = CAM_CTX_AVAILABLE;

	trace_cam_context_state("ISP", ctx);
	CAM_DBG(CAM_ISP, "Release device success[%u] next state %d",
@@ -2898,6 +2892,12 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock(

	CAM_DBG(CAM_ISP, "Stop device success next state %d on ctx %u",
		ctx->state, ctx->ctx_id);

	if (!stop_cmd) {
		rc = __cam_isp_ctx_unlink_in_ready(ctx, NULL);
		if (rc)
			CAM_ERR(CAM_ISP, "Unlink failed rc=%d", rc);
	}
	return rc;
}