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

Commit 69afdf82 authored by Harsh Shah's avatar Harsh Shah Committed by Gerrit - the friendly Code Review server
Browse files

msm: camera: fd: Protect unbalanced stop and deinit



Change the state on deinit to notify that clocks are OFF. On
unbalanced stop and deinit, we can check this state to prevent
unclocked access.

Change-Id: I8911cecd856c5effcb415dd41d792d123693c3cf
Signed-off-by: default avatarHarsh Shah <harshs@codeaurora.org>
parent c6d00752
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1210,6 +1210,7 @@ static int cam_fd_mgr_hw_release(void *hw_mgr_priv, void *hw_release_args)
	if (rc)
		CAM_ERR(CAM_FD, "Failed in release device, rc=%d", rc);

	hw_ctx->ctx_in_use = false;
	list_del_init(&hw_ctx->list);
	cam_fd_mgr_util_put_ctx(&hw_mgr->free_ctx_list, &hw_ctx);

+16 −5
Original line number Diff line number Diff line
@@ -643,6 +643,7 @@ int cam_fd_hw_init(void *hw_priv, void *init_hw_args, uint32_t arg_size)
	struct cam_fd_hw_init_args *init_args =
		(struct cam_fd_hw_init_args *)init_hw_args;
	int rc = 0;
	unsigned long flags;

	if (!fd_hw || !init_args) {
		CAM_ERR(CAM_FD, "Invalid argument %pK %pK", fd_hw, init_args);
@@ -671,6 +672,11 @@ int cam_fd_hw_init(void *hw_priv, void *init_hw_args, uint32_t arg_size)
		goto unlock_return;
	}

	spin_lock_irqsave(&fd_core->spin_lock, flags);
	fd_hw->hw_state = CAM_HW_STATE_POWER_UP;
	fd_core->core_state = CAM_FD_CORE_STATE_IDLE;
	spin_unlock_irqrestore(&fd_core->spin_lock, flags);

	rc = cam_fd_hw_reset(hw_priv, NULL, 0);
	if (rc) {
		CAM_ERR(CAM_FD, "Reset Failed, rc=%d", rc);
@@ -679,9 +685,6 @@ int cam_fd_hw_init(void *hw_priv, void *init_hw_args, uint32_t arg_size)

	cam_fd_hw_util_enable_power_on_settings(fd_hw);

	fd_hw->hw_state = CAM_HW_STATE_POWER_UP;
	fd_core->core_state = CAM_FD_CORE_STATE_IDLE;

cdm_streamon:
	fd_hw->open_count++;
	CAM_DBG(CAM_FD, "FD HW Init ref count after %d", fd_hw->open_count);
@@ -707,6 +710,11 @@ int cam_fd_hw_init(void *hw_priv, void *init_hw_args, uint32_t arg_size)
disable_soc:
	if (cam_fd_soc_disable_resources(&fd_hw->soc_info))
		CAM_ERR(CAM_FD, "Error in disable soc resources");

	spin_lock_irqsave(&fd_core->spin_lock, flags);
	fd_hw->hw_state = CAM_HW_STATE_POWER_DOWN;
	fd_core->core_state = CAM_FD_CORE_STATE_POWERDOWN;
	spin_unlock_irqrestore(&fd_core->spin_lock, flags);
unlock_return:
	mutex_unlock(&fd_hw->hw_mutex);
	return rc;
@@ -719,6 +727,7 @@ int cam_fd_hw_deinit(void *hw_priv, void *deinit_hw_args, uint32_t arg_size)
	struct cam_fd_hw_deinit_args *deinit_args =
		(struct cam_fd_hw_deinit_args *)deinit_hw_args;
	int rc = 0;
	unsigned long flags;

	if (!fd_hw || !deinit_hw_args) {
		CAM_ERR(CAM_FD, "Invalid argument");
@@ -756,8 +765,9 @@ int cam_fd_hw_deinit(void *hw_priv, void *deinit_hw_args, uint32_t arg_size)
	/* With the ref_cnt correct, this should never happen */
	WARN_ON(!fd_core);

	spin_lock_irqsave(&fd_core->spin_lock, flags);
	fd_core->core_state = CAM_FD_CORE_STATE_POWERDOWN;

	spin_unlock_irqrestore(&fd_core->spin_lock, flags);
positive_ref_cnt:
	if (deinit_args->ctx_hw_private) {
		struct cam_fd_ctx_hw_private *ctx_hw_private =
@@ -794,7 +804,8 @@ int cam_fd_hw_reset(void *hw_priv, void *reset_core_args, uint32_t arg_size)
	soc_info = &fd_hw->soc_info;

	spin_lock_irqsave(&fd_core->spin_lock, flags);
	if (fd_core->core_state == CAM_FD_CORE_STATE_RESET_PROGRESS) {
	if ((fd_core->core_state == CAM_FD_CORE_STATE_POWERDOWN) ||
		(fd_core->core_state == CAM_FD_CORE_STATE_RESET_PROGRESS)) {
		CAM_ERR(CAM_FD, "Reset not allowed in %d state",
			fd_core->core_state);
		spin_unlock_irqrestore(&fd_core->spin_lock, flags);