Merge "msm: Remove VFE global variable" 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_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__