Merge "Bluetooth: Clear sk_send_head when purging ERTM transmit queue" into msm-3.0
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index 4d4c27f..8492aa3 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -133,6 +133,7 @@
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
 CONFIG_PARTITION_ADVANCED=y
+CONFIG_EFI_PARTITION=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ASCII=y
 CONFIG_NLS_ISO8859_1=y
diff --git a/arch/arm/configs/msm7627-perf_defconfig b/arch/arm/configs/msm7627-perf_defconfig
index 0f2ffc1..82160ce 100644
--- a/arch/arm/configs/msm7627-perf_defconfig
+++ b/arch/arm/configs/msm7627-perf_defconfig
@@ -151,6 +151,8 @@
 # CONFIG_WIRELESS_EXT_SYSFS is not set
 CONFIG_RFKILL=y
 # CONFIG_RFKILL_PM is not set
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
 CONFIG_MTD=y
 CONFIG_MTD_TESTS=m
 CONFIG_MTD_CMDLINE_PARTS=y
diff --git a/arch/arm/configs/msm7627_defconfig b/arch/arm/configs/msm7627_defconfig
index d1d0e66..c5f1b30 100644
--- a/arch/arm/configs/msm7627_defconfig
+++ b/arch/arm/configs/msm7627_defconfig
@@ -151,6 +151,8 @@
 # CONFIG_WIRELESS_EXT_SYSFS is not set
 CONFIG_RFKILL=y
 # CONFIG_RFKILL_PM is not set
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
 CONFIG_MTD=y
 CONFIG_MTD_TESTS=m
 CONFIG_MTD_CMDLINE_PARTS=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 2abe7e9..f68aa30 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -83,6 +83,7 @@
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_VMALLOC_RESERVE=0x19000000
+CONFIG_CC_STACKPROTECTOR=y
 CONFIG_CP_ACCESS=y
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h
index c86fad9..75ec143 100644
--- a/arch/arm/include/asm/mach/mmc.h
+++ b/arch/arm/include/asm/mach/mmc.h
@@ -130,6 +130,8 @@
 	void (*sdio_lpm_gpio_setup)(struct device *, unsigned int);
         unsigned int status_irq;
 	unsigned int status_gpio;
+	/* Indicates the polarity of the GPIO line when card is inserted */
+	bool is_status_gpio_active_low;
         unsigned int sdiowakeup_irq;
         unsigned long irq_flags;
         unsigned long mmc_bus_width;
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index a0cf8ca..c049b5f 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -75,6 +75,7 @@
 	select ARCH_REQUIRE_GPIOLIB
 	select MSM_ADM3
 	select REGULATOR
+	select MSM_RPM_REGULATOR
 	select MSM_V2_TLMM
 	select MSM_PIL
 	select MSM_SCM
@@ -128,6 +129,7 @@
 	select MSM_SCM if SMP
 	select MSM_DIRECT_SCLK_ACCESS
 	select REGULATOR
+	select MSM_RPM_REGULATOR
 	select MSM_RPM
 	select MSM_XO
 	select MSM_QDSP6_APR
@@ -153,6 +155,7 @@
 	select FIX_MOVABLE_ZONE
 	select CLEANCACHE
 	select QCACHE
+	select MSM_MULTIMEDIA_USE_ION
 
 config ARCH_MSM8930
 	bool "MSM8930"
@@ -229,6 +232,9 @@
 	select MSM_RPM
 	select MSM_SPM_V2
 	select MSM_NATIVE_RESTART
+	select REGULATOR
+	select MSM_RPM_REGULATOR
+
 endmenu
 
 choice
@@ -1571,6 +1577,14 @@
 	  for idle power collapse, wait the number of microseconds in case
 	  Modem becomes ready soon.
 
+config MSM_RPM_REGULATOR
+	bool "RPM regulator driver"
+	depends on RPM && REGULATOR
+	help
+	  Compile in support for the RPM regulator driver, used for setting
+	  voltages and other parameters of the various power rails supplied
+	  by some Qualcomm PMICs.
+
 config MSM_PIL
 	bool "Peripheral image loading"
 	select FW_LOADER
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index ee15313..f826659 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -174,9 +174,15 @@
 obj-$(CONFIG_ARCH_MSM8X60) += devices-msm8x60.o clock-local.o clock-8x60.o acpuclock-8x60.o
 obj-$(CONFIG_ARCH_MSM8X60) += clock-rpm.o
 obj-$(CONFIG_ARCH_MSM8X60) += saw-regulator.o
-obj-$(CONFIG_ARCH_MSM8X60) += rpm-regulator.o rpm-regulator-8660.o
 obj-$(CONFIG_ARCH_MSM8X60) += footswitch-8x60.o
 
+ifdef CONFIG_MSM_RPM_REGULATOR
+obj-y += rpm-regulator.o
+obj-$(CONFIG_ARCH_MSM8X60) += rpm-regulator-8660.o
+obj-$(CONFIG_ARCH_MSM8960) += rpm-regulator-8960.o
+obj-$(CONFIG_ARCH_MSM9615) += rpm-regulator-9615.o
+endif
+
 ifdef CONFIG_MSM_SUBSYSTEM_RESTART
 	obj-y += subsystem_notif.o
 	obj-y += subsystem_restart.o
@@ -227,7 +233,7 @@
 obj-$(CONFIG_ARCH_MSM8960) += footswitch-8x60.o
 obj-$(CONFIG_ARCH_MSM8960) += acpuclock-8960.o
 obj-$(CONFIG_ARCH_MSM8960) += memory_topology.o
-obj-$(CONFIG_ARCH_MSM8960) += saw-regulator.o rpm-regulator.o rpm-regulator-8960.o
+obj-$(CONFIG_ARCH_MSM8960) += saw-regulator.o
 obj-$(CONFIG_ARCH_MSM8960) += devices-8960.o
 obj-$(CONFIG_ARCH_APQ8064) += devices-8960.o devices-8064.o
 board-8960-all-objs += board-8960.o board-8960-camera.o board-8960-display.o board-8960-pmic.o board-8960-storage.o board-8960-gpiomux.o
@@ -246,7 +252,6 @@
 obj-$(CONFIG_MACH_APQ8064_RUMI3) += board-8064-all.o board-8064-regulator.o
 obj-$(CONFIG_ARCH_MSM9615) += board-9615.o devices-9615.o board-9615-regulator.o
 obj-$(CONFIG_ARCH_MSM9615) += clock-local.o clock-9615.o acpuclock-9615.o clock-rpm.o
-obj-$(CONFIG_ARCH_MSM9615) += rpm-regulator.o rpm-regulator-9615.o
 obj-$(CONFIG_ARCH_MSMCOPPER) += board-copper.o board-dt.o
 
 obj-$(CONFIG_MACH_SAPPHIRE) += board-sapphire.o board-sapphire-gpio.o
diff --git a/arch/arm/mach-msm/acpuclock-7201.c b/arch/arm/mach-msm/acpuclock-7201.c
index 0338d53..9fbe364 100644
--- a/arch/arm/mach-msm/acpuclock-7201.c
+++ b/arch/arm/mach-msm/acpuclock-7201.c
@@ -33,7 +33,6 @@
 #include <asm/mach-types.h>
 #include <mach/socinfo.h>
 
-#include "proc_comm.h"
 #include "smd_private.h"
 #include "acpuclock.h"
 
@@ -76,7 +75,6 @@
 	struct clkctl_acpu_speed	*current_speed;
 	struct mutex			lock;
 	uint32_t			max_speed_delta_khz;
-	unsigned long			max_axi_khz;
 	struct clk			*ebi1_clk;
 };
 
@@ -127,62 +125,6 @@
  * largest frequency jump that's less than max_speed_delta_khz on each PLL.
  */
 
-/* 7x01/7x25 normal with GSM capable modem */
-static struct clkctl_acpu_speed pll0_245_pll1_768_pll2_1056_pll4_0[] = {
-	{ 0, 19200, ACPU_PLL_TCXO, 0, 0, 19200, 0, 0, 30720 },
-	{ 1, 122880, ACPU_PLL_0, 4, 1,  61440, 1, 3,  61440 },
-	{ 0, 128000, ACPU_PLL_1, 1, 5,  64000, 1, 3,  61440 },
-	{ 0, 176000, ACPU_PLL_2, 2, 5,  88000, 1, 3,  61440 },
-	{ 1, 245760, ACPU_PLL_0, 4, 0,  81920, 2, 4,  61440 },
-	{ 1, 256000, ACPU_PLL_1, 1, 2, 128000, 1, 5, 128000 },
-	{ 0, 352000, ACPU_PLL_2, 2, 2,  88000, 3, 5, 128000 },
-	{ 1, 384000, ACPU_PLL_1, 1, 1, 128000, 2, 6, 128000 },
-	{ 1, 528000, ACPU_PLL_2, 2, 1, 132000, 3, 7, 128000 },
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
-};
-
-/* 7x01/7x25 normal with CDMA-only modem */
-static struct clkctl_acpu_speed pll0_196_pll1_768_pll2_1056_pll4_0[] = {
-	{ 0, 19200, ACPU_PLL_TCXO, 0, 0, 19200, 0, 0, 24576 },
-	{ 1,  98304, ACPU_PLL_0, 4, 1,  49152, 1, 3,  24576 },
-	{ 0, 128000, ACPU_PLL_1, 1, 5,  64000, 1, 3,  24576 },
-	{ 0, 176000, ACPU_PLL_2, 2, 5,  88000, 1, 3,  24576 },
-	{ 1, 196608, ACPU_PLL_0, 4, 0,  65536, 2, 4,  24576 },
-	{ 1, 256000, ACPU_PLL_1, 1, 2, 128000, 1, 5, 128000 },
-	{ 0, 352000, ACPU_PLL_2, 2, 2,  88000, 3, 5, 128000 },
-	{ 1, 384000, ACPU_PLL_1, 1, 1, 128000, 2, 6, 128000 },
-	{ 1, 528000, ACPU_PLL_2, 2, 1, 132000, 3, 7, 128000 },
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
-};
-
-/* 7x01/7x25 turbo with GSM capable modem */
-static struct clkctl_acpu_speed pll0_245_pll1_960_pll2_1056_pll4_0[] = {
-	{ 0, 19200, ACPU_PLL_TCXO, 0, 0, 19200, 0, 0, 30720 },
-	{ 0, 120000, ACPU_PLL_1, 1, 7,  60000, 1, 3,  61440 },
-	{ 1, 122880, ACPU_PLL_0, 4, 1,  61440, 1, 3,  61440 },
-	{ 0, 176000, ACPU_PLL_2, 2, 5,  88000, 1, 3,  61440 },
-	{ 1, 245760, ACPU_PLL_0, 4, 0,  81920, 2, 4,  61440 },
-	{ 1, 320000, ACPU_PLL_1, 1, 2, 107000, 2, 5, 120000 },
-	{ 0, 352000, ACPU_PLL_2, 2, 2,  88000, 3, 5, 120000 },
-	{ 1, 480000, ACPU_PLL_1, 1, 1, 120000, 3, 6, 120000 },
-	{ 1, 528000, ACPU_PLL_2, 2, 1, 132000, 3, 7, 122880 },
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
-};
-
-/* 7x01/7x25 turbo with CDMA-only modem */
-static struct clkctl_acpu_speed pll0_196_pll1_960_pll2_1056_pll4_0[] = {
-	{ 0, 19200, ACPU_PLL_TCXO, 0, 0, 19200, 0, 0, 24576 },
-	{ 1,  98304, ACPU_PLL_0, 4, 1,  49152, 1, 3,  24576 },
-	{ 0, 120000, ACPU_PLL_1, 1, 7,  60000, 1, 3,  24576 },
-	{ 0, 176000, ACPU_PLL_2, 2, 5,  88000, 1, 3,  24576 },
-	{ 1, 196608, ACPU_PLL_0, 4, 0,  65536, 2, 4,  24576 },
-	{ 1, 320000, ACPU_PLL_1, 1, 2, 107000, 2, 5, 120000 },
-	{ 0, 352000, ACPU_PLL_2, 2, 2,  88000, 3, 5, 120000 },
-	{ 1, 480000, ACPU_PLL_1, 1, 1, 120000, 3, 6, 120000 },
-	{ 1, 528000, ACPU_PLL_2, 2, 1, 132000, 3, 7, 120000 },
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
-};
-
 /* 7x27 normal with GSM capable modem */
 static struct clkctl_acpu_speed pll0_245_pll1_960_pll2_1200_pll4_0[] = {
 	{ 0, 19200, ACPU_PLL_TCXO, 0, 0, 19200, 0, 0, 30720 },
@@ -190,10 +132,10 @@
 	{ 1, 122880, ACPU_PLL_0, 4, 1,  61440, 1, 3,  61440 },
 	{ 0, 200000, ACPU_PLL_2, 2, 5,  66667, 2, 4,  61440 },
 	{ 1, 245760, ACPU_PLL_0, 4, 0, 122880, 1, 4,  61440 },
-	{ 1, 320000, ACPU_PLL_1, 1, 2, 160000, 1, 5, 122880 },
-	{ 0, 400000, ACPU_PLL_2, 2, 2, 133333, 2, 5, 122880 },
-	{ 1, 480000, ACPU_PLL_1, 1, 1, 160000, 2, 6, 122880 },
-	{ 1, 600000, ACPU_PLL_2, 2, 1, 200000, 2, 7, 122880 },
+	{ 1, 320000, ACPU_PLL_1, 1, 2, 160000, 1, 5, 160000 },
+	{ 0, 400000, ACPU_PLL_2, 2, 2, 133333, 2, 5, 160000 },
+	{ 1, 480000, ACPU_PLL_1, 1, 1, 160000, 2, 6, 160000 },
+	{ 1, 600000, ACPU_PLL_2, 2, 1, 200000, 2, 7, 200000 },
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
@@ -204,10 +146,10 @@
 	{ 0, 120000, ACPU_PLL_1, 1, 7,  60000, 1, 3,  49152 },
 	{ 1, 196608, ACPU_PLL_0, 4, 0,  65536, 2, 4,  98304 },
 	{ 0, 200000, ACPU_PLL_2, 2, 5,  66667, 2, 4,  98304 },
-	{ 1, 320000, ACPU_PLL_1, 1, 2, 160000, 1, 5, 120000 },
-	{ 0, 400000, ACPU_PLL_2, 2, 2, 133333, 2, 5, 120000 },
-	{ 1, 480000, ACPU_PLL_1, 1, 1, 160000, 2, 6, 120000 },
-	{ 1, 600000, ACPU_PLL_2, 2, 1, 200000, 2, 7, 120000 },
+	{ 1, 320000, ACPU_PLL_1, 1, 2, 160000, 1, 5, 160000 },
+	{ 0, 400000, ACPU_PLL_2, 2, 2, 133333, 2, 5, 160000 },
+	{ 1, 480000, ACPU_PLL_1, 1, 1, 160000, 2, 6, 160000 },
+	{ 1, 600000, ACPU_PLL_2, 2, 1, 200000, 2, 7, 200000 },
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
@@ -218,10 +160,10 @@
 	{ 1, 122880, ACPU_PLL_1, 1, 1,  61440, 1, 3,  61440 },
 	{ 0, 200000, ACPU_PLL_2, 2, 5,  66667, 2, 4,  61440 },
 	{ 1, 245760, ACPU_PLL_1, 1, 0, 122880, 1, 4,  61440 },
-	{ 1, 320000, ACPU_PLL_0, 4, 2, 160000, 1, 5, 122880 },
-	{ 0, 400000, ACPU_PLL_2, 2, 2, 133333, 2, 5, 122880 },
-	{ 1, 480000, ACPU_PLL_0, 4, 1, 160000, 2, 6, 122880 },
-	{ 1, 600000, ACPU_PLL_2, 2, 1, 200000, 2, 7, 122880 },
+	{ 1, 320000, ACPU_PLL_0, 4, 2, 160000, 1, 5, 160000 },
+	{ 0, 400000, ACPU_PLL_2, 2, 2, 133333, 2, 5, 160000 },
+	{ 1, 480000, ACPU_PLL_0, 4, 1, 160000, 2, 6, 160000 },
+	{ 1, 600000, ACPU_PLL_2, 2, 1, 200000, 2, 7, 200000 },
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
@@ -232,10 +174,10 @@
 	{ 0, 120000, ACPU_PLL_0, 4, 7,  60000, 1, 3,  49152 },
 	{ 1, 196608, ACPU_PLL_1, 1, 0,  65536, 2, 4,  98304 },
 	{ 0, 200000, ACPU_PLL_2, 2, 5,  66667, 2, 4,  98304 },
-	{ 1, 320000, ACPU_PLL_0, 4, 2, 160000, 1, 5, 120000 },
-	{ 0, 400000, ACPU_PLL_2, 2, 2, 133333, 2, 5, 120000 },
-	{ 1, 480000, ACPU_PLL_0, 4, 1, 160000, 2, 6, 120000 },
-	{ 1, 600000, ACPU_PLL_2, 2, 1, 200000, 2, 7, 120000 },
+	{ 1, 320000, ACPU_PLL_0, 4, 2, 160000, 1, 5, 160000 },
+	{ 0, 400000, ACPU_PLL_2, 2, 2, 133333, 2, 5, 160000 },
+	{ 1, 480000, ACPU_PLL_0, 4, 1, 160000, 2, 6, 160000 },
+	{ 1, 600000, ACPU_PLL_2, 2, 1, 200000, 2, 7, 200000 },
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
@@ -246,10 +188,10 @@
 	{ 1, 122880, ACPU_PLL_1, 1, 1,  61440, 1, 3,  61440 },
 	{ 0, 200000, ACPU_PLL_2, 2, 3,  66667, 2, 4,  61440 },
 	{ 1, 245760, ACPU_PLL_1, 1, 0, 122880, 1, 4,  61440 },
-	{ 1, 320000, ACPU_PLL_0, 4, 2, 160000, 1, 5, 122880 },
-	{ 0, 400000, ACPU_PLL_2, 2, 1, 133333, 2, 5, 122880 },
-	{ 1, 480000, ACPU_PLL_0, 4, 1, 160000, 2, 6, 122880 },
-	{ 1, 800000, ACPU_PLL_2, 2, 0, 200000, 3, 7, 122880 },
+	{ 1, 320000, ACPU_PLL_0, 4, 2, 160000, 1, 5, 160000 },
+	{ 0, 400000, ACPU_PLL_2, 2, 1, 133333, 2, 5, 160000 },
+	{ 1, 480000, ACPU_PLL_0, 4, 1, 160000, 2, 6, 160000 },
+	{ 1, 800000, ACPU_PLL_2, 2, 0, 200000, 3, 7, 200000 },
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
@@ -260,10 +202,10 @@
 	{ 0, 120000, ACPU_PLL_0, 4, 7,  60000, 1, 3,  49152 },
 	{ 1, 196608, ACPU_PLL_1, 1, 0,  65536, 2, 4,  98304 },
 	{ 0, 200000, ACPU_PLL_2, 2, 3,  66667, 2, 4,  98304 },
-	{ 1, 320000, ACPU_PLL_0, 4, 2, 160000, 1, 5, 120000 },
-	{ 0, 400000, ACPU_PLL_2, 2, 1, 133333, 2, 5, 120000 },
-	{ 1, 480000, ACPU_PLL_0, 4, 1, 160000, 2, 6, 120000 },
-	{ 1, 800000, ACPU_PLL_2, 2, 0, 200000, 3, 7, 120000 },
+	{ 1, 320000, ACPU_PLL_0, 4, 2, 160000, 1, 5, 160000 },
+	{ 0, 400000, ACPU_PLL_2, 2, 1, 133333, 2, 5, 160000 },
+	{ 1, 480000, ACPU_PLL_0, 4, 1, 160000, 2, 6, 160000 },
+	{ 1, 800000, ACPU_PLL_2, 2, 0, 200000, 3, 7, 200000 },
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
@@ -418,14 +360,11 @@
 #define PLL_0_MHZ	0
 #define PLL_196_MHZ	10
 #define PLL_245_MHZ	12
-#define PLL_491_MHZ	25
 #define PLL_589_MHZ	30
 #define PLL_737_MHZ	38
-#define PLL_768_MHZ	40
 #define PLL_800_MHZ	41
 #define PLL_960_MHZ	50
 #define PLL_1008_MHZ	52
-#define PLL_1056_MHZ	55
 #define PLL_1200_MHZ	62
 
 #define PLL_CONFIG(m0, m1, m2, m4) { \
@@ -442,10 +381,6 @@
 };
 
 static struct pll_freq_tbl_map acpu_freq_tbl_list[] = {
-	PLL_CONFIG(196, 768, 1056, 0),
-	PLL_CONFIG(245, 768, 1056, 0),
-	PLL_CONFIG(196, 960, 1056, 0),
-	PLL_CONFIG(245, 960, 1056, 0),
 	PLL_CONFIG(196, 960, 1200, 0),
 	PLL_CONFIG(245, 960, 1200, 0),
 	PLL_CONFIG(960, 196, 1200, 0),
@@ -523,30 +458,22 @@
 	if (id >= ACPU_PLL_END)
 		return -EINVAL;
 
-	if (pll_control) {
-		remote_spin_lock(&pll_lock);
-		if (on) {
-			pll_control->pll[PLL_BASE + id].votes |= 2;
-			if (!pll_control->pll[PLL_BASE + id].on) {
-				pll_enable(soc_pll[id].mod_reg, 1);
-				pll_control->pll[PLL_BASE + id].on = 1;
-			}
-		} else {
-			pll_control->pll[PLL_BASE + id].votes &= ~2;
-			if (pll_control->pll[PLL_BASE + id].on
-			    && !pll_control->pll[PLL_BASE + id].votes) {
-				pll_enable(soc_pll[id].mod_reg, 0);
-				pll_control->pll[PLL_BASE + id].on = 0;
-			}
+	remote_spin_lock(&pll_lock);
+	if (on) {
+		pll_control->pll[PLL_BASE + id].votes |= 2;
+		if (!pll_control->pll[PLL_BASE + id].on) {
+			pll_enable(soc_pll[id].mod_reg, 1);
+			pll_control->pll[PLL_BASE + id].on = 1;
 		}
-		remote_spin_unlock(&pll_lock);
 	} else {
-		res = msm_proc_comm(PCOM_CLKCTL_RPC_PLL_REQUEST, &id, &on);
-		if (res < 0)
-			return res;
-		else if ((int) id < 0)
-			return -EINVAL;
+		pll_control->pll[PLL_BASE + id].votes &= ~2;
+		if (pll_control->pll[PLL_BASE + id].on
+		    && !pll_control->pll[PLL_BASE + id].votes) {
+			pll_enable(soc_pll[id].mod_reg, 0);
+			pll_control->pll[PLL_BASE + id].on = 0;
+		}
 	}
+	remote_spin_unlock(&pll_lock);
 
 	if (on)
 		pr_debug("PLL enabled\n");
@@ -556,23 +483,10 @@
 	return res;
 }
 
-
-/*----------------------------------------------------------------------------
- * ARM11 'owned' clock control
- *---------------------------------------------------------------------------*/
-
 static int acpuclk_set_vdd_level(int vdd)
 {
 	uint32_t current_vdd;
 
-	/*
-	 * NOTE: v1.0 of 7x27a/7x25a chip doesn't have working
-	 * VDD switching support.
-	 */
-	if ((cpu_is_msm7x27a() || cpu_is_msm7x25a()) &&
-			(SOCINFO_VERSION_MINOR(socinfo_get_version()) < 1))
-		return 0;
-
 	current_vdd = readl_relaxed(A11S_VDD_SVS_PLEVEL_ADDR) & 0x07;
 
 	pr_debug("Switching VDD from %u mV -> %d mV\n",
@@ -635,7 +549,7 @@
 	}
 }
 
-static int acpuclk_7201_set_rate(int cpu, unsigned long rate,
+static int acpuclk_7627_set_rate(int cpu, unsigned long rate,
 				 enum setrate_reason reason)
 {
 	uint32_t reg_clkctl;
@@ -712,9 +626,9 @@
 
 	while (cur_s != tgt_s) {
 		/*
-		 * Always jump to target freq if within 256mhz, regulardless of
-		 * PLL. If differnece is greater, use the predefinied
-		 * steppings in the table.
+		 * Always jump to target freq if within max_speed_delta_khz,
+		 * regardless of PLL. If differnece is greater, use the
+		 * predefined steppings in the table.
 		 */
 		int d = abs((int)(cur_s->a11clk_khz - tgt_s->a11clk_khz));
 		if (d > drv_state.max_speed_delta_khz) {
@@ -834,11 +748,6 @@
 		div = readl_relaxed(A11S_CLK_CNTL_ADDR) & 0x0f;
 	}
 
-	/* Accomodate bootloaders that might not be implementing the
-	 * workaround for the h/w bug in 7x25. */
-	if (cpu_is_msm7x25() && sel == 2)
-		sel = 3;
-
 	for (speed = acpu_freq_tbl; speed->a11clk_khz != 0; speed++) {
 		if (speed->a11clk_src_sel == sel
 		 && (speed->a11clk_src_div == div))
@@ -872,7 +781,7 @@
 	pr_info("ACPU running at %d KHz\n", speed->a11clk_khz);
 }
 
-static unsigned long acpuclk_7201_get_rate(int cpu)
+static unsigned long acpuclk_7627_get_rate(int cpu)
 {
 	WARN_ONCE(drv_state.current_speed == NULL,
 		  "%s: not initialized\n", __func__);
@@ -886,17 +795,10 @@
  * Clock driver initialization
  *---------------------------------------------------------------------------*/
 
-#define DIV2REG(n)		((n)-1)
-#define REG2DIV(n)		((n)+1)
-#define SLOWER_BY(div, factor)	div = DIV2REG(REG2DIV(div) * factor)
-
 static void __init acpu_freq_tbl_fixup(void)
 {
 	unsigned long pll0_l, pll1_l, pll2_l, pll4_l;
-	int axi_160mhz = 0, axi_200mhz = 0;
 	struct pll_freq_tbl_map *lst;
-	struct clkctl_acpu_speed *t;
-	unsigned int pll0_needs_fixup = 0;
 
 	/* Wait for the PLLs to be initialized and then read their frequency.
 	 */
@@ -934,15 +836,6 @@
 		pll4_l = 0;
 	}
 
-	/* Some configurations run PLL0 twice as fast. Instead of having
-	 * separate tables for this case, we simply fix up the ACPU clock
-	 * source divider since it's a simple fix up.
-	 */
-	if (pll0_l == PLL_491_MHZ) {
-		pll0_l = PLL_245_MHZ;
-		pll0_needs_fixup = 1;
-	}
-
 	/* Fix the tables for 7x25a variant to not conflict with 7x27 ones */
 	if (cpu_is_msm7x25a()) {
 		if (pll1_l == PLL_245_MHZ) {
@@ -969,38 +862,11 @@
 		BUG();
 	}
 
-	/* Fix up PLL0 source divider if necessary. Also, fix up the AXI to
-	 * the max that's supported by the board (RAM used in board).
-	 */
-	axi_160mhz = (pll0_l == PLL_960_MHZ || pll1_l == PLL_960_MHZ);
-	axi_200mhz = (pll2_l == PLL_1200_MHZ || pll2_l == PLL_800_MHZ);
-	for (t = &acpu_freq_tbl[0]; t->a11clk_khz != 0; t++) {
-
-		if (pll0_needs_fixup && t->pll == ACPU_PLL_0)
-			SLOWER_BY(t->a11clk_src_div, 2);
-		if (axi_160mhz && drv_state.max_axi_khz >= 160000
-		    && t->ahbclk_khz > 128000)
-			t->axiclk_khz = 160000;
-		if (axi_200mhz && drv_state.max_axi_khz >= 200000
-		    && t->ahbclk_khz > 160000)
-			t->axiclk_khz = 200000;
-	}
-
-	t--;
-	drv_state.max_axi_khz = t->axiclk_khz;
-
 	/* The default 7x27 ACPU clock plan supports running the AXI bus at
 	 * 200 MHz. So we don't classify it as Turbo mode.
 	 */
 	if (cpu_is_msm7x27())
 		return;
-
-	if (!axi_160mhz)
-		pr_info("Turbo mode not supported.\n");
-	else if (t->axiclk_khz == 160000)
-		pr_info("Turbo mode supported and enabled.\n");
-	else
-		pr_info("Turbo mode supported but not enabled.\n");
 }
 
 /*
@@ -1102,51 +968,42 @@
 	}
 }
 
-static void msm7x25_acpu_pll_hw_bug_fix(void)
-{
-	unsigned int n;
-
-	/* The 7625 has a hardware bug and in order to select PLL2 we
-	 * must program PLL3.  Use the same table, and just fix up the
-	 * numbers on this target. */
-	for (n = 0; acpu_freq_tbl[n].a11clk_khz != 0; n++)
-		if (acpu_freq_tbl[n].pll == ACPU_PLL_2)
-			acpu_freq_tbl[n].a11clk_src_sel = 3;
-}
-
 static void shared_pll_control_init(void)
 {
 #define PLL_REMOTE_SPINLOCK_ID "S:7"
 	unsigned smem_size;
+
 	remote_spin_lock_init(&pll_lock, PLL_REMOTE_SPINLOCK_ID);
 	pll_control = smem_get_entry(SMEM_CLKREGIM_SOURCES, &smem_size);
 
-	if (!pll_control)
-		pr_warning("Can't find shared PLL control data structure!\n");
+	if (!pll_control) {
+		pr_err("Can't find shared PLL control data structure!\n");
+		BUG();
 	/* There might be more PLLs than what the application processor knows
 	 * about. But the index used for each PLL is guaranteed to remain the
 	 * same. */
-	else if (smem_size < sizeof(struct shared_pll_control))
-		pr_warning("Shared PLL control data structure too small!\n");
-	else if (pll_control->version != 0xCCEE0001)
-		pr_warning("Shared PLL control version mismatch!\n");
-	else {
+	} else if (smem_size < sizeof(struct shared_pll_control)) {
+			pr_err("Shared PLL control data"
+					"structure too small!\n");
+			BUG();
+	} else if (pll_control->version != 0xCCEE0001) {
+			pr_err("Shared PLL control version mismatch!\n");
+			BUG();
+	} else {
 		pr_info("Shared PLL control available.\n");
 		return;
 	}
 
-	pll_control = NULL;
-	pr_warning("Falling back to proc_comm PLL control.\n");
 }
 
-static struct acpuclk_data acpuclk_7201_data = {
-	.set_rate = acpuclk_7201_set_rate,
-	.get_rate = acpuclk_7201_get_rate,
+static struct acpuclk_data acpuclk_7627_data = {
+	.set_rate = acpuclk_7627_set_rate,
+	.get_rate = acpuclk_7627_get_rate,
 	.power_collapse_khz = POWER_COLLAPSE_KHZ,
 	.switch_time_us = 50,
 };
 
-static int __init acpuclk_7201_init(struct acpuclk_soc_data *soc_data)
+static int __init acpuclk_7627_init(struct acpuclk_soc_data *soc_data)
 {
 	pr_info("%s()\n", __func__);
 
@@ -1156,16 +1013,13 @@
 	mutex_init(&drv_state.lock);
 	shared_pll_control_init();
 	drv_state.max_speed_delta_khz = soc_data->max_speed_delta_khz;
-	drv_state.max_axi_khz = soc_data->max_axi_khz;
 	acpu_freq_tbl_fixup();
-	acpuclk_7201_data.wait_for_irq_khz = find_wait_for_irq_khz();
+	acpuclk_7627_data.wait_for_irq_khz = find_wait_for_irq_khz();
 	precompute_stepping();
-	if (cpu_is_msm7x25())
-		msm7x25_acpu_pll_hw_bug_fix();
 	acpuclk_hw_init();
 	lpj_init();
 	print_acpu_freq_tbl();
-	acpuclk_register(&acpuclk_7201_data);
+	acpuclk_register(&acpuclk_7627_data);
 
 #ifdef CONFIG_CPU_FREQ_MSM
 	cpufreq_table_init();
@@ -1174,26 +1028,17 @@
 	return 0;
 }
 
-struct acpuclk_soc_data acpuclk_7201_soc_data __initdata = {
-	.max_speed_delta_khz = 400000,
-	.max_axi_khz = 160000,
-	.init = acpuclk_7201_init,
-};
-
 struct acpuclk_soc_data acpuclk_7x27_soc_data __initdata = {
 	.max_speed_delta_khz = 400000,
-	.max_axi_khz = 200000,
-	.init = acpuclk_7201_init,
+	.init = acpuclk_7627_init,
 };
 
 struct acpuclk_soc_data acpuclk_7x27a_soc_data __initdata = {
 	.max_speed_delta_khz = 400000,
-	.max_axi_khz = 200000,
-	.init = acpuclk_7201_init,
+	.init = acpuclk_7627_init,
 };
 
 struct acpuclk_soc_data acpuclk_7x27aa_soc_data __initdata = {
 	.max_speed_delta_khz = 504000,
-	.max_axi_khz = 200000,
-	.init = acpuclk_7201_init,
+	.init = acpuclk_7627_init,
 };
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index c9ca339..5aa75c7 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -422,17 +422,17 @@
 	{ 1, {   810000, HFPLL, 1, 0, 0x1E }, L2(11), 1062500 },
 	{ 1, {   864000, HFPLL, 1, 0, 0x20 }, L2(11), 1062500 },
 	{ 1, {   918000, HFPLL, 1, 0, 0x22 }, L2(11), 1087500 },
-	{ 1, {   972000, HFPLL, 1, 0, 0x24 }, L2(16), 1300000 },
-	{ 1, {  1026000, HFPLL, 1, 0, 0x26 }, L2(16), 1300000 },
-	{ 1, {  1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1300000 },
-	{ 1, {  1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1300000 },
-	{ 1, {  1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1300000 },
-	{ 1, {  1242000, HFPLL, 1, 0, 0x2E }, L2(16), 1300000 },
-	{ 1, {  1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1300000 },
-	{ 1, {  1350000, HFPLL, 1, 0, 0x32 }, L2(16), 1300000 },
-	{ 1, {  1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1300000 },
-	{ 1, {  1458000, HFPLL, 1, 0, 0x36 }, L2(16), 1300000 },
-	{ 1, {  1512000, HFPLL, 1, 0, 0x38 }, L2(16), 1300000 },
+	{ 1, {   972000, HFPLL, 1, 0, 0x24 }, L2(16), 1100000 },
+	{ 1, {  1026000, HFPLL, 1, 0, 0x26 }, L2(16), 1100000 },
+	{ 1, {  1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1100000 },
+	{ 1, {  1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1100000 },
+	{ 1, {  1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1125000 },
+	{ 1, {  1242000, HFPLL, 1, 0, 0x2E }, L2(16), 1137500 },
+	{ 1, {  1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1150000 },
+	{ 1, {  1350000, HFPLL, 1, 0, 0x32 }, L2(16), 1175000 },
+	{ 1, {  1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1187500 },
+	{ 1, {  1458000, HFPLL, 1, 0, 0x36 }, L2(16), 1225000 },
+	{ 1, {  1512000, HFPLL, 1, 0, 0x38 }, L2(16), 1250000 },
 	{ 0, { 0 } }
 };
 
@@ -449,17 +449,17 @@
 	{ 1, {   810000, HFPLL, 1, 0, 0x1E }, L2(11), 1012500 },
 	{ 1, {   864000, HFPLL, 1, 0, 0x20 }, L2(11), 1025000 },
 	{ 1, {   918000, HFPLL, 1, 0, 0x22 }, L2(11), 1025000 },
-	{ 1, {   972000, HFPLL, 1, 0, 0x24 }, L2(16), 1300000 },
-	{ 1, {  1026000, HFPLL, 1, 0, 0x26 }, L2(16), 1300000 },
-	{ 1, {  1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1300000 },
-	{ 1, {  1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1300000 },
-	{ 1, {  1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1300000 },
-	{ 1, {  1242000, HFPLL, 1, 0, 0x2E }, L2(16), 1300000 },
-	{ 1, {  1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1300000 },
-	{ 1, {  1350000, HFPLL, 1, 0, 0x32 }, L2(16), 1300000 },
-	{ 1, {  1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1300000 },
-	{ 1, {  1458000, HFPLL, 1, 0, 0x36 }, L2(16), 1300000 },
-	{ 1, {  1512000, HFPLL, 1, 0, 0x38 }, L2(16), 1300000 },
+	{ 1, {   972000, HFPLL, 1, 0, 0x24 }, L2(16), 1100000 },
+	{ 1, {  1026000, HFPLL, 1, 0, 0x26 }, L2(16), 1100000 },
+	{ 1, {  1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1100000 },
+	{ 1, {  1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1100000 },
+	{ 1, {  1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1125000 },
+	{ 1, {  1242000, HFPLL, 1, 0, 0x2E }, L2(16), 1137500 },
+	{ 1, {  1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1150000 },
+	{ 1, {  1350000, HFPLL, 1, 0, 0x32 }, L2(16), 1175000 },
+	{ 1, {  1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1187500 },
+	{ 1, {  1458000, HFPLL, 1, 0, 0x36 }, L2(16), 1225000 },
+	{ 1, {  1512000, HFPLL, 1, 0, 0x38 }, L2(16), 1250000 },
 	{ 0, { 0 } }
 };
 
diff --git a/arch/arm/mach-msm/acpuclock.h b/arch/arm/mach-msm/acpuclock.h
index b12258f..6ea691b 100644
--- a/arch/arm/mach-msm/acpuclock.h
+++ b/arch/arm/mach-msm/acpuclock.h
@@ -102,7 +102,6 @@
 extern struct acpuclk_soc_data acpuclk_7x27_soc_data;
 extern struct acpuclk_soc_data acpuclk_7x27a_soc_data;
 extern struct acpuclk_soc_data acpuclk_7x27aa_soc_data;
-extern struct acpuclk_soc_data acpuclk_7201_soc_data;
 extern struct acpuclk_soc_data acpuclk_7x30_soc_data;
 extern struct acpuclk_soc_data acpuclk_8x50_soc_data;
 extern struct acpuclk_soc_data acpuclk_8x60_soc_data;
diff --git a/arch/arm/mach-msm/board-8930-display.c b/arch/arm/mach-msm/board-8930-display.c
index 2fb6153..c1b880c 100644
--- a/arch/arm/mach-msm/board-8930-display.c
+++ b/arch/arm/mach-msm/board-8930-display.c
@@ -17,6 +17,7 @@
 #include <linux/bootmem.h>
 #include <asm/mach-types.h>
 #include <mach/msm_bus_board.h>
+#include <mach/msm_memtypes.h>
 #include <mach/board.h>
 #include <mach/gpio.h>
 #include <mach/gpiomux.h>
@@ -46,25 +47,26 @@
 #define MSM_FB_EXT_BUF_SIZE	0
 #endif
 
-#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
-/* width x height x 3 bpp x 2 frame buffer */
-#define MSM_FB_WRITEBACK_SIZE (1376 * 768 * 3 * 2)
-#define MSM_FB_WRITEBACK_OFFSET  \
-		(MSM_FB_PRIM_BUF_SIZE + MSM_FB_EXT_BUF_SIZE)
-#else
-#define MSM_FB_WRITEBACK_SIZE   0
-#define MSM_FB_WRITEBACK_OFFSET 0
-#endif
-
 #ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
 /* 4 bpp x 2 page HDMI case */
 #define MSM_FB_SIZE roundup((1920 * 1088 * 4 * 2), 4096)
 #else
 /* Note: must be multiple of 4096 */
-#define MSM_FB_SIZE roundup(MSM_FB_PRIM_BUF_SIZE + MSM_FB_EXT_BUF_SIZE + \
-				MSM_FB_WRITEBACK_SIZE, 4096)
+#define MSM_FB_SIZE roundup(MSM_FB_PRIM_BUF_SIZE + MSM_FB_EXT_BUF_SIZE, 4096)
 #endif
 
+#ifdef CONFIG_FB_MSM_OVERLAY0_WRITEBACK
+#define MSM_FB_OVERLAY0_WRITEBACK_SIZE roundup((1376 * 768 * 3 * 2), 4096)
+#else
+#define MSM_FB_OVERLAY0_WRITEBACK_SIZE (0)
+#endif  /* CONFIG_FB_MSM_OVERLAY0_WRITEBACK */
+
+#ifdef CONFIG_FB_MSM_OVERLAY1_WRITEBACK
+#define MSM_FB_OVERLAY1_WRITEBACK_SIZE roundup((1920 * 1088 * 3 * 2), 4096)
+#else
+#define MSM_FB_OVERLAY1_WRITEBACK_SIZE (0)
+#endif  /* CONFIG_FB_MSM_OVERLAY1_WRITEBACK */
+
 #define MDP_VSYNC_GPIO 0
 
 #define PANEL_NAME_MAX_LEN	30
@@ -77,11 +79,6 @@
 #define HDMI_PANEL_NAME	"hdmi_msm"
 #define TVOUT_PANEL_NAME	"tvout_msm"
 
-static int writeback_offset(void)
-{
-	return MSM_FB_WRITEBACK_OFFSET;
-}
-
 static struct resource msm_fb_resources[] = {
 	{
 		.flags = IORESOURCE_DMA,
@@ -438,9 +435,21 @@
 	.mdp_bus_scale_table = &mdp_bus_scale_pdata,
 #endif
 	.mdp_rev = MDP_REV_42,
-	.writeback_offset = writeback_offset,
+	.mdp_writeback_memtype = MEMTYPE_EBI1,
+	.mdp_writeback_phys = NULL,
 };
 
+void __init msm8930_mdp_writeback(struct memtype_reserve* reserve_table)
+{
+	mdp_pdata.mdp_writeback_size_ov0 = MSM_FB_OVERLAY0_WRITEBACK_SIZE;
+	mdp_pdata.mdp_writeback_size_ov1 = MSM_FB_OVERLAY1_WRITEBACK_SIZE;
+
+	reserve_table[mdp_pdata.mdp_writeback_memtype].size +=
+		mdp_pdata.mdp_writeback_size_ov0;
+	reserve_table[mdp_pdata.mdp_writeback_memtype].size +=
+		mdp_pdata.mdp_writeback_size_ov1;
+}
+
 #define LPM_CHANNEL0 0
 static int toshiba_gpio[] = {LPM_CHANNEL0};
 
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 620716a..41074d1 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -326,11 +326,18 @@
 	msm8930_reserve_table[MEMTYPE_EBI1].size += MSM_ION_ADSP_SIZE;
 #endif
 }
+
+static void __init reserve_mdp_memory(void)
+{
+	msm8930_mdp_writeback(msm8930_reserve_table);
+}
+
 static void __init msm8930_calculate_reserve_sizes(void)
 {
 	size_pmem_devices();
 	reserve_pmem_memory();
 	reserve_ion_memory();
+	reserve_mdp_memory();
 }
 
 static struct reserve_info msm8930_reserve_info __initdata = {
@@ -776,10 +783,8 @@
 #ifdef CONFIG_USB_MSM_OTG_72K
 static struct msm_otg_platform_data msm_otg_pdata;
 #else
-#define USB_5V_EN		42
 static void msm_hsusb_vbus_power(bool on)
 {
-	int rc;
 	static bool vbus_is_on;
 	static struct regulator *mvs_otg_switch;
 
@@ -793,42 +798,16 @@
 			pr_err("Unable to get mvs_otg_switch\n");
 			return;
 		}
-		/* TODO: Replace this with appropriate PM8038 alternative */
-#ifndef MSM8930_PHASE_2
-		rc = gpio_request(PM8921_GPIO_PM_TO_SYS(USB_5V_EN),
-						"usb_5v_en");
-#endif
-		if (rc < 0) {
-			pr_err("failed to request usb_5v_en gpio\n");
-			goto put_mvs_otg;
-		}
 
-		/* TODO: Replace this with appropriate PM8038 alternative */
-#ifndef MSM8930_PHASE_2
-		rc = gpio_direction_output(PM8921_GPIO_PM_TO_SYS(USB_5V_EN), 1);
-		if (rc) {
-			pr_err("%s: unable to set_direction for gpio [%d]\n",
-				__func__, PM8921_GPIO_PM_TO_SYS(USB_5V_EN));
-			goto free_usb_5v_en;
-		}
-#endif
 		if (regulator_enable(mvs_otg_switch)) {
 			pr_err("unable to enable mvs_otg_switch\n");
-			goto err_ldo_gpio_set_dir;
+			goto put_mvs_otg;
 		}
 
 		vbus_is_on = true;
 		return;
 	}
 	regulator_disable(mvs_otg_switch);
-
-/* TODO: Replace this with appropriate PM8038 alternative */
-#ifndef MSM8930_PHASE_2
-err_ldo_gpio_set_dir:
-	gpio_set_value(PM8921_GPIO_PM_TO_SYS(USB_5V_EN), 0);
-free_usb_5v_en:
-	gpio_free(PM8921_GPIO_PM_TO_SYS(USB_5V_EN));
-#endif
 put_mvs_otg:
 	regulator_put(mvs_otg_switch);
 	vbus_is_on = false;
@@ -1556,6 +1535,9 @@
 	&msm8930_device_ext_5v_vreg,
 	&msm8930_device_ext_l2_vreg,
 	&msm8960_device_ssbi_pmic,
+	&msm_8960_q6_lpass,
+	&msm_8960_q6_mss_fw,
+	&msm_8960_q6_mss_sw,
 	&msm8960_device_qup_spi_gsbi1,
 	&msm8960_device_qup_i2c_gsbi3,
 	&msm8960_device_qup_i2c_gsbi4,
diff --git a/arch/arm/mach-msm/board-8930.h b/arch/arm/mach-msm/board-8930.h
index ec0b867..61eb408 100644
--- a/arch/arm/mach-msm/board-8930.h
+++ b/arch/arm/mach-msm/board-8930.h
@@ -18,6 +18,7 @@
 #include <linux/i2c/sx150x.h>
 #include <mach/irqs.h>
 #include <mach/rpm-regulator.h>
+#include <mach/msm_memtypes.h>
 
 /*
  * TODO: When physical 8930/PM8038 hardware becomes
@@ -106,6 +107,7 @@
 int msm8930_init_gpiomux(void);
 void msm8930_allocate_fb_region(void);
 void msm8930_pm8038_gpio_mpp_init(void);
+void msm8930_mdp_writeback(struct memtype_reserve *reserve_table);
 
 #define PLATFORM_IS_CHARM25() \
 	(machine_is_msm8930_cdp() && \
diff --git a/arch/arm/mach-msm/board-8960-display.c b/arch/arm/mach-msm/board-8960-display.c
index 63c51ea..df351d2 100644
--- a/arch/arm/mach-msm/board-8960-display.c
+++ b/arch/arm/mach-msm/board-8960-display.c
@@ -17,6 +17,7 @@
 #include <linux/bootmem.h>
 #include <asm/mach-types.h>
 #include <mach/msm_bus_board.h>
+#include <mach/msm_memtypes.h>
 #include <mach/board.h>
 #include <mach/gpio.h>
 #include <mach/gpiomux.h>
@@ -37,25 +38,26 @@
 #define MSM_FB_EXT_BUF_SIZE	0
 #endif
 
-#ifdef CONFIG_FB_MSM_OVERLAY0_WRITEBACK
-/* width x height x 3 bpp x 2 frame buffer */
-#define MSM_FB_WRITEBACK_SIZE (1376 * 768 * 3 * 2)
-#define MSM_FB_WRITEBACK_OFFSET  \
-		(MSM_FB_PRIM_BUF_SIZE + MSM_FB_EXT_BUF_SIZE)
-#else
-#define MSM_FB_WRITEBACK_SIZE   0
-#define MSM_FB_WRITEBACK_OFFSET 0
-#endif
-
 #ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
 /* 4 bpp x 2 page HDMI case */
 #define MSM_FB_SIZE roundup((1920 * 1088 * 4 * 2), 4096)
 #else
 /* Note: must be multiple of 4096 */
-#define MSM_FB_SIZE roundup(MSM_FB_PRIM_BUF_SIZE + MSM_FB_EXT_BUF_SIZE + \
-				MSM_FB_WRITEBACK_SIZE, 4096)
+#define MSM_FB_SIZE roundup(MSM_FB_PRIM_BUF_SIZE + MSM_FB_EXT_BUF_SIZE, 4096)
 #endif
 
+#ifdef CONFIG_FB_MSM_OVERLAY0_WRITEBACK
+#define MSM_FB_OVERLAY0_WRITEBACK_SIZE roundup((1376 * 768 * 3 * 2), 4096)
+#else
+#define MSM_FB_OVERLAY0_WRITEBACK_SIZE (0)
+#endif  /* CONFIG_FB_MSM_OVERLAY0_WRITEBACK */
+
+#ifdef CONFIG_FB_MSM_OVERLAY1_WRITEBACK
+#define MSM_FB_OVERLAY1_WRITEBACK_SIZE roundup((1920 * 1088 * 3 * 2), 4096)
+#else
+#define MSM_FB_OVERLAY1_WRITEBACK_SIZE (0)
+#endif  /* CONFIG_FB_MSM_OVERLAY1_WRITEBACK */
+
 #define MDP_VSYNC_GPIO 0
 
 #define PANEL_NAME_MAX_LEN	30
@@ -68,11 +70,6 @@
 #define HDMI_PANEL_NAME	"hdmi_msm"
 #define TVOUT_PANEL_NAME	"tvout_msm"
 
-static int writeback_offset(void)
-{
-	return MSM_FB_WRITEBACK_OFFSET;
-}
-
 static struct resource msm_fb_resources[] = {
 	{
 		.flags = IORESOURCE_DMA,
@@ -553,9 +550,21 @@
 	.mdp_bus_scale_table = &mdp_bus_scale_pdata,
 #endif
 	.mdp_rev = MDP_REV_42,
-	.writeback_offset = writeback_offset,
+	.mdp_writeback_memtype = MEMTYPE_EBI1,
+	.mdp_writeback_phys = NULL,
 };
 
+void __init msm8960_mdp_writeback(struct memtype_reserve* reserve_table)
+{
+	mdp_pdata.mdp_writeback_size_ov0 = MSM_FB_OVERLAY0_WRITEBACK_SIZE;
+	mdp_pdata.mdp_writeback_size_ov1 = MSM_FB_OVERLAY1_WRITEBACK_SIZE;
+
+	reserve_table[mdp_pdata.mdp_writeback_memtype].size +=
+		mdp_pdata.mdp_writeback_size_ov0;
+	reserve_table[mdp_pdata.mdp_writeback_memtype].size +=
+		mdp_pdata.mdp_writeback_size_ov1;
+}
+
 static struct platform_device mipi_dsi_renesas_panel_device = {
 	.name = "mipi_renesas",
 	.id = 0,
diff --git a/arch/arm/mach-msm/board-8960-regulator.c b/arch/arm/mach-msm/board-8960-regulator.c
index de4a6d6..5049791 100644
--- a/arch/arm/mach-msm/board-8960-regulator.c
+++ b/arch/arm/mach-msm/board-8960-regulator.c
@@ -212,7 +212,6 @@
 };
 VREG_CONSUMERS(USB_OTG) = {
 	REGULATOR_SUPPLY("8921_usb_otg",	NULL),
-	REGULATOR_SUPPLY("vbus_otg",		"msm_otg"),
 };
 VREG_CONSUMERS(HDMI_MVS) = {
 	REGULATOR_SUPPLY("8921_hdmi_mvs",	NULL),
@@ -234,6 +233,10 @@
 	REGULATOR_SUPPLY("vdd_lvds_3p3v",	"mipi_dsi.1"),
 	REGULATOR_SUPPLY("mhl_ext_3p3v",	"msm_otg"),
 };
+VREG_CONSUMERS(EXT_OTG_SW) = {
+	REGULATOR_SUPPLY("ext_otg_sw",		NULL),
+	REGULATOR_SUPPLY("vbus_otg",		"msm_otg"),
+};
 
 #define PM8921_VREG_INIT(_id, _min_uV, _max_uV, _modes, _ops, _apply_uV, \
 			 _pull_down, _always_on, _supply_regulator, \
@@ -325,7 +328,7 @@
 		.pin_ctrl = _pin_ctrl, \
 	}
 
-#define GPIO_VREG_INIT(_id, _reg_name, _gpio_label, _gpio) \
+#define GPIO_VREG(_id, _reg_name, _gpio_label, _gpio, _supply_regulator) \
 	[GPIO_VREG_ID_##_id] = { \
 		.init_data = { \
 			.constraints = { \
@@ -334,6 +337,7 @@
 			.num_consumer_supplies	= \
 					ARRAY_SIZE(vreg_consumers_##_id), \
 			.consumer_supplies	= vreg_consumers_##_id, \
+			.supply_regulator	= _supply_regulator, \
 		}, \
 		.regulator_name = _reg_name, \
 		.gpio_label	= _gpio_label, \
@@ -445,10 +449,13 @@
 
 /* GPIO regulator constraints */
 struct gpio_regulator_platform_data msm_gpio_regulator_pdata[] __devinitdata = {
-	GPIO_VREG_INIT(EXT_5V, "ext_5v", "ext_5v_en", PM8921_MPP_PM_TO_SYS(7)),
-	GPIO_VREG_INIT(EXT_L2, "ext_l2", "ext_l2_en", 91),
-	GPIO_VREG_INIT(EXT_3P3V, "ext_3p3v", "ext_3p3v_en",
-			PM8921_GPIO_PM_TO_SYS(17)),
+	/*        ID      vreg_name gpio_label   gpio                  supply */
+	GPIO_VREG(EXT_5V, "ext_5v", "ext_5v_en", PM8921_MPP_PM_TO_SYS(7), NULL),
+	GPIO_VREG(EXT_L2, "ext_l2", "ext_l2_en", 91, NULL),
+	GPIO_VREG(EXT_3P3V, "ext_3p3v", "ext_3p3v_en",
+		PM8921_GPIO_PM_TO_SYS(17), NULL),
+	GPIO_VREG(EXT_OTG_SW, "ext_otg_sw", "ext_otg_sw_en",
+		PM8921_GPIO_PM_TO_SYS(42), "8921_usb_otg"),
 };
 
 /* SAW regulator constraints */
diff --git a/arch/arm/mach-msm/board-8960-storage.c b/arch/arm/mach-msm/board-8960-storage.c
index dfcafd4..8521717 100644
--- a/arch/arm/mach-msm/board-8960-storage.c
+++ b/arch/arm/mach-msm/board-8960-storage.c
@@ -247,6 +247,7 @@
 	.status_gpio	= PM8921_GPIO_PM_TO_SYS(26),
 	.status_irq	= PM8921_GPIO_IRQ(PM8921_IRQ_BASE, 26),
 	.irq_flags	= IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+	.is_status_gpio_active_low = true,
 #endif
 	.xpc_cap	= 1,
 	.uhs_caps	= (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 3ef7dea..9c6cd9b 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -377,12 +377,19 @@
 	msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_ADSP_SIZE;
 #endif
 }
+
+static void __init reserve_mdp_memory(void)
+{
+	msm8960_mdp_writeback(msm8960_reserve_table);
+}
+
 static void __init msm8960_calculate_reserve_sizes(void)
 {
 	size_pmem_devices();
 	reserve_pmem_memory();
 	reserve_ion_memory();
 	reserve_fmem_memory();
+	reserve_mdp_memory();
 }
 
 static struct reserve_info msm8960_reserve_info __initdata = {
@@ -818,10 +825,8 @@
 #ifdef CONFIG_USB_MSM_OTG_72K
 static struct msm_otg_platform_data msm_otg_pdata;
 #else
-#define USB_5V_EN		42
 static void msm_hsusb_vbus_power(bool on)
 {
-	int rc;
 	static bool vbus_is_on;
 	static struct regulator *mvs_otg_switch;
 
@@ -836,33 +841,15 @@
 			return;
 		}
 
-		rc = gpio_request(PM8921_GPIO_PM_TO_SYS(USB_5V_EN),
-						"usb_5v_en");
-		if (rc < 0) {
-			pr_err("failed to request usb_5v_en gpio\n");
-			goto put_mvs_otg;
-		}
-
-		rc = gpio_direction_output(PM8921_GPIO_PM_TO_SYS(USB_5V_EN), 1);
-		if (rc) {
-			pr_err("%s: unable to set_direction for gpio [%d]\n",
-				__func__, PM8921_GPIO_PM_TO_SYS(USB_5V_EN));
-			goto free_usb_5v_en;
-		}
-
 		if (regulator_enable(mvs_otg_switch)) {
 			pr_err("unable to enable mvs_otg_switch\n");
-			goto err_ldo_gpio_set_dir;
+			goto put_mvs_otg;
 		}
 
 		vbus_is_on = true;
 		return;
 	}
 	regulator_disable(mvs_otg_switch);
-err_ldo_gpio_set_dir:
-	gpio_set_value_cansleep(PM8921_GPIO_PM_TO_SYS(USB_5V_EN), 0);
-free_usb_5v_en:
-	gpio_free(PM8921_GPIO_PM_TO_SYS(USB_5V_EN));
 put_mvs_otg:
 	regulator_put(mvs_otg_switch);
 	vbus_is_on = false;
@@ -1599,6 +1586,15 @@
 	},
 };
 
+static struct platform_device msm8960_device_ext_otg_sw_vreg __devinitdata = {
+	.name	= GPIO_REGULATOR_DEV_NAME,
+	.id	= PM8921_GPIO_PM_TO_SYS(42),
+	.dev	= {
+		.platform_data =
+			&msm_gpio_regulator_pdata[GPIO_VREG_ID_EXT_OTG_SW],
+	},
+};
+
 static struct platform_device msm8960_device_rpm_regulator __devinitdata = {
 	.name	= "rpm-regulator",
 	.id	= -1,
@@ -1635,6 +1631,7 @@
 	&msm_device_saw_core1,
 	&msm8960_device_ext_5v_vreg,
 	&msm8960_device_ssbi_pmic,
+	&msm8960_device_ext_otg_sw_vreg,
 	&msm8960_device_qup_spi_gsbi1,
 	&msm8960_device_qup_i2c_gsbi3,
 	&msm8960_device_qup_i2c_gsbi4,
diff --git a/arch/arm/mach-msm/board-8960.h b/arch/arm/mach-msm/board-8960.h
index e22868f..125ae4d 100644
--- a/arch/arm/mach-msm/board-8960.h
+++ b/arch/arm/mach-msm/board-8960.h
@@ -18,6 +18,7 @@
 #include <linux/i2c/sx150x.h>
 #include <mach/irqs.h>
 #include <mach/rpm-regulator.h>
+#include <mach/msm_memtypes.h>
 
 /* Macros assume PMIC GPIOs and MPPs start at 1 */
 #define PM8921_GPIO_BASE		NR_GPIO_IRQS
@@ -34,6 +35,7 @@
 #define GPIO_VREG_ID_EXT_5V		0
 #define GPIO_VREG_ID_EXT_L2		1
 #define GPIO_VREG_ID_EXT_3P3V		2
+#define GPIO_VREG_ID_EXT_OTG_SW		3
 
 extern struct gpio_regulator_platform_data
 	msm_gpio_regulator_pdata[] __devinitdata;
@@ -76,7 +78,7 @@
 int msm8960_init_gpiomux(void);
 void msm8960_allocate_fb_region(void);
 void msm8960_pm8921_gpio_mpp_init(void);
-
+void msm8960_mdp_writeback(struct memtype_reserve *reserve_table);
 #define PLATFORM_IS_CHARM25() \
 	(machine_is_msm8960_cdp() && \
 		(socinfo_get_platform_subtype() == 1) \
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index f5bd44d..835a327 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -534,12 +534,12 @@
 
 #ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
 static unsigned int sdc1_sup_clk_rates[] = {
-	400000, 24000000, 48000000
+	400000, 24000000, 48000000,
 };
 
 static struct mmc_platform_data sdc1_data = {
-	.ocr_mask       = MMC_VDD_27_28 | MMC_VDD_28_29,
-	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
+	.ocr_mask	= MMC_VDD_27_28 | MMC_VDD_28_29,
+	.mmc_bus_width	= MMC_CAP_4_BIT_DATA,
 	.sup_clk_table	= sdc1_sup_clk_rates,
 	.sup_clk_cnt	= ARRAY_SIZE(sdc1_sup_clk_rates),
 	.pclk_src_dfab	= true,
@@ -552,7 +552,7 @@
 #endif
 	.xpc_cap	= 1,
 	.uhs_caps	= (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
-			   MMC_CAP_MAX_CURRENT_400)
+			   MMC_CAP_MAX_CURRENT_400),
 };
 static struct mmc_platform_data *msm9615_sdc1_pdata = &sdc1_data;
 #else
@@ -561,7 +561,7 @@
 
 #ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
 static unsigned int sdc2_sup_clk_rates[] = {
-	400000, 24000000, 48000000
+	400000, 24000000, 48000000,
 };
 
 static struct mmc_platform_data sdc2_data = {
diff --git a/arch/arm/mach-msm/board-msm7x27.c b/arch/arm/mach-msm/board-msm7x27.c
index d8efcfe..a09485a 100644
--- a/arch/arm/mach-msm/board-msm7x27.c
+++ b/arch/arm/mach-msm/board-msm7x27.c
@@ -1757,10 +1757,7 @@
 		}
 	}
 #endif
-	if (cpu_is_msm7x27())
-		acpuclk_init(&acpuclk_7x27_soc_data);
-	else
-		acpuclk_init(&acpuclk_7201_soc_data);
+	acpuclk_init(&acpuclk_7x27_soc_data);
 
 	usb_mpp_init();
 
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 75c1b80..a459ba1 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -2627,23 +2627,12 @@
 #define MSM_FB_EXT_BUFT_SIZE	0
 #endif
 
-#ifdef CONFIG_FB_MSM_OVERLAY0_WRITEBACK
-/* width x height x 3 bpp x 2 frame buffer */
-#define MSM_FB_WRITEBACK_SIZE (1024 * 600 * 3 * 2)
-#define MSM_FB_WRITEBACK_OFFSET  \
-		(MSM_FB_PRIM_BUF_SIZE + MSM_FB_EXT_BUF_SIZE)
-#else
-#define MSM_FB_WRITEBACK_SIZE	0
-#define MSM_FB_WRITEBACK_OFFSET 0
-#endif
-
 #ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
 /* 4 bpp x 2 page HDMI case */
 #define MSM_FB_SIZE roundup((1920 * 1088 * 4 * 2), 4096)
 #else
 /* Note: must be multiple of 4096 */
 #define MSM_FB_SIZE roundup(MSM_FB_PRIM_BUF_SIZE + MSM_FB_EXT_BUF_SIZE + \
-				MSM_FB_WRITEBACK_SIZE + \
 				MSM_FB_DSUB_PMEM_ADDER, 4096)
 #endif
 
@@ -2653,10 +2642,17 @@
 #define MSM_PMEM_SF_SIZE 0x4000000 /* 64 Mbytes */
 #endif
 
-static int writeback_offset(void)
-{
-	return MSM_FB_WRITEBACK_OFFSET;
-}
+#ifdef CONFIG_FB_MSM_OVERLAY0_WRITEBACK
+#define MSM_FB_OVERLAY0_WRITEBACK_SIZE roundup((1376 * 768 * 3 * 2), 4096)
+#else
+#define MSM_FB_OVERLAY0_WRITEBACK_SIZE (0)
+#endif  /* CONFIG_FB_MSM_OVERLAY0_WRITEBACK */
+
+#ifdef CONFIG_FB_MSM_OVERLAY1_WRITEBACK
+#define MSM_FB_OVERLAY1_WRITEBACK_SIZE roundup((1920 * 1088 * 3 * 2), 4096)
+#else
+#define MSM_FB_OVERLAY1_WRITEBACK_SIZE (0)
+#endif  /* CONFIG_FB_MSM_OVERLAY1_WRITEBACK */
 
 #define MSM_PMEM_KERNEL_EBI1_SIZE  0x600000
 #define MSM_PMEM_ADSP_SIZE         0x2000000
@@ -2873,18 +2869,20 @@
 	.name = "pmem_smi",
 };
 
-void request_smi_region(void *data)
+int request_smi_region(void *data)
 {
 	int bus_id = (int) data;
 
 	msm_bus_scale_client_update_request(bus_id, 1);
+	return 0;
 }
 
-void release_smi_region(void *data)
+int release_smi_region(void *data)
 {
 	int bus_id = (int) data;
 
 	msm_bus_scale_client_update_request(bus_id, 0);
+	return 0;
 }
 
 void *setup_smi_region(void)
@@ -5347,13 +5345,14 @@
 #endif
 }
 
-
+static void __init reserve_mdp_memory(void);
 
 static void __init msm8x60_calculate_reserve_sizes(void)
 {
 	size_pmem_devices();
 	reserve_pmem_memory();
 	reserve_ion_memory();
+	reserve_mdp_memory();
 }
 
 static int msm8x60_paddr_to_memtype(unsigned int paddr)
@@ -9421,9 +9420,21 @@
 	.mdp_bus_scale_table = &mdp_bus_scale_pdata,
 #endif
 	.mdp_rev = MDP_REV_41,
-	.writeback_offset = writeback_offset,
+	.mdp_writeback_memtype = MEMTYPE_EBI1,
+	.mdp_writeback_phys = NULL,
 };
 
+static void __init reserve_mdp_memory(void)
+{
+	mdp_pdata.mdp_writeback_size_ov0 = MSM_FB_OVERLAY0_WRITEBACK_SIZE;
+	mdp_pdata.mdp_writeback_size_ov1 = MSM_FB_OVERLAY1_WRITEBACK_SIZE;
+
+	msm8x60_reserve_table[mdp_pdata.mdp_writeback_memtype].size +=
+		mdp_pdata.mdp_writeback_size_ov0;
+	msm8x60_reserve_table[mdp_pdata.mdp_writeback_memtype].size +=
+		mdp_pdata.mdp_writeback_size_ov1;
+}
+
 #ifdef CONFIG_FB_MSM_TVOUT
 
 #ifdef CONFIG_MSM_BUS_SCALING
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index 889ac00..e8f6443 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -60,6 +60,15 @@
 #define BAHAMA_SLAVE_ID_QMEMBIST_ADDR   0x7B
 #define BAHAMA_SLAVE_ID_FM_REG 0x02
 #define FM_GPIO	83
+#define BT_PCM_BCLK_MODE  0x88
+#define BT_PCM_DIN_MODE   0x89
+#define BT_PCM_DOUT_MODE  0x8A
+#define BT_PCM_SYNC_MODE  0x8B
+#define FM_I2S_SD_MODE    0x8E
+#define FM_I2S_WS_MODE    0x8F
+#define FM_I2S_SCK_MODE   0x90
+#define I2C_PIN_CTL       0x15
+#define I2C_NORMAL        0x40
 
 enum {
 	GPIO_HOST_VBUS_EN	= 107,
@@ -79,6 +88,57 @@
 #define FPGA_MSM_CNTRL_REG2 0x90008010
 
 #if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
+static int switch_pcm_i2s_reg_mode(int mode)
+{
+	unsigned char reg = 0;
+	int rc = -1;
+	unsigned char set = I2C_PIN_CTL; /*SET PIN CTL mode*/
+	unsigned char unset = I2C_NORMAL; /* UNSET PIN CTL MODE*/
+	struct marimba config = { .mod_id =  SLAVE_ID_BAHAMA};
+
+	if (mode == 0) {
+		/* as we need to switch path to FM we need to move
+		 BT AUX PCM lines to PIN CONTROL mode then move
+		 FM to normal mode.*/
+		for (reg = BT_PCM_BCLK_MODE; reg <= BT_PCM_SYNC_MODE; reg++) {
+			rc = marimba_write(&config, reg, &set, 1);
+			if (rc < 0) {
+				pr_err("pcm pinctl failed = %d", rc);
+				goto err_all;
+			}
+		}
+		for (reg = FM_I2S_SD_MODE; reg <= FM_I2S_SCK_MODE; reg++) {
+			rc = marimba_write(&config, reg, &unset, 1);
+			if (rc < 0) {
+				pr_err("i2s normal failed = %d", rc);
+				goto err_all;
+			}
+		}
+	} else {
+		/* as we need to switch path to AUXPCM we need to move
+		 FM I2S lines to PIN CONTROL mode then move
+		 BT AUX_PCM to normal mode.*/
+		for (reg = FM_I2S_SD_MODE; reg <= FM_I2S_SCK_MODE; reg++) {
+			rc = marimba_write(&config, reg, &set, 1);
+			if (rc < 0) {
+				pr_err("i2s pinctl failed = %d", rc);
+				goto err_all;
+			}
+		}
+		for (reg = BT_PCM_BCLK_MODE; reg <= BT_PCM_SYNC_MODE; reg++) {
+			rc = marimba_write(&config, reg, &unset, 1);
+			if (rc < 0) {
+				pr_err("pcm normal failed = %d", rc);
+				goto err_all;
+			}
+		}
+	}
+
+	return 0;
+
+err_all:
+	return rc;
+}
 static void config_pcm_i2s_mode(int mode)
 {
 	void __iomem *cfg_ptr;
@@ -174,6 +234,12 @@
 		if (machine_is_msm7627a_qrd1())
 			config_pcm_i2s_mode(0);
 		pr_err("%s mode = FM_I2S_ON", __func__);
+
+		rc = switch_pcm_i2s_reg_mode(0);
+		if (rc) {
+			pr_err("switch mode failed");
+			return rc;
+		}
 		for (pin = 0; pin < ARRAY_SIZE(fm_i2s_config_power_on);
 			pin++) {
 				rc = gpio_tlmm_config(
@@ -185,6 +251,11 @@
 			}
 	} else if (mode == FM_I2S_OFF) {
 		pr_err("%s mode = FM_I2S_OFF", __func__);
+		rc = switch_pcm_i2s_reg_mode(1);
+		if (rc) {
+			pr_err("switch mode failed");
+			return rc;
+		}
 		for (pin = 0; pin < ARRAY_SIZE(fm_i2s_config_power_off);
 			pin++) {
 				rc = gpio_tlmm_config(
@@ -205,6 +276,11 @@
 		if (machine_is_msm7627a_qrd1())
 			config_pcm_i2s_mode(1);
 		pr_err("%s mode =BT_PCM_ON", __func__);
+		rc = switch_pcm_i2s_reg_mode(1);
+		if (rc) {
+			pr_err("switch mode failed");
+			return rc;
+		}
 		for (pin = 0; pin < ARRAY_SIZE(bt_config_pcm_on);
 			pin++) {
 				rc = gpio_tlmm_config(bt_config_pcm_on[pin],
@@ -214,6 +290,11 @@
 			}
 	} else if (mode == BT_PCM_OFF) {
 		pr_err("%s mode =BT_PCM_OFF", __func__);
+		rc = switch_pcm_i2s_reg_mode(0);
+		if (rc) {
+			pr_err("switch mode failed");
+			return rc;
+		}
 		for (pin = 0; pin < ARRAY_SIZE(bt_config_pcm_off);
 			pin++) {
 				rc = gpio_tlmm_config(bt_config_pcm_off[pin],
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 8c251ba..172e124 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -2090,7 +2090,7 @@
 	},
 };
 
-static struct msm_bus_vectors grp2d0_max_vectors[] = {
+static struct msm_bus_vectors grp2d0_nominal_vectors[] = {
 	{
 		.src = MSM_BUS_MASTER_GRAPHICS_2D_CORE0,
 		.dst = MSM_BUS_SLAVE_EBI_CH0,
@@ -2099,12 +2099,25 @@
 	},
 };
 
+static struct msm_bus_vectors grp2d0_max_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_GRAPHICS_2D_CORE0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = KGSL_CONVERT_TO_MBPS(2048),
+	},
+};
+
 static struct msm_bus_paths grp2d0_bus_scale_usecases[] = {
 	{
 		ARRAY_SIZE(grp2d0_init_vectors),
 		grp2d0_init_vectors,
 	},
 	{
+		ARRAY_SIZE(grp2d0_nominal_vectors),
+		grp2d0_nominal_vectors,
+	},
+	{
 		ARRAY_SIZE(grp2d0_max_vectors),
 		grp2d0_max_vectors,
 	},
@@ -2125,7 +2138,7 @@
 	},
 };
 
-static struct msm_bus_vectors grp2d1_max_vectors[] = {
+static struct msm_bus_vectors grp2d1_nominal_vectors[] = {
 	{
 		.src = MSM_BUS_MASTER_GRAPHICS_2D_CORE1,
 		.dst = MSM_BUS_SLAVE_EBI_CH0,
@@ -2134,12 +2147,25 @@
 	},
 };
 
+static struct msm_bus_vectors grp2d1_max_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_GRAPHICS_2D_CORE1,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = KGSL_CONVERT_TO_MBPS(2048),
+	},
+};
+
 static struct msm_bus_paths grp2d1_bus_scale_usecases[] = {
 	{
 		ARRAY_SIZE(grp2d1_init_vectors),
 		grp2d1_init_vectors,
 	},
 	{
+		ARRAY_SIZE(grp2d1_nominal_vectors),
+		grp2d1_nominal_vectors,
+	},
+	{
 		ARRAY_SIZE(grp2d1_max_vectors),
 		grp2d1_max_vectors,
 	},
@@ -2236,17 +2262,21 @@
 	.pwrlevel = {
 		{
 			.gpu_freq = 200000000,
+			.bus_freq = 2,
+		},
+		{
+			.gpu_freq = 96000000,
 			.bus_freq = 1,
 		},
 		{
-			.gpu_freq = 200000000,
+			.gpu_freq = 27000000,
 			.bus_freq = 0,
 		},
 	},
 	.init_level = 0,
-	.num_levels = 2,
+	.num_levels = 3,
 	.set_grp_async = NULL,
-	.idle_timeout = HZ/10,
+	.idle_timeout = HZ/5,
 	.nap_allowed = true,
 	.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE,
 #ifdef CONFIG_MSM_BUS_SCALING
@@ -2285,17 +2315,21 @@
 	.pwrlevel = {
 		{
 			.gpu_freq = 200000000,
+			.bus_freq = 2,
+		},
+		{
+			.gpu_freq = 96000000,
 			.bus_freq = 1,
 		},
 		{
-			.gpu_freq = 200000000,
+			.gpu_freq = 27000000,
 			.bus_freq = 0,
 		},
 	},
 	.init_level = 0,
-	.num_levels = 2,
+	.num_levels = 3,
 	.set_grp_async = NULL,
-	.idle_timeout = HZ/10,
+	.idle_timeout = HZ/5,
 	.nap_allowed = true,
 	.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE,
 #ifdef CONFIG_MSM_BUS_SCALING
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 06a389e..0cd1c5c 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -311,9 +311,14 @@
 	struct msm_bus_scale_pdata *mdp_bus_scale_table;
 #endif
 	int mdp_rev;
-	int (*writeback_offset)(void);
+	int mdp_writeback_memtype;
+	void *mdp_writeback_phys;    /* writeback physical addr */
+	int mdp_writeback_size_ov0;  /* overlay0 writeback size */
+	int mdp_writeback_size_ov1;  /* overlay1 writeback size */
 };
 
+
+
 struct lcdc_platform_data {
 	int (*lcdc_gpio_config)(int on);
 	int (*lcdc_power_save)(int);
diff --git a/arch/arm/mach-msm/include/mach/rpm-regulator-copper.h b/arch/arm/mach-msm/include/mach/rpm-regulator-copper.h
new file mode 100644
index 0000000..2006ad3
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/rpm-regulator-copper.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_INCLUDE_MACH_RPM_REGULATOR_COPPER_H
+#define __ARCH_ARM_MACH_MSM_INCLUDE_MACH_RPM_REGULATOR_COPPER_H
+
+/**
+ * enum rpm_vreg_id - RPM regulator ID numbers (both real and pin control)
+ */
+enum rpm_vreg_id_copper {
+	RPM_VREG_ID_PM8941_S1,
+	RPM_VREG_ID_PM8941_S2,
+	RPM_VREG_ID_PM8941_L12,
+	RPM_VREG_ID_PM8941_MAX,
+};
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/rpm-regulator.h b/arch/arm/mach-msm/include/mach/rpm-regulator.h
index f857ab8..1095078 100644
--- a/arch/arm/mach-msm/include/mach/rpm-regulator.h
+++ b/arch/arm/mach-msm/include/mach/rpm-regulator.h
@@ -20,6 +20,7 @@
 #include <mach/rpm-regulator-8660.h>
 #include <mach/rpm-regulator-8960.h>
 #include <mach/rpm-regulator-9615.h>
+#include <mach/rpm-regulator-copper.h>
 
 /**
  * enum rpm_vreg_version - supported RPM regulator versions
@@ -136,6 +137,7 @@
 	RPM_VREG_VOTER_COUNT,
 };
 
+#ifdef CONFIG_MSM_RPM_REGULATOR
 /**
  * rpm_vreg_set_voltage - vote for a min_uV value of specified regualtor
  * @vreg: ID for regulator
@@ -172,4 +174,25 @@
  */
 int rpm_vreg_set_frequency(int vreg_id, enum rpm_vreg_freq freq);
 
+#else
+
+/*
+ * These stubs exist to allow consumers of these APIs to compile and run
+ * in absence of a real RPM regulator driver. It is assumed that they are
+ * aware of the state of their regulators and have either set them
+ * correctly by some other means or don't care about their state at all.
+ */
+static inline int rpm_vreg_set_voltage(int vreg_id, enum rpm_vreg_voter voter,
+				       int min_uV, int max_uV, int sleep_also)
+{
+	return 0;
+}
+
+static inline int rpm_vreg_set_frequency(int vreg_id, enum rpm_vreg_freq freq)
+{
+	return 0;
+}
+
+#endif /* CONFIG_MSM_RPM_REGULATOR */
+
 #endif
diff --git a/arch/arm/mach-msm/mdm.c b/arch/arm/mach-msm/mdm.c
index 01cc48a..cbdc92a 100644
--- a/arch/arm/mach-msm/mdm.c
+++ b/arch/arm/mach-msm/mdm.c
@@ -29,9 +29,9 @@
 #include <linux/completion.h>
 #include <linux/workqueue.h>
 #include <linux/clk.h>
-#include <linux/mfd/pmic8058.h>
 #include <asm/mach-types.h>
 #include <asm/uaccess.h>
+#include <linux/mfd/pm8xxx/misc.h>
 #include <mach/mdm.h>
 #include <mach/restart.h>
 #include <mach/subsystem_notif.h>
@@ -120,7 +120,7 @@
 	CHARM_DBG("%s: setting AP2MDM_ERRFATAL high for a non graceful reset\n",
 			 __func__);
 	if (get_restart_level() == RESET_SOC)
-		pm8058_stay_on();
+		pm8xxx_stay_on();
 
 	charm_disable_irqs();
 	gpio_set_value(AP2MDM_ERRFATAL, 1);
@@ -238,7 +238,7 @@
 {
 	pr_info("Reseting the charm due to an errfatal\n");
 	if (get_restart_level() == RESET_SOC)
-		pm8058_stay_on();
+		pm8xxx_stay_on();
 	subsystem_restart("external_modem");
 }
 
diff --git a/arch/arm/mach-msm/memory.c b/arch/arm/mach-msm/memory.c
index 33db3fa..46695c4 100644
--- a/arch/arm/mach-msm/memory.c
+++ b/arch/arm/mach-msm/memory.c
@@ -37,6 +37,7 @@
 #include <mach/msm_iomap.h>
 #include <mach/socinfo.h>
 #include <../../mm/mm.h>
+#include <linux/fmem.h>
 
 void *strongly_ordered_page;
 char strongly_ordered_mem[PAGE_SIZE*2-4];
@@ -439,3 +440,13 @@
 	asm("mrc p15, 0, %0, c2, c0, 0\n"
 		: "=r" (msm_ttbr0));
 }
+
+int request_fmem_c_region(void *unused)
+{
+	return fmem_set_state(FMEM_C_STATE);
+}
+
+int release_fmem_c_region(void *unused)
+{
+	return fmem_set_state(FMEM_T_STATE);
+}
diff --git a/arch/arm/mach-msm/msm_rq_stats.c b/arch/arm/mach-msm/msm_rq_stats.c
index da7fb51..492612f 100644
--- a/arch/arm/mach-msm/msm_rq_stats.c
+++ b/arch/arm/mach-msm/msm_rq_stats.c
@@ -95,10 +95,7 @@
 static ssize_t show_def_timer_ms(struct kobject *kobj,
 		struct kobj_attribute *attr, char *buf)
 {
-	int64_t diff_ms;
-	diff_ms = ktime_to_ns(ktime_get()) - rq_info.def_start_time;
-	do_div(diff_ms, 1000 * 1000);
-	return snprintf(buf, MAX_LONG_SIZE, "%lld\n", diff_ms);
+	return snprintf(buf, MAX_LONG_SIZE, "%u\n", rq_info.def_interval);
 }
 
 static ssize_t store_def_timer_ms(struct kobject *kobj,
diff --git a/arch/arm/mach-msm/pil-q6v4.c b/arch/arm/mach-msm/pil-q6v4.c
index 24c479c..d8ebab5 100644
--- a/arch/arm/mach-msm/pil-q6v4.c
+++ b/arch/arm/mach-msm/pil-q6v4.c
@@ -28,7 +28,7 @@
 #include "pil-q6v4.h"
 #include "scm-pas.h"
 
-#define PROXY_VOTE_TIMEOUT	10000
+#define PROXY_VOTE_TIMEOUT	40000
 
 #define QDSP6SS_RST_EVB		0x0
 #define QDSP6SS_RESET		0x04
diff --git a/arch/arm/mach-msm/sdio_tty.c b/arch/arm/mach-msm/sdio_tty.c
index e249d06..2aaa41e 100644
--- a/arch/arm/mach-msm/sdio_tty.c
+++ b/arch/arm/mach-msm/sdio_tty.c
@@ -18,6 +18,7 @@
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/module.h>
+#include <linux/debugfs.h>
 #include <mach/sdio_al.h>
 
 #define INPUT_SPEED			4800
@@ -77,10 +78,17 @@
 	enum sdio_tty_state sdio_tty_state;
 	int is_sdio_open;
 	int tty_open_count;
+	int total_rx;
+	int total_tx;
 };
 
 static struct sdio_tty *sdio_tty[MAX_SDIO_TTY_DEVS];
 
+#ifdef CONFIG_DEBUG_FS
+struct dentry *sdio_tty_debug_root;
+struct dentry *sdio_tty_debug_info;
+#endif
+
 #define DEBUG_MSG(sdio_tty_drv, x...) if (sdio_tty_drv->debug_msg_on) pr_info(x)
 
 /*
@@ -183,10 +191,11 @@
 		}
 
 		tty_flip_buffer_push(sdio_tty_drv->tty_str);
+		sdio_tty_drv->total_rx += read_avail;
 
-		DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME
-				": %s: End of read %d bytes for dev %s",
-				__func__, read_avail,
+		DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: Rx: %d, "
+				"Total Rx = %d bytes for dev %s", __func__,
+				read_avail, sdio_tty_drv->total_rx,
 				sdio_tty_drv->tty_dev_name);
 	}
 }
@@ -302,10 +311,11 @@
 		return 0;
 	}
 
-	DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: End of function, "
-			"dev=%s, len=%d bytes\n", __func__,
-			sdio_tty_drv->tty_dev_name, len);
+	sdio_tty_drv->total_tx += len;
 
+	DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: Tx: %d, "
+			"Total Tx = %d for dev %s", __func__, len,
+			sdio_tty_drv->total_tx, sdio_tty_drv->tty_dev_name);
 	return len;
 }
 
@@ -407,8 +417,8 @@
 			return ret;
 		}
 
-		pr_info(SDIO_TTY_MODULE_NAME ": %s: SDIO_TTY channel(%s) opened "
-			"\n", __func__, sdio_tty_drv->sdio_ch_name);
+		pr_info(SDIO_TTY_MODULE_NAME ": %s: SDIO_TTY channel(%s) "
+			"opened\n", __func__, sdio_tty_drv->sdio_ch_name);
 
 		sdio_tty_drv->is_sdio_open = 1;
 	} else {
@@ -748,6 +758,39 @@
 	},
 };
 
+#ifdef CONFIG_DEBUG_FS
+void sdio_tty_print_info(void)
+{
+	int i = 0;
+
+	for (i = 0; i < MAX_SDIO_TTY_DEVS; i++) {
+		if (sdio_tty[i] == NULL)
+			continue;
+		pr_info(SDIO_TTY_MODULE_NAME ": %s: Total Rx=%d, Tx = %d "
+			"for dev %s", __func__, sdio_tty[i]->total_rx,
+			sdio_tty[i]->total_tx, sdio_tty[i]->tty_dev_name);
+	}
+}
+
+static int tty_debug_info_open(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+static ssize_t tty_debug_info_write(struct file *file,
+		const char __user *buf, size_t count, loff_t *ppos)
+{
+	sdio_tty_print_info();
+	return count;
+}
+
+const struct file_operations tty_debug_info_ops = {
+	.open = tty_debug_info_open,
+	.write = tty_debug_info_write,
+};
+#endif
+
 /*
  *  Module Init.
  *
@@ -763,6 +806,19 @@
 		pr_err(SDIO_TTY_MODULE_NAME ": %s: platform_driver_register "
 					    "failed", __func__);
 	}
+#ifdef CONFIG_DEBUG_FS
+	else {
+		sdio_tty_debug_root = debugfs_create_dir("sdio_tty", NULL);
+		if (sdio_tty_debug_root) {
+			sdio_tty_debug_info = debugfs_create_file(
+							"sdio_tty_debug",
+							S_IRUGO | S_IWUGO,
+							sdio_tty_debug_root,
+							NULL,
+							&tty_debug_info_ops);
+		}
+	}
+#endif
 	return ret;
 };
 
@@ -774,6 +830,10 @@
  */
 static void __exit sdio_tty_exit(void)
 {
+#ifdef CONFIG_DEBUG_FS
+	debugfs_remove(sdio_tty_debug_info);
+	debugfs_remove(sdio_tty_debug_root);
+#endif
 	platform_driver_unregister(&sdio_tty_pdrv);
 }
 
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index 87b6d3f..0c2d4f7 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -31,6 +31,7 @@
 	HW_PLATFORM_FLUID   = 3,
 	HW_PLATFORM_SVLTE_FFA	= 4,
 	HW_PLATFORM_SVLTE_SURF	= 5,
+	HW_PLATFORM_MTP  = 8,
 	HW_PLATFORM_LIQUID  = 9,
 	/* Dragonboard platform id is assigned as 10 in CDT */
 	HW_PLATFORM_DRAGON	= 10,
@@ -42,9 +43,10 @@
 	[HW_PLATFORM_SURF] = "Surf",
 	[HW_PLATFORM_FFA] = "FFA",
 	[HW_PLATFORM_FLUID] = "Fluid",
-	[HW_PLATFORM_LIQUID] = "Liquid",
 	[HW_PLATFORM_SVLTE_FFA] = "SVLTE_FFA",
 	[HW_PLATFORM_SVLTE_SURF] = "SLVTE_SURF",
+	[HW_PLATFORM_MTP] = "MTP",
+	[HW_PLATFORM_LIQUID] = "Liquid",
 	[HW_PLATFORM_DRAGON] = "Dragon"
 };
 
diff --git a/drivers/base/genlock.c b/drivers/base/genlock.c
index 41bbd3a..dcc1d28 100644
--- a/drivers/base/genlock.c
+++ b/drivers/base/genlock.c
@@ -48,11 +48,28 @@
 				     taken */
 };
 
+/*
+ * Create a spinlock to protect against a race condition when a lock gets
+ * released while another process tries to attach it
+ */
+
+static DEFINE_SPINLOCK(genlock_file_lock);
+
 static void genlock_destroy(struct kref *kref)
 {
 	struct genlock *lock = container_of(kref, struct genlock,
 			refcount);
 
+	/*
+	 * Clear the private data for the file descriptor in case the fd is
+	 * still active after the lock gets released
+	 */
+
+	spin_lock(&genlock_file_lock);
+	if (lock->file)
+		lock->file->private_data = NULL;
+	spin_unlock(&genlock_file_lock);
+
 	kfree(lock);
 }
 
@@ -63,6 +80,15 @@
 
 static int genlock_release(struct inode *inodep, struct file *file)
 {
+	struct genlock *lock = file->private_data;
+	/*
+	 * Clear the refrence back to this file structure to avoid
+	 * somehow reusing the lock after the file has been destroyed
+	 */
+
+	if (lock)
+		lock->file = NULL;
+
 	return 0;
 }
 
@@ -119,7 +145,7 @@
 {
 	int ret;
 
-	if (!lock->file)
+	if (lock->file == NULL)
 		return -EINVAL;
 
 	ret = get_unused_fd_flags(0);
@@ -149,7 +175,14 @@
 	if (file == NULL)
 		return ERR_PTR(-EBADF);
 
+	/*
+	 * take a spinlock to avoid a race condition if the lock is
+	 * released and then attached
+	 */
+
+	spin_lock(&genlock_file_lock);
 	lock = file->private_data;
+	spin_unlock(&genlock_file_lock);
 
 	fput(file);
 
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index d2e4e4b..a8a0e59 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -194,7 +194,7 @@
 
 	if (device->requested_state == KGSL_STATE_NONE) {
 		if (device->pwrctrl.nap_allowed == true) {
-			device->requested_state = KGSL_STATE_NAP;
+			kgsl_pwrctrl_request_state(device, KGSL_STATE_NAP);
 			queue_work(device->work_queue, &device->idle_check_ws);
 		} else if (device->pwrscale.policy != NULL) {
 			queue_work(device->work_queue, &device->idle_check_ws);
@@ -495,8 +495,7 @@
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 	int init_reftimestamp = 0x7fffffff;
 
-	device->state = KGSL_STATE_INIT;
-	device->requested_state = KGSL_STATE_NONE;
+	kgsl_pwrctrl_set_state(device, KGSL_STATE_INIT);
 
 	/* Power up the device */
 	kgsl_pwrctrl_enable(device);
@@ -716,33 +715,27 @@
 static int
 adreno_dump_and_recover(struct kgsl_device *device)
 {
-	static int recovery;
 	int result = -ETIMEDOUT;
 
 	if (device->state == KGSL_STATE_HUNG)
 		goto done;
-	if (device->state == KGSL_STATE_DUMP_AND_RECOVER && !recovery) {
+	if (device->state == KGSL_STATE_DUMP_AND_RECOVER) {
 		mutex_unlock(&device->mutex);
 		wait_for_completion(&device->recovery_gate);
 		mutex_lock(&device->mutex);
-		if (!(device->state & KGSL_STATE_HUNG))
-			/* recovery success */
+		if (device->state != KGSL_STATE_HUNG)
 			result = 0;
 	} else {
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_DUMP_AND_RECOVER);
 		INIT_COMPLETION(device->recovery_gate);
 		/* Detected a hang - trigger an automatic dump */
 		adreno_postmortem_dump(device, 0);
-		if (!recovery) {
-			recovery = 1;
-			result = adreno_recover_hang(device);
-			if (result)
-				device->state = KGSL_STATE_HUNG;
-			recovery = 0;
-			complete_all(&device->recovery_gate);
-		} else
-			KGSL_DRV_ERR(device,
-				"Cannot recover from another hang while "
-				"recovering from a hang\n");
+		result = adreno_recover_hang(device);
+		if (result)
+			kgsl_pwrctrl_set_state(device, KGSL_STATE_HUNG);
+		else
+			kgsl_pwrctrl_set_state(device, KGSL_STATE_ACTIVE);
+		complete_all(&device->recovery_gate);
 	}
 done:
 	return result;
diff --git a/drivers/gpu/msm/adreno_postmortem.c b/drivers/gpu/msm/adreno_postmortem.c
index 9e49e6a..aafef21 100644
--- a/drivers/gpu/msm/adreno_postmortem.c
+++ b/drivers/gpu/msm/adreno_postmortem.c
@@ -21,6 +21,7 @@
 #include "adreno_postmortem.h"
 #include "adreno_debugfs.h"
 #include "kgsl_cffdump.h"
+#include "kgsl_pwrctrl.h"
 
 #include "a2xx_reg.h"
 
@@ -828,11 +829,9 @@
 
 	/* Disable the idle timer so we don't get interrupted */
 	del_timer_sync(&device->idle_timer);
-
 	mutex_unlock(&device->mutex);
 	flush_workqueue(device->work_queue);
 	mutex_lock(&device->mutex);
-	adreno_dump(device);
 
 	/* Turn off napping to make sure we have the clocks full
 	   attention through the following process */
@@ -845,15 +844,7 @@
 	/* Disable the irq */
 	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
 
-	/* If this is not a manual trigger, then set up the
-	   state to try to recover */
-
-	if (!manual) {
-		device->state = KGSL_STATE_DUMP_AND_RECOVER;
-		KGSL_PWR_WARN(device,
-				"state -> DUMP_AND_RECOVER, device %d\n",
-				device->id);
-	}
+	adreno_dump(device);
 
 	/* Restore nap mode */
 	device->pwrctrl.nap_allowed = saved_nap;
@@ -867,7 +858,7 @@
 		kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON);
 
 		/* try to go into a sleep mode until the next event */
-		device->requested_state = KGSL_STATE_SLEEP;
+		kgsl_pwrctrl_request_state(device, KGSL_STATE_SLEEP);
 		kgsl_pwrctrl_sleep(device);
 	}
 
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index a098200..7ace67a 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -393,7 +393,6 @@
 	if (rb->flags & KGSL_FLAGS_STARTED) {
 		/* ME_HALT */
 		adreno_regwrite(rb->device, REG_CP_ME_CNTL, 0x10000000);
-
 		rb->flags &= ~KGSL_FLAGS_STARTED;
 	}
 }
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 7a42dcd..3207040 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -302,7 +302,7 @@
 	if (device->pwrctrl.nap_allowed == true &&
 	    device->state == KGSL_STATE_ACTIVE &&
 		device->requested_state == KGSL_STATE_NONE) {
-		device->requested_state = KGSL_STATE_NAP;
+		kgsl_pwrctrl_request_state(device, KGSL_STATE_NAP);
 		if (kgsl_pwrctrl_sleep(device) != 0)
 			mod_timer(&device->idle_timer,
 				  jiffies +
@@ -395,7 +395,7 @@
 	device->pwrctrl.nap_allowed = false;
 	policy_saved = device->pwrscale.policy;
 	device->pwrscale.policy = NULL;
-	device->requested_state = KGSL_STATE_SUSPEND;
+	kgsl_pwrctrl_request_state(device, KGSL_STATE_SUSPEND);
 	/* Make sure no user process is waiting for a timestamp *
 	 * before supending */
 	if (device->active_cnt != 0) {
@@ -417,22 +417,18 @@
 			INIT_COMPLETION(device->hwaccess_gate);
 			device->ftbl->suspend_context(device);
 			device->ftbl->stop(device);
-			device->state = KGSL_STATE_SUSPEND;
-			KGSL_PWR_WARN(device, "state -> SUSPEND, device %d\n",
-				device->id);
+			kgsl_pwrctrl_set_state(device, KGSL_STATE_SUSPEND);
 			break;
 		case KGSL_STATE_SLUMBER:
 			INIT_COMPLETION(device->hwaccess_gate);
-			device->state = KGSL_STATE_SUSPEND;
-			KGSL_PWR_WARN(device, "state -> SUSPEND, device %d\n",
-				device->id);
+			kgsl_pwrctrl_set_state(device, KGSL_STATE_SUSPEND);
 			break;
 		default:
 			KGSL_PWR_ERR(device, "suspend fail, device %d\n",
 					device->id);
 			goto end;
 	}
-	device->requested_state = KGSL_STATE_NONE;
+	kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
 	device->pwrctrl.nap_allowed = nap_allowed_saved;
 	device->pwrscale.policy = policy_saved;
 	status = 0;
@@ -453,14 +449,11 @@
 	KGSL_PWR_WARN(device, "resume start\n");
 	mutex_lock(&device->mutex);
 	if (device->state == KGSL_STATE_SUSPEND) {
-		device->state = KGSL_STATE_SLUMBER;
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_SLUMBER);
 		status = 0;
-		KGSL_PWR_WARN(device,
-				"state -> SLUMBER, device %d\n",
-				device->id);
 		complete_all(&device->hwaccess_gate);
 	}
-	device->requested_state = KGSL_STATE_NONE;
+	kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
 
 	mutex_unlock(&device->mutex);
 	KGSL_PWR_WARN(device, "resume end\n");
@@ -505,7 +498,7 @@
 					struct kgsl_device, display_off);
 	KGSL_PWR_WARN(device, "early suspend start\n");
 	mutex_lock(&device->mutex);
-	device->requested_state = KGSL_STATE_SLUMBER;
+	kgsl_pwrctrl_request_state(device, KGSL_STATE_SLUMBER);
 	kgsl_pwrctrl_sleep(device);
 	mutex_unlock(&device->mutex);
 	KGSL_PWR_WARN(device, "early suspend end\n");
@@ -535,6 +528,7 @@
 	mutex_lock(&device->mutex);
 	kgsl_pwrctrl_wake(device);
 	device->pwrctrl.restore_slumber = 0;
+	kgsl_pwrctrl_pwrlevel_change(device, KGSL_PWRLEVEL_TURBO);
 	mutex_unlock(&device->mutex);
 	kgsl_check_idle(device);
 	KGSL_PWR_WARN(device, "late resume end\n");
@@ -651,8 +645,7 @@
 	device->open_count--;
 	if (device->open_count == 0) {
 		result = device->ftbl->stop(device);
-		device->state = KGSL_STATE_INIT;
-		KGSL_PWR_WARN(device, "state -> INIT, device %d\n", device->id);
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_INIT);
 	}
 	/* clean up any to-be-freed entries that belong to this
 	 * process and this device
@@ -720,9 +713,7 @@
 			mutex_unlock(&device->mutex);
 			goto err_putprocess;
 		}
-		device->state = KGSL_STATE_ACTIVE;
-		KGSL_PWR_WARN(device,
-				"state -> ACTIVE, device %d\n", minor);
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_ACTIVE);
 	}
 	device->open_count++;
 	mutex_unlock(&device->mutex);
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 3ef11ce..b301743 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -175,6 +175,7 @@
 	struct kobject pwrscale_kobj;
 	struct work_struct ts_expired_ws;
 	struct list_head events;
+	s64 on_time;
 };
 
 struct kgsl_context {
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index dbbe4d5..89b4df1 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -599,6 +599,9 @@
 {
 	struct kgsl_device *device = container_of(work, struct kgsl_device,
 							idle_check_ws);
+	WARN_ON(device == NULL);
+	if (device == NULL)
+		return;
 
 	mutex_lock(&device->mutex);
 	if (device->state & (KGSL_STATE_ACTIVE | KGSL_STATE_NAP)) {
@@ -620,7 +623,7 @@
 		}
 	} else if (device->state & (KGSL_STATE_HUNG |
 					KGSL_STATE_DUMP_AND_RECOVER)) {
-		device->requested_state = KGSL_STATE_NONE;
+		kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
 	}
 
 	mutex_unlock(&device->mutex);
@@ -632,7 +635,7 @@
 
 	KGSL_PWR_INFO(device, "idle timer expired device %d\n", device->id);
 	if (device->requested_state != KGSL_STATE_SUSPEND) {
-		device->requested_state = KGSL_STATE_SLEEP;
+		kgsl_pwrctrl_request_state(device, KGSL_STATE_SLEEP);
 		/* Have work run in a non-interrupt context. */
 		queue_work(device->work_queue, &device->idle_check_ws);
 	}
@@ -663,155 +666,182 @@
 }
 
 static int
-_slumber(struct kgsl_device *device)
+_nap(struct kgsl_device *device)
 {
-	int status = -EINVAL;
-	if (!device)
-		return -EINVAL;
-	KGSL_PWR_WARN(device, "Slumber start\n");
-
-	device->requested_state = KGSL_STATE_SLUMBER;
-	del_timer(&device->idle_timer);
 	switch (device->state) {
 	case KGSL_STATE_ACTIVE:
-		/* Wait for the device to become idle */
-		device->ftbl->idle(device, KGSL_TIMEOUT_DEFAULT);
+		if (!device->ftbl->isidle(device)) {
+			kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
+			return -EBUSY;
+		}
+		kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
+		kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF);
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_NAP);
+		if (device->idle_wakelock.name)
+			wake_unlock(&device->idle_wakelock);
 	case KGSL_STATE_NAP:
 	case KGSL_STATE_SLEEP:
-		device->ftbl->suspend_context(device);
-		device->ftbl->stop(device);
-		device->state = KGSL_STATE_SLUMBER;
-		device->pwrctrl.restore_slumber = 1;
-		KGSL_PWR_WARN(device, "state -> SLUMBER, device %d\n",
-				device->id);
+	case KGSL_STATE_SLUMBER:
 		break;
 	default:
+		kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
 		break;
 	}
-	status = 0;
-	/* Don't set requested state to NONE
-	It's done in kgsl_pwrctrl_sleep*/
-	KGSL_PWR_WARN(device, "Done going to slumber\n");
-	return status;
+	return 0;
+}
+
+static void
+_sleep_accounting(struct kgsl_device *device)
+{
+	kgsl_pwrctrl_busy_time(device, false);
+	device->pwrctrl.busy.start.tv_sec = 0;
+	device->pwrctrl.time = 0;
+	kgsl_pwrscale_sleep(device);
+}
+
+static int
+_sleep(struct kgsl_device *device)
+{
+	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
+	switch (device->state) {
+	case KGSL_STATE_ACTIVE:
+		if (!device->ftbl->isidle(device)) {
+			kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
+			return -EBUSY;
+		}
+		/* fall through */
+	case KGSL_STATE_NAP:
+		kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
+		kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_OFF);
+		if (pwr->pwrlevels[0].gpu_freq > 0)
+			clk_set_rate(pwr->grp_clks[0],
+				pwr->pwrlevels[pwr->num_pwrlevels - 1].
+				gpu_freq);
+		_sleep_accounting(device);
+		kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF);
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_SLEEP);
+		if (device->idle_wakelock.name)
+			wake_unlock(&device->idle_wakelock);
+		break;
+	case KGSL_STATE_SLEEP:
+	case KGSL_STATE_SLUMBER:
+		break;
+	default:
+		KGSL_PWR_WARN(device, "unhandled state %x\n",
+				device->state);
+		break;
+	}
+	return 0;
+}
+
+static int
+_slumber(struct kgsl_device *device)
+{
+	switch (device->state) {
+	case KGSL_STATE_ACTIVE:
+		if (!device->ftbl->isidle(device)) {
+			kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
+			device->pwrctrl.restore_slumber = true;
+			return -EBUSY;
+		}
+		/* fall through */
+	case KGSL_STATE_NAP:
+	case KGSL_STATE_SLEEP:
+		del_timer_sync(&device->idle_timer);
+		kgsl_pwrctrl_pwrlevel_change(device, KGSL_PWRLEVEL_NOMINAL);
+		device->ftbl->suspend_context(device);
+		device->ftbl->stop(device);
+		device->pwrctrl.restore_slumber = true;
+		_sleep_accounting(device);
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_SLUMBER);
+		if (device->idle_wakelock.name)
+			wake_unlock(&device->idle_wakelock);
+		break;
+	case KGSL_STATE_SLUMBER:
+		break;
+	default:
+		KGSL_PWR_WARN(device, "unhandled state %x\n",
+				device->state);
+		break;
+	}
+	return 0;
 }
 
 /******************************************************************/
 /* Caller must hold the device mutex. */
 int kgsl_pwrctrl_sleep(struct kgsl_device *device)
 {
-	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
+	int status = 0;
 	KGSL_PWR_INFO(device, "sleep device %d\n", device->id);
 
 	/* Work through the legal state transitions */
-	if ((device->requested_state == KGSL_STATE_NAP)) {
+	switch (device->requested_state) {
+	case KGSL_STATE_NAP:
 		if (device->pwrctrl.restore_slumber) {
-			device->requested_state = KGSL_STATE_NONE;
-			return 0;
-		} else if (device->ftbl->isidle(device))
-			goto nap;
-	} else if (device->requested_state == KGSL_STATE_SLEEP) {
-		if (device->state == KGSL_STATE_NAP ||
-			device->ftbl->isidle(device)) {
-			if (!device->pwrctrl.restore_slumber)
-				goto sleep;
-			else
-				goto slumber;
-			}
-	} else if (device->requested_state == KGSL_STATE_SLUMBER) {
-		if (device->state == KGSL_STATE_INIT)
-			return 0;
-		if (device->ftbl->isidle(device))
-			goto slumber;
+			kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
+			break;
+		}
+		status = _nap(device);
+		break;
+	case KGSL_STATE_SLEEP:
+		if (device->pwrctrl.restore_slumber)
+			status = _slumber(device);
 		else
-			device->pwrctrl.restore_slumber = true;
+			status = _sleep(device);
+		break;
+	case KGSL_STATE_SLUMBER:
+		status = _slumber(device);
+		break;
+	default:
+		KGSL_PWR_INFO(device, "bad state request 0x%x\n",
+				device->requested_state);
+		kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
+		status = -EINVAL;
+		break;
 	}
-
-	device->requested_state = KGSL_STATE_NONE;
-	return -EBUSY;
-
-
-slumber:
-	_slumber(device);
-
-sleep:
-	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
-	kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_OFF);
-	if (pwr->pwrlevels[0].gpu_freq > 0)
-		clk_set_rate(pwr->grp_clks[0],
-				pwr->pwrlevels[pwr->num_pwrlevels - 1].
-				gpu_freq);
-	kgsl_pwrctrl_busy_time(device, false);
-	pwr->busy.start.tv_sec = 0;
-	device->pwrctrl.time = 0;
-
-	kgsl_pwrscale_sleep(device);
-	goto clk_off;
-
-nap:
-	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
-clk_off:
-	kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF);
-
-	device->state = device->requested_state;
-	device->requested_state = KGSL_STATE_NONE;
-	if (device->idle_wakelock.name)
-		wake_unlock(&device->idle_wakelock);
-	KGSL_PWR_WARN(device, "state -> NAP/SLEEP(%d), device %d\n",
-				  device->state, device->id);
-
-	return 0;
-}
-EXPORT_SYMBOL(kgsl_pwrctrl_sleep);
-
-static int
-_wake_from_slumber(struct kgsl_device *device)
-{
-	int status = -EINVAL;
-	if (!device)
-		return -EINVAL;
-
-	KGSL_PWR_WARN(device, "wake from slumber start\n");
-
-	device->requested_state = KGSL_STATE_ACTIVE;
-	kgsl_pwrctrl_pwrlevel_change(device, KGSL_PWRLEVEL_NOMINAL);
-	status = device->ftbl->start(device, 0);
-	device->requested_state = KGSL_STATE_NONE;
-
-	KGSL_PWR_WARN(device, "Done waking from slumber\n");
 	return status;
 }
+EXPORT_SYMBOL(kgsl_pwrctrl_sleep);
 
 /******************************************************************/
 /* Caller must hold the device mutex. */
 void kgsl_pwrctrl_wake(struct kgsl_device *device)
 {
-	if (device->state & (KGSL_STATE_SUSPEND | KGSL_STATE_INIT))
-		return;
-
-	if (device->state == KGSL_STATE_SLUMBER)
-		_wake_from_slumber(device);
-
-	if (device->state != KGSL_STATE_NAP) {
+	int status;
+	kgsl_pwrctrl_request_state(device, KGSL_STATE_ACTIVE);
+	switch (device->state) {
+	case KGSL_STATE_SLUMBER:
+		status = device->ftbl->start(device, 0);
+		if (status) {
+			kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
+			KGSL_DRV_ERR(device, "start failed %d\n", status);
+			break;
+		}
+		/* fall through */
+	case KGSL_STATE_SLEEP:
 		kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_ON);
 		kgsl_pwrscale_wake(device);
-	}
-
-	/* Turn on the core clocks */
-	kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_ON);
-
-	/* Enable state before turning on irq */
-	device->state = KGSL_STATE_ACTIVE;
-	KGSL_PWR_WARN(device, "state -> ACTIVE, device %d\n", device->id);
-	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON);
-
-	/* Re-enable HW access */
-	mod_timer(&device->idle_timer,
+		/* fall through */
+	case KGSL_STATE_NAP:
+		/* Turn on the core clocks */
+		kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_ON);
+		/* Enable state before turning on irq */
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_ACTIVE);
+		kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON);
+		/* Re-enable HW access */
+		mod_timer(&device->idle_timer,
 				jiffies + device->pwrctrl.interval_timeout);
 
-	if (device->idle_wakelock.name)
-		wake_lock(&device->idle_wakelock);
-
-	KGSL_PWR_INFO(device, "wake return for device %d\n", device->id);
+		if (device->idle_wakelock.name)
+			wake_lock(&device->idle_wakelock);
+	case KGSL_STATE_ACTIVE:
+		break;
+	default:
+		KGSL_PWR_WARN(device, "unhandled state %x\n",
+				device->state);
+		kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
+		break;
+	}
 }
 EXPORT_SYMBOL(kgsl_pwrctrl_wake);
 
@@ -832,3 +862,19 @@
 	kgsl_pwrctrl_pwrrail(device, KGSL_PWRFLAGS_OFF);
 }
 EXPORT_SYMBOL(kgsl_pwrctrl_disable);
+
+void kgsl_pwrctrl_set_state(struct kgsl_device *device, unsigned int state)
+{
+	KGSL_PWR_WARN(device, "%x\n", state);
+	device->state = state;
+	device->requested_state = KGSL_STATE_NONE;
+}
+EXPORT_SYMBOL(kgsl_pwrctrl_set_state);
+
+void kgsl_pwrctrl_request_state(struct kgsl_device *device, unsigned int state)
+{
+	if (state != KGSL_STATE_NONE && state != device->requested_state)
+		KGSL_PWR_INFO(device, "%x\n", state);
+	device->requested_state = state;
+}
+EXPORT_SYMBOL(kgsl_pwrctrl_request_state);
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h
index 8b33fcd..8ec41be 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.h
+++ b/drivers/gpu/msm/kgsl_pwrctrl.h
@@ -77,4 +77,6 @@
 	return (clk != NULL) ? clk_get_rate(clk) : 0;
 }
 
+void kgsl_pwrctrl_set_state(struct kgsl_device *device, unsigned int state);
+void kgsl_pwrctrl_request_state(struct kgsl_device *device, unsigned int state);
 #endif /* __KGSL_PWRCTRL_H */
diff --git a/drivers/gpu/msm/kgsl_pwrscale_trustzone.c b/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
index f3e84e4..eeade17 100644
--- a/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
+++ b/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/io.h>
+#include <linux/spinlock.h>
 #include <mach/socinfo.h>
 #include <mach/scm.h>
 
@@ -29,6 +30,7 @@
 	unsigned int no_switch_cnt;
 	unsigned int skip_cnt;
 };
+spinlock_t tz_lock;
 
 #define SWITCH_OFF		200
 #define SWITCH_OFF_RESET_TH	40
@@ -38,13 +40,17 @@
 
 #ifdef CONFIG_MSM_SCM
 /* Trap into the TrustZone, and call funcs there. */
-static int __secure_tz_entry(u32 cmd, u32 val)
+static int __secure_tz_entry(u32 cmd, u32 val, u32 id)
 {
+	int ret;
+	spin_lock(&tz_lock);
 	__iowmb();
-	return scm_call_atomic1(SCM_SVC_IO, cmd, val);
+	ret = scm_call_atomic2(SCM_SVC_IO, cmd, val, id);
+	spin_unlock(&tz_lock);
+	return ret;
 }
 #else
-static int __secure_tz_entry(u32 cmd, u32 val)
+static int __secure_tz_entry(u32 cmd, u32 val, u32 id)
 {
 	return 0;
 }
@@ -117,7 +123,7 @@
 	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
 	struct tz_priv *priv = pwrscale->priv;
 	struct kgsl_power_stats stats;
-	int val;
+	int val, idle;
 
 	/* In "performance" mode the clock speed always stays
 	   the same */
@@ -145,19 +151,26 @@
 		priv->no_switch_cnt = 0;
 	}
 
-	val = __secure_tz_entry(TZ_UPDATE_ID,
-				stats.total_time - stats.busy_time);
+	idle = stats.total_time - stats.busy_time;
+	idle = (idle > 0) ? idle : 0;
+	val = __secure_tz_entry(TZ_UPDATE_ID, idle, device->id);
 	if (val)
 		kgsl_pwrctrl_pwrlevel_change(device,
 					     pwr->active_pwrlevel + val);
 }
 
+static void tz_busy(struct kgsl_device *device,
+	struct kgsl_pwrscale *pwrscale)
+{
+	device->on_time = ktime_to_us(ktime_get());
+}
+
 static void tz_sleep(struct kgsl_device *device,
 	struct kgsl_pwrscale *pwrscale)
 {
 	struct tz_priv *priv = pwrscale->priv;
 
-	__secure_tz_entry(TZ_RESET_ID, 0);
+	__secure_tz_entry(TZ_RESET_ID, 0, device->id);
 	priv->no_switch_cnt = 0;
 }
 
@@ -174,6 +187,7 @@
 		return -ENOMEM;
 
 	priv->governor = TZ_GOVERNOR_ONDEMAND;
+	spin_lock_init(&tz_lock);
 	kgsl_pwrscale_policy_add_files(device, pwrscale, &tz_attr_group);
 
 	return 0;
@@ -189,6 +203,7 @@
 struct kgsl_pwrscale_policy kgsl_pwrscale_policy_tz = {
 	.name = "trustzone",
 	.init = tz_init,
+	.busy = tz_busy,
 	.idle = tz_idle,
 	.sleep = tz_sleep,
 	.wake = tz_wake,
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index cf74e64..de7d1be 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -248,7 +248,7 @@
 
 	if ((device->pwrctrl.nap_allowed == true) &&
 		(device->requested_state == KGSL_STATE_NONE)) {
-		device->requested_state = KGSL_STATE_NAP;
+		kgsl_pwrctrl_request_state(device, KGSL_STATE_NAP);
 		queue_work(device->work_queue, &device->idle_check_ws);
 	}
 	mod_timer(&device->idle_timer,
@@ -460,6 +460,7 @@
 	z180_dev->ringbuffer.prevctx = context->id;
 
 	addcmd(&z180_dev->ringbuffer, index, cmd + ofs, cnt);
+	kgsl_pwrscale_busy(device);
 
 	/* Make sure the next ringbuffer entry has a marker */
 	addmarker(&z180_dev->ringbuffer, nextindex);
@@ -523,6 +524,7 @@
 		goto error_close_ringbuffer;
 
 	kgsl_pwrscale_init(device);
+	kgsl_pwrscale_attach_policy(device, Z180_DEFAULT_PWRSCALE_POLICY);
 
 	return status;
 
@@ -551,9 +553,7 @@
 {
 	int status = 0;
 
-	device->state = KGSL_STATE_INIT;
-	device->requested_state = KGSL_STATE_NONE;
-	KGSL_PWR_WARN(device, "state -> INIT, device %d\n", device->id);
+	kgsl_pwrctrl_set_state(device, KGSL_STATE_INIT);
 
 	kgsl_pwrctrl_enable(device);
 
@@ -834,8 +834,7 @@
 		status = 0;
 	else if (timeout == 0) {
 		status = -ETIMEDOUT;
-		device->state = KGSL_STATE_HUNG;
-		KGSL_PWR_WARN(device, "state -> HUNG, device %d\n", device->id);
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_HUNG);
 	} else
 		status = timeout;
 
@@ -861,17 +860,17 @@
 			    struct kgsl_power_stats *stats)
 {
 	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
+	s64 tmp = ktime_to_us(ktime_get());
 
 	if (pwr->time == 0) {
-		pwr->time = ktime_to_us(ktime_get());
+		pwr->time = tmp;
 		stats->total_time = 0;
 		stats->busy_time = 0;
 	} else {
-		s64 tmp;
-		tmp = ktime_to_us(ktime_get());
 		stats->total_time = tmp - pwr->time;
-		stats->busy_time = tmp - pwr->time;
 		pwr->time = tmp;
+		stats->busy_time = tmp - device->on_time;
+		device->on_time = tmp;
 	}
 }
 
diff --git a/drivers/gpu/msm/z180.h b/drivers/gpu/msm/z180.h
index 28b1cc6..e5c5ef3 100644
--- a/drivers/gpu/msm/z180.h
+++ b/drivers/gpu/msm/z180.h
@@ -19,6 +19,8 @@
 #define DEVICE_2D0_NAME "kgsl-2d0"
 #define DEVICE_2D1_NAME "kgsl-2d1"
 
+#define Z180_DEFAULT_PWRSCALE_POLICY  NULL
+
 struct z180_ringbuffer {
 	unsigned int prevctx;
 	struct kgsl_memdesc      cmdbufdesc;
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index 689a614..2adbbd2 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -325,6 +325,19 @@
 		break;
 	}
 
+	case MSM_CAM_IOCTL_GET_KERNEL_SYSTEM_TIME: {
+		struct timeval timestamp;
+		if (copy_from_user(&timestamp, argp, sizeof(timestamp))) {
+			ERR_COPY_FROM_USER();
+			rc = -EFAULT;
+		} else {
+			msm_mctl_gettimeofday(&timestamp);
+			rc = copy_to_user((void *)argp,
+				 &timestamp, sizeof(timestamp));
+		}
+		break;
+	}
+
 	case MSM_CAM_IOCTL_FLASH_CTRL: {
 		struct flash_ctrl_data flash_info;
 		if (copy_from_user(&flash_info, argp, sizeof(flash_info))) {
@@ -599,6 +612,7 @@
 				PM_QOS_DEFAULT_VALUE);
 	pm_qos_remove_request(&p_mctl->pm_qos_req_list);
 
+	wake_unlock(&sync->wake_lock);
 	return rc;
 }
 
diff --git a/drivers/mfd/pmic8058.c b/drivers/mfd/pmic8058.c
index 7c56dd6..814b59c 100644
--- a/drivers/mfd/pmic8058.c
+++ b/drivers/mfd/pmic8058.c
@@ -73,119 +73,8 @@
 	struct mfd_cell         *mfd_regulators, *mfd_xo_buffers;
 
 	u8		revision;
-
-	struct mutex	pm_lock;
 };
 
-static struct pm8058_chip *pmic_chip;
-
-static inline int
-ssbi_read(struct device *dev, u16 addr, u8 *buf, size_t len)
-{
-	return msm_ssbi_read(dev->parent, addr, buf, len);
-}
-
-static inline int
-ssbi_write(struct device *dev, u16 addr, u8 *buf, size_t len)
-{
-	return msm_ssbi_write(dev->parent, addr, buf, len);
-}
-
-/**
- * pm8058_stay_on - enables stay_on feature
- *
- * PMIC stay-on feature allows PMIC to ignore MSM PS_HOLD=low
- * signal so that some special functions like debugging could be
- * performed.
- *
- * This feature should not be used in any product release.
- *
- * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
- */
-int pm8058_stay_on(void)
-{
-	u8	ctrl = 0x92;
-	int	rc;
-
-	rc = ssbi_write(pmic_chip->dev, SSBI_REG_ADDR_GP_TEST_1, &ctrl, 1);
-	pr_info("%s: set stay-on: rc = %d\n", __func__, rc);
-	return rc;
-}
-EXPORT_SYMBOL(pm8058_stay_on);
-
-/*
-   power on hard reset configuration
-   config = DISABLE_HARD_RESET to disable hard reset
-	  = SHUTDOWN_ON_HARD_RESET to turn off the system on hard reset
-	  = RESTART_ON_HARD_RESET to restart the system on hard reset
- */
-int pm8058_hard_reset_config(enum pon_config config)
-{
-	int rc, ret;
-	u8 pon, pon_5;
-
-	if (config >= MAX_PON_CONFIG)
-		return -EINVAL;
-
-	if (pmic_chip == NULL)
-		return -ENODEV;
-
-	mutex_lock(&pmic_chip->pm_lock);
-
-	rc = ssbi_read(pmic_chip->dev, SSBI_REG_ADDR_PON_CNTL_5, &pon, 1);
-	if (rc) {
-		pr_err("%s: FAIL ssbi_read(0x%x): rc=%d\n",
-		       __func__, SSBI_REG_ADDR_PON_CNTL_5, rc);
-		mutex_unlock(&pmic_chip->pm_lock);
-		return rc;
-	}
-
-	pon_5 = pon;
-	(config != DISABLE_HARD_RESET) ? (pon |= PM8058_HARD_RESET_EN_MASK) :
-					(pon &= ~PM8058_HARD_RESET_EN_MASK);
-
-	rc = ssbi_write(pmic_chip->dev, SSBI_REG_ADDR_PON_CNTL_5, &pon, 1);
-	if (rc) {
-		pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d\n",
-		       __func__, SSBI_REG_ADDR_PON_CNTL_5, pon, rc);
-		mutex_unlock(&pmic_chip->pm_lock);
-		return rc;
-	}
-
-	if (config == DISABLE_HARD_RESET) {
-		mutex_unlock(&pmic_chip->pm_lock);
-		return 0;
-	}
-
-	rc = ssbi_read(pmic_chip->dev, SSBI_REG_ADDR_PON_CNTL_4, &pon, 1);
-	if (rc) {
-		pr_err("%s: FAIL ssbi_read(0x%x): rc=%d\n",
-		       __func__, SSBI_REG_ADDR_PON_CNTL_4, rc);
-		goto err_restore_pon_5;
-	}
-
-	(config == RESTART_ON_HARD_RESET) ? (pon |= PM8058_PON_RESET_EN_MASK) :
-					(pon &= ~PM8058_PON_RESET_EN_MASK);
-
-	rc = ssbi_write(pmic_chip->dev, SSBI_REG_ADDR_PON_CNTL_4, &pon, 1);
-	if (rc) {
-		pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d\n",
-		       __func__, SSBI_REG_ADDR_PON_CNTL_4, pon, rc);
-		goto err_restore_pon_5;
-	}
-	mutex_unlock(&pmic_chip->pm_lock);
-	return 0;
-
-err_restore_pon_5:
-	ret = ssbi_write(pmic_chip->dev, SSBI_REG_ADDR_PON_CNTL_5, &pon_5, 1);
-	if (ret)
-		pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d\n",
-		       __func__, SSBI_REG_ADDR_PON_CNTL_5, pon, ret);
-	mutex_unlock(&pmic_chip->pm_lock);
-	return rc;
-}
-EXPORT_SYMBOL(pm8058_hard_reset_config);
-
 static int pm8058_readb(const struct device *dev, u16 addr, u8 *val)
 {
 	const struct pm8xxx_drvdata *pm8058_drvdata = dev_get_drvdata(dev);
@@ -823,9 +712,6 @@
 	pm8058_drvdata.pm_chip_data = pmic;
 	platform_set_drvdata(pdev, &pm8058_drvdata);
 
-	mutex_init(&pmic->pm_lock);
-	pmic_chip = pmic;
-
 	/* Read PMIC chip revision */
 	rc = pm8058_readb(pmic->dev, PM8058_REG_REV, &pmic->revision);
 	if (rc)
@@ -843,7 +729,7 @@
 		goto err;
 	}
 
-	rc = pm8058_hard_reset_config(SHUTDOWN_ON_HARD_RESET);
+	rc = pm8xxx_hard_reset_config(PM8XXX_SHUTDOWN_ON_HARD_RESET);
 	if (rc < 0)
 		pr_err("%s: failed to config shutdown on hard reset: %d\n",
 								__func__, rc);
@@ -870,7 +756,6 @@
 			mfd_remove_devices(pmic->dev);
 		if (pmic->irq_chip)
 			pm8xxx_irq_exit(pmic->irq_chip);
-		mutex_destroy(&pmic->pm_lock);
 		kfree(pmic->mfd_regulators);
 		kfree(pmic);
 	}
diff --git a/drivers/misc/pmem.c b/drivers/misc/pmem.c
index 692849a..7ee7c11 100644
--- a/drivers/misc/pmem.c
+++ b/drivers/misc/pmem.c
@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/fs.h>
 #include <linux/file.h>
+#include <linux/fmem.h>
 #include <linux/mm.h>
 #include <linux/list.h>
 #include <linux/debugfs.h>
@@ -229,12 +230,12 @@
 	 * request function for a region when the allocation count goes
 	 * from 0 -> 1
 	 */
-	void (*mem_request)(void *);
+	int (*mem_request)(void *);
 	/*
 	 * release function for a region when the allocation count goes
 	 * from 1 -> 0
 	 */
-	void (*mem_release)(void *);
+	int (*mem_release)(void *);
 	/*
 	 * private data for the request/release callback
 	 */
@@ -243,6 +244,10 @@
 	 * map and unmap as needed
 	 */
 	int map_on_demand;
+	/*
+	 * memory will be reused through fmem
+	 */
+	int reusable;
 };
 #define to_pmem_info_id(a) (container_of(a, struct pmem_info, kobj)->id)
 
@@ -582,8 +587,13 @@
 	atomic_inc(&pmem[id].allocation_cnt);
 	if (!pmem[id].vbase) {
 		DLOG("PMEMDEBUG: mapping for %s", pmem[id].name);
-		if (pmem[id].mem_request)
-				pmem[id].mem_request(pmem[id].region_data);
+		if (pmem[id].mem_request) {
+			int ret = pmem[id].mem_request(pmem[id].region_data);
+			if (ret) {
+				atomic_dec(&pmem[id].allocation_cnt);
+				return 1;
+			}
+		}
 		ioremap_pmem(id);
 	}
 
@@ -610,8 +620,11 @@
 			unmap_kernel_range((unsigned long)pmem[id].vbase,
 				 pmem[id].size);
 			pmem[id].vbase = NULL;
-			if (pmem[id].mem_release)
-				pmem[id].mem_release(pmem[id].region_data);
+			if (pmem[id].mem_release) {
+				int ret = pmem[id].mem_release(
+						pmem[id].region_data);
+				WARN(ret, "mem_release failed");
+			}
 
 		}
 	}
@@ -2785,19 +2798,26 @@
 	pr_info("allocating %lu bytes at %p (%lx physical) for %s\n",
 		pmem[id].size, pmem[id].vbase, pmem[id].base, pmem[id].name);
 
-	pmem[id].map_on_demand = pdata->map_on_demand;
+	pmem[id].reusable = pdata->reusable;
+	/* reusable pmem requires map on demand */
+	pmem[id].map_on_demand = pdata->map_on_demand || pdata->reusable;
 	if (pmem[id].map_on_demand) {
-		pmem_vma = get_vm_area(pmem[id].size, VM_IOREMAP);
-		if (!pmem_vma) {
-			pr_err("pmem: Failed to allocate virtual space for "
+		if (pmem[id].reusable) {
+			const struct fmem_data *fmem_info = fmem_get_info();
+			pmem[id].area = fmem_info->area;
+		} else {
+			pmem_vma = get_vm_area(pmem[id].size, VM_IOREMAP);
+			if (!pmem_vma) {
+				pr_err("pmem: Failed to allocate virtual space for "
 					"%s\n", pdata->name);
-			goto out_put_kobj;
-		}
-		pr_err("pmem: Reserving virtual address range %lx - %lx for"
+				goto out_put_kobj;
+			}
+			pr_err("pmem: Reserving virtual address range %lx - %lx for"
 				" %s\n", (unsigned long) pmem_vma->addr,
 				(unsigned long) pmem_vma->addr + pmem[id].size,
 				pdata->name);
-		pmem[id].area = pmem_vma;
+			pmem[id].area = pmem_vma;
+		}
 	} else
 		pmem[id].area = NULL;
 
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 0410473..0a239da 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -2897,7 +2897,7 @@
 	} else {
 		status = gpio_direction_input(gpio_no);
 		if (!status)
-			status = !gpio_get_value_cansleep(gpio_no);
+			status = gpio_get_value_cansleep(gpio_no);
 		gpio_free(gpio_no);
 	}
 	return status;
@@ -2910,15 +2910,36 @@
 	unsigned int status;
 
 	if (host->plat->status || host->plat->status_gpio) {
-		if (host->plat->status)
+		if (host->plat->status) {
 			status = host->plat->status(mmc_dev(host->mmc));
-		else
+			host->eject = !status;
+		} else {
 			status = msmsdcc_slot_status(host);
 
-		host->eject = !status;
+			if (host->plat->is_status_gpio_active_low)
+				host->eject = status;
+			else
+				host->eject = !status;
+		}
+
 		if (status ^ host->oldstat) {
-			pr_info("%s: Slot status change detected (%d -> %d)\n",
-			       mmc_hostname(host->mmc), host->oldstat, status);
+			if (host->plat->status)
+				pr_info("%s: Slot status change detected "
+					"(%d -> %d)\n",
+					mmc_hostname(host->mmc),
+					host->oldstat, status);
+			else if (host->plat->is_status_gpio_active_low)
+				pr_info("%s: Slot status change detected "
+					"(%d -> %d) and the card detect GPIO"
+					" is ACTIVE_LOW\n",
+					mmc_hostname(host->mmc),
+					host->oldstat, status);
+			else
+				pr_info("%s: Slot status change detected "
+					"(%d -> %d) and the card detect GPIO"
+					" is ACTIVE_HIGH\n",
+					mmc_hostname(host->mmc),
+					host->oldstat, status);
 			mmc_detect_change(host->mmc, 0);
 		}
 		host->oldstat = status;
@@ -4049,11 +4070,17 @@
 	 */
 
 	if (plat->status || plat->status_gpio) {
-		if (plat->status)
+		if (plat->status) {
 			host->oldstat = plat->status(mmc_dev(host->mmc));
-		else
+			host->eject = !host->oldstat;
+		} else {
 			host->oldstat = msmsdcc_slot_status(host);
-		host->eject = !host->oldstat;
+
+			if (host->plat->is_status_gpio_active_low)
+				host->eject = host->oldstat;
+			else
+				host->eject = !host->oldstat;
+		}
 	}
 
 	if (plat->status_irq) {
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index df2d556..5f63cd7 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -1063,12 +1063,6 @@
 		soc = 100;
 	pr_debug("SOC = %u%%\n", soc);
 
-	if (bms_fake_battery) {
-		soc = BATTERY_POWER_SUPPLY_SOC;
-		pr_debug("setting SOC = %u%% bms_fake_battery = %d\n", soc,
-							bms_fake_battery);
-	}
-
 	if (soc < 0) {
 		pr_err("bad rem_usb_chg = %d rem_chg %d,"
 				"cc_mah %d, unusb_chg %d\n",
@@ -1085,7 +1079,7 @@
 
 	if (last_soc == -EINVAL || soc <= last_soc) {
 		last_soc = update_userspace ? soc : last_soc;
-		return soc;
+		return bms_fake_battery ? BATTERY_POWER_SUPPLY_SOC : soc;
 	}
 
 	/*
@@ -1100,7 +1094,7 @@
 		soc = last_soc;
 	}
 
-	return soc;
+	return bms_fake_battery ? BATTERY_POWER_SUPPLY_SOC : soc;
 }
 
 #define XOADC_MAX_1P25V		1312500
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index ef97389..5bf9c76 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -1975,7 +1975,7 @@
 	if (chip->is_bat_warm)
 		chg_current = min(chg_current, chip->warm_bat_chg_current);
 
-	if (thermal_mitigation != 0 && !chip->thermal_mitigation)
+	if (thermal_mitigation != 0 && chip->thermal_mitigation)
 		chg_current = min(chg_current,
 				chip->thermal_mitigation[thermal_mitigation]);
 
diff --git a/drivers/staging/qcache/fmem.c b/drivers/staging/qcache/fmem.c
index 9ab21da..489d27a 100644
--- a/drivers/staging/qcache/fmem.c
+++ b/drivers/staging/qcache/fmem.c
@@ -17,11 +17,36 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include "tmem.h"
+#include <asm/mach/map.h>
 
 struct fmem_data fmem_data;
 enum fmem_state fmem_state;
 static spinlock_t fmem_state_lock;
 
+void *fmem_map_virtual_area(int cacheability)
+{
+	unsigned long addr;
+	const struct mem_type *type;
+	int ret;
+
+	addr = (unsigned long) fmem_data.area->addr;
+	type = get_mem_type(cacheability);
+	ret = ioremap_page_range(addr, addr + fmem_data.size,
+			fmem_data.phys, __pgprot(type->prot_pte));
+	if (ret)
+		return ERR_PTR(ret);
+
+	fmem_data.virt = fmem_data.area->addr;
+
+	return fmem_data.virt;
+}
+
+void fmem_unmap_virtual_area(void)
+{
+	unmap_kernel_range((unsigned long)fmem_data.virt, fmem_data.size);
+	fmem_data.virt = NULL;
+}
+
 static int fmem_probe(struct platform_device *pdev)
 {
 	struct fmem_platform_data *pdata = pdev->dev.platform_data;
@@ -29,13 +54,16 @@
 	if (!pdata->size)
 		return -ENODEV;
 
-	fmem_data.virt = ioremap_cached(pdata->phys, pdata->size);
-	if (!fmem_data.virt)
-		return -ENOMEM;
-
 	fmem_data.phys = pdata->phys;
 	fmem_data.size = pdata->size;
+	fmem_data.area = get_vm_area(pdata->size, VM_IOREMAP);
+	if (!fmem_data.area)
+		return -ENOMEM;
 
+	if (!fmem_map_virtual_area(MT_DEVICE_CACHED)) {
+		remove_vm_area(fmem_data.area->addr);
+		return -ENOMEM;
+	}
 	pr_info("fmem phys %lx virt %p size %lx\n",
 		fmem_data.phys, fmem_data.virt, fmem_data.size);
 
@@ -159,10 +187,18 @@
 		}
 	}
 
-	if (new_state == FMEM_T_STATE)
+	if (new_state == FMEM_T_STATE) {
+		void *v;
+		v = fmem_map_virtual_area(MT_DEVICE_CACHED);
+		if (IS_ERR_OR_NULL(v)) {
+			ret = PTR_ERR(v);
+			goto out;
+		}
 		tmem_enable(true);
-	else
+	} else {
 		tmem_disable();
+		fmem_unmap_virtual_area();
+	}
 
 out_set:
 	fmem_state = new_state;
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index dc3ff26..79a2858 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -591,6 +591,7 @@
 	bool session_active;
 	u32 phy_ctrl_val = 0;
 	unsigned ret;
+	u32 portsc;
 
 	if (atomic_read(&motg->in_lpm))
 		return 0;
@@ -632,17 +633,21 @@
 		motg->lpm_flags |= PHY_OTG_COMP_DISABLED;
 	}
 
-	/*
+	/* Set the PHCD bit, only if it is not set by the controller.
 	 * PHY may take some time or even fail to enter into low power
 	 * mode (LPM). Hence poll for 500 msec and reset the PHY and link
 	 * in failure case.
 	 */
-	writel(readl(USB_PORTSC) | PORTSC_PHCD, USB_PORTSC);
-	while (cnt < PHY_SUSPEND_TIMEOUT_USEC) {
-		if (readl(USB_PORTSC) & PORTSC_PHCD)
-			break;
-		udelay(1);
-		cnt++;
+	portsc = readl_relaxed(USB_PORTSC);
+	if (!(portsc & PORTSC_PHCD)) {
+		writel_relaxed(portsc | PORTSC_PHCD,
+				USB_PORTSC);
+		while (cnt < PHY_SUSPEND_TIMEOUT_USEC) {
+			if (readl_relaxed(USB_PORTSC) & PORTSC_PHCD)
+				break;
+			udelay(1);
+			cnt++;
+		}
 	}
 
 	if (cnt >= PHY_SUSPEND_TIMEOUT_USEC) {
diff --git a/drivers/video/msm/external_common.c b/drivers/video/msm/external_common.c
index 5d9795a..3d89e16 100644
--- a/drivers/video/msm/external_common.c
+++ b/drivers/video/msm/external_common.c
@@ -569,11 +569,27 @@
 	return ret;
 }
 
+static ssize_t external_common_rda_hdmi_mode(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	ssize_t ret;
+
+	ret = snprintf(buf, PAGE_SIZE, "%d\n",
+		external_common_state->hdmi_sink);
+
+	DEV_DBG("%s: '%d'\n", __func__,
+		external_common_state->hdmi_sink);
+
+	return ret;
+}
+
+
 static DEVICE_ATTR(video_mode, S_IRUGO | S_IWUGO,
 	external_common_rda_video_mode, external_common_wta_video_mode);
 static DEVICE_ATTR(video_mode_str, S_IRUGO, external_common_rda_video_mode_str,
 	NULL);
 static DEVICE_ATTR(connected, S_IRUGO, external_common_rda_connected, NULL);
+static DEVICE_ATTR(hdmi_mode, S_IRUGO, external_common_rda_hdmi_mode, NULL);
 #ifdef CONFIG_FB_MSM_HDMI_COMMON
 static DEVICE_ATTR(edid_modes, S_IRUGO, hdmi_common_rda_edid_modes, NULL);
 static DEVICE_ATTR(hpd, S_IRUGO | S_IWUGO, hdmi_common_rda_hpd,
@@ -591,6 +607,7 @@
 	&dev_attr_video_mode.attr,
 	&dev_attr_video_mode_str.attr,
 	&dev_attr_connected.attr,
+	&dev_attr_hdmi_mode.attr,
 #ifdef CONFIG_FB_MSM_HDMI_COMMON
 	&dev_attr_edid_modes.attr,
 	&dev_attr_hdcp.attr,
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index c87119f..ffa4a1c 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -3479,9 +3479,11 @@
 {
 	msm_hdmi_sample_rate = rate;
 
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
 	if (hdmi_msm_has_hdcp())
 		hdcp_deauthenticate();
 	else
+#endif
 		hdmi_msm_turn_on();
 }
 EXPORT_SYMBOL(hdmi_msm_audio_sample_rate_reset);
@@ -4275,9 +4277,13 @@
 	if (rc)
 		goto error;
 
-	if (hdmi_msm_has_hdcp())
+	if (hdmi_msm_has_hdcp()) {
+		/* Don't Set Encryption in case of non HDCP builds */
+		external_common_state->present_hdcp = FALSE;
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
 		external_common_state->present_hdcp = TRUE;
-	else {
+#endif
+	} else {
 		external_common_state->present_hdcp = FALSE;
 #ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
 		/*
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 462ede1..e5c8987 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -31,7 +31,7 @@
 #include <linux/mutex.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
-
+#include <linux/memory_alloc.h>
 #include <asm/system.h>
 #include <asm/mach-types.h>
 #include <linux/semaphore.h>
@@ -52,6 +52,7 @@
 int mdp_rev;
 
 static struct regulator *footswitch;
+static unsigned int mdp_footswitch_on;
 
 struct completion mdp_ppp_comp;
 struct semaphore mdp_ppp_mutex;
@@ -1122,18 +1123,6 @@
 				__func__, mdp_hw_revision);
 }
 
-int mdp4_writeback_offset(void)
-{
-	int off = 0;
-
-	if (mdp_pdata->writeback_offset)
-		off = mdp_pdata->writeback_offset();
-
-	pr_debug("%s: writeback_offset=%d %x\n", __func__, off, off);
-
-	return off;
-}
-
 #ifdef CONFIG_FB_MSM_MDP40
 static void configure_mdp_core_clk_table(uint32 min_clk_rate)
 {
@@ -1251,8 +1240,10 @@
 	footswitch = regulator_get(NULL, "fs_mdp");
 	if (IS_ERR(footswitch))
 		footswitch = NULL;
-	else
+	else {
 		regulator_enable(footswitch);
+		mdp_footswitch_on = 1;
+	}
 
 	mdp_clk = clk_get(NULL, "mdp_clk");
 	if (IS_ERR(mdp_clk)) {
@@ -1312,6 +1303,7 @@
 #endif
 
 	if ((pdev->id == 0) && (pdev->num_resources > 0)) {
+
 		mdp_pdata = pdev->dev.platform_data;
 
 		size =  resource_size(&pdev->resource[0]);
@@ -1349,6 +1341,28 @@
 #endif
 
 		mdp_resource_initialized = 1;
+
+		if (!mdp_pdata)
+			return 0;
+
+		size = mdp_pdata->mdp_writeback_size_ov0 +
+			mdp_pdata->mdp_writeback_size_ov1;
+		if (size) {
+			mdp_pdata->mdp_writeback_phys =
+				(void *)allocate_contiguous_memory_nomap
+				(size,
+				 mdp_pdata->mdp_writeback_memtype,
+				 4); /* align to word size */
+			if (mdp_pdata->mdp_writeback_phys) {
+				pr_info("allocating %d bytes at %p for mdp writeback\n",
+					size, mdp_pdata->mdp_writeback_phys);
+			} else {
+				pr_err("%s cannot allocate memory for mdp writeback!\n",
+				       __func__);
+			}
+		} else {
+			mdp_pdata->mdp_writeback_phys = 0;
+		}
 		return 0;
 	}
 
@@ -1619,6 +1633,20 @@
 		}
 	}
 #endif
+
+	if (mdp_pdata && mdp_pdata->mdp_writeback_phys) {
+		mfd->writeback_overlay0_phys =
+			(mdp_pdata->mdp_writeback_size_ov0) ?
+			mdp_pdata->mdp_writeback_phys : 0;
+		mfd->writeback_overlay1_phys =
+			(mdp_pdata->mdp_writeback_size_ov1) ?
+			(mdp_pdata->mdp_writeback_phys +
+			 mdp_pdata->mdp_writeback_size_ov0) : 0;
+	} else {
+		mfd->writeback_overlay0_phys = 0;
+		mfd->writeback_overlay1_phys = 0;
+	}
+
 	/* set driver data */
 	platform_set_drvdata(msm_fb_dev, mfd);
 
@@ -1644,6 +1672,28 @@
 	return rc;
 }
 
+void mdp_footswitch_ctrl(boolean on)
+{
+	mutex_lock(&mdp_suspend_mutex);
+	if (!mdp_suspended || mdp4_extn_disp || !footswitch ||
+		mdp_rev <= MDP_REV_41) {
+		mutex_unlock(&mdp_suspend_mutex);
+		return;
+	}
+
+	if (on && !mdp_footswitch_on) {
+		pr_debug("Enable MDP FS\n");
+		regulator_enable(footswitch);
+		mdp_footswitch_on = 1;
+	} else if (!on && mdp_footswitch_on) {
+		pr_debug("Disable MDP FS\n");
+		regulator_disable(footswitch);
+		mdp_footswitch_on = 0;
+	}
+
+	mutex_unlock(&mdp_suspend_mutex);
+}
+
 #ifdef CONFIG_PM
 static void mdp_suspend_sub(void)
 {
@@ -1688,15 +1738,12 @@
 #ifdef CONFIG_FB_MSM_DTV
 	mdp4_dtv_set_black_screen();
 #endif
-	if (footswitch && mdp_rev > MDP_REV_42)
-		regulator_disable(footswitch);
+	mdp_footswitch_ctrl(FALSE);
 }
 
 static void mdp_early_resume(struct early_suspend *h)
 {
-	if (footswitch && mdp_rev > MDP_REV_42)
-		regulator_enable(footswitch);
-
+	mdp_footswitch_ctrl(TRUE);
 	mutex_lock(&mdp_suspend_mutex);
 	mdp_suspended = FALSE;
 	mutex_unlock(&mdp_suspend_mutex);
diff --git a/drivers/video/msm/mdp.h b/drivers/video/msm/mdp.h
index 8817213..0a0609e 100644
--- a/drivers/video/msm/mdp.h
+++ b/drivers/video/msm/mdp.h
@@ -722,6 +722,7 @@
 int mdp_start_histogram(struct fb_info *info);
 int mdp_stop_histogram(struct fb_info *info);
 int mdp_histogram_ctrl(boolean en);
+void mdp_footswitch_ctrl(boolean on);
 
 #ifdef CONFIG_FB_MSM_MDP303
 static inline void mdp4_dsi_cmd_dma_busy_wait(struct msm_fb_data_type *mfd)
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index 2bcac9c..e170702 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -219,6 +219,7 @@
 #define MDP4_OP_SCALEX_FIR 		(0 << 2)
 #define MDP4_OP_SCALEX_MN_PHASE 	(1 << 2)
 #define MDP4_OP_SCALEX_PIXEL_RPT 	(2 << 2)
+#define MDP4_OP_SCALE_RGB_ENHANCED	(1 << 4)
 #define MDP4_OP_SCALE_RGB_PIXEL_RPT	(0 << 3)
 #define MDP4_OP_SCALE_RGB_BILINEAR	(1 << 3)
 #define MDP4_OP_SCALE_ALPHA_PIXEL_RPT	(0 << 2)
@@ -635,7 +636,6 @@
 			 struct msmfb_overlay_3d *r3d);
 
 int mdp4_mixer_info(int mixer_num, struct mdp_mixer_info *info);
-int mdp4_writeback_offset(void);
 
 void mdp_dmap_vsync_set(int enable);
 int mdp_dmap_vsync_get(void);
diff --git a/drivers/video/msm/mdp4_dtv.c b/drivers/video/msm/mdp4_dtv.c
index a44f7c0..ba774b9 100644
--- a/drivers/video/msm/mdp4_dtv.c
+++ b/drivers/video/msm/mdp4_dtv.c
@@ -109,6 +109,7 @@
 		clk_disable(ebi1_clk);
 #endif
 	mdp4_extn_disp = 0;
+	mdp_footswitch_ctrl(FALSE);
 	return ret;
 }
 
@@ -126,6 +127,7 @@
 		pm_qos_rate = panel_pixclock_freq / 1000 ;
 	else
 		pm_qos_rate = 58000;
+	mdp_footswitch_ctrl(TRUE);
 	mdp4_extn_disp = 1;
 #ifdef CONFIG_MSM_BUS_SCALING
 	if (dtv_bus_scale_handle > 0)
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index a06eef8..c56828d 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -365,15 +365,16 @@
 		pipe->op_mode |= MDP4_OP_SCALEY_EN;
 
 		if (pipe->pipe_num >= OVERLAY_PIPE_VG1) {
-			if (pipe->alpha_enable)
+			if (pipe->alpha_enable && pipe->dst_h > pipe->src_h)
 				pipe->op_mode |= MDP4_OP_SCALEY_PIXEL_RPT;
 			else if (pipe->dst_h <= (pipe->src_h / 4))
 				pipe->op_mode |= MDP4_OP_SCALEY_MN_PHASE;
 			else
 				pipe->op_mode |= MDP4_OP_SCALEY_FIR;
 		} else { /* RGB pipe */
-			pipe->op_mode |= MDP4_OP_SCALE_RGB_BILINEAR;
-			pipe->op_mode |= MDP4_OP_SCALE_ALPHA_BILINEAR;
+			pipe->op_mode |= MDP4_OP_SCALE_RGB_ENHANCED |
+				MDP4_OP_SCALE_RGB_BILINEAR |
+				MDP4_OP_SCALE_ALPHA_BILINEAR;
 		}
 
 		pipe->phasey_step = mdp4_scale_phase_step(29,
@@ -386,15 +387,16 @@
 		pipe->op_mode |= MDP4_OP_SCALEX_EN;
 
 		if (pipe->pipe_num >= OVERLAY_PIPE_VG1) {
-			if (pipe->alpha_enable)
+			if (pipe->alpha_enable && pipe->dst_w > pipe->src_w)
 				pipe->op_mode |= MDP4_OP_SCALEX_PIXEL_RPT;
 			else if (pipe->dst_w <= (pipe->src_w / 4))
 				pipe->op_mode |= MDP4_OP_SCALEX_MN_PHASE;
 			else
 				pipe->op_mode |= MDP4_OP_SCALEX_FIR;
 		} else { /* RGB pipe */
-			pipe->op_mode |= MDP4_OP_SCALE_RGB_BILINEAR;
-			pipe->op_mode |= MDP4_OP_SCALE_ALPHA_BILINEAR;
+			pipe->op_mode |= MDP4_OP_SCALE_RGB_ENHANCED |
+				MDP4_OP_SCALE_RGB_BILINEAR |
+				MDP4_OP_SCALE_ALPHA_BILINEAR;
 		}
 
 		pipe->phasex_step = mdp4_scale_phase_step(29,
@@ -1960,16 +1962,16 @@
 	if (req->flags & MDP_DEINTERLACE)
 		return OVERLAY_PERF_LEVEL1;
 
+	if (ctrl->plist[OVERLAY_PIPE_VG1].pipe_used &&
+	    ctrl->plist[OVERLAY_PIPE_VG2].pipe_used)
+		return OVERLAY_PERF_LEVEL1;
+
 	if (mdp4_overlay_is_rgb_type(req->src.format) && is_fg &&
 		((req->src.width * req->src.height) <= OVERLAY_WSVGA_SIZE))
 		return OVERLAY_PERF_LEVEL4;
 	else if (mdp4_overlay_is_rgb_type(req->src.format))
 		return OVERLAY_PERF_LEVEL1;
 
-	if (ctrl->plist[OVERLAY_PIPE_VG1].pipe_used &&
-		ctrl->plist[OVERLAY_PIPE_VG2].pipe_used)
-		return OVERLAY_PERF_LEVEL1;
-
 	if (req->src.width*req->src.height <= OVERLAY_VGA_SIZE)
 		return OVERLAY_PERF_LEVEL3;
 	else if (req->src.width*req->src.height <= OVERLAY_720P_TILE_SIZE)
diff --git a/drivers/video/msm/mdp4_overlay_dsi_cmd.c b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
index 4479ece..484ed7d 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_cmd.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
@@ -45,8 +45,6 @@
 
 struct timer_list dsi_clock_timer;
 
-static int writeback_offset;
-
 void mdp4_overlay_dsi_state_set(int state)
 {
 	unsigned long flag;
@@ -119,7 +117,6 @@
 void mdp4_overlay_update_dsi_cmd(struct msm_fb_data_type *mfd)
 {
 	MDPIBUF *iBuf = &mfd->ibuf;
-	struct fb_info *fbi = mfd->fbi;
 	uint8 *src;
 	int ptype;
 	struct mdp4_overlay_pipe *pipe;
@@ -159,14 +156,9 @@
 
 		dsi_pipe = pipe; /* keep it */
 
-		writeback_offset = mdp4_writeback_offset();
+		pipe->blt_base = (ulong) mfd->writeback_overlay0_phys;
+		pipe->blt_addr = 0;
 
-		if (writeback_offset > 0) {
-			pipe->blt_base = (ulong)fbi->fix.smem_start;
-			pipe->blt_base += writeback_offset;
-		} else {
-			pipe->blt_base  = 0;
-		}
 	} else {
 		pipe = dsi_pipe;
 	}
@@ -351,7 +343,7 @@
 int mdp4_dsi_overlay_blt_offset(struct msm_fb_data_type *mfd,
 					struct msmfb_overlay_blt *req)
 {
-	req->offset = writeback_offset;
+	req->offset = 0;
 	req->width = dsi_pipe->src_width;
 	req->height = dsi_pipe->src_height;
 	req->bpp = dsi_pipe->bpp;
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
index 938d7c6..d68396a 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -37,8 +37,6 @@
 static int first_pixel_start_x;
 static int first_pixel_start_y;
 
-static int writeback_offset;
-
 static struct mdp4_overlay_pipe *dsi_pipe;
 static struct completion dsi_video_comp;
 
@@ -141,14 +139,9 @@
 		dsi_pipe = pipe; /* keep it */
 		init_completion(&dsi_video_comp);
 
-		writeback_offset = mdp4_writeback_offset();
+		pipe->blt_base = (ulong) mfd->writeback_overlay0_phys;
+		pipe->blt_addr = 0;
 
-		if (writeback_offset > 0) {
-			pipe->blt_base = (ulong)fbi->fix.smem_start;
-			pipe->blt_base += writeback_offset;
-		} else {
-			pipe->blt_base  = 0;
-		}
 	} else {
 		pipe = dsi_pipe;
 	}
@@ -634,7 +627,7 @@
 int mdp4_dsi_video_overlay_blt_offset(struct msm_fb_data_type *mfd,
 					struct msmfb_overlay_blt *req)
 {
-	req->offset = writeback_offset;
+	req->offset = 0;
 	req->width = dsi_pipe->src_width;
 	req->height = dsi_pipe->src_height;
 	req->bpp = dsi_pipe->bpp;
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index f318691..1dbbf94 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -42,8 +42,6 @@
 int first_pixel_start_x;
 int first_pixel_start_y;
 
-static int writeback_offset;
-
 static struct mdp4_overlay_pipe *lcdc_pipe;
 static struct completion lcdc_comp;
 
@@ -128,14 +126,9 @@
 		lcdc_pipe = pipe; /* keep it */
 		init_completion(&lcdc_comp);
 
-		writeback_offset = mdp4_writeback_offset();
+		pipe->blt_base = (ulong) mfd->writeback_overlay0_phys;
+		pipe->blt_addr = 0;
 
-		if (writeback_offset > 0) {
-			pipe->blt_base = (ulong)fbi->fix.smem_start;
-			pipe->blt_base += writeback_offset;
-		} else {
-			pipe->blt_base  = 0;
-		}
 	} else {
 		pipe = lcdc_pipe;
 	}
@@ -507,7 +500,7 @@
 int mdp4_lcdc_overlay_blt_offset(struct msm_fb_data_type *mfd,
 					struct msmfb_overlay_blt *req)
 {
-	req->offset = writeback_offset;
+	req->offset = 0;
 	req->width = lcdc_pipe->src_width;
 	req->height = lcdc_pipe->src_height;
 	req->bpp = lcdc_pipe->bpp;
diff --git a/drivers/video/msm/msm_fb.h b/drivers/video/msm/msm_fb.h
index de2734d..9ee8972 100644
--- a/drivers/video/msm/msm_fb.h
+++ b/drivers/video/msm/msm_fb.h
@@ -166,6 +166,8 @@
 	struct completion msmfb_update_notify;
 	struct completion msmfb_no_update_notify;
 	u32 ov_start, ov_end;
+	void *writeback_overlay0_phys;
+	void *writeback_overlay1_phys;
 	struct mutex writeback_mutex;
 	struct mutex unregister_mutex;
 	struct list_head writeback_busy_queue;
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c
index d27b354..7c68d63 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c
@@ -474,8 +474,7 @@
 	}
 	if (!input_frame ||
 	    !input_frame->vcd_frm.physical ||
-	    ddl->codec_data.encoder.input_buf_req.sz !=
-	    input_frame->vcd_frm.data_len) {
+	    !input_frame->vcd_frm.data_len) {
 		VIDC_LOGERR_STRING("ddl_enc_frame:Bad_input_params");
 		return VCD_ERR_ILLEGAL_PARM;
 	}
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c
index d1b1952..6d3c666 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c
@@ -840,6 +840,11 @@
 				ddl, property_hdr, property_value);
 			break;
 		}
+	case VCD_I_META_BUFFER_MODE:
+		{
+			vcd_status = VCD_S_SUCCESS;
+			break;
+		}
 	default:
 		{
 			vcd_status = VCD_ERR_ILLEGAL_OP;
diff --git a/include/linux/android_pmem.h b/include/linux/android_pmem.h
index c029196..ab96379 100644
--- a/include/linux/android_pmem.h
+++ b/include/linux/android_pmem.h
@@ -157,12 +157,12 @@
 	 * function to be called when the number of allocations goes from
 	 * 0 -> 1
 	 */
-	void (*request_region)(void *);
+	int (*request_region)(void *);
 	/*
 	 * function to be called when the number of allocations goes from
 	 * 1 -> 0
 	 */
-	void (*release_region)(void *);
+	int (*release_region)(void *);
 	/*
 	 * function to be called upon pmem registration
 	 */
@@ -171,6 +171,10 @@
 	 * indicates that this region should be mapped/unmaped as needed
 	 */
 	int map_on_demand;
+	/*
+	 * indicates this pmem may be reused via fmem
+	 */
+	int reusable;
 };
 
 int pmem_setup(struct android_pmem_platform_data *pdata,
diff --git a/include/linux/fmem.h b/include/linux/fmem.h
index d4d5cc7..c9e36b5 100644
--- a/include/linux/fmem.h
+++ b/include/linux/fmem.h
@@ -15,6 +15,8 @@
 #ifndef _FMEM_H_
 #define _FMEM_H_
 
+#include <linux/vmalloc.h>
+
 struct fmem_platform_data {
 	unsigned long phys;
 	unsigned long size;
@@ -23,6 +25,7 @@
 struct fmem_data {
 	unsigned long phys;
 	void *virt;
+	struct vm_struct *area;
 	unsigned long size;
 };
 
@@ -33,9 +36,22 @@
 	FMEM_O_STATE,
 };
 
+#ifdef CONFIG_QCACHE
 struct fmem_data *fmem_get_info(void);
 int fmem_set_state(enum fmem_state);
 void lock_fmem_state(void);
 void unlock_fmem_state(void);
+void *fmem_map_virtual_area(int cacheability);
+void fmem_unmap_virtual_area(void);
+#else
+static inline struct fmem_data *fmem_get_info(void) { return NULL; }
+static inline int fmem_set_state(enum fmem_state f) { return -ENODEV; }
+static inline void lock_fmem_state(void) { return; }
+static inline void unlock_fmem_state(void) { return; }
+static inline void *fmem_map_virtual_area(int cacheability) { return NULL; }
+static inline void fmem_unmap_virtual_area(void) { return; }
+#endif
 
+int request_fmem_c_region(void *unused);
+int release_fmem_c_region(void *unused);
 #endif
diff --git a/include/linux/mfd/pmic8058.h b/include/linux/mfd/pmic8058.h
index 0699c46..ff7a329 100644
--- a/include/linux/mfd/pmic8058.h
+++ b/include/linux/mfd/pmic8058.h
@@ -108,20 +108,6 @@
 	bool charger_data_valid;
 };
 
-enum pon_config{
-	DISABLE_HARD_RESET = 0,
-	SHUTDOWN_ON_HARD_RESET,
-	RESTART_ON_HARD_RESET,
-	MAX_PON_CONFIG,
-};
-
-enum pm8058_smpl_delay {
-	PM8058_SMPL_DELAY_0p5,
-	PM8058_SMPL_DELAY_1p0,
-	PM8058_SMPL_DELAY_1p5,
-	PM8058_SMPL_DELAY_2p0,
-};
-
 struct pm8058_platform_data {
 	struct pm8xxx_mpp_platform_data		*mpp_pdata;
 	struct pm8xxx_keypad_platform_data      *keypad_pdata;
@@ -144,19 +130,4 @@
 	struct pmic8058_charger_data		*charger_pdata;
 };
 
-int pm8058_hard_reset_config(enum pon_config config);
-
-/**
- * pm8058_stay_on - enables stay_on feature
- *
- * PMIC stay-on feature allows PMIC to ignore MSM PS_HOLD=low
- * signal so that some special functions like debugging could be
- * performed.
- *
- * This feature should not be used in any product release.
- *
- * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
- */
-int pm8058_stay_on(void);
-
 #endif  /* __MFD_PMIC8058_H__ */
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index a8b04df..423a849 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -165,6 +165,9 @@
 #define MSM_CAM_IOCTL_SENSOR_V4l2_QUERY_CTRL \
 	_IOR(MSM_CAM_IOCTL_MAGIC, 49, struct v4l2_queryctrl)
 
+#define MSM_CAM_IOCTL_GET_KERNEL_SYSTEM_TIME \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 50, struct timeval *)
+
 struct msm_mctl_pp_cmd {
 	int32_t  id;
 	uint16_t length;
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index 5003ab5..bf72b11 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -1717,6 +1717,7 @@
 	default:
 		/* Should never reach here */
 		pr_err("%s: Invalid MIC BIAS for MBHC\n", __func__);
+		return;
 	}
 
 	micbias_regs->cfilt_sel = cfilt;