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

Commit 563c4b40 authored by Srikanth Uyyala's avatar Srikanth Uyyala
Browse files

msm: camera: isp : Fix race condition in close sequence



Serializing reset_hw and reset_irq, to avoid race condition.

Change-Id: I8f21cb816748129bde7f0f1455b203b42603d244
Signed-off-by: default avatarSrikanth Uyyala <suyyala@codeaurora.org>
parent 035363ab
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -679,6 +679,8 @@ int vfe_hw_probe(struct platform_device *pdev)
	spin_lock_init(&vfe_dev->shared_data_lock);
	spin_lock_init(&vfe_dev->reg_update_lock);
	spin_lock_init(&req_history_lock);
	spin_lock_init(&vfe_dev->reset_completion_lock);
	spin_lock_init(&vfe_dev->halt_completion_lock);
	media_entity_init(&vfe_dev->subdev.sd.entity, 0, NULL, 0);
	vfe_dev->subdev.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	vfe_dev->subdev.sd.entity.group_id = MSM_CAMERA_SUBDEV_VFE;
+3 −1
Original line number Diff line number Diff line
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -740,6 +740,8 @@ struct vfe_device {
	struct mutex core_mutex;
	spinlock_t shared_data_lock;
	spinlock_t reg_update_lock;
	spinlock_t reset_completion_lock;
	spinlock_t halt_completion_lock;
	spinlock_t tasklet_lock;

	/* Tasklet info */
+17 −1
Original line number Diff line number Diff line
@@ -370,15 +370,24 @@ static void msm_vfe40_clear_status_reg(struct vfe_device *vfe_dev)
static void msm_vfe40_process_reset_irq(struct vfe_device *vfe_dev,
	uint32_t irq_status0, uint32_t irq_status1)
{
	if (irq_status0 & (1 << 31))
	unsigned long flags;

	if (irq_status0 & (1 << 31)) {
		spin_lock_irqsave(&vfe_dev->reset_completion_lock, flags);
		complete(&vfe_dev->reset_complete);
		spin_unlock_irqrestore(&vfe_dev->reset_completion_lock, flags);
	}
}

static void msm_vfe40_process_halt_irq(struct vfe_device *vfe_dev,
	uint32_t irq_status0, uint32_t irq_status1)
{
	unsigned long flags;

	if (irq_status1 & (1 << 8)) {
		spin_lock_irqsave(&vfe_dev->halt_completion_lock, flags);
		complete(&vfe_dev->halt_complete);
		spin_unlock_irqrestore(&vfe_dev->halt_completion_lock, flags);
		msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x2C0);
	}
}
@@ -768,7 +777,11 @@ static long msm_vfe40_reset_hardware(struct vfe_device *vfe_dev,
	uint32_t first_start, uint32_t blocking_call)
{
	long rc = 0;
	unsigned long flags;

	spin_lock_irqsave(&vfe_dev->reset_completion_lock, flags);
	init_completion(&vfe_dev->reset_complete);
	spin_unlock_irqrestore(&vfe_dev->reset_completion_lock, flags);

	if (first_start) {
		msm_camera_io_w_mb(0x1FF, vfe_dev->vfe_base + 0xC);
@@ -1735,6 +1748,7 @@ static int msm_vfe40_axi_halt(struct vfe_device *vfe_dev,
{
	int rc = 0;
	enum msm_vfe_input_src i;
	unsigned long flags;

	/* Keep only halt and restart mask */
	msm_vfe40_set_halt_restart_mask(vfe_dev);
@@ -1769,7 +1783,9 @@ static int msm_vfe40_axi_halt(struct vfe_device *vfe_dev,
	}

	if (blocking) {
		spin_lock_irqsave(&vfe_dev->halt_completion_lock, flags);
		init_completion(&vfe_dev->halt_complete);
		spin_unlock_irqrestore(&vfe_dev->halt_completion_lock, flags);
		/* Halt AXI Bus Bridge */
		msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2C0);
		rc = wait_for_completion_interruptible_timeout(