msm: camera: Fix camera switch issue

Reset CSI1 clock branches at the time of VFE_RESET to
get START_ACK from VFE block to avoid camera switch
issue from front to back.

Change-Id: I3b097e748544c28450ca772b08e8aa43eca8f769
Signed-off-by: Suresh Vankadara <svankada@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-msm7627a-camera.c b/arch/arm/mach-msm/board-msm7627a-camera.c
index 94b8710..12cd5af 100644
--- a/arch/arm/mach-msm/board-msm7627a-camera.c
+++ b/arch/arm/mach-msm/board-msm7627a-camera.c
@@ -309,6 +309,8 @@
 		platform_device_register(&msm7x27a_device_csic0);
 		platform_device_register(&msm7x27a_device_csic1);
 	}
+	if (machine_is_msm8625_evb())
+		*(int *) msm7x27a_device_clkctl.dev.platform_data = 1;
 	platform_device_register(&msm7x27a_device_clkctl);
 	platform_device_register(&msm7x27a_device_vfe);
 }
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 917500c..1391981 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -608,6 +608,7 @@
 };
 
 #ifdef CONFIG_MSM_CAMERA_V4L2
+static int apps_reset;
 static struct resource msm_csic0_resources[] = {
 	{
 		.name   = "csic",
@@ -665,6 +666,9 @@
 	.id             = 0,
 	.resource       = msm_clkctl_resources,
 	.num_resources  = ARRAY_SIZE(msm_clkctl_resources),
+	.dev = {
+		.platform_data = &apps_reset,
+	},
 };
 
 struct platform_device msm7x27a_device_vfe = {
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 5ee9e1a..8451f78 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -657,6 +657,7 @@
 void msm_camio_camif_pad_reg_reset_2(void);
 
 void msm_camio_vfe_blk_reset(void);
+void msm_camio_vfe_blk_reset_2(int flag);
 
 int32_t msm_camio_3d_enable(const struct msm_camera_sensor_info *sinfo);
 void msm_camio_3d_disable(void);
diff --git a/drivers/media/video/msm/msm_io_7x27a_v4l2.c b/drivers/media/video/msm/msm_io_7x27a_v4l2.c
index 63547c8..8b977ba 100644
--- a/drivers/media/video/msm/msm_io_7x27a_v4l2.c
+++ b/drivers/media/video/msm/msm_io_7x27a_v4l2.c
@@ -29,6 +29,7 @@
 static struct clk *camio_cam_clk;
 static struct resource *clk_ctrl_mem;
 static struct msm_camera_io_clk camio_clk;
+static int apps_reset;
 void __iomem *appbase;
 
 void msm_io_w(u32 data, void __iomem *addr)
@@ -97,18 +98,27 @@
 	clk_set_rate(clk, rate);
 }
 
-void msm_camio_vfe_blk_reset(void)
+void msm_camio_vfe_blk_reset_2(int vfe_apps_reset)
 {
 	uint32_t val;
 
+	if (apps_reset && !vfe_apps_reset)
+		return;
+
 	/* do apps reset */
 	val = readl_relaxed(appbase + 0x00000210);
-	val |= 0x1;
+	if (apps_reset)
+		val |= 0x10A0001;
+	else
+		val |= 0x1;
 	writel_relaxed(val, appbase + 0x00000210);
 	usleep_range(10000, 11000);
 
 	val = readl_relaxed(appbase + 0x00000210);
-	val &= ~0x1;
+	if (apps_reset)
+		val &= ~(0x10A0001);
+	else
+		val &= ~0x1;
 	writel_relaxed(val, appbase + 0x00000210);
 	usleep_range(10000, 11000);
 
@@ -155,6 +165,7 @@
 {
 	int rc = 0;
 
+	apps_reset = *(int *)pdev->dev.platform_data;
 	clk_ctrl_mem = platform_get_resource_byname(pdev,
 					IORESOURCE_MEM, "clk_ctl");
 	if (!clk_ctrl_mem) {
diff --git a/drivers/media/video/msm/msm_vfe7x27a_v4l2.c b/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
index e2236191..acd9158 100644
--- a/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
+++ b/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
@@ -341,6 +341,7 @@
 
 struct mutex vfe_lock;
 static void     *vfe_syncdata;
+static int apps_reset;
 static uint8_t vfestopped;
 
 static struct stop_event stopevent;
@@ -1215,7 +1216,8 @@
 		if (queue == QDSP_CMDQUEUE) {
 			switch (vfecmd.id) {
 			case VFE_CMD_RESET:
-				msm_camio_vfe_blk_reset();
+				msm_camio_vfe_blk_reset_2(apps_reset);
+				apps_reset = 0;
 				vfestopped = 0;
 				break;
 			case VFE_CMD_START:
@@ -1717,7 +1719,7 @@
 	msm_cam_clk_enable(&vfe2x_ctrl->pdev->dev, vfe2x_clk_info,
 			vfe2x_ctrl->vfe_clk, ARRAY_SIZE(vfe2x_clk_info), 0);
 	vfe_syncdata = NULL;
-
+	apps_reset = 1;
 	msm_adsp_disable(qcam_mod);
 	msm_adsp_disable(vfe_mod);