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

Commit d0b9300a authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

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

parents db3ab950 e31b52ff
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -707,7 +707,8 @@ int vfe_hw_probe(struct platform_device *pdev)
	spin_lock_init(&vfe_dev->shared_data_lock);
	spin_lock_init(&vfe_dev->shared_data_lock);
	spin_lock_init(&vfe_dev->reg_update_lock);
	spin_lock_init(&vfe_dev->reg_update_lock);
	spin_lock_init(&req_history_lock);
	spin_lock_init(&req_history_lock);
	spin_lock_init(&vfe_dev->completion_lock);
	spin_lock_init(&vfe_dev->reset_completion_lock);
	spin_lock_init(&vfe_dev->halt_completion_lock);
	media_entity_pads_init(&vfe_dev->subdev.sd.entity, 0, NULL);
	media_entity_pads_init(&vfe_dev->subdev.sd.entity, 0, NULL);
	vfe_dev->subdev.sd.entity.function = MSM_CAMERA_SUBDEV_VFE;
	vfe_dev->subdev.sd.entity.function = MSM_CAMERA_SUBDEV_VFE;
	//vfe_dev->subdev.sd.entity.group_id = MSM_CAMERA_SUBDEV_VFE;
	//vfe_dev->subdev.sd.entity.group_id = MSM_CAMERA_SUBDEV_VFE;
+2 −1
Original line number Original line Diff line number Diff line
@@ -817,7 +817,8 @@ struct vfe_device {
	struct mutex core_mutex;
	struct mutex core_mutex;
	spinlock_t shared_data_lock;
	spinlock_t shared_data_lock;
	spinlock_t reg_update_lock;
	spinlock_t reg_update_lock;
	spinlock_t completion_lock;
	spinlock_t reset_completion_lock;
	spinlock_t halt_completion_lock;


	/* Tasklet info */
	/* Tasklet info */
	atomic_t irq_cnt;
	atomic_t irq_cnt;
+16 −1
Original line number Original line Diff line number Diff line
@@ -363,15 +363,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,
static void msm_vfe40_process_reset_irq(struct vfe_device *vfe_dev,
	uint32_t irq_status0, uint32_t irq_status1)
	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);
		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,
static void msm_vfe40_process_halt_irq(struct vfe_device *vfe_dev,
	uint32_t irq_status0, uint32_t irq_status1)
	uint32_t irq_status0, uint32_t irq_status1)
{
{
	unsigned long flags;

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


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


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


	/* Keep only halt and restart mask */
	/* Keep only halt and restart mask */
	msm_vfe40_config_irq(vfe_dev, (1 << 31), (1 << 8),
	msm_vfe40_config_irq(vfe_dev, (1 << 31), (1 << 8),
@@ -1793,7 +1806,9 @@ static int msm_vfe40_axi_halt(struct vfe_device *vfe_dev,
	msm_isp_stats_stream_update(vfe_dev);
	msm_isp_stats_stream_update(vfe_dev);


	if (blocking) {
	if (blocking) {
		spin_lock_irqsave(&vfe_dev->halt_completion_lock, flags);
		init_completion(&vfe_dev->halt_complete);
		init_completion(&vfe_dev->halt_complete);
		spin_unlock_irqrestore(&vfe_dev->halt_completion_lock, flags);
		/* Halt AXI Bus Bridge */
		/* Halt AXI Bus Bridge */
		msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2C0);
		msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2C0);
		rc = wait_for_completion_interruptible_timeout(
		rc = wait_for_completion_interruptible_timeout(
+10 −4
Original line number Original line Diff line number Diff line
@@ -443,10 +443,10 @@ void msm_vfe47_process_reset_irq(struct vfe_device *vfe_dev,
	unsigned long flags;
	unsigned long flags;


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


@@ -454,9 +454,12 @@ void msm_vfe47_process_halt_irq(struct vfe_device *vfe_dev,
	uint32_t irq_status0, uint32_t irq_status1)
	uint32_t irq_status0, uint32_t irq_status1)
{
{
	uint32_t val = 0;
	uint32_t val = 0;
	unsigned long flags;


	if (irq_status1 & (1 << 8)) {
	if (irq_status1 & (1 << 8)) {
		spin_lock_irqsave(&vfe_dev->halt_completion_lock, flags);
		complete(&vfe_dev->halt_complete);
		complete(&vfe_dev->halt_complete);
		spin_unlock_irqrestore(&vfe_dev->halt_completion_lock, flags);
		msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x400);
		msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x400);
	}
	}


@@ -775,9 +778,9 @@ long msm_vfe47_reset_hardware(struct vfe_device *vfe_dev,
	uint32_t reset;
	uint32_t reset;
	unsigned long flags;
	unsigned long flags;


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


	if (blocking_call)
	if (blocking_call)
		vfe_dev->reset_pending = 1;
		vfe_dev->reset_pending = 1;
@@ -2032,6 +2035,7 @@ int msm_vfe47_axi_halt(struct vfe_device *vfe_dev,
	enum msm_vfe_input_src i;
	enum msm_vfe_input_src i;
	uint32_t val = 0;
	uint32_t val = 0;
	struct msm_isp_timestamp ts;
	struct msm_isp_timestamp ts;
	unsigned long flags;


	val = msm_camera_io_r(vfe_dev->vfe_vbif_base + VFE47_VBIF_CLK_OFFSET);
	val = msm_camera_io_r(vfe_dev->vfe_vbif_base + VFE47_VBIF_CLK_OFFSET);
	val |= 0x1;
	val |= 0x1;
@@ -2048,7 +2052,9 @@ int msm_vfe47_axi_halt(struct vfe_device *vfe_dev,
			__func__, vfe_dev->pdev->id, blocking);
			__func__, vfe_dev->pdev->id, blocking);


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