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

Commit d106f065 authored by Harsh Shah's avatar Harsh Shah
Browse files

msm: camera: core: Cleanup the logic for shutdown



Before calling release, we need to check the state to avoid
unnecessary release and putref, which would lead to underflow
of refcnt. Also, this change will set the dev and link handles
to non-zero so that the release is complete.

Change-Id: Idffab593dff16288f37b52ba2b98ff9c03df0386
Signed-off-by: default avatarHarsh Shah <harshs@codeaurora.org>
parent f52774d8
Loading
Loading
Loading
Loading
+23 −14
Original line number Diff line number Diff line
@@ -42,25 +42,34 @@ static int cam_context_handle_hw_event(void *context, uint32_t evt_id,
int cam_context_shutdown(struct cam_context *ctx)
{
	int rc = 0;
	int32_t ctx_hdl = ctx->dev_hdl;
	struct cam_release_dev_cmd cmd;

	mutex_lock(&ctx->ctx_mutex);
	if (ctx->state_machine[ctx->state].ioctl_ops.stop_dev) {
		rc = ctx->state_machine[ctx->state].ioctl_ops.stop_dev(
			ctx, NULL);
		if (rc < 0)
			CAM_ERR(CAM_CORE, "Error while dev stop %d", rc);
	}
	if (ctx->state_machine[ctx->state].ioctl_ops.release_dev) {
		rc = ctx->state_machine[ctx->state].ioctl_ops.release_dev(
			ctx, NULL);
		if (rc < 0)
			CAM_ERR(CAM_CORE, "Error while dev release %d", rc);
	if (ctx->state > CAM_CTX_AVAILABLE && ctx->state < CAM_CTX_STATE_MAX) {
		cmd.session_handle = ctx->session_hdl;
		cmd.dev_handle = ctx->dev_hdl;
		rc = cam_context_handle_release_dev(ctx, &cmd);
		if (rc)
			CAM_ERR(CAM_CORE,
				"context release failed for dev_name %s",
				ctx->dev_name);
		else
			cam_context_putref(ctx);
	} else {
		CAM_WARN(CAM_CORE,
			"dev %s context id %u state %d invalid to release hdl",
			ctx->dev_name, ctx->ctx_id, ctx->state);
		rc = -EINVAL;
	}
	mutex_unlock(&ctx->ctx_mutex);

	if (!rc)
		rc = cam_destroy_device_hdl(ctx_hdl);
	rc = cam_destroy_device_hdl(ctx->dev_hdl);
	if (rc)
		CAM_ERR(CAM_CORE, "destroy device hdl failed for node %s",
			ctx->dev_name);
	else
		ctx->dev_hdl = -1;

	return rc;
}

+2 −3
Original line number Diff line number Diff line
@@ -344,6 +344,8 @@ static int __cam_node_handle_release_dev(struct cam_node *node,
	if (rc)
		CAM_ERR(CAM_CORE, "destroy device hdl failed for node %s",
			node->name);
	else
		ctx->dev_hdl = -1;

	CAM_DBG(CAM_CORE, "[%s] Release ctx_id=%d, refcount=%d",
		node->name, ctx->ctx_id,
@@ -510,9 +512,6 @@ int cam_node_shutdown(struct cam_node *node)
				"Node [%s] invoking shutdown on context [%d]",
				node->name, i);
			rc = cam_context_shutdown(&(node->ctx_list[i]));
			if (rc)
				continue;
			cam_context_putref(&(node->ctx_list[i]));
		}
	}

+3 −2
Original line number Diff line number Diff line
@@ -2315,7 +2315,8 @@ static int __cam_req_mgr_unlink(struct cam_req_mgr_core_link *link)
	if (rc < 0) {
		CAM_ERR(CAM_CRM, "error destroying link hdl %x rc %d",
			link->link_hdl, rc);
	}
	} else
		link->link_hdl = -1;

	mutex_unlock(&link->lock);
	return rc;
@@ -2472,7 +2473,7 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info)
	__cam_req_mgr_destroy_subdev(link->l_dev);
create_subdev_failed:
	cam_destroy_device_hdl(link->link_hdl);
	link_info->link_hdl = 0;
	link_info->link_hdl = -1;
link_hdl_fail:
	mutex_unlock(&link->lock);
	__cam_req_mgr_unreserve_link(cam_session, link);