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

Commit 97fd071b authored by Harsh Shah's avatar Harsh Shah
Browse files

msm: camera: fd: Need to use irqsave for spin_lock



fd_core->spin_lock is used in irq() function, so any other place
using it should call spin_lock_irqsave and spin_unlock_irqrestore.
Without this change, we can have deadlock on this spin_lock.

Change-Id: I2b2f0699a8c8af9c67e3028df10d45b533000259
Signed-off-by: default avatarHarsh Shah <harshs@codeaurora.org>
parent 0f62c596
Loading
Loading
Loading
Loading
+24 −20
Original line number Diff line number Diff line
@@ -424,9 +424,10 @@ static int cam_fd_hw_util_processcmd_frame_done(struct cam_hw_info *fd_hw,
	struct cam_fd_hw_req_private *req_private;
	uint32_t base, face_cnt;
	uint32_t *buffer;
	unsigned long flags;
	int i;

	spin_lock(&fd_core->spin_lock);
	spin_lock_irqsave(&fd_core->spin_lock, flags);
	if ((fd_core->core_state != CAM_FD_CORE_STATE_IDLE) ||
		(fd_core->results_valid == false) ||
		!fd_core->hw_req_private) {
@@ -434,12 +435,12 @@ static int cam_fd_hw_util_processcmd_frame_done(struct cam_hw_info *fd_hw,
			"Invalid state for results state=%d, results=%d %pK",
			fd_core->core_state, fd_core->results_valid,
			fd_core->hw_req_private);
		spin_unlock(&fd_core->spin_lock);
		spin_unlock_irqrestore(&fd_core->spin_lock, flags);
		return -EINVAL;
	}
	fd_core->core_state = CAM_FD_CORE_STATE_READING_RESULTS;
	req_private = fd_core->hw_req_private;
	spin_unlock(&fd_core->spin_lock);
	spin_unlock_irqrestore(&fd_core->spin_lock, flags);

	/*
	 * Copy the register value as is into output buffers.
@@ -511,10 +512,10 @@ static int cam_fd_hw_util_processcmd_frame_done(struct cam_hw_info *fd_hw,
		}
	}

	spin_lock(&fd_core->spin_lock);
	spin_lock_irqsave(&fd_core->spin_lock, flags);
	fd_core->hw_req_private = NULL;
	fd_core->core_state = CAM_FD_CORE_STATE_IDLE;
	spin_unlock(&fd_core->spin_lock);
	spin_unlock_irqrestore(&fd_core->spin_lock, flags);

	return 0;
}
@@ -778,6 +779,7 @@ int cam_fd_hw_reset(void *hw_priv, void *reset_core_args, uint32_t arg_size)
	struct cam_fd_core *fd_core;
	struct cam_fd_hw_static_info *hw_static_info;
	struct cam_hw_soc_info *soc_info;
	unsigned long flags;
	int rc;

	if (!fd_hw) {
@@ -789,17 +791,17 @@ int cam_fd_hw_reset(void *hw_priv, void *reset_core_args, uint32_t arg_size)
	hw_static_info = fd_core->hw_static_info;
	soc_info = &fd_hw->soc_info;

	spin_lock(&fd_core->spin_lock);
	spin_lock_irqsave(&fd_core->spin_lock, flags);
	if (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(&fd_core->spin_lock);
		spin_unlock_irqrestore(&fd_core->spin_lock, flags);
		return -EINVAL;
	}

	fd_core->results_valid = false;
	fd_core->core_state = CAM_FD_CORE_STATE_RESET_PROGRESS;
	spin_unlock(&fd_core->spin_lock);
	spin_unlock_irqrestore(&fd_core->spin_lock, flags);

	cam_fd_soc_register_write(soc_info, CAM_FD_REG_WRAPPER,
		hw_static_info->wrapper_regs.cgc_disable, 0x1);
@@ -819,9 +821,9 @@ int cam_fd_hw_reset(void *hw_priv, void *reset_core_args, uint32_t arg_size)
	cam_fd_soc_register_write(soc_info, CAM_FD_REG_WRAPPER,
		hw_static_info->wrapper_regs.cgc_disable, 0x0);

	spin_lock(&fd_core->spin_lock);
	spin_lock_irqsave(&fd_core->spin_lock, flags);
	fd_core->core_state = CAM_FD_CORE_STATE_IDLE;
	spin_unlock(&fd_core->spin_lock);
	spin_unlock_irqrestore(&fd_core->spin_lock, flags);

	return rc;
}
@@ -834,6 +836,7 @@ int cam_fd_hw_start(void *hw_priv, void *hw_start_args, uint32_t arg_size)
	struct cam_fd_hw_cmd_start_args *start_args =
		(struct cam_fd_hw_cmd_start_args *)hw_start_args;
	struct cam_fd_ctx_hw_private *ctx_hw_private;
	unsigned long flags;
	int rc;

	if (!hw_priv || !start_args) {
@@ -851,11 +854,11 @@ int cam_fd_hw_start(void *hw_priv, void *hw_start_args, uint32_t arg_size)
	fd_core = (struct cam_fd_core *)fd_hw->core_info;
	hw_static_info = fd_core->hw_static_info;

	spin_lock(&fd_core->spin_lock);
	spin_lock_irqsave(&fd_core->spin_lock, flags);
	if (fd_core->core_state != CAM_FD_CORE_STATE_IDLE) {
		CAM_ERR(CAM_FD, "Cannot start in %d state",
			fd_core->core_state);
		spin_unlock(&fd_core->spin_lock);
		spin_unlock_irqrestore(&fd_core->spin_lock, flags);
		return -EINVAL;
	}

@@ -868,7 +871,7 @@ int cam_fd_hw_start(void *hw_priv, void *hw_start_args, uint32_t arg_size)
	fd_core->hw_req_private = start_args->hw_req_private;
	fd_core->core_state = CAM_FD_CORE_STATE_PROCESSING;
	fd_core->results_valid = false;
	spin_unlock(&fd_core->spin_lock);
	spin_unlock_irqrestore(&fd_core->spin_lock, flags);

	ctx_hw_private = start_args->ctx_hw_private;

@@ -913,9 +916,9 @@ int cam_fd_hw_start(void *hw_priv, void *hw_start_args, uint32_t arg_size)

	return 0;
error:
	spin_lock(&fd_core->spin_lock);
	spin_lock_irqsave(&fd_core->spin_lock, flags);
	fd_core->core_state = CAM_FD_CORE_STATE_IDLE;
	spin_unlock(&fd_core->spin_lock);
	spin_unlock_irqrestore(&fd_core->spin_lock, flags);

	return rc;
}
@@ -926,6 +929,7 @@ int cam_fd_hw_halt_reset(void *hw_priv, void *stop_args, uint32_t arg_size)
	struct cam_fd_core *fd_core;
	struct cam_fd_hw_static_info *hw_static_info;
	struct cam_hw_soc_info *soc_info;
	unsigned long flags;
	int rc;

	if (!fd_hw) {
@@ -937,18 +941,18 @@ int cam_fd_hw_halt_reset(void *hw_priv, void *stop_args, uint32_t arg_size)
	hw_static_info = fd_core->hw_static_info;
	soc_info = &fd_hw->soc_info;

	spin_lock(&fd_core->spin_lock);
	spin_lock_irqsave(&fd_core->spin_lock, flags);
	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(&fd_core->spin_lock);
		spin_unlock_irqrestore(&fd_core->spin_lock, flags);
		return -EINVAL;
	}

	fd_core->results_valid = false;
	fd_core->core_state = CAM_FD_CORE_STATE_RESET_PROGRESS;
	spin_unlock(&fd_core->spin_lock);
	spin_unlock_irqrestore(&fd_core->spin_lock, flags);

	cam_fd_soc_register_write(soc_info, CAM_FD_REG_WRAPPER,
		hw_static_info->wrapper_regs.cgc_disable, 0x1);
@@ -969,9 +973,9 @@ int cam_fd_hw_halt_reset(void *hw_priv, void *stop_args, uint32_t arg_size)
	cam_fd_soc_register_write(soc_info, CAM_FD_REG_WRAPPER,
		hw_static_info->wrapper_regs.cgc_disable, 0x0);

	spin_lock(&fd_core->spin_lock);
	spin_lock_irqsave(&fd_core->spin_lock, flags);
	fd_core->core_state = CAM_FD_CORE_STATE_IDLE;
	spin_unlock(&fd_core->spin_lock);
	spin_unlock_irqrestore(&fd_core->spin_lock, flags);

	return rc;
}