diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c index 23e27e1179d1..18961e69aadc 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c @@ -1,4 +1,4 @@ -/* 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 @@ -712,7 +712,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->completion_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; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h index acf0a90ed93d..da8fbb3cd5b9 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h @@ -804,7 +804,8 @@ struct vfe_device { struct mutex core_mutex; spinlock_t shared_data_lock; spinlock_t reg_update_lock; - spinlock_t completion_lock; + spinlock_t reset_completion_lock; + spinlock_t halt_completion_lock; /* Tasklet info */ atomic_t irq_cnt; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c index 850f1b032a8a..f4e4ca6cb6dc 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c @@ -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); } } @@ -767,7 +776,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); @@ -1780,6 +1793,7 @@ static int msm_vfe40_axi_halt(struct vfe_device *vfe_dev, int rc = 0; enum msm_vfe_input_src i; struct msm_isp_timestamp ts; + unsigned long flags; /* Keep only halt and restart mask */ msm_vfe40_config_irq(vfe_dev, (1 << 31), (1 << 8), @@ -1796,7 +1810,9 @@ static int msm_vfe40_axi_halt(struct vfe_device *vfe_dev, msm_isp_stats_stream_update(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( diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c index 0a969cc897b0..ecf0b36e345d 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c @@ -443,10 +443,10 @@ void msm_vfe47_process_reset_irq(struct vfe_device *vfe_dev, unsigned long flags; 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); 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 val = 0; + 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 + 0x400); } @@ -774,9 +777,9 @@ long msm_vfe47_reset_hardware(struct vfe_device *vfe_dev, uint32_t reset; 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); - spin_unlock_irqrestore(&vfe_dev->completion_lock, flags); + spin_unlock_irqrestore(&vfe_dev->reset_completion_lock, flags); if (blocking_call) vfe_dev->reset_pending = 1; @@ -1996,6 +1999,7 @@ int msm_vfe47_axi_halt(struct vfe_device *vfe_dev, enum msm_vfe_input_src i; uint32_t val = 0; struct msm_isp_timestamp ts; + unsigned long flags; val = msm_camera_io_r(vfe_dev->vfe_vbif_base + VFE47_VBIF_CLK_OFFSET); val |= 0x1; @@ -2012,7 +2016,9 @@ int msm_vfe47_axi_halt(struct vfe_device *vfe_dev, __func__, vfe_dev->pdev->id, blocking); 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 + 0x400); rc = wait_for_completion_interruptible_timeout(