Merge "Bluetooth: Increased the LE connection supervision timeout" into msm-3.0
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index eca2ffa..ed6a58c 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -266,9 +266,7 @@
 CONFIG_INPUT_UINPUT=y
 CONFIG_INPUT_PMIC8XXX_PWRKEY=y
 # CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_MSM=y
 CONFIG_SERIAL_MSM_HS=y
-# CONFIG_SERIAL_MSM_CLOCK_CONTROL is not set
 CONFIG_SERIAL_MSM_HSL=y
 CONFIG_SERIAL_MSM_HSL_CONSOLE=y
 CONFIG_DIAG_CHAR=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 18e9085..0bb87fb 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -267,9 +267,7 @@
 CONFIG_INPUT_UINPUT=y
 CONFIG_INPUT_PMIC8XXX_PWRKEY=y
 # CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_MSM=y
 CONFIG_SERIAL_MSM_HS=y
-# CONFIG_SERIAL_MSM_CLOCK_CONTROL is not set
 CONFIG_SERIAL_MSM_HSL=y
 CONFIG_SERIAL_MSM_HSL_CONSOLE=y
 CONFIG_DIAG_CHAR=y
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index 02b2c33..e49cd3a 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -463,25 +463,25 @@
 static struct acpu_level acpu_freq_tbl_8960_kraitv2_slow[] = {
 	{ 0, { STBY_KHZ, QSB,   0, 0, 0x00 }, L2(0),   950000 },
 	{ 1, {   384000, PLL_8, 0, 2, 0x00 }, L2(1),   950000 },
-	{ 1, {   432000, HFPLL, 2, 0, 0x20 }, L2(6),   975000 },
-	{ 1, {   486000, HFPLL, 2, 0, 0x24 }, L2(6),   975000 },
-	{ 1, {   540000, HFPLL, 2, 0, 0x28 }, L2(6),  1000000 },
-	{ 1, {   594000, HFPLL, 1, 0, 0x16 }, L2(6),  1000000 },
-	{ 1, {   648000, HFPLL, 1, 0, 0x18 }, L2(6),  1025000 },
-	{ 1, {   702000, HFPLL, 1, 0, 0x1A }, L2(6),  1025000 },
-	{ 1, {   756000, HFPLL, 1, 0, 0x1C }, L2(11), 1075000 },
-	{ 1, {   810000, HFPLL, 1, 0, 0x1E }, L2(11), 1075000 },
-	{ 1, {   864000, HFPLL, 1, 0, 0x20 }, L2(11), 1100000 },
-	{ 1, {   918000, HFPLL, 1, 0, 0x22 }, L2(11), 1100000 },
-	{ 1, {   972000, HFPLL, 1, 0, 0x24 }, L2(16), 1125000 },
-	{ 1, {  1026000, HFPLL, 1, 0, 0x26 }, L2(16), 1125000 },
-	{ 1, {  1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1175000 },
+	{ 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(16), 1175000 },
 	{ 1, {  1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1175000 },
-	{ 1, {  1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1200000 },
+	{ 0, {  1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1200000 },
 	{ 1, {  1242000, HFPLL, 1, 0, 0x2E }, L2(16), 1200000 },
-	{ 1, {  1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1225000 },
+	{ 0, {  1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1225000 },
 	{ 1, {  1350000, HFPLL, 1, 0, 0x32 }, L2(16), 1225000 },
-	{ 1, {  1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1237500 },
+	{ 0, {  1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1237500 },
 	{ 1, {  1458000, HFPLL, 1, 0, 0x36 }, L2(16), 1237500 },
 	{ 1, {  1512000, HFPLL, 1, 0, 0x38 }, L2(16), 1250000 },
 	{ 0, { 0 } }
@@ -490,25 +490,25 @@
 static struct acpu_level acpu_freq_tbl_8960_kraitv2_nom[] = {
 	{ 0, { STBY_KHZ, QSB,   0, 0, 0x00 }, L2(0),   900000 },
 	{ 1, {   384000, PLL_8, 0, 2, 0x00 }, L2(1),   900000 },
-	{ 1, {   432000, HFPLL, 2, 0, 0x20 }, L2(6),   925000 },
-	{ 1, {   486000, HFPLL, 2, 0, 0x24 }, L2(6),   925000 },
-	{ 1, {   540000, HFPLL, 2, 0, 0x28 }, L2(6),   950000 },
-	{ 1, {   594000, HFPLL, 1, 0, 0x16 }, L2(6),   950000 },
-	{ 1, {   648000, HFPLL, 1, 0, 0x18 }, L2(6),   975000 },
-	{ 1, {   702000, HFPLL, 1, 0, 0x1A }, L2(6),   975000 },
-	{ 1, {   756000, HFPLL, 1, 0, 0x1C }, L2(11), 1025000 },
-	{ 1, {   810000, HFPLL, 1, 0, 0x1E }, L2(11), 1025000 },
-	{ 1, {   864000, HFPLL, 1, 0, 0x20 }, L2(11), 1050000 },
-	{ 1, {   918000, HFPLL, 1, 0, 0x22 }, L2(11), 1050000 },
-	{ 1, {   972000, HFPLL, 1, 0, 0x24 }, L2(16), 1075000 },
-	{ 1, {  1026000, HFPLL, 1, 0, 0x26 }, L2(16), 1075000 },
-	{ 1, {  1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1125000 },
+	{ 0, {   432000, HFPLL, 2, 0, 0x20 }, L2(7),   925000 },
+	{ 1, {   486000, HFPLL, 2, 0, 0x24 }, L2(7),   925000 },
+	{ 0, {   540000, HFPLL, 2, 0, 0x28 }, L2(7),   950000 },
+	{ 1, {   594000, HFPLL, 1, 0, 0x16 }, L2(7),   950000 },
+	{ 0, {   648000, HFPLL, 1, 0, 0x18 }, L2(7),   975000 },
+	{ 1, {   702000, HFPLL, 1, 0, 0x1A }, L2(7),   975000 },
+	{ 0, {   756000, HFPLL, 1, 0, 0x1C }, L2(7),  1025000 },
+	{ 1, {   810000, HFPLL, 1, 0, 0x1E }, L2(7),  1025000 },
+	{ 0, {   864000, HFPLL, 1, 0, 0x20 }, L2(7),  1050000 },
+	{ 1, {   918000, HFPLL, 1, 0, 0x22 }, L2(7),  1050000 },
+	{ 0, {   972000, HFPLL, 1, 0, 0x24 }, L2(7),  1075000 },
+	{ 1, {  1026000, HFPLL, 1, 0, 0x26 }, L2(7),  1075000 },
+	{ 0, {  1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1125000 },
 	{ 1, {  1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1125000 },
-	{ 1, {  1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1150000 },
+	{ 0, {  1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1150000 },
 	{ 1, {  1242000, HFPLL, 1, 0, 0x2E }, L2(16), 1150000 },
-	{ 1, {  1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1175000 },
+	{ 0, {  1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1175000 },
 	{ 1, {  1350000, HFPLL, 1, 0, 0x32 }, L2(16), 1175000 },
-	{ 1, {  1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1187500 },
+	{ 0, {  1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1187500 },
 	{ 1, {  1458000, HFPLL, 1, 0, 0x36 }, L2(16), 1187500 },
 	{ 1, {  1512000, HFPLL, 1, 0, 0x38 }, L2(16), 1200000 },
 	{ 0, { 0 } }
@@ -517,25 +517,25 @@
 static struct acpu_level acpu_freq_tbl_8960_kraitv2_fast[] = {
 	{ 0, { STBY_KHZ, QSB,   0, 0, 0x00 }, L2(0),   850000 },
 	{ 1, {   384000, PLL_8, 0, 2, 0x00 }, L2(1),   850000 },
-	{ 1, {   432000, HFPLL, 2, 0, 0x20 }, L2(6),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0, 0x24 }, L2(6),   875000 },
-	{ 1, {   540000, HFPLL, 2, 0, 0x28 }, L2(6),   900000 },
-	{ 1, {   594000, HFPLL, 1, 0, 0x16 }, L2(6),   900000 },
-	{ 1, {   648000, HFPLL, 1, 0, 0x18 }, L2(6),   925000 },
-	{ 1, {   702000, HFPLL, 1, 0, 0x1A }, L2(6),   925000 },
-	{ 1, {   756000, HFPLL, 1, 0, 0x1C }, L2(11),  975000 },
-	{ 1, {   810000, HFPLL, 1, 0, 0x1E }, L2(11),  975000 },
-	{ 1, {   864000, HFPLL, 1, 0, 0x20 }, L2(11), 1000000 },
-	{ 1, {   918000, HFPLL, 1, 0, 0x22 }, L2(11), 1000000 },
-	{ 1, {   972000, HFPLL, 1, 0, 0x24 }, L2(16), 1025000 },
-	{ 1, {  1026000, HFPLL, 1, 0, 0x26 }, L2(16), 1025000 },
-	{ 1, {  1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1075000 },
+	{ 0, {   432000, HFPLL, 2, 0, 0x20 }, L2(7),   875000 },
+	{ 1, {   486000, HFPLL, 2, 0, 0x24 }, L2(7),   875000 },
+	{ 0, {   540000, HFPLL, 2, 0, 0x28 }, L2(7),   900000 },
+	{ 1, {   594000, HFPLL, 1, 0, 0x16 }, L2(7),   900000 },
+	{ 0, {   648000, HFPLL, 1, 0, 0x18 }, L2(7),   925000 },
+	{ 1, {   702000, HFPLL, 1, 0, 0x1A }, L2(7),   925000 },
+	{ 0, {   756000, HFPLL, 1, 0, 0x1C }, L2(7),   975000 },
+	{ 1, {   810000, HFPLL, 1, 0, 0x1E }, L2(7),   975000 },
+	{ 0, {   864000, HFPLL, 1, 0, 0x20 }, L2(7),  1000000 },
+	{ 1, {   918000, HFPLL, 1, 0, 0x22 }, L2(7),  1000000 },
+	{ 0, {   972000, HFPLL, 1, 0, 0x24 }, L2(7),  1025000 },
+	{ 1, {  1026000, HFPLL, 1, 0, 0x26 }, L2(7),  1025000 },
+	{ 0, {  1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1075000 },
 	{ 1, {  1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1075000 },
-	{ 1, {  1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1100000 },
+	{ 0, {  1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1100000 },
 	{ 1, {  1242000, HFPLL, 1, 0, 0x2E }, L2(16), 1100000 },
-	{ 1, {  1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1125000 },
+	{ 0, {  1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1125000 },
 	{ 1, {  1350000, HFPLL, 1, 0, 0x32 }, L2(16), 1125000 },
-	{ 1, {  1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1137500 },
+	{ 0, {  1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1137500 },
 	{ 1, {  1458000, HFPLL, 1, 0, 0x36 }, L2(16), 1137500 },
 	{ 1, {  1512000, HFPLL, 1, 0, 0x38 }, L2(16), 1150000 },
 	{ 0, { 0 } }
diff --git a/arch/arm/mach-msm/board-8064-gpu.c b/arch/arm/mach-msm/board-8064-gpu.c
index a8c5d48..0357c40 100644
--- a/arch/arm/mach-msm/board-8064-gpu.c
+++ b/arch/arm/mach-msm/board-8064-gpu.c
@@ -125,14 +125,14 @@
 static struct kgsl_device_platform_data kgsl_3d0_pdata = {
 	.pwrlevel = {
 		{
-			.gpu_freq = 400000000,
-			.bus_freq = 4,
-			.io_fraction = 0,
+			.gpu_freq = 192000000,
+			.bus_freq = 2,
+			.io_fraction = 100,
 		},
 		{
-			.gpu_freq = 320000000,
-			.bus_freq = 3,
-			.io_fraction = 33,
+			.gpu_freq = 192000000,
+			.bus_freq = 2,
+			.io_fraction = 100,
 		},
 		{
 			.gpu_freq = 1920000000,
@@ -140,8 +140,9 @@
 			.io_fraction = 100,
 		},
 		{
-			.gpu_freq = 27000000,
-			.bus_freq = 0,
+			.gpu_freq = 192000000,
+			.bus_freq = 2,
+			.io_fraction = 100,
 		},
 	},
 	.init_level = 0,
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index f3eebce..c286c7f 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -97,6 +97,9 @@
 };
 VREG_CONSUMERS(L23) = {
 	REGULATOR_SUPPLY("8921_l23",		NULL),
+	REGULATOR_SUPPLY("pll_vdd",		"pil_qdsp6v4.1"),
+	REGULATOR_SUPPLY("pll_vdd",		"pil_qdsp6v4.2"),
+
 };
 VREG_CONSUMERS(L24) = {
 	REGULATOR_SUPPLY("8921_l24",		NULL),
@@ -106,6 +109,8 @@
 	REGULATOR_SUPPLY("8921_l25",		NULL),
 	REGULATOR_SUPPLY("VDDD_CDC_D",		"tabla-slim"),
 	REGULATOR_SUPPLY("CDC_VDDA_A_1P2V",	"tabla-slim"),
+	REGULATOR_SUPPLY("VDDD_CDC_D",		"tabla2x-slim"),
+	REGULATOR_SUPPLY("CDC_VDDA_A_1P2V",	"tabla2x-slim"),
 };
 VREG_CONSUMERS(L26) = {
 	REGULATOR_SUPPLY("8921_l26",		NULL),
@@ -113,9 +118,11 @@
 };
 VREG_CONSUMERS(L27) = {
 	REGULATOR_SUPPLY("8921_l27",		NULL),
+	REGULATOR_SUPPLY("core_vdd",		"pil_qdsp6v4.2"),
 };
 VREG_CONSUMERS(L28) = {
 	REGULATOR_SUPPLY("8921_l28",		NULL),
+	REGULATOR_SUPPLY("core_vdd",		"pil_qdsp6v4.1"),
 };
 VREG_CONSUMERS(S1) = {
 	REGULATOR_SUPPLY("8921_s1",		NULL),
@@ -139,6 +146,10 @@
 	REGULATOR_SUPPLY("CDC_VDD_CP",		"tabla-slim"),
 	REGULATOR_SUPPLY("CDC_VDDA_TX",		"tabla-slim"),
 	REGULATOR_SUPPLY("CDC_VDDA_RX",		"tabla-slim"),
+	REGULATOR_SUPPLY("VDDIO_CDC",		"tabla2x-slim"),
+	REGULATOR_SUPPLY("CDC_VDD_CP",		"tabla2x-slim"),
+	REGULATOR_SUPPLY("CDC_VDDA_TX",		"tabla2x-slim"),
+	REGULATOR_SUPPLY("CDC_VDDA_RX",		"tabla2x-slim"),
 	REGULATOR_SUPPLY("riva_vddpx",		"wcnss_wlan.0"),
 };
 VREG_CONSUMERS(S5) = {
diff --git a/arch/arm/mach-msm/board-8930-camera.c b/arch/arm/mach-msm/board-8930-camera.c
index 8212e15..e0bc723 100644
--- a/arch/arm/mach-msm/board-8930-camera.c
+++ b/arch/arm/mach-msm/board-8930-camera.c
@@ -499,8 +499,8 @@
 	{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
 	{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
 	{"cam_vana", REG_LDO, 2800000, 2850000, 85600},
-	{"cam_vio", REG_VS, 0, 0, 0},
-	{"cam_vaf", REG_LDO, 2800000, 2800000, 300000},
+	{"cam_vio", REG_LDO, 1800000, 1800000, 16000},
+	{"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
 };
 
 static struct msm_camera_sensor_flash_data flash_s5k3l1yx = {
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 618d757..90cc3c5 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -40,6 +40,7 @@
 #include <linux/ks8851.h>
 #include <linux/i2c/isa1200.h>
 #include <linux/gpio_keys.h>
+#include <linux/memory.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -429,12 +430,9 @@
 
 	if (high - low <= bank_size)
 		return;
-	msm8930_reserve_info.low_unstable_address = low + bank_size;
-	/* To avoid overflow of u32 compute max_unstable_size
-	 * by first subtracting low from mb->start)
-	 * */
-	msm8930_reserve_info.max_unstable_size = (mb->start - low) +
-						mb->size - bank_size;
+	msm8930_reserve_info.low_unstable_address = mb->start -
+					MIN_MEMORY_BLOCK_SIZE + mb->size;
+	msm8930_reserve_info.max_unstable_size = MIN_MEMORY_BLOCK_SIZE;
 
 	msm8930_reserve_info.bank_size = bank_size;
 	pr_info("low unstable address %lx max size %lx bank size %lx\n",
diff --git a/arch/arm/mach-msm/board-8960-display.c b/arch/arm/mach-msm/board-8960-display.c
index fb78ce7..c5169a8 100644
--- a/arch/arm/mach-msm/board-8960-display.c
+++ b/arch/arm/mach-msm/board-8960-display.c
@@ -81,6 +81,8 @@
 	}
 };
 
+static void set_mdp_clocks_for_liquid_wuxga(void);
+
 static int msm_fb_detect_panel(const char *name)
 {
 	if (machine_is_msm8960_liquid()) {
@@ -88,8 +90,10 @@
 		if (SOCINFO_VERSION_MAJOR(ver) == 3) {
 			if (!strncmp(name, MIPI_VIDEO_CHIMEI_WUXGA_PANEL_NAME,
 				     strnlen(MIPI_VIDEO_CHIMEI_WUXGA_PANEL_NAME,
-						PANEL_NAME_MAX_LEN)))
+						PANEL_NAME_MAX_LEN))) {
+				set_mdp_clocks_for_liquid_wuxga();
 				return 0;
+			}
 		} else {
 			if (!strncmp(name, MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME,
 				     strnlen(MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME,
@@ -643,6 +647,24 @@
 #endif
 };
 
+/**
+ * Set MDP clocks to high frequency to avoid DSI underflow
+ * when using high resolution 1200x1920 WUXGA panel.
+ */
+static void set_mdp_clocks_for_liquid_wuxga(void)
+{
+	int i;
+
+	mdp_ui_vectors[0].ab = 2000000000;
+	mdp_ui_vectors[0].ib = 2000000000;
+
+	mdp_pdata.mdp_core_clk_rate = 200000000;
+
+	for (i = 0; i < ARRAY_SIZE(mdp_core_clk_rate_table); i++)
+		mdp_core_clk_rate_table[i] = 200000000;
+
+}
+
 void __init msm8960_mdp_writeback(struct memtype_reserve* reserve_table)
 {
 	mdp_pdata.ov0_wb_size = MSM_FB_OVERLAY0_WRITEBACK_SIZE;
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 786ec01..49539ef 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -1022,12 +1022,54 @@
 	0x23, 0x83,/* set source impedance sdjusment */
 	-1};
 
+#ifdef CONFIG_MSM_BUS_SCALING
+/* Bandwidth requests (zero) if no vote placed */
+static struct msm_bus_vectors usb_init_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_SPS,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = 0,
+	},
+};
+
+/* Bus bandwidth requests in Bytes/sec */
+static struct msm_bus_vectors usb_max_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_SPS,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 60000000,		/* At least 480Mbps on bus. */
+		.ib = 960000000,	/* MAX bursts rate */
+	},
+};
+
+static struct msm_bus_paths usb_bus_scale_usecases[] = {
+	{
+		ARRAY_SIZE(usb_init_vectors),
+		usb_init_vectors,
+	},
+	{
+		ARRAY_SIZE(usb_max_vectors),
+		usb_max_vectors,
+	},
+};
+
+static struct msm_bus_scale_pdata usb_bus_scale_pdata = {
+	usb_bus_scale_usecases,
+	ARRAY_SIZE(usb_bus_scale_usecases),
+	.name = "usb",
+};
+#endif
+
 static struct msm_otg_platform_data msm_otg_pdata = {
 	.mode			= USB_OTG,
 	.otg_control		= OTG_PMIC_CONTROL,
 	.phy_type		= SNPS_28NM_INTEGRATED_PHY,
 	.pmic_id_irq		= PM8921_USB_ID_IN_IRQ(PM8921_IRQ_BASE),
 	.power_budget		= 750,
+#ifdef CONFIG_MSM_BUS_SCALING
+	.bus_scale_table	= &usb_bus_scale_pdata,
+#endif
 };
 #endif
 
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index cb63395..f179bdf 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -381,6 +381,7 @@
 
 #define LPASS_SLIMBUS_PHYS	0x28080000
 #define LPASS_SLIMBUS_BAM_PHYS	0x28084000
+#define LPASS_SLIMBUS_SLEW	(MSM8960_TLMM_PHYS + 0x207C)
 /* Board info for the slimbus slave device */
 static struct resource slimbus_res[] = {
 	{
@@ -396,6 +397,12 @@
 		.name	= "slimbus_bam_physical",
 	},
 	{
+		.start	= LPASS_SLIMBUS_SLEW,
+		.end	= LPASS_SLIMBUS_SLEW + 4 - 1,
+		.flags	= IORESOURCE_MEM,
+		.name	= "slimbus_slew_reg",
+	},
+	{
 		.start	= SLIMBUS0_CORE_EE1_IRQ,
 		.end	= SLIMBUS0_CORE_EE1_IRQ,
 		.flags	= IORESOURCE_IRQ,
diff --git a/arch/arm/mach-msm/iommu_domains.c b/arch/arm/mach-msm/iommu_domains.c
index 600a2e9..c856455 100644
--- a/arch/arm/mach-msm/iommu_domains.c
+++ b/arch/arm/mach-msm/iommu_domains.c
@@ -43,123 +43,10 @@
 	char *name;
 	int  domain;
 } msm_iommu_ctx_names[] = {
-	/* Camera */
-	{
-		.name = "vpe_src",
-		.domain = GLOBAL_DOMAIN,
-	},
-	/* Camera */
-	{
-		.name = "vpe_dst",
-		.domain = GLOBAL_DOMAIN,
-	},
-	/* Camera */
-	{
-		.name = "vfe_imgwr",
-		.domain = GLOBAL_DOMAIN,
-	},
-	/* Camera */
-	{
-		.name = "vfe_misc",
-		.domain = GLOBAL_DOMAIN,
-	},
-	/* Camera */
-	{
-		.name =	"ijpeg_src",
-		.domain = GLOBAL_DOMAIN,
-	},
-	/* Camera */
-	{
-		.name =	"ijpeg_dst",
-		.domain = GLOBAL_DOMAIN,
-	},
-	/* Camera */
-	{
-		.name = "jpegd_src",
-		.domain = GLOBAL_DOMAIN,
-	},
-	/* Camera */
-	{
-		.name = "jpegd_dst",
-		.domain = GLOBAL_DOMAIN,
-	},
-	/* Display */
-	{
-		.name = "mdp_vg1",
-		.domain = GLOBAL_DOMAIN,
-	},
-	/* Display */
-	{
-		.name = "mdp_vg2",
-		.domain = GLOBAL_DOMAIN,
-	},
-	/* Display */
-	{
-		.name = "mdp_rgb1",
-		.domain = GLOBAL_DOMAIN,
-	},
-	/* Display */
-	{
-		.name = "mdp_rgb2",
-		.domain = GLOBAL_DOMAIN,
-	},
-	/* Rotator */
-	{
-		.name = "rot_src",
-		.domain = GLOBAL_DOMAIN,
-	},
-	/* Rotator */
-	{
-		.name = "rot_dst",
-		.domain = GLOBAL_DOMAIN,
-	},
-	/* Video */
-	{
-		.name = "vcodec_a_mm1",
-		.domain = GLOBAL_DOMAIN,
-	},
-	/* Video */
-	{
-		.name = "vcodec_b_mm2",
-		.domain = GLOBAL_DOMAIN,
-	},
-	/* Video */
-	{
-		.name = "vcodec_a_stream",
-		.domain = GLOBAL_DOMAIN,
-	},
-};
-
-static struct mem_pool global_pools[] =  {
-	[VIDEO_FIRMWARE_POOL] =
-	/* Low addresses, intended for video firmware */
-		{
-			.paddr	= SZ_128K,
-			.size	= SZ_16M - SZ_128K,
-		},
-	[LOW_256MB_POOL] =
-	/*
-	 * Video can only access first 256MB of memory
-	 * dedicated pool for such allocations
-	 */
-		{
-			.paddr	= SZ_16M,
-			.size	= SZ_256M - SZ_16M,
-		},
-	[HIGH_POOL] =
-	/* Remaining address space up to 2G */
-		{
-			.paddr	= SZ_256M,
-			.size	= SZ_2G - SZ_256M,
-		}
 };
 
 
 static struct msm_iommu_domain msm_iommu_domains[] = {
-	[GLOBAL_DOMAIN] = {
-		.iova_pools = global_pools,
-		.npools = ARRAY_SIZE(global_pools),
-	}
 };
 
 int msm_iommu_map_extra(struct iommu_domain *domain,
@@ -281,10 +168,8 @@
 
 int msm_use_iommu()
 {
-	/*
-	 * For now, just detect if the iommu is attached.
-	 */
-	return iommu_found();
+	/* Kill use of the iommu by these clients for now. */
+	return 0;
 }
 
 static int __init msm_subsystem_iommu_init(void)
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 7ceae89..07322cd 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -124,7 +124,8 @@
  */
 int chk_apps_master(void)
 {
-	if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm9615())
+	if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm9615() ||
+		 cpu_is_apq8064() || cpu_is_msm8627())
 		return 1;
 	else
 		return 0;
diff --git a/drivers/gpu/ion/ion_cp_heap.c b/drivers/gpu/ion/ion_cp_heap.c
index fc1cfb6..a6b0cf6 100644
--- a/drivers/gpu/ion/ion_cp_heap.c
+++ b/drivers/gpu/ion/ion_cp_heap.c
@@ -27,9 +27,11 @@
 #include <linux/memory_alloc.h>
 #include <linux/seq_file.h>
 #include <linux/fmem.h>
+#include <linux/iommu.h>
 #include <mach/msm_memtypes.h>
 #include <mach/scm.h>
-#include "ion_priv.h"
+#include <mach/iommu_domains.h>
+ #include "ion_priv.h"
 
 #include <asm/mach/map.h>
 
@@ -566,6 +568,103 @@
 	return ret_value;
 }
 
+static int ion_cp_heap_map_iommu(struct ion_buffer *buffer,
+				struct ion_iommu_map *data,
+				unsigned int domain_num,
+				unsigned int partition_num,
+				unsigned long align,
+				unsigned long iova_length,
+				unsigned long flags)
+{
+	unsigned long temp_phys, temp_iova;
+	struct iommu_domain *domain;
+	int i, ret = 0;
+	unsigned long extra;
+
+	data->mapped_size = iova_length;
+
+	if (!msm_use_iommu()) {
+		data->iova_addr = buffer->priv_phys;
+		return 0;
+	}
+
+	extra = iova_length - buffer->size;
+
+	data->iova_addr = msm_allocate_iova_address(domain_num, partition_num,
+						data->mapped_size, align);
+
+	if (!data->iova_addr) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	domain = msm_get_iommu_domain(domain_num);
+
+	if (!domain) {
+		ret = -ENOMEM;
+		goto out1;
+	}
+
+	temp_iova = data->iova_addr;
+	temp_phys = buffer->priv_phys;
+	for (i = buffer->size; i > 0; i -= SZ_4K, temp_iova += SZ_4K,
+						  temp_phys += SZ_4K) {
+		ret = iommu_map(domain, temp_iova, temp_phys,
+				get_order(SZ_4K),
+				ION_IS_CACHED(flags) ? 1 : 0);
+
+		if (ret) {
+			pr_err("%s: could not map %lx to %lx in domain %p\n",
+				__func__, temp_iova, temp_phys, domain);
+			goto out2;
+		}
+	}
+
+	if (extra && (msm_iommu_map_extra(domain, temp_iova, extra, flags) < 0))
+		goto out2;
+
+	return 0;
+
+out2:
+	for ( ; i < buffer->size; i += SZ_4K, temp_iova -= SZ_4K)
+		iommu_unmap(domain, temp_iova, get_order(SZ_4K));
+out1:
+	msm_free_iova_address(data->iova_addr, domain_num, partition_num,
+				data->mapped_size);
+out:
+	return ret;
+}
+
+static void ion_cp_heap_unmap_iommu(struct ion_iommu_map *data)
+{
+	int i;
+	unsigned long temp_iova;
+	unsigned int domain_num;
+	unsigned int partition_num;
+	struct iommu_domain *domain;
+
+	if (!msm_use_iommu())
+		return;
+
+	domain_num = iommu_map_domain(data);
+	partition_num = iommu_map_partition(data);
+
+	domain = msm_get_iommu_domain(domain_num);
+
+	if (!domain) {
+		WARN(1, "Could not get domain %d. Corruption?\n", domain_num);
+		return;
+	}
+
+	temp_iova = data->iova_addr;
+	for (i = data->mapped_size; i > 0; i -= SZ_4K, temp_iova += SZ_4K)
+		iommu_unmap(domain, temp_iova, get_order(SZ_4K));
+
+	msm_free_iova_address(data->iova_addr, domain_num, partition_num,
+				data->mapped_size);
+
+	return;
+}
 
 static struct ion_heap_ops cp_heap_ops = {
 	.allocate = ion_cp_heap_allocate,
@@ -581,6 +680,8 @@
 	.print_debug = ion_cp_print_debug,
 	.secure_heap = ion_cp_secure_heap,
 	.unsecure_heap = ion_cp_unsecure_heap,
+	.map_iommu = ion_cp_heap_map_iommu,
+	.unmap_iommu = ion_cp_heap_unmap_iommu,
 };
 
 struct ion_heap *ion_cp_heap_create(struct ion_platform_heap *heap_data)
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 805e2b6..9cbebbe 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -131,31 +131,35 @@
 	struct adreno_gpudev *gpudev;
 	unsigned int istore_size;
 	unsigned int pix_shader_start;
+	unsigned int instruction_size; /* Size of an instruction in dwords */
 } adreno_gpulist[] = {
 	{ ADRENO_REV_A200, 0, 2, ANY_ID, ANY_ID,
 		"yamato_pm4.fw", "yamato_pfp.fw", &adreno_a2xx_gpudev,
-		512, 384},
+		512, 384, 3},
 	{ ADRENO_REV_A205, 0, 1, 0, ANY_ID,
 		"yamato_pm4.fw", "yamato_pfp.fw", &adreno_a2xx_gpudev,
-		512, 384},
+		512, 384, 3},
 	{ ADRENO_REV_A220, 2, 1, ANY_ID, ANY_ID,
 		"leia_pm4_470.fw", "leia_pfp_470.fw", &adreno_a2xx_gpudev,
-		512, 384},
+		512, 384, 3},
 	/*
 	 * patchlevel 5 (8960v2) needs special pm4 firmware to work around
 	 * a hardware problem.
 	 */
 	{ ADRENO_REV_A225, 2, 2, 0, 5,
 		"a225p5_pm4.fw", "a225_pfp.fw", &adreno_a2xx_gpudev,
-		1536, 768 },
+		1536, 768, 3 },
 	{ ADRENO_REV_A225, 2, 2, 0, 6,
 		"a225_pm4.fw", "a225_pfp.fw", &adreno_a2xx_gpudev,
-		1536, 768 },
+		1536, 768, 3 },
 	{ ADRENO_REV_A225, 2, 2, ANY_ID, ANY_ID,
 		"a225_pm4.fw", "a225_pfp.fw", &adreno_a2xx_gpudev,
-		1536, 768 },
+		1536, 768, 3 },
+	/* A3XX doesn't use the pix_shader_start */
 	{ ADRENO_REV_A320, 3, 1, ANY_ID, ANY_ID,
-		"a300_pm4.fw", "a300_pfp.fw", &adreno_a3xx_gpudev },
+		"a300_pm4.fw", "a300_pfp.fw", &adreno_a3xx_gpudev,
+		512, 0, 2 },
+
 };
 
 static irqreturn_t adreno_isr(int irq, void *data)
@@ -248,6 +252,16 @@
 	unsigned int mh_mmu_invalidate = 0x00000003; /*invalidate all and tc */
 
 	/*
+	 * A3XX doesn't support the fast path (the registers don't even exist)
+	 * so just bail out early
+	 */
+
+	if (adreno_is_a3xx(adreno_dev)) {
+		kgsl_mmu_device_setstate(device, flags);
+		return;
+	}
+
+	/*
 	 * If possible, then set the state via the command stream to avoid
 	 * a CPU idle.  Otherwise, use the default setstate which uses register
 	 * writes For CFF dump we must idle and use the registers so that it is
@@ -442,6 +456,7 @@
 	adreno_dev->pm4_fwfile = adreno_gpulist[i].pm4fw;
 	adreno_dev->istore_size = adreno_gpulist[i].istore_size;
 	adreno_dev->pix_shader_start = adreno_gpulist[i].pix_shader_start;
+	adreno_dev->instruction_size = adreno_gpulist[i].instruction_size;
 }
 
 static int __devinit
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 9c2d704..9498b80 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -39,12 +39,7 @@
 #define ADRENO_DEFAULT_PWRSCALE_POLICY  NULL
 #endif
 
-/*
- * constants for the size of shader instructions
- */
-#define ADRENO_ISTORE_BYTES 12
-#define ADRENO_ISTORE_WORDS 3
-#define ADRENO_ISTORE_START 0x5000
+#define ADRENO_ISTORE_START 0x5000 /* Istore offset */
 
 enum adreno_gpurev {
 	ADRENO_REV_UNKNOWN = 0,
@@ -75,6 +70,7 @@
 	unsigned int wait_timeout;
 	unsigned int istore_size;
 	unsigned int pix_shader_start;
+	unsigned int instruction_size;
 };
 
 struct adreno_gpudev {
diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c
index e31b76b..f2b1278 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -164,7 +164,8 @@
 
 static inline int _shader_shadow_size(struct adreno_device *adreno_dev)
 {
-	return adreno_dev->istore_size*ADRENO_ISTORE_BYTES;
+	return adreno_dev->istore_size *
+		(adreno_dev->instruction_size * sizeof(unsigned int));
 }
 
 static inline int _context_size(struct adreno_device *adreno_dev)
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index 1bad811..f68bc41 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -34,7 +34,7 @@
 	0x01ea, 0x01ea, 0x01ee, 0x01f1, 0x01f5, 0x01f5, 0x01fc, 0x01ff,
 	0x0440, 0x0440, 0x0443, 0x0443, 0x0445, 0x0445, 0x044d, 0x044f,
 	0x0452, 0x0452, 0x0454, 0x046f, 0x047c, 0x047c, 0x047f, 0x047f,
-	0x0579, 0x057f, 0x0600, 0x0602, 0x0605, 0x0607, 0x060a, 0x060e,
+	0x0578, 0x057f, 0x0600, 0x0602, 0x0605, 0x0607, 0x060a, 0x060e,
 	0x0612, 0x0614, 0x0c01, 0x0c02, 0x0c06, 0x0c1d, 0x0c3d, 0x0c3f,
 	0x0c48, 0x0c4b, 0x0c80, 0x0c80, 0x0c88, 0x0c8b, 0x0ca0, 0x0cb7,
 	0x0cc0, 0x0cc1, 0x0cc6, 0x0cc7, 0x0ce4, 0x0ce5, 0x0e00, 0x0e05,
@@ -127,13 +127,8 @@
 #define HLSQ_MEMOBJ_OFFSET  0x400
 #define HLSQ_MIPMAP_OFFSET  0x800
 
-#ifdef GSL_USE_A3XX_HLSQ_SHADOW_RAM
 /* Use shadow RAM */
 #define HLSQ_SHADOW_BASE		(0x10000+SSIZE*2)
-#else
-/* Use working RAM */
-#define HLSQ_SHADOW_BASE		0x10000
-#endif
 
 #define REG_TO_MEM_LOOP_COUNT_SHIFT	15
 
@@ -258,7 +253,7 @@
 				       struct adreno_context *drawctxt)
 {
 	unsigned int *cmd = tmp_ctx.cmd;
-	unsigned int *start = cmd;
+	unsigned int *start;
 	unsigned int i;
 
 	drawctxt->constant_save_commands[0].hostptr = cmd;
@@ -266,6 +261,8 @@
 	    virt2gpu(cmd, &drawctxt->gpustate);
 	cmd++;
 
+	start = cmd;
+
 	*cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
 	*cmd++ = 0;
 
@@ -1313,7 +1310,8 @@
 		_SET(SP_FSCTRLREG1_FSINITIALOUTSTANDING, 2) |
 		_SET(SP_FSCTRLREG1_HALFPRECVAROFFSET, 63);
 	/* SP_FS_OBJ_OFFSET_REG */
-	*cmds++ = _SET(SP_OBJOFFSETREG_CONSTOBJECTSTARTOFFSET, 128);
+	*cmds++ = _SET(SP_OBJOFFSETREG_CONSTOBJECTSTARTOFFSET, 128) |
+		_SET(SP_OBJOFFSETREG_SHADEROBJOFFSETINIC, 1);
 	/* SP_FS_OBJ_START_REG */
 	*cmds++ = 0x00000000;
 
@@ -1329,7 +1327,7 @@
 	/* SP_FS_OUT_REG */
 	*cmds++ = _SET(SP_FSOUTREG_PAD0, SP_PIXEL_BASED);
 
-	*cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
+	*cmds++ = cp_type3_packet(CP_SET_CONSTANT, 5);
 	*cmds++ = CP_REG(A3XX_SP_FS_MRT_REG_0);
 	/* SP_FS_MRT_REG0 */
 	*cmds++ = _SET(SP_FSMRTREG_REGID, 4);
@@ -1426,7 +1424,7 @@
 		_SET(VPC_VPCVARPSREPLMODE_COMPONENT16, 1) |
 		_SET(VPC_VPCVARPSREPLMODE_COMPONENT17, 2);
 
-	*cmds++ = cp_type3_packet(CP_SET_CONSTANT, 11);
+	*cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
 	*cmds++ = CP_REG(A3XX_SP_SP_CTRL_REG);
 	/* SP_SP_CTRL_REG */
 	*cmds++ = _SET(SP_SPCTRLREG_SLEEPMODE, 1);
@@ -1652,7 +1650,9 @@
 	*cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
 	*cmds++ = CP_REG(A3XX_GRAS_SC_CONTROL);
 	/* GRAS_SC_CONTROL */
-	*cmds++ = _SET(GRAS_SC_CONTROL_RASTER_MODE, 1);
+	/*cmds++ = _SET(GRAS_SC_CONTROL_RASTER_MODE, 1);
+		*cmds++ = _SET(GRAS_SC_CONTROL_RASTER_MODE, 1) |*/
+	*cmds++ = 0x04001000;
 
 	*cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
 	*cmds++ = CP_REG(A3XX_GRAS_SU_MODE_CONTROL);
@@ -2130,24 +2130,17 @@
 static int a3xx_create_gmem_shadow(struct adreno_device *adreno_dev,
 				 struct adreno_context *drawctxt)
 {
+	int result;
+
 	calc_gmemsize(&drawctxt->context_gmem_shadow,
 		adreno_dev->gmemspace.sizebytes);
 	tmp_ctx.gmem_base = adreno_dev->gmemspace.gpu_base;
 
-	if (drawctxt->flags & CTXT_FLAGS_GMEM_SHADOW) {
-		int result =
-		    kgsl_allocate(&drawctxt->context_gmem_shadow.gmemshadow,
-			drawctxt->pagetable,
-			drawctxt->context_gmem_shadow.size);
+	result = kgsl_allocate(&drawctxt->context_gmem_shadow.gmemshadow,
+		drawctxt->pagetable, drawctxt->context_gmem_shadow.size);
 
-		if (result)
-			return result;
-	} else {
-		memset(&drawctxt->context_gmem_shadow.gmemshadow, 0,
-		       sizeof(drawctxt->context_gmem_shadow.gmemshadow));
-
-		return 0;
-	}
+	if (result)
+		return result;
 
 	build_quad_vtxbuff(drawctxt, &drawctxt->context_gmem_shadow,
 		&tmp_ctx.cmd);
@@ -2163,6 +2156,8 @@
 	kgsl_cache_range_op(&drawctxt->context_gmem_shadow.gmemshadow,
 		KGSL_CACHE_OP_FLUSH);
 
+	drawctxt->flags |= CTXT_FLAGS_GMEM_SHADOW;
+
 	return 0;
 }
 
@@ -2431,10 +2426,7 @@
 #define A3XX_INT_MASK \
 	((1 << A3XX_INT_RBBM_AHB_ERROR) |        \
 	 (1 << A3XX_INT_RBBM_REG_TIMEOUT) |      \
-	 (1 << A3XX_INT_RBBM_ME_MS_TIMEOUT) |    \
-	 (1 << A3XX_INT_RBBM_PFP_MS_TIMEOUT) |   \
 	 (1 << A3XX_INT_RBBM_ATB_BUS_OVERFLOW) | \
-	 (1 << A3XX_INT_VFD_ERROR) |             \
 	 (1 << A3XX_INT_CP_T0_PACKET_IN_IB) |    \
 	 (1 << A3XX_INT_CP_OPCODE_ERROR) |       \
 	 (1 << A3XX_INT_CP_RESERVED_BIT_ERROR) | \
@@ -2444,7 +2436,6 @@
 	 (1 << A3XX_INT_CP_RB_INT) |             \
 	 (1 << A3XX_INT_CP_REG_PROTECT_FAULT) |  \
 	 (1 << A3XX_INT_CP_AHB_ERROR_HALT) |     \
-	 (1 << A3XX_INT_MISC_HANG_DETECT) |      \
 	 (1 << A3XX_INT_UCHE_OOB_ACCESS))
 
 static struct {
@@ -2474,7 +2465,7 @@
 	A3XX_IRQ_CALLBACK(a3xx_err_callback),  /* 21 - CP_AHB_ERROR_FAULT */
 	A3XX_IRQ_CALLBACK(NULL),	       /* 22 - Unused */
 	A3XX_IRQ_CALLBACK(NULL),	       /* 23 - Unused */
-	A3XX_IRQ_CALLBACK(a3xx_err_callback),  /* 24 - MISC_HANG_DETECT */
+	A3XX_IRQ_CALLBACK(NULL),	       /* 24 - MISC_HANG_DETECT */
 	A3XX_IRQ_CALLBACK(a3xx_err_callback),  /* 25 - UCHE_OOB_ACCESS */
 	/* 26 to 31 - Unused */
 };
@@ -2547,6 +2538,9 @@
 {
 	struct kgsl_device *device = &adreno_dev->dev;
 
+	/* GMEM size on A320 is 512K */
+	adreno_dev->gmemspace.sizebytes = SZ_512K;
+
 	/* Reset the core */
 	adreno_regwrite(device, A3XX_RBBM_SW_RESET_CMD,
 		0x00000001);
@@ -2570,10 +2564,17 @@
 	adreno_regwrite(device, A3XX_RBBM_AHB_CTL0, 0x00000001);
 
 	/* Enable AHB error reporting */
-	adreno_regwrite(device, A3XX_RBBM_AHB_CTL1, 0xA6FFFFFF);
+	adreno_regwrite(device, A3XX_RBBM_AHB_CTL1, 0x86FFFFFF);
 
 	/* Turn on the power counters */
 	adreno_regwrite(device, A3XX_RBBM_RBBM_CTL, 0x00003000);
+
+	/* Turn on hang detection - this spews a lot of useful information
+	 * into the RBBM registers on a hang */
+
+	adreno_regwrite(device, A3XX_RBBM_INTERFACE_HANG_INT_CTL,
+			(1 << 16) | 0xFFF);
+
 }
 
 /* Defined in adreno_a3xx_snapshot.c */
diff --git a/drivers/gpu/msm/adreno_a3xx_snapshot.c b/drivers/gpu/msm/adreno_a3xx_snapshot.c
index aade50c..c8c7c44 100644
--- a/drivers/gpu/msm/adreno_a3xx_snapshot.c
+++ b/drivers/gpu/msm/adreno_a3xx_snapshot.c
@@ -80,7 +80,7 @@
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 	struct kgsl_snapshot_debug *header = snapshot;
 	unsigned int *data = snapshot + sizeof(*header);
-	int i, size = adreno_dev->pm4_fw_size >> 2;
+	int i, size = adreno_dev->pm4_fw_size - 1;
 
 	if (remain < DEBUG_SECTION_SZ(size)) {
 		SNAPSHOT_ERR_NOMEM(device, "CP PM4 RAM DEBUG");
@@ -98,7 +98,7 @@
 	 */
 
 	adreno_regwrite(device, REG_CP_ME_RAM_RADDR, 0x0);
-	for (i = 0; i < adreno_dev->pm4_fw_size >> 2; i++)
+	for (i = 0; i < size; i++)
 		adreno_regread(device, REG_CP_ME_RAM_DATA, &data[i]);
 
 	return DEBUG_SECTION_SZ(size);
@@ -110,7 +110,7 @@
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 	struct kgsl_snapshot_debug *header = snapshot;
 	unsigned int *data = snapshot + sizeof(*header);
-	int i, size = adreno_dev->pfp_fw_size >> 2;
+	int i, size = adreno_dev->pfp_fw_size - 1;
 
 	if (remain < DEBUG_SECTION_SZ(size)) {
 		SNAPSHOT_ERR_NOMEM(device, "CP PFP RAM DEBUG");
@@ -127,7 +127,7 @@
 	 * maintain always changing hardcoded constants
 	 */
 	kgsl_regwrite(device, A3XX_CP_PFP_UCODE_ADDR, 0x0);
-	for (i = 0; i < adreno_dev->pfp_fw_size >> 2; i++)
+	for (i = 0; i < size; i++)
 		adreno_regread(device, A3XX_CP_PFP_UCODE_DATA, &data[i]);
 
 	return DEBUG_SECTION_SZ(size);
@@ -175,7 +175,7 @@
 		return 0;
 	}
 
-	val = (id << 0x06) | (1 << 0x10);
+	val = (id << 8) | (1 << 16);
 
 	header->id = id;
 	header->count = DEBUGFS_BLOCK_SIZE;
diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c
index c1b9e4c..b53ca8f 100644
--- a/drivers/gpu/msm/adreno_debugfs.c
+++ b/drivers/gpu/msm/adreno_debugfs.c
@@ -143,7 +143,8 @@
 		return 0;
 
 	adreno_dev = ADRENO_DEVICE(device);
-	count = adreno_dev->istore_size * ADRENO_ISTORE_WORDS;
+	count = adreno_dev->istore_size * adreno_dev->instruction_size;
+
 	remaining = count;
 	for (i = 0; i < count; i += rowc) {
 		unsigned int vals[rowc];
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index 9bf85cf..aeb89b3 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -86,7 +86,7 @@
 	gmem_restore_quad[7] = uint2float(shadow->width);
 
 	memcpy(shadow->quad_vertices.hostptr, gmem_copy_quad, QUAD_LEN << 2);
-	memcpy(shadow->quad_vertices_restore.hostptr, gmem_copy_quad,
+	memcpy(shadow->quad_vertices_restore.hostptr, gmem_restore_quad,
 		QUAD_RESTORE_LEN << 2);
 
 	memcpy(shadow->quad_texcoords.hostptr, gmem_copy_texcoord,
diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c
index fb88a72..cc3f3e7 100644
--- a/drivers/gpu/msm/adreno_snapshot.c
+++ b/drivers/gpu/msm/adreno_snapshot.c
@@ -86,7 +86,7 @@
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 	int count, i;
 
-	count = adreno_dev->istore_size * ADRENO_ISTORE_WORDS;
+	count = adreno_dev->istore_size * adreno_dev->instruction_size;
 
 	if (remain < (count * 4) + sizeof(*header)) {
 		KGSL_DRV_ERR(device,
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
index 36248ef..671479e 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -17,6 +17,7 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/iommu.h>
+#include <mach/socinfo.h>
 
 #include "kgsl.h"
 #include "kgsl_mmu.h"
@@ -534,9 +535,16 @@
 	int ret;
 
 	if (kgsl_mmu_type == KGSL_MMU_TYPE_NONE) {
-		memdesc->gpuaddr = memdesc->physaddr;
-		return 0;
+		if (memdesc->sglen == 1) {
+			memdesc->gpuaddr = sg_phys(memdesc->sg);
+			return 0;
+		} else {
+			KGSL_CORE_ERR("Memory is not contigious "
+					"(sglen = %d)\n", memdesc->sglen);
+			return -EINVAL;
+		}
 	}
+
 	memdesc->gpuaddr = gen_pool_alloc_aligned(pagetable->pool,
 		memdesc->size, KGSL_MMU_ALIGN_SHIFT);
 
@@ -712,7 +720,14 @@
 
 void kgsl_mmu_set_mmutype(char *mmutype)
 {
-	kgsl_mmu_type = iommu_found() ? KGSL_MMU_TYPE_IOMMU : KGSL_MMU_TYPE_GPU;
+	/* Set the default MMU - GPU on <=8960 and nothing on >= 8064 */
+	kgsl_mmu_type =
+		cpu_is_apq8064() ? KGSL_MMU_TYPE_NONE : KGSL_MMU_TYPE_GPU;
+
+	/* Use the IOMMU if it is found */
+	if (iommu_found())
+		kgsl_mmu_type = KGSL_MMU_TYPE_IOMMU;
+
 	if (mmutype && !strncmp(mmutype, "gpummu", 6))
 		kgsl_mmu_type = KGSL_MMU_TYPE_GPU;
 	if (iommu_found() && mmutype && !strncmp(mmutype, "iommu", 5))
diff --git a/drivers/media/video/msm/csi/msm_ispif.c b/drivers/media/video/msm/csi/msm_ispif.c
index af61bd2..86d62c9 100644
--- a/drivers/media/video/msm/csi/msm_ispif.c
+++ b/drivers/media/video/msm/csi/msm_ispif.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
@@ -73,43 +73,54 @@
 
 
 static struct ispif_device *ispif;
+atomic_t ispif_irq_cnt;
+spinlock_t  ispif_tasklet_lock;
+struct list_head ispif_tasklet_q;
 
 static uint32_t global_intf_cmd_mask = 0xFFFFFFFF;
 
-static int msm_ispif_intf_reset(uint8_t intftype)
+
+static int msm_ispif_intf_reset(uint8_t intfmask)
 {
 	int rc = 0;
-	uint32_t data;
+	uint32_t data = 0x1;
+	uint8_t intfnum = 0, mask = intfmask;
+	while (mask != 0) {
+		if (!(intfmask & (0x1 << intfnum))) {
+			mask >>= 1;
+			intfnum++;
+			continue;
+		}
+		switch (intfnum) {
+		case PIX0:
+			data = (0x1 << STROBED_RST_EN) +
+				(0x1 << PIX_VFE_RST_STB) +
+				(0x1 << PIX_CSID_RST_STB);
+			break;
 
-	switch (intftype) {
-	case PIX0:
-		data = (0x1 << STROBED_RST_EN) +
-			(0x1 << PIX_VFE_RST_STB) +
-			(0x1 << PIX_CSID_RST_STB);
+		case RDI0:
+			data = (0x1 << STROBED_RST_EN) +
+				(0x1 << RDI_VFE_RST_STB)  +
+				(0x1 << RDI_CSID_RST_STB);
+			break;
+
+		case RDI1:
+			data = (0x1 << STROBED_RST_EN) +
+				(0x1 << RDI_1_VFE_RST_STB) +
+				(0x1 << RDI_1_CSID_RST_STB);
+			break;
+
+		default:
+			rc = -EINVAL;
+			break;
+		}
+		mask >>= 1;
+		intfnum++;
+	}	/*end while */
+	if (rc >= 0) {
 		msm_io_w(data, ispif->base + ISPIF_RST_CMD_ADDR);
-		break;
-
-	case RDI0:
-		data = (0x1 << STROBED_RST_EN) +
-			(0x1 << RDI_VFE_RST_STB)  +
-			(0x1 << RDI_CSID_RST_STB);
-		msm_io_w(data, ispif->base + ISPIF_RST_CMD_ADDR);
-		break;
-
-	case RDI1:
-		data = (0x1 << STROBED_RST_EN) +
-			(0x1 << RDI_1_VFE_RST_STB) +
-			(0x1 << RDI_1_CSID_RST_STB);
-		msm_io_w(data, ispif->base + ISPIF_RST_CMD_ADDR);
-		break;
-
-	default:
-		rc = -EINVAL;
-		break;
+		rc = wait_for_completion_interruptible(&ispif->reset_complete);
 	}
-	if (rc >= 0)
-		rc = wait_for_completion_interruptible(
-				&ispif->reset_complete);
 
 	return rc;
 }
@@ -244,97 +255,109 @@
 }
 
 static void
-msm_ispif_intf_cmd(uint8_t intftype, uint8_t intf_cmd_mask)
+msm_ispif_intf_cmd(uint8_t intfmask, uint8_t intf_cmd_mask)
 {
 	uint8_t vc = 0, val = 0;
-	uint32_t cid_mask = msm_ispif_get_cid_mask(intftype);
-
-	while (cid_mask != 0) {
-		if ((cid_mask & 0xf) != 0x0) {
-			val = (intf_cmd_mask>>(vc*2)) & 0x3;
-			global_intf_cmd_mask &= ~((0x3 & ~val)
-				<<((vc*2)+(intftype*8)));
-			CDBG("intf cmd  0x%x\n", global_intf_cmd_mask);
-			msm_io_w(global_intf_cmd_mask,
-				ispif->base + ISPIF_INTF_CMD_ADDR);
+	uint8_t mask = intfmask, intfnum = 0;
+	uint32_t cid_mask = 0;
+	while (mask != 0) {
+		if (!(intfmask & (0x1 << intfnum))) {
+			mask >>= 1;
+			intfnum++;
+			continue;
 		}
-		vc++;
-		cid_mask >>= 4;
+
+		cid_mask = msm_ispif_get_cid_mask(intfnum);
+		vc = 0;
+
+		while (cid_mask != 0) {
+			if ((cid_mask & 0xf) != 0x0) {
+				val = (intf_cmd_mask>>(vc*2)) & 0x3;
+				global_intf_cmd_mask |=
+					(0x3 << ((vc * 2) + (intfnum * 8)));
+				global_intf_cmd_mask &= ~((0x3 & ~val)
+					<< ((vc * 2) +
+					(intfnum * 8)));
+			}
+			vc++;
+			cid_mask >>= 4;
+		}
+		mask >>= 1;
+		intfnum++;
 	}
+	msm_io_w(global_intf_cmd_mask, ispif->base + ISPIF_INTF_CMD_ADDR);
 }
 
-static int msm_ispif_abort_intf_transfer(uint8_t intf)
+static int msm_ispif_abort_intf_transfer(uint8_t intfmask)
 {
 	int rc = 0;
 	uint8_t intf_cmd_mask = 0xAA;
-
-	CDBG("abort stream request\n");
+	uint8_t intfnum = 0, mask = intfmask;
 	mutex_lock(&ispif->mutex);
-	msm_ispif_intf_cmd(intf, intf_cmd_mask);
-	rc = msm_ispif_intf_reset(intf);
-	global_intf_cmd_mask |= 0xFF<<(intf * 8);
+	msm_ispif_intf_cmd(intfmask, intf_cmd_mask);
+	while (mask != 0) {
+		if (intfmask & (0x1 << intfnum))
+			global_intf_cmd_mask |= (0xFF << (intfnum * 8));
+		mask >>= 1;
+		intfnum++;
+	}
 	mutex_unlock(&ispif->mutex);
 	return rc;
 }
 
-static int msm_ispif_start_intf_transfer(uint8_t intf)
+static int msm_ispif_start_intf_transfer(uint8_t intfmask)
 {
-	uint32_t data;
 	uint8_t intf_cmd_mask = 0x55;
 	int rc = 0;
-
-	CDBG("start stream request\n");
 	mutex_lock(&ispif->mutex);
-	switch (intf) {
-	case PIX0:
-		data = msm_io_r(ispif->base + ISPIF_PIX_STATUS_ADDR);
-		if ((data & 0xf) != 0xf) {
-			CDBG("interface is busy\n");
-			mutex_unlock(&ispif->mutex);
-			return -EBUSY;
-		}
-		break;
-
-	case RDI0:
-		data  = msm_io_r(ispif->base + ISPIF_RDI_STATUS_ADDR);
-		ispif->start_ack_pending = 1;
-		break;
-
-	case RDI1:
-		data  = msm_io_r(ispif->base + ISPIF_RDI_1_STATUS_ADDR);
-		ispif->start_ack_pending = 1;
-		break;
-	}
-	msm_ispif_intf_cmd(intf, intf_cmd_mask);
+	rc = msm_ispif_intf_reset(intfmask);
+	msm_ispif_intf_cmd(intfmask, intf_cmd_mask);
 	mutex_unlock(&ispif->mutex);
 	return rc;
 }
 
-static int msm_ispif_stop_intf_transfer(uint8_t intf)
+static int msm_ispif_stop_intf_transfer(uint8_t intfmask)
 {
 	int rc = 0;
 	uint8_t intf_cmd_mask = 0x00;
-	CDBG("stop stream request\n");
+	uint8_t intfnum = 0, mask = intfmask;
 	mutex_lock(&ispif->mutex);
-	msm_ispif_intf_cmd(intf, intf_cmd_mask);
-	switch (intf) {
-	case PIX0:
-		while ((msm_io_r(ispif->base + ISPIF_PIX_STATUS_ADDR)
-			& 0xf) != 0xf) {
-			CDBG("Wait for Idle\n");
-		}
-		break;
+	msm_ispif_intf_cmd(intfmask, intf_cmd_mask);
+	while (mask != 0) {
+		if (intfmask & (0x1 << intfnum)) {
+			switch (intfnum) {
+			case PIX0:
+				while ((msm_io_r(ispif->base +
+					ISPIF_PIX_STATUS_ADDR)
+					& 0xf) != 0xf) {
+					CDBG("Wait for pix0 Idle\n");
+				}
+				break;
 
-	case RDI0:
-		while ((msm_io_r(ispif->base + ISPIF_RDI_STATUS_ADDR)
-			& 0xf) != 0xf) {
-			CDBG("Wait for Idle\n");
+			case RDI0:
+				while ((msm_io_r(ispif->base +
+					ISPIF_RDI_STATUS_ADDR)
+					& 0xf) != 0xf) {
+					CDBG("Wait for rdi0 Idle\n");
+				}
+				break;
+
+			case RDI1:
+				while ((msm_io_r(ispif->base +
+					ISPIF_RDI_1_STATUS_ADDR)
+					& 0xf) != 0xf) {
+					CDBG("Wait for rdi1 Idle\n");
+				}
+				break;
+
+			default:
+				break;
+			}
+			global_intf_cmd_mask |= (0xFF << (intfnum * 8));
 		}
-		break;
-	default:
-		break;
+		mask >>= 1;
+		intfnum++;
 	}
-	global_intf_cmd_mask |= 0xFF<<(intf * 8);
 	mutex_unlock(&ispif->mutex);
 	return rc;
 }
@@ -364,10 +387,77 @@
 	return rc;
 }
 
+static void ispif_do_tasklet(unsigned long data)
+{
+	unsigned long flags;
+
+	struct ispif_isr_queue_cmd *qcmd = NULL;
+	CDBG("=== ispif_do_tasklet start ===\n");
+
+	while (atomic_read(&ispif_irq_cnt)) {
+		spin_lock_irqsave(&ispif_tasklet_lock, flags);
+		qcmd = list_first_entry(&ispif_tasklet_q,
+			struct ispif_isr_queue_cmd, list);
+		atomic_sub(1, &ispif_irq_cnt);
+
+		if (!qcmd) {
+			spin_unlock_irqrestore(&ispif_tasklet_lock,
+				flags);
+			return;
+		}
+		list_del(&qcmd->list);
+		spin_unlock_irqrestore(&ispif_tasklet_lock,
+			flags);
+		if (qcmd->ispifInterruptStatus0 &
+			ISPIF_IRQ_STATUS_RDI_SOF_MASK) {
+			CDBG("ispif rdi irq status\n");
+		}
+		if (qcmd->ispifInterruptStatus1 &
+			ISPIF_IRQ_STATUS_RDI_SOF_MASK) {
+			CDBG("ispif rdi1 irq status\n");
+		}
+		kfree(qcmd);
+	}
+	CDBG("=== ispif_do_tasklet end ===\n");
+}
+
+DECLARE_TASKLET(ispif_tasklet, ispif_do_tasklet, 0);
+
+static void ispif_process_irq(struct ispif_irq_status *out)
+{
+	unsigned long flags;
+	struct ispif_isr_queue_cmd *qcmd;
+
+	CDBG("ispif_process_irq\n");
+	qcmd = kzalloc(sizeof(struct ispif_isr_queue_cmd),
+		GFP_ATOMIC);
+	if (!qcmd) {
+		pr_err("ispif_process_irq: qcmd malloc failed!\n");
+		return;
+	}
+	qcmd->ispifInterruptStatus0 = out->ispifIrqStatus0;
+	qcmd->ispifInterruptStatus1 = out->ispifIrqStatus1;
+
+	spin_lock_irqsave(&ispif_tasklet_lock, flags);
+	list_add_tail(&qcmd->list, &ispif_tasklet_q);
+
+	atomic_add(1, &ispif_irq_cnt);
+	spin_unlock_irqrestore(&ispif_tasklet_lock, flags);
+	tasklet_schedule(&ispif_tasklet);
+	return;
+}
+
 static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out)
 {
 	out->ispifIrqStatus0 = msm_io_r(ispif->base +
-					ISPIF_IRQ_STATUS_ADDR);
+		ISPIF_IRQ_STATUS_ADDR);
+	out->ispifIrqStatus1 = msm_io_r(ispif->base +
+		ISPIF_IRQ_STATUS_1_ADDR);
+	msm_io_w(out->ispifIrqStatus0,
+		ispif->base + ISPIF_IRQ_CLEAR_ADDR);
+	msm_io_w(out->ispifIrqStatus1,
+		ispif->base + ISPIF_IRQ_CLEAR_1_ADDR);
+
 	CDBG("ispif->irq: Irq_status0 = 0x%x\n",
 		out->ispifIrqStatus0);
 	if (out->ispifIrqStatus0 & ISPIF_IRQ_STATUS_MASK) {
@@ -377,23 +467,14 @@
 			pr_err("%s: pix intf 0 overflow.\n", __func__);
 		if (out->ispifIrqStatus0 & (0x1 << RAW_INTF_0_OVERFLOW_IRQ))
 			pr_err("%s: rdi intf 0 overflow.\n", __func__);
-		if (out->ispifIrqStatus0 & ISPIF_IRQ_STATUS_RDI_SOF_MASK) {
-			if (ispif->start_ack_pending) {
-				v4l2_subdev_notify(&ispif->subdev,
-						NOTIFY_ISP_MSG_EVT,
-						(void *)MSG_ID_START_ACK);
-				ispif->start_ack_pending = 0;
-				/* stop stream at frame boundary */
-				msm_ispif_stop_intf_transfer(RDI0);
-			}
-			v4l2_subdev_notify(&ispif->subdev, NOTIFY_ISP_MSG_EVT,
-					(void *)MSG_ID_SOF_ACK);
+		if ((out->ispifIrqStatus0 & ISPIF_IRQ_STATUS_RDI_SOF_MASK) ||
+			(out->ispifIrqStatus1 &
+				ISPIF_IRQ_STATUS_RDI_SOF_MASK)) {
+			ispif_process_irq(out);
 		}
 	}
-	msm_io_w(out->ispifIrqStatus0,
-			ispif->base + ISPIF_IRQ_CLEAR_ADDR);
 	msm_io_w(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base +
-		 ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);
+		ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);
 }
 
 static irqreturn_t msm_io_ispif_irq(int irq_num, void *data)
@@ -414,6 +495,8 @@
 static int msm_ispif_init(const uint32_t *csid_version)
 {
 	int rc = 0;
+	spin_lock_init(&ispif_tasklet_lock);
+	INIT_LIST_HEAD(&ispif_tasklet_q);
 	rc = request_irq(ispif->irq->start, msm_io_ispif_irq,
 		IRQF_TRIGGER_RISING, "ispif", 0);
 
@@ -451,6 +534,7 @@
 
 	CDBG("%s, free_irq\n", __func__);
 	free_irq(ispif->irq->start, 0);
+	tasklet_kill(&ispif_tasklet);
 }
 
 void msm_ispif_vfe_get_cid(uint8_t intftype, char *cids, int *num)
diff --git a/drivers/media/video/msm/csi/msm_ispif.h b/drivers/media/video/msm/csi/msm_ispif.h
index deadc28..8f1dd12 100644
--- a/drivers/media/video/msm/csi/msm_ispif.h
+++ b/drivers/media/video/msm/csi/msm_ispif.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
@@ -36,6 +36,12 @@
 	struct clk *ispif_clk[5];
 };
 
+struct ispif_isr_queue_cmd {
+	struct list_head list;
+	uint32_t    ispifInterruptStatus0;
+	uint32_t    ispifInterruptStatus1;
+};
+
 #define VIDIOC_MSM_ISPIF_CFG \
 	_IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct msm_ispif_params)
 
@@ -51,6 +57,12 @@
 #define ISPIF_OFF_IMMEDIATELY       (0x01 << 2)
 #define ISPIF_S_STREAM_SHIFT	4
 
+
+#define PIX_0 (0x01 << 0)
+#define RDI_0 (0x01 << 1)
+#define PIX_1 (0x01 << 2)
+#define RDI_1 (0x01 << 3)
+
 void msm_ispif_vfe_get_cid(uint8_t intftype, char *cids, int *num);
 
 #endif
diff --git a/drivers/media/video/msm/io/msm_io_util.c b/drivers/media/video/msm/io/msm_io_util.c
index 0ae247e..207f8be 100644
--- a/drivers/media/video/msm/io/msm_io_util.c
+++ b/drivers/media/video/msm/io/msm_io_util.c
@@ -40,29 +40,42 @@
 					goto cam_clk_set_err;
 				}
 			}
+			rc = clk_prepare(clk_ptr[i]);
+			if (rc < 0) {
+				pr_err("%s prepare failed\n",
+					   clk_info[i].clk_name);
+				goto cam_clk_prepare_err;
+			}
+
 			rc = clk_enable(clk_ptr[i]);
 			if (rc < 0) {
 				pr_err("%s enable failed\n",
 					   clk_info[i].clk_name);
-				goto cam_clk_set_err;
+				goto cam_clk_enable_err;
 			}
 		}
 	} else {
 		for (i = num_clk - 1; i >= 0; i--) {
-			if (clk_ptr[i] != NULL)
+			if (clk_ptr[i] != NULL) {
 				clk_disable(clk_ptr[i]);
+				clk_unprepare(clk_ptr[i]);
 				clk_put(clk_ptr[i]);
+			}
 		}
 	}
 	return rc;
 
 
+cam_clk_enable_err:
+	clk_unprepare(clk_ptr[i]);
+cam_clk_prepare_err:
 cam_clk_set_err:
 	clk_put(clk_ptr[i]);
 cam_clk_get_err:
 	for (i--; i >= 0; i--) {
 		if (clk_ptr[i] != NULL) {
 			clk_disable(clk_ptr[i]);
+			clk_unprepare(clk_ptr[i]);
 			clk_put(clk_ptr[i]);
 		}
 	}
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index 22322b8..7cab16e 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -116,6 +116,7 @@
 	NOTIFY_ISP_MSG_EVT, /* arg = enum ISP_MESSAGE_ID */
 	NOTIFY_VFE_MSG_OUT, /* arg = struct isp_msg_output */
 	NOTIFY_VFE_MSG_STATS,  /* arg = struct isp_msg_stats */
+	NOTIFY_VFE_MSG_COMP_STATS, /* arg = struct msm_stats_buf */
 	NOTIFY_VFE_BUF_EVT, /* arg = struct msm_vfe_resp */
 	NOTIFY_ISPIF_STREAM, /* arg = enable parameter for s_stream */
 	NOTIFY_VPE_MSG_EVT,
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index 6b3aef7..0cffbbf 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -307,6 +307,36 @@
 		}
 		}
 		break;
+	case NOTIFY_VFE_MSG_COMP_STATS: {
+		struct msm_stats_buf *stats = (struct msm_stats_buf *)arg;
+		struct msm_stats_buf *stats_buf = NULL;
+
+		isp_event->isp_data.isp_msg.msg_id = MSG_ID_STATS_COMPOSITE;
+		stats->aec.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+					stats->aec.buff, &(stats->aec.fd));
+		stats->awb.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+					stats->awb.buff, &(stats->awb.fd));
+		stats->af.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+					stats->af.buff, &(stats->af.fd));
+		stats->ihist.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+					stats->ihist.buff, &(stats->ihist.fd));
+		stats->rs.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+					stats->rs.buff, &(stats->rs.fd));
+		stats->cs.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+					stats->cs.buff, &(stats->cs.fd));
+
+		stats_buf = kmalloc(sizeof(struct msm_stats_buf), GFP_ATOMIC);
+		if (!stats_buf) {
+			pr_err("%s: out of memory.\n", __func__);
+			rc = -ENOMEM;
+		} else {
+			*stats_buf = *stats;
+			isp_event->isp_data.isp_msg.len	=
+				sizeof(struct msm_stats_buf);
+			isp_event->isp_data.isp_msg.data = stats_buf;
+		}
+		}
+		break;
 	case NOTIFY_VFE_MSG_STATS: {
 		struct msm_stats_buf stats;
 		struct isp_msg_stats *isp_stats = (struct isp_msg_stats *)arg;
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index 2c4fbe4..13d1daf 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -241,6 +241,7 @@
 	case NOTIFY_ISP_MSG_EVT:
 	case NOTIFY_VFE_MSG_OUT:
 	case NOTIFY_VFE_MSG_STATS:
+	case NOTIFY_VFE_MSG_COMP_STATS:
 	case NOTIFY_VFE_BUF_EVT:
 	case NOTIFY_VFE_BUF_FREE_EVT:
 		if (p_mctl->isp_sdev && p_mctl->isp_sdev->isp_notify) {
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index 4b86bd8..e1a36a8 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -589,6 +589,7 @@
 
 	vfe32_ctrl->operation_mode = *p;
 	vfe32_ctrl->stats_comp = *(++p);
+	vfe32_ctrl->hfr_mode = *(++p);
 
 	msm_io_w(*(++p), vfe32_ctrl->vfebase + VFE_CFG);
 	msm_io_w(*(++p), vfe32_ctrl->vfebase + VFE_MODULE_CFG);
@@ -684,10 +685,16 @@
 
 static void vfe32_start_common(void)
 {
+	uint32_t irq_mask = 0x00E00021;
 	vfe32_ctrl->start_ack_pending = TRUE;
 	CDBG("VFE opertaion mode = 0x%x, output mode = 0x%x\n",
 		vfe32_ctrl->operation_mode, vfe32_ctrl->outpath.output_mode);
-	msm_io_w(0x00EFE021, vfe32_ctrl->vfebase + VFE_IRQ_MASK_0);
+	if (vfe32_ctrl->stats_comp)
+		irq_mask |= VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK;
+	else
+		irq_mask |= 0x000FE000;
+
+	msm_io_w(irq_mask, vfe32_ctrl->vfebase + VFE_IRQ_MASK_0);
 	msm_io_w(VFE_IMASK_WHILE_STOPPING_1,
 		vfe32_ctrl->vfebase + VFE_IRQ_MASK_1);
 
@@ -2389,47 +2396,73 @@
 static void vfe32_stats_af_ack(struct vfe_cmd_stats_ack *pAck)
 {
 	unsigned long flags;
-	spin_lock_irqsave(&vfe32_ctrl->af_ack_lock, flags);
+	spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+		&vfe32_ctrl->comp_stats_ack_lock :
+		&vfe32_ctrl->af_ack_lock);
+	spin_lock_irqsave(lock, flags);
 	vfe32_ctrl->afStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
 	vfe32_ctrl->afStatsControl.ackPending = FALSE;
-	spin_unlock_irqrestore(&vfe32_ctrl->af_ack_lock, flags);
+	spin_unlock_irqrestore(lock, flags);
 }
 
 static void vfe32_stats_awb_ack(struct vfe_cmd_stats_ack *pAck)
 {
 	unsigned long flags;
-	spin_lock_irqsave(&vfe32_ctrl->awb_ack_lock, flags);
+	spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+		&vfe32_ctrl->comp_stats_ack_lock :
+		&vfe32_ctrl->awb_ack_lock);
+	spin_lock_irqsave(lock, flags);
 	vfe32_ctrl->awbStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
 	vfe32_ctrl->awbStatsControl.ackPending = FALSE;
-	spin_unlock_irqrestore(&vfe32_ctrl->awb_ack_lock, flags);
+	spin_unlock_irqrestore(lock, flags);
 }
 
 static void vfe32_stats_aec_ack(struct vfe_cmd_stats_ack *pAck)
 {
 	unsigned long flags;
-	spin_lock_irqsave(&vfe32_ctrl->aec_ack_lock, flags);
+	spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+		&vfe32_ctrl->comp_stats_ack_lock :
+		&vfe32_ctrl->aec_ack_lock);
+	spin_lock_irqsave(lock, flags);
 	vfe32_ctrl->aecStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
 	vfe32_ctrl->aecStatsControl.ackPending = FALSE;
-	spin_unlock_irqrestore(&vfe32_ctrl->aec_ack_lock, flags);
+	spin_unlock_irqrestore(lock, flags);
 }
 
 static void vfe32_stats_ihist_ack(struct vfe_cmd_stats_ack *pAck)
 {
+	unsigned long flags;
+	spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+		&vfe32_ctrl->comp_stats_ack_lock :
+		&vfe32_ctrl->ihist_ack_lock);
+	spin_lock_irqsave(lock, flags);
 	vfe32_ctrl->ihistStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
 	vfe32_ctrl->ihistStatsControl.ackPending = FALSE;
+	spin_unlock_irqrestore(lock, flags);
 }
 static void vfe32_stats_rs_ack(struct vfe_cmd_stats_ack *pAck)
 {
+	unsigned long flags;
+	spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+		&vfe32_ctrl->comp_stats_ack_lock :
+		&vfe32_ctrl->rs_ack_lock);
+	spin_lock_irqsave(lock, flags);
 	vfe32_ctrl->rsStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
 	vfe32_ctrl->rsStatsControl.ackPending = FALSE;
+	spin_unlock_irqrestore(lock, flags);
 }
 static void vfe32_stats_cs_ack(struct vfe_cmd_stats_ack *pAck)
 {
+	unsigned long flags;
+	spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+		&vfe32_ctrl->comp_stats_ack_lock :
+		&vfe32_ctrl->cs_ack_lock);
+	spin_lock_irqsave(lock, flags);
 	vfe32_ctrl->csStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
 	vfe32_ctrl->csStatsControl.ackPending = FALSE;
+	spin_unlock_irqrestore(lock, flags);
 }
 
-
 static inline void vfe32_read_irq_status(struct vfe32_irq_status *out)
 {
 	uint32_t *temp;
@@ -2654,6 +2687,13 @@
 			msm_io_w_mb(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
 				vfe32_ctrl->vfebase + VFE_CAMIF_COMMAND);
 		}
+	} /* if raw snapshot mode. */
+	if ((vfe32_ctrl->hfr_mode != HFR_MODE_OFF) &&
+		(vfe32_ctrl->operation_mode == VFE_MODE_OF_OPERATION_VIDEO) &&
+		(vfe32_ctrl->vfeFrameId % vfe32_ctrl->hfr_mode != 0)) {
+		vfe32_ctrl->vfeFrameId++;
+		CDBG("Skip the SOF notification when HFR enabled\n");
+		return;
 	}
 	vfe32_ctrl->vfeFrameId++;
 	vfe32_send_isp_msg(vfe32_ctrl, MSG_ID_SOF_ACK);
@@ -2907,11 +2947,6 @@
 	}
 }
 
-static void vfe32_process_stats_comb_irq(uint32_t *irqstatus)
-{
-	return;
-}
-
 static uint32_t  vfe32_process_stats_irq_common(uint32_t statsNum,
 						uint32_t newAddr) {
 
@@ -2971,17 +3006,23 @@
 
 	case statsIhistNum: {
 		msgStats.id = MSG_ID_STATS_IHIST;
+		spin_lock_irqsave(&vfe32_ctrl->ihist_ack_lock, flags);
 		vfe32_ctrl->ihistStatsControl.ackPending = TRUE;
+		spin_unlock_irqrestore(&vfe32_ctrl->ihist_ack_lock, flags);
 		}
 		break;
 	case statsRsNum: {
 		msgStats.id = MSG_ID_STATS_RS;
+		spin_lock_irqsave(&vfe32_ctrl->rs_ack_lock, flags);
 		vfe32_ctrl->rsStatsControl.ackPending = TRUE;
+		spin_unlock_irqrestore(&vfe32_ctrl->rs_ack_lock, flags);
 		}
 		break;
 	case statsCsNum: {
 		msgStats.id = MSG_ID_STATS_CS;
+		spin_lock_irqsave(&vfe32_ctrl->cs_ack_lock, flags);
 		vfe32_ctrl->csStatsControl.ackPending = TRUE;
+		spin_unlock_irqrestore(&vfe32_ctrl->cs_ack_lock, flags);
 		}
 		break;
 
@@ -2997,6 +3038,30 @@
 	return;
 }
 
+static void vfe_send_comp_stats_msg(uint32_t status_bits)
+{
+	struct msm_stats_buf msgStats;
+	uint32_t temp;
+
+	msgStats.frame_id = vfe32_ctrl->vfeFrameId;
+	msgStats.status_bits = status_bits;
+
+	msgStats.aec.buff = vfe32_ctrl->aecStatsControl.bufToRender;
+	msgStats.awb.buff = vfe32_ctrl->awbStatsControl.bufToRender;
+	msgStats.af.buff = vfe32_ctrl->afStatsControl.bufToRender;
+
+	msgStats.ihist.buff = vfe32_ctrl->ihistStatsControl.bufToRender;
+	msgStats.rs.buff = vfe32_ctrl->rsStatsControl.bufToRender;
+	msgStats.cs.buff = vfe32_ctrl->csStatsControl.bufToRender;
+
+	temp = msm_io_r(vfe32_ctrl->vfebase + VFE_STATS_AWB_SGW_CFG);
+	msgStats.awb_ymin = (0xFF00 & temp) >> 8;
+
+	v4l2_subdev_notify(&vfe32_ctrl->subdev,
+				NOTIFY_VFE_MSG_COMP_STATS,
+				&msgStats);
+}
+
 static void vfe32_process_stats_ae_irq(void)
 {
 	unsigned long flags;
@@ -3105,6 +3170,126 @@
 	}
 }
 
+static void vfe32_process_stats(uint32_t status_bits)
+{
+	unsigned long flags;
+	int32_t process_stats = false;
+	CDBG("%s, stats = 0x%x\n", __func__, status_bits);
+
+	spin_lock_irqsave(&vfe32_ctrl->comp_stats_ack_lock, flags);
+	if (status_bits & VFE_IRQ_STATUS0_STATS_AEC) {
+		if (!vfe32_ctrl->aecStatsControl.ackPending) {
+			vfe32_ctrl->aecStatsControl.ackPending = TRUE;
+			vfe32_ctrl->aecStatsControl.bufToRender =
+				vfe32_process_stats_irq_common(statsAeNum,
+				vfe32_ctrl->aecStatsControl.nextFrameAddrBuf);
+			process_stats = true;
+		} else{
+			vfe32_ctrl->aecStatsControl.bufToRender = 0;
+			vfe32_ctrl->aecStatsControl.droppedStatsFrameCount++;
+		}
+	} else {
+		vfe32_ctrl->aecStatsControl.bufToRender = 0;
+	}
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_AWB) {
+		if (!vfe32_ctrl->awbStatsControl.ackPending) {
+			vfe32_ctrl->awbStatsControl.ackPending = TRUE;
+			vfe32_ctrl->awbStatsControl.bufToRender =
+				vfe32_process_stats_irq_common(statsAwbNum,
+				vfe32_ctrl->awbStatsControl.nextFrameAddrBuf);
+			process_stats = true;
+		} else{
+			vfe32_ctrl->awbStatsControl.droppedStatsFrameCount++;
+			vfe32_ctrl->awbStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe32_ctrl->awbStatsControl.bufToRender = 0;
+	}
+
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_AF) {
+		if (!vfe32_ctrl->afStatsControl.ackPending) {
+			vfe32_ctrl->afStatsControl.ackPending = TRUE;
+			vfe32_ctrl->afStatsControl.bufToRender =
+				vfe32_process_stats_irq_common(statsAfNum,
+				vfe32_ctrl->afStatsControl.nextFrameAddrBuf);
+			process_stats = true;
+		} else {
+			vfe32_ctrl->afStatsControl.bufToRender = 0;
+			vfe32_ctrl->afStatsControl.droppedStatsFrameCount++;
+		}
+	} else {
+		vfe32_ctrl->afStatsControl.bufToRender = 0;
+	}
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_IHIST) {
+		if (!vfe32_ctrl->ihistStatsControl.ackPending) {
+			vfe32_ctrl->ihistStatsControl.ackPending = TRUE;
+			vfe32_ctrl->ihistStatsControl.bufToRender =
+				vfe32_process_stats_irq_common(statsIhistNum,
+				vfe32_ctrl->ihistStatsControl.nextFrameAddrBuf);
+			process_stats = true;
+		} else {
+			vfe32_ctrl->ihistStatsControl.droppedStatsFrameCount++;
+			vfe32_ctrl->ihistStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe32_ctrl->ihistStatsControl.bufToRender = 0;
+	}
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_RS) {
+		if (!vfe32_ctrl->rsStatsControl.ackPending) {
+			vfe32_ctrl->rsStatsControl.ackPending = TRUE;
+			vfe32_ctrl->rsStatsControl.bufToRender =
+				vfe32_process_stats_irq_common(statsRsNum,
+				vfe32_ctrl->rsStatsControl.nextFrameAddrBuf);
+			process_stats = true;
+		} else {
+			vfe32_ctrl->rsStatsControl.droppedStatsFrameCount++;
+			vfe32_ctrl->rsStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe32_ctrl->rsStatsControl.bufToRender = 0;
+	}
+
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_CS) {
+		if (!vfe32_ctrl->csStatsControl.ackPending) {
+			vfe32_ctrl->csStatsControl.ackPending = TRUE;
+			vfe32_ctrl->csStatsControl.bufToRender =
+				vfe32_process_stats_irq_common(statsCsNum,
+				vfe32_ctrl->csStatsControl.nextFrameAddrBuf);
+			process_stats = true;
+		} else {
+			vfe32_ctrl->csStatsControl.droppedStatsFrameCount++;
+			vfe32_ctrl->csStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe32_ctrl->csStatsControl.bufToRender = 0;
+	}
+
+	spin_unlock_irqrestore(&vfe32_ctrl->comp_stats_ack_lock, flags);
+	if (process_stats)
+		vfe_send_comp_stats_msg(status_bits);
+
+	return;
+}
+
+static void vfe32_process_stats_irq(uint32_t *irqstatus)
+{
+	uint32_t status_bits = VFE_COM_STATUS & *irqstatus;
+
+	if ((vfe32_ctrl->hfr_mode != HFR_MODE_OFF) &&
+		(vfe32_ctrl->vfeFrameId % vfe32_ctrl->hfr_mode != 0)) {
+		CDBG("Skip the stats when HFR enabled\n");
+		return;
+	}
+
+	vfe32_process_stats(status_bits);
+	return;
+}
+
 static void vfe32_do_tasklet(unsigned long data)
 {
 	unsigned long flags;
@@ -3191,7 +3376,7 @@
 				if (qcmd->vfeInterruptStatus0 &
 					VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK) {
 					CDBG("Stats composite irq occured.\n");
-					vfe32_process_stats_comb_irq(
+					vfe32_process_stats_irq(
 						&qcmd->vfeInterruptStatus0);
 				}
 			} else {
@@ -3618,6 +3803,10 @@
 	spin_lock_init(&vfe32_ctrl->aec_ack_lock);
 	spin_lock_init(&vfe32_ctrl->awb_ack_lock);
 	spin_lock_init(&vfe32_ctrl->af_ack_lock);
+	spin_lock_init(&vfe32_ctrl->ihist_ack_lock);
+	spin_lock_init(&vfe32_ctrl->rs_ack_lock);
+	spin_lock_init(&vfe32_ctrl->cs_ack_lock);
+	spin_lock_init(&vfe32_ctrl->comp_stats_ack_lock);
 	spin_lock_init(&vfe32_ctrl->sd_notify_lock);
 	INIT_LIST_HEAD(&vfe32_ctrl->tasklet_q);
 
@@ -3625,6 +3814,7 @@
 	vfe32_ctrl->update_rolloff = false;
 	vfe32_ctrl->update_la = false;
 	vfe32_ctrl->update_gamma = false;
+	vfe32_ctrl->hfr_mode = HFR_MODE_OFF;
 
 	enable_irq(vfe32_ctrl->vfeirq->start);
 
diff --git a/drivers/media/video/msm/msm_vfe32.h b/drivers/media/video/msm/msm_vfe32.h
index 1adfffd..c511b69 100644
--- a/drivers/media/video/msm/msm_vfe32.h
+++ b/drivers/media/video/msm/msm_vfe32.h
@@ -168,6 +168,8 @@
 #define VFE_AF_PINGPONG_STATUS_BIT       0x100
 #define VFE_AWB_PINGPONG_STATUS_BIT      0x200
 
+#define HFR_MODE_OFF 1
+
 enum VFE32_DMI_RAM_SEL {
 	NO_MEM_SELECTED          = 0,
 	BLACK_LUT_RAM_BANK0      = 0x1,
@@ -220,7 +222,7 @@
 #define V32_OUT_CLAMP_OFF         0x00000524
 #define V32_OUT_CLAMP_LEN         8
 
-#define V32_OPERATION_CFG_LEN     32
+#define V32_OPERATION_CFG_LEN     36
 
 #define V32_AXI_OUT_OFF           0x00000038
 #define V32_AXI_OUT_LEN           216
@@ -778,6 +780,8 @@
 #define VFE32_IMASK_STATS_SKIN_BHIST_BUS_OVFL (0x00000001<<21)
 #define VFE32_IMASK_AXI_ERROR                 (0x00000001<<22)
 
+#define VFE_COM_STATUS 0x000FE000
+
 struct vfe32_output_path {
 	uint16_t output_mode;     /* bitmask  */
 
@@ -864,6 +868,7 @@
 #define VFE_CLAMP_MIN                   0x00000528
 #define VFE_REALIGN_BUF                 0x0000052C
 #define VFE_STATS_CFG                   0x00000530
+#define VFE_STATS_AWB_SGW_CFG           0x00000554
 #define VFE_DMI_CFG                     0x00000598
 #define VFE_DMI_ADDR                    0x0000059C
 #define VFE_DMI_DATA_LO                 0x000005A4
@@ -906,6 +911,10 @@
 	spinlock_t  aec_ack_lock;
 	spinlock_t  awb_ack_lock;
 	spinlock_t  af_ack_lock;
+	spinlock_t  ihist_ack_lock;
+	spinlock_t  rs_ack_lock;
+	spinlock_t  cs_ack_lock;
+	spinlock_t  comp_stats_ack_lock;
 
 	uint32_t extlen;
 	void *extdata;
@@ -958,6 +967,7 @@
 	struct platform_device *pdev;
 	struct clk *vfe_clk[3];
 	spinlock_t  sd_notify_lock;
+	uint32_t hfr_mode;
 };
 
 #define statsAeNum      0
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index 1b57350..d0b4f1f 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -215,7 +215,7 @@
 
 	v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
 		NOTIFY_ISPIF_STREAM, (void *)ISPIF_STREAM(
-		PIX0, ISPIF_OFF_IMMEDIATELY));
+		PIX_0, ISPIF_OFF_IMMEDIATELY));
 	s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
 	msleep(30);
 	if (update_type == MSM_SENSOR_REG_INIT) {
@@ -244,7 +244,7 @@
 			output_settings[res].op_pixel_clk);
 		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
 			NOTIFY_ISPIF_STREAM, (void *)ISPIF_STREAM(
-			PIX0, ISPIF_ON_FRAME_BOUNDARY));
+			PIX_0, ISPIF_ON_FRAME_BOUNDARY));
 		s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
 		msleep(30);
 	}
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 00e4fda..6dd65e8 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -42,6 +42,7 @@
 
 #include <mach/clk.h>
 #include <mach/msm_xo.h>
+#include <mach/msm_bus.h>
 
 #define MSM_USB_BASE	(motg->regs)
 #define DRIVER_NAME	"msm_otg"
@@ -1122,6 +1123,7 @@
 
 static void msm_otg_start_peripheral(struct otg_transceiver *otg, int on)
 {
+	int ret;
 	struct msm_otg *motg = container_of(otg, struct msm_otg, otg);
 	struct msm_otg_platform_data *pdata = motg->pdata;
 
@@ -1142,11 +1144,27 @@
 		 * power collapse(pc) while running in peripheral mode.
 		 */
 		otg_pm_qos_update_latency(motg, 1);
+		/* Configure BUS performance parameters for MAX bandwidth */
+		if (motg->bus_perf_client) {
+			ret = msm_bus_scale_client_update_request(
+					motg->bus_perf_client, 1);
+			if (ret)
+				dev_err(motg->otg.dev, "%s: Failed to vote for "
+					   "bus bandwidth %d\n", __func__, ret);
+		}
 		usb_gadget_vbus_connect(otg->gadget);
 	} else {
 		dev_dbg(otg->dev, "gadget off\n");
 		usb_gadget_vbus_disconnect(otg->gadget);
 		otg_pm_qos_update_latency(motg, 0);
+		/* Configure BUS performance parameters to default */
+		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);
+		}
 		if (pdata->setup_gpio)
 			pdata->setup_gpio(OTG_STATE_UNDEFINED);
 	}
@@ -2601,6 +2619,14 @@
 	pm_runtime_set_active(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
 
+	if (motg->pdata->bus_scale_table) {
+		motg->bus_perf_client =
+		    msm_bus_scale_register_client(motg->pdata->bus_scale_table);
+		if (!motg->bus_perf_client)
+			dev_err(motg->otg.dev, "%s: Failed to register BUS "
+						"scaling client!!\n", __func__);
+	}
+
 	return 0;
 
 remove_otg:
@@ -2702,6 +2728,9 @@
 	if (motg->pdata->swfi_latency)
 		pm_qos_remove_request(&motg->pm_qos_req_dma);
 
+	if (motg->bus_perf_client)
+		msm_bus_scale_unregister_client(motg->bus_perf_client);
+
 	kfree(motg);
 	return 0;
 }
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
index c7759c4..b590c41 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -309,6 +309,15 @@
 	  The panel is connected to the host
 	  via Toshiba DSI-to-LVDS bridge.
 
+config FB_MSM_MIPI_CHIMEI_WUXGA
+	bool "LVDS Chimei WUXGA Panel using Toshiba MIPI DSI-to-LVDS bridge."
+	select FB_MSM_MIPI_DSI_TC358764_DSI2LVDS
+	---help---
+	  Support for Chimei WUXGA (1920x1200) panel.
+	  The panel is using a serial LVDS input.
+	  The panel is connected to the host
+	  via Toshiba DSI-to-LVDS bridge.
+
 config FB_MSM_MIPI_TRULY_VIDEO_WVGA_PT
 	bool
 	select FB_MSM_MIPI_DSI_TRULY
@@ -446,6 +455,7 @@
 	select FB_MSM_MIPI_NT35510_CMD_WVGA_PT
 	select FB_MSM_MIPI_SIMULATOR_VIDEO
 	select FB_MSM_MIPI_CHIMEI_WXGA
+	select FB_MSM_MIPI_CHIMEI_WUXGA
 	---help---
 	  Support for MIPI panel auto detect
 
@@ -543,6 +553,10 @@
 	bool "MIPI Chimei WXGA PT Panel"
 	select FB_MSM_MIPI_CHIMEI_WXGA
 
+config FB_MSM_MIPI_CHIMEI_WUXGA_PANEL
+	bool "MIPI Chimei WUXGA Panel"
+	select FB_MSM_MIPI_CHIMEI_WUXGA
+
 config FB_MSM_MIPI_TRULY_VIDEO_WVGA_PT_PANEL
 	bool "MIPI Truly Video WVGA PT Panel"
 	select FB_MSM_MIPI_TRULY_VIDEO_WVGA_PT
diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile
index 93205bc..bd7628d 100644
--- a/drivers/video/msm/Makefile
+++ b/drivers/video/msm/Makefile
@@ -119,6 +119,7 @@
 obj-y += mipi_renesas_video_fwvga_pt.o mipi_renesas_cmd_fwvga_pt.o
 obj-y += mipi_NT35510_video_wvga_pt.o mipi_NT35510_cmd_wvga_pt.o
 obj-y += mipi_chimei_wxga_pt.o
+obj-y += mipi_chimei_wuxga.o
 obj-y += mipi_truly_video_wvga_pt.o
 else
 obj-$(CONFIG_FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT) += mipi_toshiba_video_wvga_pt.o
@@ -133,6 +134,7 @@
 obj-$(CONFIG_FB_MSM_MIPI_NT35510_VIDEO_WVGA_PT) += mipi_NT35510_video_wvga_pt.o
 obj-$(CONFIG_FB_MSM_MIPI_SIMULATOR_VIDEO) += mipi_simulator_video.o
 obj-$(CONFIG_FB_MSM_MIPI_CHIMEI_WXGA) += mipi_chimei_wxga_pt.o
+obj-$(CONFIG_FB_MSM_MIPI_CHIMEI_WUXGA) += mipi_chimei_wuxga.o
 endif
 
 obj-$(CONFIG_FB_MSM_LCDC_PANEL) += lcdc_panel.o
diff --git a/drivers/video/msm/mipi_chimei_wuxga.c b/drivers/video/msm/mipi_chimei_wuxga.c
new file mode 100644
index 0000000..c63df46
--- /dev/null
+++ b/drivers/video/msm/mipi_chimei_wuxga.c
@@ -0,0 +1,196 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/*
+ * Chimei WUXGA LVDS Panel driver.
+ * The panel model is N101JSF-L21.
+ *
+ * The panel interface includes:
+ * 1. LVDS input for video (clock & data).
+ * 2. few configuration	pins to control 3D module: Enable, Mode (2D/3D).
+ * 3. Backlight LED control (PWM 200 HZ).
+ *
+ * This panel is controled via the Toshiba DSI-to-LVDS bridge.
+ *
+ */
+
+/* #define DEBUG 1 */
+
+#include "msm_fb.h"
+#include "msm_fb_panel.h"
+#include "mipi_dsi.h"
+#include "mipi_tc358764_dsi2lvds.h"
+
+#define MHZ (1000*1000)
+
+/**
+ * Panel info parameters.
+ * The panel info is passed to the mipi framebuffer driver.
+ */
+static struct msm_panel_info chimei_wuxga_pinfo;
+
+/**
+ * The mipi_dsi_phy_ctrl is calculated according to the
+ * "dsi_timing_program.xlsm" excel sheet.
+ * Output is based on: 1200x1920, RGB565, 4 lanes , 58 frames
+ * per second.
+ */
+static struct mipi_dsi_phy_ctrl dsi_video_mode_phy_db = {
+	/* DSIPHY_REGULATOR_CTRL */
+	.regulator = {0x03, 0x0a, 0x04, 0x00, 0x20}, /* common 8960 */
+	/* DSIPHY_CTRL */
+	.ctrl = {0x5f, 0x00, 0x00, 0x10}, /* common 8960 */
+	/* DSIPHY_STRENGTH_CTRL */
+	.strength = {0xff, 0x00, 0x06, 0x00}, /* common 8960 */
+	/* DSIPHY_TIMING_CTRL */
+	.timing = { 0xC9, 0x92, 0x29, /* panel specific */
+	0, /* DSIPHY_TIMING_CTRL_3 = 0 */
+	0x2E, 0x9B, 0x2C, 0x94, 0x2E, 0x03, 0x04},  /* panel specific */
+
+	/* DSIPHY_PLL_CTRL */
+	.pll = { 0x00, /* common 8960 */
+	/* VCO */
+	0x32, (0x01 | 0x30) , (0x19 | 0xC0), /* panel specific */
+	0x00, 0x50, 0x48, 0x63,
+	0x77, 0x88, 0x99, /* Auto update by dsi-mipi driver */
+	0x00, 0x14, 0x03, 0x00, 0x02, /* common 8960 */
+	0x00, 0x20, 0x00, 0x01 }, /* common 8960 */
+};
+
+/**
+ * Module init.
+ *
+ * Register the panel-info.
+ *
+ * Some parameters are from the panel datasheet
+ * and other are *calculated* by the "dsi_timing_program.xlsm"
+ * excel file
+ *
+ * @return int
+ */
+static int __init mipi_chimei_wuxga_init(void)
+{
+	int ret;
+	struct msm_panel_info *pinfo = &chimei_wuxga_pinfo;
+
+	if (msm_fb_detect_client("mipi_video_chimei_wuxga"))
+		return 0;
+
+	pr_info("mipi-dsi chimei wuxga (1200x1920) driver ver 1.0.\n");
+
+	/* Portrait */
+	pinfo->xres = 1200;
+	pinfo->yres = 1920;
+	pinfo->type =  MIPI_VIDEO_PANEL;
+	pinfo->pdest = DISPLAY_1; /* Primary Display */
+	pinfo->wait_cycle = 0;
+	pinfo->bpp = 24; /* RGB565 requires 24 bits-per-pixel :-O */
+	pinfo->fb_num = 2; /* using two frame buffers */
+
+	/*
+	 * The CMI panel requires 80 MHZ LVDS-CLK.
+	 * The D2L bridge drives the LVDS-CLK from the DSI-CLK.
+	 * The DSI-CLK = bitclk/2, 640 MHZ/2= 320 MHZ.
+	 * LVDS-CLK = DSI-CLK/4 , 320 MHZ/4= 80 MHZ.
+	 */
+
+	pinfo->clk_rate = 640 * MHZ ; /* bitclk Calculated */
+
+	/*
+	 * this panel is operated by DE,
+	 * vsycn and hsync are ignored
+	 */
+
+	pinfo->lcdc.h_front_porch = 16;	/* thfp */
+	pinfo->lcdc.h_back_porch = 160;	/* thb */
+	pinfo->lcdc.h_pulse_width = 32;	/* thpw */
+
+	pinfo->lcdc.v_front_porch = 0;	/* tvfp */
+	pinfo->lcdc.v_back_porch = 26;	/* tvb */
+	pinfo->lcdc.v_pulse_width = 6;	/* tvpw */
+
+	pinfo->lcdc.border_clr = 0;		/* black */
+	pinfo->lcdc.underflow_clr = 0xff;	/* blue */
+
+	pinfo->lcdc.hsync_skew = 0;
+
+	/* Backlight levels - controled via PMIC pwm gpio */
+	pinfo->bl_max = 15;
+	pinfo->bl_min = 1;
+
+	/* mipi - general */
+	pinfo->mipi.vc = 0; /* virtual channel */
+	pinfo->mipi.rgb_swap = DSI_RGB_SWAP_RGB;
+	pinfo->mipi.tx_eot_append = true;
+	pinfo->mipi.t_clk_post = 34;		/* Calculated */
+	pinfo->mipi.t_clk_pre = 69;		/* Calculated */
+
+	pinfo->mipi.dsi_phy_db = &dsi_video_mode_phy_db;
+
+	/* Four lanes are recomended for 1920x1200 at 60 frames per second */
+	pinfo->mipi.frame_rate = 45; /* 45 frames per second */
+	pinfo->mipi.data_lane0 = true;
+	pinfo->mipi.data_lane1 = true;
+	pinfo->mipi.data_lane2 = true;
+	pinfo->mipi.data_lane3 = true;
+
+	pinfo->mipi.mode = DSI_VIDEO_MODE;
+	/*
+	 * Note: The CMI panel input is RGB888,
+	 * thus the DSI-to-LVDS bridge output is RGB888.
+	 * This parameter selects the DSI-Core output to the bridge.
+	 */
+	pinfo->mipi.dst_format = DSI_VIDEO_DST_FORMAT_RGB565;
+
+	/* mipi - video mode */
+	pinfo->mipi.traffic_mode = DSI_NON_BURST_SYNCH_EVENT;
+	pinfo->mipi.pulse_mode_hsa_he = false; /* sync mode */
+
+	pinfo->mipi.hfp_power_stop = false;
+	pinfo->mipi.hbp_power_stop = false;
+	pinfo->mipi.hsa_power_stop = false;
+	pinfo->mipi.eof_bllp_power_stop = false;
+	pinfo->mipi.bllp_power_stop = false;
+
+	/* mipi - command mode */
+	pinfo->mipi.te_sel = 1; /* TE from vsycn gpio */
+	pinfo->mipi.interleave_max = 1;
+	/* The bridge supports only Generic Read/Write commands */
+	pinfo->mipi.insert_dcs_cmd = false;
+	pinfo->mipi.wr_mem_continue = 0;
+	pinfo->mipi.wr_mem_start = 0;
+	pinfo->mipi.stream = false; /* dma_p */
+	pinfo->mipi.mdp_trigger = DSI_CMD_TRIGGER_NONE;
+	pinfo->mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+	/*
+	 * toshiba d2l chip does not need max_pkt_size dcs cmd
+	 * client reply len is directly configure through
+	 * RDPKTLN register (0x0404)
+	 */
+	pinfo->mipi.no_max_pkt_size = 1;
+	pinfo->mipi.force_clk_lane_hs = 1;
+
+	pinfo->is_3d_panel = FB_TYPE_3D_PANEL;
+
+	ret = mipi_tc358764_dsi2lvds_register(pinfo, MIPI_DSI_PRIM, 1);
+	if (ret)
+		pr_err("%s: failed to register device!\n", __func__);
+
+	return ret;
+}
+
+module_init(mipi_chimei_wuxga_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Chimei WUXGA LVDS Panel driver");
+MODULE_AUTHOR("Amir Samuelov <amirs@codeaurora.org>");
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 42fa2ba..489e6d2 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -1520,8 +1520,8 @@
 			pdata->set_backlight(mfd);
 			bl_level_old = unset_bl_level;
 			up(&mfd->sem);
+			bl_updated = 1;
 		}
-		bl_updated = 1;
 	}
 
 	++mfd->panel_info.frame_count;
@@ -2624,8 +2624,8 @@
 			pdata->set_backlight(mfd);
 			bl_level_old = unset_bl_level;
 			up(&mfd->sem);
+			bl_updated = 1;
 		}
-		bl_updated = 1;
 	}
 
 	return ret;
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 2cbe6ce..037cfe7 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -164,6 +164,7 @@
  * @enable_dcd: Enable Data Contact Detection circuit. if not set
  *              wait for 600msec before proceeding to primary
  *              detection.
+ * @bus_scale_table: parameters for bus bandwidth requirements
  */
 struct msm_otg_platform_data {
 	int *phy_init_seq;
@@ -179,6 +180,7 @@
 	bool disable_reset_on_disconnect;
 	u32 swfi_latency;
 	bool enable_dcd;
+	struct msm_bus_scale_pdata *bus_scale_table;
 };
 
 /**
@@ -211,6 +213,7 @@
 	collapse when cable is connected.
  * @id_timer: The timer used for polling ID line to detect ACA states.
  * @xo_handle: TCXO buffer handle
+ * @bus_perf_client: Bus performance client handle to request BUS bandwidth
  */
 struct msm_otg {
 	struct otg_transceiver otg;
@@ -241,6 +244,7 @@
 	struct timer_list id_timer;
 	unsigned long caps;
 	struct clk *xo_handle;
+	uint32_t bus_perf_client;
 	/*
 	 * Allowing PHY power collpase turns off the HSUSB 3.3v and 1.8v
 	 * analog regulators while going to low power mode.
diff --git a/include/media/msm_isp.h b/include/media/msm_isp.h
index 7caafb6..5dd1445 100644
--- a/include/media/msm_isp.h
+++ b/include/media/msm_isp.h
@@ -58,6 +58,7 @@
 #define MSG_ID_STATS_AWB_AEC            39
 #define MSG_ID_OUTPUT_PRIMARY           40
 #define MSG_ID_OUTPUT_SECONDARY         41
+#define MSG_ID_STATS_COMPOSITE          42
 
 /* ISP command IDs */
 #define VFE_CMD_DUMMY_0                                 0
diff --git a/sound/soc/msm/msm7201.c b/sound/soc/msm/msm7201.c
index 9e041c7..6408cef 100644
--- a/sound/soc/msm/msm7201.c
+++ b/sound/soc/msm/msm7201.c
@@ -1,6 +1,6 @@
 /* linux/sound/soc/msm/msm7201.c
  *
- * Copyright (c) 2008-2009, 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011, 2012 Code Aurora Forum. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
@@ -40,6 +40,8 @@
 #include <mach/msm_rpcrouter.h>
 
 static struct msm_rpc_endpoint *snd_ep;
+static uint32_t snd_mute_ear_mute;
+static uint32_t snd_mute_mic_mute;
 
 struct msm_snd_rpc_ids {
 	unsigned long   prog;
@@ -99,7 +101,7 @@
 	 * The number of devices supported is 26 (0 to 25)
 	 */
 	uinfo->value.integer.min = 0;
-	uinfo->value.integer.max = 25;
+	uinfo->value.integer.max = 36;
 	return 0;
 }
 
@@ -107,6 +109,8 @@
 				struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.integer.value[0] = (uint32_t)snd_rpc_ids.device;
+	ucontrol->value.integer.value[1] = snd_mute_ear_mute;
+	ucontrol->value.integer.value[2] = snd_mute_mic_mute;
 	return 0;
 }
 
@@ -213,8 +217,11 @@
 	if (rc < 0) {
 		printk(KERN_ERR "%s: snd rpc call failed! rc = %d\n",
 			__func__, rc);
-	} else
-		printk(KERN_INFO "snd device connected \n");
+	} else {
+		printk(KERN_INFO "snd device connected\n");
+		snd_mute_ear_mute = ucontrol->value.integer.value[1];
+		snd_mute_mic_mute = ucontrol->value.integer.value[2];
+	}
 
 	return rc;
 }