msm: camera: Use a new reset_complete per VFE

Each VFE can be reset separate from the other. As this can happen during
the reset of the other, it is not reliable to wait on a single
completion.

Also this change completes VFE1 reset_complete on reset done IRQ.

Change-Id: I37177df4d15f04a7fad81b0f62544cd7b50e9d92
Signed-off-by: Vladislav Hristov <vhrist@codeaurora.org>
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
index da512dd..bd7bdb4 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
@@ -97,8 +97,8 @@
 		unsigned long flags;
 
 		spin_lock_irqsave(&ispif->auto_complete_lock, flags);
-		ispif->wait_timeout = 0;
-		init_completion(&ispif->reset_complete);
+		ispif->wait_timeout[params->vfe_intf] = 0;
+		init_completion(&ispif->reset_complete[params->vfe_intf]);
 		spin_unlock_irqrestore(&ispif->auto_complete_lock, flags);
 
 		if (params->vfe_intf == VFE0)
@@ -106,14 +106,15 @@
 		else
 			msm_camera_io_w(data, ispif->base +
 				ISPIF_RST_CMD_1_ADDR);
+
 		lrc = wait_for_completion_interruptible_timeout(
-			&ispif->reset_complete, jiffes);
+			&ispif->reset_complete[params->vfe_intf], jiffes);
 		if (lrc < 0 || !lrc) {
 			pr_err("%s: wait timeout ret = %ld\n", __func__, lrc);
 			rc = -EIO;
 
 			spin_lock_irqsave(&ispif->auto_complete_lock, flags);
-			ispif->wait_timeout = 1;
+			ispif->wait_timeout[params->vfe_intf] = 1;
 			spin_unlock_irqrestore(
 				&ispif->auto_complete_lock, flags);
 		}
@@ -129,8 +130,12 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&ispif->auto_complete_lock, flags);
-	ispif->wait_timeout = 0;
-	init_completion(&ispif->reset_complete);
+	ispif->wait_timeout[VFE0] = 0;
+	init_completion(&ispif->reset_complete[VFE0]);
+	if (ispif->csid_version >= CSID_VERSION_V3) {
+		ispif->wait_timeout[VFE1] = 0;
+		init_completion(&ispif->reset_complete[VFE1]);
+	}
 	spin_unlock_irqrestore(&ispif->auto_complete_lock, flags);
 
 	BUG_ON(!ispif);
@@ -139,22 +144,40 @@
 
 	msm_camera_io_w(ISPIF_RST_CMD_MASK, ispif->base + ISPIF_RST_CMD_ADDR);
 
-	if (ispif->csid_version >= CSID_VERSION_V3)
-		msm_camera_io_w_mb(ISPIF_RST_CMD_1_MASK, ispif->base +
-			ISPIF_RST_CMD_1_ADDR);
-
 	lrc = wait_for_completion_interruptible_timeout(
-		&ispif->reset_complete, jiffes);
+		&ispif->reset_complete[VFE0], jiffes);
 
 	if (lrc < 0 || !lrc) {
 		pr_err("%s: wait timeout ret = %ld\n", __func__, lrc);
 		rc = -EIO;
 
 		spin_lock_irqsave(&ispif->auto_complete_lock, flags);
-		ispif->wait_timeout = 1;
+		ispif->wait_timeout[VFE0] = 1;
 		spin_unlock_irqrestore(&ispif->auto_complete_lock, flags);
+
+		goto end;
 	}
 
+	if (ispif->csid_version >= CSID_VERSION_V3) {
+		msm_camera_io_w_mb(ISPIF_RST_CMD_1_MASK, ispif->base +
+			ISPIF_RST_CMD_1_ADDR);
+
+		lrc = wait_for_completion_interruptible_timeout(
+			&ispif->reset_complete[VFE1], jiffes);
+
+		if (lrc < 0 || !lrc) {
+			pr_err("%s: wait timeout ret = %ld\n", __func__, lrc);
+			rc = -EIO;
+
+			spin_lock_irqsave(&ispif->auto_complete_lock, flags);
+			ispif->wait_timeout[VFE1] = 1;
+			spin_unlock_irqrestore(&ispif->auto_complete_lock,
+				flags);
+		}
+
+	}
+
+end:
 	return rc;
 }
 
@@ -590,8 +613,8 @@
 		if (out[VFE0].ispifIrqStatus0 & RESET_DONE_IRQ) {
 			unsigned long flags;
 			spin_lock_irqsave(&ispif->auto_complete_lock, flags);
-			if (ispif->wait_timeout == 0)
-				complete(&ispif->reset_complete);
+			if (ispif->wait_timeout[VFE0] == 0)
+				complete(&ispif->reset_complete[VFE0]);
 			spin_unlock_irqrestore(
 				&ispif->auto_complete_lock, flags);
 		}
@@ -626,6 +649,16 @@
 		msm_camera_io_w_mb(out[VFE1].ispifIrqStatus2,
 			ispif->base + ISPIF_VFE_m_IRQ_CLEAR_2(VFE1));
 
+
+		if (out[VFE1].ispifIrqStatus0 & RESET_DONE_IRQ) {
+			unsigned long flags;
+			spin_lock_irqsave(&ispif->auto_complete_lock, flags);
+			if (ispif->wait_timeout[VFE1] == 0)
+				complete(&ispif->reset_complete[VFE1]);
+			spin_unlock_irqrestore(
+				&ispif->auto_complete_lock, flags);
+		}
+
 		if (out[VFE1].ispifIrqStatus0 & PIX_INTF_0_OVERFLOW_IRQ)
 			pr_err("%s: VFE1 pix0 overflow.\n", __func__);
 
@@ -897,6 +930,7 @@
 {
 	int rc;
 	struct ispif_device *ispif;
+	int i;
 
 	ispif = kzalloc(sizeof(struct ispif_device), GFP_KERNEL);
 	if (!ispif) {
@@ -955,7 +989,9 @@
 	ispif->ispif_state = ISPIF_POWER_DOWN;
 	ispif->open_cnt = 0;
 	spin_lock_init(&ispif->auto_complete_lock);
-	ispif->wait_timeout = 0;
+	for (i = 0; i < VFE_MAX; i++)
+		ispif->wait_timeout[i] = 0;
+
 	return 0;
 
 error:
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.h b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.h
index f8c3cce..3e2bd66 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.h
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.h
@@ -47,9 +47,9 @@
 	void __iomem *base;
 	struct mutex mutex;
 	uint8_t start_ack_pending;
-	struct completion reset_complete;
+	struct completion reset_complete[VFE_MAX];
 	spinlock_t auto_complete_lock;
-	uint8_t wait_timeout;
+	uint8_t wait_timeout[VFE_MAX];
 	uint32_t csid_version;
 	int enb_dump_reg;
 	uint32_t open_cnt;