Merge "ASoC: msm: Add 4 front ends to support Multiple playback use case" into msm-3.4
diff --git a/arch/arm/boot/dts/msm-pm8841.dtsi b/arch/arm/boot/dts/msm-pm8841.dtsi
index 523c9b0..b157e95 100644
--- a/arch/arm/boot/dts/msm-pm8841.dtsi
+++ b/arch/arm/boot/dts/msm-pm8841.dtsi
@@ -153,13 +153,13 @@
 				status = "disabled";
 
 				qcom,ctl@2600 {
-					reg = <0x2300 0x100>;
+					reg = <0x2600 0x100>;
 				};
 				qcom,ps@2700 {
-					reg = <0x2400 0x100>;
+					reg = <0x2700 0x100>;
 				};
 				qcom,freq@2800 {
-					reg = <0x2500 0x100>;
+					reg = <0x2800 0x100>;
 				};
 			};
 
diff --git a/arch/arm/boot/dts/msm9625.dts b/arch/arm/boot/dts/msm9625.dts
index d5aed00..b7b8be2 100644
--- a/arch/arm/boot/dts/msm9625.dts
+++ b/arch/arm/boot/dts/msm9625.dts
@@ -33,9 +33,11 @@
 		reg = <0xfd510000 0x4000>;
 	};
 
-	timer {
+	timer: msm-qtimer@f9021000 {
 		compatible = "qcom,msm-qtimer", "arm,armv7-timer";
+		reg = <0xF9021000 0x1000>;
 		interrupts = <0 7 0>;
+		irq-is-not-percpu;
 		clock-frequency = <5000000>;
 	};
 
diff --git a/arch/arm/boot/dts/msmcopper.dtsi b/arch/arm/boot/dts/msmcopper.dtsi
index eb781b7..5b5e646 100644
--- a/arch/arm/boot/dts/msmcopper.dtsi
+++ b/arch/arm/boot/dts/msmcopper.dtsi
@@ -276,6 +276,11 @@
 		compatible = "qcom,dwc-usb3-msm";
 		reg = <0xF9200000 0xCCFF>;
 		interrupts = <0 131 0>;
+		SSUSB_VDDCX-supply = <&pm8841_s2>;
+		SSUSB_1p8-supply = <&pm8941_l6>;
+		HSUSB_VDDCX-supply = <&pm8841_s2>;
+		HSUSB_1p8-supply = <&pm8941_l6>;
+		HSUSB_3p3-supply = <&pm8941_l24>;
 		qcom,dwc-usb3-msm-dbm-eps = <4>;
 	};
 
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index 473a7d5..49fae4a 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -69,10 +69,11 @@
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_GOV_ONDEMAND=y
 CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_IDLE=y
 CONFIG_VFP=y
 CONFIG_NEON=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-# CONFIG_SUSPEND is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_NET=y
 CONFIG_UNIX=y
 CONFIG_INET=y
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index 447427a..a163829 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -192,6 +192,7 @@
 CONFIG_BLK_DEV_DM=y
 CONFIG_DM_CRYPT=y
 CONFIG_NETDEVICES=y
+CONFIG_TUN=y
 CONFIG_SMC91X=y
 CONFIG_SMSC911X=y
 CONFIG_LIBRA_SDIOIF=m
@@ -227,6 +228,7 @@
 CONFIG_BATTERY_MSM=y
 CONFIG_SENSORS_MSM_ADC=y
 CONFIG_MARIMBA_CORE=y
+CONFIG_REGULATOR_MSM_GPIO=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_MEDIA_CONTROLLER=y
 CONFIG_VIDEO_DEV=y
@@ -237,13 +239,13 @@
 CONFIG_V4L_PLATFORM_DRIVERS=y
 CONFIG_MSM_CAMERA_V4L2=y
 CONFIG_OV5647=y
-CONFIG_OV8825=y
 CONFIG_AD5046_ACT=y
 CONFIG_WEBCAM_OV9726=y
 CONFIG_MT9E013=y
 CONFIG_S5K4E1=y
 CONFIG_DW9712_ACT=y
 CONFIG_MSM_CAMERA_FLASH_SC628A=y
+CONFIG_OV8825=y
 CONFIG_MSM_CAMERA_SENSOR=y
 CONFIG_MSM_ACTUATOR=y
 CONFIG_OV7692=y
@@ -339,6 +341,5 @@
 CONFIG_ENABLE_DEFAULT_TRACERS=y
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_USER=y
-CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_TWOFISH=y
 CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index 639eb10..d8e2e3c 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -192,6 +192,7 @@
 CONFIG_BLK_DEV_DM=y
 CONFIG_DM_CRYPT=y
 CONFIG_NETDEVICES=y
+CONFIG_TUN=y
 CONFIG_SMC91X=y
 CONFIG_SMSC911X=y
 CONFIG_LIBRA_SDIOIF=m
@@ -228,6 +229,7 @@
 CONFIG_BATTERY_MSM=y
 CONFIG_SENSORS_MSM_ADC=y
 CONFIG_MARIMBA_CORE=y
+CONFIG_REGULATOR_MSM_GPIO=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_MEDIA_CONTROLLER=y
 CONFIG_VIDEO_DEV=y
@@ -238,13 +240,13 @@
 CONFIG_V4L_PLATFORM_DRIVERS=y
 CONFIG_MSM_CAMERA_V4L2=y
 CONFIG_OV5647=y
-CONFIG_OV8825=y
 CONFIG_AD5046_ACT=y
 CONFIG_WEBCAM_OV9726=y
 CONFIG_MT9E013=y
 CONFIG_S5K4E1=y
 CONFIG_DW9712_ACT=y
 CONFIG_MSM_CAMERA_FLASH_SC628A=y
+CONFIG_OV8825=y
 CONFIG_MSM_CAMERA_SENSOR=y
 CONFIG_MSM_ACTUATOR=y
 CONFIG_OV7692=y
@@ -347,6 +349,5 @@
 CONFIG_ENABLE_DEFAULT_TRACERS=y
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_USER=y
-CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_TWOFISH=y
 CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/msm7630-perf_defconfig b/arch/arm/configs/msm7630-perf_defconfig
index c39b403..136dc46 100644
--- a/arch/arm/configs/msm7630-perf_defconfig
+++ b/arch/arm/configs/msm7630-perf_defconfig
@@ -207,6 +207,7 @@
 CONFIG_DM_CRYPT=y
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=y
+CONFIG_TUN=y
 CONFIG_MSM_RMNET_SDIO=y
 CONFIG_SMC91X=y
 CONFIG_SMSC911X=y
@@ -370,7 +371,6 @@
 CONFIG_DEBUG_INFO=y
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_USER=y
-CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_TWOFISH=y
 CONFIG_CRYPTO_DEV_QCRYPTO=m
 CONFIG_CRYPTO_DEV_QCE=m
diff --git a/arch/arm/configs/msm7630_defconfig b/arch/arm/configs/msm7630_defconfig
index 8dda15f..bead86e 100644
--- a/arch/arm/configs/msm7630_defconfig
+++ b/arch/arm/configs/msm7630_defconfig
@@ -208,6 +208,7 @@
 CONFIG_DM_CRYPT=y
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=y
+CONFIG_TUN=y
 CONFIG_MSM_RMNET_SDIO=y
 CONFIG_SMC91X=y
 CONFIG_SMSC911X=y
@@ -378,7 +379,6 @@
 CONFIG_DEBUG_PAGEALLOC=y
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_USER=y
-CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_TWOFISH=y
 CONFIG_CRYPTO_DEV_QCRYPTO=m
 CONFIG_CRYPTO_DEV_QCE=m
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index d5b4007..98661be 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -248,6 +248,7 @@
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=y
+CONFIG_TUN=y
 CONFIG_MSM_RMNET_SDIO=y
 CONFIG_SMC91X=y
 CONFIG_SMC911X=y
@@ -443,7 +444,6 @@
 CONFIG_ENABLE_DEFAULT_TRACERS=y
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_USER=y
-CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_TWOFISH=y
 CONFIG_CRYPTO_DEV_QCRYPTO=m
 CONFIG_CRYPTO_DEV_QCE=m
diff --git a/arch/arm/configs/msm8660_defconfig b/arch/arm/configs/msm8660_defconfig
index 5e2c1a8..ec7c036 100644
--- a/arch/arm/configs/msm8660_defconfig
+++ b/arch/arm/configs/msm8660_defconfig
@@ -249,6 +249,7 @@
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=y
+CONFIG_TUN=y
 CONFIG_MSM_RMNET_SDIO=y
 CONFIG_SMC91X=y
 CONFIG_SMC911X=y
@@ -455,7 +456,6 @@
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_LL=y
-CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_TWOFISH=y
 CONFIG_CRYPTO_DEV_QCRYPTO=m
 CONFIG_CRYPTO_DEV_QCE=m
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 74d31b3..47d6ea8 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -66,7 +66,6 @@
 CONFIG_MSM_SMD_PKG4=y
 CONFIG_MSM_PCIE=y
 CONFIG_MSM_BAM_DMUX=y
-CONFIG_MSM_RMNET_SMUX=y
 CONFIG_MSM_DSPS=y
 CONFIG_MSM_IPC_ROUTER=y
 CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
@@ -256,9 +255,11 @@
 CONFIG_DM_CRYPT=y
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=y
+CONFIG_TUN=y
 CONFIG_KS8851=m
 # CONFIG_MSM_RMNET is not set
 CONFIG_MSM_RMNET_BAM=y
+CONFIG_MSM_RMNET_SMUX=y
 CONFIG_SMC91X=y
 CONFIG_SMC911X=y
 CONFIG_SMSC911X=y
@@ -308,7 +309,6 @@
 CONFIG_SMB349_CHARGER=y
 CONFIG_PM8921_CHARGER=y
 CONFIG_PM8921_BMS=y
-CONFIG_PM8921_BCL=y
 CONFIG_SENSORS_PM8XXX_ADC=y
 CONFIG_SENSORS_EPM_ADC=y
 CONFIG_THERMAL=y
@@ -475,7 +475,6 @@
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_USER=y
 CONFIG_PID_IN_CONTEXTIDR=y
-CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_TWOFISH=y
 CONFIG_CRYPTO_DEV_QCRYPTO=m
 CONFIG_CRYPTO_DEV_QCE=m
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 07a3f91..a0636f9 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -261,6 +261,7 @@
 CONFIG_DM_CRYPT=y
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=y
+CONFIG_TUN=y
 CONFIG_KS8851=m
 # CONFIG_MSM_RMNET is not set
 CONFIG_MSM_RMNET_BAM=y
@@ -492,7 +493,6 @@
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_USER=y
 CONFIG_PID_IN_CONTEXTIDR=y
-CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_TWOFISH=y
 CONFIG_CRYPTO_DEV_QCRYPTO=m
 CONFIG_CRYPTO_DEV_QCE=m
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index 89fb888..1e45f66 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -1,7 +1,7 @@
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
 CONFIG_EXPERIMENTAL=y
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SYSVIPC=y
-CONFIG_SPARSE_IRQ=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_CGROUPS=y
@@ -28,6 +28,7 @@
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_PARTITION_ADVANCED=y
 CONFIG_ARCH_MSM=y
 CONFIG_ARCH_MSM9625=y
 # CONFIG_MSM_STACKED_MEMORY is not set
@@ -51,7 +52,6 @@
 # CONFIG_SUSPEND is not set
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
-CONFIG_MISC_DEVICES=y
 # CONFIG_ANDROID_PMEM is not set
 # CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_KEYBOARD is not set
@@ -67,20 +67,17 @@
 CONFIG_DEBUG_GPIO=y
 CONFIG_GPIO_SYSFS=y
 # CONFIG_HWMON is not set
-# CONFIG_MFD_SUPPORT is not set
 # CONFIG_HID_SUPPORT is not set
 # CONFIG_USB_SUPPORT is not set
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
 # CONFIG_MISC_FILESYSTEMS is not set
-CONFIG_PARTITION_ADVANCED=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ASCII=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_PRINTK_TIME=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
 # CONFIG_SCHED_DEBUG is not set
 CONFIG_TIMER_STATS=y
 # CONFIG_DEBUG_PREEMPT is not set
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
index 2098288..99ee2de 100644
--- a/arch/arm/include/asm/arch_timer.h
+++ b/arch/arm/include/asm/arch_timer.h
@@ -4,7 +4,7 @@
 #include <linux/ioport.h>
 
 struct arch_timer {
-	struct resource	res[2];
+	struct resource	res[3];
 };
 
 #ifdef CONFIG_ARM_ARCH_TIMER
diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h
index 0bdb0f1..a6ec7b2 100644
--- a/arch/arm/include/asm/mach/mmc.h
+++ b/arch/arm/include/asm/mach/mmc.h
@@ -146,7 +146,6 @@
 	unsigned int msmsdcc_fmid;
 	unsigned int msmsdcc_fmax;
 	bool nonremovable;
-	bool pclk_src_dfab;
 	unsigned int mpm_sdiowakeup_int;
 	unsigned int wpswitch_gpio;
 	unsigned char wpswitch_polarity;
diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c
index 81a9a71..88cf368 100644
--- a/arch/arm/kernel/arch_timer.c
+++ b/arch/arm/kernel/arch_timer.c
@@ -19,6 +19,7 @@
 #include <linux/clockchips.h>
 #include <linux/interrupt.h>
 #include <linux/of_irq.h>
+#include <linux/of_address.h>
 #include <linux/io.h>
 #include <linux/irq.h>
 
@@ -32,8 +33,43 @@
 static unsigned long arch_timer_rate;
 static int arch_timer_ppi;
 static int arch_timer_ppi2;
+static int is_irq_percpu;
 
 static struct clock_event_device __percpu **arch_timer_evt;
+static void __iomem *timer_base;
+
+static u32 timer_reg_read_cp15(int reg);
+static void timer_reg_write_cp15(int reg, u32 val);
+static inline cycle_t counter_get_cntpct_cp15(void);
+static inline cycle_t counter_get_cntvct_cp15(void);
+
+static u32 timer_reg_read_mem(int reg);
+static void timer_reg_write_mem(int reg, u32 val);
+static inline cycle_t counter_get_cntpct_mem(void);
+static inline cycle_t counter_get_cntvct_mem(void);
+
+struct arch_timer_operations {
+	void (*reg_write)(int, u32);
+	u32 (*reg_read)(int);
+	cycle_t (*get_cntpct)(void);
+	cycle_t (*get_cntvct)(void);
+};
+
+static struct arch_timer_operations arch_timer_ops_cp15 = {
+	.reg_read = &timer_reg_read_cp15,
+	.reg_write = &timer_reg_write_cp15,
+	.get_cntpct = &counter_get_cntpct_cp15,
+	.get_cntvct = &counter_get_cntvct_cp15,
+};
+
+static struct arch_timer_operations arch_timer_ops_mem = {
+	.reg_read = &timer_reg_read_mem,
+	.reg_write = &timer_reg_write_mem,
+	.get_cntpct = &counter_get_cntpct_mem,
+	.get_cntvct = &counter_get_cntvct_mem,
+};
+
+static struct arch_timer_operations *arch_specific_timer = &arch_timer_ops_cp15;
 
 /*
  * Architected system timer support.
@@ -47,7 +83,29 @@
 #define ARCH_TIMER_REG_FREQ		1
 #define ARCH_TIMER_REG_TVAL		2
 
-static void arch_timer_reg_write(int reg, u32 val)
+/* Iomapped Register Offsets */
+#define QTIMER_CNTP_LOW_REG		0x000
+#define QTIMER_CNTP_HIGH_REG		0x004
+#define QTIMER_CNTV_LOW_REG		0x008
+#define QTIMER_CNTV_HIGH_REG		0x00C
+#define QTIMER_CTRL_REG			0x02C
+#define QTIMER_FREQ_REG			0x010
+#define QTIMER_CNTP_TVAL_REG		0x028
+#define QTIMER_CNTV_TVAL_REG		0x038
+
+static void timer_reg_write_mem(int reg, u32 val)
+{
+	switch (reg) {
+	case ARCH_TIMER_REG_CTRL:
+		__raw_writel(val, timer_base + QTIMER_CTRL_REG);
+		break;
+	case ARCH_TIMER_REG_TVAL:
+		__raw_writel(val, timer_base + QTIMER_CNTP_TVAL_REG);
+		break;
+	}
+}
+
+static void timer_reg_write_cp15(int reg, u32 val)
 {
 	switch (reg) {
 	case ARCH_TIMER_REG_CTRL:
@@ -61,7 +119,28 @@
 	isb();
 }
 
-static u32 arch_timer_reg_read(int reg)
+static u32 timer_reg_read_mem(int reg)
+{
+	u32 val;
+
+	switch (reg) {
+	case ARCH_TIMER_REG_CTRL:
+		val = __raw_readl(timer_base + QTIMER_CTRL_REG);
+		break;
+	case ARCH_TIMER_REG_FREQ:
+		val = __raw_readl(timer_base + QTIMER_FREQ_REG);
+		break;
+	case ARCH_TIMER_REG_TVAL:
+		val = __raw_readl(timer_base + QTIMER_CNTP_TVAL_REG);
+		break;
+	default:
+		BUG();
+	}
+
+	return val;
+}
+
+static u32 timer_reg_read_cp15(int reg)
 {
 	u32 val;
 
@@ -87,10 +166,11 @@
 	struct clock_event_device *evt;
 	unsigned long ctrl;
 
-	ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL);
+	ctrl = arch_specific_timer->reg_read(ARCH_TIMER_REG_CTRL);
 	if (ctrl & ARCH_TIMER_CTRL_IT_STAT) {
 		ctrl |= ARCH_TIMER_CTRL_IT_MASK;
-		arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
+		arch_specific_timer->reg_write(ARCH_TIMER_REG_CTRL,
+							ctrl);
 		evt = *__this_cpu_ptr(arch_timer_evt);
 		evt->event_handler(evt);
 		return IRQ_HANDLED;
@@ -103,9 +183,9 @@
 {
 	unsigned long ctrl;
 
-	ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL);
+	ctrl = arch_specific_timer->reg_read(ARCH_TIMER_REG_CTRL);
 	ctrl &= ~ARCH_TIMER_CTRL_ENABLE;
-	arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
+	arch_specific_timer->reg_write(ARCH_TIMER_REG_CTRL, ctrl);
 }
 
 static void arch_timer_set_mode(enum clock_event_mode mode,
@@ -126,12 +206,12 @@
 {
 	unsigned long ctrl;
 
-	ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL);
+	ctrl = arch_specific_timer->reg_read(ARCH_TIMER_REG_CTRL);
 	ctrl |= ARCH_TIMER_CTRL_ENABLE;
 	ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
 
-	arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
-	arch_timer_reg_write(ARCH_TIMER_REG_TVAL, evt);
+	arch_specific_timer->reg_write(ARCH_TIMER_REG_CTRL, ctrl);
+	arch_specific_timer->reg_write(ARCH_TIMER_REG_TVAL, evt);
 
 	return 0;
 }
@@ -168,19 +248,16 @@
 static int local_timer_is_architected(void)
 {
 	return (cpu_architecture() >= CPU_ARCH_ARMv7) &&
-	       ((read_cpuid_ext(CPUID_EXT_PFR1) >> 16) & 0xf) == 1;
+		((read_cpuid_ext(CPUID_EXT_PFR1) >> 16) & 0xf) == 1;
 }
 
 static int arch_timer_available(void)
 {
 	unsigned long freq;
 
-	if (!local_timer_is_architected())
-		return -ENXIO;
-
 	if (arch_timer_rate == 0) {
-		arch_timer_reg_write(ARCH_TIMER_REG_CTRL, 0);
-		freq = arch_timer_reg_read(ARCH_TIMER_REG_FREQ);
+		arch_specific_timer->reg_write(ARCH_TIMER_REG_CTRL, 0);
+		freq = arch_specific_timer->reg_read(ARCH_TIMER_REG_FREQ);
 
 		/* Check the timer frequency. */
 		if (freq == 0) {
@@ -196,33 +273,57 @@
 	return 0;
 }
 
-static inline cycle_t arch_counter_get_cntpct(void)
+static inline cycle_t counter_get_cntpct_mem(void)
 {
-	u32 cvall, cvalh;
+	u32 cvall, cvalh, thigh;
 
-	asm volatile("mrrc p15, 0, %0, %1, c14" : "=r" (cvall), "=r" (cvalh));
+	do {
+		cvalh = __raw_readl(timer_base + QTIMER_CNTP_HIGH_REG);
+		cvall = __raw_readl(timer_base + QTIMER_CNTP_LOW_REG);
+		thigh = __raw_readl(timer_base + QTIMER_CNTP_HIGH_REG);
+	} while (cvalh != thigh);
 
 	return ((cycle_t) cvalh << 32) | cvall;
 }
 
-static inline cycle_t arch_counter_get_cntvct(void)
+static inline cycle_t counter_get_cntpct_cp15(void)
+{
+	u32 cvall, cvalh;
+
+	asm volatile("mrrc p15, 0, %0, %1, c14" : "=r" (cvall), "=r" (cvalh));
+	return ((cycle_t) cvalh << 32) | cvall;
+}
+
+static inline cycle_t counter_get_cntvct_mem(void)
+{
+	u32 cvall, cvalh, thigh;
+
+	do {
+		cvalh = __raw_readl(timer_base + QTIMER_CNTV_HIGH_REG);
+		cvall = __raw_readl(timer_base + QTIMER_CNTV_LOW_REG);
+		thigh = __raw_readl(timer_base + QTIMER_CNTV_HIGH_REG);
+	} while (cvalh != thigh);
+
+	return ((cycle_t) cvalh << 32) | cvall;
+}
+
+static inline cycle_t counter_get_cntvct_cp15(void)
 {
 	u32 cvall, cvalh;
 
 	asm volatile("mrrc p15, 1, %0, %1, c14" : "=r" (cvall), "=r" (cvalh));
-
 	return ((cycle_t) cvalh << 32) | cvall;
 }
 
 static cycle_t arch_counter_read(struct clocksource *cs)
 {
-	return arch_counter_get_cntpct();
+	return arch_specific_timer->get_cntpct();
 }
 
 #ifdef ARCH_HAS_READ_CURRENT_TIMER
 int read_current_timer(unsigned long *timer_val)
 {
-	*timer_val = (unsigned long)arch_counter_get_cntpct();
+	*timer_val = (unsigned long)arch_specific_timer->get_cntpct();
 	return 0;
 }
 #endif
@@ -239,7 +340,7 @@
 {
 	cycle_t cntvct;
 
-	cntvct = arch_counter_get_cntvct();
+	cntvct = arch_specific_timer->get_cntvct();
 
 	/*
 	 * The sched_clock infrastructure only knows about counters
@@ -273,6 +374,9 @@
 {
 	int err;
 
+	if (!local_timer_is_architected())
+		arch_specific_timer = &arch_timer_ops_mem;
+
 	err = arch_timer_available();
 	if (err)
 		return err;
@@ -289,8 +393,12 @@
 	set_delay_fn(read_current_timer_delay_loop);
 #endif
 
-	err = request_percpu_irq(arch_timer_ppi, arch_timer_handler,
+	if (is_irq_percpu)
+		err = request_percpu_irq(arch_timer_ppi, arch_timer_handler,
 				 "arch_timer", arch_timer_evt);
+	else
+		err = request_irq(arch_timer_ppi, arch_timer_handler, 0,
+			"arch_timer", arch_timer_evt);
 	if (err) {
 		pr_err("arch_timer: can't register interrupt %d (%d)\n",
 		       arch_timer_ppi, err);
@@ -298,8 +406,13 @@
 	}
 
 	if (arch_timer_ppi2) {
-		err = request_percpu_irq(arch_timer_ppi2, arch_timer_handler,
-					 "arch_timer", arch_timer_evt);
+		if (is_irq_percpu)
+			err = request_percpu_irq(arch_timer_ppi2,
+					arch_timer_handler, "arch_timer",
+					arch_timer_evt);
+		else
+			err = request_irq(arch_timer_ppi2, arch_timer_handler,
+					0, "arch_timer", arch_timer_evt);
 		if (err) {
 			pr_err("arch_timer: can't register interrupt %d (%d)\n",
 			       arch_timer_ppi2, err);
@@ -336,6 +449,16 @@
 	if (at->res[1].start > 0 && (at->res[1].flags & IORESOURCE_IRQ))
 		arch_timer_ppi2 = at->res[1].start;
 
+	if (at->res[2].start > 0 && at->res[2].end > 0 &&
+					(at->res[2].flags & IORESOURCE_MEM))
+		timer_base = ioremap(at->res[2].start,
+				resource_size(&at->res[2]));
+
+	if (!timer_base) {
+		pr_err("arch_timer: cant map timer base\n");
+		return -ENOMEM;
+	}
+
 	return arch_timer_common_register();
 }
 
@@ -366,6 +489,18 @@
 		pr_err("arch_timer: interrupt not specified in timer node\n");
 		return -ENODEV;
 	}
+
+	timer_base = of_iomap(np, 0);
+	if (!timer_base) {
+		pr_err("arch_timer: cant map timer base\n");
+		return -ENOMEM;
+	}
+
+	if (of_get_property(np, "irq-is-not-percpu", NULL))
+		is_irq_percpu = 0;
+	else
+		is_irq_percpu = 1;
+
 	arch_timer_ppi = ret;
 	ret = irq_of_parse_and_map(np, 1);
 	if (ret > 0)
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index f316f36..5cc9471 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -288,7 +288,7 @@
 obj-$(CONFIG_ARCH_MSM9615) += clock-local.o clock-9615.o acpuclock-9615.o clock-rpm.o clock-pll.o
 obj-$(CONFIG_ARCH_MSMCOPPER) += board-copper.o board-dt.o board-copper-regulator.o board-copper-gpiomux.o
 obj-$(CONFIG_ARCH_MSMCOPPER) += acpuclock-krait.o acpuclock-copper.o
-obj-$(CONFIG_ARCH_MSMCOPPER) += clock-local2.o clock-pll.o clock-copper.o
+obj-$(CONFIG_ARCH_MSMCOPPER) += clock-local2.o clock-pll.o clock-copper.o clock-rpm.o clock-voter.o
 obj-$(CONFIG_ARCH_MSMCOPPER) += gdsc.o
 obj-$(CONFIG_ARCH_MSM9625) += board-9625.o board-9625-gpiomux.o
 
diff --git a/arch/arm/mach-msm/board-8064-display.c b/arch/arm/mach-msm/board-8064-display.c
index 71ad49a..7368f6e 100644
--- a/arch/arm/mach-msm/board-8064-display.c
+++ b/arch/arm/mach-msm/board-8064-display.c
@@ -58,11 +58,15 @@
 };
 
 #define LVDS_CHIMEI_PANEL_NAME "lvds_chimei_wxga"
+#define LVDS_FRC_PANEL_NAME "lvds_frc_fhd"
 #define MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME "mipi_video_toshiba_wsvga"
 #define MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME "mipi_video_chimei_wxga"
 #define HDMI_PANEL_NAME "hdmi_msm"
 #define TVOUT_PANEL_NAME "tvout_msm"
 
+#define LVDS_PIXEL_MAP_PATTERN_1	1
+#define LVDS_PIXEL_MAP_PATTERN_2	2
+
 #ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
 static unsigned char hdmi_is_primary = 1;
 #else
@@ -98,12 +102,18 @@
 			strnlen(MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME,
 				PANEL_NAME_MAX_LEN)))
 			return 0;
-	} else if (machine_is_apq8064_cdp() ||
-		       machine_is_mpq8064_dtv()) {
+	} else if (machine_is_apq8064_cdp()) {
 		if (!strncmp(name, LVDS_CHIMEI_PANEL_NAME,
 			strnlen(LVDS_CHIMEI_PANEL_NAME,
 				PANEL_NAME_MAX_LEN)))
 			return 0;
+	} else if (machine_is_mpq8064_dtv()) {
+		if (!strncmp(name, LVDS_FRC_PANEL_NAME,
+			strnlen(LVDS_FRC_PANEL_NAME,
+			PANEL_NAME_MAX_LEN))) {
+			set_mdp_clocks_for_wuxga();
+			return 0;
+		}
 	}
 
 	if (!strncmp(name, HDMI_PANEL_NAME,
@@ -599,7 +609,9 @@
 		u32 ver = socinfo_get_version();
 		if ((SOCINFO_VERSION_MAJOR(ver) == 1) &&
 		    (SOCINFO_VERSION_MINOR(ver) == 0))
-			return 1;
+			return LVDS_PIXEL_MAP_PATTERN_1;
+	} else if (machine_is_mpq8064_dtv()) {
+		return LVDS_PIXEL_MAP_PATTERN_2;
 	}
 	return 0;
 }
@@ -624,6 +636,23 @@
 	}
 };
 
+#define FRC_GPIO_UPDATE	(SX150X_EXP4_GPIO_BASE + 8)
+#define FRC_GPIO_RESET	(SX150X_EXP4_GPIO_BASE + 9)
+#define FRC_GPIO_PWR	(SX150X_EXP4_GPIO_BASE + 10)
+
+static int lvds_frc_gpio[] = {FRC_GPIO_UPDATE, FRC_GPIO_RESET, FRC_GPIO_PWR};
+static struct lvds_panel_platform_data lvds_frc_pdata = {
+	.gpio = lvds_frc_gpio,
+};
+
+static struct platform_device lvds_frc_panel_device = {
+	.name = "lvds_frc_fhd",
+	.id = 0,
+	.dev = {
+		.platform_data = &lvds_frc_pdata,
+	}
+};
+
 static int dsi2lvds_gpio[2] = {
 	LPM_CHANNEL,/* Backlight PWM-ID=0 for PMIC-GPIO#24 */
 	0x1F08 /* DSI2LVDS Bridge GPIO Output, mask=0x1f, out=0x08 */
@@ -921,6 +950,8 @@
 		platform_device_register(&mipi_dsi2lvds_bridge_device);
 	if (machine_is_apq8064_mtp())
 		platform_device_register(&mipi_dsi_toshiba_panel_device);
+	if (machine_is_mpq8064_dtv())
+		platform_device_register(&lvds_frc_panel_device);
 
 	msm_fb_register_device("mdp", &mdp_pdata);
 	msm_fb_register_device("lvds", &lvds_pdata);
diff --git a/arch/arm/mach-msm/board-8064-storage.c b/arch/arm/mach-msm/board-8064-storage.c
index 5f74468..fe4beab 100644
--- a/arch/arm/mach-msm/board-8064-storage.c
+++ b/arch/arm/mach-msm/board-8064-storage.c
@@ -247,7 +247,6 @@
 #endif
 	.sup_clk_table	= sdc1_sup_clk_rates,
 	.sup_clk_cnt	= ARRAY_SIZE(sdc1_sup_clk_rates),
-	.pclk_src_dfab	= 1,
 	.nonremovable	= 1,
 	.pin_data	= &mmc_slot_pin_data[SDCC1],
 	.vreg_data	= &mmc_slot_vreg_data[SDCC1],
@@ -270,7 +269,6 @@
 	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
 	.sup_clk_table	= sdc2_sup_clk_rates,
 	.sup_clk_cnt	= ARRAY_SIZE(sdc2_sup_clk_rates),
-	.pclk_src_dfab	= 1,
 	.pin_data	= &mmc_slot_pin_data[SDCC2],
 	.sdiowakeup_irq = MSM_GPIO_TO_INT(61),
 	.msm_bus_voting_data = &sps_to_ddr_bus_voting_data,
@@ -290,7 +288,6 @@
 	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
 	.sup_clk_table	= sdc3_sup_clk_rates,
 	.sup_clk_cnt	= ARRAY_SIZE(sdc3_sup_clk_rates),
-	.pclk_src_dfab	= 1,
 	.pin_data	= &mmc_slot_pin_data[SDCC3],
 	.vreg_data	= &mmc_slot_vreg_data[SDCC3],
 	.wpswitch_gpio	= PM8921_GPIO_PM_TO_SYS(17),
@@ -322,7 +319,6 @@
 	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
 	.sup_clk_table	= sdc4_sup_clk_rates,
 	.sup_clk_cnt	= ARRAY_SIZE(sdc4_sup_clk_rates),
-	.pclk_src_dfab	= 1,
 	.pin_data	= &mmc_slot_pin_data[SDCC4],
 	.sdiowakeup_irq = MSM_GPIO_TO_INT(65),
 	.msm_bus_voting_data = &sps_to_ddr_bus_voting_data,
diff --git a/arch/arm/mach-msm/board-8930-gpu.c b/arch/arm/mach-msm/board-8930-gpu.c
index e23b76c..3c3843a 100644
--- a/arch/arm/mach-msm/board-8930-gpu.c
+++ b/arch/arm/mach-msm/board-8930-gpu.c
@@ -115,7 +115,7 @@
 static struct kgsl_device_platform_data kgsl_3d0_pdata = {
 	.pwrlevel = {
 		{
-			.gpu_freq = 400000000,
+			.gpu_freq = 450000000,
 			.bus_freq = 3,
 			.io_fraction = 0,
 		},
diff --git a/arch/arm/mach-msm/board-8930-storage.c b/arch/arm/mach-msm/board-8930-storage.c
index bb35c95..65da578 100644
--- a/arch/arm/mach-msm/board-8930-storage.c
+++ b/arch/arm/mach-msm/board-8930-storage.c
@@ -239,7 +239,6 @@
 #endif
 	.sup_clk_table	= sdc1_sup_clk_rates,
 	.sup_clk_cnt	= ARRAY_SIZE(sdc1_sup_clk_rates),
-	.pclk_src_dfab	= 1,
 	.nonremovable	= 1,
 	.vreg_data	= &mmc_slot_vreg_data[SDCC1],
 	.pin_data	= &mmc_slot_pin_data[SDCC1],
@@ -254,7 +253,6 @@
 	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
 	.sup_clk_table	= sdc3_sup_clk_rates,
 	.sup_clk_cnt	= ARRAY_SIZE(sdc3_sup_clk_rates),
-	.pclk_src_dfab	= 1,
 #ifdef CONFIG_MMC_MSM_SDC3_WP_SUPPORT
 /*TODO: Insert right replacement for PM8038 */
 #ifndef MSM8930_PHASE_2
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 712b520..338cb84 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -1202,6 +1202,7 @@
 	[23] = MSM_GPIO_TO_INT(85),
 	[24] = MSM_GPIO_TO_INT(83),
 	[25] = USB1_HS_IRQ,
+	[26] = MSM_GPIO_TO_INT(6),
 	[27] = HDMI_IRQ,
 	[29] = MSM_GPIO_TO_INT(10),
 	[30] = MSM_GPIO_TO_INT(102),
@@ -1215,15 +1216,15 @@
 	[38] = MSM_GPIO_TO_INT(50),
 	[39] = MSM_GPIO_TO_INT(42),
 	[41] = MSM_GPIO_TO_INT(62),
-	[42] = MSM_GPIO_TO_INT(76),
-	[43] = MSM_GPIO_TO_INT(75),
+	[42] = MSM_GPIO_TO_INT(8),
+	[43] = MSM_GPIO_TO_INT(33),
 	[44] = MSM_GPIO_TO_INT(70),
 	[45] = MSM_GPIO_TO_INT(69),
 	[46] = MSM_GPIO_TO_INT(67),
 	[47] = MSM_GPIO_TO_INT(65),
-	[48] = MSM_GPIO_TO_INT(58),
-	[49] = MSM_GPIO_TO_INT(54),
-	[50] = MSM_GPIO_TO_INT(52),
+	[48] = MSM_GPIO_TO_INT(55),
+	[49] = MSM_GPIO_TO_INT(74),
+	[50] = MSM_GPIO_TO_INT(98),
 	[51] = MSM_GPIO_TO_INT(49),
 	[52] = MSM_GPIO_TO_INT(40),
 	[53] = MSM_GPIO_TO_INT(37),
diff --git a/arch/arm/mach-msm/board-8960-storage.c b/arch/arm/mach-msm/board-8960-storage.c
index 85785fc..e674e91 100644
--- a/arch/arm/mach-msm/board-8960-storage.c
+++ b/arch/arm/mach-msm/board-8960-storage.c
@@ -290,7 +290,6 @@
 #endif
 	.sup_clk_table	= sdc1_sup_clk_rates,
 	.sup_clk_cnt	= ARRAY_SIZE(sdc1_sup_clk_rates),
-	.pclk_src_dfab	= 1,
 	.nonremovable	= 1,
 	.vreg_data	= &mmc_slot_vreg_data[SDCC1],
 	.pin_data	= &mmc_slot_pin_data[SDCC1],
@@ -309,7 +308,6 @@
 	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
 	.sup_clk_table  = sdc2_sup_clk_rates,
 	.sup_clk_cnt    = ARRAY_SIZE(sdc2_sup_clk_rates),
-	.pclk_src_dfab  = 1,
 	.vreg_data      = &mmc_slot_vreg_data[SDCC2],
 	.pin_data       = &mmc_slot_pin_data[SDCC2],
 	.sdiowakeup_irq = MSM_GPIO_TO_INT(90),
@@ -323,7 +321,6 @@
 	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
 	.sup_clk_table	= sdc3_sup_clk_rates,
 	.sup_clk_cnt	= ARRAY_SIZE(sdc3_sup_clk_rates),
-	.pclk_src_dfab	= 1,
 #ifdef CONFIG_MMC_MSM_SDC3_WP_SUPPORT
 	.wpswitch_gpio	= PM8921_GPIO_PM_TO_SYS(16),
 #endif
@@ -354,7 +351,6 @@
 	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
 	.sup_clk_table  = sdc4_sup_clk_rates,
 	.sup_clk_cnt    = ARRAY_SIZE(sdc4_sup_clk_rates),
-	.pclk_src_dfab  = 1,
 	.vreg_data      = &mmc_slot_vreg_data[SDCC4],
 	.pin_data       = &mmc_slot_pin_data[SDCC4],
 	.sdiowakeup_irq = MSM_GPIO_TO_INT(85),
diff --git a/arch/arm/mach-msm/board-9615-storage.c b/arch/arm/mach-msm/board-9615-storage.c
index 51e2432..2025bd0 100644
--- a/arch/arm/mach-msm/board-9615-storage.c
+++ b/arch/arm/mach-msm/board-9615-storage.c
@@ -176,7 +176,6 @@
 	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
 	.sup_clk_table	= sdc1_sup_clk_rates,
 	.sup_clk_cnt	= ARRAY_SIZE(sdc1_sup_clk_rates),
-	.pclk_src_dfab	= true,
 	.vreg_data	= &mmc_slot_vreg_data[SDCC1],
 	.pin_data	= &mmc_slot_pin_data[SDCC1],
 #ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
@@ -205,7 +204,6 @@
 	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
 	.sup_clk_table	= sdc2_sup_clk_rates,
 	.sup_clk_cnt	= ARRAY_SIZE(sdc2_sup_clk_rates),
-	.pclk_src_dfab	= 1,
 	.pin_data	= &mmc_slot_pin_data[SDCC2],
 	.sdiowakeup_irq = MSM_GPIO_TO_INT(GPIO_SDC2_DAT1_WAKEUP),
 	.msm_bus_voting_data = &sps_to_ddr_bus_voting_data,
diff --git a/arch/arm/mach-msm/board-copper.c b/arch/arm/mach-msm/board-copper.c
index 2afefa6..f83b403 100644
--- a/arch/arm/mach-msm/board-copper.c
+++ b/arch/arm/mach-msm/board-copper.c
@@ -421,33 +421,6 @@
 	platform_device_register(&copper_device_tz_log);
 }
 
-/*
- * Used to satisfy dependencies for devices that need to be
- * run early or in a particular order. Most likely your device doesn't fall
- * into this category, and thus the driver should not be added here. The
- * EPROBE_DEFER can satisfy most dependency problems.
- */
-void __init msm_copper_add_drivers(void)
-{
-	msm_smd_init();
-	msm_rpm_driver_init();
-	rpm_regulator_smd_driver_init();
-	msm_spm_device_init();
-	regulator_stub_init();
-}
-
-static struct of_device_id irq_match[] __initdata  = {
-	{ .compatible = "qcom,msm-qgic2", .data = gic_of_init, },
-	{ .compatible = "qcom,msm-gpio", .data = msm_gpio_of_init, },
-	{ .compatible = "qcom,spmi-pmic-arb", .data = qpnpint_of_init, },
-	{}
-};
-
-void __init msm_copper_init_irq(void)
-{
-	of_irq_init(irq_match);
-}
-
 static struct clk_lookup msm_clocks_dummy[] = {
 	CLK_DUMMY("xo",		XO_CLK,		NULL,	OFF),
 	CLK_DUMMY("xo",		XO_CLK,		"pil_pronto",		OFF),
@@ -476,6 +449,37 @@
 	.size = ARRAY_SIZE(msm_clocks_dummy),
 };
 
+/*
+ * Used to satisfy dependencies for devices that need to be
+ * run early or in a particular order. Most likely your device doesn't fall
+ * into this category, and thus the driver should not be added here. The
+ * EPROBE_DEFER can satisfy most dependency problems.
+ */
+void __init msm_copper_add_drivers(void)
+{
+	msm_smd_init();
+	msm_rpm_driver_init();
+	rpm_regulator_smd_driver_init();
+	msm_spm_device_init();
+	regulator_stub_init();
+	if (machine_is_copper_rumi())
+		msm_clock_init(&msm_dummy_clock_init_data);
+	else
+		msm_clock_init(&msmcopper_clock_init_data);
+}
+
+static struct of_device_id irq_match[] __initdata  = {
+	{ .compatible = "qcom,msm-qgic2", .data = gic_of_init, },
+	{ .compatible = "qcom,msm-gpio", .data = msm_gpio_of_init, },
+	{ .compatible = "qcom,spmi-pmic-arb", .data = qpnpint_of_init, },
+	{}
+};
+
+void __init msm_copper_init_irq(void)
+{
+	of_irq_init(irq_match);
+}
+
 static struct of_dev_auxdata msm_copper_auxdata_lookup[] __initdata = {
 	OF_DEV_AUXDATA("qcom,msm-lsuart-v14", 0xF991F000, \
 			"msm_serial_hsl.0", NULL),
@@ -510,11 +514,6 @@
 {
 	msm_copper_init_gpiomux();
 
-	if (machine_is_copper_rumi())
-		msm_clock_init(&msm_dummy_clock_init_data);
-	else
-		msm_clock_init(&msmcopper_clock_init_data);
-
 	*adata = msm_copper_auxdata_lookup;
 
 	regulator_has_full_constraints();
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 73a900c..3488fb3 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -8389,7 +8389,6 @@
 	.msmsdcc_fmid	= 24000000,
 	.msmsdcc_fmax	= 48000000,
 	.nonremovable	= 1,
-	.pclk_src_dfab	= 1,
 	.msm_bus_voting_data = &sps_to_ddr_bus_voting_data,
 };
 #endif
@@ -8404,7 +8403,6 @@
 	.msmsdcc_fmid	= 24000000,
 	.msmsdcc_fmax	= 48000000,
 	.nonremovable	= 0,
-	.pclk_src_dfab  = 1,
 	.register_status_notify = sdc2_register_status_notify,
 #ifdef CONFIG_MSM_SDIO_AL
 	.is_sdio_al_client = 1,
@@ -8429,7 +8427,6 @@
 	.msmsdcc_fmid	= 24000000,
 	.msmsdcc_fmax	= 48000000,
 	.nonremovable	= 0,
-	.pclk_src_dfab  = 1,
 	.mpm_sdiowakeup_int = MSM_MPM_PIN_SDC3_DAT1,
 	.msm_bus_voting_data = &sps_to_ddr_bus_voting_data,
 };
@@ -8444,7 +8441,6 @@
 	.msmsdcc_fmid	= 24000000,
 	.msmsdcc_fmax	= 48000000,
 	.nonremovable	= 0,
-	.pclk_src_dfab  = 1,
 	.mpm_sdiowakeup_int = MSM_MPM_PIN_SDC4_DAT1,
 	.msm_bus_voting_data = &sps_to_ddr_bus_voting_data,
 };
@@ -8460,7 +8456,6 @@
 	.msmsdcc_fmid	= 24000000,
 	.msmsdcc_fmax	= 48000000,
 	.nonremovable	= 0,
-	.pclk_src_dfab  = 1,
 	.register_status_notify = sdc5_register_status_notify,
 #ifdef CONFIG_MSM_SDIO_AL
 	.is_sdio_al_client = 1,
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index c4ada1e..aca2a3b 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -934,6 +934,7 @@
 	.c = {
 		.dbg_name = "gfx2d0_p_clk",
 		.ops = &clk_ops_branch,
+		.flags = CLKFLAG_SKIP_HANDOFF,
 		CLK_INIT(gfx2d0_p_clk.c),
 	},
 };
@@ -952,6 +953,7 @@
 	.c = {
 		.dbg_name = "gfx2d1_p_clk",
 		.ops = &clk_ops_branch,
+		.flags = CLKFLAG_SKIP_HANDOFF,
 		CLK_INIT(gfx2d1_p_clk.c),
 	},
 };
@@ -3346,6 +3348,7 @@
 	.c = {
 		.dbg_name = "gfx2d0_clk",
 		.ops = &clk_ops_rcg,
+		.flags = CLKFLAG_SKIP_HANDOFF,
 		VDD_DIG_FMAX_MAP3(LOW,  100000000, NOMINAL, 200000000,
 				  HIGH, 228571000),
 		CLK_INIT(gfx2d0_clk.c),
@@ -3390,6 +3393,7 @@
 	.c = {
 		.dbg_name = "gfx2d1_clk",
 		.ops = &clk_ops_rcg,
+		.flags = CLKFLAG_SKIP_HANDOFF,
 		VDD_DIG_FMAX_MAP3(LOW,  100000000, NOMINAL, 200000000,
 				  HIGH, 228571000),
 		CLK_INIT(gfx2d1_clk.c),
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index 975587d..74d71a2 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -700,6 +700,7 @@
 	.c = {
 		.dbg_name = "gfx2d0_p_clk",
 		.ops = &clk_ops_branch,
+		.flags = CLKFLAG_SKIP_HANDOFF,
 		CLK_INIT(gfx2d0_p_clk.c),
 	},
 };
@@ -716,6 +717,7 @@
 	.c = {
 		.dbg_name = "gfx2d1_p_clk",
 		.ops = &clk_ops_branch,
+		.flags = CLKFLAG_SKIP_HANDOFF,
 		CLK_INIT(gfx2d1_p_clk.c),
 	},
 };
@@ -2178,6 +2180,7 @@
 	.c = {
 		.dbg_name = "gfx2d0_clk",
 		.ops = &clk_ops_rcg,
+		.flags = CLKFLAG_SKIP_HANDOFF,
 		VDD_DIG_FMAX_MAP3(LOW,  100000000, NOMINAL, 200000000,
 				  HIGH, 228571000),
 		CLK_INIT(gfx2d0_clk.c),
@@ -2222,6 +2225,7 @@
 	.c = {
 		.dbg_name = "gfx2d1_clk",
 		.ops = &clk_ops_rcg,
+		.flags = CLKFLAG_SKIP_HANDOFF,
 		VDD_DIG_FMAX_MAP3(LOW,  100000000, NOMINAL, 200000000,
 				  HIGH, 228571000),
 		CLK_INIT(gfx2d1_clk.c),
diff --git a/arch/arm/mach-msm/clock-copper.c b/arch/arm/mach-msm/clock-copper.c
index 778301b..72424f2 100644
--- a/arch/arm/mach-msm/clock-copper.c
+++ b/arch/arm/mach-msm/clock-copper.c
@@ -23,6 +23,8 @@
 
 #include "clock-local2.h"
 #include "clock-pll.h"
+#include "clock-rpm.h"
+#include "clock-voter.h"
 
 enum {
 	GCC_BASE,
@@ -713,6 +715,37 @@
 	},
 };
 
+#define RPM_BUS_CLK_TYPE  0x316b6c63
+#define RPM_MEM_CLK_TYPE  0x326b6c63
+
+#define PNOC_ID		0x0
+#define SNOC_ID		0x1
+#define CNOC_ID		0x2
+
+#define BIMC_ID		0x0
+#define OCMEM_ID	0x1
+
+DEFINE_CLK_RPM_SMD(pnoc_clk, pnoc_a_clk, RPM_BUS_CLK_TYPE, PNOC_ID, NULL);
+DEFINE_CLK_RPM_SMD(snoc_clk, snoc_a_clk, RPM_BUS_CLK_TYPE, SNOC_ID, NULL);
+DEFINE_CLK_RPM_SMD(cnoc_clk, cnoc_a_clk, RPM_BUS_CLK_TYPE, CNOC_ID, NULL);
+
+DEFINE_CLK_RPM_SMD(bimc_clk, bimc_a_clk, RPM_MEM_CLK_TYPE, BIMC_ID, NULL);
+DEFINE_CLK_RPM_SMD(ocmemgx_clk, ocmemgx_a_clk, RPM_MEM_CLK_TYPE, OCMEM_ID,
+			NULL);
+
+static DEFINE_CLK_VOTER(pnoc_msmbus_clk, &pnoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(snoc_msmbus_clk, &snoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(cnoc_msmbus_clk, &cnoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(pnoc_msmbus_a_clk, &pnoc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(snoc_msmbus_a_clk, &snoc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(cnoc_msmbus_a_clk, &cnoc_a_clk.c, LONG_MAX);
+
+static DEFINE_CLK_VOTER(bimc_msmbus_clk, &bimc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(bimc_msmbus_a_clk, &bimc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(bimc_acpu_a_clk, &bimc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(ocmemgx_msmbus_clk, &ocmemgx_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(ocmemgx_msmbus_a_clk, &ocmemgx_a_clk.c, LONG_MAX);
+
 static struct clk_freq_tbl ftbl_gcc_usb30_master_clk[] = {
 	F(125000000,  gpll0,   1,   5,  24),
 	F_END
@@ -2199,28 +2232,6 @@
 	},
 };
 
-static struct clk_freq_tbl ftbl_mmss_ahb_clk[] = {
-	F_MM(19200000,    cxo,   1,   0,   0),
-	F_MM(40000000,  gpll0,  15,   0,   0),
-	F_MM(80000000, mmpll0,  10,   0,   0),
-	F_END,
-};
-
-/* TODO: This may go away (may be controlled by the RPM). */
-static struct rcg_clk ahb_clk_src = {
-	.cmd_rcgr_reg = 0x5000,
-	.set_rate = set_rate_hid,
-	.freq_tbl = ftbl_mmss_ahb_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "ahb_clk_src",
-		.ops = &clk_ops_rcg,
-		VDD_DIG_FMAX_MAP2(LOW, 40000000, NOMINAL, 80000000),
-		CLK_INIT(ahb_clk_src.c),
-	},
-};
-
 static struct clk_freq_tbl ftbl_mmss_axi_clk[] = {
 	F_MM( 19200000,    cxo,   1,   0,   0),
 	F_MM(150000000,  gpll0,   4,   0,   0),
@@ -2244,6 +2255,29 @@
 	},
 };
 
+static struct clk_freq_tbl ftbl_ocmemnoc_clk[] = {
+	F_MM( 19200000,    cxo,   1,   0,   0),
+	F_MM(150000000,  gpll0,   4,   0,   0),
+	F_MM(333330000, mmpll1,   3,   0,   0),
+	F_MM(400000000, mmpll0,   2,   0,   0),
+	F_END
+};
+
+struct rcg_clk ocmemnoc_clk_src = {
+	.cmd_rcgr_reg = OCMEMNOC_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_ocmemnoc_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "ocmemnoc_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP3(LOW, 150000000, NOMINAL, 333330000,
+				  HIGH, 400000000),
+		CLK_INIT(ocmemnoc_clk_src.c),
+	},
+};
+
 static struct clk_freq_tbl ftbl_camss_csi0_3_clk[] = {
 	F_MM(100000000,  gpll0,   6,   0,   0),
 	F_MM(200000000, mmpll0,   4,   0,   0),
@@ -2869,7 +2903,6 @@
 
 static struct branch_clk camss_cci_cci_ahb_clk = {
 	.cbcr_reg = CAMSS_CCI_CCI_AHB_CBCR,
-	.parent = &ahb_clk_src.c,
 	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
@@ -2893,7 +2926,6 @@
 
 static struct branch_clk camss_csi0_ahb_clk = {
 	.cbcr_reg = CAMSS_CSI0_AHB_CBCR,
-	.parent = &ahb_clk_src.c,
 	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
@@ -2953,7 +2985,6 @@
 
 static struct branch_clk camss_csi1_ahb_clk = {
 	.cbcr_reg = CAMSS_CSI1_AHB_CBCR,
-	.parent = &ahb_clk_src.c,
 	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
@@ -3013,7 +3044,6 @@
 
 static struct branch_clk camss_csi2_ahb_clk = {
 	.cbcr_reg = CAMSS_CSI2_AHB_CBCR,
-	.parent = &ahb_clk_src.c,
 	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
@@ -3073,7 +3103,6 @@
 
 static struct branch_clk camss_csi3_ahb_clk = {
 	.cbcr_reg = CAMSS_CSI3_AHB_CBCR,
-	.parent = &ahb_clk_src.c,
 	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
@@ -3181,7 +3210,6 @@
 
 static struct branch_clk camss_ispif_ahb_clk = {
 	.cbcr_reg = CAMSS_ISPIF_AHB_CBCR,
-	.parent = &ahb_clk_src.c,
 	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
@@ -3229,7 +3257,6 @@
 
 static struct branch_clk camss_jpeg_jpeg_ahb_clk = {
 	.cbcr_reg = CAMSS_JPEG_JPEG_AHB_CBCR,
-	.parent = &ahb_clk_src.c,
 	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
@@ -3253,6 +3280,7 @@
 
 static struct branch_clk camss_jpeg_jpeg_ocmemnoc_clk = {
 	.cbcr_reg = CAMSS_JPEG_JPEG_OCMEMNOC_CBCR,
+	.parent = &ocmemnoc_clk_src.c,
 	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
@@ -3312,7 +3340,6 @@
 
 static struct branch_clk camss_micro_ahb_clk = {
 	.cbcr_reg = CAMSS_MICRO_AHB_CBCR,
-	.parent = &ahb_clk_src.c,
 	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
@@ -3360,7 +3387,6 @@
 
 static struct branch_clk camss_top_ahb_clk = {
 	.cbcr_reg = CAMSS_TOP_AHB_CBCR,
-	.parent = &ahb_clk_src.c,
 	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
@@ -3372,7 +3398,6 @@
 
 static struct branch_clk camss_vfe_cpp_ahb_clk = {
 	.cbcr_reg = CAMSS_VFE_CPP_AHB_CBCR,
-	.parent = &ahb_clk_src.c,
 	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
@@ -3420,7 +3445,6 @@
 
 static struct branch_clk camss_vfe_vfe_ahb_clk = {
 	.cbcr_reg = CAMSS_VFE_VFE_AHB_CBCR,
-	.parent = &ahb_clk_src.c,
 	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
@@ -3444,6 +3468,7 @@
 
 static struct branch_clk camss_vfe_vfe_ocmemnoc_clk = {
 	.cbcr_reg = CAMSS_VFE_VFE_OCMEMNOC_CBCR,
+	.parent = &ocmemnoc_clk_src.c,
 	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
@@ -3455,7 +3480,6 @@
 
 static struct branch_clk mdss_ahb_clk = {
 	.cbcr_reg = MDSS_AHB_CBCR,
-	.parent = &ahb_clk_src.c,
 	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
@@ -3575,7 +3599,6 @@
 
 static struct branch_clk mdss_hdmi_ahb_clk = {
 	.cbcr_reg = MDSS_HDMI_AHB_CBCR,
-	.parent = &ahb_clk_src.c,
 	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
@@ -3659,7 +3682,6 @@
 
 static struct branch_clk mmss_misc_ahb_clk = {
 	.cbcr_reg = MMSS_MISC_AHB_CBCR,
-	.parent = &ahb_clk_src.c,
 	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
@@ -3671,7 +3693,6 @@
 
 static struct branch_clk mmss_mmssnoc_ahb_clk = {
 	.cbcr_reg = MMSS_MMSSNOC_AHB_CBCR,
-	.parent = &ahb_clk_src.c,
 	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
@@ -3683,7 +3704,6 @@
 
 static struct branch_clk mmss_mmssnoc_bto_ahb_clk = {
 	.cbcr_reg = MMSS_MMSSNOC_BTO_AHB_CBCR,
-	.parent = &ahb_clk_src.c,
 	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
@@ -3717,9 +3737,21 @@
 	},
 };
 
+struct branch_clk ocmemnoc_clk = {
+	.cbcr_reg = OCMEMNOC_CBCR,
+	.parent = &ocmemnoc_clk_src.c,
+	.has_sibling = 0,
+	.bcr_reg = 0x50b0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "ocmemnoc_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(ocmemnoc_clk.c),
+	},
+};
+
 static struct branch_clk venus0_ahb_clk = {
 	.cbcr_reg = VENUS0_AHB_CBCR,
-	.parent = &ahb_clk_src.c,
 	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
@@ -3743,6 +3775,7 @@
 
 static struct branch_clk venus0_ocmemnoc_clk = {
 	.cbcr_reg = VENUS0_OCMEMNOC_CBCR,
+	.parent = &ocmemnoc_clk_src.c,
 	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
@@ -3777,7 +3810,6 @@
 
 static struct branch_clk oxilicx_ahb_clk = {
 	.cbcr_reg = OXILICX_AHB_CBCR,
-	.parent = &ahb_clk_src.c,
 	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
@@ -4310,6 +4342,7 @@
 	{&gcc_usb_hsic_system_clk.c,		GCC_BASE, 0x0061},
 	{&mmss_mmssnoc_ahb_clk.c,		MMSS_BASE, 0x0001},
 	{&mmss_mmssnoc_axi_clk.c,		MMSS_BASE, 0x0004},
+	{&ocmemnoc_clk.c,			MMSS_BASE, 0x0007},
 	{&camss_cci_cci_ahb_clk.c,		MMSS_BASE, 0x002e},
 	{&camss_cci_cci_clk.c,			MMSS_BASE, 0x002d},
 	{&camss_csi0_ahb_clk.c,			MMSS_BASE, 0x0042},
@@ -4663,7 +4696,6 @@
 
 	/* Multimedia clocks */
 	CLK_LOOKUP("bus_clk_src", axi_clk_src.c, ""),
-	CLK_LOOKUP("bus_clk_src", ahb_clk_src.c, ""),
 	CLK_LOOKUP("bus_clk", mmss_mmssnoc_ahb_clk.c, ""),
 	CLK_LOOKUP("bus_clk", mmss_mmssnoc_axi_clk.c, ""),
 	CLK_LOOKUP("core_clk", mdss_edpaux_clk.c, ""),
@@ -4787,6 +4819,33 @@
 	CLK_DUMMY("dfab_clk",  DFAB_CLK,    "msm_sps", OFF),
 	CLK_DUMMY("mem_clk",       NULL,    "msm_sps", OFF),
 	CLK_DUMMY("bus_clk",       NULL,        "scm", OFF),
+
+	CLK_LOOKUP("bus_clk", snoc_clk.c, ""),
+	CLK_LOOKUP("bus_clk", pnoc_clk.c, ""),
+	CLK_LOOKUP("bus_clk", cnoc_clk.c, ""),
+	CLK_LOOKUP("mem_clk", bimc_clk.c, ""),
+	CLK_LOOKUP("mem_clk", ocmemgx_clk.c, ""),
+	CLK_LOOKUP("bus_clk", snoc_a_clk.c, ""),
+	CLK_LOOKUP("bus_clk", pnoc_a_clk.c, ""),
+	CLK_LOOKUP("bus_clk", cnoc_a_clk.c, ""),
+	CLK_LOOKUP("mem_clk", bimc_a_clk.c, ""),
+	CLK_LOOKUP("mem_clk", ocmemgx_a_clk.c, ""),
+
+	CLK_LOOKUP("bus_clk",	cnoc_msmbus_clk.c,	"msm_config_noc"),
+	CLK_LOOKUP("bus_a_clk",	cnoc_msmbus_a_clk.c,	"msm_config_noc"),
+	CLK_LOOKUP("bus_clk",	snoc_msmbus_clk.c,	"msm_sys_noc"),
+	CLK_LOOKUP("bus_a_clk",	snoc_msmbus_a_clk.c,	"msm_sys_noc"),
+	CLK_LOOKUP("bus_clk",	pnoc_msmbus_clk.c,	"msm_periph_noc"),
+	CLK_LOOKUP("bus_a_clk",	pnoc_msmbus_a_clk.c,	"msm_periph_noc"),
+	CLK_LOOKUP("mem_clk",	bimc_msmbus_clk.c,	"msm_bimc"),
+	CLK_LOOKUP("mem_a_clk",	bimc_msmbus_a_clk.c,	"msm_bimc"),
+	CLK_LOOKUP("mem_clk",	bimc_acpu_a_clk.c,	""),
+	CLK_LOOKUP("ocmem_clk",	ocmemgx_msmbus_clk.c,	  "msm_bus"),
+	CLK_LOOKUP("ocmem_a_clk", ocmemgx_msmbus_a_clk.c, "msm_bus"),
+	CLK_LOOKUP("bus_clk",	ocmemnoc_clk.c,		"msm_ocmem_noc"),
+	CLK_LOOKUP("bus_a_clk",	ocmemnoc_clk.c,		"msm_ocmem_noc"),
+	CLK_LOOKUP("bus_clk",	axi_clk_src.c,		"msm_mmss_noc"),
+	CLK_LOOKUP("bus_a_clk",	axi_clk_src.c,		"msm_mmss_noc"),
 };
 
 static struct pll_config_regs gpll0_regs __initdata = {
@@ -4981,7 +5040,6 @@
 
 static void __init msmcopper_clock_post_init(void)
 {
-	clk_set_rate(&ahb_clk_src.c, 80000000);
 	clk_set_rate(&axi_clk_src.c, 333330000);
 
 	/* Set rates for single-rate clocks. */
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index 02e103d..b5ae4ab 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -610,10 +610,8 @@
 	ns_val = readl_relaxed(clk->ns_reg) & ns_mask;
 	for (freq = clk->freq_tbl; freq->freq_hz != FREQ_END; freq++) {
 		if ((freq->ns_val & ns_mask) == ns_val &&
-		    (!freq->md_val || freq->md_val == md_val)) {
-			pr_info("%s rate=%d\n", clk->c.dbg_name, freq->freq_hz);
+		    (!freq->md_val || freq->md_val == md_val))
 			break;
-		}
 	}
 	if (freq->freq_hz == FREQ_END)
 		return HANDOFF_UNKNOWN_RATE;
diff --git a/arch/arm/mach-msm/clock-local2.c b/arch/arm/mach-msm/clock-local2.c
index c84cfb8..467d5d1 100644
--- a/arch/arm/mach-msm/clock-local2.c
+++ b/arch/arm/mach-msm/clock-local2.c
@@ -282,7 +282,6 @@
 			if (freq->d_val != d_regval)
 				continue;
 		}
-		pr_info("%s rate=%lu\n", rcg->c.dbg_name, freq->freq_hz);
 		break;
 	}
 
@@ -448,7 +447,6 @@
 	cbcr_regval = readl_relaxed(CBCR_REG(branch));
 	if ((cbcr_regval & CBCR_BRANCH_OFF_BIT))
 		return HANDOFF_DISABLED_CLK;
-	pr_info("%s enabled.\n", branch->c.dbg_name);
 
 	if (branch->parent) {
 		if (branch->parent->ops->handoff)
@@ -459,17 +457,12 @@
 }
 
 static int __branch_clk_reset(void __iomem *bcr_reg,
-				enum clk_reset_action action, const char *name)
+				enum clk_reset_action action)
 {
 	int ret = 0;
 	unsigned long flags;
 	u32 reg_val;
 
-	if (!bcr_reg) {
-		WARN("clk_reset called on an unsupported clock (%s)\n", name);
-		return -EPERM;
-	}
-
 	spin_lock_irqsave(&local_clock_reg_lock, flags);
 	reg_val = readl_relaxed(bcr_reg);
 	switch (action) {
@@ -494,7 +487,13 @@
 static int branch_clk_reset(struct clk *c, enum clk_reset_action action)
 {
 	struct branch_clk *branch = to_branch_clk(c);
-	return __branch_clk_reset(BCR_REG(branch), action, c->dbg_name);
+
+	if (!branch->bcr_reg) {
+		WARN("clk_reset called on an unsupported clock (%s)\n",
+			c->dbg_name);
+		return -EPERM;
+	}
+	return __branch_clk_reset(BCR_REG(branch), action);
 }
 
 /*
@@ -503,7 +502,13 @@
 static int local_vote_clk_reset(struct clk *c, enum clk_reset_action action)
 {
 	struct local_vote_clk *vclk = to_local_vote_clk(c);
-	return __branch_clk_reset(BCR_REG(vclk), action, c->dbg_name);
+
+	if (!vclk->bcr_reg) {
+		WARN("clk_reset called on an unsupported clock (%s)\n",
+			c->dbg_name);
+		return -EPERM;
+	}
+	return __branch_clk_reset(BCR_REG(vclk), action);
 }
 
 static int local_vote_clk_enable(struct clk *c)
@@ -546,7 +551,6 @@
 	vote_regval = readl_relaxed(VOTE_REG(vclk));
 	if (!(vote_regval & vclk->en_mask))
 		return HANDOFF_DISABLED_CLK;
-	pr_info("%s enabled.\n", vclk->c.dbg_name);
 
 	return HANDOFF_ENABLED_CLK;
 }
diff --git a/arch/arm/mach-msm/clock-rpm.c b/arch/arm/mach-msm/clock-rpm.c
index 4539828..e0707fc 100644
--- a/arch/arm/mach-msm/clock-rpm.c
+++ b/arch/arm/mach-msm/clock-rpm.c
@@ -18,13 +18,89 @@
 #include "clock.h"
 #include "clock-rpm.h"
 
+#define __clk_rpmrs_set_rate(r, value, ctx, noirq) \
+	((r)->rpmrs_data->set_rate_fn((r), (value), (ctx), (noirq)))
+
+#define clk_rpmrs_set_rate_sleep(r, value) \
+	    __clk_rpmrs_set_rate((r), (value), (r)->rpmrs_data->ctx_sleep_id, 0)
+
+#define clk_rpmrs_set_rate_sleep_noirq(r, value) \
+	    __clk_rpmrs_set_rate((r), (value), (r)->rpmrs_data->ctx_sleep_id, 1)
+
+#define clk_rpmrs_set_rate_active(r, value) \
+	   __clk_rpmrs_set_rate((r), (value), (r)->rpmrs_data->ctx_active_id, 0)
+
+#define clk_rpmrs_set_rate_active_noirq(r, value) \
+	   __clk_rpmrs_set_rate((r), (value), (r)->rpmrs_data->ctx_active_id, 1)
+
+static int clk_rpmrs_set_rate(struct rpm_clk *r, uint32_t value,
+			   uint32_t context, int noirq)
+{
+	struct msm_rpm_iv_pair iv = {
+		.id = r->rpm_clk_id,
+		.value = value,
+	};
+	if (noirq)
+		return msm_rpmrs_set_noirq(context, &iv, 1);
+	else
+		return msm_rpmrs_set(context, &iv, 1);
+}
+
+static int clk_rpmrs_get_rate(struct rpm_clk *r)
+{
+	int rc;
+	struct msm_rpm_iv_pair iv = { .id = r->rpm_status_id, };
+	rc = msm_rpm_get_status(&iv, 1);
+	return (rc < 0) ? rc : iv.value * 1000;
+}
+
+#define RPM_SMD_KEY_CLOCK_SET_RATE	0x007A484B
+
+static int clk_rpmrs_set_rate_smd(struct rpm_clk *r, uint32_t value,
+				uint32_t context, int noirq)
+{
+	struct msm_rpm_kvp kvp = {
+		.key = RPM_SMD_KEY_CLOCK_SET_RATE,
+		.data = (void *)&value,
+		.length = sizeof(value),
+	};
+
+	if (noirq)
+		return msm_rpm_send_message_noirq(context,
+				r->rpm_res_type, r->rpm_clk_id, &kvp, 1);
+	else
+		return msm_rpm_send_message(context, r->rpm_res_type,
+						r->rpm_clk_id, &kvp, 1);
+}
+
+struct clk_rpmrs_data {
+	int (*set_rate_fn)(struct rpm_clk *r, uint32_t value,
+				uint32_t context, int noirq);
+	int (*get_rate_fn)(struct rpm_clk *r);
+	int ctx_active_id;
+	int ctx_sleep_id;
+};
+
+struct clk_rpmrs_data clk_rpmrs_data = {
+	.set_rate_fn = clk_rpmrs_set_rate,
+	.get_rate_fn = clk_rpmrs_get_rate,
+	.ctx_active_id = MSM_RPM_CTX_SET_0,
+	.ctx_sleep_id = MSM_RPM_CTX_SET_SLEEP,
+};
+
+struct clk_rpmrs_data clk_rpmrs_data_smd = {
+	.set_rate_fn = clk_rpmrs_set_rate_smd,
+	.ctx_active_id = MSM_RPM_CTX_ACTIVE_SET,
+	.ctx_sleep_id = MSM_RPM_CTX_SLEEP_SET,
+};
+
 static DEFINE_SPINLOCK(rpm_clock_lock);
 
 static int rpm_clk_enable(struct clk *clk)
 {
 	unsigned long flags;
 	struct rpm_clk *r = to_rpm_clk(clk);
-	struct msm_rpm_iv_pair iv = { .id = r->rpm_clk_id };
+	uint32_t value;
 	int rc = 0;
 	unsigned long this_khz, this_sleep_khz;
 	unsigned long peer_khz = 0, peer_sleep_khz = 0;
@@ -45,21 +121,23 @@
 		peer_sleep_khz = peer->last_set_sleep_khz;
 	}
 
-	iv.value = max(this_khz, peer_khz);
+	value = max(this_khz, peer_khz);
 	if (r->branch)
-		iv.value = !!iv.value;
+		value = !!value;
 
-	rc = msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_0, &iv, 1);
+	rc = clk_rpmrs_set_rate_active_noirq(r, value);
 	if (rc)
 		goto out;
 
-	iv.value = max(this_sleep_khz, peer_sleep_khz);
+	value = max(this_sleep_khz, peer_sleep_khz);
 	if (r->branch)
-		iv.value = !!iv.value;
-	rc = msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_SLEEP, &iv, 1);
+		value = !!value;
+
+	rc = clk_rpmrs_set_rate_sleep_noirq(r, value);
 	if (rc) {
-		iv.value = peer_khz;
-		msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_0, &iv, 1);
+		/* Undo the active set vote and restore it to peer_khz */
+		value = peer_khz;
+		rc = clk_rpmrs_set_rate_active_noirq(r, value);
 	}
 
 out:
@@ -79,7 +157,7 @@
 	spin_lock_irqsave(&rpm_clock_lock, flags);
 
 	if (r->last_set_khz) {
-		struct msm_rpm_iv_pair iv = { .id = r->rpm_clk_id };
+		uint32_t value;
 		struct rpm_clk *peer = r->peer;
 		unsigned long peer_khz = 0, peer_sleep_khz = 0;
 		int rc;
@@ -90,13 +168,13 @@
 			peer_sleep_khz = peer->last_set_sleep_khz;
 		}
 
-		iv.value = r->branch ? !!peer_khz : peer_khz;
-		rc = msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_0, &iv, 1);
+		value = r->branch ? !!peer_khz : peer_khz;
+		rc = clk_rpmrs_set_rate_active_noirq(r, value);
 		if (rc)
 			goto out;
 
-		iv.value = r->branch ? !!peer_sleep_khz : peer_sleep_khz;
-		rc = msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_SLEEP, &iv, 1);
+		value = r->branch ? !!peer_sleep_khz : peer_sleep_khz;
+		rc = clk_rpmrs_set_rate_sleep_noirq(r, value);
 	}
 	r->enabled = false;
 out:
@@ -124,25 +202,23 @@
 		this_sleep_khz = this_khz;
 
 	if (r->enabled) {
-		struct msm_rpm_iv_pair iv;
+		uint32_t value;
 		struct rpm_clk *peer = r->peer;
 		unsigned long peer_khz = 0, peer_sleep_khz = 0;
 
-		iv.id = r->rpm_clk_id;
-
 		/* Take peer clock's rate into account only if it's enabled. */
 		if (peer->enabled) {
 			peer_khz = peer->last_set_khz;
 			peer_sleep_khz = peer->last_set_sleep_khz;
 		}
 
-		iv.value = max(this_khz, peer_khz);
-		rc = msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_0, &iv, 1);
+		value = max(this_khz, peer_khz);
+		rc = clk_rpmrs_set_rate_active_noirq(r, value);
 		if (rc)
 			goto out;
 
-		iv.value = max(this_sleep_khz, peer_sleep_khz);
-		rc = msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_SLEEP, &iv, 1);
+		value = max(this_sleep_khz, peer_sleep_khz);
+		rc = clk_rpmrs_set_rate_sleep_noirq(r, value);
 	}
 	if (!rc) {
 		r->last_set_khz = this_khz;
@@ -158,13 +234,10 @@
 static unsigned long rpm_clk_get_rate(struct clk *clk)
 {
 	struct rpm_clk *r = to_rpm_clk(clk);
-	struct msm_rpm_iv_pair iv = { r->rpm_status_id };
-	int rc;
-
-	rc  = msm_rpm_get_status(&iv, 1);
-	if (rc < 0)
-		return rc;
-	return iv.value * 1000;
+	if (r->rpmrs_data->get_rate_fn)
+		return r->rpmrs_data->get_rate_fn(r);
+	else
+		return 0;
 }
 
 static int rpm_clk_is_enabled(struct clk *clk)
@@ -183,6 +256,29 @@
 	return false;
 }
 
+static enum handoff rpm_clk_handoff(struct clk *clk)
+{
+	struct rpm_clk *r = to_rpm_clk(clk);
+	struct msm_rpm_iv_pair iv = { r->rpm_status_id };
+	int rc;
+
+	/*
+	 * Querying an RPM clock's status will return 0 unless the clock's
+	 * rate has previously been set through the RPM. When handing off,
+	 * assume these clocks are enabled (unless the RPM call fails) so
+	 * child clocks of these RPM clocks can still be handed off.
+	 */
+	rc  = msm_rpm_get_status(&iv, 1);
+	if (rc < 0)
+		return HANDOFF_DISABLED_CLK;
+
+	r->last_set_khz = iv.value;
+	r->last_set_sleep_khz = iv.value;
+	clk->rate = iv.value * 1000;
+
+	return HANDOFF_ENABLED_CLK;
+}
+
 struct clk_ops clk_ops_rpm = {
 	.enable = rpm_clk_enable,
 	.disable = rpm_clk_disable,
@@ -191,10 +287,12 @@
 	.is_enabled = rpm_clk_is_enabled,
 	.round_rate = rpm_clk_round_rate,
 	.is_local = rpm_clk_is_local,
+	.handoff = rpm_clk_handoff,
 };
 
 struct clk_ops clk_ops_rpm_branch = {
 	.enable = rpm_clk_enable,
 	.disable = rpm_clk_disable,
 	.is_local = rpm_clk_is_local,
+	.handoff = rpm_clk_handoff,
 };
diff --git a/arch/arm/mach-msm/clock-rpm.h b/arch/arm/mach-msm/clock-rpm.h
index b0d5693..b2358bc 100644
--- a/arch/arm/mach-msm/clock-rpm.h
+++ b/arch/arm/mach-msm/clock-rpm.h
@@ -15,12 +15,15 @@
 #define __ARCH_ARM_MACH_MSM_CLOCK_RPM_H
 
 #include <mach/rpm.h>
+#include <mach/rpm-smd.h>
 
 struct clk_ops;
+struct clk_rpmrs_data;
 extern struct clk_ops clk_ops_rpm;
 extern struct clk_ops clk_ops_rpm_branch;
 
 struct rpm_clk {
+	const int rpm_res_type;
 	const int rpm_clk_id;
 	const int rpm_status_id;
 	const bool active_only;
@@ -29,6 +32,7 @@
 	unsigned last_set_sleep_khz;
 	bool enabled;
 	bool branch; /* true: RPM only accepts 1 for ON and 0 for OFF */
+	struct clk_rpmrs_data *rpmrs_data;
 
 	struct rpm_clk *peer;
 	struct clk c;
@@ -39,12 +43,17 @@
 	return container_of(clk, struct rpm_clk, c);
 }
 
-#define DEFINE_CLK_RPM(name, active, r_id, dep) \
+extern struct clk_rpmrs_data clk_rpmrs_data;
+extern struct clk_rpmrs_data clk_rpmrs_data_smd;
+
+#define __DEFINE_CLK_RPM(name, active, type, r_id, stat_id, dep, rpmrsdata) \
 	static struct rpm_clk active; \
 	static struct rpm_clk name = { \
-		.rpm_clk_id = MSM_RPM_ID_##r_id##_CLK, \
-		.rpm_status_id = MSM_RPM_STATUS_ID_##r_id##_CLK, \
+		.rpm_res_type = (type), \
+		.rpm_clk_id = (r_id), \
+		.rpm_status_id = (stat_id), \
 		.peer = &active, \
+		.rpmrs_data = (rpmrsdata),\
 		.c = { \
 			.ops = &clk_ops_rpm, \
 			.flags = CLKFLAG_SKIP_AUTO_OFF, \
@@ -54,10 +63,12 @@
 		}, \
 	}; \
 	static struct rpm_clk active = { \
-		.rpm_clk_id = MSM_RPM_ID_##r_id##_CLK, \
-		.rpm_status_id = MSM_RPM_STATUS_ID_##r_id##_CLK, \
+		.rpm_res_type = (type), \
+		.rpm_clk_id = (r_id), \
+		.rpm_status_id = (stat_id), \
 		.peer = &name, \
 		.active_only = true, \
+		.rpmrs_data = (rpmrsdata),\
 		.c = { \
 			.ops = &clk_ops_rpm, \
 			.flags = CLKFLAG_SKIP_AUTO_OFF, \
@@ -67,15 +78,18 @@
 		}, \
 	};
 
-#define DEFINE_CLK_RPM_BRANCH(name, active, r_id, r) \
+#define __DEFINE_CLK_RPM_BRANCH(name, active, type, r_id, stat_id, r, \
+					rpmrsdata) \
 	static struct rpm_clk active; \
 	static struct rpm_clk name = { \
-		.rpm_clk_id = MSM_RPM_ID_##r_id##_CLK, \
-		.rpm_status_id = MSM_RPM_STATUS_ID_##r_id##_CLK, \
+		.rpm_res_type = (type), \
+		.rpm_clk_id = (r_id), \
+		.rpm_status_id = (stat_id), \
 		.peer = &active, \
 		.last_set_khz = ((r) / 1000), \
 		.last_set_sleep_khz = ((r) / 1000), \
 		.branch = true, \
+		.rpmrs_data = (rpmrsdata),\
 		.c = { \
 			.ops = &clk_ops_rpm_branch, \
 			.flags = CLKFLAG_SKIP_AUTO_OFF, \
@@ -86,12 +100,14 @@
 		}, \
 	}; \
 	static struct rpm_clk active = { \
-		.rpm_clk_id = MSM_RPM_ID_##r_id##_CLK, \
-		.rpm_status_id = MSM_RPM_STATUS_ID_##r_id##_CLK, \
+		.rpm_res_type = (type), \
+		.rpm_clk_id = (r_id), \
+		.rpm_status_id = (stat_id), \
 		.peer = &name, \
 		.last_set_khz = ((r) / 1000), \
 		.active_only = true, \
 		.branch = true, \
+		.rpmrs_data = (rpmrsdata),\
 		.c = { \
 			.ops = &clk_ops_rpm_branch, \
 			.flags = CLKFLAG_SKIP_AUTO_OFF, \
@@ -102,4 +118,19 @@
 		}, \
 	};
 
+#define DEFINE_CLK_RPM(name, active, r_id, dep) \
+	__DEFINE_CLK_RPM(name, active, 0, MSM_RPM_ID_##r_id##_CLK, \
+		MSM_RPM_STATUS_ID_##r_id##_CLK, dep, &clk_rpmrs_data)
+
+#define DEFINE_CLK_RPM_BRANCH(name, active, r_id, r) \
+	__DEFINE_CLK_RPM_BRANCH(name, active, 0, MSM_RPM_ID_##r_id##_CLK, \
+			MSM_RPM_STATUS_ID_##r_id##_CLK, r, &clk_rpmrs_data)
+
+#define DEFINE_CLK_RPM_SMD(name, active, type, r_id, dep) \
+	__DEFINE_CLK_RPM(name, active, type, r_id, 0, dep, &clk_rpmrs_data_smd)
+
+#define DEFINE_CLK_RPM_SMD_BRANCH(name, active, type, r_id, dep) \
+	__DEFINE_CLK_RPM_BRANCH(name, active, type, r_id, 0, dep, \
+					&clk_rpmrs_data_smd)
+
 #endif
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index 8a1c6eb..8bf98fa 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -21,10 +21,17 @@
 #include <linux/module.h>
 #include <linux/clk.h>
 #include <linux/clkdev.h>
+#include <linux/list.h>
 #include <trace/events/power.h>
 
 #include "clock.h"
 
+struct handoff_clk {
+	struct list_head list;
+	struct clk *clk;
+};
+static LIST_HEAD(handoff_list);
+
 /* Find the voltage level required for a given rate. */
 static int find_vdd_level(struct clk *clk, unsigned long rate)
 {
@@ -203,18 +210,8 @@
 			ret = clk->ops->enable(clk);
 		if (ret)
 			goto err_enable_clock;
-	} else if (clk->flags & CLKFLAG_HANDOFF_RATE) {
-		/*
-		 * The clock was already enabled by handoff code so there is no
-		 * need to enable it again here. Clearing the handoff flag will
-		 * prevent the lateinit handoff code from disabling the clock if
-		 * a client driver still has it enabled.
-		 */
-		clk->flags &= ~CLKFLAG_HANDOFF_RATE;
-		goto out;
 	}
 	clk->count++;
-out:
 	spin_unlock_irqrestore(&clk->lock, flags);
 
 	return 0;
@@ -422,6 +419,58 @@
 
 static struct clock_init_data __initdata *clk_init_data;
 
+static enum handoff __init __handoff_clk(struct clk *clk)
+{
+	enum handoff ret;
+	struct handoff_clk *h;
+	unsigned long rate;
+	int err = 0;
+
+	/*
+	 * Tree roots don't have parents, but need to be handed off. So,
+	 * terminate recursion by returning "enabled". Also return "enabled"
+	 * for clocks with non-zero enable counts since they must have already
+	 * been handed off.
+	 */
+	if (clk == NULL || clk->count)
+		return HANDOFF_ENABLED_CLK;
+
+	/* Clocks without handoff functions are assumed to be disabled. */
+	if (!clk->ops->handoff || (clk->flags & CLKFLAG_SKIP_HANDOFF))
+		return HANDOFF_DISABLED_CLK;
+
+	/*
+	 * Handoff functions for children must be called before their parents'
+	 * so that the correct parent is returned by the clk_get_parent() below.
+	 */
+	ret = clk->ops->handoff(clk);
+	if (ret == HANDOFF_ENABLED_CLK) {
+		ret = __handoff_clk(clk_get_parent(clk));
+		if (ret == HANDOFF_ENABLED_CLK) {
+			h = kmalloc(sizeof(*h), GFP_KERNEL);
+			if (!h) {
+				err = -ENOMEM;
+				goto out;
+			}
+			err = clk_prepare_enable(clk);
+			if (err)
+				goto out;
+			rate = clk_get_rate(clk);
+			if (rate)
+				pr_debug("%s rate=%lu\n", clk->dbg_name, rate);
+			h->clk = clk;
+			list_add_tail(&h->list, &handoff_list);
+		}
+	}
+out:
+	if (err) {
+		pr_err("%s handoff failed (%d)\n", clk->dbg_name, err);
+		kfree(h);
+		ret = HANDOFF_DISABLED_CLK;
+	}
+	return ret;
+}
+
 void __init msm_clock_init(struct clock_init_data *data)
 {
 	unsigned n;
@@ -448,14 +497,8 @@
 	 * Detect and preserve initial clock state until clock_late_init() or
 	 * a driver explicitly changes it, whichever is first.
 	 */
-	for (n = 0; n < num_clocks; n++) {
-		clk = clock_tbl[n].clk;
-		if (clk->ops->handoff && !(clk->flags & CLKFLAG_HANDOFF_RATE) &&
-		    (clk->ops->handoff(clk) == HANDOFF_ENABLED_CLK)) {
-			clk->flags |= CLKFLAG_HANDOFF_RATE;
-			clk_prepare_enable(clk);
-		}
-	}
+	for (n = 0; n < num_clocks; n++)
+		__handoff_clk(clock_tbl[n].clk);
 
 	clkdev_add_table(clock_tbl, num_clocks);
 
@@ -471,13 +514,13 @@
 static int __init clock_late_init(void)
 {
 	unsigned n, count = 0;
+	struct handoff_clk *h, *h_temp;
 	unsigned long flags;
 	int ret = 0;
 
 	clock_debug_init(clk_init_data);
 	for (n = 0; n < clk_init_data->size; n++) {
 		struct clk *clk = clk_init_data->table[n].clk;
-		bool handoff = false;
 
 		clock_debug_add(clk);
 		spin_lock_irqsave(&clk->lock, flags);
@@ -487,19 +530,16 @@
 				clk->ops->auto_off(clk);
 			}
 		}
-		if (clk->flags & CLKFLAG_HANDOFF_RATE) {
-			clk->flags &= ~CLKFLAG_HANDOFF_RATE;
-			handoff = true;
-		}
 		spin_unlock_irqrestore(&clk->lock, flags);
-		/*
-		 * Calling this outside the lock is safe since
-		 * it doesn't need to be atomic with the flag change.
-		 */
-		if (handoff)
-			clk_disable_unprepare(clk);
 	}
 	pr_info("clock_late_init() disabled %d unused clocks\n", count);
+
+	list_for_each_entry_safe(h, h_temp, &handoff_list, list) {
+		clk_disable_unprepare(h->clk);
+		list_del(&h->list);
+		kfree(h);
+	}
+
 	if (clk_init_data->late_init)
 		ret = clk_init_data->late_init();
 	return ret;
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index 1be05ad..03d5790 100644
--- a/arch/arm/mach-msm/clock.h
+++ b/arch/arm/mach-msm/clock.h
@@ -29,10 +29,10 @@
 #define CLKFLAG_NOINVERT		0x00000002
 #define CLKFLAG_NONEST			0x00000004
 #define CLKFLAG_NORESET			0x00000008
-#define CLKFLAG_HANDOFF_RATE		0x00000010
 #define CLKFLAG_HWCG			0x00000020
 #define CLKFLAG_RETAIN			0x00000040
 #define CLKFLAG_NORETAIN		0x00000080
+#define CLKFLAG_SKIP_HANDOFF		0x00000100
 #define CLKFLAG_SKIP_AUTO_OFF		0x00000200
 #define CLKFLAG_MIN			0x00000400
 #define CLKFLAG_MAX			0x00000800
diff --git a/arch/arm/mach-msm/include/mach/rpm-smd.h b/arch/arm/mach-msm/include/mach/rpm-smd.h
index ff58fed..0239e36 100644
--- a/arch/arm/mach-msm/include/mach/rpm-smd.h
+++ b/arch/arm/mach-msm/include/mach/rpm-smd.h
@@ -236,6 +236,20 @@
 	return 0;
 
 }
+
+static inline int msm_rpm_send_message(enum msm_rpm_set set, uint32_t rsc_type,
+		uint32_t rsc_id, struct msm_rpm_kvp *kvp, int nelems)
+{
+	return 0;
+}
+
+static inline int msm_rpm_send_message_noirq(enum msm_rpm_set set,
+		uint32_t rsc_type, uint32_t rsc_id, struct msm_rpm_kvp *kvp,
+		int nelems)
+{
+	return 0;
+}
+
 static inline int msm_rpm_wait_for_ack(uint32_t msg_id)
 {
 	return 0;
diff --git a/arch/arm/mach-msm/include/mach/rpm.h b/arch/arm/mach-msm/include/mach/rpm.h
index 98621be..de4c9d9 100644
--- a/arch/arm/mach-msm/include/mach/rpm.h
+++ b/arch/arm/mach-msm/include/mach/rpm.h
@@ -899,6 +899,8 @@
 extern struct msm_rpm_platform_data msm8930_rpm_data;
 extern struct msm_rpm_platform_data apq8064_rpm_data;
 
+#if defined(CONFIG_MSM_RPM)
+
 int msm_rpm_local_request_is_outstanding(void);
 int msm_rpm_get_status(struct msm_rpm_iv_pair *status, int count);
 int msm_rpm_set(int ctx, struct msm_rpm_iv_pair *req, int count);
@@ -938,4 +940,70 @@
 int msm_rpm_unregister_notification(struct msm_rpm_notification *n);
 int msm_rpm_init(struct msm_rpm_platform_data *data);
 
+#else
+
+static inline int msm_rpm_local_request_is_outstanding(void)
+{
+	return -ENODEV;
+}
+
+static inline int msm_rpm_get_status(struct msm_rpm_iv_pair *status, int count)
+{
+	return -ENODEV;
+}
+
+static inline int msm_rpm_set(int ctx, struct msm_rpm_iv_pair *req, int count)
+{
+	return -ENODEV;
+}
+
+static inline int msm_rpm_set_noirq(int ctx, struct msm_rpm_iv_pair *req,
+					int count)
+{
+	return -ENODEV;
+}
+
+static inline int msm_rpm_set_nosleep(
+	int ctx, struct msm_rpm_iv_pair *req, int count)
+{
+	return -ENODEV;
+}
+
+static inline int msm_rpm_clear(int ctx, struct msm_rpm_iv_pair *req,
+				int count)
+{
+	return -ENODEV;
+}
+
+static inline int msm_rpm_clear_noirq(int ctx, struct msm_rpm_iv_pair *req,
+					int count)
+{
+	return -ENODEV;
+}
+
+static inline int msm_rpm_clear_nosleep(
+	int ctx, struct msm_rpm_iv_pair *req, int count)
+{
+	return -ENODEV;
+}
+
+static inline int msm_rpm_register_notification(struct msm_rpm_notification *n,
+	struct msm_rpm_iv_pair *req, int count)
+{
+	return -ENODEV;
+}
+
+static inline int msm_rpm_unregister_notification(
+					struct msm_rpm_notification *n)
+{
+	return -ENODEV;
+}
+
+static inline int msm_rpm_init(struct msm_rpm_platform_data *data)
+{
+	return -ENODEV;
+}
+
+#endif /* CONFIG_RPM */
+
 #endif /* __ARCH_ARM_MACH_MSM_RPM_H */
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 86e06a4..e35d99b 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -34,7 +34,7 @@
 		.virtual = (unsigned long) MSM_##name##_BASE, \
 		.pfn = __phys_to_pfn(chip##_##name##_PHYS), \
 		.length = chip##_##name##_SIZE, \
-		.type = MT_DEVICE_NONSHARED, \
+		.type = MT_DEVICE, \
 	 }
 
 #define MSM_DEVICE(name) MSM_CHIP_DEVICE(name, MSM)
diff --git a/arch/arm/mach-msm/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
index 6fa435a..c15e8b1 100644
--- a/arch/arm/mach-msm/ipc_router.c
+++ b/arch/arm/mach-msm/ipc_router.c
@@ -2023,7 +2023,7 @@
 }
 
 int msm_ipc_router_lookup_server_name(struct msm_ipc_port_name *srv_name,
-				struct msm_ipc_port_addr *srv_addr,
+				struct msm_ipc_server_info *srv_info,
 				int num_entries_in_array,
 				uint32_t lookup_mask)
 {
@@ -2036,8 +2036,8 @@
 		return -EINVAL;
 	}
 
-	if (num_entries_in_array && !srv_addr) {
-		pr_err("%s: srv_addr NULL\n", __func__);
+	if (num_entries_in_array && !srv_info) {
+		pr_err("%s: srv_info NULL\n", __func__);
 		return -EINVAL;
 	}
 
@@ -2054,10 +2054,14 @@
 			list_for_each_entry(server_port,
 				&server->server_port_list, list) {
 				if (i < num_entries_in_array) {
-					srv_addr[i].node_id =
+					srv_info[i].node_id =
 					  server_port->server_addr.node_id;
-					srv_addr[i].port_id =
+					srv_info[i].port_id =
 					  server_port->server_addr.port_id;
+					srv_info[i].service =
+					  server->name.service;
+					srv_info[i].instance =
+					  server->name.instance;
 				}
 				i++;
 			}
diff --git a/arch/arm/mach-msm/ipc_router.h b/arch/arm/mach-msm/ipc_router.h
index a90be23..07bc5e0 100644
--- a/arch/arm/mach-msm/ipc_router.h
+++ b/arch/arm/mach-msm/ipc_router.h
@@ -185,7 +185,7 @@
 int msm_ipc_router_get_curr_pkt_size(struct msm_ipc_port *port_ptr);
 int msm_ipc_router_bind_control_port(struct msm_ipc_port *port_ptr);
 int msm_ipc_router_lookup_server_name(struct msm_ipc_port_name *srv_name,
-				      struct msm_ipc_port_addr *port_addr,
+				      struct msm_ipc_server_info *srv_info,
 				      int num_entries_in_array,
 				      uint32_t lookup_mask);
 int msm_ipc_router_close_port(struct msm_ipc_port *port_ptr);
diff --git a/arch/arm/mach-msm/ipc_socket.c b/arch/arm/mach-msm/ipc_socket.c
index d82ffe5..d3917f1 100644
--- a/arch/arm/mach-msm/ipc_socket.c
+++ b/arch/arm/mach-msm/ipc_socket.c
@@ -367,8 +367,8 @@
 	struct sock *sk = sock->sk;
 	struct msm_ipc_port *port_ptr;
 	struct server_lookup_args server_arg;
-	struct msm_ipc_port_addr *port_addr = NULL;
-	unsigned int n, port_addr_sz = 0;
+	struct msm_ipc_server_info *srv_info = NULL;
+	unsigned int n, srv_info_sz = 0;
 	int ret;
 
 	if (!sk)
@@ -409,33 +409,33 @@
 			break;
 		}
 		if (server_arg.num_entries_in_array) {
-			port_addr_sz = server_arg.num_entries_in_array *
-					sizeof(*port_addr);
-			port_addr = kmalloc(port_addr_sz, GFP_KERNEL);
-			if (!port_addr) {
+			srv_info_sz = server_arg.num_entries_in_array *
+					sizeof(*srv_info);
+			srv_info = kmalloc(srv_info_sz, GFP_KERNEL);
+			if (!srv_info) {
 				ret = -ENOMEM;
 				break;
 			}
 		}
 		ret = msm_ipc_router_lookup_server_name(&server_arg.port_name,
-				port_addr, server_arg.num_entries_in_array,
+				srv_info, server_arg.num_entries_in_array,
 				server_arg.lookup_mask);
 		if (ret < 0) {
 			pr_err("%s: Server not found\n", __func__);
 			ret = -ENODEV;
-			kfree(port_addr);
+			kfree(srv_info);
 			break;
 		}
 		server_arg.num_entries_found = ret;
 
 		ret = copy_to_user((void *)arg, &server_arg,
 				   sizeof(server_arg));
-		if (port_addr_sz) {
+		if (srv_info_sz) {
 			ret = copy_to_user((void *)(arg + sizeof(server_arg)),
-					   port_addr, port_addr_sz);
+					   srv_info, srv_info_sz);
 			if (ret)
 				ret = -EFAULT;
-			kfree(port_addr);
+			kfree(srv_info);
 		}
 		break;
 
diff --git a/arch/arm/mach-msm/rpm_resources.h b/arch/arm/mach-msm/rpm_resources.h
index d594405..46d6d94 100644
--- a/arch/arm/mach-msm/rpm_resources.h
+++ b/arch/arm/mach-msm/rpm_resources.h
@@ -102,6 +102,8 @@
 	unsigned int rpmrs_target_id[MSM_RPMRS_ID_LAST];
 };
 
+#if defined(CONFIG_MSM_RPM)
+
 int msm_rpmrs_set(int ctx, struct msm_rpm_iv_pair *req, int count);
 int msm_rpmrs_set_noirq(int ctx, struct msm_rpm_iv_pair *req, int count);
 int msm_rpmrs_set_bits_noirq(int ctx, struct msm_rpm_iv_pair *req, int count,
@@ -139,4 +141,74 @@
 void msm_rpmrs_show_resources(void);
 int msm_rpmrs_levels_init(struct msm_rpmrs_platform_data *data);
 
+#else
+
+static inline int msm_rpmrs_set(int ctx, struct msm_rpm_iv_pair *req,
+				int count)
+{
+	return -ENODEV;
+}
+
+static inline int msm_rpmrs_set_noirq(int ctx, struct msm_rpm_iv_pair *req,
+					int count)
+{
+	return -ENODEV;
+}
+
+static inline int msm_rpmrs_set_bits_noirq(int ctx, struct msm_rpm_iv_pair *req,
+			int count, int *mask)
+{
+	return -ENODEV;
+}
+
+static inline int msm_rpmrs_set_nosleep(
+	int ctx, struct msm_rpm_iv_pair *req, int count)
+{
+	return -ENODEV;
+}
+
+static inline int msm_rpmrs_clear(int ctx, struct msm_rpm_iv_pair *req,
+					int count)
+{
+	return -ENODEV;
+}
+
+static inline int msm_rpmrs_clear_noirq(int ctx, struct msm_rpm_iv_pair *req,
+						int count)
+{
+	return -ENODEV;
+}
+
+static inline int msm_rpmrs_clear_nosleep(
+	int ctx, struct msm_rpm_iv_pair *req, int count)
+{
+	return -ENODEV;
+}
+
+static inline struct msm_rpmrs_limits *msm_rpmrs_lowest_limits(
+	bool from_idle, enum msm_pm_sleep_mode sleep_mode, uint32_t latency_us,
+	uint32_t sleep_us)
+{
+	return NULL;
+}
+
+static inline int msm_rpmrs_enter_sleep(uint32_t sclk_count,
+	struct msm_rpmrs_limits *limits, bool from_idle, bool notify_rpm)
+{
+	return -ENODEV;
+}
+
+static inline void msm_rpmrs_exit_sleep(struct msm_rpmrs_limits *limits,
+		bool from_idle, bool notify_rpm, bool collapsed)
+{
+	return;
+}
+
+static inline int msm_rpmrs_levels_init(struct msm_rpmrs_platform_data *data)
+{
+	return -ENODEV;
+}
+
+#endif /* CONFIG_MSM_RPM */
+
 #endif /* __ARCH_ARM_MACH_MSM_RPM_RESOURCES_H */
diff --git a/drivers/gpio/qpnp-gpio.c b/drivers/gpio/qpnp-gpio.c
index d9a23e1..97859e5 100644
--- a/drivers/gpio/qpnp-gpio.c
+++ b/drivers/gpio/qpnp-gpio.c
@@ -22,6 +22,8 @@
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/of_irq.h>
+#include <linux/export.h>
+#include <linux/module.h>
 #include <linux/qpnp/gpio.h>
 #include <linux/export.h>
 
@@ -504,27 +506,26 @@
 }
 
 static int qpnp_gpio_of_gpio_xlate(struct gpio_chip *gpio_chip,
-				   struct device_node *np,
-				   const void *gpio_spec, u32 *flags)
+				   const struct of_phandle_args *gpio_spec,
+				   u32 *flags)
 {
 	struct qpnp_gpio_chip *q_chip = dev_get_drvdata(gpio_chip->dev);
 	struct qpnp_gpio_spec *q_spec;
-	const __be32 *gpio = gpio_spec;
-	u32 n = be32_to_cpup(gpio);
 
 	if (WARN_ON(gpio_chip->of_gpio_n_cells < 2)) {
 		pr_err("of_gpio_n_cells < 2\n");
 		return -EINVAL;
 	}
 
-	q_spec = qpnp_pmic_gpio_get_spec(q_chip, n);
+	q_spec = qpnp_pmic_gpio_get_spec(q_chip, gpio_spec->args[0]);
 	if (!q_spec) {
-		pr_err("no such PMIC gpio %u in device topology\n", n);
+		pr_err("no such PMIC gpio %u in device topology\n",
+							gpio_spec->args[0]);
 		return -EINVAL;
 	}
 
 	if (flags)
-		*flags = be32_to_cpu(gpio[1]);
+		*flags = gpio_spec->args[1];
 
 	return q_spec->gpio_chip_idx;
 }
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 6041cd8..3de3af9 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -156,7 +156,7 @@
 		"a225_pm4.fw", "a225_pfp.fw", &adreno_a2xx_gpudev,
 		1536, 768, 3, SZ_512K },
 	/* A3XX doesn't use the pix_shader_start */
-	{ ADRENO_REV_A305, 3, 0, 5, 0,
+	{ ADRENO_REV_A305, 3, 0, 5, ANY_ID,
 		"a300_pm4.fw", "a300_pfp.fw", &adreno_a3xx_gpudev,
 		512, 0, 2, SZ_256K },
 	/* A3XX doesn't use the pix_shader_start */
@@ -500,8 +500,9 @@
 	 * thing and set the chip_id based on the SoC
 	 */
 
+	unsigned int version = socinfo_get_version();
+
 	if (cpu_is_apq8064()) {
-		unsigned int version = socinfo_get_version();
 
 		/* A320 */
 		majorid = 2;
@@ -518,10 +519,21 @@
 		else
 			patchid = 0;
 	} else if (cpu_is_msm8930()) {
+
 		/* A305 */
 		majorid = 0;
 		minorid = 5;
-		patchid = 0;
+
+		/*
+		 * V1.2 has some GPU work arounds that we need to communicate
+		 * up to user space via the patchid
+		 */
+
+		if ((SOCINFO_VERSION_MAJOR(version) == 1) &&
+			(SOCINFO_VERSION_MINOR(version) == 2))
+			patchid = 2;
+		else
+			patchid = 0;
 	}
 
 	return (0x03 << 24) | (majorid << 16) | (minorid << 8) | patchid;
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 4ce56a4..feaa36f 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -46,6 +46,8 @@
 
 #define ADRENO_ISTORE_START 0x5000 /* Istore offset */
 
+#define ADRENO_NUM_CTX_SWITCH_ALLOWED_BEFORE_DRAW	50
+
 enum adreno_gpurev {
 	ADRENO_REV_UNKNOWN = 0,
 	ADRENO_REV_A200 = 200,
@@ -90,11 +92,14 @@
 	unsigned int reg_rbbm_status;
 	unsigned int reg_cp_pfp_ucode_data;
 	unsigned int reg_cp_pfp_ucode_addr;
+	/* keeps track of when we need to execute the draw workaround code */
+	int ctx_switches_since_last_draw;
 
 	/* GPU specific function hooks */
 	int (*ctxt_create)(struct adreno_device *, struct adreno_context *);
 	void (*ctxt_save)(struct adreno_device *, struct adreno_context *);
 	void (*ctxt_restore)(struct adreno_device *, struct adreno_context *);
+	void (*ctxt_draw_workaround)(struct adreno_device *);
 	irqreturn_t (*irq_handler)(struct adreno_device *);
 	void (*irq_control)(struct adreno_device *, int);
 	void * (*snapshot)(struct adreno_device *, void *, int *, int);
diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c
index 7ccfd3f..c3c266e 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -1450,11 +1450,49 @@
 	return ret;
 }
 
+static void a2xx_drawctxt_draw_workaround(struct adreno_device *adreno_dev)
+{
+	struct kgsl_device *device = &adreno_dev->dev;
+	unsigned int cmd[11];
+	unsigned int *cmds = &cmd[0];
+
+	adreno_dev->gpudev->ctx_switches_since_last_draw++;
+	/* If there have been > than ADRENO_NUM_CTX_SWITCH_ALLOWED_BEFORE_DRAW
+	 * calls to context switches w/o gmem being saved then we need to
+	 * execute this workaround */
+	if (adreno_dev->gpudev->ctx_switches_since_last_draw >
+		ADRENO_NUM_CTX_SWITCH_ALLOWED_BEFORE_DRAW)
+		adreno_dev->gpudev->ctx_switches_since_last_draw = 0;
+	else
+		return;
+	/*
+	 * Issue an empty draw call to avoid possible hangs due to
+	 * repeated idles without intervening draw calls.
+	 * On adreno 225 the PC block has a cache that is only
+	 * flushed on draw calls and repeated idles can make it
+	 * overflow. The gmem save path contains draw calls so
+	 * this workaround isn't needed there.
+	 */
+	*cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
+	*cmds++ = (0x4 << 16) | (REG_PA_SU_SC_MODE_CNTL - 0x2000);
+	*cmds++ = 0;
+	*cmds++ = cp_type3_packet(CP_DRAW_INDX, 5);
+	*cmds++ = 0;
+	*cmds++ = 1<<14;
+	*cmds++ = 0;
+	*cmds++ = device->mmu.setstate_memory.gpuaddr;
+	*cmds++ = 0;
+	*cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
+	*cmds++ = 0x00000000;
+
+	adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
+				    &cmd[0], 11);
+}
+
 static void a2xx_drawctxt_save(struct adreno_device *adreno_dev,
 			struct adreno_context *context)
 {
 	struct kgsl_device *device = &adreno_dev->dev;
-	unsigned int cmd[22];
 
 	if (context == NULL)
 		return;
@@ -1499,33 +1537,11 @@
 			adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
 				context->chicken_restore, 3);
 		}
+		adreno_dev->gpudev->ctx_switches_since_last_draw = 0;
 
 		context->flags |= CTXT_FLAGS_GMEM_RESTORE;
-	} else if (adreno_is_a225(adreno_dev)) {
-		unsigned int *cmds = &cmd[0];
-		/*
-		 * Issue an empty draw call to avoid possible hangs due to
-		 * repeated idles without intervening draw calls.
-		 * On adreno 225 the PC block has a cache that is only
-		 * flushed on draw calls and repeated idles can make it
-		 * overflow. The gmem save path contains draw calls so
-		 * this workaround isn't needed there.
-		 */
-		*cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
-		*cmds++ = (0x4 << 16) | (REG_PA_SU_SC_MODE_CNTL - 0x2000);
-		*cmds++ = 0;
-		*cmds++ = cp_type3_packet(CP_DRAW_INDX, 5);
-		*cmds++ = 0;
-		*cmds++ = 1<<14;
-		*cmds++ = 0;
-		*cmds++ = device->mmu.setstate_memory.gpuaddr;
-		*cmds++ = 0;
-		*cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
-		*cmds++ = 0x00000000;
-
-		adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
-					    &cmd[0], 11);
-	}
+	} else if (adreno_is_a225(adreno_dev))
+		a2xx_drawctxt_draw_workaround(adreno_dev);
 }
 
 static void a2xx_drawctxt_restore(struct adreno_device *adreno_dev,
@@ -1983,6 +1999,7 @@
 	.ctxt_create = a2xx_drawctxt_create,
 	.ctxt_save = a2xx_drawctxt_save,
 	.ctxt_restore = a2xx_drawctxt_restore,
+	.ctxt_draw_workaround = a2xx_drawctxt_draw_workaround,
 	.irq_handler = a2xx_irq_handler,
 	.irq_control = a2xx_irq_control,
 	.snapshot = a2xx_snapshot,
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index 1902f50..600e04f 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -2621,6 +2621,7 @@
 	.ctxt_create = a3xx_drawctxt_create,
 	.ctxt_save = a3xx_drawctxt_save,
 	.ctxt_restore = a3xx_drawctxt_restore,
+	.ctxt_draw_workaround = NULL,
 	.rb_init = a3xx_rb_init,
 	.irq_control = a3xx_irq_control,
 	.irq_handler = a3xx_irq_handler,
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index 0d15fb9..49d035f 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -270,8 +270,13 @@
 	}
 
 	/* already current? */
-	if (adreno_dev->drawctxt_active == drawctxt)
+	if (adreno_dev->drawctxt_active == drawctxt) {
+		if (adreno_dev->gpudev->ctxt_draw_workaround &&
+			adreno_is_a225(adreno_dev))
+				adreno_dev->gpudev->ctxt_draw_workaround(
+					adreno_dev);
 		return;
+	}
 
 	KGSL_CTXT_INFO(device, "from %p to %p flags %d\n",
 			adreno_dev->drawctxt_active, drawctxt, flags);
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index febb265..b3f2d1e 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -82,7 +82,8 @@
 		return -ENOSYS;
 	}
 
-	ptbase = iommu_get_pt_base_addr(domain);
+	ptbase = KGSL_IOMMU_GET_IOMMU_REG(iommu_unit->reg_map.hostptr,
+					iommu_dev->ctx_id, TTBR0);
 
 	fsr = KGSL_IOMMU_GET_IOMMU_REG(iommu_unit->reg_map.hostptr,
 		iommu_dev->ctx_id, FSR);
diff --git a/drivers/gpu/msm/kgsl_trace.h b/drivers/gpu/msm/kgsl_trace.h
index 60231f6..3eff40f 100644
--- a/drivers/gpu/msm/kgsl_trace.h
+++ b/drivers/gpu/msm/kgsl_trace.h
@@ -143,7 +143,7 @@
 	),
 
 	TP_printk(
-		"d_name=%s context_id=%u curr_ts=%u timestamp=0x%x timeout=%u",
+		"d_name=%s context_id=%u curr_ts=0x%x timestamp=0x%x timeout=%u",
 		__get_str(device_name),
 		__entry->context_id,
 		__entry->curr_ts,
@@ -175,7 +175,7 @@
 	),
 
 	TP_printk(
-		"d_name=%s curr_ts=%u result=%d",
+		"d_name=%s curr_ts=0x%x result=%d",
 		__get_str(device_name),
 		__entry->curr_ts,
 		__entry->result
@@ -386,7 +386,7 @@
 
 	TP_printk(
 		"d_name=%s gpuaddr=0x%08x size=%d type=%d ctx=%u"
-		" curr_ts=0x%08x free_ts=0x%08x",
+		" curr_ts=0x%x free_ts=0x%x",
 		__get_str(device_name),
 		__entry->gpuaddr,
 		__entry->size,
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 09511b1..c3c09d4 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -108,6 +108,25 @@
 	return rc;
 }
 
+static int msm_camera_v4l2_private_s_ctrl(struct file *f, void *pctx,
+			struct msm_camera_v4l2_ioctl_t *ioctl_ptr)
+{
+	int rc = -EINVAL;
+	struct msm_cam_v4l2_device *pcam  = video_drvdata(f);
+	struct msm_cam_v4l2_dev_inst *pcam_inst;
+	pcam_inst = container_of(f->private_data,
+		struct msm_cam_v4l2_dev_inst, eventHandle);
+	WARN_ON(pctx != f->private_data);
+	mutex_lock(&pcam->vid_lock);
+	switch (ioctl_ptr->id) {
+	case MSM_V4L2_PID_CTRL_CMD:
+		rc = msm_server_proc_ctrl_cmd(pcam, ioctl_ptr, 1);
+		break;
+	}
+	mutex_unlock(&pcam->vid_lock);
+	return rc;
+}
+
 static int msm_camera_v4l2_s_ctrl(struct file *f, void *pctx,
 					struct v4l2_control *ctrl)
 {
@@ -127,17 +146,6 @@
 			 __func__, pcam_inst, pcam_inst->my_index);
 		pcam_inst->is_mem_map_inst = 1;
 		break;
-	case MSM_V4L2_PID_MMAP_ENTRY:
-		if (copy_from_user(&pcam_inst->mem_map,
-			(void *)ctrl->value,
-			sizeof(struct msm_mem_map_info))) {
-			rc = -EFAULT;
-		} else
-			D("%s:mmap entry:cookie=0x%x,mem_type=%d,len=%d\n",
-				__func__, pcam_inst->mem_map.cookie,
-				pcam_inst->mem_map.mem_type,
-				pcam_inst->mem_map.length);
-		break;
 	default:
 		if (ctrl->id == MSM_V4L2_PID_CAM_MODE)
 			pcam->op_mode = ctrl->value;
@@ -685,6 +693,22 @@
 	return rc;
 }
 
+static long msm_camera_v4l2_private_ioctl(struct file *file, void *fh,
+					  bool valid_prio, int cmd,
+					  void *arg)
+{
+	int rc = -EINVAL;
+	struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
+	D("%s: cmd %d\n", __func__, _IOC_NR(cmd));
+
+	switch (cmd) {
+	case MSM_CAM_V4L2_IOCTL_PRIVATE_S_CTRL:
+		rc = msm_camera_v4l2_private_s_ctrl(file, fh, ioctl_ptr);
+		break;
+	}
+	return rc;
+}
+
 /* v4l2_ioctl_ops */
 static const struct v4l2_ioctl_ops g_msm_ioctl_ops = {
 	.vidioc_querycap = msm_camera_v4l2_querycap,
@@ -724,6 +748,7 @@
 	/* event subscribe/unsubscribe */
 	.vidioc_subscribe_event = msm_camera_v4l2_subscribe_event,
 	.vidioc_unsubscribe_event = msm_camera_v4l2_unsubscribe_event,
+	.vidioc_default = msm_camera_v4l2_private_ioctl,
 };
 
 /* v4l2_file_operations */
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index caa2d32..42330b4 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -39,11 +39,16 @@
 #define MSM_V4L2_DIMENSION_SIZE 96
 #define MAX_DEV_NAME_LEN 50
 
-#define ERR_USER_COPY(to) pr_debug("%s(%d): copy %s user\n", \
+#define ERR_USER_COPY(to) pr_err("%s(%d): copy %s user\n", \
 				__func__, __LINE__, ((to) ? "to" : "from"))
 #define ERR_COPY_FROM_USER() ERR_USER_COPY(0)
 #define ERR_COPY_TO_USER() ERR_USER_COPY(1)
 
+#define COPY_FROM_USER(error, dest, src, size) \
+	(error = (copy_from_user(dest, src, size) ? -EFAULT : 0))
+#define COPY_TO_USER(error, dest, src, size) \
+	(error = (copy_to_user(dest, src, size) ? -EFAULT : 0))
+
 #define MSM_CSIPHY_DRV_NAME "msm_csiphy"
 #define MSM_CSID_DRV_NAME "msm_csid"
 #define MSM_CSIC_DRV_NAME "msm_csic"
@@ -102,6 +107,7 @@
 		qcmd = list_first_entry(&__q->list,   \
 			struct msm_queue_cmd, member);	\
 			list_del_init(&qcmd->member);	 \
+			kfree(qcmd->command);		\
 			free_qcmd(qcmd);		\
 	 };			  \
 	spin_unlock_irqrestore(&__q->lock, flags);	\
@@ -147,7 +153,6 @@
 	NOTIFY_VFE_MSG_COMP_STATS, /* arg = struct msm_stats_buf */
 	NOTIFY_VFE_BUF_EVT, /* arg = struct msm_vfe_resp */
 	NOTIFY_ISPIF_STREAM, /* arg = enable parameter for s_stream */
-	NOTIFY_VPE_MSG_EVT,
 	NOTIFY_PCLK_CHANGE, /* arg = pclk */
 	NOTIFY_CSIPHY_CFG, /* arg = msm_camera_csiphy_params */
 	NOTIFY_CSID_CFG, /* arg = msm_camera_csid_params */
@@ -206,6 +211,7 @@
 	struct msm_pp_frame src_frame;
 	struct msm_pp_frame dest_frame;
 	struct msm_mctl_pp_frame_cmd pp_frame_cmd;
+	struct msm_cam_media_controller *p_mctl;
 };
 
 struct msm_mctl_pp_ctrl {
@@ -587,6 +593,10 @@
 int msm_cam_server_close_mctl_session(struct msm_cam_v4l2_device *pcam);
 long msm_v4l2_evt_notify(struct msm_cam_media_controller *mctl,
 		unsigned int cmd, unsigned long evt);
+int msm_mctl_pp_get_vpe_buf_info(struct msm_mctl_pp_frame_info *zoom);
+void msm_queue_init(struct msm_device_queue *queue, const char *name);
+void msm_enqueue(struct msm_device_queue *queue, struct list_head *entry);
+void msm_drain_eventq(struct msm_device_queue *queue);
 #endif /* __KERNEL__ */
 
 #endif /* _MSM_H */
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index 848beda..c266b85 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -742,13 +742,6 @@
 
 	D("%s: cmd %d\n", __func__, _IOC_NR(cmd));
 	switch (cmd) {
-	case MSM_CAM_IOCTL_PICT_PP_DONE:
-		/* Release the preview of snapshot frame
-		 * that was grabbed.
-		 */
-		/*rc = msm_pp_release(pmsm->sync, arg);*/
-		break;
-
 	case MSM_CAM_IOCTL_CONFIG_VFE:
 		/* Coming from config thread for update */
 		rc = msm_config_vfe(sd, pmctl, argp);
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index e6523cd..ed6c493 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -767,8 +767,10 @@
 			VIDIOC_MSM_CSIPHY_RELEASE, NULL);
 	}
 
-	if (p_mctl->act_sdev)
+	if (p_mctl->act_sdev) {
 		v4l2_subdev_call(p_mctl->act_sdev, core, s_power, 0);
+		p_mctl->act_sdev = NULL;
+	}
 
 	v4l2_subdev_call(p_mctl->sensor_sdev, core, s_power, 0);
 
diff --git a/drivers/media/video/msm/msm_mctl_buf.c b/drivers/media/video/msm/msm_mctl_buf.c
index 1088a54..eade6f1 100644
--- a/drivers/media/video/msm/msm_mctl_buf.c
+++ b/drivers/media/video/msm/msm_mctl_buf.c
@@ -454,7 +454,7 @@
 					image_mode, fbuf,
 					&frame_id, 1);
 				D("%s mctl node buf done %d\n", __func__, 0);
-				return -EINVAL;
+				return rc;
 			} else {
 			  pr_err("%s Invalid instance, dropping buffer\n",
 				  __func__);
diff --git a/drivers/media/video/msm/msm_mctl_pp.c b/drivers/media/video/msm/msm_mctl_pp.c
index f4c04bb..844a3ff 100644
--- a/drivers/media/video/msm/msm_mctl_pp.c
+++ b/drivers/media/video/msm/msm_mctl_pp.c
@@ -36,18 +36,6 @@
 #define D(fmt, args...) do {} while (0)
 #endif
 
-
-static int msm_mctl_pp_vpe_ioctl(struct v4l2_subdev *vpe_sd,
-	struct msm_mctl_pp_cmd *cmd, void *data)
-{
-	int rc = 0;
-	struct msm_mctl_pp_params parm;
-	parm.cmd = cmd;
-	parm.data = data;
-	rc = v4l2_subdev_call(vpe_sd, core, ioctl, VIDIOC_MSM_VPE_CFG, &parm);
-	return rc;
-}
-
 static int msm_mctl_pp_buf_divert(
 			struct msm_cam_media_controller *pmctl,
 			struct msm_cam_v4l2_dev_inst *pcam_inst,
@@ -384,244 +372,6 @@
 		return -EINVAL;
 }
 
-int msm_mctl_pp_proc_vpe_cmd(
-	struct msm_cam_media_controller *p_mctl,
-	struct msm_mctl_pp_cmd *pp_cmd)
-{
-	int rc = 0, idx;
-	void __user *argp = (void __user *)pp_cmd->value;
-	struct msm_cam_v4l2_dev_inst *pcam_inst;
-
-	switch (pp_cmd->id) {
-	case VPE_CMD_INIT:
-	case VPE_CMD_DEINIT:
-		rc = msm_mctl_pp_vpe_ioctl(
-			p_mctl->vpe_sdev, pp_cmd, NULL);
-		break;
-	case VPE_CMD_DISABLE:
-	case VPE_CMD_RESET:
-		rc = msm_mctl_pp_vpe_ioctl(
-			p_mctl->vpe_sdev, pp_cmd, NULL);
-		break;
-	case VPE_CMD_ENABLE: {
-		struct msm_vpe_clock_rate clk_rate;
-		if (sizeof(struct msm_vpe_clock_rate) !=
-			pp_cmd->length) {
-			pr_err("%s: vpe cmd size mismatch "
-				"(id=%d, length = %d, expect size = %d",
-				__func__, pp_cmd->id, pp_cmd->length,
-				sizeof(struct msm_vpe_clock_rate));
-				rc = -EINVAL;
-				break;
-		}
-		if (copy_from_user(&clk_rate, pp_cmd->value,
-			sizeof(struct msm_vpe_clock_rate))) {
-			pr_err("%s:clk_rate copy failed", __func__);
-			return -EFAULT;
-		}
-		pp_cmd->value = (void *)&clk_rate;
-		rc = msm_mctl_pp_vpe_ioctl(
-			p_mctl->vpe_sdev, pp_cmd, NULL);
-		pp_cmd->value = argp;
-		break;
-	}
-	case VPE_CMD_FLUSH: {
-		struct msm_vpe_flush_frame_buffer flush_buf;
-		if (sizeof(struct msm_vpe_flush_frame_buffer) !=
-			pp_cmd->length) {
-			D("%s: size mismatch(id=%d, len = %d, expected = %d",
-				__func__, pp_cmd->id, pp_cmd->length,
-				sizeof(struct msm_vpe_flush_frame_buffer));
-				rc = -EINVAL;
-				break;
-		}
-		if (copy_from_user(
-			&flush_buf, pp_cmd->value, sizeof(flush_buf)))
-			return -EFAULT;
-		pp_cmd->value = (void *)&flush_buf;
-		rc = msm_mctl_pp_vpe_ioctl(
-			p_mctl->vpe_sdev, pp_cmd, NULL);
-		if (rc == 0) {
-			if (copy_to_user((void *)argp,
-						&flush_buf,
-						sizeof(flush_buf))) {
-				ERR_COPY_TO_USER();
-				rc = -EFAULT;
-			}
-			pp_cmd->value = argp;
-		}
-	}
-	break;
-	case VPE_CMD_OPERATION_MODE_CFG: {
-		struct msm_vpe_op_mode_cfg op_mode_cfg;
-		if (sizeof(struct msm_vpe_op_mode_cfg) !=
-		pp_cmd->length) {
-			D("%s: size mismatch(id=%d, len = %d, expected = %d",
-				__func__, pp_cmd->id, pp_cmd->length,
-				sizeof(struct msm_vpe_op_mode_cfg));
-				rc = -EINVAL;
-				break;
-		}
-		if (copy_from_user(&op_mode_cfg,
-			pp_cmd->value,
-			sizeof(op_mode_cfg)))
-			return -EFAULT;
-		pp_cmd->value = (void *)&op_mode_cfg;
-		rc = msm_mctl_pp_vpe_ioctl(
-			p_mctl->vpe_sdev, pp_cmd, NULL);
-		break;
-	}
-	case VPE_CMD_INPUT_PLANE_CFG: {
-		struct msm_vpe_input_plane_cfg input_cfg;
-		if (sizeof(struct msm_vpe_input_plane_cfg) !=
-			pp_cmd->length) {
-			D("%s: mismatch(id=%d, len = %d, expected = %d",
-				__func__, pp_cmd->id, pp_cmd->length,
-				sizeof(struct msm_vpe_input_plane_cfg));
-				rc = -EINVAL;
-				break;
-		}
-		if (copy_from_user(
-			&input_cfg, pp_cmd->value, sizeof(input_cfg)))
-			return -EFAULT;
-		pp_cmd->value = (void *)&input_cfg;
-		rc = msm_mctl_pp_vpe_ioctl(
-			p_mctl->vpe_sdev, pp_cmd, NULL);
-		break;
-	}
-	case VPE_CMD_OUTPUT_PLANE_CFG: {
-		struct msm_vpe_output_plane_cfg output_cfg;
-		if (sizeof(struct msm_vpe_output_plane_cfg) !=
-			pp_cmd->length) {
-			D("%s: size mismatch(id=%d, len = %d, expected = %d",
-				__func__, pp_cmd->id, pp_cmd->length,
-				sizeof(struct msm_vpe_output_plane_cfg));
-				rc = -EINVAL;
-				break;
-		}
-		if (copy_from_user(&output_cfg, pp_cmd->value,
-			sizeof(output_cfg))) {
-			D("%s: cannot copy pp_cmd->value, size=%d",
-				__func__, pp_cmd->length);
-			return -EFAULT;
-		}
-		pp_cmd->value = (void *)&output_cfg;
-		rc = msm_mctl_pp_vpe_ioctl(
-			p_mctl->vpe_sdev, pp_cmd, NULL);
-		break;
-	}
-	case VPE_CMD_INPUT_PLANE_UPDATE: {
-		struct msm_vpe_input_plane_update_cfg input_update_cfg;
-		if (sizeof(struct msm_vpe_input_plane_update_cfg) !=
-			pp_cmd->length) {
-			D("%s: size mismatch(id=%d, len = %d, expected = %d",
-				__func__, pp_cmd->id, pp_cmd->length,
-				sizeof(struct msm_vpe_input_plane_update_cfg));
-				rc = -EINVAL;
-				break;
-		}
-		if (copy_from_user(&input_update_cfg, pp_cmd->value,
-			sizeof(input_update_cfg)))
-			return -EFAULT;
-		pp_cmd->value = (void *)&input_update_cfg;
-		rc = msm_mctl_pp_vpe_ioctl(
-			p_mctl->vpe_sdev, pp_cmd, NULL);
-		break;
-	}
-	case VPE_CMD_SCALE_CFG_TYPE: {
-		struct msm_vpe_scaler_cfg scaler_cfg;
-		if (sizeof(struct msm_vpe_scaler_cfg) !=
-			pp_cmd->length) {
-			D("%s: size mismatch(id=%d, len = %d, expected = %d",
-				__func__, pp_cmd->id, pp_cmd->length,
-				sizeof(struct msm_vpe_scaler_cfg));
-				rc = -EINVAL;
-				break;
-		}
-		if (copy_from_user(&scaler_cfg, pp_cmd->value,
-			sizeof(scaler_cfg)))
-			return -EFAULT;
-		pp_cmd->value = (void *)&scaler_cfg;
-		rc = msm_mctl_pp_vpe_ioctl(
-			p_mctl->vpe_sdev, pp_cmd, NULL);
-		break;
-	}
-	case VPE_CMD_ZOOM: {
-		struct msm_mctl_pp_frame_info *zoom;
-		zoom = kmalloc(sizeof(struct msm_mctl_pp_frame_info),
-					GFP_ATOMIC);
-		if (!zoom) {
-			rc = -ENOMEM;
-			break;
-		}
-		if (sizeof(zoom->pp_frame_cmd) != pp_cmd->length) {
-			D("%s: size mismatch(id=%d, len = %d, expected = %d",
-				__func__, pp_cmd->id, pp_cmd->length,
-				sizeof(zoom->pp_frame_cmd));
-				rc = -EINVAL;
-				kfree(zoom);
-				break;
-		}
-		if (copy_from_user(&zoom->pp_frame_cmd, pp_cmd->value,
-			sizeof(zoom->pp_frame_cmd))) {
-			kfree(zoom);
-			return -EFAULT;
-		}
-		D("%s: src=0x%x, dest=0x%x,cookie=0x%x,action=0x%x,path=0x%x",
-				__func__, zoom->pp_frame_cmd.src_buf_handle,
-				zoom->pp_frame_cmd.dest_buf_handle,
-				zoom->pp_frame_cmd.cookie,
-				zoom->pp_frame_cmd.vpe_output_action,
-				zoom->pp_frame_cmd.path);
-		idx = msm_mctl_pp_path_to_inst_index(p_mctl->pcam_ptr,
-			zoom->pp_frame_cmd.path);
-		if (idx < 0) {
-			pr_err("%s Invalid path, returning\n", __func__);
-			kfree(zoom);
-			return idx;
-		}
-		pcam_inst = p_mctl->pcam_ptr->dev_inst[idx];
-		if (!pcam_inst) {
-			pr_err("%s Invalid instance, returning\n", __func__);
-			kfree(zoom);
-			return -EINVAL;
-		}
-		zoom->user_cmd = pp_cmd->id;
-		rc = msm_mctl_pp_get_phy_addr(pcam_inst,
-			zoom->pp_frame_cmd.src_buf_handle, &zoom->src_frame);
-		if (rc) {
-			kfree(zoom);
-			break;
-		}
-		rc = msm_mctl_pp_get_phy_addr(pcam_inst,
-			zoom->pp_frame_cmd.dest_buf_handle, &zoom->dest_frame);
-		if (rc) {
-			kfree(zoom);
-			break;
-		}
-		rc = msm_mctl_pp_copy_timestamp_and_frame_id(
-			zoom->pp_frame_cmd.src_buf_handle,
-
-			zoom->pp_frame_cmd.dest_buf_handle);
-		if (rc) {
-			kfree(zoom);
-			break;
-		}
-		rc = msm_mctl_pp_vpe_ioctl(
-			p_mctl->vpe_sdev, pp_cmd, (void *)zoom);
-		if (rc) {
-			kfree(zoom);
-			break;
-		}
-		break;
-	}
-	default:
-		rc = -1;
-		break;
-	}
-	return rc;
-}
-
 static int msm_mctl_pp_path_to_img_mode(int path)
 {
 	switch (path) {
@@ -717,9 +467,6 @@
 		return -EFAULT;
 
 	switch (pp_cmd.type) {
-	case MSM_PP_CMD_TYPE_VPE:
-		rc = msm_mctl_pp_proc_vpe_cmd(p_mctl, &pp_cmd.cmd);
-		break;
 	case MSM_PP_CMD_TYPE_MCTL:
 		rc = msm_mctl_pp_proc_cmd(p_mctl, &pp_cmd.cmd);
 		break;
@@ -739,71 +486,6 @@
 	return rc;
 }
 
-int msm_mctl_pp_notify(struct msm_cam_media_controller *p_mctl,
-			struct msm_mctl_pp_frame_info *pp_frame_info)
-{
-		struct msm_mctl_pp_frame_cmd *pp_frame_cmd;
-		pp_frame_cmd = &pp_frame_info->pp_frame_cmd;
-
-		D("%s: msm_cam_evt_divert_frame=%d",
-			__func__, sizeof(struct msm_mctl_pp_event_info));
-		if ((MSM_MCTL_PP_VPE_FRAME_TO_APP &
-			pp_frame_cmd->vpe_output_action)) {
-			struct msm_free_buf done_frame;
-			int img_mode =
-				msm_mctl_pp_path_to_img_mode(
-					pp_frame_cmd->path);
-			if (img_mode < 0) {
-				pr_err("%s Invalid image mode\n", __func__);
-				return img_mode;
-			}
-			done_frame.ch_paddr[0] =
-				pp_frame_info->dest_frame.sp.phy_addr;
-			done_frame.vb =
-				pp_frame_info->dest_frame.handle;
-			msm_mctl_buf_done_pp(
-				p_mctl, img_mode, &done_frame, 0, 0);
-			D("%s: vpe done to app, vb=0x%x, path=%d, phy=0x%x",
-				__func__, done_frame.vb,
-				pp_frame_cmd->path, done_frame.ch_paddr[0]);
-		}
-		if ((MSM_MCTL_PP_VPE_FRAME_ACK &
-			pp_frame_cmd->vpe_output_action)) {
-			struct v4l2_event v4l2_evt;
-			struct msm_mctl_pp_event_info *pp_event_info;
-			struct msm_isp_event_ctrl *isp_event;
-			isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl),
-								GFP_ATOMIC);
-			if (!isp_event) {
-				pr_err("%s Insufficient memory.", __func__);
-				return -ENOMEM;
-			}
-			memset(&v4l2_evt, 0, sizeof(v4l2_evt));
-			*((uint32_t *)v4l2_evt.u.data) = (uint32_t)isp_event;
-
-			/* Get hold of pp event info struct inside event ctrl.*/
-			pp_event_info = &(isp_event->isp_data.pp_event_info);
-
-			pp_event_info->event = MCTL_PP_EVENT_CMD_ACK;
-			pp_event_info->ack.cmd = pp_frame_info->user_cmd;
-			pp_event_info->ack.status = 0;
-			pp_event_info->ack.cookie = pp_frame_cmd->cookie;
-			v4l2_evt.id = 0;
-			v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
-						MSM_CAM_RESP_MCTL_PP_EVENT;
-
-			v4l2_event_queue(
-				p_mctl->config_device->
-					config_stat_event_queue.pvdev,
-				&v4l2_evt);
-			D("%s: ack to daemon, cookie=0x%x, event = 0x%x",
-				__func__, pp_frame_info->pp_frame_cmd.cookie,
-				v4l2_evt.type);
-		}
-		kfree(pp_frame_info); /* free mem */
-		return 0;
-}
-
 int msm_mctl_pp_reserve_free_frame(
 	struct msm_cam_media_controller *p_mctl,
 	void __user *arg)
@@ -1027,3 +709,54 @@
 
 	return rc;
 }
+
+int msm_mctl_pp_get_vpe_buf_info(struct msm_mctl_pp_frame_info *zoom)
+{
+	struct msm_cam_media_controller *p_mctl;
+	struct msm_cam_v4l2_dev_inst *pcam_inst;
+	int rc = 0, idx;
+
+	if (!zoom || !zoom->p_mctl) {
+		pr_err("%s Invalid input, not sending buffer to VPE ",
+			__func__);
+		return -EINVAL;
+	}
+	p_mctl = zoom->p_mctl;
+	idx = msm_mctl_pp_path_to_inst_index(p_mctl->pcam_ptr,
+		zoom->pp_frame_cmd.path);
+	if (idx < 0) {
+		pr_err("%s Invalid path, returning\n", __func__);
+		return idx;
+	}
+	pcam_inst = p_mctl->pcam_ptr->dev_inst[idx];
+	if (!pcam_inst) {
+		pr_err("%s Invalid instance, returning\n", __func__);
+		return -EINVAL;
+	}
+
+	rc = msm_mctl_pp_get_phy_addr(pcam_inst,
+		zoom->pp_frame_cmd.src_buf_handle, &zoom->src_frame);
+	if (rc) {
+		pr_err("%s Error getting buffer address for src frame\n",
+			__func__);
+		return rc;
+	}
+
+	rc = msm_mctl_pp_get_phy_addr(pcam_inst,
+		zoom->pp_frame_cmd.dest_buf_handle, &zoom->dest_frame);
+	if (rc) {
+		pr_err("%s Error getting buffer address for dest frame\n",
+			__func__);
+		return rc;
+	}
+
+	rc = msm_mctl_pp_copy_timestamp_and_frame_id(
+		zoom->pp_frame_cmd.src_buf_handle,
+		zoom->pp_frame_cmd.dest_buf_handle);
+	if (rc < 0) {
+		pr_err("%s Error copying timestamp info\n",
+			__func__);
+		return rc;
+	}
+	return rc;
+}
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index 98c1ca0..3611656 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -30,25 +30,24 @@
 atomic_t irq_cnt;
 
 #define VFE32_AXI_OFFSET 0x0050
-#define vfe32_get_ch_ping_addr(chn) \
-	(msm_camera_io_r(vfe32_ctrl->vfebase + 0x0050 + 0x18 * (chn)))
-#define vfe32_get_ch_pong_addr(chn) \
-	(msm_camera_io_r(vfe32_ctrl->vfebase + 0x0050 + 0x18 * (chn) + 4))
-#define vfe32_get_ch_addr(ping_pong, chn) \
-	(((ping_pong) & (1 << (chn))) == 0 ? \
-	vfe32_get_ch_pong_addr(chn) : vfe32_get_ch_ping_addr(chn))
+#define vfe32_get_ch_ping_addr(base, chn) \
+	(msm_camera_io_r((base) + 0x0050 + 0x18 * (chn)))
+#define vfe32_get_ch_pong_addr(base, chn) \
+	(msm_camera_io_r((base) + 0x0050 + 0x18 * (chn) + 4))
+#define vfe32_get_ch_addr(ping_pong, base, chn) \
+	((((ping_pong) & (1 << (chn))) == 0) ? \
+	(vfe32_get_ch_pong_addr((base), chn)) : \
+	(vfe32_get_ch_ping_addr((base), chn)))
 
-#define vfe32_put_ch_ping_addr(chn, addr) \
-	(msm_camera_io_w((addr), vfe32_ctrl->vfebase + 0x0050 + 0x18 * (chn)))
-#define vfe32_put_ch_pong_addr(chn, addr) \
-	(msm_camera_io_w((addr), \
-	vfe32_ctrl->vfebase + 0x0050 + 0x18 * (chn) + 4))
-#define vfe32_put_ch_addr(ping_pong, chn, addr) \
+#define vfe32_put_ch_ping_addr(base, chn, addr) \
+	(msm_camera_io_w((addr), (base) + 0x0050 + 0x18 * (chn)))
+#define vfe32_put_ch_pong_addr(base, chn, addr) \
+	(msm_camera_io_w((addr), (base) + 0x0050 + 0x18 * (chn) + 4))
+#define vfe32_put_ch_addr(ping_pong, base, chn, addr) \
 	(((ping_pong) & (1 << (chn))) == 0 ?   \
-	vfe32_put_ch_pong_addr((chn), (addr)) : \
-	vfe32_put_ch_ping_addr((chn), (addr)))
+	vfe32_put_ch_pong_addr((base), (chn), (addr)) : \
+	vfe32_put_ch_ping_addr((base), (chn), (addr)))
 
-static struct vfe32_ctrl_type *vfe32_ctrl;
 static uint32_t vfe_clk_rate;
 
 struct vfe32_isr_queue_cmd {
@@ -357,112 +356,117 @@
 	"DEMOSAICV3_UPDATE",
 };
 
-static void vfe32_stop(void)
+static void vfe32_stop(struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	unsigned long flags;
 
-	atomic_set(&vfe32_ctrl->vstate, 0);
+	atomic_set(&vfe32_ctrl->share_ctrl->vstate, 0);
 
 	/* for reset hw modules, and send msg when reset_irq comes.*/
-	spin_lock_irqsave(&vfe32_ctrl->stop_flag_lock, flags);
-	vfe32_ctrl->stop_ack_pending = TRUE;
-	spin_unlock_irqrestore(&vfe32_ctrl->stop_flag_lock, flags);
+	spin_lock_irqsave(&vfe32_ctrl->share_ctrl->stop_flag_lock, flags);
+	vfe32_ctrl->share_ctrl->stop_ack_pending = TRUE;
+	spin_unlock_irqrestore(&vfe32_ctrl->share_ctrl->stop_flag_lock, flags);
 
 	/* disable all interrupts.  */
 	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
-		vfe32_ctrl->vfebase + VFE_IRQ_MASK_0);
+		vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
 	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
-			vfe32_ctrl->vfebase + VFE_IRQ_MASK_1);
+			vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
 
 	/* clear all pending interrupts*/
 	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
-		vfe32_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+		vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
 	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
-		vfe32_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+		vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
 	/* Ensure the write order while writing
 	to the command register using the barrier */
 	msm_camera_io_w_mb(1,
-		vfe32_ctrl->vfebase + VFE_IRQ_CMD);
+		vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_CMD);
 
 	/* in either continuous or snapshot mode, stop command can be issued
 	 * at any time. stop camif immediately. */
 	msm_camera_io_w(CAMIF_COMMAND_STOP_IMMEDIATELY,
-		vfe32_ctrl->vfebase + VFE_CAMIF_COMMAND);
-
+		vfe32_ctrl->share_ctrl->vfebase + VFE_CAMIF_COMMAND);
 }
 
-static void vfe32_subdev_notify(int id, int path)
+static void vfe32_subdev_notify(int id, int path,
+	struct v4l2_subdev *sd, struct vfe_share_ctrl_t *share_ctrl)
 {
 	struct msm_vfe_resp rp;
 	unsigned long flags = 0;
-	spin_lock_irqsave(&vfe32_ctrl->sd_notify_lock, flags);
+	spin_lock_irqsave(&share_ctrl->sd_notify_lock, flags);
 	CDBG("vfe32_subdev_notify : msgId = %d\n", id);
 	memset(&rp, 0, sizeof(struct msm_vfe_resp));
 	rp.evt_msg.type   = MSM_CAMERA_MSG;
 	rp.evt_msg.msg_id = path;
 	rp.type	   = id;
-	v4l2_subdev_notify(&vfe32_ctrl->subdev, NOTIFY_VFE_BUF_EVT, &rp);
-	spin_unlock_irqrestore(&vfe32_ctrl->sd_notify_lock, flags);
+	v4l2_subdev_notify(sd, NOTIFY_VFE_BUF_EVT, &rp);
+	spin_unlock_irqrestore(&share_ctrl->sd_notify_lock, flags);
 }
 
-static int vfe32_config_axi(int mode, uint32_t *ao)
+static int vfe32_config_axi(
+	struct axi_ctrl_t *axi_ctrl, int mode, uint32_t *ao)
 {
 	uint32_t *ch_info;
 	uint32_t *axi_cfg = ao+V32_AXI_BUS_FMT_OFF;
 
 	/* Update the corresponding write masters for each output*/
 	ch_info = axi_cfg + V32_AXI_CFG_LEN;
-	vfe32_ctrl->outpath.out0.ch0 = 0x0000FFFF & *ch_info;
-	vfe32_ctrl->outpath.out0.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
-	vfe32_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info++;
-	vfe32_ctrl->outpath.out1.ch0 = 0x0000FFFF & *ch_info;
-	vfe32_ctrl->outpath.out1.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
-	vfe32_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info++;
-	vfe32_ctrl->outpath.out2.ch0 = 0x0000FFFF & *ch_info;
-	vfe32_ctrl->outpath.out2.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
-	vfe32_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info++;
+	axi_ctrl->share_ctrl->outpath.out0.ch0 = 0x0000FFFF & *ch_info;
+	axi_ctrl->share_ctrl->outpath.out0.ch1 =
+		0x0000FFFF & (*ch_info++ >> 16);
+	axi_ctrl->share_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info++;
+	axi_ctrl->share_ctrl->outpath.out1.ch0 = 0x0000FFFF & *ch_info;
+	axi_ctrl->share_ctrl->outpath.out1.ch1 =
+		0x0000FFFF & (*ch_info++ >> 16);
+	axi_ctrl->share_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info++;
+	axi_ctrl->share_ctrl->outpath.out2.ch0 = 0x0000FFFF & *ch_info;
+	axi_ctrl->share_ctrl->outpath.out2.ch1 =
+		0x0000FFFF & (*ch_info++ >> 16);
+	axi_ctrl->share_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info++;
 
 	switch (mode) {
 	case OUTPUT_PRIM:
-		vfe32_ctrl->outpath.output_mode =
+		axi_ctrl->share_ctrl->outpath.output_mode =
 			VFE32_OUTPUT_MODE_PRIMARY;
 		break;
 	case OUTPUT_PRIM_ALL_CHNLS:
-		vfe32_ctrl->outpath.output_mode =
+		axi_ctrl->share_ctrl->outpath.output_mode =
 			VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
 		break;
 	case OUTPUT_PRIM|OUTPUT_SEC:
-		vfe32_ctrl->outpath.output_mode =
+		axi_ctrl->share_ctrl->outpath.output_mode =
 			VFE32_OUTPUT_MODE_PRIMARY;
-		vfe32_ctrl->outpath.output_mode |=
+		axi_ctrl->share_ctrl->outpath.output_mode |=
 			VFE32_OUTPUT_MODE_SECONDARY;
 		break;
 	case OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS:
-		vfe32_ctrl->outpath.output_mode =
+		axi_ctrl->share_ctrl->outpath.output_mode =
 			VFE32_OUTPUT_MODE_PRIMARY;
-		vfe32_ctrl->outpath.output_mode |=
+		axi_ctrl->share_ctrl->outpath.output_mode |=
 			VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS;
 		break;
 	case OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC:
-		vfe32_ctrl->outpath.output_mode =
+		axi_ctrl->share_ctrl->outpath.output_mode =
 			VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
-		vfe32_ctrl->outpath.output_mode |=
+		axi_ctrl->share_ctrl->outpath.output_mode |=
 			VFE32_OUTPUT_MODE_SECONDARY;
 		break;
 	default:
 		pr_err("%s Invalid AXI mode %d ", __func__, mode);
 		return -EINVAL;
 	}
-	msm_camera_io_w(*ao, vfe32_ctrl->vfebase +
+	msm_camera_io_w(*ao, axi_ctrl->share_ctrl->vfebase +
 		VFE_BUS_IO_FORMAT_CFG);
-	msm_camera_io_memcpy(vfe32_ctrl->vfebase +
+	msm_camera_io_memcpy(axi_ctrl->share_ctrl->vfebase +
 		vfe32_cmd[VFE_CMD_AXI_OUT_CFG].offset, axi_cfg,
 		vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length - V32_AXI_CH_INF_LEN
 		- V32_AXI_BUS_FMT_LEN);
 	return 0;
 }
 
-static void vfe32_reset_internal_variables(void)
+static void vfe32_reset_internal_variables(
+	struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	unsigned long flags;
 	vfe32_ctrl->vfeImaskCompositePacked = 0;
@@ -470,9 +474,9 @@
 	vfe32_ctrl->start_ack_pending = FALSE;
 	atomic_set(&irq_cnt, 0);
 
-	spin_lock_irqsave(&vfe32_ctrl->stop_flag_lock, flags);
-	vfe32_ctrl->stop_ack_pending  = FALSE;
-	spin_unlock_irqrestore(&vfe32_ctrl->stop_flag_lock, flags);
+	spin_lock_irqsave(&vfe32_ctrl->share_ctrl->stop_flag_lock, flags);
+	vfe32_ctrl->share_ctrl->stop_ack_pending  = FALSE;
+	spin_unlock_irqrestore(&vfe32_ctrl->share_ctrl->stop_flag_lock, flags);
 
 	vfe32_ctrl->reset_ack_pending  = FALSE;
 
@@ -481,17 +485,17 @@
 	spin_unlock_irqrestore(&vfe32_ctrl->update_ack_lock, flags);
 
 	vfe32_ctrl->recording_state = VFE_STATE_IDLE;
-	vfe32_ctrl->liveshot_state = VFE_STATE_IDLE;
+	vfe32_ctrl->share_ctrl->liveshot_state = VFE_STATE_IDLE;
 
-	atomic_set(&vfe32_ctrl->vstate, 0);
+	atomic_set(&vfe32_ctrl->share_ctrl->vstate, 0);
 
 	/* 0 for continuous mode, 1 for snapshot mode */
-	vfe32_ctrl->operation_mode = 0;
-	vfe32_ctrl->outpath.output_mode = 0;
-	vfe32_ctrl->vfe_capture_count = 0;
+	vfe32_ctrl->share_ctrl->operation_mode = 0;
+	vfe32_ctrl->share_ctrl->outpath.output_mode = 0;
+	vfe32_ctrl->share_ctrl->vfe_capture_count = 0;
 
 	/* this is unsigned 32 bit integer. */
-	vfe32_ctrl->vfeFrameId = 0;
+	vfe32_ctrl->share_ctrl->vfeFrameId = 0;
 	/* Stats control variables. */
 	memset(&(vfe32_ctrl->afStatsControl), 0,
 		sizeof(struct vfe_stats_control));
@@ -516,30 +520,30 @@
 	vfe32_ctrl->snapshot_frame_cnt = 0;
 }
 
-static void vfe32_reset(void)
+static void vfe32_reset(struct vfe32_ctrl_type *vfe32_ctrl)
 {
-	vfe32_reset_internal_variables();
+	vfe32_reset_internal_variables(vfe32_ctrl);
 	/* disable all interrupts.  vfeImaskLocal is also reset to 0
 	* to begin with. */
 	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
-		vfe32_ctrl->vfebase + VFE_IRQ_MASK_0);
+		vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
 
 	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
-		vfe32_ctrl->vfebase + VFE_IRQ_MASK_1);
+		vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
 
 	/* clear all pending interrupts*/
 	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
-		vfe32_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+		vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
 	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
-		vfe32_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+		vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
 
 	/* Ensure the write order while writing
 	to the command register using the barrier */
-	msm_camera_io_w_mb(1, vfe32_ctrl->vfebase + VFE_IRQ_CMD);
+	msm_camera_io_w_mb(1, vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_CMD);
 
 	/* enable reset_ack interrupt.  */
 	msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
-	vfe32_ctrl->vfebase + VFE_IRQ_MASK_1);
+	vfe32_ctrl->share_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
@@ -549,409 +553,516 @@
 	/* Ensure the write order while writing
 	to the command register using the barrier */
 	msm_camera_io_w_mb(VFE_RESET_UPON_RESET_CMD,
-		vfe32_ctrl->vfebase + VFE_GLOBAL_RESET);
+		vfe32_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
 }
 
-static int vfe32_operation_config(uint32_t *cmd)
+static int vfe32_operation_config(uint32_t *cmd,
+			struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	uint32_t *p = cmd;
 
-	vfe32_ctrl->operation_mode = *p;
-	vfe32_ctrl->stats_comp = *(++p);
+	vfe32_ctrl->share_ctrl->operation_mode = *p;
+	vfe32_ctrl->share_ctrl->stats_comp = *(++p);
 	vfe32_ctrl->hfr_mode = *(++p);
 
-	msm_camera_io_w(*(++p), vfe32_ctrl->vfebase + VFE_CFG);
-	msm_camera_io_w(*(++p), vfe32_ctrl->vfebase + VFE_MODULE_CFG);
-	msm_camera_io_w(*(++p), vfe32_ctrl->vfebase + VFE_PIXEL_IF_CFG);
-	if (msm_camera_io_r(vfe32_ctrl->vfebase + V32_GET_HW_VERSION_OFF) ==
+	msm_camera_io_w(*(++p),
+		vfe32_ctrl->share_ctrl->vfebase + VFE_CFG);
+	msm_camera_io_w(*(++p),
+		vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+	msm_camera_io_w(*(++p),
+		vfe32_ctrl->share_ctrl->vfebase + VFE_PIXEL_IF_CFG);
+	if (msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
+		V32_GET_HW_VERSION_OFF) ==
 		VFE33_HW_NUMBER) {
-		msm_camera_io_w(*(++p), vfe32_ctrl->vfebase + VFE_RDI0_CFG);
-		msm_camera_io_w(*(++p), vfe32_ctrl->vfebase + VFE_RDI1_CFG);
+		msm_camera_io_w(*(++p),
+			vfe32_ctrl->share_ctrl->vfebase + VFE_RDI0_CFG);
+		msm_camera_io_w(*(++p),
+			vfe32_ctrl->share_ctrl->vfebase + VFE_RDI1_CFG);
 	}  else {
 		++p;
 		++p;
 	}
-	msm_camera_io_w(*(++p), vfe32_ctrl->vfebase + VFE_REALIGN_BUF);
-	msm_camera_io_w(*(++p), vfe32_ctrl->vfebase + VFE_CHROMA_UP);
-	msm_camera_io_w(*(++p), vfe32_ctrl->vfebase + VFE_STATS_CFG);
+	msm_camera_io_w(*(++p),
+		vfe32_ctrl->share_ctrl->vfebase + VFE_REALIGN_BUF);
+	msm_camera_io_w(*(++p),
+		vfe32_ctrl->share_ctrl->vfebase + VFE_CHROMA_UP);
+	msm_camera_io_w(*(++p),
+		vfe32_ctrl->share_ctrl->vfebase + VFE_STATS_CFG);
 	return 0;
 }
 
-static uint32_t vfe_stats_awb_buf_init(struct vfe_cmd_stats_buf *in)
+static uint32_t vfe_stats_awb_buf_init(
+	struct vfe32_ctrl_type *vfe32_ctrl, struct vfe_cmd_stats_buf *in)
 {
 	uint32_t *ptr = in->statsBuf;
 	uint32_t addr;
 
 	addr = ptr[0];
 	msm_camera_io_w(addr,
-		vfe32_ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_AWB_WR_PING_ADDR);
 	addr = ptr[1];
 	msm_camera_io_w(addr,
-		vfe32_ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_AWB_WR_PONG_ADDR);
 	vfe32_ctrl->awbStatsControl.nextFrameAddrBuf = in->statsBuf[2];
 	return 0;
 }
 
-static uint32_t vfe_stats_aec_buf_init(struct vfe_cmd_stats_buf *in)
+static uint32_t vfe_stats_aec_buf_init(
+	struct vfe32_ctrl_type *vfe32_ctrl, struct vfe_cmd_stats_buf *in)
 {
 	uint32_t *ptr = in->statsBuf;
 	uint32_t addr;
 
 	addr = ptr[0];
 	msm_camera_io_w(addr,
-		vfe32_ctrl->vfebase + VFE_BUS_STATS_AEC_WR_PING_ADDR);
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_AEC_WR_PING_ADDR);
 	addr = ptr[1];
 	msm_camera_io_w(addr,
-		vfe32_ctrl->vfebase + VFE_BUS_STATS_AEC_WR_PONG_ADDR);
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_AEC_WR_PONG_ADDR);
 
 	vfe32_ctrl->aecStatsControl.nextFrameAddrBuf = in->statsBuf[2];
 	return 0;
 }
 
-static uint32_t vfe_stats_af_buf_init(struct vfe_cmd_stats_buf *in)
+static uint32_t vfe_stats_af_buf_init(
+	struct vfe32_ctrl_type *vfe32_ctrl, struct vfe_cmd_stats_buf *in)
 {
 	uint32_t *ptr = in->statsBuf;
 	uint32_t addr;
 
 	addr = ptr[0];
 	msm_camera_io_w(addr,
-		vfe32_ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_AF_WR_PING_ADDR);
 	addr = ptr[1];
 	msm_camera_io_w(addr,
-		vfe32_ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_AF_WR_PONG_ADDR);
 
 	vfe32_ctrl->afStatsControl.nextFrameAddrBuf = in->statsBuf[2];
 	return 0;
 }
 
-static uint32_t vfe_stats_ihist_buf_init(struct vfe_cmd_stats_buf *in)
+static uint32_t vfe_stats_ihist_buf_init(
+	struct vfe32_ctrl_type *vfe32_ctrl, struct vfe_cmd_stats_buf *in)
 {
 	uint32_t *ptr = in->statsBuf;
 	uint32_t addr;
 
 	addr = ptr[0];
 	msm_camera_io_w(addr,
-		vfe32_ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PING_ADDR);
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_HIST_WR_PING_ADDR);
 	addr = ptr[1];
 	msm_camera_io_w(addr,
-		vfe32_ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PONG_ADDR);
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_HIST_WR_PONG_ADDR);
 
 	vfe32_ctrl->ihistStatsControl.nextFrameAddrBuf = in->statsBuf[2];
 	return 0;
 }
 
-static uint32_t vfe_stats_rs_buf_init(struct vfe_cmd_stats_buf *in)
+static uint32_t vfe_stats_rs_buf_init(
+	struct vfe32_ctrl_type *vfe32_ctrl, struct vfe_cmd_stats_buf *in)
 {
 	uint32_t *ptr = in->statsBuf;
 	uint32_t addr;
 
 	addr = ptr[0];
 	msm_camera_io_w(addr,
-		vfe32_ctrl->vfebase + VFE_BUS_STATS_RS_WR_PING_ADDR);
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_RS_WR_PING_ADDR);
 	addr = ptr[1];
 	msm_camera_io_w(addr,
-		vfe32_ctrl->vfebase + VFE_BUS_STATS_RS_WR_PONG_ADDR);
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_RS_WR_PONG_ADDR);
 
 	vfe32_ctrl->rsStatsControl.nextFrameAddrBuf = in->statsBuf[2];
 	return 0;
 }
 
-static uint32_t vfe_stats_cs_buf_init(struct vfe_cmd_stats_buf *in)
+static uint32_t vfe_stats_cs_buf_init(
+	struct vfe32_ctrl_type *vfe32_ctrl, struct vfe_cmd_stats_buf *in)
 {
 	uint32_t *ptr = in->statsBuf;
 	uint32_t addr;
 
 	addr = ptr[0];
 	msm_camera_io_w(addr,
-		vfe32_ctrl->vfebase + VFE_BUS_STATS_CS_WR_PING_ADDR);
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_CS_WR_PING_ADDR);
 	addr = ptr[1];
 	msm_camera_io_w(addr,
-		vfe32_ctrl->vfebase + VFE_BUS_STATS_CS_WR_PONG_ADDR);
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_CS_WR_PONG_ADDR);
 
 	vfe32_ctrl->csStatsControl.nextFrameAddrBuf = in->statsBuf[2];
 	return 0;
 }
 
-static void vfe32_start_common(void)
+static void vfe32_start_common(struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	uint32_t irq_mask = 0x00E00021;
 	vfe32_ctrl->start_ack_pending = TRUE;
 	CDBG("VFE opertaion mode = 0x%x, output mode = 0x%x\n",
-		vfe32_ctrl->operation_mode, vfe32_ctrl->outpath.output_mode);
-	if (vfe32_ctrl->stats_comp)
+		vfe32_ctrl->share_ctrl->operation_mode,
+		vfe32_ctrl->share_ctrl->outpath.output_mode);
+	if (vfe32_ctrl->share_ctrl->stats_comp)
 		irq_mask |= VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK;
 	else
 		irq_mask |= 0x000FE000;
 
-	msm_camera_io_w(irq_mask, vfe32_ctrl->vfebase + VFE_IRQ_MASK_0);
+	msm_camera_io_w(irq_mask,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
 	msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
-		vfe32_ctrl->vfebase + VFE_IRQ_MASK_1);
+		vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
 
 	/* Ensure the write order while writing
 	to the command register using the barrier */
-	msm_camera_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	msm_camera_io_w_mb(1, vfe32_ctrl->vfebase + VFE_CAMIF_COMMAND);
+	msm_camera_io_w_mb(1,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	msm_camera_io_w_mb(1,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_CAMIF_COMMAND);
 
-
-	atomic_set(&vfe32_ctrl->vstate, 1);
+	atomic_set(&vfe32_ctrl->share_ctrl->vstate, 1);
 }
 
-static int vfe32_start_recording(struct msm_cam_media_controller *pmctl)
+static int vfe32_start_recording(
+	struct msm_cam_media_controller *pmctl,
+	struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	msm_camio_bus_scale_cfg(
 		pmctl->sdata->pdata->cam_bus_scale_table, S_VIDEO);
 	vfe32_ctrl->recording_state = VFE_STATE_START_REQUESTED;
-	msm_camera_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	msm_camera_io_w_mb(1,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
 	return 0;
 }
 
-static int vfe32_stop_recording(struct msm_cam_media_controller *pmctl)
+static int vfe32_stop_recording(
+	struct msm_cam_media_controller *pmctl,
+	struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	vfe32_ctrl->recording_state = VFE_STATE_STOP_REQUESTED;
-	msm_camera_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	msm_camera_io_w_mb(1,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
 	msm_camio_bus_scale_cfg(
 		pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
 	return 0;
 }
 
-static void vfe32_start_liveshot(struct msm_cam_media_controller *pmctl)
+static void vfe32_start_liveshot(
+	struct msm_cam_media_controller *pmctl,
+	struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	/* Hardcode 1 live snapshot for now. */
-	vfe32_ctrl->outpath.out0.capture_cnt = 1;
-	vfe32_ctrl->vfe_capture_count = vfe32_ctrl->outpath.out0.capture_cnt;
+	vfe32_ctrl->share_ctrl->outpath.out0.capture_cnt = 1;
+	vfe32_ctrl->share_ctrl->vfe_capture_count =
+		vfe32_ctrl->share_ctrl->outpath.out0.capture_cnt;
 
-	vfe32_ctrl->liveshot_state = VFE_STATE_START_REQUESTED;
-	msm_camera_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	vfe32_ctrl->share_ctrl->liveshot_state = VFE_STATE_START_REQUESTED;
+	msm_camera_io_w_mb(1, vfe32_ctrl->
+		share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
 }
 
-static int vfe32_zsl(struct msm_cam_media_controller *pmctl)
+static int vfe32_zsl(
+	struct msm_cam_media_controller *pmctl,
+	struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	uint32_t irq_comp_mask = 0;
 	/* capture command is valid for both idle and active state. */
 	irq_comp_mask	=
-		msm_camera_io_r(vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+		msm_camera_io_r(vfe32_ctrl->
+		share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
 
 	CDBG("%s:op mode %d O/P Mode %d\n", __func__,
-		vfe32_ctrl->operation_mode, vfe32_ctrl->outpath.output_mode);
+		vfe32_ctrl->share_ctrl->operation_mode,
+		vfe32_ctrl->share_ctrl->outpath.output_mode);
 
-	if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_PRIMARY) {
-		irq_comp_mask |= ((0x1 << (vfe32_ctrl->outpath.out0.ch0)) |
-				(0x1 << (vfe32_ctrl->outpath.out0.ch1)));
-	} else if (vfe32_ctrl->outpath.output_mode &
+	if (vfe32_ctrl->share_ctrl->outpath.output_mode &
+		VFE32_OUTPUT_MODE_PRIMARY) {
+		irq_comp_mask |= (
+			(0x1 << (vfe32_ctrl->share_ctrl->outpath.out0.ch0)) |
+			(0x1 << (vfe32_ctrl->share_ctrl->outpath.out0.ch1)));
+	} else if (vfe32_ctrl->share_ctrl->outpath.output_mode &
 			VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
-		irq_comp_mask |= ((0x1 << (vfe32_ctrl->outpath.out0.ch0)) |
-				(0x1 << (vfe32_ctrl->outpath.out0.ch1)) |
-				(0x1 << (vfe32_ctrl->outpath.out0.ch2)));
+		irq_comp_mask |= (
+			(0x1 << (vfe32_ctrl->share_ctrl->outpath.out0.ch0)) |
+			(0x1 << (vfe32_ctrl->share_ctrl->outpath.out0.ch1)) |
+			(0x1 << (vfe32_ctrl->share_ctrl->outpath.out0.ch2)));
 	}
 
-	if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_SECONDARY) {
-		irq_comp_mask |= ((0x1 << (vfe32_ctrl->outpath.out1.ch0 + 8)) |
-				(0x1 << (vfe32_ctrl->outpath.out1.ch1 + 8)));
-	} else if (vfe32_ctrl->outpath.output_mode &
+	if (vfe32_ctrl->share_ctrl->outpath.output_mode &
+		VFE32_OUTPUT_MODE_SECONDARY) {
+		irq_comp_mask |= ((0x1 << (vfe32_ctrl->
+				share_ctrl->outpath.out1.ch0 + 8)) |
+			(0x1 << (vfe32_ctrl->
+				share_ctrl->outpath.out1.ch1 + 8)));
+	} else if (vfe32_ctrl->share_ctrl->outpath.output_mode &
 			   VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
-		irq_comp_mask |= ((0x1 << (vfe32_ctrl->outpath.out1.ch0 + 8)) |
-				(0x1 << (vfe32_ctrl->outpath.out1.ch1 + 8)) |
-				(0x1 << (vfe32_ctrl->outpath.out1.ch2 + 8)));
+		irq_comp_mask |= (
+			(0x1 << (vfe32_ctrl->
+				share_ctrl->outpath.out1.ch0 + 8)) |
+			(0x1 << (vfe32_ctrl->
+				share_ctrl->outpath.out1.ch1 + 8)) |
+			(0x1 << (vfe32_ctrl->
+				share_ctrl->outpath.out1.ch2 + 8)));
 	}
 
-	if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_PRIMARY) {
-		msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
-		msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
-	} else if (vfe32_ctrl->outpath.output_mode &
+	if (vfe32_ctrl->share_ctrl->outpath.output_mode &
+			VFE32_OUTPUT_MODE_PRIMARY) {
+		msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[vfe32_ctrl->
+			share_ctrl->outpath.out0.ch0]);
+		msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[vfe32_ctrl->
+			share_ctrl->outpath.out0.ch1]);
+	} else if (vfe32_ctrl->share_ctrl->outpath.output_mode &
 				VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
-		msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
-		msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
-		msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch2]);
+		msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[vfe32_ctrl->
+			share_ctrl->outpath.out0.ch0]);
+		msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[vfe32_ctrl->
+			share_ctrl->outpath.out0.ch1]);
+		msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[vfe32_ctrl->
+			share_ctrl->outpath.out0.ch2]);
 	}
 
-	if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_SECONDARY) {
-		msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
-		msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
-	} else if (vfe32_ctrl->outpath.output_mode &
+	if (vfe32_ctrl->share_ctrl->outpath.output_mode &
+			VFE32_OUTPUT_MODE_SECONDARY) {
+		msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[vfe32_ctrl->
+			share_ctrl->outpath.out1.ch0]);
+		msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[vfe32_ctrl->
+			share_ctrl->outpath.out1.ch1]);
+	} else if (vfe32_ctrl->share_ctrl->outpath.output_mode &
 				VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
-		msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
-		msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
-		msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch2]);
+		msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[vfe32_ctrl->
+			share_ctrl->outpath.out1.ch0]);
+		msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[vfe32_ctrl->
+			share_ctrl->outpath.out1.ch1]);
+		msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[vfe32_ctrl->
+			share_ctrl->outpath.out1.ch2]);
 	}
 
-	msm_camera_io_w(irq_comp_mask, vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-	vfe32_start_common();
+	msm_camera_io_w(irq_comp_mask,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+	vfe32_start_common(vfe32_ctrl);
 	msm_camio_bus_scale_cfg(
 		pmctl->sdata->pdata->cam_bus_scale_table, S_ZSL);
 
-	msm_camera_io_w(1, vfe32_ctrl->vfebase + 0x18C);
-	msm_camera_io_w(1, vfe32_ctrl->vfebase + 0x188);
+	msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase + 0x18C);
+	msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase + 0x188);
 	return 0;
 }
 static int vfe32_capture_raw(
 	struct msm_cam_media_controller *pmctl,
+	struct vfe32_ctrl_type *vfe32_ctrl,
 	uint32_t num_frames_capture)
 {
 	uint32_t irq_comp_mask = 0;
 
-	vfe32_ctrl->outpath.out0.capture_cnt = num_frames_capture;
-	vfe32_ctrl->vfe_capture_count = num_frames_capture;
+	vfe32_ctrl->share_ctrl->outpath.out0.capture_cnt = num_frames_capture;
+	vfe32_ctrl->share_ctrl->vfe_capture_count = num_frames_capture;
 
 	irq_comp_mask	=
-		msm_camera_io_r(vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+		msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
 
-	if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_PRIMARY) {
-		irq_comp_mask |= (0x1 << (vfe32_ctrl->outpath.out0.ch0));
-		msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
+	if (vfe32_ctrl->share_ctrl->outpath.output_mode &
+		VFE32_OUTPUT_MODE_PRIMARY) {
+		irq_comp_mask |=
+			(0x1 << (vfe32_ctrl->share_ctrl->outpath.out0.ch0));
+		msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[vfe32_ctrl->
+			share_ctrl->outpath.out0.ch0]);
 	}
 
-	msm_camera_io_w(irq_comp_mask, vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+	msm_camera_io_w(irq_comp_mask,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
 	msm_camio_bus_scale_cfg(
 		pmctl->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
-	vfe32_start_common();
+	vfe32_start_common(vfe32_ctrl);
 	return 0;
 }
 
 static int vfe32_capture(
 	struct msm_cam_media_controller *pmctl,
-	uint32_t num_frames_capture)
+	uint32_t num_frames_capture,
+	struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	uint32_t irq_comp_mask = 0;
 
 	/* capture command is valid for both idle and active state. */
-	vfe32_ctrl->outpath.out1.capture_cnt = num_frames_capture;
-	if (vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
-		vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN ||
-		vfe32_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
-		vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) {
-		vfe32_ctrl->outpath.out0.capture_cnt =
+	vfe32_ctrl->share_ctrl->outpath.out1.capture_cnt = num_frames_capture;
+	if (vfe32_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_MAIN_AND_THUMB ||
+		vfe32_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_THUMB_AND_MAIN ||
+		vfe32_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_JPEG_AND_THUMB ||
+		vfe32_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_THUMB_AND_JPEG) {
+		vfe32_ctrl->share_ctrl->outpath.out0.capture_cnt =
 			num_frames_capture;
 	}
 
-	vfe32_ctrl->vfe_capture_count = num_frames_capture;
+	vfe32_ctrl->share_ctrl->vfe_capture_count = num_frames_capture;
 	irq_comp_mask = msm_camera_io_r(
-				vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+			vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
 
-	if (vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
-		vfe32_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
-		vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN) {
-		if (vfe32_ctrl->outpath.output_mode &
+	if (vfe32_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_MAIN_AND_THUMB ||
+		vfe32_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_JPEG_AND_THUMB ||
+		vfe32_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_THUMB_AND_MAIN) {
+		if (vfe32_ctrl->share_ctrl->outpath.output_mode &
 			VFE32_OUTPUT_MODE_PRIMARY) {
-			irq_comp_mask |= (0x1 << vfe32_ctrl->outpath.out0.ch0 |
-					0x1 << vfe32_ctrl->outpath.out0.ch1);
+			irq_comp_mask |= (0x1 << vfe32_ctrl->
+				share_ctrl->outpath.out0.ch0 |
+				0x1 << vfe32_ctrl->
+				share_ctrl->outpath.out0.ch1);
 		}
-		if (vfe32_ctrl->outpath.output_mode &
+		if (vfe32_ctrl->share_ctrl->outpath.output_mode &
 			VFE32_OUTPUT_MODE_SECONDARY) {
 			irq_comp_mask |=
-				(0x1 << (vfe32_ctrl->outpath.out1.ch0 + 8) |
-				0x1 << (vfe32_ctrl->outpath.out1.ch1 + 8));
+				(0x1 << (vfe32_ctrl->
+					share_ctrl->outpath.out1.ch0 + 8) |
+				0x1 << (vfe32_ctrl->
+					share_ctrl->outpath.out1.ch1 + 8));
 		}
-		if (vfe32_ctrl->outpath.output_mode &
+		if (vfe32_ctrl->share_ctrl->outpath.output_mode &
 			VFE32_OUTPUT_MODE_PRIMARY) {
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
+			msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[vfe32_ctrl->
+				share_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[vfe32_ctrl->
+				share_ctrl->outpath.out0.ch1]);
 		}
-		if (vfe32_ctrl->outpath.output_mode &
+		if (vfe32_ctrl->share_ctrl->outpath.output_mode &
 			VFE32_OUTPUT_MODE_SECONDARY) {
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
+			msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[vfe32_ctrl->
+				share_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[vfe32_ctrl->
+				share_ctrl->outpath.out1.ch1]);
 		}
 	}
 
-	vfe32_ctrl->vfe_capture_count = num_frames_capture;
+	vfe32_ctrl->share_ctrl->vfe_capture_count = num_frames_capture;
 
-	msm_camera_io_w(irq_comp_mask, vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-	msm_camera_io_r(vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+	msm_camera_io_w(irq_comp_mask,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+	msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
 	msm_camio_bus_scale_cfg(
 		pmctl->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
 
-	vfe32_start_common();
+	vfe32_start_common(vfe32_ctrl);
 	/* for debug */
-	msm_camera_io_w(1, vfe32_ctrl->vfebase + 0x18C);
-	msm_camera_io_w(1, vfe32_ctrl->vfebase + 0x188);
+	msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase + 0x18C);
+	msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase + 0x188);
 	return 0;
 }
 
-static int vfe32_start(struct msm_cam_media_controller *pmctl)
+static int vfe32_start(
+	struct msm_cam_media_controller *pmctl,
+	struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	uint32_t irq_comp_mask = 0;
 	irq_comp_mask	=
-		msm_camera_io_r(vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+		msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
+			VFE_IRQ_COMP_MASK);
 
-	if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_PRIMARY) {
-		irq_comp_mask |= (0x1 << vfe32_ctrl->outpath.out0.ch0 |
-			0x1 << vfe32_ctrl->outpath.out0.ch1);
-	} else if (vfe32_ctrl->outpath.output_mode &
+	if (vfe32_ctrl->share_ctrl->outpath.output_mode &
+			VFE32_OUTPUT_MODE_PRIMARY) {
+		irq_comp_mask |= (
+			0x1 << vfe32_ctrl->share_ctrl->outpath.out0.ch0 |
+			0x1 << vfe32_ctrl->share_ctrl->outpath.out0.ch1);
+	} else if (vfe32_ctrl->share_ctrl->outpath.output_mode &
 			   VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
-		irq_comp_mask |= (0x1 << vfe32_ctrl->outpath.out0.ch0 |
-			0x1 << vfe32_ctrl->outpath.out0.ch1 |
-			0x1 << vfe32_ctrl->outpath.out0.ch2);
+		irq_comp_mask |= (
+			0x1 << vfe32_ctrl->share_ctrl->outpath.out0.ch0 |
+			0x1 << vfe32_ctrl->share_ctrl->outpath.out0.ch1 |
+			0x1 << vfe32_ctrl->share_ctrl->outpath.out0.ch2);
 	}
-	if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_SECONDARY) {
-		irq_comp_mask |= (0x1 << (vfe32_ctrl->outpath.out1.ch0 + 8) |
-			0x1 << (vfe32_ctrl->outpath.out1.ch1 + 8));
-	} else if (vfe32_ctrl->outpath.output_mode &
+	if (vfe32_ctrl->share_ctrl->outpath.output_mode &
+			VFE32_OUTPUT_MODE_SECONDARY) {
+		irq_comp_mask |= (
+			0x1 << (vfe32_ctrl->share_ctrl->outpath.out1.ch0 + 8) |
+			0x1 << (vfe32_ctrl->share_ctrl->outpath.out1.ch1 + 8));
+	} else if (vfe32_ctrl->share_ctrl->outpath.output_mode &
 			VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
-		irq_comp_mask |= (0x1 << (vfe32_ctrl->outpath.out1.ch0 + 8) |
-			0x1 << (vfe32_ctrl->outpath.out1.ch1 + 8) |
-			0x1 << (vfe32_ctrl->outpath.out1.ch2 + 8));
+		irq_comp_mask |= (
+			0x1 << (vfe32_ctrl->share_ctrl->outpath.out1.ch0 + 8) |
+			0x1 << (vfe32_ctrl->share_ctrl->outpath.out1.ch1 + 8) |
+			0x1 << (vfe32_ctrl->share_ctrl->outpath.out1.ch2 + 8));
 	}
-	msm_camera_io_w(irq_comp_mask, vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+	msm_camera_io_w(irq_comp_mask,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
 
 	msm_camio_bus_scale_cfg(
 		pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
-	vfe32_start_common();
+	vfe32_start_common(vfe32_ctrl);
 	return 0;
 }
 
-static void vfe32_update(void)
+static void vfe32_update(struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	unsigned long flags;
 	uint32_t value = 0;
 	if (vfe32_ctrl->update_linear) {
 		if (!msm_camera_io_r(
-			vfe32_ctrl->vfebase + V32_LINEARIZATION_OFF1))
+			vfe32_ctrl->share_ctrl->vfebase +
+			V32_LINEARIZATION_OFF1))
 			msm_camera_io_w(1,
-				vfe32_ctrl->vfebase + V32_LINEARIZATION_OFF1);
+				vfe32_ctrl->share_ctrl->vfebase +
+				V32_LINEARIZATION_OFF1);
 		else
 			msm_camera_io_w(0,
-				vfe32_ctrl->vfebase + V32_LINEARIZATION_OFF1);
+				vfe32_ctrl->share_ctrl->vfebase +
+				V32_LINEARIZATION_OFF1);
 		vfe32_ctrl->update_linear = false;
 	}
 
 	if (vfe32_ctrl->update_rolloff) {
-		value = msm_camera_io_r(vfe32_ctrl->vfebase +
+		value = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
 			V33_PCA_ROLL_OFF_CFG_OFF1);
 		value ^= V33_PCA_ROLL_OFF_LUT_BANK_SEL_MASK;
-		msm_camera_io_w(value, vfe32_ctrl->vfebase +
+		msm_camera_io_w(value, vfe32_ctrl->share_ctrl->vfebase +
 			V33_PCA_ROLL_OFF_CFG_OFF1);
 		vfe32_ctrl->update_rolloff = false;
 	}
 
 	if (vfe32_ctrl->update_la) {
-		if (!msm_camera_io_r(vfe32_ctrl->vfebase + V32_LA_OFF))
+		if (!msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + V32_LA_OFF))
 			msm_camera_io_w(1,
-				vfe32_ctrl->vfebase + V32_LA_OFF);
+				vfe32_ctrl->share_ctrl->vfebase + V32_LA_OFF);
 		else
 			msm_camera_io_w(0,
-				vfe32_ctrl->vfebase + V32_LA_OFF);
+				vfe32_ctrl->share_ctrl->vfebase + V32_LA_OFF);
 		vfe32_ctrl->update_la = false;
 	}
 
 	if (vfe32_ctrl->update_gamma) {
-		value = msm_camera_io_r(vfe32_ctrl->vfebase + V32_RGB_G_OFF);
+		value = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + V32_RGB_G_OFF);
 		value ^= V32_GAMMA_LUT_BANK_SEL_MASK;
-		msm_camera_io_w(value, vfe32_ctrl->vfebase + V32_RGB_G_OFF);
+		msm_camera_io_w(value,
+			vfe32_ctrl->share_ctrl->vfebase + V32_RGB_G_OFF);
 		vfe32_ctrl->update_gamma = false;
 	}
 
@@ -960,11 +1071,12 @@
 	spin_unlock_irqrestore(&vfe32_ctrl->update_ack_lock, flags);
 	/* Ensure the write order while writing
 	to the command register using the barrier */
-	msm_camera_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	msm_camera_io_w_mb(1,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
 	return;
 }
 
-static void vfe32_sync_timer_stop(void)
+static void vfe32_sync_timer_stop(struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	uint32_t value = 0;
 	vfe32_ctrl->sync_timer_state = 0;
@@ -976,10 +1088,13 @@
 		value = 0x40000;
 
 	/* Timer Stop */
-	msm_camera_io_w(value, vfe32_ctrl->vfebase + V32_SYNC_TIMER_OFF);
+	msm_camera_io_w(value,
+		vfe32_ctrl->share_ctrl->vfebase + V32_SYNC_TIMER_OFF);
 }
 
-static void vfe32_sync_timer_start(const uint32_t *tbl)
+static void vfe32_sync_timer_start(
+	const uint32_t *tbl,
+	struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	/* set bit 8 for auto increment. */
 	uint32_t value = 1;
@@ -1001,14 +1116,17 @@
 	}
 
 	/* Timer Start */
-	msm_camera_io_w(value, vfe32_ctrl->vfebase + V32_SYNC_TIMER_OFF);
+	msm_camera_io_w(value,
+		vfe32_ctrl->share_ctrl->vfebase + V32_SYNC_TIMER_OFF);
 	/* Sync Timer Line Start */
 	value = *tbl++;
-	msm_camera_io_w(value, vfe32_ctrl->vfebase + V32_SYNC_TIMER_OFF +
+	msm_camera_io_w(value,
+		vfe32_ctrl->share_ctrl->vfebase + V32_SYNC_TIMER_OFF +
 		4 + ((vfe32_ctrl->sync_timer_number) * 12));
 	/* Sync Timer Pixel Start */
 	value = *tbl++;
-	msm_camera_io_w(value, vfe32_ctrl->vfebase + V32_SYNC_TIMER_OFF +
+	msm_camera_io_w(value,
+			vfe32_ctrl->share_ctrl->vfebase + V32_SYNC_TIMER_OFF +
 			 8 + ((vfe32_ctrl->sync_timer_number) * 12));
 	/* Sync Timer Pixel Duration */
 	value = *tbl++;
@@ -1016,87 +1134,99 @@
 	val = 10000000 / val;
 	val = value * 10000 / val;
 	CDBG("%s: Pixel Clk Cycles!!! %d\n", __func__, val);
-	msm_camera_io_w(val, vfe32_ctrl->vfebase + V32_SYNC_TIMER_OFF +
+	msm_camera_io_w(val,
+		vfe32_ctrl->share_ctrl->vfebase + V32_SYNC_TIMER_OFF +
 		12 + ((vfe32_ctrl->sync_timer_number) * 12));
 	/* Timer0 Active High/LOW */
 	value = *tbl++;
 	msm_camera_io_w(value,
-		vfe32_ctrl->vfebase + V32_SYNC_TIMER_POLARITY_OFF);
+		vfe32_ctrl->share_ctrl->vfebase + V32_SYNC_TIMER_POLARITY_OFF);
 	/* Selects sync timer 0 output to drive onto timer1 port */
 	value = 0;
-	msm_camera_io_w(value, vfe32_ctrl->vfebase + V32_TIMER_SELECT_OFF);
+	msm_camera_io_w(value,
+		vfe32_ctrl->share_ctrl->vfebase + V32_TIMER_SELECT_OFF);
 }
 
-static void vfe32_program_dmi_cfg(enum VFE32_DMI_RAM_SEL bankSel)
+static void vfe32_program_dmi_cfg(
+	enum VFE32_DMI_RAM_SEL bankSel,
+	struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	/* 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_camera_io_w(value, vfe32_ctrl->vfebase + VFE_DMI_CFG);
+	msm_camera_io_w(value, vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_CFG);
 	/* by default, always starts with offset 0.*/
-	msm_camera_io_w(0, vfe32_ctrl->vfebase + VFE_DMI_ADDR);
+	msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_ADDR);
 }
-static void vfe32_write_gamma_cfg(enum VFE32_DMI_RAM_SEL channel_sel,
-						const uint32_t *tbl)
+static void vfe32_write_gamma_cfg(
+	enum VFE32_DMI_RAM_SEL channel_sel,
+	const uint32_t *tbl,
+	struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	int i;
 	uint32_t value, value1, value2;
-	vfe32_program_dmi_cfg(channel_sel);
+	vfe32_program_dmi_cfg(channel_sel, vfe32_ctrl);
 	for (i = 0 ; i < (VFE32_GAMMA_NUM_ENTRIES/2) ; i++) {
 		value = *tbl++;
 		value1 = value & 0x0000FFFF;
 		value2 = (value & 0xFFFF0000)>>16;
 		msm_camera_io_w((value1),
-			vfe32_ctrl->vfebase + VFE_DMI_DATA_LO);
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
 		msm_camera_io_w((value2),
-			vfe32_ctrl->vfebase + VFE_DMI_DATA_LO);
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
 	}
-	vfe32_program_dmi_cfg(NO_MEM_SELECTED);
+	vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
 }
 
-static void vfe32_read_gamma_cfg(enum VFE32_DMI_RAM_SEL channel_sel,
-	uint32_t *tbl)
+static void vfe32_read_gamma_cfg(
+	enum VFE32_DMI_RAM_SEL channel_sel,
+	uint32_t *tbl,
+	struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	int i;
-	vfe32_program_dmi_cfg(channel_sel);
+	vfe32_program_dmi_cfg(channel_sel, vfe32_ctrl);
 	CDBG("%s: Gamma table channel: %d\n", __func__, channel_sel);
 	for (i = 0 ; i < VFE32_GAMMA_NUM_ENTRIES ; i++) {
-		*tbl = msm_camera_io_r(vfe32_ctrl->vfebase + VFE_DMI_DATA_LO);
+		*tbl = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
 		CDBG("%s: %08x\n", __func__, *tbl);
 		tbl++;
 	}
-	vfe32_program_dmi_cfg(NO_MEM_SELECTED);
+	vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
 }
 
-static void vfe32_write_la_cfg(enum VFE32_DMI_RAM_SEL channel_sel,
-						const uint32_t *tbl)
+static void vfe32_write_la_cfg(
+	enum VFE32_DMI_RAM_SEL channel_sel,
+	const uint32_t *tbl,
+	struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	uint32_t i;
 	uint32_t value, value1, value2;
 
-	vfe32_program_dmi_cfg(channel_sel);
+	vfe32_program_dmi_cfg(channel_sel, vfe32_ctrl);
 	for (i = 0 ; i < (VFE32_LA_TABLE_LENGTH/2) ; i++) {
 		value = *tbl++;
 		value1 = value & 0x0000FFFF;
 		value2 = (value & 0xFFFF0000)>>16;
 		msm_camera_io_w((value1),
-			vfe32_ctrl->vfebase + VFE_DMI_DATA_LO);
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
 		msm_camera_io_w((value2),
-			vfe32_ctrl->vfebase + VFE_DMI_DATA_LO);
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
 	}
-	vfe32_program_dmi_cfg(NO_MEM_SELECTED);
+	vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
 }
 
-static struct vfe32_output_ch *vfe32_get_ch(int path)
+static struct vfe32_output_ch *vfe32_get_ch(
+	int path, struct vfe_share_ctrl_t *share_ctrl)
 {
 	struct vfe32_output_ch *ch = NULL;
 
 	if (path == VFE_MSG_OUTPUT_PRIMARY)
-		ch = &vfe32_ctrl->outpath.out0;
+		ch = &share_ctrl->outpath.out0;
 	else if (path == VFE_MSG_OUTPUT_SECONDARY)
-		ch = &vfe32_ctrl->outpath.out1;
+		ch = &share_ctrl->outpath.out1;
 	else
 		pr_err("%s: Invalid path %d\n", __func__,
 			path);
@@ -1104,44 +1234,54 @@
 	BUG_ON(ch == NULL);
 	return ch;
 }
-static struct msm_free_buf *vfe32_check_free_buffer(int id, int path)
+static struct msm_free_buf *vfe32_check_free_buffer(
+	int id, int path, struct axi_ctrl_t *axi_ctrl)
 {
 	struct vfe32_output_ch *outch = NULL;
 	struct msm_free_buf *b = NULL;
-	vfe32_subdev_notify(id, path);
-	outch = vfe32_get_ch(path);
+	vfe32_subdev_notify(id, path,
+		&axi_ctrl->subdev, axi_ctrl->share_ctrl);
+	outch = vfe32_get_ch(path, axi_ctrl->share_ctrl);
 	if (outch->free_buf.ch_paddr[0])
 		b = &outch->free_buf;
 	return b;
 }
-static int vfe32_configure_pingpong_buffers(int id, int path)
+static int vfe32_configure_pingpong_buffers(
+	int id, int path, struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	struct vfe32_output_ch *outch = NULL;
 	int rc = 0;
-	vfe32_subdev_notify(id, path);
-	outch = vfe32_get_ch(path);
+	vfe32_subdev_notify(id, path,
+		&vfe32_ctrl->subdev, vfe32_ctrl->share_ctrl);
+	outch = vfe32_get_ch(path, vfe32_ctrl->share_ctrl);
 	if (outch->ping.ch_paddr[0] && outch->pong.ch_paddr[0]) {
 		/* Configure Preview Ping Pong */
 		pr_info("%s Configure ping/pong address for %d",
 						__func__, path);
-		vfe32_put_ch_ping_addr(outch->ch0,
+		vfe32_put_ch_ping_addr(
+			vfe32_ctrl->share_ctrl->vfebase, outch->ch0,
 			outch->ping.ch_paddr[0]);
-		vfe32_put_ch_pong_addr(outch->ch0,
+		vfe32_put_ch_pong_addr(
+			vfe32_ctrl->share_ctrl->vfebase, outch->ch0,
 			outch->pong.ch_paddr[0]);
 
-		if (vfe32_ctrl->operation_mode !=
+		if (vfe32_ctrl->share_ctrl->operation_mode !=
 			VFE_OUTPUTS_RAW) {
-			vfe32_put_ch_ping_addr(outch->ch1,
+			vfe32_put_ch_ping_addr(
+				vfe32_ctrl->share_ctrl->vfebase, outch->ch1,
 				outch->ping.ch_paddr[1]);
-			vfe32_put_ch_pong_addr(outch->ch1,
+			vfe32_put_ch_pong_addr(
+				vfe32_ctrl->share_ctrl->vfebase, outch->ch1,
 				outch->pong.ch_paddr[1]);
 		}
 
 		if (outch->ping.num_planes > 2)
-			vfe32_put_ch_ping_addr(outch->ch2,
+			vfe32_put_ch_ping_addr(
+				vfe32_ctrl->share_ctrl->vfebase, outch->ch2,
 				outch->ping.ch_paddr[2]);
 		if (outch->pong.num_planes > 2)
-			vfe32_put_ch_pong_addr(outch->ch2,
+			vfe32_put_ch_pong_addr(
+				vfe32_ctrl->share_ctrl->vfebase, outch->ch2,
 				outch->pong.ch_paddr[2]);
 
 		/* avoid stale info */
@@ -1154,37 +1294,41 @@
 	return rc;
 }
 
-static void vfe32_write_linear_cfg(enum VFE32_DMI_RAM_SEL channel_sel,
-	const uint32_t *tbl)
+static void vfe32_write_linear_cfg(
+	enum VFE32_DMI_RAM_SEL channel_sel,
+	const uint32_t *tbl, struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	uint32_t i;
 
-	vfe32_program_dmi_cfg(channel_sel);
+	vfe32_program_dmi_cfg(channel_sel, vfe32_ctrl);
 	/* for loop for configuring LUT. */
 	for (i = 0 ; i < VFE32_LINEARIZATON_TABLE_LENGTH ; i++) {
-		msm_camera_io_w(*tbl, vfe32_ctrl->vfebase + VFE_DMI_DATA_LO);
+		msm_camera_io_w(*tbl,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
 		tbl++;
 	}
 	CDBG("done writing to linearization table\n");
-	vfe32_program_dmi_cfg(NO_MEM_SELECTED);
+	vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
 }
 
 static void vfe32_send_isp_msg(
-	struct vfe32_ctrl_type *vctrl,
+	struct v4l2_subdev *sd,
+	uint32_t vfeFrameId,
 	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 = vfe32_ctrl->vfeFrameId;
-	v4l2_subdev_notify(&vctrl->subdev,
+	isp_msg_evt.sof_count = vfeFrameId;
+	v4l2_subdev_notify(sd,
 			NOTIFY_ISP_MSG_EVT,
 			(void *)&isp_msg_evt);
 }
 
 static int vfe32_proc_general(
 	struct msm_cam_media_controller *pmctl,
-	struct msm_isp_cmd *cmd)
+	struct msm_isp_cmd *cmd,
+	struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	int i , rc = 0;
 	uint32_t old_val = 0 , new_val = 0;
@@ -1199,32 +1343,34 @@
 	case VFE_CMD_RESET:
 		pr_info("vfe32_proc_general: cmdID = %s\n",
 			vfe32_general_cmd[cmd->id]);
-		vfe32_reset();
+		vfe32_reset(vfe32_ctrl);
 		break;
 	case VFE_CMD_START:
 		pr_info("vfe32_proc_general: cmdID = %s\n",
 			vfe32_general_cmd[cmd->id]);
-		if ((vfe32_ctrl->operation_mode ==
+		if ((vfe32_ctrl->share_ctrl->operation_mode ==
 				VFE_OUTPUTS_PREVIEW_AND_VIDEO) ||
-				(vfe32_ctrl->operation_mode ==
+				(vfe32_ctrl->share_ctrl->operation_mode ==
 				VFE_OUTPUTS_PREVIEW))
 			/* Configure primary channel */
 			rc = vfe32_configure_pingpong_buffers(
-				VFE_MSG_V32_START, VFE_MSG_OUTPUT_PRIMARY);
+				VFE_MSG_V32_START, VFE_MSG_OUTPUT_PRIMARY,
+				vfe32_ctrl);
 		else
 			/* Configure secondary channel */
 			rc = vfe32_configure_pingpong_buffers(
-				VFE_MSG_V32_START, VFE_MSG_OUTPUT_SECONDARY);
+				VFE_MSG_V32_START, VFE_MSG_OUTPUT_SECONDARY,
+				vfe32_ctrl);
 		if (rc < 0) {
 			pr_err("%s error configuring pingpong buffers"
 				   " for preview", __func__);
 			rc = -EINVAL;
 			goto proc_general_done;
 		}
-		rc = vfe32_start(pmctl);
+		rc = vfe32_start(pmctl, vfe32_ctrl);
 		break;
 	case VFE_CMD_UPDATE:
-		vfe32_update();
+		vfe32_update(vfe32_ctrl);
 		break;
 	case VFE_CMD_CAPTURE_RAW:
 		pr_info("%s: cmdID = VFE_CMD_CAPTURE_RAW\n", __func__);
@@ -1233,15 +1379,16 @@
 			rc = -EFAULT;
 			goto proc_general_done;
 		}
-		rc = vfe32_configure_pingpong_buffers(VFE_MSG_V32_CAPTURE,
-							VFE_MSG_OUTPUT_PRIMARY);
+		rc = vfe32_configure_pingpong_buffers(
+			VFE_MSG_V32_CAPTURE, VFE_MSG_OUTPUT_PRIMARY,
+			vfe32_ctrl);
 		if (rc < 0) {
 			pr_err("%s error configuring pingpong buffers"
 				   " for snapshot", __func__);
 			rc = -EINVAL;
 			goto proc_general_done;
 		}
-		rc = vfe32_capture_raw(pmctl, snapshot_cnt);
+		rc = vfe32_capture_raw(pmctl, vfe32_ctrl, snapshot_cnt);
 		break;
 	case VFE_CMD_CAPTURE:
 		if (copy_from_user(&snapshot_cnt, (void __user *)(cmd->value),
@@ -1250,8 +1397,10 @@
 			goto proc_general_done;
 		}
 
-		if (vfe32_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
-		vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) {
+		if (vfe32_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_JPEG_AND_THUMB ||
+		vfe32_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_THUMB_AND_JPEG) {
 			if (snapshot_cnt != 1) {
 				pr_err("only support 1 inline snapshot\n");
 				rc = -EINVAL;
@@ -1260,12 +1409,14 @@
 			/* Configure primary channel for JPEG */
 			rc = vfe32_configure_pingpong_buffers(
 				VFE_MSG_V32_JPEG_CAPTURE,
-				VFE_MSG_OUTPUT_PRIMARY);
+				VFE_MSG_OUTPUT_PRIMARY,
+				vfe32_ctrl);
 		} else {
 			/* Configure primary channel */
 			rc = vfe32_configure_pingpong_buffers(
 				VFE_MSG_V32_CAPTURE,
-				VFE_MSG_OUTPUT_PRIMARY);
+				VFE_MSG_OUTPUT_PRIMARY,
+				vfe32_ctrl);
 		}
 		if (rc < 0) {
 			pr_err("%s error configuring pingpong buffers"
@@ -1274,41 +1425,44 @@
 			goto proc_general_done;
 		}
 		/* Configure secondary channel */
-		rc = vfe32_configure_pingpong_buffers(VFE_MSG_V32_CAPTURE,
-						  VFE_MSG_OUTPUT_SECONDARY);
+		rc = vfe32_configure_pingpong_buffers(
+				VFE_MSG_V32_CAPTURE, VFE_MSG_OUTPUT_SECONDARY,
+				vfe32_ctrl);
 		if (rc < 0) {
 			pr_err("%s error configuring pingpong buffers"
 				   " for secondary output", __func__);
 			rc = -EINVAL;
 			goto proc_general_done;
 		}
-		rc = vfe32_capture(pmctl, snapshot_cnt);
+		rc = vfe32_capture(pmctl, snapshot_cnt, vfe32_ctrl);
 		break;
 	case VFE_CMD_START_RECORDING:
 		pr_info("vfe32_proc_general: cmdID = %s\n",
 			vfe32_general_cmd[cmd->id]);
-		if (vfe32_ctrl->operation_mode ==
+		if (vfe32_ctrl->share_ctrl->operation_mode ==
 			VFE_OUTPUTS_PREVIEW_AND_VIDEO)
 			rc = vfe32_configure_pingpong_buffers(
 				VFE_MSG_V32_START_RECORDING,
-				VFE_MSG_OUTPUT_SECONDARY);
-		else if (vfe32_ctrl->operation_mode ==
+				VFE_MSG_OUTPUT_SECONDARY,
+				vfe32_ctrl);
+		else if (vfe32_ctrl->share_ctrl->operation_mode ==
 			VFE_OUTPUTS_VIDEO_AND_PREVIEW)
 			rc = vfe32_configure_pingpong_buffers(
 				VFE_MSG_V32_START_RECORDING,
-				VFE_MSG_OUTPUT_PRIMARY);
+				VFE_MSG_OUTPUT_PRIMARY,
+				vfe32_ctrl);
 		if (rc < 0) {
 			pr_err("%s error configuring pingpong buffers"
 				" for video", __func__);
 			rc = -EINVAL;
 			goto proc_general_done;
 		}
-		rc = vfe32_start_recording(pmctl);
+		rc = vfe32_start_recording(pmctl, vfe32_ctrl);
 		break;
 	case VFE_CMD_STOP_RECORDING:
 		pr_info("vfe32_proc_general: cmdID = %s\n",
 			vfe32_general_cmd[cmd->id]);
-		rc = vfe32_stop_recording(pmctl);
+		rc = vfe32_stop_recording(pmctl, vfe32_ctrl);
 		break;
 	case VFE_CMD_OPERATION_CFG: {
 		if (cmd->length != V32_OPERATION_CFG_LEN) {
@@ -1322,7 +1476,7 @@
 			rc = -EFAULT;
 			goto proc_general_done;
 		}
-		rc = vfe32_operation_config(cmdp);
+		rc = vfe32_operation_config(cmdp, vfe32_ctrl);
 		}
 		break;
 
@@ -1338,12 +1492,14 @@
 			rc = -EFAULT;
 			goto proc_general_done;
 		}
-		old_val = msm_camera_io_r(vfe32_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
 		old_val |= AE_BG_ENABLE_MASK;
 		msm_camera_io_w(old_val,
-			vfe32_ctrl->vfebase + VFE_MODULE_CFG);
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + vfe32_cmd[cmd->id].offset,
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
 			cmdp, (vfe32_cmd[cmd->id].length));
 		}
 		break;
@@ -1359,12 +1515,14 @@
 			rc = -EFAULT;
 			goto proc_general_done;
 		}
-		old_val = msm_camera_io_r(vfe32_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
+			VFE_MODULE_CFG);
 		old_val |= AF_BF_ENABLE_MASK;
 		msm_camera_io_w(old_val,
-			vfe32_ctrl->vfebase + VFE_MODULE_CFG);
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + vfe32_cmd[cmd->id].offset,
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
 			cmdp, (vfe32_cmd[cmd->id].length));
 		}
 		break;
@@ -1380,12 +1538,14 @@
 			rc = -EFAULT;
 			goto proc_general_done;
 		}
-		old_val = msm_camera_io_r(vfe32_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
 		old_val |= AWB_ENABLE_MASK;
 		msm_camera_io_w(old_val,
-			vfe32_ctrl->vfebase + VFE_MODULE_CFG);
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + vfe32_cmd[cmd->id].offset,
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
 			cmdp, (vfe32_cmd[cmd->id].length));
 		}
 		break;
@@ -1402,12 +1562,14 @@
 			rc = -EFAULT;
 			goto proc_general_done;
 		}
-		old_val = msm_camera_io_r(vfe32_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
 		old_val |= IHIST_ENABLE_MASK;
 		msm_camera_io_w(old_val,
-			vfe32_ctrl->vfebase + VFE_MODULE_CFG);
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + vfe32_cmd[cmd->id].offset,
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
 			cmdp, (vfe32_cmd[cmd->id].length));
 		}
 		break;
@@ -1426,7 +1588,8 @@
 			goto proc_general_done;
 		}
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + vfe32_cmd[cmd->id].offset,
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
 			cmdp, (vfe32_cmd[cmd->id].length));
 		}
 		break;
@@ -1444,7 +1607,8 @@
 			goto proc_general_done;
 		}
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + vfe32_cmd[cmd->id].offset,
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
 			cmdp, (vfe32_cmd[cmd->id].length));
 		}
 		break;
@@ -1454,7 +1618,7 @@
 		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_camera_io_r(vfe32_ctrl->vfebase +
+		old_val = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
 			V32_CHROMA_SUP_OFF + 4);
 		if (!cmdp) {
 			rc = -ENOMEM;
@@ -1471,21 +1635,22 @@
 		old_val &= MCE_EN_MASK;
 		new_val = new_val | old_val;
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + V32_CHROMA_SUP_OFF + 4,
-			&new_val, 4);
+			vfe32_ctrl->share_ctrl->vfebase +
+			V32_CHROMA_SUP_OFF + 4, &new_val, 4);
 		cmdp_local += 1;
 
-		old_val = msm_camera_io_r(vfe32_ctrl->vfebase +
+		old_val = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
 			V32_CHROMA_SUP_OFF + 8);
 		new_val = *cmdp_local;
 		old_val &= MCE_Q_K_MASK;
 		new_val = new_val | old_val;
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + V32_CHROMA_SUP_OFF + 8,
-			&new_val, 4);
+			vfe32_ctrl->share_ctrl->vfebase +
+			V32_CHROMA_SUP_OFF + 8, &new_val, 4);
 		cmdp_local += 1;
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + vfe32_cmd[cmd->id].offset,
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
 			cmdp_local, (vfe32_cmd[cmd->id].length));
 		}
 		break;
@@ -1503,31 +1668,31 @@
 			goto proc_general_done;
 		}
 		cmdp_local = cmdp;
-		msm_camera_io_memcpy(vfe32_ctrl->vfebase + V32_CHROMA_SUP_OFF,
-			cmdp_local, 4);
+		msm_camera_io_memcpy(vfe32_ctrl->share_ctrl->vfebase +
+			V32_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_camera_io_r(vfe32_ctrl->vfebase +
+		old_val = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
 			V32_CHROMA_SUP_OFF + 4);
 		old_val &= ~MCE_EN_MASK;
 		new_val = new_val | old_val;
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + V32_CHROMA_SUP_OFF + 4,
-			&new_val, 4);
+			vfe32_ctrl->share_ctrl->vfebase +
+			V32_CHROMA_SUP_OFF + 4, &new_val, 4);
 		cmdp_local += 1;
 
-		old_val = msm_camera_io_r(vfe32_ctrl->vfebase +
+		old_val = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
 			V32_CHROMA_SUP_OFF + 8);
 		new_val = *cmdp_local;
 		old_val &= ~MCE_Q_K_MASK;
 		new_val = new_val | old_val;
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + V32_CHROMA_SUP_OFF + 8,
-			&new_val, 4);
+			vfe32_ctrl->share_ctrl->vfebase +
+			V32_CHROMA_SUP_OFF + 8, &new_val, 4);
 		}
 		break;
 	case VFE_CMD_BLACK_LEVEL_CFG:
@@ -1547,27 +1712,28 @@
 		}
 		cmdp_local = cmdp;
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + vfe32_cmd[cmd->id].offset,
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
 			cmdp_local, 16);
 		cmdp_local += 4;
-		vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0);
+		vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0, vfe32_ctrl);
 		/* for loop for extrcting init table. */
 		for (i = 0; i < (V32_MESH_ROLL_OFF_INIT_TABLE_SIZE * 2); i++) {
 			msm_camera_io_w(*cmdp_local ,
-			vfe32_ctrl->vfebase + VFE_DMI_DATA_LO);
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
 			cmdp_local++;
 		}
 		CDBG("done writing init table\n");
 		/* by default, always starts with offset 0. */
 		msm_camera_io_w(V32_MESH_ROLL_OFF_DELTA_TABLE_OFFSET,
-		vfe32_ctrl->vfebase + VFE_DMI_ADDR);
+		vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_ADDR);
 		/* for loop for extracting delta table. */
 		for (i = 0; i < (V32_MESH_ROLL_OFF_DELTA_TABLE_SIZE * 2); i++) {
 			msm_camera_io_w(*cmdp_local,
-			vfe32_ctrl->vfebase + VFE_DMI_DATA_LO);
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
 			cmdp_local++;
 		}
-		vfe32_program_dmi_cfg(NO_MEM_SELECTED);
+		vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
 		}
 		break;
 
@@ -1584,27 +1750,29 @@
 			goto proc_general_done;
 		}
 		cmdp_local = cmdp;
-		vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0);
+		vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0, vfe32_ctrl);
 		CDBG("%s: Mesh Rolloff init Table\n", __func__);
 		for (i = 0; i < (V32_MESH_ROLL_OFF_INIT_TABLE_SIZE * 2); i++) {
 			*cmdp_local =
 				msm_camera_io_r(
-					vfe32_ctrl->vfebase + VFE_DMI_DATA_LO);
+					vfe32_ctrl->share_ctrl->vfebase +
+					VFE_DMI_DATA_LO);
 			CDBG("%s: %08x\n", __func__, *cmdp_local);
 			cmdp_local++;
 		}
 		msm_camera_io_w(V32_MESH_ROLL_OFF_DELTA_TABLE_OFFSET,
-			vfe32_ctrl->vfebase + VFE_DMI_ADDR);
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_ADDR);
 		CDBG("%s: Mesh Rolloff Delta Table\n", __func__);
 		for (i = 0; i < (V32_MESH_ROLL_OFF_DELTA_TABLE_SIZE * 2); i++) {
 			*cmdp_local =
 				msm_camera_io_r(
-					vfe32_ctrl->vfebase + VFE_DMI_DATA_LO);
+					vfe32_ctrl->share_ctrl->vfebase +
+					VFE_DMI_DATA_LO);
 			CDBG("%s: %08x\n", __func__, *cmdp_local);
 			cmdp_local++;
 		}
 		CDBG("done reading delta table\n");
-		vfe32_program_dmi_cfg(NO_MEM_SELECTED);
+		vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
 		if (copy_to_user((void __user *)(cmd->value), cmdp,
 			temp1)) {
 			rc = -EFAULT;
@@ -1626,11 +1794,13 @@
 		}
 		cmdp_local = cmdp;
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + vfe32_cmd[cmd->id].offset,
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
 			cmdp_local, (vfe32_cmd[cmd->id].length));
 
 		cmdp_local += 1;
-		vfe32_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0, cmdp_local);
+		vfe32_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0,
+						   cmdp_local, vfe32_ctrl);
 		break;
 
 	case VFE_CMD_LA_UPDATE: {
@@ -1648,13 +1818,14 @@
 		}
 
 		cmdp_local = cmdp + 1;
-		old_val = msm_camera_io_r(vfe32_ctrl->vfebase + V32_LA_OFF);
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + V32_LA_OFF);
 		if (old_val != 0x0)
 			vfe32_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0,
-				cmdp_local);
+				cmdp_local, vfe32_ctrl);
 		else
 			vfe32_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK1,
-				cmdp_local);
+				cmdp_local, vfe32_ctrl);
 		}
 		vfe32_ctrl->update_la = true;
 		break;
@@ -1671,19 +1842,24 @@
 			goto proc_general_done;
 		}
 		cmdp_local = cmdp;
-		if (msm_camera_io_r(vfe32_ctrl->vfebase + V32_LA_OFF))
-			vfe32_program_dmi_cfg(LUMA_ADAPT_LUT_RAM_BANK1);
+		if (msm_camera_io_r(vfe32_ctrl->
+				share_ctrl->vfebase + V32_LA_OFF))
+			vfe32_program_dmi_cfg(LUMA_ADAPT_LUT_RAM_BANK1,
+						vfe32_ctrl);
 		else
-			vfe32_program_dmi_cfg(LUMA_ADAPT_LUT_RAM_BANK0);
+			vfe32_program_dmi_cfg(LUMA_ADAPT_LUT_RAM_BANK0,
+						vfe32_ctrl);
 		for (i = 0 ; i < (VFE32_LA_TABLE_LENGTH / 2) ; i++) {
 			*cmdp_local =
 				msm_camera_io_r(
-					vfe32_ctrl->vfebase + VFE_DMI_DATA_LO);
-			*cmdp_local |= (msm_camera_io_r(vfe32_ctrl->vfebase +
+					vfe32_ctrl->share_ctrl->vfebase +
+					VFE_DMI_DATA_LO);
+			*cmdp_local |= (msm_camera_io_r(
+				vfe32_ctrl->share_ctrl->vfebase +
 				VFE_DMI_DATA_LO)) << 16;
 			cmdp_local++;
 		}
-		vfe32_program_dmi_cfg(NO_MEM_SELECTED);
+		vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
 		if (copy_to_user((void __user *)(cmd->value), cmdp,
 			temp1)) {
 			rc = -EFAULT;
@@ -1703,22 +1879,23 @@
 			rc = -EFAULT;
 			goto proc_general_done;
 		}
-		msm_camera_io_memcpy(vfe32_ctrl->vfebase + V32_SCE_OFF,
-				cmdp, V32_SCE_LEN);
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase + V32_SCE_OFF,
+			cmdp, V32_SCE_LEN);
 		}
 		break;
 
 	case VFE_CMD_LIVESHOT:
 		/* Configure primary channel */
 		rc = vfe32_configure_pingpong_buffers(VFE_MSG_V32_CAPTURE,
-						VFE_MSG_OUTPUT_PRIMARY);
+					VFE_MSG_OUTPUT_PRIMARY, vfe32_ctrl);
 		if (rc < 0) {
 			pr_err("%s error configuring pingpong buffers"
 				   " for primary output", __func__);
 			rc = -EINVAL;
 			goto proc_general_done;
 		}
-		vfe32_start_liveshot(pmctl);
+		vfe32_start_liveshot(pmctl, vfe32_ctrl);
 		break;
 
 	case VFE_CMD_LINEARIZATION_CFG:
@@ -1734,15 +1911,18 @@
 		}
 		cmdp_local = cmdp;
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + V32_LINEARIZATION_OFF1,
+			vfe32_ctrl->share_ctrl->vfebase +
+			V32_LINEARIZATION_OFF1,
 			cmdp_local, V32_LINEARIZATION_LEN1);
 		cmdp_local += 4;
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + V32_LINEARIZATION_OFF2,
+			vfe32_ctrl->share_ctrl->vfebase +
+			V32_LINEARIZATION_OFF2,
 			cmdp_local, V32_LINEARIZATION_LEN2);
 
 		cmdp_local = cmdp + 17;
-		vfe32_write_linear_cfg(BLACK_LUT_RAM_BANK0, cmdp_local);
+		vfe32_write_linear_cfg(BLACK_LUT_RAM_BANK0,
+					cmdp_local, vfe32_ctrl);
 		break;
 
 	case VFE_CMD_LINEARIZATION_UPDATE:
@@ -1759,21 +1939,26 @@
 		cmdp_local = cmdp;
 		cmdp_local++;
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + V32_LINEARIZATION_OFF1 + 4,
+			vfe32_ctrl->share_ctrl->vfebase +
+			V32_LINEARIZATION_OFF1 + 4,
 			cmdp_local, (V32_LINEARIZATION_LEN1 - 4));
 		cmdp_local += 3;
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + V32_LINEARIZATION_OFF2,
+			vfe32_ctrl->share_ctrl->vfebase +
+			V32_LINEARIZATION_OFF2,
 			cmdp_local, V32_LINEARIZATION_LEN2);
 		cmdp_local = cmdp + 17;
 		/*extracting the bank select*/
 		old_val = msm_camera_io_r(
-				vfe32_ctrl->vfebase + V32_LINEARIZATION_OFF1);
+				vfe32_ctrl->share_ctrl->vfebase +
+				V32_LINEARIZATION_OFF1);
 
 		if (old_val != 0x0)
-			vfe32_write_linear_cfg(BLACK_LUT_RAM_BANK0, cmdp_local);
+			vfe32_write_linear_cfg(BLACK_LUT_RAM_BANK0,
+						cmdp_local, vfe32_ctrl);
 		else
-			vfe32_write_linear_cfg(BLACK_LUT_RAM_BANK1, cmdp_local);
+			vfe32_write_linear_cfg(BLACK_LUT_RAM_BANK1,
+						cmdp_local, vfe32_ctrl);
 		vfe32_ctrl->update_linear = true;
 		break;
 
@@ -1790,18 +1975,20 @@
 		}
 		cmdp_local = cmdp;
 		if (msm_camera_io_r(
-			vfe32_ctrl->vfebase + V32_LINEARIZATION_OFF1))
-			vfe32_program_dmi_cfg(BLACK_LUT_RAM_BANK1);
+			vfe32_ctrl->share_ctrl->vfebase +
+			V32_LINEARIZATION_OFF1))
+			vfe32_program_dmi_cfg(BLACK_LUT_RAM_BANK1, vfe32_ctrl);
 		else
-			vfe32_program_dmi_cfg(BLACK_LUT_RAM_BANK0);
+			vfe32_program_dmi_cfg(BLACK_LUT_RAM_BANK0, vfe32_ctrl);
 		CDBG("%s: Linearization Table\n", __func__);
 		for (i = 0 ; i < VFE32_LINEARIZATON_TABLE_LENGTH ; i++) {
 			*cmdp_local = msm_camera_io_r(
-					vfe32_ctrl->vfebase + VFE_DMI_DATA_LO);
+				vfe32_ctrl->share_ctrl->vfebase +
+				VFE_DMI_DATA_LO);
 			CDBG("%s: %08x\n", __func__, *cmdp_local);
 			cmdp_local++;
 		}
-		vfe32_program_dmi_cfg(NO_MEM_SELECTED);
+		vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
 		if (copy_to_user((void __user *)(cmd->value), cmdp,
 			temp1)) {
 			rc = -EFAULT;
@@ -1829,15 +2016,17 @@
 		new_val = *cmdp_local;
 
 		old_val = msm_camera_io_r(
-				vfe32_ctrl->vfebase + V32_DEMOSAICV3_0_OFF);
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF);
 		old_val &= DEMOSAIC_MASK;
 		new_val = new_val | old_val;
 		*cmdp_local = new_val;
 
-		msm_camera_io_memcpy(vfe32_ctrl->vfebase + V32_DEMOSAICV3_0_OFF,
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF,
 			cmdp_local, V32_DEMOSAICV3_0_LEN);
 		cmdp_local += 1;
-		msm_camera_io_memcpy(vfe32_ctrl->vfebase + V32_DEMOSAICV3_1_OFF,
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_1_OFF,
 			cmdp_local, V32_DEMOSAICV3_1_LEN);
 		break;
 
@@ -1862,22 +2051,25 @@
 		new_val = *cmdp_local;
 
 		old_val = msm_camera_io_r(
-				vfe32_ctrl->vfebase + V32_DEMOSAICV3_0_OFF);
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF);
 		old_val &= DEMOSAIC_MASK;
 		new_val = new_val | old_val;
 		*cmdp_local = new_val;
 
-		msm_camera_io_memcpy(vfe32_ctrl->vfebase + V32_DEMOSAICV3_0_OFF,
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF,
 			cmdp_local, V32_DEMOSAICV3_0_LEN);
 		/* As the address space is not contiguous increment by 2
 		 * before copying to next address space */
 		cmdp_local += 1;
-		msm_camera_io_memcpy(vfe32_ctrl->vfebase + V32_DEMOSAICV3_1_OFF,
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_1_OFF,
 			cmdp_local, 2 * V32_DEMOSAICV3_0_LEN);
 		/* As the address space is not contiguous increment by 2
 		 * before copying to next address space */
 		cmdp_local += 2;
-		msm_camera_io_memcpy(vfe32_ctrl->vfebase + V32_DEMOSAICV3_2_OFF,
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_2_OFF,
 			cmdp_local, 2 * V32_DEMOSAICV3_0_LEN);
 		break;
 
@@ -1902,17 +2094,19 @@
 		new_val = *cmdp_local;
 
 		old_val = msm_camera_io_r(
-				vfe32_ctrl->vfebase + V32_DEMOSAICV3_0_OFF);
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF);
 		old_val &= ABF_MASK;
 		new_val = new_val | old_val;
 		*cmdp_local = new_val;
 
-		msm_camera_io_memcpy(vfe32_ctrl->vfebase + V32_DEMOSAICV3_0_OFF,
-		    cmdp_local, 4);
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF,
+			cmdp_local, 4);
 
 		cmdp_local += 1;
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + vfe32_cmd[cmd->id].offset,
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
 			cmdp_local, (vfe32_cmd[cmd->id].length));
 		}
 		break;
@@ -1934,16 +2128,18 @@
 		new_val = *cmdp_local;
 
 		old_val = msm_camera_io_r(
-				vfe32_ctrl->vfebase + V32_DEMOSAICV3_0_OFF);
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF);
 		old_val &= DBCC_MASK;
 
 		new_val = new_val | old_val;
 		*cmdp_local = new_val;
-		msm_camera_io_memcpy(vfe32_ctrl->vfebase + V32_DEMOSAICV3_0_OFF,
-					cmdp_local, 4);
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF,
+			cmdp_local, 4);
 		cmdp_local += 1;
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + vfe32_cmd[cmd->id].offset,
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
 			cmdp_local, (vfe32_cmd[cmd->id].length));
 		break;
 
@@ -1964,28 +2160,28 @@
 		new_val = *cmdp_local;
 
 		old_val = msm_camera_io_r(
-				vfe32_ctrl->vfebase + V32_DEMOSAICV3_0_OFF);
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF);
 		old_val &= DBPC_MASK;
 
 		new_val = new_val | old_val;
 		*cmdp_local = new_val;
-		msm_camera_io_memcpy(vfe32_ctrl->vfebase +
+		msm_camera_io_memcpy(vfe32_ctrl->share_ctrl->vfebase +
 			V32_DEMOSAICV3_0_OFF,
 			cmdp_local, V32_DEMOSAICV3_LEN);
 		cmdp_local += 1;
-		msm_camera_io_memcpy(vfe32_ctrl->vfebase +
+		msm_camera_io_memcpy(vfe32_ctrl->share_ctrl->vfebase +
 			V32_DEMOSAICV3_DBPC_CFG_OFF,
 			cmdp_local, V32_DEMOSAICV3_DBPC_LEN);
 		cmdp_local += 1;
-		msm_camera_io_memcpy(vfe32_ctrl->vfebase +
+		msm_camera_io_memcpy(vfe32_ctrl->share_ctrl->vfebase +
 			V32_DEMOSAICV3_DBPC_CFG_OFF0,
 			cmdp_local, V32_DEMOSAICV3_DBPC_LEN);
 		cmdp_local += 1;
-		msm_camera_io_memcpy(vfe32_ctrl->vfebase +
+		msm_camera_io_memcpy(vfe32_ctrl->share_ctrl->vfebase +
 			V32_DEMOSAICV3_DBPC_CFG_OFF1,
 			cmdp_local, V32_DEMOSAICV3_DBPC_LEN);
 		cmdp_local += 1;
-		msm_camera_io_memcpy(vfe32_ctrl->vfebase +
+		msm_camera_io_memcpy(vfe32_ctrl->share_ctrl->vfebase +
 			V32_DEMOSAICV3_DBPC_CFG_OFF2,
 			cmdp_local, V32_DEMOSAICV3_DBPC_LEN);
 		break;
@@ -2002,13 +2198,14 @@
 			rc = -EFAULT;
 			goto proc_general_done;
 		}
-		msm_camera_io_memcpy(vfe32_ctrl->vfebase + V32_RGB_G_OFF,
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase + V32_RGB_G_OFF,
 			cmdp, 4);
 		cmdp += 1;
 
-		vfe32_write_gamma_cfg(RGBLUT_RAM_CH0_BANK0, cmdp);
-		vfe32_write_gamma_cfg(RGBLUT_RAM_CH1_BANK0, cmdp);
-		vfe32_write_gamma_cfg(RGBLUT_RAM_CH2_BANK0, cmdp);
+		vfe32_write_gamma_cfg(RGBLUT_RAM_CH0_BANK0, cmdp, vfe32_ctrl);
+		vfe32_write_gamma_cfg(RGBLUT_RAM_CH1_BANK0, cmdp, vfe32_ctrl);
+		vfe32_write_gamma_cfg(RGBLUT_RAM_CH2_BANK0, cmdp, vfe32_ctrl);
 		}
 	    cmdp -= 1;
 		break;
@@ -2025,16 +2222,23 @@
 			goto proc_general_done;
 		}
 
-		old_val = msm_camera_io_r(vfe32_ctrl->vfebase + V32_RGB_G_OFF);
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + V32_RGB_G_OFF);
 		cmdp += 1;
 		if (old_val != 0x0) {
-			vfe32_write_gamma_cfg(RGBLUT_RAM_CH0_BANK0, cmdp);
-			vfe32_write_gamma_cfg(RGBLUT_RAM_CH1_BANK0, cmdp);
-			vfe32_write_gamma_cfg(RGBLUT_RAM_CH2_BANK0, cmdp);
+			vfe32_write_gamma_cfg(
+				RGBLUT_RAM_CH0_BANK0, cmdp, vfe32_ctrl);
+			vfe32_write_gamma_cfg(
+				RGBLUT_RAM_CH1_BANK0, cmdp, vfe32_ctrl);
+			vfe32_write_gamma_cfg(
+				RGBLUT_RAM_CH2_BANK0, cmdp, vfe32_ctrl);
 		} else {
-			vfe32_write_gamma_cfg(RGBLUT_RAM_CH0_BANK1, cmdp);
-			vfe32_write_gamma_cfg(RGBLUT_RAM_CH1_BANK1, cmdp);
-			vfe32_write_gamma_cfg(RGBLUT_RAM_CH2_BANK1, cmdp);
+			vfe32_write_gamma_cfg(
+				RGBLUT_RAM_CH0_BANK1, cmdp, vfe32_ctrl);
+			vfe32_write_gamma_cfg(
+				RGBLUT_RAM_CH1_BANK1, cmdp, vfe32_ctrl);
+			vfe32_write_gamma_cfg(
+				RGBLUT_RAM_CH2_BANK1, cmdp, vfe32_ctrl);
 		}
 		}
 		vfe32_ctrl->update_gamma = TRUE;
@@ -2054,12 +2258,14 @@
 		}
 		cmdp_local = cmdp;
 
-		old_val = msm_camera_io_r(vfe32_ctrl->vfebase + V32_RGB_G_OFF);
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + V32_RGB_G_OFF);
 		temp2 = old_val ? RGBLUT_RAM_CH0_BANK1 :
 			RGBLUT_RAM_CH0_BANK0;
 		for (i = 0; i < 3; i++) {
 			vfe32_read_gamma_cfg(temp2,
-				cmdp_local + (VFE32_GAMMA_NUM_ENTRIES * i));
+				cmdp_local + (VFE32_GAMMA_NUM_ENTRIES * i),
+				vfe32_ctrl);
 			temp2 += 2;
 		}
 		if (copy_to_user((void __user *)(cmd->value), cmdp,
@@ -2070,54 +2276,60 @@
 		break;
 
 	case VFE_CMD_STATS_AWB_STOP: {
-		old_val = msm_camera_io_r(vfe32_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
 		old_val &= ~AWB_ENABLE_MASK;
 		msm_camera_io_w(old_val,
-			vfe32_ctrl->vfebase + VFE_MODULE_CFG);
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
 		}
 		break;
 	case VFE_CMD_STATS_AE_STOP: {
-		old_val = msm_camera_io_r(vfe32_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
 		old_val &= ~AE_BG_ENABLE_MASK;
 		msm_camera_io_w(old_val,
-			vfe32_ctrl->vfebase + VFE_MODULE_CFG);
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
 		}
 		break;
 	case VFE_CMD_STATS_AF_STOP: {
-		old_val = msm_camera_io_r(vfe32_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
 		old_val &= ~AF_BF_ENABLE_MASK;
 		msm_camera_io_w(old_val,
-			vfe32_ctrl->vfebase + VFE_MODULE_CFG);
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
 		}
 		break;
 
 	case VFE_CMD_STATS_IHIST_STOP: {
-		old_val = msm_camera_io_r(vfe32_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
 		old_val &= ~IHIST_ENABLE_MASK;
 		msm_camera_io_w(old_val,
-			vfe32_ctrl->vfebase + VFE_MODULE_CFG);
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
 		}
 		break;
 
 	case VFE_CMD_STATS_RS_STOP: {
-		old_val = msm_camera_io_r(vfe32_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
 		old_val &= ~RS_ENABLE_MASK;
 		msm_camera_io_w(old_val,
-			vfe32_ctrl->vfebase + VFE_MODULE_CFG);
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
 		}
 		break;
 
 	case VFE_CMD_STATS_CS_STOP: {
-		old_val = msm_camera_io_r(vfe32_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
 		old_val &= ~CS_ENABLE_MASK;
 		msm_camera_io_w(old_val,
-			vfe32_ctrl->vfebase + VFE_MODULE_CFG);
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
 		}
 		break;
 	case VFE_CMD_STOP:
 		pr_info("vfe32_proc_general: cmdID = %s\n",
 			vfe32_general_cmd[cmd->id]);
-		vfe32_stop();
+		vfe32_stop(vfe32_ctrl);
 		break;
 
 	case VFE_CMD_SYNC_TIMER_SETTING:
@@ -2131,7 +2343,7 @@
 			rc = -EFAULT;
 			goto proc_general_done;
 		}
-		vfe32_sync_timer_start(cmdp);
+		vfe32_sync_timer_start(cmdp, vfe32_ctrl);
 		break;
 
 	case VFE_CMD_MODULE_CFG: {
@@ -2147,27 +2359,29 @@
 			goto proc_general_done;
 		}
 		*cmdp &= ~STATS_ENABLE_MASK;
-		old_val = msm_camera_io_r(vfe32_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
 		old_val &= STATS_ENABLE_MASK;
 		*cmdp |= old_val;
 
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + vfe32_cmd[cmd->id].offset,
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
 			cmdp, (vfe32_cmd[cmd->id].length));
 		}
 		break;
 
 	case VFE_CMD_ZSL:
 		rc = vfe32_configure_pingpong_buffers(VFE_MSG_V32_START,
-			VFE_MSG_OUTPUT_PRIMARY);
+			VFE_MSG_OUTPUT_PRIMARY, vfe32_ctrl);
 		if (rc < 0)
 			goto proc_general_done;
 		rc = vfe32_configure_pingpong_buffers(VFE_MSG_V32_START,
-			VFE_MSG_OUTPUT_SECONDARY);
+			VFE_MSG_OUTPUT_SECONDARY, vfe32_ctrl);
 		if (rc < 0)
 			goto proc_general_done;
 
-		rc = vfe32_zsl(pmctl);
+		rc = vfe32_zsl(pmctl, vfe32_ctrl);
 		break;
 
 	case VFE_CMD_ASF_CFG:
@@ -2183,11 +2397,13 @@
 			goto proc_general_done;
 		}
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + vfe32_cmd[cmd->id].offset,
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
 			cmdp, (vfe32_cmd[cmd->id].length));
 		cmdp_local = cmdp + V32_ASF_LEN/4;
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + V32_ASF_SPECIAL_EFX_CFG_OFF,
+			vfe32_ctrl->share_ctrl->vfebase +
+			V32_ASF_SPECIAL_EFX_CFG_OFF,
 			cmdp_local, V32_ASF_SPECIAL_EFX_CFG_LEN);
 		break;
 
@@ -2209,37 +2425,44 @@
 		cmdp_local++;
 
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + V33_PCA_ROLL_OFF_CFG_OFF1,
+			vfe32_ctrl->share_ctrl->vfebase +
+			V33_PCA_ROLL_OFF_CFG_OFF1,
 			cmdp_local, V33_PCA_ROLL_OFF_CFG_LEN1);
 		cmdp_local += 4;
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + V33_PCA_ROLL_OFF_CFG_OFF2,
+			vfe32_ctrl->share_ctrl->vfebase +
+			V33_PCA_ROLL_OFF_CFG_OFF2,
 			cmdp_local, V33_PCA_ROLL_OFF_CFG_LEN2);
 
 		cmdp_local += 3;
 		CDBG("%s: start writing RollOff Ram0 table\n", __func__);
-		vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0);
-		msm_camera_io_w(temp1, vfe32_ctrl->vfebase + VFE_DMI_ADDR);
+		vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0, vfe32_ctrl);
+		msm_camera_io_w(temp1,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_ADDR);
 		for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE ; i++) {
 			msm_camera_io_w(*(cmdp_local + 1),
-				vfe32_ctrl->vfebase + VFE33_DMI_DATA_HI);
+				vfe32_ctrl->share_ctrl->vfebase +
+				VFE33_DMI_DATA_HI);
 			msm_camera_io_w(*cmdp_local,
-				vfe32_ctrl->vfebase + VFE33_DMI_DATA_LO);
+				vfe32_ctrl->share_ctrl->vfebase +
+				VFE33_DMI_DATA_LO);
 			cmdp_local += 2;
 		}
 		CDBG("%s: end writing RollOff Ram0 table\n", __func__);
 
 		CDBG("%s: start writing RollOff Ram1 table\n", __func__);
-		vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK0);
-		msm_camera_io_w(temp1, vfe32_ctrl->vfebase + VFE_DMI_ADDR);
+		vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK0, vfe32_ctrl);
+		msm_camera_io_w(temp1,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_ADDR);
 		for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE ; i++) {
 			msm_camera_io_w(*cmdp_local,
-				vfe32_ctrl->vfebase + VFE33_DMI_DATA_LO);
+				vfe32_ctrl->share_ctrl->vfebase +
+				VFE33_DMI_DATA_LO);
 			cmdp_local += 2;
 		}
 		CDBG("%s: end writing RollOff Ram1 table\n", __func__);
 
-		vfe32_program_dmi_cfg(NO_MEM_SELECTED);
+		vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
 		break;
 
 	case VFE_CMD_PCA_ROLL_OFF_UPDATE:
@@ -2259,41 +2482,46 @@
 		temp1 = *cmdp_local;
 		cmdp_local += 8;
 
-		temp2 = msm_camera_io_r(vfe32_ctrl->vfebase +
+		temp2 = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
 			V33_PCA_ROLL_OFF_CFG_OFF1)
 			& V33_PCA_ROLL_OFF_LUT_BANK_SEL_MASK;
 
 		CDBG("%s: start writing RollOff Ram0 table\n", __func__);
 		if (temp2)
-			vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0);
+			vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0, vfe32_ctrl);
 		else
-			vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK1);
+			vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK1, vfe32_ctrl);
 
-		msm_camera_io_w(temp1, vfe32_ctrl->vfebase + VFE_DMI_ADDR);
+		msm_camera_io_w(temp1,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_ADDR);
 		for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE ; i++) {
 			msm_camera_io_w(*(cmdp_local + 1),
-				vfe32_ctrl->vfebase + VFE33_DMI_DATA_HI);
+				vfe32_ctrl->share_ctrl->vfebase +
+				VFE33_DMI_DATA_HI);
 			msm_camera_io_w(*cmdp_local,
-				vfe32_ctrl->vfebase + VFE33_DMI_DATA_LO);
+				vfe32_ctrl->share_ctrl->vfebase +
+				VFE33_DMI_DATA_LO);
 			cmdp_local += 2;
 		}
 		CDBG("%s: end writing RollOff Ram0 table\n", __func__);
 
 		CDBG("%s: start writing RollOff Ram1 table\n", __func__);
 		if (temp2)
-			vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK0);
+			vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK0, vfe32_ctrl);
 		else
-			vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK1);
+			vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK1, vfe32_ctrl);
 
-		msm_camera_io_w(temp1, vfe32_ctrl->vfebase + VFE_DMI_ADDR);
+		msm_camera_io_w(temp1,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_ADDR);
 		for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE ; i++) {
 			msm_camera_io_w(*cmdp_local,
-				vfe32_ctrl->vfebase + VFE33_DMI_DATA_LO);
+				vfe32_ctrl->share_ctrl->vfebase +
+				VFE33_DMI_DATA_LO);
 			cmdp_local += 2;
 		}
 		CDBG("%s: end writing RollOff Ram1 table\n", __func__);
 
-		vfe32_program_dmi_cfg(NO_MEM_SELECTED);
+		vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
 		vfe32_ctrl->update_rolloff = true;
 		break;
 	case VFE_CMD_GET_PCA_ROLLOFF_TABLE:
@@ -2308,33 +2536,37 @@
 			goto proc_general_done;
 		}
 		cmdp_local = cmdp;
-		old_val = msm_camera_io_r(vfe32_ctrl->vfebase +
+		old_val = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
 			V33_PCA_ROLL_OFF_CFG_OFF1) &
 			V33_PCA_ROLL_OFF_LUT_BANK_SEL_MASK;
 
 		if (old_val)
-			vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK1);
+			vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK1, vfe32_ctrl);
 		else
-			vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0);
+			vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0, vfe32_ctrl);
 
 		CDBG("%s: PCA Rolloff Ram0\n", __func__);
 		for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE * 2; i++) {
 			temp2 = (i == (V33_PCA_ROLL_OFF_TABLE_SIZE));
 			if (old_val && temp2)
-				vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK1);
+				vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK1,
+				vfe32_ctrl);
 			else if (!old_val && temp2)
-				vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK0);
+				vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK0,
+				vfe32_ctrl);
 
-			*cmdp_local = msm_camera_io_r(vfe32_ctrl->vfebase +
+			*cmdp_local = msm_camera_io_r(
+				vfe32_ctrl->share_ctrl->vfebase +
 				VFE33_DMI_DATA_LO);
 			*(cmdp_local + 1) =
-				msm_camera_io_r(vfe32_ctrl->vfebase +
+				msm_camera_io_r(
+				vfe32_ctrl->share_ctrl->vfebase +
 				VFE33_DMI_DATA_HI);
 			CDBG("%s: %08x%08x\n", __func__,
 				*(cmdp_local + 1), *cmdp_local);
 			cmdp_local += 2;
 		}
-		vfe32_program_dmi_cfg(NO_MEM_SELECTED);
+		vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
 		if (copy_to_user((void __user *)(cmd->value), cmdp,
 			temp1)) {
 			rc = -EFAULT;
@@ -2352,7 +2584,7 @@
 			goto proc_general_done;
 		}
 		*cmdp = msm_camera_io_r(
-				vfe32_ctrl->vfebase+V32_GET_HW_VERSION_OFF);
+			vfe32_ctrl->share_ctrl->vfebase+V32_GET_HW_VERSION_OFF);
 		if (copy_to_user((void __user *)(cmd->value), cmdp,
 			V32_GET_HW_VERSION_LEN)) {
 			rc = -EFAULT;
@@ -2360,7 +2592,8 @@
 		}
 		break;
 	case VFE_CMD_GET_REG_DUMP:
-		temp1 = sizeof(uint32_t) * vfe32_ctrl->register_total;
+		temp1 = sizeof(uint32_t) *
+			vfe32_ctrl->share_ctrl->register_total;
 		if (cmd->length != temp1) {
 			rc = -EINVAL;
 			goto proc_general_done;
@@ -2370,11 +2603,12 @@
 			rc = -ENOMEM;
 			goto proc_general_done;
 		}
-		msm_camera_io_dump(
-			vfe32_ctrl->vfebase, vfe32_ctrl->register_total*4);
+		msm_camera_io_dump(vfe32_ctrl->share_ctrl->vfebase,
+			vfe32_ctrl->share_ctrl->register_total*4);
 		CDBG("%s: %p %p %d\n", __func__, (void *)cmdp,
-			vfe32_ctrl->vfebase, temp1);
-		memcpy_fromio((void *)cmdp, vfe32_ctrl->vfebase, temp1);
+			vfe32_ctrl->share_ctrl->vfebase, temp1);
+		memcpy_fromio((void *)cmdp,
+			vfe32_ctrl->share_ctrl->vfebase, temp1);
 		if (copy_to_user((void __user *)(cmd->value), cmdp, temp1)) {
 			rc = -EFAULT;
 			goto proc_general_done;
@@ -2399,7 +2633,8 @@
 		}
 
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + vfe32_cmd[cmd->id].offset,
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
 			cmdp, (vfe32_cmd[cmd->id].length));
 		vfe32_ctrl->frame_skip_cnt = ((uint32_t)
 			*cmdp & VFE_FRAME_SKIP_PERIOD_MASK) + 1;
@@ -2423,7 +2658,8 @@
 			goto proc_general_done;
 		}
 		msm_camera_io_memcpy(
-			vfe32_ctrl->vfebase + vfe32_cmd[cmd->id].offset,
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
 			cmdp, (vfe32_cmd[cmd->id].length));
 		break;
 
@@ -2435,10 +2671,11 @@
 	return rc;
 }
 
-static void vfe32_stats_af_ack(struct vfe_cmd_stats_ack *pAck)
+static void vfe32_stats_af_ack(
+	struct vfe32_ctrl_type *vfe32_ctrl, struct vfe_cmd_stats_ack *pAck)
 {
 	unsigned long flags;
-	spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+	spinlock_t *lock = (vfe32_ctrl->share_ctrl->stats_comp ?
 		&vfe32_ctrl->comp_stats_ack_lock :
 		&vfe32_ctrl->af_ack_lock);
 	spin_lock_irqsave(lock, flags);
@@ -2447,10 +2684,11 @@
 	spin_unlock_irqrestore(lock, flags);
 }
 
-static void vfe32_stats_awb_ack(struct vfe_cmd_stats_ack *pAck)
+static void vfe32_stats_awb_ack(
+	struct vfe32_ctrl_type *vfe32_ctrl, struct vfe_cmd_stats_ack *pAck)
 {
 	unsigned long flags;
-	spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+	spinlock_t *lock = (vfe32_ctrl->share_ctrl->stats_comp ?
 		&vfe32_ctrl->comp_stats_ack_lock :
 		&vfe32_ctrl->awb_ack_lock);
 	spin_lock_irqsave(lock, flags);
@@ -2459,10 +2697,11 @@
 	spin_unlock_irqrestore(lock, flags);
 }
 
-static void vfe32_stats_aec_ack(struct vfe_cmd_stats_ack *pAck)
+static void vfe32_stats_aec_ack(
+	struct vfe32_ctrl_type *vfe32_ctrl, struct vfe_cmd_stats_ack *pAck)
 {
 	unsigned long flags;
-	spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+	spinlock_t *lock = (vfe32_ctrl->share_ctrl->stats_comp ?
 		&vfe32_ctrl->comp_stats_ack_lock :
 		&vfe32_ctrl->aec_ack_lock);
 	spin_lock_irqsave(lock, flags);
@@ -2471,10 +2710,11 @@
 	spin_unlock_irqrestore(lock, flags);
 }
 
-static void vfe32_stats_ihist_ack(struct vfe_cmd_stats_ack *pAck)
+static void vfe32_stats_ihist_ack(
+	struct vfe32_ctrl_type *vfe32_ctrl, struct vfe_cmd_stats_ack *pAck)
 {
 	unsigned long flags;
-	spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+	spinlock_t *lock = (vfe32_ctrl->share_ctrl->stats_comp ?
 		&vfe32_ctrl->comp_stats_ack_lock :
 		&vfe32_ctrl->ihist_ack_lock);
 	spin_lock_irqsave(lock, flags);
@@ -2482,10 +2722,11 @@
 	vfe32_ctrl->ihistStatsControl.ackPending = FALSE;
 	spin_unlock_irqrestore(lock, flags);
 }
-static void vfe32_stats_rs_ack(struct vfe_cmd_stats_ack *pAck)
+static void vfe32_stats_rs_ack(
+	struct vfe32_ctrl_type *vfe32_ctrl, struct vfe_cmd_stats_ack *pAck)
 {
 	unsigned long flags;
-	spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+	spinlock_t *lock = (vfe32_ctrl->share_ctrl->stats_comp ?
 		&vfe32_ctrl->comp_stats_ack_lock :
 		&vfe32_ctrl->rs_ack_lock);
 	spin_lock_irqsave(lock, flags);
@@ -2493,10 +2734,11 @@
 	vfe32_ctrl->rsStatsControl.ackPending = FALSE;
 	spin_unlock_irqrestore(lock, flags);
 }
-static void vfe32_stats_cs_ack(struct vfe_cmd_stats_ack *pAck)
+static void vfe32_stats_cs_ack(
+	struct vfe32_ctrl_type *vfe32_ctrl, struct vfe_cmd_stats_ack *pAck)
 {
 	unsigned long flags;
-	spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+	spinlock_t *lock = (vfe32_ctrl->share_ctrl->stats_comp ?
 		&vfe32_ctrl->comp_stats_ack_lock :
 		&vfe32_ctrl->cs_ack_lock);
 	spin_lock_irqsave(lock, flags);
@@ -2505,73 +2747,85 @@
 	spin_unlock_irqrestore(lock, flags);
 }
 
-static inline void vfe32_read_irq_status(struct vfe32_irq_status *out)
+static inline void vfe32_read_irq_status(
+	struct axi_ctrl_t *axi_ctrl, struct vfe32_irq_status *out)
 {
 	uint32_t *temp;
 	memset(out, 0, sizeof(struct vfe32_irq_status));
-	temp = (uint32_t *)(vfe32_ctrl->vfebase + VFE_IRQ_STATUS_0);
+	temp = (uint32_t *)(axi_ctrl->share_ctrl->vfebase + VFE_IRQ_STATUS_0);
 	out->vfeIrqStatus0 = msm_camera_io_r(temp);
 
-	temp = (uint32_t *)(vfe32_ctrl->vfebase + VFE_IRQ_STATUS_1);
+	temp = (uint32_t *)(axi_ctrl->share_ctrl->vfebase + VFE_IRQ_STATUS_1);
 	out->vfeIrqStatus1 = msm_camera_io_r(temp);
 
-	temp = (uint32_t *)(vfe32_ctrl->vfebase + VFE_CAMIF_STATUS);
+	temp = (uint32_t *)(axi_ctrl->share_ctrl->vfebase + VFE_CAMIF_STATUS);
 	out->camifStatus = msm_camera_io_r(temp);
 	CDBG("camifStatus  = 0x%x\n", out->camifStatus);
 
 	/* clear the pending interrupt of the same kind.*/
 	msm_camera_io_w(out->vfeIrqStatus0,
-		vfe32_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
 	msm_camera_io_w(out->vfeIrqStatus1,
-		vfe32_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
 
 	/* Ensure the write order while writing
 	to the command register using the barrier */
-	msm_camera_io_w_mb(1, vfe32_ctrl->vfebase + VFE_IRQ_CMD);
+	msm_camera_io_w_mb(1, axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CMD);
 
 }
 
-static void vfe32_process_reg_update_irq(void)
+static void vfe32_process_reg_update_irq(
+		struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	unsigned long flags;
 
 	if (vfe32_ctrl->recording_state == VFE_STATE_START_REQUESTED) {
-		if (vfe32_ctrl->operation_mode ==
+		if (vfe32_ctrl->share_ctrl->operation_mode ==
 				VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
-		} else if (vfe32_ctrl->operation_mode ==
+			msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[vfe32_ctrl->
+				share_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[vfe32_ctrl->
+				share_ctrl->outpath.out0.ch1]);
+		} else if (vfe32_ctrl->share_ctrl->operation_mode ==
 				VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
+			msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[vfe32_ctrl->
+				share_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[vfe32_ctrl->
+				share_ctrl->outpath.out1.ch1]);
 		}
 		vfe32_ctrl->recording_state = VFE_STATE_STARTED;
-		msm_camera_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+		msm_camera_io_w_mb(1,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
 		CDBG("start video triggered .\n");
 	} else if (vfe32_ctrl->recording_state ==
 			VFE_STATE_STOP_REQUESTED) {
-		if (vfe32_ctrl->operation_mode ==
+		if (vfe32_ctrl->share_ctrl->operation_mode ==
 				VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
-			msm_camera_io_w(0, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(0, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
-		} else if (vfe32_ctrl->operation_mode ==
+			msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[vfe32_ctrl->
+				share_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[vfe32_ctrl->
+				share_ctrl->outpath.out0.ch1]);
+		} else if (vfe32_ctrl->share_ctrl->operation_mode ==
 				VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
-			msm_camera_io_w(0, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(0, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
+			msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[vfe32_ctrl->
+				share_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[vfe32_ctrl->
+				share_ctrl->outpath.out1.ch1]);
 		}
 		CDBG("stop video triggered .\n");
 	}
 
 	if (vfe32_ctrl->start_ack_pending == TRUE) {
-		vfe32_send_isp_msg(vfe32_ctrl, MSG_ID_START_ACK);
+		vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+			vfe32_ctrl->share_ctrl->vfeFrameId, MSG_ID_START_ACK);
 		vfe32_ctrl->start_ack_pending = FALSE;
 	} else {
 		if (vfe32_ctrl->recording_state ==
@@ -2581,10 +2835,12 @@
 			 * when we process the next reg update irq.
 			 */
 			msm_camera_io_w_mb(1,
-			vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+			vfe32_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
 		} else if (vfe32_ctrl->recording_state ==
 					VFE_STATE_STOPPED) {
-			vfe32_send_isp_msg(vfe32_ctrl, MSG_ID_STOP_REC_ACK);
+			vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+				vfe32_ctrl->share_ctrl->vfeFrameId,
+				MSG_ID_STOP_REC_ACK);
 			vfe32_ctrl->recording_state = VFE_STATE_IDLE;
 		}
 		spin_lock_irqsave(&vfe32_ctrl->update_ack_lock, flags);
@@ -2592,80 +2848,102 @@
 			vfe32_ctrl->update_ack_pending = FALSE;
 			spin_unlock_irqrestore(
 				&vfe32_ctrl->update_ack_lock, flags);
-			vfe32_send_isp_msg(vfe32_ctrl, MSG_ID_UPDATE_ACK);
+			vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+				vfe32_ctrl->share_ctrl->vfeFrameId,
+				MSG_ID_UPDATE_ACK);
 		} else {
 			spin_unlock_irqrestore(
 				&vfe32_ctrl->update_ack_lock, flags);
 		}
 	}
 
-	if (vfe32_ctrl->liveshot_state == VFE_STATE_START_REQUESTED) {
+	if (vfe32_ctrl->share_ctrl->liveshot_state ==
+		VFE_STATE_START_REQUESTED) {
 		pr_info("%s enabling liveshot output\n", __func__);
-		if (vfe32_ctrl->outpath.output_mode &
+		if (vfe32_ctrl->share_ctrl->outpath.output_mode &
 				VFE32_OUTPUT_MODE_PRIMARY) {
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
-			vfe32_ctrl->liveshot_state = VFE_STATE_STARTED;
+			msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[vfe32_ctrl->
+				share_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[vfe32_ctrl->
+				share_ctrl->outpath.out0.ch1]);
+			vfe32_ctrl->share_ctrl->liveshot_state =
+				VFE_STATE_STARTED;
 		}
 	}
 
-	if (vfe32_ctrl->liveshot_state == VFE_STATE_STARTED) {
-		vfe32_ctrl->vfe_capture_count--;
-		if (!vfe32_ctrl->vfe_capture_count)
-			vfe32_ctrl->liveshot_state = VFE_STATE_STOP_REQUESTED;
-		msm_camera_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	} else if (vfe32_ctrl->liveshot_state == VFE_STATE_STOP_REQUESTED) {
+	if (vfe32_ctrl->share_ctrl->liveshot_state == VFE_STATE_STARTED) {
+		vfe32_ctrl->share_ctrl->vfe_capture_count--;
+		if (!vfe32_ctrl->share_ctrl->vfe_capture_count)
+			vfe32_ctrl->share_ctrl->liveshot_state =
+				VFE_STATE_STOP_REQUESTED;
+		msm_camera_io_w_mb(1, vfe32_ctrl->
+			share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	} else if (vfe32_ctrl->share_ctrl->liveshot_state ==
+			VFE_STATE_STOP_REQUESTED) {
 		CDBG("%s: disabling liveshot output\n", __func__);
-		if (vfe32_ctrl->outpath.output_mode &
+		if (vfe32_ctrl->share_ctrl->outpath.output_mode &
 			VFE32_OUTPUT_MODE_PRIMARY) {
-			msm_camera_io_w(0, vfe32_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(0, vfe32_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
-			vfe32_ctrl->liveshot_state = VFE_STATE_STOPPED;
-			msm_camera_io_w_mb(1, vfe32_ctrl->vfebase +
+			msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[vfe32_ctrl->
+				share_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[vfe32_ctrl->
+				share_ctrl->outpath.out0.ch1]);
+			vfe32_ctrl->share_ctrl->liveshot_state =
+				VFE_STATE_STOPPED;
+			msm_camera_io_w_mb(1, vfe32_ctrl->share_ctrl->vfebase +
 				VFE_REG_UPDATE_CMD);
 		}
-	} else if (vfe32_ctrl->liveshot_state == VFE_STATE_STOPPED) {
-		vfe32_ctrl->liveshot_state = VFE_STATE_IDLE;
+	} else if (vfe32_ctrl->share_ctrl->liveshot_state ==
+			VFE_STATE_STOPPED) {
+		vfe32_ctrl->share_ctrl->liveshot_state = VFE_STATE_IDLE;
 	}
 
-	if ((vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN) ||
-		(vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB) ||
-		(vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) ||
-		(vfe32_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB)) {
+	if ((vfe32_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_THUMB_AND_MAIN) ||
+		(vfe32_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_MAIN_AND_THUMB) ||
+		(vfe32_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_THUMB_AND_JPEG) ||
+		(vfe32_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_JPEG_AND_THUMB)) {
 		/* in snapshot mode */
 		/* later we need to add check for live snapshot mode. */
 		if (vfe32_ctrl->frame_skip_pattern & (0x1 <<
 			(vfe32_ctrl->snapshot_frame_cnt %
 				vfe32_ctrl->frame_skip_cnt))) {
-			vfe32_ctrl->vfe_capture_count--;
+			vfe32_ctrl->share_ctrl->vfe_capture_count--;
 			/* if last frame to be captured: */
-			if (vfe32_ctrl->vfe_capture_count == 0) {
+			if (vfe32_ctrl->share_ctrl->vfe_capture_count == 0) {
 				/* stop the bus output:write master enable = 0*/
-				if (vfe32_ctrl->outpath.output_mode &
-						VFE32_OUTPUT_MODE_PRIMARY) {
-					msm_camera_io_w(0, vfe32_ctrl->vfebase +
+				if (vfe32_ctrl->share_ctrl->outpath.output_mode
+					& VFE32_OUTPUT_MODE_PRIMARY) {
+					msm_camera_io_w(0,
+						vfe32_ctrl->share_ctrl->vfebase+
 						vfe32_AXI_WM_CFG[vfe32_ctrl->
-							outpath.out0.ch0]);
-					msm_camera_io_w(0, vfe32_ctrl->vfebase +
+						share_ctrl->outpath.out0.ch0]);
+					msm_camera_io_w(0,
+						vfe32_ctrl->share_ctrl->vfebase+
 						vfe32_AXI_WM_CFG[vfe32_ctrl->
-							outpath.out0.ch1]);
+						share_ctrl->outpath.out0.ch1]);
 				}
-				if (vfe32_ctrl->outpath.output_mode &
+				if (vfe32_ctrl->share_ctrl->outpath.output_mode&
 						VFE32_OUTPUT_MODE_SECONDARY) {
-					msm_camera_io_w(0, vfe32_ctrl->vfebase +
+					msm_camera_io_w(0,
+						vfe32_ctrl->share_ctrl->vfebase+
 						vfe32_AXI_WM_CFG[vfe32_ctrl->
-							outpath.out1.ch0]);
-					msm_camera_io_w(0, vfe32_ctrl->vfebase +
+						share_ctrl->outpath.out1.ch0]);
+					msm_camera_io_w(0,
+						vfe32_ctrl->share_ctrl->vfebase+
 						vfe32_AXI_WM_CFG[vfe32_ctrl->
-							outpath.out1.ch1]);
+						share_ctrl->outpath.out1.ch1]);
 				}
 				msm_camera_io_w_mb
 				(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
-				vfe32_ctrl->vfebase + VFE_CAMIF_COMMAND);
+				vfe32_ctrl->share_ctrl->vfebase +
+				VFE_CAMIF_COMMAND);
 				vfe32_ctrl->snapshot_frame_cnt = -1;
 				vfe32_ctrl->frame_skip_cnt = 31;
 				vfe32_ctrl->frame_skip_pattern = 0xffffffff;
@@ -2673,116 +2951,143 @@
 		} /*if frame is not being dropped*/
 		vfe32_ctrl->snapshot_frame_cnt++;
 		/* then do reg_update. */
-		msm_camera_io_w(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+		msm_camera_io_w(1,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
 	} /* if snapshot mode. */
 }
 
-static void vfe32_set_default_reg_values(void)
+static void vfe32_set_default_reg_values(
+			struct vfe32_ctrl_type *vfe32_ctrl)
 {
-	msm_camera_io_w(0x800080, vfe32_ctrl->vfebase + VFE_DEMUX_GAIN_0);
-	msm_camera_io_w(0x800080, vfe32_ctrl->vfebase + VFE_DEMUX_GAIN_1);
+	msm_camera_io_w(0x800080,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_DEMUX_GAIN_0);
+	msm_camera_io_w(0x800080,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_DEMUX_GAIN_1);
 	/* What value should we program CGC_OVERRIDE to? */
-	msm_camera_io_w(0xFFFFF, vfe32_ctrl->vfebase + VFE_CGC_OVERRIDE);
+	msm_camera_io_w(0xFFFFF,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_CGC_OVERRIDE);
 
 	/* default frame drop period and pattern */
-	msm_camera_io_w(0x1f, vfe32_ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG);
-	msm_camera_io_w(0x1f, vfe32_ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_CFG);
+	msm_camera_io_w(0x1f,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG);
+	msm_camera_io_w(0x1f,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_CFG);
 	msm_camera_io_w(0xFFFFFFFF,
-		vfe32_ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN);
+		vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN);
 	msm_camera_io_w(0xFFFFFFFF,
-		vfe32_ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_PATTERN);
-	msm_camera_io_w(0x1f, vfe32_ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y);
-	msm_camera_io_w(0x1f, vfe32_ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR);
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_FRAMEDROP_ENC_CBCR_PATTERN);
+	msm_camera_io_w(0x1f,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y);
+	msm_camera_io_w(0x1f,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR);
 	msm_camera_io_w(0xFFFFFFFF,
-		vfe32_ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN);
+		vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN);
 	msm_camera_io_w(0xFFFFFFFF,
-		vfe32_ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR_PATTERN);
-	msm_camera_io_w(0, vfe32_ctrl->vfebase + VFE_CLAMP_MIN);
-	msm_camera_io_w(0xFFFFFF, vfe32_ctrl->vfebase + VFE_CLAMP_MAX);
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_FRAMEDROP_VIEW_CBCR_PATTERN);
+	msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase + VFE_CLAMP_MIN);
+	msm_camera_io_w(0xFFFFFF,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_CLAMP_MAX);
 
 	/* stats UB config */
 	msm_camera_io_w(0x3980007,
-		vfe32_ctrl->vfebase + VFE_BUS_STATS_AEC_UB_CFG);
+		vfe32_ctrl->share_ctrl->vfebase + VFE_BUS_STATS_AEC_UB_CFG);
 	msm_camera_io_w(0x3A00007,
-		vfe32_ctrl->vfebase + VFE_BUS_STATS_AF_UB_CFG);
+		vfe32_ctrl->share_ctrl->vfebase + VFE_BUS_STATS_AF_UB_CFG);
 	msm_camera_io_w(0x3A8000F,
-		vfe32_ctrl->vfebase + VFE_BUS_STATS_AWB_UB_CFG);
+		vfe32_ctrl->share_ctrl->vfebase + VFE_BUS_STATS_AWB_UB_CFG);
 	msm_camera_io_w(0x3B80007,
-		vfe32_ctrl->vfebase + VFE_BUS_STATS_RS_UB_CFG);
+		vfe32_ctrl->share_ctrl->vfebase + VFE_BUS_STATS_RS_UB_CFG);
 	msm_camera_io_w(0x3C0001F,
-		vfe32_ctrl->vfebase + VFE_BUS_STATS_CS_UB_CFG);
+		vfe32_ctrl->share_ctrl->vfebase + VFE_BUS_STATS_CS_UB_CFG);
 	msm_camera_io_w(0x3E0001F,
-		vfe32_ctrl->vfebase + VFE_BUS_STATS_HIST_UB_CFG);
+		vfe32_ctrl->share_ctrl->vfebase + VFE_BUS_STATS_HIST_UB_CFG);
 }
 
-static void vfe32_process_reset_irq(void)
+static void vfe32_process_reset_irq(
+		struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	unsigned long flags;
 
-	atomic_set(&vfe32_ctrl->vstate, 0);
+	atomic_set(&vfe32_ctrl->share_ctrl->vstate, 0);
 
-	spin_lock_irqsave(&vfe32_ctrl->stop_flag_lock, flags);
-	if (vfe32_ctrl->stop_ack_pending) {
-		vfe32_ctrl->stop_ack_pending = FALSE;
-		spin_unlock_irqrestore(&vfe32_ctrl->stop_flag_lock, flags);
-		vfe32_send_isp_msg(vfe32_ctrl, MSG_ID_STOP_ACK);
+	spin_lock_irqsave(&vfe32_ctrl->share_ctrl->stop_flag_lock, flags);
+	if (vfe32_ctrl->share_ctrl->stop_ack_pending) {
+		vfe32_ctrl->share_ctrl->stop_ack_pending = FALSE;
+		spin_unlock_irqrestore(
+			&vfe32_ctrl->share_ctrl->stop_flag_lock, flags);
+		vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+			vfe32_ctrl->share_ctrl->vfeFrameId, MSG_ID_STOP_ACK);
 	} else {
-		spin_unlock_irqrestore(&vfe32_ctrl->stop_flag_lock, flags);
+		spin_unlock_irqrestore(
+			&vfe32_ctrl->share_ctrl->stop_flag_lock, flags);
 		/* this is from reset command. */
-		vfe32_set_default_reg_values();
+		vfe32_set_default_reg_values(vfe32_ctrl);
 
 		/* reload all write masters. (frame & line)*/
-		msm_camera_io_w(0x7FFF, vfe32_ctrl->vfebase + VFE_BUS_CMD);
-		vfe32_send_isp_msg(vfe32_ctrl, MSG_ID_RESET_ACK);
+		msm_camera_io_w(0x7FFF,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
+		vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+			vfe32_ctrl->share_ctrl->vfeFrameId, MSG_ID_RESET_ACK);
 	}
 }
 
-static void vfe32_process_camif_sof_irq(void)
+static void vfe32_process_camif_sof_irq(
+		struct vfe32_ctrl_type *vfe32_ctrl)
 {
-	if (vfe32_ctrl->operation_mode ==
+	if (vfe32_ctrl->share_ctrl->operation_mode ==
 		VFE_OUTPUTS_RAW) {
 		if (vfe32_ctrl->start_ack_pending) {
-			vfe32_send_isp_msg(vfe32_ctrl, MSG_ID_START_ACK);
+			vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+				vfe32_ctrl->share_ctrl->vfeFrameId,
+				MSG_ID_START_ACK);
 			vfe32_ctrl->start_ack_pending = FALSE;
 		}
-		vfe32_ctrl->vfe_capture_count--;
+		vfe32_ctrl->share_ctrl->vfe_capture_count--;
 		/* if last frame to be captured: */
-		if (vfe32_ctrl->vfe_capture_count == 0) {
+		if (vfe32_ctrl->share_ctrl->vfe_capture_count == 0) {
 			/* Ensure the write order while writing
 			 to the command register using the barrier */
 			msm_camera_io_w_mb(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
-				vfe32_ctrl->vfebase + VFE_CAMIF_COMMAND);
+			vfe32_ctrl->share_ctrl->vfebase + VFE_CAMIF_COMMAND);
 		}
 	} /* if raw snapshot mode. */
 	if ((vfe32_ctrl->hfr_mode != HFR_MODE_OFF) &&
-		(vfe32_ctrl->operation_mode == VFE_MODE_OF_OPERATION_VIDEO) &&
-		(vfe32_ctrl->vfeFrameId % vfe32_ctrl->hfr_mode != 0)) {
-		vfe32_ctrl->vfeFrameId++;
+		(vfe32_ctrl->share_ctrl->operation_mode ==
+			VFE_MODE_OF_OPERATION_VIDEO) &&
+		(vfe32_ctrl->share_ctrl->vfeFrameId %
+			vfe32_ctrl->hfr_mode != 0)) {
+		vfe32_ctrl->share_ctrl->vfeFrameId++;
 		CDBG("Skip the SOF notification when HFR enabled\n");
 		return;
 	}
-	vfe32_ctrl->vfeFrameId++;
-	vfe32_send_isp_msg(vfe32_ctrl, MSG_ID_SOF_ACK);
-	CDBG("camif_sof_irq, frameId = %d\n", vfe32_ctrl->vfeFrameId);
+	vfe32_ctrl->share_ctrl->vfeFrameId++;
+	vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+		vfe32_ctrl->share_ctrl->vfeFrameId, MSG_ID_SOF_ACK);
+	CDBG("camif_sof_irq, frameId = %d\n",
+		vfe32_ctrl->share_ctrl->vfeFrameId);
 
 	if (vfe32_ctrl->sync_timer_state) {
 		if (vfe32_ctrl->sync_timer_repeat_count == 0)
-			vfe32_sync_timer_stop();
+			vfe32_sync_timer_stop(vfe32_ctrl);
 		else
 			vfe32_ctrl->sync_timer_repeat_count--;
 	}
 }
 
-static void vfe32_process_error_irq(uint32_t errStatus)
+static void vfe32_process_error_irq(
+	struct axi_ctrl_t *axi_ctrl, uint32_t errStatus)
 {
 	uint32_t reg_value;
 
 	if (errStatus & VFE32_IMASK_CAMIF_ERROR) {
 		pr_err("vfe32_irq: camif errors\n");
 		reg_value = msm_camera_io_r(
-				vfe32_ctrl->vfebase + VFE_CAMIF_STATUS);
+			axi_ctrl->share_ctrl->vfebase + VFE_CAMIF_STATUS);
 		pr_err("camifStatus  = 0x%x\n", reg_value);
-		vfe32_send_isp_msg(vfe32_ctrl, MSG_ID_CAMIF_ERROR);
+		vfe32_send_isp_msg(&axi_ctrl->subdev,
+			axi_ctrl->share_ctrl->vfeFrameId, MSG_ID_CAMIF_ERROR);
 	}
 
 	if (errStatus & VFE32_IMASK_BHIST_OVWR)
@@ -2806,7 +3111,7 @@
 	if (errStatus & VFE32_IMASK_VIOLATION) {
 		pr_err("vfe32_irq: violation interrupt\n");
 		reg_value = msm_camera_io_r(
-				vfe32_ctrl->vfebase + VFE_VIOLATION_STATUS);
+			axi_ctrl->share_ctrl->vfebase + VFE_VIOLATION_STATUS);
 		pr_err("%s: violationStatus  = 0x%x\n", __func__, reg_value);
 	}
 
@@ -2856,7 +3161,8 @@
 		pr_err("vfe32_irq: axi error\n");
 }
 
-static void vfe_send_outmsg(struct v4l2_subdev *sd, uint8_t msgid,
+static void vfe_send_outmsg(
+	struct axi_ctrl_t *axi_ctrl, uint8_t msgid,
 	uint32_t ch0_paddr, uint32_t ch1_paddr, uint32_t ch2_paddr)
 {
 	struct isp_msg_output msg;
@@ -2865,15 +3171,16 @@
 	msg.buf.ch_paddr[0]	= ch0_paddr;
 	msg.buf.ch_paddr[1]	= ch1_paddr;
 	msg.buf.ch_paddr[2]	= ch2_paddr;
-	msg.frameCounter = vfe32_ctrl->vfeFrameId;
+	msg.frameCounter = axi_ctrl->share_ctrl->vfeFrameId;
 
-	v4l2_subdev_notify(&vfe32_ctrl->subdev,
+	v4l2_subdev_notify(&axi_ctrl->subdev,
 			NOTIFY_VFE_MSG_OUT,
 			&msg);
 	return;
 }
 
-static void vfe32_process_output_path_irq_0(void)
+static void vfe32_process_output_path_irq_0(
+	struct axi_ctrl_t *axi_ctrl)
 {
 	uint32_t ping_pong;
 	uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
@@ -2881,7 +3188,7 @@
 	struct msm_free_buf *free_buf = NULL;
 
 	free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
-		VFE_MSG_OUTPUT_PRIMARY);
+		VFE_MSG_OUTPUT_PRIMARY, axi_ctrl);
 
 	/* we render frames in the following conditions:
 	1. Continuous mode and the free buffer is avaialable.
@@ -2889,73 +3196,91 @@
 	when pending snapshot count is <=1,  then no need to use
 	free buffer.
 	*/
-	out_bool = ((vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN ||
-		vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
-		vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG ||
-		vfe32_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
-		vfe32_ctrl->operation_mode == VFE_OUTPUTS_RAW ||
-		vfe32_ctrl->liveshot_state == VFE_STATE_STARTED ||
-		vfe32_ctrl->liveshot_state == VFE_STATE_STOP_REQUESTED ||
-		vfe32_ctrl->liveshot_state == VFE_STATE_STOPPED) &&
-		(vfe32_ctrl->vfe_capture_count <= 1)) || free_buf;
+	out_bool = (
+		(axi_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_THUMB_AND_MAIN ||
+		axi_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_MAIN_AND_THUMB ||
+		axi_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_THUMB_AND_JPEG ||
+		axi_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_JPEG_AND_THUMB ||
+		axi_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_RAW ||
+		axi_ctrl->share_ctrl->liveshot_state ==
+			VFE_STATE_STARTED ||
+		axi_ctrl->share_ctrl->liveshot_state ==
+			VFE_STATE_STOP_REQUESTED ||
+		axi_ctrl->share_ctrl->liveshot_state ==
+			VFE_STATE_STOPPED) &&
+		(axi_ctrl->share_ctrl->vfe_capture_count <= 1)) ||
+			free_buf;
 
 	if (out_bool) {
-		ping_pong = msm_camera_io_r(vfe32_ctrl->vfebase +
+		ping_pong = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
 			VFE_BUS_PING_PONG_STATUS);
 
 		/* Channel 0*/
-		ch0_paddr = vfe32_get_ch_addr(ping_pong,
-			vfe32_ctrl->outpath.out0.ch0);
+		ch0_paddr = vfe32_get_ch_addr(
+			ping_pong, axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out0.ch0);
 		/* Channel 1*/
-		ch1_paddr = vfe32_get_ch_addr(ping_pong,
-			vfe32_ctrl->outpath.out0.ch1);
+		ch1_paddr = vfe32_get_ch_addr(
+			ping_pong, axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out0.ch1);
 		/* Channel 2*/
-		ch2_paddr = vfe32_get_ch_addr(ping_pong,
-			vfe32_ctrl->outpath.out0.ch2);
+		ch2_paddr = vfe32_get_ch_addr(
+			ping_pong, axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_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 */
 			vfe32_put_ch_addr(ping_pong,
-			vfe32_ctrl->outpath.out0.ch0,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out0.ch0,
 			free_buf->ch_paddr[0]);
 			/* Chroma channel */
 			vfe32_put_ch_addr(ping_pong,
-			vfe32_ctrl->outpath.out0.ch1,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out0.ch1,
 			free_buf->ch_paddr[1]);
 			if (free_buf->num_planes > 2)
 				vfe32_put_ch_addr(ping_pong,
-					vfe32_ctrl->outpath.out0.ch2,
+					axi_ctrl->share_ctrl->vfebase,
+					axi_ctrl->share_ctrl->outpath.out0.ch2,
 					free_buf->ch_paddr[2]);
 		}
-		if (vfe32_ctrl->operation_mode ==
+		if (axi_ctrl->share_ctrl->operation_mode ==
 				VFE_OUTPUTS_THUMB_AND_MAIN ||
-			vfe32_ctrl->operation_mode ==
+			axi_ctrl->share_ctrl->operation_mode ==
 				VFE_OUTPUTS_MAIN_AND_THUMB ||
-			vfe32_ctrl->operation_mode ==
+			axi_ctrl->share_ctrl->operation_mode ==
 				VFE_OUTPUTS_THUMB_AND_JPEG ||
-			vfe32_ctrl->operation_mode ==
+			axi_ctrl->share_ctrl->operation_mode ==
 				VFE_OUTPUTS_JPEG_AND_THUMB ||
-			vfe32_ctrl->operation_mode ==
+			axi_ctrl->share_ctrl->operation_mode ==
 				VFE_OUTPUTS_RAW ||
-			vfe32_ctrl->liveshot_state == VFE_STATE_STOPPED)
-			vfe32_ctrl->outpath.out0.capture_cnt--;
+			axi_ctrl->share_ctrl->liveshot_state ==
+				VFE_STATE_STOPPED)
+			axi_ctrl->share_ctrl->outpath.out0.capture_cnt--;
 
-		vfe_send_outmsg(&vfe32_ctrl->subdev,
+		vfe_send_outmsg(axi_ctrl,
 			MSG_ID_OUTPUT_PRIMARY, ch0_paddr,
 			ch1_paddr, ch2_paddr);
 
-		if (vfe32_ctrl->liveshot_state == VFE_STATE_STOPPED)
-			vfe32_ctrl->liveshot_state = VFE_STATE_IDLE;
+		if (axi_ctrl->share_ctrl->liveshot_state == VFE_STATE_STOPPED)
+			axi_ctrl->share_ctrl->liveshot_state = VFE_STATE_IDLE;
 
 	} else {
-		vfe32_ctrl->outpath.out0.frame_drop_cnt++;
+		axi_ctrl->share_ctrl->outpath.out0.frame_drop_cnt++;
 		CDBG("path_irq_0 - no free buffer!\n");
 	}
 }
 
-static void vfe32_process_output_path_irq_1(void)
+static void vfe32_process_output_path_irq_1(
+	struct axi_ctrl_t *axi_ctrl)
 {
 	uint32_t ping_pong;
 	uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
@@ -2964,81 +3289,89 @@
 	struct msm_free_buf *free_buf = NULL;
 
 	free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
-		VFE_MSG_OUTPUT_SECONDARY);
-	out_bool = ((vfe32_ctrl->operation_mode ==
+		VFE_MSG_OUTPUT_SECONDARY, axi_ctrl);
+	out_bool = ((axi_ctrl->share_ctrl->operation_mode ==
 				VFE_OUTPUTS_THUMB_AND_MAIN ||
-			vfe32_ctrl->operation_mode ==
+			axi_ctrl->share_ctrl->operation_mode ==
 				VFE_OUTPUTS_MAIN_AND_THUMB ||
-			vfe32_ctrl->operation_mode ==
+			axi_ctrl->share_ctrl->operation_mode ==
 				VFE_OUTPUTS_RAW ||
-			vfe32_ctrl->operation_mode ==
+			axi_ctrl->share_ctrl->operation_mode ==
 				VFE_OUTPUTS_JPEG_AND_THUMB) &&
-			(vfe32_ctrl->vfe_capture_count <= 1)) || free_buf;
+			(axi_ctrl->share_ctrl->vfe_capture_count <= 1)) ||
+				free_buf;
 
 	if (out_bool) {
-		ping_pong = msm_camera_io_r(vfe32_ctrl->vfebase +
+		ping_pong = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
 			VFE_BUS_PING_PONG_STATUS);
 
 		/* Y channel */
 		ch0_paddr = vfe32_get_ch_addr(ping_pong,
-			vfe32_ctrl->outpath.out1.ch0);
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out1.ch0);
 		/* Chroma channel */
 		ch1_paddr = vfe32_get_ch_addr(ping_pong,
-			vfe32_ctrl->outpath.out1.ch1);
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out1.ch1);
 		ch2_paddr = vfe32_get_ch_addr(ping_pong,
-			vfe32_ctrl->outpath.out1.ch2);
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out1.ch2);
 
 		CDBG("%s ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
 			__func__, ch0_paddr, ch1_paddr, ch2_paddr);
 		if (free_buf) {
 			/* Y channel */
 			vfe32_put_ch_addr(ping_pong,
-			vfe32_ctrl->outpath.out1.ch0,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out1.ch0,
 			free_buf->ch_paddr[0]);
 			/* Chroma channel */
 			vfe32_put_ch_addr(ping_pong,
-			vfe32_ctrl->outpath.out1.ch1,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out1.ch1,
 			free_buf->ch_paddr[1]);
 			if (free_buf->num_planes > 2)
 				vfe32_put_ch_addr(ping_pong,
-					vfe32_ctrl->outpath.out1.ch2,
+					axi_ctrl->share_ctrl->vfebase,
+					axi_ctrl->share_ctrl->outpath.out1.ch2,
 					free_buf->ch_paddr[2]);
 		}
-		if (vfe32_ctrl->operation_mode ==
+		if (axi_ctrl->share_ctrl->operation_mode ==
 				VFE_OUTPUTS_THUMB_AND_MAIN ||
-			vfe32_ctrl->operation_mode ==
+			axi_ctrl->share_ctrl->operation_mode ==
 				VFE_OUTPUTS_MAIN_AND_THUMB ||
-			vfe32_ctrl->operation_mode ==
+			axi_ctrl->share_ctrl->operation_mode ==
 				VFE_OUTPUTS_RAW ||
-			vfe32_ctrl->operation_mode ==
+			axi_ctrl->share_ctrl->operation_mode ==
 				VFE_OUTPUTS_JPEG_AND_THUMB)
-			vfe32_ctrl->outpath.out1.capture_cnt--;
+			axi_ctrl->share_ctrl->outpath.out1.capture_cnt--;
 
-		vfe_send_outmsg(&vfe32_ctrl->subdev,
+		vfe_send_outmsg(axi_ctrl,
 			MSG_ID_OUTPUT_SECONDARY, ch0_paddr,
 			ch1_paddr, ch2_paddr);
 	} else {
-		vfe32_ctrl->outpath.out1.frame_drop_cnt++;
+		axi_ctrl->share_ctrl->outpath.out1.frame_drop_cnt++;
 		CDBG("path_irq_1 - no free buffer!\n");
 	}
 }
 
-static uint32_t  vfe32_process_stats_irq_common(uint32_t statsNum,
-						uint32_t newAddr) {
-
+static uint32_t  vfe32_process_stats_irq_common(
+	struct vfe32_ctrl_type *vfe32_ctrl,
+	uint32_t statsNum, uint32_t newAddr)
+{
 	uint32_t pingpongStatus;
 	uint32_t returnAddr;
 	uint32_t pingpongAddr;
 
 	/* must be 0=ping, 1=pong */
 	pingpongStatus =
-		((msm_camera_io_r(vfe32_ctrl->vfebase +
+		((msm_camera_io_r(vfe32_ctrl->share_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)(vfe32_ctrl->vfebase +
+		((uint32_t)(vfe32_ctrl->share_ctrl->vfebase +
 				VFE_BUS_STATS_PING_PONG_BASE)) +
 				(3*statsNum)*4 + (1-pingpongStatus)*4;
 	returnAddr = msm_camera_io_r((uint32_t *)pingpongAddr);
@@ -3047,14 +3380,15 @@
 }
 
 static void
-vfe_send_stats_msg(uint32_t bufAddress, uint32_t statsNum)
+vfe_send_stats_msg(struct vfe32_ctrl_type *vfe32_ctrl,
+	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 = vfe32_ctrl->vfeFrameId;
+	msgStats.frameCounter = vfe32_ctrl->share_ctrl->vfeFrameId;
 	msgStats.buffer = bufAddress;
 
 	switch (statsNum) {
@@ -3114,12 +3448,13 @@
 	return;
 }
 
-static void vfe_send_comp_stats_msg(uint32_t status_bits)
+static void vfe_send_comp_stats_msg(
+	struct vfe32_ctrl_type *vfe32_ctrl, uint32_t status_bits)
 {
 	struct msm_stats_buf msgStats;
 	uint32_t temp;
 
-	msgStats.frame_id = vfe32_ctrl->vfeFrameId;
+	msgStats.frame_id = vfe32_ctrl->share_ctrl->vfeFrameId;
 	msgStats.status_bits = status_bits;
 
 	msgStats.aec.buff = vfe32_ctrl->aecStatsControl.bufToRender;
@@ -3130,7 +3465,8 @@
 	msgStats.rs.buff = vfe32_ctrl->rsStatsControl.bufToRender;
 	msgStats.cs.buff = vfe32_ctrl->csStatsControl.bufToRender;
 
-	temp = msm_camera_io_r(vfe32_ctrl->vfebase + VFE_STATS_AWB_SGW_CFG);
+	temp = msm_camera_io_r(
+		vfe32_ctrl->share_ctrl->vfebase + VFE_STATS_AWB_SGW_CFG);
 	msgStats.awb_ymin = (0xFF00 & temp) >> 8;
 
 	v4l2_subdev_notify(&vfe32_ctrl->subdev,
@@ -3138,18 +3474,18 @@
 				&msgStats);
 }
 
-static void vfe32_process_stats_ae_irq(void)
+static void vfe32_process_stats_ae_irq(struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&vfe32_ctrl->aec_ack_lock, flags);
 	if (!(vfe32_ctrl->aecStatsControl.ackPending)) {
 		spin_unlock_irqrestore(&vfe32_ctrl->aec_ack_lock, flags);
 		vfe32_ctrl->aecStatsControl.bufToRender =
-			vfe32_process_stats_irq_common(statsAeNum,
+			vfe32_process_stats_irq_common(vfe32_ctrl, statsAeNum,
 			vfe32_ctrl->aecStatsControl.nextFrameAddrBuf);
 
-		vfe_send_stats_msg(vfe32_ctrl->aecStatsControl.bufToRender,
-						statsAeNum);
+		vfe_send_stats_msg(vfe32_ctrl,
+			vfe32_ctrl->aecStatsControl.bufToRender, statsAeNum);
 	} else{
 		spin_unlock_irqrestore(&vfe32_ctrl->aec_ack_lock, flags);
 		vfe32_ctrl->aecStatsControl.droppedStatsFrameCount++;
@@ -3158,18 +3494,18 @@
 	}
 }
 
-static void vfe32_process_stats_awb_irq(void)
+static void vfe32_process_stats_awb_irq(struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&vfe32_ctrl->awb_ack_lock, flags);
 	if (!(vfe32_ctrl->awbStatsControl.ackPending)) {
 		spin_unlock_irqrestore(&vfe32_ctrl->awb_ack_lock, flags);
 		vfe32_ctrl->awbStatsControl.bufToRender =
-			vfe32_process_stats_irq_common(statsAwbNum,
+			vfe32_process_stats_irq_common(vfe32_ctrl, statsAwbNum,
 			vfe32_ctrl->awbStatsControl.nextFrameAddrBuf);
 
-		vfe_send_stats_msg(vfe32_ctrl->awbStatsControl.bufToRender,
-						statsAwbNum);
+		vfe_send_stats_msg(vfe32_ctrl,
+			vfe32_ctrl->awbStatsControl.bufToRender, statsAwbNum);
 	} else{
 		spin_unlock_irqrestore(&vfe32_ctrl->awb_ack_lock, flags);
 		vfe32_ctrl->awbStatsControl.droppedStatsFrameCount++;
@@ -3178,18 +3514,18 @@
 	}
 }
 
-static void vfe32_process_stats_af_irq(void)
+static void vfe32_process_stats_af_irq(struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&vfe32_ctrl->af_ack_lock, flags);
 	if (!(vfe32_ctrl->afStatsControl.ackPending)) {
 		spin_unlock_irqrestore(&vfe32_ctrl->af_ack_lock, flags);
 		vfe32_ctrl->afStatsControl.bufToRender =
-			vfe32_process_stats_irq_common(statsAfNum,
+			vfe32_process_stats_irq_common(vfe32_ctrl, statsAfNum,
 			vfe32_ctrl->afStatsControl.nextFrameAddrBuf);
 
-		vfe_send_stats_msg(vfe32_ctrl->afStatsControl.bufToRender,
-						statsAfNum);
+		vfe_send_stats_msg(vfe32_ctrl,
+			vfe32_ctrl->afStatsControl.bufToRender, statsAfNum);
 	} else{
 		spin_unlock_irqrestore(&vfe32_ctrl->af_ack_lock, flags);
 		vfe32_ctrl->afStatsControl.droppedStatsFrameCount++;
@@ -3198,15 +3534,17 @@
 	}
 }
 
-static void vfe32_process_stats_ihist_irq(void)
+static void vfe32_process_stats_ihist_irq(struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	if (!(vfe32_ctrl->ihistStatsControl.ackPending)) {
 		vfe32_ctrl->ihistStatsControl.bufToRender =
-			vfe32_process_stats_irq_common(statsIhistNum,
+			vfe32_process_stats_irq_common(
+			vfe32_ctrl, statsIhistNum,
 			vfe32_ctrl->ihistStatsControl.nextFrameAddrBuf);
 
-		vfe_send_stats_msg(vfe32_ctrl->ihistStatsControl.bufToRender,
-						statsIhistNum);
+		vfe_send_stats_msg(vfe32_ctrl,
+			vfe32_ctrl->ihistStatsControl.bufToRender,
+			statsIhistNum);
 	} else {
 		vfe32_ctrl->ihistStatsControl.droppedStatsFrameCount++;
 		CDBG("%s: droppedStatsFrameCount = %d", __func__,
@@ -3214,15 +3552,15 @@
 	}
 }
 
-static void vfe32_process_stats_rs_irq(void)
+static void vfe32_process_stats_rs_irq(struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	if (!(vfe32_ctrl->rsStatsControl.ackPending)) {
 		vfe32_ctrl->rsStatsControl.bufToRender =
-			vfe32_process_stats_irq_common(statsRsNum,
+			vfe32_process_stats_irq_common(vfe32_ctrl, statsRsNum,
 			vfe32_ctrl->rsStatsControl.nextFrameAddrBuf);
 
-		vfe_send_stats_msg(vfe32_ctrl->rsStatsControl.bufToRender,
-						statsRsNum);
+		vfe_send_stats_msg(vfe32_ctrl,
+			vfe32_ctrl->rsStatsControl.bufToRender, statsRsNum);
 	} else {
 		vfe32_ctrl->rsStatsControl.droppedStatsFrameCount++;
 		CDBG("%s: droppedStatsFrameCount = %d", __func__,
@@ -3230,15 +3568,15 @@
 	}
 }
 
-static void vfe32_process_stats_cs_irq(void)
+static void vfe32_process_stats_cs_irq(struct vfe32_ctrl_type *vfe32_ctrl)
 {
 	if (!(vfe32_ctrl->csStatsControl.ackPending)) {
 		vfe32_ctrl->csStatsControl.bufToRender =
-			vfe32_process_stats_irq_common(statsCsNum,
+			vfe32_process_stats_irq_common(vfe32_ctrl, statsCsNum,
 			vfe32_ctrl->csStatsControl.nextFrameAddrBuf);
 
-		vfe_send_stats_msg(vfe32_ctrl->csStatsControl.bufToRender,
-						statsCsNum);
+		vfe_send_stats_msg(vfe32_ctrl,
+			vfe32_ctrl->csStatsControl.bufToRender, statsCsNum);
 	} else {
 		vfe32_ctrl->csStatsControl.droppedStatsFrameCount++;
 		CDBG("%s: droppedStatsFrameCount = %d", __func__,
@@ -3246,7 +3584,8 @@
 	}
 }
 
-static void vfe32_process_stats(uint32_t status_bits)
+static void vfe32_process_stats(struct vfe32_ctrl_type *vfe32_ctrl,
+	uint32_t status_bits)
 {
 	unsigned long flags;
 	int32_t process_stats = false;
@@ -3257,7 +3596,8 @@
 		if (!vfe32_ctrl->aecStatsControl.ackPending) {
 			vfe32_ctrl->aecStatsControl.ackPending = TRUE;
 			vfe32_ctrl->aecStatsControl.bufToRender =
-				vfe32_process_stats_irq_common(statsAeNum,
+				vfe32_process_stats_irq_common(
+				vfe32_ctrl, statsAeNum,
 				vfe32_ctrl->aecStatsControl.nextFrameAddrBuf);
 			process_stats = true;
 		} else{
@@ -3272,7 +3612,8 @@
 		if (!vfe32_ctrl->awbStatsControl.ackPending) {
 			vfe32_ctrl->awbStatsControl.ackPending = TRUE;
 			vfe32_ctrl->awbStatsControl.bufToRender =
-				vfe32_process_stats_irq_common(statsAwbNum,
+				vfe32_process_stats_irq_common(
+				vfe32_ctrl, statsAwbNum,
 				vfe32_ctrl->awbStatsControl.nextFrameAddrBuf);
 			process_stats = true;
 		} else{
@@ -3288,7 +3629,8 @@
 		if (!vfe32_ctrl->afStatsControl.ackPending) {
 			vfe32_ctrl->afStatsControl.ackPending = TRUE;
 			vfe32_ctrl->afStatsControl.bufToRender =
-				vfe32_process_stats_irq_common(statsAfNum,
+				vfe32_process_stats_irq_common(
+				vfe32_ctrl, statsAfNum,
 				vfe32_ctrl->afStatsControl.nextFrameAddrBuf);
 			process_stats = true;
 		} else {
@@ -3303,7 +3645,8 @@
 		if (!vfe32_ctrl->ihistStatsControl.ackPending) {
 			vfe32_ctrl->ihistStatsControl.ackPending = TRUE;
 			vfe32_ctrl->ihistStatsControl.bufToRender =
-				vfe32_process_stats_irq_common(statsIhistNum,
+				vfe32_process_stats_irq_common(
+				vfe32_ctrl, statsIhistNum,
 				vfe32_ctrl->ihistStatsControl.nextFrameAddrBuf);
 			process_stats = true;
 		} else {
@@ -3318,7 +3661,8 @@
 		if (!vfe32_ctrl->rsStatsControl.ackPending) {
 			vfe32_ctrl->rsStatsControl.ackPending = TRUE;
 			vfe32_ctrl->rsStatsControl.bufToRender =
-				vfe32_process_stats_irq_common(statsRsNum,
+				vfe32_process_stats_irq_common(
+				vfe32_ctrl, statsRsNum,
 				vfe32_ctrl->rsStatsControl.nextFrameAddrBuf);
 			process_stats = true;
 		} else {
@@ -3329,12 +3673,12 @@
 		vfe32_ctrl->rsStatsControl.bufToRender = 0;
 	}
 
-
 	if (status_bits & VFE_IRQ_STATUS0_STATS_CS) {
 		if (!vfe32_ctrl->csStatsControl.ackPending) {
 			vfe32_ctrl->csStatsControl.ackPending = TRUE;
 			vfe32_ctrl->csStatsControl.bufToRender =
-				vfe32_process_stats_irq_common(statsCsNum,
+				vfe32_process_stats_irq_common(
+				vfe32_ctrl, statsCsNum,
 				vfe32_ctrl->csStatsControl.nextFrameAddrBuf);
 			process_stats = true;
 		} else {
@@ -3347,83 +3691,89 @@
 
 	spin_unlock_irqrestore(&vfe32_ctrl->comp_stats_ack_lock, flags);
 	if (process_stats)
-		vfe_send_comp_stats_msg(status_bits);
+		vfe_send_comp_stats_msg(vfe32_ctrl, status_bits);
 
 	return;
 }
 
-static void vfe32_process_stats_irq(uint32_t irqstatus)
+static void vfe32_process_stats_irq(
+	struct vfe32_ctrl_type *vfe32_ctrl, uint32_t irqstatus)
 {
 	uint32_t status_bits = VFE_COM_STATUS & irqstatus;
 
 	if ((vfe32_ctrl->hfr_mode != HFR_MODE_OFF) &&
-		(vfe32_ctrl->vfeFrameId % vfe32_ctrl->hfr_mode != 0)) {
+		(vfe32_ctrl->share_ctrl->vfeFrameId %
+		 vfe32_ctrl->hfr_mode != 0)) {
 		CDBG("Skip the stats when HFR enabled\n");
 		return;
 	}
 
-	vfe32_process_stats(status_bits);
+	vfe32_process_stats(vfe32_ctrl, status_bits);
 	return;
 }
 
-static void vfe32_process_irq(uint32_t irqstatus)
+static void vfe32_process_irq(
+	struct vfe32_ctrl_type *vfe32_ctrl, uint32_t irqstatus)
 {
 	if (irqstatus &
 		VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK) {
-		vfe32_process_stats_irq(irqstatus);
+		vfe32_process_stats_irq(vfe32_ctrl, irqstatus);
 		return;
 	}
 
 	switch (irqstatus) {
 	case VFE_IRQ_STATUS0_CAMIF_SOF_MASK:
 		CDBG("irq	camifSofIrq\n");
-		vfe32_process_camif_sof_irq();
+		vfe32_process_camif_sof_irq(vfe32_ctrl);
 		break;
 	case VFE_IRQ_STATUS0_REG_UPDATE_MASK:
 		CDBG("irq	regUpdateIrq\n");
-		vfe32_process_reg_update_irq();
+		vfe32_process_reg_update_irq(vfe32_ctrl);
 		break;
 	case VFE_IMASK_WHILE_STOPPING_1:
 		CDBG("irq	resetAckIrq\n");
-		vfe32_process_reset_irq();
+		vfe32_process_reset_irq(vfe32_ctrl);
 		break;
 	case VFE_IRQ_STATUS0_STATS_AEC:
 		CDBG("Stats AEC irq occured.\n");
-		vfe32_process_stats_ae_irq();
+		vfe32_process_stats_ae_irq(vfe32_ctrl);
 		break;
 	case VFE_IRQ_STATUS0_STATS_AWB:
 		CDBG("Stats AWB irq occured.\n");
-		vfe32_process_stats_awb_irq();
+		vfe32_process_stats_awb_irq(vfe32_ctrl);
 		break;
 	case VFE_IRQ_STATUS0_STATS_AF:
 		CDBG("Stats AF irq occured.\n");
-		vfe32_process_stats_af_irq();
+		vfe32_process_stats_af_irq(vfe32_ctrl);
 		break;
 	case VFE_IRQ_STATUS0_STATS_IHIST:
 		CDBG("Stats IHIST irq occured.\n");
-		vfe32_process_stats_ihist_irq();
+		vfe32_process_stats_ihist_irq(vfe32_ctrl);
 		break;
 	case VFE_IRQ_STATUS0_STATS_RS:
 		CDBG("Stats RS irq occured.\n");
-		vfe32_process_stats_rs_irq();
+		vfe32_process_stats_rs_irq(vfe32_ctrl);
 		break;
 	case VFE_IRQ_STATUS0_STATS_CS:
 		CDBG("Stats CS irq occured.\n");
-		vfe32_process_stats_cs_irq();
+		vfe32_process_stats_cs_irq(vfe32_ctrl);
 		break;
 	case VFE_IRQ_STATUS0_SYNC_TIMER0:
 		CDBG("SYNC_TIMER 0 irq occured.\n");
-		vfe32_send_isp_msg(vfe32_ctrl,
+		vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+			vfe32_ctrl->share_ctrl->vfeFrameId,
 			MSG_ID_SYNC_TIMER0_DONE);
 		break;
 	case VFE_IRQ_STATUS0_SYNC_TIMER1:
 		CDBG("SYNC_TIMER 1 irq occured.\n");
-		vfe32_send_isp_msg(vfe32_ctrl,
+		vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+			vfe32_ctrl->share_ctrl->vfeFrameId,
 			MSG_ID_SYNC_TIMER1_DONE);
 		break;
 	case VFE_IRQ_STATUS0_SYNC_TIMER2:
 		CDBG("SYNC_TIMER 2 irq occured.\n");
-		vfe32_send_isp_msg(vfe32_ctrl,
+		vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+			vfe32_ctrl->share_ctrl->vfeFrameId,
 			MSG_ID_SYNC_TIMER2_DONE);
 		break;
 	default:
@@ -3474,11 +3824,12 @@
 				NOTIFY_VFE_IRQ,
 				(void *)VFE_IMASK_WHILE_STOPPING_1);
 
-		if (atomic_read(&vfe32_ctrl->vstate)) {
+		if (atomic_read(&axi_ctrl->share_ctrl->vstate)) {
 			if (qcmd->vfeInterruptStatus1 &
 					VFE32_IMASK_ERROR_ONLY_1) {
 				pr_err("irq	errorIrq\n");
 				vfe32_process_error_irq(
+					axi_ctrl,
 					qcmd->vfeInterruptStatus1 &
 					VFE32_IMASK_ERROR_ONLY_1);
 			}
@@ -3487,7 +3838,7 @@
 				(void *)qcmd->vfeInterruptStatus0);
 
 			/* then process stats irq. */
-			if (vfe32_ctrl->stats_comp) {
+			if (axi_ctrl->share_ctrl->stats_comp) {
 				/* process stats comb interrupt. */
 				if (qcmd->vfeInterruptStatus0 &
 					VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK) {
@@ -3567,7 +3918,7 @@
 
 	CDBG("vfe_parse_irq\n");
 
-	vfe32_read_irq_status(&irq);
+	vfe32_read_irq_status(axi_ctrl, &irq);
 
 	if ((irq.vfeIrqStatus0 == 0) && (irq.vfeIrqStatus1 == 0)) {
 		CDBG("vfe_parse_irq: vfeIrqStatus0 & 1 are both 0!\n");
@@ -3581,12 +3932,12 @@
 		return IRQ_HANDLED;
 	}
 
-	spin_lock_irqsave(&vfe32_ctrl->stop_flag_lock, flags);
-	if (vfe32_ctrl->stop_ack_pending) {
+	spin_lock_irqsave(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
+	if (axi_ctrl->share_ctrl->stop_ack_pending) {
 		irq.vfeIrqStatus0 &= VFE_IMASK_WHILE_STOPPING_0;
 		irq.vfeIrqStatus1 &= VFE_IMASK_WHILE_STOPPING_1;
 	}
-	spin_unlock_irqrestore(&vfe32_ctrl->stop_flag_lock, flags);
+	spin_unlock_irqrestore(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
 
 	CDBG("vfe_parse_irq: Irq_status0 = 0x%x, Irq_status1 = 0x%x.\n",
 		irq.vfeIrqStatus0, irq.vfeIrqStatus1);
@@ -3608,6 +3959,8 @@
 {
 	struct msm_cam_media_controller *pmctl =
 		(struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
+	struct vfe32_ctrl_type *vfe32_ctrl =
+		(struct vfe32_ctrl_type *)v4l2_get_subdevdata(sd);
 	struct msm_isp_cmd vfecmd;
 	struct msm_camvfe_params *vfe_params =
 		(struct msm_camvfe_params *)arg;
@@ -3619,8 +3972,14 @@
 	struct vfe_cmd_stats_buf *scfg = NULL;
 	struct msm_pmem_region   *regptr = NULL;
 	struct vfe_cmd_stats_ack *sack = NULL;
+
+	if (!vfe32_ctrl->share_ctrl->vfebase) {
+		pr_err("%s: base address unmapped\n", __func__);
+		return -EFAULT;
+	}
+
 	if (cmd->cmd_type == CMD_VFE_PROCESS_IRQ) {
-		vfe32_process_irq((uint32_t) data);
+		vfe32_process_irq(vfe32_ctrl, (uint32_t) data);
 		return rc;
 	} else if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
 		cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
@@ -3688,22 +4047,22 @@
 		/* individual */
 		switch (cmd->cmd_type) {
 		case CMD_STATS_AEC_ENABLE:
-			rc = vfe_stats_aec_buf_init(scfg);
+			rc = vfe_stats_aec_buf_init(vfe32_ctrl, scfg);
 			break;
 		case CMD_STATS_AF_ENABLE:
-			rc = vfe_stats_af_buf_init(scfg);
+			rc = vfe_stats_af_buf_init(vfe32_ctrl, scfg);
 			break;
 		case CMD_STATS_AWB_ENABLE:
-			rc = vfe_stats_awb_buf_init(scfg);
+			rc = vfe_stats_awb_buf_init(vfe32_ctrl, scfg);
 			break;
 		case CMD_STATS_IHIST_ENABLE:
-			rc = vfe_stats_ihist_buf_init(scfg);
+			rc = vfe_stats_ihist_buf_init(vfe32_ctrl, scfg);
 			break;
 		case CMD_STATS_RS_ENABLE:
-			rc = vfe_stats_rs_buf_init(scfg);
+			rc = vfe_stats_rs_buf_init(vfe32_ctrl, scfg);
 			break;
 		case CMD_STATS_CS_ENABLE:
-			rc = vfe_stats_cs_buf_init(scfg);
+			rc = vfe_stats_cs_buf_init(vfe32_ctrl, scfg);
 			break;
 		default:
 			pr_err("%s Unsupported cmd type %d",
@@ -3714,50 +4073,51 @@
 	}
 	switch (cmd->cmd_type) {
 	case CMD_GENERAL:
-		rc = vfe32_proc_general(pmctl, &vfecmd);
+		rc = vfe32_proc_general(pmctl, &vfecmd, vfe32_ctrl);
 		break;
-
 	case CMD_CONFIG_PING_ADDR: {
 		int path = *((int *)cmd->value);
-		struct vfe32_output_ch *outch = vfe32_get_ch(path);
+		struct vfe32_output_ch *outch =
+			vfe32_get_ch(path, vfe32_ctrl->share_ctrl);
 		outch->ping = *((struct msm_free_buf *)data);
 	}
 		break;
 
 	case CMD_CONFIG_PONG_ADDR: {
 		int path = *((int *)cmd->value);
-		struct vfe32_output_ch *outch = vfe32_get_ch(path);
+		struct vfe32_output_ch *outch =
+			vfe32_get_ch(path, vfe32_ctrl->share_ctrl);
 		outch->pong = *((struct msm_free_buf *)data);
 	}
 		break;
 
 	case CMD_CONFIG_FREE_BUF_ADDR: {
 		int path = *((int *)cmd->value);
-		struct vfe32_output_ch *outch = vfe32_get_ch(path);
+		struct vfe32_output_ch *outch =
+			vfe32_get_ch(path, vfe32_ctrl->share_ctrl);
 		outch->free_buf = *((struct msm_free_buf *)data);
 	}
 		break;
-
 	case CMD_SNAP_BUF_RELEASE:
 		break;
 	case CMD_STATS_AEC_BUF_RELEASE:
-		vfe32_stats_aec_ack(sack);
+		vfe32_stats_aec_ack(vfe32_ctrl, sack);
 		break;
 	case CMD_STATS_AF_BUF_RELEASE:
-		vfe32_stats_af_ack(sack);
+		vfe32_stats_af_ack(vfe32_ctrl, sack);
 		break;
 	case CMD_STATS_AWB_BUF_RELEASE:
-		vfe32_stats_awb_ack(sack);
+		vfe32_stats_awb_ack(vfe32_ctrl, sack);
 		break;
 
 	case CMD_STATS_IHIST_BUF_RELEASE:
-		vfe32_stats_ihist_ack(sack);
+		vfe32_stats_ihist_ack(vfe32_ctrl, sack);
 		break;
 	case CMD_STATS_RS_BUF_RELEASE:
-		vfe32_stats_rs_ack(sack);
+		vfe32_stats_rs_ack(vfe32_ctrl, sack);
 		break;
 	case CMD_STATS_CS_BUF_RELEASE:
-		vfe32_stats_cs_ack(sack);
+		vfe32_stats_cs_ack(vfe32_ctrl, sack);
 		break;
 	default:
 		pr_err("%s Unsupported AXI configuration %x ", __func__,
@@ -3816,17 +4176,16 @@
 	v4l2_set_subdev_hostdata(sd, mctl);
 	spin_lock_init(&axi_ctrl->tasklet_lock);
 	INIT_LIST_HEAD(&axi_ctrl->tasklet_q);
+	spin_lock_init(&axi_ctrl->share_ctrl->sd_notify_lock);
 
-	axi_ctrl->vfebase = ioremap(axi_ctrl->vfemem->start,
+	axi_ctrl->share_ctrl->vfebase = ioremap(axi_ctrl->vfemem->start,
 		resource_size(axi_ctrl->vfemem));
-	if (!axi_ctrl->vfebase) {
+	if (!axi_ctrl->share_ctrl->vfebase) {
 		rc = -ENOMEM;
 		pr_err("%s: vfe ioremap failed\n", __func__);
 		goto remap_failed;
 	}
 
-	vfe32_ctrl->vfebase = axi_ctrl->vfebase;
-
 	if (axi_ctrl->fs_vfe == NULL) {
 		axi_ctrl->fs_vfe =
 			regulator_get(&axi_ctrl->pdev->dev, "fs_vfe");
@@ -3854,11 +4213,12 @@
 	msm_camio_bus_scale_cfg(
 		mctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
 
-	if (msm_camera_io_r(vfe32_ctrl->vfebase + V32_GET_HW_VERSION_OFF) ==
+	if (msm_camera_io_r(
+		axi_ctrl->share_ctrl->vfebase + V32_GET_HW_VERSION_OFF) ==
 		VFE32_HW_NUMBER)
-		vfe32_ctrl->register_total = VFE32_REGISTER_TOTAL;
+		axi_ctrl->share_ctrl->register_total = VFE32_REGISTER_TOTAL;
 	else
-		vfe32_ctrl->register_total = VFE33_REGISTER_TOTAL;
+		axi_ctrl->share_ctrl->register_total = VFE33_REGISTER_TOTAL;
 
 	enable_irq(axi_ctrl->vfeirq->start);
 
@@ -3868,8 +4228,8 @@
 	regulator_put(axi_ctrl->fs_vfe);
 	axi_ctrl->fs_vfe = NULL;
 fs_failed:
-	iounmap(axi_ctrl->vfebase);
-	axi_ctrl->vfebase = NULL;
+	iounmap(axi_ctrl->share_ctrl->vfebase);
+	axi_ctrl->share_ctrl->vfebase = NULL;
 remap_failed:
 	disable_irq(axi_ctrl->vfeirq->start);
 	return rc;
@@ -3879,9 +4239,11 @@
 			struct msm_cam_media_controller *mctl)
 {
 	int rc = 0;
+	struct vfe32_ctrl_type *vfe32_ctrl =
+		(struct vfe32_ctrl_type *)v4l2_get_subdevdata(sd);
 	v4l2_set_subdev_hostdata(sd, mctl);
 
-	spin_lock_init(&vfe32_ctrl->stop_flag_lock);
+	spin_lock_init(&vfe32_ctrl->share_ctrl->stop_flag_lock);
 	spin_lock_init(&vfe32_ctrl->state_lock);
 	spin_lock_init(&vfe32_ctrl->io_lock);
 	spin_lock_init(&vfe32_ctrl->update_ack_lock);
@@ -3893,7 +4255,6 @@
 	spin_lock_init(&vfe32_ctrl->rs_ack_lock);
 	spin_lock_init(&vfe32_ctrl->cs_ack_lock);
 	spin_lock_init(&vfe32_ctrl->comp_stats_ack_lock);
-	spin_lock_init(&vfe32_ctrl->sd_notify_lock);
 
 	vfe32_ctrl->update_linear = false;
 	vfe32_ctrl->update_rolloff = false;
@@ -3909,6 +4270,11 @@
 	struct msm_cam_media_controller *pmctl =
 		(struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
 	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+	if (!axi_ctrl->share_ctrl->vfebase) {
+		pr_err("%s: base address unmapped\n", __func__);
+		return;
+	}
+
 	CDBG("%s, free_irq\n", __func__);
 	disable_irq(axi_ctrl->vfeirq->start);
 	tasklet_kill(&axi_ctrl->vfe32_tasklet);
@@ -3919,8 +4285,8 @@
 		regulator_put(axi_ctrl->fs_vfe);
 		axi_ctrl->fs_vfe = NULL;
 	}
-	iounmap(axi_ctrl->vfebase);
-	axi_ctrl->vfebase = NULL;
+	iounmap(axi_ctrl->share_ctrl->vfebase);
+	axi_ctrl->share_ctrl->vfebase = NULL;
 
 	if (atomic_read(&irq_cnt))
 		pr_warning("%s, Warning IRQ Count not ZERO\n", __func__);
@@ -3931,78 +4297,92 @@
 
 void msm_vfe_subdev_release(struct v4l2_subdev *sd)
 {
-	vfe32_ctrl->vfebase = 0;
+	struct vfe32_ctrl_type *vfe32_ctrl =
+		(struct vfe32_ctrl_type *)v4l2_get_subdevdata(sd);
+	if (!vfe32_ctrl->share_ctrl->vfebase)
+		vfe32_ctrl->share_ctrl->vfebase = NULL;
 }
 
-void axi_start(void)
+void axi_start(struct axi_ctrl_t *axi_ctrl)
 {
-	switch (vfe32_ctrl->operation_mode) {
+	switch (axi_ctrl->share_ctrl->operation_mode) {
 	case VFE_OUTPUTS_PREVIEW:
 	case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
-		if (vfe32_ctrl->outpath.output_mode &
+		if (axi_ctrl->share_ctrl->outpath.output_mode &
 			VFE32_OUTPUT_MODE_PRIMARY) {
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
-		} else if (vfe32_ctrl->outpath.output_mode &
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out0.ch1]);
+		} else if (axi_ctrl->share_ctrl->outpath.output_mode &
 				VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch2]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out0.ch1]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out0.ch2]);
 		}
 		break;
 	default:
-		if (vfe32_ctrl->outpath.output_mode &
+		if (axi_ctrl->share_ctrl->outpath.output_mode &
 			VFE32_OUTPUT_MODE_SECONDARY) {
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
-		} else if (vfe32_ctrl->outpath.output_mode &
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out1.ch1]);
+		} else if (axi_ctrl->share_ctrl->outpath.output_mode &
 			VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch2]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out1.ch1]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out1.ch2]);
 		}
 		break;
 	}
 }
 
-void axi_stop(void)
+void axi_stop(struct axi_ctrl_t *axi_ctrl)
 {
 	uint8_t  axiBusyFlag = true;
-		/* axi halt command. */
+	/* axi halt command. */
 	msm_camera_io_w(AXI_HALT,
-		vfe32_ctrl->vfebase + VFE_AXI_CMD);
+		axi_ctrl->share_ctrl->vfebase + VFE_AXI_CMD);
 	wmb();
 	while (axiBusyFlag) {
-		if (msm_camera_io_r(vfe32_ctrl->vfebase + VFE_AXI_STATUS) & 0x1)
+		if (msm_camera_io_r(
+			axi_ctrl->share_ctrl->vfebase + VFE_AXI_STATUS) & 0x1)
 			axiBusyFlag = false;
 	}
 	/* Ensure the write order while writing
 	to the command register using the barrier */
 	msm_camera_io_w_mb(AXI_HALT_CLEAR,
-		vfe32_ctrl->vfebase + VFE_AXI_CMD);
+		axi_ctrl->share_ctrl->vfebase + VFE_AXI_CMD);
 
 	/* after axi halt, then ok to apply global reset. */
 	/* enable reset_ack and async timer interrupt only while
 	stopping the pipeline.*/
 	msm_camera_io_w(0xf0000000,
-		vfe32_ctrl->vfebase + VFE_IRQ_MASK_0);
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
 	msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
-		vfe32_ctrl->vfebase + VFE_IRQ_MASK_1);
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
 
 	/* Ensure the write order while writing
 	to the command register using the barrier */
 	msm_camera_io_w_mb(VFE_RESET_UPON_STOP_CMD,
-		vfe32_ctrl->vfebase + VFE_GLOBAL_RESET);
+		axi_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
 }
 
 static int msm_axi_config(struct v4l2_subdev *sd, void __user *arg)
@@ -4010,7 +4390,12 @@
 	struct msm_vfe_cfg_cmd cfgcmd;
 	struct msm_isp_cmd vfecmd;
 	int rc = 0;
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
 
+	if (!axi_ctrl->share_ctrl->vfebase) {
+		pr_err("%s: base address unmapped\n", __func__);
+		return -EFAULT;
+	}
 	if (NULL != arg) {
 		if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
 			ERR_COPY_FROM_USER();
@@ -4043,7 +4428,7 @@
 			rc = -EFAULT;
 			break;
 		}
-		vfe32_config_axi(OUTPUT_PRIM, axio);
+		vfe32_config_axi(axi_ctrl, OUTPUT_PRIM, axio);
 		kfree(axio);
 	}
 		break;
@@ -4062,7 +4447,7 @@
 			rc = -EFAULT;
 			break;
 		}
-		vfe32_config_axi(OUTPUT_PRIM_ALL_CHNLS, axio);
+		vfe32_config_axi(axi_ctrl, OUTPUT_PRIM_ALL_CHNLS, axio);
 		kfree(axio);
 	}
 		break;
@@ -4081,7 +4466,7 @@
 			rc = -EFAULT;
 			break;
 		}
-		vfe32_config_axi(OUTPUT_PRIM|OUTPUT_SEC, axio);
+		vfe32_config_axi(axi_ctrl, OUTPUT_PRIM|OUTPUT_SEC, axio);
 		kfree(axio);
 	}
 		break;
@@ -4100,7 +4485,8 @@
 			rc = -EFAULT;
 			break;
 		}
-		vfe32_config_axi(OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS, axio);
+		vfe32_config_axi(axi_ctrl,
+			OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS, axio);
 		kfree(axio);
 	}
 		break;
@@ -4119,7 +4505,8 @@
 			rc = -EFAULT;
 			break;
 		}
-		vfe32_config_axi(OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC, axio);
+		vfe32_config_axi(axi_ctrl,
+			OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC, axio);
 		kfree(axio);
 	}
 		break;
@@ -4128,10 +4515,10 @@
 			__func__, cfgcmd.cmd_type);
 		break;
 	case CMD_AXI_START:
-		axi_start();
+		axi_start(axi_ctrl);
 		break;
 	case CMD_AXI_STOP:
-		axi_stop();
+		axi_stop(axi_ctrl);
 		break;
 	default:
 		pr_err("%s Unsupported AXI configuration %x ", __func__,
@@ -4143,43 +4530,95 @@
 
 static void msm_axi_process_irq(struct v4l2_subdev *sd, void *arg)
 {
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
 	uint32_t irqstatus = (uint32_t) arg;
+
+	if (!axi_ctrl->share_ctrl->vfebase) {
+		pr_err("%s: base address unmapped\n", __func__);
+		return;
+	}
 	/* next, check output path related interrupts. */
 	if (irqstatus &
 		VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK) {
 		CDBG("Image composite done 0 irq occured.\n");
-		vfe32_process_output_path_irq_0();
+		vfe32_process_output_path_irq_0(axi_ctrl);
 	}
 	if (irqstatus &
 		VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK) {
 		CDBG("Image composite done 1 irq occured.\n");
-		vfe32_process_output_path_irq_1();
+		vfe32_process_output_path_irq_1(axi_ctrl);
 	}
 	/* in snapshot mode if done then send
 	snapshot done message */
-	if (vfe32_ctrl->operation_mode ==
+	if (axi_ctrl->share_ctrl->operation_mode ==
 			VFE_OUTPUTS_THUMB_AND_MAIN ||
-		vfe32_ctrl->operation_mode ==
+		axi_ctrl->share_ctrl->operation_mode ==
 			VFE_OUTPUTS_MAIN_AND_THUMB ||
-		vfe32_ctrl->operation_mode ==
+		axi_ctrl->share_ctrl->operation_mode ==
 			VFE_OUTPUTS_THUMB_AND_JPEG ||
-		vfe32_ctrl->operation_mode ==
+		axi_ctrl->share_ctrl->operation_mode ==
 			VFE_OUTPUTS_JPEG_AND_THUMB ||
-		vfe32_ctrl->operation_mode ==
+		axi_ctrl->share_ctrl->operation_mode ==
 			VFE_OUTPUTS_RAW) {
-		if ((vfe32_ctrl->outpath.out0.capture_cnt == 0)
-				&& (vfe32_ctrl->outpath.out1.
+		if ((axi_ctrl->share_ctrl->outpath.out0.capture_cnt == 0)
+				&& (axi_ctrl->share_ctrl->outpath.out1.
 				capture_cnt == 0)) {
 			msm_camera_io_w_mb(
 				CAMIF_COMMAND_STOP_IMMEDIATELY,
-				vfe32_ctrl->vfebase +
+				axi_ctrl->share_ctrl->vfebase +
 				VFE_CAMIF_COMMAND);
-			vfe32_send_isp_msg(vfe32_ctrl,
+			vfe32_send_isp_msg(&axi_ctrl->subdev,
+				axi_ctrl->share_ctrl->vfeFrameId,
 				MSG_ID_SNAPSHOT_DONE);
 		}
 	}
 }
 
+static int msm_axi_buf_cfg(struct v4l2_subdev *sd, void __user *arg)
+{
+	struct msm_camvfe_params *vfe_params =
+		(struct msm_camvfe_params *)arg;
+	struct msm_vfe_cfg_cmd *cmd = vfe_params->vfe_cfg;
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+	void *data = vfe_params->data;
+	int rc = 0;
+
+	if (!axi_ctrl->share_ctrl->vfebase) {
+		pr_err("%s: base address unmapped\n", __func__);
+		return -EFAULT;
+	}
+
+	switch (cmd->cmd_type) {
+	case CMD_CONFIG_PING_ADDR: {
+		int path = *((int *)cmd->value);
+		struct vfe32_output_ch *outch =
+			vfe32_get_ch(path, axi_ctrl->share_ctrl);
+		outch->ping = *((struct msm_free_buf *)data);
+	}
+		break;
+
+	case CMD_CONFIG_PONG_ADDR: {
+		int path = *((int *)cmd->value);
+		struct vfe32_output_ch *outch =
+			vfe32_get_ch(path, axi_ctrl->share_ctrl);
+		outch->pong = *((struct msm_free_buf *)data);
+	}
+		break;
+
+	case CMD_CONFIG_FREE_BUF_ADDR: {
+		int path = *((int *)cmd->value);
+		struct vfe32_output_ch *outch =
+			vfe32_get_ch(path, axi_ctrl->share_ctrl);
+		outch->free_buf = *((struct msm_free_buf *)data);
+	}
+		break;
+	default:
+		pr_err("%s Unsupported AXI Buf config %x ", __func__,
+			cmd->cmd_type);
+	}
+	return rc;
+};
+
 static const struct v4l2_subdev_internal_ops msm_vfe_internal_ops;
 
 static long msm_axi_subdev_ioctl(struct v4l2_subdev *sd,
@@ -4198,6 +4637,10 @@
 		msm_axi_process_irq(sd, arg);
 		rc = 0;
 		break;
+	case VIDIOC_MSM_AXI_BUF_CFG:
+		msm_axi_buf_cfg(sd, arg);
+		rc = 0;
+		break;
 	case VIDIOC_MSM_AXI_RELEASE:
 		msm_axi_subdev_release(sd);
 		rc = 0;
@@ -4227,14 +4670,36 @@
 {
 	int rc = 0;
 	struct axi_ctrl_t *axi_ctrl;
+	struct vfe32_ctrl_type *vfe32_ctrl;
+	struct vfe_share_ctrl_t *share_ctrl;
 	CDBG("%s: device id = %d\n", __func__, pdev->id);
-	vfe32_ctrl = kzalloc(sizeof(struct vfe32_ctrl_type), GFP_KERNEL);
-	if (!vfe32_ctrl) {
+
+	share_ctrl = kzalloc(sizeof(struct vfe_share_ctrl_t), GFP_KERNEL);
+	if (!share_ctrl) {
 		pr_err("%s: no enough memory\n", __func__);
 		return -ENOMEM;
 	}
 
 	axi_ctrl = kzalloc(sizeof(struct axi_ctrl_t), GFP_KERNEL);
+	if (!axi_ctrl) {
+		pr_err("%s: no enough memory\n", __func__);
+		kfree(share_ctrl);
+		return -ENOMEM;
+	}
+
+	vfe32_ctrl = kzalloc(sizeof(struct vfe32_ctrl_type), GFP_KERNEL);
+	if (!vfe32_ctrl) {
+		pr_err("%s: no enough memory\n", __func__);
+		kfree(share_ctrl);
+		kfree(axi_ctrl);
+		return -ENOMEM;
+	}
+
+	share_ctrl->axi_ctrl = axi_ctrl;
+	share_ctrl->vfe32_ctrl = vfe32_ctrl;
+	axi_ctrl->share_ctrl = share_ctrl;
+	vfe32_ctrl->share_ctrl = share_ctrl;
+
 	v4l2_subdev_init(&axi_ctrl->subdev, &msm_axi_subdev_ops);
 	axi_ctrl->subdev.internal_ops = &msm_axi_internal_ops;
 	axi_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
diff --git a/drivers/media/video/msm/msm_vfe32.h b/drivers/media/video/msm/msm_vfe32.h
index d1faded..086600a 100644
--- a/drivers/media/video/msm/msm_vfe32.h
+++ b/drivers/media/video/msm/msm_vfe32.h
@@ -900,6 +900,30 @@
 	uint32_t droppedStatsFrameCount;
 	uint32_t bufToRender;
 };
+struct axi_ctrl_t;
+struct vfe32_ctrl_type;
+
+struct vfe_share_ctrl_t {
+	void __iomem *vfebase;
+	uint32_t register_total;
+
+	atomic_t vstate;
+	uint32_t vfeFrameId;
+	uint32_t stats_comp;
+	spinlock_t  stop_flag_lock;
+	int8_t stop_ack_pending;
+	enum vfe_output_state liveshot_state;
+	uint32_t vfe_capture_count;
+
+	uint16_t operation_mode;     /* streaming or snapshot */
+	struct vfe32_output_path outpath;
+
+	uint32_t ref_count;
+	spinlock_t  sd_notify_lock;
+
+	struct axi_ctrl_t *axi_ctrl;
+	struct vfe32_ctrl_type *vfe32_ctrl;
+};
 
 struct axi_ctrl_t {
 	struct v4l2_subdev subdev;
@@ -908,7 +932,6 @@
 	spinlock_t  tasklet_lock;
 	struct list_head tasklet_q;
 
-	void __iomem *vfebase;
 	void *syncdata;
 
 	struct resource	*vfemem;
@@ -916,15 +939,12 @@
 	struct regulator *fs_vfe;
 	struct clk *vfe_clk[3];
 	struct tasklet_struct vfe32_tasklet;
+	struct vfe_share_ctrl_t *share_ctrl;
 };
 
 struct vfe32_ctrl_type {
-	uint16_t operation_mode;     /* streaming or snapshot */
-	struct vfe32_output_path outpath;
-
 	uint32_t vfeImaskCompositePacked;
 
-	spinlock_t  stop_flag_lock;
 	spinlock_t  update_ack_lock;
 	spinlock_t  state_lock;
 	spinlock_t  io_lock;
@@ -941,7 +961,6 @@
 	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;
@@ -949,19 +968,13 @@
 	int8_t update_rolloff;
 	int8_t update_la;
 	int8_t update_gamma;
-	enum vfe_output_state liveshot_state;
 
-	void __iomem *vfebase;
-	uint32_t register_total;
+	struct vfe_share_ctrl_t *share_ctrl;
 
-	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;
@@ -978,7 +991,6 @@
 	/* v4l2 subdev */
 	struct v4l2_subdev subdev;
 	struct platform_device *pdev;
-	spinlock_t  sd_notify_lock;
 	uint32_t hfr_mode;
 	uint32_t frame_skip_cnt;
 	uint32_t frame_skip_pattern;
@@ -1015,4 +1027,7 @@
 #define VIDIOC_MSM_AXI_IRQ \
 	_IOWR('V', BASE_VIDIOC_PRIVATE + 21, void *)
 
+#define VIDIOC_MSM_AXI_BUF_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 22, void *)
+
 #endif /* __MSM_VFE32_H__ */
diff --git a/drivers/media/video/msm/msm_vpe.c b/drivers/media/video/msm/msm_vpe.c
index f9ce74b..54e9582 100644
--- a/drivers/media/video/msm/msm_vpe.c
+++ b/drivers/media/video/msm/msm_vpe.c
@@ -30,14 +30,19 @@
 #include "msm.h"
 #include "msm_vpe.h"
 
+#ifdef CONFIG_MSM_CAMERA_DEBUG
+#define D(fmt, args...) pr_debug("msm_vpe: " fmt, ##args)
+#else
+#define D(fmt, args...) do {} while (0)
+#endif
+
 static int vpe_enable(uint32_t);
 static int vpe_disable(void);
 static int vpe_update_scaler(struct msm_pp_crop *pcrop);
 struct vpe_ctrl_type *vpe_ctrl;
 static atomic_t vpe_init_done = ATOMIC_INIT(0);
 
-static int msm_vpe_do_pp(struct msm_mctl_pp_cmd *cmd,
-	struct msm_mctl_pp_frame_info *pp_frame_info);
+static int msm_vpe_do_pp(struct msm_mctl_pp_frame_info *pp_frame_info);
 
 static long long vpe_do_div(long long num, long long den)
 {
@@ -57,8 +62,7 @@
 	msm_camera_io_dump(vpe_ctrl->vpebase + 0x50400, 0x10);
 
 	/* this triggers the operation. */
-	msm_camera_io_w(1, vpe_ctrl->vpebase + VPE_DL0_START_OFFSET);
-	wmb();
+	msm_camera_io_w_mb(1, vpe_ctrl->vpebase + VPE_DL0_START_OFFSET);
 	return 0;
 }
 
@@ -72,7 +76,7 @@
 static void vpe_config_axi_default(void)
 {
 	msm_camera_io_w(0x25, vpe_ctrl->vpebase + VPE_AXI_ARB_2_OFFSET);
-	CDBG("%s: yaddr %ld cbcraddr %ld", __func__,
+	D("%s: yaddr %ld cbcraddr %ld", __func__,
 		 vpe_ctrl->out_y_addr, vpe_ctrl->out_cbcr_addr);
 	if (!vpe_ctrl->out_y_addr || !vpe_ctrl->out_cbcr_addr)
 		return;
@@ -81,7 +85,6 @@
 	/* for video  CbCr address */
 	msm_camera_io_w(vpe_ctrl->out_cbcr_addr,
 		vpe_ctrl->vpebase + VPE_OUTP1_ADDR_OFFSET);
-
 }
 
 static int vpe_reset(void)
@@ -92,7 +95,7 @@
 
 	spin_lock_irqsave(&vpe_ctrl->lock, flags);
 	if (vpe_ctrl->state == VPE_STATE_IDLE) {
-		CDBG("%s: VPE already disabled.", __func__);
+		D("%s: VPE already disabled.", __func__);
 		spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
 		return rc;
 	}
@@ -101,7 +104,7 @@
 	vpe_reset_state_variables();
 	vpe_version = msm_camera_io_r(
 			vpe_ctrl->vpebase + VPE_HW_VERSION_OFFSET);
-	CDBG("vpe_version = 0x%x\n", vpe_version);
+	D("vpe_version = 0x%x\n", vpe_version);
 	/* disable all interrupts.*/
 	msm_camera_io_w(0, vpe_ctrl->vpebase + VPE_INTR_ENABLE_OFFSET);
 	/* clear all pending interrupts*/
@@ -139,13 +142,13 @@
 	rot_flag = msm_camera_io_r(vpe_ctrl->vpebase +
 						VPE_OP_MODE_OFFSET) & 0xE00;
 	if (pinfo != NULL) {
-		CDBG("%s: Crop info in2_w = %d, in2_h = %d "
+		D("%s: Crop info in2_w = %d, in2_h = %d "
 			"out2_w = %d out2_h = %d\n",
 			__func__, pcrop->src_w, pcrop->src_h,
 			pcrop->dst_w, pcrop->dst_h);
 		rc = vpe_update_scaler(pcrop);
 	}
-	CDBG("return rc = %d rot_flag = %d\n", rc, rot_flag);
+	D("return rc = %d rot_flag = %d\n", rc, rot_flag);
 	rc |= rot_flag;
 
 	return rc;
@@ -200,7 +203,7 @@
 		vpe_ctrl->out_w = w;
 		vpe_ctrl->out_h = h;
 	}
-	CDBG("%s: out_w=%d, out_h=%d", __func__, vpe_ctrl->out_w,
+	D("%s: out_w=%d, out_h=%d", __func__, vpe_ctrl->out_w,
 		vpe_ctrl->out_h);
 	return 0;
 }
@@ -239,7 +242,7 @@
 	out_ROI_width = pcrop->dst_w;
 	out_ROI_height = pcrop->dst_h;
 
-	CDBG("src w = 0x%x, h=0x%x, dst w = 0x%x, h =0x%x.\n",
+	D("src w = 0x%x, h=0x%x, dst w = 0x%x, h =0x%x.\n",
 		src_ROI_width, src_ROI_height, out_ROI_width,
 		out_ROI_height);
 	src_roi = (src_ROI_height << 16) + src_ROI_width;
@@ -249,12 +252,12 @@
 	src_x = pcrop->src_x;
 	src_y = pcrop->src_y;
 
-	CDBG("src_x = %d, src_y=%d.\n", src_x, src_y);
+	D("src_x = %d, src_y=%d.\n", src_x, src_y);
 
 	src_xy = src_y*(1<<16) + src_x;
 	msm_camera_io_w(src_xy, vpe_ctrl->vpebase +
 			VPE_SRC_XY_OFFSET);
-	CDBG("src_xy = %d, src_roi=%d.\n", src_xy, src_roi);
+	D("src_xy = %d, src_roi=%d.\n", src_xy, src_roi);
 
 	/* decide whether to use FIR or M/N for scaling */
 	if ((out_ROI_width == 1 && src_ROI_width < 4) ||
@@ -387,9 +390,9 @@
 	} else if (scale_unit_sel_y == 1) /* M over N scalar   */
 		phase_init_y = 0;
 
-	CDBG("phase step x = %d, step y = %d.\n",
+	D("phase step x = %d, step y = %d.\n",
 		 phase_step_x, phase_step_y);
-	CDBG("phase init x = %d, init y = %d.\n",
+	D("phase init x = %d, init y = %d.\n",
 		 phase_init_x, phase_init_y);
 
 	msm_camera_io_w(phase_step_x, vpe_ctrl->vpebase +
@@ -416,24 +419,40 @@
 	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
 	return busy;
 }
+
 static int msm_send_frame_to_vpe(void)
 {
 	int rc = 0;
 	unsigned long flags;
+	unsigned long srcP0, srcP1, outP0, outP1;
+	struct msm_mctl_pp_frame_info *frame = vpe_ctrl->pp_frame_info;
 
 	spin_lock_irqsave(&vpe_ctrl->lock, flags);
-	msm_camera_io_w((vpe_ctrl->pp_frame_info->src_frame.sp.phy_addr +
-			  vpe_ctrl->pp_frame_info->src_frame.sp.y_off),
-			vpe_ctrl->vpebase + VPE_SRCP0_ADDR_OFFSET);
-	msm_camera_io_w((vpe_ctrl->pp_frame_info->src_frame.sp.phy_addr +
-			  vpe_ctrl->pp_frame_info->src_frame.sp.cbcr_off),
-			vpe_ctrl->vpebase + VPE_SRCP1_ADDR_OFFSET);
-	msm_camera_io_w((vpe_ctrl->pp_frame_info->dest_frame.sp.phy_addr +
-			  vpe_ctrl->pp_frame_info->dest_frame.sp.y_off),
-			vpe_ctrl->vpebase + VPE_OUTP0_ADDR_OFFSET);
-	msm_camera_io_w((vpe_ctrl->pp_frame_info->dest_frame.sp.phy_addr +
-			  vpe_ctrl->pp_frame_info->dest_frame.sp.cbcr_off),
-			vpe_ctrl->vpebase + VPE_OUTP1_ADDR_OFFSET);
+	if (frame->src_frame.num_planes > 1) {
+		srcP0 = vpe_ctrl->pp_frame_info->src_frame.mp[0].phy_addr +
+			vpe_ctrl->pp_frame_info->src_frame.mp[0].data_offset;
+		srcP1 = vpe_ctrl->pp_frame_info->src_frame.mp[1].phy_addr +
+			vpe_ctrl->pp_frame_info->src_frame.mp[1].data_offset;
+		outP0 = vpe_ctrl->pp_frame_info->dest_frame.mp[0].phy_addr +
+			vpe_ctrl->pp_frame_info->dest_frame.mp[0].data_offset;
+		outP1 = vpe_ctrl->pp_frame_info->dest_frame.mp[1].phy_addr +
+			vpe_ctrl->pp_frame_info->dest_frame.mp[1].data_offset;
+	} else {
+		srcP0 = vpe_ctrl->pp_frame_info->src_frame.sp.phy_addr +
+			vpe_ctrl->pp_frame_info->src_frame.sp.y_off;
+		srcP1 = vpe_ctrl->pp_frame_info->src_frame.sp.phy_addr +
+			vpe_ctrl->pp_frame_info->src_frame.sp.cbcr_off;
+		outP0 = vpe_ctrl->pp_frame_info->dest_frame.sp.phy_addr +
+			vpe_ctrl->pp_frame_info->dest_frame.sp.y_off;
+		outP1 = vpe_ctrl->pp_frame_info->dest_frame.sp.phy_addr +
+			vpe_ctrl->pp_frame_info->dest_frame.sp.cbcr_off;
+	}
+
+	msm_camera_io_w(srcP0, vpe_ctrl->vpebase + VPE_SRCP0_ADDR_OFFSET);
+	msm_camera_io_w(srcP1, vpe_ctrl->vpebase + VPE_SRCP1_ADDR_OFFSET);
+	msm_camera_io_w(outP0, vpe_ctrl->vpebase + VPE_OUTP0_ADDR_OFFSET);
+	msm_camera_io_w(outP1, vpe_ctrl->vpebase + VPE_OUTP1_ADDR_OFFSET);
+
 	vpe_ctrl->state = VPE_STATE_ACTIVE;
 	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
 	vpe_start();
@@ -443,27 +462,33 @@
 static void vpe_send_outmsg(void)
 {
 	unsigned long flags;
-	struct msm_vpe_resp rp;
-	memset(&rp, 0, sizeof(rp));
+	struct v4l2_event v4l2_evt;
+	struct msm_queue_cmd *event_qcmd;
 	spin_lock_irqsave(&vpe_ctrl->lock, flags);
 	if (vpe_ctrl->state == VPE_STATE_IDLE) {
 		pr_err("%s VPE is in IDLE state. Ignore the ack msg", __func__);
 		spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
 		return;
 	}
-	rp.type = vpe_ctrl->pp_frame_info->pp_frame_cmd.path;
-	rp.extdata = (void *)vpe_ctrl->pp_frame_info;
-	rp.extlen = sizeof(*vpe_ctrl->pp_frame_info);
-	vpe_ctrl->state = VPE_STATE_INIT;   /* put it back to idle. */
+	event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_ATOMIC);
+	atomic_set(&event_qcmd->on_heap, 1);
+	event_qcmd->command = (void *)vpe_ctrl->pp_frame_info;
 	vpe_ctrl->pp_frame_info = NULL;
+	vpe_ctrl->state = VPE_STATE_INIT;   /* put it back to idle. */
+
+	/* Enqueue the event payload. */
+	msm_enqueue(&vpe_ctrl->eventData_q, &event_qcmd->list_eventdata);
+	/* Now queue the event. */
+	v4l2_evt.type = V4L2_EVENT_PRIVATE_START + MSM_CAM_RESP_MCTL_PP_EVENT;
+	v4l2_evt.id = 0;
+	v4l2_event_queue(vpe_ctrl->subdev.devnode, &v4l2_evt);
+
 	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
-	v4l2_subdev_notify(&vpe_ctrl->subdev,
-		NOTIFY_VPE_MSG_EVT, (void *)&rp);
 }
 
 static void vpe_do_tasklet(unsigned long data)
 {
-	CDBG("%s: irq_status = 0x%x",
+	D("%s: irq_status = 0x%x",
 		   __func__, vpe_ctrl->irq_status);
 	if (vpe_ctrl->irq_status & 0x1)
 		vpe_send_outmsg();
@@ -478,7 +503,7 @@
 	msm_camera_io_w_mb(vpe_ctrl->irq_status, vpe_ctrl->vpebase +
 				VPE_INTR_CLEAR_OFFSET);
 	msm_camera_io_w(0, vpe_ctrl->vpebase + VPE_INTR_ENABLE_OFFSET);
-	CDBG("%s: vpe_parse_irq =0x%x.\n", __func__, vpe_ctrl->irq_status);
+	D("%s: vpe_parse_irq =0x%x.\n", __func__, vpe_ctrl->irq_status);
 	tasklet_schedule(&vpe_tasklet);
 	return IRQ_HANDLED;
 }
@@ -492,7 +517,7 @@
 {
 	int rc = 0;
 	unsigned long flags = 0;
-	CDBG("%s", __func__);
+	D("%s", __func__);
 	/* don't change the order of clock and irq.*/
 	spin_lock_irqsave(&vpe_ctrl->lock, flags);
 	if (vpe_ctrl->state != VPE_STATE_IDLE) {
@@ -536,10 +561,10 @@
 {
 	int rc = 0;
 	unsigned long flags = 0;
-	CDBG("%s", __func__);
+	D("%s", __func__);
 	spin_lock_irqsave(&vpe_ctrl->lock, flags);
 	if (vpe_ctrl->state == VPE_STATE_IDLE) {
-		CDBG("%s: VPE already disabled", __func__);
+		D("%s: VPE already disabled", __func__);
 		spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
 		return rc;
 	}
@@ -559,8 +584,7 @@
 	return rc;
 }
 
-static int msm_vpe_do_pp(struct msm_mctl_pp_cmd *cmd,
-			struct msm_mctl_pp_frame_info *pp_frame_info)
+static int msm_vpe_do_pp(struct msm_mctl_pp_frame_info *pp_frame_info)
 {
 	int rc = 0;
 	unsigned long flags;
@@ -577,7 +601,7 @@
 	vpe_ctrl->pp_frame_info = pp_frame_info;
 	msm_vpe_cfg_update(
 		&vpe_ctrl->pp_frame_info->pp_frame_cmd.crop);
-	CDBG("%s Sending frame idx %d id %d to VPE ", __func__,
+	D("%s Sending frame idx %d id %d to VPE ", __func__,
 		pp_frame_info->src_frame.buf_idx,
 		pp_frame_info->src_frame.frame_id);
 	rc = msm_send_frame_to_vpe();
@@ -590,7 +614,7 @@
 		struct msm_cam_media_controller *mctl)
 {
 	int rc = 0;
-	CDBG("%s:begin", __func__);
+	D("%s:begin", __func__);
 	if (atomic_read(&vpe_init_done)) {
 		pr_err("%s: VPE has been initialized", __func__);
 		return -EBUSY;
@@ -604,7 +628,7 @@
 	}
 	v4l2_set_subdev_hostdata(sd, mctl);
 	spin_lock_init(&vpe_ctrl->lock);
-	CDBG("%s:end", __func__);
+	D("%s:end", __func__);
 	return rc;
 }
 EXPORT_SYMBOL(msm_vpe_subdev_init);
@@ -646,84 +670,310 @@
 }
 EXPORT_SYMBOL(msm_vpe_subdev_release);
 
-static long msm_vpe_subdev_ioctl(struct v4l2_subdev *sd,
-			unsigned int subdev_cmd, void *arg)
+static int msm_vpe_process_vpe_cmd(struct msm_vpe_cfg_cmd *vpe_cmd)
 {
-	struct msm_mctl_pp_params *vpe_params;
-	struct msm_mctl_pp_cmd *cmd;
 	int rc = 0;
 
-	if (subdev_cmd == VIDIOC_MSM_VPE_INIT) {
+	switch (vpe_cmd->cmd_type) {
+	case VPE_CMD_RESET:
+		rc = vpe_reset();
+		break;
+
+	case VPE_CMD_OPERATION_MODE_CFG: {
+		struct msm_vpe_op_mode_cfg op_mode_cfg;
+		if (sizeof(struct msm_vpe_op_mode_cfg) != vpe_cmd->length) {
+			pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d",
+				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
+				sizeof(struct msm_vpe_op_mode_cfg));
+			rc = -EINVAL;
+			break;
+		}
+		COPY_FROM_USER(rc, &op_mode_cfg, (void __user *)vpe_cmd->value,
+			sizeof(op_mode_cfg));
+		if (rc) {
+			ERR_COPY_FROM_USER();
+			break;
+		}
+
+		vpe_cmd->value = (void *)&op_mode_cfg;
+		rc = vpe_operation_config(vpe_cmd->value);
+		break;
+		}
+
+	case VPE_CMD_INPUT_PLANE_CFG: {
+		struct msm_vpe_input_plane_cfg input_cfg;
+		if (sizeof(struct msm_vpe_input_plane_cfg) != vpe_cmd->length) {
+			pr_err("%s: mismatch cmd = %d, len = %d, expected = %d",
+				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
+				sizeof(struct msm_vpe_input_plane_cfg));
+			rc = -EINVAL;
+			break;
+		}
+		COPY_FROM_USER(rc, &input_cfg, (void __user *)vpe_cmd->value,
+			sizeof(input_cfg));
+		if (rc) {
+			ERR_COPY_FROM_USER();
+			break;
+		}
+
+		vpe_cmd->value = (void *)&input_cfg;
+		vpe_input_plane_config(vpe_cmd->value);
+		break;
+		}
+
+	case VPE_CMD_OUTPUT_PLANE_CFG: {
+		struct msm_vpe_output_plane_cfg output_cfg;
+		if (sizeof(struct msm_vpe_output_plane_cfg) !=
+			vpe_cmd->length) {
+			pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d",
+				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
+				sizeof(struct msm_vpe_output_plane_cfg));
+				rc = -EINVAL;
+				break;
+		}
+		COPY_FROM_USER(rc, &output_cfg, (void __user *)vpe_cmd->value,
+			sizeof(output_cfg));
+		if (rc) {
+			ERR_COPY_FROM_USER();
+			break;
+		}
+
+		vpe_cmd->value = (void *)&output_cfg;
+		vpe_output_plane_config(vpe_cmd->value);
+		break;
+		}
+
+	case VPE_CMD_SCALE_CFG_TYPE:{
+		struct msm_vpe_scaler_cfg scaler_cfg;
+		if (sizeof(struct msm_vpe_scaler_cfg) != vpe_cmd->length) {
+			pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d",
+				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
+				sizeof(struct msm_vpe_scaler_cfg));
+			rc = -EINVAL;
+			break;
+		}
+		COPY_FROM_USER(rc, &scaler_cfg, (void __user *)vpe_cmd->value,
+			sizeof(scaler_cfg));
+		if (rc) {
+			ERR_COPY_FROM_USER();
+			break;
+		}
+
+		vpe_cmd->value = (void *)&scaler_cfg;
+		vpe_update_scale_coef(vpe_cmd->value);
+		break;
+		}
+
+	case VPE_CMD_ZOOM: {
+		struct msm_mctl_pp_frame_info *zoom;
+		zoom = kmalloc(sizeof(struct msm_mctl_pp_frame_info),
+				GFP_ATOMIC);
+		if (!zoom) {
+			pr_err("%s Not enough memory ", __func__);
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (sizeof(zoom->pp_frame_cmd) != vpe_cmd->length) {
+			pr_err("%s: size mismatch id=%d, len=%d, expected=%d",
+				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
+				sizeof(zoom->pp_frame_cmd));
+			rc = -EINVAL;
+			kfree(zoom);
+			break;
+		}
+		COPY_FROM_USER(rc, &zoom->pp_frame_cmd,
+			(void __user *)vpe_cmd->value,
+			sizeof(zoom->pp_frame_cmd));
+		if (rc) {
+			ERR_COPY_FROM_USER();
+			kfree(zoom);
+			break;
+		}
+
+		zoom->user_cmd = vpe_cmd->cmd_type;
+		zoom->p_mctl = v4l2_get_subdev_hostdata(&vpe_ctrl->subdev);
+		D("%s: src=0x%x, dest=0x%x,cookie=0x%x,action=0x%x,path=0x%x",
+			__func__, zoom->pp_frame_cmd.src_buf_handle,
+			zoom->pp_frame_cmd.dest_buf_handle,
+			zoom->pp_frame_cmd.cookie,
+			zoom->pp_frame_cmd.vpe_output_action,
+			zoom->pp_frame_cmd.path);
+		rc = msm_mctl_pp_get_vpe_buf_info(zoom);
+		if (rc < 0) {
+			pr_err("%s Error getting buffer info from mctl rc = %d",
+				__func__, rc);
+			kfree(zoom);
+			break;
+		}
+		rc = msm_vpe_do_pp(zoom);
+		break;
+		}
+
+	case VPE_CMD_ENABLE: {
+		struct msm_vpe_clock_rate clk_rate;
+		int turbo_mode;
+		if (sizeof(struct msm_vpe_clock_rate) != vpe_cmd->length) {
+			pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d",
+				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
+				sizeof(struct msm_vpe_clock_rate));
+			rc = -EINVAL;
+			break;
+		}
+		if (copy_from_user(&clk_rate, (void __user *)vpe_cmd->value,
+			sizeof(struct msm_vpe_clock_rate))) {
+			pr_err("%s:clk_rate copy failed", __func__);
+			return -EFAULT;
+		}
+		turbo_mode = (int)clk_rate.rate;
+		rc = turbo_mode ? vpe_enable(VPE_TURBO_MODE_CLOCK_RATE) :
+				vpe_enable(VPE_NORMAL_MODE_CLOCK_RATE);
+		break;
+		}
+
+	case VPE_CMD_DISABLE:
+		rc = vpe_disable();
+		break;
+
+	default:
+		break;
+	}
+
+	return rc;
+}
+
+static long msm_vpe_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg)
+{
+	struct msm_vpe_cfg_cmd *vpe_cmd;
+	int rc = 0;
+
+	switch (cmd) {
+	case VIDIOC_MSM_VPE_INIT: {
 		struct msm_cam_media_controller *mctl =
 			(struct msm_cam_media_controller *)arg;
 		msm_vpe_subdev_init(sd, mctl);
-	} else if (subdev_cmd == VIDIOC_MSM_VPE_RELEASE) {
+		break;
+		}
+
+	case VIDIOC_MSM_VPE_RELEASE:
 		msm_vpe_subdev_release();
-	} else if (subdev_cmd == VIDIOC_MSM_VPE_CFG) {
-		vpe_params = (struct msm_mctl_pp_params *)arg;
-		cmd = vpe_params->cmd;
-		switch (cmd->id) {
-		case VPE_CMD_INIT:
-		case VPE_CMD_DEINIT:
-			break;
-		case VPE_CMD_RESET:
-			rc = vpe_reset();
-			break;
-		case VPE_CMD_OPERATION_MODE_CFG:
-			rc = vpe_operation_config(cmd->value);
-			break;
-		case VPE_CMD_INPUT_PLANE_CFG:
-			vpe_input_plane_config(cmd->value);
-			break;
-		case VPE_CMD_OUTPUT_PLANE_CFG:
-			vpe_output_plane_config(cmd->value);
-			break;
-		case VPE_CMD_SCALE_CFG_TYPE:
-			vpe_update_scale_coef(cmd->value);
-			break;
-		case VPE_CMD_ZOOM: {
-			rc = msm_vpe_do_pp(cmd,
-			(struct msm_mctl_pp_frame_info *)vpe_params->data);
+		break;
+
+	case MSM_CAM_V4L2_IOCTL_CFG_VPE: {
+		vpe_cmd = (struct msm_vpe_cfg_cmd *)arg;
+		rc = msm_vpe_process_vpe_cmd(vpe_cmd);
+		if (rc < 0) {
+			pr_err("%s Error processing VPE cmd %d ",
+				__func__, vpe_cmd->cmd_type);
 			break;
 		}
-		case VPE_CMD_ENABLE: {
-			struct msm_vpe_clock_rate *clk_rate = cmd->value;
-			int turbo_mode = (int)clk_rate->rate;
-			rc = turbo_mode ?
-				vpe_enable(VPE_TURBO_MODE_CLOCK_RATE) :
-				vpe_enable(VPE_NORMAL_MODE_CLOCK_RATE);
-			break;
+		break;
 		}
-		case VPE_CMD_DISABLE:
-			rc = vpe_disable();
-			break;
-		case VPE_CMD_INPUT_PLANE_UPDATE:
-		case VPE_CMD_FLUSH:
-		default:
-			break;
+
+	case MSM_CAM_V4L2_IOCTL_GET_EVENT_PAYLOAD: {
+		struct msm_device_queue *queue = &vpe_ctrl->eventData_q;
+		struct msm_queue_cmd *event_qcmd;
+		struct msm_mctl_pp_event_info pp_event_info;
+		struct msm_mctl_pp_frame_info *pp_frame_info;
+		struct msm_camera_v4l2_ioctl_t *v4l2_ioctl = arg;
+
+		event_qcmd = msm_dequeue(queue, list_eventdata);
+		if (!event_qcmd) {
+			pr_err("%s No events in the queue", __func__);
+			return -EFAULT;
 		}
-		CDBG("%s: end, id = %d, rc = %d", __func__, cmd->id, rc);
+		pp_frame_info = event_qcmd->command;
+		pp_event_info.event = MCTL_PP_EVENT_CMD_ACK;
+		pp_event_info.ack.cmd = pp_frame_info->user_cmd;
+		pp_event_info.ack.status = 0;
+		pp_event_info.ack.cookie = pp_frame_info->pp_frame_cmd.cookie;
+		D("%s Sending payload %d %d %d", __func__,
+			pp_event_info.ack.cmd, pp_event_info.ack.status,
+			pp_event_info.ack.cookie);
+		if (copy_to_user((void __user *)v4l2_ioctl->ioctl_ptr,
+			&pp_event_info,
+			sizeof(struct msm_mctl_pp_event_info)))
+			pr_err("%s EVENTPAYLOAD Copy to user failed ",
+				__func__);
+		kfree(pp_frame_info);
+		kfree(event_qcmd);
+		break;
+		}
+
+	default:
+		break;
 	}
 	return rc;
 }
 
+int msm_vpe_subdev_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub)
+{
+	D("%s E\n", __func__);
+	return v4l2_event_subscribe(fh, sub, VPE_SUBDEV_MAX_EVENTS);
+}
+
+int msm_vpe_subdev_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub)
+{
+	D("%s E\n", __func__);
+	return v4l2_event_unsubscribe(fh, sub);
+}
+
 static const struct v4l2_subdev_core_ops msm_vpe_subdev_core_ops = {
 	.ioctl = msm_vpe_subdev_ioctl,
+	.subscribe_event = msm_vpe_subdev_subscribe_event,
+	.unsubscribe_event = msm_vpe_subdev_unsubscribe_event,
 };
 
 static const struct v4l2_subdev_ops msm_vpe_subdev_ops = {
 	.core = &msm_vpe_subdev_core_ops,
 };
 
-static const struct v4l2_subdev_internal_ops msm_vpe_internal_ops;
+static int msm_vpe_subdev_open(struct v4l2_subdev *sd,
+	struct v4l2_subdev_fh *fh)
+{
+	struct vpe_ctrl_type *vpe_ctrl = v4l2_get_subdevdata(sd);
+	/* Only one client of VPE allowed. */
+	if (atomic_read(&vpe_ctrl->active) != 0) {
+		pr_err("%s already opened\n", __func__);
+		return -EINVAL;
+	}
 
-static int __devinit vpe_probe(struct platform_device *pdev)
+	D("%s E ", __func__);
+	atomic_inc(&vpe_ctrl->active);
+	return 0;
+}
+
+static int msm_vpe_subdev_close(struct v4l2_subdev *sd,
+	struct v4l2_subdev_fh *fh)
+{
+	struct vpe_ctrl_type *vpe_ctrl = v4l2_get_subdevdata(sd);
+	if (atomic_read(&vpe_ctrl->active) == 0) {
+		pr_err("%s already closed\n", __func__);
+		return -EINVAL;
+	}
+
+	D("%s E ", __func__);
+	/* Drain the payload queue. */
+	msm_queue_drain(&vpe_ctrl->eventData_q, list_eventdata);
+	atomic_dec(&vpe_ctrl->active);
+	return 0;
+}
+
+static const struct v4l2_subdev_internal_ops msm_vpe_internal_ops = {
+	.open = msm_vpe_subdev_open,
+	.close = msm_vpe_subdev_close,
+};
+
+static int __devinit msm_vpe_probe(struct platform_device *pdev)
 {
 	int rc = 0;
-	CDBG("%s: device id = %d\n", __func__, pdev->id);
+	D("%s: device id = %d\n", __func__, pdev->id);
 	vpe_ctrl = kzalloc(sizeof(struct vpe_ctrl_type), GFP_KERNEL);
 	if (!vpe_ctrl) {
-		pr_err("%s: no enough memory\n", __func__);
+		pr_err("%s: not enough memory\n", __func__);
 		return -ENOMEM;
 	}
 
@@ -734,6 +984,13 @@
 	snprintf(vpe_ctrl->subdev.name, sizeof(vpe_ctrl->subdev.name), "vpe");
 	platform_set_drvdata(pdev, &vpe_ctrl->subdev);
 
+	media_entity_init(&vpe_ctrl->subdev.entity, 0, NULL, 0);
+	vpe_ctrl->subdev.entity.type = MEDIA_ENT_T_DEVNODE_V4L;
+	vpe_ctrl->subdev.entity.group_id = VPE_DEV;
+	vpe_ctrl->subdev.entity.name = vpe_ctrl->subdev.name;
+
+	vpe_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
+
 	vpe_ctrl->vpemem = platform_get_resource_byname(pdev,
 					IORESOURCE_MEM, "vpe");
 	if (!vpe_ctrl->vpemem) {
@@ -769,17 +1026,22 @@
 
 	disable_irq(vpe_ctrl->vpeirq->start);
 
+	atomic_set(&vpe_ctrl->active, 0);
 	vpe_ctrl->pdev = pdev;
 	msm_cam_register_subdev_node(&vpe_ctrl->subdev, VPE_DEV, pdev->id);
+	vpe_ctrl->subdev.entity.revision = vpe_ctrl->subdev.devnode->num;
+	msm_queue_init(&vpe_ctrl->eventData_q, "ackevents");
+
 	return 0;
 
 vpe_no_resource:
+	pr_err("%s: VPE Probe failed.\n", __func__);
 	kfree(vpe_ctrl);
 	return 0;
 }
 
-struct platform_driver vpe_driver = {
-	.probe = vpe_probe,
+struct platform_driver msm_vpe_driver = {
+	.probe = msm_vpe_probe,
 	.driver = {
 		.name = MSM_VPE_DRV_NAME,
 		.owner = THIS_MODULE,
@@ -788,9 +1050,15 @@
 
 static int __init msm_vpe_init_module(void)
 {
-	return platform_driver_register(&vpe_driver);
+	return platform_driver_register(&msm_vpe_driver);
+}
+
+static void __exit msm_vpe_exit_module(void)
+{
+	platform_driver_unregister(&msm_vpe_driver);
 }
 
 module_init(msm_vpe_init_module);
+module_exit(msm_vpe_exit_module);
 MODULE_DESCRIPTION("VPE driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/msm_vpe.h b/drivers/media/video/msm/msm_vpe.h
index 0d14626..5cf0309 100644
--- a/drivers/media/video/msm/msm_vpe.h
+++ b/drivers/media/video/msm/msm_vpe.h
@@ -79,8 +79,8 @@
 #define VPE_DEFAULT_SCALE_CONFIG      0x3c
 
 #define VPE_NORMAL_MODE_CLOCK_RATE   150000000
-#define VPE_TURBO_MODE_CLOCK_RATE   200000000
-
+#define VPE_TURBO_MODE_CLOCK_RATE    200000000
+#define VPE_SUBDEV_MAX_EVENTS        30
 
 /**************************************************/
 /*********** End of command id ********************/
@@ -119,6 +119,8 @@
 	struct regulator *fs_vpe;
 	struct clk	*vpe_clk[2];
 	struct msm_mctl_pp_frame_info *pp_frame_info;
+	atomic_t active;
+	struct msm_device_queue eventData_q; /*V4L2 Event Payload Queue*/
 };
 
 /*
diff --git a/drivers/media/video/msm/server/msm_cam_server.c b/drivers/media/video/msm/server/msm_cam_server.c
index 8d004f6..cb59737 100644
--- a/drivers/media/video/msm/server/msm_cam_server.c
+++ b/drivers/media/video/msm/server/msm_cam_server.c
@@ -34,7 +34,7 @@
 static void msm_cam_server_subdev_notify(struct v4l2_subdev *sd,
 	unsigned int notification, void *arg);
 
-static void msm_queue_init(struct msm_device_queue *queue, const char *name)
+void msm_queue_init(struct msm_device_queue *queue, const char *name)
 {
 	D("%s\n", __func__);
 	spin_lock_init(&queue->lock);
@@ -45,7 +45,7 @@
 	init_waitqueue_head(&queue->wait);
 }
 
-static void msm_enqueue(struct msm_device_queue *queue,
+void msm_enqueue(struct msm_device_queue *queue,
 			struct list_head *entry)
 {
 	unsigned long flags;
@@ -62,7 +62,7 @@
 	spin_unlock_irqrestore(&queue->lock, flags);
 }
 
-static void msm_drain_eventq(struct msm_device_queue *queue)
+void msm_drain_eventq(struct msm_device_queue *queue)
 {
 	unsigned long flags;
 	struct msm_queue_cmd *qcmd;
@@ -560,55 +560,52 @@
 }
 
 int msm_server_proc_ctrl_cmd(struct msm_cam_v4l2_device *pcam,
-				 struct v4l2_control *ctrl, int is_set_cmd)
+		struct msm_camera_v4l2_ioctl_t *ioctl_ptr, int is_set_cmd)
 {
 	int rc = 0;
-	struct msm_ctrl_cmd ctrlcmd, *tmp_cmd;
+	struct msm_ctrl_cmd ctrlcmd, tmp_cmd, *cmd_ptr;
 	uint8_t *ctrl_data = NULL;
-	void __user *uptr_cmd;
-	void __user *uptr_value;
 	uint32_t cmd_len = sizeof(struct msm_ctrl_cmd);
 	uint32_t value_len;
 
-	tmp_cmd = (struct msm_ctrl_cmd *)ctrl->value;
-	uptr_cmd = (void __user *)ctrl->value;
-	uptr_value = (void __user *)tmp_cmd->value;
-	value_len = tmp_cmd->length;
-
-	D("%s: cmd type = %d, up1=0x%x, ulen1=%d, up2=0x%x, ulen2=%d\n",
-		__func__, tmp_cmd->type, (uint32_t)uptr_cmd, cmd_len,
-		(uint32_t)uptr_value, tmp_cmd->length);
-
-	ctrl_data = kzalloc(value_len+cmd_len, GFP_KERNEL);
-	if (ctrl_data == 0) {
-		pr_err("%s could not allocate memory\n", __func__);
-		rc = -ENOMEM;
-		goto end;
-	}
-	tmp_cmd = (struct msm_ctrl_cmd *)ctrl_data;
-	if (copy_from_user((void *)ctrl_data, uptr_cmd,
-					cmd_len)) {
+	if (copy_from_user(&tmp_cmd,
+		(void __user *)ioctl_ptr->ioctl_ptr, cmd_len)) {
 		pr_err("%s: copy_from_user failed.\n", __func__);
 		rc = -EINVAL;
 		goto end;
 	}
-	tmp_cmd->value = (void *)(ctrl_data+cmd_len);
-	if (uptr_value && tmp_cmd->length > 0) {
-		if (copy_from_user((void *)tmp_cmd->value, uptr_value,
-						value_len)) {
-			pr_err("%s: copy_from_user failed, size=%d\n",
-				__func__, value_len);
+	value_len = tmp_cmd.length;
+	ctrl_data = kzalloc(value_len+cmd_len, GFP_KERNEL);
+	if (!ctrl_data) {
+		pr_err("%s could not allocate memory\n", __func__);
+		rc = -ENOMEM;
+		goto end;
+	}
+
+	cmd_ptr = (struct msm_ctrl_cmd *) ctrl_data;
+	*cmd_ptr = tmp_cmd;
+	if (tmp_cmd.value && tmp_cmd.length > 0) {
+		cmd_ptr->value = (void *)(ctrl_data+cmd_len);
+		if (copy_from_user((void *)cmd_ptr->value,
+				   (void __user *)tmp_cmd.value,
+				   value_len)) {
+			pr_err("%s: copy_from_user failed.\n", __func__);
 			rc = -EINVAL;
 			goto end;
 		}
-	} else
-	tmp_cmd->value = NULL;
+	} else {
+		cmd_ptr->value = NULL;
+	}
+
+	D("%s: cmd type = %d, up1=0x%x, ulen1=%d, up2=0x%x, ulen2=%d\n",
+		__func__, tmp_cmd.type, (uint32_t)ioctl_ptr->ioctl_ptr, cmd_len,
+		(uint32_t)tmp_cmd.value, tmp_cmd.length);
 
 	ctrlcmd.type = MSM_V4L2_SET_CTRL_CMD;
 	ctrlcmd.length = cmd_len + value_len;
 	ctrlcmd.value = (void *)ctrl_data;
-	if (tmp_cmd->timeout_ms > 0)
-		ctrlcmd.timeout_ms = tmp_cmd->timeout_ms;
+	if (tmp_cmd.timeout_ms > 0)
+		ctrlcmd.timeout_ms = tmp_cmd.timeout_ms;
 	else
 		ctrlcmd.timeout_ms = 1000;
 	ctrlcmd.vnode_id = pcam->vnode_id;
@@ -618,17 +615,17 @@
 	rc = msm_server_control(&g_server_dev, &ctrlcmd);
 	D("%s: msm_server_control rc=%d\n", __func__, rc);
 	if (rc == 0) {
-		if (uptr_value && tmp_cmd->length > 0 &&
-			copy_to_user((void __user *)uptr_value,
-				(void *)(ctrl_data+cmd_len), tmp_cmd->length)) {
+		if (tmp_cmd.value && tmp_cmd.length > 0 &&
+			copy_to_user((void __user *)tmp_cmd.value,
+				(void *)(ctrl_data+cmd_len), tmp_cmd.length)) {
 			pr_err("%s: copy_to_user failed, size=%d\n",
-				__func__, tmp_cmd->length);
+				__func__, tmp_cmd.length);
 			rc = -EINVAL;
 			goto end;
 		}
-		tmp_cmd->value = uptr_value;
-		if (copy_to_user((void __user *)uptr_cmd,
-			(void *)tmp_cmd, cmd_len)) {
+
+		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
+			(void *)&tmp_cmd, cmd_len)) {
 			pr_err("%s: copy_to_user failed in cpy, size=%d\n",
 				__func__, cmd_len);
 			rc = -EINVAL;
@@ -637,8 +634,8 @@
 	}
 end:
 	D("%s: END, type = %d, vaddr = 0x%x, vlen = %d, status = %d, rc = %d\n",
-		__func__, tmp_cmd->type, (uint32_t)tmp_cmd->value,
-		tmp_cmd->length, tmp_cmd->status, rc);
+		__func__, tmp_cmd.type, (uint32_t)tmp_cmd.value,
+		tmp_cmd.length, tmp_cmd.status, rc);
 	kfree(ctrl_data);
 	return rc;
 }
@@ -655,8 +652,6 @@
 		pr_err("%s Invalid control\n", __func__);
 		return -EINVAL;
 	}
-	if (ctrl->id == MSM_V4L2_PID_CTRL_CMD)
-		return msm_server_proc_ctrl_cmd(pcam, ctrl, 1);
 
 	memset(ctrl_data, 0, sizeof(ctrl_data));
 
@@ -687,8 +682,6 @@
 		pr_err("%s Invalid control\n", __func__);
 		return -EINVAL;
 	}
-	if (ctrl->id == MSM_V4L2_PID_CTRL_CMD)
-		return msm_server_proc_ctrl_cmd(pcam, ctrl, 0);
 
 	memset(ctrl_data, 0, sizeof(ctrl_data));
 
@@ -1421,16 +1414,6 @@
 				g_server_dev.vfe_device[0], notification, arg);
 		}
 		break;
-	case NOTIFY_VPE_MSG_EVT: {
-		struct msm_cam_media_controller *pmctl =
-		(struct msm_cam_media_controller *)
-		v4l2_get_subdev_hostdata(sd);
-		struct msm_vpe_resp *vdata = (struct msm_vpe_resp *)arg;
-		msm_mctl_pp_notify(pmctl,
-		(struct msm_mctl_pp_frame_info *)
-		vdata->extdata);
-		break;
-	}
 	case NOTIFY_VFE_IRQ:{
 		struct msm_vfe_cfg_cmd cfg_cmd;
 		struct msm_camvfe_params vfe_params;
diff --git a/drivers/media/video/msm/server/msm_cam_server.h b/drivers/media/video/msm/server/msm_cam_server.h
index 2fe4c2b..677feaa 100644
--- a/drivers/media/video/msm/server/msm_cam_server.h
+++ b/drivers/media/video/msm/server/msm_cam_server.h
@@ -36,7 +36,7 @@
 int msm_server_get_usecount(void);
 int32_t msm_find_free_queue(void);
 int msm_server_proc_ctrl_cmd(struct msm_cam_v4l2_device *pcam,
-	struct v4l2_control *ctrl, int is_set_cmd);
+	struct msm_camera_v4l2_ioctl_t *ioctl_ptr, int is_set_cmd);
 int msm_server_s_ctrl(struct msm_cam_v4l2_device *pcam,
 	struct v4l2_control *ctrl);
 int msm_server_g_ctrl(struct msm_cam_v4l2_device *pcam,
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 5e0d669..2558c96 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -606,7 +606,6 @@
 	struct mmc_request mrq = {NULL};
 	struct mmc_command cmd = {0};
 	struct mmc_data data = {0};
-	unsigned int timeout_us;
 
 	struct scatterlist sg;
 
@@ -626,23 +625,12 @@
 	cmd.arg = 0;
 	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
 
-	data.timeout_ns = card->csd.tacc_ns * 100;
-	data.timeout_clks = card->csd.tacc_clks * 100;
-
-	timeout_us = data.timeout_ns / 1000;
-	timeout_us += data.timeout_clks * 1000 /
-		(card->host->ios.clock / 1000);
-
-	if (timeout_us > 100000) {
-		data.timeout_ns = 100000000;
-		data.timeout_clks = 0;
-	}
-
 	data.blksz = 4;
 	data.blocks = 1;
 	data.flags = MMC_DATA_READ;
 	data.sg = &sg;
 	data.sg_len = 1;
+	mmc_set_data_timeout(&data, card);
 
 	mrq.cmd = &cmd;
 	mrq.data = &data;
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index e7838f5..e84d87b 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -1173,6 +1173,9 @@
 	clks = (unsigned long long)data->timeout_ns * host->clk_rate;
 	do_div(clks, 1000000000UL);
 	timeout = data->timeout_clks + (unsigned int)clks*2 ;
+	WARN(!timeout,
+	     "%s: data timeout is zero. timeout_ns=0x%x, timeout_clks=0x%x\n",
+	     mmc_hostname(host->mmc), data->timeout_ns, data->timeout_clks);
 
 	if (host->is_dma_mode && (datactrl & MCI_DPSM_DMAENABLE)) {
 		/* Use ADM (Application Data Mover) HW for Data transfer */
@@ -2338,8 +2341,8 @@
 static inline void msmsdcc_setup_clocks(struct msmsdcc_host *host, bool enable)
 {
 	if (enable) {
-		if (!IS_ERR_OR_NULL(host->dfab_pclk))
-			clk_prepare_enable(host->dfab_pclk);
+		if (!IS_ERR_OR_NULL(host->bus_clk))
+			clk_prepare_enable(host->bus_clk);
 		if (!IS_ERR(host->pclk))
 			clk_prepare_enable(host->pclk);
 		clk_prepare_enable(host->clk);
@@ -2351,8 +2354,8 @@
 		clk_disable_unprepare(host->clk);
 		if (!IS_ERR(host->pclk))
 			clk_disable_unprepare(host->pclk);
-		if (!IS_ERR_OR_NULL(host->dfab_pclk))
-			clk_disable_unprepare(host->dfab_pclk);
+		if (!IS_ERR_OR_NULL(host->bus_clk))
+			clk_disable_unprepare(host->bus_clk);
 	}
 }
 
@@ -4825,21 +4828,17 @@
 	}
 
 	/*
-	 * Setup SDCC clock if derived from Dayatona
-	 * fabric core clock.
+	 * Setup SDCC bus voter clock.
 	 */
-	if (plat->pclk_src_dfab) {
-		host->dfab_pclk = clk_get(&pdev->dev, "bus_clk");
-		if (!IS_ERR(host->dfab_pclk)) {
-			/* Set the clock rate to 64MHz for max. performance */
-			ret = clk_set_rate(host->dfab_pclk, 64000000);
-			if (ret)
-				goto dfab_pclk_put;
-			ret = clk_prepare_enable(host->dfab_pclk);
-			if (ret)
-				goto dfab_pclk_put;
-		} else
-			goto dma_free;
+	host->bus_clk = clk_get(&pdev->dev, "bus_clk");
+	if (!IS_ERR_OR_NULL(host->bus_clk)) {
+		/* Vote for max. clk rate for max. performance */
+		ret = clk_set_rate(host->bus_clk, INT_MAX);
+		if (ret)
+			goto bus_clk_put;
+		ret = clk_prepare_enable(host->bus_clk);
+		if (ret)
+			goto bus_clk_put;
 	}
 
 	/*
@@ -5226,12 +5225,11 @@
  pclk_put:
 	if (!IS_ERR(host->pclk))
 		clk_put(host->pclk);
-	if (!IS_ERR_OR_NULL(host->dfab_pclk))
-		clk_disable_unprepare(host->dfab_pclk);
- dfab_pclk_put:
-	if (!IS_ERR_OR_NULL(host->dfab_pclk))
-		clk_put(host->dfab_pclk);
- dma_free:
+	if (!IS_ERR_OR_NULL(host->bus_clk))
+		clk_disable_unprepare(host->bus_clk);
+ bus_clk_put:
+	if (!IS_ERR_OR_NULL(host->bus_clk))
+		clk_put(host->bus_clk);
 	if (host->is_dma_mode) {
 		if (host->dmares)
 			dma_free_coherent(NULL,
@@ -5288,8 +5286,8 @@
 	clk_put(host->clk);
 	if (!IS_ERR(host->pclk))
 		clk_put(host->pclk);
-	if (!IS_ERR_OR_NULL(host->dfab_pclk))
-		clk_put(host->dfab_pclk);
+	if (!IS_ERR_OR_NULL(host->bus_clk))
+		clk_put(host->bus_clk);
 
 	if (host->cpu_dma_latency)
 		pm_qos_remove_request(&host->pm_qos_req_dma);
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index 1fe5129..2222337 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -350,7 +350,7 @@
 	struct mmc_host		*mmc;
 	struct clk		*clk;		/* main MMC bus clock */
 	struct clk		*pclk;		/* SDCC peripheral bus clock */
-	struct clk		*dfab_pclk;	/* Daytona Fabric SDCC clock */
+	struct clk		*bus_clk;	/* SDCC bus voter clock */
 	unsigned int		clks_on;	/* set if clocks are enabled */
 
 	unsigned int		eject;		/* eject state */
diff --git a/drivers/mtd/devices/msm_nand.c b/drivers/mtd/devices/msm_nand.c
index bd36aea..c43abca 100644
--- a/drivers/mtd/devices/msm_nand.c
+++ b/drivers/mtd/devices/msm_nand.c
@@ -1990,20 +1990,74 @@
 {
 	int ret;
 	struct mtd_oob_ops ops;
+	int (*read_oob)(struct mtd_info *, loff_t, struct mtd_oob_ops *);
 
-	/* printk("msm_nand_read %llx %x\n", from, len); */
+	if (!dual_nand_ctlr_present)
+		read_oob = msm_nand_read_oob;
+	else
+		read_oob = msm_nand_read_oob_dualnandc;
 
 	ops.mode = MTD_OPS_PLACE_OOB;
-	ops.len = len;
 	ops.retlen = 0;
 	ops.ooblen = 0;
-	ops.datbuf = buf;
 	ops.oobbuf = NULL;
-	if (!dual_nand_ctlr_present)
-		ret =  msm_nand_read_oob(mtd, from, &ops);
-	else
-		ret = msm_nand_read_oob_dualnandc(mtd, from, &ops);
-	*retlen = ops.retlen;
+	ret = 0;
+	*retlen = 0;
+
+	if ((from & (mtd->writesize - 1)) == 0 && len == mtd->writesize) {
+		/* reading a page on page boundary */
+		ops.len = len;
+		ops.datbuf = buf;
+		ret = read_oob(mtd, from, &ops);
+		*retlen = ops.retlen;
+	} else if (len > 0) {
+		/* reading any size on any offset. partial page is supported */
+		u8 *bounce_buf;
+		loff_t aligned_from;
+		loff_t offset;
+		size_t actual_len;
+
+		bounce_buf = kmalloc(mtd->writesize, GFP_KERNEL);
+		if (!bounce_buf) {
+			pr_err("%s: could not allocate memory\n", __func__);
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		ops.len = mtd->writesize;
+		offset = from & (mtd->writesize - 1);
+		aligned_from = from - offset;
+
+		for (;;) {
+			int no_copy;
+
+			actual_len = mtd->writesize - offset;
+			if (actual_len > len)
+				actual_len = len;
+
+			no_copy = (offset == 0 && actual_len == mtd->writesize);
+			ops.datbuf = (no_copy) ? buf : bounce_buf;
+			ret = read_oob(mtd, aligned_from, &ops);
+			if (ret < 0)
+				break;
+
+			if (!no_copy)
+				memcpy(buf, bounce_buf + offset, actual_len);
+
+			len -= actual_len;
+			*retlen += actual_len;
+			if (len == 0)
+				break;
+
+			buf += actual_len;
+			offset = 0;
+			aligned_from += mtd->writesize;
+		}
+
+		kfree(bounce_buf);
+	}
+
+out:
 	return ret;
 }
 
@@ -2963,18 +3017,54 @@
 {
 	int ret;
 	struct mtd_oob_ops ops;
+	int (*write_oob)(struct mtd_info *, loff_t, struct mtd_oob_ops *);
+
+	if (!dual_nand_ctlr_present)
+		write_oob = msm_nand_write_oob;
+	else
+		write_oob = msm_nand_write_oob_dualnandc;
 
 	ops.mode = MTD_OPS_PLACE_OOB;
-	ops.len = len;
 	ops.retlen = 0;
 	ops.ooblen = 0;
-	ops.datbuf = (uint8_t *)buf;
 	ops.oobbuf = NULL;
-	if (!dual_nand_ctlr_present)
-		ret =  msm_nand_write_oob(mtd, to, &ops);
-	else
-		ret =  msm_nand_write_oob_dualnandc(mtd, to, &ops);
-	*retlen = ops.retlen;
+	ret = 0;
+	*retlen = 0;
+
+	if (!virt_addr_valid(buf) &&
+	    ((to | len) & (mtd->writesize - 1)) == 0 &&
+	    ((unsigned long) buf & ~PAGE_MASK) + len > PAGE_SIZE) {
+		/*
+		 * Handle writing of large size write buffer in vmalloc
+		 * address space that does not fit in an MMU page.
+		 * The destination address must be on page boundary,
+		 * and the size must be multiple of NAND page size.
+		 * Writing partial page is not supported.
+		 */
+		ops.len = mtd->writesize;
+
+		for (;;) {
+			ops.datbuf = (uint8_t *) buf;
+
+			ret = write_oob(mtd, to, &ops);
+			if (ret < 0)
+				break;
+
+			len -= mtd->writesize;
+			*retlen += mtd->writesize;
+			if (len == 0)
+				break;
+
+			buf += mtd->writesize;
+			to += mtd->writesize;
+		}
+	} else {
+		ops.len = len;
+		ops.datbuf = (uint8_t *) buf;
+		ret = write_oob(mtd, to, &ops);
+		*retlen = ops.retlen;
+	}
+
 	return ret;
 }
 
@@ -6747,6 +6837,7 @@
 		mtd->writesize = supported_flash.pagesize * i;
 		mtd->oobsize   = supported_flash.oobsize  * i;
 		mtd->erasesize = supported_flash.blksize  * i;
+		mtd->writebufsize = mtd->writesize;
 
 		if (!interleave_enable)
 			mtd_writesize = mtd->writesize;
diff --git a/drivers/regulator/msm-gpio-regulator.c b/drivers/regulator/msm-gpio-regulator.c
index 5c99f4c..15e5b53 100644
--- a/drivers/regulator/msm-gpio-regulator.c
+++ b/drivers/regulator/msm-gpio-regulator.c
@@ -42,11 +42,13 @@
 	/* Request GPIO now if it hasn't been requested before. */
 	if (!vreg->gpio_requested) {
 		rc = gpio_request(vreg->gpio, vreg->gpio_label);
-		if (rc < 0)
+		if (rc < 0) {
 			pr_err("failed to request gpio %u (%s), rc=%d\n",
 				vreg->gpio, vreg->gpio_label, rc);
-		else
+			return rc;
+		} else {
 			vreg->gpio_requested = true;
+		}
 
 		rc = gpio_sysfs_set_active_low(vreg->gpio, vreg->active_low);
 		if (rc < 0)
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 4e6091e..81ce143 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -26,6 +26,9 @@
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/msm_hsusb.h>
+#include <linux/regulator/consumer.h>
+
+#include <mach/rpm-regulator.h>
 
 #include "core.h"
 #include "gadget.h"
@@ -95,6 +98,49 @@
 	u8 ep_num_mapping[DBM_MAX_EPS];
 	const struct usb_ep_ops *original_ep_ops[DWC3_ENDPOINTS_NUM];
 	struct list_head req_complete_list;
+	struct regulator	*hsusb_3p3;
+	struct regulator	*hsusb_1p8;
+	struct regulator	*hsusb_vddcx;
+	struct regulator	*ssusb_1p8;
+	struct regulator	*ssusb_vddcx;
+	enum usb_vdd_type	ss_vdd_type;
+	enum usb_vdd_type	hs_vdd_type;
+};
+
+#define USB_HSPHY_3P3_VOL_MIN		3050000 /* uV */
+#define USB_HSPHY_3P3_VOL_MAX		3300000 /* uV */
+#define USB_HSPHY_3P3_HPM_LOAD		16000	/* uA */
+
+#define USB_HSPHY_1P8_VOL_MIN		1800000 /* uV */
+#define USB_HSPHY_1P8_VOL_MAX		1800000 /* uV */
+#define USB_HSPHY_1P8_HPM_LOAD		19000	/* uA */
+
+#define USB_SSPHY_1P8_VOL_MIN		1800000 /* uV */
+#define USB_SSPHY_1P8_VOL_MAX		1800000 /* uV */
+#define USB_SSPHY_1P8_HPM_LOAD		23000	/* uA */
+
+#define USB_PHY_VDD_DIG_VOL_NONE	0	/* uV */
+#define USB_PHY_VDD_DIG_VOL_MIN		1045000 /* uV */
+#define USB_PHY_VDD_DIG_VOL_MAX		1320000 /* uV */
+
+enum usb_vdd_value {
+	VDD_NONE = 0,
+	VDD_MIN,
+	VDD_MAX,
+	VDD_VAL_MAX,
+};
+
+static const int vdd_val[VDD_TYPE_MAX][VDD_VAL_MAX] = {
+		{  /* VDD_CX CORNER Voting */
+			[VDD_NONE]	= RPM_VREG_CORNER_NONE,
+			[VDD_MIN]	= RPM_VREG_CORNER_NOMINAL,
+			[VDD_MAX]	= RPM_VREG_CORNER_HIGH,
+		},
+		{ /* VDD_CX Voltage Voting */
+			[VDD_NONE]	= USB_PHY_VDD_DIG_VOL_NONE,
+			[VDD_MIN]	= USB_PHY_VDD_DIG_VOL_MIN,
+			[VDD_MAX]	= USB_PHY_VDD_DIG_VOL_MAX,
+		},
 };
 
 static struct dwc3_msm *context;
@@ -750,6 +796,213 @@
 }
 EXPORT_SYMBOL(msm_ep_unconfig);
 
+/* HSPHY */
+static int dwc3_hsusb_config_vddcx(int high)
+{
+	int min_vol, ret;
+	struct dwc3_msm *dwc = context;
+	enum usb_vdd_type vdd_type = context->hs_vdd_type;
+	int max_vol = vdd_val[vdd_type][VDD_MAX];
+
+	min_vol = vdd_val[vdd_type][high ? VDD_MIN : VDD_NONE];
+	ret = regulator_set_voltage(dwc->hsusb_vddcx, min_vol, max_vol);
+	if (ret) {
+		dev_err(dwc->dev, "unable to set voltage for HSUSB_VDDCX\n");
+		return ret;
+	}
+
+	dev_dbg(dwc->dev, "%s: min_vol:%d max_vol:%d\n", __func__,
+							min_vol, max_vol);
+
+	return ret;
+}
+
+static int dwc3_hsusb_ldo_init(int init)
+{
+	int rc = 0;
+	struct dwc3_msm *dwc = context;
+
+	if (!init) {
+		regulator_set_voltage(dwc->hsusb_1p8, 0, USB_HSPHY_1P8_VOL_MAX);
+		regulator_set_voltage(dwc->hsusb_3p3, 0, USB_HSPHY_3P3_VOL_MAX);
+		return 0;
+	}
+
+	dwc->hsusb_3p3 = devm_regulator_get(dwc->dev, "HSUSB_3p3");
+	if (IS_ERR(dwc->hsusb_3p3)) {
+		dev_err(dwc->dev, "unable to get hsusb 3p3\n");
+		return PTR_ERR(dwc->hsusb_3p3);
+	}
+
+	rc = regulator_set_voltage(dwc->hsusb_3p3,
+			USB_HSPHY_3P3_VOL_MIN, USB_HSPHY_3P3_VOL_MAX);
+	if (rc) {
+		dev_err(dwc->dev, "unable to set voltage for hsusb 3p3\n");
+		return rc;
+	}
+	dwc->hsusb_1p8 = devm_regulator_get(dwc->dev, "HSUSB_1p8");
+	if (IS_ERR(dwc->hsusb_1p8)) {
+		dev_err(dwc->dev, "unable to get hsusb 1p8\n");
+		rc = PTR_ERR(dwc->hsusb_1p8);
+		goto devote_3p3;
+	}
+	rc = regulator_set_voltage(dwc->hsusb_1p8,
+			USB_HSPHY_1P8_VOL_MIN, USB_HSPHY_1P8_VOL_MAX);
+	if (rc) {
+		dev_err(dwc->dev, "unable to set voltage for hsusb 1p8\n");
+		goto devote_3p3;
+	}
+
+	return 0;
+
+devote_3p3:
+	regulator_set_voltage(dwc->hsusb_3p3, 0, USB_HSPHY_3P3_VOL_MAX);
+
+	return rc;
+}
+
+static int dwc3_hsusb_ldo_enable(int on)
+{
+	int rc = 0;
+	struct dwc3_msm *dwc = context;
+
+	dev_dbg(dwc->dev, "reg (%s)\n", on ? "HPM" : "LPM");
+
+	if (!on)
+		goto disable_regulators;
+
+
+	rc = regulator_set_optimum_mode(dwc->hsusb_1p8, USB_HSPHY_1P8_HPM_LOAD);
+	if (rc < 0) {
+		dev_err(dwc->dev, "Unable to set HPM of regulator HSUSB_1p8\n");
+		return rc;
+	}
+
+	rc = regulator_enable(dwc->hsusb_1p8);
+	if (rc) {
+		dev_err(dwc->dev, "Unable to enable HSUSB_1p8\n");
+		goto put_1p8_lpm;
+	}
+
+	rc = regulator_set_optimum_mode(dwc->hsusb_3p3,	USB_HSPHY_3P3_HPM_LOAD);
+	if (rc < 0) {
+		dev_err(dwc->dev, "Unable to set HPM of regulator HSUSB_3p3\n");
+		goto disable_1p8;
+	}
+
+	rc = regulator_enable(dwc->hsusb_3p3);
+	if (rc) {
+		dev_err(dwc->dev, "Unable to enable HSUSB_3p3\n");
+		goto put_3p3_lpm;
+	}
+
+	return 0;
+
+disable_regulators:
+	rc = regulator_disable(dwc->hsusb_3p3);
+	if (rc)
+		dev_err(dwc->dev, "Unable to disable HSUSB_3p3\n");
+
+put_3p3_lpm:
+	rc = regulator_set_optimum_mode(dwc->hsusb_3p3, 0);
+	if (rc < 0)
+		dev_err(dwc->dev, "Unable to set LPM of regulator HSUSB_3p3\n");
+
+disable_1p8:
+	rc = regulator_disable(dwc->hsusb_1p8);
+	if (rc)
+		dev_err(dwc->dev, "Unable to disable HSUSB_1p8\n");
+
+put_1p8_lpm:
+	rc = regulator_set_optimum_mode(dwc->hsusb_1p8, 0);
+	if (rc < 0)
+		dev_err(dwc->dev, "Unable to set LPM of regulator HSUSB_1p8\n");
+
+	return rc < 0 ? rc : 0;
+}
+
+/* SSPHY */
+static int dwc3_ssusb_config_vddcx(int high)
+{
+	int min_vol, ret;
+	struct dwc3_msm *dwc = context;
+	enum usb_vdd_type vdd_type = context->ss_vdd_type;
+	int max_vol = vdd_val[vdd_type][VDD_MAX];
+
+	min_vol = vdd_val[vdd_type][high ? VDD_MIN : VDD_NONE];
+	ret = regulator_set_voltage(dwc->ssusb_vddcx, min_vol, max_vol);
+	if (ret) {
+		dev_err(dwc->dev, "unable to set voltage for SSUSB_VDDCX\n");
+		return ret;
+	}
+
+	dev_dbg(dwc->dev, "%s: min_vol:%d max_vol:%d\n", __func__,
+							min_vol, max_vol);
+	return ret;
+}
+
+/* 3.3v supply not needed for SS PHY */
+static int dwc3_ssusb_ldo_init(int init)
+{
+	int rc = 0;
+	struct dwc3_msm *dwc = context;
+
+	if (!init) {
+		regulator_set_voltage(dwc->ssusb_1p8, 0, USB_SSPHY_1P8_VOL_MAX);
+		return 0;
+	}
+
+	dwc->ssusb_1p8 = devm_regulator_get(dwc->dev, "SSUSB_1p8");
+	if (IS_ERR(dwc->ssusb_1p8)) {
+		dev_err(dwc->dev, "unable to get ssusb 1p8\n");
+		return PTR_ERR(dwc->ssusb_1p8);
+	}
+	rc = regulator_set_voltage(dwc->ssusb_1p8,
+			USB_SSPHY_1P8_VOL_MIN, USB_SSPHY_1P8_VOL_MAX);
+	if (rc)
+		dev_err(dwc->dev, "unable to set voltage for ssusb 1p8\n");
+
+	return rc;
+}
+
+static int dwc3_ssusb_ldo_enable(int on)
+{
+	int rc = 0;
+	struct dwc3_msm *dwc = context;
+
+	dev_dbg(context->dev, "reg (%s)\n", on ? "HPM" : "LPM");
+
+	if (!on)
+		goto disable_regulators;
+
+
+	rc = regulator_set_optimum_mode(dwc->ssusb_1p8, USB_SSPHY_1P8_HPM_LOAD);
+	if (rc < 0) {
+		dev_err(dwc->dev, "Unable to set HPM of SSUSB_1p8\n");
+		return rc;
+	}
+
+	rc = regulator_enable(dwc->ssusb_1p8);
+	if (rc) {
+		dev_err(dwc->dev, "Unable to enable SSUSB_1p8\n");
+		goto put_1p8_lpm;
+	}
+
+	return 0;
+
+disable_regulators:
+	rc = regulator_disable(dwc->ssusb_1p8);
+	if (rc)
+		dev_err(dwc->dev, "Unable to disable SSUSB_1p8\n");
+
+put_1p8_lpm:
+	rc = regulator_set_optimum_mode(dwc->ssusb_1p8, 0);
+	if (rc < 0)
+		dev_err(dwc->dev, "Unable to set LPM of SSUSB_1p8\n");
+
+	return rc < 0 ? rc : 0;
+}
+
 static int __devinit dwc3_msm_probe(struct platform_device *pdev)
 {
 	struct device_node *node = pdev->dev.of_node;
@@ -766,26 +1019,107 @@
 
 	platform_set_drvdata(pdev, msm);
 	context = msm;
+	msm->dev = &pdev->dev;
 
 	INIT_LIST_HEAD(&msm->req_complete_list);
 
+	/* SS PHY */
+	msm->ss_vdd_type = VDDCX_CORNER;
+	msm->ssusb_vddcx = devm_regulator_get(&pdev->dev, "ssusb_vdd_dig");
+	if (IS_ERR(msm->ssusb_vddcx)) {
+		msm->ssusb_vddcx = devm_regulator_get(&pdev->dev,
+							"SSUSB_VDDCX");
+		if (IS_ERR(msm->ssusb_vddcx)) {
+			dev_err(&pdev->dev, "unable to get ssusb vddcx\n");
+			return PTR_ERR(msm->ssusb_vddcx);
+		}
+		msm->ss_vdd_type = VDDCX;
+		dev_dbg(&pdev->dev, "ss_vdd_type: VDDCX\n");
+	}
+
+	ret = dwc3_ssusb_config_vddcx(1);
+	if (ret) {
+		dev_err(&pdev->dev, "ssusb vddcx configuration failed\n");
+		return ret;
+	}
+
+	ret = regulator_enable(context->ssusb_vddcx);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to enable the ssusb vddcx\n");
+		goto unconfig_ss_vddcx;
+	}
+
+	ret = dwc3_ssusb_ldo_init(1);
+	if (ret) {
+		dev_err(&pdev->dev, "ssusb vreg configuration failed\n");
+		goto disable_ss_vddcx;
+	}
+
+	ret = dwc3_ssusb_ldo_enable(1);
+	if (ret) {
+		dev_err(&pdev->dev, "ssusb vreg enable failed\n");
+		goto free_ss_ldo_init;
+	}
+
+	/* HS PHY */
+	msm->hs_vdd_type = VDDCX_CORNER;
+	msm->hsusb_vddcx = devm_regulator_get(&pdev->dev, "hsusb_vdd_dig");
+	if (IS_ERR(msm->hsusb_vddcx)) {
+		msm->hsusb_vddcx = devm_regulator_get(&pdev->dev,
+							"HSUSB_VDDCX");
+		if (IS_ERR(msm->hsusb_vddcx)) {
+			dev_err(&pdev->dev, "unable to get hsusb vddcx\n");
+			ret = PTR_ERR(msm->ssusb_vddcx);
+			goto disable_ss_ldo;
+		}
+		msm->hs_vdd_type = VDDCX;
+		dev_dbg(&pdev->dev, "hs_vdd_type: VDDCX\n");
+	}
+
+	ret = dwc3_hsusb_config_vddcx(1);
+	if (ret) {
+		dev_err(&pdev->dev, "hsusb vddcx configuration failed\n");
+		goto disable_ss_ldo;
+	}
+
+	ret = regulator_enable(context->hsusb_vddcx);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to enable the hsusb vddcx\n");
+		goto unconfig_hs_vddcx;
+	}
+
+	ret = dwc3_hsusb_ldo_init(1);
+	if (ret) {
+		dev_err(&pdev->dev, "hsusb vreg configuration failed\n");
+		goto disable_hs_vddcx;
+	}
+
+	ret = dwc3_hsusb_ldo_enable(1);
+	if (ret) {
+		dev_err(&pdev->dev, "hsusb vreg enable failed\n");
+		goto free_hs_ldo_init;
+	}
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		dev_err(&pdev->dev, "missing memory base resource\n");
-		return -ENODEV;
+		ret = -ENODEV;
+		goto disable_hs_ldo;
 	}
 
 	msm->base = devm_ioremap_nocache(&pdev->dev, res->start,
 		resource_size(res));
 	if (!msm->base) {
 		dev_err(&pdev->dev, "ioremap failed\n");
-		return -ENODEV;
+		ret = -ENODEV;
+		goto disable_hs_ldo;
 	}
 
 	dwc3 = platform_device_alloc("dwc3-msm", -1);
 	if (!dwc3) {
 		dev_err(&pdev->dev, "couldn't allocate dwc3 device\n");
-		return -ENOMEM;
+		ret = -ENODEV;
+		goto disable_hs_ldo;
 	}
 
 	dma_set_coherent_mask(&dwc3->dev, pdev->dev.coherent_dma_mask);
@@ -794,7 +1128,6 @@
 	dwc3->dev.dma_mask = pdev->dev.dma_mask;
 	dwc3->dev.dma_parms = pdev->dev.dma_parms;
 	msm->resource_size = resource_size(res);
-	msm->dev = &pdev->dev;
 	msm->dwc3 = dwc3;
 
 	if (of_property_read_u32(node, "qcom,dwc-usb3-msm-dbm-eps",
@@ -810,20 +1143,20 @@
 			"max: %d, dbm_num_eps: %d\n",
 			DBM_MAX_EPS, msm->dbm_num_eps);
 		ret = -ENODEV;
-		goto err1;
+		goto put_pdev;
 	}
 
 	ret = platform_device_add_resources(dwc3, pdev->resource,
 		pdev->num_resources);
 	if (ret) {
 		dev_err(&pdev->dev, "couldn't add resources to dwc3 device\n");
-		goto err1;
+		goto put_pdev;
 	}
 
 	ret = platform_device_add(dwc3);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to register dwc3 device\n");
-		goto err1;
+		goto put_pdev;
 	}
 
 	/* Reset the DBM */
@@ -831,8 +1164,24 @@
 
 	return 0;
 
-err1:
+put_pdev:
 	platform_device_put(dwc3);
+disable_hs_ldo:
+	dwc3_hsusb_ldo_enable(0);
+free_hs_ldo_init:
+	dwc3_hsusb_ldo_init(0);
+disable_hs_vddcx:
+	regulator_disable(context->hsusb_vddcx);
+unconfig_hs_vddcx:
+	dwc3_hsusb_config_vddcx(0);
+disable_ss_ldo:
+	dwc3_ssusb_ldo_enable(0);
+free_ss_ldo_init:
+	dwc3_ssusb_ldo_init(0);
+disable_ss_vddcx:
+	regulator_disable(context->ssusb_vddcx);
+unconfig_ss_vddcx:
+	dwc3_ssusb_config_vddcx(0);
 
 	return ret;
 }
@@ -843,6 +1192,15 @@
 
 	platform_device_unregister(msm->dwc3);
 
+	dwc3_hsusb_ldo_enable(0);
+	dwc3_hsusb_ldo_init(0);
+	regulator_disable(msm->hsusb_vddcx);
+	dwc3_hsusb_config_vddcx(0);
+	dwc3_ssusb_ldo_enable(0);
+	dwc3_ssusb_ldo_init(0);
+	regulator_disable(msm->ssusb_vddcx);
+	dwc3_ssusb_config_vddcx(0);
+
 	return 0;
 }
 
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
index b8d1df8..7777154 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -297,6 +297,11 @@
 	select FB_MSM_LVDS
 	default n
 
+config FB_MSM_LVDS_FRC_FHD
+	bool
+	select FB_MSM_LVDS
+	default n
+
 config FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT
 	bool
 	select FB_MSM_MIPI_DSI_TOSHIBA
@@ -490,6 +495,15 @@
         ---help---
           Support for LVDS Chimei WXGA(1366x768) panel
 
+config FB_MSM_LVDS_FRC_FHD_PANEL
+	bool "LVDS FRC FHD Panel"
+	select FB_MSM_LVDS_FRC_FHD
+	---help---
+	  Support for LVDS Frc FHD(1920x1080) panel
+	  FRC(Frame Rate Converter) uses LVDS as input
+	  interface. It is treated as a HDMI panel with
+	  1920x1080 resolution.
+
 config FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
 	depends on FB_MSM_LCDC_HW
 	bool "MDDI Panel Auto Detect + LCDC Prism WVGA"
@@ -568,6 +582,7 @@
 config FB_MSM_LVDS_MIPI_PANEL_DETECT
 	bool "LVDS + MIPI Panel Auto Detect"
 	select FB_MSM_LVDS_CHIMEI_WXGA
+	select FB_MSM_LVDS_FRC_FHD
 	select FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT
 	select FB_MSM_MIPI_TOSHIBA_VIDEO_WSVGA_PT
 	select FB_MSM_MIPI_TOSHIBA_VIDEO_WUXGA
diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile
index b2ecb08..e4a0948 100644
--- a/drivers/video/msm/Makefile
+++ b/drivers/video/msm/Makefile
@@ -165,6 +165,7 @@
 obj-$(CONFIG_FB_MSM_HDMI_ADV7520_PANEL) += adv7520.o
 obj-$(CONFIG_FB_MSM_LCDC_ST15_WXGA) += lcdc_st15.o
 obj-$(CONFIG_FB_MSM_LVDS_CHIMEI_WXGA) += lvds_chimei_wxga.o
+obj-$(CONFIG_FB_MSM_LVDS_FRC_FHD) += lvds_frc_fhd.o
 obj-$(CONFIG_FB_MSM_HDMI_MSM_PANEL) += hdmi_msm.o
 obj-$(CONFIG_FB_MSM_EXT_INTERFACE_COMMON) += external_common.o
 obj-$(CONFIG_FB_MSM_LCDC_TRULY_HVGA_IPS3P2335) += lcdc_truly_ips3p2335.o
diff --git a/drivers/video/msm/lvds.c b/drivers/video/msm/lvds.c
index 6323423..f5d8201 100644
--- a/drivers/video/msm/lvds.c
+++ b/drivers/video/msm/lvds.c
@@ -33,6 +33,9 @@
 
 #include "msm_fb.h"
 #include "mdp4.h"
+
+#define LVDS_PIXEL_MAP_PATTERN_2	2
+
 static int lvds_probe(struct platform_device *pdev);
 static int lvds_remove(struct platform_device *pdev);
 
@@ -65,14 +68,39 @@
 	usleep(1000);
 
 	/* LVDS PHY PLL configuration */
-	MDP_OUTP(MDP_BASE + 0xc3004, 0x62);
-	MDP_OUTP(MDP_BASE + 0xc3008, 0x30);
-	MDP_OUTP(MDP_BASE + 0xc300c, 0xc4);
-	MDP_OUTP(MDP_BASE + 0xc3014, 0x10);
-	MDP_OUTP(MDP_BASE + 0xc3018, 0x05);
-	MDP_OUTP(MDP_BASE + 0xc301c, 0x62);
-	MDP_OUTP(MDP_BASE + 0xc3020, 0x41);
-	MDP_OUTP(MDP_BASE + 0xc3024, 0x0d);
+	if (mfd->panel_info.clk_rate == 74250000) {
+		MDP_OUTP(MDP_BASE + 0xc3000, 0x08);
+		MDP_OUTP(MDP_BASE + 0xc3004, 0x4c);
+		MDP_OUTP(MDP_BASE + 0xc3008, 0x30);
+		MDP_OUTP(MDP_BASE + 0xc300c, 0xc3);
+		MDP_OUTP(MDP_BASE + 0xc3014, 0x10);
+		MDP_OUTP(MDP_BASE + 0xc3018, 0x04);
+		MDP_OUTP(MDP_BASE + 0xc301c, 0x62);
+		MDP_OUTP(MDP_BASE + 0xc3020, 0x41);
+		MDP_OUTP(MDP_BASE + 0xc3024, 0x0d);
+		MDP_OUTP(MDP_BASE + 0xc3028, 0x07);
+		MDP_OUTP(MDP_BASE + 0xc302c, 0x00);
+		MDP_OUTP(MDP_BASE + 0xc3030, 0x1c);
+		MDP_OUTP(MDP_BASE + 0xc3034, 0x01);
+		MDP_OUTP(MDP_BASE + 0xc3038, 0x00);
+		MDP_OUTP(MDP_BASE + 0xc3040, 0xC0);
+		MDP_OUTP(MDP_BASE + 0xc3044, 0x00);
+		MDP_OUTP(MDP_BASE + 0xc3048, 0x30);
+		MDP_OUTP(MDP_BASE + 0xc304c, 0x00);
+
+		MDP_OUTP(MDP_BASE + 0xc3000, 0x11);
+		MDP_OUTP(MDP_BASE + 0xc3064, 0x05);
+		MDP_OUTP(MDP_BASE + 0xc3050, 0x20);
+	} else {
+		MDP_OUTP(MDP_BASE + 0xc3004, 0x62);
+		MDP_OUTP(MDP_BASE + 0xc3008, 0x30);
+		MDP_OUTP(MDP_BASE + 0xc300c, 0xc4);
+		MDP_OUTP(MDP_BASE + 0xc3014, 0x10);
+		MDP_OUTP(MDP_BASE + 0xc3018, 0x05);
+		MDP_OUTP(MDP_BASE + 0xc301c, 0x62);
+		MDP_OUTP(MDP_BASE + 0xc3020, 0x41);
+		MDP_OUTP(MDP_BASE + 0xc3024, 0x0d);
+	}
 
 	MDP_OUTP(MDP_BASE + 0xc3000, 0x01);
 	/* Wait until LVDS PLL is locked and ready */
@@ -99,22 +127,42 @@
 		if (lvds_pdata &&
 		    lvds_pdata->lvds_pixel_remap &&
 		    lvds_pdata->lvds_pixel_remap()) {
-			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_3_TO_0 */
-			MDP_OUTP(MDP_BASE +  0xc2014, 0x05080001);
-			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_6_TO_4 */
-			MDP_OUTP(MDP_BASE +  0xc2018, 0x00020304);
-			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_3_TO_0 */
-			MDP_OUTP(MDP_BASE +  0xc201c, 0x1011090a);
-			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_6_TO_4 */
-			MDP_OUTP(MDP_BASE +  0xc2020, 0x000b0c0d);
-			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_3_TO_0 */
-			MDP_OUTP(MDP_BASE +  0xc2024, 0x191a1213);
-			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_6_TO_4 */
-			MDP_OUTP(MDP_BASE +  0xc2028, 0x00141518);
-			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_3_TO_0 */
-			MDP_OUTP(MDP_BASE +  0xc202c, 0x171b0607);
-			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_6_TO_4 */
-			MDP_OUTP(MDP_BASE +  0xc2030, 0x000e0f16);
+			if (lvds_pdata->lvds_pixel_remap() ==
+				LVDS_PIXEL_MAP_PATTERN_2) {
+				/* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_3_TO_0 */
+				MDP_OUTP(MDP_BASE +  0xc2014, 0x070A1B1B);
+				/* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_6_TO_4 */
+				MDP_OUTP(MDP_BASE +  0xc2018, 0x00040506);
+				/* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_3_TO_0 */
+				MDP_OUTP(MDP_BASE +  0xc201c, 0x12131B1B);
+				/* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_6_TO_4 */
+				MDP_OUTP(MDP_BASE +  0xc2020, 0x000B0C0D);
+				/* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_3_TO_0 */
+				MDP_OUTP(MDP_BASE +  0xc2024, 0x191A1B1B);
+				/* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_6_TO_4 */
+				MDP_OUTP(MDP_BASE +  0xc2028, 0x00141518);
+				/* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_3_TO_0 */
+				MDP_OUTP(MDP_BASE +  0xc202c, 0x171B1B1B);
+				/* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_6_TO_4 */
+				MDP_OUTP(MDP_BASE +  0xc2030, 0x000e0f16);
+			} else {
+				/* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_3_TO_0 */
+				MDP_OUTP(MDP_BASE +  0xc2014, 0x05080001);
+				/* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_6_TO_4 */
+				MDP_OUTP(MDP_BASE +  0xc2018, 0x00020304);
+				/* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_3_TO_0 */
+				MDP_OUTP(MDP_BASE +  0xc201c, 0x1011090a);
+				/* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_6_TO_4 */
+				MDP_OUTP(MDP_BASE +  0xc2020, 0x000b0c0d);
+				/* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_3_TO_0 */
+				MDP_OUTP(MDP_BASE +  0xc2024, 0x191a1213);
+				/* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_6_TO_4 */
+				MDP_OUTP(MDP_BASE +  0xc2028, 0x00141518);
+				/* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_3_TO_0 */
+				MDP_OUTP(MDP_BASE +  0xc202c, 0x171b0607);
+				/* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_6_TO_4 */
+				MDP_OUTP(MDP_BASE +  0xc2030, 0x000e0f16);
+			}
 		} else {
 			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_3_TO_0 */
 			MDP_OUTP(MDP_BASE +  0xc2014, 0x03040508);
@@ -135,7 +183,7 @@
 		}
 		if (mfd->panel_info.lvds.channel_mode ==
 			LVDS_DUAL_CHANNEL_MODE) {
-			lvds_intf = 0x0001ff80;
+			lvds_intf = 0x0003ff80;
 			lvds_phy_cfg0 = BIT(6) | BIT(7);
 			if (mfd->panel_info.lvds.channel_swap)
 				lvds_intf |= BIT(4);
@@ -159,7 +207,7 @@
 
 		if (mfd->panel_info.lvds.channel_mode ==
 			LVDS_DUAL_CHANNEL_MODE) {
-			lvds_intf = 0x00017788;
+			lvds_intf = 0x00037788;
 			lvds_phy_cfg0 = BIT(6) | BIT(7);
 			if (mfd->panel_info.lvds.channel_swap)
 				lvds_intf |= BIT(4);
diff --git a/drivers/video/msm/lvds_frc_fhd.c b/drivers/video/msm/lvds_frc_fhd.c
new file mode 100644
index 0000000..7739588
--- /dev/null
+++ b/drivers/video/msm/lvds_frc_fhd.c
@@ -0,0 +1,201 @@
+/* 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 <mach/gpio.h>
+#include "msm_fb.h"
+
+static struct lvds_panel_platform_data *frc_pdata;
+static struct platform_device *frc_fbpdev;
+static int gpio_update;		/* 268 */
+static int gpio_reset;	/* 269 */
+static int gpio_pwr;		/* 270 */
+
+static int lvds_frc_panel_on(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = gpio_request(gpio_pwr, "frc_pwr");
+	if (ret) {
+		pr_err("%s: gpio_pwr=%d, gpio_request failed\n",
+			__func__, gpio_pwr);
+		goto panel_on_exit;
+	}
+	ret = gpio_request(gpio_update, "frc_update");
+	if (ret) {
+		pr_err("%s: gpio_update=%d, gpio_request failed\n",
+			__func__, gpio_update);
+		goto panel_on_exit1;
+	}
+	ret = gpio_request(gpio_reset, "frc_reset");
+	if (ret) {
+		pr_err("%s: gpio_reset=%d, gpio_request failed\n",
+			__func__, gpio_reset);
+		goto panel_on_exit2;
+	}
+
+	gpio_direction_output(gpio_reset, 1);
+	gpio_direction_output(gpio_pwr, 0);
+	gpio_direction_output(gpio_update, 0);
+	usleep(1000);
+	gpio_direction_output(gpio_reset, 0);
+	usleep(1000);
+	gpio_direction_output(gpio_pwr, 1);
+	usleep(1000);
+	gpio_direction_output(gpio_update, 1);
+	usleep(1000);
+	gpio_direction_output(gpio_reset, 1);
+	usleep(1000);
+	gpio_free(gpio_reset);
+panel_on_exit2:
+	gpio_free(gpio_update);
+panel_on_exit1:
+	gpio_free(gpio_pwr);
+panel_on_exit:
+	return ret;
+}
+
+static int lvds_frc_panel_off(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = gpio_request(gpio_pwr, "frc_pwr");
+	if (ret) {
+		pr_err("%s: gpio_pwr=%d, gpio_request failed\n",
+			__func__, gpio_pwr);
+		goto panel_off_exit;
+	}
+	ret = gpio_request(gpio_update, "frc_update");
+	if (ret) {
+		pr_err("%s: gpio_update=%d, gpio_request failed\n",
+			__func__, gpio_update);
+		goto panel_off_exit1;
+	}
+	ret = gpio_request(gpio_reset, "frc_reset");
+	if (ret) {
+		pr_err("%s: gpio_reset=%d, gpio_request failed\n",
+			__func__, gpio_reset);
+		goto panel_off_exit2;
+	}
+	gpio_direction_output(gpio_reset, 0);
+	usleep(1000);
+	gpio_direction_output(gpio_update, 0);
+	usleep(1000);
+	gpio_direction_output(gpio_pwr, 0);
+	usleep(1000);
+	gpio_free(gpio_reset);
+panel_off_exit2:
+	gpio_free(gpio_update);
+panel_off_exit1:
+	gpio_free(gpio_pwr);
+panel_off_exit:
+	return ret;
+}
+
+static int __devinit lvds_frc_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	if (pdev->id == 0) {
+		frc_pdata = pdev->dev.platform_data;
+		if (frc_pdata != NULL) {
+			gpio_update = frc_pdata->gpio[0];
+			gpio_reset = frc_pdata->gpio[1];
+			gpio_pwr = frc_pdata->gpio[2];
+			pr_info("%s: power=%d update=%d reset=%d\n",
+				__func__, gpio_pwr, gpio_update, gpio_reset);
+		}
+		return 0;
+	}
+
+	frc_fbpdev = msm_fb_add_device(pdev);
+	if (!frc_fbpdev) {
+		dev_err(&pdev->dev, "failed to add msm_fb device\n");
+		rc = -ENODEV;
+		goto probe_exit;
+	}
+
+probe_exit:
+	return rc;
+}
+
+static struct platform_driver this_driver = {
+	.probe  = lvds_frc_probe,
+	.driver = {
+		.name   = "lvds_frc_fhd",
+	},
+};
+
+static struct msm_fb_panel_data lvds_frc_panel_data = {
+	.on = lvds_frc_panel_on,
+	.off = lvds_frc_panel_off,
+};
+
+static struct platform_device this_device = {
+	.name   = "lvds_frc_fhd",
+	.id	= 1,
+	.dev	= {
+		.platform_data = &lvds_frc_panel_data,
+	}
+};
+
+static int __init lvds_frc_fhd_init(void)
+{
+	int ret;
+	struct msm_panel_info *pinfo;
+
+	if (msm_fb_detect_client("lvds_frc_fhd"))
+		return 0;
+
+	ret = platform_driver_register(&this_driver);
+	if (ret)
+		return ret;
+
+	pinfo = &lvds_frc_panel_data.panel_info;
+	pinfo->xres = 1920;
+	pinfo->yres = 1080;
+	MSM_FB_SINGLE_MODE_PANEL(pinfo);
+	pinfo->type = LVDS_PANEL;
+	pinfo->pdest = DISPLAY_1;
+	pinfo->wait_cycle = 0;
+	pinfo->bpp = 24;
+	pinfo->fb_num = 2;
+	pinfo->clk_rate = 74250000;
+	pinfo->bl_max = 255;
+	pinfo->bl_min = 1;
+
+	/*
+	 * use hdmi 1080p60 setting, for dual channel mode,
+	 * horizontal length is half.
+	 */
+	pinfo->lcdc.h_back_porch = 148/2;
+	pinfo->lcdc.h_front_porch = 88/2;
+	pinfo->lcdc.h_pulse_width = 44/2;
+	pinfo->lcdc.v_back_porch = 36;
+	pinfo->lcdc.v_front_porch = 4;
+	pinfo->lcdc.v_pulse_width = 5;
+	pinfo->lcdc.underflow_clr = 0xff;
+	pinfo->lcdc.hsync_skew = 0;
+	pinfo->lvds.channel_mode = LVDS_DUAL_CHANNEL_MODE;
+	pinfo->lcdc.is_sync_active_high = TRUE;
+
+	/* Set border color, padding only for reducing active display region */
+	pinfo->lcdc.border_clr = 0x0;
+	pinfo->lcdc.xres_pad = 0;
+	pinfo->lcdc.yres_pad = 0;
+
+	ret = platform_device_register(&this_device);
+	if (ret)
+		platform_driver_unregister(&this_driver);
+
+	return ret;
+}
+
+module_init(lvds_frc_fhd_init);
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index 18d2107..8410592 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -181,7 +181,12 @@
 	lcdc_bpp = mfd->panel_info.bpp;
 
 	hsync_period =
-	    hsync_pulse_width + h_back_porch + lcdc_width + h_front_porch;
+	    hsync_pulse_width + h_back_porch + h_front_porch;
+	if ((mfd->panel_info.type == LVDS_PANEL) &&
+		(mfd->panel_info.lvds.channel_mode == LVDS_DUAL_CHANNEL_MODE))
+		hsync_period += lcdc_width / 2;
+	else
+		hsync_period += lcdc_width;
 	hsync_ctrl = (hsync_period << 16) | hsync_pulse_width;
 	hsync_start_x = hsync_pulse_width + h_back_porch;
 	hsync_end_x = hsync_period - h_front_porch - 1;
@@ -216,8 +221,13 @@
 
 
 #ifdef CONFIG_FB_MSM_MDP40
-	hsync_polarity = 1;
-	vsync_polarity = 1;
+	if (mfd->panel_info.lcdc.is_sync_active_high) {
+		hsync_polarity = 0;
+		vsync_polarity = 0;
+	} else {
+		hsync_polarity = 1;
+		vsync_polarity = 1;
+	}
 	lcdc_underflow_clr |= 0x80000000;	/* enable recovery */
 #else
 	hsync_polarity = 0;
diff --git a/drivers/video/msm/msm_fb_panel.h b/drivers/video/msm/msm_fb_panel.h
index 8ccc21c..a2c3db1 100644
--- a/drivers/video/msm/msm_fb_panel.h
+++ b/drivers/video/msm/msm_fb_panel.h
@@ -82,6 +82,7 @@
 	uint32 xres_pad;
 	/* Pad height */
 	uint32 yres_pad;
+	boolean is_sync_active_high;
 };
 
 struct mddi_panel_info {
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index ec9f187..4358a92 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -977,7 +977,7 @@
 	struct ubifs_budget_req ino_req = { .dirtied_ino = 1,
 			.dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) };
 	struct timespec time;
-	unsigned int saved_nlink;
+	unsigned int saved_nlink = 0;
 
 	/*
 	 * Budget request settings: deletion direntry, new direntry, removing
diff --git a/include/linux/msm_ipc.h b/include/linux/msm_ipc.h
index 82f76a6..44fa8eb 100644
--- a/include/linux/msm_ipc.h
+++ b/include/linux/msm_ipc.h
@@ -62,12 +62,19 @@
 #define IPC_ROUTER_IOCTL_BIND_CONTROL_PORT \
 	_IOR(IPC_ROUTER_IOCTL_MAGIC, 4, unsigned int)
 
+struct msm_ipc_server_info {
+	uint32_t node_id;
+	uint32_t port_id;
+	uint32_t service;
+	uint32_t instance;
+};
+
 struct server_lookup_args {
 	struct msm_ipc_port_name port_name;
 	int num_entries_in_array;
 	int num_entries_found;
 	uint32_t lookup_mask;
-	struct msm_ipc_port_addr port_addr[0];
+	struct msm_ipc_server_info srv_info[0];
 };
 
 #endif
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 6d72470..271079e 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -1450,25 +1450,33 @@
 #define QCAMERA_VNODE_GROUP_ID 2
 
 #define MSM_CAM_V4L2_IOCTL_GET_CAMERA_INFO \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct msm_camera_v4l2_ioctl_t *)
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct msm_camera_v4l2_ioctl_t)
 
 #define MSM_CAM_V4L2_IOCTL_GET_CONFIG_INFO \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 2, struct msm_camera_v4l2_ioctl_t *)
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 2, struct msm_camera_v4l2_ioctl_t)
 
 #define MSM_CAM_V4L2_IOCTL_GET_MCTL_INFO \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 3, struct msm_camera_v4l2_ioctl_t *)
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 3, struct msm_camera_v4l2_ioctl_t)
 
 #define MSM_CAM_V4L2_IOCTL_CTRL_CMD_DONE \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 4, struct msm_camera_v4l2_ioctl_t *)
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 4, struct msm_camera_v4l2_ioctl_t)
 
 #define MSM_CAM_V4L2_IOCTL_GET_EVENT_PAYLOAD \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 5, struct msm_camera_v4l2_ioctl_t *)
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 5, struct msm_camera_v4l2_ioctl_t)
 
 #define MSM_CAM_IOCTL_SEND_EVENT \
 	_IOWR('V', BASE_VIDIOC_PRIVATE + 6, struct v4l2_event)
 
+#define MSM_CAM_V4L2_IOCTL_CFG_VPE \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 7, struct msm_vpe_cfg_cmd)
+
+#define MSM_CAM_V4L2_IOCTL_PRIVATE_S_CTRL \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 8, struct msm_camera_v4l2_ioctl_t)
+
 struct msm_camera_v4l2_ioctl_t {
+	uint32_t id;
 	void __user *ioctl_ptr;
+	uint32_t len;
 };
 
 #endif /* __LINUX_MSM_CAMERA_H */
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 77a6dd9..deb67f5 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1634,7 +1634,8 @@
 			 $exec_file =~ /^Kconfig$/) &&
 			$rawline =~ /^new (file )?mode\s([0-9]+)$/ &&
 			(oct($2) & 0111))  {
-			    ERROR("Source file has +x permissions: " .
+			    ERROR("EXECUTE_PERMISSIONS",
+				  "Source file has +x permissions: " .
 			    "$exec_file\n");
 		}
 		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
@@ -1647,7 +1648,8 @@
 			if ($shorttext == IN_SHORTTEXT_BLANKLINE && $line=~/\S/) {
 				# the subject line was just processed,
 				# a blank line must be next
-				WARN("non-blank line after summary line\n" . $herecurr);
+				WARN("NONBLANK_AFTER_SUMMARY",
+				     "non-blank line after summary line\n" . $herecurr);
 				$shorttext = IN_SHORTTEXT;
 				# this non-blank line may or may not be commit text -
 				# a warning has been generated so assume it is commit
@@ -1658,7 +1660,8 @@
 			if ($shorttext == IN_SHORTTEXT) {
 				if ($line=~/^---/ || $line=~/^diff.*/) {
 					if ($commit_text_present == 0) {
-						WARN("please add commit text explaining " .
+						WARN("NO_COMMIT_TEXT",
+						     "please add commit text explaining " .
 						     "*why* the change is needed\n" .
 						     $herecurr);
 					}
@@ -1668,7 +1671,8 @@
 					 && $line !~ /^:([0-7]{6}\s){2}
 						      ([[:xdigit:]]+\.*
 						       \s){2}\w+\s\w+/xms) {
-					WARN("commit text line over " .
+					WARN("LONG_COMMIT_TEXT",
+					     "commit text line over " .
 					     SHORTTEXT_LIMIT .
 					     " characters\n" . $herecurr);
 				} elsif ($line=~/^\s*change-id:/i ||
@@ -1678,7 +1682,8 @@
 					# this is a tag, there must be commit
 					# text by now
 					if ($commit_text_present == 0) {
-						WARN("please add commit text explaining " .
+						WARN("NO_COMMIT_TEXT",
+						     "please add commit text explaining " .
 						     "*why* the change is needed\n" .
 						     $herecurr);
 						# prevent duplicate warnings
@@ -1699,7 +1704,8 @@
 					$shorttext = IN_SHORTTEXT;
 					# Check for Subject line followed by a blank line.
 					if (length($line) != 0) {
-						WARN("non-blank line after " .
+						WARN("NONBLANK_AFTER_SUMMARY",
+						     "non-blank line after " .
 						     "summary line\n" .
 						     $sublinenr . $here .
 						     "\n" . $subjectline .
@@ -1721,7 +1727,8 @@
 				$sublinenr = "#$linenr & ";
 # Check for Subject line less than line limit
 				if (length($1) > SHORTTEXT_LIMIT) {
-					WARN("summary line over " .
+					WARN("LONG_SUMMARY_LINE",
+					     "summary line over " .
 					     SHORTTEXT_LIMIT .
 					     " characters\n" . $herecurr);
 				}
@@ -1732,7 +1739,8 @@
 				$shorttext = IN_SHORTTEXT_BLANKLINE;
 				$shorttext_exspc = 4;
 				if (length($1) > SHORTTEXT_LIMIT) {
-					WARN("summary line over " .
+					WARN("LONG_SUMMARY_LINE",
+					     "summary line over " .
 					     SHORTTEXT_LIMIT .
 					     " characters\n" . $herecurr);
 				}
@@ -1797,13 +1805,14 @@
 				}
 			}
 			if ($line =~ /^\s*signed-off-by:.*(quicinc|qualcomm)\.com/i) {
-				WARN("invalid Signed-off-by identity\n" . $line );
+				WARN("BAD_SIGN_OFF",
+				     "invalid Signed-off-by identity\n" . $line );
 			}
 		}
 
 #check the patch for invalid author credentials
 		if ($line =~ /^From:.*(quicinc|qualcomm)\.com/) {
-			WARN("invalid author identity\n" . $line );
+			WARN("BAD_AUTHOR", "invalid author identity\n" . $line );
 		}
 
 # Check for wrappage within a valid hunk of the file
@@ -3291,19 +3300,20 @@
 
 # sys_open/read/write/close are not allowed in the kernel
 		if ($line =~ /\b(sys_(?:open|read|write|close))\b/) {
-			ERROR("$1 is inappropriate in kernel code.\n" .
+			ERROR("FILE_OPS", "$1 is inappropriate in kernel code.\n" .
 			      $herecurr);
 		}
 
 # filp_open is a backdoor for sys_open
 		if ($line =~ /\b(filp_open)\b/) {
-			ERROR("$1 is inappropriate in kernel code.\n" .
+			ERROR("FILE_OPS", "$1 is inappropriate in kernel code.\n" .
 			      $herecurr);
 		}
 
 # read[bwl] & write[bwl] use too many barriers, use the _relaxed variants
 		if ($line =~ /\b((?:read|write)[bwl])\b/) {
-			ERROR("Use of $1 is deprecated: use $1_relaxed\n\t" .
+			ERROR("NON_RELAXED_IO",
+			      "Use of $1 is deprecated: use $1_relaxed\n\t" .
 			      "with appropriate memory barriers instead.\n" .
 			      $herecurr);
 		}
@@ -3313,7 +3323,8 @@
 			my ($all, $pref, $suf) = ($1, $2, $3);
 			$pref =~ s/in/read/;
 			$pref =~ s/out/write/;
-			ERROR("Use of $all is deprecated: use " .
+			ERROR("NON_RELAXED_IO",
+			      "Use of $all is deprecated: use " .
 			      "__raw_$pref$suf\n\t" .
 			      "with appropriate memory barriers instead.\n" .
 			      $herecurr);
@@ -3321,7 +3332,8 @@
 
 # dsb is too ARMish, and should usually be mb.
 		if ($line =~ /\bdsb\b/) {
-			WARN("Use of dsb is discouranged: prefer mb.\n" .
+			WARN("ARM_BARRIER",
+			     "Use of dsb is discouranged: prefer mb.\n" .
 			     $herecurr);
 		}
 
@@ -3329,12 +3341,13 @@
 	if ($realfile =~ /\/mach-msm\/board-[0-9]+/ &&
 	    $realfile !~ /camera/ && $realfile !~ /gpiomux/ &&
 	    $line =~ /\s*struct msm_gpiomux_config\s*/ ) {
-		WARN("Non gpiomux board file cannot have a gpiomux config declarations. Please declare gpiomux configs in board-*-gpiomux.c file.\n" . $herecurr);
+		WARN("GPIOMUX_IN_BOARD",
+		     "Non gpiomux board file cannot have a gpiomux config declarations. Please declare gpiomux configs in board-*-gpiomux.c file.\n" . $herecurr);
 	}
 
 # MSM - check if vreg_xxx function are used
 	if ($line =~ /\b(vreg_(get|put|set_level|enable|disable))\b/) {
-		WARN("Use of $1 API is deprecated: " .
+		WARN("DEPRECATED_VREG_APIS", "Use of $1 API is deprecated: " .
 			"use regulator APIs\n" . $herecurr);
 	}
 
@@ -3354,7 +3367,8 @@
 		);
 		foreach my $k (keys %str_fns) {
 			if ($line =~ /\b$k\b/) {
-				ERROR("Use of $k is deprecated: " .
+				ERROR("UNBOUNDED_STRING_FNS",
+				      "Use of $k is deprecated: " .
 				      "use $str_fns{$k} instead.\n" .
 				      $herecurr);
 			}
@@ -3362,13 +3376,15 @@
 
 # warn about #if 0
 		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
-			WARN("if this code is redundant consider removing it\n"
+			WARN("IF_0",
+			     "if this code is redundant consider removing it\n"
 				.  $herecurr);
 		}
 
 # warn about #if 1
 		if ($line =~ /^.\s*\#\s*if\s+1\b/) {
-			WARN("if this code is required consider removing"
+			WARN("IF_1",
+			     "if this code is required consider removing"
 				. " #if 1\n" .  $herecurr);
 		}
 
@@ -3408,7 +3424,8 @@
 
 # check the patch for use of mdelay
 		if ($line =~ /\bmdelay\s*\(/) {
-			WARN("use of mdelay() found: msleep() is the preferred API.\n" . $line );
+			WARN("MDELAY",
+			     "use of mdelay() found: msleep() is the preferred API.\n" . $line );
 		}
 
 # warn about #ifdefs in C files
@@ -3598,7 +3615,8 @@
 
 # check for return codes on error paths
 		if ($line =~ /\breturn\s+-\d+/) {
-			ERROR("illegal return value, please use an error code\n" . $herecurr);
+			ERROR("NO_ERROR_CODE",
+			      "illegal return value, please use an error code\n" . $herecurr);
 		}
 
 # check for gcc specific __FUNCTION__