Merge "usb: serial: csvt: Modify interface sub class value for PID 0x904c" into msm-3.0
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0a7fe5f..b46d7f1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -140,7 +140,7 @@
 	  Enable ticket locks, which help preserve fairness among
 	  contended locks and prevent livelock in multicore systems.
 	  Say 'y' if system stability is important.
-	default y if ARCH_MSM_SCORPIONMP
+	default y if ARCH_MSM_SCORPIONMP || ARCH_MSM_KRAITMP
 	depends on SMP
 
 config RWSEM_GENERIC_SPINLOCK
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index 613ad72..0b89d45 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -106,6 +106,8 @@
 # CONFIG_MFD_SUPPORT is not set
 CONFIG_ION=y
 CONFIG_ION_MSM=y
+CONFIG_FB=y
+CONFIG_FB_VIRTUAL=y
 # CONFIG_HID_SUPPORT is not set
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_CI13XXX_MSM=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 043b823..e4456dc 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -227,7 +227,7 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_HAPTIC_ISA1200=y
 CONFIG_PMIC8XXX_VIBRATOR=y
-CONFIG_TZCOM=y
+CONFIG_QSEECOM=y
 CONFIG_SCSI=y
 CONFIG_SCSI_TGT=y
 CONFIG_BLK_DEV_SD=y
@@ -337,7 +337,7 @@
 CONFIG_FB_MSM_OVERLAY0_WRITEBACK=y
 CONFIG_FB_MSM_OVERLAY1_WRITEBACK=y
 CONFIG_FB_MSM_WRITEBACK_MSM_PANEL=y
-CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
+CONFIG_FB_MSM_LVDS_MIPI_PANEL_DETECT=y
 CONFIG_FB_MSM_HDMI_MSM_PANEL=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index f41b396..406992a 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -229,7 +229,7 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_HAPTIC_ISA1200=y
 CONFIG_PMIC8XXX_VIBRATOR=y
-CONFIG_TZCOM=y
+CONFIG_QSEECOM=y
 CONFIG_SCSI=y
 CONFIG_SCSI_TGT=y
 CONFIG_BLK_DEV_SD=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index c325217..a2c8827 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -485,6 +485,14 @@
 	help
 	  Support for the Qualcomm MSM8625 SURF.
 
+config MACH_MSM8625_EVB
+	depends on ARCH_MSM8625
+	depends on !MSM_STACKED_MEMORY
+	default y
+	bool "MSM8625 EVB"
+	help
+	  Support for the Qualcomm MSM8625 Reference Design.
+
 config MACH_MSM7X30_SURF
        depends on ARCH_MSM7X30
        depends on !MSM_STACKED_MEMORY
@@ -2090,6 +2098,7 @@
 config MSM_RTB_SEPARATE_CPUS
 	bool "Separate entries for each cpu"
 	depends on MSM_RTB
+	depends on SMP
 	help
 	  Under some circumstances, it may be beneficial to give dedicated space
 	  for each cpu to log accesses. Selecting this option will log each cpu
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 2f55215..1f3945e 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -232,6 +232,7 @@
 obj-$(CONFIG_ARCH_MSM8625) += devices-msm7x27a.o clock-pcom-lookup.o
 obj-$(CONFIG_MACH_MSM8625_RUMI3) += board-msm7x27a.o
 obj-$(CONFIG_MACH_MSM8625_SURF) +=  board-msm7x27a.o board-7627a-all.o
+obj-$(CONFIG_MACH_MSM8625_EVB) +=  board-qrd7627a.o board-7627a-all.o
 obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o memory_topology.o
 obj-$(CONFIG_ARCH_MSM7X30) += clock-local.o clock-7x30.o acpuclock-7x30.o
 obj-$(CONFIG_MACH_MSM7X25_SURF) += board-msm7x27.o devices-msm7x25.o
diff --git a/arch/arm/mach-msm/acpuclock-7201.c b/arch/arm/mach-msm/acpuclock-7201.c
index c4409ff..781d896 100644
--- a/arch/arm/mach-msm/acpuclock-7201.c
+++ b/arch/arm/mach-msm/acpuclock-7201.c
@@ -87,7 +87,6 @@
 	unsigned int	ahbclk_div;
 	int		vdd;
 	unsigned int	axiclk_khz;
-	unsigned long	lpj; /* loops_per_jiffy */
 	/* Pointers in acpu_freq_tbl[] for max up/down steppings. */
 	struct clkctl_acpu_speed *down[ACPU_PLL_END];
 	struct clkctl_acpu_speed *up[ACPU_PLL_END];
@@ -115,7 +114,7 @@
 	{ 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} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7627 with CDMA capable modem */
@@ -129,7 +128,7 @@
 	{ 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} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7627 with GSM capable modem - PLL2 @ 800 */
@@ -143,7 +142,7 @@
 	{ 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} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7627 with CDMA capable modem - PLL2 @ 800 */
@@ -157,7 +156,7 @@
 	{ 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} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7627a PLL2 @ 1200MHz with GSM capable modem */
@@ -172,7 +171,7 @@
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
 	{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7627a PLL2 @ 1200MHz with CDMA capable modem */
@@ -187,7 +186,7 @@
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 120000 },
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
 	{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7627aa PLL4 @ 1008MHz with GSM capable modem */
@@ -202,7 +201,7 @@
 	{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
 	{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7627aa PLL4 @ 1008MHz with CDMA capable modem */
@@ -217,7 +216,7 @@
 	{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
 	{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7625a PLL2 @ 1200MHz with GSM capable modem */
@@ -231,7 +230,7 @@
 	{ 0, 400000, ACPU_PLL_2, 2, 2, 50000, 3, 4, 122880 },
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7627a PLL2 @ 1200MHz with GSM capable modem */
@@ -246,7 +245,7 @@
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
 	{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7627a PLL2 @ 1200MHz with CDMA capable modem */
@@ -261,7 +260,7 @@
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 120000 },
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
 	{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7627aa PLL4 @ 1008MHz with GSM capable modem */
@@ -276,7 +275,7 @@
 	{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
 	{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7627aa PLL4 @ 1008MHz with CDMA capable modem */
@@ -291,7 +290,7 @@
 	{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
 	{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7625a PLL2 @ 1200MHz with GSM capable modem */
@@ -305,7 +304,7 @@
 	{ 0, 400000, ACPU_PLL_2, 2, 2, 50000, 3, 4, 122880 },
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 #define PLL_CONFIG(m0, m1, m2, m4) { \
@@ -578,8 +577,6 @@
 
 		acpuclk_set_div(cur_s);
 		drv_state.current_speed = cur_s;
-		/* Re-adjust lpj for the new clock speed. */
-		loops_per_jiffy = cur_s->lpj;
 		mb();
 		udelay(50);
 	}
@@ -763,18 +760,6 @@
 	return found_khz;
 }
 
-/* Initalize the lpj field in the acpu_freq_tbl. */
-static void __init lpj_init(void)
-{
-	int i;
-	const struct clkctl_acpu_speed *base_clk = drv_state.current_speed;
-	for (i = 0; acpu_freq_tbl[i].a11clk_khz; i++) {
-		acpu_freq_tbl[i].lpj = cpufreq_scale(loops_per_jiffy,
-						base_clk->a11clk_khz,
-						acpu_freq_tbl[i].a11clk_khz);
-	}
-}
-
 static void __init precompute_stepping(void)
 {
 	int i, step_idx;
@@ -867,7 +852,6 @@
 	acpuclk_7627_data.wait_for_irq_khz = find_wait_for_irq_khz();
 	precompute_stepping();
 	acpuclk_hw_init();
-	lpj_init();
 	print_acpu_freq_tbl();
 	acpuclk_register(&acpuclk_7627_data);
 
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index 99c3d78..8d35148 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -194,7 +194,7 @@
 			.hfpll_base      = MSM_HFPLL_BASE + 0x200,
 			.aux_clk_sel     = MSM_ACC0_BASE  + 0x014,
 			.l2cpmr_iaddr    = L2CPUCPMR_IADDR,
-			.vreg[VREG_CORE] = { "krait0",     1150000 },
+			.vreg[VREG_CORE] = { "krait0",     1300000 },
 			.vreg[VREG_MEM]  = { "krait0_mem", 1150000,
 					     RPM_VREG_VOTER1,
 					     RPM_VREG_ID_PM8921_L24 },
@@ -209,7 +209,7 @@
 			.hfpll_base      = MSM_HFPLL_BASE + 0x240,
 			.aux_clk_sel     = MSM_ACC1_BASE  + 0x014,
 			.l2cpmr_iaddr    = L2CPUCPMR_IADDR,
-			.vreg[VREG_CORE] = { "krait1",     1150000 },
+			.vreg[VREG_CORE] = { "krait1",     1300000 },
 			.vreg[VREG_MEM]  = { "krait1_mem", 1150000,
 					     RPM_VREG_VOTER2,
 					     RPM_VREG_ID_PM8921_L24 },
@@ -224,7 +224,7 @@
 			.hfpll_base      = MSM_HFPLL_BASE + 0x280,
 			.aux_clk_sel     = MSM_ACC2_BASE  + 0x014,
 			.l2cpmr_iaddr    = L2CPUCPMR_IADDR,
-			.vreg[VREG_CORE] = { "krait2",     1150000 },
+			.vreg[VREG_CORE] = { "krait2",     1300000 },
 			.vreg[VREG_MEM]  = { "krait2_mem", 1150000,
 					     RPM_VREG_VOTER4,
 					     RPM_VREG_ID_PM8921_L24 },
@@ -239,7 +239,7 @@
 			.hfpll_base      = MSM_HFPLL_BASE + 0x2C0,
 			.aux_clk_sel     = MSM_ACC3_BASE  + 0x014,
 			.l2cpmr_iaddr    = L2CPUCPMR_IADDR,
-			.vreg[VREG_CORE] = { "krait3",     1150000 },
+			.vreg[VREG_CORE] = { "krait3",     1300000 },
 			.vreg[VREG_MEM]  = { "krait3_mem", 1150000,
 					     RPM_VREG_VOTER5,
 					     RPM_VREG_ID_PM8921_L24 },
@@ -375,6 +375,7 @@
 	[4] = BW_MBPS(3200), /* At least 400 MHz on bus. */
 	[5] = BW_MBPS(3600), /* At least 450 MHz on bus. */
 	[6] = BW_MBPS(3936), /* At least 492 MHz on bus. */
+	[7] = BW_MBPS(4264), /* At least 533 MHz on bus. */
 };
 
 static struct msm_bus_scale_pdata bus_client_pdata = {
@@ -546,47 +547,48 @@
 #define L2(x) (&l2_freq_tbl_8064[(x)])
 static struct l2_level l2_freq_tbl_8064[] = {
 	[0]  = { {STBY_KHZ, QSB,   0, 0, 0x00 }, 1050000, 1050000, 0 },
-	[1]  = { {  384000, PLL_8, 0, 2, 0x00 }, 1050000, 1050000, 0 },
-	[2]  = { {  432000, HFPLL, 2, 0, 0x20 }, 1050000, 1050000, 1 },
-	[3]  = { {  486000, HFPLL, 2, 0, 0x24 }, 1050000, 1050000, 1 },
-	[4]  = { {  540000, HFPLL, 2, 0, 0x28 }, 1050000, 1050000, 1 },
+	[1]  = { {  384000, PLL_8, 0, 2, 0x00 }, 1050000, 1050000, 1 },
+	[2]  = { {  432000, HFPLL, 2, 0, 0x20 }, 1050000, 1050000, 2 },
+	[3]  = { {  486000, HFPLL, 2, 0, 0x24 }, 1050000, 1050000, 2 },
+	[4]  = { {  540000, HFPLL, 2, 0, 0x28 }, 1050000, 1050000, 2 },
 	[5]  = { {  594000, HFPLL, 1, 0, 0x16 }, 1050000, 1050000, 2 },
-	[6]  = { {  648000, HFPLL, 1, 0, 0x18 }, 1050000, 1050000, 2 },
-	[7]  = { {  702000, HFPLL, 1, 0, 0x1A }, 1050000, 1050000, 2 },
-	[8]  = { {  756000, HFPLL, 1, 0, 0x1C }, 1150000, 1150000, 3 },
-	[9]  = { {  810000, HFPLL, 1, 0, 0x1E }, 1150000, 1150000, 3 },
-	[10] = { {  864000, HFPLL, 1, 0, 0x20 }, 1150000, 1150000, 3 },
-	[11] = { {  918000, HFPLL, 1, 0, 0x22 }, 1150000, 1150000, 3 },
-	[12] = { {  972000, HFPLL, 1, 0, 0x24 }, 1150000, 1150000, 3 },
-	[13] = { { 1026000, HFPLL, 1, 0, 0x26 }, 1150000, 1150000, 3 },
-	[14] = { { 1080000, HFPLL, 1, 0, 0x28 }, 1150000, 1150000, 4 },
-	[15] = { { 1134000, HFPLL, 1, 0, 0x2A }, 1150000, 1150000, 4 },
-	[16] = { { 1188000, HFPLL, 1, 0, 0x2C }, 1150000, 1150000, 4 },
-	[17] = { { 1242000, HFPLL, 1, 0, 0x2E }, 1150000, 1150000, 4 },
-	[18] = { { 1296000, HFPLL, 1, 0, 0x30 }, 1150000, 1150000, 4 },
-	[19] = { { 1350000, HFPLL, 1, 0, 0x32 }, 1150000, 1150000, 4 },
-	[20] = { { 1404000, HFPLL, 1, 0, 0x34 }, 1150000, 1150000, 4 },
-	[21] = { { 1458000, HFPLL, 1, 0, 0x36 }, 1150000, 1150000, 5 },
-	[22] = { { 1512000, HFPLL, 1, 0, 0x38 }, 1150000, 1150000, 5 },
-	[23] = { { 1566000, HFPLL, 1, 0, 0x3A }, 1150000, 1150000, 5 },
-	[24] = { { 1620000, HFPLL, 1, 0, 0x3C }, 1150000, 1150000, 5 },
-	[25] = { { 1674000, HFPLL, 1, 0, 0x3E }, 1150000, 1150000, 5 },
+	[6]  = { {  648000, HFPLL, 1, 0, 0x18 }, 1050000, 1050000, 4 },
+	[7]  = { {  702000, HFPLL, 1, 0, 0x1A }, 1050000, 1050000, 4 },
+	[8]  = { {  756000, HFPLL, 1, 0, 0x1C }, 1150000, 1150000, 4 },
+	[9]  = { {  810000, HFPLL, 1, 0, 0x1E }, 1150000, 1150000, 4 },
+	[10] = { {  864000, HFPLL, 1, 0, 0x20 }, 1150000, 1150000, 4 },
+	[11] = { {  918000, HFPLL, 1, 0, 0x22 }, 1150000, 1150000, 7 },
+	[12] = { {  972000, HFPLL, 1, 0, 0x24 }, 1150000, 1150000, 7 },
+	[13] = { { 1026000, HFPLL, 1, 0, 0x26 }, 1150000, 1150000, 7 },
+	[14] = { { 1080000, HFPLL, 1, 0, 0x28 }, 1150000, 1150000, 7 },
+	[15] = { { 1134000, HFPLL, 1, 0, 0x2A }, 1150000, 1150000, 7 },
 };
 
 /* TODO: Update core voltages when data is available. */
 static struct acpu_level acpu_freq_tbl_8064[] = {
-	{ 0, {STBY_KHZ, QSB,   0, 0, 0x00 }, L2(0),  1050000 },
-	{ 1, {  384000, PLL_8, 0, 2, 0x00 }, L2(1),  1050000 },
-	{ 1, {  432000, HFPLL, 2, 0, 0x20 }, L2(2),  1050000 },
-	{ 1, {  486000, HFPLL, 2, 0, 0x24 }, L2(3),  1050000 },
-	{ 1, {  540000, HFPLL, 2, 0, 0x28 }, L2(4),  1050000 },
-	{ 1, {  594000, HFPLL, 1, 0, 0x16 }, L2(5),  1050000 },
-	{ 1, {  648000, HFPLL, 1, 0, 0x18 }, L2(6),  1050000 },
-	{ 1, {  702000, HFPLL, 1, 0, 0x1A }, L2(7),  1050000 },
-	{ 1, {  756000, HFPLL, 1, 0, 0x1C }, L2(8),  1150000 },
-	{ 1, {  810000, HFPLL, 1, 0, 0x1E }, L2(9),  1150000 },
-	{ 1, {  864000, HFPLL, 1, 0, 0x20 }, L2(10), 1150000 },
-	{ 1, {  918000, HFPLL, 1, 0, 0x22 }, L2(11), 1150000 },
+	{ 0, { STBY_KHZ, QSB,   0, 0, 0x00 }, L2(0),   950000 },
+	{ 1, {   384000, PLL_8, 0, 2, 0x00 }, L2(1),   950000 },
+	{ 0, {   432000, HFPLL, 2, 0, 0x20 }, L2(7),   975000 },
+	{ 1, {   486000, HFPLL, 2, 0, 0x24 }, L2(7),   975000 },
+	{ 0, {   540000, HFPLL, 2, 0, 0x28 }, L2(7),  1000000 },
+	{ 1, {   594000, HFPLL, 1, 0, 0x16 }, L2(7),  1000000 },
+	{ 0, {   648000, HFPLL, 1, 0, 0x18 }, L2(7),  1025000 },
+	{ 1, {   702000, HFPLL, 1, 0, 0x1A }, L2(7),  1025000 },
+	{ 0, {   756000, HFPLL, 1, 0, 0x1C }, L2(7),  1075000 },
+	{ 1, {   810000, HFPLL, 1, 0, 0x1E }, L2(7),  1075000 },
+	{ 0, {   864000, HFPLL, 1, 0, 0x20 }, L2(7),  1100000 },
+	{ 1, {   918000, HFPLL, 1, 0, 0x22 }, L2(7),  1100000 },
+	{ 0, {   972000, HFPLL, 1, 0, 0x24 }, L2(7),  1125000 },
+	{ 1, {  1026000, HFPLL, 1, 0, 0x26 }, L2(7),  1125000 },
+	{ 0, {  1080000, HFPLL, 1, 0, 0x28 }, L2(15), 1175000 },
+	{ 1, {  1134000, HFPLL, 1, 0, 0x2A }, L2(15), 1175000 },
+	{ 0, {  1188000, HFPLL, 1, 0, 0x2C }, L2(15), 1200000 },
+	{ 1, {  1242000, HFPLL, 1, 0, 0x2E }, L2(15), 1200000 },
+	{ 0, {  1296000, HFPLL, 1, 0, 0x30 }, L2(15), 1225000 },
+	{ 1, {  1350000, HFPLL, 1, 0, 0x32 }, L2(15), 1225000 },
+	{ 0, {  1404000, HFPLL, 1, 0, 0x34 }, L2(15), 1237500 },
+	{ 1, {  1458000, HFPLL, 1, 0, 0x36 }, L2(15), 1237500 },
+	{ 1, {  1512000, HFPLL, 1, 0, 0x38 }, L2(15), 1250000 },
 	{ 0, { 0 } }
 };
 
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index 5bef079..97f8722 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -556,8 +556,7 @@
 
 		if (!a2_pc_disabled) {
 			a2_pc_disabled = 1;
-			schedule_delayed_work(&ul_timeout_work,
-				msecs_to_jiffies(UL_TIMEOUT_DELAY));
+			ul_wakeup();
 		}
 
 		handle_bam_mux_cmd_open(rx_hdr);
diff --git a/arch/arm/mach-msm/board-8064-camera.c b/arch/arm/mach-msm/board-8064-camera.c
index 486ebd3..f23bf2a 100644
--- a/arch/arm/mach-msm/board-8064-camera.c
+++ b/arch/arm/mach-msm/board-8064-camera.c
@@ -102,6 +102,13 @@
 
 static struct msm_gpiomux_config apq8064_cam_common_configs[] = {
 	{
+		.gpio = 1,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[2],
+			[GPIOMUX_SUSPENDED] = &cam_settings[0],
+		},
+	},
+	{
 		.gpio = 2,
 		.settings = {
 			[GPIOMUX_ACTIVE]    = &cam_settings[12],
@@ -111,7 +118,7 @@
 	{
 		.gpio = 3,
 		.settings = {
-			[GPIOMUX_ACTIVE]    = &cam_settings[1],
+			[GPIOMUX_ACTIVE]    = &cam_settings[2],
 			[GPIOMUX_SUSPENDED] = &cam_settings[0],
 		},
 	},
@@ -173,6 +180,16 @@
 	},
 };
 
+
+#define VFE_CAMIF_TIMER1_GPIO 3
+#define VFE_CAMIF_TIMER2_GPIO 1
+
+static struct msm_camera_sensor_flash_src msm_flash_src = {
+	.flash_sr_type = MSM_CAMERA_FLASH_SRC_EXT,
+	._fsrc.ext_driver_src.led_en = VFE_CAMIF_TIMER1_GPIO,
+	._fsrc.ext_driver_src.led_flash_en = VFE_CAMIF_TIMER2_GPIO,
+};
+
 static struct msm_gpiomux_config apq8064_cam_2d_configs[] = {
 };
 
@@ -419,7 +436,8 @@
 };
 
 static struct msm_camera_sensor_flash_data flash_imx074 = {
-	.flash_type	= MSM_CAMERA_FLASH_NONE,
+	.flash_type	= MSM_CAMERA_FLASH_LED,
+	.flash_src	= &msm_flash_src
 };
 
 static struct msm_camera_sensor_platform_info sensor_board_info_imx074 = {
@@ -518,6 +536,9 @@
 	I2C_BOARD_INFO("ov2720", 0x6C),
 	.platform_data = &msm_camera_sensor_ov2720_data,
 	},
+	{
+	I2C_BOARD_INFO("sc628a", 0x6E),
+	},
 };
 
 struct msm_camera_board_info apq8064_camera_board_info = {
diff --git a/arch/arm/mach-msm/board-8064-gpu.c b/arch/arm/mach-msm/board-8064-gpu.c
index e9b497b..9fbb1c7 100644
--- a/arch/arm/mach-msm/board-8064-gpu.c
+++ b/arch/arm/mach-msm/board-8064-gpu.c
@@ -151,17 +151,17 @@
 	.pwrlevel = {
 		{
 			.gpu_freq = 400000000,
-			.bus_freq = 4,
+			.bus_freq = 3,
 			.io_fraction = 0,
 		},
 		{
 			.gpu_freq = 320000000,
-			.bus_freq = 3,
+			.bus_freq = 2,
 			.io_fraction = 33,
 		},
 		{
 			.gpu_freq = 1920000000,
-			.bus_freq = 2,
+			.bus_freq = 1,
 			.io_fraction = 100,
 		},
 		{
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index bd5f703..05002a2 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -310,8 +310,8 @@
 static struct pm8xxx_irq_platform_data
 apq8064_pm8921_irq_pdata __devinitdata = {
 	.irq_base		= PM8921_IRQ_BASE,
-	.devirq			= PM8921_USR_IRQ_N,
-	.irq_trigger_flag	= IRQF_TRIGGER_HIGH,
+	.devirq			= MSM_GPIO_TO_INT(74),
+	.irq_trigger_flag	= IRQF_TRIGGER_LOW,
 	.dev_id			= 0,
 };
 
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index 247b230..5a1957b 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -469,15 +469,15 @@
 /* SAW regulator constraints */
 struct regulator_init_data msm8064_saw_regulator_pdata_8921_s5 =
 	/*	      ID  vreg_name	       min_uV   max_uV */
-	SAW_VREG_INIT(S5, "8921_s5",	       950000, 1150000);
+	SAW_VREG_INIT(S5, "8921_s5",	       950000, 1300000);
 struct regulator_init_data msm8064_saw_regulator_pdata_8921_s6 =
-	SAW_VREG_INIT(S6, "8921_s6",	       950000, 1150000);
+	SAW_VREG_INIT(S6, "8921_s6",	       950000, 1300000);
 
 struct regulator_init_data msm8064_saw_regulator_pdata_8821_s0 =
 	/*	      ID       vreg_name	min_uV  max_uV */
-	SAW_VREG_INIT(8821_S0, "8821_s0",       950000, 1150000);
+	SAW_VREG_INIT(8821_S0, "8821_s0",       950000, 1300000);
 struct regulator_init_data msm8064_saw_regulator_pdata_8821_s1 =
-	SAW_VREG_INIT(8821_S1, "8821_s1",       950000, 1150000);
+	SAW_VREG_INIT(8821_S1, "8821_s1",       950000, 1300000);
 
 /* PM8921 regulator constraints */
 struct pm8xxx_regulator_platform_data
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 3848262..9d4f0aa 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -54,10 +54,12 @@
 #include <linux/bootmem.h>
 #include <asm/setup.h>
 #include <mach/dma.h>
+#include <mach/msm_dsps.h>
 #include <mach/msm_bus_board.h>
 #include <mach/cpuidle.h>
 #include <mach/mdm2.h>
 #include <linux/msm_tsens.h>
+#include <mach/msm_xo.h>
 
 #include "msm_watchdog.h"
 #include "board-8064.h"
@@ -1846,6 +1848,18 @@
 	},
 };
 
+/* Sensors DSPS platform data */
+#define DSPS_PIL_GENERIC_NAME		"dsps"
+static void __init apq8064_init_dsps(void)
+{
+	struct msm_dsps_platform_data *pdata =
+		msm_dsps_device_8064.dev.platform_data;
+	pdata->pil_name = DSPS_PIL_GENERIC_NAME;
+	pdata->gpios = NULL;
+	pdata->gpios_num = 0;
+
+	platform_device_register(&msm_dsps_device_8064);
+}
 
 static void __init apq8064_clock_init(void)
 {
@@ -1939,6 +1953,8 @@
 	BUG_ON(msm_rpmrs_levels_init(&msm_rpmrs_data));
 	regulator_suppress_info_printing();
 	platform_device_register(&apq8064_device_rpm_regulator);
+	if (msm_xo_init())
+		pr_err("Failed to initialize XO votes\n");
 	apq8064_clock_init();
 	apq8064_init_gpiomux();
 	apq8064_i2c_init();
@@ -1967,6 +1983,7 @@
 	platform_device_register(&apq8064_slim_ctrl);
 	slim_register_board_info(apq8064_slim_devices,
 		ARRAY_SIZE(apq8064_slim_devices));
+	apq8064_init_dsps();
 	msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
 	acpuclk_init(&acpuclk_8064_soc_data);
 	msm_spm_l2_init(msm_spm_l2_data);
diff --git a/arch/arm/mach-msm/board-8930-storage.c b/arch/arm/mach-msm/board-8930-storage.c
index e89bed4..26211bf 100644
--- a/arch/arm/mach-msm/board-8930-storage.c
+++ b/arch/arm/mach-msm/board-8930-storage.c
@@ -52,7 +52,7 @@
 		.name = "sdc_vdd",
 		.high_vol_level = 2950000,
 		.low_vol_level = 2950000,
-		.hpm_uA = 600000, /* 600mA */
+		.hpm_uA = 800000, /* 800mA */
 	}
 };
 
@@ -208,11 +208,11 @@
 };
 
 static unsigned int sdc1_sup_clk_rates[] = {
-	400000, 24000000, 48000000
+	400000, 24000000, 48000000,
 };
 
 static unsigned int sdc3_sup_clk_rates[] = {
-	400000, 24000000, 48000000, 96000000
+	400000, 24000000, 48000000, 96000000, 192000000,
 };
 
 #ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
@@ -264,7 +264,7 @@
 	.xpc_cap	= 1,
 	.uhs_caps	= (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
 			MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_DDR50 |
-			MMC_CAP_MAX_CURRENT_600),
+			MMC_CAP_UHS_SDR104 | MMC_CAP_MAX_CURRENT_800),
 };
 #endif
 
diff --git a/arch/arm/mach-msm/board-8960-regulator.c b/arch/arm/mach-msm/board-8960-regulator.c
index d98ae56..9c1a439 100644
--- a/arch/arm/mach-msm/board-8960-regulator.c
+++ b/arch/arm/mach-msm/board-8960-regulator.c
@@ -221,7 +221,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),
@@ -245,12 +244,12 @@
 };
 VREG_CONSUMERS(EXT_OTG_SW) = {
 	REGULATOR_SUPPLY("ext_otg_sw",		NULL),
+	REGULATOR_SUPPLY("vbus_otg",		"msm_otg"),
 };
 
 #define PM8XXX_VREG_INIT(_id, _name, _min_uV, _max_uV, _modes, _ops, \
 			 _apply_uV, _pull_down, _always_on, _supply_regulator, \
-			 _system_uA, _enable_time, _reg_id, _ocp_enable, \
-			 _ocp_enable_time) \
+			 _system_uA, _enable_time, _reg_id) \
 	{ \
 		.init_data = { \
 			.constraints = { \
@@ -272,8 +271,6 @@
 		.pull_down_enable	= _pull_down, \
 		.system_uA		= _system_uA, \
 		.enable_time		= _enable_time, \
-		.ocp_enable		= _ocp_enable, \
-		.ocp_enable_time	= _ocp_enable_time, \
 	}
 
 #define PM8XXX_LDO(_id, _name, _always_on, _pull_down, _min_uV, _max_uV, \
@@ -282,7 +279,7 @@
 		| REGULATOR_MODE_IDLE, REGULATOR_CHANGE_VOLTAGE | \
 		REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_MODE | \
 		REGULATOR_CHANGE_DRMS, 0, _pull_down, _always_on, \
-		_supply_regulator, _system_uA, _enable_time, _reg_id, 0, 0)
+		_supply_regulator, _system_uA, _enable_time, _reg_id)
 
 #define PM8XXX_NLDO1200(_id, _name, _always_on, _pull_down, _min_uV, \
 		_max_uV, _enable_time, _supply_regulator, _system_uA, _reg_id) \
@@ -290,7 +287,7 @@
 		| REGULATOR_MODE_IDLE, REGULATOR_CHANGE_VOLTAGE | \
 		REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_MODE | \
 		REGULATOR_CHANGE_DRMS, 0, _pull_down, _always_on, \
-		_supply_regulator, _system_uA, _enable_time, _reg_id, 0, 0)
+		_supply_regulator, _system_uA, _enable_time, _reg_id)
 
 #define PM8XXX_SMPS(_id, _name, _always_on, _pull_down, _min_uV, _max_uV, \
 		_enable_time, _supply_regulator, _system_uA, _reg_id) \
@@ -298,32 +295,32 @@
 		| REGULATOR_MODE_IDLE, REGULATOR_CHANGE_VOLTAGE | \
 		REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_MODE | \
 		REGULATOR_CHANGE_DRMS, 0, _pull_down, _always_on, \
-		_supply_regulator, _system_uA, _enable_time, _reg_id, 0, 0)
+		_supply_regulator, _system_uA, _enable_time, _reg_id)
 
 #define PM8XXX_FTSMPS(_id, _name, _always_on, _pull_down, _min_uV, _max_uV, \
 		_enable_time, _supply_regulator, _system_uA, _reg_id) \
 	PM8XXX_VREG_INIT(_id, _name, _min_uV, _max_uV, REGULATOR_MODE_NORMAL, \
 		REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS \
 		| REGULATOR_CHANGE_MODE, 0, _pull_down, _always_on, \
-		_supply_regulator, _system_uA, _enable_time, _reg_id, 0, 0)
+		_supply_regulator, _system_uA, _enable_time, _reg_id)
 
 #define PM8XXX_VS(_id, _name, _always_on, _pull_down, _enable_time, \
-		_ocp_enable, _ocp_enable_time, _supply_regulator, _reg_id) \
+		_supply_regulator, _reg_id) \
 	PM8XXX_VREG_INIT(_id, _name, 0, 0, 0, REGULATOR_CHANGE_STATUS, 0, \
 		_pull_down, _always_on, _supply_regulator, 0, _enable_time, \
-		_reg_id, _ocp_enable, _ocp_enable_time)
+		_reg_id)
 
 #define PM8XXX_VS300(_id, _name, _always_on, _pull_down, _enable_time, \
-		_ocp_enable, _ocp_enable_time, _supply_regulator, _reg_id) \
+		_supply_regulator, _reg_id) \
 	PM8XXX_VREG_INIT(_id, _name, 0, 0, 0, REGULATOR_CHANGE_STATUS, 0, \
 		_pull_down, _always_on, _supply_regulator, 0, _enable_time, \
-		_reg_id, _ocp_enable, _ocp_enable_time)
+		_reg_id)
 
 #define PM8XXX_NCP(_id, _name, _always_on, _min_uV, _max_uV, _enable_time, \
 		_supply_regulator, _reg_id) \
 	PM8XXX_VREG_INIT(_id, _name, _min_uV, _max_uV, 0, \
 		REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS, 0, 0, \
-		_always_on, _supply_regulator, 0, _enable_time, _reg_id, 0, 0)
+		_always_on, _supply_regulator, 0, _enable_time, _reg_id)
 
 /* Pin control initialization */
 #define PM8XXX_PC(_id, _name, _always_on, _pin_fn, _pin_ctrl, \
@@ -472,7 +469,7 @@
 	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), "ext_5v"),
+		PM8921_GPIO_PM_TO_SYS(42), "8921_usb_otg"),
 };
 
 /* SAW regulator constraints */
@@ -498,13 +495,9 @@
 	PM8XXX_LDO(L29,      "8921_l29", 0, 1, 2050000, 2100000, 200, "8921_s8",
 		0, 4),
 
-	/*
-	 *	     ID       name      always_on pd en_t ocp ocp_t supply
-	 *	reg_ID
-	 */
-	PM8XXX_VS300(USB_OTG,  "8921_usb_otg",  0, 0,   0, 1, 500, "ext_otg_sw",
-		5),
-	PM8XXX_VS300(HDMI_MVS, "8921_hdmi_mvs", 0, 1,   0, 0,   0, "ext_5v", 6),
+	/*	     ID        name      always_on pd en_t supply    reg_ID */
+	PM8XXX_VS300(USB_OTG,  "8921_usb_otg",  0, 1, 0,   "ext_5v", 5),
+	PM8XXX_VS300(HDMI_MVS, "8921_hdmi_mvs", 0, 1, 0,   "ext_5v", 6),
 };
 
 static struct rpm_regulator_init_data
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 3a48b25..9a8b843 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -2081,8 +2081,8 @@
 	&msm_device_saw_core0,
 	&msm_device_saw_core1,
 	&msm8960_device_ext_5v_vreg,
-	&msm8960_device_ext_otg_sw_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,
@@ -2120,6 +2120,14 @@
 	&msm_device_bam_dmux,
 	&msm_fm_platform_init,
 
+#if defined(CONFIG_TSIF) || defined(CONFIG_TSIF_MODULE)
+#ifdef CONFIG_MSM_USE_TSIF1
+	&msm_device_tsif[1],
+#else
+	&msm_device_tsif[0],
+#endif
+#endif
+
 #ifdef CONFIG_HW_RANDOM_MSM
 	&msm_device_rng,
 #endif
diff --git a/arch/arm/mach-msm/board-msm7627a-bt.c b/arch/arm/mach-msm/board-msm7627a-bt.c
index 9f79abb..a8ab81a 100644
--- a/arch/arm/mach-msm/board-msm7627a-bt.c
+++ b/arch/arm/mach-msm/board-msm7627a-bt.c
@@ -100,7 +100,7 @@
 {
 	if (machine_is_msm7627a_qrd1())
 		gpio_bt_sys_rest_en = 114;
-	if (machine_is_msm7627a_evb())
+	if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
 		gpio_bt_sys_rest_en = 16;
 }
 
@@ -109,14 +109,36 @@
 	int rc = 0;
 	struct marimba config = { .mod_id =  SLAVE_ID_BAHAMA};
 
+	pr_debug("%s: Setting SYS_RST_PIN(%d) to %d\n",
+			__func__, gpio_bt_sys_rest_en, on);
 	if (on) {
-		rc = gpio_direction_output(gpio_bt_sys_rest_en, 1);
+
+		if (machine_is_msm7627a_evb()) {
+			rc = gpio_tlmm_config(GPIO_CFG(gpio_bt_sys_rest_en, 0,
+					GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+					GPIO_CFG_2MA),
+					GPIO_CFG_ENABLE);
+
+			gpio_set_value(gpio_bt_sys_rest_en, 1);
+		} else {
+			rc = gpio_direction_output(gpio_bt_sys_rest_en, 1);
+		}
 		msleep(100);
 	} else {
+
 		if (!marimba_get_fm_status(&config) &&
 				!marimba_get_bt_status(&config)) {
-			gpio_set_value_cansleep(gpio_bt_sys_rest_en, 0);
-			rc = gpio_direction_input(gpio_bt_sys_rest_en);
+			if (machine_is_msm7627a_evb()) {
+				gpio_set_value(gpio_bt_sys_rest_en, 0);
+				rc = gpio_tlmm_config(GPIO_CFG(
+					gpio_bt_sys_rest_en, 0,
+					GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN,
+					GPIO_CFG_2MA),
+					GPIO_CFG_ENABLE);
+			} else {
+				gpio_set_value_cansleep(gpio_bt_sys_rest_en, 0);
+				rc = gpio_direction_input(gpio_bt_sys_rest_en);
+			}
 			msleep(100);
 		}
 	}
diff --git a/arch/arm/mach-msm/board-msm7627a-camera.c b/arch/arm/mach-msm/board-msm7627a-camera.c
index 06fbb7b..7b075cd 100644
--- a/arch/arm/mach-msm/board-msm7627a-camera.c
+++ b/arch/arm/mach-msm/board-msm7627a-camera.c
@@ -1041,7 +1041,7 @@
 
 	pr_debug("msm7627a_camera_init Entered\n");
 	/* LCD and camera power (VREG & LDO) init */
-	if (machine_is_msm7627a_evb())
+	if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
 		lcd_camera_power_init();
 
 #ifndef CONFIG_MSM_CAMERA_V4L2
@@ -1049,7 +1049,7 @@
 		qrd1_camera_gpio_cfg();
 		platform_add_devices(camera_devices_qrd,
 				ARRAY_SIZE(camera_devices_qrd));
-	} else if (machine_is_msm7627a_evb()) {
+	} else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
 		evb_camera_gpio_cfg();
 		platform_add_devices(camera_devices_evb,
 				ARRAY_SIZE(camera_devices_evb));
@@ -1059,7 +1059,8 @@
 		platform_add_devices(camera_devices_msm,
 				ARRAY_SIZE(camera_devices_msm));
 #endif
-	if (!machine_is_msm7627a_qrd1() || !machine_is_msm7627a_evb())
+	if (!machine_is_msm7627a_qrd1() || !machine_is_msm7627a_evb()
+					|| !machine_is_msm8625_evb())
 		register_i2c_devices();
 	rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_camera), regs_camera);
 
@@ -1083,7 +1084,7 @@
 		i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
 				i2c_camera_devices_qrd,
 				ARRAY_SIZE(i2c_camera_devices_qrd));
-	} else if (machine_is_msm7627a_evb()) {
+	} else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
 		pr_debug("machine_is_msm7627a_evb i2c_register_board_info\n");
 		i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
 				i2c_camera_devices_evb,
diff --git a/arch/arm/mach-msm/board-msm7627a-display.c b/arch/arm/mach-msm/board-msm7627a-display.c
index 8093295..45bfaed 100644
--- a/arch/arm/mach-msm/board-msm7627a-display.c
+++ b/arch/arm/mach-msm/board-msm7627a-display.c
@@ -227,7 +227,7 @@
 	} else if (machine_is_msm7627a_qrd1()) {
 		if (!strncmp(name, "mipi_video_truly_wvga", 21))
 			ret = 0;
-	} else if (machine_is_msm7627a_evb()) {
+	} else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
 		if (!strncmp(name, "mipi_cmd_nt35510_wvga", 21))
 			ret = 0;
 	}
@@ -558,7 +558,7 @@
 
 	if (machine_is_msm7627a_qrd1())
 		rc = msm_fb_dsi_client_qrd1_reset();
-	else if (machine_is_msm7627a_evb())
+	else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
 		rc = msm_fb_dsi_client_qrd3_reset();
 	else
 		rc = msm_fb_dsi_client_msm_reset();
@@ -823,7 +823,7 @@
 
 	if (machine_is_msm7627a_qrd1())
 		rc = mipi_dsi_panel_qrd1_power(on);
-	else if (machine_is_msm7627a_evb())
+	else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
 		rc = mipi_dsi_panel_qrd3_power(on);
 	else
 		rc = mipi_dsi_panel_msm_power(on);
@@ -846,7 +846,7 @@
 	if (machine_is_msm7627a_qrd1())
 		platform_add_devices(qrd_fb_devices,
 				ARRAY_SIZE(qrd_fb_devices));
-	else if (machine_is_msm7627a_evb())
+	else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
 		platform_add_devices(evb_fb_devices,
 				ARRAY_SIZE(evb_fb_devices));
 	else if (machine_is_msm7627a_qrd3())
diff --git a/arch/arm/mach-msm/board-msm7627a-storage.c b/arch/arm/mach-msm/board-msm7627a-storage.c
index 3bb9c8b..e4ee52e 100644
--- a/arch/arm/mach-msm/board-msm7627a-storage.c
+++ b/arch/arm/mach-msm/board-msm7627a-storage.c
@@ -150,7 +150,8 @@
 static int gpio_sdc1_hw_det = 85;
 static void gpio_sdc1_config(void)
 {
-	if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb())
+	if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()
+					|| machine_is_msm8625_evb())
 		gpio_sdc1_hw_det = 42;
 }
 
@@ -251,7 +252,8 @@
 		status = gpio_direction_input(gpio_sdc1_hw_det);
 		if (!status) {
 			if (machine_is_msm7627a_qrd1() ||
-					machine_is_msm7627a_evb())
+					machine_is_msm7627a_evb() ||
+					machine_is_msm8625_evb())
 				status = !gpio_get_value(gpio_sdc1_hw_det);
 			else
 				status = gpio_get_value(gpio_sdc1_hw_det);
diff --git a/arch/arm/mach-msm/board-msm7627a-wlan.c b/arch/arm/mach-msm/board-msm7627a-wlan.c
index 6df7626..53d3c56 100644
--- a/arch/arm/mach-msm/board-msm7627a-wlan.c
+++ b/arch/arm/mach-msm/board-msm7627a-wlan.c
@@ -48,7 +48,8 @@
 int gpio_wlan_sys_rest_en = 134;
 static void gpio_wlan_config(void)
 {
-	if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb())
+	if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()
+					|| machine_is_msm8625_evb())
 		gpio_wlan_sys_rest_en = 124;
 }
 
@@ -229,7 +230,8 @@
 	 * gpio_wlan_sys_rest_en is not from the GPIO expander for QRD7627a,
 	 * EVB1.0 and QRD8625,so the below step is required for those devices.
 	 */
-	if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()) {
+	if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()
+					|| machine_is_msm8625_evb()) {
 		rc = gpio_tlmm_config(GPIO_CFG(gpio_wlan_sys_rest_en, 0,
 					GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
 					GPIO_CFG_2MA), GPIO_CFG_ENABLE);
@@ -302,7 +304,8 @@
 	 * gpio_wlan_sys_rest_en is not from the GPIO expander for QRD7627a,
 	 * EVB1.0 and QRD8625,so the below step is required for those devices.
 	 */
-	if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()) {
+	if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()
+					|| machine_is_msm8625_evb()) {
 		rc = gpio_tlmm_config(GPIO_CFG(gpio_wlan_sys_rest_en, 0,
 					GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
 					GPIO_CFG_2MA), GPIO_CFG_ENABLE);
diff --git a/arch/arm/mach-msm/board-msm7627a.h b/arch/arm/mach-msm/board-msm7627a.h
index 8737de8..bde9b61 100644
--- a/arch/arm/mach-msm/board-msm7627a.h
+++ b/arch/arm/mach-msm/board-msm7627a.h
@@ -66,6 +66,7 @@
 	QRD_GPIO_CAM_GP_CAMIF_RESET,
 };
 
+#define ADSP_RPC_PROG           0x3000000a
 #if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
 
 #define FPGA_MSM_CNTRL_REG2 0x90008010
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 628f281..3ad4773 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -14,6 +14,7 @@
 #include <linux/gpio_event.h>
 #include <linux/memblock.h>
 #include <asm/mach-types.h>
+#include <linux/memblock.h>
 #include <asm/mach/arch.h>
 #include <asm/hardware/gic.h>
 #include <mach/board.h>
@@ -60,7 +61,6 @@
 
 #define PMEM_KERNEL_EBI1_SIZE	0x3A000
 #define MSM_PMEM_AUDIO_SIZE	0x5B000
-#define ADSP_RPC_PROG           0x3000000a
 
 #if defined(CONFIG_GPIO_SX150X)
 enum {
@@ -384,6 +384,72 @@
 	.p_addr = 0,
 };
 
+/* 8625 PM platform data */
+static struct msm_pm_platform_data msm8625_pm_data[MSM_PM_SLEEP_MODE_NR * 2] = {
+	/* CORE0 entries */
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE)] = {
+					.idle_supported = 1,
+					.suspend_supported = 1,
+					.idle_enabled = 0,
+					.suspend_enabled = 0,
+					.latency = 16000,
+					.residency = 20000,
+	},
+
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN)] = {
+					.idle_supported = 1,
+					.suspend_supported = 1,
+					.idle_enabled = 0,
+					.suspend_enabled = 0,
+					.latency = 12000,
+					.residency = 20000,
+	},
+
+	/* picked latency & redisdency values from 7x30 */
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE)] = {
+					.idle_supported = 1,
+					.suspend_supported = 1,
+					.idle_enabled = 0,
+					.suspend_enabled = 0,
+					.latency = 500,
+					.residency = 6000,
+	},
+
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
+					.idle_supported = 1,
+					.suspend_supported = 1,
+					.idle_enabled = 1,
+					.suspend_enabled = 1,
+					.latency = 2,
+					.residency = 10,
+	},
+
+	/* picked latency & redisdency values from 7x30 */
+	[MSM_PM_MODE(1, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE)] = {
+					.idle_supported = 1,
+					.suspend_supported = 1,
+					.idle_enabled = 0,
+					.suspend_enabled = 0,
+					.latency = 500,
+					.residency = 6000,
+	},
+
+	[MSM_PM_MODE(1, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
+					.idle_supported = 1,
+					.suspend_supported = 1,
+					.idle_enabled = 1,
+					.suspend_enabled = 1,
+					.latency = 2,
+					.residency = 10,
+	},
+
+};
+
+static struct msm_pm_boot_platform_data msm_pm_8625_boot_pdata __initdata = {
+	.mode = MSM_PM_BOOT_CONFIG_REMAP_BOOT_ADDR,
+	.v_addr = MSM_CFG_CTL_BASE,
+};
+
 static struct android_pmem_platform_data android_pmem_adsp_pdata = {
 	.name = "pmem_adsp",
 	.allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
@@ -880,8 +946,9 @@
 
 static void __init msm8625_reserve(void)
 {
-	memblock_remove(MSM8625_SECONDARY_PHYS, SZ_8);
 	msm7x27a_reserve();
+	memblock_remove(MSM8625_SECONDARY_PHYS, SZ_8);
+	msm_pm_8625_boot_pdata.p_addr = memblock_alloc(SZ_8, SZ_64K);
 }
 
 static void __init msm7x27a_device_i2c_init(void)
@@ -1186,6 +1253,11 @@
 	msm8625_device_i2c_init();
 	platform_add_devices(msm8625_rumi3_devices,
 			ARRAY_SIZE(msm8625_rumi3_devices));
+
+	msm_pm_set_platform_data(msm8625_pm_data,
+			 ARRAY_SIZE(msm8625_pm_data));
+	BUG_ON(msm_pm_boot_init(&msm_pm_8625_boot_pdata));
+	msm8x25_spm_device_init();
 }
 
 #define LED_GPIO_PDM		96
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index 260c880..9f7104f 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -5236,7 +5236,8 @@
 	&msm_batt_device,
 	&msm_adc_device,
 	&msm_ebi0_thermal,
-	&msm_ebi1_thermal
+	&msm_ebi1_thermal,
+	&msm_adsp_device
 };
 
 static struct msm_gpio msm_i2c_gpios_hw[] = {
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index aef9275..61443c3 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -28,9 +28,11 @@
 #include <linux/input/rmi_i2c.h>
 #include <linux/i2c/atmel_mxt_ts.h>
 #include <linux/regulator/consumer.h>
+#include <linux/memblock.h>
 #include <asm/mach/mmc.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
+#include <asm/hardware/gic.h>
 #include <mach/board.h>
 #include <mach/msm_iomap.h>
 #include <mach/msm_hsusb.h>
@@ -659,7 +661,20 @@
 	.dev.platform_data  = &msm_psy_batt_data,
 };
 
-static struct platform_device *qrd_common_devices[] __initdata = {
+static struct platform_device *common_devices[] __initdata = {
+	&android_usb_device,
+	&android_pmem_device,
+	&android_pmem_adsp_device,
+	&android_pmem_audio_device,
+	&msm_batt_device,
+	&msm_device_adspdec,
+	&msm_device_snd,
+	&asoc_msm_pcm,
+	&asoc_msm_dai0,
+	&asoc_msm_dai1,
+};
+
+static struct platform_device *qrd7627a_devices[] __initdata = {
 	&msm_device_dmov,
 	&msm_device_smd,
 	&msm_device_uart1,
@@ -668,23 +683,23 @@
 	&msm_gsbi1_qup_i2c_device,
 	&msm_device_otg,
 	&msm_device_gadget_peripheral,
-	&android_usb_device,
-	&android_pmem_device,
-	&android_pmem_adsp_device,
-	&android_pmem_audio_device,
-	&msm_device_snd,
-	&msm_device_adspdec,
-	&msm_batt_device,
 	&msm_kgsl_3d0,
-	&asoc_msm_pcm,
-	&asoc_msm_dai0,
-	&asoc_msm_dai1,
 };
 
 static struct platform_device *qrd3_devices[] __initdata = {
 	&msm_device_nand,
 };
 
+static struct platform_device *msm8625_evb_devices[] __initdata = {
+	&msm8625_device_dmov,
+	&msm8625_device_smd,
+	&msm8625_gsbi0_qup_i2c_device,
+	&msm8625_gsbi1_qup_i2c_device,
+	&msm8625_device_uart1,
+	&msm8625_device_otg,
+	&msm8625_device_gadget_peripheral,
+};
+
 static unsigned pmem_kernel_ebi1_size = PMEM_KERNEL_EBI1_SIZE;
 static int __init pmem_kernel_ebi1_size_setup(char *p)
 {
@@ -759,12 +774,49 @@
 	msm_reserve();
 }
 
-static void __init msm_device_i2c_init(void)
+static void __init msm8625_reserve(void)
+{
+	memblock_remove(MSM8625_SECONDARY_PHYS, SZ_8);
+	msm7627a_reserve();
+}
+
+static void msmqrd_adsp_add_pdev(void)
+{
+	int rc = 0;
+	struct rpc_board_dev *rpc_adsp_pdev;
+
+	rpc_adsp_pdev = kzalloc(sizeof(struct rpc_board_dev), GFP_KERNEL);
+	if (rpc_adsp_pdev == NULL) {
+		pr_err("%s: Memory Allocation failure\n", __func__);
+		return;
+	}
+	rpc_adsp_pdev->prog = ADSP_RPC_PROG;
+
+	if (cpu_is_msm8625())
+		rpc_adsp_pdev->pdev = msm8625_device_adsp;
+	else
+		rpc_adsp_pdev->pdev = msm_adsp_device;
+	rc = msm_rpc_add_board_dev(rpc_adsp_pdev, 1);
+	if (rc < 0) {
+		pr_err("%s: return val: %d\n",	__func__, rc);
+		kfree(rpc_adsp_pdev);
+	}
+}
+
+static void __init msm7627a_device_i2c_init(void)
 {
 	msm_gsbi0_qup_i2c_device.dev.platform_data = &msm_gsbi0_qup_i2c_pdata;
 	msm_gsbi1_qup_i2c_device.dev.platform_data = &msm_gsbi1_qup_i2c_pdata;
 }
 
+static void __init msm8625_device_i2c_init(void)
+{
+	msm8625_gsbi0_qup_i2c_device.dev.platform_data
+					= &msm_gsbi0_qup_i2c_pdata;
+	msm8625_gsbi1_qup_i2c_device.dev.platform_data
+					= &msm_gsbi1_qup_i2c_pdata;
+}
+
 static struct msm_handset_platform_data hs_platform_data = {
 	.hs_name = "7k_handset",
 	.pwr_key_delay_ms = 500, /* 0 will disable end key */
@@ -955,7 +1007,7 @@
 		i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
 					synaptic_i2c_clearpad3k,
 					ARRAY_SIZE(synaptic_i2c_clearpad3k));
-	} else if (machine_is_msm7627a_evb()) {
+	} else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
 		rc = gpio_tlmm_config(GPIO_CFG(MXT_TS_IRQ_GPIO, 0,
 				GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
 				GPIO_CFG_8MA), GPIO_CFG_ENABLE);
@@ -986,11 +1038,11 @@
 #endif
 
 	/* keypad */
-	if (machine_is_msm7627a_evb())
+	if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
 		platform_device_register(&kp_pdev_8625);
 
 	/* leds */
-	if (machine_is_msm7627a_evb()) {
+	if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
 		rc = gpio_tlmm_config(GPIO_CFG(LED_RED_GPIO_8625, 0,
 				GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
 				GPIO_CFG_16MA), GPIO_CFG_ENABLE);
@@ -1019,32 +1071,63 @@
 
 static void add_platform_devices(void)
 {
-	platform_add_devices(qrd_common_devices,
-			ARRAY_SIZE(qrd_common_devices));
-
-	if (machine_is_msm7627a_qrd3())
-		platform_add_devices(qrd3_devices,
-				ARRAY_SIZE(qrd3_devices));
+	if (machine_is_msm8625_evb())
+		platform_add_devices(msm8625_evb_devices,
+				ARRAY_SIZE(msm8625_evb_devices));
+	else {
+		platform_add_devices(qrd7627a_devices,
+				ARRAY_SIZE(qrd7627a_devices));
+		if (machine_is_msm7627a_qrd3())
+			platform_add_devices(qrd3_devices,
+					ARRAY_SIZE(qrd3_devices));
+	}
+	platform_add_devices(common_devices,
+			ARRAY_SIZE(common_devices));
 }
 
 #define UART1DM_RX_GPIO		45
+static void __init qrd7627a_uart1dm_config(void)
+{
+	msm_uart_dm1_pdata.wakeup_irq = gpio_to_irq(UART1DM_RX_GPIO);
+	if (cpu_is_msm8625())
+		msm8625_device_uart_dm1.dev.platform_data =
+			&msm_uart_dm1_pdata;
+	else
+		msm_device_uart_dm1.dev.platform_data = &msm_uart_dm1_pdata;
+}
+
+static void __init qrd7627a_otg_gadget(void)
+{
+	msm_otg_pdata.swfi_latency = msm7627a_pm_data
+		[MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT].latency;
+
+	if (cpu_is_msm8625()) {
+		msm8625_device_otg.dev.platform_data = &msm_otg_pdata;
+		msm8625_device_gadget_peripheral.dev.platform_data =
+					&msm_gadget_pdata;
+
+	} else {
+		msm_device_otg.dev.platform_data = &msm_otg_pdata;
+		msm_device_gadget_peripheral.dev.platform_data =
+					&msm_gadget_pdata;
+	}
+}
+
 static void __init msm_qrd_init(void)
 {
 	msm7x2x_misc_init();
 	msm7627a_init_regulators();
-	msm_device_i2c_init();
-#ifdef CONFIG_SERIAL_MSM_HS
-	msm_uart_dm1_pdata.wakeup_irq = gpio_to_irq(UART1DM_RX_GPIO);
-	msm_device_uart_dm1.dev.platform_data = &msm_uart_dm1_pdata;
-#endif
+	msmqrd_adsp_add_pdev();
 
-#ifdef CONFIG_USB_MSM_OTG_72K
-	msm_otg_pdata.swfi_latency = msm7627a_pm_data
-		[MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT].latency;
-	msm_device_otg.dev.platform_data = &msm_otg_pdata;
-#endif
-	msm_device_gadget_peripheral.dev.platform_data =
-		&msm_gadget_pdata;
+	if (cpu_is_msm8625())
+		msm8625_device_i2c_init();
+	else
+		msm7627a_device_i2c_init();
+
+	/* uart1dm*/
+	qrd7627a_uart1dm_config();
+	/*OTG gadget*/
+	qrd7627a_otg_gadget();
 
 	add_platform_devices();
 
@@ -1055,9 +1138,11 @@
 #ifdef CONFIG_USB_EHCI_MSM_72K
 	msm7627a_init_host();
 #endif
-	msm_pm_set_platform_data(msm7627a_pm_data,
+	if (!machine_is_msm8625_evb()) {
+		msm_pm_set_platform_data(msm7627a_pm_data,
 				ARRAY_SIZE(msm7627a_pm_data));
-	BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
+		BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
+	}
 
 	msm_fb_add_devices();
 
@@ -1066,7 +1151,6 @@
 #endif
 
 	msm7627a_camera_init();
-
 	msm7627a_add_io_devices();
 }
 
@@ -1105,3 +1189,13 @@
 	.init_early	= qrd7627a_init_early,
 	.handle_irq	= vic_handle_irq,
 MACHINE_END
+MACHINE_START(MSM8625_EVB, "QRD MSM8625 EVB")
+	.boot_params	= PHYS_OFFSET + 0x100,
+	.map_io		= msm8625_map_io,
+	.reserve	= msm8625_reserve,
+	.init_irq	= msm8625_init_irq,
+	.init_machine	= msm_qrd_init,
+	.timer		= &msm_timer,
+	.init_early	= qrd7627a_init_early,
+	.handle_irq	= gic_handle_irq,
+MACHINE_END
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 5996388..0a3632e 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5045,7 +5045,7 @@
 	CLK_LOOKUP("tv_clk",		mdp_tv_clk.c,	"footswitch-8x60.4"),
 	CLK_LOOKUP("hdmi_clk",		hdmi_tv_clk.c,		""),
 	CLK_LOOKUP("core_clk",		hdmi_app_clk.c,		""),
-	CLK_LOOKUP("vpe_clk",		vpe_clk.c,		""),
+	CLK_LOOKUP("vpe_clk",		vpe_clk.c,		"msm_vpe.0"),
 	CLK_LOOKUP("core_clk",		vpe_clk.c,	"footswitch-8x60.9"),
 	CLK_LOOKUP("vfe_clk",		vfe_clk.c,		"msm_vfe.0"),
 	CLK_LOOKUP("core_clk",		vfe_clk.c,	"footswitch-8x60.8"),
@@ -5082,7 +5082,7 @@
 	CLK_LOOKUP("iface_clk",		vcodec_p_clk.c,	"footswitch-8x60.7"),
 	CLK_LOOKUP("vfe_pclk",		vfe_p_clk.c,		"msm_vfe.0"),
 	CLK_LOOKUP("iface_clk",		vfe_p_clk.c,	"footswitch-8x60.8"),
-	CLK_LOOKUP("vpe_pclk",		vpe_p_clk.c,		""),
+	CLK_LOOKUP("vpe_pclk",		vpe_p_clk.c,		"msm_vpe.0"),
 	CLK_LOOKUP("iface_clk",		vpe_p_clk.c,	"footswitch-8x60.9"),
 
 	CLK_LOOKUP("bit_clk",		mi2s_bit_clk.c,		"msm-dai-q6.6"),
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index ca85a0a..630c128 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -23,11 +23,13 @@
 #include <mach/usbdiag.h>
 #include <mach/msm_sps.h>
 #include <mach/dma.h>
+#include <mach/msm_dsps.h>
 #include <sound/msm-dai-q6.h>
 #include <sound/apr_audio.h>
 #include <mach/msm_bus_board.h>
 #include <mach/rpm.h>
 #include <mach/mdm2.h>
+#include <mach/msm_smd.h>
 #include <linux/ion.h>
 #include "clock.h"
 #include "devices.h"
@@ -1217,9 +1219,157 @@
 	.dev.platform_data = &msm_sps_pdata,
 };
 
+static struct resource smd_resource[] = {
+	{
+		.name   = "a9_m2a_0",
+		.start  = INT_A9_M2A_0,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.name   = "a9_m2a_5",
+		.start  = INT_A9_M2A_5,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.name   = "adsp_a11",
+		.start  = INT_ADSP_A11,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.name   = "adsp_a11_smsm",
+		.start  = INT_ADSP_A11_SMSM,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.name   = "dsps_a11",
+		.start  = INT_DSPS_A11,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.name   = "dsps_a11_smsm",
+		.start  = INT_DSPS_A11_SMSM,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.name   = "wcnss_a11",
+		.start  = INT_WCNSS_A11,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.name   = "wcnss_a11_smsm",
+		.start  = INT_WCNSS_A11_SMSM,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct smd_subsystem_config smd_config_list[] = {
+	{
+		.irq_config_id = SMD_MODEM,
+		.subsys_name = "gss",
+		.edge = SMD_APPS_MODEM,
+
+		.smd_int.irq_name = "a9_m2a_0",
+		.smd_int.flags = IRQF_TRIGGER_RISING,
+		.smd_int.irq_id = -1,
+		.smd_int.device_name = "smd_dev",
+		.smd_int.dev_id = 0,
+		.smd_int.out_bit_pos =  1 << 3,
+		.smd_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+		.smd_int.out_offset = 0x8,
+
+		.smsm_int.irq_name = "a9_m2a_5",
+		.smsm_int.flags = IRQF_TRIGGER_RISING,
+		.smsm_int.irq_id = -1,
+		.smsm_int.device_name = "smd_smsm",
+		.smsm_int.dev_id = 0,
+		.smsm_int.out_bit_pos =  1 << 4,
+		.smsm_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+		.smsm_int.out_offset = 0x8,
+	},
+	{
+		.irq_config_id = SMD_Q6,
+		.subsys_name = "q6",
+		.edge = SMD_APPS_QDSP,
+
+		.smd_int.irq_name = "adsp_a11",
+		.smd_int.flags = IRQF_TRIGGER_RISING,
+		.smd_int.irq_id = -1,
+		.smd_int.device_name = "smd_dev",
+		.smd_int.dev_id = 0,
+		.smd_int.out_bit_pos =  1 << 15,
+		.smd_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+		.smd_int.out_offset = 0x8,
+
+		.smsm_int.irq_name = "adsp_a11_smsm",
+		.smsm_int.flags = IRQF_TRIGGER_RISING,
+		.smsm_int.irq_id = -1,
+		.smsm_int.device_name = "smd_smsm",
+		.smsm_int.dev_id = 0,
+		.smsm_int.out_bit_pos =  1 << 14,
+		.smsm_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+		.smsm_int.out_offset = 0x8,
+	},
+	{
+		.irq_config_id = SMD_DSPS,
+		.subsys_name = "dsps",
+		.edge = SMD_APPS_DSPS,
+
+		.smd_int.irq_name = "dsps_a11",
+		.smd_int.flags = IRQF_TRIGGER_RISING,
+		.smd_int.irq_id = -1,
+		.smd_int.device_name = "smd_dev",
+		.smd_int.dev_id = 0,
+		.smd_int.out_bit_pos =  1,
+		.smd_int.out_base = (void __iomem *)MSM_SIC_NON_SECURE_BASE,
+		.smd_int.out_offset = 0x4080,
+
+		.smsm_int.irq_name = "dsps_a11_smsm",
+		.smsm_int.flags = IRQF_TRIGGER_RISING,
+		.smsm_int.irq_id = -1,
+		.smsm_int.device_name = "smd_smsm",
+		.smsm_int.dev_id = 0,
+		.smsm_int.out_bit_pos =  1,
+		.smsm_int.out_base = (void __iomem *)MSM_SIC_NON_SECURE_BASE,
+		.smsm_int.out_offset = 0x4094,
+	},
+	{
+		.irq_config_id = SMD_WCNSS,
+		.subsys_name = "wcnss",
+		.edge = SMD_APPS_WCNSS,
+
+		.smd_int.irq_name = "wcnss_a11",
+		.smd_int.flags = IRQF_TRIGGER_RISING,
+		.smd_int.irq_id = -1,
+		.smd_int.device_name = "smd_dev",
+		.smd_int.dev_id = 0,
+		.smd_int.out_bit_pos =  1 << 25,
+		.smd_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+		.smd_int.out_offset = 0x8,
+
+		.smsm_int.irq_name = "wcnss_a11_smsm",
+		.smsm_int.flags = IRQF_TRIGGER_RISING,
+		.smsm_int.irq_id = -1,
+		.smsm_int.device_name = "smd_smsm",
+		.smsm_int.dev_id = 0,
+		.smsm_int.out_bit_pos =  1 << 23,
+		.smsm_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+		.smsm_int.out_offset = 0x8,
+	},
+};
+
+static struct smd_platform smd_platform_data = {
+	.num_ss_configs = ARRAY_SIZE(smd_config_list),
+	.smd_ss_configs = smd_config_list,
+};
+
 struct platform_device msm_device_smd_apq8064 = {
 	.name		= "msm_smd",
 	.id		= -1,
+	.resource = smd_resource,
+	.num_resources = ARRAY_SIZE(smd_resource),
+	.dev = {
+		.platform_data = &smd_platform_data,
+	},
 };
 
 #ifdef CONFIG_HW_RANDOM_MSM
@@ -1752,6 +1902,53 @@
 	},
 };
 
+/* Sensors DSPS platform data */
+
+#define PPSS_REG_PHYS_BASE	0x12080000
+
+static struct dsps_clk_info dsps_clks[] = {};
+static struct dsps_regulator_info dsps_regs[] = {};
+
+/*
+ * Note: GPIOs field is	intialized in run-time at the function
+ * apq8064_init_dsps().
+ */
+
+struct msm_dsps_platform_data msm_dsps_pdata_8064 = {
+	.clks = dsps_clks,
+	.clks_num = ARRAY_SIZE(dsps_clks),
+	.gpios = NULL,
+	.gpios_num = 0,
+	.regs = dsps_regs,
+	.regs_num = ARRAY_SIZE(dsps_regs),
+	.dsps_pwr_ctl_en = 1,
+	.signature = DSPS_SIGNATURE,
+};
+
+static struct resource msm_dsps_resources[] = {
+	{
+		.start = PPSS_REG_PHYS_BASE,
+		.end   = PPSS_REG_PHYS_BASE + SZ_8K - 1,
+		.name  = "ppss_reg",
+		.flags = IORESOURCE_MEM,
+	},
+
+	{
+		.start = PPSS_WDOG_TIMER_IRQ,
+		.end   = PPSS_WDOG_TIMER_IRQ,
+		.name  = "ppss_wdog",
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device msm_dsps_device_8064 = {
+	.name          = "msm_dsps",
+	.id            = 0,
+	.num_resources = ARRAY_SIZE(msm_dsps_resources),
+	.resource      = msm_dsps_resources,
+	.dev.platform_data = &msm_dsps_pdata_8064,
+};
+
 #ifdef CONFIG_MSM_MPM
 static uint16_t msm_mpm_irqs_m2a[MSM_MPM_NR_MPM_IRQS] __initdata = {
 	[1] = MSM_GPIO_TO_INT(26),
@@ -1891,4 +2088,3 @@
 	.num_resources	= ARRAY_SIZE(mdm_resources),
 	.resource	= mdm_resources,
 };
-
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 19a8db7..718cfb1 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -30,8 +30,10 @@
 #include <mach/rpm.h>
 #include <mach/msm_bus_board.h>
 #include <mach/msm_memtypes.h>
+#include <mach/msm_smd.h>
 #include <sound/msm-dai-q6.h>
 #include <sound/apr_audio.h>
+#include <mach/msm_tsif.h>
 #include "clock.h"
 #include "devices.h"
 #include "devices-msm8x60.h"
@@ -950,9 +952,158 @@
 	.id = -1,
 };
 
+static struct resource smd_resource[] = {
+	{
+		.name   = "a9_m2a_0",
+		.start  = INT_A9_M2A_0,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.name   = "a9_m2a_5",
+		.start  = INT_A9_M2A_5,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.name   = "adsp_a11",
+		.start  = INT_ADSP_A11,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.name   = "adsp_a11_smsm",
+		.start  = INT_ADSP_A11_SMSM,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.name   = "dsps_a11",
+		.start  = INT_DSPS_A11,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.name   = "dsps_a11_smsm",
+		.start  = INT_DSPS_A11_SMSM,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.name   = "wcnss_a11",
+		.start  = INT_WCNSS_A11,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.name   = "wcnss_a11_smsm",
+		.start  = INT_WCNSS_A11_SMSM,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct smd_subsystem_config smd_config_list[] = {
+	{
+		.irq_config_id = SMD_MODEM,
+		.subsys_name = "modem",
+		.edge = SMD_APPS_MODEM,
+
+		.smd_int.irq_name = "a9_m2a_0",
+		.smd_int.flags = IRQF_TRIGGER_RISING,
+		.smd_int.irq_id = -1,
+		.smd_int.device_name = "smd_dev",
+		.smd_int.dev_id = 0,
+		.smd_int.out_bit_pos =  1 << 3,
+		.smd_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+		.smd_int.out_offset = 0x8,
+
+		.smsm_int.irq_name = "a9_m2a_5",
+		.smsm_int.flags = IRQF_TRIGGER_RISING,
+		.smsm_int.irq_id = -1,
+		.smsm_int.device_name = "smd_smsm",
+		.smsm_int.dev_id = 0,
+		.smsm_int.out_bit_pos =  1 << 4,
+		.smsm_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+		.smsm_int.out_offset = 0x8,
+	},
+	{
+		.irq_config_id = SMD_Q6,
+		.subsys_name = "q6",
+		.edge = SMD_APPS_QDSP,
+
+		.smd_int.irq_name = "adsp_a11",
+		.smd_int.flags = IRQF_TRIGGER_RISING,
+		.smd_int.irq_id = -1,
+		.smd_int.device_name = "smd_dev",
+		.smd_int.dev_id = 0,
+		.smd_int.out_bit_pos =  1 << 15,
+		.smd_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+		.smd_int.out_offset = 0x8,
+
+		.smsm_int.irq_name = "adsp_a11_smsm",
+		.smsm_int.flags = IRQF_TRIGGER_RISING,
+		.smsm_int.irq_id = -1,
+		.smsm_int.device_name = "smd_smsm",
+		.smsm_int.dev_id = 0,
+		.smsm_int.out_bit_pos =  1 << 14,
+		.smsm_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+		.smsm_int.out_offset = 0x8,
+	},
+	{
+		.irq_config_id = SMD_DSPS,
+		.subsys_name = "dsps",
+		.edge = SMD_APPS_DSPS,
+
+		.smd_int.irq_name = "dsps_a11",
+		.smd_int.flags = IRQF_TRIGGER_RISING,
+		.smd_int.irq_id = -1,
+		.smd_int.device_name = "smd_dev",
+		.smd_int.dev_id = 0,
+		.smd_int.out_bit_pos =  1,
+		.smd_int.out_base = (void __iomem *)MSM_SIC_NON_SECURE_BASE,
+		.smd_int.out_offset = 0x4080,
+
+		.smsm_int.irq_name = "dsps_a11_smsm",
+		.smsm_int.flags = IRQF_TRIGGER_RISING,
+		.smsm_int.irq_id = -1,
+		.smsm_int.device_name = "smd_smsm",
+		.smsm_int.dev_id = 0,
+		.smsm_int.out_bit_pos =  1,
+		.smsm_int.out_base = (void __iomem *)MSM_SIC_NON_SECURE_BASE,
+		.smsm_int.out_offset = 0x4094,
+	},
+	{
+		.irq_config_id = SMD_WCNSS,
+		.subsys_name = "wcnss",
+		.edge = SMD_APPS_WCNSS,
+
+		.smd_int.irq_name = "wcnss_a11",
+		.smd_int.flags = IRQF_TRIGGER_RISING,
+		.smd_int.irq_id = -1,
+		.smd_int.device_name = "smd_dev",
+		.smd_int.dev_id = 0,
+		.smd_int.out_bit_pos =  1 << 25,
+		.smd_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+		.smd_int.out_offset = 0x8,
+
+		.smsm_int.irq_name = "wcnss_a11_smsm",
+		.smsm_int.flags = IRQF_TRIGGER_RISING,
+		.smsm_int.irq_id = -1,
+		.smsm_int.device_name = "smd_smsm",
+		.smsm_int.dev_id = 0,
+		.smsm_int.out_bit_pos =  1 << 23,
+		.smsm_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+		.smsm_int.out_offset = 0x8,
+	},
+};
+
+static struct smd_platform smd_platform_data = {
+	.num_ss_configs = ARRAY_SIZE(smd_config_list),
+	.smd_ss_configs = smd_config_list,
+};
+
+
 struct platform_device msm_device_smd = {
 	.name		= "msm_smd",
 	.id		= -1,
+	.resource = smd_resource,
+	.num_resources = ARRAY_SIZE(smd_resource),
+	.dev = {
+		.platform_data = &smd_platform_data,
+	},
 };
 
 struct platform_device msm_device_bam_dmux = {
@@ -1355,6 +1506,111 @@
 };
 #endif
 
+#define MSM_TSIF0_PHYS       (0x18200000)
+#define MSM_TSIF1_PHYS       (0x18201000)
+#define MSM_TSIF_SIZE        (0x200)
+
+#define TSIF_0_CLK       GPIO_CFG(75, 1, GPIO_CFG_INPUT, \
+	GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+#define TSIF_0_EN        GPIO_CFG(76, 1, GPIO_CFG_INPUT, \
+	GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+#define TSIF_0_DATA      GPIO_CFG(77, 1, GPIO_CFG_INPUT, \
+	GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+#define TSIF_0_SYNC      GPIO_CFG(82, 1, GPIO_CFG_INPUT, \
+	GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+#define TSIF_1_CLK       GPIO_CFG(79, 1, GPIO_CFG_INPUT, \
+	GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+#define TSIF_1_EN        GPIO_CFG(80, 1, GPIO_CFG_INPUT, \
+	GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+#define TSIF_1_DATA      GPIO_CFG(81, 1, GPIO_CFG_INPUT, \
+	GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+#define TSIF_1_SYNC      GPIO_CFG(78, 1, GPIO_CFG_INPUT, \
+	GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+
+static const struct msm_gpio tsif0_gpios[] = {
+	{ .gpio_cfg = TSIF_0_CLK,  .label =  "tsif_clk", },
+	{ .gpio_cfg = TSIF_0_EN,   .label =  "tsif_en", },
+	{ .gpio_cfg = TSIF_0_DATA, .label =  "tsif_data", },
+	{ .gpio_cfg = TSIF_0_SYNC, .label =  "tsif_sync", },
+};
+
+static const struct msm_gpio tsif1_gpios[] = {
+	{ .gpio_cfg = TSIF_1_CLK,  .label =  "tsif_clk", },
+	{ .gpio_cfg = TSIF_1_EN,   .label =  "tsif_en", },
+	{ .gpio_cfg = TSIF_1_DATA, .label =  "tsif_data", },
+	{ .gpio_cfg = TSIF_1_SYNC, .label =  "tsif_sync", },
+};
+
+struct msm_tsif_platform_data tsif1_platform_data = {
+	.num_gpios = ARRAY_SIZE(tsif1_gpios),
+	.gpios = tsif1_gpios,
+	.tsif_pclk = "tsif_pclk",
+	.tsif_ref_clk = "tsif_ref_clk",
+};
+
+struct resource tsif1_resources[] = {
+	[0] = {
+		.flags = IORESOURCE_IRQ,
+		.start = TSIF2_IRQ,
+		.end   = TSIF2_IRQ,
+	},
+	[1] = {
+		.flags = IORESOURCE_MEM,
+		.start = MSM_TSIF1_PHYS,
+		.end   = MSM_TSIF1_PHYS + MSM_TSIF_SIZE - 1,
+	},
+	[2] = {
+		.flags = IORESOURCE_DMA,
+		.start = DMOV_TSIF_CHAN,
+		.end   = DMOV_TSIF_CRCI,
+	},
+};
+
+struct msm_tsif_platform_data tsif0_platform_data = {
+	.num_gpios = ARRAY_SIZE(tsif0_gpios),
+	.gpios = tsif0_gpios,
+	.tsif_pclk = "tsif_pclk",
+	.tsif_ref_clk = "tsif_ref_clk",
+};
+struct resource tsif0_resources[] = {
+	[0] = {
+		.flags = IORESOURCE_IRQ,
+		.start = TSIF1_IRQ,
+		.end   = TSIF1_IRQ,
+	},
+	[1] = {
+		.flags = IORESOURCE_MEM,
+		.start = MSM_TSIF0_PHYS,
+		.end   = MSM_TSIF0_PHYS + MSM_TSIF_SIZE - 1,
+	},
+	[2] = {
+		.flags = IORESOURCE_DMA,
+		.start = DMOV_TSIF_CHAN,
+		.end   = DMOV_TSIF_CRCI,
+	},
+};
+
+struct platform_device msm_device_tsif[2] = {
+	{
+		.name          = "msm_tsif",
+		.id            = 0,
+		.num_resources = ARRAY_SIZE(tsif0_resources),
+		.resource      = tsif0_resources,
+		.dev = {
+			.platform_data = &tsif0_platform_data
+		},
+	},
+	{
+		.name          = "msm_tsif",
+		.id            = 1,
+		.num_resources = ARRAY_SIZE(tsif1_resources),
+		.resource      = tsif1_resources,
+		.dev = {
+			.platform_data = &tsif1_platform_data
+		},
+	}
+};
+
 static struct resource resources_ssbi_pmic[] = {
 	{
 		.start  = MSM_PMIC1_SSBI_CMD_PHYS,
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 334abc0..9a4696f 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -33,6 +33,7 @@
 #include "devices-msm7x2xa.h"
 #include "footswitch.h"
 #include "acpuclock.h"
+#include "spm.h"
 
 /* Address of GSBI blocks */
 #define MSM_GSBI0_PHYS		0xA1200000
@@ -641,6 +642,55 @@
 
 #endif
 
+/* Command sequence for simple WFI */
+static uint8_t spm_wfi_cmd_sequence[] __initdata = {
+	0x00, 0x40, 0x40, 0x03,
+	0x00, 0x40, 0x40, 0x0f,
+};
+
+/* Command sequence for GDFS, this won't send any interrupt to the modem */
+static uint8_t spm_pc_without_modem[] __initdata = {
+	0x20, 0x00, 0x30, 0x10,
+	0x40, 0x40, 0x03, 0x10,
+	0x00, 0x30, 0x2E, 0x40,
+	0x40, 0x0f,
+};
+
+static struct msm_spm_seq_entry msm_spm_seq_list[] __initdata = {
+	[0] = {
+		.mode = MSM_SPM_MODE_CLOCK_GATING,
+		.notify_rpm = false,
+		.cmd = spm_wfi_cmd_sequence,
+	},
+	[1] = {
+		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
+		.notify_rpm = false,
+		.cmd = spm_pc_without_modem,
+	},
+};
+
+static struct msm_spm_platform_data msm_spm_data[] __initdata = {
+	[0] = {
+		.reg_base_addr = MSM_SAW0_BASE,
+		.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x0,
+		.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
+		.num_modes = ARRAY_SIZE(msm_spm_seq_list),
+		.modes = msm_spm_seq_list,
+	},
+	[1] = {
+		.reg_base_addr = MSM_SAW1_BASE,
+		.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x0,
+		.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
+		.num_modes = ARRAY_SIZE(msm_spm_seq_list),
+		.modes = msm_spm_seq_list,
+	},
+};
+
+void __init msm8x25_spm_device_init(void)
+{
+	msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
+}
+
 #define MDP_BASE		0xAA200000
 #define MIPI_DSI_HW_BASE	0xA1100000
 
diff --git a/arch/arm/mach-msm/devices-msm7x2xa.h b/arch/arm/mach-msm/devices-msm7x2xa.h
index c2383c6..3c81ccf 100644
--- a/arch/arm/mach-msm/devices-msm7x2xa.h
+++ b/arch/arm/mach-msm/devices-msm7x2xa.h
@@ -30,4 +30,5 @@
 void __init msm8625_init_irq(void);
 void __init msm8625_map_io(void);
 int  ar600x_wlan_power(bool on);
+void __init msm8x25_spm_device_init(void);
 #endif
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index e9b94f6..89c8aaf 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -74,6 +74,20 @@
 	.resource       = msm_ebi1_thermal_resources
 };
 
+static struct resource resources_adsp[] = {
+{
+	.start  = INT_ADSP_A9_A11,
+	.end    = INT_ADSP_A9_A11,
+	.flags  = IORESOURCE_IRQ,
+},
+};
+
+struct platform_device msm_adsp_device = {
+	.name           = "msm_adsp",
+	.id             = -1,
+	.num_resources  = ARRAY_SIZE(resources_adsp),
+	.resource       = resources_adsp,
+};
 
 static struct resource resources_uart1[] = {
 	{
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 82a3fa1..7f2855d 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -323,3 +323,5 @@
 extern struct platform_device msm_bus_8064_cpss_fpb;
 
 extern struct platform_device mdm_8064_device;
+
+extern struct platform_device msm_dsps_device_8064;
diff --git a/arch/arm/mach-msm/idle.h b/arch/arm/mach-msm/idle.h
index 830e36b..6311b3c 100644
--- a/arch/arm/mach-msm/idle.h
+++ b/arch/arm/mach-msm/idle.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007-2009,2011 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2007-2009,2012 Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -28,6 +28,15 @@
 {
 	/* empty */
 }
+static inline void msm_pm_boot_entry(void)
+{
+	/* empty */
+}
+static inline void msm_pm_write_boot_vector(unsigned int cpu,
+						unsigned long address)
+{
+	/* empty */
+}
 #endif
 
 #endif
diff --git a/arch/arm/mach-msm/include/mach/diag_bridge.h b/arch/arm/mach-msm/include/mach/diag_bridge.h
index a39ed25..b06f020 100644
--- a/arch/arm/mach-msm/include/mach/diag_bridge.h
+++ b/arch/arm/mach-msm/include/mach/diag_bridge.h
@@ -19,6 +19,8 @@
 			int buf_size, int actual);
 	void (*write_complete_cb)(void *ctxt, char *buf,
 			int buf_size, int actual);
+	int (*suspend)(void *ctxt);
+	void (*resume)(void *ctxt);
 };
 
 #if defined(CONFIG_USB_QCOM_DIAG_BRIDGE) \
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h
index 3cb79b7..d170f5f 100644
--- a/arch/arm/mach-msm/include/mach/dma.h
+++ b/arch/arm/mach-msm/include/mach/dma.h
@@ -177,6 +177,9 @@
 #define DMOV_CE_OUT_CHAN       1
 #define DMOV_CE_OUT_CRCI       3
 
+#define DMOV_TSIF_CHAN         2
+#define DMOV_TSIF_CRCI         11
+
 #define DMOV_HSUART_GSBI6_TX_CHAN	7
 #define DMOV_HSUART_GSBI6_TX_CRCI	6
 
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-copper.h b/arch/arm/mach-msm/include/mach/msm_iomap-copper.h
index 6311dbe..b560276 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-copper.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-copper.h
@@ -34,7 +34,7 @@
 #define COPPER_APCS_GCC_PHYS	0xF9011000
 #define COPPER_APCS_GCC_SIZE	SZ_4K
 
-#define COPPER_TLMM_PHYS	0xFD400000
+#define COPPER_TLMM_PHYS	0xFD510000
 #define COPPER_TLMM_SIZE	SZ_16K
 
 #ifdef CONFIG_DEBUG_MSMCOPPER_UART
diff --git a/arch/arm/mach-msm/include/mach/msm_smd.h b/arch/arm/mach-msm/include/mach/msm_smd.h
index 4be6d9ea..8d3e640 100644
--- a/arch/arm/mach-msm/include/mach/msm_smd.h
+++ b/arch/arm/mach-msm/include/mach/msm_smd.h
@@ -236,6 +236,22 @@
  */
 int smd_write_end(smd_channel_t *ch);
 
+/*
+ * Returns a pointer to the subsystem name or NULL if no
+ * subsystem name is available.
+ *
+ * @type - Edge definition
+ */
+const char *smd_edge_to_subsystem(uint32_t type);
+
+/*
+ * Returns a pointer to the subsystem name given the
+ * remote processor ID.
+ *
+ * @pid     Remote processor ID
+ * @returns Pointer to subsystem name or NULL if not found
+ */
+const char *smd_pid_to_subsystem(uint32_t pid);
 #else
 
 static inline int smd_open(const char *name, smd_channel_t **ch, void *priv,
@@ -337,6 +353,16 @@
 {
 	return -ENODEV;
 }
+
+static inline const char *smd_edge_to_subsystem(uint32_t type)
+{
+	return NULL;
+}
+
+static inline const char *smd_pid_to_subsystem(uint32_t pid)
+{
+	return NULL;
+}
 #endif
 
 #endif
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_dev_ctl.h b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_dev_ctl.h
index 71f2bd9..20c6fc4 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_dev_ctl.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_dev_ctl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -96,6 +96,8 @@
 
 int msm_reset_all_device(void);
 
+int reset_device(void);
+
 int msm_clear_all_session(void);
 
 struct msm_snddev_info *audio_dev_ctrl_find_dev(u32 dev_id);
diff --git a/arch/arm/mach-msm/mdm_common.c b/arch/arm/mach-msm/mdm_common.c
index 7445a61..04c29cc 100644
--- a/arch/arm/mach-msm/mdm_common.c
+++ b/arch/arm/mach-msm/mdm_common.c
@@ -242,6 +242,8 @@
 
 static int mdm_subsys_powerup(const struct subsys_data *crashed_subsys)
 {
+	gpio_direction_output(mdm_drv->ap2mdm_errfatal_gpio, 0);
+	gpio_direction_output(mdm_drv->ap2mdm_status_gpio, 1);
 	mdm_drv->ops->power_on_mdm_cb(mdm_drv);
 	mdm_drv->boot_type = CHARM_NORMAL_BOOT;
 	complete(&mdm_needs_reload);
diff --git a/arch/arm/mach-msm/msm_watchdog.c b/arch/arm/mach-msm/msm_watchdog.c
index 5bff832..28b5995 100644
--- a/arch/arm/mach-msm/msm_watchdog.c
+++ b/arch/arm/mach-msm/msm_watchdog.c
@@ -304,6 +304,9 @@
 static void init_watchdog_work(struct work_struct *work)
 {
 	u64 timeout = (bark_time * WDT_HZ)/1000;
+
+	configure_bark_dump();
+
 	__raw_writel(timeout, msm_tmr0_base + WDT0_BARK_TIME);
 	__raw_writel(timeout + 3*WDT_HZ, msm_tmr0_base + WDT0_BITE_TIME);
 
@@ -366,8 +369,6 @@
 	if (pdata->needs_expired_enable)
 		__raw_writel(0x1, MSM_CLK_CTL_BASE + 0x3820);
 
-	configure_bark_dump();
-
 	delay_time = msecs_to_jiffies(pdata->pet_time);
 	schedule_work_on(0, &init_dogwork_struct);
 	return 0;
diff --git a/arch/arm/mach-msm/msm_xo.c b/arch/arm/mach-msm/msm_xo.c
index 74c64c1..f7d2bcb 100644
--- a/arch/arm/mach-msm/msm_xo.c
+++ b/arch/arm/mach-msm/msm_xo.c
@@ -237,13 +237,6 @@
 	unsigned long flags;
 	struct msm_xo_voter *xo_voter;
 
-	/*
-	 * TODO: Remove early return for 8064 once RPM XO voting support
-	 * is available.
-	 */
-	if (cpu_is_apq8064())
-		return NULL;
-
 	if (xo_id >= NUM_MSM_XO_IDS) {
 		ret = -EINVAL;
 		goto err;
diff --git a/arch/arm/mach-msm/platsmp-8625.c b/arch/arm/mach-msm/platsmp-8625.c
index 8081b45..3c46d0f 100644
--- a/arch/arm/mach-msm/platsmp-8625.c
+++ b/arch/arm/mach-msm/platsmp-8625.c
@@ -62,6 +62,10 @@
 
 void __cpuinit platform_secondary_init(unsigned int cpu)
 {
+	pr_debug("CPU%u: Booted secondary processor\n", cpu);
+
+	WARN_ON(msm_platform_secondary_init(cpu));
+
 	/*
 	 * if any interrupts are already enabled for the primary
 	 * core (e.g. timer irq), then they will not have been enabled
diff --git a/arch/arm/mach-msm/pm-boot.c b/arch/arm/mach-msm/pm-boot.c
index ce09f9f..f4536f7 100644
--- a/arch/arm/mach-msm/pm-boot.c
+++ b/arch/arm/mach-msm/pm-boot.c
@@ -101,6 +101,7 @@
 int __init msm_pm_boot_init(struct msm_pm_boot_platform_data *pdata)
 {
 	int ret = 0;
+	unsigned long entry;
 
 	switch (pdata->mode) {
 	case MSM_PM_BOOT_CONFIG_TZ:
@@ -130,15 +131,44 @@
 		if (!pdata->p_addr || !pdata->v_addr)
 			return -ENODEV;
 
-		__raw_writel((pdata->p_addr | BOOT_REMAP_ENABLE),
-				pdata->v_addr);
-
 		ret = msm_pm_boot_reset_vector_init(__va(pdata->p_addr));
 
-		msm_pm_boot_before_pc
-			= msm_pm_config_rst_vector_before_pc;
-		msm_pm_boot_after_pc
-			= msm_pm_config_rst_vector_after_pc;
+		if (!cpu_is_msm8625()) {
+			__raw_writel((pdata->p_addr | BOOT_REMAP_ENABLE),
+					pdata->v_addr);
+
+			msm_pm_boot_before_pc
+				= msm_pm_config_rst_vector_before_pc;
+			msm_pm_boot_after_pc
+				= msm_pm_config_rst_vector_after_pc;
+		} else {
+			entry = virt_to_phys(msm_pm_boot_entry);
+
+			msm_pm_reset_vector[0] = 0xE51FF004; /* ldr pc, 4 */
+			msm_pm_reset_vector[1] = entry;
+
+			/* Here upper 16bits[16:31] used by CORE1
+			 * lower 16bits[0:15] used by CORE0
+			 */
+			entry = (pdata->p_addr) |
+					((pdata->p_addr & 0xFFFF0000) >> 16);
+
+			/* write 'entry' to boot remapper register */
+			__raw_writel(entry, (pdata->v_addr +
+						MPA5_BOOT_REMAP_ADDR));
+
+			/* Enable boot remapper for C0 [bit:25th] */
+			__raw_writel(readl_relaxed(pdata->v_addr +
+					MPA5_CFG_CTL_REG) | BIT(25),
+					pdata->v_addr + MPA5_CFG_CTL_REG);
+
+			/* Enable boot remapper for C1 [bit:26th] */
+			__raw_writel(readl_relaxed(pdata->v_addr +
+					MPA5_CFG_CTL_REG) | BIT(26),
+					pdata->v_addr + MPA5_CFG_CTL_REG);
+
+			msm_pm_boot_before_pc = msm_pm_write_boot_vector;
+		}
 		break;
 	default:
 		__WARN();
diff --git a/arch/arm/mach-msm/pm-boot.h b/arch/arm/mach-msm/pm-boot.h
index 185d542..30b67c21 100644
--- a/arch/arm/mach-msm/pm-boot.h
+++ b/arch/arm/mach-msm/pm-boot.h
@@ -13,6 +13,11 @@
 #ifndef _ARCH_ARM_MACH_MSM_PM_BOOT_H
 #define _ARCH_ARM_MACH_MSM_PM_BOOT_H
 
+/* 8x25 specific macros */
+#define MPA5_CFG_CTL_REG	0x30
+#define MPA5_BOOT_REMAP_ADDR	0x34
+/* end */
+
 enum {
 	MSM_PM_BOOT_CONFIG_TZ		     = 0,
 	MSM_PM_BOOT_CONFIG_RESET_VECTOR_PHYS = 1,
diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c
index 7977d22..1396463 100644
--- a/arch/arm/mach-msm/pm2.c
+++ b/arch/arm/mach-msm/pm2.c
@@ -48,6 +48,7 @@
 #ifdef CONFIG_MSM_MEMORY_LOW_POWER_MODE_SUSPEND_DEEP_POWER_DOWN
 #include <mach/msm_migrate_pages.h>
 #endif
+#include <mach/socinfo.h>
 
 #include "smd_private.h"
 #include "smd_rpcrouter.h"
@@ -68,13 +69,14 @@
  *****************************************************************************/
 
 enum {
-	MSM_PM_DEBUG_SUSPEND = 1U << 0,
-	MSM_PM_DEBUG_POWER_COLLAPSE = 1U << 1,
-	MSM_PM_DEBUG_STATE = 1U << 2,
-	MSM_PM_DEBUG_CLOCK = 1U << 3,
-	MSM_PM_DEBUG_RESET_VECTOR = 1U << 4,
-	MSM_PM_DEBUG_SMSM_STATE = 1U << 5,
-	MSM_PM_DEBUG_IDLE = 1U << 6,
+	MSM_PM_DEBUG_SUSPEND = BIT(0),
+	MSM_PM_DEBUG_POWER_COLLAPSE = BIT(1),
+	MSM_PM_DEBUG_STATE = BIT(2),
+	MSM_PM_DEBUG_CLOCK = BIT(3),
+	MSM_PM_DEBUG_RESET_VECTOR = BIT(4),
+	MSM_PM_DEBUG_SMSM_STATE = BIT(5),
+	MSM_PM_DEBUG_IDLE = BIT(6),
+	MSM_PM_DEBUG_HOTPLUG = BIT(7),
 };
 
 static int msm_pm_debug_mask;
@@ -142,7 +144,6 @@
 static char *msm_pm_sleep_mode_labels[MSM_PM_SLEEP_MODE_NR] = {
 	[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_SUSPEND] = " ",
 	[MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = "power_collapse",
-	[MSM_PM_SLEEP_MODE_APPS_SLEEP] = "apps_sleep",
 	[MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT] =
 		"ramp_down_and_wfi",
 	[MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT] = "wfi",
@@ -682,8 +683,6 @@
 	MSM_PM_STAT_IDLE_WFI,
 	MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE,
 	MSM_PM_STAT_IDLE_FAILED_STANDALONE_POWER_COLLAPSE,
-	MSM_PM_STAT_IDLE_SLEEP,
-	MSM_PM_STAT_IDLE_FAILED_SLEEP,
 	MSM_PM_STAT_IDLE_POWER_COLLAPSE,
 	MSM_PM_STAT_IDLE_FAILED_POWER_COLLAPSE,
 	MSM_PM_STAT_SUSPEND,
@@ -1008,6 +1007,13 @@
 
 	memset(msm_pm_smem_data, 0, sizeof(*msm_pm_smem_data));
 
+	if (cpu_is_msm8625()) {
+		/* Program the SPM */
+		ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_POWER_COLLAPSE,
+									false);
+		WARN_ON(ret);
+	}
+
 	msm_irq_enter_sleep1(true, from_idle, &msm_pm_smem_data->irq_mask);
 	msm_sirc_enter_sleep();
 	msm_gpio_enter_sleep(from_idle);
@@ -1210,6 +1216,13 @@
 	MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): RUN");
 
 	smd_sleep_exit();
+
+	if (cpu_is_msm8625()) {
+		ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING,
+									false);
+		WARN_ON(ret);
+	}
+
 	return 0;
 
 power_collapse_early_exit:
@@ -1263,6 +1276,12 @@
 		smd_sleep_exit();
 
 power_collapse_bail:
+	if (cpu_is_msm8625()) {
+		ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING,
+									false);
+		WARN_ON(ret);
+	}
+
 	return ret;
 }
 
@@ -1272,10 +1291,11 @@
  * Return value:
  *      0: success
  */
-static int msm_pm_power_collapse_standalone(void)
+static int msm_pm_power_collapse_standalone(bool from_idle)
 {
 	int collapsed = 0;
 	int ret;
+	void *entry;
 
 	MSM_PM_DPRINTK(MSM_PM_DEBUG_SUSPEND|MSM_PM_DEBUG_POWER_COLLAPSE,
 		KERN_INFO, "%s()\n", __func__);
@@ -1283,21 +1303,26 @@
 	ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_POWER_COLLAPSE, false);
 	WARN_ON(ret);
 
+	entry = (!smp_processor_id() || from_idle) ?
+			msm_pm_collapse_exit : msm_secondary_startup;
+
 	msm_pm_boot_config_before_pc(smp_processor_id(),
-			virt_to_phys(msm_pm_collapse_exit));
+						virt_to_phys(entry));
 
 #ifdef CONFIG_VFP
 	vfp_flush_context();
 #endif
 
 #ifdef CONFIG_CACHE_L2X0
-	l2x0_suspend();
+	if (!cpu_is_msm8625())
+		l2x0_suspend();
 #endif
 
 	collapsed = msm_pm_collapse();
 
 #ifdef CONFIG_CACHE_L2X0
-	l2x0_resume(collapsed);
+	if (!cpu_is_msm8625())
+		l2x0_resume(collapsed);
 #endif
 
 	msm_pm_boot_config_after_pc(smp_processor_id());
@@ -1321,18 +1346,6 @@
 }
 
 /*
- * Apps-sleep the Apps processor.  This function execute the handshake
- * protocol with Modem.
- *
- * Return value:
- *      -ENOSYS: function not implemented yet
- */
-static int msm_pm_apps_sleep(uint32_t sleep_delay, uint32_t sleep_limit)
-{
-	return -ENOSYS;
-}
-
-/*
  * Bring the Apps processor to SWFI.
  *
  * Return value:
@@ -1353,7 +1366,9 @@
 			return -EIO;
 	}
 
-	msm_pm_config_hw_before_swfi();
+	if (!cpu_is_msm8625())
+		msm_pm_config_hw_before_swfi();
+
 	msm_arch_idle();
 
 	if (ramp_acpu) {
@@ -1395,7 +1410,7 @@
 	int64_t t1;
 	static int64_t t2;
 	int exit_stat;
- #endif /* CONFIG_MSM_IDLE_STATS */
+ #endif
 
 	if (!atomic_read(&msm_pm_init_done))
 		return;
@@ -1412,19 +1427,19 @@
 
 	exit_stat = MSM_PM_STAT_IDLE_SPIN;
 	low_power = 0;
-#endif /* CONFIG_MSM_IDLE_STATS */
+#endif
 
 	for (i = 0; i < ARRAY_SIZE(allow); i++)
 		allow[i] = true;
 
-	if ((timer_expiration < msm_pm_idle_sleep_min_time) ||
+	if (num_online_cpus() > 1 ||
+		(timer_expiration < msm_pm_idle_sleep_min_time) ||
 #ifdef CONFIG_HAS_WAKELOCK
 		has_wake_lock(WAKE_LOCK_IDLE) ||
 #endif
 		!msm_irq_idle_sleep_allowed()) {
 		allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = false;
 		allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN] = false;
-		allow[MSM_PM_SLEEP_MODE_APPS_SLEEP] = false;
 	}
 
 	for (i = 0; i < ARRAY_SIZE(allow); i++) {
@@ -1493,32 +1508,15 @@
 			exit_stat = MSM_PM_STAT_IDLE_POWER_COLLAPSE;
 			msm_pm_sleep_limit = sleep_limit;
 		}
-#endif /* CONFIG_MSM_IDLE_STATS */
-	} else if (allow[MSM_PM_SLEEP_MODE_APPS_SLEEP]) {
-		uint32_t sleep_delay;
-
-		sleep_delay = (uint32_t) msm_pm_convert_and_cap_time(
-			timer_expiration, MSM_PM_SLEEP_TICK_LIMIT);
-		if (sleep_delay == 0) /* 0 would mean infinite time */
-			sleep_delay = 1;
-
-		ret = msm_pm_apps_sleep(sleep_delay, sleep_limit);
-		low_power = 0;
-
-#ifdef CONFIG_MSM_IDLE_STATS
-		if (ret)
-			exit_stat = MSM_PM_STAT_IDLE_FAILED_SLEEP;
-		else
-			exit_stat = MSM_PM_STAT_IDLE_SLEEP;
-#endif /* CONFIG_MSM_IDLE_STATS */
+#endif
 	} else if (allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE]) {
-		ret = msm_pm_power_collapse_standalone();
+		ret = msm_pm_power_collapse_standalone(true);
 		low_power = 0;
 #ifdef CONFIG_MSM_IDLE_STATS
 		exit_stat = ret ?
 			MSM_PM_STAT_IDLE_FAILED_STANDALONE_POWER_COLLAPSE :
 			MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE;
-#endif /* CONFIG_MSM_IDLE_STATS */
+#endif
 	} else if (allow[MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT]) {
 		ret = msm_pm_swfi(true);
 		if (ret)
@@ -1527,20 +1525,20 @@
 		low_power = 0;
 #ifdef CONFIG_MSM_IDLE_STATS
 		exit_stat = ret ? MSM_PM_STAT_IDLE_SPIN : MSM_PM_STAT_IDLE_WFI;
-#endif /* CONFIG_MSM_IDLE_STATS */
+#endif
 	} else if (allow[MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT]) {
 		msm_pm_swfi(false);
 		low_power = 0;
 #ifdef CONFIG_MSM_IDLE_STATS
 		exit_stat = MSM_PM_STAT_IDLE_WFI;
-#endif /* CONFIG_MSM_IDLE_STATS */
+#endif
 	} else {
 		while (!msm_irq_pending())
 			udelay(1);
 		low_power = 0;
 #ifdef CONFIG_MSM_IDLE_STATS
 		exit_stat = MSM_PM_STAT_IDLE_SPIN;
-#endif /* CONFIG_MSM_IDLE_STATS */
+#endif
 	}
 
 	msm_timer_exit_idle(low_power);
@@ -1548,13 +1546,14 @@
 #ifdef CONFIG_MSM_IDLE_STATS
 	t2 = ktime_to_ns(ktime_get());
 	msm_pm_add_stat(exit_stat, t2 - t1);
-#endif /* CONFIG_MSM_IDLE_STATS */
+#endif
 }
 
 /*
  * Suspend the Apps processor.
  *
  * Return value:
+ *	-EPERM: Suspend happened by a not permitted core
  *      -EAGAIN: modem reset occurred or early exit from suspend
  *      -EBUSY: modem not ready for our suspend
  *      -EINVAL: invalid sleep mode
@@ -1566,13 +1565,20 @@
 {
 	bool allow[MSM_PM_SLEEP_MODE_NR];
 	uint32_t sleep_limit = SLEEP_LIMIT_NONE;
-	int ret;
+	int ret = -EPERM;
 	int i;
-
 #ifdef CONFIG_MSM_IDLE_STATS
 	int64_t period = 0;
 	int64_t time = 0;
+#endif
 
+	/* Must executed by CORE0 */
+	if (smp_processor_id()) {
+		__WARN();
+		goto suspend_exit;
+	}
+
+#ifdef CONFIG_MSM_IDLE_STATS
 	time = msm_timer_get_sclk_time(&period);
 #endif
 
@@ -1589,8 +1595,6 @@
 			allow[i] = false;
 	}
 
-	ret = 0;
-
 	if (allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE] ||
 		allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN]) {
 #ifdef CONFIG_MSM_IDLE_STATS
@@ -1647,7 +1651,7 @@
 		msm_pm_add_stat(id, time);
 #endif
 	} else if (allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE]) {
-		ret = msm_pm_power_collapse_standalone();
+		ret = msm_pm_power_collapse_standalone(false);
 	} else if (allow[MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT]) {
 		ret = msm_pm_swfi(true);
 		if (ret)
@@ -1657,6 +1661,7 @@
 		msm_pm_swfi(false);
 	}
 
+suspend_exit:
 	MSM_PM_DPRINTK(MSM_PM_DEBUG_SUSPEND, KERN_INFO,
 		"%s(): return %d\n", __func__, ret);
 
@@ -1673,7 +1678,27 @@
  */
 void msm_pm_cpu_enter_lowpower(unsigned int cpu)
 {
-	return;
+	bool allow[MSM_PM_SLEEP_MODE_NR];
+	int i;
+
+	for (i = 0; i < MSM_PM_SLEEP_MODE_NR; i++) {
+		struct msm_pm_platform_data *mode;
+
+		mode = &msm_pm_modes[MSM_PM_MODE(cpu, i)];
+		allow[i] = mode->suspend_supported && mode->suspend_enabled;
+	}
+
+	MSM_PM_DPRINTK(MSM_PM_DEBUG_HOTPLUG, KERN_INFO,
+		"CPU%u: %s: shutting down cpu\n", cpu, __func__);
+
+	if (allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE]) {
+		msm_pm_power_collapse_standalone(false);
+	} else if (allow[MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT]) {
+		msm_pm_swfi(false);
+	} else {
+		MSM_PM_DPRINTK(MSM_PM_DEBUG_HOTPLUG, KERN_INFO,
+			"CPU%u: %s: shutting down failed!!!\n", cpu, __func__);
+	}
 }
 
 /******************************************************************************
@@ -1725,10 +1750,6 @@
 };
 
 
-/******************************************************************************
- *
- *****************************************************************************/
-
 /*
  * Initialize the power management subsystem.
  *
@@ -1837,15 +1858,6 @@
 			first_bucket_time =
 			CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
 
-		stats[MSM_PM_STAT_IDLE_SLEEP].name = "idle-sleep";
-		stats[MSM_PM_STAT_IDLE_SLEEP].first_bucket_time =
-			CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
-
-		stats[MSM_PM_STAT_IDLE_FAILED_SLEEP].name =
-			"idle-failed-sleep";
-		stats[MSM_PM_STAT_IDLE_FAILED_SLEEP].first_bucket_time =
-			CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
-
 		stats[MSM_PM_STAT_IDLE_POWER_COLLAPSE].name =
 			"idle-power-collapse";
 		stats[MSM_PM_STAT_IDLE_POWER_COLLAPSE].first_bucket_time =
diff --git a/arch/arm/mach-msm/qdsp5/audio_voicememo.c b/arch/arm/mach-msm/qdsp5/audio_voicememo.c
index 7a962b2..2011c42 100644
--- a/arch/arm/mach-msm/qdsp5/audio_voicememo.c
+++ b/arch/arm/mach-msm/qdsp5/audio_voicememo.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * This code is based in part on arch/arm/mach-msm/qdsp5/audio_mp3.c
  *
@@ -836,6 +836,7 @@
 
 	file->private_data = audio;
 	audio->opened = 1;
+	audio->stopped = 0;
 	rc = 0;
 done:
 	mutex_unlock(&audio->lock);
diff --git a/arch/arm/mach-msm/qdsp5v2/adsp.c b/arch/arm/mach-msm/qdsp5v2/adsp.c
index b7b56c8..acd9c4c 100644
--- a/arch/arm/mach-msm/qdsp5v2/adsp.c
+++ b/arch/arm/mach-msm/qdsp5v2/adsp.c
@@ -2,7 +2,7 @@
  * Register/Interrupt access for userspace aDSP library.
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2009,2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009,2011-2012 Code Aurora Forum. All rights reserved.
  * Author: Iliyan Malchev <ibm@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -46,8 +46,6 @@
 static int wdump, rdump;
 #endif /* CONFIG_DEBUG_FS */
 
-#define INT_ADSP INT_ADSP_A9_A11
-
 static struct adsp_info adsp_info;
 static struct msm_adsp_module *adsp_modules;
 static int adsp_open_count;
@@ -889,7 +887,7 @@
 
 		mutex_lock(&adsp_open_lock);
 		if (adsp_open_count++ == 0)
-			enable_irq(INT_ADSP);
+			enable_irq(adsp_info.int_adsp);
 		mutex_unlock(&adsp_open_lock);
 		break;
 	case ADSP_STATE_ENABLING:
@@ -944,7 +942,7 @@
 		mutex_unlock(&module->lock);
 		mutex_lock(&adsp_open_lock);
 		if (--adsp_open_count == 0) {
-			disable_irq(INT_ADSP);
+			disable_irq(adsp_info.int_adsp);
 			MM_INFO("disable interrupt\n");
 		}
 		mutex_unlock(&adsp_open_lock);
@@ -959,6 +957,12 @@
 	unsigned count;
 	int rc, i;
 
+	adsp_info.int_adsp = platform_get_irq(pdev, 0);
+	if (adsp_info.int_adsp < 0) {
+		MM_ERR("no irq resource?\n");
+		return -ENODEV;
+	}
+
 	adsp_info.init_info_ptr = kzalloc(
 		(sizeof(struct adsp_rtos_mp_mtoa_init_info_type)), GFP_KERNEL);
 	if (!adsp_info.init_info_ptr)
@@ -996,11 +1000,11 @@
 	spin_lock_init(&adsp_cmd_lock);
 	spin_lock_init(&adsp_write_lock);
 
-	rc = request_irq(INT_ADSP, adsp_irq_handler,
+	rc = request_irq(adsp_info.int_adsp, adsp_irq_handler,
 			IRQF_TRIGGER_RISING, "adsp", 0);
 	if (rc < 0)
 		goto fail_request_irq;
-	disable_irq(INT_ADSP);
+	disable_irq(adsp_info.int_adsp);
 
 	for (i = 0; i < count; i++) {
 		struct msm_adsp_module *mod = adsp_modules + i;
@@ -1056,8 +1060,8 @@
 	daldevice_detach(adsp_info.handle);
 	adsp_info.handle = NULL;
 fail_dal_attach:
-	enable_irq(INT_ADSP);
-	free_irq(INT_ADSP, 0);
+	enable_irq(adsp_info.int_adsp);
+	free_irq(adsp_info.int_adsp, 0);
 fail_request_irq:
 	kfree(adsp_modules);
 	kfree(adsp_info.init_info_ptr);
@@ -1187,11 +1191,6 @@
 	},
 };
 
-struct platform_device msm_adsp_device = {
-	.name = "msm_adsp",
-	.id = -1,
-};
-
 static char msm_adsp_driver_name[] = "msm_adsp";
 
 #ifdef CONFIG_DEBUG_FS
@@ -1218,7 +1217,6 @@
 #endif /* CONFIG_DEBUG_FS */
 
 	msm_adsp_driver.driver.name = msm_adsp_driver_name;
-	rc = platform_device_register(&msm_adsp_device);
 	rc = platform_driver_register(&msm_adsp_driver);
 	MM_INFO("%s -- %d\n", msm_adsp_driver_name, rc);
 	return rc;
diff --git a/arch/arm/mach-msm/qdsp5v2/adsp.h b/arch/arm/mach-msm/qdsp5v2/adsp.h
index 18f4046..5aceff9 100644
--- a/arch/arm/mach-msm/qdsp5v2/adsp.h
+++ b/arch/arm/mach-msm/qdsp5v2/adsp.h
@@ -229,6 +229,9 @@
 
 	void *handle;
 	void *cb_handle;
+
+	/* Interrupt value */
+	int int_adsp;
 };
 
 #define ADSP_STATE_DISABLED   0
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c b/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c
index 0a5acce..aaae776 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -17,6 +17,7 @@
 #include <linux/slab.h>
 #include <linux/wait.h>
 #include <linux/sched.h>
+#include <linux/workqueue.h>
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
 #include <mach/qdsp6v2/audio_dev_ctl.h>
@@ -31,6 +32,9 @@
 
 
 static DEFINE_MUTEX(session_lock);
+static struct workqueue_struct *msm_reset_device_work_queue;
+static void reset_device_work(struct work_struct *work);
+static DECLARE_WORK(msm_reset_device_work, reset_device_work);
 
 struct audio_dev_ctrl_state {
 	struct msm_snddev_info *devs[AUDIO_DEV_CTL_MAX_DEV];
@@ -119,6 +123,18 @@
 }
 EXPORT_SYMBOL(msm_reset_all_device);
 
+static void reset_device_work(struct work_struct *work)
+{
+	msm_reset_all_device();
+}
+
+int reset_device(void)
+{
+	queue_work(msm_reset_device_work_queue, &msm_reset_device_work);
+	return 0;
+}
+EXPORT_SYMBOL(reset_device);
+
 int msm_set_copp_id(int session_id, int copp_id)
 {
 	int rc = 0;
@@ -1686,7 +1702,9 @@
 	init_waitqueue_head(&audio_dev_ctrl.wait);
 
 	event.cb = NULL;
-
+	msm_reset_device_work_queue = create_workqueue("reset_device");
+	if (msm_reset_device_work_queue == NULL)
+		return -ENOMEM;
 	atomic_set(&audio_dev_ctrl.opened, 0);
 	audio_dev_ctrl.num_dev = 0;
 	audio_dev_ctrl.voice_tx_dev = NULL;
@@ -1704,6 +1722,7 @@
 
 static void __exit audio_dev_ctrl_exit(void)
 {
+	destroy_workqueue(msm_reset_device_work_queue);
 }
 module_init(audio_dev_ctrl_init);
 module_exit(audio_dev_ctrl_exit);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_lpa.c b/arch/arm/mach-msm/qdsp6v2/audio_lpa.c
index 599198e..41a7387 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_lpa.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_lpa.c
@@ -28,8 +28,8 @@
 #include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/earlysuspend.h>
+#include <linux/ion.h>
 #include <linux/list.h>
-#include <linux/android_pmem.h>
 #include <linux/slab.h>
 #include <asm/atomic.h>
 #include <asm/ioctls.h>
@@ -88,10 +88,10 @@
 	int event_type;
 	union msm_audio_event_payload payload;
 };
-
-struct audlpa_pmem_region {
+struct audlpa_ion_region {
 	struct list_head list;
-	struct file *file;
+	struct ion_handle *handle;
+	struct ion_client *client;
 	int fd;
 	void *vaddr;
 	unsigned long paddr;
@@ -115,12 +115,13 @@
 
 static void audlpa_post_event(struct audio *audio, int type,
 	union msm_audio_event_payload payload);
-static unsigned long audlpa_pmem_fixup(struct audio *audio, void *addr,
+
+static unsigned long audlpa_ion_fixup(struct audio *audio, void *addr,
 				unsigned long len, int ref_up);
+static void audlpa_unmap_ion_region(struct audio *audio);
 static void audlpa_async_send_data(struct audio *audio, unsigned needed,
 				uint32_t token);
 static int audlpa_pause(struct audio *audio);
-static void audlpa_unmap_pmem_region(struct audio *audio);
 static long pcm_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 static int audlpa_set_pcm_params(void *data);
 
@@ -422,7 +423,7 @@
 	    drv_evt->event_type == AUDIO_EVENT_READ_DONE)) {
 		pr_debug("%s: AUDIO_EVENT_WRITE_DONE completing\n", __func__);
 		mutex_lock(&audio->lock);
-		audlpa_pmem_fixup(audio, drv_evt->payload.aio_buf.buf_addr,
+		audlpa_ion_fixup(audio, drv_evt->payload.aio_buf.buf_addr,
 				  drv_evt->payload.aio_buf.buf_len, 0);
 		mutex_unlock(&audio->lock);
 	}
@@ -432,38 +433,41 @@
 	return rc;
 }
 
-static int audlpa_pmem_check(struct audio *audio,
-		void *vaddr, unsigned long len)
+static int audlpa_ion_check(struct audio *audio,
+			void *vaddr, unsigned long len)
 {
-	struct audlpa_pmem_region *region_elt;
-	struct audlpa_pmem_region t = { .vaddr = vaddr, .len = len };
+	struct audlpa_ion_region *region_elt;
+	struct audlpa_ion_region t = {.vaddr = vaddr, .len = len };
 
-	list_for_each_entry(region_elt, &audio->pmem_region_queue, list) {
+	list_for_each_entry(region_elt, &audio->ion_region_queue, list) {
 		if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) ||
 		    OVERLAPS(region_elt, &t)) {
-			pr_err("%s: region (vaddr %p len %ld)"
-				" clashes with registered region"
-				" (vaddr %p paddr %p len %ld)\n",
-				__func__, vaddr, len,
-				region_elt->vaddr,
-				(void *)region_elt->paddr,
-				region_elt->len);
+			pr_err("%s[%p]:region (vaddr %p len %ld)"
+			" clashes with registered region"
+			" (vaddr %p paddr %p len %ld)\n",
+			__func__, audio, vaddr, len,
+			region_elt->vaddr,
+			(void *)region_elt->paddr, region_elt->len);
 			return -EINVAL;
 		}
 	}
 
 	return 0;
 }
-
-static int audlpa_pmem_add(struct audio *audio,
-	struct msm_audio_pmem_info *info)
+static int audlpa_ion_add(struct audio *audio,
+			struct msm_audio_ion_info *info)
 {
-	unsigned long paddr, kvaddr, len;
-	struct file *file;
-	struct audlpa_pmem_region *region;
+	ion_phys_addr_t paddr;
+	size_t len;
+	unsigned long kvaddr;
+	struct audlpa_ion_region *region;
 	int rc = -EINVAL;
+	struct ion_handle *handle;
+	struct ion_client *client;
+	unsigned long ionflag;
+	void *temp_ptr;
 
-	pr_debug("%s:\n", __func__);
+	pr_debug("%s[%p]:\n", __func__, audio);
 	region = kmalloc(sizeof(*region), GFP_KERNEL);
 
 	if (!region) {
@@ -471,61 +475,105 @@
 		goto end;
 	}
 
-	if (get_pmem_file(info->fd, &paddr, &kvaddr, &len, &file)) {
-		kfree(region);
-		goto end;
+	client = msm_ion_client_create(UINT_MAX, "Audio_LPA_Client");
+	if (IS_ERR_OR_NULL(client)) {
+		pr_err("Unable to create ION client\n");
+		goto client_error;
 	}
 
-	rc = audlpa_pmem_check(audio, info->vaddr, len);
+	handle = ion_import_fd(client, info->fd);
+	if (IS_ERR_OR_NULL(handle)) {
+		pr_err("%s: could not get handle of the given fd\n", __func__);
+		goto import_error;
+	}
+
+	rc = ion_handle_get_flags(client, handle, &ionflag);
+	if (rc) {
+		pr_err("%s: could not get flags for the handle\n", __func__);
+		goto flag_error;
+	}
+
+	temp_ptr = ion_map_kernel(client, handle, ionflag);
+	if (IS_ERR_OR_NULL(temp_ptr)) {
+		pr_err("%s: could not get virtual address\n", __func__);
+		goto map_error;
+	}
+	kvaddr = (unsigned long) temp_ptr;
+
+	rc = ion_phys(client, handle, &paddr, &len);
+	if (rc) {
+		pr_err("%s: could not get physical address\n", __func__);
+		goto ion_error;
+	}
+
+	rc = audlpa_ion_check(audio, info->vaddr, len);
 	if (rc < 0) {
-		put_pmem_file(file);
-		kfree(region);
-		goto end;
+		pr_err("%s: audlpa_ion_check failed\n", __func__);
+		goto ion_error;
 	}
 
+	region->client = client;
+	region->handle = handle;
 	region->vaddr = info->vaddr;
 	region->fd = info->fd;
 	region->paddr = paddr;
 	region->kvaddr = kvaddr;
 	region->len = len;
-	region->file = file;
 	region->ref_cnt = 0;
-	pr_debug("%s: add region paddr %lx vaddr %p, len %lu\n", __func__,
-			 region->paddr, region->vaddr,
-			 region->len);
-	list_add_tail(&region->list, &audio->pmem_region_queue);
+	pr_debug("%s[%p]:add region paddr %lx vaddr %p, len %lu kvaddr %lx\n",
+		__func__, audio,
+		region->paddr, region->vaddr, region->len, region->kvaddr);
+	list_add_tail(&region->list, &audio->ion_region_queue);
+
 	rc = q6asm_memory_map(audio->ac, (uint32_t)paddr, IN, (uint32_t)len, 1);
-	if (rc < 0)
-		pr_err("%s: memory map failed\n", __func__);
+	if (rc < 0) {
+		pr_err("%s[%p]: memory map failed\n", __func__, audio);
+		goto ion_error;
+	} else {
+		goto end;
+	}
+
+ion_error:
+	ion_unmap_kernel(client, handle);
+map_error:
+	ion_free(client, handle);
+flag_error:
+import_error:
+	ion_client_destroy(client);
+client_error:
+	kfree(region);
 end:
 	return rc;
 }
 
-static int audlpa_pmem_remove(struct audio *audio,
-	struct msm_audio_pmem_info *info)
+static int audlpa_ion_remove(struct audio *audio,
+			struct msm_audio_ion_info *info)
 {
-	struct audlpa_pmem_region *region;
+	struct audlpa_ion_region *region;
 	struct list_head *ptr, *next;
 	int rc = -EINVAL;
 
-	list_for_each_safe(ptr, next, &audio->pmem_region_queue) {
-		region = list_entry(ptr, struct audlpa_pmem_region, list);
+	list_for_each_safe(ptr, next, &audio->ion_region_queue) {
+		region = list_entry(ptr, struct audlpa_ion_region, list);
 
-		if ((region != NULL) && (region->fd == info->fd) &&
-		    (region->vaddr == info->vaddr)) {
+		if (region != NULL && (region->fd == info->fd) &&
+			(region->vaddr == info->vaddr)) {
 			if (region->ref_cnt) {
-				pr_debug("%s: region %p in use ref_cnt %d\n",
-					__func__, region, region->ref_cnt);
+				pr_debug("%s[%p]:region %p in use ref_cnt %d\n",
+					__func__, audio, region,
+					region->ref_cnt);
 				break;
 			}
 			rc = q6asm_memory_unmap(audio->ac,
-						(uint32_t)region->paddr,
-						IN);
+				(uint32_t) region->paddr, IN);
 			if (rc < 0)
-				pr_err("%s: memory unmap failed\n", __func__);
+				pr_err("%s[%p]: memory unmap failed\n",
+					__func__, audio);
 
 			list_del(&region->list);
-			put_pmem_file(region->file);
+			ion_unmap_kernel(region->client, region->handle);
+			ion_free(region->client, region->handle);
+			ion_client_destroy(region->client);
 			kfree(region);
 			rc = 0;
 			break;
@@ -535,24 +583,21 @@
 	return rc;
 }
 
-static int audlpa_pmem_lookup_vaddr(struct audio *audio, void *addr,
-		     unsigned long len, struct audlpa_pmem_region **region)
+static int audlpa_ion_lookup_vaddr(struct audio *audio, void *addr,
+			unsigned long len, struct audlpa_ion_region **region)
 {
-	struct audlpa_pmem_region *region_elt;
-
+	struct audlpa_ion_region *region_elt;
 	int match_count = 0;
-
 	*region = NULL;
 
 	/* returns physical address or zero */
-	list_for_each_entry(region_elt, &audio->pmem_region_queue,
-		list) {
+	list_for_each_entry(region_elt, &audio->ion_region_queue, list) {
 		if (addr >= region_elt->vaddr &&
-		    addr < region_elt->vaddr + region_elt->len &&
-		    addr + len <= region_elt->vaddr + region_elt->len) {
+			addr < region_elt->vaddr + region_elt->len &&
+			addr + len <= region_elt->vaddr + region_elt->len) {
 			/* offset since we could pass vaddr inside a registerd
-			 * pmem buffer
-			 */
+			* ion buffer
+			*/
 
 			match_count++;
 			if (!*region)
@@ -561,32 +606,33 @@
 	}
 
 	if (match_count > 1) {
-		pr_err("%s: multiple hits for vaddr %p, len %ld\n", __func__,
-			   addr, len);
-		list_for_each_entry(region_elt,
-		  &audio->pmem_region_queue, list) {
-			if (addr >= region_elt->vaddr &&
-			    addr < region_elt->vaddr + region_elt->len &&
-			    addr + len <= region_elt->vaddr + region_elt->len)
-				pr_err("%s: \t%p, %ld --> %p\n", __func__,
-					   region_elt->vaddr, region_elt->len,
-					   (void *)region_elt->paddr);
+		pr_err("%s[%p]:multiple hits for vaddr %p, len %ld\n",
+			 __func__, audio, addr, len);
+		list_for_each_entry(region_elt, &audio->ion_region_queue,
+					list) {
+		if (addr >= region_elt->vaddr &&
+			addr < region_elt->vaddr + region_elt->len &&
+			addr + len <= region_elt->vaddr + region_elt->len)
+			pr_err("\t%s[%p]:%p, %ld --> %p\n",
+				__func__, audio,
+					region_elt->vaddr,
+					region_elt->len,
+					(void *)region_elt->paddr);
 		}
 	}
-
 	return *region ? 0 : -1;
 }
-
-unsigned long audlpa_pmem_fixup(struct audio *audio, void *addr,
-		    unsigned long len, int ref_up)
+static unsigned long audlpa_ion_fixup(struct audio *audio, void *addr,
+			unsigned long len, int ref_up)
 {
-	struct audlpa_pmem_region *region;
+	struct audlpa_ion_region *region;
 	unsigned long paddr;
 	int ret;
 
-	ret = audlpa_pmem_lookup_vaddr(audio, addr, len, &region);
+	ret = audlpa_ion_lookup_vaddr(audio, addr, len, &region);
 	if (ret) {
-		pr_err("%s: lookup (%p, %ld) failed\n", __func__, addr, len);
+		pr_err("%s[%p]:lookup (%p, %ld) failed\n",
+			__func__, audio, addr, len);
 		return 0;
 	}
 	if (ref_up)
@@ -613,7 +659,7 @@
 		return -EFAULT;
 	}
 
-	buf_node->paddr = audlpa_pmem_fixup(
+	buf_node->paddr = audlpa_ion_fixup(
 		audio, buf_node->buf.buf_addr,
 		buf_node->buf.buf_len, 1);
 	if (dir) {
@@ -669,6 +715,9 @@
 		break;
 	case ASM_SESSION_CMDRSP_GET_SESSION_TIME:
 		break;
+	case RESET_EVENTS:
+		reset_device();
+		break;
 	default:
 		break;
 	}
@@ -918,25 +967,26 @@
 		}
 		break;
 
-	case AUDIO_REGISTER_PMEM: {
-			struct msm_audio_pmem_info info;
-			pr_debug("%s: AUDIO_REGISTER_PMEM\n", __func__);
-			if (copy_from_user(&info, (void *) arg, sizeof(info)))
-				rc = -EFAULT;
-			else
-				rc = audlpa_pmem_add(audio, &info);
-			break;
-		}
+	case AUDIO_REGISTER_ION: {
+		struct msm_audio_ion_info info;
+		pr_debug("%s: AUDIO_REGISTER_ION\n", __func__);
+		if (copy_from_user(&info, (void *)arg, sizeof(info)))
+			rc = -EFAULT;
+		else
+			rc = audlpa_ion_add(audio, &info);
+		break;
+	}
 
-	case AUDIO_DEREGISTER_PMEM: {
-			struct msm_audio_pmem_info info;
-			pr_debug("%s: AUDIO_DEREGISTER_PMEM\n", __func__);
-			if (copy_from_user(&info, (void *) arg, sizeof(info)))
-				rc = -EFAULT;
-			else
-				rc = audlpa_pmem_remove(audio, &info);
-			break;
-		}
+	case AUDIO_DEREGISTER_ION: {
+		struct msm_audio_ion_info info;
+		pr_debug("%s: AUDIO_DEREGISTER_ION\n", __func__);
+		if (copy_from_user(&info, (void *)arg, sizeof(info)))
+			rc = -EFAULT;
+		else
+			rc = audlpa_ion_remove(audio, &info);
+		break;
+	}
+
 	case AUDIO_ASYNC_WRITE:
 		pr_debug("%s: AUDIO_ASYNC_WRITE\n", __func__);
 		if (audio->drv_status & ADRV_STATUS_FSYNC)
@@ -1035,34 +1085,37 @@
 	return audlpa_async_fsync(audio);
 }
 
-static void audlpa_reset_pmem_region(struct audio *audio)
+void audlpa_reset_ion_region(struct audio *audio)
 {
-	struct audlpa_pmem_region *region;
+	struct audlpa_ion_region *region;
 	struct list_head *ptr, *next;
 
-	list_for_each_safe(ptr, next, &audio->pmem_region_queue) {
-		region = list_entry(ptr, struct audlpa_pmem_region, list);
+	list_for_each_safe(ptr, next, &audio->ion_region_queue) {
+		region = list_entry(ptr, struct audlpa_ion_region, list);
 		list_del(&region->list);
-		put_pmem_file(region->file);
+		ion_unmap_kernel(region->client, region->handle);
+		ion_free(region->client, region->handle);
+		ion_client_destroy(region->client);
 		kfree(region);
 	}
 
 	return;
 }
 
-static void audlpa_unmap_pmem_region(struct audio *audio)
+static void audlpa_unmap_ion_region(struct audio *audio)
 {
-	struct audlpa_pmem_region *region;
+	struct audlpa_ion_region *region;
 	struct list_head *ptr, *next;
 	int rc = -EINVAL;
 
-	pr_debug("%s:\n", __func__);
-	list_for_each_safe(ptr, next, &audio->pmem_region_queue) {
-		region = list_entry(ptr, struct audlpa_pmem_region, list);
-		pr_debug("%s: phy_address = 0x%lx\n", __func__, region->paddr);
+	pr_debug("%s[%p]:\n", __func__, audio);
+	list_for_each_safe(ptr, next, &audio->ion_region_queue) {
+		region = list_entry(ptr, struct audlpa_ion_region, list);
+		pr_debug("%s[%p]: phy_address = 0x%lx\n",
+			__func__, audio, region->paddr);
 		if (region != NULL) {
 			rc = q6asm_memory_unmap(audio->ac,
-						(uint32_t)region->paddr, IN);
+					(uint32_t)region->paddr, IN);
 			if (rc < 0)
 				pr_err("%s: memory unmap failed\n", __func__);
 		}
@@ -1081,12 +1134,12 @@
 	if (audio->out_enabled)
 		audlpa_async_flush(audio);
 	audio->wflush = 0;
-	audlpa_unmap_pmem_region(audio);
+	audlpa_unmap_ion_region(audio);
 	audio_disable(audio);
 	msm_clear_session_id(audio->ac->session);
 	auddev_unregister_evt_listner(AUDDEV_CLNT_DEC, audio->ac->session);
 	q6asm_audio_client_free(audio->ac);
-	audlpa_reset_pmem_region(audio);
+	audlpa_reset_ion_region(audio);
 #ifdef CONFIG_HAS_EARLYSUSPEND
 	unregister_early_suspend(&audio->suspend_ctl.node);
 #endif
@@ -1096,7 +1149,6 @@
 	audio->event_abort = 1;
 	wake_up(&audio->event_wait);
 	audlpa_reset_event_queue(audio);
-	pmem_kfree(audio->phys);
 	if (audio->stopped == 0)
 		audlpa_allow_sleep(audio);
 	wake_lock_destroy(&audio->wakelock);
@@ -1274,7 +1326,7 @@
 	spin_lock_init(&audio->dsp_lock);
 	init_waitqueue_head(&audio->write_wait);
 	INIT_LIST_HEAD(&audio->out_queue);
-	INIT_LIST_HEAD(&audio->pmem_region_queue);
+	INIT_LIST_HEAD(&audio->ion_region_queue);
 	INIT_LIST_HEAD(&audio->free_event_queue);
 	INIT_LIST_HEAD(&audio->event_queue);
 	init_waitqueue_head(&audio->wait);
@@ -1339,7 +1391,6 @@
 	return rc;
 err:
 	q6asm_audio_client_free(audio->ac);
-	pmem_kfree(audio->phys);
 	kfree(audio);
 	return rc;
 }
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_lpa.h b/arch/arm/mach-msm/qdsp6v2/audio_lpa.h
index ffc27ad..34b53f2 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_lpa.h
+++ b/arch/arm/mach-msm/qdsp6v2/audio_lpa.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -88,7 +88,7 @@
 
 	uint32_t device_events;
 
-	struct list_head pmem_region_queue; /* protected by lock */
+	struct list_head ion_region_queue; /* protected by lock */
 
 	int eq_enable;
 	int eq_needs_commit;
diff --git a/arch/arm/mach-msm/qdsp6v2/pcm_in.c b/arch/arm/mach-msm/qdsp6v2/pcm_in.c
index 1f20aa7..667628c 100644
--- a/arch/arm/mach-msm/qdsp6v2/pcm_in.c
+++ b/arch/arm/mach-msm/qdsp6v2/pcm_in.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -72,6 +72,9 @@
 	case ASM_DATA_EVENT_READ_DONE:
 		pcm_in_get_dsp_buffers(pcm, token, payload);
 		break;
+	case RESET_EVENTS:
+		reset_device();
+		break;
 	default:
 		break;
 	}
diff --git a/arch/arm/mach-msm/qdsp6v2/pcm_out.c b/arch/arm/mach-msm/qdsp6v2/pcm_out.c
index a4a6b72..733d5e3 100644
--- a/arch/arm/mach-msm/qdsp6v2/pcm_out.c
+++ b/arch/arm/mach-msm/qdsp6v2/pcm_out.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2009 Google, Inc.
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -66,6 +66,9 @@
 		atomic_inc(&pcm->out_count);
 		wake_up(&pcm->write_wait);
 		break;
+	case RESET_EVENTS:
+		reset_device();
+		break;
 	default:
 		break;
 	}
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index bca1e0c..9321b40 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -72,6 +72,7 @@
 	MSM_SMSM_DEBUG = 1U << 1,
 	MSM_SMD_INFO = 1U << 2,
 	MSM_SMSM_INFO = 1U << 3,
+	MSM_SMx_POWER_INFO = 1U << 4,
 };
 
 struct smsm_shared_info {
@@ -117,29 +118,34 @@
 };
 
 static irqreturn_t smd_modem_irq_handler(int irq, void *data);
+static irqreturn_t smsm_modem_irq_handler(int irq, void *data);
 static irqreturn_t smd_dsp_irq_handler(int irq, void *data);
+static irqreturn_t smsm_dsp_irq_handler(int irq, void *data);
 static irqreturn_t smd_dsps_irq_handler(int irq, void *data);
+static irqreturn_t smsm_dsps_irq_handler(int irq, void *data);
 static irqreturn_t smd_wcnss_irq_handler(int irq, void *data);
+static irqreturn_t smsm_wcnss_irq_handler(int irq, void *data);
 static irqreturn_t smsm_irq_handler(int irq, void *data);
 
 static struct interrupt_config private_intr_config[NUM_SMD_SUBSYSTEMS] = {
 	[SMD_MODEM] = {
 		.smd.irq_handler = smd_modem_irq_handler,
-		.smsm.irq_handler = smsm_irq_handler,
+		.smsm.irq_handler = smsm_modem_irq_handler,
 	},
 	[SMD_Q6] = {
 		.smd.irq_handler = smd_dsp_irq_handler,
-		.smsm.irq_handler = smsm_irq_handler,
+		.smsm.irq_handler = smsm_dsp_irq_handler,
 	},
 	[SMD_DSPS] = {
 		.smd.irq_handler = smd_dsps_irq_handler,
-		.smsm.irq_handler = smsm_irq_handler,
+		.smsm.irq_handler = smsm_dsps_irq_handler,
 	},
 	[SMD_WCNSS] = {
 		.smd.irq_handler = smd_wcnss_irq_handler,
-		.smsm.irq_handler = smsm_irq_handler,
+		.smsm.irq_handler = smsm_wcnss_irq_handler,
 	},
 };
+struct interrupt_stat interrupt_stats[NUM_SMD_SUBSYSTEMS];
 
 #define SMSM_STATE_ADDR(entry)           (smsm_info.state + entry)
 #define SMSM_INTR_MASK_ADDR(entry, host) (smsm_info.intr_mask + \
@@ -175,11 +181,16 @@
 		if (msm_smd_debug_mask & MSM_SMSM_INFO) \
 			printk(KERN_INFO x);		\
 	} while (0)
+#define SMx_POWER_INFO(x...) do {				\
+		if (msm_smd_debug_mask & MSM_SMx_POWER_INFO) \
+			printk(KERN_INFO x);		\
+	} while (0)
 #else
 #define SMD_DBG(x...) do { } while (0)
 #define SMSM_DBG(x...) do { } while (0)
 #define SMD_INFO(x...) do { } while (0)
 #define SMSM_INFO(x...) do { } while (0)
+#define SMx_POWER_INFO(x...) do { } while (0)
 #endif
 
 static unsigned last_heap_free = 0xffffffff;
@@ -214,24 +225,6 @@
 #define MSM_TRIG_A2DSPS_SMSM_INT
 #define MSM_TRIG_A2WCNSS_SMD_INT
 #define MSM_TRIG_A2WCNSS_SMSM_INT
-#elif defined(CONFIG_ARCH_MSM8960) || defined(CONFIG_ARCH_MSM8930) || \
-	defined(CONFIG_ARCH_APQ8064)
-#define MSM_TRIG_A2M_SMD_INT     \
-			(smd_write_intr(1 << 3, MSM_APCS_GCC_BASE + 0x8))
-#define MSM_TRIG_A2Q6_SMD_INT    \
-			(smd_write_intr(1 << 15, MSM_APCS_GCC_BASE + 0x8))
-#define MSM_TRIG_A2M_SMSM_INT    \
-			(smd_write_intr(1 << 4, MSM_APCS_GCC_BASE + 0x8))
-#define MSM_TRIG_A2Q6_SMSM_INT   \
-			(smd_write_intr(1 << 14, MSM_APCS_GCC_BASE + 0x8))
-#define MSM_TRIG_A2DSPS_SMD_INT  \
-			(smd_write_intr(1, MSM_SIC_NON_SECURE_BASE + 0x4080))
-#define MSM_TRIG_A2DSPS_SMSM_INT \
-			(smd_write_intr(1, MSM_SIC_NON_SECURE_BASE + 0x4094))
-#define MSM_TRIG_A2WCNSS_SMD_INT  \
-			(smd_write_intr(1 << 25, MSM_APCS_GCC_BASE + 0x8))
-#define MSM_TRIG_A2WCNSS_SMSM_INT  \
-			(smd_write_intr(1 << 23, MSM_APCS_GCC_BASE + 0x8))
 #elif defined(CONFIG_ARCH_MSM9615)
 #define MSM_TRIG_A2M_SMD_INT     \
 			(smd_write_intr(1 << 3, MSM_APCS_GCC_BASE + 0x8))
@@ -258,15 +251,33 @@
 #define MSM_TRIG_A2DSPS_SMSM_INT
 #define MSM_TRIG_A2WCNSS_SMD_INT
 #define MSM_TRIG_A2WCNSS_SMSM_INT
-#else
+#elif defined(CONFIG_ARCH_MSM7X01A) || defined(CONFIG_ARCH_MSM7x25)
 #define MSM_TRIG_A2M_SMD_INT     \
 			(smd_write_intr(1, MSM_CSR_BASE + 0x400 + (0) * 4))
-#define MSM_TRIG_A2Q6_SMD_INT    \
-			(smd_write_intr(1, MSM_CSR_BASE + 0x400 + (8) * 4))
+#define MSM_TRIG_A2Q6_SMD_INT
 #define MSM_TRIG_A2M_SMSM_INT    \
 			(smd_write_intr(1, MSM_CSR_BASE + 0x400 + (5) * 4))
-#define MSM_TRIG_A2Q6_SMSM_INT   \
-			(smd_write_intr(1, MSM_CSR_BASE + 0x400 + (8) * 4))
+#define MSM_TRIG_A2Q6_SMSM_INT
+#define MSM_TRIG_A2DSPS_SMD_INT
+#define MSM_TRIG_A2DSPS_SMSM_INT
+#define MSM_TRIG_A2WCNSS_SMD_INT
+#define MSM_TRIG_A2WCNSS_SMSM_INT
+#elif defined(CONFIG_ARCH_MSM7X27) || defined(CONFIG_ARCH_MSM7X27A)
+#define MSM_TRIG_A2M_SMD_INT     \
+			(smd_write_intr(1, MSM_CSR_BASE + 0x400 + (0) * 4))
+#define MSM_TRIG_A2Q6_SMD_INT
+#define MSM_TRIG_A2M_SMSM_INT    \
+			(smd_write_intr(1, MSM_CSR_BASE + 0x400 + (5) * 4))
+#define MSM_TRIG_A2Q6_SMSM_INT
+#define MSM_TRIG_A2DSPS_SMD_INT
+#define MSM_TRIG_A2DSPS_SMSM_INT
+#define MSM_TRIG_A2WCNSS_SMD_INT
+#define MSM_TRIG_A2WCNSS_SMSM_INT
+#else /* use platform device / device tree configuration */
+#define MSM_TRIG_A2M_SMD_INT
+#define MSM_TRIG_A2Q6_SMD_INT
+#define MSM_TRIG_A2M_SMSM_INT
+#define MSM_TRIG_A2Q6_SMSM_INT
 #define MSM_TRIG_A2DSPS_SMD_INT
 #define MSM_TRIG_A2DSPS_SMSM_INT
 #define MSM_TRIG_A2WCNSS_SMD_INT
@@ -349,33 +360,42 @@
 {
 	static const struct interrupt_config_item *intr
 	   = &private_intr_config[SMD_MODEM].smd;
-	if (intr->out_base)
+	if (intr->out_base) {
+		++interrupt_stats[SMD_MODEM].smd_out_config_count;
 		smd_write_intr(intr->out_bit_pos,
 		intr->out_base + intr->out_offset);
-	else
+	} else {
+		++interrupt_stats[SMD_MODEM].smd_out_hardcode_count;
 		MSM_TRIG_A2M_SMD_INT;
+	}
 }
 
 static inline void notify_dsp_smd(void)
 {
 	static const struct interrupt_config_item *intr
 		= &private_intr_config[SMD_Q6].smd;
-	if (intr->out_base)
+	if (intr->out_base) {
+		++interrupt_stats[SMD_Q6].smd_out_config_count;
 		smd_write_intr(intr->out_bit_pos,
 		intr->out_base + intr->out_offset);
-	else
+	} else {
+		++interrupt_stats[SMD_Q6].smd_out_hardcode_count;
 		MSM_TRIG_A2Q6_SMD_INT;
+	}
 }
 
 static inline void notify_dsps_smd(void)
 {
 	static const struct interrupt_config_item *intr
 		= &private_intr_config[SMD_DSPS].smd;
-	if (intr->out_base)
+	if (intr->out_base) {
+		++interrupt_stats[SMD_DSPS].smd_out_config_count;
 		smd_write_intr(intr->out_bit_pos,
 		intr->out_base + intr->out_offset);
-	else
+	} else {
+		++interrupt_stats[SMD_DSPS].smd_out_hardcode_count;
 		MSM_TRIG_A2DSPS_SMD_INT;
+	}
 }
 
 static inline void notify_wcnss_smd(void)
@@ -384,44 +404,56 @@
 		= &private_intr_config[SMD_WCNSS].smd;
 	wakeup_v1_riva();
 
-	if (intr->out_base)
+	if (intr->out_base) {
+		++interrupt_stats[SMD_WCNSS].smd_out_config_count;
 		smd_write_intr(intr->out_bit_pos,
 		intr->out_base + intr->out_offset);
-	else
+	} else {
+		++interrupt_stats[SMD_WCNSS].smd_out_hardcode_count;
 		MSM_TRIG_A2WCNSS_SMD_INT;
+	}
 }
 
 static inline void notify_modem_smsm(void)
 {
 	static const struct interrupt_config_item *intr
 		= &private_intr_config[SMD_MODEM].smsm;
-	if (intr->out_base)
+	if (intr->out_base) {
+		++interrupt_stats[SMD_MODEM].smsm_out_config_count;
 		smd_write_intr(intr->out_bit_pos,
 		intr->out_base + intr->out_offset);
-	else
+	} else {
+		++interrupt_stats[SMD_MODEM].smsm_out_hardcode_count;
 		MSM_TRIG_A2M_SMSM_INT;
+	}
 }
 
 static inline void notify_dsp_smsm(void)
 {
 	static const struct interrupt_config_item *intr
 		= &private_intr_config[SMD_Q6].smsm;
-	if (intr->out_base)
+	if (intr->out_base) {
+		++interrupt_stats[SMD_Q6].smsm_out_config_count;
 		smd_write_intr(intr->out_bit_pos,
 		intr->out_base + intr->out_offset);
-	else
+	} else {
+		++interrupt_stats[SMD_Q6].smsm_out_hardcode_count;
 		MSM_TRIG_A2Q6_SMSM_INT;
+	}
 }
 
 static inline void notify_dsps_smsm(void)
 {
 	static const struct interrupt_config_item *intr
 		= &private_intr_config[SMD_DSPS].smsm;
-	if (intr->out_base)
+	if (intr->out_base) {
+		++interrupt_stats[SMD_DSPS].smsm_out_config_count;
 		smd_write_intr(intr->out_bit_pos,
 		intr->out_base + intr->out_offset);
-	else
+	} else {
+		++interrupt_stats[SMD_DSPS].smsm_out_hardcode_count;
 		MSM_TRIG_A2DSPS_SMSM_INT;
+	}
 }
 
 static inline void notify_wcnss_smsm(void)
@@ -430,11 +462,14 @@
 		= &private_intr_config[SMD_WCNSS].smsm;
 	wakeup_v1_riva();
 
-	if (intr->out_base)
+	if (intr->out_base) {
+		++interrupt_stats[SMD_WCNSS].smsm_out_config_count;
 		smd_write_intr(intr->out_bit_pos,
 		intr->out_base + intr->out_offset);
-	else
+	} else {
+		++interrupt_stats[SMD_WCNSS].smsm_out_hardcode_count;
 		MSM_TRIG_A2WCNSS_SMSM_INT;
+	}
 }
 
 static void notify_other_smsm(uint32_t smsm_entry, uint32_t notify_mask)
@@ -589,27 +624,28 @@
 struct edge_to_pid {
 	uint32_t	local_pid;
 	uint32_t	remote_pid;
+	char		subsys_name[SMD_MAX_CH_NAME_LEN];
 };
 
 /**
  * Maps edge type to local and remote processor ID's.
  */
 static struct edge_to_pid edge_to_pids[] = {
-	[SMD_APPS_MODEM] = {SMSM_APPS, SMSM_MODEM},
-	[SMD_APPS_QDSP] = {SMSM_APPS, SMSM_Q6},
-	[SMD_MODEM_QDSP] = {SMSM_MODEM, SMSM_Q6},
-	[SMD_APPS_DSPS] = {SMSM_APPS, SMSM_DSPS},
-	[SMD_MODEM_DSPS] = {SMSM_MODEM, SMSM_DSPS},
-	[SMD_QDSP_DSPS] = {SMSM_Q6, SMSM_DSPS},
-	[SMD_APPS_WCNSS] = {SMSM_APPS, SMSM_WCNSS},
-	[SMD_MODEM_WCNSS] = {SMSM_MODEM, SMSM_WCNSS},
-	[SMD_QDSP_WCNSS] = {SMSM_Q6, SMSM_WCNSS},
-	[SMD_DSPS_WCNSS] = {SMSM_DSPS, SMSM_WCNSS},
-	[SMD_APPS_Q6FW] = {SMSM_APPS, SMD_MODEM_Q6_FW},
-	[SMD_MODEM_Q6FW] = {SMSM_MODEM, SMD_MODEM_Q6_FW},
-	[SMD_QDSP_Q6FW] = {SMSM_Q6, SMD_MODEM_Q6_FW},
-	[SMD_DSPS_Q6FW] = {SMSM_DSPS, SMD_MODEM_Q6_FW},
-	[SMD_WCNSS_Q6FW] = {SMSM_WCNSS, SMD_MODEM_Q6_FW},
+	[SMD_APPS_MODEM] = {SMD_APPS, SMD_MODEM, "modem"},
+	[SMD_APPS_QDSP] = {SMD_APPS, SMD_Q6, "q6"},
+	[SMD_MODEM_QDSP] = {SMD_MODEM, SMD_Q6},
+	[SMD_APPS_DSPS] = {SMD_APPS, SMD_DSPS, "dsps"},
+	[SMD_MODEM_DSPS] = {SMD_MODEM, SMD_DSPS},
+	[SMD_QDSP_DSPS] = {SMD_Q6, SMD_DSPS},
+	[SMD_APPS_WCNSS] = {SMD_APPS, SMD_WCNSS, "wcnss"},
+	[SMD_MODEM_WCNSS] = {SMD_MODEM, SMD_WCNSS},
+	[SMD_QDSP_WCNSS] = {SMD_Q6, SMD_WCNSS},
+	[SMD_DSPS_WCNSS] = {SMD_DSPS, SMD_WCNSS},
+	[SMD_APPS_Q6FW] = {SMD_APPS, SMD_MODEM_Q6_FW},
+	[SMD_MODEM_Q6FW] = {SMD_MODEM, SMD_MODEM_Q6_FW},
+	[SMD_QDSP_Q6FW] = {SMD_Q6, SMD_MODEM_Q6_FW},
+	[SMD_DSPS_Q6FW] = {SMD_DSPS, SMD_MODEM_Q6_FW},
+	[SMD_WCNSS_Q6FW] = {SMD_WCNSS, SMD_MODEM_Q6_FW},
 };
 
 struct restart_notifier_block {
@@ -721,6 +757,50 @@
 	return ret;
 }
 
+/*
+ * Returns a pointer to the subsystem name or NULL if no
+ * subsystem name is available.
+ *
+ * @type - Edge definition
+ */
+const char *smd_edge_to_subsystem(uint32_t type)
+{
+	const char *subsys = NULL;
+
+	if (type < ARRAY_SIZE(edge_to_pids)) {
+		subsys = edge_to_pids[type].subsys_name;
+		if (subsys[0] == 0x0)
+			subsys = NULL;
+	}
+	return subsys;
+}
+EXPORT_SYMBOL(smd_edge_to_subsystem);
+
+/*
+ * Returns a pointer to the subsystem name given the
+ * remote processor ID.
+ *
+ * @pid     Remote processor ID
+ * @returns Pointer to subsystem name or NULL if not found
+ */
+const char *smd_pid_to_subsystem(uint32_t pid)
+{
+	const char *subsys = NULL;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(edge_to_pids); ++i) {
+		if (pid == edge_to_pids[i].remote_pid &&
+			edge_to_pids[i].subsys_name[0] != 0x0
+			) {
+			subsys = edge_to_pids[i].subsys_name;
+			break;
+		}
+	}
+
+	return subsys;
+}
+EXPORT_SYMBOL(smd_pid_to_subsystem);
+
 static void smd_reset_edge(struct smd_half_channel *ch, unsigned new_state)
 {
 	if (ch->state != SMD_SS_CLOSED) {
@@ -796,9 +876,10 @@
 
 		/* notify SMSM processors */
 		smsm_irq_handler(0, 0);
-		MSM_TRIG_A2M_SMSM_INT;
-		MSM_TRIG_A2Q6_SMSM_INT;
-		MSM_TRIG_A2DSPS_SMSM_INT;
+		notify_modem_smsm();
+		notify_dsp_smsm();
+		notify_dsps_smsm();
+		notify_wcnss_smsm();
 	}
 
 	/* change all remote states to CLOSING */
@@ -1110,15 +1191,24 @@
 		}
 		tmp = ch->recv->state;
 		if (tmp != ch->last_state) {
+			SMx_POWER_INFO("SMD ch%d '%s' State change %d->%d\n",
+					ch->n, ch->name, ch->last_state, tmp);
 			smd_state_change(ch, ch->last_state, tmp);
 			state_change = 1;
 		}
-		if (ch_flags) {
+		if (ch_flags & 0x3) {
 			ch->update_state(ch);
+			SMx_POWER_INFO("SMD ch%d '%s' Data event r%d/w%d\n",
+					ch->n, ch->name,
+					ch->read_avail(ch),
+					ch->fifo_size - ch->write_avail(ch));
 			ch->notify(ch->priv, SMD_EVENT_DATA);
 		}
-		if (ch_flags & 0x4 && !state_change)
+		if (ch_flags & 0x4 && !state_change) {
+			SMx_POWER_INFO("SMD ch%d '%s' State update\n",
+					ch->n, ch->name);
 			ch->notify(ch->priv, SMD_EVENT_STATUS);
+		}
 	}
 	spin_unlock_irqrestore(&smd_lock, flags);
 	do_smd_probe();
@@ -1126,6 +1216,8 @@
 
 static irqreturn_t smd_modem_irq_handler(int irq, void *data)
 {
+	SMx_POWER_INFO("SMD Int Modem->Apps\n");
+	++interrupt_stats[SMD_MODEM].smd_in_count;
 	handle_smd_irq(&smd_ch_list_modem, notify_modem_smd);
 	handle_smd_irq_closing_list();
 	return IRQ_HANDLED;
@@ -1133,6 +1225,8 @@
 
 static irqreturn_t smd_dsp_irq_handler(int irq, void *data)
 {
+	SMx_POWER_INFO("SMD Int LPASS->Apps\n");
+	++interrupt_stats[SMD_Q6].smd_in_count;
 	handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd);
 	handle_smd_irq_closing_list();
 	return IRQ_HANDLED;
@@ -1140,6 +1234,8 @@
 
 static irqreturn_t smd_dsps_irq_handler(int irq, void *data)
 {
+	SMx_POWER_INFO("SMD Int DSPS->Apps\n");
+	++interrupt_stats[SMD_DSPS].smd_in_count;
 	handle_smd_irq(&smd_ch_list_dsps, notify_dsps_smd);
 	handle_smd_irq_closing_list();
 	return IRQ_HANDLED;
@@ -1147,6 +1243,8 @@
 
 static irqreturn_t smd_wcnss_irq_handler(int irq, void *data)
 {
+	SMx_POWER_INFO("SMD Int WCNSS->Apps\n");
+	++interrupt_stats[SMD_WCNSS].smd_in_count;
 	handle_smd_irq(&smd_ch_list_wcnss, notify_wcnss_smd);
 	handle_smd_irq_closing_list();
 	return IRQ_HANDLED;
@@ -2286,6 +2384,34 @@
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t smsm_modem_irq_handler(int irq, void *data)
+{
+	SMx_POWER_INFO("SMSM Int Modem->Apps\n");
+	++interrupt_stats[SMD_MODEM].smsm_in_count;
+	return smsm_irq_handler(irq, data);
+}
+
+static irqreturn_t smsm_dsp_irq_handler(int irq, void *data)
+{
+	SMx_POWER_INFO("SMSM Int LPASS->Apps\n");
+	++interrupt_stats[SMD_Q6].smsm_in_count;
+	return smsm_irq_handler(irq, data);
+}
+
+static irqreturn_t smsm_dsps_irq_handler(int irq, void *data)
+{
+	SMx_POWER_INFO("SMSM Int DSPS->Apps\n");
+	++interrupt_stats[SMD_DSPS].smsm_in_count;
+	return smsm_irq_handler(irq, data);
+}
+
+static irqreturn_t smsm_wcnss_irq_handler(int irq, void *data)
+{
+	SMx_POWER_INFO("SMSM Int WCNSS->Apps\n");
+	++interrupt_stats[SMD_WCNSS].smsm_in_count;
+	return smsm_irq_handler(irq, data);
+}
+
 int smsm_change_intr_mask(uint32_t smsm_entry,
 			  uint32_t clear_mask, uint32_t set_mask)
 {
@@ -2417,6 +2543,9 @@
 
 			state_changes = state_info->last_value ^ new_state;
 			if (state_changes) {
+				SMx_POWER_INFO("SMSM Change %d: %08x->%08x\n",
+						n, state_info->last_value,
+						new_state);
 				list_for_each_entry(cb_info,
 					&state_info->callbacks, cb_list) {
 
@@ -2567,7 +2696,7 @@
 		pr_err("smd_core_init: "
 		       "enable_irq_wake failed for INT_A9_M2A_0\n");
 
-	r = request_irq(INT_A9_M2A_5, smsm_irq_handler,
+	r = request_irq(INT_A9_M2A_5, smsm_modem_irq_handler,
 			flags, "smsm_dev", 0);
 	if (r < 0) {
 		free_irq(INT_A9_M2A_0, 0);
@@ -2590,8 +2719,8 @@
 		return r;
 	}
 
-	r = request_irq(INT_ADSP_A11_SMSM, smsm_irq_handler,
-			flags, "smsm_dev", smsm_irq_handler);
+	r = request_irq(INT_ADSP_A11_SMSM, smsm_dsp_irq_handler,
+			flags, "smsm_dev", smsm_dsp_irq_handler);
 	if (r < 0) {
 		free_irq(INT_A9_M2A_0, 0);
 		free_irq(INT_A9_M2A_5, 0);
@@ -2620,7 +2749,7 @@
 		free_irq(INT_A9_M2A_0, 0);
 		free_irq(INT_A9_M2A_5, 0);
 		free_irq(INT_ADSP_A11, smd_dsp_irq_handler);
-		free_irq(INT_ADSP_A11_SMSM, smsm_irq_handler);
+		free_irq(INT_ADSP_A11_SMSM, smsm_dsp_irq_handler);
 		return r;
 	}
 
@@ -2637,7 +2766,7 @@
 		free_irq(INT_A9_M2A_0, 0);
 		free_irq(INT_A9_M2A_5, 0);
 		free_irq(INT_ADSP_A11, smd_dsp_irq_handler);
-		free_irq(INT_ADSP_A11_SMSM, smsm_irq_handler);
+		free_irq(INT_ADSP_A11_SMSM, smsm_dsp_irq_handler);
 		free_irq(INT_DSPS_A11, smd_dsps_irq_handler);
 		return r;
 	}
@@ -2647,13 +2776,13 @@
 		pr_err("smd_core_init: "
 		       "enable_irq_wake failed for INT_WCNSS_A11\n");
 
-	r = request_irq(INT_WCNSS_A11_SMSM, smsm_irq_handler,
-			flags, "smsm_dev", smsm_irq_handler);
+	r = request_irq(INT_WCNSS_A11_SMSM, smsm_wcnss_irq_handler,
+			flags, "smsm_dev", smsm_wcnss_irq_handler);
 	if (r < 0) {
 		free_irq(INT_A9_M2A_0, 0);
 		free_irq(INT_A9_M2A_5, 0);
 		free_irq(INT_ADSP_A11, smd_dsp_irq_handler);
-		free_irq(INT_ADSP_A11_SMSM, smsm_irq_handler);
+		free_irq(INT_ADSP_A11_SMSM, smsm_dsp_irq_handler);
 		free_irq(INT_DSPS_A11, smd_dsps_irq_handler);
 		free_irq(INT_WCNSS_A11, smd_wcnss_irq_handler);
 		return r;
@@ -2666,16 +2795,16 @@
 #endif
 
 #if defined(CONFIG_DSPS_SMSM)
-	r = request_irq(INT_DSPS_A11_SMSM, smsm_irq_handler,
-			flags, "smsm_dev", smsm_irq_handler);
+	r = request_irq(INT_DSPS_A11_SMSM, smsm_dsps_irq_handler,
+			flags, "smsm_dev", smsm_dsps_irq_handler);
 	if (r < 0) {
 		free_irq(INT_A9_M2A_0, 0);
 		free_irq(INT_A9_M2A_5, 0);
 		free_irq(INT_ADSP_A11, smd_dsp_irq_handler);
-		free_irq(INT_ADSP_A11_SMSM, smsm_irq_handler);
+		free_irq(INT_ADSP_A11_SMSM, smsm_dsp_irq_handler);
 		free_irq(INT_DSPS_A11, smd_dsps_irq_handler);
 		free_irq(INT_WCNSS_A11, smd_wcnss_irq_handler);
-		free_irq(INT_WCNSS_A11_SMSM, smsm_irq_handler);
+		free_irq(INT_WCNSS_A11_SMSM, smsm_wcnss_irq_handler);
 		return r;
 	}
 
@@ -2770,6 +2899,9 @@
 				cfg->smsm_int.irq_name);
 			break;
 		}
+
+		strncpy(edge_to_pids[cfg->edge].subsys_name,
+				cfg->subsys_name, SMD_MAX_CH_NAME_LEN);
 	}
 
 	if (err_ret < 0) {
diff --git a/arch/arm/mach-msm/smd_debug.c b/arch/arm/mach-msm/smd_debug.c
index b95a35c..764102d 100644
--- a/arch/arm/mach-msm/smd_debug.c
+++ b/arch/arm/mach-msm/smd_debug.c
@@ -95,6 +95,61 @@
 	return max;
 }
 
+static int debug_int_stats(char *buf, int max)
+{
+	int i = 0;
+	int subsys;
+	struct interrupt_stat *stats = interrupt_stats;
+	const char *subsys_name;
+
+	i += scnprintf(buf + i, max - i,
+		"   Subsystem    |     In    | Out (Hardcoded) |"
+		" Out (Configured) |\n");
+
+	for (subsys = 0; subsys < NUM_SMD_SUBSYSTEMS; ++subsys) {
+		subsys_name = smd_pid_to_subsystem(subsys);
+		if (subsys_name) {
+			i += scnprintf(buf + i, max - i,
+				"%-10s %4s | %9u |       %9u |        %9u |\n",
+				smd_pid_to_subsystem(subsys), "smd",
+				stats->smd_in_count,
+				stats->smd_out_hardcode_count,
+				stats->smd_out_config_count);
+
+			i += scnprintf(buf + i, max - i,
+				"%-10s %4s | %9u |       %9u |        %9u |\n",
+				smd_pid_to_subsystem(subsys), "smsm",
+				stats->smsm_in_count,
+				stats->smsm_out_hardcode_count,
+				stats->smsm_out_config_count);
+		}
+		++stats;
+	}
+
+	return i;
+}
+
+static int debug_int_stats_reset(char *buf, int max)
+{
+	int i = 0;
+	int subsys;
+	struct interrupt_stat *stats = interrupt_stats;
+
+	i += scnprintf(buf + i, max - i, "Resetting interrupt stats.\n");
+
+	for (subsys = 0; subsys < NUM_SMD_SUBSYSTEMS; ++subsys) {
+		stats->smd_in_count = 0;
+		stats->smd_out_hardcode_count = 0;
+		stats->smd_out_config_count = 0;
+		stats->smsm_in_count = 0;
+		stats->smsm_out_hardcode_count = 0;
+		stats->smsm_out_config_count = 0;
+		++stats;
+	}
+
+	return i;
+}
+
 static int debug_diag(char *buf, int max)
 {
 	int i = 0;
@@ -694,6 +749,8 @@
 	debug_create("modem_err_f3", 0444, dent, debug_modem_err_f3);
 	debug_create("print_diag", 0444, dent, debug_diag);
 	debug_create("print_f3", 0444, dent, debug_f3);
+	debug_create("int_stats", 0444, dent, debug_int_stats);
+	debug_create("int_stats_reset", 0444, dent, debug_int_stats_reset);
 
 	/* NNV: this is google only stuff */
 	debug_create("build", 0444, dent, debug_read_build_id);
diff --git a/arch/arm/mach-msm/smd_pkt.c b/arch/arm/mach-msm/smd_pkt.c
index aeffbfd..158015a 100644
--- a/arch/arm/mach-msm/smd_pkt.c
+++ b/arch/arm/mach-msm/smd_pkt.c
@@ -607,7 +607,7 @@
 {
 	int r = 0;
 	struct smd_pkt_dev *smd_pkt_devp;
-	char *peripheral = NULL;
+	const char *peripheral = NULL;
 
 	smd_pkt_devp = container_of(inode->i_cdev, struct smd_pkt_dev, cdev);
 
@@ -622,12 +622,8 @@
 
 	mutex_lock(&smd_pkt_devp->ch_lock);
 	if (smd_pkt_devp->ch == 0) {
-
-		if (smd_ch_edge[smd_pkt_devp->i] == SMD_APPS_MODEM)
-			peripheral = "modem";
-		else if (smd_ch_edge[smd_pkt_devp->i] == SMD_APPS_QDSP)
-			peripheral = "q6";
-
+		peripheral = smd_edge_to_subsystem(
+				smd_ch_edge[smd_pkt_devp->i]);
 		if (peripheral) {
 			smd_pkt_devp->pil = pil_get(peripheral);
 			if (IS_ERR(smd_pkt_devp->pil)) {
diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h
index a4c60e8..e39c57b 100644
--- a/arch/arm/mach-msm/smd_private.h
+++ b/arch/arm/mach-msm/smd_private.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/smd_private.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -19,6 +19,7 @@
 #include <linux/types.h>
 #include <linux/spinlock.h>
 #include <mach/msm_smsm.h>
+#include <mach/msm_smd.h>
 
 #define PC_APPS  0
 #define PC_MODEM 1
@@ -208,4 +209,15 @@
 
 void smd_diag(void);
 
+struct interrupt_stat {
+	uint32_t smd_in_count;
+	uint32_t smd_out_hardcode_count;
+	uint32_t smd_out_config_count;
+
+	uint32_t smsm_in_count;
+	uint32_t smsm_out_hardcode_count;
+	uint32_t smsm_out_config_count;
+};
+extern struct interrupt_stat interrupt_stats[NUM_SMD_SUBSYSTEMS];
+
 #endif
diff --git a/arch/arm/mach-msm/smd_tty.c b/arch/arm/mach-msm/smd_tty.c
index 4248be4..d856024 100644
--- a/arch/arm/mach-msm/smd_tty.c
+++ b/arch/arm/mach-msm/smd_tty.c
@@ -235,7 +235,7 @@
 	int res = 0;
 	unsigned int n = tty->index;
 	struct smd_tty_info *info;
-	char *peripheral = NULL;
+	const char *peripheral = NULL;
 
 
 	if (n >= MAX_SMD_TTYS || !smd_tty[n].smd)
@@ -247,9 +247,7 @@
 	tty->driver_data = info;
 
 	if (info->open_count++ == 0) {
-		if (smd_tty[n].smd->edge == SMD_APPS_MODEM)
-			peripheral = "modem";
-
+		peripheral = smd_edge_to_subsystem(smd_tty[n].smd->edge);
 		if (peripheral) {
 			info->pil = pil_get(peripheral);
 			if (IS_ERR(info->pil)) {
diff --git a/arch/arm/mach-msm/wcnss-ssr-8960.c b/arch/arm/mach-msm/wcnss-ssr-8960.c
index 9970c90..59abfe6 100644
--- a/arch/arm/mach-msm/wcnss-ssr-8960.c
+++ b/arch/arm/mach-msm/wcnss-ssr-8960.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -35,6 +35,7 @@
 static void riva_fatal_fn(struct work_struct *);
 static DECLARE_WORK(riva_fatal_work, riva_fatal_fn);
 
+static struct delayed_work cancel_vote_work;
 static void *riva_ramdump_dev;
 static int riva_crash;
 static int ss_restart_inprogress;
@@ -97,20 +98,24 @@
 	smsm_change_state(SMSM_APPS_STATE, SMSM_RESET, SMSM_RESET);
 }
 
-/* Subsystem handlers */
-static int riva_shutdown(const struct subsys_data *subsys)
+static void riva_post_bootup(struct work_struct *work)
 {
 	struct platform_device *pdev = wcnss_get_platform_device();
 	struct wcnss_wlan_config *pwlanconfig = wcnss_get_wlan_config();
-	int    ret = -1;
 
+	pr_debug(MODULE_NAME ": Cancel APPS vote for Iris & Riva\n");
+
+	wcnss_wlan_power(&pdev->dev, pwlanconfig,
+		WCNSS_WLAN_SWITCH_OFF);
+}
+
+/* Subsystem handlers */
+static int riva_shutdown(const struct subsys_data *subsys)
+{
 	pil_force_shutdown("wcnss");
+	flush_delayed_work(&cancel_vote_work);
 
-	/* proxy vote on behalf of Riva */
-	if (pdev && pwlanconfig)
-		ret = wcnss_wlan_power(&pdev->dev, pwlanconfig,
-					WCNSS_WLAN_SWITCH_OFF);
-	return ret;
+	return 0;
 }
 
 static int riva_powerup(const struct subsys_data *subsys)
@@ -131,6 +136,7 @@
 	}
 	ss_restart_inprogress = false;
 	enable_irq(RIVA_APSS_WDOG_BITE_RESET_RDY_IRQ);
+	schedule_delayed_work(&cancel_vote_work, msecs_to_jiffies(5000));
 
 	return ret;
 }
@@ -222,6 +228,8 @@
 		ret = -ENOMEM;
 		goto out;
 	}
+	INIT_DELAYED_WORK(&cancel_vote_work, riva_post_bootup);
+
 	pr_info("%s: module initialized\n", MODULE_NAME);
 out:
 	return ret;
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 321abe8..edede47 100755
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -1140,3 +1140,4 @@
 mpq8064_dtv		MACH_MPQ8064_DTV	MPQ8064_DTV		3995
 msm7627a_qrd3		MACH_MSM7627A_QRD3	MSM7627A_QRD3		4005
 msm8625_surf		MACH_MSM8625_SURF	MSM8625_SURF		4037
+msm8625_evb		MACH_MSM8625_EVB	MSM8625_EVB		4042
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index 371d319..a701773 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -228,6 +228,7 @@
 	int hsic_ch;
 	int hsic_device_enabled;
 	int hsic_device_opened;
+	int hsic_suspend;
 	int read_len_mdm;
 	int in_busy_hsic_read_on_mdm;
 	int in_busy_hsic_write_on_mdm;
@@ -238,6 +239,8 @@
 	struct workqueue_struct *diag_hsic_wq;
 	struct work_struct diag_read_mdm_work;
 	struct work_struct diag_read_hsic_work;
+	struct work_struct diag_disconnect_work;
+	struct work_struct diag_usb_read_complete_work;
 	struct diag_request *usb_read_mdm_ptr;
 	struct diag_request *write_ptr_mdm;
 #endif
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index efba92b..d9f12ac 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -48,7 +48,7 @@
 };
 /* The following variables can be specified by module options */
  /* for copy buffer */
-static unsigned int itemsize = 2048; /*Size of item in the mempool */
+static unsigned int itemsize = 4096; /*Size of item in the mempool */
 static unsigned int poolsize = 10; /*Number of items in the mempool */
 /* for hdlc buffer */
 static unsigned int itemsize_hdlc = 8192; /*Size of item in the mempool */
@@ -768,6 +768,14 @@
 		return 0;
 	}
 
+	if (payload_size > itemsize) {
+		pr_err("diag: Dropping packet, packet payload size crosses"
+				"4KB limit. Current payload size %d\n",
+				payload_size);
+		driver->dropped_count++;
+		return -EBADMSG;
+	}
+
 	buf_copy = diagmem_alloc(driver, payload_size, POOL_TYPE_COPY);
 	if (!buf_copy) {
 		driver->dropped_count++;
diff --git a/drivers/char/diag/diagfwd_hsic.c b/drivers/char/diag/diagfwd_hsic.c
index ac5722f..b2080b3 100644
--- a/drivers/char/diag/diagfwd_hsic.c
+++ b/drivers/char/diag/diagfwd_hsic.c
@@ -102,14 +102,16 @@
 						driver->write_ptr_mdm);
 		}
 	} else {
-		pr_err("DIAG in %s: actual_size: %d\n", __func__, actual_size);
+		pr_debug("%s: actual_size: %d\n", __func__, actual_size);
 	}
 
 	/*
 	 * If for some reason there was no hsic data to write to the
 	 * mdm channel, set up another read
 	 */
-	if (!driver->in_busy_hsic_write_on_mdm)
+	if (!driver->in_busy_hsic_write_on_mdm &&
+			driver->usb_mdm_connected &&
+			!driver->hsic_suspend)
 		queue_work(driver->diag_hsic_wq, &driver->diag_read_hsic_work);
 }
 
@@ -127,13 +129,34 @@
 	if (actual_size < 0)
 		pr_err("DIAG in %s: actual_size: %d\n", __func__, actual_size);
 
-	queue_work(driver->diag_hsic_wq, &driver->diag_read_mdm_work);
+	if (driver->usb_mdm_connected)
+		queue_work(driver->diag_hsic_wq, &driver->diag_read_mdm_work);
+}
+
+static int diag_hsic_suspend(void *ctxt)
+{
+	if (driver->in_busy_hsic_write)
+		return -EBUSY;
+
+	driver->hsic_suspend = 1;
+
+	return 0;
+}
+
+static void diag_hsic_resume(void *ctxt)
+{
+	driver->hsic_suspend = 0;
+
+	if (!driver->in_busy_hsic_write_on_mdm && driver->usb_mdm_connected)
+		queue_work(driver->diag_hsic_wq, &driver->diag_read_hsic_work);
 }
 
 static struct diag_bridge_ops hsic_diag_bridge_ops = {
 	.ctxt = NULL,
 	.read_complete_cb = diag_hsic_read_complete_callback,
 	.write_complete_cb = diag_hsic_write_complete_callback,
+	.suspend = diag_hsic_suspend,
+	.resume = diag_hsic_resume,
 };
 
 static int diag_hsic_close(void)
@@ -177,11 +200,11 @@
 				pr_err("DIAG: HSIC channel open error: %d\n",
 					err);
 			} else {
-				pr_info("DIAG: opened HSIC channel\n");
+				pr_debug("DIAG: opened HSIC channel\n");
 				driver->hsic_device_opened = 1;
 			}
 		} else {
-			pr_info("DIAG: HSIC channel already open\n");
+			pr_debug("DIAG: HSIC channel already open\n");
 		}
 
 		/*
@@ -220,9 +243,7 @@
 	driver->in_busy_hsic_read = 1;
 
 	/* Turn off communication over usb mdm and hsic */
-	driver->hsic_ch = 0;
-
-	return 0;
+	return diag_hsic_close();
 }
 
 /*
@@ -311,10 +332,11 @@
 		diagfwd_connect_hsic();
 		break;
 	case USB_DIAG_DISCONNECT:
-		diagfwd_disconnect_hsic();
+		queue_work(driver->diag_hsic_wq, &driver->diag_disconnect_work);
 		break;
 	case USB_DIAG_READ_DONE:
-		diagfwd_read_complete_hsic(d_req);
+		queue_work(driver->diag_hsic_wq,
+				&driver->diag_usb_read_complete_work);
 		break;
 	case USB_DIAG_WRITE_DONE:
 		diagfwd_write_complete_hsic();
@@ -326,6 +348,16 @@
 	}
 }
 
+static void diag_usb_read_complete_fn(struct work_struct *w)
+{
+	diagfwd_read_complete_hsic(driver->usb_read_mdm_ptr);
+}
+
+static void diag_disconnect_work_fn(struct work_struct *w)
+{
+	diagfwd_disconnect_hsic();
+}
+
 static void diag_read_mdm_work_fn(struct work_struct *work)
 {
 	if (!driver->hsic_ch) {
@@ -380,7 +412,6 @@
 		sizeof(struct diag_request), GFP_KERNEL);
 	if (driver->usb_read_mdm_ptr == NULL)
 		goto err;
-	driver->diag_hsic_wq = create_singlethread_workqueue("diag_hsic_wq");
 #ifdef CONFIG_DIAG_OVER_USB
 	INIT_WORK(&(driver->diag_read_mdm_work), diag_read_mdm_work_fn);
 #endif
@@ -413,23 +444,22 @@
 		}
 	}
 
-	/* The hsic (diag_bridge) platform device driver is enabled */
-	err = diag_bridge_open(&hsic_diag_bridge_ops);
-	if (err) {
-		pr_err("DIAG could not open HSIC channel, err: %d\n", err);
-		driver->hsic_device_opened = 0;
-		return err;
-	}
-
-	pr_info("DIAG opened HSIC channel\n");
-	driver->hsic_device_opened = 1;
-
 	/*
 	 * The probe function was called after the usb was connected
 	 * on the legacy channel. Communication over usb mdm and hsic
 	 * needs to be turned on.
 	 */
-	if (driver->usb_connected) {
+	if (driver->usb_mdm_connected) {
+		/* The hsic (diag_bridge) platform device driver is enabled */
+		err = diag_bridge_open(&hsic_diag_bridge_ops);
+		if (err) {
+			pr_err("DIAG could not open HSIC, err: %d\n", err);
+			driver->hsic_device_opened = 0;
+			return err;
+		}
+
+		pr_debug("DIAG opened HSIC channel\n");
+		driver->hsic_device_opened = 1;
 		driver->hsic_ch = 1;
 		driver->in_busy_hsic_write_on_mdm = 0;
 		driver->in_busy_hsic_read_on_mdm = 0;
@@ -448,7 +478,7 @@
 
 static int diag_hsic_remove(struct platform_device *pdev)
 {
-	pr_info("DIAG: %s called\n", __func__);
+	pr_debug("DIAG: %s called\n", __func__);
 	diag_hsic_close();
 	return 0;
 }
@@ -487,6 +517,11 @@
 
 	pr_debug("DIAG in %s\n", __func__);
 
+	driver->diag_hsic_wq = create_singlethread_workqueue("diag_hsic_wq");
+	INIT_WORK(&(driver->diag_disconnect_work), diag_disconnect_work_fn);
+	INIT_WORK(&(driver->diag_usb_read_complete_work),
+			diag_usb_read_complete_fn);
+
 #ifdef CONFIG_DIAG_OVER_USB
 	driver->mdm_ch = usb_diag_open(DIAG_MDM, driver, diagfwd_hsic_notifier);
 	if (IS_ERR(driver->mdm_ch)) {
diff --git a/drivers/char/msm_rotator.c b/drivers/char/msm_rotator.c
index bd48925..3d9c9d1 100644
--- a/drivers/char/msm_rotator.c
+++ b/drivers/char/msm_rotator.c
@@ -749,7 +749,8 @@
 }
 
 static int get_img(struct msmfb_data *fbd, unsigned long *start,
-	unsigned long *len, struct file **p_file, struct ion_handle **p_ihdl)
+	unsigned long *len, struct file **p_file, int *p_need,
+	struct ion_handle **p_ihdl)
 {
 	int ret = 0;
 #ifdef CONFIG_FB
@@ -760,6 +761,8 @@
 	unsigned long vstart;
 #endif
 
+	*p_need = 0;
+
 #ifdef CONFIG_FB
 	if (fbd->flags & MDP_MEMORY_ID_TYPE_FB) {
 		file = fget_light(fbd->memory_id, &put_needed);
@@ -770,8 +773,10 @@
 			fb_num = MINOR(file->f_dentry->d_inode->i_rdev);
 			if (get_fb_phys_info(start, len, fb_num))
 				ret = -1;
-			else
+			else {
 				*p_file = file;
+				*p_need = put_needed;
+			}
 		} else
 			ret = -1;
 		if (ret)
@@ -822,6 +827,7 @@
 	struct file *srcp1_file = NULL, *dstp1_file = NULL;
 	struct ion_handle *srcp0_ihdl = NULL, *dstp0_ihdl = NULL;
 	struct ion_handle *srcp1_ihdl = NULL, *dstp1_ihdl = NULL;
+	int ps0_need, p_need;
 	unsigned int in_chroma_paddr = 0, out_chroma_paddr = 0;
 	unsigned int in_chroma2_paddr = 0;
 	struct msm_rotator_img_info *img_info;
@@ -872,8 +878,9 @@
 		goto do_rotate_unlock_mutex;
 	}
 
+
 	rc = get_img(&info.src, (unsigned long *)&in_paddr,
-			(unsigned long *)&src_len, &srcp0_file, &srcp0_ihdl);
+		(unsigned long *)&src_len, &srcp0_file, &ps0_need, &srcp0_ihdl);
 	if (rc) {
 		pr_err("%s: in get_img() failed id=0x%08x\n",
 			DRIVER_NAME, info.src.memory_id);
@@ -881,7 +888,7 @@
 	}
 
 	rc = get_img(&info.dst, (unsigned long *)&out_paddr,
-			(unsigned long *)&dst_len, &dstp0_file, &dstp0_ihdl);
+		(unsigned long *)&dst_len, &dstp0_file, &p_need, &dstp0_ihdl);
 	if (rc) {
 		pr_err("%s: out get_img() failed id=0x%08x\n",
 		       DRIVER_NAME, info.dst.memory_id);
@@ -911,7 +918,7 @@
 
 		rc = get_img(&info.src_chroma,
 				(unsigned long *)&in_chroma_paddr,
-				(unsigned long *)&src_len, &srcp1_file,
+				(unsigned long *)&src_len, &srcp1_file, &p_need,
 				&srcp1_ihdl);
 		if (rc) {
 			pr_err("%s: in chroma get_img() failed id=0x%08x\n",
@@ -921,7 +928,7 @@
 
 		rc = get_img(&info.dst_chroma,
 				(unsigned long *)&out_chroma_paddr,
-				(unsigned long *)&dst_len, &dstp1_file,
+				(unsigned long *)&dst_len, &dstp1_file, &p_need,
 				&dstp1_ihdl);
 		if (rc) {
 			pr_err("%s: out chroma get_img() failed id=0x%08x\n",
@@ -1089,7 +1096,12 @@
 	put_img(dstp1_file, dstp1_ihdl);
 	put_img(srcp1_file, srcp1_ihdl);
 	put_img(dstp0_file, dstp0_ihdl);
-	put_img(srcp0_file, srcp0_ihdl);
+
+	/* only source may use frame buffer */
+	if (info.src.flags & MDP_MEMORY_ID_TYPE_FB)
+		fput_light(srcp0_file, ps0_need);
+	else
+		put_img(srcp0_file, srcp0_ihdl);
 	mutex_unlock(&msm_rotator_dev->rotator_lock);
 	dev_dbg(msm_rotator_dev->device, "%s() returning rc = %d\n",
 		__func__, rc);
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index c1a65fc..fff494c 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -1,6 +1,6 @@
 /* Qualcomm CE device driver.
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -172,7 +172,7 @@
 #endif
 }
 
-static int qcedev_ce_high_bw_req(struct qcedev_control *podev,
+static void qcedev_ce_high_bw_req(struct qcedev_control *podev,
 							bool high_bw_req)
 {
 	int ret = 0;
@@ -180,18 +180,22 @@
 	mutex_lock(&sent_bw_req);
 	if (high_bw_req) {
 		if (podev->high_bw_req_count == 0)
-			msm_bus_scale_client_update_request(
+			ret = msm_bus_scale_client_update_request(
 					podev->bus_scale_handle, 1);
+		if (ret)
+			pr_err("%s Unable to set to high bandwidth\n",
+							__func__);
 		podev->high_bw_req_count++;
 	} else {
 		if (podev->high_bw_req_count == 1)
-			msm_bus_scale_client_update_request(
+			ret = msm_bus_scale_client_update_request(
 					podev->bus_scale_handle, 0);
+		if (ret)
+			pr_err("%s Unable to set to low bandwidth\n",
+							__func__);
 		podev->high_bw_req_count--;
 	}
 	mutex_unlock(&sent_bw_req);
-
-	return ret;
 }
 
 
@@ -331,7 +335,7 @@
 	handle->cntl = podev;
 	file->private_data = handle;
 	if (podev->platform_support.bus_scale_table != NULL)
-		return qcedev_ce_high_bw_req(podev, true);
+		qcedev_ce_high_bw_req(podev, true);
 	return 0;
 }
 
@@ -349,7 +353,7 @@
 	kzfree(handle);
 	file->private_data = NULL;
 	if (podev->platform_support.bus_scale_table != NULL)
-		return qcedev_ce_high_bw_req(podev, false);
+		qcedev_ce_high_bw_req(podev, false);
 	return 0;
 }
 
@@ -2218,7 +2222,7 @@
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Mona Hossain <mhossain@codeaurora.org>");
 MODULE_DESCRIPTION("Qualcomm DEV Crypto driver");
-MODULE_VERSION("1.25");
+MODULE_VERSION("1.26");
 
 module_init(qcedev_init);
 module_exit(qcedev_exit);
diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c
index 3fff05c..21c3aff 100644
--- a/drivers/crypto/msm/qcrypto.c
+++ b/drivers/crypto/msm/qcrypto.c
@@ -1,6 +1,6 @@
 /* Qualcomm Crypto driver
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -329,7 +329,7 @@
 	}
 }
 
-static int qcrypto_ce_high_bw_req(struct crypto_priv *cp, bool high_bw_req)
+static void qcrypto_ce_high_bw_req(struct crypto_priv *cp, bool high_bw_req)
 {
 	int ret = 0;
 
@@ -338,16 +338,20 @@
 		if (cp->high_bw_req_count == 0)
 			ret = msm_bus_scale_client_update_request(
 				cp->bus_scale_handle, 1);
+		if (ret)
+			pr_err("%s Unable to set to high bandwidth\n",
+							__func__);
 		cp->high_bw_req_count++;
 	} else {
 		if (cp->high_bw_req_count == 1)
 			ret = msm_bus_scale_client_update_request(
 				cp->bus_scale_handle, 0);
+		if (ret)
+			pr_err("%s Unable to set to low bandwidth\n",
+							__func__);
 		cp->high_bw_req_count--;
 	}
 	mutex_unlock(&sent_bw_req);
-
-	return ret;
 }
 
 static void _start_qcrypto_process(struct crypto_priv *cp);
@@ -403,7 +407,7 @@
 	/* random first IV */
 	get_random_bytes(ctx->iv, QCRYPTO_MAX_IV_LENGTH);
 	if (ctx->cp->platform_support.bus_scale_table != NULL)
-		return  qcrypto_ce_high_bw_req(ctx->cp, true);
+		qcrypto_ce_high_bw_req(ctx->cp, true);
 
 	return 0;
 };
@@ -440,7 +444,7 @@
 
 	sha_ctx->ahash_req = NULL;
 	if (sha_ctx->cp->platform_support.bus_scale_table != NULL)
-		return qcrypto_ce_high_bw_req(sha_ctx->cp, true);
+		qcrypto_ce_high_bw_req(sha_ctx->cp, true);
 
 	return 0;
 };
@@ -3359,4 +3363,4 @@
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Mona Hossain <mhossain@codeaurora.org>");
 MODULE_DESCRIPTION("Qualcomm Crypto driver");
-MODULE_VERSION("1.20");
+MODULE_VERSION("1.21");
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index e33155f..ea16c31 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -1274,7 +1274,7 @@
 	default:
 		KGSL_DRV_INFO(dev_priv->device,
 			"invalid ioctl code %08x\n", cmd);
-		result = -EINVAL;
+		result = -ENOIOCTLCMD;
 		break;
 	}
 	return result;
diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c
index b53ca8f..68299cf 100644
--- a/drivers/gpu/msm/adreno_debugfs.c
+++ b/drivers/gpu/msm/adreno_debugfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2008-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -23,7 +23,8 @@
 #include "a2xx_reg.h"
 
 unsigned int kgsl_cff_dump_enable;
-int kgsl_pm_regs_enabled;
+int adreno_pm_regs_enabled;
+int adreno_pm_ib_enabled;
 
 static struct dentry *pm_d_debugfs;
 
@@ -46,20 +47,37 @@
 
 static int pm_regs_enabled_set(void *data, u64 val)
 {
-	kgsl_pm_regs_enabled = val ? 1 : 0;
+	adreno_pm_regs_enabled = val ? 1 : 0;
 	return 0;
 }
 
 static int pm_regs_enabled_get(void *data, u64 *val)
 {
-	*val = kgsl_pm_regs_enabled;
+	*val = adreno_pm_regs_enabled;
 	return 0;
 }
 
+static int pm_ib_enabled_set(void *data, u64 val)
+{
+	adreno_pm_ib_enabled = val ? 1 : 0;
+	return 0;
+}
+
+static int pm_ib_enabled_get(void *data, u64 *val)
+{
+	*val = adreno_pm_ib_enabled;
+	return 0;
+}
+
+
 DEFINE_SIMPLE_ATTRIBUTE(pm_regs_enabled_fops,
 			pm_regs_enabled_get,
 			pm_regs_enabled_set, "%llu\n");
 
+DEFINE_SIMPLE_ATTRIBUTE(pm_ib_enabled_fops,
+			pm_ib_enabled_get,
+			pm_ib_enabled_set, "%llu\n");
+
 
 static int kgsl_cff_dump_enable_set(void *data, u64 val)
 {
@@ -358,4 +376,6 @@
 			    &pm_dump_fops);
 	debugfs_create_file("regs_enabled", 0644, pm_d_debugfs, device,
 			    &pm_regs_enabled_fops);
+	debugfs_create_file("ib_enabled", 0644, pm_d_debugfs, device,
+				    &pm_ib_enabled_fops);
 }
diff --git a/drivers/gpu/msm/adreno_debugfs.h b/drivers/gpu/msm/adreno_debugfs.h
index 0356ac6..5f8d89a 100644
--- a/drivers/gpu/msm/adreno_debugfs.h
+++ b/drivers/gpu/msm/adreno_debugfs.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2008-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -17,11 +17,17 @@
 
 int adreno_debugfs_init(struct kgsl_device *device);
 
-extern int kgsl_pm_regs_enabled;
+extern int adreno_pm_regs_enabled;
+extern int adreno_pm_ib_enabled;
 
-static inline int kgsl_pmregs_enabled(void)
+static inline int is_adreno_pm_regs_enabled(void)
 {
-	return kgsl_pm_regs_enabled;
+	return adreno_pm_regs_enabled;
+}
+
+static inline int is_adreno_pm_ib_enabled(void)
+{
+	return adreno_pm_ib_enabled;
 }
 
 #else
diff --git a/drivers/gpu/msm/adreno_postmortem.c b/drivers/gpu/msm/adreno_postmortem.c
index 7902f30..f9e498f 100644
--- a/drivers/gpu/msm/adreno_postmortem.c
+++ b/drivers/gpu/msm/adreno_postmortem.c
@@ -294,15 +294,6 @@
 	}
 }
 
-static bool adreno_ib_dump_enabled(void)
-{
-#ifdef CONFIG_MSM_KGSL_PSTMRTMDMP_NO_IB_DUMP
-	return 0;
-#else
-	return 1;
-#endif
-}
-
 struct log_field {
 	bool show;
 	const char *display;
@@ -817,7 +808,7 @@
 		cp_rb_base, cp_rb_rptr, cp_rb_wptr, read_idx);
 	adreno_dump_rb(device, rb_copy, num_item<<2, read_idx, rb_count);
 
-	if (adreno_ib_dump_enabled()) {
+	if (is_adreno_pm_ib_enabled()) {
 		for (read_idx = NUM_DWORDS_OF_RINGBUFFER_HISTORY;
 			read_idx >= 0; --read_idx) {
 			uint32_t this_cmd = rb_copy[read_idx];
@@ -849,16 +840,17 @@
 	}
 
 	/* Dump the registers if the user asked for it */
-
-	if (adreno_is_a20x(adreno_dev))
-		adreno_dump_regs(device, a200_registers,
-			a200_registers_count);
-	else if (adreno_is_a22x(adreno_dev))
-		adreno_dump_regs(device, a220_registers,
-			a220_registers_count);
-	else if (adreno_is_a3xx(adreno_dev))
-		adreno_dump_regs(device, a3xx_registers,
-			a3xx_registers_count);
+	if (is_adreno_pm_regs_enabled()) {
+		if (adreno_is_a20x(adreno_dev))
+			adreno_dump_regs(device, a200_registers,
+					a200_registers_count);
+		else if (adreno_is_a22x(adreno_dev))
+			adreno_dump_regs(device, a220_registers,
+					a220_registers_count);
+		else if (adreno_is_a3xx(adreno_dev))
+			adreno_dump_regs(device, a3xx_registers,
+					a3xx_registers_count);
+	}
 
 error_vfree:
 	vfree(rb_copy);
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 45007da..b7356ac 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -1024,6 +1024,7 @@
 	spin_lock(&entry->priv->mem_lock);
 	list_del(&entry->list);
 	spin_unlock(&entry->priv->mem_lock);
+	trace_kgsl_mem_timestamp_free(entry, timestamp);
 	kgsl_mem_entry_put(entry);
 }
 
@@ -1034,12 +1035,18 @@
 	int result = 0;
 	struct kgsl_cmdstream_freememontimestamp *param = data;
 	struct kgsl_mem_entry *entry = NULL;
+	struct kgsl_device *device = dev_priv->device;
+	unsigned int cur;
 
 	spin_lock(&dev_priv->process_priv->mem_lock);
 	entry = kgsl_sharedmem_find(dev_priv->process_priv, param->gpuaddr);
 	spin_unlock(&dev_priv->process_priv->mem_lock);
 
 	if (entry) {
+		cur = device->ftbl->readtimestamp(device,
+						KGSL_TIMESTAMP_RETIRED);
+
+		trace_kgsl_mem_timestamp_queue(entry, cur);
 		result = kgsl_add_event(dev_priv->device, param->timestamp,
 					kgsl_freemem_event_cb, entry, dev_priv);
 	} else {
@@ -1118,6 +1125,7 @@
 	spin_unlock(&private->mem_lock);
 
 	if (entry) {
+		trace_kgsl_mem_free(entry);
 		kgsl_mem_entry_put(entry);
 	} else {
 		KGSL_CORE_ERR("invalid gpuaddr %08x\n", param->gpuaddr);
@@ -1218,6 +1226,7 @@
 
 	kgsl_mem_entry_attach_process(entry, private);
 
+	trace_kgsl_mem_alloc(entry);
 	/* Process specific statistics */
 	kgsl_process_add_stats(private, entry->memtype, len);
 
@@ -1652,6 +1661,7 @@
 	kgsl_process_add_stats(private, entry->memtype, param->len);
 
 	kgsl_mem_entry_attach_process(entry, private);
+	trace_kgsl_mem_map(entry, param->fd);
 
 	kgsl_check_idle(dev_priv->device);
 	return result;
@@ -1718,6 +1728,7 @@
 		param->gpuaddr = entry->memdesc.gpuaddr;
 
 		kgsl_process_add_stats(private, entry->memtype, param->size);
+		trace_kgsl_mem_alloc(entry);
 	} else
 		kfree(entry);
 
@@ -1964,7 +1975,7 @@
 		if (!func) {
 			KGSL_DRV_INFO(dev_priv->device,
 				      "invalid ioctl code %08x\n", cmd);
-			ret = -EINVAL;
+			ret = -ENOIOCTLCMD;
 			goto done;
 		}
 		lock = 1;
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index 389ed6d..7264c25 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -150,7 +150,7 @@
 #endif
 	MEM_ENTRY_STAT(KGSL_MEM_ENTRY_USER, user),
 #ifdef CONFIG_ION
-	MEM_ENTRY_STAT(KGSL_MEM_ENTRY_USER, ion),
+	MEM_ENTRY_STAT(KGSL_MEM_ENTRY_ION, ion),
 #endif
 };
 
diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c
index de39ee4..93fdc08 100644
--- a/drivers/gpu/msm/kgsl_snapshot.c
+++ b/drivers/gpu/msm/kgsl_snapshot.c
@@ -10,7 +10,6 @@
  * GNU General Public License for more details.
  */
 
-#include <linux/vmalloc.h>
 #include <linux/time.h>
 #include <linux/sysfs.h>
 #include <linux/utsname.h>
@@ -299,6 +298,10 @@
 	/* Freeze the snapshot on a hang until it gets read */
 	device->snapshot_frozen = (hang) ? 1 : 0;
 
+	/* log buffer info to aid in ramdump recovery */
+	KGSL_DRV_ERR(device, "snapshot created at va %p pa %lx size %d\n",
+			device->snapshot, __pa(device->snapshot),
+			device->snapshot_size);
 	return 0;
 }
 EXPORT_SYMBOL(kgsl_device_snapshot);
@@ -448,7 +451,7 @@
 	int ret;
 
 	if (device->snapshot == NULL)
-		device->snapshot = vmalloc(KGSL_SNAPSHOT_MEMSIZE);
+		device->snapshot = kzalloc(KGSL_SNAPSHOT_MEMSIZE, GFP_KERNEL);
 
 	if (device->snapshot == NULL)
 		return -ENOMEM;
@@ -491,7 +494,7 @@
 
 	kobject_put(&device->snapshot_kobj);
 
-	vfree(device->snapshot);
+	kfree(device->snapshot);
 
 	device->snapshot = NULL;
 	device->snapshot_maxsize = 0;
diff --git a/drivers/gpu/msm/kgsl_trace.h b/drivers/gpu/msm/kgsl_trace.h
index 86a9adc..22bc576 100644
--- a/drivers/gpu/msm/kgsl_trace.h
+++ b/drivers/gpu/msm/kgsl_trace.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -257,6 +257,122 @@
 	TP_ARGS(device, state)
 );
 
+TRACE_EVENT(kgsl_mem_alloc,
+
+	TP_PROTO(struct kgsl_mem_entry *mem_entry),
+
+	TP_ARGS(mem_entry),
+
+	TP_STRUCT__entry(
+		__field(unsigned int, gpuaddr)
+		__field(unsigned int, size)
+	),
+
+	TP_fast_assign(
+		__entry->gpuaddr = mem_entry->memdesc.gpuaddr;
+		__entry->size = mem_entry->memdesc.size;
+	),
+
+	TP_printk(
+		"gpuaddr=0x%08x size=%d",
+		__entry->gpuaddr, __entry->size
+	)
+);
+
+TRACE_EVENT(kgsl_mem_map,
+
+	TP_PROTO(struct kgsl_mem_entry *mem_entry, int fd),
+
+	TP_ARGS(mem_entry, fd),
+
+	TP_STRUCT__entry(
+		__field(unsigned int, gpuaddr)
+		__field(unsigned int, size)
+		__field(int, fd)
+		__field(int, type)
+	),
+
+	TP_fast_assign(
+		__entry->gpuaddr = mem_entry->memdesc.gpuaddr;
+		__entry->size = mem_entry->memdesc.size;
+		__entry->fd = fd;
+		__entry->type = mem_entry->memtype;
+	),
+
+	TP_printk(
+		"gpuaddr=0x%08x size=%d type=%d fd=%d",
+		__entry->gpuaddr, __entry->size,
+		__entry->type, __entry->fd
+	)
+);
+
+TRACE_EVENT(kgsl_mem_free,
+
+	TP_PROTO(struct kgsl_mem_entry *mem_entry),
+
+	TP_ARGS(mem_entry),
+
+	TP_STRUCT__entry(
+		__field(unsigned int, gpuaddr)
+		__field(unsigned int, size)
+		__field(int, type)
+		__field(int, fd)
+	),
+
+	TP_fast_assign(
+		__entry->gpuaddr = mem_entry->memdesc.gpuaddr;
+		__entry->size = mem_entry->memdesc.size;
+		__entry->type = mem_entry->memtype;
+	),
+
+	TP_printk(
+		"gpuaddr=0x%08x size=%d type=%d",
+		__entry->gpuaddr, __entry->size, __entry->type
+	)
+);
+
+DECLARE_EVENT_CLASS(kgsl_mem_timestamp_template,
+
+	TP_PROTO(struct kgsl_mem_entry *mem_entry, unsigned int curr_ts),
+
+	TP_ARGS(mem_entry, curr_ts),
+
+	TP_STRUCT__entry(
+		__field(unsigned int, gpuaddr)
+		__field(unsigned int, size)
+		__field(int, type)
+		__field(unsigned int, drawctxt_id)
+		__field(unsigned int, curr_ts)
+		__field(unsigned int, free_ts)
+	),
+
+	TP_fast_assign(
+		__entry->gpuaddr = mem_entry->memdesc.gpuaddr;
+		__entry->size = mem_entry->memdesc.size;
+		__entry->drawctxt_id = 1337;
+		__entry->type = mem_entry->memtype;
+		__entry->curr_ts = curr_ts;
+		__entry->free_ts = mem_entry->free_timestamp;
+	),
+
+	TP_printk(
+		"gpuaddr=0x%08x size=%d type=%d ctx=%u curr_ts=0x%08x free_ts=0x%08x",
+		__entry->gpuaddr, __entry->size, __entry->type,
+		__entry->drawctxt_id, __entry->curr_ts, __entry->free_ts
+	)
+);
+
+DEFINE_EVENT(kgsl_mem_timestamp_template, kgsl_mem_timestamp_queue,
+	TP_PROTO(struct kgsl_mem_entry *mem_entry, unsigned int curr_ts),
+	TP_ARGS(mem_entry, curr_ts)
+);
+
+DEFINE_EVENT(kgsl_mem_timestamp_template, kgsl_mem_timestamp_free,
+	TP_PROTO(struct kgsl_mem_entry *mem_entry, unsigned int curr_ts),
+	TP_ARGS(mem_entry, curr_ts)
+);
+
+
 #endif /* _KGSL_TRACE_H */
 
 /* This part must be outside protection */
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index cb3da90..6c43a75 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -339,13 +339,15 @@
 	*p++ = ADDR_VGV3_LAST << 24;
 }
 
-static void z180_cmdstream_start(struct kgsl_device *device)
+static void z180_cmdstream_start(struct kgsl_device *device, int init_ram)
 {
 	struct z180_device *z180_dev = Z180_DEVICE(device);
 	unsigned int cmd = VGV3_NEXTCMD_JUMP << VGV3_NEXTCMD_NEXTCMD_FSHIFT;
 
-	z180_dev->timestamp = 0;
-	z180_dev->current_timestamp = 0;
+	if (init_ram) {
+		z180_dev->timestamp = 0;
+		z180_dev->current_timestamp = 0;
+	}
 
 	addmarker(&z180_dev->ringbuffer, 0);
 
@@ -566,7 +568,7 @@
 	if (status)
 		goto error_clk_off;
 
-	z180_cmdstream_start(device);
+	z180_cmdstream_start(device, init_ram);
 
 	mod_timer(&device->idle_timer, jiffies + FIRST_TIMEOUT);
 	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON);
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index f18c2d0..f5bfc7b 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -514,6 +514,31 @@
 	}
 }
 
+static int mxt_get_bootloader_id(struct i2c_client *client)
+{
+	u8 val;
+	u8 buf[3];
+
+	if (i2c_master_recv(client, &val, 1) != 1) {
+		dev_err(&client->dev, "%s: i2c recv failed\n", __func__);
+		return -EIO;
+	}
+
+	if (val | MXT_BOOT_EXTENDED_ID)	{
+		if (i2c_master_recv(client, &buf[0], 3) != 3) {
+			dev_err(&client->dev, "%s: i2c recv failed\n",
+								__func__);
+			return -EIO;
+		}
+		return buf[1];
+	} else {
+		dev_info(&client->dev, "Bootloader ID:%d",
+			val & MXT_BOOT_ID_MASK);
+
+		return val & MXT_BOOT_ID_MASK;
+	}
+}
+
 static int mxt_check_bootloader(struct i2c_client *client,
 				unsigned int state)
 {
@@ -1449,24 +1474,69 @@
 	return ret;
 }
 
+static const char *
+mxt_search_fw_name(struct mxt_data *data, u8 bootldr_id)
+{
+	const struct mxt_platform_data *pdata = data->pdata;
+	const struct mxt_config_info *cfg_info;
+	const char *fw_name = NULL;
+	int i;
+
+	for (i = 0; i < pdata->config_array_size; i++) {
+		cfg_info = &pdata->config_array[i];
+		if (bootldr_id == cfg_info->bootldr_id && cfg_info->fw_name) {
+			data->config_info = cfg_info;
+			data->info.family_id = cfg_info->family_id;
+			fw_name = cfg_info->fw_name;
+		}
+	}
+
+	return fw_name;
+}
+
 static ssize_t mxt_update_fw_store(struct device *dev,
 					struct device_attribute *attr,
 					const char *buf, size_t count)
 {
 	struct mxt_data *data = dev_get_drvdata(dev);
 	int error;
+	const char *fw_name;
+	u8 bootldr_id;
 
 	/* If fw_name is set, then the existing firmware has an upgrade */
 	if (!data->fw_name) {
-		dev_err(dev, "Firmware name not specifed in platform data\n");
-		return -EINVAL;
+		/*
+		 * If the device boots up in the bootloader mode, check if
+		 * there is a firmware to upgrade.
+		 */
+		if (data->state == BOOTLOADER) {
+			bootldr_id = mxt_get_bootloader_id(data->client);
+			if (bootldr_id <= 0) {
+				dev_err(dev,
+					"Unable to retrieve bootloader id\n");
+				return -EINVAL;
+			}
+			fw_name = mxt_search_fw_name(data, bootldr_id);
+			if (fw_name == NULL) {
+				dev_err(dev,
+				"Unable to find fw from bootloader id\n");
+				return -EINVAL;
+			}
+		} else {
+			/* In APPMODE, if the f/w name does not exist, quit */
+			dev_err(dev,
+			"Firmware name not specified in platform data\n");
+			return -EINVAL;
+		}
+	} else {
+		fw_name = data->fw_name;
 	}
 
-	dev_info(dev, "Upgrading the firmware file to %s\n", data->fw_name);
+	dev_info(dev, "Upgrading the firmware file to %s\n", fw_name);
 
 	disable_irq(data->irq);
 
-	error = mxt_load_fw(dev, data->fw_name);
+	error = mxt_load_fw(dev, fw_name);
 	if (error) {
 		dev_err(dev, "The firmware update failed(%d)\n", error);
 		count = error;
@@ -1559,10 +1629,12 @@
 	struct mxt_data *data = input_get_drvdata(dev);
 	int error;
 
-	error = mxt_start(data);
-	if (error < 0) {
-		dev_err(&data->client->dev, "mxt_start failed in input_open\n");
-		return error;
+	if (data->state == APPMODE) {
+		error = mxt_start(data);
+		if (error < 0) {
+			dev_err(&data->client->dev, "mxt_start failed in input_open\n");
+			return error;
+		}
 	}
 
 	return 0;
@@ -1573,10 +1645,11 @@
 	struct mxt_data *data = input_get_drvdata(dev);
 	int error;
 
-	error = mxt_stop(data);
-	if (error < 0)
-		dev_err(&data->client->dev, "mxt_stop failed in input_close\n");
-
+	if (data->state == APPMODE) {
+		error = mxt_stop(data);
+		if (error < 0)
+			dev_err(&data->client->dev, "mxt_stop failed in input_close\n");
+	}
 }
 
 static int reg_set_optimum_mode_check(struct regulator *reg, int load_uA)
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 4598b31..78c474e 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -522,6 +522,7 @@
 	ctrlcmd.value = (void *)ctrl_data;
 	memcpy(ctrlcmd.value, ctrl, ctrlcmd.length);
 	ctrlcmd.timeout_ms = 1000;
+	ctrlcmd.vnode_id = pcam->vnode_id;
 	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
 
 	/* send command to config thread in usersspace, and get return value */
@@ -547,6 +548,7 @@
 	ctrlcmd.value = (void *)ctrl_data;
 	memcpy(ctrlcmd.value, queryctrl, ctrlcmd.length);
 	ctrlcmd.timeout_ms = 1000;
+	ctrlcmd.vnode_id = pcam->vnode_id;
 	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
 
 	/* send command to config thread in userspace, and get return value */
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index e4c3152..a8f9f35 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -199,7 +199,7 @@
 };
 
 static int __qseecom_is_svc_unique(struct qseecom_dev_handle *data,
-		struct qseecom_register_listener_req svc)
+		struct qseecom_register_listener_req *svc)
 {
 	struct qseecom_registered_listener_list *ptr;
 	int unique = 1;
@@ -207,7 +207,7 @@
 
 	spin_lock_irqsave(&qseecom.registered_listener_list_lock, flags);
 	list_for_each_entry(ptr, &qseecom.registered_listener_list_head, list) {
-		if (ptr->svc.listener_id == svc.listener_id) {
+		if (ptr->svc.listener_id == svc->listener_id) {
 			pr_err("Service id: %u is already registered\n",
 					ptr->svc.listener_id);
 			unique = 0;
@@ -333,16 +333,12 @@
 		pr_err("copy_from_user failed\n");
 		return ret;
 	}
-
-	if (!__qseecom_is_svc_unique(data, rcvd_lstnr)) {
+	data->listener.id = 0;
+	data->service = true;
+	if (!__qseecom_is_svc_unique(data, &rcvd_lstnr)) {
 		pr_err("Service is not unique and is already registered\n");
-		return ret;
-	}
-
-	ret = copy_to_user(argp, &rcvd_lstnr, sizeof(rcvd_lstnr));
-	if (ret) {
-		pr_err("copy_to_user failed\n");
-		return ret;
+		data->released = true;
+		return -EBUSY;
 	}
 
 	new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
@@ -360,13 +356,14 @@
 		kzfree(new_entry);
 		return -ENOMEM;
 	}
+
 	data->listener.id = rcvd_lstnr.listener_id;
-	data->service = true;
 	init_waitqueue_head(&new_entry->rcv_req_wq);
 
 	spin_lock_irqsave(&qseecom.registered_listener_list_lock, flags);
 	list_add_tail(&new_entry->list, &qseecom.registered_listener_list_head);
 	spin_unlock_irqrestore(&qseecom.registered_listener_list_lock, flags);
+
 	return ret;
 }
 
@@ -743,6 +740,7 @@
 					break;
 				} else {
 					ptr_app->ref_cnt--;
+					data->released = true;
 					break;
 				}
 			}
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 0d2b11d..ad4dfe6 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -134,6 +134,7 @@
 		      u32 c);
 static inline void msmsdcc_delay(struct msmsdcc_host *host);
 static void msmsdcc_dump_sdcc_state(struct msmsdcc_host *host);
+static void msmsdcc_sg_start(struct msmsdcc_host *host);
 
 static inline unsigned short msmsdcc_get_nr_sg(struct msmsdcc_host *host)
 {
@@ -1076,21 +1077,15 @@
 
 	/* Is data transfer in PIO mode required? */
 	if (!(datactrl & MCI_DPSM_DMAENABLE)) {
-		unsigned int sg_miter_flags = SG_MITER_ATOMIC;
-
 		if (data->flags & MMC_DATA_READ) {
-			sg_miter_flags |= SG_MITER_TO_SG;
 			pio_irqmask = MCI_RXFIFOHALFFULLMASK;
 			if (host->curr.xfer_remain < MCI_FIFOSIZE)
 				pio_irqmask |= MCI_RXDATAAVLBLMASK;
-		} else {
-			sg_miter_flags |= SG_MITER_FROM_SG;
+		} else
 			pio_irqmask = MCI_TXFIFOHALFEMPTYMASK |
 					MCI_TXFIFOEMPTYMASK;
-		}
 
-		sg_miter_start(&host->sg_miter, data->sg, data->sg_len,
-				sg_miter_flags);
+		msmsdcc_sg_start(host);
 	}
 
 	if (data->flags & MMC_DATA_READ)
@@ -1250,6 +1245,144 @@
 	return ptr - buffer;
 }
 
+/*
+ * Copy up to a word (4 bytes) between a scatterlist
+ * and a temporary bounce buffer when the word lies across
+ * two pages. The temporary buffer can then be read to/
+ * written from the FIFO once.
+ */
+static void _msmsdcc_sg_consume_word(struct msmsdcc_host *host)
+{
+	struct msmsdcc_pio_data *pio = &host->pio;
+	unsigned int bytes_avail;
+
+	if (host->curr.data->flags & MMC_DATA_READ)
+		memcpy(pio->sg_miter.addr, pio->bounce_buf,
+		       pio->bounce_buf_len);
+	else
+		memcpy(pio->bounce_buf, pio->sg_miter.addr,
+		       pio->bounce_buf_len);
+
+	while (pio->bounce_buf_len != 4) {
+		if (!sg_miter_next(&pio->sg_miter))
+			break;
+		bytes_avail = min_t(unsigned int, pio->sg_miter.length,
+			4 - pio->bounce_buf_len);
+		if (host->curr.data->flags & MMC_DATA_READ)
+			memcpy(pio->sg_miter.addr,
+			       &pio->bounce_buf[pio->bounce_buf_len],
+			       bytes_avail);
+		else
+			memcpy(&pio->bounce_buf[pio->bounce_buf_len],
+			       pio->sg_miter.addr, bytes_avail);
+
+		pio->sg_miter.consumed = bytes_avail;
+		pio->bounce_buf_len += bytes_avail;
+	}
+}
+
+/*
+ * Use sg_miter_next to return as many 4-byte aligned
+ * chunks as possible, using a temporary 4 byte buffer
+ * for alignment if necessary
+ */
+static int msmsdcc_sg_next(struct msmsdcc_host *host, char **buf, int *len)
+{
+	struct msmsdcc_pio_data *pio = &host->pio;
+	unsigned int length, rlength;
+	char *buffer;
+
+	if (!sg_miter_next(&pio->sg_miter))
+		return 0;
+
+	buffer = pio->sg_miter.addr;
+	length = pio->sg_miter.length;
+
+	if (length < host->curr.xfer_remain) {
+		rlength = round_down(length, 4);
+		if (rlength) {
+			/*
+			 * We have a 4-byte aligned chunk.
+			 * The rounding will be reflected by
+			 * a call to msmsdcc_sg_consumed
+			 */
+			length = rlength;
+			goto sg_next_end;
+		}
+		/*
+		 * We have a length less than 4 bytes. Check to
+		 * see if more buffer is available, and combine
+		 * to make 4 bytes if possible.
+		 */
+		pio->bounce_buf_len = length;
+		memset(pio->bounce_buf, 0, 4);
+
+		/*
+		 * On a read, get 4 bytes from FIFO, and distribute
+		 * (4-bouce_buf_len) bytes into consecutive
+		 * sgl buffers when msmsdcc_sg_consumed is called
+		 */
+		if (host->curr.data->flags & MMC_DATA_READ) {
+			buffer = pio->bounce_buf;
+			length = 4;
+			goto sg_next_end;
+		} else {
+			_msmsdcc_sg_consume_word(host);
+			buffer = pio->bounce_buf;
+			length = pio->bounce_buf_len;
+		}
+	}
+
+sg_next_end:
+	*buf = buffer;
+	*len = length;
+	return 1;
+}
+
+/*
+ * Update sg_miter.consumed based on how many bytes were
+ * consumed. If the bounce buffer was used to read from FIFO,
+ * redistribute into sgls.
+ */
+static void msmsdcc_sg_consumed(struct msmsdcc_host *host,
+				unsigned int length)
+{
+	struct msmsdcc_pio_data *pio = &host->pio;
+
+	if (host->curr.data->flags & MMC_DATA_READ) {
+		if (length > pio->sg_miter.consumed)
+			/*
+			 * consumed 4 bytes, but sgl
+			 * describes < 4 bytes
+			 */
+			_msmsdcc_sg_consume_word(host);
+		else
+			pio->sg_miter.consumed = length;
+	} else
+		if (length < pio->sg_miter.consumed)
+			pio->sg_miter.consumed = length;
+}
+
+static void msmsdcc_sg_start(struct msmsdcc_host *host)
+{
+	unsigned int sg_miter_flags = SG_MITER_ATOMIC;
+
+	host->pio.bounce_buf_len = 0;
+
+	if (host->curr.data->flags & MMC_DATA_READ)
+		sg_miter_flags |= SG_MITER_TO_SG;
+	else
+		sg_miter_flags |= SG_MITER_FROM_SG;
+
+	sg_miter_start(&host->pio.sg_miter, host->curr.data->sg,
+		       host->curr.data->sg_len, sg_miter_flags);
+}
+
+static void msmsdcc_sg_stop(struct msmsdcc_host *host)
+{
+	sg_miter_stop(&host->pio.sg_miter);
+}
+
 static irqreturn_t
 msmsdcc_pio_irq(int irq, void *dev_id)
 {
@@ -1257,6 +1390,8 @@
 	void __iomem		*base = host->base;
 	uint32_t		status;
 	unsigned long flags;
+	unsigned int remain;
+	char *buffer;
 
 	spin_lock(&host->lock);
 
@@ -1267,45 +1402,43 @@
 		spin_unlock(&host->lock);
 		return IRQ_NONE;
 	}
-
 #if IRQ_DEBUG
 	msmsdcc_print_status(host, "irq1-r", status);
 #endif
 	local_irq_save(flags);
 
-	while (sg_miter_next(&host->sg_miter)) {
-
-		unsigned int remain, len;
-		char *buffer;
+	do {
+		unsigned int len;
 
 		if (!(status & (MCI_TXFIFOHALFEMPTY | MCI_TXFIFOEMPTY
 				| MCI_RXDATAAVLBL)))
 			break;
 
-		buffer = host->sg_miter.addr;
-		remain = host->sg_miter.length;
+		if (!msmsdcc_sg_next(host, &buffer, &remain))
+			break;
 
 		len = 0;
 		if (status & MCI_RXACTIVE)
 			len = msmsdcc_pio_read(host, buffer, remain);
 		if (status & MCI_TXACTIVE)
 			len = msmsdcc_pio_write(host, buffer, remain);
+
 		/* len might have aligned to 32bits above */
 		if (len > remain)
 			len = remain;
 
-		host->sg_miter.consumed = len;
 		host->curr.xfer_remain -= len;
 		host->curr.data_xfered += len;
 		remain -= len;
+		msmsdcc_sg_consumed(host, len);
 
 		if (remain) /* Done with this page? */
 			break; /* Nope */
 
 		status = readl_relaxed(base + MMCISTATUS);
-	}
+	} while (1);
 
-	sg_miter_stop(&host->sg_miter);
+	msmsdcc_sg_stop(host);
 	local_irq_restore(flags);
 
 	if (status & MCI_RXACTIVE && host->curr.xfer_remain < MCI_FIFOSIZE) {
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index 319d721..8a728f2 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -281,9 +281,10 @@
 };
 
 struct msmsdcc_pio_data {
-	struct scatterlist	*sg;
-	unsigned int		sg_len;
-	unsigned int		sg_off;
+	struct sg_mapping_iter		sg_miter;
+	char				bounce_buf[4];
+	/* valid bytes in bounce_buf */
+	int				bounce_buf_len;
 };
 
 struct msmsdcc_curr_req {
@@ -361,7 +362,7 @@
 	struct msmsdcc_sps_data sps;
 	bool			is_dma_mode;
 	bool			is_sps_mode;
-	struct sg_mapping_iter sg_miter;
+	struct msmsdcc_pio_data	pio;
 
 #ifdef CONFIG_HAS_EARLYSUSPEND
 	struct early_suspend early_suspend;
diff --git a/drivers/mtd/devices/msm_nand.c b/drivers/mtd/devices/msm_nand.c
index 5ced423..2479a11 100644
--- a/drivers/mtd/devices/msm_nand.c
+++ b/drivers/mtd/devices/msm_nand.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -6718,7 +6718,7 @@
 			supported_flash.pagesize = 1024 << (devcfg & 0x3);
 			supported_flash.blksize = (64 * 1024) <<
 							((devcfg >> 4) & 0x3);
-			supported_flash.oobsize = (8 << ((devcfg >> 2) & 1)) *
+			supported_flash.oobsize = (8 << ((devcfg >> 2) & 0x3)) *
 				(supported_flash.pagesize >> 9);
 		} else {
 			supported_flash.flash_id = flash_id;
diff --git a/drivers/net/usb/rmnet_usb_ctrl.c b/drivers/net/usb/rmnet_usb_ctrl.c
index dcbd761..5a016bb 100644
--- a/drivers/net/usb/rmnet_usb_ctrl.c
+++ b/drivers/net/usb/rmnet_usb_ctrl.c
@@ -264,19 +264,10 @@
 {
 	int	retval = 0;
 
-	retval = usb_autopm_get_interface(dev->intf);
-	if (retval < 0) {
-		dev_err(dev->devicep, "%s Resumption fail\n", __func__);
-		goto done_nopm;
-	}
-
 	retval = usb_submit_urb(dev->inturb, GFP_KERNEL);
 	if (retval < 0)
 		dev_err(dev->devicep, "%s Intr submit %d\n", __func__, retval);
 
-	usb_autopm_put_interface(dev->intf);
-
-done_nopm:
 	return retval;
 }
 
@@ -342,35 +333,19 @@
 }
 static int rmnet_usb_ctrl_write_cmd(struct rmnet_ctrl_dev *dev)
 {
-	int			retval = 0;
 	struct usb_device	*udev;
 
 	if (!is_dev_connected(dev))
 		return -ENODEV;
 
 	udev = interface_to_usbdev(dev->intf);
-	retval = usb_autopm_get_interface(dev->intf);
-	if (retval < 0) {
-		dev_err(dev->devicep, "%s: Unable to resume interface: %d\n",
-			__func__, retval);
-
-		/*
-		* Revisit if (retval == -EPERM)
-		*		rmnet_usb_suspend(dev->intf, PMSG_SUSPEND);
-		*/
-
-		return retval;
-	}
 	dev->set_ctrl_line_state_cnt++;
-	retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+	return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
 		USB_CDC_REQ_SET_CONTROL_LINE_STATE,
 		(USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE),
 		dev->cbits_tomdm,
 		dev->intf->cur_altsetting->desc.bInterfaceNumber,
 		NULL, 0, USB_CTRL_SET_TIMEOUT);
-	usb_autopm_put_interface(dev->intf);
-
-	return retval;
 }
 
 static void ctrl_write_callback(struct urb *urb)
@@ -428,7 +403,7 @@
 			     (unsigned char *)out_ctlreq, (void *)buf, size,
 			     ctrl_write_callback, dev);
 
-	result = usb_autopm_get_interface_async(dev->intf);
+	result = usb_autopm_get_interface(dev->intf);
 	if (result < 0) {
 		dev_err(dev->devicep, "%s: Unable to resume interface: %d\n",
 			__func__, result);
@@ -450,7 +425,7 @@
 		dev_err(dev->devicep, "%s: Submit URB error %d\n",
 			__func__, result);
 		dev->snd_encap_cmd_cnt--;
-		usb_autopm_put_interface_async(dev->intf);
+		usb_autopm_put_interface(dev->intf);
 		usb_unanchor_urb(sndurb);
 		usb_free_urb(sndurb);
 		kfree(out_ctlreq);
@@ -662,6 +637,8 @@
 static int rmnet_ctrl_tiocmset(struct rmnet_ctrl_dev *dev, unsigned int set,
 		unsigned int clear)
 {
+	int retval;
+
 	mutex_lock(&dev->dev_lock);
 	if (set & TIOCM_DTR)
 		dev->cbits_tomdm |= ACM_CTRL_DTR;
@@ -681,7 +658,17 @@
 
 	mutex_unlock(&dev->dev_lock);
 
-	return rmnet_usb_ctrl_write_cmd(dev);
+	retval = usb_autopm_get_interface(dev->intf);
+	if (retval < 0) {
+		dev_err(dev->devicep, "%s: Unable to resume interface: %d\n",
+			__func__, retval);
+		return retval;
+	}
+
+	retval = rmnet_usb_ctrl_write_cmd(dev);
+
+	usb_autopm_put_interface(dev->intf);
+	return retval;
 }
 
 static int rmnet_ctrl_tiocmget(struct rmnet_ctrl_dev *dev)
@@ -774,6 +761,10 @@
 	dev->tx_ctrl_err_cnt = 0;
 	dev->set_ctrl_line_state_cnt = 0;
 
+	ret = rmnet_usb_ctrl_write_cmd(dev);
+	if (ret < 0)
+		return ret;
+
 	dev->inturb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!dev->inturb) {
 		dev_err(dev->devicep, "Error allocating int urb\n");
@@ -799,19 +790,15 @@
 		dev->intf->cur_altsetting->desc.bInterfaceNumber;
 	dev->in_ctlreq->wLength = cpu_to_le16(DEFAULT_READ_URB_LENGTH);
 
-	interval =
-		max((int)int_in->desc.bInterval,
-		(udev->speed == USB_SPEED_HIGH) ? HS_INTERVAL : FS_LS_INTERVAL);
+	interval = max((int)int_in->desc.bInterval,
+			(udev->speed == USB_SPEED_HIGH) ? HS_INTERVAL
+							: FS_LS_INTERVAL);
 
 	usb_fill_int_urb(dev->inturb, udev,
 			 dev->int_pipe,
 			 dev->intbuf, wMaxPacketSize,
 			 notification_available_cb, dev, interval);
 
-	ret = rmnet_usb_ctrl_write_cmd(dev);
-	if (ret < 0)
-		return ret;
-
 	return rmnet_usb_ctrl_start_rx(dev);
 }
 
diff --git a/drivers/net/usb/rmnet_usb_data.c b/drivers/net/usb/rmnet_usb_data.c
index 658b393..1eb6845 100644
--- a/drivers/net/usb/rmnet_usb_data.c
+++ b/drivers/net/usb/rmnet_usb_data.c
@@ -148,7 +148,6 @@
 
 	retval = usbnet_resume(iface);
 	if (!retval) {
-
 		if (oldstate & PM_EVENT_SUSPEND)
 			retval = rmnet_usb_ctrl_start(dev);
 	}
@@ -260,6 +259,12 @@
 	return 1;
 }
 
+static int rmnet_usb_manage_power(struct usbnet *dev, int on)
+{
+	dev->intf->needs_remote_wakeup = on;
+	return 0;
+}
+
 static int rmnet_change_mtu(struct net_device *dev, int new_mtu)
 {
 	if (0 > new_mtu || RMNET_DATA_LEN < new_mtu)
@@ -501,6 +506,7 @@
 	.bind          = rmnet_usb_bind,
 	.tx_fixup      = rmnet_usb_tx_fixup,
 	.rx_fixup      = rmnet_usb_rx_fixup,
+	.manage_power  = rmnet_usb_manage_power,
 	.data          = PID9034_IFACE_MASK,
 };
 
@@ -509,6 +515,7 @@
 	.bind          = rmnet_usb_bind,
 	.tx_fixup      = rmnet_usb_tx_fixup,
 	.rx_fixup      = rmnet_usb_rx_fixup,
+	.manage_power  = rmnet_usb_manage_power,
 	.data          = PID9048_IFACE_MASK,
 };
 
@@ -517,6 +524,7 @@
 	.bind          = rmnet_usb_bind,
 	.tx_fixup      = rmnet_usb_tx_fixup,
 	.rx_fixup      = rmnet_usb_rx_fixup,
+	.manage_power  = rmnet_usb_manage_power,
 	.data          = PID904C_IFACE_MASK,
 };
 
diff --git a/drivers/net/wireless/libra/libra_sdioif.c b/drivers/net/wireless/libra/libra_sdioif.c
index 3955642..3421f84 100644
--- a/drivers/net/wireless/libra/libra_sdioif.c
+++ b/drivers/net/wireless/libra/libra_sdioif.c
@@ -29,6 +29,37 @@
 static suspend_handler_t *libra_suspend_hldr;
 static resume_handler_t *libra_resume_hldr;
 
+int libra_enable_sdio_irq_in_chip(struct sdio_func *func, u8 enable)
+{
+	unsigned char reg = 0;
+	int err = 0;
+
+	sdio_claim_host(func);
+
+	/* Read the value into reg */
+	libra_sdiocmd52(func, SDIO_CCCR_IENx, &reg, 0, &err);
+	if (err)
+		printk(KERN_ERR "%s: Could not read  SDIO_CCCR_IENx register "
+				"err=%d\n", __func__, err);
+
+	if (libra_mmc_host) {
+		if (enable) {
+			reg |= 1 << func->num;
+			reg |= 1;
+		} else {
+			reg &= ~(1 << func->num);
+		}
+		libra_sdiocmd52(func, SDIO_CCCR_IENx, &reg, 1, &err);
+		if (err)
+			printk(KERN_ERR "%s: Could not enable/disable irq "
+					 "err=%d\n", __func__, err);
+	 }
+	sdio_release_host(func);
+
+	return err;
+}
+EXPORT_SYMBOL(libra_enable_sdio_irq_in_chip);
+
 /**
  * libra_sdio_configure() - Function to configure the SDIO device param
  * @libra_sdio_rxhandler    Rx handler
@@ -89,6 +120,8 @@
 		goto cfg_error;
 	}
 
+	libra_enable_sdio_irq_in_chip(func, 0);
+
 	sdio_release_host(func);
 
 	return 0;
diff --git a/drivers/net/wireless/libra/qcomwlan_pwrif.c b/drivers/net/wireless/libra/qcomwlan_pwrif.c
index 6a0c78f..94ea0b3 100644
--- a/drivers/net/wireless/libra/qcomwlan_pwrif.c
+++ b/drivers/net/wireless/libra/qcomwlan_pwrif.c
@@ -154,7 +154,7 @@
 
 	/* WLAN VREG settings */
 	for (i = 0; i < ARRAY_SIZE(vregs_qwlan_name); i++) {
-		if (vregs_qwlan[i] == NULL) {
+		if (on && !wlan_on)	{
 			vregs_qwlan[i] = regulator_get(NULL,
 					vregs_qwlan_name[i]);
 			if (IS_ERR(vregs_qwlan[i])) {
@@ -187,8 +187,7 @@
 					goto vreg_fail;
 				}
 			}
-		}
-		if (on && !wlan_on) {
+
 			if (vregs_qwlan_peek_current[i]) {
 				rc = regulator_set_optimum_mode(vregs_qwlan[i],
 						vregs_qwlan_peek_current[i]);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 5442297..4a37dc2 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1690,7 +1690,7 @@
 
 #ifdef CONFIG_USB_OTG
 	if (udev->bus->hnp_support && udev->portnum == udev->bus->otg_port) {
-		cancel_delayed_work(&udev->bus->hnp_polling);
+		cancel_delayed_work_sync(&udev->bus->hnp_polling);
 		udev->bus->hnp_support = 0;
 	}
 #endif
@@ -1811,7 +1811,10 @@
 				 * compliant to revision 2.0 or subsequent
 				 * versions.
 				 */
-				if (le16_to_cpu(desc->bcdOTG) >= 0x0200)
+
+				if ((le16_to_cpu(desc->bLength) ==
+						USB_DT_OTG_SIZE) &&
+					le16_to_cpu(desc->bcdOTG) >= 0x0200)
 					goto out;
 
 				/* Legacy B-device i.e compliant to spec
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 4c33695..4fe494b 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -858,6 +858,7 @@
 	u16				w_length = le16_to_cpu(ctrl->wLength);
 	struct usb_function		*f = NULL;
 	u8				endp;
+	struct usb_configuration *c;
 
 
 	if (w_length > USB_BUFSIZ)
@@ -902,6 +903,16 @@
 			if (value >= 0)
 				value = min(w_length, (u16) value);
 			break;
+		case USB_DT_OTG:
+			if (!gadget_is_otg(gadget))
+				break;
+			c = list_first_entry(&cdev->configs,
+				struct usb_configuration, list);
+			if (c && c->descriptors)
+				value = usb_find_descriptor_fillbuf(req->buf,
+						USB_BUFSIZ, c->descriptors,
+						USB_DT_OTG);
+			break;
 		case USB_DT_STRING:
 			value = get_string(cdev, req->buf,
 					w_index, w_value & 0xff);
diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c
index 09084fd..384332c 100644
--- a/drivers/usb/gadget/config.c
+++ b/drivers/usb/gadget/config.c
@@ -28,6 +28,40 @@
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 
+/**
+ * usb_find_descriptor_fillbuf - fill buffer with the requested descriptor
+ * @buf: Buffer to be filled
+ * @buflen: Size of buf
+ * @src: Array of descriptor pointers, terminated by null pointer.
+ * @desc_type: bDescriptorType field of the requested descriptor.
+ *
+ * Copies the requested descriptor into the buffer, returning the length
+ * or a negative error code if it is not found or can't be copied.  Useful
+ * when DT_OTG descriptor is requested.
+ */
+int
+usb_find_descriptor_fillbuf(void *buf, unsigned buflen,
+		const struct usb_descriptor_header **src, u8 desc_type)
+{
+	if (!src)
+		return -EINVAL;
+
+	for (; NULL != *src; src++) {
+		unsigned len;
+
+		if ((*src)->bDescriptorType != desc_type)
+			continue;
+
+		len = (*src)->bLength;
+		if (len > buflen)
+			return -EINVAL;
+
+		memcpy(buf, *src, len);
+		return len;
+	}
+
+	return -ENOENT;
+}
 
 /**
  * usb_descriptor_fillbuf - fill buffer with descriptors
diff --git a/drivers/usb/misc/diag_bridge.c b/drivers/usb/misc/diag_bridge.c
index 5ab987e..9794918 100644
--- a/drivers/usb/misc/diag_bridge.c
+++ b/drivers/usb/misc/diag_bridge.c
@@ -82,6 +82,7 @@
 			urb->status, urb->actual_length);
 
 	if (urb->status == -EPROTO) {
+		dev_err(&dev->udev->dev, "%s: proto error\n", __func__);
 		/* save error so that subsequent read/write returns ESHUTDOWN */
 		dev->err = urb->status;
 		return;
@@ -119,27 +120,36 @@
 	if (dev->err)
 		return -ESHUTDOWN;
 
-	urb = usb_alloc_urb(0, GFP_ATOMIC);
+	urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!urb) {
 		dev_err(&dev->udev->dev, "unable to allocate urb\n");
 		return -ENOMEM;
 	}
 
+	ret = usb_autopm_get_interface(dev->ifc);
+	if (ret < 0) {
+		dev_err(&dev->udev->dev, "autopm_get failed:%d\n", ret);
+		usb_free_urb(urb);
+		return ret;
+	}
+
 	pipe = usb_rcvbulkpipe(dev->udev, dev->in_epAddr);
 	usb_fill_bulk_urb(urb, dev->udev, pipe, data, size,
 				diag_bridge_read_cb, dev);
 	usb_anchor_urb(urb, &dev->submitted);
 	dev->pending_reads++;
 
-	ret = usb_submit_urb(urb, GFP_ATOMIC);
+	ret = usb_submit_urb(urb, GFP_KERNEL);
 	if (ret) {
 		dev_err(&dev->udev->dev, "submitting urb failed err:%d\n", ret);
 		dev->pending_reads--;
 		usb_unanchor_urb(urb);
 		usb_free_urb(urb);
+		usb_autopm_put_interface(dev->ifc);
 		return ret;
 	}
 
+	usb_autopm_put_interface(dev->ifc);
 	usb_free_urb(urb);
 
 	return 0;
@@ -153,7 +163,10 @@
 
 	dev_dbg(&dev->udev->dev, "%s:\n", __func__);
 
+	usb_autopm_put_interface_async(dev->ifc);
+
 	if (urb->status == -EPROTO) {
+		dev_err(&dev->udev->dev, "%s: proto error\n", __func__);
 		/* save error so that subsequent read/write returns ESHUTDOWN */
 		dev->err = urb->status;
 		return;
@@ -191,24 +204,32 @@
 	if (dev->err)
 		return -ESHUTDOWN;
 
-	urb = usb_alloc_urb(0, GFP_ATOMIC);
+	urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!urb) {
 		err("unable to allocate urb");
 		return -ENOMEM;
 	}
 
+	ret = usb_autopm_get_interface(dev->ifc);
+	if (ret < 0) {
+		dev_err(&dev->udev->dev, "autopm_get failed:%d\n", ret);
+		usb_free_urb(urb);
+		return ret;
+	}
+
 	pipe = usb_sndbulkpipe(dev->udev, dev->out_epAddr);
 	usb_fill_bulk_urb(urb, dev->udev, pipe, data, size,
 				diag_bridge_write_cb, dev);
 	usb_anchor_urb(urb, &dev->submitted);
 	dev->pending_writes++;
 
-	ret = usb_submit_urb(urb, GFP_ATOMIC);
+	ret = usb_submit_urb(urb, GFP_KERNEL);
 	if (ret) {
 		dev_err(&dev->udev->dev, "submitting urb failed err:%d\n", ret);
 		dev->pending_writes--;
 		usb_unanchor_urb(urb);
 		usb_free_urb(urb);
+		usb_autopm_put_interface(dev->ifc);
 		return ret;
 	}
 
@@ -381,6 +402,37 @@
 	usb_set_intfdata(ifc, NULL);
 }
 
+static int diag_bridge_suspend(struct usb_interface *ifc, pm_message_t message)
+{
+	struct diag_bridge	*dev = usb_get_intfdata(ifc);
+	struct diag_bridge_ops	*cbs = dev->ops;
+	int ret = 0;
+
+	if (cbs && cbs->suspend) {
+		ret = cbs->suspend(cbs->ctxt);
+		if (ret) {
+			dev_dbg(&dev->udev->dev,
+				"%s: diag veto'd suspend\n", __func__);
+			return ret;
+		}
+
+		usb_kill_anchored_urbs(&dev->submitted);
+	}
+
+	return ret;
+}
+
+static int diag_bridge_resume(struct usb_interface *ifc)
+{
+	struct diag_bridge	*dev = usb_get_intfdata(ifc);
+	struct diag_bridge_ops	*cbs = dev->ops;
+
+
+	if (cbs && cbs->resume)
+		cbs->resume(cbs->ctxt);
+
+	return 0;
+}
 
 #define VALID_INTERFACE_NUM	0
 static const struct usb_device_id diag_bridge_ids[] = {
@@ -401,7 +453,10 @@
 	.name =		"diag_bridge",
 	.probe =	diag_bridge_probe,
 	.disconnect =	diag_bridge_disconnect,
+	.suspend =	diag_bridge_suspend,
+	.resume =	diag_bridge_resume,
 	.id_table =	diag_bridge_ids,
+	.supports_autosuspend = 1,
 };
 
 static int __init diag_bridge_init(void)
@@ -410,8 +465,7 @@
 
 	ret = usb_register(&diag_bridge_driver);
 	if (ret) {
-		err("%s: unable to register diag driver",
-				__func__);
+		err("%s: unable to register diag driver", __func__);
 		return ret;
 	}
 
diff --git a/drivers/usb/misc/mdm_data_bridge.c b/drivers/usb/misc/mdm_data_bridge.c
index a77d98f..cce819f 100644
--- a/drivers/usb/misc/mdm_data_bridge.c
+++ b/drivers/usb/misc/mdm_data_bridge.c
@@ -1013,6 +1013,7 @@
 #define PID9001_IFACE_MASK	0xC
 #define PID9034_IFACE_MASK	0xC
 #define PID9048_IFACE_MASK	0x18
+#define PID904C_IFACE_MASK	0x28
 
 static const struct usb_device_id bridge_ids[] = {
 	{ USB_DEVICE(0x5c6, 0x9001),
@@ -1024,6 +1025,9 @@
 	{ USB_DEVICE(0x5c6, 0x9048),
 	.driver_info = PID9048_IFACE_MASK,
 	},
+	{ USB_DEVICE(0x5c6, 0x904c),
+	.driver_info = PID904C_IFACE_MASK,
+	},
 
 	{ } /* Terminating entry */
 };
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 6964835..dd07d4e 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -67,6 +67,7 @@
 static DECLARE_COMPLETION(pmic_vbus_init);
 static struct msm_otg *the_msm_otg;
 static bool debug_aca_enabled;
+static bool debug_bus_voting_enabled;
 
 /* Prevent idle power collapse(pc) while operating in peripheral mode */
 static void otg_pm_qos_update_latency(struct msm_otg *dev, int vote)
@@ -1155,7 +1156,7 @@
 		 */
 		otg_pm_qos_update_latency(motg, 1);
 		/* Configure BUS performance parameters for MAX bandwidth */
-		if (motg->bus_perf_client) {
+		if (motg->bus_perf_client && debug_bus_voting_enabled) {
 			ret = msm_bus_scale_client_update_request(
 					motg->bus_perf_client, 1);
 			if (ret)
@@ -2232,13 +2233,64 @@
 	.release = single_release,
 };
 
+static int msm_otg_bus_show(struct seq_file *s, void *unused)
+{
+	if (debug_bus_voting_enabled)
+		seq_printf(s, "enabled\n");
+	else
+		seq_printf(s, "disabled\n");
+
+	return 0;
+}
+
+static int msm_otg_bus_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, msm_otg_bus_show, inode->i_private);
+}
+
+static ssize_t msm_otg_bus_write(struct file *file, const char __user *ubuf,
+				size_t count, loff_t *ppos)
+{
+	char buf[8];
+	int ret;
+	struct seq_file *s = file->private_data;
+	struct msm_otg *motg = s->private;
+
+	memset(buf, 0x00, sizeof(buf));
+
+	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
+		return -EFAULT;
+
+	if (!strncmp(buf, "enable", 6)) {
+		/* Do not vote here. Let OTG statemachine decide when to vote */
+		debug_bus_voting_enabled = true;
+	} else {
+		debug_bus_voting_enabled = false;
+		if (motg->bus_perf_client) {
+			ret = msm_bus_scale_client_update_request(
+					motg->bus_perf_client, 0);
+			if (ret)
+				dev_err(motg->otg.dev, "%s: Failed to devote "
+					   "for bus bw %d\n", __func__, ret);
+		}
+	}
+
+	return count;
+}
+
+const struct file_operations msm_otg_bus_fops = {
+	.open = msm_otg_bus_open,
+	.read = seq_read,
+	.write = msm_otg_bus_write,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
 static struct dentry *msm_otg_dbg_root;
-static struct dentry *msm_otg_dbg_mode;
-static struct dentry *msm_otg_chg_type;
-static struct dentry *msm_otg_dbg_aca;
 
 static int msm_otg_debugfs_init(struct msm_otg *motg)
 {
+	struct dentry *msm_otg_dentry;
 
 	msm_otg_dbg_root = debugfs_create_dir("msm_otg", NULL);
 
@@ -2248,35 +2300,43 @@
 	if (motg->pdata->mode == USB_OTG &&
 		motg->pdata->otg_control == OTG_USER_CONTROL) {
 
-		msm_otg_dbg_mode = debugfs_create_file("mode", S_IRUGO |
+		msm_otg_dentry = debugfs_create_file("mode", S_IRUGO |
 			S_IWUSR, msm_otg_dbg_root, motg,
 			&msm_otg_mode_fops);
 
-		if (!msm_otg_dbg_mode) {
+		if (!msm_otg_dentry) {
 			debugfs_remove(msm_otg_dbg_root);
 			msm_otg_dbg_root = NULL;
 			return -ENODEV;
 		}
 	}
 
-	msm_otg_chg_type = debugfs_create_file("chg_type", S_IRUGO,
+	msm_otg_dentry = debugfs_create_file("chg_type", S_IRUGO,
 		msm_otg_dbg_root, motg,
 		&msm_otg_chg_fops);
 
-	if (!msm_otg_chg_type) {
+	if (!msm_otg_dentry) {
 		debugfs_remove_recursive(msm_otg_dbg_root);
 		return -ENODEV;
 	}
 
-	msm_otg_dbg_aca = debugfs_create_file("aca", S_IRUGO | S_IWUSR,
+	msm_otg_dentry = debugfs_create_file("aca", S_IRUGO | S_IWUSR,
 		msm_otg_dbg_root, motg,
 		&msm_otg_aca_fops);
 
-	if (!msm_otg_dbg_aca) {
+	if (!msm_otg_dentry) {
 		debugfs_remove_recursive(msm_otg_dbg_root);
 		return -ENODEV;
 	}
 
+	msm_otg_dentry = debugfs_create_file("bus_voting", S_IRUGO | S_IWUSR,
+		msm_otg_dbg_root, motg,
+		&msm_otg_bus_fops);
+
+	if (!msm_otg_dentry) {
+		debugfs_remove_recursive(msm_otg_dbg_root);
+		return -ENODEV;
+	}
 	return 0;
 }
 
@@ -2642,6 +2702,8 @@
 		if (!motg->bus_perf_client)
 			dev_err(motg->otg.dev, "%s: Failed to register BUS "
 						"scaling client!!\n", __func__);
+		else
+			debug_bus_voting_enabled = true;
 	}
 
 	return 0;
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index ef357db..96d9487 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -2475,12 +2475,6 @@
 			goto error;
 		}
 
-		/*
-		 * A small delay is needed here to avoid device crash observed
-		 * during reauthentication in MSM8960
-		 */
-		msleep(20);
-
 		/* 0x0168 HDCP_RCVPORT_DATA12
 		   [23:8] BSTATUS
 		   [7:0] BCAPS */
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index c57ec5d..033a73c 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -1887,7 +1887,7 @@
 
 static int get_img(struct msmfb_data *img, struct fb_info *info,
 	unsigned long *start, unsigned long *len, struct file **srcp_file,
-	struct ion_handle **srcp_ihdl)
+	int *p_need, struct ion_handle **srcp_ihdl)
 {
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
@@ -1897,6 +1897,8 @@
 #ifdef CONFIG_ANDROID_PMEM
 	unsigned long vstart;
 #endif
+	*p_need = 0;
+
 	if (img->flags & MDP_BLIT_SRC_GEM) {
 		*srcp_file = NULL;
 		return kgsl_gem_obj_addr(img->memory_id, (int) img->priv,
@@ -1912,8 +1914,10 @@
 			fb_num = MINOR(file->f_dentry->d_inode->i_rdev);
 			if (get_fb_phys_info(start, len, fb_num))
 				ret = -1;
-			else
+			else {
 				*srcp_file = file;
+				*p_need = put_needed;
+			}
 		} else
 			ret = -1;
 		if (ret)
@@ -2137,6 +2141,21 @@
 	mfd->ov0_blt_state = mfd->use_ov0_blt;
 }
 
+static void mdp4_overlay1_update_blt_mode(struct msm_fb_data_type *mfd)
+{
+	if (mfd->ov1_blt_state == mfd->use_ov1_blt)
+		return;
+	if (mfd->use_ov1_blt) {
+		mdp4_allocate_writeback_buf(mfd, MDP4_MIXER1);
+		mdp4_dtv_overlay_blt_start(mfd);
+		pr_debug("%s overlay1 writeback is enabled\n", __func__);
+	} else {
+		mdp4_dtv_overlay_blt_stop(mfd);
+		pr_debug("%s overlay1 writeback is disabled\n", __func__);
+	}
+	mfd->ov1_blt_state = mfd->use_ov1_blt;
+}
+
 static u32 mdp4_overlay_blt_enable(struct mdp_overlay *req,
 	struct msm_fb_data_type *mfd, uint32 perf_level)
 {
@@ -2147,7 +2166,8 @@
 		clk_rate = (&mfd->panel_info.mipi)->dsi_pclk_rate;
 
 	if ((mfd->panel_info.type == LCDC_PANEL) ||
-		(mfd->panel_info.type == MIPI_VIDEO_PANEL))
+	    (mfd->panel_info.type == MIPI_VIDEO_PANEL) ||
+	    (mfd->panel_info.type == DTV_PANEL))
 		pull_mode = 1;
 
 	if (pull_mode && (req->src_rect.h > req->dst_rect.h ||
@@ -2166,7 +2186,8 @@
 			if (req->dst_rect.x != 0)
 				use_blt = 1;
 		}
-		if (mfd->panel_info.xres > 1280)
+		if ((mfd->panel_info.xres > 1280) &&
+		    (mfd->panel_info.type != DTV_PANEL))
 			use_blt = 1;
 	}
 	return use_blt;
@@ -2249,8 +2270,12 @@
 	}
 
 	if (ctrl->panel_mode & MDP4_PANEL_DTV &&
-	    pipe->mixer_num == MDP4_MIXER1)
+	    pipe->mixer_num == MDP4_MIXER1) {
+		u32 use_blt = mdp4_overlay_blt_enable(req, mfd, perf_level);
 		mdp4_overlay_dtv_set(mfd, pipe);
+		mfd->use_ov1_blt &= ~(1 << (pipe->pipe_ndx-1));
+		mfd->use_ov1_blt |= (use_blt << (pipe->pipe_ndx-1));
+	}
 
 	if (new_perf_level != perf_level) {
 		u32 old_level = new_perf_level;
@@ -2358,8 +2383,14 @@
 			if (!mfd->use_ov0_blt)
 				mdp4_free_writeback_buf(mfd, MDP4_MIXER0);
 		} else {	/* mixer1, DTV, ATV */
-			if (ctrl->panel_mode & MDP4_PANEL_DTV)
+			if (ctrl->panel_mode & MDP4_PANEL_DTV) {
 				mdp4_overlay_dtv_unset(mfd, pipe);
+				mfd->use_ov1_blt &= ~(1 << (pipe->pipe_ndx-1));
+				mdp4_overlay1_update_blt_mode(mfd);
+				if (!mfd->use_ov1_blt)
+					mdp4_free_writeback_buf(mfd,
+								MDP4_MIXER1);
+			}
 		}
 	}
 
@@ -2436,6 +2467,9 @@
 
 	mdp4_mixer_stage_commit(pipe->mixer_num);
 
+	if (mfd->use_ov1_blt)
+		mdp4_overlay1_update_blt_mode(mfd);
+
 	mdp4_overlay_dtv_wait_for_ov(mfd, pipe);
 
 	mutex_unlock(&mfd->dma->ov_mutex);
@@ -2453,6 +2487,7 @@
 	struct file *srcp1_file = NULL, *srcp2_file = NULL;
 	struct ion_handle *srcp0_ihdl = NULL;
 	struct ion_handle *srcp1_ihdl = NULL, *srcp2_ihdl = NULL;
+	int ps0_need, p_need;
 	uint32_t overlay_version = 0;
 	int ret = 0;
 
@@ -2472,7 +2507,7 @@
 		return -EINTR;
 
 	img = &req->data;
-	get_img(img, info, &start, &len, &srcp0_file, &srcp0_ihdl);
+	get_img(img, info, &start, &len, &srcp0_file, &ps0_need, &srcp0_ihdl);
 	if (len == 0) {
 		mutex_unlock(&mfd->dma->ov_mutex);
 		pr_err("%s: pmem Error\n", __func__);
@@ -2491,7 +2526,7 @@
 		if (overlay_version > 0) {
 			img = &req->plane1_data;
 			get_img(img, info, &start, &len, &srcp1_file,
-				&srcp1_ihdl);
+				&p_need, &srcp1_ihdl);
 			if (len == 0) {
 				mutex_unlock(&mfd->dma->ov_mutex);
 				pr_err("%s: Error to get plane1\n", __func__);
@@ -2523,7 +2558,7 @@
 		if (overlay_version > 0) {
 			img = &req->plane1_data;
 			get_img(img, info, &start, &len, &srcp1_file,
-				&srcp1_ihdl);
+				&p_need, &srcp1_ihdl);
 			if (len == 0) {
 				mutex_unlock(&mfd->dma->ov_mutex);
 				pr_err("%s: Error to get plane1\n", __func__);
@@ -2534,7 +2569,7 @@
 
 			img = &req->plane2_data;
 			get_img(img, info, &start, &len, &srcp2_file,
-				&srcp2_ihdl);
+				&p_need, &srcp2_ihdl);
 			if (len == 0) {
 				mutex_unlock(&mfd->dma->ov_mutex);
 				pr_err("%s: Error to get plane2\n", __func__);
@@ -2577,6 +2612,9 @@
 	if (mfd->use_ov0_blt)
 		mdp4_overlay_update_blt_mode(mfd);
 
+	if (mfd->use_ov1_blt)
+		mdp4_overlay1_update_blt_mode(mfd);
+
 	if (pipe->pipe_type == OVERLAY_TYPE_VIDEO) {
 		mdp4_overlay_vg_setup(pipe);	/* video/graphic pipe */
 	} else {
@@ -2602,8 +2640,11 @@
 	} else if (pipe->mixer_num == MDP4_MIXER1) {
 		ctrl->mixer1_played++;
 		/* enternal interface */
-		if (ctrl->panel_mode & MDP4_PANEL_DTV)
+		if (ctrl->panel_mode & MDP4_PANEL_DTV) {
 			mdp4_overlay_dtv_ov_done_push(mfd, pipe);
+			if (!mfd->use_ov1_blt)
+				mdp4_overlay1_update_blt_mode(mfd);
+			}
 	} else {
 
 		/* primary interface */
@@ -2656,9 +2697,13 @@
 	if (srcp2_file)
 		put_pmem_file(srcp2_file);
 #endif
+	/* only source may use frame buffer */
+	if (img->flags & MDP_MEMORY_ID_TYPE_FB)
+		fput_light(srcp0_file, ps0_need);
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	if (!IS_ERR_OR_NULL(srcp0_ihdl))
+	else if (!IS_ERR_OR_NULL(srcp0_ihdl))
 		ion_free(mfd->iclient, srcp0_ihdl);
+
 	if (!IS_ERR_OR_NULL(srcp1_ihdl))
 		ion_free(mfd->iclient, srcp1_ihdl);
 	if (!IS_ERR_OR_NULL(srcp2_ihdl))
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index 635b104..d5c08e8 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -301,7 +301,7 @@
 		/* MSP_BORDER_COLOR */
 		MDP_OUTP(MDP_BASE + MDP4_OVERLAYPROC1_BASE + 0x5008,
 			(0x0 & 0xFFF));		/* 12-bit R */
-		mdp_pipe_ctrl(MDP_OVERLAY1_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 	} else {
 		switch (mfd->ibuf.bpp) {
 		case 2:
@@ -596,13 +596,11 @@
 
 void mdp4_dtv_overlay_blt_start(struct msm_fb_data_type *mfd)
 {
-	mdp4_allocate_writeback_buf(mfd, MDP4_MIXER1);
 	mdp4_dtv_do_blt(mfd, 1);
 }
 
 void mdp4_dtv_overlay_blt_stop(struct msm_fb_data_type *mfd)
 {
-	mdp4_free_writeback_buf(mfd, MDP4_MIXER1);
 	mdp4_dtv_do_blt(mfd, 0);
 }
 
diff --git a/drivers/video/msm/msm_dss_io_8960.c b/drivers/video/msm/msm_dss_io_8960.c
index 3b000ec..0f40c77 100644
--- a/drivers/video/msm/msm_dss_io_8960.c
+++ b/drivers/video/msm/msm_dss_io_8960.c
@@ -11,6 +11,7 @@
  *
  */
 #include <linux/clk.h>
+#include <mach/clk.h>
 #include "msm_fb.h"
 #include "mdp.h"
 #include "mdp4.h"
@@ -634,6 +635,10 @@
 	hdmi_msm_clk(0);
 	udelay(5);
 	hdmi_msm_clk(1);
+
+	clk_reset(hdmi_msm_state->hdmi_app_clk, CLK_RESET_ASSERT);
+	udelay(20);
+	clk_reset(hdmi_msm_state->hdmi_app_clk, CLK_RESET_DEASSERT);
 }
 
 void hdmi_msm_init_phy(int video_format)
diff --git a/drivers/video/msm/msm_fb.h b/drivers/video/msm/msm_fb.h
index 9837f07..a4b46ea 100644
--- a/drivers/video/msm/msm_fb.h
+++ b/drivers/video/msm/msm_fb.h
@@ -177,6 +177,7 @@
 	u32 mem_hid;
 	u32 mdp_rev;
 	u32 use_ov0_blt, ov0_blt_state;
+	u32 use_ov1_blt, ov1_blt_state;
 	u32 writeback_state;
 };
 
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c
index 3f54756..267e924 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -246,6 +246,8 @@
 	DDL_METADATA_ALIGNSIZE(suffix);
 	encoder->suffix = suffix;
 	encoder->output_buf_req.sz += suffix;
+	encoder->output_buf_req.sz =
+		DDL_ALIGN(encoder->output_buf_req.sz, DDL_KILO_BYTE(4));
 }
 
 u32 ddl_set_metadata_params(struct ddl_client_context *ddl,
@@ -454,6 +456,7 @@
 		return;
 	}
 	out_frame->flags |= VCD_FRAME_FLAG_EXTRADATA;
+	DDL_MSG_LOW("processing metadata for encoder");
 	start_addr = (u32) ((u8 *)out_frame->virtual + out_frame->offset);
 	qfiller = (u32 *)((out_frame->data_len +
 				start_addr + 3) & ~3);
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
index 51a72c8..444db9f 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -915,10 +915,15 @@
 	}
 	case VCD_I_METADATA_ENABLE:
 	case VCD_I_METADATA_HEADER:
-		DDL_MSG_ERROR("Meta Data Interface is Requested");
-		vcd_status = ddl_set_metadata_params(ddl, property_hdr,
-			property_value);
-		vcd_status = VCD_S_SUCCESS;
+		DDL_MSG_LOW("Meta Data Interface is Requested");
+		if (!res_trk_check_for_sec_session()) {
+			vcd_status = ddl_set_metadata_params(ddl,
+				property_hdr, property_value);
+		} else {
+			DDL_MSG_ERROR("Meta Data Interface is not "
+				"supported in secure session");
+			vcd_status = VCD_ERR_ILLEGAL_OP;
+		}
 	break;
 	case VCD_I_META_BUFFER_MODE:
 		vcd_status = VCD_S_SUCCESS;
@@ -1836,8 +1841,16 @@
 		/*original_buf_req->align <= req_buf_req->align,*/
 		original_buf_req->sz <= req_buf_req->sz)
 		status = true;
-	else
+	else {
 		DDL_MSG_ERROR("ddl_valid_buf_req:Failed");
+		DDL_MSG_ERROR("codec_buf_req: min_cnt=%d, mx_cnt=%d, "
+			"align=%d, sz=%d\n", original_buf_req->min_count,
+			original_buf_req->max_count, original_buf_req->align,
+			original_buf_req->sz);
+		DDL_MSG_ERROR("client_buffs: actual_count=%d, align=%d, "
+			"sz=%d\n", req_buf_req->actual_count,
+			req_buf_req->align,	req_buf_req->sz);
+	}
 	return status;
 }
 
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index 6d6dcdc..3c25751 100644
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.c
@@ -1575,6 +1575,34 @@
 		}
 		break;
 	}
+	case VEN_IOCTL_SET_EXTRADATA:
+	case VEN_IOCTL_GET_EXTRADATA:
+	{
+		u32 extradata_flag;
+		DBG("VEN_IOCTL_(G)SET_EXTRADATA\n");
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		if (cmd == VEN_IOCTL_SET_EXTRADATA) {
+			if (copy_from_user(&extradata_flag, venc_msg.in,
+					sizeof(u32)))
+				return -EFAULT;
+			result = vid_enc_set_get_extradata(client_ctx,
+					&extradata_flag, true);
+		} else {
+			result = vid_enc_set_get_extradata(client_ctx,
+					&extradata_flag, false);
+			if (result) {
+				if (copy_to_user(venc_msg.out, &extradata_flag,
+						sizeof(u32)))
+					return -EFAULT;
+			}
+		}
+		if (!result) {
+			ERR("setting VEN_IOCTL_(G)SET_LIVE_MODE failed\n");
+			return -EIO;
+		}
+		break;
+	}
 	case VEN_IOCTL_SET_AC_PREDICTION:
 	case VEN_IOCTL_GET_AC_PREDICTION:
 	case VEN_IOCTL_SET_RVLC:
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.c b/drivers/video/msm/vidc/common/enc/venc_internal.c
index f362f7b..cac5dc4 100644
--- a/drivers/video/msm/vidc/common/enc/venc_internal.c
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.c
@@ -316,6 +316,42 @@
 	return true;
 }
 
+u32 vid_enc_set_get_extradata(struct video_client_ctx *client_ctx,
+		u32 *extradata_flag, u32 set_flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_meta_data_enable vcd_meta_data;
+	u32 vcd_status = VCD_ERR_FAIL;
+	if (!client_ctx || !extradata_flag)
+		return false;
+	vcd_property_hdr.prop_id = VCD_I_METADATA_ENABLE;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_meta_data_enable);
+	if (set_flag) {
+		DBG("vcd_set_property: VCD_I_METADATA_ENABLE = %d\n",
+				*extradata_flag);
+		vcd_meta_data.meta_data_enable_flag = *extradata_flag;
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &vcd_meta_data);
+		if (vcd_status) {
+			ERR("%s(): Set VCD_I_METADATA_ENABLE Failed\n",
+				__func__);
+			return false;
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &vcd_meta_data);
+		if (vcd_status) {
+			ERR("%s(): Get VCD_I_METADATA_ENABLE Failed\n",
+				__func__);
+			return false;
+		}
+		*extradata_flag = vcd_meta_data.meta_data_enable_flag;
+		DBG("vcd_get_property: VCD_I_METADATA_ENABLE = %d\n",
+				*extradata_flag);
+	}
+	return true;
+}
+
 u32 vid_enc_set_get_framerate(struct video_client_ctx *client_ctx,
 		struct venc_framerate *frame_rate, u32 set_flag)
 {
@@ -1494,6 +1530,11 @@
 		venc_buf_req->alignment = buffer_req.align;
 		venc_buf_req->bufpoolid = buffer_req.buf_pool_id;
 		venc_buf_req->suffixsize = 0;
+		DBG("%s: actual_count=%d, align=%d, sz=%d, min_count=%d, "
+			"max_count=%d, buf_pool_id=%d\n", __func__,
+			buffer_req.actual_count, buffer_req.align,
+			buffer_req.sz, buffer_req.min_count,
+			buffer_req.max_count, buffer_req.buf_pool_id);
 	}
 	return status;
 }
@@ -1521,6 +1562,11 @@
 	buffer_req.align = venc_buf_req->alignment;
 	buffer_req.buf_pool_id = 0;
 
+	DBG("%s: actual_count=%d, align=%d, sz=%d, min_count=%d, "
+		"max_count=%d, buf_pool_id=%d\n", __func__,
+		buffer_req.actual_count, buffer_req.align, buffer_req.sz,
+		buffer_req.min_count, buffer_req.max_count,
+		buffer_req.buf_pool_id);
 	vcd_status = vcd_set_buffer_requirements(client_ctx->vcd_handle,
 				buffer, &buffer_req);
 
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.h b/drivers/video/msm/vidc/common/enc/venc_internal.h
index a07f7ab..8a07fdb 100644
--- a/drivers/video/msm/vidc/common/enc/venc_internal.h
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.h
@@ -68,6 +68,9 @@
 u32 vid_enc_set_get_live_mode(struct video_client_ctx *client_ctx,
 		struct venc_switch *encoder_switch, u32 set_flag);
 
+u32 vid_enc_set_get_extradata(struct video_client_ctx *client_ctx,
+		u32 *extradata_flag, u32 set_flag);
+
 u32 vid_enc_set_get_short_header(struct video_client_ctx *client_ctx,
 		struct venc_switch *encoder_switch, u32 set_flag);
 
diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h
index 3ac41bc..a2391e3 100644
--- a/include/linux/i2c/atmel_mxt_ts.h
+++ b/include/linux/i2c/atmel_mxt_ts.h
@@ -29,6 +29,12 @@
 /* MXT_TOUCH_KEYARRAY_T15 */
 #define MXT_KEYARRAY_MAX_KEYS	32
 
+/* Bootoader IDs */
+#define MXT_BOOTLOADER_ID_224		0x0A
+#define MXT_BOOTLOADER_ID_224E		0x06
+#define MXT_BOOTLOADER_ID_1386		0x01
+#define MXT_BOOTLOADER_ID_1386E		0x10
+
 /* Config data for a given maXTouch controller with a specific firmware */
 struct mxt_config_info {
 	const u8 *config;
@@ -37,6 +43,7 @@
 	u8 variant_id;
 	u8 version;
 	u8 build;
+	u8 bootldr_id;
 	/* Points to the firmware name to be upgraded to */
 	const char *fw_name;
 };
diff --git a/include/linux/libra_sdioif.h b/include/linux/libra_sdioif.h
index 965e2b5..08be83a 100644
--- a/include/linux/libra_sdioif.h
+++ b/include/linux/libra_sdioif.h
@@ -35,6 +35,7 @@
 typedef int (suspend_handler_t)(struct sdio_func *);
 typedef void (resume_handler_t)(struct sdio_func *);
 
+int libra_enable_sdio_irq_in_chip(struct sdio_func *func, u8 enable);
 int    libra_sdio_configure(sdio_irq_handler_t libra_sdio_rxhandler,
 		void (*func_drv_fn)(int *status),
 		u32 funcdrv_timeout, u32 blksize);
diff --git a/include/linux/mfd/wcd9xxx/wcd9310_registers.h b/include/linux/mfd/wcd9xxx/wcd9310_registers.h
index d2736ea..67c2a6b 100644
--- a/include/linux/mfd/wcd9xxx/wcd9310_registers.h
+++ b/include/linux/mfd/wcd9xxx/wcd9310_registers.h
@@ -897,6 +897,38 @@
 #define TABLA_A_CDC_DEBUG_B5_CTL__POR			(0x00000000)
 #define TABLA_A_CDC_DEBUG_B6_CTL			(0x0000036D)
 #define TABLA_A_CDC_DEBUG_B6_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP1_B1_CTL			(0x00000370)
+#define TABLA_A_CDC_COMP1_B1_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP1_B2_CTL			(0x00000371)
+#define TABLA_A_CDC_COMP1_B2_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP1_B3_CTL			(0x00000372)
+#define TABLA_A_CDC_COMP1_B3_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP1_B4_CTL			(0x00000373)
+#define TABLA_A_CDC_COMP1_B4_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP1_B5_CTL			(0x00000374)
+#define TABLA_A_CDC_COMP1_B5_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP1_B6_CTL			(0x00000375)
+#define TABLA_A_CDC_COMP1_B6_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS		(0x00000376)
+#define TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS__POR	(0x00000000)
+#define TABLA_A_CDC_COMP1_FS_CFG			(0x00000377)
+#define TABLA_A_CDC_COMP1_FS_CFG__POR			(0x00000000)
+#define TABLA_A_CDC_COMP2_B1_CTL			(0x00000378)
+#define TABLA_A_CDC_COMP2_B1_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP2_B2_CTL			(0x00000379)
+#define TABLA_A_CDC_COMP2_B2_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP2_B3_CTL			(0x0000037A)
+#define TABLA_A_CDC_COMP2_B3_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP2_B4_CTL			(0x0000037B)
+#define TABLA_A_CDC_COMP2_B4_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP2_B5_CTL			(0x0000037C)
+#define TABLA_A_CDC_COMP2_B5_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP2_B6_CTL			(0x0000037D)
+#define TABLA_A_CDC_COMP2_B6_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP2_SHUT_DOWN_STATUS		(0x0000037E)
+#define TABLA_A_CDC_COMP2_SHUT_DOWN_STATUS__POR	(0x00000000)
+#define TABLA_A_CDC_COMP2_FS_CFG			(0x0000037F)
+#define TABLA_A_CDC_COMP2_FS_CFG__POR			(0x00000000)
 #define TABLA_A_CDC_CONN_RX1_B1_CTL			(0x00000380)
 #define TABLA_A_CDC_CONN_RX1_B1_CTL__POR			(0x00000000)
 #define TABLA_A_CDC_CONN_RX1_B2_CTL			(0x00000381)
diff --git a/include/linux/msm_vidc_enc.h b/include/linux/msm_vidc_enc.h
index 1f264e9..bf149eb 100644
--- a/include/linux/msm_vidc_enc.h
+++ b/include/linux/msm_vidc_enc.h
@@ -52,6 +52,11 @@
 #define VEN_BUFFLAG_EXTRADATA	0x00000040
 #define VEN_BUFFLAG_CODECCONFIG	0x00000080
 
+/*Post processing flags bit masks*/
+#define VEN_EXTRADATA_NONE          0x001
+#define VEN_EXTRADATA_QCOMFILLER    0x002
+#define VEN_EXTRADATA_SLICEINFO     0x100
+
 /*ENCODER CONFIGURATION CONSTANTS*/
 
 /*Encoded video frame types*/
@@ -257,6 +262,8 @@
 #define VEN_IOCTL_GET_RECON_BUFFER_SIZE \
 	_IOW(VEN_IOCTLBASE_NENC, 22, struct venc_ioctl_msg)
 
+
+
 /*ENCODER PROPERTY CONFIGURATION & CAPABILITY IOCTLs*/
 
 /*IOCTL params:SET: InputData - venc_basecfg, OutputData - NULL
@@ -439,6 +446,14 @@
 #define VEN_IOCTL_SET_METABUFFER_MODE \
 	_IOW(VEN_IOCTLBASE_ENC, 47, struct venc_ioctl_msg)
 
+
+/*IOCTL params:SET: InputData - unsigned int, OutputData - NULL.*/
+#define VEN_IOCTL_SET_EXTRADATA \
+	_IOW(VEN_IOCTLBASE_ENC, 48, struct venc_ioctl_msg)
+/*IOCTL params:GET: InputData - NULL, OutputData - unsigned int.*/
+#define VEN_IOCTL_GET_EXTRADATA \
+	_IOR(VEN_IOCTLBASE_ENC, 49, struct venc_ioctl_msg)
+
 struct venc_switch{
 	unsigned char	status;
 };
diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
index 736203b..e4ee15c 100644
--- a/include/linux/usb/ch9.h
+++ b/include/linux/usb/ch9.h
@@ -147,7 +147,7 @@
 #define USB_ENDPOINT_HALT		0	/* IN/OUT will STALL */
 
 #define OTG_STATUS_SELECTOR	0xF000
-#define THOST_REQ_POLL		2000    /* msec */
+#define THOST_REQ_POLL			1500    /* msec (1000 - 2000) */
 #define HOST_REQUEST_FLAG	0
 
 /* Bit array elements as returned by the USB_REQ_GET_STATUS request. */
@@ -617,8 +617,10 @@
 	__u8  bDescriptorType;
 
 	__u8  bmAttributes;	/* support for HNP, SRP, etc */
+	__le16 bcdOTG;
 } __attribute__ ((packed));
 
+#define USB_DT_OTG_SIZE		5
 /* from usb_otg_descriptor.bmAttributes */
 #define USB_OTG_SRP		(1 << 0)
 #define USB_OTG_HNP		(1 << 1)	/* swap host/device roles */
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 47e8427..a9c1b6a 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -860,6 +860,11 @@
 
 /* utility to simplify managing config descriptors */
 
+/* Find and fill the requested descriptor into buffer */
+int
+usb_find_descriptor_fillbuf(void *, unsigned,
+		const struct usb_descriptor_header **, u8);
+
 /* write vector of descriptors into buffer */
 int usb_descriptor_fillbuf(void *, unsigned,
 		const struct usb_descriptor_header **);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index fec6f32..86479ab 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1106,9 +1106,25 @@
 
 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
 	if (conn) {
-		if (status && conn->state == BT_CONFIG) {
-			hci_proto_connect_cfm(conn, status);
-			hci_conn_put(conn);
+		if (status) {
+			mgmt_auth_failed(hdev->id, &conn->dst, status);
+			clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
+
+			if (conn->state == BT_CONFIG) {
+				conn->state = BT_CONNECTED;
+				hci_proto_connect_cfm(conn, status);
+				hci_conn_put(conn);
+			} else {
+				hci_auth_cfm(conn, status);
+				hci_conn_hold(conn);
+				conn->disc_timeout = HCI_DISCONN_TIMEOUT;
+				hci_conn_put(conn);
+			}
+
+			if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
+				clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
+				hci_encrypt_cfm(conn, status, 0x00);
+			}
 		}
 		conn->auth_initiator = 1;
 	}
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 9662795..a3d5e34 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -569,7 +569,7 @@
 		struct hci_chan *ampchan = l2cap_pi(sk)->ampchan;
 		l2cap_pi(sk)->ampchan = NULL;
 		if (!hci_chan_put(ampchan))
-			l2cap_deaggregate(l2cap_pi(sk)->ampchan, l2cap_pi(sk));
+			l2cap_deaggregate(ampchan, l2cap_pi(sk));
 	}
 
 	sk->sk_state = BT_CLOSED;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 910ef77..25ad435 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2672,8 +2672,11 @@
 	if ((conn->auth_type & HCI_AT_DEDICATED_BONDING) &&
 			conn->auth_initiator && rem_cap == 0x03)
 		ev.auto_confirm = 1;
-	else if (loc_cap == 0x01 && (rem_cap == 0x00 || rem_cap == 0x03))
+	else if (loc_cap == 0x01 && (rem_cap == 0x00 || rem_cap == 0x03)) {
+		if (!loc_mitm && !rem_mitm)
+			value = 0;
 		goto no_auto_confirm;
+	}
 
 
 	if ((!loc_mitm || rem_cap == 0x03) && (!rem_mitm || loc_cap == 0x03))
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 0d41625..11e1a67 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -8,9 +8,10 @@
 use strict;
 
 use constant BEFORE_SHORTTEXT => 0;
-use constant IN_SHORTTEXT => 1;
-use constant AFTER_SHORTTEXT => 2;
-use constant CHECK_NEXT_SHORTTEXT => 3;
+use constant IN_SHORTTEXT_BLANKLINE => 1;
+use constant IN_SHORTTEXT => 2;
+use constant AFTER_SHORTTEXT => 3;
+use constant CHECK_NEXT_SHORTTEXT => 4;
 use constant SHORTTEXT_LIMIT => 75;
 
 my $P = $0;
@@ -1233,6 +1234,7 @@
 
 	my $shorttext = BEFORE_SHORTTEXT;
 	my $shorttext_exspc = 0;
+	my $commit_text_present = 0;
 
 	sanitise_line_reset();
 	cleanup_continuation_headers();
@@ -1416,8 +1418,24 @@
 		my $hereprev = "$here\n$prevrawline\n$rawline\n";
 
 		if ($shorttext != AFTER_SHORTTEXT) {
+			if ($shorttext == IN_SHORTTEXT_BLANKLINE && $line=~/\S/) {
+				# the subject line was just processed,
+				# a blank line must be next
+				WARN("non-blank line after summary line\n" . $herecurr);
+				$shorttext = IN_SHORTTEXT;
+				# this non-blank line may or may not be commit text -
+				# a warning has been generated so assume it is commit
+				# text and move on
+				$commit_text_present = 1;
+				# fall through and treat this line as IN_SHORTTEXT
+			}
 			if ($shorttext == IN_SHORTTEXT) {
 				if ($line=~/^---/ || $line=~/^diff.*/) {
+					if ($commit_text_present == 0) {
+						WARN("please add commit text explaining " .
+						     "*why* the change is needed\n" .
+						     $herecurr);
+					}
 					$shorttext = AFTER_SHORTTEXT;
 				} elsif (length($line) > (SHORTTEXT_LIMIT +
 							  $shorttext_exspc)
@@ -1427,7 +1445,22 @@
 					WARN("commit text line over " .
 					     SHORTTEXT_LIMIT .
 					     " characters\n" . $herecurr);
+				} elsif ($line=~/^\s*[\x21-\x39\x3b-\x7e]+:/) {
+					# this is a tag, there must be commit
+					# text by now
+					if ($commit_text_present == 0) {
+						WARN("please add commit text explaining " .
+						     "*why* the change is needed\n" .
+						     $herecurr);
+						# prevent duplicate warnings
+						$commit_text_present = 1;
+					}
+				} elsif ($line=~/\S/) {
+					$commit_text_present = 1;
 				}
+			} elsif ($shorttext == IN_SHORTTEXT_BLANKLINE) {
+				# case of non-blank line in this state handled above
+				$shorttext = IN_SHORTTEXT;
 			} elsif ($shorttext == CHECK_NEXT_SHORTTEXT) {
 # The Subject line doesn't have to be the last header in the patch.
 # Avoid moving to the IN_SHORTTEXT state until clear of all headers.
@@ -1435,16 +1468,25 @@
 # text which looks like a header is definitely a header.
 				if ($line!~/^[\x21-\x39\x3b-\x7e]+:/) {
 					$shorttext = IN_SHORTTEXT;
-# Check for Subject line followed by a blank line.
+					# Check for Subject line followed by a blank line.
 					if (length($line) != 0) {
 						WARN("non-blank line after " .
 						     "summary line\n" .
 						     $sublinenr . $here .
 						     "\n" . $subjectline .
 						     "\n" . $line . "\n");
+						# this non-blank line may or may not
+						# be commit text - a warning has been
+						# generated so assume it is commit
+						# text and move on
+						$commit_text_present = 1;
 					}
 				}
+			# The next two cases are BEFORE_SHORTTEXT.
 			} elsif ($line=~/^Subject: \[[^\]]*\] (.*)/) {
+				# This is the subject line. Go to
+				# CHECK_NEXT_SHORTTEXT to wait for the commit
+				# text to show up.
 				$shorttext = CHECK_NEXT_SHORTTEXT;
 				$subjectline = $line;
 				$sublinenr = "#$linenr & ";
@@ -1455,7 +1497,10 @@
 					     " characters\n" . $herecurr);
 				}
 			} elsif ($line=~/^    (.*)/) {
-				$shorttext = IN_SHORTTEXT;
+				# Indented format, this must be the summary
+				# line (i.e. git show). There will be no more
+				# headers so we are now in the shorttext.
+				$shorttext = IN_SHORTTEXT_BLANKLINE;
 				$shorttext_exspc = 4;
 				if (length($1) > SHORTTEXT_LIMIT) {
 					WARN("summary line over " .
diff --git a/scripts/setlocalversion b/scripts/setlocalversion
index 4d40384..2c52866 100755
--- a/scripts/setlocalversion
+++ b/scripts/setlocalversion
@@ -55,16 +55,17 @@
 				echo "+"
 				return
 			fi
-			# If we are past a tagged commit (like
-			# "v2.6.30-rc5-302-g72357d5"), we pretty print it.
-			if atag="`git describe 2>/dev/null`"; then
-				echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'
-
-			# If we don't have a tag at all we print -g{commitish}.
-			else
-				printf '%s%s' -g $head
-			fi
 		fi
+		# If we are past a tagged commit (like
+		# "v2.6.30-rc5-302-g72357d5"), we pretty print it but strip
+		# off the v2.6.30-rc5 part because that's in the Makefile.
+		if atag="`git describe 2>/dev/null`"; then
+			atag="-${atag/v$KERNELVERSION-/}"
+		# If we don't have a tag at all we print -g{commitish}.
+		else
+			atag="-g$head"
+		fi
+		printf '%s' "$atag"
 
 		# Is this git on svn?
 		if git config --get svn-remote.svn.url >/dev/null; then
diff --git a/sound/soc/codecs/wcd9310-tables.c b/sound/soc/codecs/wcd9310-tables.c
index e0ad541..2cba59d 100644
--- a/sound/soc/codecs/wcd9310-tables.c
+++ b/sound/soc/codecs/wcd9310-tables.c
@@ -451,6 +451,22 @@
 	[TABLA_A_CDC_DEBUG_B4_CTL] = 1,
 	[TABLA_A_CDC_DEBUG_B5_CTL] = 1,
 	[TABLA_A_CDC_DEBUG_B6_CTL] = 1,
+	[TABLA_A_CDC_COMP1_B1_CTL] = 1,
+	[TABLA_A_CDC_COMP1_B2_CTL] = 1,
+	[TABLA_A_CDC_COMP1_B3_CTL] = 1,
+	[TABLA_A_CDC_COMP1_B4_CTL] = 1,
+	[TABLA_A_CDC_COMP1_B5_CTL] = 1,
+	[TABLA_A_CDC_COMP1_B6_CTL] = 1,
+	[TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS] = 1,
+	[TABLA_A_CDC_COMP1_FS_CFG] = 1,
+	[TABLA_A_CDC_COMP2_B1_CTL] = 1,
+	[TABLA_A_CDC_COMP2_B2_CTL] = 1,
+	[TABLA_A_CDC_COMP2_B3_CTL] = 1,
+	[TABLA_A_CDC_COMP2_B4_CTL] = 1,
+	[TABLA_A_CDC_COMP2_B5_CTL] = 1,
+	[TABLA_A_CDC_COMP2_B6_CTL] = 1,
+	[TABLA_A_CDC_COMP2_SHUT_DOWN_STATUS] = 1,
+	[TABLA_A_CDC_COMP2_FS_CFG] = 1,
 	[TABLA_A_CDC_CONN_RX1_B1_CTL] = 1,
 	[TABLA_A_CDC_CONN_RX1_B2_CTL] = 1,
 	[TABLA_A_CDC_CONN_RX1_B3_CTL] = 1,
@@ -993,6 +1009,24 @@
 	[TABLA_A_CDC_DEBUG_B4_CTL] = TABLA_A_CDC_DEBUG_B4_CTL__POR,
 	[TABLA_A_CDC_DEBUG_B5_CTL] = TABLA_A_CDC_DEBUG_B5_CTL__POR,
 	[TABLA_A_CDC_DEBUG_B6_CTL] = TABLA_A_CDC_DEBUG_B6_CTL__POR,
+	[TABLA_A_CDC_COMP1_B1_CTL] = TABLA_A_CDC_COMP1_B1_CTL__POR,
+	[TABLA_A_CDC_COMP1_B2_CTL] = TABLA_A_CDC_COMP1_B2_CTL__POR,
+	[TABLA_A_CDC_COMP1_B3_CTL] = TABLA_A_CDC_COMP1_B3_CTL__POR,
+	[TABLA_A_CDC_COMP1_B4_CTL] = TABLA_A_CDC_COMP1_B4_CTL__POR,
+	[TABLA_A_CDC_COMP1_B5_CTL] = TABLA_A_CDC_COMP1_B5_CTL__POR,
+	[TABLA_A_CDC_COMP1_B6_CTL] = TABLA_A_CDC_COMP1_B6_CTL__POR,
+	[TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS] =
+		TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS__POR,
+	[TABLA_A_CDC_COMP1_FS_CFG] = TABLA_A_CDC_COMP1_FS_CFG__POR,
+	[TABLA_A_CDC_COMP2_B1_CTL] = TABLA_A_CDC_COMP2_B1_CTL__POR,
+	[TABLA_A_CDC_COMP2_B2_CTL] = TABLA_A_CDC_COMP2_B2_CTL__POR,
+	[TABLA_A_CDC_COMP2_B3_CTL] = TABLA_A_CDC_COMP2_B3_CTL__POR,
+	[TABLA_A_CDC_COMP2_B4_CTL] = TABLA_A_CDC_COMP2_B4_CTL__POR,
+	[TABLA_A_CDC_COMP2_B5_CTL] = TABLA_A_CDC_COMP2_B5_CTL__POR,
+	[TABLA_A_CDC_COMP2_B6_CTL] = TABLA_A_CDC_COMP2_B6_CTL__POR,
+	[TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS] =
+		TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS__POR,
+	[TABLA_A_CDC_COMP2_FS_CFG] = TABLA_A_CDC_COMP2_FS_CFG__POR,
 	[TABLA_A_CDC_CONN_RX1_B1_CTL] = TABLA_A_CDC_CONN_RX1_B1_CTL__POR,
 	[TABLA_A_CDC_CONN_RX1_B2_CTL] = TABLA_A_CDC_CONN_RX1_B2_CTL__POR,
 	[TABLA_A_CDC_CONN_RX1_B3_CTL] = TABLA_A_CDC_CONN_RX1_B3_CTL__POR,
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index 082b29e..0ae9680 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -53,6 +53,7 @@
 #define AIF1_CAP 2
 #define AIF2_PB 3
 #define NUM_CODEC_DAIS 3
+#define TABLA_COMP_DIGITAL_GAIN_OFFSET 3
 
 struct tabla_codec_dai_data {
 	u32 rate;
@@ -103,6 +104,20 @@
 	BAND_MAX,
 };
 
+enum {
+	COMPANDER_1 = 0,
+	COMPANDER_2,
+	COMPANDER_MAX,
+};
+
+enum {
+	COMPANDER_FS_8KHZ = 0,
+	COMPANDER_FS_16KHZ,
+	COMPANDER_FS_32KHZ,
+	COMPANDER_FS_48KHZ,
+	COMPANDER_FS_MAX,
+};
+
 /* Flags to track of PA and DAC state.
  * PA and DAC should be tracked separately as AUXPGA loopback requires
  * only PA to be turned on without DAC being on. */
@@ -113,6 +128,13 @@
 	TABLA_HPHR_DAC_OFF_ACK
 };
 
+
+struct comp_sample_dependent_params {
+	u32 peak_det_timeout;
+	u32 rms_meter_div_fact;
+	u32 rms_meter_resamp_fact;
+};
+
 /* Data used by MBHC */
 struct mbhc_internal_cal_data {
 	u16 dce_z;
@@ -210,12 +232,56 @@
 
 	/* num of slim ports required */
 	struct tabla_codec_dai_data dai[NUM_CODEC_DAIS];
+
+	/*compander*/
+	int comp_enabled[COMPANDER_MAX];
+	u32 comp_fs[COMPANDER_MAX];
 };
 
 #ifdef CONFIG_DEBUG_FS
 struct tabla_priv *debug_tabla_priv;
 #endif
 
+static const u32 comp_shift[] = {
+	0,
+	2,
+};
+
+static const int comp_rx_path[] = {
+	COMPANDER_1,
+	COMPANDER_1,
+	COMPANDER_2,
+	COMPANDER_2,
+	COMPANDER_2,
+	COMPANDER_2,
+	COMPANDER_MAX,
+};
+
+static const struct comp_sample_dependent_params comp_samp_params[] = {
+	{
+		.peak_det_timeout = 0x2,
+		.rms_meter_div_fact = 0x8 << 4,
+		.rms_meter_resamp_fact = 0x21,
+	},
+	{
+		.peak_det_timeout = 0x3,
+		.rms_meter_div_fact = 0x9 << 4,
+		.rms_meter_resamp_fact = 0x28,
+	},
+
+	{
+		.peak_det_timeout = 0x5,
+		.rms_meter_div_fact = 0xB << 4,
+		.rms_meter_resamp_fact = 0x28,
+	},
+
+	{
+		.peak_det_timeout = 0x5,
+		.rms_meter_div_fact = 0xB << 4,
+		.rms_meter_resamp_fact = 0x28,
+	},
+};
+
 static int tabla_codec_enable_charge_pump(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *kcontrol, int event)
 {
@@ -479,6 +545,192 @@
 	return 0;
 }
 
+static int tabla_compander_gain_offset(
+	struct snd_soc_codec *codec, u32 enable,
+	unsigned int reg, int mask,	int event)
+{
+	int pa_mode = snd_soc_read(codec, reg) & mask;
+	int gain_offset = 0;
+	/*  if PMU && enable is 1-> offset is 3
+	 *  if PMU && enable is 0-> offset is 0
+	 *  if PMD && pa_mode is PA -> offset is 0: PMU compander is off
+	 *  if PMD && pa_mode is comp -> offset is -3: PMU compander is on.
+	 */
+
+	if (SND_SOC_DAPM_EVENT_ON(event) && (enable != 0))
+		gain_offset = TABLA_COMP_DIGITAL_GAIN_OFFSET;
+	if (SND_SOC_DAPM_EVENT_OFF(event) && (pa_mode == 0))
+		gain_offset = -TABLA_COMP_DIGITAL_GAIN_OFFSET;
+	return gain_offset;
+}
+
+
+static int tabla_config_gain_compander(
+				struct snd_soc_codec *codec,
+				u32 compander, u32 enable, int event)
+{
+	int value = 0;
+	int mask = 1 << 4;
+	int gain = 0;
+	int gain_offset;
+	if (compander >= COMPANDER_MAX) {
+		pr_err("%s: Error, invalid compander channel\n", __func__);
+		return -EINVAL;
+	}
+
+	if ((enable == 0) || SND_SOC_DAPM_EVENT_OFF(event))
+		value = 1 << 4;
+
+	if (compander == COMPANDER_1) {
+		gain_offset = tabla_compander_gain_offset(codec, enable,
+				TABLA_A_RX_HPH_L_GAIN, mask, event);
+		snd_soc_update_bits(codec, TABLA_A_RX_HPH_L_GAIN, mask, value);
+		gain = snd_soc_read(codec, TABLA_A_CDC_RX1_VOL_CTL_B2_CTL);
+		snd_soc_update_bits(codec, TABLA_A_CDC_RX1_VOL_CTL_B2_CTL,
+				0xFF, gain - gain_offset);
+		gain_offset = tabla_compander_gain_offset(codec, enable,
+				TABLA_A_RX_HPH_R_GAIN, mask, event);
+		snd_soc_update_bits(codec, TABLA_A_RX_HPH_R_GAIN, mask, value);
+		gain = snd_soc_read(codec, TABLA_A_CDC_RX2_VOL_CTL_B2_CTL);
+		snd_soc_update_bits(codec, TABLA_A_CDC_RX2_VOL_CTL_B2_CTL,
+				0xFF, gain - gain_offset);
+	} else if (compander == COMPANDER_2) {
+		gain_offset = tabla_compander_gain_offset(codec, enable,
+				TABLA_A_RX_LINE_1_GAIN, mask, event);
+		snd_soc_update_bits(codec, TABLA_A_RX_LINE_1_GAIN, mask, value);
+		gain = snd_soc_read(codec, TABLA_A_CDC_RX3_VOL_CTL_B2_CTL);
+		snd_soc_update_bits(codec, TABLA_A_CDC_RX3_VOL_CTL_B2_CTL,
+				0xFF, gain - gain_offset);
+		gain_offset = tabla_compander_gain_offset(codec, enable,
+				TABLA_A_RX_LINE_3_GAIN, mask, event);
+		snd_soc_update_bits(codec, TABLA_A_RX_LINE_3_GAIN, mask, value);
+		gain = snd_soc_read(codec, TABLA_A_CDC_RX4_VOL_CTL_B2_CTL);
+		snd_soc_update_bits(codec, TABLA_A_CDC_RX4_VOL_CTL_B2_CTL,
+				0xFF, gain - gain_offset);
+		gain_offset = tabla_compander_gain_offset(codec, enable,
+				TABLA_A_RX_LINE_2_GAIN, mask, event);
+		snd_soc_update_bits(codec, TABLA_A_RX_LINE_2_GAIN, mask, value);
+		gain = snd_soc_read(codec, TABLA_A_CDC_RX5_VOL_CTL_B2_CTL);
+		snd_soc_update_bits(codec, TABLA_A_CDC_RX5_VOL_CTL_B2_CTL,
+				0xFF, gain - gain_offset);
+		gain_offset = tabla_compander_gain_offset(codec, enable,
+				TABLA_A_RX_LINE_4_GAIN, mask, event);
+		snd_soc_update_bits(codec, TABLA_A_RX_LINE_4_GAIN, mask, value);
+		gain = snd_soc_read(codec, TABLA_A_CDC_RX6_VOL_CTL_B2_CTL);
+		snd_soc_update_bits(codec, TABLA_A_CDC_RX6_VOL_CTL_B2_CTL,
+				0xFF, gain - gain_offset);
+	}
+	return 0;
+}
+static int tabla_get_compander(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_value *ucontrol)
+{
+
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	int comp = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->max;
+	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+
+	ucontrol->value.integer.value[0] = tabla->comp_enabled[comp];
+
+	return 0;
+}
+
+static int tabla_set_compander(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+	int comp = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->max;
+	int value = ucontrol->value.integer.value[0];
+
+	if (value == tabla->comp_enabled[comp]) {
+		pr_debug("%s: compander #%d enable %d no change\n",
+			    __func__, comp, value);
+		return 0;
+	}
+	tabla->comp_enabled[comp] = value;
+	return 0;
+}
+
+
+static int tabla_config_compander(struct snd_soc_dapm_widget *w,
+						  struct snd_kcontrol *kcontrol,
+						  int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+	u32 rate = tabla->comp_fs[w->shift];
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		if (tabla->comp_enabled[w->shift] != 0) {
+			/* Enable both L/R compander clocks */
+			snd_soc_update_bits(codec,
+					TABLA_A_CDC_CLK_RX_B2_CTL,
+					0x03 << comp_shift[w->shift],
+					0x03 << comp_shift[w->shift]);
+			/* Clar the HALT for the compander*/
+			snd_soc_update_bits(codec,
+					TABLA_A_CDC_COMP1_B1_CTL +
+					w->shift * 8, 1 << 2, 0);
+			/* Toggle compander reset bits*/
+			snd_soc_update_bits(codec,
+					TABLA_A_CDC_CLK_OTHR_RESET_CTL,
+					0x03 << comp_shift[w->shift],
+					0x03 << comp_shift[w->shift]);
+			snd_soc_update_bits(codec,
+					TABLA_A_CDC_CLK_OTHR_RESET_CTL,
+					0x03 << comp_shift[w->shift], 0);
+			tabla_config_gain_compander(codec, w->shift, 1, event);
+			/* Update the RMS meter resampling*/
+			snd_soc_update_bits(codec,
+					TABLA_A_CDC_COMP1_B3_CTL +
+					w->shift * 8, 0xFF, 0x01);
+			/* Wait for 1ms*/
+			usleep_range(1000, 1000);
+		}
+		break;
+	case SND_SOC_DAPM_POST_PMU:
+		/* Set sample rate dependent paramater*/
+		if (tabla->comp_enabled[w->shift] != 0) {
+			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_FS_CFG +
+			w->shift * 8, 0x03,	rate);
+			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B2_CTL +
+			w->shift * 8, 0x0F,
+			comp_samp_params[rate].peak_det_timeout);
+			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B2_CTL +
+			w->shift * 8, 0xF0,
+			comp_samp_params[rate].rms_meter_div_fact);
+			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B3_CTL +
+			w->shift * 8, 0xFF,
+			comp_samp_params[rate].rms_meter_resamp_fact);
+			/* Compander enable -> 0x370/0x378*/
+			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
+			w->shift * 8, 0x03, 0x03);
+		}
+		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		/* Halt the compander*/
+		snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
+			w->shift * 8, 1 << 2, 1 << 2);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		/* Restore the gain */
+		tabla_config_gain_compander(codec, w->shift,
+				tabla->comp_enabled[w->shift], event);
+		/* Disable the compander*/
+		snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
+			w->shift * 8, 0x03, 0x00);
+		/* Turn off the clock for compander in pair*/
+		snd_soc_update_bits(codec, TABLA_A_CDC_CLK_RX_B2_CTL,
+			0x03 << comp_shift[w->shift], 0);
+		break;
+	}
+	return 0;
+}
+
 static const char *tabla_ear_pa_gain_text[] = {"POS_6_DB", "POS_2_DB"};
 static const struct soc_enum tabla_ear_pa_gain_enum[] = {
 		SOC_ENUM_SINGLE_EXT(2, tabla_ear_pa_gain_text),
@@ -696,6 +948,10 @@
 	tabla_get_iir_band_audio_mixer, tabla_put_iir_band_audio_mixer),
 	SOC_SINGLE_MULTI_EXT("IIR2 Band5", IIR2, BAND5, 255, 0, 5,
 	tabla_get_iir_band_audio_mixer, tabla_put_iir_band_audio_mixer),
+	SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, 1, COMPANDER_1, 0,
+				   tabla_get_compander, tabla_set_compander),
+	SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, 0, COMPANDER_2, 0,
+				   tabla_get_compander, tabla_set_compander),
 };
 
 static const struct snd_kcontrol_new tabla_1_x_snd_controls[] = {
@@ -2075,6 +2331,12 @@
 	{"LINEOUT4 DAC", NULL, "RX_BIAS"},
 	{"LINEOUT5 DAC", NULL, "RX_BIAS"},
 
+	{"RX1 MIX1", NULL, "COMP1_CLK"},
+	{"RX2 MIX1", NULL, "COMP1_CLK"},
+	{"RX3 MIX1", NULL, "COMP2_CLK"},
+	{"RX5 MIX1", NULL, "COMP2_CLK"},
+
+
 	{"RX1 MIX1", NULL, "RX1 MIX1 INP1"},
 	{"RX1 MIX1", NULL, "RX1 MIX1 INP2"},
 	{"RX2 MIX1", NULL, "RX2 MIX1 INP1"},
@@ -2748,6 +3010,7 @@
 	u8 path, shift;
 	u16 tx_fs_reg, rx_fs_reg;
 	u8 tx_fs_rate, rx_fs_rate, rx_state, tx_state;
+	u32 compander_fs;
 
 	pr_debug("%s: DAI-ID %x rate %d\n", __func__, dai->id,
 						params_rate(params));
@@ -2756,18 +3019,22 @@
 	case 8000:
 		tx_fs_rate = 0x00;
 		rx_fs_rate = 0x00;
+		compander_fs = COMPANDER_FS_8KHZ;
 		break;
 	case 16000:
 		tx_fs_rate = 0x01;
 		rx_fs_rate = 0x20;
+		compander_fs = COMPANDER_FS_16KHZ;
 		break;
 	case 32000:
 		tx_fs_rate = 0x02;
 		rx_fs_rate = 0x40;
+		compander_fs = COMPANDER_FS_32KHZ;
 		break;
 	case 48000:
 		tx_fs_rate = 0x03;
 		rx_fs_rate = 0x60;
+		compander_fs = COMPANDER_FS_48KHZ;
 		break;
 	default:
 		pr_err("%s: Invalid sampling rate %d\n", __func__,
@@ -2845,6 +3112,9 @@
 						+ (BITS_PER_REG*(path-1));
 				snd_soc_update_bits(codec, rx_fs_reg,
 						0xE0, rx_fs_rate);
+				if (comp_rx_path[shift] < COMPANDER_MAX)
+					tabla->comp_fs[comp_rx_path[shift]]
+					= compander_fs;
 			}
 		}
 		if (tabla->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
@@ -3229,6 +3499,13 @@
 	SND_SOC_DAPM_SUPPLY("LDO_H", TABLA_A_LDO_H_MODE_1, 7, 0,
 		tabla_codec_enable_ldo_h, SND_SOC_DAPM_POST_PMU),
 
+	SND_SOC_DAPM_SUPPLY("COMP1_CLK", SND_SOC_NOPM, 0, 0,
+		tabla_config_compander, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
+	SND_SOC_DAPM_SUPPLY("COMP2_CLK", SND_SOC_NOPM, 1, 0,
+		tabla_config_compander, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
+
 	SND_SOC_DAPM_INPUT("AMIC1"),
 	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External", TABLA_A_MICB_1_CTL, 7, 0,
 		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
@@ -4989,6 +5266,10 @@
 	tabla->mbhc_fake_ins_start = 0;
 	tabla->no_mic_headset_override = false;
 	tabla->codec = codec;
+	for (i = 0; i < COMPANDER_MAX; i++) {
+		tabla->comp_enabled[i] = 0;
+		tabla->comp_fs[i] = COMPANDER_FS_48KHZ;
+	}
 	tabla->pdata = dev_get_platdata(codec->dev->parent);
 	tabla->intf_type = wcd9xxx_get_intf_type();
 
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index 73de89e..fe31b27 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -827,6 +827,9 @@
 	if (data->opcode == RESET_EVENTS) {
 		pr_debug("q6asm_callback: Reset event is received: %d %d apr[%p]\n",
 				data->reset_event, data->reset_proc, ac->apr);
+			if (ac->cb)
+				ac->cb(data->opcode, data->token,
+					(uint32_t *)data->payload, ac->priv);
 		apr_reset(ac->apr);
 		return 0;
 	}