Merge changes I09afb2dc,Ia37263f0 into msm-3.0

* changes:
  msm: Select ENABLE_HOLES_IN_ZONE
  arm: Add HOLES_IN_ZONE option
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 253a238..0cef857 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -199,6 +199,9 @@
 	obj-$(CONFIG_ARCH_MSM9615) += cpuidle.o
 endif
 
+ifdef CONFIG_MSM_CAMERA_V4L2
+	obj-$(CONFIG_ARCH_MSM8X60) += board-msm8x60-camera.o
+endif
 obj-$(CONFIG_ARCH_FSM9XXX) += devices-fsm9xxx.o
 obj-$(CONFIG_ARCH_FSM9XXX) += clock-fsm9xxx.o clock-local.o acpuclock-fsm9xxx.o
 obj-$(CONFIG_ARCH_FSM9XXX) += dfe-fsm9xxx.o rfic-fsm9xxx.o
diff --git a/arch/arm/mach-msm/board-msm8x60-camera.c b/arch/arm/mach-msm/board-msm8x60-camera.c
new file mode 100644
index 0000000..95561e4
--- /dev/null
+++ b/arch/arm/mach-msm/board-msm8x60-camera.c
@@ -0,0 +1,471 @@
+/* Copyright (c) 2012 Code Aurora Forum. 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <asm/mach-types.h>
+#include <devices-msm8x60.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/mfd/pmic8901.h>
+#include <mach/board.h>
+#include <mach/board-msm8660.h>
+#include <mach/gpiomux.h>
+#include <mach/msm_bus_board.h>
+#include "devices.h"
+
+#define GPIO_EXT_CAMIF_PWR_EN1 (PM8901_MPP_BASE + PM8901_MPPS + 13)
+#ifdef CONFIG_MSM_CAMERA_FLASH
+#define VFE_CAMIF_TIMER1_GPIO 29
+#define VFE_CAMIF_TIMER2_GPIO 30
+#define VFE_CAMIF_TIMER3_GPIO_INT 31
+#define FUSION_VFE_CAMIF_TIMER1_GPIO 42
+
+static struct msm_camera_sensor_flash_src msm_flash_src = {
+	.flash_sr_type = MSM_CAMERA_FLASH_SRC_PMIC,
+	._fsrc.pmic_src.num_of_src = 2,
+	._fsrc.pmic_src.low_current  = 100,
+	._fsrc.pmic_src.high_current = 300,
+	._fsrc.pmic_src.led_src_1 = PMIC8058_ID_FLASH_LED_0,
+	._fsrc.pmic_src.led_src_2 = PMIC8058_ID_FLASH_LED_1,
+	._fsrc.pmic_src.pmic_set_current = pm8058_set_flash_led_current,
+};
+static struct msm_camera_sensor_strobe_flash_data strobe_flash_xenon = {
+	.flash_trigger = VFE_CAMIF_TIMER2_GPIO,
+	.flash_charge = VFE_CAMIF_TIMER1_GPIO,
+	.flash_charge_done = VFE_CAMIF_TIMER3_GPIO_INT,
+	.flash_recharge_duration = 50000,
+	.irq = MSM_GPIO_TO_INT(VFE_CAMIF_TIMER3_GPIO_INT),
+};
+#endif
+
+static struct msm_bus_vectors cam_init_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_SMI,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_SMI,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_SMI,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+};
+
+static struct msm_bus_vectors cam_preview_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_SMI,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 283115520,
+		.ib  = 452984832,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_SMI,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_SMI,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+};
+
+static struct msm_bus_vectors cam_video_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_SMI,
+		.ab  = 283115520,
+		.ib  = 452984832,
+	},
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 283115520,
+		.ib  = 452984832,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_SMI,
+		.ab  = 319610880,
+		.ib  = 511377408,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_SMI,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+};
+
+static struct msm_bus_vectors cam_snapshot_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_SMI,
+		.ab  = 566231040,
+		.ib  = 905969664,
+	},
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 69984000,
+		.ib  = 111974400,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_SMI,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_SMI,
+		.ab  = 320864256,
+		.ib  = 513382810,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 320864256,
+		.ib  = 513382810,
+	},
+};
+
+static struct msm_bus_vectors cam_zsl_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_SMI,
+		.ab  = 566231040,
+		.ib  = 905969664,
+	},
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 706199040,
+		.ib  = 1129918464,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_SMI,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_SMI,
+		.ab  = 320864256,
+		.ib  = 513382810,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 320864256,
+		.ib  = 513382810,
+	},
+};
+
+static struct msm_bus_vectors cam_stereo_video_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_SMI,
+		.ab  = 212336640,
+		.ib  = 339738624,
+	},
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 25090560,
+		.ib  = 40144896,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_SMI,
+		.ab  = 239708160,
+		.ib  = 383533056,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 79902720,
+		.ib  = 127844352,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_SMI,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+};
+
+static struct msm_bus_vectors cam_stereo_snapshot_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_SMI,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 300902400,
+		.ib  = 481443840,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_SMI,
+		.ab  = 230307840,
+		.ib  = 368492544,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 245113344,
+		.ib  = 392181351,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_SMI,
+		.ab  = 106536960,
+		.ib  = 170459136,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 106536960,
+		.ib  = 170459136,
+	},
+};
+
+static struct msm_bus_paths cam_bus_client_config[] = {
+	{
+		ARRAY_SIZE(cam_init_vectors),
+		cam_zsl_vectors,
+	},
+	{
+		ARRAY_SIZE(cam_preview_vectors),
+		cam_zsl_vectors,
+	},
+	{
+		ARRAY_SIZE(cam_video_vectors),
+		cam_zsl_vectors,
+	},
+	{
+		ARRAY_SIZE(cam_snapshot_vectors),
+		cam_snapshot_vectors,
+	},
+	{
+		ARRAY_SIZE(cam_zsl_vectors),
+		cam_zsl_vectors,
+	},
+	{
+		ARRAY_SIZE(cam_stereo_video_vectors),
+		cam_stereo_video_vectors,
+	},
+	{
+		ARRAY_SIZE(cam_stereo_snapshot_vectors),
+		cam_stereo_snapshot_vectors,
+	},
+};
+
+static struct msm_bus_scale_pdata cam_bus_client_pdata = {
+		cam_bus_client_config,
+		ARRAY_SIZE(cam_bus_client_config),
+		.name = "msm_camera",
+};
+
+static struct msm_camera_device_platform_data msm_camera_csi_device_data[] = {
+	{
+		.csid_core = 0,
+		.is_csic = 1,
+		.is_vpe    = 1,
+		.cam_bus_scale_table = &cam_bus_client_pdata,
+		.ioclk = {
+			.vfe_clk_rate =	228570000,
+		},
+	},
+	{
+		.csid_core = 1,
+		.is_csic = 1,
+		.is_vpe    = 1,
+		.cam_bus_scale_table = &cam_bus_client_pdata,
+		.ioclk = {
+			.vfe_clk_rate =	228570000,
+		},
+	},
+};
+static struct camera_vreg_t msm_8x60_back_cam_vreg[] = {
+	{"cam_vana", REG_LDO, 2850000, 2850000, -1},
+	{"cam_vio", REG_VS, 0, 0, 0},
+	{"cam_vdig", REG_LDO, 1200000, 1200000, -1},
+};
+
+static struct gpio msm8x60_common_cam_gpio[] = {
+	{32, GPIOF_DIR_IN, "CAMIF_MCLK"},
+	{47, GPIOF_DIR_IN, "CAMIF_I2C_DATA"},
+	{48, GPIOF_DIR_IN, "CAMIF_I2C_CLK"},
+	{105, GPIOF_DIR_IN, "STANDBY"},
+	{GPIO_EXT_CAMIF_PWR_EN1, GPIOF_DIR_OUT, "CAMIF_PWR_EN"},
+};
+
+static struct gpio msm8x60_back_cam_gpio[] = {
+	{106, GPIOF_DIR_OUT, "CAM_RESET"},
+};
+
+static struct msm_gpio_set_tbl msm8x60_back_cam_gpio_set_tbl[] = {
+	{GPIO_EXT_CAMIF_PWR_EN1, GPIOF_OUT_INIT_LOW, 10000},
+	{GPIO_EXT_CAMIF_PWR_EN1, GPIOF_OUT_INIT_HIGH, 5000},
+	{106, GPIOF_OUT_INIT_LOW, 1000},
+	{106, GPIOF_OUT_INIT_HIGH, 4000},
+};
+
+static struct msm_camera_gpio_conf msm_8x60_back_cam_gpio_conf = {
+	.cam_gpio_common_tbl = msm8x60_common_cam_gpio,
+	.cam_gpio_common_tbl_size = ARRAY_SIZE(msm8x60_common_cam_gpio),
+	.cam_gpio_req_tbl = msm8x60_back_cam_gpio,
+	.cam_gpio_req_tbl_size = ARRAY_SIZE(msm8x60_back_cam_gpio),
+	.cam_gpio_set_tbl = msm8x60_back_cam_gpio_set_tbl,
+	.cam_gpio_set_tbl_size = ARRAY_SIZE(msm8x60_back_cam_gpio_set_tbl),
+};
+
+
+static struct i2c_board_info imx074_actuator_i2c_info = {
+	I2C_BOARD_INFO("imx074_act", 0x11),
+};
+
+static struct msm_actuator_info imx074_actuator_info = {
+	.board_info     = &imx074_actuator_i2c_info,
+	.bus_id         = MSM_GSBI4_QUP_I2C_BUS_ID,
+	.vcm_pwd        = 0,
+	.vcm_enable     = 1,
+};
+
+static struct msm_camera_sensor_flash_data flash_imx074 = {
+	.flash_type	= MSM_CAMERA_FLASH_LED,
+#ifdef CONFIG_MSM_CAMERA_FLASH
+	.flash_src	= &msm_flash_src,
+#endif
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_imx074 = {
+	.mount_angle	= 0,
+	.cam_vreg = msm_8x60_back_cam_vreg,
+	.num_vreg = ARRAY_SIZE(msm_8x60_back_cam_vreg),
+	.gpio_conf = &msm_8x60_back_cam_gpio_conf,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_imx074_data = {
+	.sensor_name	= "imx074",
+	.pdata	= &msm_camera_csi_device_data[0],
+	.flash_data	= &flash_imx074,
+	.strobe_flash_data = &strobe_flash_xenon,
+	.sensor_platform_info = &sensor_board_info_imx074,
+	.csi_if	= 1,
+	.camera_type = BACK_CAMERA_2D,
+	.actuator_info = &imx074_actuator_info
+};
+
+void __init msm8x60_init_cam(void)
+{
+	platform_device_register(&msm_device_csic0);
+	platform_device_register(&msm_device_csic1);
+	platform_device_register(&msm_device_vfe);
+	platform_device_register(&msm_device_vpe);
+}
+
+#ifdef CONFIG_I2C
+static struct i2c_board_info msm8x60_camera_i2c_boardinfo[] = {
+	{
+	I2C_BOARD_INFO("imx074", 0x1A),
+	.platform_data = &msm_camera_sensor_imx074_data,
+	},
+};
+
+struct msm_camera_board_info msm8x60_camera_board_info = {
+	.board_info = msm8x60_camera_i2c_boardinfo,
+	.num_i2c_board_info = ARRAY_SIZE(msm8x60_camera_i2c_boardinfo),
+};
+#endif
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 5db8de4..9497735 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -1562,6 +1562,7 @@
 #endif
 
 #ifdef CONFIG_MSM_VPE
+#ifndef CONFIG_MSM_CAMERA_V4L2
 static struct resource msm_vpe_resources[] = {
 	{
 		.start	= 0x05300000,
@@ -1582,8 +1583,10 @@
 	.resource = msm_vpe_resources,
 };
 #endif
+#endif
 
 #ifdef CONFIG_MSM_CAMERA
+#ifndef CONFIG_MSM_CAMERA_V4L2
 #ifdef CONFIG_MSM_CAMERA_FLASH
 #define VFE_CAMIF_TIMER1_GPIO 29
 #define VFE_CAMIF_TIMER2_GPIO 30
@@ -2486,6 +2489,7 @@
 	#endif
 };
 #endif
+#endif
 
 #ifdef CONFIG_MSM_GEMINI
 static struct resource msm_gemini_resources[] = {
@@ -3868,6 +3872,7 @@
 };
 static struct regulator_consumer_supply vreg_consumers_PM8058_L15[] = {
 	REGULATOR_SUPPLY("8058_l15",		NULL),
+	REGULATOR_SUPPLY("cam_vana",		"1-001a"),
 };
 static struct regulator_consumer_supply vreg_consumers_PM8058_L16[] = {
 	REGULATOR_SUPPLY("8058_l16",		NULL),
@@ -3898,6 +3903,7 @@
 };
 static struct regulator_consumer_supply vreg_consumers_PM8058_L25[] = {
 	REGULATOR_SUPPLY("8058_l25",		NULL),
+	REGULATOR_SUPPLY("cam_vdig",		"1-001a"),
 };
 static struct regulator_consumer_supply vreg_consumers_PM8058_S0[] = {
 	REGULATOR_SUPPLY("8058_s0",		NULL),
@@ -3916,6 +3922,7 @@
 };
 static struct regulator_consumer_supply vreg_consumers_PM8058_LVS0[] = {
 	REGULATOR_SUPPLY("8058_lvs0",		NULL),
+	REGULATOR_SUPPLY("cam_vio",			"1-001a"),
 };
 static struct regulator_consumer_supply vreg_consumers_PM8058_LVS1[] = {
 	REGULATOR_SUPPLY("8058_lvs1",		NULL),
@@ -4279,6 +4286,7 @@
 	&hdmi_msm_device,
 #endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
 #ifdef CONFIG_MSM_CAMERA
+#ifndef CONFIG_MSM_CAMERA_V4L2
 #ifdef CONFIG_MT9E013
 	&msm_camera_sensor_mt9e013,
 #endif
@@ -4298,12 +4306,15 @@
 	&msm_camera_sensor_qs_s5k4e1,
 #endif
 #endif
+#endif
 #ifdef CONFIG_MSM_GEMINI
 	&msm_gemini_device,
 #endif
 #ifdef CONFIG_MSM_VPE
+#ifndef CONFIG_MSM_CAMERA_V4L2
 	&msm_vpe_device,
 #endif
+#endif
 	&msm_device_vidc,
 };
 
@@ -5223,6 +5234,7 @@
 	&mipi_dsi_novatek_panel_device,
 #endif
 #ifdef CONFIG_MSM_CAMERA
+#ifndef CONFIG_MSM_CAMERA_V4L2
 #ifdef CONFIG_MT9E013
 	&msm_camera_sensor_mt9e013,
 #endif
@@ -5242,12 +5254,15 @@
 	&msm_camera_sensor_vx6953,
 #endif
 #endif
+#endif
 #ifdef CONFIG_MSM_GEMINI
 	&msm_gemini_device,
 #endif
 #ifdef CONFIG_MSM_VPE
+#ifndef CONFIG_MSM_CAMERA_V4L2
 	&msm_vpe_device,
 #endif
+#endif
 
 #if defined(CONFIG_MSM_RPM_LOG) || defined(CONFIG_MSM_RPM_LOG_MODULE)
 	&msm8660_rpm_log_device,
@@ -7245,6 +7260,7 @@
 	},
 #endif
 #ifdef CONFIG_MSM_CAMERA
+#ifndef CONFIG_MSM_CAMERA_V4L2
 	{
 		I2C_SURF | I2C_FFA | I2C_FLUID ,
 		MSM_GSBI4_QUP_I2C_BUS_ID,
@@ -7258,6 +7274,7 @@
 		ARRAY_SIZE(msm_camera_dragon_boardinfo),
 	},
 #endif
+#endif
 	{
 		I2C_SURF | I2C_FFA | I2C_FLUID,
 		MSM_GSBI7_QUP_I2C_BUS_ID,
@@ -7340,6 +7357,14 @@
 #ifdef CONFIG_I2C
 	u8 mach_mask = 0;
 	int i;
+#ifdef CONFIG_MSM_CAMERA_V4L2
+	struct i2c_registry msm8x60_camera_i2c_devices = {
+		I2C_SURF | I2C_FFA | I2C_FLUID,
+		MSM_GSBI4_QUP_I2C_BUS_ID,
+		msm8x60_camera_board_info.board_info,
+		msm8x60_camera_board_info.num_i2c_board_info,
+	};
+#endif
 
 	/* Build the matching 'supported_machs' bitmask */
 	if (machine_is_msm8x60_surf() || machine_is_msm8x60_fusion())
@@ -7364,6 +7389,12 @@
 						msm8x60_i2c_devices[i].info,
 						msm8x60_i2c_devices[i].len);
 	}
+#ifdef CONFIG_MSM_CAMERA_V4L2
+	if (msm8x60_camera_i2c_devices.machs & mach_mask)
+		i2c_register_board_info(msm8x60_camera_i2c_devices.bus,
+			msm8x60_camera_i2c_devices.info,
+			msm8x60_camera_i2c_devices.len);
+#endif
 #endif
 }
 
@@ -10323,8 +10354,12 @@
 	msm8x60_init_tlmm();
 	msm8x60_init_gpiomux(board_data->gpiomux_cfgs);
 	msm8x60_init_uart12dm();
+#ifdef CONFIG_MSM_CAMERA_V4L2
+	msm8x60_init_cam();
+#endif
 	msm8x60_init_mmc();
 
+
 #if defined(CONFIG_PMIC8058_OTHC) || defined(CONFIG_PMIC8058_OTHC_MODULE)
 	msm8x60_init_pm8058_othc();
 #endif
@@ -10335,13 +10370,13 @@
 		pm8058_platform_data.keypad_pdata = &dragon_keypad_data;
 	else
 		pm8058_platform_data.keypad_pdata = &ffa_keypad_data;
-
+#ifndef CONFIG_MSM_CAMERA_V4L2
 	/* Specify reset pin for OV9726 */
 	if (machine_is_msm8x60_dragon()) {
 		msm_camera_sensor_ov9726_data.sensor_reset = 62;
 		ov9726_sensor_8660_info.mount_angle = 270;
 	}
-
+#endif
 #ifdef CONFIG_BATTERY_MSM8X60
 	if (machine_is_msm8x60_surf() || machine_is_msm8x60_ffa() ||
 		machine_is_msm8x60_fusion() || machine_is_msm8x60_dragon() ||
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index c724414..3bfb5a3 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -3612,6 +3612,7 @@
 	CLK_LOOKUP("csi_clk",		csi0_clk.c,		NULL),
 	CLK_LOOKUP("csi_clk",		csi1_clk.c, "msm_camera_ov7692.0"),
 	CLK_LOOKUP("csi_clk",		csi1_clk.c, "msm_camera_ov9726.0"),
+	CLK_LOOKUP("csi_clk",		csi1_clk.c, "msm_csic.1"),
 	CLK_LOOKUP("csi_src_clk",	csi_src_clk.c,		NULL),
 	CLK_LOOKUP("dsi_byte_div_clk",	dsi_byte_clk.c,		NULL),
 	CLK_LOOKUP("dsi_esc_clk",	dsi_esc_clk.c,		NULL),
@@ -3649,6 +3650,7 @@
 	CLK_LOOKUP("csi_vfe_clk",	csi0_vfe_clk.c,		NULL),
 	CLK_LOOKUP("csi_vfe_clk",	csi1_vfe_clk.c, "msm_camera_ov7692.0"),
 	CLK_LOOKUP("csi_vfe_clk",	csi1_vfe_clk.c, "msm_camera_ov9726.0"),
+	CLK_LOOKUP("csi_vfe_clk",	csi1_vfe_clk.c, "msm_csic.1"),
 	CLK_LOOKUP("vfe_clk",		vfe_clk.c,		NULL),
 	CLK_LOOKUP("core_clk",		vfe_clk.c,	"footswitch-8x60.8"),
 	CLK_LOOKUP("bus_clk",		vfe_axi_clk.c,	"footswitch-8x60.8"),
@@ -3662,6 +3664,7 @@
 	CLK_LOOKUP("csi_pclk",		csi0_p_clk.c,		NULL),
 	CLK_LOOKUP("csi_pclk",		csi1_p_clk.c, "msm_camera_ov7692.0"),
 	CLK_LOOKUP("csi_pclk",		csi1_p_clk.c, "msm_camera_ov9726.0"),
+	CLK_LOOKUP("csi_pclk",		csi1_p_clk.c,		"msm_csic.1"),
 	CLK_LOOKUP("dsi_m_pclk",	dsi_m_p_clk.c,		NULL),
 	CLK_LOOKUP("dsi_s_pclk",	dsi_s_p_clk.c,		NULL),
 	CLK_LOOKUP("iface_clk",		gfx2d0_p_clk.c,	"kgsl-2d0.0"),
diff --git a/arch/arm/mach-msm/devices-msm8x60.c b/arch/arm/mach-msm/devices-msm8x60.c
index ba7ac2a..84ba9fe 100644
--- a/arch/arm/mach-msm/devices-msm8x60.c
+++ b/arch/arm/mach-msm/devices-msm8x60.c
@@ -1378,6 +1378,98 @@
 	return platform_device_register(pdev);
 }
 
+#ifdef CONFIG_MSM_CAMERA_V4L2
+static struct resource msm_csic0_resources[] = {
+	{
+		.name   = "csic",
+		.start  = 0x04800000,
+		.end    = 0x04800000 + 0x00000400 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "csic",
+		.start  = CSI_0_IRQ,
+		.end    = CSI_0_IRQ,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource msm_csic1_resources[] = {
+	{
+		.name   = "csic",
+		.start  = 0x04900000,
+		.end    = 0x04900000 + 0x00000400 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "csic",
+		.start  = CSI_1_IRQ,
+		.end    = CSI_1_IRQ,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+struct resource msm_vfe_resources[] = {
+	{
+		.name   = "msm_vfe",
+		.start	= 0x04500000,
+		.end	= 0x04500000 + SZ_1M - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name   = "msm_vfe",
+		.start	= VFE_IRQ,
+		.end	= VFE_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct resource msm_vpe_resources[] = {
+	{
+		.name   = "vpe",
+		.start	= 0x05300000,
+		.end	= 0x05300000 + SZ_1M - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name   = "vpe",
+		.start	= INT_VPE,
+		.end	= INT_VPE,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device msm_device_csic0 = {
+	.name           = "msm_csic",
+	.id             = 0,
+	.resource       = msm_csic0_resources,
+	.num_resources  = ARRAY_SIZE(msm_csic0_resources),
+};
+
+struct platform_device msm_device_csic1 = {
+	.name           = "msm_csic",
+	.id             = 1,
+	.resource       = msm_csic1_resources,
+	.num_resources  = ARRAY_SIZE(msm_csic1_resources),
+};
+
+struct platform_device msm_device_vfe = {
+	.name           = "msm_vfe",
+	.id             = 0,
+	.resource       = msm_vfe_resources,
+	.num_resources  = ARRAY_SIZE(msm_vfe_resources),
+};
+
+struct platform_device msm_device_vpe = {
+	.name           = "msm_vpe",
+	.id             = 0,
+	.resource       = msm_vpe_resources,
+	.num_resources  = ARRAY_SIZE(msm_vpe_resources),
+};
+
+#endif
+
+
 #define MIPI_DSI_HW_BASE	0x04700000
 #define ROTATOR_HW_BASE		0x04E00000
 #define TVENC_HW_BASE		0x04F00000
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 29e4dd0..624debd 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -356,3 +356,9 @@
 extern struct platform_device msm_bus_8930_mm_fabric;
 extern struct platform_device msm_bus_8930_sys_fpb;
 extern struct platform_device msm_bus_8930_cpss_fpb;
+
+extern struct platform_device msm_device_csic0;
+extern struct platform_device msm_device_csic1;
+extern struct platform_device msm_device_vfe;
+extern struct platform_device msm_device_vpe;
+
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
index b055f4e..087227c 100644
--- a/arch/arm/mach-msm/dma.c
+++ b/arch/arm/mach-msm/dma.c
@@ -61,17 +61,16 @@
 	size_t sd_size;
 	struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
 	struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
-	struct mutex lock;
-	spinlock_t list_lock;
+	spinlock_t lock;
 	unsigned int irq;
 	struct clk *clk;
 	struct clk *pclk;
 	struct clk *ebiclk;
 	unsigned int clk_ctl;
-	struct delayed_work work;
+	struct timer_list timer;
 };
 
-static void msm_dmov_clock_work(struct work_struct *);
+static void msm_dmov_clock_timer(unsigned long);
 static int msm_dmov_clk_toggle(int, int);
 
 #ifdef CONFIG_ARCH_MSM8X60
@@ -164,19 +163,15 @@
 	{
 		.crci_conf = adm0_crci_conf,
 		.chan_conf = adm0_chan_conf,
-		.lock = __MUTEX_INITIALIZER(dmov_conf[0].lock),
-		.list_lock = __SPIN_LOCK_UNLOCKED(dmov_list_lock),
+		.lock = __SPIN_LOCK_UNLOCKED(dmov_lock),
 		.clk_ctl = CLK_DIS,
-		.work = __DELAYED_WORK_INITIALIZER(dmov_conf[0].work,
-				msm_dmov_clock_work),
+		.timer = TIMER_INITIALIZER(msm_dmov_clock_timer, 0, 0),
 	}, {
 		.crci_conf = adm1_crci_conf,
 		.chan_conf = adm1_chan_conf,
-		.lock = __MUTEX_INITIALIZER(dmov_conf[1].lock),
-		.list_lock = __SPIN_LOCK_UNLOCKED(dmov_list_lock),
+		.lock = __SPIN_LOCK_UNLOCKED(dmov_lock),
 		.clk_ctl = CLK_DIS,
-		.work = __DELAYED_WORK_INITIALIZER(dmov_conf[1].work,
-				msm_dmov_clock_work),
+		.timer = TIMER_INITIALIZER(msm_dmov_clock_timer, 0, 1),
 	}
 };
 #else
@@ -184,11 +179,9 @@
 	{
 		.crci_conf = NULL,
 		.chan_conf = NULL,
-		.lock = __MUTEX_INITIALIZER(dmov_conf[0].lock),
-		.list_lock = __SPIN_LOCK_UNLOCKED(dmov_list_lock),
+		.lock = __SPIN_LOCK_UNLOCKED(dmov_lock),
 		.clk_ctl = CLK_DIS,
-		.work = __DELAYED_WORK_INITIALIZER(dmov_conf[0].work,
-				msm_dmov_clock_work),
+		.timer = TIMER_INITIALIZER(msm_dmov_clock_timer, 0, 0),
 	}
 };
 #endif
@@ -264,18 +257,16 @@
 	return ret;
 }
 
-static void msm_dmov_clock_work(struct work_struct *work)
+static void msm_dmov_clock_timer(unsigned long adm)
 {
-	struct msm_dmov_conf *conf =
-		container_of(to_delayed_work(work), struct msm_dmov_conf, work);
-	int adm = DMOV_IRQ_TO_ADM(conf->irq);
-	mutex_lock(&conf->lock);
-	if (conf->clk_ctl == CLK_TO_BE_DIS) {
-		BUG_ON(conf->channel_active);
+	unsigned long irq_flags;
+	spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
+	if (dmov_conf[adm].clk_ctl == CLK_TO_BE_DIS) {
+		BUG_ON(dmov_conf[adm].channel_active);
 		msm_dmov_clk_toggle(adm, 0);
-		conf->clk_ctl = CLK_DIS;
+		dmov_conf[adm].clk_ctl = CLK_DIS;
 	}
-	mutex_unlock(&conf->lock);
+	spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
 }
 
 void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful)
@@ -287,83 +278,48 @@
 }
 EXPORT_SYMBOL(msm_dmov_stop_cmd);
 
-/* Caller must hold the list lock */
-static void start_ready_cmd(unsigned ch, int adm)
+void msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd)
 {
-	struct msm_dmov_cmd *cmd;
-
-	if (list_empty(&dmov_conf[adm].ready_commands[ch]))
-		return;
-
-	cmd = list_entry(dmov_conf[adm].ready_commands[ch].next, typeof(*cmd),
-			 list);
-	list_del(&cmd->list);
-	if (cmd->exec_func)
-		cmd->exec_func(cmd);
-	list_add_tail(&cmd->list, &dmov_conf[adm].active_commands[ch]);
-	if (!dmov_conf[adm].channel_active)
-		enable_irq(dmov_conf[adm].irq);
-	dmov_conf[adm].channel_active |= BIT(ch);
-	PRINT_IO("msm dmov enqueue command %x\n", cmd->cmdptr);
-	writel_relaxed(cmd->cmdptr, DMOV_REG(DMOV_CMD_PTR(ch), adm));
-}
-
-static void msm_dmov_enqueue_cmd_ext_work(struct work_struct *work)
-{
-	struct msm_dmov_cmd *cmd =
-		container_of(work, struct msm_dmov_cmd, work);
-	unsigned id = cmd->id;
-	unsigned status;
-	unsigned long flags;
+	unsigned long irq_flags;
+	unsigned int status;
 	int adm = DMOV_ID_TO_ADM(id);
 	int ch = DMOV_ID_TO_CHAN(id);
 
-	mutex_lock(&dmov_conf[adm].lock);
+	spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
 	if (dmov_conf[adm].clk_ctl == CLK_DIS) {
 		status = msm_dmov_clk_toggle(adm, 1);
 		if (status != 0)
 			goto error;
 	} else if (dmov_conf[adm].clk_ctl == CLK_TO_BE_DIS)
-		cancel_delayed_work_sync(&dmov_conf[adm].work);
+		del_timer(&dmov_conf[adm].timer);
 	dmov_conf[adm].clk_ctl = CLK_EN;
 
-	spin_lock_irqsave(&dmov_conf[adm].list_lock, flags);
-
 	status = readl_relaxed(DMOV_REG(DMOV_STATUS(ch), adm));
 	if (status & DMOV_STATUS_CMD_PTR_RDY) {
 		PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n",
 			id, status);
-		start_ready_cmd(ch, adm);
+		if (cmd->exec_func)
+			cmd->exec_func(cmd);
+		list_add_tail(&cmd->list, &dmov_conf[adm].active_commands[ch]);
+		if (!dmov_conf[adm].channel_active)
+			enable_irq(dmov_conf[adm].irq);
+		dmov_conf[adm].channel_active |= 1U << ch;
+		PRINT_IO("Writing %x exactly to register", cmd->cmdptr);
+		writel_relaxed(cmd->cmdptr, DMOV_REG(DMOV_CMD_PTR(ch), adm));
 	} else {
-		if (list_empty(&dmov_conf[adm].active_commands[ch]) &&
-		    !list_empty(&dmov_conf[adm].ready_commands[ch]))
+		if (!dmov_conf[adm].channel_active) {
+			dmov_conf[adm].clk_ctl = CLK_TO_BE_DIS;
+			mod_timer(&dmov_conf[adm].timer, jiffies + HZ);
+		}
+		if (list_empty(&dmov_conf[adm].active_commands[ch]))
 			PRINT_ERROR("msm_dmov_enqueue_cmd_ext(%d), stalled, "
 				"status %x\n", id, status);
 		PRINT_IO("msm_dmov_enqueue_cmd(%d), enqueue command, status "
 		    "%x\n", id, status);
+		list_add_tail(&cmd->list, &dmov_conf[adm].ready_commands[ch]);
 	}
-	if (!dmov_conf[adm].channel_active) {
-		dmov_conf[adm].clk_ctl = CLK_TO_BE_DIS;
-		schedule_delayed_work(&dmov_conf[adm].work, HZ);
-	}
-	spin_unlock_irqrestore(&dmov_conf[adm].list_lock, flags);
 error:
-	mutex_unlock(&dmov_conf[adm].lock);
-}
-
-void msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd)
-{
-	int adm = DMOV_ID_TO_ADM(id);
-	int ch = DMOV_ID_TO_CHAN(id);
-	unsigned long flags;
-	cmd->id = id;
-	INIT_WORK(&cmd->work, msm_dmov_enqueue_cmd_ext_work);
-
-	spin_lock_irqsave(&dmov_conf[adm].list_lock, flags);
-	list_add_tail(&cmd->list, &dmov_conf[adm].ready_commands[ch]);
-	spin_unlock_irqrestore(&dmov_conf[adm].list_lock, flags);
-
-	schedule_work(&cmd->work);
+	spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
 }
 EXPORT_SYMBOL(msm_dmov_enqueue_cmd_ext);
 
@@ -381,14 +337,14 @@
 	unsigned long irq_flags;
 	int ch = DMOV_ID_TO_CHAN(id);
 	int adm = DMOV_ID_TO_ADM(id);
-	spin_lock_irqsave(&dmov_conf[adm].list_lock, irq_flags);
+	spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
 	/* XXX not checking if flush cmd sent already */
 	if (!list_empty(&dmov_conf[adm].active_commands[ch])) {
 		PRINT_IO("msm_dmov_flush(%d), send flush cmd\n", id);
 		writel_relaxed(DMOV_FLUSH_TYPE, DMOV_REG(DMOV_FLUSH0(ch), adm));
 	}
 	/* spin_unlock_irqrestore has the necessary barrier */
-	spin_unlock_irqrestore(&dmov_conf[adm].list_lock, irq_flags);
+	spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
 }
 EXPORT_SYMBOL(msm_dmov_flush);
 
@@ -450,7 +406,7 @@
 	errdata->flush[5] = readl_relaxed(DMOV_REG(DMOV_FLUSH5(ch), adm));
 }
 
-static irqreturn_t msm_dmov_isr(int irq, void *dev_id)
+static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
 {
 	unsigned int int_status;
 	unsigned int mask;
@@ -463,12 +419,11 @@
 	struct msm_dmov_cmd *cmd;
 	int adm = DMOV_IRQ_TO_ADM(irq);
 
-	mutex_lock(&dmov_conf[adm].lock);
+	spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
 	/* read and clear isr */
 	int_status = readl_relaxed(DMOV_REG(DMOV_ISR, adm));
 	PRINT_FLOW("msm_datamover_irq_handler: DMOV_ISR %x\n", int_status);
 
-	spin_lock_irqsave(&dmov_conf[adm].list_lock, irq_flags);
 	while (int_status) {
 		mask = int_status & -int_status;
 		ch = fls(mask) - 1;
@@ -536,40 +491,50 @@
 			ch_status = readl_relaxed(DMOV_REG(DMOV_STATUS(ch),
 						  adm));
 			PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
-			if (ch_status & DMOV_STATUS_CMD_PTR_RDY) {
-				start_ready_cmd(ch, adm);
+			if ((ch_status & DMOV_STATUS_CMD_PTR_RDY) &&
+			    !list_empty(&dmov_conf[adm].ready_commands[ch])) {
+				cmd = list_entry(dmov_conf[adm].
+					ready_commands[ch].next, typeof(*cmd),
+					list);
+				list_del(&cmd->list);
+				if (cmd->exec_func)
+					cmd->exec_func(cmd);
+				list_add_tail(&cmd->list,
+					&dmov_conf[adm].active_commands[ch]);
 				PRINT_FLOW("msm_datamover_irq_handler id %d, start command\n", id);
+				writel_relaxed(cmd->cmdptr,
+					       DMOV_REG(DMOV_CMD_PTR(ch), adm));
 			}
 		} while (ch_status & DMOV_STATUS_RSLT_VALID);
 		if (list_empty(&dmov_conf[adm].active_commands[ch]) &&
-		    list_empty(&dmov_conf[adm].ready_commands[ch]))
+				list_empty(&dmov_conf[adm].ready_commands[ch]))
 			dmov_conf[adm].channel_active &= ~(1U << ch);
 		PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
 	}
-	spin_unlock_irqrestore(&dmov_conf[adm].list_lock, irq_flags);
 
 	if (!dmov_conf[adm].channel_active && valid) {
 		disable_irq_nosync(dmov_conf[adm].irq);
 		dmov_conf[adm].clk_ctl = CLK_TO_BE_DIS;
-		schedule_delayed_work(&dmov_conf[adm].work, HZ);
+		mod_timer(&dmov_conf[adm].timer, jiffies + HZ);
 	}
 
-	mutex_unlock(&dmov_conf[adm].lock);
+	spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
 	return valid ? IRQ_HANDLED : IRQ_NONE;
 }
 
 static int msm_dmov_suspend_late(struct device *dev)
 {
+	unsigned long irq_flags;
 	struct platform_device *pdev = to_platform_device(dev);
 	int adm = (pdev->id >= 0) ? pdev->id : 0;
-	mutex_lock(&dmov_conf[adm].lock);
+	spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
 	if (dmov_conf[adm].clk_ctl == CLK_TO_BE_DIS) {
 		BUG_ON(dmov_conf[adm].channel_active);
-		cancel_delayed_work_sync(&dmov_conf[adm].work);
+		del_timer(&dmov_conf[adm].timer);
 		msm_dmov_clk_toggle(adm, 0);
 		dmov_conf[adm].clk_ctl = CLK_DIS;
 	}
-	mutex_unlock(&dmov_conf[adm].lock);
+	spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
 	return 0;
 }
 
@@ -684,8 +649,8 @@
 	if (!dmov_conf[adm].base)
 		return -ENOMEM;
 
-	ret = request_threaded_irq(dmov_conf[adm].irq, NULL, msm_dmov_isr,
-				   IRQF_ONESHOT, "msmdatamover", NULL);
+	ret = request_irq(dmov_conf[adm].irq, msm_datamover_irq_handler,
+		0, "msmdatamover", NULL);
 	if (ret) {
 		PRINT_ERROR("Requesting ADM%d irq %d failed\n", adm,
 			dmov_conf[adm].irq);
diff --git a/arch/arm/mach-msm/include/mach/board-msm8660.h b/arch/arm/mach-msm/include/mach/board-msm8660.h
index b07cc62..22e378c 100644
--- a/arch/arm/mach-msm/include/mach/board-msm8660.h
+++ b/arch/arm/mach-msm/include/mach/board-msm8660.h
@@ -33,4 +33,9 @@
 #define PM8901_IRQ_BASE				(PM8058_IRQ_BASE + \
 						NR_PMIC8058_IRQS)
 
+#ifdef CONFIG_MSM_CAMERA_V4L2
+extern struct msm_camera_board_info msm8x60_camera_board_info;
+void msm8x60_init_cam(void);
+#endif
+
 #endif
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index ba038cb..5ee9e1a 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -200,12 +200,14 @@
 	struct msm_camera_csiphy_params csiphy_params;
 };
 
+#ifndef CONFIG_MSM_CAMERA_V4L2
 #define VFE31_OUTPUT_MODE_PT (0x1 << 0)
 #define VFE31_OUTPUT_MODE_S (0x1 << 1)
 #define VFE31_OUTPUT_MODE_V (0x1 << 2)
 #define VFE31_OUTPUT_MODE_P (0x1 << 3)
 #define VFE31_OUTPUT_MODE_T (0x1 << 4)
 #define VFE31_OUTPUT_MODE_P_ALL_CHNLS (0x1 << 5)
+#endif
 
 #define CSI_EMBED_DATA 0x12
 #define CSI_YUV422_8  0x1E
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h
index 6e58ebe..d170f5f 100644
--- a/arch/arm/mach-msm/include/mach/dma.h
+++ b/arch/arm/mach-msm/include/mach/dma.h
@@ -1,7 +1,7 @@
 /* linux/include/asm-arm/arch-msm/dma.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -35,8 +35,6 @@
 			      unsigned int result,
 			      struct msm_dmov_errdata *err);
 	void (*exec_func)(struct msm_dmov_cmd *cmd);
-	struct work_struct work;
-	unsigned id;    /* For internal use */
 	void *user;	/* Pointer for caller's reference */
 };
 
diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c
index a5e52be..4f3c7e4 100644
--- a/arch/arm/mach-msm/pm2.c
+++ b/arch/arm/mach-msm/pm2.c
@@ -565,7 +565,7 @@
 		__raw_writel(0, APPS_CLK_SLEEP_EN);
 		mb();
 
-		if (cpu_is_msm8625()) {
+		if (cpu_is_msm8625() && power_collapsed) {
 			/*
 			 * enable the SCU while coming out of power
 			 * collapse.
@@ -1089,6 +1089,8 @@
 	unsigned long saved_acpuclk_rate;
 	int collapsed = 0;
 	int ret;
+	int val;
+	int modem_early_exit = 0;
 
 	MSM_PM_DPRINTK(MSM_PM_DEBUG_SUSPEND|MSM_PM_DEBUG_POWER_COLLAPSE,
 		KERN_INFO, "%s(): idle %d, delay %u, limit %u\n", __func__,
@@ -1194,8 +1196,25 @@
 #endif
 
 	collapsed = msm_pm_collapse();
-	if (collapsed)
-		power_collapsed = 1;
+
+	/*
+	 * TBD: Currently recognise the MODEM early exit
+	 * path by reading the MPA5_GDFS_CNT_VAL register.
+	 */
+	if (cpu_is_msm8625()) {
+		/*
+		 * on system reset default value of MPA5_GDFS_CNT_VAL
+		 * is = 0xFF, later power driver reprogrammed this
+		 * as: 0x000300FF. Currently based on the value of
+		 * MPA5_GDFS_CNT_VAL register decide whether it is
+		 * a modem early exit are not.
+		 */
+		val = __raw_readl(MSM_CFG_CTL_BASE + 0x38);
+		if (val != 0xFF)
+			modem_early_exit = 1;
+		else
+			power_collapsed = 1;
+	}
 
 #ifdef CONFIG_CACHE_L2X0
 	l2x0_resume(collapsed);
@@ -1256,7 +1275,7 @@
 	}
 
 	/* Sanity check */
-	if (collapsed) {
+	if (collapsed && !modem_early_exit) {
 		BUG_ON(!(state_grps[0].value_read & DEM_MASTER_SMSM_RSA));
 	} else {
 		BUG_ON(!(state_grps[0].value_read &
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index d960eaf..7c451a9 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -334,7 +334,8 @@
 	do_gettimeofday(&(b->start));
 }
 
-void kgsl_pwrctrl_clk(struct kgsl_device *device, int state)
+void kgsl_pwrctrl_clk(struct kgsl_device *device, int state,
+					  int requested_state)
 {
 	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
 	int i = 0;
@@ -346,7 +347,7 @@
 				if (pwr->grp_clks[i])
 					clk_disable(pwr->grp_clks[i]);
 			if ((pwr->pwrlevels[0].gpu_freq > 0) &&
-				(device->requested_state != KGSL_STATE_NAP))
+				(requested_state != KGSL_STATE_NAP))
 				clk_set_rate(pwr->grp_clks[0],
 					pwr->pwrlevels[pwr->num_pwrlevels - 1].
 					gpu_freq);
@@ -698,8 +699,8 @@
 			return -EBUSY;
 		}
 		kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
-		kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF);
-		kgsl_pwrctrl_set_state(device, device->requested_state);
+		kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF, KGSL_STATE_NAP);
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_NAP);
 		if (device->idle_wakelock.name)
 			wake_unlock(&device->idle_wakelock);
 	case KGSL_STATE_NAP:
@@ -741,7 +742,7 @@
 				pwr->pwrlevels[pwr->num_pwrlevels - 1].
 				gpu_freq);
 		_sleep_accounting(device);
-		kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF);
+		kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF, KGSL_STATE_SLEEP);
 		kgsl_pwrctrl_set_state(device, KGSL_STATE_SLEEP);
 		wake_unlock(&device->idle_wakelock);
 		pm_qos_update_request(&device->pm_qos_req_dma,
@@ -845,7 +846,7 @@
 		/* fall through */
 	case KGSL_STATE_NAP:
 		/* Turn on the core clocks */
-		kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_ON);
+		kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_ON, KGSL_STATE_ACTIVE);
 		/* Enable state before turning on irq */
 		kgsl_pwrctrl_set_state(device, KGSL_STATE_ACTIVE);
 		kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON);
@@ -871,7 +872,7 @@
 {
 	/* Order pwrrail/clk sequence based upon platform */
 	kgsl_pwrctrl_pwrrail(device, KGSL_PWRFLAGS_ON);
-	kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_ON);
+	kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_ON, KGSL_STATE_ACTIVE);
 	kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_ON);
 }
 EXPORT_SYMBOL(kgsl_pwrctrl_enable);
@@ -880,7 +881,7 @@
 {
 	/* Order pwrrail/clk sequence based upon platform */
 	kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_OFF);
-	kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF);
+	kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF, KGSL_STATE_SLEEP);
 	kgsl_pwrctrl_pwrrail(device, KGSL_PWRFLAGS_OFF);
 }
 EXPORT_SYMBOL(kgsl_pwrctrl_disable);
diff --git a/drivers/hwmon/pm8xxx-adc.c b/drivers/hwmon/pm8xxx-adc.c
index 2f59235..6bef3d3 100644
--- a/drivers/hwmon/pm8xxx-adc.c
+++ b/drivers/hwmon/pm8xxx-adc.c
@@ -239,6 +239,7 @@
 
 	if (arb_cntrl) {
 		data_arb_cntrl |= PM8XXX_ADC_ARB_USRP_CNTRL1_REQ;
+		INIT_COMPLETION(adc_pmic->adc_rslt_completion);
 		rc = pm8xxx_writeb(adc_pmic->dev->parent,
 			PM8XXX_ADC_ARB_USRP_CNTRL1, data_arb_cntrl);
 	} else
@@ -336,7 +337,6 @@
 static int32_t pm8xxx_adc_configure(
 				struct pm8xxx_adc_amux_properties *chan_prop)
 {
-	struct pm8xxx_adc *adc_pmic = pmic_adc;
 	u8 data_amux_chan = 0, data_arb_rsv = 0, data_dig_param = 0;
 	int rc;
 
@@ -395,9 +395,6 @@
 	if (rc < 0)
 		return rc;
 
-	if (!pm8xxx_adc_calib_first_adc)
-		enable_irq(adc_pmic->adc_irq);
-
 	rc = pm8xxx_adc_arb_cntrl(1, data_amux_chan);
 	if (rc < 0) {
 		pr_err("Configuring ADC Arbiter"
@@ -476,16 +473,21 @@
 	spin_unlock_irqrestore(&adc_pmic->btm_lock, flags);
 }
 
+void trigger_completion(struct work_struct *work)
+{
+	struct pm8xxx_adc *adc_8xxx = pmic_adc;
+
+	complete(&adc_8xxx->adc_rslt_completion);
+}
+DECLARE_WORK(trigger_completion_work, trigger_completion);
+
 static irqreturn_t pm8xxx_adc_isr(int irq, void *dev_id)
 {
-	struct pm8xxx_adc *adc_8xxx = dev_id;
-
-	disable_irq_nosync(adc_8xxx->adc_irq);
 
 	if (pm8xxx_adc_calib_first_adc)
 		return IRQ_HANDLED;
-	/* TODO Handle spurius interrupt condition */
-	complete(&adc_8xxx->adc_rslt_completion);
+
+	schedule_work(&trigger_completion_work);
 
 	return IRQ_HANDLED;
 }
@@ -1214,10 +1216,10 @@
 	if (rc) {
 		dev_err(&pdev->dev, "failed to request adc irq "
 						"with error %d\n", rc);
+	} else {
+		enable_irq_wake(adc_pmic->adc_irq);
 	}
 
-	disable_irq_nosync(adc_pmic->adc_irq);
-
 	adc_pmic->btm_warm_irq = platform_get_irq(pdev, PM8XXX_ADC_IRQ_1);
 	if (adc_pmic->btm_warm_irq < 0)
 		return adc_pmic->btm_warm_irq;
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index 45b0134..198298b 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -56,6 +56,7 @@
 			rc-norwood.o \
 			rc-npgtech.o \
 			rc-pctv-sedna.o \
+			rc-philips.o \
 			rc-pinnacle-color.o \
 			rc-pinnacle-grey.o \
 			rc-pinnacle-pctv-hd.o \
diff --git a/drivers/media/rc/keymaps/rc-philips.c b/drivers/media/rc/keymaps/rc-philips.c
new file mode 100644
index 0000000..ff2caf9
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-philips.c
@@ -0,0 +1,81 @@
+/* Copyright (c) 2012, Code Aurora Forum. 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <media/rc-map.h>
+
+static struct rc_map_table philips[] = {
+
+	{ 0x00, KEY_NUMERIC_0 },
+	{ 0x01, KEY_NUMERIC_1 },
+	{ 0x02, KEY_NUMERIC_2 },
+	{ 0x03, KEY_NUMERIC_3 },
+	{ 0x04, KEY_NUMERIC_4 },
+	{ 0x05, KEY_NUMERIC_5 },
+	{ 0x06, KEY_NUMERIC_6 },
+	{ 0x07, KEY_NUMERIC_7 },
+	{ 0x08, KEY_NUMERIC_8 },
+	{ 0x09, KEY_NUMERIC_9 },
+	{ 0xF4, KEY_SOUND },
+	{ 0xF3, KEY_SCREEN },	/* Picture */
+
+	{ 0x10, KEY_VOLUMEUP },
+	{ 0x11, KEY_VOLUMEDOWN },
+	{ 0x0d, KEY_MUTE },
+	{ 0x20, KEY_CHANNELUP },
+	{ 0x21, KEY_CHANNELDOWN },
+	{ 0x0A, KEY_BACK },
+	{ 0x0f, KEY_INFO },
+	{ 0x5c, KEY_OK },
+	{ 0x58, KEY_UP },
+	{ 0x59, KEY_DOWN },
+	{ 0x5a, KEY_LEFT },
+	{ 0x5b, KEY_RIGHT },
+	{ 0xcc, KEY_PAUSE },
+	{ 0x6d, KEY_PVR },	/* Demo */
+	{ 0x40, KEY_EXIT },
+	{ 0x6e, KEY_PROG1 },	/* Scenea */
+	{ 0x6f, KEY_MODE },	/* Dual */
+	{ 0x70, KEY_SLEEP },
+	{ 0xf5, KEY_TUNER },	/* Format */
+
+	{ 0x4f, KEY_TV },
+	{ 0x3c, KEY_NEW },	/* USB */
+	{ 0x38, KEY_COMPOSE },	/* Source */
+	{ 0x54, KEY_MENU },
+
+	{ 0x0C, KEY_POWER },
+};
+
+static struct rc_map_list rc6_philips_map = {
+	.map = {
+		.scan    = philips,
+		.size    = ARRAY_SIZE(philips),
+		.rc_type = RC_TYPE_RC6,
+		.name    = RC_MAP_RC6_PHILIPS,
+	}
+};
+
+static int __init init_rc_map_rc6_philips(void)
+{
+	return rc_map_register(&rc6_philips_map);
+}
+
+static void __exit exit_rc_map_rc6_philips(void)
+{
+	rc_map_unregister(&rc6_philips_map);
+}
+
+module_init(init_rc_map_rc6_philips)
+module_exit(exit_rc_map_rc6_philips)
+
+MODULE_DESCRIPTION("Philips Remote Keymap ");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/Kconfig b/drivers/media/video/msm/Kconfig
index ec034b1..c00f4c6 100644
--- a/drivers/media/video/msm/Kconfig
+++ b/drivers/media/video/msm/Kconfig
@@ -82,7 +82,7 @@
 #	This uses the CSI interface.
 config VX6953
 	bool "Sensor VX6953 (BAYER 5M)"
-	depends on MSM_CAMERA && (ARCH_MSM7X30 || ARCH_MSM8X60)
+	depends on MSM_CAMERA && (ARCH_MSM7X30 || ARCH_MSM8X60) && !MSM_CAMERA_V4L2
 	default y
 	---help---
 	STM 5M Bayer Sensor with EDOF
diff --git a/drivers/media/video/msm/Makefile b/drivers/media/video/msm/Makefile
index f817561..ca80fc1 100644
--- a/drivers/media/video/msm/Makefile
+++ b/drivers/media/video/msm/Makefile
@@ -20,9 +20,14 @@
 else
   obj-$(CONFIG_ARCH_MSM7X27A) += msm_vfe7x27a.o msm_io_7x27a.o
 endif
-obj-$(CONFIG_ARCH_MSM7X30) += msm_vfe31.o msm_io_vfe31.o msm_vpe1.o
 obj-$(CONFIG_ARCH_QSD8X50) += msm_vfe8x.o msm_vfe8x_proc.o msm_io8x.o
-obj-$(CONFIG_ARCH_MSM8X60) += msm_vfe31.o msm_io_8x60.o msm_vpe1.o
+ifeq ($(CONFIG_MSM_CAMERA_V4L2),y)
+  obj-$(CONFIG_ARCH_MSM8X60) += msm_io_vfe31_v4l2.o msm_vfe31_v4l2.o msm_vpe.o
+  obj-$(CONFIG_ARCH_MSM7X30) += msm_io_vfe31_v4l2.o msm_vfe31_v4l2.o msm_vpe.o msm_axi_qos.o
+else
+  obj-$(CONFIG_ARCH_MSM8X60) += msm_vfe31.o msm_io_8x60.o msm_vpe1.o
+  obj-$(CONFIG_ARCH_MSM7X30) += msm_vfe31.o msm_io_vfe31.o msm_vpe1.o
+endif
 obj-$(CONFIG_ARCH_MSM8960) += msm_io_8960.o msm_vfe32.o msm_vpe.o
 obj-$(CONFIG_MT9T013) += mt9t013.o mt9t013_reg.o
 obj-$(CONFIG_SN12M0PZ) += sn12m0pz.o sn12m0pz_reg.o
@@ -32,9 +37,7 @@
 obj-$(CONFIG_MT9P012_KM) += mt9p012_km.o mt9p012_km_reg.o
 obj-$(CONFIG_S5K3E2FX) += s5k3e2fx.o
 #FIXME: Merge the two ifeq causes VX6953 preview not coming up.
-ifeq ($(CONFIG_MSM_CAMERA_V4L2),y)
-  obj-$(CONFIG_VX6953) += vx6953_v4l2.o vx6953_reg_v4l2.o
-else
+ifneq ($(CONFIG_MSM_CAMERA_V4L2),y)
   obj-$(CONFIG_VX6953) += vx6953.o vx6953_reg.o
   obj-$(CONFIG_IMX074) += imx074.o imx074_reg.o
   obj-$(CONFIG_MT9E013) += mt9e013.o mt9e013_reg.o
diff --git a/drivers/media/video/msm/csi/Makefile b/drivers/media/video/msm/csi/Makefile
index 6e8eb122..e5d5966 100644
--- a/drivers/media/video/msm/csi/Makefile
+++ b/drivers/media/video/msm/csi/Makefile
@@ -2,3 +2,5 @@
 EXTRA_CFLAGS += -Idrivers/media/video/msm
 obj-$(CONFIG_ARCH_MSM8960) += msm_csiphy.o msm_csid.o msm_ispif.o
 obj-$(CONFIG_ARCH_MSM7X27A) += msm_csic.o
+obj-$(CONFIG_ARCH_MSM8X60) += msm_csic.o
+obj-$(CONFIG_ARCH_MSM7X30) += msm_csic.o
diff --git a/drivers/media/video/msm/csi/msm_csic.c b/drivers/media/video/msm/csi/msm_csic.c
index 3a642c7..1ca4fa3 100644
--- a/drivers/media/video/msm/csi/msm_csic.c
+++ b/drivers/media/video/msm/csi/msm_csic.c
@@ -13,6 +13,7 @@
 #include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <mach/clk.h>
 #include <mach/board.h>
 #include <mach/camera.h>
 #include <media/msm_isp.h>
@@ -54,7 +55,7 @@
 /* Data format for unpacking purpose */
 #define	MIPI_PROTOCOL_CONTROL_DATA_FORMAT_SHFT			0x13
 /* Enable decoding of payload based on data type filed of packet hdr */
-#define	MIPI_PROTOCOL_CONTROL_DECODE_ID_BMSK			0x00000
+#define	MIPI_PROTOCOL_CONTROL_DECODE_ID_BMSK			0x40000
 /* Enable error correction on packet headers */
 #define	MIPI_PROTOCOL_CONTROL_ECC_EN_BMSK			0x20000
 
@@ -132,7 +133,7 @@
 #define MSM_AXI_QOS_SNAPSHOT 200000
 #define MSM_AXI_QOS_RECORDING 200000
 
-#define MIPI_PWR_CNTL_ENA	0x07
+#define MIPI_PWR_CNTL_EN	0x07
 #define MIPI_PWR_CNTL_DIS	0x0
 
 static int msm_csic_config(struct csic_cfg_params *cfg_params)
@@ -210,9 +211,9 @@
 		break;
 	}
 
-	msm_io_w(0xFFFFF3FF, csicbase + MIPI_INTERRUPT_MASK);
-	/*clear IRQ bits - write 1 clears the status*/
-	msm_io_w(0xFFFFF3FF, csicbase + MIPI_INTERRUPT_STATUS);
+	msm_io_w(0xF077F3C0, csicbase + MIPI_INTERRUPT_MASK);
+	/*clear IRQ bits*/
+	msm_io_w(0xF077F3C0, csicbase + MIPI_INTERRUPT_STATUS);
 
 	return rc;
 }
@@ -244,7 +245,14 @@
 	return 0;
 }
 
-static struct msm_cam_clk_info csic_clk_info[] = {
+static struct msm_cam_clk_info csic_8x_clk_info[] = {
+	{"csi_src_clk", 384000000},
+	{"csi_clk", -1},
+	{"csi_vfe_clk", -1},
+	{"csi_pclk", -1},
+};
+
+static struct msm_cam_clk_info csic_7x_clk_info[] = {
 	{"csi_clk", 400000000},
 	{"csi_vfe_clk", -1},
 	{"csi_pclk", -1},
@@ -267,12 +275,18 @@
 		return rc;
 	}
 
-	pr_info("msm_cam_clk_enable: enable csi_pclk, csi_clk, csi_vfe_clk\n");
-	rc = msm_cam_clk_enable(&csic_dev->pdev->dev, csic_clk_info,
-		csic_dev->csic_clk, ARRAY_SIZE(csic_clk_info), 1);
+	csic_dev->hw_version = CSIC_8X;
+	rc = msm_cam_clk_enable(&csic_dev->pdev->dev, csic_8x_clk_info,
+		csic_dev->csic_clk, ARRAY_SIZE(csic_8x_clk_info), 1);
 	if (rc < 0) {
-		iounmap(csic_dev->base);
-		return rc;
+		csic_dev->hw_version = CSIC_7X;
+		rc = msm_cam_clk_enable(&csic_dev->pdev->dev, csic_7x_clk_info,
+			csic_dev->csic_clk, ARRAY_SIZE(csic_7x_clk_info), 1);
+		if (rc < 0) {
+			csic_dev->hw_version = 0;
+			iounmap(csic_dev->base);
+			return rc;
+		}
 	}
 
 #if DBG_CSIC
@@ -282,20 +296,58 @@
 	return 0;
 }
 
+static void msm_csic_disable(struct v4l2_subdev *sd)
+{
+	uint32_t val;
+	struct csic_device *csic_dev;
+	csic_dev = v4l2_get_subdevdata(sd);
+
+	val = 0x0;
+	if (csic_dev->base != NULL) {
+		CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val);
+		msm_io_w(val, csic_dev->base + MIPI_PHY_D0_CONTROL2);
+		msm_io_w(val, csic_dev->base + MIPI_PHY_D1_CONTROL2);
+		msm_io_w(val, csic_dev->base + MIPI_PHY_D2_CONTROL2);
+		msm_io_w(val, csic_dev->base + MIPI_PHY_D3_CONTROL2);
+		CDBG("%s MIPI_PHY_CL_CONTROL val=0x%x\n", __func__, val);
+		msm_io_w(val, csic_dev->base + MIPI_PHY_CL_CONTROL);
+		msleep(20);
+		val = msm_io_r(csic_dev->base + MIPI_PHY_D1_CONTROL);
+		val &=
+		~((0x1 << MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT)
+		|(0x1 << MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT));
+		CDBG("%s MIPI_PHY_D1_CONTROL val=0x%x\n", __func__, val);
+		msm_io_w(val, csic_dev->base + MIPI_PHY_D1_CONTROL);
+		usleep_range(5000, 6000);
+		msm_io_w(0x0, csic_dev->base + MIPI_INTERRUPT_MASK);
+		msm_io_w(0x0, csic_dev->base + MIPI_INTERRUPT_STATUS);
+		msm_io_w(MIPI_PROTOCOL_CONTROL_SW_RST_BMSK,
+			csic_dev->base + MIPI_PROTOCOL_CONTROL);
+
+		msm_io_w(0xE400, csic_dev->base + MIPI_CAMERA_CNTL);
+	}
+}
+
 static int msm_csic_release(struct v4l2_subdev *sd)
 {
 	struct csic_device *csic_dev;
 	csic_dev = v4l2_get_subdevdata(sd);
 
+	msm_csic_disable(sd);
 #if DBG_CSIC
 	disable_irq(csic_dev->irq->start);
 #endif
 
-	pr_info("msm_cam_clk_enable: disble csi_pclk, csi_clk, csi_vfe_clk\n");
-	msm_cam_clk_enable(&csic_dev->pdev->dev, csic_clk_info,
-		csic_dev->csic_clk, ARRAY_SIZE(csic_clk_info), 0);
+	if (csic_dev->hw_version == CSIC_8X) {
+		msm_cam_clk_enable(&csic_dev->pdev->dev, csic_8x_clk_info,
+			csic_dev->csic_clk, ARRAY_SIZE(csic_8x_clk_info), 0);
+	} else if (csic_dev->hw_version == CSIC_7X) {
+		msm_cam_clk_enable(&csic_dev->pdev->dev, csic_7x_clk_info,
+			csic_dev->csic_clk, ARRAY_SIZE(csic_7x_clk_info), 0);
+	}
 
 	iounmap(csic_dev->base);
+	csic_dev->base = NULL;
 	return 0;
 }
 
@@ -365,7 +417,7 @@
 	}
 
 	rc = request_irq(new_csic_dev->irq->start, msm_csic_irq,
-			IRQF_TRIGGER_HIGH, "csic", new_csic_dev);
+		IRQF_TRIGGER_HIGH, "csic", new_csic_dev);
 	if (rc < 0) {
 		release_mem_region(new_csic_dev->mem->start,
 			resource_size(new_csic_dev->mem));
@@ -374,20 +426,6 @@
 		goto csic_no_resource;
 	}
 	disable_irq(new_csic_dev->irq->start);
-	pr_info("msm_cam_clk_enable: enable csi_pclk\n");
-	msm_cam_clk_enable(&pdev->dev, &csic_clk_info[2],
-				new_csic_dev->csic_clk, 1, 1);
-	new_csic_dev->base = ioremap(new_csic_dev->mem->start,
-		resource_size(new_csic_dev->mem));
-	if (!new_csic_dev->base) {
-		rc = -ENOMEM;
-		goto csic_no_resource;
-	}
-
-	msm_io_w(MIPI_PWR_CNTL_DIS, new_csic_dev->base + MIPI_PWR_CNTL_DIS);
-	pr_info("msm_cam_clk_enable: disable csi_pclk\n");
-	msm_cam_clk_enable(&pdev->dev, &csic_clk_info[2],
-					new_csic_dev->csic_clk, 1, 0);
 	iounmap(new_csic_dev->base);
 
 	new_csic_dev->pdev = pdev;
diff --git a/drivers/media/video/msm/csi/msm_csic.h b/drivers/media/video/msm/csi/msm_csic.h
index 08dde52..177e9d1 100644
--- a/drivers/media/video/msm/csi/msm_csic.h
+++ b/drivers/media/video/msm/csi/msm_csic.h
@@ -17,6 +17,9 @@
 #include <linux/io.h>
 #include <media/v4l2-subdev.h>
 
+#define CSIC_7X 0x1
+#define CSIC_8X (0x1 << 1)
+
 struct csic_device {
 	struct platform_device *pdev;
 	struct v4l2_subdev subdev;
diff --git a/drivers/media/video/msm/io/msm_io_util.c b/drivers/media/video/msm/io/msm_io_util.c
index a04d6fd..cc6bab2 100644
--- a/drivers/media/video/msm/io/msm_io_util.c
+++ b/drivers/media/video/msm/io/msm_io_util.c
@@ -111,15 +111,15 @@
 						curr_vreg->reg_name);
 					goto vreg_set_voltage_fail;
 				}
-				if (curr_vreg->op_mode) {
+				if (curr_vreg->op_mode >= 0) {
 					rc = regulator_set_optimum_mode(
 						reg_ptr[i],
 						curr_vreg->op_mode);
 					if (rc < 0) {
-						pr_err("%s: %s set optimum"
-							"mode failed\n",
-							__func__,
-							curr_vreg->reg_name);
+						pr_err(
+						"%s: %s set optimum mode failed\n",
+						__func__,
+						curr_vreg->reg_name);
 						goto vreg_set_opt_mode_fail;
 					}
 				}
@@ -130,9 +130,10 @@
 			curr_vreg = &cam_vreg[i];
 			if (reg_ptr[i]) {
 				if (curr_vreg->type == REG_LDO) {
-					if (curr_vreg->op_mode)
+					if (curr_vreg->op_mode >= 0) {
 						regulator_set_optimum_mode(
 							reg_ptr[i], 0);
+					}
 					regulator_set_voltage(
 						reg_ptr[i], 0, curr_vreg->
 						max_voltage);
diff --git a/drivers/media/video/msm/msm_io_vfe31_v4l2.c b/drivers/media/video/msm/msm_io_vfe31_v4l2.c
new file mode 100644
index 0000000..03810f4
--- /dev/null
+++ b/drivers/media/video/msm/msm_io_vfe31_v4l2.c
@@ -0,0 +1,408 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/regulator/consumer.h>
+#include <mach/gpio.h>
+#include <mach/board.h>
+#include <mach/camera.h>
+#include <mach/vreg.h>
+#include <mach/camera.h>
+#include <mach/clk.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+
+#include <linux/pm_qos_params.h>
+
+/* AXI rates in KHz */
+#define MSM_AXI_QOS_PREVIEW     192000
+#define MSM_AXI_QOS_SNAPSHOT    192000
+#define MSM_AXI_QOS_RECORDING   192000
+
+#define BUFF_SIZE_128 128
+
+static struct clk *camio_jpeg_clk;
+static struct clk *camio_vfe_clk;
+static struct clk *camio_jpeg_pclk;
+static struct clk *camio_vpe_clk;
+static struct clk *camio_vpe_pclk;
+static struct regulator *fs_ijpeg;
+static struct regulator *fs_vpe;
+
+static int vpe_clk_rate;
+void msm_io_w(u32 data, void __iomem *addr)
+{
+	CDBG("%s: %08x %08x\n", __func__, (int) (addr), (data));
+	writel_relaxed((data), (addr));
+}
+
+void msm_io_w_mb(u32 data, void __iomem *addr)
+{
+	CDBG("%s: %08x %08x\n", __func__, (int) (addr), (data));
+	wmb();
+	writel_relaxed((data), (addr));
+	wmb();
+}
+
+u32 msm_io_r(void __iomem *addr)
+{
+	uint32_t data = readl_relaxed(addr);
+	CDBG("%s: %08x %08x\n", __func__, (int) (addr), (data));
+	return data;
+}
+
+u32 msm_io_r_mb(void __iomem *addr)
+{
+	uint32_t data;
+	rmb();
+	data = readl_relaxed(addr);
+	rmb();
+	CDBG("%s: %08x %08x\n", __func__, (int) (addr), (data));
+	return data;
+}
+
+void msm_io_memcpy_toio(void __iomem *dest_addr,
+	void __iomem *src_addr, u32 len)
+{
+	int i;
+	u32 *d = (u32 *) dest_addr;
+	u32 *s = (u32 *) src_addr;
+	/* memcpy_toio does not work. Use writel for now */
+	for (i = 0; i < len; i++)
+		writel_relaxed(*s++, d++);
+}
+
+void msm_io_dump(void __iomem *addr, int size)
+{
+	char line_str[BUFF_SIZE_128], *p_str;
+	int i;
+	u32 *p = (u32 *) addr;
+	u32 data;
+	CDBG("%s: %p %d\n", __func__, addr, size);
+	line_str[0] = '\0';
+	p_str = line_str;
+	for (i = 0; i < size/4; i++) {
+		if (i % 4 == 0) {
+			snprintf(p_str, 12, "%08x: ", (u32) p);
+			p_str += 10;
+		}
+		data = readl_relaxed(p++);
+		snprintf(p_str, 12, "%08x ", data);
+		p_str += 9;
+		if ((i + 1) % 4 == 0) {
+			CDBG("%s\n", line_str);
+			line_str[0] = '\0';
+			p_str = line_str;
+		}
+	}
+	if (line_str[0] != '\0')
+		CDBG("%s\n", line_str);
+}
+
+void msm_io_memcpy(void __iomem *dest_addr, void __iomem *src_addr, u32 len)
+{
+	CDBG("%s: %p %p %d\n", __func__, dest_addr, src_addr, len);
+	msm_io_memcpy_toio(dest_addr, src_addr, len / 4);
+	msm_io_dump(dest_addr, len);
+}
+
+int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
+{
+	int rc = 0;
+	struct clk *clk = NULL;
+
+	switch (clktype) {
+	case CAMIO_JPEG_CLK:
+		camio_jpeg_clk =
+		clk = clk_get(NULL, "ijpeg_clk");
+		rc = clk_set_rate(clk, 228571000);
+		if (rc < 0)
+			rc = clk_set_rate(clk, 153600000);
+		break;
+
+	case CAMIO_JPEG_PCLK:
+		camio_jpeg_pclk =
+		clk = clk_get(NULL, "ijpeg_pclk");
+		break;
+
+	case CAMIO_VPE_CLK:
+		camio_vpe_clk =
+		clk = clk_get(NULL, "vpe_clk");
+		vpe_clk_rate = clk_round_rate(camio_vpe_clk, vpe_clk_rate);
+		clk_set_rate(camio_vpe_clk, vpe_clk_rate);
+		break;
+
+	case CAMIO_VPE_PCLK:
+		camio_vpe_pclk =
+		clk = clk_get(NULL, "vpe_pclk");
+		break;
+
+	default:
+		break;
+	}
+
+	if (!IS_ERR(clk)) {
+		clk_prepare(clk);
+		clk_enable(clk);
+	} else {
+		rc = -1;
+	}
+	return rc;
+}
+
+int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
+{
+	int rc = 0;
+	struct clk *clk = NULL;
+
+	switch (clktype) {
+	case CAMIO_JPEG_CLK:
+		clk = camio_jpeg_clk;
+		break;
+
+	case CAMIO_JPEG_PCLK:
+		clk = camio_jpeg_pclk;
+		break;
+
+	case CAMIO_VPE_CLK:
+		clk = camio_vpe_clk;
+		break;
+
+	case CAMIO_VPE_PCLK:
+		clk = camio_vpe_pclk;
+		break;
+
+	default:
+		break;
+	}
+
+	if (!IS_ERR(clk)) {
+		clk_disable(clk);
+		clk_unprepare(clk);
+		clk_put(clk);
+	} else {
+		rc = -1;
+	}
+
+	return rc;
+}
+
+int msm_camio_vfe_clk_rate_set(int rate)
+{
+	int rc = 0;
+	struct clk *clk = camio_vfe_clk;
+	if (rate > clk_get_rate(clk))
+		rc = clk_set_rate(clk, rate);
+	return rc;
+}
+
+void msm_camio_clk_rate_set_2(struct clk *clk, int rate)
+{
+	clk_set_rate(clk, rate);
+}
+
+int msm_camio_jpeg_clk_disable(void)
+{
+	int rc = 0;
+	if (fs_ijpeg) {
+		rc = regulator_disable(fs_ijpeg);
+		if (rc < 0) {
+			CDBG("%s: Regulator disable failed %d\n", __func__, rc);
+			return rc;
+		}
+		regulator_put(fs_ijpeg);
+	}
+	rc = msm_camio_clk_disable(CAMIO_JPEG_PCLK);
+	if (rc < 0)
+		return rc;
+	rc = msm_camio_clk_disable(CAMIO_JPEG_CLK);
+	CDBG("%s: exit %d\n", __func__, rc);
+	return rc;
+}
+
+int msm_camio_jpeg_clk_enable(void)
+{
+	int rc = 0;
+	rc = msm_camio_clk_enable(CAMIO_JPEG_CLK);
+	if (rc < 0)
+		return rc;
+	rc = msm_camio_clk_enable(CAMIO_JPEG_PCLK);
+	if (rc < 0)
+		return rc;
+	fs_ijpeg = regulator_get(NULL, "fs_ijpeg");
+	if (IS_ERR(fs_ijpeg)) {
+		CDBG("%s: Regulator FS_IJPEG get failed %ld\n", __func__,
+			PTR_ERR(fs_ijpeg));
+		fs_ijpeg = NULL;
+	} else if (regulator_enable(fs_ijpeg)) {
+		CDBG("%s: Regulator FS_IJPEG enable failed\n", __func__);
+		regulator_put(fs_ijpeg);
+	}
+	CDBG("%s: exit %d\n", __func__, rc);
+	return rc;
+}
+
+int msm_camio_vpe_clk_disable(void)
+{
+	int rc = 0;
+	if (fs_vpe) {
+		regulator_disable(fs_vpe);
+		regulator_put(fs_vpe);
+	}
+
+	rc = msm_camio_clk_disable(CAMIO_VPE_CLK);
+	if (rc < 0)
+		return rc;
+	rc = msm_camio_clk_disable(CAMIO_VPE_PCLK);
+	return rc;
+}
+
+int msm_camio_vpe_clk_enable(uint32_t clk_rate)
+{
+	int rc = 0;
+	fs_vpe = regulator_get(NULL, "fs_vpe");
+	if (IS_ERR(fs_vpe)) {
+		CDBG("%s: Regulator FS_VPE get failed %ld\n", __func__,
+			PTR_ERR(fs_vpe));
+		fs_vpe = NULL;
+	} else if (regulator_enable(fs_vpe)) {
+		CDBG("%s: Regulator FS_VPE enable failed\n", __func__);
+		regulator_put(fs_vpe);
+	}
+
+	vpe_clk_rate = clk_rate;
+	rc = msm_camio_clk_enable(CAMIO_VPE_CLK);
+	if (rc < 0)
+		return rc;
+
+	rc = msm_camio_clk_enable(CAMIO_VPE_PCLK);
+	return rc;
+}
+
+void msm_camio_vfe_blk_reset(void)
+{
+	return;
+}
+
+static void msm_camio_axi_cfg(enum msm_bus_perf_setting perf_setting)
+{
+	switch (perf_setting) {
+	case S_INIT:
+		add_axi_qos();
+		break;
+	case S_PREVIEW:
+		update_axi_qos(MSM_AXI_QOS_PREVIEW);
+		break;
+	case S_VIDEO:
+		update_axi_qos(MSM_AXI_QOS_RECORDING);
+		break;
+	case S_CAPTURE:
+		update_axi_qos(MSM_AXI_QOS_SNAPSHOT);
+		break;
+	case S_DEFAULT:
+		update_axi_qos(PM_QOS_DEFAULT_VALUE);
+		break;
+	case S_EXIT:
+		release_axi_qos();
+		break;
+	default:
+		CDBG("%s: INVALID CASE\n", __func__);
+	}
+}
+
+void msm_camio_bus_scale_cfg(struct msm_bus_scale_pdata *cam_bus_scale_table,
+		enum msm_bus_perf_setting perf_setting)
+{
+	static uint32_t bus_perf_client;
+	int rc = 0;
+	if (cam_bus_scale_table == NULL) {
+		msm_camio_axi_cfg(perf_setting);
+		return;
+	}
+
+	switch (perf_setting) {
+	case S_INIT:
+		bus_perf_client =
+			msm_bus_scale_register_client(cam_bus_scale_table);
+		if (!bus_perf_client) {
+			pr_err("%s: Registration Failed!!!\n", __func__);
+			bus_perf_client = 0;
+			return;
+		}
+		CDBG("%s: S_INIT rc = %u\n", __func__, bus_perf_client);
+		break;
+	case S_EXIT:
+		if (bus_perf_client) {
+			CDBG("%s: S_EXIT\n", __func__);
+			msm_bus_scale_unregister_client(bus_perf_client);
+		} else
+			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_PREVIEW:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 1);
+			CDBG("%s: S_PREVIEW rc = %d\n", __func__, rc);
+		} else
+			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_VIDEO:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 2);
+			CDBG("%s: S_VIDEO rc = %d\n", __func__, rc);
+		} else
+			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_CAPTURE:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 3);
+			CDBG("%s: S_CAPTURE rc = %d\n", __func__, rc);
+		} else
+			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+
+	case S_ZSL:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 4);
+			CDBG("%s: S_ZSL rc = %d\n", __func__, rc);
+		} else
+			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_STEREO_VIDEO:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 5);
+			CDBG("%s: S_STEREO_VIDEO rc = %d\n", __func__, rc);
+		} else
+			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_STEREO_CAPTURE:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 6);
+			CDBG("%s: S_STEREO_VIDEO rc = %d\n", __func__, rc);
+		} else
+			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_DEFAULT:
+		break;
+	default:
+		pr_warning("%s: INVALID CASE\n", __func__);
+	}
+}
+
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index d7ec5b4..3031e1f 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -632,6 +632,22 @@
 			goto msm_open_done;
 		}
 
+		/* then sensor - move sub dev later*/
+		rc = v4l2_subdev_call(p_mctl->sensor_sdev, core, s_power, 1);
+
+		if (rc < 0) {
+			pr_err("%s: isp init failed: %d\n", __func__, rc);
+			goto msm_open_done;
+		}
+		if (sync->actctrl.a_power_up)
+			rc = sync->actctrl.a_power_up(
+				sync->sdata->actuator_info);
+
+		if (rc < 0) {
+			pr_err("%s: act power failed:%d\n", __func__, rc);
+			goto msm_open_done;
+		}
+
 		if (camdev->is_csiphy) {
 			rc = v4l2_subdev_call(p_mctl->csiphy_sdev, core, ioctl,
 				VIDIOC_MSM_CSIPHY_INIT, NULL);
@@ -683,22 +699,6 @@
 			}
 		}
 
-		/* then sensor - move sub dev later*/
-		rc = v4l2_subdev_call(p_mctl->sensor_sdev, core, s_power, 1);
-
-		if (rc < 0) {
-			pr_err("%s: isp init failed: %d\n", __func__, rc);
-			goto msm_open_done;
-		}
-		if (sync->actctrl.a_power_up)
-			rc = sync->actctrl.a_power_up(
-				sync->sdata->actuator_info);
-
-		if (rc < 0) {
-			pr_err("%s: act power failed:%d\n", __func__, rc);
-			goto msm_open_done;
-		}
-
 		if (camdev->is_ispif) {
 			pm_qos_add_request(&p_mctl->pm_qos_req_list,
 					PM_QOS_CPU_DMA_LATENCY,
@@ -728,6 +728,11 @@
 			VIDIOC_MSM_ISPIF_RELEASE, NULL);
 	}
 
+	if (camdev->is_csic) {
+		v4l2_subdev_call(p_mctl->csic_sdev, core, ioctl,
+			VIDIOC_MSM_CSIC_RELEASE, NULL);
+	}
+
 	if (p_mctl->isp_sdev && p_mctl->isp_sdev->isp_release)
 		p_mctl->isp_sdev->isp_release(&p_mctl->sync,
 				p_mctl->gemini_sdev);
@@ -737,26 +742,22 @@
 			VIDIOC_MSM_CSID_RELEASE, NULL);
 	}
 
-	if (camdev->is_csic) {
-		v4l2_subdev_call(p_mctl->csic_sdev, core, ioctl,
-			VIDIOC_MSM_CSIC_RELEASE, NULL);
-	}
-
 	if (camdev->is_csiphy) {
 		v4l2_subdev_call(p_mctl->csiphy_sdev, core, ioctl,
 			VIDIOC_MSM_CSIPHY_RELEASE, NULL);
 	}
 
-	if (p_mctl->sync.actctrl.a_power_down)
-		p_mctl->sync.actctrl.a_power_down(
-			p_mctl->sync.sdata->actuator_info);
-
-	v4l2_subdev_call(p_mctl->sensor_sdev, core, s_power, 0);
 	if (camdev->is_ispif) {
 		pm_qos_update_request(&p_mctl->pm_qos_req_list,
 				PM_QOS_DEFAULT_VALUE);
 		pm_qos_remove_request(&p_mctl->pm_qos_req_list);
 	}
+	if (p_mctl->sync.actctrl.a_power_down)
+		p_mctl->sync.actctrl.a_power_down(
+			p_mctl->sync.sdata->actuator_info);
+
+	v4l2_subdev_call(p_mctl->sensor_sdev, core, s_power, 0);
+
 	wake_unlock(&p_mctl->sync.wake_lock);
 	return rc;
 }
diff --git a/drivers/media/video/msm/msm_vfe31_v4l2.c b/drivers/media/video/msm/msm_vfe31_v4l2.c
new file mode 100644
index 0000000..1f17ebe
--- /dev/null
+++ b/drivers/media/video/msm/msm_vfe31_v4l2.c
@@ -0,0 +1,3850 @@
+/* Copyright (c) 2012 Code Aurora Forum. 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/uaccess.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/atomic.h>
+#include <linux/regulator/consumer.h>
+#include <linux/clk.h>
+#include <mach/clk.h>
+#include <mach/irqs.h>
+#include <mach/camera.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include <media/msm_isp.h>
+
+#include "msm.h"
+#include "msm_vfe31_v4l2.h"
+
+atomic_t irq_cnt;
+
+#define BUFF_SIZE_128 128
+
+#define VFE31_AXI_OFFSET 0x0050
+#define vfe31_get_ch_ping_addr(chn) \
+	(msm_io_r(vfe31_ctrl->vfebase + 0x0050 + 0x18 * (chn)))
+#define vfe31_get_ch_pong_addr(chn) \
+	(msm_io_r(vfe31_ctrl->vfebase + 0x0050 + 0x18 * (chn) + 4))
+#define vfe31_get_ch_addr(ping_pong, chn) \
+	(((ping_pong) & (1 << (chn))) == 0 ? \
+	vfe31_get_ch_pong_addr(chn) : vfe31_get_ch_ping_addr(chn))
+
+#define vfe31_put_ch_ping_addr(chn, addr) \
+	(msm_io_w((addr), vfe31_ctrl->vfebase + 0x0050 + 0x18 * (chn)))
+#define vfe31_put_ch_pong_addr(chn, addr) \
+	(msm_io_w((addr), vfe31_ctrl->vfebase + 0x0050 + 0x18 * (chn) + 4))
+#define vfe31_put_ch_addr(ping_pong, chn, addr) \
+	(((ping_pong) & (1 << (chn))) == 0 ?   \
+	vfe31_put_ch_pong_addr((chn), (addr)) : \
+	vfe31_put_ch_ping_addr((chn), (addr)))
+
+#define VFE_CLK_RATE	153600000
+#define CAMIF_CFG_RMSK             0x1fffff
+
+static struct vfe31_ctrl_type *vfe31_ctrl;
+static void  *vfe_syncdata;
+static uint32_t vfe_clk_rate;
+
+struct vfe31_isr_queue_cmd {
+	struct list_head	list;
+	uint32_t		vfeInterruptStatus0;
+	uint32_t		vfeInterruptStatus1;
+};
+
+/*TODO: Why is V32 reference in arch/arm/mach-msm/include/mach/camera.h?*/
+#define VFE_MSG_V31_START VFE_MSG_V32_START
+#define VFE_MSG_V31_CAPTURE VFE_MSG_V32_CAPTURE
+#define VFE_MSG_V31_JPEG_CAPTURE VFE_MSG_V32_JPEG_CAPTURE
+#define VFE_MSG_V31_START_RECORDING VFE_MSG_V32_START_RECORDING
+
+static struct vfe31_cmd_type vfe31_cmd[] = {
+/* 0*/	{VFE_CMD_DUMMY_0},
+		{VFE_CMD_SET_CLK},
+		{VFE_CMD_RESET},
+		{VFE_CMD_START},
+		{VFE_CMD_TEST_GEN_START},
+/* 5*/	{VFE_CMD_OPERATION_CFG, V31_OPERATION_CFG_LEN},
+		{VFE_CMD_AXI_OUT_CFG, V31_AXI_OUT_LEN, V31_AXI_OUT_OFF, 0xFF},
+		{VFE_CMD_CAMIF_CFG, V31_CAMIF_LEN, V31_CAMIF_OFF, 0xFF},
+		{VFE_CMD_AXI_INPUT_CFG},
+		{VFE_CMD_BLACK_LEVEL_CFG, V31_BLACK_LEVEL_LEN,
+		V31_BLACK_LEVEL_OFF,
+		0xFF},
+/*10*/  {VFE_CMD_MESH_ROLL_OFF_CFG, V31_MESH_ROLL_OFF_CFG_LEN,
+		V31_MESH_ROLL_OFF_CFG_OFF, 0xFF},
+		{VFE_CMD_DEMUX_CFG, V31_DEMUX_LEN, V31_DEMUX_OFF, 0xFF},
+		{VFE_CMD_FOV_CFG, V31_FOV_LEN, V31_FOV_OFF, 0xFF},
+		{VFE_CMD_MAIN_SCALER_CFG, V31_MAIN_SCALER_LEN,
+		V31_MAIN_SCALER_OFF, 0xFF},
+		{VFE_CMD_WB_CFG, V31_WB_LEN, V31_WB_OFF, 0xFF},
+/*15*/	{VFE_CMD_COLOR_COR_CFG, V31_COLOR_COR_LEN, V31_COLOR_COR_OFF, 0xFF},
+		{VFE_CMD_RGB_G_CFG, V31_RGB_G_LEN, V31_RGB_G_OFF, 0xFF},
+		{VFE_CMD_LA_CFG, V31_LA_LEN, V31_LA_OFF, 0xFF },
+		{VFE_CMD_CHROMA_EN_CFG, V31_CHROMA_EN_LEN, V31_CHROMA_EN_OFF,
+		0xFF},
+		{VFE_CMD_CHROMA_SUP_CFG, V31_CHROMA_SUP_LEN, V31_CHROMA_SUP_OFF,
+		0xFF},
+/*20*/	{VFE_CMD_MCE_CFG, V31_MCE_LEN, V31_MCE_OFF, 0xFF},
+		{VFE_CMD_SK_ENHAN_CFG, V31_SCE_LEN, V31_SCE_OFF, 0xFF},
+		{VFE_CMD_ASF_CFG, V31_ASF_LEN, V31_ASF_OFF, 0xFF},
+		{VFE_CMD_S2Y_CFG, V31_S2Y_LEN, V31_S2Y_OFF, 0xFF},
+		{VFE_CMD_S2CbCr_CFG, V31_S2CbCr_LEN, V31_S2CbCr_OFF, 0xFF},
+/*25*/	{VFE_CMD_CHROMA_SUBS_CFG, V31_CHROMA_SUBS_LEN, V31_CHROMA_SUBS_OFF,
+		0xFF},
+		{VFE_CMD_OUT_CLAMP_CFG, V31_OUT_CLAMP_LEN, V31_OUT_CLAMP_OFF,
+		0xFF},
+		{VFE_CMD_FRAME_SKIP_CFG, V31_FRAME_SKIP_LEN, V31_FRAME_SKIP_OFF,
+		0xFF},
+		{VFE_CMD_DUMMY_1},
+		{VFE_CMD_DUMMY_2},
+/*30*/	{VFE_CMD_DUMMY_3},
+		{VFE_CMD_UPDATE},
+		{VFE_CMD_BL_LVL_UPDATE, V31_BLACK_LEVEL_LEN,
+		V31_BLACK_LEVEL_OFF, 0xFF},
+		{VFE_CMD_DEMUX_UPDATE, V31_DEMUX_LEN, V31_DEMUX_OFF, 0xFF},
+		{VFE_CMD_FOV_UPDATE, V31_FOV_LEN, V31_FOV_OFF, 0xFF},
+/*35*/	{VFE_CMD_MAIN_SCALER_UPDATE, V31_MAIN_SCALER_LEN, V31_MAIN_SCALER_OFF,
+		0xFF},
+		{VFE_CMD_WB_UPDATE, V31_WB_LEN, V31_WB_OFF, 0xFF},
+		{VFE_CMD_COLOR_COR_UPDATE, V31_COLOR_COR_LEN, V31_COLOR_COR_OFF,
+		0xFF},
+		{VFE_CMD_RGB_G_UPDATE, V31_RGB_G_LEN, V31_CHROMA_EN_OFF, 0xFF},
+		{VFE_CMD_LA_UPDATE, V31_LA_LEN, V31_LA_OFF, 0xFF },
+/*40*/	{VFE_CMD_CHROMA_EN_UPDATE, V31_CHROMA_EN_LEN, V31_CHROMA_EN_OFF,
+		0xFF},
+		{VFE_CMD_CHROMA_SUP_UPDATE, V31_CHROMA_SUP_LEN,
+		V31_CHROMA_SUP_OFF, 0xFF},
+		{VFE_CMD_MCE_UPDATE, V31_MCE_LEN, V31_MCE_OFF, 0xFF},
+		{VFE_CMD_SK_ENHAN_UPDATE, V31_SCE_LEN, V31_SCE_OFF, 0xFF},
+		{VFE_CMD_S2CbCr_UPDATE, V31_S2CbCr_LEN, V31_S2CbCr_OFF, 0xFF},
+/*45*/	{VFE_CMD_S2Y_UPDATE, V31_S2Y_LEN, V31_S2Y_OFF, 0xFF},
+		{VFE_CMD_ASF_UPDATE, V31_ASF_UPDATE_LEN, V31_ASF_OFF, 0xFF},
+		{VFE_CMD_FRAME_SKIP_UPDATE},
+		{VFE_CMD_CAMIF_FRAME_UPDATE},
+		{VFE_CMD_STATS_AF_UPDATE, V31_STATS_AF_LEN, V31_STATS_AF_OFF},
+/*50*/	{VFE_CMD_STATS_AE_UPDATE, V31_STATS_AE_LEN, V31_STATS_AE_OFF},
+		{VFE_CMD_STATS_AWB_UPDATE, V31_STATS_AWB_LEN,
+		V31_STATS_AWB_OFF},
+		{VFE_CMD_STATS_RS_UPDATE, V31_STATS_RS_LEN, V31_STATS_RS_OFF},
+		{VFE_CMD_STATS_CS_UPDATE, V31_STATS_CS_LEN, V31_STATS_CS_OFF},
+		{VFE_CMD_STATS_SKIN_UPDATE},
+/*55*/	{VFE_CMD_STATS_IHIST_UPDATE, V31_STATS_IHIST_LEN, V31_STATS_IHIST_OFF},
+		{VFE_CMD_DUMMY_4},
+		{VFE_CMD_EPOCH1_ACK},
+		{VFE_CMD_EPOCH2_ACK},
+		{VFE_CMD_START_RECORDING},
+/*60*/	{VFE_CMD_STOP_RECORDING},
+		{VFE_CMD_DUMMY_5},
+		{VFE_CMD_DUMMY_6},
+		{VFE_CMD_CAPTURE, V31_CAPTURE_LEN, 0xFF},
+		{VFE_CMD_DUMMY_7},
+/*65*/	{VFE_CMD_STOP},
+		{VFE_CMD_GET_HW_VERSION, V31_GET_HW_VERSION_LEN,
+		V31_GET_HW_VERSION_OFF},
+		{VFE_CMD_GET_FRAME_SKIP_COUNTS},
+		{VFE_CMD_OUTPUT1_BUFFER_ENQ},
+		{VFE_CMD_OUTPUT2_BUFFER_ENQ},
+/*70*/	{VFE_CMD_OUTPUT3_BUFFER_ENQ},
+		{VFE_CMD_JPEG_OUT_BUF_ENQ},
+		{VFE_CMD_RAW_OUT_BUF_ENQ},
+		{VFE_CMD_RAW_IN_BUF_ENQ},
+		{VFE_CMD_STATS_AF_ENQ},
+/*75*/	{VFE_CMD_STATS_AE_ENQ},
+		{VFE_CMD_STATS_AWB_ENQ},
+		{VFE_CMD_STATS_RS_ENQ},
+		{VFE_CMD_STATS_CS_ENQ},
+		{VFE_CMD_STATS_SKIN_ENQ},
+/*80*/	{VFE_CMD_STATS_IHIST_ENQ},
+		{VFE_CMD_DUMMY_8},
+		{VFE_CMD_JPEG_ENC_CFG},
+		{VFE_CMD_DUMMY_9},
+		{VFE_CMD_STATS_AF_START, V31_STATS_AF_LEN, V31_STATS_AF_OFF},
+/*85*/	{VFE_CMD_STATS_AF_STOP},
+		{VFE_CMD_STATS_AE_START, V31_STATS_AE_LEN, V31_STATS_AE_OFF},
+		{VFE_CMD_STATS_AE_STOP},
+		{VFE_CMD_STATS_AWB_START, V31_STATS_AWB_LEN, V31_STATS_AWB_OFF},
+		{VFE_CMD_STATS_AWB_STOP},
+/*90*/	{VFE_CMD_STATS_RS_START, V31_STATS_RS_LEN, V31_STATS_RS_OFF},
+		{VFE_CMD_STATS_RS_STOP},
+		{VFE_CMD_STATS_CS_START, V31_STATS_CS_LEN, V31_STATS_CS_OFF},
+		{VFE_CMD_STATS_CS_STOP},
+		{VFE_CMD_STATS_SKIN_START},
+/*95*/	{VFE_CMD_STATS_SKIN_STOP},
+		{VFE_CMD_STATS_IHIST_START,
+		V31_STATS_IHIST_LEN, V31_STATS_IHIST_OFF},
+		{VFE_CMD_STATS_IHIST_STOP},
+		{VFE_CMD_DUMMY_10},
+		{VFE_CMD_SYNC_TIMER_SETTING, V31_SYNC_TIMER_LEN,
+			V31_SYNC_TIMER_OFF},
+/*100*/	{VFE_CMD_ASYNC_TIMER_SETTING, V31_ASYNC_TIMER_LEN, V31_ASYNC_TIMER_OFF},
+		{VFE_CMD_LIVESHOT},
+		{VFE_CMD_LA_SETUP},
+		{VFE_CMD_LINEARIZATION_CFG},
+		{VFE_CMD_DEMOSAICV3},
+/*105*/	{VFE_CMD_DEMOSAICV3_ABCC_CFG},
+	{VFE_CMD_DEMOSAICV3_DBCC_CFG},
+		{VFE_CMD_DEMOSAICV3_DBPC_CFG, V31_DEMOSAICV3_DBPC_LEN,
+			V31_DEMOSAICV3_DBPC_CFG_OFF},
+		{VFE_CMD_DEMOSAICV3_ABF_CFG, V31_DEMOSAICV3_ABF_LEN,
+			V31_DEMOSAICV3_ABF_OFF},
+		{VFE_CMD_DEMOSAICV3_ABCC_UPDATE},
+/*110*/	{VFE_CMD_DEMOSAICV3_DBCC_UPDATE},
+		{VFE_CMD_DEMOSAICV3_DBPC_UPDATE, V31_DEMOSAICV3_DBPC_LEN,
+			V31_DEMOSAICV3_DBPC_CFG_OFF},
+		{VFE_CMD_XBAR_CFG},
+		{VFE_CMD_MODULE_CFG, V31_MODULE_CFG_LEN, V31_MODULE_CFG_OFF},
+		{VFE_CMD_ZSL},
+/*115*/	{VFE_CMD_LINEARIZATION_UPDATE},
+		{VFE_CMD_DEMOSAICV3_ABF_UPDATE, V31_DEMOSAICV3_ABF_LEN,
+			V31_DEMOSAICV3_ABF_OFF},
+		{VFE_CMD_CLF_CFG},
+		{VFE_CMD_CLF_LUMA_UPDATE},
+		{VFE_CMD_CLF_CHROMA_UPDATE},
+/*120*/ {VFE_CMD_PCA_ROLL_OFF_CFG},
+		{VFE_CMD_PCA_ROLL_OFF_UPDATE},
+		{VFE_CMD_GET_REG_DUMP},
+		{VFE_CMD_GET_LINEARIZATON_TABLE},
+		{VFE_CMD_GET_MESH_ROLLOFF_TABLE},
+/*125*/ {VFE_CMD_GET_PCA_ROLLOFF_TABLE},
+		{VFE_CMD_GET_RGB_G_TABLE},
+		{VFE_CMD_GET_LA_TABLE},
+		{VFE_CMD_DEMOSAICV3_UPDATE},
+};
+
+uint32_t vfe31_AXI_WM_CFG[] = {
+	0x0000004C,
+	0x00000064,
+	0x0000007C,
+	0x00000094,
+	0x000000AC,
+	0x000000C4,
+	0x000000DC,
+};
+
+static const char * const vfe31_general_cmd[] = {
+	"DUMMY_0",  /* 0 */
+	"SET_CLK",
+	"RESET",
+	"START",
+	"TEST_GEN_START",
+	"OPERATION_CFG",  /* 5 */
+	"AXI_OUT_CFG",
+	"CAMIF_CFG",
+	"AXI_INPUT_CFG",
+	"BLACK_LEVEL_CFG",
+	"ROLL_OFF_CFG",  /* 10 */
+	"DEMUX_CFG",
+	"FOV_CFG",
+	"MAIN_SCALER_CFG",
+	"WB_CFG",
+	"COLOR_COR_CFG", /* 15 */
+	"RGB_G_CFG",
+	"LA_CFG",
+	"CHROMA_EN_CFG",
+	"CHROMA_SUP_CFG",
+	"MCE_CFG", /* 20 */
+	"SK_ENHAN_CFG",
+	"ASF_CFG",
+	"S2Y_CFG",
+	"S2CbCr_CFG",
+	"CHROMA_SUBS_CFG",  /* 25 */
+	"OUT_CLAMP_CFG",
+	"FRAME_SKIP_CFG",
+	"DUMMY_1",
+	"DUMMY_2",
+	"DUMMY_3",  /* 30 */
+	"UPDATE",
+	"BL_LVL_UPDATE",
+	"DEMUX_UPDATE",
+	"FOV_UPDATE",
+	"MAIN_SCALER_UPDATE",  /* 35 */
+	"WB_UPDATE",
+	"COLOR_COR_UPDATE",
+	"RGB_G_UPDATE",
+	"LA_UPDATE",
+	"CHROMA_EN_UPDATE",  /* 40 */
+	"CHROMA_SUP_UPDATE",
+	"MCE_UPDATE",
+	"SK_ENHAN_UPDATE",
+	"S2CbCr_UPDATE",
+	"S2Y_UPDATE",  /* 45 */
+	"ASF_UPDATE",
+	"FRAME_SKIP_UPDATE",
+	"CAMIF_FRAME_UPDATE",
+	"STATS_AF_UPDATE",
+	"STATS_AE_UPDATE",  /* 50 */
+	"STATS_AWB_UPDATE",
+	"STATS_RS_UPDATE",
+	"STATS_CS_UPDATE",
+	"STATS_SKIN_UPDATE",
+	"STATS_IHIST_UPDATE",  /* 55 */
+	"DUMMY_4",
+	"EPOCH1_ACK",
+	"EPOCH2_ACK",
+	"START_RECORDING",
+	"STOP_RECORDING",  /* 60 */
+	"DUMMY_5",
+	"DUMMY_6",
+	"CAPTURE",
+	"DUMMY_7",
+	"STOP",  /* 65 */
+	"GET_HW_VERSION",
+	"GET_FRAME_SKIP_COUNTS",
+	"OUTPUT1_BUFFER_ENQ",
+	"OUTPUT2_BUFFER_ENQ",
+	"OUTPUT3_BUFFER_ENQ",  /* 70 */
+	"JPEG_OUT_BUF_ENQ",
+	"RAW_OUT_BUF_ENQ",
+	"RAW_IN_BUF_ENQ",
+	"STATS_AF_ENQ",
+	"STATS_AE_ENQ",  /* 75 */
+	"STATS_AWB_ENQ",
+	"STATS_RS_ENQ",
+	"STATS_CS_ENQ",
+	"STATS_SKIN_ENQ",
+	"STATS_IHIST_ENQ",  /* 80 */
+	"DUMMY_8",
+	"JPEG_ENC_CFG",
+	"DUMMY_9",
+	"STATS_AF_START",
+	"STATS_AF_STOP",  /* 85 */
+	"STATS_AE_START",
+	"STATS_AE_STOP",
+	"STATS_AWB_START",
+	"STATS_AWB_STOP",
+	"STATS_RS_START",  /* 90 */
+	"STATS_RS_STOP",
+	"STATS_CS_START",
+	"STATS_CS_STOP",
+	"STATS_SKIN_START",
+	"STATS_SKIN_STOP",  /* 95 */
+	"STATS_IHIST_START",
+	"STATS_IHIST_STOP",
+	"DUMMY_10",
+	"SYNC_TIMER_SETTING",
+	"ASYNC_TIMER_SETTING",  /* 100 */
+	"LIVESHOT",
+	"LA_SETUP",
+	"LINEARIZATION_CFG",
+	"DEMOSAICV3",
+	"DEMOSAICV3_ABCC_CFG", /* 105 */
+	"DEMOSAICV3_DBCC_CFG",
+	"DEMOSAICV3_DBPC_CFG",
+	"DEMOSAICV3_ABF_CFG",
+	"DEMOSAICV3_ABCC_UPDATE",
+	"DEMOSAICV3_DBCC_UPDATE", /* 110 */
+	"DEMOSAICV3_DBPC_UPDATE",
+	"XBAR_CFG",
+	"EZTUNE_CFG",
+	"V31_ZSL",
+	"LINEARIZATION_UPDATE", /*115*/
+	"DEMOSAICV3_ABF_UPDATE",
+	"CLF_CFG",
+	"CLF_LUMA_UPDATE",
+	"CLF_CHROMA_UPDATE",
+	"PCA_ROLL_OFF_CFG", /*120*/
+	"PCA_ROLL_OFF_UPDATE",
+	"GET_REG_DUMP",
+	"GET_LINEARIZATON_TABLE",
+	"GET_MESH_ROLLOFF_TABLE",
+	"GET_PCA_ROLLOFF_TABLE", /*125*/
+	"GET_RGB_G_TABLE",
+	"GET_LA_TABLE",
+	"DEMOSAICV3_UPDATE",
+};
+
+static void vfe31_stop(void)
+{
+	unsigned long flags;
+
+	atomic_set(&vfe31_ctrl->vstate, 0);
+
+	/* for reset hw modules, and send msg when reset_irq comes.*/
+	spin_lock_irqsave(&vfe31_ctrl->stop_flag_lock, flags);
+	vfe31_ctrl->stop_ack_pending = TRUE;
+	spin_unlock_irqrestore(&vfe31_ctrl->stop_flag_lock, flags);
+
+	/* disable all interrupts.  */
+	/* in either continuous or snapshot mode, stop command can be issued
+	 * at any time. stop camif immediately. */
+	msm_io_w_mb(CAMIF_COMMAND_STOP_IMMEDIATELY,
+		vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
+
+	/* disable all interrupts.  */
+	msm_io_w(VFE_DISABLE_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
+	msm_io_w(VFE_DISABLE_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* clear all pending interrupts*/
+	msm_io_w(VFE_CLEAR_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+	msm_io_w(VFE_CLEAR_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_io_w_mb(1,
+		vfe31_ctrl->vfebase + VFE_IRQ_CMD);
+
+	/* now enable only halt_irq & reset_irq */
+	msm_io_w(0xf0000000,          /* this is for async timer. */
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
+	msm_io_w(VFE_IMASK_WHILE_STOPPING_1,
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* then apply axi halt command. */
+	msm_io_w_mb(AXI_HALT,
+		vfe31_ctrl->vfebase + VFE_AXI_CMD);
+
+	msm_io_w_mb(VFE_RESET_UPON_STOP_CMD,
+		vfe31_ctrl->vfebase + VFE_GLOBAL_RESET);
+}
+
+static void vfe31_subdev_notify(int id, int path)
+{
+	struct msm_vfe_resp *rp;
+	unsigned long flags;
+	spin_lock_irqsave(&vfe31_ctrl->sd_notify_lock, flags);
+	rp = msm_isp_sync_alloc(sizeof(struct msm_vfe_resp), GFP_ATOMIC);
+	if (!rp) {
+		CDBG("rp: cannot allocate buffer\n");
+		spin_unlock_irqrestore(&vfe31_ctrl->sd_notify_lock, flags);
+		return;
+	}
+	CDBG("vfe31_subdev_notify : msgId = %d\n", id);
+	rp->evt_msg.type   = MSM_CAMERA_MSG;
+	rp->evt_msg.msg_id = path;
+	rp->type	   = id;
+	v4l2_subdev_notify(&vfe31_ctrl->subdev, NOTIFY_VFE_BUF_EVT, rp);
+	spin_unlock_irqrestore(&vfe31_ctrl->sd_notify_lock, flags);
+}
+
+static int vfe31_config_axi(int mode, uint32_t *ao)
+{
+	uint32_t *ch_info;
+	uint32_t *axi_cfg = ao+V31_AXI_RESERVED;
+	/* Update the corresponding write masters for each output*/
+	ch_info = axi_cfg + V31_AXI_CFG_LEN;
+	vfe31_ctrl->outpath.out0.ch0 = 0x0000FFFF & *ch_info;
+	vfe31_ctrl->outpath.out0.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
+	vfe31_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info++;
+	vfe31_ctrl->outpath.out1.ch0 = 0x0000FFFF & *ch_info;
+	vfe31_ctrl->outpath.out1.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
+	vfe31_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info++;
+	vfe31_ctrl->outpath.out2.ch0 = 0x0000FFFF & *ch_info;
+	vfe31_ctrl->outpath.out2.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
+	vfe31_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info++;
+
+	switch (mode) {
+	case OUTPUT_PRIM:
+		vfe31_ctrl->outpath.output_mode =
+			VFE31_OUTPUT_MODE_PRIMARY;
+		break;
+	case OUTPUT_PRIM_ALL_CHNLS:
+		vfe31_ctrl->outpath.output_mode =
+			VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
+		break;
+	case OUTPUT_PRIM|OUTPUT_SEC:
+		vfe31_ctrl->outpath.output_mode =
+			VFE31_OUTPUT_MODE_PRIMARY;
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_SECONDARY;
+		break;
+	case OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS:
+		vfe31_ctrl->outpath.output_mode =
+			VFE31_OUTPUT_MODE_PRIMARY;
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS;
+		break;
+	case OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC:
+		vfe31_ctrl->outpath.output_mode =
+			VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_SECONDARY;
+		break;
+	default:
+		pr_err("%s Invalid AXI mode %d ", __func__, mode);
+		return -EINVAL;
+	}
+
+	msm_io_memcpy(vfe31_ctrl->vfebase +
+		vfe31_cmd[VFE_CMD_AXI_OUT_CFG].offset, axi_cfg,
+		vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length - V31_AXI_CH_INF_LEN -
+			V31_AXI_RESERVED);
+	return 0;
+}
+
+static void vfe31_reset_internal_variables(void)
+{
+	unsigned long flags;
+	vfe31_ctrl->vfeImaskCompositePacked = 0;
+	/* state control variables */
+	vfe31_ctrl->start_ack_pending = FALSE;
+	atomic_set(&irq_cnt, 0);
+
+	spin_lock_irqsave(&vfe31_ctrl->stop_flag_lock, flags);
+	vfe31_ctrl->stop_ack_pending  = FALSE;
+	spin_unlock_irqrestore(&vfe31_ctrl->stop_flag_lock, flags);
+
+	vfe31_ctrl->reset_ack_pending  = FALSE;
+
+	spin_lock_irqsave(&vfe31_ctrl->update_ack_lock, flags);
+	vfe31_ctrl->update_ack_pending = FALSE;
+	spin_unlock_irqrestore(&vfe31_ctrl->update_ack_lock, flags);
+
+	vfe31_ctrl->recording_state = VFE_STATE_IDLE;
+	vfe31_ctrl->liveshot_state = VFE_STATE_IDLE;
+
+	atomic_set(&vfe31_ctrl->vstate, 0);
+
+	/* 0 for continuous mode, 1 for snapshot mode */
+	vfe31_ctrl->operation_mode = 0;
+	vfe31_ctrl->outpath.output_mode = 0;
+	vfe31_ctrl->vfe_capture_count = 0;
+
+	/* this is unsigned 32 bit integer. */
+	vfe31_ctrl->vfeFrameId = 0;
+	/* Stats control variables. */
+	memset(&(vfe31_ctrl->afStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe31_ctrl->awbStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe31_ctrl->aecStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe31_ctrl->ihistStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe31_ctrl->rsStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe31_ctrl->csStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	vfe31_ctrl->frame_skip_cnt = 31;
+	vfe31_ctrl->frame_skip_pattern = 0xffffffff;
+	vfe31_ctrl->snapshot_frame_cnt = 0;
+}
+
+static void vfe31_reset(void)
+{
+	vfe31_reset_internal_variables();
+	/* disable all interrupts.  vfeImaskLocal is also reset to 0
+	* to begin with. */
+	msm_io_w(VFE_DISABLE_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
+
+	msm_io_w(VFE_DISABLE_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* clear all pending interrupts*/
+	msm_io_w(VFE_CLEAR_ALL_IRQS, vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+	msm_io_w(VFE_CLEAR_ALL_IRQS, vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_io_w_mb(1, vfe31_ctrl->vfebase + VFE_IRQ_CMD);
+
+	/* enable reset_ack interrupt.  */
+	msm_io_w(VFE_IMASK_WHILE_STOPPING_1,
+	vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* Write to VFE_GLOBAL_RESET_CMD to reset the vfe hardware. Once reset
+	 * is done, hardware interrupt will be generated.  VFE ist processes
+	 * the interrupt to complete the function call.  Note that the reset
+	 * function is synchronous. */
+
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_io_w_mb(VFE_RESET_UPON_RESET_CMD,
+		vfe31_ctrl->vfebase + VFE_GLOBAL_RESET);
+}
+
+static int vfe31_operation_config(uint32_t *cmd)
+{
+	uint32_t *p = cmd;
+
+	vfe31_ctrl->operation_mode = *p;
+	vfe31_ctrl->stats_comp = *(++p);
+	vfe31_ctrl->hfr_mode = *(++p);
+
+	msm_io_w(*(++p), vfe31_ctrl->vfebase + VFE_CFG);
+	msm_io_w(*(++p), vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+	msm_io_w(*(++p), vfe31_ctrl->vfebase + VFE_REALIGN_BUF);
+	msm_io_w(*(++p), vfe31_ctrl->vfebase + VFE_CHROMA_UP);
+	msm_io_w(*(++p), vfe31_ctrl->vfebase + VFE_STATS_CFG);
+	return 0;
+}
+
+static uint32_t vfe_stats_awb_buf_init(struct vfe_cmd_stats_buf *in)
+{
+	uint32_t *ptr = in->statsBuf;
+	uint32_t addr;
+
+	addr = ptr[0];
+	msm_io_w(addr, vfe31_ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
+	addr = ptr[1];
+	msm_io_w(addr, vfe31_ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
+	vfe31_ctrl->awbStatsControl.nextFrameAddrBuf = in->statsBuf[2];
+	return 0;
+}
+
+static uint32_t vfe_stats_aec_buf_init(struct vfe_cmd_stats_buf *in)
+{
+	uint32_t *ptr = in->statsBuf;
+	uint32_t addr;
+
+	addr = ptr[0];
+	msm_io_w(addr, vfe31_ctrl->vfebase + VFE_BUS_STATS_AEC_WR_PING_ADDR);
+	addr = ptr[1];
+	msm_io_w(addr, vfe31_ctrl->vfebase + VFE_BUS_STATS_AEC_WR_PONG_ADDR);
+
+	vfe31_ctrl->aecStatsControl.nextFrameAddrBuf = in->statsBuf[2];
+	return 0;
+}
+
+static uint32_t vfe_stats_af_buf_init(struct vfe_cmd_stats_buf *in)
+{
+	uint32_t *ptr = in->statsBuf;
+	uint32_t addr;
+
+	addr = ptr[0];
+	msm_io_w(addr, vfe31_ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
+	addr = ptr[1];
+	msm_io_w(addr, vfe31_ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
+
+	vfe31_ctrl->afStatsControl.nextFrameAddrBuf = in->statsBuf[2];
+	return 0;
+}
+
+static uint32_t vfe_stats_ihist_buf_init(struct vfe_cmd_stats_buf *in)
+{
+	uint32_t *ptr = in->statsBuf;
+	uint32_t addr;
+
+	addr = ptr[0];
+	msm_io_w(addr, vfe31_ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PING_ADDR);
+	addr = ptr[1];
+	msm_io_w(addr, vfe31_ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PONG_ADDR);
+
+	vfe31_ctrl->ihistStatsControl.nextFrameAddrBuf = in->statsBuf[2];
+	return 0;
+}
+
+static uint32_t vfe_stats_rs_buf_init(struct vfe_cmd_stats_buf *in)
+{
+	uint32_t *ptr = in->statsBuf;
+	uint32_t addr;
+
+	addr = ptr[0];
+	msm_io_w(addr, vfe31_ctrl->vfebase + VFE_BUS_STATS_RS_WR_PING_ADDR);
+	addr = ptr[1];
+	msm_io_w(addr, vfe31_ctrl->vfebase + VFE_BUS_STATS_RS_WR_PONG_ADDR);
+
+	vfe31_ctrl->rsStatsControl.nextFrameAddrBuf = in->statsBuf[2];
+	return 0;
+}
+
+static uint32_t vfe_stats_cs_buf_init(struct vfe_cmd_stats_buf *in)
+{
+	uint32_t *ptr = in->statsBuf;
+	uint32_t addr;
+
+	addr = ptr[0];
+	msm_io_w(addr, vfe31_ctrl->vfebase + VFE_BUS_STATS_CS_WR_PING_ADDR);
+	addr = ptr[1];
+	msm_io_w(addr, vfe31_ctrl->vfebase + VFE_BUS_STATS_CS_WR_PONG_ADDR);
+
+	vfe31_ctrl->csStatsControl.nextFrameAddrBuf = in->statsBuf[2];
+	return 0;
+}
+
+static void msm_io_dump2(void __iomem *addr, int size)
+{
+	char line_str[BUFF_SIZE_128], *p_str;
+	int i;
+	u32 *p = (u32 *) addr;
+	u32 data;
+	CDBG("%s: %p %d\n", __func__, addr, size);
+	line_str[0] = '\0';
+	p_str = line_str;
+	for (i = 0; i < size/4; i++) {
+		if (i % 4 == 0) {
+			snprintf(p_str, 12, "%08x: ", (u32) p);
+			p_str += 10;
+		}
+		data = readl_relaxed(p++);
+		snprintf(p_str, 12, "%08x ", data);
+		p_str += 9;
+		if ((i + 1) % 4 == 0) {
+			CDBG("%s\n", line_str);
+			line_str[0] = '\0';
+			p_str = line_str;
+		}
+	}
+	if (line_str[0] != '\0')
+		CDBG("%s\n", line_str);
+}
+
+static void vfe31_start_common(void)
+{
+	uint32_t irq_mask = 0x00E00021;
+	vfe31_ctrl->start_ack_pending = TRUE;
+	CDBG("VFE opertaion mode = 0x%x, output mode = 0x%x\n",
+		vfe31_ctrl->operation_mode, vfe31_ctrl->outpath.output_mode);
+	if (vfe31_ctrl->stats_comp)
+		irq_mask |= VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK;
+	else
+		irq_mask |= 0x000FE000;
+
+	msm_io_w(irq_mask, vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
+	msm_io_w(VFE_IMASK_WHILE_STOPPING_1,
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	msm_io_w_mb(1, vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
+
+	msm_io_dump2(vfe31_ctrl->vfebase, vfe31_ctrl->register_total*4);
+	atomic_set(&vfe31_ctrl->vstate, 1);
+}
+
+static int vfe31_start_recording(void)
+{
+	struct msm_sync *sync = vfe_syncdata;
+	msm_camio_bus_scale_cfg(
+		sync->sdata->pdata->cam_bus_scale_table, S_VIDEO);
+	vfe31_ctrl->recording_state = VFE_STATE_START_REQUESTED;
+	msm_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	return 0;
+}
+
+static int vfe31_stop_recording(void)
+{
+	struct msm_sync *sync = vfe_syncdata;
+	vfe31_ctrl->recording_state = VFE_STATE_STOP_REQUESTED;
+	msm_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	msm_camio_bus_scale_cfg(
+		sync->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
+	return 0;
+}
+
+static void vfe31_start_liveshot(void){
+	struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
+	if (p_sync)
+		p_sync->liveshot_enabled = true;
+
+	/* Hardcode 1 live snapshot for now. */
+	vfe31_ctrl->outpath.out0.capture_cnt = 1;
+	vfe31_ctrl->vfe_capture_count = vfe31_ctrl->outpath.out0.capture_cnt;
+
+	vfe31_ctrl->liveshot_state = VFE_STATE_START_REQUESTED;
+	msm_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+}
+
+static int vfe31_zsl(void)
+{
+	struct msm_sync *sync = vfe_syncdata;
+	uint32_t irq_comp_mask = 0;
+	/* capture command is valid for both idle and active state. */
+	irq_comp_mask	=
+		msm_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+
+	CDBG("%s:op mode %d O/P Mode %d\n", __func__,
+		vfe31_ctrl->operation_mode, vfe31_ctrl->outpath.output_mode);
+
+	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PRIMARY) {
+		irq_comp_mask |= ((0x1 << (vfe31_ctrl->outpath.out0.ch0)) |
+			(0x1 << (vfe31_ctrl->outpath.out0.ch1)));
+	} else if (vfe31_ctrl->outpath.output_mode &
+		VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+		irq_comp_mask |= ((0x1 << (vfe31_ctrl->outpath.out0.ch0)) |
+			(0x1 << (vfe31_ctrl->outpath.out0.ch1)) |
+			(0x1 << (vfe31_ctrl->outpath.out0.ch2)));
+	}
+
+	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_SECONDARY) {
+		irq_comp_mask |= ((0x1 << (vfe31_ctrl->outpath.out1.ch0 + 8)) |
+			(0x1 << (vfe31_ctrl->outpath.out1.ch1 + 8)));
+	} else if (vfe31_ctrl->outpath.output_mode &
+		VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+		irq_comp_mask |= ((0x1 << (vfe31_ctrl->outpath.out1.ch0 + 8)) |
+			(0x1 << (vfe31_ctrl->outpath.out1.ch1 + 8)) |
+			(0x1 << (vfe31_ctrl->outpath.out1.ch2 + 8)));
+	}
+
+	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PRIMARY) {
+		msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+		msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+	} else if (vfe31_ctrl->outpath.output_mode &
+		VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+		msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+		msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+		msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
+	}
+
+	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_SECONDARY) {
+		msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+		msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
+	} else if (vfe31_ctrl->outpath.output_mode &
+		VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+		msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+		msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
+		msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch2]);
+	}
+
+	msm_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+	vfe31_start_common();
+	msm_camio_bus_scale_cfg(
+		sync->sdata->pdata->cam_bus_scale_table, S_ZSL);
+
+	msm_io_w(1, vfe31_ctrl->vfebase + 0x18C);
+	msm_io_w(1, vfe31_ctrl->vfebase + 0x188);
+	return 0;
+}
+static int vfe31_capture_raw(uint32_t num_frames_capture)
+{
+	uint32_t irq_comp_mask = 0;
+	struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
+
+	vfe31_ctrl->outpath.out0.capture_cnt = num_frames_capture;
+	vfe31_ctrl->vfe_capture_count = num_frames_capture;
+
+	irq_comp_mask =
+		msm_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+
+	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PRIMARY) {
+		irq_comp_mask |= (0x1 << (vfe31_ctrl->outpath.out0.ch0));
+		msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+	}
+
+	msm_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+	msm_camio_bus_scale_cfg(
+		p_sync->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
+	vfe31_start_common();
+	return 0;
+}
+
+static int vfe31_capture(uint32_t num_frames_capture)
+{
+	uint32_t irq_comp_mask = 0;
+	struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
+	if (p_sync) {
+		p_sync->snap_count = num_frames_capture;
+		p_sync->thumb_count = num_frames_capture;
+	}
+	/* capture command is valid for both idle and active state. */
+	vfe31_ctrl->outpath.out1.capture_cnt = num_frames_capture;
+	if (vfe31_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
+		vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN ||
+		vfe31_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
+		vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) {
+		vfe31_ctrl->outpath.out0.capture_cnt =
+			num_frames_capture;
+	}
+
+	vfe31_ctrl->vfe_capture_count = num_frames_capture;
+	irq_comp_mask	= msm_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+
+	if (vfe31_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
+		vfe31_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
+		vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN) {
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_PRIMARY) {
+			irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
+				0x1 << vfe31_ctrl->outpath.out0.ch1);
+		}
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_SECONDARY) {
+			irq_comp_mask |=
+				(0x1 << (vfe31_ctrl->outpath.out1.ch0 + 8) |
+				0x1 << (vfe31_ctrl->outpath.out1.ch1 + 8));
+		}
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_PRIMARY) {
+			msm_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+			msm_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+		}
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_SECONDARY) {
+			msm_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+			msm_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
+		}
+	}
+
+	vfe31_ctrl->vfe_capture_count = num_frames_capture;
+
+	msm_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+	msm_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+	msm_camio_bus_scale_cfg(
+		p_sync->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
+
+	vfe31_start_common();
+	/* for debug */
+	msm_io_w(1, vfe31_ctrl->vfebase + 0x18C);
+	msm_io_w(1, vfe31_ctrl->vfebase + 0x188);
+	return 0;
+}
+
+static int vfe31_start(void)
+{
+	uint32_t irq_comp_mask = 0;
+	struct msm_sync *sync = vfe_syncdata;
+
+	irq_comp_mask	=
+		msm_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+
+	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PRIMARY) {
+		irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
+			0x1 << vfe31_ctrl->outpath.out0.ch1);
+	} else if (vfe31_ctrl->outpath.output_mode &
+		VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+		irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
+			0x1 << vfe31_ctrl->outpath.out0.ch1 |
+			0x1 << vfe31_ctrl->outpath.out0.ch2);
+	}
+	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_SECONDARY) {
+		irq_comp_mask |= (0x1 << (vfe31_ctrl->outpath.out1.ch0 + 8) |
+			0x1 << (vfe31_ctrl->outpath.out1.ch1 + 8));
+	} else if (vfe31_ctrl->outpath.output_mode &
+		VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+		irq_comp_mask |= (0x1 << (vfe31_ctrl->outpath.out1.ch0 + 8) |
+			0x1 << (vfe31_ctrl->outpath.out1.ch1 + 8) |
+			0x1 << (vfe31_ctrl->outpath.out1.ch2 + 8));
+	}
+	msm_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+
+	switch (vfe31_ctrl->operation_mode) {
+	case VFE_OUTPUTS_PREVIEW:
+	case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_PRIMARY) {
+			msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+			msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+		} else if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+			msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+			msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+			msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
+		}
+		break;
+	default:
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_SECONDARY) {
+			msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+			msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
+		} else if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+			msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+			msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
+			msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch2]);
+		}
+		break;
+	}
+	msm_camio_bus_scale_cfg(
+		sync->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
+	vfe31_start_common();
+	return 0;
+}
+
+static void vfe31_update(void)
+{
+	unsigned long flags;
+
+	if (vfe31_ctrl->update_la) {
+		if (!msm_io_r(vfe31_ctrl->vfebase + V31_LA_OFF))
+			msm_io_w(1, vfe31_ctrl->vfebase + V31_LA_OFF);
+		else
+			msm_io_w(0, vfe31_ctrl->vfebase + V31_LA_OFF);
+		vfe31_ctrl->update_la = false;
+	}
+
+	if (vfe31_ctrl->update_gamma) {
+		if (!msm_io_r(vfe31_ctrl->vfebase + V31_RGB_G_OFF))
+			msm_io_w(7, vfe31_ctrl->vfebase+V31_RGB_G_OFF);
+		else
+			msm_io_w(0, vfe31_ctrl->vfebase+V31_RGB_G_OFF);
+		vfe31_ctrl->update_gamma = false;
+	}
+
+	spin_lock_irqsave(&vfe31_ctrl->update_ack_lock, flags);
+	vfe31_ctrl->update_ack_pending = TRUE;
+	spin_unlock_irqrestore(&vfe31_ctrl->update_ack_lock, flags);
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	return;
+}
+
+static void vfe31_sync_timer_stop(void)
+{
+	uint32_t value = 0;
+	vfe31_ctrl->sync_timer_state = 0;
+	if (vfe31_ctrl->sync_timer_number == 0)
+		value = 0x10000;
+	else if (vfe31_ctrl->sync_timer_number == 1)
+		value = 0x20000;
+	else if (vfe31_ctrl->sync_timer_number == 2)
+		value = 0x40000;
+
+	/* Timer Stop */
+	msm_io_w(value, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF);
+}
+
+static void vfe31_sync_timer_start(const uint32_t *tbl)
+{
+	/* set bit 8 for auto increment. */
+	uint32_t value = 1;
+	uint32_t val;
+
+	vfe31_ctrl->sync_timer_state = *tbl++;
+	vfe31_ctrl->sync_timer_repeat_count = *tbl++;
+	vfe31_ctrl->sync_timer_number = *tbl++;
+	CDBG("%s timer_state %d, repeat_cnt %d timer number %d\n",
+		 __func__, vfe31_ctrl->sync_timer_state,
+		 vfe31_ctrl->sync_timer_repeat_count,
+		 vfe31_ctrl->sync_timer_number);
+
+	if (vfe31_ctrl->sync_timer_state) { /* Start Timer */
+		value = value << vfe31_ctrl->sync_timer_number;
+	} else { /* Stop Timer */
+		CDBG("Failed to Start timer\n");
+		return;
+	}
+
+	/* Timer Start */
+	msm_io_w(value, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF);
+	/* Sync Timer Line Start */
+	value = *tbl++;
+	msm_io_w(value, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF +
+		4 + ((vfe31_ctrl->sync_timer_number) * 12));
+	/* Sync Timer Pixel Start */
+	value = *tbl++;
+	msm_io_w(value, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF +
+		 8 + ((vfe31_ctrl->sync_timer_number) * 12));
+	/* Sync Timer Pixel Duration */
+	value = *tbl++;
+	val = vfe_clk_rate / 10000;
+	val = 10000000 / val;
+	val = value * 10000 / val;
+	CDBG("%s: Pixel Clk Cycles!!! %d\n", __func__, val);
+	msm_io_w(val, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF +
+		12 + ((vfe31_ctrl->sync_timer_number) * 12));
+	/* Timer0 Active High/LOW */
+	value = *tbl++;
+	msm_io_w(value, vfe31_ctrl->vfebase + V31_SYNC_TIMER_POLARITY_OFF);
+	/* Selects sync timer 0 output to drive onto timer1 port */
+	value = 0;
+	msm_io_w(value, vfe31_ctrl->vfebase + V31_TIMER_SELECT_OFF);
+}
+
+static void vfe31_program_dmi_cfg(enum VFE31_DMI_RAM_SEL bankSel)
+{
+	/* set bit 8 for auto increment. */
+	uint32_t value = VFE_DMI_CFG_DEFAULT;
+	value += (uint32_t)bankSel;
+	CDBG("%s: banksel = %d\n", __func__, bankSel);
+
+	msm_io_w(value, vfe31_ctrl->vfebase + VFE_DMI_CFG);
+	/* by default, always starts with offset 0.*/
+	msm_io_w(0, vfe31_ctrl->vfebase + VFE_DMI_ADDR);
+}
+static void vfe31_write_gamma_cfg(enum VFE31_DMI_RAM_SEL channel_sel,
+						const uint32_t *tbl)
+{
+	int i;
+	uint32_t value, value1, value2;
+	vfe31_program_dmi_cfg(channel_sel);
+	for (i = 0 ; i < (VFE31_GAMMA_NUM_ENTRIES/2) ; i++) {
+		value = *tbl++;
+		value1 = value & 0x0000FFFF;
+		value2 = (value & 0xFFFF0000)>>16;
+		msm_io_w((value1), vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+		msm_io_w((value2), vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+	}
+	vfe31_program_dmi_cfg(NO_MEM_SELECTED);
+}
+
+static void vfe31_read_gamma_cfg(enum VFE31_DMI_RAM_SEL channel_sel,
+	uint32_t *tbl)
+{
+	int i;
+	vfe31_program_dmi_cfg(channel_sel);
+	CDBG("%s: Gamma table channel: %d\n", __func__, channel_sel);
+	for (i = 0 ; i < VFE31_GAMMA_NUM_ENTRIES ; i++) {
+		*tbl = msm_io_r(vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+		CDBG("%s: %08x\n", __func__, *tbl);
+		tbl++;
+	}
+	vfe31_program_dmi_cfg(NO_MEM_SELECTED);
+}
+
+static void vfe31_write_la_cfg(enum VFE31_DMI_RAM_SEL channel_sel,
+						const uint32_t *tbl)
+{
+	uint32_t i;
+	uint32_t value, value1, value2;
+
+	vfe31_program_dmi_cfg(channel_sel);
+	for (i = 0 ; i < (VFE31_LA_TABLE_LENGTH/2) ; i++) {
+		value = *tbl++;
+		value1 = value & 0x0000FFFF;
+		value2 = (value & 0xFFFF0000)>>16;
+		msm_io_w((value1), vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+		msm_io_w((value2), vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+	}
+	vfe31_program_dmi_cfg(NO_MEM_SELECTED);
+}
+
+static struct vfe31_output_ch *vfe31_get_ch(int path)
+{
+	struct vfe31_output_ch *ch = NULL;
+
+	if (path == VFE_MSG_OUTPUT_PRIMARY)
+		ch = &vfe31_ctrl->outpath.out0;
+	else if (path == VFE_MSG_OUTPUT_SECONDARY)
+		ch = &vfe31_ctrl->outpath.out1;
+	else
+		pr_err("%s: Invalid path %d\n", __func__, path);
+
+	BUG_ON(ch == NULL);
+	return ch;
+}
+static struct msm_free_buf *vfe31_check_free_buffer(int id, int path)
+{
+	struct vfe31_output_ch *outch = NULL;
+	struct msm_free_buf *b = NULL;
+	vfe31_subdev_notify(id, path);
+	outch = vfe31_get_ch(path);
+	if (outch->free_buf.ch_paddr[0])
+		b = &outch->free_buf;
+	return b;
+}
+static int vfe31_configure_pingpong_buffers(int id, int path)
+{
+	struct vfe31_output_ch *outch = NULL;
+	int rc = 0;
+	vfe31_subdev_notify(id, path);
+	outch = vfe31_get_ch(path);
+	if (outch->ping.ch_paddr[0] && outch->pong.ch_paddr[0]) {
+		/* Configure Preview Ping Pong */
+		CDBG("%s Configure ping/pong address for %d",
+			__func__, path);
+		vfe31_put_ch_ping_addr(outch->ch0,
+			outch->ping.ch_paddr[0]);
+		vfe31_put_ch_pong_addr(outch->ch0,
+			outch->pong.ch_paddr[0]);
+
+		if (vfe31_ctrl->operation_mode !=
+			VFE_OUTPUTS_RAW) {
+			vfe31_put_ch_ping_addr(outch->ch1,
+				outch->ping.ch_paddr[1]);
+			vfe31_put_ch_pong_addr(outch->ch1,
+				outch->pong.ch_paddr[1]);
+		}
+
+		if (outch->ping.num_planes > 2)
+			vfe31_put_ch_ping_addr(outch->ch2,
+				outch->ping.ch_paddr[2]);
+		if (outch->pong.num_planes > 2)
+			vfe31_put_ch_pong_addr(outch->ch2,
+				outch->pong.ch_paddr[2]);
+
+		/* avoid stale info */
+		memset(&outch->ping, 0, sizeof(struct msm_free_buf));
+		memset(&outch->pong, 0, sizeof(struct msm_free_buf));
+	} else {
+		pr_err("%s ping/pong addr is null!!", __func__);
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+static void vfe31_send_isp_msg(struct vfe31_ctrl_type *vctrl,
+	uint32_t isp_msg_id)
+{
+	struct isp_msg_event isp_msg_evt;
+
+	isp_msg_evt.msg_id = isp_msg_id;
+	isp_msg_evt.sof_count = vfe31_ctrl->vfeFrameId;
+	v4l2_subdev_notify(&vctrl->subdev,
+		NOTIFY_ISP_MSG_EVT, (void *)&isp_msg_evt);
+}
+
+static int vfe31_proc_general(struct msm_isp_cmd *cmd)
+{
+	int i , rc = 0;
+	uint32_t old_val = 0 , new_val = 0;
+	uint32_t *cmdp = NULL;
+	uint32_t *cmdp_local = NULL;
+	uint32_t snapshot_cnt = 0;
+	uint32_t temp1 = 0, temp2 = 0;
+
+	CDBG("vfe31_proc_general: cmdID = %s, length = %d\n",
+		vfe31_general_cmd[cmd->id], cmd->length);
+	switch (cmd->id) {
+	case VFE_CMD_RESET:
+		pr_info("vfe31_proc_general: cmdID = %s\n",
+			vfe31_general_cmd[cmd->id]);
+		vfe31_reset();
+		break;
+	case VFE_CMD_START:
+		pr_info("vfe31_proc_general: cmdID = %s\n",
+			vfe31_general_cmd[cmd->id]);
+		if ((vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_PREVIEW_AND_VIDEO) ||
+			(vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_PREVIEW))
+			/* Configure primary channel */
+			rc = vfe31_configure_pingpong_buffers(
+				VFE_MSG_V31_START, VFE_MSG_OUTPUT_PRIMARY);
+		else
+			/* Configure secondary channel */
+			rc = vfe31_configure_pingpong_buffers(
+				VFE_MSG_V31_START, VFE_MSG_OUTPUT_SECONDARY);
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers"
+				" for preview", __func__);
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		rc = vfe31_start();
+		break;
+	case VFE_CMD_UPDATE:
+		vfe31_update();
+		break;
+	case VFE_CMD_CAPTURE_RAW:
+		pr_info("%s: cmdID = VFE_CMD_CAPTURE_RAW\n", __func__);
+		if (copy_from_user(&snapshot_cnt, (void __user *)(cmd->value),
+			sizeof(uint32_t))) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		rc = vfe31_configure_pingpong_buffers(VFE_MSG_V31_CAPTURE,
+			VFE_MSG_OUTPUT_PRIMARY);
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers"
+				" for snapshot", __func__);
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		rc = vfe31_capture_raw(snapshot_cnt);
+		break;
+	case VFE_CMD_CAPTURE:
+		if (copy_from_user(&snapshot_cnt, (void __user *)(cmd->value),
+			sizeof(uint32_t))) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+
+		if (vfe31_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
+		vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) {
+			if (snapshot_cnt != 1) {
+				pr_err("only support 1 inline snapshot\n");
+				rc = -EINVAL;
+				goto proc_general_done;
+			}
+			/* Configure primary channel for JPEG */
+			rc = vfe31_configure_pingpong_buffers(
+				VFE_MSG_V31_JPEG_CAPTURE,
+				VFE_MSG_OUTPUT_PRIMARY);
+		} else {
+			/* Configure primary channel */
+			rc = vfe31_configure_pingpong_buffers(
+				VFE_MSG_V31_CAPTURE,
+				VFE_MSG_OUTPUT_PRIMARY);
+		}
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers"
+				" for primary output", __func__);
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		/* Configure secondary channel */
+		rc = vfe31_configure_pingpong_buffers(VFE_MSG_V31_CAPTURE,
+			VFE_MSG_OUTPUT_SECONDARY);
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers"
+				" for secondary output", __func__);
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		rc = vfe31_capture(snapshot_cnt);
+		break;
+	case VFE_CMD_START_RECORDING:
+		pr_info("vfe31_proc_general: cmdID = %s\n",
+			vfe31_general_cmd[cmd->id]);
+		if (vfe31_ctrl->operation_mode ==
+			VFE_OUTPUTS_PREVIEW_AND_VIDEO)
+			rc = vfe31_configure_pingpong_buffers(
+				VFE_MSG_V31_START_RECORDING,
+				VFE_MSG_OUTPUT_SECONDARY);
+		else if (vfe31_ctrl->operation_mode ==
+			VFE_OUTPUTS_VIDEO_AND_PREVIEW)
+			rc = vfe31_configure_pingpong_buffers(
+				VFE_MSG_V31_START_RECORDING,
+				VFE_MSG_OUTPUT_PRIMARY);
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers"
+				" for video", __func__);
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		rc = vfe31_start_recording();
+		break;
+	case VFE_CMD_STOP_RECORDING:
+		pr_info("vfe31_proc_general: cmdID = %s\n",
+			vfe31_general_cmd[cmd->id]);
+		rc = vfe31_stop_recording();
+		break;
+	case VFE_CMD_OPERATION_CFG:
+		if (cmd->length != V31_OPERATION_CFG_LEN) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(V31_OPERATION_CFG_LEN, GFP_ATOMIC);
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			V31_OPERATION_CFG_LEN)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		rc = vfe31_operation_config(cmdp);
+		break;
+
+	case VFE_CMD_STATS_AE_START:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val |= AE_BG_ENABLE_MASK;
+		msm_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		msm_io_memcpy(vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+		cmdp, (vfe31_cmd[cmd->id].length));
+		break;
+	case VFE_CMD_STATS_AF_START:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val |= AF_BF_ENABLE_MASK;
+		msm_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		msm_io_memcpy(vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+		cmdp, (vfe31_cmd[cmd->id].length));
+		break;
+	case VFE_CMD_STATS_AWB_START:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val |= AWB_ENABLE_MASK;
+		msm_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		msm_io_memcpy(vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+				cmdp, (vfe31_cmd[cmd->id].length));
+		break;
+
+	case VFE_CMD_STATS_IHIST_START:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val |= IHIST_ENABLE_MASK;
+		msm_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		msm_io_memcpy(vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp, (vfe31_cmd[cmd->id].length));
+		break;
+
+	case VFE_CMD_STATS_RS_START:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_io_memcpy(vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp, (vfe31_cmd[cmd->id].length));
+		break;
+
+	case VFE_CMD_STATS_CS_START:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_io_memcpy(vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp, (vfe31_cmd[cmd->id].length));
+		break;
+
+	case VFE_CMD_MCE_UPDATE:
+	case VFE_CMD_MCE_CFG:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		/* Incrementing with 4 so as to point to the 2nd Register as
+		the 2nd register has the mce_enable bit */
+		old_val = msm_io_r(vfe31_ctrl->vfebase +
+			V31_CHROMA_SUP_OFF + 4);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+		old_val &= MCE_EN_MASK;
+		new_val = new_val | old_val;
+		msm_io_memcpy(vfe31_ctrl->vfebase + V31_CHROMA_SUP_OFF + 4,
+			&new_val, 4);
+		cmdp_local += 1;
+
+		old_val = msm_io_r(vfe31_ctrl->vfebase +
+			V31_CHROMA_SUP_OFF + 8);
+		new_val = *cmdp_local;
+		old_val &= MCE_Q_K_MASK;
+		new_val = new_val | old_val;
+		msm_io_memcpy(vfe31_ctrl->vfebase + V31_CHROMA_SUP_OFF + 8,
+			&new_val, 4);
+		cmdp_local += 1;
+		msm_io_memcpy(vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp_local, (vfe31_cmd[cmd->id].length));
+		break;
+	case VFE_CMD_CHROMA_SUP_UPDATE:
+	case VFE_CMD_CHROMA_SUP_CFG:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		msm_io_memcpy(vfe31_ctrl->vfebase + V31_CHROMA_SUP_OFF,
+			cmdp_local, 4);
+
+		cmdp_local += 1;
+		new_val = *cmdp_local;
+		/* Incrementing with 4 so as to point to the 2nd Register as
+		 * the 2nd register has the mce_enable bit
+		 */
+		old_val = msm_io_r(vfe31_ctrl->vfebase +
+			V31_CHROMA_SUP_OFF + 4);
+		old_val &= ~MCE_EN_MASK;
+		new_val = new_val | old_val;
+		msm_io_memcpy(vfe31_ctrl->vfebase + V31_CHROMA_SUP_OFF + 4,
+			&new_val, 4);
+		cmdp_local += 1;
+
+		old_val = msm_io_r(vfe31_ctrl->vfebase +
+			V31_CHROMA_SUP_OFF + 8);
+		new_val = *cmdp_local;
+		old_val &= ~MCE_Q_K_MASK;
+		new_val = new_val | old_val;
+		msm_io_memcpy(vfe31_ctrl->vfebase + V31_CHROMA_SUP_OFF + 8,
+			&new_val, 4);
+		break;
+
+	case VFE_CMD_MESH_ROLL_OFF_CFG:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value) , cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		msm_io_memcpy(vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp_local, 16);
+		cmdp_local += 4;
+		vfe31_program_dmi_cfg(ROLLOFF_RAM);
+		/* for loop for extrcting init table. */
+		for (i = 0; i < (V31_MESH_ROLL_OFF_INIT_TABLE_SIZE * 2); i++) {
+			msm_io_w(*cmdp_local ,
+			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+			cmdp_local++;
+		}
+		CDBG("done writing init table\n");
+		/* by default, always starts with offset 0. */
+		msm_io_w(V31_MESH_ROLL_OFF_DELTA_TABLE_OFFSET,
+		vfe31_ctrl->vfebase + VFE_DMI_ADDR);
+		/* for loop for extracting delta table. */
+		for (i = 0; i < (V31_MESH_ROLL_OFF_DELTA_TABLE_SIZE * 2); i++) {
+			msm_io_w(*cmdp_local,
+			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+			cmdp_local++;
+		}
+		vfe31_program_dmi_cfg(NO_MEM_SELECTED);
+		break;
+
+	case VFE_CMD_GET_MESH_ROLLOFF_TABLE:
+		temp1 = sizeof(uint32_t) * ((V31_MESH_ROLL_OFF_INIT_TABLE_SIZE *
+			2) + (V31_MESH_ROLL_OFF_DELTA_TABLE_SIZE * 2));
+		if (cmd->length != temp1) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kzalloc(temp1, GFP_KERNEL);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		vfe31_program_dmi_cfg(ROLLOFF_RAM);
+		CDBG("%s: Mesh Rolloff init Table\n", __func__);
+		for (i = 0; i < (V31_MESH_ROLL_OFF_INIT_TABLE_SIZE * 2); i++) {
+			*cmdp_local =
+				msm_io_r(vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+			CDBG("%s: %08x\n", __func__, *cmdp_local);
+			cmdp_local++;
+		}
+		msm_io_w(V31_MESH_ROLL_OFF_DELTA_TABLE_OFFSET,
+			vfe31_ctrl->vfebase + VFE_DMI_ADDR);
+		CDBG("%s: Mesh Rolloff Delta Table\n", __func__);
+		for (i = 0; i < (V31_MESH_ROLL_OFF_DELTA_TABLE_SIZE * 2); i++) {
+			*cmdp_local =
+				msm_io_r(vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+			CDBG("%s: %08x\n", __func__, *cmdp_local);
+			cmdp_local++;
+		}
+		CDBG("done reading delta table\n");
+		vfe31_program_dmi_cfg(NO_MEM_SELECTED);
+		if (copy_to_user((void __user *)(cmd->value), cmdp,
+			temp1)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		break;
+	case VFE_CMD_LA_CFG:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		msm_io_memcpy(vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp_local, (vfe31_cmd[cmd->id].length));
+
+		cmdp_local += 1;
+		vfe31_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0, cmdp_local);
+		break;
+
+	case VFE_CMD_LA_UPDATE:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+
+		cmdp_local = cmdp + 1;
+		old_val = msm_io_r(vfe31_ctrl->vfebase + V31_LA_OFF);
+		if (old_val != 0x0)
+			vfe31_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0,
+				cmdp_local);
+		else
+			vfe31_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK1,
+				cmdp_local);
+		vfe31_ctrl->update_la = true;
+		break;
+
+	case VFE_CMD_GET_LA_TABLE:
+		temp1 = sizeof(uint32_t) * VFE31_LA_TABLE_LENGTH / 2;
+		if (cmd->length != temp1) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kzalloc(temp1, GFP_KERNEL);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		if (msm_io_r(vfe31_ctrl->vfebase + V31_LA_OFF))
+			vfe31_program_dmi_cfg(LUMA_ADAPT_LUT_RAM_BANK1);
+		else
+			vfe31_program_dmi_cfg(LUMA_ADAPT_LUT_RAM_BANK0);
+		for (i = 0 ; i < (VFE31_LA_TABLE_LENGTH / 2) ; i++) {
+			*cmdp_local =
+				msm_io_r(vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+			*cmdp_local |= (msm_io_r(vfe31_ctrl->vfebase +
+				VFE_DMI_DATA_LO)) << 16;
+			cmdp_local++;
+		}
+		vfe31_program_dmi_cfg(NO_MEM_SELECTED);
+		if (copy_to_user((void __user *)(cmd->value), cmdp,
+			temp1)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		break;
+	case VFE_CMD_SK_ENHAN_CFG:
+	case VFE_CMD_SK_ENHAN_UPDATE:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_io_memcpy(vfe31_ctrl->vfebase + V31_SCE_OFF,
+			cmdp, V31_SCE_LEN);
+		break;
+
+	case VFE_CMD_LIVESHOT:
+		/* Configure primary channel */
+		rc = vfe31_configure_pingpong_buffers(VFE_MSG_V31_CAPTURE,
+			VFE_MSG_OUTPUT_PRIMARY);
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers"
+				" for primary output", __func__);
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		vfe31_start_liveshot();
+		break;
+
+	case VFE_CMD_DEMOSAICV3:
+		if (cmd->length != V31_DEMOSAICV3_LEN) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+
+		old_val = msm_io_r(vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF);
+		old_val &= DEMOSAIC_MASK;
+		new_val = new_val | old_val;
+		*cmdp_local = new_val;
+
+		msm_io_memcpy(vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF,
+			cmdp_local, V31_DEMOSAICV3_LEN);
+		break;
+
+	case VFE_CMD_DEMOSAICV3_UPDATE:
+		if (cmd->length !=
+			V31_DEMOSAICV3_LEN * V31_DEMOSAICV3_UP_REG_CNT) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+
+		old_val = msm_io_r(vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF);
+		old_val &= DEMOSAIC_MASK;
+		new_val = new_val | old_val;
+		*cmdp_local = new_val;
+
+		msm_io_memcpy(vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF,
+			cmdp_local, V31_DEMOSAICV3_LEN);
+
+		break;
+
+	case VFE_CMD_DEMOSAICV3_ABCC_CFG:
+		rc = -EFAULT;
+		break;
+
+	case VFE_CMD_DEMOSAICV3_ABF_UPDATE:/* 116 ABF update  */
+	case VFE_CMD_DEMOSAICV3_ABF_CFG: /* 108 ABF config  */
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+
+		old_val = msm_io_r(vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF);
+		old_val &= ABF_MASK;
+		new_val = new_val | old_val;
+		*cmdp_local = new_val;
+
+		msm_io_memcpy(vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF,
+		    cmdp_local, 4);
+
+		cmdp_local += 1;
+		msm_io_memcpy(vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp_local, (vfe31_cmd[cmd->id].length));
+		break;
+
+	case VFE_CMD_DEMOSAICV3_DBCC_CFG:
+	case VFE_CMD_DEMOSAICV3_DBCC_UPDATE:
+		return -EINVAL;
+
+	case VFE_CMD_DEMOSAICV3_DBPC_CFG:
+	case VFE_CMD_DEMOSAICV3_DBPC_UPDATE:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+
+		old_val = msm_io_r(vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF);
+		old_val &= BPC_MASK;
+
+		new_val = new_val | old_val;
+		*cmdp_local = new_val;
+		msm_io_memcpy(vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF,
+					cmdp_local, V31_DEMOSAICV3_LEN);
+		cmdp_local += 1;
+		msm_io_memcpy(vfe31_ctrl->vfebase + V31_DEMOSAICV3_DBPC_CFG_OFF,
+			cmdp_local, V31_DEMOSAICV3_DBPC_LEN);
+		break;
+
+	case VFE_CMD_RGB_G_CFG:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_io_memcpy(vfe31_ctrl->vfebase + V31_RGB_G_OFF,
+			cmdp, 4);
+		cmdp += 1;
+
+		vfe31_write_gamma_cfg(RGBLUT_RAM_CH0_BANK0, cmdp);
+		vfe31_write_gamma_cfg(RGBLUT_RAM_CH1_BANK0, cmdp);
+		vfe31_write_gamma_cfg(RGBLUT_RAM_CH2_BANK0, cmdp);
+		cmdp -= 1;
+		break;
+
+	case VFE_CMD_RGB_G_UPDATE:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+
+		old_val = msm_io_r(vfe31_ctrl->vfebase + V31_RGB_G_OFF);
+		cmdp += 1;
+		if (old_val != 0x0) {
+			vfe31_write_gamma_cfg(RGBLUT_RAM_CH0_BANK0, cmdp);
+			vfe31_write_gamma_cfg(RGBLUT_RAM_CH1_BANK0, cmdp);
+			vfe31_write_gamma_cfg(RGBLUT_RAM_CH2_BANK0, cmdp);
+		} else {
+			vfe31_write_gamma_cfg(RGBLUT_RAM_CH0_BANK1, cmdp);
+			vfe31_write_gamma_cfg(RGBLUT_RAM_CH1_BANK1, cmdp);
+			vfe31_write_gamma_cfg(RGBLUT_RAM_CH2_BANK1, cmdp);
+		}
+		vfe31_ctrl->update_gamma = TRUE;
+		cmdp -= 1;
+		break;
+
+	case VFE_CMD_GET_RGB_G_TABLE:
+		temp1 = sizeof(uint32_t) * VFE31_GAMMA_NUM_ENTRIES * 3;
+		if (cmd->length != temp1) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kzalloc(temp1, GFP_KERNEL);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+
+		old_val = msm_io_r(vfe31_ctrl->vfebase + V31_RGB_G_OFF);
+		temp2 = old_val ? RGBLUT_RAM_CH0_BANK1 :
+			RGBLUT_RAM_CH0_BANK0;
+		for (i = 0; i < 3; i++) {
+			vfe31_read_gamma_cfg(temp2,
+				cmdp_local + (VFE31_GAMMA_NUM_ENTRIES * i));
+			temp2 += 2;
+		}
+		if (copy_to_user((void __user *)(cmd->value), cmdp,
+			temp1)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		break;
+
+	case VFE_CMD_STATS_AWB_STOP:
+		old_val = msm_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~AWB_ENABLE_MASK;
+		msm_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		break;
+	case VFE_CMD_STATS_AE_STOP:
+		old_val = msm_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~AE_BG_ENABLE_MASK;
+		msm_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		break;
+	case VFE_CMD_STATS_AF_STOP:
+		old_val = msm_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~AF_BF_ENABLE_MASK;
+		msm_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		break;
+
+	case VFE_CMD_STATS_IHIST_STOP:
+		old_val = msm_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~IHIST_ENABLE_MASK;
+		msm_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		break;
+
+	case VFE_CMD_STATS_RS_STOP:
+		old_val = msm_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~RS_ENABLE_MASK;
+		msm_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		break;
+
+	case VFE_CMD_STATS_CS_STOP:
+		old_val = msm_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~CS_ENABLE_MASK;
+		msm_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		break;
+
+	case VFE_CMD_STOP:
+		pr_info("vfe31_proc_general: cmdID = %s\n",
+			vfe31_general_cmd[cmd->id]);
+		vfe31_stop();
+		break;
+
+	case VFE_CMD_SYNC_TIMER_SETTING:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		vfe31_sync_timer_start(cmdp);
+		break;
+
+	case VFE_CMD_MODULE_CFG:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		*cmdp &= ~STATS_ENABLE_MASK;
+		old_val = msm_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= STATS_ENABLE_MASK;
+		*cmdp |= old_val;
+
+		msm_io_memcpy(vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp, (vfe31_cmd[cmd->id].length));
+		break;
+
+	case VFE_CMD_ZSL:
+		rc = vfe31_configure_pingpong_buffers(VFE_MSG_V31_START,
+			VFE_MSG_OUTPUT_PRIMARY);
+		if (rc < 0)
+			goto proc_general_done;
+		rc = vfe31_configure_pingpong_buffers(VFE_MSG_V31_START,
+			VFE_MSG_OUTPUT_SECONDARY);
+		if (rc < 0)
+			goto proc_general_done;
+
+		rc = vfe31_zsl();
+		break;
+
+	case VFE_CMD_ASF_CFG:
+	case VFE_CMD_ASF_UPDATE:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_io_memcpy(vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp, (vfe31_cmd[cmd->id].length));
+		cmdp_local = cmdp + V31_ASF_LEN/4;
+		break;
+
+	case VFE_CMD_GET_HW_VERSION:
+		if (cmd->length != V31_GET_HW_VERSION_LEN) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(V31_GET_HW_VERSION_LEN, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		*cmdp = msm_io_r(vfe31_ctrl->vfebase+V31_GET_HW_VERSION_OFF);
+		if (copy_to_user((void __user *)(cmd->value), cmdp,
+			V31_GET_HW_VERSION_LEN)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		break;
+	case VFE_CMD_GET_REG_DUMP:
+		temp1 = sizeof(uint32_t) * vfe31_ctrl->register_total;
+		if (cmd->length != temp1) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(temp1, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		msm_io_dump(vfe31_ctrl->vfebase, vfe31_ctrl->register_total*4);
+		CDBG("%s: %p %p %d\n", __func__, (void *)cmdp,
+			vfe31_ctrl->vfebase, temp1);
+		memcpy_fromio((void *)cmdp, vfe31_ctrl->vfebase, temp1);
+		if (copy_to_user((void __user *)(cmd->value), cmdp, temp1)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		break;
+	case VFE_CMD_FRAME_SKIP_CFG:
+		if (cmd->length != vfe31_cmd[cmd->id].length)
+			return -EINVAL;
+
+		cmdp = kmalloc(vfe31_cmd[cmd->id].length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_io_memcpy(vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp, (vfe31_cmd[cmd->id].length));
+		vfe31_ctrl->frame_skip_cnt = ((uint32_t)
+			*cmdp & VFE_FRAME_SKIP_PERIOD_MASK) + 1;
+		vfe31_ctrl->frame_skip_pattern = (uint32_t)(*(cmdp + 2));
+		break;
+	default:
+		if (cmd->length != vfe31_cmd[cmd->id].length)
+			return -EINVAL;
+
+		cmdp = kmalloc(vfe31_cmd[cmd->id].length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_io_memcpy(vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp, (vfe31_cmd[cmd->id].length));
+		break;
+
+	}
+
+proc_general_done:
+	kfree(cmdp);
+
+	return rc;
+}
+
+static void vfe31_stats_af_ack(struct vfe_cmd_stats_ack *pAck)
+{
+	unsigned long flags;
+	spinlock_t *lock = (vfe31_ctrl->stats_comp ?
+		&vfe31_ctrl->comp_stats_ack_lock :
+		&vfe31_ctrl->af_ack_lock);
+	spin_lock_irqsave(lock, flags);
+	vfe31_ctrl->afStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
+	vfe31_ctrl->afStatsControl.ackPending = FALSE;
+	spin_unlock_irqrestore(lock, flags);
+}
+
+static void vfe31_stats_awb_ack(struct vfe_cmd_stats_ack *pAck)
+{
+	unsigned long flags;
+	spinlock_t *lock = (vfe31_ctrl->stats_comp ?
+		&vfe31_ctrl->comp_stats_ack_lock :
+		&vfe31_ctrl->awb_ack_lock);
+	spin_lock_irqsave(lock, flags);
+	vfe31_ctrl->awbStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
+	vfe31_ctrl->awbStatsControl.ackPending = FALSE;
+	spin_unlock_irqrestore(lock, flags);
+}
+
+static void vfe31_stats_aec_ack(struct vfe_cmd_stats_ack *pAck)
+{
+	unsigned long flags;
+	spinlock_t *lock = (vfe31_ctrl->stats_comp ?
+		&vfe31_ctrl->comp_stats_ack_lock :
+		&vfe31_ctrl->aec_ack_lock);
+	spin_lock_irqsave(lock, flags);
+	vfe31_ctrl->aecStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
+	vfe31_ctrl->aecStatsControl.ackPending = FALSE;
+	spin_unlock_irqrestore(lock, flags);
+}
+
+static void vfe31_stats_ihist_ack(struct vfe_cmd_stats_ack *pAck)
+{
+	unsigned long flags;
+	spinlock_t *lock = (vfe31_ctrl->stats_comp ?
+		&vfe31_ctrl->comp_stats_ack_lock :
+		&vfe31_ctrl->ihist_ack_lock);
+	spin_lock_irqsave(lock, flags);
+	vfe31_ctrl->ihistStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
+	vfe31_ctrl->ihistStatsControl.ackPending = FALSE;
+	spin_unlock_irqrestore(lock, flags);
+}
+static void vfe31_stats_rs_ack(struct vfe_cmd_stats_ack *pAck)
+{
+	unsigned long flags;
+	spinlock_t *lock = (vfe31_ctrl->stats_comp ?
+		&vfe31_ctrl->comp_stats_ack_lock :
+		&vfe31_ctrl->rs_ack_lock);
+	spin_lock_irqsave(lock, flags);
+	vfe31_ctrl->rsStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
+	vfe31_ctrl->rsStatsControl.ackPending = FALSE;
+	spin_unlock_irqrestore(lock, flags);
+}
+static void vfe31_stats_cs_ack(struct vfe_cmd_stats_ack *pAck)
+{
+	unsigned long flags;
+	spinlock_t *lock = (vfe31_ctrl->stats_comp ?
+		&vfe31_ctrl->comp_stats_ack_lock :
+		&vfe31_ctrl->cs_ack_lock);
+	spin_lock_irqsave(lock, flags);
+	vfe31_ctrl->csStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
+	vfe31_ctrl->csStatsControl.ackPending = FALSE;
+	spin_unlock_irqrestore(lock, flags);
+}
+
+static inline void vfe31_read_irq_status(struct vfe31_irq_status *out)
+{
+	uint32_t *temp;
+	memset(out, 0, sizeof(struct vfe31_irq_status));
+	temp = (uint32_t *)(vfe31_ctrl->vfebase + VFE_IRQ_STATUS_0);
+	out->vfeIrqStatus0 = msm_io_r(temp);
+
+	temp = (uint32_t *)(vfe31_ctrl->vfebase + VFE_IRQ_STATUS_1);
+	out->vfeIrqStatus1 = msm_io_r(temp);
+
+	temp = (uint32_t *)(vfe31_ctrl->vfebase + VFE_CAMIF_STATUS);
+	out->camifStatus = msm_io_r(temp);
+	CDBG("camifStatus  = 0x%x\n", out->camifStatus);
+
+	/* clear the pending interrupt of the same kind.*/
+	msm_io_w(out->vfeIrqStatus0, vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+	msm_io_w(out->vfeIrqStatus1, vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_io_w_mb(1, vfe31_ctrl->vfebase + VFE_IRQ_CMD);
+
+}
+
+static void vfe31_process_reg_update_irq(void)
+{
+	unsigned long flags;
+
+	if (vfe31_ctrl->recording_state == VFE_STATE_START_REQUESTED) {
+		if (vfe31_ctrl->operation_mode ==
+			VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
+			msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+			msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+		} else if (vfe31_ctrl->operation_mode ==
+			VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
+			msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+			msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
+		}
+		vfe31_ctrl->recording_state = VFE_STATE_STARTED;
+		msm_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+		CDBG("start video triggered .\n");
+	} else if (vfe31_ctrl->recording_state ==
+		VFE_STATE_STOP_REQUESTED) {
+		if (vfe31_ctrl->operation_mode ==
+			VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
+			msm_io_w(0, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+			msm_io_w(0, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+		} else if (vfe31_ctrl->operation_mode ==
+			VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
+			msm_io_w(0, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+			msm_io_w(0, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
+		}
+		CDBG("stop video triggered .\n");
+	}
+
+	if (vfe31_ctrl->start_ack_pending == TRUE) {
+		vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_START_ACK);
+		vfe31_ctrl->start_ack_pending = FALSE;
+	} else {
+		if (vfe31_ctrl->recording_state ==
+			VFE_STATE_STOP_REQUESTED) {
+			vfe31_ctrl->recording_state = VFE_STATE_STOPPED;
+			/* request a reg update and send STOP_REC_ACK
+			 * when we process the next reg update irq.
+			 */
+			msm_io_w_mb(1,
+			vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+		} else if (vfe31_ctrl->recording_state ==
+			VFE_STATE_STOPPED) {
+			vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_STOP_REC_ACK);
+			vfe31_ctrl->recording_state = VFE_STATE_IDLE;
+		}
+		spin_lock_irqsave(&vfe31_ctrl->update_ack_lock, flags);
+		if (vfe31_ctrl->update_ack_pending == TRUE) {
+			vfe31_ctrl->update_ack_pending = FALSE;
+			spin_unlock_irqrestore(
+				&vfe31_ctrl->update_ack_lock, flags);
+			vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_UPDATE_ACK);
+		} else {
+			spin_unlock_irqrestore(
+				&vfe31_ctrl->update_ack_lock, flags);
+		}
+	}
+
+	if (vfe31_ctrl->liveshot_state == VFE_STATE_START_REQUESTED) {
+		pr_info("%s enabling liveshot output\n", __func__);
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_PRIMARY) {
+			msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+			msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+			vfe31_ctrl->liveshot_state = VFE_STATE_STARTED;
+		}
+	}
+
+	if (vfe31_ctrl->liveshot_state == VFE_STATE_STARTED) {
+		vfe31_ctrl->vfe_capture_count--;
+		if (!vfe31_ctrl->vfe_capture_count)
+			vfe31_ctrl->liveshot_state = VFE_STATE_STOP_REQUESTED;
+		msm_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	} else if (vfe31_ctrl->liveshot_state == VFE_STATE_STOP_REQUESTED) {
+		CDBG("%s: disabling liveshot output\n", __func__);
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_PRIMARY) {
+			msm_io_w(0, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+			msm_io_w(0, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+			vfe31_ctrl->liveshot_state = VFE_STATE_STOPPED;
+			msm_io_w_mb(1, vfe31_ctrl->vfebase +
+				VFE_REG_UPDATE_CMD);
+		}
+	} else if (vfe31_ctrl->liveshot_state == VFE_STATE_STOPPED) {
+		vfe31_ctrl->liveshot_state = VFE_STATE_IDLE;
+	}
+
+	if ((vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN) ||
+		(vfe31_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB) ||
+		(vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) ||
+		(vfe31_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB)) {
+		/* in snapshot mode */
+		/* later we need to add check for live snapshot mode. */
+		if (vfe31_ctrl->frame_skip_pattern & (0x1 <<
+			(vfe31_ctrl->snapshot_frame_cnt %
+			vfe31_ctrl->frame_skip_cnt))) {
+			vfe31_ctrl->vfe_capture_count--;
+			/* if last frame to be captured: */
+			if (vfe31_ctrl->vfe_capture_count == 0) {
+				/* stop the bus output:write master enable = 0*/
+				if (vfe31_ctrl->outpath.output_mode &
+					VFE31_OUTPUT_MODE_PRIMARY) {
+					msm_io_w(0, vfe31_ctrl->vfebase +
+						vfe31_AXI_WM_CFG[vfe31_ctrl->
+						outpath.out0.ch0]);
+					msm_io_w(0, vfe31_ctrl->vfebase +
+						vfe31_AXI_WM_CFG[vfe31_ctrl->
+						outpath.out0.ch1]);
+				}
+				if (vfe31_ctrl->outpath.output_mode &
+					VFE31_OUTPUT_MODE_SECONDARY) {
+					msm_io_w(0, vfe31_ctrl->vfebase +
+						vfe31_AXI_WM_CFG[vfe31_ctrl->
+						outpath.out1.ch0]);
+					msm_io_w(0, vfe31_ctrl->vfebase +
+						vfe31_AXI_WM_CFG[vfe31_ctrl->
+						outpath.out1.ch1]);
+				}
+				msm_io_w_mb
+				(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
+				vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
+				vfe31_ctrl->snapshot_frame_cnt = -1;
+				vfe31_ctrl->frame_skip_cnt = 31;
+				vfe31_ctrl->frame_skip_pattern = 0xffffffff;
+			} /*if snapshot count is 0*/
+		} /*if frame is not being dropped*/
+		vfe31_ctrl->snapshot_frame_cnt++;
+		/* then do reg_update. */
+		msm_io_w(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	} /* if snapshot mode. */
+}
+
+static void vfe31_set_default_reg_values(void)
+{
+	msm_io_w(0x800080, vfe31_ctrl->vfebase + VFE_DEMUX_GAIN_0);
+	msm_io_w(0x800080, vfe31_ctrl->vfebase + VFE_DEMUX_GAIN_1);
+	/* What value should we program CGC_OVERRIDE to? */
+	msm_io_w(0xFFFFF, vfe31_ctrl->vfebase + VFE_CGC_OVERRIDE);
+
+	/* default frame drop period and pattern */
+	msm_io_w(0x1f, vfe31_ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG);
+	msm_io_w(0x1f, vfe31_ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_CFG);
+	msm_io_w(0xFFFFFFFF, vfe31_ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN);
+	msm_io_w(0xFFFFFFFF,
+		vfe31_ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_PATTERN);
+	msm_io_w(0x1f, vfe31_ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y);
+	msm_io_w(0x1f, vfe31_ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR);
+	msm_io_w(0xFFFFFFFF,
+		vfe31_ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN);
+	msm_io_w(0xFFFFFFFF,
+		vfe31_ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR_PATTERN);
+	msm_io_w(0, vfe31_ctrl->vfebase + VFE_CLAMP_MIN);
+	msm_io_w(0xFFFFFF, vfe31_ctrl->vfebase + VFE_CLAMP_MAX);
+
+	/* stats UB config */
+	msm_io_w(0x3980007, vfe31_ctrl->vfebase + VFE_BUS_STATS_AEC_UB_CFG);
+	msm_io_w(0x3A00007, vfe31_ctrl->vfebase + VFE_BUS_STATS_AF_UB_CFG);
+	msm_io_w(0x3A8000F, vfe31_ctrl->vfebase + VFE_BUS_STATS_AWB_UB_CFG);
+	msm_io_w(0x3B80007, vfe31_ctrl->vfebase + VFE_BUS_STATS_RS_UB_CFG);
+	msm_io_w(0x3C0001F, vfe31_ctrl->vfebase + VFE_BUS_STATS_CS_UB_CFG);
+	msm_io_w(0x3E0001F, vfe31_ctrl->vfebase + VFE_BUS_STATS_HIST_UB_CFG);
+}
+
+static void vfe31_process_reset_irq(void)
+{
+	unsigned long flags;
+
+	atomic_set(&vfe31_ctrl->vstate, 0);
+
+	spin_lock_irqsave(&vfe31_ctrl->stop_flag_lock, flags);
+	if (vfe31_ctrl->stop_ack_pending) {
+		vfe31_ctrl->stop_ack_pending = FALSE;
+		spin_unlock_irqrestore(&vfe31_ctrl->stop_flag_lock, flags);
+		vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_STOP_ACK);
+	} else {
+		spin_unlock_irqrestore(&vfe31_ctrl->stop_flag_lock, flags);
+		/* this is from reset command. */
+		vfe31_set_default_reg_values();
+
+		/* reload all write masters. (frame & line)*/
+		msm_io_w(0x7FFF, vfe31_ctrl->vfebase + VFE_BUS_CMD);
+		vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_RESET_ACK);
+	}
+}
+
+static void vfe31_process_camif_sof_irq(void)
+{
+	if (vfe31_ctrl->operation_mode ==
+		VFE_OUTPUTS_RAW) {
+		if (vfe31_ctrl->start_ack_pending) {
+			vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_START_ACK);
+			vfe31_ctrl->start_ack_pending = FALSE;
+		}
+		vfe31_ctrl->vfe_capture_count--;
+		/* if last frame to be captured: */
+		if (vfe31_ctrl->vfe_capture_count == 0) {
+			/* Ensure the write order while writing
+			 to the command register using the barrier */
+			msm_io_w_mb(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
+				vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
+		}
+	} /* if raw snapshot mode. */
+	if ((vfe31_ctrl->hfr_mode != HFR_MODE_OFF) &&
+		(vfe31_ctrl->operation_mode == VFE_MODE_OF_OPERATION_VIDEO) &&
+		(vfe31_ctrl->vfeFrameId % vfe31_ctrl->hfr_mode != 0)) {
+		vfe31_ctrl->vfeFrameId++;
+		CDBG("Skip the SOF notification when HFR enabled\n");
+		return;
+	}
+	vfe31_ctrl->vfeFrameId++;
+	vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_SOF_ACK);
+	CDBG("camif_sof_irq, frameId = %d\n", vfe31_ctrl->vfeFrameId);
+
+	if (vfe31_ctrl->sync_timer_state) {
+		if (vfe31_ctrl->sync_timer_repeat_count == 0)
+			vfe31_sync_timer_stop();
+		else
+			vfe31_ctrl->sync_timer_repeat_count--;
+	}
+}
+
+static void vfe31_process_error_irq(uint32_t errStatus)
+{
+	uint32_t reg_value, read_val;
+
+	if (errStatus & VFE31_IMASK_CAMIF_ERROR) {
+		pr_err("vfe31_irq: camif errors\n");
+		reg_value = msm_io_r(vfe31_ctrl->vfebase + VFE_CAMIF_STATUS);
+		pr_err("camifStatus  = 0x%x\n", reg_value);
+		vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_CAMIF_ERROR);
+	}
+
+	if (errStatus & VFE31_IMASK_STATS_CS_OVWR)
+		pr_err("vfe31_irq: stats cs overwrite\n");
+
+	if (errStatus & VFE31_IMASK_STATS_IHIST_OVWR)
+		pr_err("vfe31_irq: stats ihist overwrite\n");
+
+	if (errStatus & VFE31_IMASK_REALIGN_BUF_Y_OVFL)
+		pr_err("vfe31_irq: realign bug Y overflow\n");
+
+	if (errStatus & VFE31_IMASK_REALIGN_BUF_CB_OVFL)
+		pr_err("vfe31_irq: realign bug CB overflow\n");
+
+	if (errStatus & VFE31_IMASK_REALIGN_BUF_CR_OVFL)
+		pr_err("vfe31_irq: realign bug CR overflow\n");
+
+	if (errStatus & VFE31_IMASK_VIOLATION)
+		pr_err("vfe31_irq: violation interrupt\n");
+
+	if (errStatus & VFE31_IMASK_IMG_MAST_0_BUS_OVFL)
+		pr_err("vfe31_irq: image master 0 bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_IMG_MAST_1_BUS_OVFL)
+		pr_err("vfe31_irq: image master 1 bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_IMG_MAST_2_BUS_OVFL)
+		pr_err("vfe31_irq: image master 2 bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_IMG_MAST_3_BUS_OVFL)
+		pr_err("vfe31_irq: image master 3 bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_IMG_MAST_4_BUS_OVFL)
+		pr_err("vfe31_irq: image master 4 bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_IMG_MAST_5_BUS_OVFL)
+		pr_err("vfe31_irq: image master 5 bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_IMG_MAST_6_BUS_OVFL)
+		pr_err("vfe31_irq: image master 6 bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_STATS_AE_BG_BUS_OVFL)
+		pr_err("vfe31_irq: ae/bg stats bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_STATS_AF_BF_BUS_OVFL)
+		pr_err("vfe31_irq: af/bf stats bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_STATS_AWB_BUS_OVFL)
+		pr_err("vfe31_irq: awb stats bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_STATS_RS_BUS_OVFL)
+		pr_err("vfe31_irq: rs stats bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_STATS_CS_BUS_OVFL)
+		pr_err("vfe31_irq: cs stats bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_STATS_IHIST_BUS_OVFL)
+		pr_err("vfe31_irq: ihist stats bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_STATS_SKIN_BHIST_BUS_OVFL)
+		pr_err("vfe31_irq: skin/bhist stats bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_AXI_ERROR) {
+		pr_err("vfe31_irq: axi error\n");
+		/* read status too when overflow happens.*/
+		read_val = msm_io_r(vfe31_ctrl->vfebase +
+			VFE_BUS_PING_PONG_STATUS);
+		pr_debug("VFE_BUS_PING_PONG_STATUS = 0x%x\n", read_val);
+		read_val = msm_io_r(vfe31_ctrl->vfebase +
+			VFE_BUS_OPERATION_STATUS);
+		pr_debug("VFE_BUS_OPERATION_STATUS = 0x%x\n", read_val);
+		read_val = msm_io_r(vfe31_ctrl->vfebase +
+			VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_0);
+		pr_debug("VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_0 = 0x%x\n",
+			read_val);
+		read_val = msm_io_r(vfe31_ctrl->vfebase +
+			VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_1);
+		pr_debug("VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_1 = 0x%x\n",
+			read_val);
+		read_val = msm_io_r(vfe31_ctrl->vfebase +
+			VFE_AXI_STATUS);
+		pr_debug("VFE_AXI_STATUS = 0x%x\n", read_val);
+	}
+}
+static void vfe_send_outmsg(struct v4l2_subdev *sd, uint8_t msgid,
+	uint32_t ch0_paddr, uint32_t ch1_paddr, uint32_t ch2_paddr)
+{
+	struct isp_msg_output msg;
+
+	msg.output_id		= msgid;
+	msg.buf.ch_paddr[0]	= ch0_paddr;
+	msg.buf.ch_paddr[1]	= ch1_paddr;
+	msg.buf.ch_paddr[2]	= ch2_paddr;
+	msg.frameCounter	= vfe31_ctrl->vfeFrameId;
+
+	v4l2_subdev_notify(&vfe31_ctrl->subdev,
+		NOTIFY_VFE_MSG_OUT, &msg);
+	return;
+}
+
+static void vfe31_process_output_path_irq_0(void)
+{
+	uint32_t ping_pong;
+	uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
+	uint8_t out_bool = 0;
+	struct msm_free_buf *free_buf = NULL;
+
+	free_buf = vfe31_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
+		VFE_MSG_OUTPUT_PRIMARY);
+
+	/* we render frames in the following conditions:
+	 * 1. Continuous mode and the free buffer is avaialable.
+	 * 2. In snapshot shot mode, free buffer is not always available.
+	 * when pending snapshot count is <=1,  then no need to use
+	 * free buffer.
+	 */
+	out_bool = ((vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN ||
+		vfe31_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
+		vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG ||
+		vfe31_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
+		vfe31_ctrl->operation_mode == VFE_OUTPUTS_RAW ||
+		vfe31_ctrl->liveshot_state == VFE_STATE_STARTED ||
+		vfe31_ctrl->liveshot_state == VFE_STATE_STOP_REQUESTED ||
+		vfe31_ctrl->liveshot_state == VFE_STATE_STOPPED) &&
+		(vfe31_ctrl->vfe_capture_count <= 1)) || free_buf;
+
+	if (out_bool) {
+		ping_pong = msm_io_r(vfe31_ctrl->vfebase +
+			VFE_BUS_PING_PONG_STATUS);
+
+		/* Channel 0*/
+		ch0_paddr = vfe31_get_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out0.ch0);
+		/* Channel 1*/
+		ch1_paddr = vfe31_get_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out0.ch1);
+		/* Channel 2*/
+		ch2_paddr = vfe31_get_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out0.ch2);
+
+		CDBG("output path 0, ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
+			ch0_paddr, ch1_paddr, ch2_paddr);
+		if (free_buf) {
+			/* Y channel */
+			vfe31_put_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out0.ch0,
+			free_buf->ch_paddr[0]);
+			/* Chroma channel */
+			vfe31_put_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out0.ch1,
+			free_buf->ch_paddr[1]);
+			if (free_buf->num_planes > 2)
+				vfe31_put_ch_addr(ping_pong,
+					vfe31_ctrl->outpath.out0.ch2,
+					free_buf->ch_paddr[2]);
+		}
+		if (vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_THUMB_AND_MAIN ||
+			vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_MAIN_AND_THUMB ||
+			vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_THUMB_AND_JPEG ||
+			vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_JPEG_AND_THUMB ||
+			vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_RAW ||
+			vfe31_ctrl->liveshot_state == VFE_STATE_STOPPED)
+			vfe31_ctrl->outpath.out0.capture_cnt--;
+
+		vfe_send_outmsg(&vfe31_ctrl->subdev,
+			MSG_ID_OUTPUT_PRIMARY, ch0_paddr,
+			ch1_paddr, ch2_paddr);
+
+		if (vfe31_ctrl->liveshot_state == VFE_STATE_STOPPED)
+			vfe31_ctrl->liveshot_state = VFE_STATE_IDLE;
+
+	} else {
+		vfe31_ctrl->outpath.out0.frame_drop_cnt++;
+		CDBG("path_irq_0 - no free buffer!\n");
+	}
+}
+
+static void vfe31_process_output_path_irq_1(void)
+{
+	uint32_t ping_pong;
+	uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
+	/* this must be snapshot main image output. */
+	uint8_t out_bool = 0;
+	struct msm_free_buf *free_buf = NULL;
+
+	free_buf = vfe31_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
+		VFE_MSG_OUTPUT_SECONDARY);
+	out_bool = ((vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_THUMB_AND_MAIN ||
+			vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_MAIN_AND_THUMB ||
+			vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_RAW ||
+			vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_JPEG_AND_THUMB) &&
+			(vfe31_ctrl->vfe_capture_count <= 1)) || free_buf;
+
+	if (out_bool) {
+		ping_pong = msm_io_r(vfe31_ctrl->vfebase +
+			VFE_BUS_PING_PONG_STATUS);
+
+		/* Y channel */
+		ch0_paddr = vfe31_get_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out1.ch0);
+		/* Chroma channel */
+		ch1_paddr = vfe31_get_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out1.ch1);
+		ch2_paddr = vfe31_get_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out1.ch2);
+
+		pr_debug("%s ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
+			__func__, ch0_paddr, ch1_paddr, ch2_paddr);
+		if (free_buf) {
+			/* Y channel */
+			vfe31_put_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out1.ch0,
+			free_buf->ch_paddr[0]);
+			/* Chroma channel */
+			vfe31_put_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out1.ch1,
+			free_buf->ch_paddr[1]);
+			if (free_buf->num_planes > 2)
+				vfe31_put_ch_addr(ping_pong,
+					vfe31_ctrl->outpath.out1.ch2,
+					free_buf->ch_paddr[2]);
+		}
+		if (vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_THUMB_AND_MAIN ||
+			vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_MAIN_AND_THUMB ||
+			vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_RAW ||
+			vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_JPEG_AND_THUMB)
+			vfe31_ctrl->outpath.out1.capture_cnt--;
+
+		vfe_send_outmsg(&vfe31_ctrl->subdev,
+			MSG_ID_OUTPUT_SECONDARY, ch0_paddr,
+			ch1_paddr, ch2_paddr);
+	} else {
+		vfe31_ctrl->outpath.out1.frame_drop_cnt++;
+		CDBG("path_irq_1 - no free buffer!\n");
+	}
+}
+
+static uint32_t  vfe31_process_stats_irq_common(uint32_t statsNum,
+	uint32_t newAddr)
+{
+
+	uint32_t pingpongStatus;
+	uint32_t returnAddr;
+	uint32_t pingpongAddr;
+
+	/* must be 0=ping, 1=pong */
+	pingpongStatus =
+		((msm_io_r(vfe31_ctrl->vfebase +
+		VFE_BUS_PING_PONG_STATUS))
+		& ((uint32_t)(1<<(statsNum + 7)))) >> (statsNum + 7);
+	/* stats bits starts at 7 */
+	CDBG("statsNum %d, pingpongStatus %d\n", statsNum, pingpongStatus);
+	pingpongAddr =
+		((uint32_t)(vfe31_ctrl->vfebase +
+		VFE_BUS_STATS_PING_PONG_BASE)) +
+		(3*statsNum)*4 + (1-pingpongStatus)*4;
+	returnAddr = msm_io_r((uint32_t *)pingpongAddr);
+	msm_io_w(newAddr, (uint32_t *)pingpongAddr);
+	return returnAddr;
+}
+
+static void
+vfe_send_stats_msg(uint32_t bufAddress, uint32_t statsNum)
+{
+	unsigned long flags;
+	/* fill message with right content. */
+	/* @todo This is causing issues, need further investigate */
+	/* spin_lock_irqsave(&ctrl->state_lock, flags); */
+	struct isp_msg_stats msgStats;
+	msgStats.frameCounter = vfe31_ctrl->vfeFrameId;
+	msgStats.buffer = bufAddress;
+
+	switch (statsNum) {
+	case STATS_AE_NUM:{
+		msgStats.id = MSG_ID_STATS_AEC;
+		spin_lock_irqsave(&vfe31_ctrl->aec_ack_lock, flags);
+		vfe31_ctrl->aecStatsControl.ackPending = TRUE;
+		spin_unlock_irqrestore(&vfe31_ctrl->aec_ack_lock, flags);
+		}
+		break;
+	case STATS_AF_NUM:{
+		msgStats.id = MSG_ID_STATS_AF;
+		spin_lock_irqsave(&vfe31_ctrl->af_ack_lock, flags);
+		vfe31_ctrl->afStatsControl.ackPending = TRUE;
+		spin_unlock_irqrestore(&vfe31_ctrl->af_ack_lock, flags);
+		}
+		break;
+	case STATS_AWB_NUM: {
+		msgStats.id = MSG_ID_STATS_AWB;
+		spin_lock_irqsave(&vfe31_ctrl->awb_ack_lock, flags);
+		vfe31_ctrl->awbStatsControl.ackPending = TRUE;
+		spin_unlock_irqrestore(&vfe31_ctrl->awb_ack_lock, flags);
+		}
+		break;
+
+	case STATS_IHIST_NUM: {
+		msgStats.id = MSG_ID_STATS_IHIST;
+		spin_lock_irqsave(&vfe31_ctrl->ihist_ack_lock, flags);
+		vfe31_ctrl->ihistStatsControl.ackPending = TRUE;
+		spin_unlock_irqrestore(&vfe31_ctrl->ihist_ack_lock, flags);
+		}
+		break;
+	case STATS_RS_NUM: {
+		msgStats.id = MSG_ID_STATS_RS;
+		spin_lock_irqsave(&vfe31_ctrl->rs_ack_lock, flags);
+		vfe31_ctrl->rsStatsControl.ackPending = TRUE;
+		spin_unlock_irqrestore(&vfe31_ctrl->rs_ack_lock, flags);
+		}
+		break;
+	case STATS_CS_NUM: {
+		msgStats.id = MSG_ID_STATS_CS;
+		spin_lock_irqsave(&vfe31_ctrl->cs_ack_lock, flags);
+		vfe31_ctrl->csStatsControl.ackPending = TRUE;
+		spin_unlock_irqrestore(&vfe31_ctrl->cs_ack_lock, flags);
+		}
+		break;
+
+	default:
+		goto stats_done;
+	}
+
+	v4l2_subdev_notify(&vfe31_ctrl->subdev,
+				NOTIFY_VFE_MSG_STATS,
+				&msgStats);
+stats_done:
+	/* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
+	return;
+}
+
+static void vfe_send_comp_stats_msg(uint32_t status_bits)
+{
+	struct msm_stats_buf msgStats;
+	uint32_t temp;
+
+	msgStats.frame_id = vfe31_ctrl->vfeFrameId;
+	msgStats.status_bits = status_bits;
+
+	msgStats.aec.buff = vfe31_ctrl->aecStatsControl.bufToRender;
+	msgStats.awb.buff = vfe31_ctrl->awbStatsControl.bufToRender;
+	msgStats.af.buff = vfe31_ctrl->afStatsControl.bufToRender;
+
+	msgStats.ihist.buff = vfe31_ctrl->ihistStatsControl.bufToRender;
+	msgStats.rs.buff = vfe31_ctrl->rsStatsControl.bufToRender;
+	msgStats.cs.buff = vfe31_ctrl->csStatsControl.bufToRender;
+
+	temp = msm_io_r(vfe31_ctrl->vfebase + VFE_STATS_AWB_SGW_CFG);
+	msgStats.awb_ymin = (0xFF00 & temp) >> 8;
+
+	v4l2_subdev_notify(&vfe31_ctrl->subdev,
+		NOTIFY_VFE_MSG_COMP_STATS, &msgStats);
+}
+
+static void vfe31_process_stats_ae_irq(void)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&vfe31_ctrl->aec_ack_lock, flags);
+	if (!(vfe31_ctrl->aecStatsControl.ackPending)) {
+		spin_unlock_irqrestore(&vfe31_ctrl->aec_ack_lock, flags);
+		vfe31_ctrl->aecStatsControl.bufToRender =
+			vfe31_process_stats_irq_common(STATS_AE_NUM,
+			vfe31_ctrl->aecStatsControl.nextFrameAddrBuf);
+
+		vfe_send_stats_msg(vfe31_ctrl->aecStatsControl.bufToRender,
+			STATS_AE_NUM);
+	} else{
+		spin_unlock_irqrestore(&vfe31_ctrl->aec_ack_lock, flags);
+		vfe31_ctrl->aecStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe31_ctrl->aecStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe31_process_stats_awb_irq(void)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&vfe31_ctrl->awb_ack_lock, flags);
+	if (!(vfe31_ctrl->awbStatsControl.ackPending)) {
+		spin_unlock_irqrestore(&vfe31_ctrl->awb_ack_lock, flags);
+		vfe31_ctrl->awbStatsControl.bufToRender =
+			vfe31_process_stats_irq_common(STATS_AWB_NUM,
+			vfe31_ctrl->awbStatsControl.nextFrameAddrBuf);
+
+		vfe_send_stats_msg(vfe31_ctrl->awbStatsControl.bufToRender,
+			STATS_AWB_NUM);
+	} else{
+		spin_unlock_irqrestore(&vfe31_ctrl->awb_ack_lock, flags);
+		vfe31_ctrl->awbStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe31_ctrl->awbStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe31_process_stats_af_irq(void)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&vfe31_ctrl->af_ack_lock, flags);
+	if (!(vfe31_ctrl->afStatsControl.ackPending)) {
+		spin_unlock_irqrestore(&vfe31_ctrl->af_ack_lock, flags);
+		vfe31_ctrl->afStatsControl.bufToRender =
+			vfe31_process_stats_irq_common(STATS_AF_NUM,
+			vfe31_ctrl->afStatsControl.nextFrameAddrBuf);
+
+		vfe_send_stats_msg(vfe31_ctrl->afStatsControl.bufToRender,
+			STATS_AF_NUM);
+	} else{
+		spin_unlock_irqrestore(&vfe31_ctrl->af_ack_lock, flags);
+		vfe31_ctrl->afStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe31_ctrl->afStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe31_process_stats_ihist_irq(void)
+{
+	if (!(vfe31_ctrl->ihistStatsControl.ackPending)) {
+		vfe31_ctrl->ihistStatsControl.bufToRender =
+			vfe31_process_stats_irq_common(STATS_IHIST_NUM,
+			vfe31_ctrl->ihistStatsControl.nextFrameAddrBuf);
+
+		vfe_send_stats_msg(vfe31_ctrl->ihistStatsControl.bufToRender,
+			STATS_IHIST_NUM);
+	} else {
+		vfe31_ctrl->ihistStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe31_ctrl->ihistStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe31_process_stats_rs_irq(void)
+{
+	if (!(vfe31_ctrl->rsStatsControl.ackPending)) {
+		vfe31_ctrl->rsStatsControl.bufToRender =
+			vfe31_process_stats_irq_common(STATS_RS_NUM,
+			vfe31_ctrl->rsStatsControl.nextFrameAddrBuf);
+
+		vfe_send_stats_msg(vfe31_ctrl->rsStatsControl.bufToRender,
+			STATS_RS_NUM);
+	} else {
+		vfe31_ctrl->rsStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe31_ctrl->rsStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe31_process_stats_cs_irq(void)
+{
+	if (!(vfe31_ctrl->csStatsControl.ackPending)) {
+		vfe31_ctrl->csStatsControl.bufToRender =
+			vfe31_process_stats_irq_common(STATS_CS_NUM,
+			vfe31_ctrl->csStatsControl.nextFrameAddrBuf);
+
+		vfe_send_stats_msg(vfe31_ctrl->csStatsControl.bufToRender,
+			STATS_CS_NUM);
+	} else {
+		vfe31_ctrl->csStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe31_ctrl->csStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe31_process_stats(uint32_t status_bits)
+{
+	unsigned long flags;
+	int32_t process_stats = false;
+	CDBG("%s, stats = 0x%x\n", __func__, status_bits);
+
+	spin_lock_irqsave(&vfe31_ctrl->comp_stats_ack_lock, flags);
+	if (status_bits & VFE_IRQ_STATUS0_STATS_AEC) {
+		if (!vfe31_ctrl->aecStatsControl.ackPending) {
+			vfe31_ctrl->aecStatsControl.ackPending = TRUE;
+			vfe31_ctrl->aecStatsControl.bufToRender =
+				vfe31_process_stats_irq_common(STATS_AE_NUM,
+				vfe31_ctrl->aecStatsControl.nextFrameAddrBuf);
+			process_stats = true;
+		} else{
+			vfe31_ctrl->aecStatsControl.bufToRender = 0;
+			vfe31_ctrl->aecStatsControl.droppedStatsFrameCount++;
+		}
+	} else {
+		vfe31_ctrl->aecStatsControl.bufToRender = 0;
+	}
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_AWB) {
+		if (!vfe31_ctrl->awbStatsControl.ackPending) {
+			vfe31_ctrl->awbStatsControl.ackPending = TRUE;
+			vfe31_ctrl->awbStatsControl.bufToRender =
+				vfe31_process_stats_irq_common(STATS_AWB_NUM,
+				vfe31_ctrl->awbStatsControl.nextFrameAddrBuf);
+			process_stats = true;
+		} else{
+			vfe31_ctrl->awbStatsControl.droppedStatsFrameCount++;
+			vfe31_ctrl->awbStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe31_ctrl->awbStatsControl.bufToRender = 0;
+	}
+
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_AF) {
+		if (!vfe31_ctrl->afStatsControl.ackPending) {
+			vfe31_ctrl->afStatsControl.ackPending = TRUE;
+			vfe31_ctrl->afStatsControl.bufToRender =
+				vfe31_process_stats_irq_common(STATS_AF_NUM,
+				vfe31_ctrl->afStatsControl.nextFrameAddrBuf);
+			process_stats = true;
+		} else {
+			vfe31_ctrl->afStatsControl.bufToRender = 0;
+			vfe31_ctrl->afStatsControl.droppedStatsFrameCount++;
+		}
+	} else {
+		vfe31_ctrl->afStatsControl.bufToRender = 0;
+	}
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_IHIST) {
+		if (!vfe31_ctrl->ihistStatsControl.ackPending) {
+			vfe31_ctrl->ihistStatsControl.ackPending = TRUE;
+			vfe31_ctrl->ihistStatsControl.bufToRender =
+				vfe31_process_stats_irq_common(STATS_IHIST_NUM,
+				vfe31_ctrl->ihistStatsControl.nextFrameAddrBuf);
+			process_stats = true;
+		} else {
+			vfe31_ctrl->ihistStatsControl.droppedStatsFrameCount++;
+			vfe31_ctrl->ihistStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe31_ctrl->ihistStatsControl.bufToRender = 0;
+	}
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_RS) {
+		if (!vfe31_ctrl->rsStatsControl.ackPending) {
+			vfe31_ctrl->rsStatsControl.ackPending = TRUE;
+			vfe31_ctrl->rsStatsControl.bufToRender =
+				vfe31_process_stats_irq_common(STATS_RS_NUM,
+				vfe31_ctrl->rsStatsControl.nextFrameAddrBuf);
+			process_stats = true;
+		} else {
+			vfe31_ctrl->rsStatsControl.droppedStatsFrameCount++;
+			vfe31_ctrl->rsStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe31_ctrl->rsStatsControl.bufToRender = 0;
+	}
+
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_CS) {
+		if (!vfe31_ctrl->csStatsControl.ackPending) {
+			vfe31_ctrl->csStatsControl.ackPending = TRUE;
+			vfe31_ctrl->csStatsControl.bufToRender =
+				vfe31_process_stats_irq_common(STATS_CS_NUM,
+				vfe31_ctrl->csStatsControl.nextFrameAddrBuf);
+			process_stats = true;
+		} else {
+			vfe31_ctrl->csStatsControl.droppedStatsFrameCount++;
+			vfe31_ctrl->csStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe31_ctrl->csStatsControl.bufToRender = 0;
+	}
+
+	spin_unlock_irqrestore(&vfe31_ctrl->comp_stats_ack_lock, flags);
+	if (process_stats)
+		vfe_send_comp_stats_msg(status_bits);
+
+	return;
+}
+
+static void vfe31_process_stats_irq(uint32_t *irqstatus)
+{
+	uint32_t status_bits = VFE_COM_STATUS & *irqstatus;
+
+	if ((vfe31_ctrl->hfr_mode != HFR_MODE_OFF) &&
+		(vfe31_ctrl->vfeFrameId % vfe31_ctrl->hfr_mode != 0)) {
+		CDBG("Skip the stats when HFR enabled\n");
+		return;
+	}
+
+	vfe31_process_stats(status_bits);
+	return;
+}
+
+static void vfe31_do_tasklet(unsigned long data)
+{
+	unsigned long flags;
+
+	struct vfe31_isr_queue_cmd *qcmd = NULL;
+
+	CDBG("=== vfe31_do_tasklet start ===\n");
+
+	while (atomic_read(&irq_cnt)) {
+		spin_lock_irqsave(&vfe31_ctrl->tasklet_lock, flags);
+		qcmd = list_first_entry(&vfe31_ctrl->tasklet_q,
+			struct vfe31_isr_queue_cmd, list);
+		atomic_sub(1, &irq_cnt);
+
+		if (!qcmd) {
+			spin_unlock_irqrestore(&vfe31_ctrl->tasklet_lock,
+				flags);
+			return;
+		}
+
+		list_del(&qcmd->list);
+		spin_unlock_irqrestore(&vfe31_ctrl->tasklet_lock,
+			flags);
+
+		if (qcmd->vfeInterruptStatus0 &
+			VFE_IRQ_STATUS0_CAMIF_SOF_MASK) {
+			CDBG("irq	camifSofIrq\n");
+			vfe31_process_camif_sof_irq();
+		}
+		/* interrupt to be processed,  *qcmd has the payload.  */
+		if (qcmd->vfeInterruptStatus0 &
+			VFE_IRQ_STATUS0_REG_UPDATE_MASK) {
+			CDBG("irq	regUpdateIrq\n");
+			vfe31_process_reg_update_irq();
+		}
+
+		if (qcmd->vfeInterruptStatus1 &
+			VFE_IMASK_WHILE_STOPPING_1) {
+			CDBG("irq	resetAckIrq\n");
+			vfe31_process_reset_irq();
+		}
+
+		if (atomic_read(&vfe31_ctrl->vstate)) {
+			if (qcmd->vfeInterruptStatus1 &
+				VFE31_IMASK_ERROR_ONLY_1) {
+				pr_err("irq	errorIrq\n");
+				vfe31_process_error_irq(
+					qcmd->vfeInterruptStatus1 &
+					VFE31_IMASK_ERROR_ONLY_1);
+			}
+			/* next, check output path related interrupts. */
+			if (qcmd->vfeInterruptStatus0 &
+				VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK) {
+				CDBG("Image composite done 0 irq occured.\n");
+				vfe31_process_output_path_irq_0();
+			}
+			if (qcmd->vfeInterruptStatus0 &
+				VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK) {
+				CDBG("Image composite done 1 irq occured.\n");
+				vfe31_process_output_path_irq_1();
+			}
+			/* in snapshot mode if done then send
+			snapshot done message */
+			if (vfe31_ctrl->operation_mode ==
+					VFE_OUTPUTS_THUMB_AND_MAIN ||
+				vfe31_ctrl->operation_mode ==
+					VFE_OUTPUTS_MAIN_AND_THUMB ||
+				vfe31_ctrl->operation_mode ==
+					VFE_OUTPUTS_THUMB_AND_JPEG ||
+				vfe31_ctrl->operation_mode ==
+					VFE_OUTPUTS_JPEG_AND_THUMB ||
+				vfe31_ctrl->operation_mode ==
+					VFE_OUTPUTS_RAW) {
+				if ((vfe31_ctrl->outpath.out0.capture_cnt == 0)
+					&& (vfe31_ctrl->outpath.out1.
+					capture_cnt == 0)) {
+					msm_io_w_mb(
+						CAMIF_COMMAND_STOP_IMMEDIATELY,
+						vfe31_ctrl->vfebase +
+						VFE_CAMIF_COMMAND);
+					vfe31_send_isp_msg(vfe31_ctrl,
+						MSG_ID_SNAPSHOT_DONE);
+				}
+			}
+			/* then process stats irq. */
+			if (vfe31_ctrl->stats_comp) {
+				/* process stats comb interrupt. */
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK) {
+					CDBG("Stats composite irq occured.\n");
+					vfe31_process_stats_irq(
+						&qcmd->vfeInterruptStatus0);
+				}
+			} else {
+				/* process individual stats interrupt. */
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_AEC) {
+					CDBG("Stats AEC irq occured.\n");
+					vfe31_process_stats_ae_irq();
+				}
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_AWB) {
+					CDBG("Stats AWB irq occured.\n");
+					vfe31_process_stats_awb_irq();
+				}
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_AF) {
+					CDBG("Stats AF irq occured.\n");
+					vfe31_process_stats_af_irq();
+				}
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_IHIST) {
+					CDBG("Stats IHIST irq occured.\n");
+					vfe31_process_stats_ihist_irq();
+				}
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_RS) {
+					CDBG("Stats RS irq occured.\n");
+					vfe31_process_stats_rs_irq();
+				}
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_CS) {
+					CDBG("Stats CS irq occured.\n");
+					vfe31_process_stats_cs_irq();
+				}
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_SYNC_TIMER0) {
+					CDBG("SYNC_TIMER 0 irq occured.\n");
+					vfe31_send_isp_msg(vfe31_ctrl,
+						MSG_ID_SYNC_TIMER0_DONE);
+				}
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_SYNC_TIMER1) {
+					CDBG("SYNC_TIMER 1 irq occured.\n");
+					vfe31_send_isp_msg(vfe31_ctrl,
+						MSG_ID_SYNC_TIMER1_DONE);
+				}
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_SYNC_TIMER2) {
+					CDBG("SYNC_TIMER 2 irq occured.\n");
+					vfe31_send_isp_msg(vfe31_ctrl,
+						MSG_ID_SYNC_TIMER2_DONE);
+				}
+			}
+		}
+		kfree(qcmd);
+	}
+	CDBG("=== vfe31_do_tasklet end ===\n");
+}
+
+DECLARE_TASKLET(vfe31_tasklet, vfe31_do_tasklet, 0);
+
+static irqreturn_t vfe31_parse_irq(int irq_num, void *data)
+{
+	unsigned long flags;
+	struct vfe31_irq_status irq;
+	struct vfe31_isr_queue_cmd *qcmd;
+
+	CDBG("vfe_parse_irq\n");
+
+	vfe31_read_irq_status(&irq);
+
+	if ((irq.vfeIrqStatus0 == 0) && (irq.vfeIrqStatus1 == 0)) {
+		CDBG("vfe_parse_irq: vfeIrqStatus0 & 1 are both 0!\n");
+		return IRQ_HANDLED;
+	}
+
+	qcmd = kzalloc(sizeof(struct vfe31_isr_queue_cmd),
+		GFP_ATOMIC);
+	if (!qcmd) {
+		pr_err("vfe_parse_irq: qcmd malloc failed!\n");
+		return IRQ_HANDLED;
+	}
+
+	spin_lock_irqsave(&vfe31_ctrl->stop_flag_lock, flags);
+	if (vfe31_ctrl->stop_ack_pending) {
+		irq.vfeIrqStatus0 &= VFE_IMASK_WHILE_STOPPING_0;
+		irq.vfeIrqStatus1 &= VFE_IMASK_WHILE_STOPPING_1;
+	}
+	spin_unlock_irqrestore(&vfe31_ctrl->stop_flag_lock, flags);
+
+	CDBG("vfe_parse_irq: Irq_status0 = 0x%x, Irq_status1 = 0x%x.\n",
+		irq.vfeIrqStatus0, irq.vfeIrqStatus1);
+
+	qcmd->vfeInterruptStatus0 = irq.vfeIrqStatus0;
+	qcmd->vfeInterruptStatus1 = irq.vfeIrqStatus1;
+
+	spin_lock_irqsave(&vfe31_ctrl->tasklet_lock, flags);
+	list_add_tail(&qcmd->list, &vfe31_ctrl->tasklet_q);
+
+	atomic_add(1, &irq_cnt);
+	spin_unlock_irqrestore(&vfe31_ctrl->tasklet_lock, flags);
+	tasklet_schedule(&vfe31_tasklet);
+	return IRQ_HANDLED;
+}
+
+static long msm_vfe_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int subdev_cmd, void *arg)
+{
+	struct msm_isp_cmd vfecmd;
+	struct msm_camvfe_params *vfe_params =
+		(struct msm_camvfe_params *)arg;
+	struct msm_vfe_cfg_cmd *cmd = vfe_params->vfe_cfg;
+	void *data = vfe_params->data;
+
+	long rc = 0;
+	uint32_t i = 0;
+	struct vfe_cmd_stats_buf *scfg = NULL;
+	struct msm_pmem_region   *regptr = NULL;
+	struct vfe_cmd_stats_ack *sack = NULL;
+	if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
+		cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
+		cmd->cmd_type != CMD_CONFIG_FREE_BUF_ADDR &&
+		cmd->cmd_type != CMD_STATS_AEC_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_AWB_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_IHIST_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_RS_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_CS_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE) {
+		if (copy_from_user(&vfecmd,
+			(void __user *)(cmd->value),
+			sizeof(vfecmd))) {
+			pr_err("%s %d: copy_from_user failed\n", __func__,
+				__LINE__);
+			return -EFAULT;
+		}
+	} else {
+	/* here eith stats release or frame release. */
+		if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
+			cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
+			cmd->cmd_type != CMD_CONFIG_FREE_BUF_ADDR) {
+			/* then must be stats release. */
+			if (!data)
+				return -EFAULT;
+			sack = kmalloc(sizeof(struct vfe_cmd_stats_ack),
+							GFP_ATOMIC);
+			if (!sack)
+				return -ENOMEM;
+
+			sack->nextStatsBuf = *(uint32_t *)data;
+		}
+	}
+
+	CDBG("%s: cmdType = %d\n", __func__, cmd->cmd_type);
+
+	if ((cmd->cmd_type == CMD_STATS_AF_ENABLE)    ||
+		(cmd->cmd_type == CMD_STATS_AWB_ENABLE)   ||
+		(cmd->cmd_type == CMD_STATS_IHIST_ENABLE) ||
+		(cmd->cmd_type == CMD_STATS_RS_ENABLE)    ||
+		(cmd->cmd_type == CMD_STATS_CS_ENABLE)    ||
+		(cmd->cmd_type == CMD_STATS_AEC_ENABLE)) {
+		struct axidata *axid;
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			goto vfe31_config_done;
+		}
+
+		scfg =
+			kmalloc(sizeof(struct vfe_cmd_stats_buf),
+				GFP_ATOMIC);
+		if (!scfg) {
+			rc = -ENOMEM;
+			goto vfe31_config_done;
+		}
+		regptr = axid->region;
+		if (axid->bufnum1 > 0) {
+			for (i = 0; i < axid->bufnum1; i++) {
+				scfg->statsBuf[i] =
+					(uint32_t)(regptr->paddr);
+				regptr++;
+			}
+		}
+		/* individual */
+		switch (cmd->cmd_type) {
+		case CMD_STATS_AEC_ENABLE:
+			rc = vfe_stats_aec_buf_init(scfg);
+			break;
+		case CMD_STATS_AF_ENABLE:
+			rc = vfe_stats_af_buf_init(scfg);
+			break;
+		case CMD_STATS_AWB_ENABLE:
+			rc = vfe_stats_awb_buf_init(scfg);
+			break;
+		case CMD_STATS_IHIST_ENABLE:
+			rc = vfe_stats_ihist_buf_init(scfg);
+			break;
+		case CMD_STATS_RS_ENABLE:
+			rc = vfe_stats_rs_buf_init(scfg);
+			break;
+		case CMD_STATS_CS_ENABLE:
+			rc = vfe_stats_cs_buf_init(scfg);
+			break;
+		default:
+			pr_err("%s Unsupported cmd type %d",
+				__func__, cmd->cmd_type);
+			break;
+		}
+		goto vfe31_config_done;
+	}
+	switch (cmd->cmd_type) {
+	case CMD_GENERAL: {
+		rc = vfe31_proc_general(&vfecmd);
+		}
+		break;
+	case CMD_CONFIG_PING_ADDR: {
+		int path = *((int *)cmd->value);
+		struct vfe31_output_ch *outch = vfe31_get_ch(path);
+		outch->ping = *((struct msm_free_buf *)data);
+		}
+		break;
+
+	case CMD_CONFIG_PONG_ADDR: {
+		int path = *((int *)cmd->value);
+		struct vfe31_output_ch *outch = vfe31_get_ch(path);
+		outch->pong = *((struct msm_free_buf *)data);
+		}
+		break;
+
+	case CMD_CONFIG_FREE_BUF_ADDR: {
+		int path = *((int *)cmd->value);
+		struct vfe31_output_ch *outch = vfe31_get_ch(path);
+		outch->free_buf = *((struct msm_free_buf *)data);
+		}
+		break;
+
+	case CMD_SNAP_BUF_RELEASE:
+		break;
+
+	case CMD_STATS_AEC_BUF_RELEASE: {
+		vfe31_stats_aec_ack(sack);
+		}
+		break;
+
+	case CMD_STATS_AF_BUF_RELEASE: {
+		vfe31_stats_af_ack(sack);
+		}
+		break;
+
+	case CMD_STATS_AWB_BUF_RELEASE: {
+		vfe31_stats_awb_ack(sack);
+		}
+		break;
+
+	case CMD_STATS_IHIST_BUF_RELEASE: {
+		vfe31_stats_ihist_ack(sack);
+		}
+		break;
+
+	case CMD_STATS_RS_BUF_RELEASE: {
+		vfe31_stats_rs_ack(sack);
+		}
+		break;
+
+	case CMD_STATS_CS_BUF_RELEASE: {
+		vfe31_stats_cs_ack(sack);
+		}
+		break;
+
+	case CMD_AXI_CFG_PRIM: {
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe31_config_axi(OUTPUT_PRIM, axio);
+		kfree(axio);
+		}
+		break;
+
+	case CMD_AXI_CFG_PRIM_ALL_CHNLS: {
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe31_config_axi(OUTPUT_PRIM_ALL_CHNLS, axio);
+		kfree(axio);
+		}
+		break;
+
+	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC: {
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe31_config_axi(OUTPUT_PRIM|OUTPUT_SEC, axio);
+		kfree(axio);
+		}
+		break;
+
+	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC_ALL_CHNLS: {
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe31_config_axi(OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS, axio);
+		kfree(axio);
+		}
+		break;
+
+	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC: {
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe31_config_axi(OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC, axio);
+		kfree(axio);
+		}
+		break;
+
+	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC_ALL_CHNLS: {
+		pr_err("%s Invalid/Unsupported AXI configuration %x",
+			__func__, cmd->cmd_type);
+		}
+		break;
+
+	default:
+		pr_err("%s Unsupported AXI configuration %x ", __func__,
+			cmd->cmd_type);
+		break;
+	}
+vfe31_config_done:
+	kfree(scfg);
+	kfree(sack);
+	CDBG("%s done: rc = %d\n", __func__, (int) rc);
+	return rc;
+}
+
+static int msm_vfe_subdev_s_crystal_freq(struct v4l2_subdev *sd,
+	u32 freq, u32 flags)
+{
+	int rc = 0;
+	int round_rate;
+
+	round_rate = clk_round_rate(vfe31_ctrl->vfe_clk[0], freq);
+	if (rc < 0) {
+		pr_err("%s: clk_round_rate failed %d\n",
+			__func__, rc);
+		return rc;
+	}
+
+	vfe_clk_rate = round_rate;
+	rc = clk_set_rate(vfe31_ctrl->vfe_clk[0], round_rate);
+	if (rc < 0)
+		pr_err("%s: clk_set_rate failed %d\n",
+			__func__, rc);
+
+	return rc;
+}
+
+static const struct v4l2_subdev_video_ops msm_vfe_subdev_video_ops = {
+	.s_crystal_freq = msm_vfe_subdev_s_crystal_freq,
+};
+
+static const struct v4l2_subdev_core_ops msm_vfe_subdev_core_ops = {
+	.ioctl = msm_vfe_subdev_ioctl,
+};
+
+static const struct v4l2_subdev_ops msm_vfe_subdev_ops = {
+	.core = &msm_vfe_subdev_core_ops,
+	.video = &msm_vfe_subdev_video_ops,
+};
+
+static struct msm_cam_clk_info vfe_clk_info[] = {
+	{"vfe_clk", VFE_CLK_RATE},
+	{"vfe_pclk", -1},
+};
+
+static struct msm_cam_clk_info vfe_camif_clk_info[] = {
+	{"camif_pad_pclk", -1},
+	{"vfe_camif_clk", -1},
+};
+
+static void msm_vfe_camio_clk_sel(enum msm_camio_clk_src_type srctype)
+{
+	struct clk *clk = NULL;
+
+	clk = vfe31_ctrl->vfe_camif_clk[1];
+
+	if (clk != NULL) {
+		switch (srctype) {
+		case MSM_CAMIO_CLK_SRC_INTERNAL:
+			clk_set_flags(clk, 0x00000100 << 1);
+			break;
+
+		case MSM_CAMIO_CLK_SRC_EXTERNAL:
+			clk_set_flags(clk, 0x00000100);
+			break;
+
+		default:
+			break;
+		}
+	}
+}
+
+static void msm_vfe_camif_pad_reg_reset(void)
+{
+	uint32_t reg;
+
+	msm_vfe_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL);
+	usleep_range(10000, 15000);
+
+	reg = (msm_io_r(vfe31_ctrl->camifbase)) & CAMIF_CFG_RMSK;
+	reg |= 0x3;
+	msm_io_w(reg, vfe31_ctrl->camifbase);
+	usleep_range(10000, 15000);
+
+	reg = (msm_io_r(vfe31_ctrl->camifbase)) & CAMIF_CFG_RMSK;
+	reg |= 0x10;
+	msm_io_w(reg, vfe31_ctrl->camifbase);
+	usleep_range(10000, 15000);
+
+	reg = (msm_io_r(vfe31_ctrl->camifbase)) & CAMIF_CFG_RMSK;
+	/* Need to be uninverted*/
+	reg &= 0x03;
+	msm_io_w(reg, vfe31_ctrl->camifbase);
+	usleep_range(10000, 15000);
+}
+
+int msm_vfe_subdev_init(struct v4l2_subdev *sd, void *data,
+	struct platform_device *pdev)
+{
+	int rc = 0;
+	struct msm_sync *sync = data;
+	v4l2_set_subdev_hostdata(sd, data);
+	vfe_syncdata = data;
+
+	spin_lock_init(&vfe31_ctrl->stop_flag_lock);
+	spin_lock_init(&vfe31_ctrl->state_lock);
+	spin_lock_init(&vfe31_ctrl->io_lock);
+	spin_lock_init(&vfe31_ctrl->update_ack_lock);
+	spin_lock_init(&vfe31_ctrl->tasklet_lock);
+
+	spin_lock_init(&vfe31_ctrl->aec_ack_lock);
+	spin_lock_init(&vfe31_ctrl->awb_ack_lock);
+	spin_lock_init(&vfe31_ctrl->af_ack_lock);
+	spin_lock_init(&vfe31_ctrl->ihist_ack_lock);
+	spin_lock_init(&vfe31_ctrl->rs_ack_lock);
+	spin_lock_init(&vfe31_ctrl->cs_ack_lock);
+	spin_lock_init(&vfe31_ctrl->comp_stats_ack_lock);
+	spin_lock_init(&vfe31_ctrl->sd_notify_lock);
+	INIT_LIST_HEAD(&vfe31_ctrl->tasklet_q);
+
+	vfe31_ctrl->update_linear = false;
+	vfe31_ctrl->update_rolloff = false;
+	vfe31_ctrl->update_la = false;
+	vfe31_ctrl->update_gamma = false;
+	vfe31_ctrl->hfr_mode = HFR_MODE_OFF;
+
+	vfe31_ctrl->vfebase = ioremap(vfe31_ctrl->vfemem->start,
+		resource_size(vfe31_ctrl->vfemem));
+	if (!vfe31_ctrl->vfebase) {
+		rc = -ENOMEM;
+		pr_err("%s: vfe ioremap failed\n", __func__);
+		goto vfe_remap_failed;
+	}
+	if (!sync->sdata->csi_if) {
+		vfe31_ctrl->camifbase = ioremap(vfe31_ctrl->camifmem->start,
+			resource_size(vfe31_ctrl->camifmem));
+		if (!vfe31_ctrl->camifbase) {
+			rc = -ENOMEM;
+			pr_err("%s: camif ioremap failed\n", __func__);
+			goto camif_remap_failed;
+		}
+	}
+
+	if (vfe31_ctrl->fs_vfe == NULL) {
+		vfe31_ctrl->fs_vfe =
+			regulator_get(&vfe31_ctrl->pdev->dev, "fs_vfe");
+		if (IS_ERR(vfe31_ctrl->fs_vfe)) {
+			pr_err("%s: Regulator FS_VFE get failed %ld\n",
+				__func__, PTR_ERR(vfe31_ctrl->fs_vfe));
+			vfe31_ctrl->fs_vfe = NULL;
+			goto vfe_fs_failed;
+		} else if (regulator_enable(vfe31_ctrl->fs_vfe)) {
+			pr_err("%s: Regulator FS_VFE enable failed\n",
+							__func__);
+			regulator_put(vfe31_ctrl->fs_vfe);
+			vfe31_ctrl->fs_vfe = NULL;
+			goto vfe_fs_failed;
+		}
+	}
+
+	rc = msm_cam_clk_enable(&vfe31_ctrl->pdev->dev, vfe_clk_info,
+		vfe31_ctrl->vfe_clk, ARRAY_SIZE(vfe_clk_info), 1);
+	if (rc < 0)
+		goto vfe_clk_enable_failed;
+
+	if (!sync->sdata->csi_if) {
+		rc = msm_cam_clk_enable(&vfe31_ctrl->pdev->dev,
+			vfe_camif_clk_info,
+			vfe31_ctrl->vfe_camif_clk,
+			ARRAY_SIZE(vfe_camif_clk_info), 1);
+		if (rc < 0)
+			goto vfe_clk_enable_failed;
+		msm_vfe_camif_pad_reg_reset();
+	}
+
+	msm_camio_bus_scale_cfg(
+		sync->sdata->pdata->cam_bus_scale_table, S_INIT);
+	msm_camio_bus_scale_cfg(
+		sync->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
+	vfe31_ctrl->register_total = VFE31_REGISTER_TOTAL;
+
+	enable_irq(vfe31_ctrl->vfeirq->start);
+
+	return rc;
+
+vfe_clk_enable_failed:
+	regulator_disable(vfe31_ctrl->fs_vfe);
+	regulator_put(vfe31_ctrl->fs_vfe);
+	vfe31_ctrl->fs_vfe = NULL;
+vfe_fs_failed:
+	if (!sync->sdata->csi_if)
+		iounmap(vfe31_ctrl->camifbase);
+camif_remap_failed:
+	iounmap(vfe31_ctrl->vfebase);
+vfe_remap_failed:
+	disable_irq(vfe31_ctrl->vfeirq->start);
+	return rc;
+}
+
+void msm_vfe_subdev_release(struct platform_device *pdev)
+{
+	struct msm_sync *sync = vfe_syncdata;
+	disable_irq(vfe31_ctrl->vfeirq->start);
+	tasklet_kill(&vfe31_tasklet);
+
+	if (!sync->sdata->csi_if)
+		msm_cam_clk_enable(&vfe31_ctrl->pdev->dev,
+			vfe_camif_clk_info,
+			vfe31_ctrl->vfe_camif_clk,
+			ARRAY_SIZE(vfe_camif_clk_info), 0);
+
+	msm_cam_clk_enable(&vfe31_ctrl->pdev->dev, vfe_clk_info,
+		vfe31_ctrl->vfe_clk, ARRAY_SIZE(vfe_clk_info), 0);
+	if (vfe31_ctrl->fs_vfe) {
+		regulator_disable(vfe31_ctrl->fs_vfe);
+		regulator_put(vfe31_ctrl->fs_vfe);
+		vfe31_ctrl->fs_vfe = NULL;
+	}
+	CDBG("%s, 31ee_irq\n", __func__);
+	if (!sync->sdata->csi_if)
+		iounmap(vfe31_ctrl->camifbase);
+	iounmap(vfe31_ctrl->vfebase);
+
+	if (atomic_read(&irq_cnt))
+		pr_warning("%s, Warning IRQ Count not ZERO\n", __func__);
+
+	msm_camio_bus_scale_cfg(
+		sync->sdata->pdata->cam_bus_scale_table, S_EXIT);
+	vfe_syncdata = NULL;
+}
+
+
+static int __devinit vfe31_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+	CDBG("%s: device id = %d\n", __func__, pdev->id);
+	vfe31_ctrl = kzalloc(sizeof(struct vfe31_ctrl_type), GFP_KERNEL);
+	if (!vfe31_ctrl) {
+		pr_err("%s: no enough memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	v4l2_subdev_init(&vfe31_ctrl->subdev, &msm_vfe_subdev_ops);
+	snprintf(vfe31_ctrl->subdev.name,
+			 sizeof(vfe31_ctrl->subdev.name), "vfe3.1");
+	v4l2_set_subdevdata(&vfe31_ctrl->subdev, vfe31_ctrl);
+	platform_set_drvdata(pdev, &vfe31_ctrl->subdev);
+
+	vfe31_ctrl->vfemem = platform_get_resource_byname(pdev,
+		IORESOURCE_MEM, "msm_vfe");
+	if (!vfe31_ctrl->vfemem) {
+		pr_err("%s: no mem resource?\n", __func__);
+		rc = -ENODEV;
+		goto vfe31_no_resource;
+	}
+	vfe31_ctrl->vfeirq = platform_get_resource_byname(pdev,
+		IORESOURCE_IRQ, "msm_vfe");
+	if (!vfe31_ctrl->vfeirq) {
+		pr_err("%s: no irq resource?\n", __func__);
+		rc = -ENODEV;
+		goto vfe31_no_resource;
+	}
+	vfe31_ctrl->camifmem = platform_get_resource_byname(pdev,
+		IORESOURCE_MEM, "msm_camif");
+	if (!vfe31_ctrl->camifmem)
+		pr_err("%s: camif not supported\n", __func__);
+
+	vfe31_ctrl->vfeio = request_mem_region(vfe31_ctrl->vfemem->start,
+		resource_size(vfe31_ctrl->vfemem), pdev->name);
+	if (!vfe31_ctrl->vfeio) {
+		pr_err("%s: no valid mem region\n", __func__);
+		rc = -EBUSY;
+		goto vfe31_no_resource;
+	}
+
+	if (vfe31_ctrl->camifmem) {
+		vfe31_ctrl->camifio = request_mem_region(
+			vfe31_ctrl->camifmem->start,
+			resource_size(vfe31_ctrl->camifmem), pdev->name);
+		if (!vfe31_ctrl->camifio) {
+			release_mem_region(vfe31_ctrl->vfemem->start,
+				resource_size(vfe31_ctrl->vfemem));
+			pr_err("%s: no valid mem region\n", __func__);
+			rc = -EBUSY;
+			goto vfe31_no_resource;
+		}
+	}
+
+	rc = request_irq(vfe31_ctrl->vfeirq->start, vfe31_parse_irq,
+		IRQF_TRIGGER_RISING, "vfe", 0);
+	if (rc < 0) {
+		if (vfe31_ctrl->camifmem) {
+			release_mem_region(vfe31_ctrl->camifmem->start,
+				resource_size(vfe31_ctrl->camifmem));
+		}
+		release_mem_region(vfe31_ctrl->vfemem->start,
+			resource_size(vfe31_ctrl->vfemem));
+		pr_err("%s: irq request fail\n", __func__);
+		rc = -EBUSY;
+		goto vfe31_no_resource;
+	}
+
+	disable_irq(vfe31_ctrl->vfeirq->start);
+
+	vfe31_ctrl->pdev = pdev;
+	return 0;
+
+vfe31_no_resource:
+	kfree(vfe31_ctrl);
+	return 0;
+}
+
+static struct platform_driver vfe31_driver = {
+	.probe = vfe31_probe,
+	.driver = {
+	.name = MSM_VFE_DRV_NAME,
+	.owner = THIS_MODULE,
+	},
+};
+
+static int __init msm_vfe31_init_module(void)
+{
+	return platform_driver_register(&vfe31_driver);
+}
+
+static void __exit msm_vfe31_exit_module(void)
+{
+	platform_driver_unregister(&vfe31_driver);
+}
+
+module_init(msm_vfe31_init_module);
+module_exit(msm_vfe31_exit_module);
+MODULE_DESCRIPTION("VFE 3.1 driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/msm_vfe31_v4l2.h b/drivers/media/video/msm/msm_vfe31_v4l2.h
new file mode 100644
index 0000000..e94f286
--- /dev/null
+++ b/drivers/media/video/msm/msm_vfe31_v4l2.h
@@ -0,0 +1,955 @@
+/* Copyright (c) 2012 Code Aurora Forum. 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MSM_VFE31_V4L2_H__
+#define __MSM_VFE31_V4L2_H__
+
+#include <linux/bitops.h>
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/* This defines total number registers in VFE.
+ * Each register is 4 bytes so to get the range,
+ * multiply this number with 4. */
+#define VFE31_REGISTER_TOTAL 0x0000017F
+
+/* at start of camif,  bit 1:0 = 0x01:enable
+ * image data capture at frame boundary. */
+#define CAMIF_COMMAND_START  0x00000005
+
+/* bit 2= 0x1:clear the CAMIF_STATUS register
+ * value. */
+#define CAMIF_COMMAND_CLEAR  0x00000004
+
+/* at stop of vfe pipeline, for now it is assumed
+ * that camif will stop at any time. Bit 1:0 = 0x10:
+ * disable image data capture immediately. */
+#define CAMIF_COMMAND_STOP_IMMEDIATELY  0x00000002
+
+/* at stop of vfe pipeline, for now it is assumed
+ * that camif will stop at any time. Bit 1:0 = 0x00:
+ * disable image data capture at frame boundary */
+#define CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY  0x00000000
+
+/* to halt axi bridge */
+#define AXI_HALT  0x00000001
+
+/* clear the halt bit. */
+#define AXI_HALT_CLEAR  0x00000000
+
+/* clear axi_halt_irq */
+#define MASK_AXI_HALT_IRQ	0xFF7FFFFF
+
+/* reset the pipeline when stop command is issued.
+ * (without reset the register.) bit 26-31 = 0,
+ * domain reset, bit 0-9 = 1 for module reset, except
+ * register module. */
+#define VFE_RESET_UPON_STOP_CMD  0x000003ef
+
+/* reset the pipeline when reset command.
+ * bit 26-31 = 0, domain reset, bit 0-9 = 1 for module reset. */
+#define VFE_RESET_UPON_RESET_CMD  0x000003ff
+
+/* bit 5 is for axi status idle or busy.
+ * 1 =  halted,  0 = busy */
+#define AXI_STATUS_BUSY_MASK 0x00000020
+
+/* bit 0 & bit 1 = 1, both y and cbcr irqs need to be present
+ * for frame done interrupt */
+#define VFE_COMP_IRQ_BOTH_Y_CBCR 3
+
+/* bit 1 = 1, only cbcr irq triggers frame done interrupt */
+#define VFE_COMP_IRQ_CBCR_ONLY 2
+
+/* bit 0 = 1, only y irq triggers frame done interrupt */
+#define VFE_COMP_IRQ_Y_ONLY 1
+
+/* bit 0 = 1, PM go;   bit1 = 1, PM stop */
+#define VFE_PERFORMANCE_MONITOR_GO   0x00000001
+#define VFE_PERFORMANCE_MONITOR_STOP 0x00000002
+
+/* bit 0 = 1, test gen go;   bit1 = 1, test gen stop */
+#define VFE_TEST_GEN_GO   0x00000001
+#define VFE_TEST_GEN_STOP 0x00000002
+
+/* the chroma is assumed to be interpolated between
+ * the luma samples.  JPEG 4:2:2 */
+#define VFE_CHROMA_UPSAMPLE_INTERPOLATED 0
+
+/* constants for irq registers */
+#define VFE_DISABLE_ALL_IRQS 0
+/* bit =1 is to clear the corresponding bit in VFE_IRQ_STATUS.  */
+#define VFE_CLEAR_ALL_IRQS   0xffffffff
+
+#define VFE_IRQ_STATUS0_CAMIF_SOF_MASK            0x00000001
+#define VFE_IRQ_STATUS0_CAMIF_EOF_MASK            0x00000004
+#define VFE_IRQ_STATUS0_REG_UPDATE_MASK           0x00000020
+#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK 0x00200000
+#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK 0x00400000
+#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE2_MASK 0x00800000
+#define VFE_IRQ_STATUS1_RESET_AXI_HALT_ACK_MASK   0x00800000
+#define VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK       0x01000000
+
+#define VFE_IRQ_STATUS0_STATS_AEC     0x2000  /* bit 13 */
+#define VFE_IRQ_STATUS0_STATS_AF      0x4000  /* bit 14 */
+#define VFE_IRQ_STATUS0_STATS_AWB     0x8000  /* bit 15 */
+#define VFE_IRQ_STATUS0_STATS_RS      0x10000  /* bit 16 */
+#define VFE_IRQ_STATUS0_STATS_CS      0x20000  /* bit 17 */
+#define VFE_IRQ_STATUS0_STATS_IHIST   0x40000  /* bit 18 */
+
+#define VFE_IRQ_STATUS0_SYNC_TIMER0   0x2000000  /* bit 25 */
+#define VFE_IRQ_STATUS0_SYNC_TIMER1   0x4000000  /* bit 26 */
+#define VFE_IRQ_STATUS0_SYNC_TIMER2   0x8000000  /* bit 27 */
+#define VFE_IRQ_STATUS0_ASYNC_TIMER0  0x10000000  /* bit 28 */
+#define VFE_IRQ_STATUS0_ASYNC_TIMER1  0x20000000  /* bit 29 */
+#define VFE_IRQ_STATUS0_ASYNC_TIMER2  0x40000000  /* bit 30 */
+#define VFE_IRQ_STATUS0_ASYNC_TIMER3  0x80000000  /* bit 31 */
+
+/* imask for while waiting for stop ack,  driver has already
+ * requested stop, waiting for reset irq, and async timer irq.
+ * For irq_status_0, bit 28-31 are for async timer. For
+ * irq_status_1, bit 22 for reset irq, bit 23 for axi_halt_ack
+   irq */
+#define VFE_IMASK_WHILE_STOPPING_0  0xF0000000
+#define VFE_IMASK_WHILE_STOPPING_1  0x00C00000
+#define VFE_IMASK_RESET             0x00400000
+#define VFE_IMASK_AXI_HALT          0x00800000
+
+
+/* no error irq in mask 0 */
+#define VFE_IMASK_ERROR_ONLY_0  0x0
+/* when normal case, don't want to block error status. */
+/* bit 0-21 are error irq bits */
+#define VFE_IMASK_ERROR_ONLY_1  0x003fffff
+
+/* For BPC bit 0,bit 12-17 and bit 26 -20 are set to zero and other's 1 */
+#define BPC_MASK 0xF80C0FFE
+
+/* For BPC bit 1 and 2 are set to zero and other's 1 */
+#define ABF_MASK 0xFFFFFFF9
+
+/* For DBPC bit 0 is set to zero and other's 1 */
+#define DBPC_MASK 0xFFFFFFFE
+
+/* For DBCC bit 1 is set to zero and other's 1 */
+#define DBCC_MASK 0xFFFFFFFD
+
+/* For DBPC/ABF/DBCC/ABCC bits are set to 1 all others 0 */
+#define DEMOSAIC_MASK 0x8FFFFFFF
+/* For MCE enable bit 28 set to zero and other's 1 */
+#define MCE_EN_MASK 0xEFFFFFFF
+
+/* For MCE Q_K bit 28 to 31 set to zero and other's 1 */
+#define MCE_Q_K_MASK 0x0FFFFFFF
+
+#define AE_BG_ENABLE_MASK 0x00000020      /* bit 5 */
+#define AF_BF_ENABLE_MASK 0x00000040      /* bit 6 */
+#define AWB_ENABLE_MASK 0x00000080     /* bit 7 */
+
+#define RS_ENABLE_MASK 0x00000100      /* bit 8  */
+#define CS_ENABLE_MASK 0x00000200      /* bit 9  */
+#define RS_CS_ENABLE_MASK 0x00000300   /* bit 8,9  */
+#define IHIST_ENABLE_MASK 0x00008000   /* bit 15 */
+#define STATS_ENABLE_MASK 0x000483E0   /* bit 18,15,9,8,7,6,5*/
+
+#define VFE_REG_UPDATE_TRIGGER           1
+#define VFE_PM_BUF_MAX_CNT_MASK          0xFF
+#define VFE_DMI_CFG_DEFAULT              0x00000100
+#define VFE_AE_PINGPONG_STATUS_BIT       0x80
+#define VFE_AF_PINGPONG_STATUS_BIT       0x100
+#define VFE_AWB_PINGPONG_STATUS_BIT      0x200
+
+#define HFR_MODE_OFF 1
+#define VFE_FRAME_SKIP_PERIOD_MASK 0x0000001F /*bits 0 -4*/
+
+enum VFE31_DMI_RAM_SEL {
+	 NO_MEM_SELECTED          = 0,
+	 ROLLOFF_RAM              = 0x1,
+	 RGBLUT_RAM_CH0_BANK0     = 0x2,
+	 RGBLUT_RAM_CH0_BANK1     = 0x3,
+	 RGBLUT_RAM_CH1_BANK0     = 0x4,
+	 RGBLUT_RAM_CH1_BANK1     = 0x5,
+	 RGBLUT_RAM_CH2_BANK0     = 0x6,
+	 RGBLUT_RAM_CH2_BANK1     = 0x7,
+	 STATS_HIST_RAM           = 0x8,
+	 RGBLUT_CHX_BANK0         = 0x9,
+	 RGBLUT_CHX_BANK1         = 0xa,
+	 LUMA_ADAPT_LUT_RAM_BANK0 = 0xb,
+	 LUMA_ADAPT_LUT_RAM_BANK1 = 0xc
+};
+
+enum vfe_output_state {
+	VFE_STATE_IDLE,
+	VFE_STATE_START_REQUESTED,
+	VFE_STATE_STARTED,
+	VFE_STATE_STOP_REQUESTED,
+	VFE_STATE_STOPPED,
+};
+
+#define V31_CAMIF_OFF             0x000001E4
+#define V31_CAMIF_LEN             32
+
+#define V31_DEMUX_OFF             0x00000284
+#define V31_DEMUX_LEN             20
+
+#define V31_DEMOSAICV3_UP_REG_CNT 5
+
+#define V31_OUT_CLAMP_OFF         0x00000524
+#define V31_OUT_CLAMP_LEN         8
+
+#define V31_OPERATION_CFG_LEN     32
+
+#define V31_AXI_OUT_OFF           0x00000038
+#define V31_AXI_OUT_LEN           212
+#define V31_AXI_CH_INF_LEN        24
+#define V31_AXI_CFG_LEN           47
+#define V31_AXI_RESERVED            1
+
+#define V31_FRAME_SKIP_OFF        0x00000504
+#define V31_FRAME_SKIP_LEN        32
+
+#define V31_CHROMA_SUBS_OFF       0x000004F8
+#define V31_CHROMA_SUBS_LEN       12
+
+#define V31_FOV_OFF           0x00000360
+#define V31_FOV_LEN           8
+
+#define V31_MAIN_SCALER_OFF 0x00000368
+#define V31_MAIN_SCALER_LEN 28
+
+#define V31_S2Y_OFF 0x000004D0
+#define V31_S2Y_LEN 20
+
+#define V31_S2CbCr_OFF 0x000004E4
+#define V31_S2CbCr_LEN 20
+
+#define V31_CHROMA_EN_OFF 0x000003C4
+#define V31_CHROMA_EN_LEN 36
+
+#define V31_SYNC_TIMER_OFF      0x0000020C
+#define V31_SYNC_TIMER_POLARITY_OFF 0x00000234
+#define V31_TIMER_SELECT_OFF        0x0000025C
+#define V31_SYNC_TIMER_LEN 28
+
+#define V31_ASYNC_TIMER_OFF 0x00000238
+#define V31_ASYNC_TIMER_LEN 28
+
+#define V31_BLACK_LEVEL_OFF 0x00000264
+#define V31_BLACK_LEVEL_LEN 16
+
+#define V31_MESH_ROLL_OFF_CFG_OFF             0x00000274
+#define V31_MESH_ROLL_OFF_CFG_LEN             16
+#define V31_MESH_ROLL_OFF_INIT_TABLE_SIZE     13
+#define V31_MESH_ROLL_OFF_DELTA_TABLE_SIZE    208
+#define V31_MESH_ROLL_OFF_DELTA_TABLE_OFFSET  32
+
+#define V31_COLOR_COR_OFF 0x00000388
+#define V31_COLOR_COR_LEN 52
+
+#define V31_WB_OFF 0x00000384
+#define V31_WB_LEN 4
+
+#define V31_RGB_G_OFF 0x000003BC
+#define V31_RGB_G_LEN 4
+
+#define V31_LA_OFF 0x000003C0
+#define V31_LA_LEN 4
+
+#define V31_SCE_OFF 0x00000418
+#define V31_SCE_LEN 136
+
+#define V31_CHROMA_SUP_OFF 0x000003E8
+#define V31_CHROMA_SUP_LEN 12
+
+#define V31_MCE_OFF 0x000003F4
+#define V31_MCE_LEN 36
+#define V31_STATS_AF_OFF 0x0000053c
+#define V31_STATS_AF_LEN 16
+
+#define V31_STATS_AE_OFF 0x00000534
+#define V31_STATS_AE_LEN 8
+
+#define V31_STATS_AWB_OFF 0x0000054c
+#define V31_STATS_AWB_LEN 32
+
+#define V31_STATS_IHIST_OFF 0x0000057c
+#define V31_STATS_IHIST_LEN 8
+
+#define V31_STATS_RS_OFF 0x0000056c
+#define V31_STATS_RS_LEN 8
+
+#define V31_STATS_CS_OFF 0x00000574
+#define V31_STATS_CS_LEN 8
+
+#define V31_ASF_OFF 0x000004A0
+#define V31_ASF_LEN 48
+#define V31_ASF_UPDATE_LEN 36
+#define V31_CAPTURE_LEN 4
+#define V31_GET_HW_VERSION_OFF 0
+#define V31_GET_HW_VERSION_LEN 4
+#define V31_DEMOSAICV3_OFF 0x00000298
+#define V31_DEMOSAICV3_LEN 4
+/* BPC     */
+#define V31_DEMOSAICV3_DBPC_CFG_OFF  0x0000029C
+#define V31_DEMOSAICV3_DBPC_LEN 8
+#define V31_XBAR_CFG_OFF 0x00000040
+/* ABF     */
+#define V31_DEMOSAICV3_ABF_OFF 0x000002A4
+#define V31_DEMOSAICV3_ABF_LEN 180
+#define V31_XBAR_CFG_LEN 8
+
+#define V31_MODULE_CFG_OFF 0x00000010
+#define V31_MODULE_CFG_LEN 4
+#define V31_EZTUNE_CFG_OFF 0x00000010
+#define V31_EZTUNE_CFG_LEN 4
+
+struct vfe_cmd_hw_version {
+	uint32_t minorVersion;
+	uint32_t majorVersion;
+	uint32_t coreVersion;
+};
+
+enum VFE_AXI_OUTPUT_MODE {
+	VFE_AXI_OUTPUT_MODE_Output1,
+	VFE_AXI_OUTPUT_MODE_Output2,
+	VFE_AXI_OUTPUT_MODE_Output1AndOutput2,
+	VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2,
+	VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1,
+	VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2,
+	VFE_AXI_LAST_OUTPUT_MODE_ENUM
+};
+
+enum VFE_RAW_WR_PATH_SEL {
+	VFE_RAW_OUTPUT_DISABLED,
+	VFE_RAW_OUTPUT_ENC_CBCR_PATH,
+	VFE_RAW_OUTPUT_VIEW_CBCR_PATH,
+	VFE_RAW_OUTPUT_PATH_INVALID
+};
+
+#define VFE_AXI_OUTPUT_BURST_LENGTH     4
+#define VFE_MAX_NUM_FRAGMENTS_PER_FRAME 4
+#define VFE_AXI_OUTPUT_CFG_FRAME_COUNT  3
+
+struct vfe_cmds_per_write_master {
+	uint16_t imageWidth;
+	uint16_t imageHeight;
+	uint16_t outRowCount;
+	uint16_t outRowIncrement;
+	uint32_t outFragments[VFE_AXI_OUTPUT_CFG_FRAME_COUNT]
+		[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
+};
+
+struct vfe_cmds_axi_per_output_path {
+	uint8_t fragmentCount;
+	struct vfe_cmds_per_write_master firstWM;
+	struct vfe_cmds_per_write_master secondWM;
+};
+
+enum VFE_AXI_BURST_LENGTH {
+	VFE_AXI_BURST_LENGTH_IS_2  = 2,
+	VFE_AXI_BURST_LENGTH_IS_4  = 4,
+	VFE_AXI_BURST_LENGTH_IS_8  = 8,
+	VFE_AXI_BURST_LENGTH_IS_16 = 16
+};
+
+struct vfe_cmd_fov_crop_config {
+	uint8_t enable;
+	uint16_t firstPixel;
+	uint16_t lastPixel;
+	uint16_t firstLine;
+	uint16_t lastLine;
+};
+
+struct vfe_cmds_main_scaler_stripe_init {
+	uint16_t MNCounterInit;
+	uint16_t phaseInit;
+};
+
+struct vfe_cmds_scaler_one_dimension {
+	uint8_t  enable;
+	uint16_t inputSize;
+	uint16_t outputSize;
+	uint32_t phaseMultiplicationFactor;
+	uint8_t  interpolationResolution;
+};
+
+struct vfe_cmd_main_scaler_config {
+	uint8_t enable;
+	struct vfe_cmds_scaler_one_dimension    hconfig;
+	struct vfe_cmds_scaler_one_dimension    vconfig;
+	struct vfe_cmds_main_scaler_stripe_init MNInitH;
+	struct vfe_cmds_main_scaler_stripe_init MNInitV;
+};
+
+struct vfe_cmd_scaler2_config {
+	uint8_t enable;
+	struct vfe_cmds_scaler_one_dimension hconfig;
+	struct vfe_cmds_scaler_one_dimension vconfig;
+};
+
+
+struct vfe_cmd_frame_skip_update {
+	uint32_t output1Pattern;
+	uint32_t output2Pattern;
+};
+
+struct vfe_cmd_output_clamp_config {
+	uint8_t minCh0;
+	uint8_t minCh1;
+	uint8_t minCh2;
+	uint8_t maxCh0;
+	uint8_t maxCh1;
+	uint8_t maxCh2;
+};
+
+struct vfe_cmd_chroma_subsample_config {
+	uint8_t enable;
+	uint8_t cropEnable;
+	uint8_t vsubSampleEnable;
+	uint8_t hsubSampleEnable;
+	uint8_t vCosited;
+	uint8_t hCosited;
+	uint8_t vCositedPhase;
+	uint8_t hCositedPhase;
+	uint16_t cropWidthFirstPixel;
+	uint16_t cropWidthLastPixel;
+	uint16_t cropHeightFirstLine;
+	uint16_t cropHeightLastLine;
+};
+
+enum VFE_START_PIXEL_PATTERN {
+	VFE_BAYER_RGRGRG,
+	VFE_BAYER_GRGRGR,
+	VFE_BAYER_BGBGBG,
+	VFE_BAYER_GBGBGB,
+	VFE_YUV_YCbYCr,
+	VFE_YUV_YCrYCb,
+	VFE_YUV_CbYCrY,
+	VFE_YUV_CrYCbY
+};
+
+enum VFE_BUS_RD_INPUT_PIXEL_PATTERN {
+	VFE_BAYER_RAW,
+	VFE_YUV_INTERLEAVED,
+	VFE_YUV_PSEUDO_PLANAR_Y,
+	VFE_YUV_PSEUDO_PLANAR_CBCR
+};
+
+enum VFE_YUV_INPUT_COSITING_MODE {
+	VFE_YUV_COSITED,
+	VFE_YUV_INTERPOLATED
+};
+
+#define VFE31_GAMMA_NUM_ENTRIES  64
+
+#define VFE31_LA_TABLE_LENGTH    64
+
+#define VFE31_HIST_TABLE_LENGTH  256
+
+struct vfe_cmds_demosaic_abf {
+	uint8_t   enable;
+	uint8_t   forceOn;
+	uint8_t   shift;
+	uint16_t  lpThreshold;
+	uint16_t  max;
+	uint16_t  min;
+	uint8_t   ratio;
+};
+
+struct vfe_cmds_demosaic_bpc {
+	uint8_t   enable;
+	uint16_t  fmaxThreshold;
+	uint16_t  fminThreshold;
+	uint16_t  redDiffThreshold;
+	uint16_t  blueDiffThreshold;
+	uint16_t  greenDiffThreshold;
+};
+
+struct vfe_cmd_demosaic_config {
+	uint8_t   enable;
+	uint8_t   slopeShift;
+	struct vfe_cmds_demosaic_abf abfConfig;
+	struct vfe_cmds_demosaic_bpc bpcConfig;
+};
+
+struct vfe_cmd_demosaic_bpc_update {
+	struct vfe_cmds_demosaic_bpc bpcUpdate;
+};
+
+struct vfe_cmd_demosaic_abf_update {
+	struct vfe_cmds_demosaic_abf abfUpdate;
+};
+
+struct vfe_cmd_white_balance_config {
+	uint8_t  enable;
+	uint16_t ch2Gain;
+	uint16_t ch1Gain;
+	uint16_t ch0Gain;
+};
+
+enum VFE_COLOR_CORRECTION_COEF_QFACTOR {
+	COEF_IS_Q7_SIGNED,
+	COEF_IS_Q8_SIGNED,
+	COEF_IS_Q9_SIGNED,
+	COEF_IS_Q10_SIGNED
+};
+
+struct vfe_cmd_color_correction_config {
+	uint8_t     enable;
+	enum VFE_COLOR_CORRECTION_COEF_QFACTOR coefQFactor;
+	int16_t  C0;
+	int16_t  C1;
+	int16_t  C2;
+	int16_t  C3;
+	int16_t  C4;
+	int16_t  C5;
+	int16_t  C6;
+	int16_t  C7;
+	int16_t  C8;
+	int16_t  K0;
+	int16_t  K1;
+	int16_t  K2;
+};
+
+#define VFE_LA_TABLE_LENGTH 64
+
+struct vfe_cmd_la_config {
+	uint8_t enable;
+	int16_t table[VFE_LA_TABLE_LENGTH];
+};
+
+#define VFE_GAMMA_TABLE_LENGTH 256
+enum VFE_RGB_GAMMA_TABLE_SELECT {
+	RGB_GAMMA_CH0_SELECTED,
+	RGB_GAMMA_CH1_SELECTED,
+	RGB_GAMMA_CH2_SELECTED,
+	RGB_GAMMA_CH0_CH1_SELECTED,
+	RGB_GAMMA_CH0_CH2_SELECTED,
+	RGB_GAMMA_CH1_CH2_SELECTED,
+	RGB_GAMMA_CH0_CH1_CH2_SELECTED
+};
+
+struct vfe_cmd_rgb_gamma_config {
+	uint8_t enable;
+	enum VFE_RGB_GAMMA_TABLE_SELECT channelSelect;
+	int16_t table[VFE_GAMMA_TABLE_LENGTH];
+};
+
+struct vfe_cmd_chroma_enhan_config {
+	uint8_t  enable;
+	int16_t am;
+	int16_t ap;
+	int16_t bm;
+	int16_t bp;
+	int16_t cm;
+	int16_t cp;
+	int16_t dm;
+	int16_t dp;
+	int16_t kcr;
+	int16_t kcb;
+	int16_t RGBtoYConversionV0;
+	int16_t RGBtoYConversionV1;
+	int16_t RGBtoYConversionV2;
+	uint8_t RGBtoYConversionOffset;
+};
+
+struct vfe_cmd_chroma_suppression_config {
+	uint8_t enable;
+	uint8_t m1;
+	uint8_t m3;
+	uint8_t n1;
+	uint8_t n3;
+	uint8_t nn1;
+	uint8_t mm1;
+};
+
+struct vfe_cmd_asf_config {
+	uint8_t enable;
+	uint8_t smoothFilterEnabled;
+	uint8_t sharpMode;
+	uint8_t smoothCoefCenter;
+	uint8_t smoothCoefSurr;
+	uint8_t normalizeFactor;
+	uint8_t sharpK1;
+	uint8_t sharpK2;
+	uint8_t sharpThreshE1;
+	int8_t sharpThreshE2;
+	int8_t sharpThreshE3;
+	int8_t sharpThreshE4;
+	int8_t sharpThreshE5;
+	int8_t filter1Coefficients[9];
+	int8_t filter2Coefficients[9];
+	uint8_t  cropEnable;
+	uint16_t cropFirstPixel;
+	uint16_t cropLastPixel;
+	uint16_t cropFirstLine;
+	uint16_t cropLastLine;
+};
+
+struct vfe_cmd_asf_update {
+	uint8_t enable;
+	uint8_t smoothFilterEnabled;
+	uint8_t sharpMode;
+	uint8_t smoothCoefCenter;
+	uint8_t smoothCoefSurr;
+	uint8_t normalizeFactor;
+	uint8_t sharpK1;
+	uint8_t sharpK2;
+	uint8_t sharpThreshE1;
+	int8_t  sharpThreshE2;
+	int8_t  sharpThreshE3;
+	int8_t  sharpThreshE4;
+	int8_t  sharpThreshE5;
+	int8_t  filter1Coefficients[9];
+	int8_t  filter2Coefficients[9];
+	uint8_t cropEnable;
+};
+
+enum VFE_TEST_GEN_SYNC_EDGE {
+	VFE_TEST_GEN_SYNC_EDGE_ActiveHigh,
+	VFE_TEST_GEN_SYNC_EDGE_ActiveLow
+};
+
+
+struct vfe_cmd_bus_pm_start {
+	uint8_t output2YWrPmEnable;
+	uint8_t output2CbcrWrPmEnable;
+	uint8_t output1YWrPmEnable;
+	uint8_t output1CbcrWrPmEnable;
+};
+
+struct  vfe_frame_skip_counts {
+	uint32_t  totalFrameCount;
+	uint32_t  output1Count;
+	uint32_t  output2Count;
+};
+
+enum VFE_AXI_RD_UNPACK_HBI_SEL {
+	VFE_AXI_RD_HBI_32_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_64_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_128_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_256_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_512_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_1024_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_2048_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_4096_CLOCK_CYCLES
+};
+
+struct vfe_frame_bpc_info {
+	uint32_t greenDefectPixelCount;
+	uint32_t redBlueDefectPixelCount;
+};
+
+struct vfe_frame_asf_info {
+	uint32_t  asfMaxEdge;
+	uint32_t  asfHbiCount;
+};
+
+struct vfe_msg_camif_status {
+	uint8_t  camifState;
+	uint32_t pixelCount;
+	uint32_t lineCount;
+};
+
+struct vfe31_irq_status {
+	uint32_t vfeIrqStatus0;
+	uint32_t vfeIrqStatus1;
+	uint32_t camifStatus;
+	uint32_t demosaicStatus;
+	uint32_t asfMaxEdge;
+};
+
+#define V31_PREVIEW_AXI_FLAG  0x00000001
+#define V31_SNAPSHOT_AXI_FLAG (0x00000001<<1)
+
+struct vfe31_cmd_type {
+	uint16_t id;
+	uint32_t length;
+	uint32_t offset;
+	uint32_t flag;
+};
+
+struct vfe31_free_buf {
+	struct list_head node;
+	uint32_t paddr;
+	uint32_t y_off;
+	uint32_t cbcr_off;
+};
+
+struct vfe31_output_ch {
+	struct list_head free_buf_queue;
+	spinlock_t free_buf_lock;
+	uint16_t output_fmt;
+	int8_t ch0;
+	int8_t ch1;
+	int8_t ch2;
+	uint32_t  capture_cnt;
+	uint32_t  frame_drop_cnt;
+	struct msm_free_buf ping;
+	struct msm_free_buf pong;
+	struct msm_free_buf free_buf;
+};
+
+/* no error irq in mask 0 */
+#define VFE31_IMASK_ERROR_ONLY_0  0x0
+/* when normal case, don't want to block error status. */
+/* bit 0-21 are error irq bits */
+#define VFE31_IMASK_ERROR_ONLY_1               0x003FFFFF
+#define VFE31_IMASK_CAMIF_ERROR               (0x00000001<<0)
+#define VFE31_IMASK_STATS_CS_OVWR             (0x00000001<<1)
+#define VFE31_IMASK_STATS_IHIST_OVWR          (0x00000001<<2)
+#define VFE31_IMASK_REALIGN_BUF_Y_OVFL        (0x00000001<<3)
+#define VFE31_IMASK_REALIGN_BUF_CB_OVFL       (0x00000001<<4)
+#define VFE31_IMASK_REALIGN_BUF_CR_OVFL       (0x00000001<<5)
+#define VFE31_IMASK_VIOLATION                 (0x00000001<<6)
+#define VFE31_IMASK_IMG_MAST_0_BUS_OVFL       (0x00000001<<7)
+#define VFE31_IMASK_IMG_MAST_1_BUS_OVFL       (0x00000001<<8)
+#define VFE31_IMASK_IMG_MAST_2_BUS_OVFL       (0x00000001<<9)
+#define VFE31_IMASK_IMG_MAST_3_BUS_OVFL       (0x00000001<<10)
+#define VFE31_IMASK_IMG_MAST_4_BUS_OVFL       (0x00000001<<11)
+#define VFE31_IMASK_IMG_MAST_5_BUS_OVFL       (0x00000001<<12)
+#define VFE31_IMASK_IMG_MAST_6_BUS_OVFL       (0x00000001<<13)
+#define VFE31_IMASK_STATS_AE_BG_BUS_OVFL         (0x00000001<<14)
+#define VFE31_IMASK_STATS_AF_BF_BUS_OVFL         (0x00000001<<15)
+#define VFE31_IMASK_STATS_AWB_BUS_OVFL        (0x00000001<<16)
+#define VFE31_IMASK_STATS_RS_BUS_OVFL         (0x00000001<<17)
+#define VFE31_IMASK_STATS_CS_BUS_OVFL         (0x00000001<<18)
+#define VFE31_IMASK_STATS_IHIST_BUS_OVFL      (0x00000001<<19)
+#define VFE31_IMASK_STATS_SKIN_BHIST_BUS_OVFL       (0x00000001<<20)
+#define VFE31_IMASK_AXI_ERROR                 (0x00000001<<21)
+
+#define VFE_COM_STATUS 0x000FE000
+
+struct vfe31_output_path {
+	uint16_t output_mode;     /* bitmask  */
+
+	struct vfe31_output_ch out0; /* preview and thumbnail */
+	struct vfe31_output_ch out1; /* snapshot */
+	struct vfe31_output_ch out2; /* video    */
+};
+
+struct vfe31_frame_extra {
+	uint32_t greenDefectPixelCount;
+	uint32_t redBlueDefectPixelCount;
+
+	uint32_t  asfMaxEdge;
+	uint32_t  asfHbiCount;
+
+	uint32_t yWrPmStats0;
+	uint32_t yWrPmStats1;
+	uint32_t cbcrWrPmStats0;
+	uint32_t cbcrWrPmStats1;
+
+	uint32_t  frameCounter;
+};
+
+#define VFE_DISABLE_ALL_IRQS             0
+#define VFE_CLEAR_ALL_IRQS               0xffffffff
+
+#define VFE_HW_VERSION					 0x00000000
+#define VFE_GLOBAL_RESET                 0x00000004
+#define VFE_MODULE_RESET				 0x00000008
+#define VFE_CGC_OVERRIDE                 0x0000000C
+#define VFE_MODULE_CFG                   0x00000010
+#define VFE_CFG				 0x00000014
+#define VFE_IRQ_CMD                      0x00000018
+#define VFE_IRQ_MASK_0                   0x0000001C
+#define VFE_IRQ_MASK_1                   0x00000020
+#define VFE_IRQ_CLEAR_0                  0x00000024
+#define VFE_IRQ_CLEAR_1                  0x00000028
+#define VFE_IRQ_STATUS_0                 0x0000002C
+#define VFE_IRQ_STATUS_1                 0x00000030
+#define VFE_IRQ_COMP_MASK                0x00000034
+#define VFE_BUS_CMD                      0x00000038
+#define VFE_BUS_PING_PONG_STATUS         0x00000180
+#define VFE_BUS_OPERATION_STATUS         0x00000184
+
+#define VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_0        0x00000190
+#define VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_1        0x00000194
+
+#define VFE_AXI_CMD                      0x000001D8
+#define VFE_AXI_STATUS                   0x000001DC
+#define VFE_BUS_STATS_PING_PONG_BASE     0x000000F4
+
+#define VFE_BUS_STATS_AEC_WR_PING_ADDR   0x000000F4
+#define VFE_BUS_STATS_AEC_WR_PONG_ADDR   0x000000F8
+#define VFE_BUS_STATS_AEC_UB_CFG         0x000000FC
+#define VFE_BUS_STATS_AF_WR_PING_ADDR    0x00000100
+#define VFE_BUS_STATS_AF_WR_PONG_ADDR    0x00000104
+#define VFE_BUS_STATS_AF_UB_CFG          0x00000108
+#define VFE_BUS_STATS_AWB_WR_PING_ADDR   0x0000010C
+#define VFE_BUS_STATS_AWB_WR_PONG_ADDR   0x00000110
+#define VFE_BUS_STATS_AWB_UB_CFG         0x00000114
+#define VFE_BUS_STATS_RS_WR_PING_ADDR    0x00000118
+#define VFE_BUS_STATS_RS_WR_PONG_ADDR    0x0000011C
+#define VFE_BUS_STATS_RS_UB_CFG          0x00000120
+
+#define VFE_BUS_STATS_CS_WR_PING_ADDR    0x00000124
+#define VFE_BUS_STATS_CS_WR_PONG_ADDR    0x00000128
+#define VFE_BUS_STATS_CS_UB_CFG          0x0000012C
+#define VFE_BUS_STATS_HIST_WR_PING_ADDR  0x00000130
+#define VFE_BUS_STATS_HIST_WR_PONG_ADDR  0x00000134
+#define VFE_BUS_STATS_HIST_UB_CFG        0x00000138
+#define VFE_BUS_STATS_SKIN_WR_PING_ADDR  0x0000013C
+#define VFE_BUS_STATS_SKIN_WR_PONG_ADDR  0x00000140
+#define VFE_BUS_STATS_SKIN_UB_CFG        0x00000144
+#define VFE_BUS_PM_CMD                   0x00000188
+#define VFE_BUS_PM_CFG                   0x0000018C
+#define VFE_CAMIF_COMMAND                0x000001E0
+#define VFE_CAMIF_STATUS                 0x00000204
+#define VFE_REG_UPDATE_CMD               0x00000260
+#define VFE_DEMUX_GAIN_0                 0x00000288
+#define VFE_DEMUX_GAIN_1                 0x0000028C
+#define VFE_CHROMA_UP                    0x0000035C
+#define VFE_FRAMEDROP_ENC_Y_CFG          0x00000504
+#define VFE_FRAMEDROP_ENC_CBCR_CFG       0x00000508
+#define VFE_FRAMEDROP_ENC_Y_PATTERN      0x0000050C
+#define VFE_FRAMEDROP_ENC_CBCR_PATTERN   0x00000510
+#define VFE_FRAMEDROP_VIEW_Y             0x00000514
+#define VFE_FRAMEDROP_VIEW_CBCR          0x00000518
+#define VFE_FRAMEDROP_VIEW_Y_PATTERN     0x0000051C
+#define VFE_FRAMEDROP_VIEW_CBCR_PATTERN  0x00000520
+#define VFE_CLAMP_MAX                    0x00000524
+#define VFE_CLAMP_MIN                    0x00000528
+#define VFE_REALIGN_BUF                  0x0000052C
+#define VFE_STATS_CFG                    0x00000530
+#define VFE_STATS_AWB_SGW_CFG            0x00000554
+#define VFE_DMI_CFG                      0x00000598
+#define VFE_DMI_ADDR                     0x0000059C
+#define VFE_DMI_DATA_LO                  0x000005A4
+#define VFE_AXI_CFG                      0x00000600
+
+#define VFE31_OUTPUT_MODE_PT		BIT(0)
+#define VFE31_OUTPUT_MODE_S			BIT(1)
+#define VFE31_OUTPUT_MODE_V			BIT(2)
+#define VFE31_OUTPUT_MODE_P			BIT(3)
+#define VFE31_OUTPUT_MODE_T			BIT(4)
+#define VFE31_OUTPUT_MODE_P_ALL_CHNLS		BIT(5)
+#define VFE31_OUTPUT_MODE_PRIMARY		BIT(6)
+#define VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS	BIT(7)
+#define VFE31_OUTPUT_MODE_SECONDARY		BIT(8)
+#define VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS	BIT(9)
+struct vfe_stats_control {
+	uint8_t  ackPending;
+	uint32_t nextFrameAddrBuf;
+	uint32_t droppedStatsFrameCount;
+	uint32_t bufToRender;
+};
+
+struct vfe31_ctrl_type {
+	uint16_t operation_mode;     /* streaming or snapshot */
+	struct vfe31_output_path outpath;
+
+	uint32_t vfeImaskCompositePacked;
+
+	spinlock_t  stop_flag_lock;
+	spinlock_t  update_ack_lock;
+	spinlock_t  state_lock;
+	spinlock_t  io_lock;
+
+	spinlock_t  aec_ack_lock;
+	spinlock_t  awb_ack_lock;
+	spinlock_t  af_ack_lock;
+	spinlock_t  ihist_ack_lock;
+	spinlock_t  rs_ack_lock;
+	spinlock_t  cs_ack_lock;
+	spinlock_t  comp_stats_ack_lock;
+
+	uint32_t extlen;
+	void *extdata;
+
+	int8_t start_ack_pending;
+	int8_t stop_ack_pending;
+	int8_t reset_ack_pending;
+	int8_t update_ack_pending;
+	enum vfe_output_state recording_state;
+	int8_t update_linear;
+	int8_t update_rolloff;
+	int8_t update_la;
+	int8_t update_gamma;
+	enum vfe_output_state liveshot_state;
+
+	spinlock_t  tasklet_lock;
+	struct list_head tasklet_q;
+	void __iomem *vfebase;
+	void __iomem *camifbase;
+	void *syncdata;
+	uint32_t register_total;
+
+	struct resource	*vfemem;
+	struct resource	*camifmem;
+	struct resource *vfeio;
+	struct resource *camifio;
+	struct resource *vfeirq;
+	struct regulator *fs_vfe;
+
+	uint32_t stats_comp;
+	atomic_t vstate;
+	uint32_t vfe_capture_count;
+	uint32_t sync_timer_repeat_count;
+	uint32_t sync_timer_state;
+	uint32_t sync_timer_number;
+
+	uint32_t vfeFrameId;
+	uint32_t output1Pattern;
+	uint32_t output1Period;
+	uint32_t output2Pattern;
+	uint32_t output2Period;
+	uint32_t vfeFrameSkipCount;
+	uint32_t vfeFrameSkipPeriod;
+	struct vfe_stats_control afStatsControl;
+	struct vfe_stats_control awbStatsControl;
+	struct vfe_stats_control aecStatsControl;
+	struct vfe_stats_control ihistStatsControl;
+	struct vfe_stats_control rsStatsControl;
+	struct vfe_stats_control csStatsControl;
+
+	/* v4l2 subdev */
+	struct v4l2_subdev subdev;
+	struct platform_device *pdev;
+	struct clk *vfe_clk[5];
+	struct clk *vfe_camif_clk[2];
+	spinlock_t  sd_notify_lock;
+	uint32_t hfr_mode;
+	uint32_t frame_skip_cnt;
+	uint32_t frame_skip_pattern;
+	uint32_t snapshot_frame_cnt;
+};
+
+enum VFE31_STATS_NUM {
+	STATS_AE_NUM,
+	STATS_AF_NUM,
+	STATS_AWB_NUM,
+	STATS_RS_NUM,
+	STATS_CS_NUM,
+	STATS_IHIST_NUM,
+	STATS_SKIN_NUM,
+	STATS_MAX_NUM,
+};
+
+struct vfe_cmd_stats_ack {
+	uint32_t  nextStatsBuf;
+};
+
+#define VFE_STATS_BUFFER_COUNT            3
+
+struct vfe_cmd_stats_buf {
+	uint32_t statsBuf[VFE_STATS_BUFFER_COUNT];
+};
+#endif /* __MSM_VFE31_H__ */
diff --git a/drivers/media/video/msm/sensors/imx074_v4l2.c b/drivers/media/video/msm/sensors/imx074_v4l2.c
index af9d1f4..5330d7b 100644
--- a/drivers/media/video/msm/sensors/imx074_v4l2.c
+++ b/drivers/media/video/msm/sensors/imx074_v4l2.c
@@ -168,6 +168,19 @@
 	},
 };
 
+static struct msm_camera_csi_params imx074_csic_params = {
+	.data_format = CSI_10BIT,
+	.lane_cnt    = 4,
+	.lane_assign = 0xe4,
+	.dpcm_scheme = 0,
+	.settle_cnt  = 0x14,
+};
+
+static struct msm_camera_csi_params *imx074_csic_params_array[] = {
+	&imx074_csic_params,
+	&imx074_csic_params,
+};
+
 static struct msm_camera_csid_vc_cfg imx074_cid_cfg[] = {
 	{0, CSI_RAW10, CSI_DECODE_10BIT},
 	{1, CSI_EMBED_DATA, CSI_DECODE_8BIT},
@@ -288,6 +301,7 @@
 	.sensor_write_exp_gain = msm_sensor_write_exp_gain1,
 	.sensor_write_snapshot_exp_gain = msm_sensor_write_exp_gain1,
 	.sensor_setting = msm_sensor_setting,
+	.sensor_csi_setting = msm_sensor_setting1,
 	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
 	.sensor_mode_init = msm_sensor_mode_init,
 	.sensor_get_output_info = msm_sensor_get_output_info,
@@ -323,6 +337,7 @@
 	.sensor_id_info = &imx074_id_info,
 	.sensor_exp_gain_info = &imx074_exp_gain_info,
 	.cam_mode = MSM_SENSOR_MODE_INVALID,
+	.csic_params = &imx074_csic_params_array[0],
 	.csi_params = &imx074_csi_params_array[0],
 	.msm_sensor_mutex = &imx074_mut,
 	.sensor_i2c_driver = &imx074_i2c_driver,
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index d882e52..3da7c5d 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -245,6 +245,10 @@
 			msleep(30);
 			csi_config = 1;
 		}
+		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
+			NOTIFY_PCLK_CHANGE,
+			&s_ctrl->sensordata->pdata->ioclk.vfe_clk_rate);
+
 		s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
 		msleep(50);
 	}
@@ -312,8 +316,13 @@
 			s_ctrl->msm_sensor_reg->
 			output_settings[res].line_length_pclk;
 
-		if (s_ctrl->func_tbl->sensor_setting
-			(s_ctrl, MSM_SENSOR_UPDATE_PERIODIC, res) < 0)
+		if (s_ctrl->sensordata->pdata->is_csic)
+			rc = s_ctrl->func_tbl->sensor_csi_setting(s_ctrl,
+				MSM_SENSOR_UPDATE_PERIODIC, res);
+		else
+			rc = s_ctrl->func_tbl->sensor_setting(s_ctrl,
+				MSM_SENSOR_UPDATE_PERIODIC, res);
+		if (rc < 0)
 			return rc;
 		s_ctrl->curr_res = res;
 	}
@@ -333,8 +342,12 @@
 		s_ctrl->curr_res = MSM_SENSOR_INVALID_RES;
 		s_ctrl->cam_mode = mode;
 
-		rc = s_ctrl->func_tbl->sensor_setting(s_ctrl,
-			MSM_SENSOR_REG_INIT, 0);
+		if (s_ctrl->sensordata->pdata->is_csic)
+			rc = s_ctrl->func_tbl->sensor_csi_setting(s_ctrl,
+				MSM_SENSOR_REG_INIT, 0);
+		else
+			rc = s_ctrl->func_tbl->sensor_setting(s_ctrl,
+				MSM_SENSOR_REG_INIT, 0);
 	}
 	return rc;
 }
@@ -608,6 +621,8 @@
 		msm_sensor_disable_i2c_mux(
 			data->sensor_platform_info->i2c_conf);
 
+	s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
+	msleep(20);
 	if (data->sensor_platform_info->ext_power_ctrl != NULL)
 		data->sensor_platform_info->ext_power_ctrl(0);
 	msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->dev,
@@ -626,7 +641,6 @@
 	return 0;
 }
 
-
 int32_t msm_sensor_match_id(struct msm_sensor_ctrl_t *s_ctrl)
 {
 	int32_t rc = 0;
@@ -686,7 +700,10 @@
 	if (rc < 0)
 		goto probe_fail;
 
-	rc = msm_sensor_match_id(s_ctrl);
+	if (s_ctrl->func_tbl->sensor_match_id)
+		rc = s_ctrl->func_tbl->sensor_match_id(s_ctrl);
+	else
+		rc = msm_sensor_match_id(s_ctrl);
 	if (rc < 0)
 		goto probe_fail;
 
@@ -717,7 +734,7 @@
 	msm_sensor_register(&s_ctrl->sensor_v4l2_subdev);
 	goto power_down;
 probe_fail:
-	CDBG("%s_i2c_probe failed\n", client->name);
+	pr_err("%s_i2c_probe failed\n", client->name);
 power_down:
 	if (rc > 0)
 		rc = 0;
diff --git a/drivers/media/video/msm/sensors/msm_sensor.h b/drivers/media/video/msm/sensors/msm_sensor.h
index d1a6cee..421e1d1 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.h
+++ b/drivers/media/video/msm/sensors/msm_sensor.h
@@ -120,6 +120,8 @@
 			uint16_t, uint32_t);
 	int32_t (*sensor_setting) (struct msm_sensor_ctrl_t *,
 			int update_type, int rt);
+	int32_t (*sensor_csi_setting) (struct msm_sensor_ctrl_t *,
+			int update_type, int rt);
 	int32_t (*sensor_set_sensor_mode)
 			(struct msm_sensor_ctrl_t *, int, int);
 	int32_t (*sensor_mode_init) (struct msm_sensor_ctrl_t *,
@@ -130,6 +132,7 @@
 	int (*sensor_power_down)
 		(struct msm_sensor_ctrl_t *);
 	int (*sensor_power_up) (struct msm_sensor_ctrl_t *);
+	int32_t (*sensor_match_id)(struct msm_sensor_ctrl_t *s_ctrl);
 };
 
 struct msm_sensor_ctrl_t {
diff --git a/drivers/media/video/msm/sensors/mt9e013_v4l2.c b/drivers/media/video/msm/sensors/mt9e013_v4l2.c
index a6bc653..e6e2d52 100644
--- a/drivers/media/video/msm/sensors/mt9e013_v4l2.c
+++ b/drivers/media/video/msm/sensors/mt9e013_v4l2.c
@@ -465,7 +465,7 @@
 	.sensor_set_fps = msm_sensor_set_fps,
 	.sensor_write_exp_gain = mt9e013_write_exp_gain,
 	.sensor_write_snapshot_exp_gain = mt9e013_write_exp_snapshot_gain,
-	.sensor_setting = msm_sensor_setting1,
+	.sensor_csi_setting = msm_sensor_setting1,
 	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
 	.sensor_mode_init = msm_sensor_mode_init,
 	.sensor_get_output_info = msm_sensor_get_output_info,
diff --git a/drivers/media/video/msm/sensors/ov5647_v4l2.c b/drivers/media/video/msm/sensors/ov5647_v4l2.c
index ba0592e..7c23fe6 100644
--- a/drivers/media/video/msm/sensors/ov5647_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov5647_v4l2.c
@@ -693,7 +693,7 @@
 	.sensor_set_fps = msm_sensor_set_fps,
 	.sensor_write_exp_gain = ov5647_write_prev_exp_gain,
 	.sensor_write_snapshot_exp_gain = ov5647_write_pict_exp_gain,
-	.sensor_setting = ov5647_sensor_setting,
+	.sensor_csi_setting = ov5647_sensor_setting,
 	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
 	.sensor_mode_init = msm_sensor_mode_init,
 	.sensor_get_output_info = msm_sensor_get_output_info,
diff --git a/drivers/media/video/msm/sensors/ov7692_qrd_v4l2.c b/drivers/media/video/msm/sensors/ov7692_qrd_v4l2.c
index 99e96f0..9fe2e8a 100644
--- a/drivers/media/video/msm/sensors/ov7692_qrd_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov7692_qrd_v4l2.c
@@ -688,7 +688,7 @@
 	.sensor_group_hold_on = msm_sensor_group_hold_on,
 	.sensor_group_hold_off = msm_sensor_group_hold_off,
 	.sensor_set_fps = ov7692_sensor_set_fps,
-	.sensor_setting = msm_sensor_setting3,
+	.sensor_csi_setting = msm_sensor_setting3,
 	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
 	.sensor_mode_init = msm_sensor_mode_init,
 	.sensor_get_output_info = msm_sensor_get_output_info,
diff --git a/drivers/media/video/msm/sensors/ov9726_v4l2.c b/drivers/media/video/msm/sensors/ov9726_v4l2.c
index 17291ff..61c693e 100644
--- a/drivers/media/video/msm/sensors/ov9726_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov9726_v4l2.c
@@ -229,7 +229,7 @@
 	.sensor_set_fps = msm_sensor_set_fps,
 	.sensor_write_exp_gain = msm_sensor_write_exp_gain1,
 	.sensor_write_snapshot_exp_gain = msm_sensor_write_exp_gain1,
-	.sensor_setting = msm_sensor_setting1,
+	.sensor_csi_setting = msm_sensor_setting1,
 	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
 	.sensor_mode_init = msm_sensor_mode_init,
 	.sensor_get_output_info = msm_sensor_get_output_info,
diff --git a/drivers/media/video/msm/sensors/s5k4e1_v4l2.c b/drivers/media/video/msm/sensors/s5k4e1_v4l2.c
index 699f0dd..6671073 100644
--- a/drivers/media/video/msm/sensors/s5k4e1_v4l2.c
+++ b/drivers/media/video/msm/sensors/s5k4e1_v4l2.c
@@ -450,7 +450,7 @@
 	.sensor_set_fps = msm_sensor_set_fps,
 	.sensor_write_exp_gain = s5k4e1_write_prev_exp_gain,
 	.sensor_write_snapshot_exp_gain = s5k4e1_write_pict_exp_gain,
-	.sensor_setting = msm_sensor_setting1,
+	.sensor_csi_setting = msm_sensor_setting1,
 	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
 	.sensor_mode_init = msm_sensor_mode_init,
 	.sensor_get_output_info = msm_sensor_get_output_info,
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index c275a06..e21862a 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -44,6 +44,8 @@
 #define ADC_ARB_SECP_DATA0	0x196
 
 #define ADC_ARB_BMS_CNTRL	0x18D
+#define AMUX_TRIM_2		0x322
+#define TEST_PROGRAM_REV	0x339
 
 enum pmic_bms_interrupts {
 	PM8921_BMS_SBI_WRITE_OK,
@@ -121,6 +123,7 @@
 	int			batt_temp_suspend;
 	int			soc_rbatt_suspend;
 	int			default_rbatt_mohm;
+	int			amux_2_trim_delta;
 	uint16_t		prev_last_good_ocv_raw;
 };
 
@@ -520,6 +523,20 @@
 	return 0;
 }
 
+static int adjust_xo_vbatt_reading_for_mbg(struct pm8921_bms_chip *chip,
+						int result)
+{
+	int64_t numerator;
+	int64_t denominator;
+
+	if (chip->amux_2_trim_delta == 0)
+		return result;
+
+	numerator = (s64)result * 1000000;
+	denominator = (1000000 + (410 * (s64)chip->amux_2_trim_delta));
+	return div_s64(numerator, denominator);
+}
+
 static int convert_vbatt_raw_to_uv(struct pm8921_bms_chip *chip,
 					int usb_chg,
 					uint16_t reading, int *result)
@@ -528,6 +545,7 @@
 	pr_debug("raw = %04x vbatt = %u\n", reading, *result);
 	*result = adjust_xo_vbatt_reading(chip, usb_chg, *result);
 	pr_debug("after adj vbatt = %u\n", *result);
+	*result = adjust_xo_vbatt_reading_for_mbg(chip, *result);
 	return 0;
 }
 
@@ -902,6 +920,19 @@
 	return 0;
 }
 
+#define MBG_TRANSIENT_ERROR_RAW 51
+static void adjust_pon_ocv_raw(struct pm8921_bms_chip *chip,
+				struct pm8921_soc_params *raw)
+{
+	/* in 8921 parts the PON ocv is taken when the MBG is not settled.
+	 * decrease the pon ocv by 15mV raw value to account for it
+	 * Since a 1/3rd  of vbatt is supplied to the adc the raw value
+	 * needs to be adjusted by 5mV worth bits
+	 */
+	if (raw->last_good_ocv_raw >= MBG_TRANSIENT_ERROR_RAW)
+		raw->last_good_ocv_raw -= MBG_TRANSIENT_ERROR_RAW;
+}
+
 static int read_soc_params_raw(struct pm8921_bms_chip *chip,
 				struct pm8921_soc_params *raw)
 {
@@ -919,8 +950,13 @@
 
 	usb_chg =  usb_chg_plugged_in();
 
-	if (chip->prev_last_good_ocv_raw == 0 ||
-		chip->prev_last_good_ocv_raw != raw->last_good_ocv_raw) {
+	if (chip->prev_last_good_ocv_raw == 0) {
+		chip->prev_last_good_ocv_raw = raw->last_good_ocv_raw;
+		adjust_pon_ocv_raw(chip, raw);
+		convert_vbatt_raw_to_uv(chip, usb_chg,
+			raw->last_good_ocv_raw, &raw->last_good_ocv_uv);
+		last_ocv_uv = raw->last_good_ocv_uv;
+	} else if (chip->prev_last_good_ocv_raw != raw->last_good_ocv_raw) {
 		chip->prev_last_good_ocv_raw = raw->last_good_ocv_raw;
 		convert_vbatt_raw_to_uv(chip, usb_chg,
 			raw->last_good_ocv_raw, &raw->last_good_ocv_uv);
@@ -929,9 +965,6 @@
 		raw->last_good_ocv_uv = last_ocv_uv;
 	}
 
-	if (raw->last_good_ocv_uv)
-		last_ocv_uv = raw->last_good_ocv_uv;
-
 	pr_debug("0p625 = %duV\n", chip->xoadc_v0625);
 	pr_debug("1p25 = %duV\n", chip->xoadc_v125);
 	pr_debug("last_good_ocv_raw= 0x%x, last_good_ocv_uv= %duV\n",
@@ -2190,6 +2223,61 @@
 	}
 }
 
+#define REG_SBI_CONFIG		0x04F
+#define PAGE3_ENABLE_MASK	0x6
+#define PROGRAM_REV_MASK	0x0F
+#define PROGRAM_REV		0x9
+static int read_ocv_trim(struct pm8921_bms_chip *chip)
+{
+	int rc;
+	u8 reg, sbi_config;
+
+	rc = pm8xxx_readb(chip->dev->parent, REG_SBI_CONFIG, &sbi_config);
+	if (rc) {
+		pr_err("error = %d reading sbi config reg\n", rc);
+		return rc;
+	}
+
+	reg = sbi_config | PAGE3_ENABLE_MASK;
+	rc = pm8xxx_writeb(chip->dev->parent, REG_SBI_CONFIG, reg);
+	if (rc) {
+		pr_err("error = %d writing sbi config reg\n", rc);
+		return rc;
+	}
+
+	rc = pm8xxx_readb(chip->dev->parent, TEST_PROGRAM_REV, &reg);
+	if (rc)
+		pr_err("Error %d reading %d addr %d\n",
+			rc, reg, TEST_PROGRAM_REV);
+	pr_err("program rev reg is 0x%x\n", reg);
+	reg &= PROGRAM_REV_MASK;
+
+	/* If the revision is equal or higher do not adjust trim delta */
+	if (reg >= PROGRAM_REV) {
+		chip->amux_2_trim_delta = 0;
+		goto restore_sbi_config;
+	}
+
+	rc = pm8xxx_readb(chip->dev->parent, AMUX_TRIM_2, &reg);
+	if (rc) {
+		pr_err("error = %d reading trim reg\n", rc);
+		return rc;
+	}
+
+	pr_err("trim reg is 0x%x\n", reg);
+	chip->amux_2_trim_delta = abs(0x49 - reg);
+	pr_err("trim delta is %d\n", chip->amux_2_trim_delta);
+
+restore_sbi_config:
+	rc = pm8xxx_writeb(chip->dev->parent, REG_SBI_CONFIG, sbi_config);
+	if (rc) {
+		pr_err("error = %d writing sbi config reg\n", rc);
+		return rc;
+	}
+
+	return 0;
+}
+
 static int __devinit pm8921_bms_probe(struct platform_device *pdev)
 {
 	int rc = 0;
@@ -2259,6 +2347,11 @@
 	the_chip = chip;
 	create_debugfs_entries(chip);
 
+	rc = read_ocv_trim(chip);
+	if (rc) {
+		pr_err("couldn't adjust ocv_trim rc= %d\n", rc);
+		goto free_irqs;
+	}
 	check_initial_ocv(chip);
 
 	INIT_DELAYED_WORK(&chip->calib_ccadc_work, calibrate_ccadc_work);
diff --git a/drivers/usb/gadget/f_mbim.c b/drivers/usb/gadget/f_mbim.c
index 8288496..21b393e 100644
--- a/drivers/usb/gadget/f_mbim.c
+++ b/drivers/usb/gadget/f_mbim.c
@@ -553,7 +553,7 @@
 	}
 
 	spin_lock_irqsave(&dev->lock, flags);
-	list_add(&cpkt->list, &dev->cpkt_resp_q);
+	list_add_tail(&cpkt->list, &dev->cpkt_resp_q);
 	spin_unlock_irqrestore(&dev->lock, flags);
 
 	fmbim_ctrl_response_available(dev);
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index 226ea68..2114287 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -114,6 +114,7 @@
 #define RC_MAP_NORWOOD                   "rc-norwood"
 #define RC_MAP_NPGTECH                   "rc-npgtech"
 #define RC_MAP_PCTV_SEDNA                "rc-pctv-sedna"
+#define RC_MAP_RC6_PHILIPS		 "rc-philips"
 #define RC_MAP_PINNACLE_COLOR            "rc-pinnacle-color"
 #define RC_MAP_PINNACLE_GREY             "rc-pinnacle-grey"
 #define RC_MAP_PINNACLE_PCTV_HD          "rc-pinnacle-pctv-hd"