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

Commit 9e7f86d6 authored by Jing Zhou's avatar Jing Zhou
Browse files

msm: isp: use proper spin lock on isr and tasklet



When CPU do spin lock irq save, it will disable irq/preemption.
If the same CPU do spin lock (without disabling irq),
then irq context can preempt and acuire the lock hold by user,
which will possibly hang CPU.

Avoid the issue to use spin lock irq save consistantly.

Change-Id: I52e17d189668166ae126dc5948fe51bd79ae9859
Signed-off-by: default avatarPeter Liu <pingchie@codeaurora.org>
Signed-off-by: default avatarJing Zhou <jzhou70@codeaurora.org>
parent 83390eba
Loading
Loading
Loading
Loading
+15 −7
Original line number Diff line number Diff line
@@ -774,6 +774,7 @@ void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type,
	struct msm_vfe_sof_info *sof_info = NULL, *self_sof = NULL;
	enum msm_vfe_dual_hw_ms_type ms_type;
	int i, j;
	unsigned long flags;

	memset(&event_data, 0, sizeof(event_data));

@@ -812,12 +813,14 @@ void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type,
		 */
		if (vfe_dev->axi_data.src_info[frame_src].dual_hw_type ==
			DUAL_HW_MASTER_SLAVE) {
			spin_lock(&vfe_dev->common_data->common_dev_data_lock);
			spin_lock_irqsave(
				&vfe_dev->common_data->common_dev_data_lock,
				flags);
			self_sof = vfe_dev->axi_data.src_info[frame_src].
				dual_hw_ms_info.sof_info;
			if (!self_sof) {
				spin_unlock(&vfe_dev->common_data->
					common_dev_data_lock);
				spin_unlock_irqrestore(&vfe_dev->common_data->
					common_dev_data_lock, flags);
				break;
			}
			ms_type = vfe_dev->axi_data.src_info[frame_src].
@@ -850,8 +853,8 @@ void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type,
					self_sof->mono_timestamp_ms -
					sof_info->mono_timestamp_ms;
			}
			spin_unlock(&vfe_dev->common_data->
				common_dev_data_lock);
			spin_unlock_irqrestore(&vfe_dev->common_data->
				common_dev_data_lock, flags);
		} else
			if (frame_src == VFE_PIX_0) {
				msm_isp_check_for_output_error(vfe_dev, ts,
@@ -2368,6 +2371,7 @@ static int msm_isp_update_dual_HW_ms_info_at_stop(
	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
	enum msm_vfe_input_src stream_src = VFE_SRC_MAX;
	struct msm_vfe_src_info *src_info = NULL;
	unsigned long flags;

	if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM ||
		stream_cfg_cmd->num_streams == 0)
@@ -2391,7 +2395,9 @@ static int msm_isp_update_dual_HW_ms_info_at_stop(
		if (src_info->dual_hw_type != DUAL_HW_MASTER_SLAVE)
			continue;

		spin_lock(&vfe_dev->common_data->common_dev_data_lock);
		spin_lock_irqsave(
			&vfe_dev->common_data->common_dev_data_lock,
			flags);
		if (src_info->dual_hw_ms_info.dual_hw_ms_type ==
			MS_TYPE_MASTER) {
			/*
@@ -2408,7 +2414,9 @@ static int msm_isp_update_dual_HW_ms_info_at_stop(
			vfe_dev->common_data->ms_resource.num_slave--;
		}
		src_info->dual_hw_ms_info.sof_info = NULL;
		spin_unlock(&vfe_dev->common_data->common_dev_data_lock);
		spin_unlock_irqrestore(
			&vfe_dev->common_data->common_dev_data_lock,
			flags);
		vfe_dev->vfe_ub_policy = 0;
	}

+7 −2
Original line number Diff line number Diff line
@@ -718,6 +718,7 @@ static int msm_isp_set_dual_HW_master_slave_mode(
	int rc = 0, i, j;
	struct msm_isp_set_dual_hw_ms_cmd *dual_hw_ms_cmd = NULL;
	struct msm_vfe_src_info *src_info = NULL;
	unsigned long flags;

	if (!vfe_dev || !arg) {
		pr_err("%s: Error! Invalid input vfe_dev %p arg %p\n",
@@ -746,7 +747,9 @@ static int msm_isp_set_dual_HW_master_slave_mode(
		vfe_dev->common_data->ms_resource.sof_delta_threshold =
			dual_hw_ms_cmd->sof_delta_threshold;
	} else if (src_info != NULL) {
		spin_lock(&vfe_dev->common_data->common_dev_data_lock);
		spin_lock_irqsave(
			&vfe_dev->common_data->common_dev_data_lock,
			flags);
		src_info->dual_hw_type = DUAL_HW_MASTER_SLAVE;
		ISP_DBG("%s: Slave\n", __func__);

@@ -765,7 +768,9 @@ static int msm_isp_set_dual_HW_master_slave_mode(
			ISP_DBG("%s: Slave id %d\n", __func__, j);
			break;
		}
		spin_unlock(&vfe_dev->common_data->common_dev_data_lock);
		spin_unlock_irqrestore(
			&vfe_dev->common_data->common_dev_data_lock,
			flags);

		if (j == MS_NUM_SLAVE_MAX) {
			pr_err("%s: Error! Cannot find free aux resource\n",