Merge changes I7fdde988,I982dd4c4 into msm-3.4

* changes:
  mmc: msm_sdcc: add warning if data timeout is zero
  mmc: block: fix data timeout issue with ACMD22
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/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/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index 447427a..7efd66a 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
@@ -237,13 +238,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 +340,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..abe46bc 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
@@ -238,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
@@ -347,6 +348,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..62369ac 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -1,7 +1,6 @@
 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 +27,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 +51,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 +66,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/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-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-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/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/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.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..1f20c8a 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;
@@ -1421,16 +1421,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/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/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..7b5e841 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -1467,6 +1467,9 @@
 #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)
+
 struct msm_camera_v4l2_ioctl_t {
 	void __user *ioctl_ptr;
 };
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__