Merge "wcnss : Add more arguments to Thermal Mitigation APIs" into msm-3.0
diff --git a/arch/arm/boot/dts/msmcopper-regulator.dtsi b/arch/arm/boot/dts/msmcopper-regulator.dtsi
index 48d5720..bb26e00 100644
--- a/arch/arm/boot/dts/msmcopper-regulator.dtsi
+++ b/arch/arm/boot/dts/msmcopper-regulator.dtsi
@@ -313,6 +313,7 @@
 				regulator-max-microvolt = <1150000>;
 				qcom,enable-time = <500>;
 				qcom,pull-down-enable = <1>;
+				regulator-always-on;
 				status = "okay";
 			};
 
diff --git a/arch/arm/boot/dts/msmcopper.dtsi b/arch/arm/boot/dts/msmcopper.dtsi
index 66f5fa1..aa7adc5 100644
--- a/arch/arm/boot/dts/msmcopper.dtsi
+++ b/arch/arm/boot/dts/msmcopper.dtsi
@@ -134,7 +134,7 @@
 		compatible = "qcom,spi-qup-v2";
 		reg = <0xf9924000 0x1000>;
 		interrupts = <0 96 0>;
-		spi-max-frequency = <24000000>;
+		spi-max-frequency = <25000000>;
 	};
 
 	slim@fe12f000 {
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 11b1f73..255d92a 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -331,6 +331,7 @@
 CONFIG_MT9M114=y
 CONFIG_IMX074_ACT=y
 CONFIG_MSM_CAMERA_FLASH_SC628A=y
+CONFIG_MSM_CAMERA_FLASH_TPS61310=y
 CONFIG_OV2720=y
 CONFIG_MSM_CAMERA_SENSOR=y
 CONFIG_MSM_ACTUATOR=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 886a691..62b1a57 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -340,6 +340,7 @@
 CONFIG_MT9M114=y
 CONFIG_IMX074_ACT=y
 CONFIG_MSM_CAMERA_FLASH_SC628A=y
+CONFIG_MSM_CAMERA_FLASH_TPS61310=y
 CONFIG_OV2720=y
 CONFIG_MSM_CAMERA_SENSOR=y
 CONFIG_MSM_ACTUATOR=y
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index a65c5b0..6986a29 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -370,6 +370,7 @@
 		},
 	[L2] = {
 			.hfpll_base   = MSM_HFPLL_BASE    + 0x400,
+			.hfpll_vdd_tbl = hfpll_vdd_dig_tbl_8930,
 			.aux_clk_sel  = MSM_APCS_GCC_BASE + 0x028,
 			.l2cpmr_iaddr = L2CPMR_IADDR,
 			.vreg[VREG_HFPLL_B] = { "hfpll_l2", 1800000,
diff --git a/arch/arm/mach-msm/board-8064-camera.c b/arch/arm/mach-msm/board-8064-camera.c
index 36953ef..114b271 100644
--- a/arch/arm/mach-msm/board-8064-camera.c
+++ b/arch/arm/mach-msm/board-8064-camera.c
@@ -188,6 +188,7 @@
 	.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,
+	._fsrc.ext_driver_src.flash_id = MAM_CAMERA_EXT_LED_FLASH_SC628A,
 };
 
 static struct msm_gpiomux_config apq8064_cam_2d_configs[] = {
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index 3431cd0..e873498 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -342,6 +342,12 @@
 	.pull = GPIOMUX_PULL_KEEPER,
 };
 
+static struct gpiomux_setting mbhc_hs_detect = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
 static struct gpiomux_setting cdc_mclk = {
 	.func = GPIOMUX_FUNC_1,
 	.drv = GPIOMUX_DRV_8MA,
@@ -730,6 +736,12 @@
 
 static struct msm_gpiomux_config apq8064_audio_codec_configs[] __initdata = {
 	{
+		.gpio = 38,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &mbhc_hs_detect,
+		},
+	},
+	{
 		.gpio = 39,
 		.settings = {
 			[GPIOMUX_SUSPENDED] = &cdc_mclk,
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index 3d2dbaa..40222b8 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -549,7 +549,7 @@
 	 *		ID   name always_on pd min_uV   max_uV   en_t supply
 	 *	system_uA reg_ID
 	 */
-	PM8XXX_NLDO1200(L26, "8921_l26", 0, 1, 1050000, 1050000, 200, "8921_s7",
+	PM8XXX_NLDO1200(L26, "8921_l26", 0, 1, 375000, 1050000, 200, "8921_s7",
 		0, 1),
 
 	/*           ID        name     always_on pd       en_t supply reg_ID */
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index c123138..d04e5e4 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -95,14 +95,15 @@
 #ifdef CONFIG_MSM_IOMMU
 #define MSM_ION_MM_SIZE		0x3800000
 #define MSM_ION_SF_SIZE		0
+#define MSM_ION_QSECOM_SIZE	0x780000 /* (7.5MB) */
 #define MSM_ION_HEAP_NUM	7
 #else
 #define MSM_ION_MM_SIZE		MSM_PMEM_ADSP_SIZE
 #define MSM_ION_SF_SIZE		MSM_PMEM_SIZE
+#define MSM_ION_QSECOM_SIZE	0x600000 /* (6MB) */
 #define MSM_ION_HEAP_NUM	8
 #endif
 #define MSM_ION_MM_FW_SIZE	0x200000 /* (2MB) */
-#define MSM_ION_QSECOM_SIZE	0x300000 /* (3MB) */
 #define MSM_ION_MFC_SIZE	SZ_8K
 #define MSM_ION_AUDIO_SIZE	MSM_PMEM_AUDIO_SIZE
 #else
@@ -1129,23 +1130,31 @@
 #define ISA1200_HAP_LEN_GPIO		PM8921_GPIO_PM_TO_SYS(20)
 #define ISA1200_HAP_CLK			PM8921_GPIO_PM_TO_SYS(44)
 
-static int isa1200_power(int on)
+static int isa1200_clk_enable(bool on)
 {
 	int rc = 0;
 
-	gpio_set_value_cansleep(ISA1200_HAP_CLK, !!on);
+	gpio_set_value_cansleep(ISA1200_HAP_CLK, on);
 
-	if (on)
+	if (on) {
 		rc = pm8xxx_aux_clk_control(CLK_MP3_2, XO_DIV_1, true);
-	else
+		if (rc) {
+			pr_err("%s: unable to write aux clock register(%d)\n",
+				__func__, rc);
+			goto err_gpio_dis;
+		}
+	} else {
 		rc = pm8xxx_aux_clk_control(CLK_MP3_2, XO_DIV_NONE, true);
-
-	if (rc) {
-		pr_err("%s: unable to write aux clock register(%d)\n",
-			__func__, rc);
+		if (rc)
+			pr_err("%s: unable to write aux clock register(%d)\n",
+				__func__, rc);
 	}
 
 	return rc;
+
+err_gpio_dis:
+	gpio_set_value_cansleep(ISA1200_HAP_CLK, !on);
+	return rc;
 }
 
 static int isa1200_dev_setup(bool enable)
@@ -1187,7 +1196,7 @@
 static struct isa1200_platform_data isa1200_1_pdata = {
 	.name = "vibrator",
 	.dev_setup = isa1200_dev_setup,
-	.power_on = isa1200_power,
+	.clk_enable = isa1200_clk_enable,
 	.hap_en_gpio = ISA1200_HAP_EN_GPIO,
 	.hap_len_gpio = ISA1200_HAP_LEN_GPIO,
 	.max_timeout = 15000,
@@ -2279,6 +2288,33 @@
 	.id	= -1,
 };
 
+static int rf4ce_gpio_init(void)
+{
+	if (!machine_is_mpq8064_cdp())
+		return -EINVAL;
+
+	/* CC2533 SRDY Input */
+	if (!gpio_request(SX150X_GPIO(4, 6), "rf4ce_srdy")) {
+		gpio_direction_input(SX150X_GPIO(4, 6));
+		gpio_export(SX150X_GPIO(4, 6), true);
+	}
+
+	/* CC2533 MRDY Output */
+	if (!gpio_request(SX150X_GPIO(4, 5), "rf4ce_mrdy")) {
+		gpio_direction_output(SX150X_GPIO(4, 5), 1);
+		gpio_export(SX150X_GPIO(4, 5), true);
+	}
+
+	/* CC2533 Reset Output */
+	if (!gpio_request(SX150X_GPIO(4, 7), "rf4ce_reset")) {
+		gpio_direction_output(SX150X_GPIO(4, 7), 0);
+		gpio_export(SX150X_GPIO(4, 7), true);
+	}
+
+	return 0;
+}
+late_initcall(rf4ce_gpio_init);
+
 static struct platform_device *mpq_devices[] __initdata = {
 	&msm_device_sps_apq8064,
 	&mpq8064_device_qup_i2c_gsbi5,
diff --git a/arch/arm/mach-msm/board-8930-camera.c b/arch/arm/mach-msm/board-8930-camera.c
index cc5b13c..c9d720c 100644
--- a/arch/arm/mach-msm/board-8930-camera.c
+++ b/arch/arm/mach-msm/board-8930-camera.c
@@ -198,12 +198,9 @@
 #ifdef CONFIG_MSM_CAMERA_FLASH
 static struct msm_camera_sensor_flash_src msm_flash_src = {
 	.flash_sr_type = MSM_CAMERA_FLASH_SRC_EXT,
-	._fsrc.ext_driver_src.led_en = GPIO_CAM_GP_LED_EN1,
-	._fsrc.ext_driver_src.led_flash_en = GPIO_CAM_GP_LED_EN2,
-#if defined(CONFIG_I2C) && (defined(CONFIG_GPIO_SX150X) || \
-			defined(CONFIG_GPIO_SX150X_MODULE))
-	._fsrc.ext_driver_src.expander_info = cam_expander_info,
-#endif
+	._fsrc.ext_driver_src.led_en = VFE_CAMIF_TIMER1_GPIO,
+	._fsrc.ext_driver_src.led_flash_en = VFE_CAMIF_TIMER2_GPIO,
+	._fsrc.ext_driver_src.flash_id = MAM_CAMERA_EXT_LED_FLASH_TPS61310,
 };
 #endif
 
@@ -536,7 +533,8 @@
 };
 
 static struct msm_camera_sensor_flash_data flash_s5k3l1yx = {
-	.flash_type = MSM_CAMERA_FLASH_NONE,
+	.flash_type = MSM_CAMERA_FLASH_LED,
+	.flash_src = &msm_flash_src
 };
 
 static struct msm_camera_csi_lane_params s5k3l1yx_csi_lane_params = {
@@ -585,6 +583,15 @@
 		struct msm_camera_sensor_info *s_info;
 		s_info = &msm_camera_sensor_s5k3l1yx_data;
 		s_info->sensor_platform_info->mount_angle = 0;
+		msm_flash_src._fsrc.ext_driver_src.led_en =
+			GPIO_CAM_GP_LED_EN1;
+		msm_flash_src._fsrc.ext_driver_src.led_flash_en =
+			GPIO_CAM_GP_LED_EN2;
+#if defined(CONFIG_I2C) && (defined(CONFIG_GPIO_SX150X) || \
+	defined(CONFIG_GPIO_SX150X_MODULE))
+		msm_flash_src._fsrc.ext_driver_src.expander_info =
+			cam_expander_info;
+#endif
 	}
 
 	platform_device_register(&msm_camera_server);
@@ -615,11 +622,9 @@
 	I2C_BOARD_INFO("s5k3l1yx", 0x20),
 	.platform_data = &msm_camera_sensor_s5k3l1yx_data,
 	},
-#ifdef CONFIG_MSM_CAMERA_FLASH_SC628A
 	{
-	I2C_BOARD_INFO("sc628a", 0x6E),
+	I2C_BOARD_INFO("tps61310", 0x66),
 	},
-#endif
 };
 
 struct msm_camera_board_info msm8930_camera_board_info = {
diff --git a/arch/arm/mach-msm/board-8930-regulator.c b/arch/arm/mach-msm/board-8930-regulator.c
index fc89a11..2f24c95 100644
--- a/arch/arm/mach-msm/board-8930-regulator.c
+++ b/arch/arm/mach-msm/board-8930-regulator.c
@@ -84,6 +84,9 @@
 	REGULATOR_SUPPLY("VDDIO_CDC",		"sitar-slim"),
 	REGULATOR_SUPPLY("CDC_VDDA_TX",		"sitar-slim"),
 	REGULATOR_SUPPLY("CDC_VDDA_RX",		"sitar-slim"),
+	REGULATOR_SUPPLY("VDDIO_CDC",		"sitar1p1-slim"),
+	REGULATOR_SUPPLY("CDC_VDDA_TX",		"sitar1p1-slim"),
+	REGULATOR_SUPPLY("CDC_VDDA_RX",		"sitar1p1-slim"),
 	REGULATOR_SUPPLY("vddp",		"0-0048"),
 };
 VREG_CONSUMERS(L12) = {
@@ -118,6 +121,8 @@
 	REGULATOR_SUPPLY("8038_l20",		NULL),
 	REGULATOR_SUPPLY("VDDD_CDC_D",		"sitar-slim"),
 	REGULATOR_SUPPLY("CDC_VDDA_A_1P2V",	"sitar-slim"),
+	REGULATOR_SUPPLY("VDDD_CDC_D",		"sitar1p1-slim"),
+	REGULATOR_SUPPLY("CDC_VDDA_A_1P2V",	"sitar1p1-slim"),
 };
 VREG_CONSUMERS(L21) = {
 	REGULATOR_SUPPLY("8038_l21",		NULL),
@@ -159,6 +164,7 @@
 VREG_CONSUMERS(S4) = {
 	REGULATOR_SUPPLY("8038_s4",		NULL),
 	REGULATOR_SUPPLY("CDC_VDD_CP",		"sitar-slim"),
+	REGULATOR_SUPPLY("CDC_VDD_CP",		"sitar1p1-slim"),
 };
 VREG_CONSUMERS(S5) = {
 	REGULATOR_SUPPLY("8038_s5",		NULL),
@@ -446,11 +452,11 @@
 	 *	    ID  name always_on pd min_uV   max_uV   en_t supply
 	 *	system_uA reg_ID
 	 */
-	PM8XXX_NLDO1200(L16, "8038_l16", 0, 1, 1050000, 1050000, 200, "8038_s3",
+	PM8XXX_NLDO1200(L16, "8038_l16", 0, 1, 375000, 1050000, 200, "8038_s3",
 		0, 0),
-	PM8XXX_NLDO1200(L19, "8038_l19", 0, 1, 1050000, 1050000, 200, "8038_s3",
+	PM8XXX_NLDO1200(L19, "8038_l19", 0, 1, 375000, 1050000, 200, "8038_s3",
 		0, 1),
-	PM8XXX_NLDO1200(L27, "8038_l27", 0, 1, 1050000, 1050000, 200, "8038_s3",
+	PM8XXX_NLDO1200(L27, "8038_l27", 0, 1, 375000, 1050000, 200, "8038_s3",
 		0, 2),
 };
 
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 1c4251c..0fff814 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -131,14 +131,15 @@
 #ifdef CONFIG_MSM_IOMMU
 #define MSM_ION_MM_SIZE            0x3800000 /* Need to be multiple of 64K */
 #define MSM_ION_SF_SIZE            0x0
+#define MSM_ION_QSECOM_SIZE	0x780000 /* (7.5MB) */
 #define MSM_ION_HEAP_NUM	7
 #else
 #define MSM_ION_SF_SIZE		MSM_PMEM_SIZE
 #define MSM_ION_MM_SIZE		MSM_PMEM_ADSP_SIZE
+#define MSM_ION_QSECOM_SIZE	0x600000 /* (6MB) */
 #define MSM_ION_HEAP_NUM	8
 #endif
 #define MSM_ION_MM_FW_SIZE	0x200000 /* (2MB) */
-#define MSM_ION_QSECOM_SIZE	0x300000 /* (3MB) */
 #define MSM_ION_MFC_SIZE	SZ_8K
 #define MSM_ION_AUDIO_SIZE	MSM_PMEM_AUDIO_SIZE
 
@@ -797,6 +798,70 @@
 	.platform_data = &sitar_platform_data,
 	},
 };
+
+static struct wcd9xxx_pdata sitar1p1_platform_data = {
+		.slimbus_slave_device = {
+		.name = "sitar-slave",
+		.e_addr = {0, 0, 0x70, 0, 0x17, 2},
+	},
+	.irq = MSM_GPIO_TO_INT(62),
+	.irq_base = SITAR_INTERRUPT_BASE,
+	.num_irqs = NR_WCD9XXX_IRQS,
+	.reset_gpio = 42,
+	.micbias = {
+		.ldoh_v = SITAR_LDOH_2P85_V,
+		.cfilt1_mv = 1800,
+		.cfilt2_mv = 1800,
+		.bias1_cfilt_sel = SITAR_CFILT1_SEL,
+		.bias2_cfilt_sel = SITAR_CFILT2_SEL,
+	},
+	.regulator = {
+	{
+		.name = "CDC_VDD_CP",
+		.min_uV = 1950000,
+		.max_uV = 2200000,
+		.optimum_uA = WCD9XXX_CDC_VDDA_CP_CUR_MAX,
+	},
+	{
+		.name = "CDC_VDDA_RX",
+		.min_uV = 1800000,
+		.max_uV = 1800000,
+		.optimum_uA = WCD9XXX_CDC_VDDA_RX_CUR_MAX,
+	},
+	{
+		.name = "CDC_VDDA_TX",
+		.min_uV = 1800000,
+		.max_uV = 1800000,
+		.optimum_uA = WCD9XXX_CDC_VDDA_TX_CUR_MAX,
+	},
+	{
+		.name = "VDDIO_CDC",
+		.min_uV = 1800000,
+		.max_uV = 1800000,
+		.optimum_uA = WCD9XXX_VDDIO_CDC_CUR_MAX,
+	},
+	{
+		.name = "VDDD_CDC_D",
+		.min_uV = 1200000,
+		.max_uV = 1200000,
+		.optimum_uA = WCD9XXX_VDDD_CDC_D_CUR_MAX,
+	},
+	{
+		.name = "CDC_VDDA_A_1P2V",
+		.min_uV = 1200000,
+		.max_uV = 1200000,
+		.optimum_uA = WCD9XXX_VDDD_CDC_A_CUR_MAX,
+	},
+	},
+};
+
+static struct slim_device msm_slim_sitar1p1 = {
+	.name = "sitar1p1-slim",
+	.e_addr = {0, 1, 0x70, 0, 0x17, 2},
+	.dev = {
+	.platform_data = &sitar1p1_platform_data,
+	},
+};
 #endif
 
 
@@ -806,6 +871,10 @@
 		.bus_num = 1,
 		.slim_slave = &msm_slim_sitar,
 	},
+	{
+		.bus_num = 1,
+		.slim_slave = &msm_slim_sitar1p1,
+	},
 #endif
 	/* add more slimbus slaves as needed */
 };
@@ -2267,6 +2336,8 @@
 	platform_device_register(&msm8930_device_rpm_regulator);
 	msm_clock_init(&msm8930_clock_init_data);
 	msm8960_device_otg.dev.platform_data = &msm_otg_pdata;
+	android_usb_pdata.swfi_latency =
+			msm_rpmrs_levels[0].latency_us;
 	msm8930_init_gpiomux();
 	msm8960_device_qup_spi_gsbi1.dev.platform_data =
 				&msm8960_qup_spi_gsbi1_pdata;
diff --git a/arch/arm/mach-msm/board-8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
index 371bb53..ad9b03d 100644
--- a/arch/arm/mach-msm/board-8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -197,6 +197,7 @@
 	.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,
+	._fsrc.ext_driver_src.flash_id = MAM_CAMERA_EXT_LED_FLASH_SC628A,
 };
 #endif
 
diff --git a/arch/arm/mach-msm/board-8960-regulator.c b/arch/arm/mach-msm/board-8960-regulator.c
index 3923ecf..edb6f03 100644
--- a/arch/arm/mach-msm/board-8960-regulator.c
+++ b/arch/arm/mach-msm/board-8960-regulator.c
@@ -497,11 +497,11 @@
 	 *		ID   name always_on pd min_uV   max_uV   en_t supply
 	 *	system_uA reg_ID
 	 */
-	PM8XXX_NLDO1200(L26, "8921_l26", 0, 1, 1050000, 1050000, 200, "8921_s7",
+	PM8XXX_NLDO1200(L26, "8921_l26", 0, 1, 375000, 1050000, 200, "8921_s7",
 		0, 1),
-	PM8XXX_NLDO1200(L27, "8921_l27", 0, 1, 1050000, 1050000, 200, "8921_s7",
+	PM8XXX_NLDO1200(L27, "8921_l27", 0, 1, 375000, 1050000, 200, "8921_s7",
 		0, 2),
-	PM8XXX_NLDO1200(L28, "8921_l28", 0, 1, 1050000, 1050000, 200, "8921_s7",
+	PM8XXX_NLDO1200(L28, "8921_l28", 0, 1, 375000, 1050000, 200, "8921_s7",
 		0, 3),
 	PM8XXX_LDO(L29,      "8921_l29", 0, 1, 2050000, 2100000, 200, "8921_s8",
 		0, 4),
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index 06affd4..67697d2 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -754,6 +754,7 @@
 	.phy_type		= SNPS_28NM_INTEGRATED_PHY,
 	.vbus_power		= msm_hsusb_vbus_power,
 	.disable_reset_on_disconnect	= true,
+	.enable_lpm_on_dev_suspend	= true,
 };
 
 static struct msm_hsic_peripheral_platform_data msm_hsic_peripheral_pdata = {
diff --git a/arch/arm/mach-msm/board-copper.c b/arch/arm/mach-msm/board-copper.c
index d33f478..c28d172 100644
--- a/arch/arm/mach-msm/board-copper.c
+++ b/arch/arm/mach-msm/board-copper.c
@@ -390,6 +390,40 @@
 	.id	= -1,
 };
 
+#define SHARED_IMEM_TZ_BASE 0xFE805720
+static struct resource tzlog_resources[] = {
+	{
+		.start = SHARED_IMEM_TZ_BASE,
+		.end = SHARED_IMEM_TZ_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+struct platform_device apq_device_tz_log = {
+	.name		= "tz_log",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(tzlog_resources),
+	.resource	= tzlog_resources,
+};
+
+#ifdef CONFIG_HW_RANDOM_MSM
+/* PRNG device */
+#define MSM_PRNG_PHYS  0xF9BFF000
+static struct resource rng_resources = {
+	.flags = IORESOURCE_MEM,
+	.start = MSM_PRNG_PHYS,
+	.end   = MSM_PRNG_PHYS + SZ_512 - 1,
+};
+
+struct platform_device msm8974_device_rng = {
+	.name          = "msm_rng",
+	.id            = 0,
+	.num_resources = 1,
+	.resource      = &rng_resources,
+};
+#endif
+
+
 void __init msm_copper_add_devices(void)
 {
 #ifdef CONFIG_ION_MSM
@@ -399,6 +433,10 @@
 	platform_device_register(&android_usb_device);
 	platform_add_devices(msm_copper_stub_regulator_devices,
 					msm_copper_stub_regulator_devices_len);
+	platform_device_register(&apq_device_tz_log);
+#ifdef CONFIG_HW_RANDOM_MSM
+	platform_device_register(&msm8974_device_rng);
+#endif
 }
 
 /*
diff --git a/arch/arm/mach-msm/clock-7x30.c b/arch/arm/mach-msm/clock-7x30.c
index f51eb5b..fcd6386 100644
--- a/arch/arm/mach-msm/clock-7x30.c
+++ b/arch/arm/mach-msm/clock-7x30.c
@@ -2651,14 +2651,14 @@
 }
 #endif /* CONFIG_DEBUG_FS */
 
-static struct clk_ops measure_clk_ops = {
+static struct clk_ops clk_ops_measure = {
 	.set_parent = measure_clk_set_parent,
 	.get_rate = measure_clk_get_rate,
 };
 
 static struct clk measure_clk = {
 	.dbg_name = "measure_clk",
-	.ops = &measure_clk_ops,
+	.ops = &clk_ops_measure,
 	CLK_INIT(measure_clk),
 };
 
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 1ebf597..93251a4 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -4882,7 +4882,7 @@
 }
 #endif /* CONFIG_DEBUG_FS */
 
-static struct clk_ops measure_clk_ops = {
+static struct clk_ops clk_ops_measure = {
 	.set_parent = measure_clk_set_parent,
 	.get_rate = measure_clk_get_rate,
 };
@@ -4890,7 +4890,7 @@
 static struct measure_clk measure_clk = {
 	.c = {
 		.dbg_name = "measure_clk",
-		.ops = &measure_clk_ops,
+		.ops = &clk_ops_measure,
 		CLK_INIT(measure_clk.c),
 	},
 	.multiplier = 1,
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index 8d2b37a..6972302 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -3445,7 +3445,7 @@
 }
 #endif /* CONFIG_DEBUG_FS */
 
-static struct clk_ops measure_clk_ops = {
+static struct clk_ops clk_ops_measure = {
 	.set_parent = measure_clk_set_parent,
 	.get_rate = measure_clk_get_rate,
 };
@@ -3453,7 +3453,7 @@
 static struct measure_clk measure_clk = {
 	.c = {
 		.dbg_name = "measure_clk",
-		.ops = &measure_clk_ops,
+		.ops = &clk_ops_measure,
 		CLK_INIT(measure_clk.c),
 	},
 	.multiplier = 1,
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index a950e46..66d849a 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -1560,7 +1560,7 @@
 }
 #endif /* CONFIG_DEBUG_FS */
 
-static struct clk_ops measure_clk_ops = {
+static struct clk_ops clk_ops_measure = {
 	.set_parent = measure_clk_set_parent,
 	.get_rate = measure_clk_get_rate,
 };
@@ -1568,7 +1568,7 @@
 static struct measure_clk measure_clk = {
 	.c = {
 		.dbg_name = "measure_clk",
-		.ops = &measure_clk_ops,
+		.ops = &clk_ops_measure,
 		CLK_INIT(measure_clk.c),
 	},
 	.multiplier = 1,
diff --git a/arch/arm/mach-msm/clock-copper.c b/arch/arm/mach-msm/clock-copper.c
index 80403f8..c0245a3 100644
--- a/arch/arm/mach-msm/clock-copper.c
+++ b/arch/arm/mach-msm/clock-copper.c
@@ -4699,7 +4699,7 @@
 }
 #endif /* CONFIG_DEBUG_FS */
 
-static struct clk_ops measure_clk_ops = {
+static struct clk_ops clk_ops_measure = {
 	.set_parent = measure_clk_set_parent,
 	.get_rate = measure_clk_get_rate,
 };
@@ -4707,7 +4707,7 @@
 static struct measure_clk measure_clk = {
 	.c = {
 		.dbg_name = "measure_clk",
-		.ops = &measure_clk_ops,
+		.ops = &clk_ops_measure,
 		CLK_INIT(measure_clk.c),
 	},
 	.multiplier = 1,
@@ -4910,6 +4910,7 @@
 	CLK_LOOKUP("bus_clk",  q6ss_ahb_lfabif_clk.c, "pil-q6v5-lpass"),
 	CLK_LOOKUP("mem_clk", gcc_boot_rom_ahb_clk.c, ""),
 	CLK_LOOKUP("bus_clk",  gcc_mss_cfg_ahb_clk.c, ""),
+	CLK_DUMMY("core_clk", PRNG_CLK , "msm_rng.0", OFF),
 
 	/* TODO: Remove dummy clocks as soon as they become unnecessary */
 	CLK_DUMMY("phy_clk",       NULL,    "msm_otg", OFF),
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index e1b3381..4f365fa 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -627,20 +627,16 @@
 	return HANDOFF_ENABLED_CLK;
 }
 
-struct clk_ops clk_ops_gnd = {
-};
+struct clk_ops clk_ops_empty;
 
 struct fixed_clk gnd_clk = {
 	.c = {
 		.dbg_name = "ground_clk",
-		.ops = &clk_ops_gnd,
+		.ops = &clk_ops_empty,
 		CLK_INIT(gnd_clk.c),
 	},
 };
 
-struct clk_ops clk_ops_measure = {
-};
-
 static int branch_clk_enable(struct clk *clk)
 {
 	unsigned long flags;
diff --git a/arch/arm/mach-msm/clock-local.h b/arch/arm/mach-msm/clock-local.h
index a419d69..ffc7057 100644
--- a/arch/arm/mach-msm/clock-local.h
+++ b/arch/arm/mach-msm/clock-local.h
@@ -77,7 +77,7 @@
  */
 #define DEFINE_CLK_MEASURE(name) \
 	struct clk name = { \
-		.ops = &clk_ops_measure, \
+		.ops = &clk_ops_empty, \
 		.dbg_name = #name, \
 		CLK_INIT(name), \
 	}; \
@@ -264,7 +264,7 @@
 	struct clk c;
 };
 
-extern struct clk_ops clk_ops_measure;
+extern struct clk_ops clk_ops_empty;
 
 static inline struct measure_clk *to_measure_clk(struct clk *clk)
 {
diff --git a/arch/arm/mach-msm/clock-local2.h b/arch/arm/mach-msm/clock-local2.h
index c8d53cb..547e633 100644
--- a/arch/arm/mach-msm/clock-local2.h
+++ b/arch/arm/mach-msm/clock-local2.h
@@ -153,8 +153,6 @@
 	struct clk c;
 };
 
-extern struct clk_ops clk_ops_measure;
-
 static inline struct measure_clk *to_measure_clk(struct clk *clk)
 {
 	return container_of(clk, struct measure_clk, c);
diff --git a/arch/arm/mach-msm/clock-pcom-lookup.c b/arch/arm/mach-msm/clock-pcom-lookup.c
index d842d45..f71d6d5 100644
--- a/arch/arm/mach-msm/clock-pcom-lookup.c
+++ b/arch/arm/mach-msm/clock-pcom-lookup.c
@@ -39,7 +39,7 @@
 	.id = PLL_0,
 	.mode_reg = PLLn_MODE(0),
 	.c = {
-		.ops = &clk_pll_ops,
+		.ops = &clk_ops_pll,
 		.dbg_name = "pll0_clk",
 		CLK_INIT(pll0_clk.c),
 	},
@@ -49,7 +49,7 @@
 	.id = PLL_1,
 	.mode_reg = PLLn_MODE(1),
 	.c = {
-		.ops = &clk_pll_ops,
+		.ops = &clk_ops_pll,
 		.dbg_name = "pll1_clk",
 		CLK_INIT(pll1_clk.c),
 	},
@@ -59,7 +59,7 @@
 	.id = PLL_2,
 	.mode_reg = PLLn_MODE(2),
 	.c = {
-		.ops = &clk_pll_ops,
+		.ops = &clk_ops_pll,
 		.dbg_name = "pll2_clk",
 		CLK_INIT(pll2_clk.c),
 	},
@@ -69,7 +69,7 @@
 	.id = PLL_4,
 	.mode_reg = PLL4_MODE,
 	.c = {
-		.ops = &clk_pll_ops,
+		.ops = &clk_ops_pll,
 		.dbg_name = "pll4_clk",
 		CLK_INIT(pll4_clk.c),
 	},
diff --git a/arch/arm/mach-msm/clock-pll.c b/arch/arm/mach-msm/clock-pll.c
index 3a232c5..ead4fcb 100644
--- a/arch/arm/mach-msm/clock-pll.c
+++ b/arch/arm/mach-msm/clock-pll.c
@@ -427,7 +427,7 @@
 	return HANDOFF_ENABLED_CLK;
 }
 
-struct clk_ops clk_pll_ops = {
+struct clk_ops clk_ops_pll = {
 	.enable = pll_clk_enable,
 	.disable = pll_clk_disable,
 	.handoff = pll_clk_handoff,
diff --git a/arch/arm/mach-msm/clock-pll.h b/arch/arm/mach-msm/clock-pll.h
index 231668f..a8c642f 100644
--- a/arch/arm/mach-msm/clock-pll.h
+++ b/arch/arm/mach-msm/clock-pll.h
@@ -43,7 +43,7 @@
 	void *const __iomem *base;
 };
 
-extern struct clk_ops clk_pll_ops;
+extern struct clk_ops clk_ops_pll;
 
 static inline struct pll_shared_clk *to_pll_shared_clk(struct clk *clk)
 {
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 29a90e4..424edce 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -477,13 +477,24 @@
  */
 struct msm_dai_auxpcm_pdata apq_auxpcm_pdata = {
 	.clk = "pcm_clk",
-	.mode = AFE_PCM_CFG_MODE_PCM,
-	.sync = AFE_PCM_CFG_SYNC_INT,
-	.frame = AFE_PCM_CFG_FRM_256BPF,
-	.quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD,
-	.slot = 0,
-	.data = AFE_PCM_CFG_CDATAOE_MASTER,
-	.pcm_clk_rate = 2048000,
+	.mode_8k = {
+		.mode = AFE_PCM_CFG_MODE_PCM,
+		.sync = AFE_PCM_CFG_SYNC_INT,
+		.frame = AFE_PCM_CFG_FRM_256BPF,
+		.quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD,
+		.slot = 0,
+		.data = AFE_PCM_CFG_CDATAOE_MASTER,
+		.pcm_clk_rate = 2048000,
+	},
+	.mode_16k = {
+		.mode = AFE_PCM_CFG_MODE_PCM,
+		.sync = AFE_PCM_CFG_SYNC_INT,
+		.frame = AFE_PCM_CFG_FRM_256BPF,
+		.quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD,
+		.slot = 0,
+		.data = AFE_PCM_CFG_CDATAOE_MASTER,
+		.pcm_clk_rate = 4096000,
+	}
 };
 
 struct platform_device apq_cpudai_auxpcm_rx = {
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index f1553b6..e474e36 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -1892,13 +1892,24 @@
  */
 struct msm_dai_auxpcm_pdata auxpcm_pdata = {
 	.clk = "pcm_clk",
-	.mode = AFE_PCM_CFG_MODE_PCM,
-	.sync = AFE_PCM_CFG_SYNC_INT,
-	.frame = AFE_PCM_CFG_FRM_256BPF,
-	.quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD,
-	.slot = 0,
-	.data = AFE_PCM_CFG_CDATAOE_MASTER,
-	.pcm_clk_rate = 2048000,
+	.mode_8k = {
+		.mode = AFE_PCM_CFG_MODE_PCM,
+		.sync = AFE_PCM_CFG_SYNC_INT,
+		.frame = AFE_PCM_CFG_FRM_256BPF,
+		.quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD,
+		.slot = 0,
+		.data = AFE_PCM_CFG_CDATAOE_MASTER,
+		.pcm_clk_rate = 2048000,
+	},
+	.mode_16k = {
+		.mode = AFE_PCM_CFG_MODE_PCM,
+		.sync = AFE_PCM_CFG_SYNC_INT,
+		.frame = AFE_PCM_CFG_FRM_256BPF,
+		.quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD,
+		.slot = 0,
+		.data = AFE_PCM_CFG_CDATAOE_MASTER,
+		.pcm_clk_rate = 4096000,
+	}
 };
 
 struct platform_device msm_cpudai_auxpcm_rx = {
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index 8eb1580..76d79a6 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -135,6 +135,8 @@
 	},
 };
 
+#define MSM_HSUSB_RESUME_GPIO	79
+
 static struct resource resources_hsusb[] = {
 	{
 		.start	= MSM9615_HSUSB_PHYS,
@@ -146,6 +148,12 @@
 		.end	= USB1_HS_IRQ,
 		.flags	= IORESOURCE_IRQ,
 	},
+	{
+		.start	= MSM_HSUSB_RESUME_GPIO,
+		.end	= MSM_HSUSB_RESUME_GPIO,
+		.name	= "USB_RESUME",
+		.flags	= IORESOURCE_IO,
+	},
 };
 
 static struct resource resources_usb_bam[] = {
@@ -448,13 +456,24 @@
  */
 struct msm_dai_auxpcm_pdata auxpcm_pdata = {
 	.clk = "pcm_clk",
-	.mode = AFE_PCM_CFG_MODE_PCM,
-	.sync = AFE_PCM_CFG_SYNC_INT,
-	.frame = AFE_PCM_CFG_FRM_256BPF,
-	.quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD,
-	.slot = 0,
-	.data = AFE_PCM_CFG_CDATAOE_MASTER,
-	.pcm_clk_rate = 2048000,
+	.mode_8k = {
+		.mode = AFE_PCM_CFG_MODE_PCM,
+		.sync = AFE_PCM_CFG_SYNC_INT,
+		.frame = AFE_PCM_CFG_FRM_256BPF,
+		.quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD,
+		.slot = 0,
+		.data = AFE_PCM_CFG_CDATAOE_MASTER,
+		.pcm_clk_rate = 2048000,
+	},
+	.mode_16k = {
+		.mode = AFE_PCM_CFG_MODE_PCM,
+		.sync = AFE_PCM_CFG_SYNC_INT,
+		.frame = AFE_PCM_CFG_FRM_256BPF,
+		.quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD,
+		.slot = 0,
+		.data = AFE_PCM_CFG_CDATAOE_MASTER,
+		.pcm_clk_rate = 4096000,
+	}
 };
 
 struct platform_device msm_cpudai_auxpcm_rx = {
diff --git a/arch/arm/mach-msm/devices-iommu.c b/arch/arm/mach-msm/devices-iommu.c
index 9a03afd..2e0253b 100644
--- a/arch/arm/mach-msm/devices-iommu.c
+++ b/arch/arm/mach-msm/devices-iommu.c
@@ -568,26 +568,26 @@
 	.mids = {1, -1}
 };
 
-static struct msm_iommu_ctx_dev mdp_vg1_ctx = {
-	.name = "mdp_vg1",
+static struct msm_iommu_ctx_dev mdp_port0_cb0_ctx = {
+	.name = "mdp_port0_cb0",
 	.num = 0,
 	.mids = {0, 2, -1}
 };
 
-static struct msm_iommu_ctx_dev mdp_rgb1_ctx = {
-	.name = "mdp_rgb1",
+static struct msm_iommu_ctx_dev mdp_port0_cb1_ctx = {
+	.name = "mdp_port0_cb1",
 	.num = 1,
 	.mids = {1, 3, 4, 5, 6, 7, 8, 9, 10, -1}
 };
 
-static struct msm_iommu_ctx_dev mdp_vg2_ctx = {
-	.name = "mdp_vg2",
+static struct msm_iommu_ctx_dev mdp_port1_cb0_ctx = {
+	.name = "mdp_port1_cb0",
 	.num = 0,
 	.mids = {0, 2, -1}
 };
 
-static struct msm_iommu_ctx_dev mdp_rgb2_ctx = {
-	.name = "mdp_rgb2",
+static struct msm_iommu_ctx_dev mdp_port1_cb1_ctx = {
+	.name = "mdp_port1_cb1",
 	.num = 1,
 	.mids = {1, 3, 4, 5, 6, 7, 8, 9, 10, -1}
 };
@@ -732,39 +732,39 @@
 	},
 };
 
-static struct platform_device msm_device_mdp_vg1_ctx = {
+static struct platform_device msm_device_mdp_port0_cb0_ctx = {
 	.name = "msm_iommu_ctx",
 	.id = 4,
 	.dev = {
 		.parent = &msm_device_iommu_mdp0.dev,
-		.platform_data = &mdp_vg1_ctx,
+		.platform_data = &mdp_port0_cb0_ctx,
 	},
 };
 
-static struct platform_device msm_device_mdp_rgb1_ctx = {
+static struct platform_device msm_device_mdp_port0_cb1_ctx = {
 	.name = "msm_iommu_ctx",
 	.id = 5,
 	.dev = {
 		.parent = &msm_device_iommu_mdp0.dev,
-		.platform_data = &mdp_rgb1_ctx,
+		.platform_data = &mdp_port0_cb1_ctx,
 	},
 };
 
-static struct platform_device msm_device_mdp_vg2_ctx = {
+static struct platform_device msm_device_mdp_port1_cb0_ctx = {
 	.name = "msm_iommu_ctx",
 	.id = 6,
 	.dev = {
 		.parent = &msm_device_iommu_mdp1.dev,
-		.platform_data = &mdp_vg2_ctx,
+		.platform_data = &mdp_port1_cb0_ctx,
 	},
 };
 
-static struct platform_device msm_device_mdp_rgb2_ctx = {
+static struct platform_device msm_device_mdp_port1_cb1_ctx = {
 	.name = "msm_iommu_ctx",
 	.id = 7,
 	.dev = {
 		.parent = &msm_device_iommu_mdp1.dev,
-		.platform_data = &mdp_rgb2_ctx,
+		.platform_data = &mdp_port1_cb1_ctx,
 	},
 };
 
@@ -950,10 +950,10 @@
 static struct platform_device *msm_iommu_common_ctx_devs[] = {
 	&msm_device_vpe_src_ctx,
 	&msm_device_vpe_dst_ctx,
-	&msm_device_mdp_vg1_ctx,
-	&msm_device_mdp_rgb1_ctx,
-	&msm_device_mdp_vg2_ctx,
-	&msm_device_mdp_rgb2_ctx,
+	&msm_device_mdp_port0_cb0_ctx,
+	&msm_device_mdp_port0_cb1_ctx,
+	&msm_device_mdp_port1_cb0_ctx,
+	&msm_device_mdp_port1_cb1_ctx,
 	&msm_device_rot_src_ctx,
 	&msm_device_rot_dst_ctx,
 	&msm_device_ijpeg_src_ctx,
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index d01a229..100d99a 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -396,3 +396,7 @@
 extern struct platform_device apq8064_rtb_device;
 
 extern struct platform_device msm8960_cache_dump_device;
+
+extern struct platform_device apq_device_tz_log;
+
+extern struct platform_device msm8974_device_rng;
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 56210d5..17ac3ac 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -125,9 +125,15 @@
 	const struct pmic8058_leds_platform_data *driver_channel;
 };
 
+enum msm_camera_ext_led_flash_id {
+	MAM_CAMERA_EXT_LED_FLASH_SC628A,
+	MAM_CAMERA_EXT_LED_FLASH_TPS61310,
+};
+
 struct msm_camera_sensor_flash_external {
 	uint32_t led_en;
 	uint32_t led_flash_en;
+	enum msm_camera_ext_led_flash_id flash_id;
 	struct msm_cam_expander_info *expander_info;
 };
 
diff --git a/arch/arm/mach-msm/include/mach/iommu_domains.h b/arch/arm/mach-msm/include/mach/iommu_domains.h
index dfb100c..1a3a022 100644
--- a/arch/arm/mach-msm/include/mach/iommu_domains.h
+++ b/arch/arm/mach-msm/include/mach/iommu_domains.h
@@ -56,14 +56,28 @@
 	unsigned int domain_alloc_flags;
 };
 
+
+struct msm_iova_partition {
+	unsigned long start;
+	unsigned long size;
+};
+
+struct msm_iova_layout {
+	struct msm_iova_partition *partitions;
+	int npartitions;
+	const char *client_name;
+	unsigned int domain_flags;
+};
+
 #if defined(CONFIG_MSM_IOMMU)
 
 extern struct iommu_domain *msm_get_iommu_domain(int domain_num);
 
-extern unsigned long msm_allocate_iova_address(unsigned int iommu_domain,
+extern int msm_allocate_iova_address(unsigned int iommu_domain,
 					unsigned int partition_no,
 					unsigned long size,
-					unsigned long align);
+					unsigned long align,
+					unsigned long *iova);
 
 extern void msm_free_iova_address(unsigned long iova,
 			unsigned int iommu_domain,
@@ -97,16 +111,19 @@
 					unsigned int partition_no,
 					unsigned long size);
 
+extern int msm_register_domain(struct msm_iova_layout *layout);
+
 #else
 static inline struct iommu_domain
 	*msm_get_iommu_domain(int subsys_id) { return NULL; }
 
 
 
-static inline unsigned long msm_allocate_iova_address(unsigned int iommu_domain,
+static inline int msm_allocate_iova_address(unsigned int iommu_domain,
 					unsigned int partition_no,
 					unsigned long size,
-					unsigned long align) { return 0; }
+					unsigned long align,
+					unsigned long *iova) { return -ENOMEM; }
 
 static inline void msm_free_iova_address(unsigned long iova,
 			unsigned int iommu_domain,
@@ -153,6 +170,11 @@
 {
 	return;
 }
+
+static inline int msm_register_domain(struct msm_iova_layout *layout)
+{
+	return -ENODEV;
+}
 #endif
 
 #endif
diff --git a/arch/arm/mach-msm/iommu_domains.c b/arch/arm/mach-msm/iommu_domains.c
index 34c16d1..271e252b 100644
--- a/arch/arm/mach-msm/iommu_domains.c
+++ b/arch/arm/mach-msm/iommu_domains.c
@@ -10,27 +10,34 @@
  * GNU General Public License for more details.
  */
 
-#include <mach/msm_subsystem_map.h>
-#include <linux/memory_alloc.h>
+#include <linux/init.h>
 #include <linux/iommu.h>
+#include <linux/memory_alloc.h>
 #include <linux/platform_device.h>
+#include <linux/rbtree.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <asm/sizes.h>
 #include <asm/page.h>
-#include <linux/init.h>
 #include <mach/iommu.h>
 #include <mach/iommu_domains.h>
 #include <mach/socinfo.h>
+#include <mach/msm_subsystem_map.h>
 
 /* dummy 64K for overmapping */
 char iommu_dummy[2*SZ_64K-4];
 
-struct msm_iommu_domain_state {
-	struct msm_iommu_domain *domains;
-	int ndomains;
+struct msm_iova_data {
+	struct rb_node node;
+	struct mem_pool *pools;
+	int npools;
+	struct iommu_domain *domain;
+	int domain_num;
 };
 
-static struct msm_iommu_domain_state domain_state;
+static struct rb_root domain_root;
+DEFINE_MUTEX(domain_mutex);
+static atomic_t domain_nums = ATOMIC_INIT(-1);
 
 int msm_iommu_map_extra(struct iommu_domain *domain,
 				unsigned long start_iova,
@@ -127,9 +134,10 @@
 	if (size & (align - 1))
 		return -EINVAL;
 
-	iova = msm_allocate_iova_address(domain_no, partition_no, size, align);
+	ret = msm_allocate_iova_address(domain_no, partition_no, size, align,
+						&iova);
 
-	if (!iova)
+	if (ret)
 		return -ENOMEM;
 
 	ret = msm_iommu_map_iova_phys(msm_get_iommu_domain(domain_no), iova,
@@ -152,73 +160,210 @@
 	msm_free_iova_address(iova, domain_no, partition_no, size);
 }
 
+static struct msm_iova_data *find_domain(int domain_num)
+{
+	struct rb_root *root = &domain_root;
+	struct rb_node *p = root->rb_node;
+
+	mutex_lock(&domain_mutex);
+
+	while (p) {
+		struct msm_iova_data *node;
+
+		node = rb_entry(p, struct msm_iova_data, node);
+		if (domain_num < node->domain_num)
+			p = p->rb_left;
+		else if (domain_num > domain_num)
+			p = p->rb_right;
+		else {
+			mutex_unlock(&domain_mutex);
+			return node;
+		}
+	}
+	mutex_unlock(&domain_mutex);
+	return NULL;
+}
+
+static int add_domain(struct msm_iova_data *node)
+{
+	struct rb_root *root = &domain_root;
+	struct rb_node **p = &root->rb_node;
+	struct rb_node *parent = NULL;
+
+	mutex_lock(&domain_mutex);
+	while (*p) {
+		struct msm_iova_data *tmp;
+		parent = *p;
+
+		tmp = rb_entry(parent, struct msm_iova_data, node);
+
+		if (node->domain_num < tmp->domain_num)
+			p = &(*p)->rb_left;
+		else if (node->domain_num > tmp->domain_num)
+			p = &(*p)->rb_right;
+		else
+			BUG();
+	}
+	rb_link_node(&node->node, parent, p);
+	rb_insert_color(&node->node, root);
+	mutex_unlock(&domain_mutex);
+	return 0;
+}
+
 struct iommu_domain *msm_get_iommu_domain(int domain_num)
 {
-	if (domain_num >= 0 && domain_num < domain_state.ndomains)
-		return domain_state.domains[domain_num].domain;
+	struct msm_iova_data *data;
+
+	data = find_domain(domain_num);
+
+	if (data)
+		return data->domain;
 	else
 		return NULL;
 }
 
-unsigned long msm_allocate_iova_address(unsigned int iommu_domain,
+int msm_allocate_iova_address(unsigned int iommu_domain,
 					unsigned int partition_no,
 					unsigned long size,
-					unsigned long align)
+					unsigned long align,
+					unsigned long *iova)
 {
+	struct msm_iova_data *data;
 	struct mem_pool *pool;
-	unsigned long iova;
+	unsigned long va;
 
-	if (iommu_domain >= domain_state.ndomains)
-		return 0;
+	data = find_domain(iommu_domain);
 
-	if (partition_no >= domain_state.domains[iommu_domain].npools)
-		return 0;
+	if (!data)
+		return -EINVAL;
 
-	pool = &domain_state.domains[iommu_domain].iova_pools[partition_no];
+	if (partition_no >= data->npools)
+		return -EINVAL;
+
+	pool = &data->pools[partition_no];
 
 	if (!pool->gpool)
-		return 0;
+		return -EINVAL;
 
-	iova = gen_pool_alloc_aligned(pool->gpool, size, ilog2(align));
-	if (iova)
+	va = gen_pool_alloc_aligned(pool->gpool, size, ilog2(align));
+	if (va) {
 		pool->free -= size;
+		/* Offset because genpool can't handle 0 addresses */
+		if (pool->paddr == 0)
+			va -= SZ_4K;
+		*iova = va;
+		return 0;
+	}
 
-	return iova;
+	return -ENOMEM;
 }
 
 void msm_free_iova_address(unsigned long iova,
-			   unsigned int iommu_domain,
-			   unsigned int partition_no,
-			   unsigned long size)
+				unsigned int iommu_domain,
+				unsigned int partition_no,
+				unsigned long size)
 {
+	struct msm_iova_data *data;
 	struct mem_pool *pool;
 
-	if (iommu_domain >= domain_state.ndomains) {
+	data = find_domain(iommu_domain);
+
+	if (!data) {
 		WARN(1, "Invalid domain %d\n", iommu_domain);
 		return;
 	}
 
-	if (partition_no >= domain_state.domains[iommu_domain].npools) {
+	if (partition_no >= data->npools) {
 		WARN(1, "Invalid partition %d for domain %d\n",
 			partition_no, iommu_domain);
 		return;
 	}
 
-	pool = &domain_state.domains[iommu_domain].iova_pools[partition_no];
+	pool = &data->pools[partition_no];
 
 	if (!pool)
 		return;
 
 	pool->free += size;
+
+	/* Offset because genpool can't handle 0 addresses */
+	if (pool->paddr == 0)
+		iova += SZ_4K;
+
 	gen_pool_free(pool->gpool, iova, size);
 }
 
+int msm_register_domain(struct msm_iova_layout *layout)
+{
+	int i;
+	struct msm_iova_data *data;
+	struct mem_pool *pools;
+
+	if (!layout)
+		return -EINVAL;
+
+	data = kmalloc(sizeof(*data), GFP_KERNEL);
+
+	if (!data)
+		return -ENOMEM;
+
+	pools = kmalloc(sizeof(struct mem_pool) * layout->npartitions,
+			GFP_KERNEL);
+
+	if (!pools)
+		goto out;
+
+	for (i = 0; i < layout->npartitions; i++) {
+		if (layout->partitions[i].size == 0)
+			continue;
+
+		pools[i].gpool = gen_pool_create(PAGE_SHIFT, -1);
+
+		if (!pools[i].gpool)
+			continue;
+
+		pools[i].paddr = layout->partitions[i].start;
+		pools[i].size = layout->partitions[i].size;
+
+		/*
+		 * genalloc can't handle a pool starting at address 0.
+		 * For now, solve this problem by offsetting the value
+		 * put in by 4k.
+		 * gen pool address = actual address + 4k
+		 */
+		if (pools[i].paddr == 0)
+			layout->partitions[i].start += SZ_4K;
+
+		if (gen_pool_add(pools[i].gpool,
+			layout->partitions[i].start,
+			layout->partitions[i].size, -1)) {
+			gen_pool_destroy(pools[i].gpool);
+			pools[i].gpool = NULL;
+			continue;
+		}
+	}
+
+	data->pools = pools;
+	data->npools = layout->npartitions;
+	data->domain_num = atomic_inc_return(&domain_nums);
+	data->domain = iommu_domain_alloc(layout->domain_flags);
+
+	add_domain(data);
+
+	return data->domain_num;
+
+out:
+	kfree(data);
+
+	return -EINVAL;
+}
+
 int msm_use_iommu()
 {
 	/*
 	 * If there are no domains, don't bother trying to use the iommu
 	 */
-	return domain_state.ndomains && iommu_found();
+	return iommu_found();
 }
 
 static int __init iommu_domain_probe(struct platform_device *pdev)
@@ -229,64 +374,52 @@
 	if (!p)
 		return -ENODEV;
 
-	domain_state.domains = p->domains;
-	domain_state.ndomains = p->ndomains;
+	for (i = 0; i < p->ndomains; i++) {
+		struct msm_iova_layout l;
+		struct msm_iova_partition *part;
+		struct msm_iommu_domain *domains;
 
-	for (i = 0; i < domain_state.ndomains; i++) {
-		domain_state.domains[i].domain = iommu_domain_alloc(
-							p->domain_alloc_flags);
-		if (!domain_state.domains[i].domain)
+		domains = p->domains;
+		l.npartitions = domains[i].npools;
+		part = kmalloc(
+			sizeof(struct msm_iova_partition) * l.npartitions,
+				GFP_KERNEL);
+
+		if (!part) {
+			pr_info("%s: could not allocate space for domain %d",
+				__func__, i);
 			continue;
-
-		for (j = 0; j < domain_state.domains[i].npools; j++) {
-			struct mem_pool *pool = &domain_state.domains[i].
-							iova_pools[j];
-			mutex_init(&pool->pool_mutex);
-			if (pool->size) {
-				pool->gpool = gen_pool_create(PAGE_SHIFT, -1);
-
-				if (!pool->gpool) {
-					pr_err("%s: could not allocate pool\n",
-						__func__);
-					pr_err("%s: domain %d iova space %d\n",
-						__func__, i, j);
-					continue;
-				}
-
-				if (gen_pool_add(pool->gpool, pool->paddr,
-						pool->size, -1)) {
-					pr_err("%s: could not add memory\n",
-						__func__);
-					pr_err("%s: domain %d pool %d\n",
-						__func__, i, j);
-					gen_pool_destroy(pool->gpool);
-					pool->gpool = NULL;
-					continue;
-				}
-			} else {
-				pool->gpool = NULL;
-			}
 		}
+
+		for (j = 0; j < l.npartitions; j++) {
+			part[j].start = p->domains[i].iova_pools[j].paddr;
+			part[j].size = p->domains[i].iova_pools[j].size;
+		}
+
+		l.partitions = part;
+
+		msm_register_domain(&l);
+
+		kfree(part);
 	}
 
 	for (i = 0; i < p->nnames; i++) {
-		int domain_idx;
 		struct device *ctx = msm_iommu_get_ctx(
 						p->domain_names[i].name);
+		struct iommu_domain *domain;
 
 		if (!ctx)
 			continue;
 
-		domain_idx = p->domain_names[i].domain;
+		domain = msm_get_iommu_domain(p->domain_names[i].domain);
 
-		if (!domain_state.domains[domain_idx].domain)
+		if (!domain)
 			continue;
 
-		if (iommu_attach_device(domain_state.domains[domain_idx].domain,
-					ctx)) {
-			WARN(1, "%s: could not attach domain %d to context %s."
+		if (iommu_attach_device(domain, ctx)) {
+			WARN(1, "%s: could not attach domain %p to context %s."
 				" iommu programming will not occur.\n",
-				__func__, domain_idx,
+				__func__, domain,
 				p->domain_names[i].name);
 			continue;
 		}
diff --git a/arch/arm/mach-msm/peripheral-loader.c b/arch/arm/mach-msm/peripheral-loader.c
index 7208a48..9d0ce0d 100644
--- a/arch/arm/mach-msm/peripheral-loader.c
+++ b/arch/arm/mach-msm/peripheral-loader.c
@@ -578,6 +578,10 @@
 				"invalid proxy voting. ignoring\n"))
 		((struct pil_reset_ops *)desc->ops)->proxy_unvote = NULL;
 
+	WARN(desc->ops->proxy_unvote && !desc->proxy_timeout,
+		"A proxy timeout of 0 ms was specified for %s. Specify one in "
+		"desc->proxy_timeout.\n", desc->name);
+
 	pil = kzalloc(sizeof(*pil), GFP_KERNEL);
 	if (!pil)
 		return ERR_PTR(-ENOMEM);
diff --git a/arch/arm/mach-msm/pil-q6v4.c b/arch/arm/mach-msm/pil-q6v4.c
index 8446e42..131a74b 100644
--- a/arch/arm/mach-msm/pil-q6v4.c
+++ b/arch/arm/mach-msm/pil-q6v4.c
@@ -116,14 +116,9 @@
 	int err;
 	struct q6v4_data *drv = dev_get_drvdata(dev);
 
-	err = regulator_set_voltage(drv->vreg, 1050000, 1050000);
+	err = regulator_set_voltage(drv->vreg, 375000, 375000);
 	if (err) {
-		dev_err(dev, "Failed to set regulator's voltage.\n");
-		return err;
-	}
-	err = regulator_set_optimum_mode(drv->vreg, 100000);
-	if (err < 0) {
-		dev_err(dev, "Failed to set regulator's mode.\n");
+		dev_err(dev, "Failed to set regulator's voltage step.\n");
 		return err;
 	}
 	err = regulator_enable(drv->vreg);
@@ -131,6 +126,18 @@
 		dev_err(dev, "Failed to enable regulator.\n");
 		return err;
 	}
+
+	/*
+	 * Q6 hardware requires a two step voltage ramp-up.
+	 * Delay between the steps.
+	 */
+	udelay(100);
+
+	err = regulator_set_voltage(drv->vreg, 1050000, 1050000);
+	if (err) {
+		dev_err(dev, "Failed to set regulator's voltage.\n");
+		return err;
+	}
 	drv->vreg_enabled = true;
 	return 0;
 }
@@ -411,6 +418,12 @@
 	if (IS_ERR(drv->vreg))
 		return PTR_ERR(drv->vreg);
 
+	ret = regulator_set_optimum_mode(drv->vreg, 100000);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to set regulator's mode.\n");
+		return ret;
+	}
+
 	drv->xo = devm_clk_get(&pdev->dev, "xo");
 	if (IS_ERR(drv->xo))
 		return PTR_ERR(drv->xo);
diff --git a/arch/arm/mach-msm/pil-q6v5-lpass.c b/arch/arm/mach-msm/pil-q6v5-lpass.c
index 8691ac7..311f8a7 100644
--- a/arch/arm/mach-msm/pil-q6v5-lpass.c
+++ b/arch/arm/mach-msm/pil-q6v5-lpass.c
@@ -15,7 +15,6 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
-#include <linux/iopoll.h>
 #include <linux/err.h>
 #include <linux/of.h>
 #include <linux/clk.h>
@@ -23,28 +22,14 @@
 #include "peripheral-loader.h"
 #include "pil-q6v5.h"
 
-/* Register Offsets */
 #define QDSP6SS_RST_EVB			0x010
-#define AXI_HALTREQ			0x0
-#define AXI_HALTACK			0x4
-#define AXI_IDLE			0x8
-
-#define HALT_ACK_TIMEOUT_US		100000
+#define PROXY_TIMEOUT_MS		10000
 
 static int pil_lpass_shutdown(struct pil_desc *pil)
 {
 	struct q6v5_data *drv = dev_get_drvdata(pil->dev);
-	int ret;
-	u32 status;
 
-	writel_relaxed(1, drv->axi_halt_base + AXI_HALTREQ);
-	ret = readl_poll_timeout(drv->axi_halt_base + AXI_HALTACK,
-		status,	status, 50, HALT_ACK_TIMEOUT_US);
-	if (ret)
-		dev_err(pil->dev, "Port halt timeout\n");
-	else if (!readl_relaxed(drv->axi_halt_base + AXI_IDLE))
-		dev_err(pil->dev, "Port halt failed\n");
-	writel_relaxed(0, drv->axi_halt_base + AXI_HALTREQ);
+	pil_q6v5_halt_axi_port(pil, drv->axi_halt_base);
 
 	/*
 	 * If the shutdown function is called before the reset function, clocks
@@ -98,7 +83,6 @@
 {
 	struct q6v5_data *drv;
 	struct pil_desc *desc;
-	struct resource *res;
 
 	desc = pil_q6v5_init(pdev);
 	if (IS_ERR(desc))
@@ -110,12 +94,7 @@
 
 	desc->ops = &pil_lpass_ops;
 	desc->owner = THIS_MODULE;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	drv->axi_halt_base = devm_ioremap(&pdev->dev, res->start,
-					  resource_size(res));
-	if (!drv->axi_halt_base)
-		return -ENOMEM;
+	desc->proxy_timeout = PROXY_TIMEOUT_MS;
 
 	drv->pil = msm_pil_register(desc);
 	if (IS_ERR(drv->pil))
diff --git a/arch/arm/mach-msm/pil-q6v5.c b/arch/arm/mach-msm/pil-q6v5.c
index 3b9d542..6a96990 100644
--- a/arch/arm/mach-msm/pil-q6v5.c
+++ b/arch/arm/mach-msm/pil-q6v5.c
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/elf.h>
 #include <linux/err.h>
 #include <linux/of.h>
@@ -25,11 +26,18 @@
 #include "peripheral-loader.h"
 #include "pil-q6v5.h"
 
-/* Register Offsets */
+/* QDSP6SS Register Offsets */
 #define QDSP6SS_RESET			0x014
 #define QDSP6SS_GFMUX_CTL		0x020
 #define QDSP6SS_PWR_CTL			0x030
 
+/* AXI Halt Register Offsets */
+#define AXI_HALTREQ			0x0
+#define AXI_HALTACK			0x4
+#define AXI_IDLE			0x8
+
+#define HALT_ACK_TIMEOUT_US		100000
+
 /* QDSP6SS_RESET */
 #define Q6SS_CORE_ARES			BIT(1)
 #define Q6SS_ETM_ISDB_ARES		BIT(3)
@@ -68,6 +76,27 @@
 }
 EXPORT_SYMBOL(pil_q6v5_remove_proxy_votes);
 
+void pil_q6v5_halt_axi_port(struct pil_desc *pil, void __iomem *halt_base)
+{
+	int ret;
+	u32 status;
+
+	/* Assert halt request */
+	writel_relaxed(1, halt_base + AXI_HALTREQ);
+
+	/* Wait for halt */
+	ret = readl_poll_timeout(halt_base + AXI_HALTACK,
+		status, status != 0, 50, HALT_ACK_TIMEOUT_US);
+	if (ret)
+		dev_warn(pil->dev, "Port %p halt timeout\n", halt_base);
+	else if (!readl_relaxed(halt_base + AXI_IDLE))
+		dev_warn(pil->dev, "Port %p halt failed\n", halt_base);
+
+	/* Clear halt request (port will remain halted until reset) */
+	writel_relaxed(0, halt_base + AXI_HALTREQ);
+}
+EXPORT_SYMBOL(pil_q6v5_halt_axi_port);
+
 int pil_q6v5_init_image(struct pil_desc *pil, const u8 *metadata,
 			       size_t size)
 {
@@ -210,6 +239,11 @@
 				     resource_size(res));
 	if (!drv->reg_base)
 		return ERR_PTR(-ENOMEM);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	drv->axi_halt_base = devm_ioremap(&pdev->dev, res->start,
+					  resource_size(res));
+	if (!drv->axi_halt_base)
+		return ERR_PTR(-ENOMEM);
 
 	desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
 	if (!desc)
diff --git a/arch/arm/mach-msm/pil-q6v5.h b/arch/arm/mach-msm/pil-q6v5.h
index 5f283da..a9a8d07 100644
--- a/arch/arm/mach-msm/pil-q6v5.h
+++ b/arch/arm/mach-msm/pil-q6v5.h
@@ -35,6 +35,7 @@
 
 int pil_q6v5_make_proxy_votes(struct pil_desc *pil);
 void pil_q6v5_remove_proxy_votes(struct pil_desc *pil);
+void pil_q6v5_halt_axi_port(struct pil_desc *pil, void __iomem *halt_base);
 int pil_q6v5_init_image(struct pil_desc *pil, const u8 *metadata,
 			size_t size);
 void pil_q6v5_shutdown(struct pil_desc *pil);
diff --git a/arch/arm/mach-msm/platsmp-8625.c b/arch/arm/mach-msm/platsmp-8625.c
index 3826b12..91f1133 100644
--- a/arch/arm/mach-msm/platsmp-8625.c
+++ b/arch/arm/mach-msm/platsmp-8625.c
@@ -170,6 +170,8 @@
 {
 	unsigned long timeout;
 
+	preset_lpj = loops_per_jiffy;
+
 	if (cold_boot_done == false) {
 		if (msm8625_release_secondary()) {
 			pr_err("Failed to release secondary core\n");
diff --git a/arch/arm/mach-msm/smd_pkt.c b/arch/arm/mach-msm/smd_pkt.c
index abcd336..b9cba8c 100644
--- a/arch/arm/mach-msm/smd_pkt.c
+++ b/arch/arm/mach-msm/smd_pkt.c
@@ -40,7 +40,7 @@
 #ifdef CONFIG_ARCH_FSM9XXX
 #define NUM_SMD_PKT_PORTS 4
 #else
-#define NUM_SMD_PKT_PORTS 14
+#define NUM_SMD_PKT_PORTS 15
 #endif
 
 #define LOOPBACK_INX (NUM_SMD_PKT_PORTS - 1)
@@ -677,6 +677,7 @@
 	"apr_apps2",
 	"smdcntl8",
 	"smd_sns_adsp",
+	"smd_cxm_qmi",
 	"smd_pkt_loopback",
 };
 
@@ -694,6 +695,7 @@
 	"apr_apps2",
 	"DATA40_CNTL",
 	"SENSOR",
+	"CXM_QMI_PORT_8064",
 	"LOOPBACK",
 };
 
@@ -711,6 +713,7 @@
 	SMD_APPS_QDSP,
 	SMD_APPS_MODEM,
 	SMD_APPS_QDSP,
+	SMD_APPS_WCNSS,
 	SMD_APPS_MODEM,
 };
 #endif
diff --git a/arch/arm/mach-msm/subsystem_map.c b/arch/arm/mach-msm/subsystem_map.c
index 4a1285b..916686f 100644
--- a/arch/arm/mach-msm/subsystem_map.c
+++ b/arch/arm/mach-msm/subsystem_map.c
@@ -375,12 +375,13 @@
 			partition_no = msm_subsystem_get_partition_no(
 								subsys_ids[i]);
 
-			iova_start = msm_allocate_iova_address(domain_no,
+			ret = msm_allocate_iova_address(domain_no,
 						partition_no,
 						map_size,
-						max(min_align, SZ_4K));
+						max(min_align, SZ_4K),
+						&iova_start);
 
-			if (!iova_start) {
+			if (ret) {
 				pr_err("%s: could not allocate iova address\n",
 					__func__);
 				continue;
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
index 404538a..bacba58 100644
--- a/arch/arm/vfp/vfphw.S
+++ b/arch/arm/vfp/vfphw.S
@@ -159,6 +159,22 @@
 	tst	r5, #FPSCR_IXE
 	bne	process_exception
 
+#ifdef CONFIG_ARCH_MSM_KRAIT
+	@ Krait does not set FPEXC.DEX for unsupported short vector instructions
+	mrc     p15, 0, r2, c0, c0, 0
+	ldr     r4, =0xff00fc00
+	and     r4, r2, r4
+	ldr     r2, =0x51000400
+	cmp     r2, r4
+	bne skip
+
+	tst	r5, #FPSCR_LENGTH_MASK
+	beq	skip
+	orr	r1, r1, #FPEXC_DEX
+	b process_exception
+skip:
+#endif
+
 	@ Fall into hand on to next handler - appropriate coproc instr
 	@ not recognised by VFP
 
diff --git a/drivers/char/msm_rotator.c b/drivers/char/msm_rotator.c
index 81a9fa7..6cd1806 100644
--- a/drivers/char/msm_rotator.c
+++ b/drivers/char/msm_rotator.c
@@ -45,6 +45,7 @@
 #define MSM_ROTATOR_START			(MSM_ROTATOR_BASE+0x0030)
 #define MSM_ROTATOR_MAX_BURST_SIZE		(MSM_ROTATOR_BASE+0x0050)
 #define MSM_ROTATOR_HW_VERSION			(MSM_ROTATOR_BASE+0x0070)
+#define MSM_ROTATOR_SW_RESET			(MSM_ROTATOR_BASE+0x0074)
 #define MSM_ROTATOR_SRC_SIZE			(MSM_ROTATOR_BASE+0x1108)
 #define MSM_ROTATOR_SRCP0_ADDR			(MSM_ROTATOR_BASE+0x110c)
 #define MSM_ROTATOR_SRCP1_ADDR			(MSM_ROTATOR_BASE+0x1110)
@@ -906,8 +907,7 @@
 			break;
 
 	if (s == MAX_SESSIONS) {
-		dev_dbg(msm_rotator_dev->device,
-			"%s() : Attempt to use invalid session_id %d\n",
+		pr_err("%s() : Attempt to use invalid session_id %d\n",
 			__func__, s);
 		rc = -EINVAL;
 		goto do_rotate_unlock_mutex;
@@ -1129,11 +1129,13 @@
 		break;
 	default:
 		rc = -EINVAL;
+		pr_err("%s(): Unsupported format %u\n", __func__, format);
 		goto do_rotate_exit;
 	}
 
 	if (rc != 0) {
 		msm_rotator_dev->last_session_idx = INVALID_SESSION;
+		pr_err("%s(): Invalid session error\n", __func__);
 		goto do_rotate_exit;
 	}
 
@@ -1145,8 +1147,11 @@
 	wait_event(msm_rotator_dev->wq,
 		   (msm_rotator_dev->processing == 0));
 	status = (unsigned char)ioread32(MSM_ROTATOR_INTR_STATUS);
-	if ((status & 0x03) != 0x01)
+	if ((status & 0x03) != 0x01) {
+		pr_err("%s(): AXI Bus Error, issuing SW_RESET\n", __func__);
+		iowrite32(0x1, MSM_ROTATOR_SW_RESET);
 		rc = -EFAULT;
+	}
 	iowrite32(0, MSM_ROTATOR_INTR_ENABLE);
 	iowrite32(3, MSM_ROTATOR_INTR_CLEAR);
 
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index bbb13f3..56f986d 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -1674,12 +1674,158 @@
 	return size;
 }
 
+/**
+ * Searches through a clients handles to find if the buffer is owned
+ * by this client. Used for debug output.
+ * @param client pointer to candidate owner of buffer
+ * @param buf pointer to buffer that we are trying to find the owner of
+ * @return 1 if found, 0 otherwise
+ */
+static int ion_debug_find_buffer_owner(const struct ion_client *client,
+				       const struct ion_buffer *buf)
+{
+	struct rb_node *n;
+
+	for (n = rb_first(&client->handles); n; n = rb_next(n)) {
+		const struct ion_handle *handle = rb_entry(n,
+						     const struct ion_handle,
+						     node);
+		if (handle->buffer == buf)
+			return 1;
+	}
+	return 0;
+}
+
+/**
+ * Adds mem_map_data pointer to the tree of mem_map
+ * Used for debug output.
+ * @param mem_map The mem_map tree
+ * @param data The new data to add to the tree
+ */
+static void ion_debug_mem_map_add(struct rb_root *mem_map,
+				  struct mem_map_data *data)
+{
+	struct rb_node **p = &mem_map->rb_node;
+	struct rb_node *parent = NULL;
+	struct mem_map_data *entry;
+
+	while (*p) {
+		parent = *p;
+		entry = rb_entry(parent, struct mem_map_data, node);
+
+		if (data->addr < entry->addr) {
+			p = &(*p)->rb_left;
+		} else if (data->addr > entry->addr) {
+			p = &(*p)->rb_right;
+		} else {
+			pr_err("%s: mem_map_data already found.", __func__);
+			BUG();
+		}
+	}
+	rb_link_node(&data->node, parent, p);
+	rb_insert_color(&data->node, mem_map);
+}
+
+/**
+ * Search for an owner of a buffer by iterating over all ION clients.
+ * @param dev ion device containing pointers to all the clients.
+ * @param buffer pointer to buffer we are trying to find the owner of.
+ * @return name of owner.
+ */
+const char *ion_debug_locate_owner(const struct ion_device *dev,
+					 const struct ion_buffer *buffer)
+{
+	struct rb_node *j;
+	const char *client_name = NULL;
+
+	for (j = rb_first(&dev->user_clients); j && !client_name;
+			  j = rb_next(j)) {
+		struct ion_client *client = rb_entry(j, struct ion_client,
+						     node);
+		if (ion_debug_find_buffer_owner(client, buffer))
+			client_name = client->name;
+	}
+	for (j = rb_first(&dev->kernel_clients); j && !client_name;
+			  j = rb_next(j)) {
+		struct ion_client *client = rb_entry(j, struct ion_client,
+						     node);
+		if (ion_debug_find_buffer_owner(client, buffer))
+			client_name = client->name;
+	}
+	return client_name;
+}
+
+/**
+ * Create a mem_map of the heap.
+ * @param s seq_file to log error message to.
+ * @param heap The heap to create mem_map for.
+ * @param mem_map The mem map to be created.
+ */
+void ion_debug_mem_map_create(struct seq_file *s, struct ion_heap *heap,
+			      struct rb_root *mem_map)
+{
+	struct ion_device *dev = heap->dev;
+	struct rb_node *n;
+
+	for (n = rb_first(&dev->buffers); n; n = rb_next(n)) {
+		struct ion_buffer *buffer =
+				rb_entry(n, struct ion_buffer, node);
+		if (buffer->heap->id == heap->id) {
+			struct mem_map_data *data =
+					kzalloc(sizeof(*data), GFP_KERNEL);
+			if (!data) {
+				seq_printf(s, "ERROR: out of memory. "
+					   "Part of memory map will not be logged\n");
+				break;
+			}
+			data->addr = buffer->priv_phys;
+			data->addr_end = buffer->priv_phys + buffer->size-1;
+			data->size = buffer->size;
+			data->client_name = ion_debug_locate_owner(dev, buffer);
+			ion_debug_mem_map_add(mem_map, data);
+		}
+	}
+}
+
+/**
+ * Free the memory allocated by ion_debug_mem_map_create
+ * @param mem_map The mem map to free.
+ */
+static void ion_debug_mem_map_destroy(struct rb_root *mem_map)
+{
+	if (mem_map) {
+		struct rb_node *n;
+		while ((n = rb_first(mem_map)) != 0) {
+			struct mem_map_data *data =
+					rb_entry(n, struct mem_map_data, node);
+			rb_erase(&data->node, mem_map);
+			kfree(data);
+		}
+	}
+}
+
+/**
+ * Print heap debug information.
+ * @param s seq_file to log message to.
+ * @param heap pointer to heap that we will print debug information for.
+ */
+static void ion_heap_print_debug(struct seq_file *s, struct ion_heap *heap)
+{
+	if (heap->ops->print_debug) {
+		struct rb_root mem_map = RB_ROOT;
+		ion_debug_mem_map_create(s, heap, &mem_map);
+		heap->ops->print_debug(heap, s, &mem_map);
+		ion_debug_mem_map_destroy(&mem_map);
+	}
+}
+
 static int ion_debug_heap_show(struct seq_file *s, void *unused)
 {
 	struct ion_heap *heap = s->private;
 	struct ion_device *dev = heap->dev;
 	struct rb_node *n;
 
+	mutex_lock(&dev->lock);
 	seq_printf(s, "%16.s %16.s %16.s\n", "client", "pid", "size");
 	for (n = rb_first(&dev->user_clients); n; n = rb_next(n)) {
 		struct ion_client *client = rb_entry(n, struct ion_client,
@@ -1703,8 +1849,8 @@
 		seq_printf(s, "%16.s %16u %16x\n", client->name, client->pid,
 			   size);
 	}
-	if (heap->ops->print_debug)
-		heap->ops->print_debug(heap, s);
+	ion_heap_print_debug(s, heap);
+	mutex_unlock(&dev->lock);
 	return 0;
 }
 
diff --git a/drivers/gpu/ion/ion_carveout_heap.c b/drivers/gpu/ion/ion_carveout_heap.c
index ca2380b..710583b 100644
--- a/drivers/gpu/ion/ion_carveout_heap.c
+++ b/drivers/gpu/ion/ion_carveout_heap.c
@@ -251,7 +251,8 @@
 	return 0;
 }
 
-static int ion_carveout_print_debug(struct ion_heap *heap, struct seq_file *s)
+static int ion_carveout_print_debug(struct ion_heap *heap, struct seq_file *s,
+				    const struct rb_root *mem_map)
 {
 	struct ion_carveout_heap *carveout_heap =
 		container_of(heap, struct ion_carveout_heap, heap);
@@ -260,6 +261,44 @@
 		carveout_heap->allocated_bytes);
 	seq_printf(s, "total heap size: %lx\n", carveout_heap->total_size);
 
+	if (mem_map) {
+		unsigned long base = carveout_heap->base;
+		unsigned long size = carveout_heap->total_size;
+		unsigned long end = base+size;
+		unsigned long last_end = base;
+		struct rb_node *n;
+
+		seq_printf(s, "\nMemory Map\n");
+		seq_printf(s, "%16.s %14.s %14.s %14.s\n",
+			   "client", "start address", "end address",
+			   "size (hex)");
+
+		for (n = rb_first(mem_map); n; n = rb_next(n)) {
+			struct mem_map_data *data =
+					rb_entry(n, struct mem_map_data, node);
+			const char *client_name = "(null)";
+
+			if (last_end < data->addr) {
+				seq_printf(s, "%16.s %14lx %14lx %14lu (%lx)\n",
+					   "FREE", last_end, data->addr-1,
+					   data->addr-last_end,
+					   data->addr-last_end);
+			}
+
+			if (data->client_name)
+				client_name = data->client_name;
+
+			seq_printf(s, "%16.s %14lx %14lx %14lu (%lx)\n",
+				   client_name, data->addr,
+				   data->addr_end,
+				   data->size, data->size);
+			last_end = data->addr_end+1;
+		}
+		if (last_end < end) {
+			seq_printf(s, "%16.s %14lx %14lx %14lu (%lx)\n", "FREE",
+				last_end, end-1, end-last_end, end-last_end);
+		}
+	}
 	return 0;
 }
 
@@ -287,13 +326,12 @@
 
 	extra = iova_length - buffer->size;
 
-	data->iova_addr = msm_allocate_iova_address(domain_num, partition_num,
-						data->mapped_size, align);
+	ret = msm_allocate_iova_address(domain_num, partition_num,
+						data->mapped_size, align,
+						&data->iova_addr);
 
-	if (!data->iova_addr) {
-		ret = -ENOMEM;
+	if (ret)
 		goto out;
-	}
 
 	domain = msm_get_iommu_domain(domain_num);
 
diff --git a/drivers/gpu/ion/ion_cp_heap.c b/drivers/gpu/ion/ion_cp_heap.c
index 052b778..fcbf1d4 100644
--- a/drivers/gpu/ion/ion_cp_heap.c
+++ b/drivers/gpu/ion/ion_cp_heap.c
@@ -563,7 +563,8 @@
 	return 0;
 }
 
-static int ion_cp_print_debug(struct ion_heap *heap, struct seq_file *s)
+static int ion_cp_print_debug(struct ion_heap *heap, struct seq_file *s,
+			      const struct rb_root *mem_map)
 {
 	unsigned long total_alloc;
 	unsigned long total_size;
@@ -588,6 +589,45 @@
 	seq_printf(s, "heap protected: %s\n", heap_protected ? "Yes" : "No");
 	seq_printf(s, "reusable: %s\n", cp_heap->reusable  ? "Yes" : "No");
 
+	if (mem_map) {
+		unsigned long base = cp_heap->base;
+		unsigned long size = cp_heap->total_size;
+		unsigned long end = base+size;
+		unsigned long last_end = base;
+		struct rb_node *n;
+
+		seq_printf(s, "\nMemory Map\n");
+		seq_printf(s, "%16.s %14.s %14.s %14.s\n",
+			   "client", "start address", "end address",
+			   "size (hex)");
+
+		for (n = rb_first(mem_map); n; n = rb_next(n)) {
+			struct mem_map_data *data =
+					rb_entry(n, struct mem_map_data, node);
+			const char *client_name = "(null)";
+
+			if (last_end < data->addr) {
+				seq_printf(s, "%16.s %14lx %14lx %14lu (%lx)\n",
+					   "FREE", last_end, data->addr-1,
+					   data->addr-last_end,
+					   data->addr-last_end);
+			}
+
+			if (data->client_name)
+				client_name = data->client_name;
+
+			seq_printf(s, "%16.s %14lx %14lx %14lu (%lx)\n",
+				   client_name, data->addr,
+				   data->addr_end,
+				   data->size, data->size);
+			last_end = data->addr_end+1;
+		}
+		if (last_end < end) {
+			seq_printf(s, "%16.s %14lx %14lx %14lu (%lx)\n", "FREE",
+				last_end, end-1, end-last_end, end-last_end);
+		}
+	}
+
 	return 0;
 }
 
@@ -647,13 +687,15 @@
 	}
 	if (!ret_value && domain) {
 		unsigned long temp_phys = cp_heap->base;
-		unsigned long temp_iova =
-				msm_allocate_iova_address(domain_num, partition,
-						virt_addr_len, SZ_64K);
-		if (!temp_iova) {
+		unsigned long temp_iova;
+
+		ret_value = msm_allocate_iova_address(domain_num, partition,
+						virt_addr_len, SZ_64K,
+						&temp_iova);
+
+		if (ret_value) {
 			pr_err("%s: could not allocate iova from domain %lu, partition %d\n",
 				__func__, domain_num, partition);
-			ret_value = -ENOMEM;
 			goto out;
 		}
 		cp_heap->iommu_iova[domain_num] = temp_iova;
@@ -742,13 +784,12 @@
 
 	extra = iova_length - buffer->size;
 
-	data->iova_addr = msm_allocate_iova_address(domain_num, partition_num,
-						data->mapped_size, align);
+	ret = msm_allocate_iova_address(domain_num, partition_num,
+						data->mapped_size, align,
+						&data->iova_addr);
 
-	if (!data->iova_addr) {
-		ret = -ENOMEM;
+	if (ret)
 		goto out;
-	}
 
 	domain = msm_get_iommu_domain(domain_num);
 
@@ -918,6 +959,14 @@
 	cp_heap = NULL;
 }
 
+void ion_cp_heap_get_base(struct ion_heap *heap, unsigned long *base,
+		unsigned long *size) \
+{
+	struct ion_cp_heap *cp_heap =
+	     container_of(heap, struct  ion_cp_heap, heap);
+	*base = cp_heap->base;
+	*size = cp_heap->total_size;
+}
 
 /*  SCM related code for locking down memory for content protection */
 
diff --git a/drivers/gpu/ion/ion_iommu_heap.c b/drivers/gpu/ion/ion_iommu_heap.c
index 312ca42..70bdc7f 100644
--- a/drivers/gpu/ion/ion_iommu_heap.c
+++ b/drivers/gpu/ion/ion_iommu_heap.c
@@ -190,13 +190,12 @@
 	data->mapped_size = iova_length;
 	extra = iova_length - buffer->size;
 
-	data->iova_addr = msm_allocate_iova_address(domain_num, partition_num,
-						data->mapped_size, align);
+	ret = msm_allocate_iova_address(domain_num, partition_num,
+						data->mapped_size, align,
+						&data->iova_addr);
 
-	if (!data->iova_addr) {
-		ret = -ENOMEM;
+	if (!data->iova_addr)
 		goto out;
-	}
 
 	domain = msm_get_iommu_domain(domain_num);
 
diff --git a/drivers/gpu/ion/ion_priv.h b/drivers/gpu/ion/ion_priv.h
index 98e11cf..00ce33f 100644
--- a/drivers/gpu/ion/ion_priv.h
+++ b/drivers/gpu/ion/ion_priv.h
@@ -155,7 +155,8 @@
 				unsigned long iova_length,
 				unsigned long flags);
 	void (*unmap_iommu)(struct ion_iommu_map *data);
-	int (*print_debug)(struct ion_heap *heap, struct seq_file *s);
+	int (*print_debug)(struct ion_heap *heap, struct seq_file *s,
+			   const struct rb_root *mem_map);
 	int (*secure_heap)(struct ion_heap *heap);
 	int (*unsecure_heap)(struct ion_heap *heap);
 };
@@ -185,7 +186,22 @@
 	const char *name;
 };
 
-
+/**
+ * struct mem_map_data - represents information about the memory map for a heap
+ * @node:		rb node used to store in the tree of mem_map_data
+ * @addr:		start address of memory region.
+ * @addr:		end address of memory region.
+ * @size:		size of memory region
+ * @client_name:		name of the client who owns this buffer.
+ *
+ */
+struct mem_map_data {
+	struct rb_node node;
+	unsigned long addr;
+	unsigned long addr_end;
+	unsigned long size;
+	const char *client_name;
+};
 
 #define iommu_map_domain(__m)		((__m)->domain_info[1])
 #define iommu_map_partition(__m)	((__m)->domain_info[0])
@@ -298,4 +314,9 @@
 			void *uaddr, unsigned long offset, unsigned long len,
 			unsigned int cmd);
 
+void ion_cp_heap_get_base(struct ion_heap *heap, unsigned long *base,
+			unsigned long *size);
+
+void ion_mem_map_show(struct ion_heap *heap);
+
 #endif /* _ION_PRIV_H */
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
index ed9ae27..26c6632 100644
--- a/drivers/gpu/ion/ion_system_heap.c
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -204,7 +204,8 @@
 	return 0;
 }
 
-static int ion_system_print_debug(struct ion_heap *heap, struct seq_file *s)
+static int ion_system_print_debug(struct ion_heap *heap, struct seq_file *s,
+				  const struct rb_root *unused)
 {
 	seq_printf(s, "total bytes currently allocated: %lx\n",
 			(unsigned long) atomic_read(&system_heap_allocated));
@@ -240,13 +241,12 @@
 	data->mapped_size = iova_length;
 	extra = iova_length - buffer->size;
 
-	data->iova_addr = msm_allocate_iova_address(domain_num, partition_num,
-						data->mapped_size, align);
+	ret = msm_allocate_iova_address(domain_num, partition_num,
+						data->mapped_size, align,
+						&data->iova_addr);
 
-	if (!data->iova_addr) {
-		ret = -ENOMEM;
+	if (ret)
 		goto out;
-	}
 
 	domain = msm_get_iommu_domain(domain_num);
 
@@ -423,7 +423,8 @@
 }
 
 static int ion_system_contig_print_debug(struct ion_heap *heap,
-					 struct seq_file *s)
+					 struct seq_file *s,
+					 const struct rb_root *unused)
 {
 	seq_printf(s, "total bytes currently allocated: %lx\n",
 		(unsigned long) atomic_read(&system_contig_heap_allocated));
@@ -458,13 +459,12 @@
 	data->mapped_size = iova_length;
 	extra = iova_length - buffer->size;
 
-	data->iova_addr = msm_allocate_iova_address(domain_num, partition_num,
-						data->mapped_size, align);
+	ret = msm_allocate_iova_address(domain_num, partition_num,
+						data->mapped_size, align,
+						&data->iova_addr);
 
-	if (!data->iova_addr) {
-		ret = -ENOMEM;
+	if (ret)
 		goto out;
-	}
 
 	domain = msm_get_iommu_domain(domain_num);
 
diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c
index ae846da..8a132df 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -830,9 +830,6 @@
 	*cmds++ = 0x00010000;
 
 	if (adreno_is_a22x(adreno_dev)) {
-		*cmds++ = cp_type3_packet(CP_SET_DRAW_INIT_FLAGS, 1);
-		*cmds++ = 0;
-
 		*cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
 		*cmds++ = CP_REG(REG_A220_RB_LRZ_VSC_CONTROL);
 		*cmds++ = 0x0000000;
@@ -1052,9 +1049,6 @@
 	*cmds++ = 0x00010000;
 
 	if (adreno_is_a22x(adreno_dev)) {
-		*cmds++ = cp_type3_packet(CP_SET_DRAW_INIT_FLAGS, 1);
-		*cmds++ = 0;
-
 		*cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
 		*cmds++ = CP_REG(REG_A220_RB_LRZ_VSC_CONTROL);
 		*cmds++ = 0x0000000;
diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h
index da3e4b2..7f38b72 100644
--- a/drivers/gpu/msm/kgsl.h
+++ b/drivers/gpu/msm/kgsl.h
@@ -122,6 +122,8 @@
 	int (*map_kernel_mem)(struct kgsl_memdesc *);
 };
 
+#define KGSL_MEMDESC_GUARD_PAGE BIT(0)
+
 /* shared memory allocation */
 struct kgsl_memdesc {
 	struct kgsl_pagetable *pagetable;
@@ -133,6 +135,7 @@
 	struct scatterlist *sg;
 	unsigned int sglen;
 	struct kgsl_memdesc_ops *ops;
+	int flags;
 };
 
 /* List of different memory entry types */
diff --git a/drivers/gpu/msm/kgsl_gpummu.c b/drivers/gpu/msm/kgsl_gpummu.c
index ab47f40..8f61ab6 100644
--- a/drivers/gpu/msm/kgsl_gpummu.c
+++ b/drivers/gpu/msm/kgsl_gpummu.c
@@ -591,7 +591,7 @@
 {
 	unsigned int numpages;
 	unsigned int pte, ptefirst, ptelast, superpte;
-	unsigned int range = memdesc->size;
+	unsigned int range = kgsl_sg_size(memdesc->sg, memdesc->sglen);
 	struct kgsl_gpummu_pt *gpummu_pt = mmu_specific_pt;
 
 	/* All GPU addresses as assigned are page aligned, but some
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index fb65565..1f1571b 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -654,7 +654,7 @@
 		struct kgsl_memdesc *memdesc)
 {
 	int ret;
-	unsigned int range = memdesc->size;
+	unsigned int range = kgsl_sg_size(memdesc->sg, memdesc->sglen);
 	struct kgsl_iommu_pt *iommu_pt = mmu_specific_pt;
 
 	/* All GPU addresses as assigned are page aligned, but some
@@ -684,6 +684,7 @@
 	int ret;
 	unsigned int iommu_virt_addr;
 	struct kgsl_iommu_pt *iommu_pt = mmu_specific_pt;
+	int size = kgsl_sg_size(memdesc->sg, memdesc->sglen);
 
 	BUG_ON(NULL == iommu_pt);
 
@@ -691,11 +692,11 @@
 	iommu_virt_addr = memdesc->gpuaddr;
 
 	ret = iommu_map_range(iommu_pt->domain, iommu_virt_addr, memdesc->sg,
-				memdesc->size, (IOMMU_READ | IOMMU_WRITE));
+				size, (IOMMU_READ | IOMMU_WRITE));
 	if (ret) {
 		KGSL_CORE_ERR("iommu_map_range(%p, %x, %p, %d, %d) "
 				"failed with err: %d\n", iommu_pt->domain,
-				iommu_virt_addr, memdesc->sg, memdesc->size,
+				iommu_virt_addr, memdesc->sg, size,
 				(IOMMU_READ | IOMMU_WRITE), ret);
 		return ret;
 	}
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
index b882807..9092b96 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -595,6 +595,7 @@
 {
 	int ret;
 	struct gen_pool *pool;
+	int size;
 
 	if (kgsl_mmu_type == KGSL_MMU_TYPE_NONE) {
 		if (memdesc->sglen == 1) {
@@ -614,13 +615,15 @@
 		}
 	}
 
+	size = kgsl_sg_size(memdesc->sg, memdesc->sglen);
+
 	/* Allocate from kgsl pool if it exists for global mappings */
 	pool = _get_pool(pagetable, memdesc->priv);
 
-	memdesc->gpuaddr = gen_pool_alloc(pool, memdesc->size);
+	memdesc->gpuaddr = gen_pool_alloc(pool, size);
 	if (memdesc->gpuaddr == 0) {
 		KGSL_CORE_ERR("gen_pool_alloc(%d) failed from pool: %s\n",
-			memdesc->size,
+			size,
 			(pool == pagetable->kgsl_pool) ?
 			"kgsl_pool" : "general_pool");
 		KGSL_CORE_ERR(" [%d] allocated=%d, entries=%d\n",
@@ -644,7 +647,7 @@
 	KGSL_STATS_ADD(1, pagetable->stats.entries,
 		       pagetable->stats.max_entries);
 
-	KGSL_STATS_ADD(memdesc->size, pagetable->stats.mapped,
+	KGSL_STATS_ADD(size, pagetable->stats.mapped,
 		       pagetable->stats.max_mapped);
 
 	spin_unlock(&pagetable->lock);
@@ -653,7 +656,7 @@
 
 err_free_gpuaddr:
 	spin_unlock(&pagetable->lock);
-	gen_pool_free(pool, memdesc->gpuaddr, memdesc->size);
+	gen_pool_free(pool, memdesc->gpuaddr, size);
 	memdesc->gpuaddr = 0;
 	return ret;
 }
@@ -664,6 +667,8 @@
 		struct kgsl_memdesc *memdesc)
 {
 	struct gen_pool *pool;
+	int size;
+
 	if (memdesc->size == 0 || memdesc->gpuaddr == 0)
 		return 0;
 
@@ -671,6 +676,9 @@
 		memdesc->gpuaddr = 0;
 		return 0;
 	}
+
+	size = kgsl_sg_size(memdesc->sg, memdesc->sglen);
+
 	if (KGSL_MMU_TYPE_IOMMU != kgsl_mmu_get_mmutype())
 		spin_lock(&pagetable->lock);
 	pagetable->pt_ops->mmu_unmap(pagetable->priv, memdesc);
@@ -678,12 +686,12 @@
 		spin_lock(&pagetable->lock);
 	/* Remove the statistics */
 	pagetable->stats.entries--;
-	pagetable->stats.mapped -= memdesc->size;
+	pagetable->stats.mapped -= size;
 
 	spin_unlock(&pagetable->lock);
 
 	pool = _get_pool(pagetable, memdesc->priv);
-	gen_pool_free(pool, memdesc->gpuaddr, memdesc->size);
+	gen_pool_free(pool, memdesc->gpuaddr, size);
 
 	/*
 	 * Don't clear the gpuaddr on global mappings because they
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index a51f29f..8829102 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -63,6 +63,13 @@
 }
 
 
+/*
+ * One page allocation for a guard region to protect against over-zealous
+ * GPU pre-fetch
+ */
+
+static struct page *kgsl_guard_page;
+
 /**
  * Given a kobj, find the process structure attached to it
  */
@@ -333,13 +340,20 @@
 {
 	int i = 0;
 	struct scatterlist *sg;
+	int sglen = memdesc->sglen;
+
+	/* Don't free the guard page if it was used */
+	if (memdesc->flags & KGSL_MEMDESC_GUARD_PAGE)
+		sglen--;
+
 	kgsl_driver.stats.page_alloc -= memdesc->size;
+
 	if (memdesc->hostptr) {
 		vunmap(memdesc->hostptr);
 		kgsl_driver.stats.vmalloc -= memdesc->size;
 	}
 	if (memdesc->sg)
-		for_each_sg(memdesc->sg, sg, memdesc->sglen, i)
+		for_each_sg(memdesc->sg, sg, sglen, i)
 			__free_page(sg_page(sg));
 }
 
@@ -362,17 +376,23 @@
 		pgprot_t page_prot = pgprot_writecombine(PAGE_KERNEL);
 		struct page **pages = NULL;
 		struct scatterlist *sg;
+		int sglen = memdesc->sglen;
 		int i;
+
+		/* Don't map the guard page if it exists */
+		if (memdesc->flags & KGSL_MEMDESC_GUARD_PAGE)
+			sglen--;
+
 		/* create a list of pages to call vmap */
-		pages = vmalloc(memdesc->sglen * sizeof(struct page *));
+		pages = vmalloc(sglen * sizeof(struct page *));
 		if (!pages) {
 			KGSL_CORE_ERR("vmalloc(%d) failed\n",
-				memdesc->sglen * sizeof(struct page *));
+				sglen * sizeof(struct page *));
 			return -ENOMEM;
 		}
-		for_each_sg(memdesc->sg, sg, memdesc->sglen, i)
+		for_each_sg(memdesc->sg, sg, sglen, i)
 			pages[i] = sg_page(sg);
-		memdesc->hostptr = vmap(pages, memdesc->sglen,
+		memdesc->hostptr = vmap(pages, sglen,
 					VM_IOREMAP, page_prot);
 		KGSL_STATS_ADD(memdesc->size, kgsl_driver.stats.vmalloc,
 				kgsl_driver.stats.vmalloc_max);
@@ -471,6 +491,14 @@
 	int sglen = PAGE_ALIGN(size) / PAGE_SIZE;
 	int i;
 
+	/*
+	 * Add guard page to the end of the allocation when the
+	 * IOMMU is in use.
+	 */
+
+	if (kgsl_mmu_get_mmutype() == KGSL_MMU_TYPE_IOMMU)
+		sglen++;
+
 	memdesc->size = size;
 	memdesc->pagetable = pagetable;
 	memdesc->priv = KGSL_MEMFLAGS_CACHED;
@@ -490,7 +518,7 @@
 	memdesc->sglen = sglen;
 	sg_init_table(memdesc->sg, sglen);
 
-	for (i = 0; i < memdesc->sglen; i++) {
+	for (i = 0; i < PAGE_ALIGN(size) / PAGE_SIZE; i++) {
 		struct page *page = alloc_page(GFP_KERNEL | __GFP_ZERO |
 						__GFP_HIGHMEM);
 		if (!page) {
@@ -501,6 +529,22 @@
 		flush_dcache_page(page);
 		sg_set_page(&memdesc->sg[i], page, PAGE_SIZE, 0);
 	}
+
+	/* ADd the guard page to the end of the sglist */
+
+	if (kgsl_mmu_get_mmutype() == KGSL_MMU_TYPE_IOMMU) {
+		if (kgsl_guard_page == NULL)
+			kgsl_guard_page = alloc_page(GFP_KERNEL | __GFP_ZERO |
+				__GFP_HIGHMEM);
+
+		if (kgsl_guard_page != NULL) {
+			sg_set_page(&memdesc->sg[sglen - 1], kgsl_guard_page,
+				PAGE_SIZE, 0);
+			memdesc->flags |= KGSL_MEMDESC_GUARD_PAGE;
+		} else
+			memdesc->sglen--;
+	}
+
 	outer_cache_range_op_sg(memdesc->sg, memdesc->sglen,
 				KGSL_CACHE_OP_FLUSH);
 
diff --git a/drivers/gpu/msm/kgsl_sharedmem.h b/drivers/gpu/msm/kgsl_sharedmem.h
index fb8dd95..034ade4 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.h
+++ b/drivers/gpu/msm/kgsl_sharedmem.h
@@ -157,4 +157,15 @@
 	return ret;
 }
 
+static inline int kgsl_sg_size(struct scatterlist *sg, int sglen)
+{
+	int i, size = 0;
+	struct scatterlist *s;
+
+	for_each_sg(sg, s, sglen, i) {
+		size += s->length;
+	}
+
+	return size;
+}
 #endif /* __KGSL_SHAREDMEM_H */
diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h
index ff0c9d8..a57ad44 100644
--- a/drivers/media/dvb/dvb-core/demux.h
+++ b/drivers/media/dvb/dvb-core/demux.h
@@ -136,6 +136,8 @@
 		    struct timespec timeout);
 	int (*start_filtering) (struct dmx_ts_feed* feed);
 	int (*stop_filtering) (struct dmx_ts_feed* feed);
+	int (*set_indexing_params) (struct dmx_ts_feed *feed,
+				struct dmx_indexing_video_params *params);
 };
 
 /*--------------------------------------------------------------------------*/
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index ed3f731..1d310f2 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -1186,6 +1186,24 @@
 		return ret;
 	}
 
+	/* Support indexing for video PES */
+	if ((para->pes_type == DMX_PES_VIDEO0) ||
+	    (para->pes_type == DMX_PES_VIDEO1) ||
+	    (para->pes_type == DMX_PES_VIDEO2) ||
+	    (para->pes_type == DMX_PES_VIDEO3)) {
+
+		if (tsfeed->set_indexing_params) {
+			ret = tsfeed->set_indexing_params(tsfeed,
+							&para->video_params);
+
+			if (ret < 0) {
+				dmxdev->demux->release_ts_feed(dmxdev->demux,
+								tsfeed);
+				return ret;
+			}
+		}
+	}
+
 	ret = tsfeed->start_filtering(tsfeed);
 	if (ret < 0) {
 		dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);
@@ -1464,6 +1482,23 @@
 	if (params->pes_type > DMX_PES_OTHER || params->pes_type < 0)
 		return -EINVAL;
 
+	if (params->flags & DMX_ENABLE_INDEXING) {
+		if (!(dmxdev->capabilities & DMXDEV_CAP_INDEXING))
+			return -EINVAL;
+
+		/* can do indexing only on video PES */
+		if ((params->pes_type != DMX_PES_VIDEO0) &&
+		    (params->pes_type != DMX_PES_VIDEO1) &&
+		    (params->pes_type != DMX_PES_VIDEO2) &&
+		    (params->pes_type != DMX_PES_VIDEO3))
+			return -EINVAL;
+
+		/* can do indexing only when recording */
+		if ((params->output != DMX_OUT_TS_TAP) &&
+		    (params->output != DMX_OUT_TSDEMUX_TAP))
+			return -EINVAL;
+	}
+
 	dmxdevfilter->type = DMXDEV_TYPE_PES;
 	memcpy(&dmxdevfilter->params, params,
 	       sizeof(struct dmx_pes_filter_params));
diff --git a/drivers/media/dvb/dvb-core/dmxdev.h b/drivers/media/dvb/dvb-core/dmxdev.h
index 82f8f6d..4c52e84 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.h
+++ b/drivers/media/dvb/dvb-core/dmxdev.h
@@ -108,6 +108,7 @@
 #define DMXDEV_CAP_DUPLEX			0x1
 #define DMXDEV_CAP_PULL_MODE		0x2
 #define DMXDEV_CAP_PCR_EXTRACTION	0x4
+#define DMXDEV_CAP_INDEXING		0x8
 
 	enum dmx_playback_mode_t playback_mode;
 	dmx_source_t source;
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index 966b48d..0ff2a55 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -1027,6 +1027,18 @@
 	return ret;
 }
 
+static int dmx_ts_set_indexing_params(
+	struct dmx_ts_feed *ts_feed,
+	struct dmx_indexing_video_params *params)
+{
+	struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
+
+	memcpy(&feed->indexing_params, params,
+			sizeof(struct dmx_indexing_video_params));
+
+	return 0;
+}
+
 static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx,
 				   struct dmx_ts_feed **ts_feed,
 				   dmx_ts_cb callback)
@@ -1048,6 +1060,8 @@
 	feed->pid = 0xffff;
 	feed->peslen = 0xfffa;
 	feed->buffer = NULL;
+	memset(&feed->indexing_params, 0,
+			sizeof(struct dmx_indexing_video_params));
 
 	/* default behaviour - pass first PES data even if it is
 	 * partial PES data from previous PES that we didn't receive its header.
@@ -1063,6 +1077,7 @@
 	(*ts_feed)->start_filtering = dmx_ts_feed_start_filtering;
 	(*ts_feed)->stop_filtering = dmx_ts_feed_stop_filtering;
 	(*ts_feed)->set = dmx_ts_feed_set;
+	(*ts_feed)->set_indexing_params = dmx_ts_set_indexing_params;
 
 	if (!(feed->filter = dvb_dmx_filter_alloc(demux))) {
 		feed->state = DMX_STATE_FREE;
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h
index 297f3df..17f4960 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.h
+++ b/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -95,10 +95,12 @@
 	int cc;
 	int pusi_seen;		/* prevents feeding of garbage from previous section */
 
-	u16 peslen;
+	u32 peslen;
 
 	struct list_head list_head;
 	unsigned int index;	/* a unique index for each feed (can be used as hardware pid filter index) */
+
+	struct dmx_indexing_video_params indexing_params;
 };
 
 struct dvb_demux {
diff --git a/drivers/media/video/msm/Kconfig b/drivers/media/video/msm/Kconfig
index b602c37..ab4a6f2 100644
--- a/drivers/media/video/msm/Kconfig
+++ b/drivers/media/video/msm/Kconfig
@@ -177,6 +177,15 @@
 	  supports spotlight and flash light modes with
 	  differrent current levels.
 
+config MSM_CAMERA_FLASH_TPS61310
+	bool "Qualcomm MSM camera tps61310 flash support"
+	depends on MSM_CAMERA
+	default n
+	---help---
+	  Enable support for LED flash for msm camera.
+	  It is a Texas Instruments multiple LED Flash
+	  for camera flash and video light applications.
+
 config IMX072
 	bool "Sensor imx072 (Sony 5M)"
 	default n
diff --git a/drivers/media/video/msm/flash.c b/drivers/media/video/msm/flash.c
index 0d17e13..ba86d8c 100644
--- a/drivers/media/video/msm/flash.c
+++ b/drivers/media/video/msm/flash.c
@@ -1,5 +1,5 @@
 
-/* 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
@@ -30,54 +30,54 @@
 	MSM_CAM_FLASH_ON,
 };
 
-#if defined CONFIG_MSM_CAMERA_FLASH_SC628A
 static struct i2c_client *sc628a_client;
 
-static const struct i2c_device_id sc628a_i2c_id[] = {
-	{"sc628a", 0},
-	{ }
-};
-
-static int32_t sc628a_i2c_txdata(unsigned short saddr,
+static int32_t flash_i2c_txdata(struct i2c_client *client,
 		unsigned char *txdata, int length)
 {
 	struct i2c_msg msg[] = {
 		{
-			.addr = saddr,
+			.addr = client->addr >> 1,
 			.flags = 0,
 			.len = length,
 			.buf = txdata,
 		},
 	};
-	if (i2c_transfer(sc628a_client->adapter, msg, 1) < 0) {
-		CDBG("sc628a_i2c_txdata faild 0x%x\n", saddr);
+	if (i2c_transfer(client->adapter, msg, 1) < 0) {
+		CDBG("flash_i2c_txdata faild 0x%x\n", client->addr >> 1);
 		return -EIO;
 	}
 
 	return 0;
 }
 
-static int32_t sc628a_i2c_write_b_flash(uint8_t waddr, uint8_t bdata)
+static int32_t flash_i2c_write_b(struct i2c_client *client,
+	uint8_t baddr, uint8_t bdata)
 {
 	int32_t rc = -EFAULT;
 	unsigned char buf[2];
-	if (!sc628a_client)
+	if (!client)
 		return  -ENOTSUPP;
 
 	memset(buf, 0, sizeof(buf));
-	buf[0] = waddr;
+	buf[0] = baddr;
 	buf[1] = bdata;
 
-	rc = sc628a_i2c_txdata(sc628a_client->addr>>1, buf, 2);
+	rc = flash_i2c_txdata(client, buf, 2);
 	if (rc < 0) {
 		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
-				waddr, bdata);
+				baddr, bdata);
 	}
 	usleep_range(4000, 5000);
 
 	return rc;
 }
 
+static const struct i2c_device_id sc628a_i2c_id[] = {
+	{"sc628a", 0},
+	{ }
+};
+
 static int sc628a_i2c_probe(struct i2c_client *client,
 		const struct i2c_device_id *id)
 {
@@ -91,7 +91,7 @@
 
 	sc628a_client = client;
 
-	CDBG("sc628a_probe successed! rc = %d\n", rc);
+	CDBG("sc628a_probe success rc = %d\n", rc);
 	return 0;
 
 probe_failure:
@@ -107,7 +107,49 @@
 		.name = "sc628a",
 	},
 };
-#endif
+
+static struct i2c_client *tps61310_client;
+
+static const struct i2c_device_id tps61310_i2c_id[] = {
+	{"tps61310", 0},
+	{ }
+};
+
+static int tps61310_i2c_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	int rc = 0;
+	CDBG("%s enter\n", __func__);
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		pr_err("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+
+	tps61310_client = client;
+
+	rc = flash_i2c_write_b(tps61310_client, 0x01, 0x00);
+	if (rc < 0) {
+		tps61310_client = NULL;
+		goto probe_failure;
+	}
+
+	CDBG("%s success! rc = %d\n", __func__, rc);
+	return 0;
+
+probe_failure:
+	pr_err("%s failed! rc = %d\n", __func__, rc);
+	return rc;
+}
+
+static struct i2c_driver tps61310_i2c_driver = {
+	.id_table = tps61310_i2c_id,
+	.probe  = tps61310_i2c_probe,
+	.remove = __exit_p(tps61310_i2c_remove),
+	.driver = {
+		.name = "tps61310",
+	},
+};
 
 static int config_flash_gpio_table(enum msm_cam_flash_stat stat,
 			struct msm_camera_sensor_strobe_flash_data *sfdata)
@@ -278,18 +320,34 @@
 {
 	int rc = 0;
 
-#if defined CONFIG_MSM_CAMERA_FLASH_SC628A
 	switch (led_state) {
 
 	case MSM_CAMERA_LED_INIT:
-		if (!sc628a_client) {
-			rc = i2c_add_driver(&sc628a_i2c_driver);
-			if (rc < 0 || sc628a_client == NULL) {
-				rc = -ENOTSUPP;
-				CDBG("I2C add driver failed");
-				return rc;
+		if (external->flash_id == MAM_CAMERA_EXT_LED_FLASH_SC628A) {
+			if (!sc628a_client) {
+				rc = i2c_add_driver(&sc628a_i2c_driver);
+				if (rc < 0 || sc628a_client == NULL) {
+					pr_err("sc628a_i2c_driver add failed\n");
+					rc = -ENOTSUPP;
+					return rc;
+				}
 			}
+		} else if (external->flash_id ==
+			MAM_CAMERA_EXT_LED_FLASH_TPS61310) {
+			if (!tps61310_client) {
+				rc = i2c_add_driver(&tps61310_i2c_driver);
+				if (rc < 0 || tps61310_client == NULL) {
+					pr_err("tps61310_i2c_driver add failed\n");
+					rc = -ENOTSUPP;
+					return rc;
+				}
+			}
+		} else {
+			pr_err("Flash id not supported\n");
+			rc = -ENOTSUPP;
+			return rc;
 		}
+
 #if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
 		if (external->expander_info && !sx150x_client) {
 			struct i2c_adapter *adapter =
@@ -298,20 +356,37 @@
 				sx150x_client = i2c_new_device(adapter,
 					external->expander_info->board_info);
 			if (!sx150x_client || !adapter) {
+				pr_err("sx150x_client is not available\n");
 				rc = -ENOTSUPP;
-				i2c_del_driver(&sc628a_i2c_driver);
-				sc628a_client = NULL;
+				if (sc628a_client) {
+					i2c_del_driver(&sc628a_i2c_driver);
+					sc628a_client = NULL;
+				}
+				if (tps61310_client) {
+					i2c_del_driver(&tps61310_i2c_driver);
+					tps61310_client = NULL;
+				}
 				return rc;
 			}
+			i2c_put_adapter(adapter);
 		}
 #endif
-		rc = gpio_request(external->led_en, "sc628a");
+		if (sc628a_client)
+			rc = gpio_request(external->led_en, "sc628a");
+		if (tps61310_client)
+			rc = gpio_request(external->led_en, "tps61310");
+
 		if (!rc) {
 			gpio_direction_output(external->led_en, 0);
 		} else {
-			goto err1;
+			goto error;
 		}
-		rc = gpio_request(external->led_flash_en, "sc628a");
+
+		if (sc628a_client)
+			rc = gpio_request(external->led_flash_en, "sc628a");
+		if (tps61310_client)
+			rc = gpio_request(external->led_flash_en, "tps61310");
+
 		if (!rc) {
 			gpio_direction_output(external->led_flash_en, 0);
 			break;
@@ -319,19 +394,32 @@
 
 		gpio_set_value_cansleep(external->led_en, 0);
 		gpio_free(external->led_en);
-
-err1:
-		i2c_del_driver(&sc628a_i2c_driver);
-		sc628a_client = NULL;
-
+error:
+		pr_err("%s gpio request failed\n", __func__);
+		if (sc628a_client) {
+			i2c_del_driver(&sc628a_i2c_driver);
+			sc628a_client = NULL;
+		}
+		if (tps61310_client) {
+			i2c_del_driver(&tps61310_i2c_driver);
+			tps61310_client = NULL;
+		}
 		break;
 
 	case MSM_CAMERA_LED_RELEASE:
-		if (sc628a_client) {
+		if (sc628a_client || tps61310_client) {
 			gpio_set_value_cansleep(external->led_en, 0);
 			gpio_free(external->led_en);
 			gpio_set_value_cansleep(external->led_flash_en, 0);
 			gpio_free(external->led_flash_en);
+			if (sc628a_client) {
+				i2c_del_driver(&sc628a_i2c_driver);
+				sc628a_client = NULL;
+			}
+			if (tps61310_client) {
+				i2c_del_driver(&tps61310_i2c_driver);
+				tps61310_client = NULL;
+			}
 		}
 #if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
 		if (external->expander_info && sx150x_client) {
@@ -342,37 +430,38 @@
 		break;
 
 	case MSM_CAMERA_LED_OFF:
-		rc = sc628a_i2c_write_b_flash(0x02, 0x0);
-		if (sc628a_client) {
-			gpio_set_value_cansleep(external->led_en, 0);
-			gpio_set_value_cansleep(external->led_flash_en, 0);
-		}
+		if (sc628a_client)
+			rc = flash_i2c_write_b(sc628a_client, 0x02, 0x00);
+		if (tps61310_client)
+			rc = flash_i2c_write_b(tps61310_client, 0x01, 0x00);
+		gpio_set_value_cansleep(external->led_en, 0);
+		gpio_set_value_cansleep(external->led_flash_en, 0);
 		break;
 
 	case MSM_CAMERA_LED_LOW:
-		if (sc628a_client) {
-			gpio_set_value_cansleep(external->led_en, 1);
-			gpio_set_value_cansleep(external->led_flash_en, 1);
-			usleep_range(2000, 3000);
-		}
-		rc = sc628a_i2c_write_b_flash(0x02, 0x06);
+		gpio_set_value_cansleep(external->led_en, 1);
+		gpio_set_value_cansleep(external->led_flash_en, 1);
+		usleep_range(2000, 3000);
+		if (sc628a_client)
+			rc = flash_i2c_write_b(sc628a_client, 0x02, 0x06);
+		if (tps61310_client)
+			rc = flash_i2c_write_b(tps61310_client, 0x01, 0x86);
 		break;
 
 	case MSM_CAMERA_LED_HIGH:
-		if (sc628a_client) {
-			gpio_set_value_cansleep(external->led_en, 1);
-			gpio_set_value_cansleep(external->led_flash_en, 1);
-			usleep_range(2000, 3000);
-		}
-		rc = sc628a_i2c_write_b_flash(0x02, 0x49);
+		gpio_set_value_cansleep(external->led_en, 1);
+		gpio_set_value_cansleep(external->led_flash_en, 1);
+		usleep_range(2000, 3000);
+		if (sc628a_client)
+			rc = flash_i2c_write_b(sc628a_client, 0x02, 0x49);
+		if (tps61310_client)
+			rc = flash_i2c_write_b(tps61310_client, 0x01, 0x8B);
 		break;
 
 	default:
 		rc = -EFAULT;
 		break;
 	}
-#endif
-
 	return rc;
 }
 
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index d678d86..315f218 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -246,7 +246,6 @@
 		pr_err("%s: Invalid vdata type: %d\n", __func__, vdata->type);
 		break;
 	}
-	msm_isp_sync_free(vdata);
 	return rc;
 }
 
diff --git a/drivers/media/video/msm/msm_vfe31_v4l2.c b/drivers/media/video/msm/msm_vfe31_v4l2.c
index 90ba214..89615ec 100644
--- a/drivers/media/video/msm/msm_vfe31_v4l2.c
+++ b/drivers/media/video/msm/msm_vfe31_v4l2.c
@@ -423,20 +423,15 @@
 
 static void vfe31_subdev_notify(int id, int path)
 {
-	struct msm_vfe_resp *rp;
+	struct msm_vfe_resp rp;
 	unsigned long flags;
 	spin_lock_irqsave(&vfe31_ctrl->sd_notify_lock, flags);
-	rp = msm_isp_sync_alloc(sizeof(struct msm_vfe_resp), GFP_ATOMIC);
-	if (!rp) {
-		CDBG("rp: cannot allocate buffer\n");
-		spin_unlock_irqrestore(&vfe31_ctrl->sd_notify_lock, flags);
-		return;
-	}
+	memset(&rp, 0, sizeof(struct msm_vfe_resp));
 	CDBG("vfe31_subdev_notify : msgId = %d\n", id);
-	rp->evt_msg.type   = MSM_CAMERA_MSG;
-	rp->evt_msg.msg_id = path;
-	rp->type	   = id;
-	v4l2_subdev_notify(&vfe31_ctrl->subdev, NOTIFY_VFE_BUF_EVT, rp);
+	rp.evt_msg.type   = MSM_CAMERA_MSG;
+	rp.evt_msg.msg_id = path;
+	rp.type	   = id;
+	v4l2_subdev_notify(&vfe31_ctrl->subdev, NOTIFY_VFE_BUF_EVT, &rp);
 	spin_unlock_irqrestore(&vfe31_ctrl->sd_notify_lock, flags);
 }
 
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index 3e8d3be..d50b778 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -418,19 +418,15 @@
 
 static void vfe32_subdev_notify(int id, int path)
 {
-	struct msm_vfe_resp *rp;
+	struct msm_vfe_resp rp;
 	unsigned long flags = 0;
 	spin_lock_irqsave(&vfe32_ctrl->sd_notify_lock, flags);
-	rp = msm_isp_sync_alloc(sizeof(struct msm_vfe_resp), GFP_ATOMIC);
-	if (!rp) {
-		CDBG("rp: cannot allocate buffer\n");
-		return;
-	}
 	CDBG("vfe32_subdev_notify : msgId = %d\n", id);
-	rp->evt_msg.type   = MSM_CAMERA_MSG;
-	rp->evt_msg.msg_id = path;
-	rp->type	   = id;
-	v4l2_subdev_notify(&vfe32_ctrl->subdev, NOTIFY_VFE_BUF_EVT, rp);
+	memset(&rp, 0, sizeof(struct msm_vfe_resp));
+	rp.evt_msg.type   = MSM_CAMERA_MSG;
+	rp.evt_msg.msg_id = path;
+	rp.type	   = id;
+	v4l2_subdev_notify(&vfe32_ctrl->subdev, NOTIFY_VFE_BUF_EVT, &rp);
 	spin_unlock_irqrestore(&vfe32_ctrl->sd_notify_lock, flags);
 }
 
diff --git a/drivers/media/video/msm/msm_vfe7x27a_v4l2.c b/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
index 0f71404..f9414a5 100644
--- a/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
+++ b/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
@@ -840,19 +840,15 @@
 
 static void vfe2x_subdev_notify(int id, int path)
 {
-	struct msm_vfe_resp *rp;
+	struct msm_vfe_resp rp;
 	unsigned long flags = 0;
 	spin_lock_irqsave(&vfe2x_ctrl->sd_notify_lock, flags);
-	rp = msm_isp_sync_alloc(sizeof(struct msm_vfe_resp), GFP_ATOMIC);
-	if (!rp) {
-		CDBG("rp: cannot allocate buffer\n");
-		return;
-	}
+	memset(&rp, 0, sizeof(struct msm_vfe_resp));
 	CDBG("vfe2x_subdev_notify : msgId = %d\n", id);
-	rp->evt_msg.type   = MSM_CAMERA_MSG;
-	rp->evt_msg.msg_id = path;
-	rp->type	   = id;
-	v4l2_subdev_notify(&vfe2x_ctrl->subdev, NOTIFY_VFE_BUF_EVT, rp);
+	rp.evt_msg.type   = MSM_CAMERA_MSG;
+	rp.evt_msg.msg_id = path;
+	rp.type	   = id;
+	v4l2_subdev_notify(&vfe2x_ctrl->subdev, NOTIFY_VFE_BUF_EVT, &rp);
 	spin_unlock_irqrestore(&vfe2x_ctrl->sd_notify_lock, flags);
 }
 
diff --git a/drivers/media/video/msm/wfd/wfd-ioctl.c b/drivers/media/video/msm/wfd/wfd-ioctl.c
index 2242aa8..4f6c09d 100644
--- a/drivers/media/video/msm/wfd/wfd-ioctl.c
+++ b/drivers/media/video/msm/wfd/wfd-ioctl.c
@@ -498,7 +498,6 @@
 	if (rc)
 		WFD_MSG_ERR("Failed to free output buffer\n");
 	wfd_unregister_out_buf(inst, minfo);
-	wfd_free_input_buffers(wfd_dev, inst);
 }
 
 static int mdp_output_thread(void *data)
@@ -1344,12 +1343,13 @@
 	inst = filp->private_data;
 	if (inst) {
 		wfdioc_streamoff(filp, NULL, V4L2_BUF_TYPE_VIDEO_CAPTURE);
-		vb2_queue_release(&inst->vid_bufq);
 		rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
 				MDP_CLOSE, (void *)inst->mdp_inst);
 		if (rc)
 			WFD_MSG_ERR("Failed to CLOSE mdp subdevice: %d\n", rc);
 
+		vb2_queue_release(&inst->vid_bufq);
+		wfd_free_input_buffers(wfd_dev, inst);
 		rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
 				CLOSE, (void *)inst->venc_inst);
 
diff --git a/drivers/media/video/msm_vidc/msm_vdec.c b/drivers/media/video/msm_vidc/msm_vdec.c
index 3c279c9..3011a2b 100644
--- a/drivers/media/video/msm_vidc/msm_vdec.c
+++ b/drivers/media/video/msm_vidc/msm_vdec.c
@@ -239,37 +239,12 @@
 {
 	int rc = 0;
 	struct vb2_queue *q;
-	unsigned long flags;
-	struct list_head *ptr, *next;
-	struct internal_buf *buf;
-	struct extradata_buf *ebuf;
 
 	q = msm_comm_get_vb2q(inst, i);
 	if (!q) {
 		pr_err("Failed to find buffer queue for type = %d\n", i);
 		return -EINVAL;
 	}
-	if (i == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-		spin_lock_irqsave(&inst->lock, flags);
-		if (!list_empty(&inst->internalbufs)) {
-			list_for_each_safe(ptr, next, &inst->internalbufs) {
-				buf = list_entry(ptr, struct internal_buf,
-								 list);
-				list_del(&buf->list);
-				msm_smem_free(inst->mem_client, buf->handle);
-				kfree(buf);
-			}
-		}
-		if (!list_empty(&inst->extradatabufs)) {
-			list_for_each_safe(ptr, next, &inst->extradatabufs) {
-				ebuf = list_entry(ptr, struct extradata_buf,
-								  list);
-				ebuf->device_addr = 0;
-			}
-		}
-		spin_unlock_irqrestore(&inst->lock, flags);
-	}
-
 	pr_debug("Calling streamoff\n");
 	rc = vb2_streamoff(q, i);
 	if (rc)
@@ -286,8 +261,7 @@
 	switch (b->type) {
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
 		break;
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: {
-		struct extradata_buf *binfo;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
 		for (i = 0; i < b->length; i++) {
 			pr_err("device_addr = %ld, size = %d\n",
 				b->m.planes[i].m.userptr,
@@ -297,19 +271,8 @@
 			buffer_info.num_buffers = 1;
 			buffer_info.align_device_addr =
 				b->m.planes[i].m.userptr;
-			binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
-			if (!binfo) {
-				pr_err("Failed to allocate shared mem\n");
-				return -ENOMEM;
-			}
-			binfo->device_addr = b->m.planes[i].m.userptr;
-			rc = msm_comm_allocate_extradata_buffers(inst, binfo);
-			if (rc) {
-				pr_err("msm_comm_allocate_extradata_buffers failed");
-				break;
-			}
-			buffer_info.extradata_size = binfo->handle->size;
-			buffer_info.extradata_addr = binfo->handle->device_addr;
+			buffer_info.extradata_size = 0;
+			buffer_info.extradata_addr = 0;
 			rc = vidc_hal_session_set_buffers((void *)inst->session,
 					&buffer_info);
 			if (rc) {
@@ -318,7 +281,6 @@
 			}
 		}
 		break;
-	}
 	default:
 		pr_err("Buffer type not recognized: %d\n", b->type);
 		break;
@@ -336,10 +298,9 @@
 	switch (b->type) {
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
 		break;
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: {
-		struct extradata_buf *addr;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
 		for (i = 0; i < b->length; i++) {
-			pr_err("Release device_addr = %ld, size = %d\n",
+			pr_debug("Release device_addr = %ld, size = %d\n",
 				b->m.planes[i].m.userptr,
 				b->m.planes[i].length);
 			buffer_info.buffer_size = b->m.planes[i].length;
@@ -347,26 +308,13 @@
 			buffer_info.num_buffers = 1;
 			buffer_info.align_device_addr =
 				 b->m.planes[i].m.userptr;
-			if (!list_empty(&inst->extradatabufs)) {
-				list_for_each_entry(addr, &inst->
-					extradatabufs, list) {
-					if (addr->device_addr ==
-							buffer_info.
-						align_device_addr) {
-						buffer_info.extradata_addr =
-							addr->handle->
-							device_addr;
-						break;
-					}
-				}
-			}
+			buffer_info.extradata_addr = 0;
 			rc = vidc_hal_session_release_buffers(
 				(void *)inst->session, &buffer_info);
 			if (rc)
 				pr_err("vidc_hal_session_release_buffers failed");
 		}
 		break;
-	}
 	default:
 		pr_err("Buffer type not recognized: %d\n", b->type);
 		break;
diff --git a/drivers/media/video/msm_vidc/msm_vidc.c b/drivers/media/video/msm_vidc/msm_vidc.c
index d589bf5..09d37ce 100644
--- a/drivers/media/video/msm_vidc/msm_vidc.c
+++ b/drivers/media/video/msm_vidc/msm_vidc.c
@@ -246,7 +246,6 @@
 	inst->session_type = session_type;
 	INIT_LIST_HEAD(&inst->pendingq);
 	INIT_LIST_HEAD(&inst->internalbufs);
-	INIT_LIST_HEAD(&inst->extradatabufs);
 	inst->state = MSM_VIDC_CORE_UNINIT_DONE;
 	inst->core = core;
 	for (i = SESSION_MSG_INDEX(SESSION_MSG_START);
@@ -301,7 +300,6 @@
 	struct list_head *ptr, *next;
 	struct vb2_buf_entry *entry;
 	struct internal_buf *buf;
-
 	if (inst) {
 		spin_lock_irqsave(&inst->lock, flags);
 		if (!list_empty(&inst->pendingq)) {
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
index 8a51301..31879b7 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -892,23 +892,9 @@
 					&frame_data);
 			pr_debug("Sent etb to HAL\n");
 		} else if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-			struct extradata_buf *addr;
 			frame_data.filled_len = 0;
 			frame_data.buffer_type = HAL_BUFFER_OUTPUT;
 			frame_data.extradata_addr = 0;
-			if (!list_empty(&inst->extradatabufs)) {
-				list_for_each_entry(addr, &inst->extradatabufs,
-									list) {
-					if (addr->device_addr ==
-							frame_data.
-						device_addr) {
-						frame_data.extradata_addr =
-							addr->
-							handle->device_addr;
-						break;
-					}
-				}
-			}
 			pr_debug("Sending ftb to hal...: Alloc: %d :filled: %d"
 				" extradata_addr: %d\n", frame_data.alloc_len,
 				   frame_data.filled_len,
@@ -969,49 +955,31 @@
 	return rc;
 }
 
-int msm_comm_allocate_extradata_buffers(struct msm_vidc_inst *inst,
-	struct extradata_buf *binfo)
-{
-	int rc = 0;
-	unsigned long flags;
-	struct msm_smem *handle;
-	pr_debug("Extradata: num = %d, size = %d, align = %d\n",
-			inst->buff_req.buffer[4].buffer_count_actual,
-			inst->buff_req.buffer[4].buffer_size,
-			inst->buff_req.buffer[4].buffer_alignment);
-	if (!inst->buff_req.buffer[4].buffer_size) {
-		pr_err("invalid size: %d",
-			   inst->buff_req.buffer[4].buffer_size);
-		rc = -ENOMEM;
-		goto err_no_mem;
-	}
-	handle = msm_smem_alloc(inst->mem_client,
-			inst->buff_req.buffer[4].buffer_size,
-			inst->buff_req.buffer[4].buffer_alignment, 0);
-	if (!handle) {
-		pr_err("Failed to allocate Extradata memory\n");
-		rc = -ENOMEM;
-		goto err_no_mem;
-	}
-	binfo->handle = handle;
-	spin_lock_irqsave(&inst->lock, flags);
-	list_add_tail(&binfo->list, &inst->extradatabufs);
-	spin_unlock_irqrestore(&inst->lock, flags);
-err_no_mem:
-	return rc;
-}
-
 int msm_comm_set_scratch_buffers(struct msm_vidc_inst *inst)
 {
 	int rc = 0;
 	struct msm_smem *handle;
 	struct internal_buf *binfo;
+	struct list_head *ptr, *next;
 	struct vidc_buffer_addr_info buffer_info;
 	unsigned long flags;
 	int i;
 	pr_debug("scratch: num = %d, size = %d\n",
 			inst->buff_req.buffer[6].buffer_count_actual,
 			inst->buff_req.buffer[6].buffer_size);
+	spin_lock_irqsave(&inst->lock, flags);
+	if (!list_empty(&inst->internalbufs)) {
+		list_for_each_safe(ptr, next, &inst->internalbufs) {
+			binfo = list_entry(ptr, struct internal_buf,
+					list);
+			list_del(&binfo->list);
+			msm_smem_free(inst->mem_client, binfo->handle);
+			kfree(binfo);
+		}
+	}
+	spin_unlock_irqrestore(&inst->lock, flags);
+
+
 	for (i = 0; i < inst->buff_req.buffer[6].buffer_count_actual;
 				i++) {
 		handle = msm_smem_alloc(inst->mem_client,
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.h b/drivers/media/video/msm_vidc/msm_vidc_common.h
index 45bfa7b..2fafa79 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.h
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.h
@@ -27,8 +27,6 @@
 		struct msm_vidc_inst *inst, enum v4l2_buf_type type);
 int msm_comm_try_state(struct msm_vidc_inst *inst, int state);
 int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst);
-int msm_comm_allocate_extradata_buffers(struct msm_vidc_inst *inst,
-	struct extradata_buf *binfo);
 int msm_comm_set_scratch_buffers(struct msm_vidc_inst *inst);
 int msm_comm_qbuf(struct vb2_buffer *vb);
 #define IS_PRIV_CTRL(idx) (\
diff --git a/drivers/media/video/msm_vidc/msm_vidc_internal.h b/drivers/media/video/msm_vidc/msm_vidc_internal.h
index 2c7853b..fb1ab58 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_internal.h
+++ b/drivers/media/video/msm_vidc/msm_vidc_internal.h
@@ -90,12 +90,6 @@
 	struct msm_smem *handle;
 };
 
-struct extradata_buf {
-	struct list_head list;
-	struct msm_smem *handle;
-	u32 device_addr;
-};
-
 struct msm_vidc_format {
 	char name[64];
 	u8 description[32];
@@ -149,7 +143,6 @@
 	spinlock_t lock;
 	struct list_head pendingq;
 	struct list_head internalbufs;
-	struct list_head extradatabufs;
 	struct buffer_requirements buff_req;
 	void *mem_client;
 	struct v4l2_ctrl_handler ctrl_handler;
diff --git a/drivers/media/video/vcap_v4l2.c b/drivers/media/video/vcap_v4l2.c
index 219f7a0..fb02676 100644
--- a/drivers/media/video/vcap_v4l2.c
+++ b/drivers/media/video/vcap_v4l2.c
@@ -279,20 +279,16 @@
 					struct v4l2_format *f)
 {
 	int size;
-#ifdef NEW_S_FMT
+	struct vcap_priv_fmt *priv_fmt;
 	struct v4l2_format_vc_ext *vc_format;
-#endif
 	struct vcap_client_data *c_data = file->private_data;
 
-	switch (f->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-#ifdef NEW_S_FMT
-		vc_format = (struct v4l2_format_vc_ext *) f->fmt.raw_data;
+	priv_fmt = (struct vcap_priv_fmt *) f->fmt.raw_data;
+
+	switch (priv_fmt->type) {
+	case VC_TYPE:
+		vc_format = (struct v4l2_format_vc_ext *) &priv_fmt->u.timing;
 		c_data->vc_format = *vc_format;
-#else
-		c_data->vc_format =
-			vcap_vc_lut[f->fmt.pix.priv];
-#endif
 
 		config_vc_format(c_data);
 
@@ -304,22 +300,20 @@
 		else
 			size *= 2;
 
-#ifndef NEW_S_FMT
-		f->fmt.pix.bytesperline = size;
+		priv_fmt->u.timing.bytesperline = size;
 		size *= (c_data->vc_format.vactive_end -
 			c_data->vc_format.vactive_start);
-		f->fmt.pix.sizeimage = size;
-#endif
+		priv_fmt->u.timing.sizeimage = size;
 		vcap_ctrl->vc_client = c_data;
 		break;
-	case V4L2_BUF_TYPE_INTERLACED_IN_DECODER:
+	case VP_IN_TYPE:
 		c_data->vp_buf_type_field = V4L2_BUF_TYPE_INTERLACED_IN_DECODER;
 		c_data->vp_format.field = f->fmt.pix.field;
 		c_data->vp_format.height = f->fmt.pix.height;
 		c_data->vp_format.width = f->fmt.pix.width;
 		c_data->vp_format.pixelformat = f->fmt.pix.pixelformat;
 		break;
-	case V4L2_BUF_TYPE_INTERLACED_IN_AFE:
+	case VP_OUT_TYPE:
 		break;
 	default:
 		break;
@@ -522,6 +516,8 @@
 	.vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,
 	.vidioc_try_fmt_vid_cap   = vidioc_try_fmt_vid_cap,
 	.vidioc_s_fmt_vid_cap     = vidioc_s_fmt_vid_cap,
+	.vidioc_s_fmt_type_private     = vidioc_s_fmt_vid_cap,
+	.vidioc_g_fmt_type_private     = vidioc_g_fmt_vid_cap,
 	.vidioc_reqbufs       = vidioc_reqbufs,
 	.vidioc_querybuf      = vidioc_querybuf,
 	.vidioc_qbuf          = vidioc_qbuf,
diff --git a/drivers/media/video/vcap_vc.c b/drivers/media/video/vcap_vc.c
index ed0bc25..84b52b2 100644
--- a/drivers/media/video/vcap_vc.c
+++ b/drivers/media/video/vcap_vc.c
@@ -34,401 +34,6 @@
 			printk(KERN_DEBUG "VC: " fmt, ## arg);		\
 	} while (0)
 
-struct v4l2_format_vc_ext vcap_vc_lut[] = {
-		/* 1080p */
-	{
-		HAL_VCAP_YUV_1080p_60_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 148.5,
-		32, 2200, 192, 2112, 4, 24, 0, 2, 0, 44, 0, 0, 0, 0,
-		0, 0
-	},
-	{
-		HAL_VCAP_YUV_1080p_60_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 148.5,
-		1125, 2200, 192, 2112, 41, 1121, 0, 5, 0, 44, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_RGB_1080p_60_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_RGB, 148.5,
-		1125, 2200, 192, 2112, 41, 1121, 0, 5, 0, 44, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_1080p_24_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
-		1125, 2750, 192, 2112, 41, 1121, 0, 5, 0, 44, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_1080p_24_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
-		112, 2750, 192, 2112, 4, 110, 0, 2, 0, 44, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_1080p_24_RW, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
-		1125, 275, 19, 211, 41, 1121, 0, 5, 0, 16, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_1080p_60_RW, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 148.5,
-		1125, 200, 22, 182, 41, 1121, 0, 5, 0, 16, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_1080p_50_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 148.5,
-		1125, 2640, 192, 2112, 41, 1121, 0, 5, 0, 44, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_1080p_50_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 148.5,
-		15, 2640, 192, 2112, 6, 13, 0, 5, 0, 44, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_1080p_25_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
-		1125, 2640, 192, 2112, 41, 1121, 0, 5, 0, 44, 0, 0,
-		0, 0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_1080p_25_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
-		10, 2640, 192, 2112, 4, 8, 0, 2, 0, 44, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_1080p_30_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
-		1125, 2200, 192, 2112, 41, 1121, 0, 5, 0, 44, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_RGB_1080p_25_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_RGB, 74.25,
-		1125, 2640, 192, 2112, 41, 1121, 0, 5, 0, 44, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_RGB_1080p_25_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_RGB, 74.25,
-		10, 2640, 192, 2112, 4, 8, 0, 2, 0, 44, 0, 0, 0,
-		0, 0, 0
-	},
-		/* 1080i */
-	{
-		HAL_VCAP_YUV_1080i_60_FL, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
-		1125, 2200, 192, 2112, 20, 560, 0, 5, 0, 44, 583, 1123, 1100,
-		1100, 563, 568
-	},
-	{
-		HAL_VCAP_YUV_1080i_60_RH, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
-		18, 2200, 192, 2112, 3, 7, 0, 2, 0, 44, 11, 15, 1100,
-		1100, 8, 10
-	},
-	{
-		HAL_VCAP_YUV_1080i_60_RW, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
-		1125, 220, 19, 211, 20, 560, 0, 5, 0, 4, 583, 1123, 110,
-		110, 563, 568
-	},
-	{
-		HAL_VCAP_YUV_1080i_50_FL, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 72.00,
-		1125, 2640, 192, 2112, 20, 560, 0, 5, 0, 44, 583, 1123, 1320,
-		1320, 563, 568
-	},
-	{
-		HAL_VCAP_YUV_1080i_50_RH, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 72.00,
-		52, 2640, 192, 2112, 4, 24, 0, 2, 0, 44, 30, 50, 1320,
-		1320, 26, 28},
-	{
-		HAL_VCAP_YUV_1080i_50_RW, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 72.00,
-		1125, 264, 19, 211, 20, 560, 0, 5, 0, 4, 583, 1123, 110,
-		110, 563, 568
-	},
-	{
-		HAL_VCAP_RGB_1080i_50_FL, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_RGB, 72.00,
-		1125, 2640, 192, 2112, 20, 560, 0, 5, 0, 44, 583, 1123, 1320,
-		1320, 563, 568
-	},
-	{
-		HAL_VCAP_RGB_1080i_50_RH, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_RGB, 72.00,
-		52, 2640, 192, 2112, 4, 24, 0, 2, 0, 44, 30, 50, 1320,
-		1320, 26, 28
-	},
-		/* 480i */
-	{
-		HAL_VCAP_YUV_480i_60_RH, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.027,
-		20, 1716, 238, 1678, 3, 7, 0, 2, 0, 124, 14, 18, 820,
-		820, 10, 12
-	},
-	{
-		HAL_VCAP_YUV_480i_60_FL, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.027,
-		525, 1716, 238, 1678, 18, 258, 0, 3, 0, 124, 281, 521, 858,
-		858, 262, 265
-	},
-	{
-		HAL_VCAP_YUV_480i_60_RW, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.027,
-		525, 172, 24, 168, 18, 258, 0, 3, 0, 12, 281, 521, 86,
-		86, 262, 265
-	},
-	{
-		HAL_VCAP_YUV_2880_480i_60_FL, HAL_VCAP_MODE_INT,
-		HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_YUV, 54.000, 525, 3432, 476, 3356, 18, 258, 0, 3,
-		0, 248, 281, 521, 1716, 1716, 262, 265
-	},
-	{
-		HAL_VCAP_YUV_2880_480i_60_RH, HAL_VCAP_MODE_INT,
-		HAL_VCAP_POLAR_NEG,	HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_YUV, 54.000, 32, 3432, 476, 3356, 4, 14, 0, 3, 0,
-		248, 20, 30, 1716, 1716, 16, 19
-	},
-		/* 480p */
-	{
-		HAL_VCAP_YUV_480p_60_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.027,
-		8, 858, 122, 842, 2, 5, 0, 1, 0, 62, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_RGB_480p_60_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_RGB, 27.027,
-		52, 858, 122, 842, 3, 50, 0, 2, 0, 62, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_RGB_480p_60_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_RGB, 27.027,
-		525, 858, 122, 842, 36, 516, 0, 6, 0, 62, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_480p_60_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.027,
-		525, 858, 122, 842, 36, 516, 0, 6, 0, 62, 0, 0, 0, 0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_480p_60_RW, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.027,
-		525, 86, 12, 84, 36, 516, 0, 6, 0, 6, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_2880_480p_60_FL, HAL_VCAP_MODE_PRO,
-		HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_YUV, 108.000, 525, 3432, 488, 3368, 36, 516, 0, 6,
-		0, 248, 0, 0, 0, 0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_2880_480p_60_RH, HAL_VCAP_MODE_PRO,
-		HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_YUV, 108.000, 25, 3432, 488, 3368, 8, 22, 0, 6, 0,
-		248, 0, 0, 0,	0, 0, 0
-	},
-		/* 720p */
-	{
-		HAL_VCAP_YUV_720p_60_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
-		750, 1650, 260, 1540, 25, 745, 0, 5, 0, 40, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_RGB_720p_60_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_RGB, 74.25,
-		750, 1650, 260, 1540, 25, 745, 0, 5, 0, 40, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_720p_60_RW, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
-		750, 165, 26, 154, 25, 745, 0, 5, 0, 4, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_720p_60_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
-		35, 1650, 260, 1540, 5, 32, 0, 3, 0, 40, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_720p_50_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
-		750, 1980, 260, 1540, 25, 745, 0, 5, 0, 40, 0, 0, 0,
-		 0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_720p_50_RW, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
-		750, 198, 26, 154, 25, 745, 0, 5, 0, 4, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_720p_50_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
-		6, 1980, 260, 1540, 2, 5, 0, 1, 0, 40, 0, 0, 0,
-		0, 0, 0
-	},
-		/* 576p */
-	{
-		HAL_VCAP_YUV_576p_50_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.0,
-		625, 864, 132, 852, 44, 620, 0, 5, 0, 64, 0, 0, 0,
-		0, 0, 0},
-	{
-		HAL_VCAP_RGB_576p_50_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_RGB, 27.0,
-		625, 864, 132, 852, 44, 620, 0, 5, 0, 64, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_576p_50_RW, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.0,
-		625, 86, 13, 85, 44, 620, 0, 5, 0, 6, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_576p_50_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.0,
-		25, 864, 132, 852, 4, 23, 0, 3, 0, 64, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_1440_576p_50_RH, HAL_VCAP_MODE_PRO,
-		HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_YUV, 54.000, 25, 1728, 264, 1704, 6, 23, 0, 5, 0,
-		128, 0, 0, 0,	0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_2880_576p_50_FL, HAL_VCAP_MODE_PRO,
-		HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_YUV, 108.000, 625, 3456, 528, 3408, 44, 620, 0, 5,
-		0, 256, 0, 0, 0, 0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_2880_576p_50_RH, HAL_VCAP_MODE_PRO,
-		HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_YUV, 108.000, 25, 3456, 528, 3408, 6, 23, 0, 5, 0,
-		256, 0, 0, 0, 0, 0, 0
-	},
-		/* 576i */
-	{
-		HAL_VCAP_YUV_576i_50_FL, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.0,
-		625, 1728, 264, 1704, 22, 310, 0, 3, 0, 126, 335, 623, 864,
-		864, 313, 316
-	},
-	{
-		HAL_VCAP_YUV_576i_50_RW, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.0,
-		625, 172, 26, 170, 22, 310, 0, 3, 0, 13, 335, 623, 86,
-		86, 313, 316
-	},
-	{
-		HAL_VCAP_YUV_576i_50_RH, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.0,
-		29, 1728, 264, 1704, 3, 13, 0, 1, 0, 126, 16, 26, 864, 864,
-		14, 15
-	},
-		/* XGA 1024x768 */
-	{
-		HAL_VCAP_YUV_XGA_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 63.5,
-		798, 1328, 256, 1280, 27, 795, 0, 4, 0, 104, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_XGA_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 63.5,
-		12, 1328, 256, 1280, 6, 10, 0, 4, 0, 104, 0, 0, 0, 0,
-		0, 0
-	},
-	{
-		HAL_VCAP_YUV_XGA_RB, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 63.5,
-		12, 1216, 112, 1136, 6, 10, 0, 4, 0, 32, 0, 0, 0, 0,
-		0, 0
-	},
-		/* SXGA 1280x1024 */
-	{
-		HAL_VCAP_YUV_SXGA_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 109.0,
-		1063, 1712, 352, 1632, 36, 1060, 0, 7, 0, 136, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_RGB_SXGA_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_RGB, 109.0,
-		1063, 1712, 352, 1632, 36, 1060, 0, 7, 0, 136, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_SXGA_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 109.0,
-		17, 1712, 352, 1632, 8, 15, 0, 7, 0, 136, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_SXGA_RB, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 109.0,
-		17, 1440, 112, 1392, 8, 15, 0, 7, 0, 32, 0, 0, 0, 0,
-		0, 0
-	},
-		/* UXGA 1600x1200 */
-	{
-		HAL_VCAP_YUV_UXGA_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 161.0,
-		1245, 2160, 448, 2048, 42, 1242, 0, 4, 0, 168, 0,
-		0, 0, 0, 0, 0
-	},
-	{
-		HAL_VCAP_RGB_UXGA_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_RGB, 161.0,
-		1245, 2160, 448, 2048, 42, 1242, 0, 4, 0, 168, 0,
-		0, 0, 0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_UXGA_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 161.0,
-		12, 2160, 448, 2048, 6, 10, 0, 4, 0, 168, 0, 0, 0,
-		0, 0, 0
-	},
-	{
-		HAL_VCAP_YUV_UXGA_RB, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 161.0,
-		12, 1808, 112, 1712, 6, 10, 0, 4, 0, 32, 0, 0, 0, 0,
-		0, 0
-	},
-		/* test odd height */
-	{
-		HAL_VCAP_ODD_HEIGHT, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_NEG, HAL_VCAP_YUV, 148.5,
-		65, 1728, 264, 1704, 5, 20, 0, 3, 0, 126, 25, 40, 864,
-		864, 21, 24
-	},
-		/* test odd width RGB only */
-	{
-		HAL_VCAP_ODD_WIDTH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
-		HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_NEG, HAL_VCAP_RGB, 148.5,
-		52, 859, 122, 843, 3, 50, 0, 2, 0, 62, 0, 0, 0, 0, 0, 0
-	},
-};
-
 void config_buffer(struct vcap_client_data *c_data,
 			struct vcap_buffer *buf,
 			void __iomem *y_addr,
@@ -655,10 +260,8 @@
 	writel_relaxed(0x00000002, VCAP_VC_NPL_CTRL);
 	writel_relaxed(0x00000004 | vc_format->color_space << 1, VCAP_VC_CTRL);
 
-	writel_relaxed(vc_format->h_polar << 4 |
-			vc_format->v_polar << 0, VCAP_VC_POLARITY);
-
-	writel_relaxed(vc_format->h_polar << 4 |
+	writel_relaxed(vc_format->d_polar << 8 |
+			vc_format->h_polar << 4 |
 			vc_format->v_polar << 0, VCAP_VC_POLARITY);
 	writel_relaxed(((vc_format->htotal << 16) | vc_format->vtotal),
 			VCAP_VC_V_H_TOTAL);
diff --git a/drivers/media/video/vcap_vc.h b/drivers/media/video/vcap_vc.h
index e431038..57d13cd 100644
--- a/drivers/media/video/vcap_vc.h
+++ b/drivers/media/video/vcap_vc.h
@@ -13,11 +13,9 @@
 #ifndef VCAP_VC_H
 #define VCAP_VC_H
 
-/* #define NEW_S_FMT */
 #include <linux/interrupt.h>
 
 #include <media/vcap_v4l2.h>
-extern struct v4l2_format_vc_ext vcap_vc_lut[];
 
 #define VCAP_HARDWARE_VERSION 0x10000000
 
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index b128a61..e2dff4b 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -1054,6 +1054,22 @@
 	.suspend = wcd9xxx_slim_suspend,
 };
 
+static const struct slim_device_id sitar1p1_slimtest_id[] = {
+	{"sitar1p1-slim", 0},
+	{}
+};
+static struct slim_driver sitar1p1_slim_driver = {
+	.driver = {
+		.name = "sitar1p1-slim",
+		.owner = THIS_MODULE,
+	},
+	.probe = wcd9xxx_slim_probe,
+	.remove = wcd9xxx_slim_remove,
+	.id_table = sitar1p1_slimtest_id,
+	.resume = wcd9xxx_slim_resume,
+	.suspend = wcd9xxx_slim_suspend,
+};
+
 static const struct slim_device_id slimtest_id[] = {
 	{"tabla-slim", 0},
 	{}
@@ -1116,7 +1132,7 @@
 
 static int __init wcd9xxx_init(void)
 {
-	int ret1, ret2, ret3, ret4;
+	int ret1, ret2, ret3, ret4, ret5;
 
 	ret1 = slim_driver_register(&tabla_slim_driver);
 	if (ret1 != 0)
@@ -1131,10 +1147,14 @@
 		pr_err("failed to add the I2C driver\n");
 
 	ret4 = slim_driver_register(&sitar_slim_driver);
-	if (ret1 != 0)
+	if (ret4 != 0)
 		pr_err("Failed to register sitar SB driver: %d\n", ret4);
 
-	return (ret1 && ret2 && ret3 && ret4) ? -1 : 0;
+	ret5 = slim_driver_register(&sitar1p1_slim_driver);
+	if (ret5 != 0)
+		pr_err("Failed to register sitar SB driver: %d\n", ret5);
+
+	return (ret1 && ret2 && ret3 && ret4 && ret5) ? -1 : 0;
 }
 module_init(wcd9xxx_init);
 
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index a162586..ca54265 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -363,33 +363,24 @@
 show_perf(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct mmc_host *host = dev_get_drvdata(dev);
-	int64_t rtime_mmcq, wtime_mmcq, rtime_drv, wtime_drv;
-	unsigned long rbytes_mmcq, wbytes_mmcq, rbytes_drv, wbytes_drv;
+	int64_t rtime_drv, wtime_drv;
+	unsigned long rbytes_drv, wbytes_drv;
 
 	spin_lock(&host->lock);
 
-	rbytes_mmcq = host->perf.rbytes_mmcq;
-	wbytes_mmcq = host->perf.wbytes_mmcq;
 	rbytes_drv = host->perf.rbytes_drv;
 	wbytes_drv = host->perf.wbytes_drv;
 
-	rtime_mmcq = ktime_to_us(host->perf.rtime_mmcq);
-	wtime_mmcq = ktime_to_us(host->perf.wtime_mmcq);
 	rtime_drv = ktime_to_us(host->perf.rtime_drv);
 	wtime_drv = ktime_to_us(host->perf.wtime_drv);
 
 	spin_unlock(&host->lock);
 
-	return snprintf(buf, PAGE_SIZE, "Write performance at MMCQ Level:"
-					"%lu bytes in %lld microseconds\n"
-					"Read performance at MMCQ Level:"
-					"%lu bytes in %lld microseconds\n"
-					"Write performance at driver Level:"
+	return snprintf(buf, PAGE_SIZE, "Write performance at driver Level:"
 					"%lu bytes in %lld microseconds\n"
 					"Read performance at driver Level:"
 					"%lu bytes in %lld microseconds\n",
-					wbytes_mmcq, wtime_mmcq, rbytes_mmcq,
-					rtime_mmcq, wbytes_drv, wtime_drv,
+					wbytes_drv, wtime_drv,
 					rbytes_drv, rtime_drv);
 }
 
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 9385087..8fce9a6 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -464,6 +464,11 @@
 			ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 |
 			ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 |
 			ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24;
+
+		card->ext_csd.max_packed_writes =
+			ext_csd[EXT_CSD_MAX_PACKED_WRITES];
+		card->ext_csd.max_packed_reads =
+			ext_csd[EXT_CSD_MAX_PACKED_READS];
 	}
 
 out:
@@ -1183,6 +1188,25 @@
 		card->ext_csd.cache_ctrl = err ? 0 : 1;
 	}
 
+	if ((host->caps2 & MMC_CAP2_PACKED_CMD) &&
+			(card->ext_csd.max_packed_writes > 0) &&
+			(card->ext_csd.max_packed_reads > 0)) {
+		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+				EXT_CSD_EXP_EVENTS_CTRL,
+				EXT_CSD_PACKED_EVENT_EN,
+				card->ext_csd.generic_cmd6_time);
+		if (err && err != -EBADMSG)
+			goto free_card;
+		if (err) {
+			pr_warning("%s: Enabling packed event failed\n",
+					mmc_hostname(card->host));
+			card->ext_csd.packed_event_en = 0;
+			err = 0;
+		} else {
+			card->ext_csd.packed_event_en = 1;
+		}
+	}
+
 	if (!oldcard)
 		host->card = card;
 
diff --git a/drivers/spi/spi_qsd.c b/drivers/spi/spi_qsd.c
index 2fc95af..152bbb4 100644
--- a/drivers/spi/spi_qsd.c
+++ b/drivers/spi/spi_qsd.c
@@ -392,6 +392,7 @@
 	u32 num_transfers;
 
 	atomic_set(&dd->rx_irq_called, 0);
+	atomic_set(&dd->tx_irq_called, 0);
 	if (dd->write_len && !dd->read_len) {
 		/* WR-WR transfer */
 		bytes_sent = dd->cur_msg_len - dd->tx_bytes_remaining;
@@ -712,6 +713,8 @@
 		    readl_relaxed(dd->base + SPI_OPERATIONAL) &
 		    SPI_OP_MAX_OUTPUT_DONE_FLAG) {
 			msm_spi_ack_transfer(dd);
+			if (atomic_inc_return(&dd->tx_irq_called) == 1)
+				return IRQ_HANDLED;
 			msm_spi_complete(dd);
 			return IRQ_HANDLED;
 		}
@@ -1586,9 +1589,12 @@
 	}
 	/* restore original context */
 	dd = container_of(cmd, struct msm_spi, tx_hdr);
-	if (result & DMOV_RSLT_DONE)
+	if (result & DMOV_RSLT_DONE) {
 		dd->stat_dmov_tx++;
-	else {
+		if ((atomic_inc_return(&dd->tx_irq_called) == 1))
+			return;
+		complete(&dd->transfer_complete);
+	} else {
 		/* Error or flush */
 		if (result & DMOV_RSLT_ERROR) {
 			dev_err(dd->dev, "DMA error (0x%08x)\n", result);
diff --git a/drivers/spi/spi_qsd.h b/drivers/spi/spi_qsd.h
index a434bbb..223fce6 100644
--- a/drivers/spi/spi_qsd.h
+++ b/drivers/spi/spi_qsd.h
@@ -285,6 +285,7 @@
 	int                      output_block_size;
 	int                      burst_size;
 	atomic_t                 rx_irq_called;
+	atomic_t                 tx_irq_called;
 	/* Used to pad messages unaligned to block size */
 	u8                       *tx_padding;
 	dma_addr_t               tx_padding_dma;
diff --git a/drivers/thermal/msm8960_tsens.c b/drivers/thermal/msm8960_tsens.c
index fbb377e..78a1292 100644
--- a/drivers/thermal/msm8960_tsens.c
+++ b/drivers/thermal/msm8960_tsens.c
@@ -723,7 +723,8 @@
 	} else if (tmdev->hw_type == APQ_8064) {
 		reg_cntl |= TSENS_8960_SLP_CLK_ENA |
 			(TSENS_MEASURE_PERIOD << 18) |
-			TSENS_8064_SENSORS_EN;
+			(((1 << tmdev->tsens_num_sensor) - 1)
+					<< TSENS_SENSOR0_SHIFT);
 		writel_relaxed(reg_cntl, TSENS_CNTL_ADDR);
 		reg_status_cntl = readl_relaxed(TSENS_8064_STATUS_CNTL);
 		reg_status_cntl |= TSENS_MIN_STATUS_MASK |
@@ -823,7 +824,8 @@
 	} else if (tmdev->hw_type == APQ_8064) {
 		reg_cntl |= TSENS_8960_SLP_CLK_ENA |
 			(TSENS_MEASURE_PERIOD << 18) |
-			TSENS_8064_SENSORS_EN;
+			(((1 << tmdev->tsens_num_sensor) - 1)
+					<< TSENS_SENSOR0_SHIFT);
 		writel_relaxed(reg_cntl, TSENS_CNTL_ADDR);
 		reg_status_cntl = readl_relaxed(TSENS_8064_STATUS_CNTL);
 		reg_status_cntl |= TSENS_LOWER_STATUS_CLR |
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index d310381..d0b8323 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -1964,12 +1964,25 @@
 	INIT_WORK(&msm_uport->clock_off_w, hsuart_clock_off_work);
 	mutex_init(&msm_uport->clk_mutex);
 
+	clk_prepare_enable(msm_uport->clk);
+	if (msm_uport->pclk)
+		clk_prepare_enable(msm_uport->pclk);
+
 	ret = uartdm_init_port(uport);
-	if (unlikely(ret))
+	if (unlikely(ret)) {
+		clk_disable_unprepare(msm_uport->clk);
+		if (msm_uport->pclk)
+			clk_disable_unprepare(msm_uport->pclk);
 		return ret;
+	}
 
 	/* configure the CR Protection to Enable */
 	msm_hs_write(uport, UARTDM_CR_ADDR, CR_PROTECTION_EN);
+
+	clk_disable_unprepare(msm_uport->clk);
+	if (msm_uport->pclk)
+		clk_disable_unprepare(msm_uport->pclk);
+
 	/*
 	 * Enable Command register protection before going ahead as this hw
 	 * configuration makes sure that issued cmd to CR register gets complete
diff --git a/drivers/usb/gadget/ci13xxx_msm.c b/drivers/usb/gadget/ci13xxx_msm.c
index 863143b..7fd120f 100644
--- a/drivers/usb/gadget/ci13xxx_msm.c
+++ b/drivers/usb/gadget/ci13xxx_msm.c
@@ -16,6 +16,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/usb/msm_hsusb_hw.h>
 #include <linux/usb/ulpi.h>
+#include <mach/gpio.h>
 
 #include "ci13xxx_udc.c"
 
@@ -24,7 +25,11 @@
 struct ci13xxx_udc_context {
 	int irq;
 	void __iomem *regs;
+	int wake_gpio;
+	int wake_irq;
+	bool wake_irq_state;
 };
+
 static struct ci13xxx_udc_context _udc_ctxt;
 
 static irqreturn_t msm_udc_irq(int irq, void *data)
@@ -32,22 +37,71 @@
 	return udc_irq();
 }
 
+static void ci13xxx_msm_suspend(void)
+{
+	struct device *dev = _udc->gadget.dev.parent;
+	dev_dbg(dev, "ci13xxx_msm_suspend\n");
+
+	if (_udc_ctxt.wake_irq && !_udc_ctxt.wake_irq_state) {
+		enable_irq_wake(_udc_ctxt.wake_irq);
+		enable_irq(_udc_ctxt.wake_irq);
+		_udc_ctxt.wake_irq_state = true;
+	}
+}
+
+static void ci13xxx_msm_resume(void)
+{
+	struct device *dev = _udc->gadget.dev.parent;
+	dev_dbg(dev, "ci13xxx_msm_resume\n");
+
+	if (_udc_ctxt.wake_irq && _udc_ctxt.wake_irq_state) {
+		disable_irq_wake(_udc_ctxt.wake_irq);
+		disable_irq(_udc_ctxt.wake_irq);
+		_udc_ctxt.wake_irq_state = false;
+	}
+}
+
 static void ci13xxx_msm_notify_event(struct ci13xxx *udc, unsigned event)
 {
 	struct device *dev = udc->gadget.dev.parent;
 
 	switch (event) {
 	case CI13XXX_CONTROLLER_RESET_EVENT:
-		dev_dbg(dev, "CI13XXX_CONTROLLER_RESET_EVENT received\n");
+		dev_info(dev, "CI13XXX_CONTROLLER_RESET_EVENT received\n");
 		writel(0, USB_AHBBURST);
 		writel_relaxed(0x08, USB_AHBMODE);
 		break;
+	case CI13XXX_CONTROLLER_DISCONNECT_EVENT:
+		dev_info(dev, "CI13XXX_CONTROLLER_DISCONNECT_EVENT received\n");
+		ci13xxx_msm_resume();
+		break;
+	case CI13XXX_CONTROLLER_SUSPEND_EVENT:
+		dev_info(dev, "CI13XXX_CONTROLLER_SUSPEND_EVENT received\n");
+		ci13xxx_msm_suspend();
+		break;
+	case CI13XXX_CONTROLLER_RESUME_EVENT:
+		dev_info(dev, "CI13XXX_CONTROLLER_RESUME_EVENT received\n");
+		ci13xxx_msm_resume();
+		break;
+
 	default:
 		dev_dbg(dev, "unknown ci13xxx_udc event\n");
 		break;
 	}
 }
 
+static irqreturn_t ci13xxx_msm_resume_irq(int irq, void *data)
+{
+	struct ci13xxx *udc = _udc;
+
+	if (udc->transceiver && udc->vbus_active && udc->suspended)
+		otg_set_suspend(udc->transceiver, 0);
+	else if (!udc->suspended)
+		ci13xxx_msm_resume();
+
+	return IRQ_HANDLED;
+}
+
 static struct ci13xxx_udc_driver ci13xxx_msm_udc_driver = {
 	.name			= "ci13xxx_msm",
 	.flags			= CI13XXX_REGS_SHARED |
@@ -60,6 +114,52 @@
 	.notify_event		= ci13xxx_msm_notify_event,
 };
 
+static int ci13xxx_msm_install_wake_gpio(struct platform_device *pdev,
+				struct resource *res)
+{
+	int wake_irq;
+	int ret;
+
+	dev_dbg(&pdev->dev, "ci13xxx_msm_install_wake_gpio\n");
+
+	_udc_ctxt.wake_gpio = res->start;
+	gpio_request(_udc_ctxt.wake_gpio, "USB_RESUME");
+	gpio_direction_input(_udc_ctxt.wake_gpio);
+	wake_irq = MSM_GPIO_TO_INT(_udc_ctxt.wake_gpio);
+	if (wake_irq < 0) {
+		dev_err(&pdev->dev, "could not register USB_RESUME GPIO.\n");
+		return -ENXIO;
+	}
+
+	dev_dbg(&pdev->dev, "_udc_ctxt.gpio_irq = %d and irq = %d\n",
+			_udc_ctxt.wake_gpio, wake_irq);
+	ret = request_irq(wake_irq, ci13xxx_msm_resume_irq,
+		IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "usb resume", NULL);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "could not register USB_RESUME IRQ.\n");
+		goto gpio_free;
+	}
+	disable_irq(wake_irq);
+	_udc_ctxt.wake_irq = wake_irq;
+
+	return 0;
+
+gpio_free:
+	gpio_free(_udc_ctxt.wake_gpio);
+	_udc_ctxt.wake_gpio = 0;
+	return ret;
+}
+
+static void ci13xxx_msm_uninstall_wake_gpio(struct platform_device *pdev)
+{
+	dev_dbg(&pdev->dev, "ci13xxx_msm_uninstall_wake_gpio\n");
+
+	if (_udc_ctxt.wake_gpio) {
+		gpio_free(_udc_ctxt.wake_gpio);
+		_udc_ctxt.wake_gpio = 0;
+	}
+}
+
 static int ci13xxx_msm_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -92,11 +192,20 @@
 		goto udc_remove;
 	}
 
+	res = platform_get_resource_byname(pdev, IORESOURCE_IO, "USB_RESUME");
+	if (res) {
+		ret = ci13xxx_msm_install_wake_gpio(pdev, res);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "gpio irq install failed\n");
+			goto udc_remove;
+		}
+	}
+
 	ret = request_irq(_udc_ctxt.irq, msm_udc_irq, IRQF_SHARED, pdev->name,
 					  pdev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "request_irq failed\n");
-		goto udc_remove;
+		goto gpio_uninstall;
 	}
 
 	pm_runtime_no_callbacks(&pdev->dev);
@@ -104,6 +213,8 @@
 
 	return 0;
 
+gpio_uninstall:
+	ci13xxx_msm_uninstall_wake_gpio(pdev);
 udc_remove:
 	udc_remove();
 iounmap:
@@ -116,6 +227,7 @@
 {
 	pm_runtime_disable(&pdev->dev);
 	free_irq(_udc_ctxt.irq, pdev);
+	ci13xxx_msm_uninstall_wake_gpio(pdev);
 	udc_remove();
 	iounmap(_udc_ctxt.regs);
 	return 0;
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index b612a0b..b29ef82 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -2005,6 +2005,51 @@
 }
 
 /**
+ * isr_resume_handler: USB PCI interrupt handler
+ * @udc: UDC device
+ *
+ */
+static void isr_resume_handler(struct ci13xxx *udc)
+{
+	udc->gadget.speed = hw_port_is_high_speed() ?
+		USB_SPEED_HIGH : USB_SPEED_FULL;
+	if (udc->suspended) {
+		spin_unlock(udc->lock);
+		if (udc->udc_driver->notify_event)
+			udc->udc_driver->notify_event(udc,
+			  CI13XXX_CONTROLLER_RESUME_EVENT);
+		if (udc->transceiver)
+			otg_set_suspend(udc->transceiver, 0);
+		udc->driver->resume(&udc->gadget);
+		spin_lock(udc->lock);
+		udc->suspended = 0;
+	}
+}
+
+/**
+ * isr_resume_handler: USB SLI interrupt handler
+ * @udc: UDC device
+ *
+ */
+static void isr_suspend_handler(struct ci13xxx *udc)
+{
+	if (udc->gadget.speed != USB_SPEED_UNKNOWN &&
+		udc->vbus_active) {
+		if (udc->suspended == 0) {
+			spin_unlock(udc->lock);
+			udc->driver->suspend(&udc->gadget);
+			if (udc->udc_driver->notify_event)
+				udc->udc_driver->notify_event(udc,
+				CI13XXX_CONTROLLER_SUSPEND_EVENT);
+			if (udc->transceiver)
+				otg_set_suspend(udc->transceiver, 1);
+			spin_lock(udc->lock);
+			udc->suspended = 1;
+		}
+	}
+}
+
+/**
  * isr_get_status_complete: get_status request complete function
  * @ep:  endpoint
  * @req: request handled
@@ -2865,6 +2910,9 @@
 		} else {
 			hw_device_state(0);
 			_gadget_stop_activity(&udc->gadget);
+			if (udc->udc_driver->notify_event)
+				udc->udc_driver->notify_event(udc,
+					CI13XXX_CONTROLLER_DISCONNECT_EVENT);
 			pm_runtime_put_sync(&_gadget->dev);
 		}
 	}
@@ -3174,14 +3222,7 @@
 		}
 		if (USBi_PCI & intr) {
 			isr_statistics.pci++;
-			udc->gadget.speed = hw_port_is_high_speed() ?
-				USB_SPEED_HIGH : USB_SPEED_FULL;
-			if (udc->suspended) {
-				spin_unlock(udc->lock);
-				udc->driver->resume(&udc->gadget);
-				spin_lock(udc->lock);
-				udc->suspended = 0;
-			}
+			isr_resume_handler(udc);
 		}
 		if (USBi_UEI & intr)
 			isr_statistics.uei++;
@@ -3190,15 +3231,7 @@
 			isr_tr_complete_handler(udc);
 		}
 		if (USBi_SLI & intr) {
-			if (udc->gadget.speed != USB_SPEED_UNKNOWN) {
-				udc->suspended = 1;
-				spin_unlock(udc->lock);
-				udc->driver->suspend(&udc->gadget);
-				if (udc->udc_driver->notify_event)
-					udc->udc_driver->notify_event(udc,
-					  CI13XXX_CONTROLLER_SUSPEND_EVENT);
-				spin_lock(udc->lock);
-			}
+			isr_suspend_handler(udc);
 			isr_statistics.sli++;
 		}
 		retval = IRQ_HANDLED;
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h
index 8e2b093..8cb62da 100644
--- a/drivers/usb/gadget/ci13xxx_udc.h
+++ b/drivers/usb/gadget/ci13xxx_udc.h
@@ -124,6 +124,8 @@
 #define CI13XXX_CONTROLLER_CONNECT_EVENT		1
 #define CI13XXX_CONTROLLER_SUSPEND_EVENT		2
 #define CI13XXX_CONTROLLER_REMOTE_WAKEUP_EVENT	3
+#define CI13XXX_CONTROLLER_RESUME_EVENT	        4
+#define CI13XXX_CONTROLLER_DISCONNECT_EVENT	    5
 	void	(*notify_event) (struct ci13xxx *udc, unsigned event);
 };
 
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 0ff0a48..5b05c5b 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -673,8 +673,7 @@
 {
 	struct msm_otg *motg = container_of(otg, struct msm_otg, otg);
 
-	if (aca_enabled() || (test_bit(ID, &motg->inputs) &&
-				 !test_bit(ID_A, &motg->inputs)))
+	if (aca_enabled())
 		return 0;
 
 	if (suspend) {
@@ -688,6 +687,14 @@
 			clear_bit(A_BUS_REQ, &motg->inputs);
 			queue_work(system_nrt_wq, &motg->sm_work);
 			break;
+		case OTG_STATE_B_PERIPHERAL:
+			pr_debug("peripheral bus suspend\n");
+			if (!(motg->caps & ALLOW_LPM_ON_DEV_SUSPEND))
+				break;
+			set_bit(A_BUS_SUSPEND, &motg->inputs);
+			queue_work(system_nrt_wq, &motg->sm_work);
+			break;
+
 		default:
 			break;
 		}
@@ -701,6 +708,13 @@
 			/* ensure hardware is not in low power mode */
 			pm_runtime_resume(otg->dev);
 			break;
+		case OTG_STATE_B_PERIPHERAL:
+			pr_debug("peripheral bus resume\n");
+			if (!(motg->caps & ALLOW_LPM_ON_DEV_SUSPEND))
+				break;
+			clear_bit(A_BUS_SUSPEND, &motg->inputs);
+			queue_work(system_nrt_wq, &motg->sm_work);
+			break;
 		default:
 			break;
 		}
@@ -718,7 +732,7 @@
 	struct usb_bus *bus = otg->host;
 	struct msm_otg_platform_data *pdata = motg->pdata;
 	int cnt = 0;
-	bool host_bus_suspend, dcp;
+	bool host_bus_suspend, device_bus_suspend, dcp;
 	u32 phy_ctrl_val = 0, cmd_val;
 	unsigned ret;
 	u32 portsc;
@@ -728,6 +742,9 @@
 
 	disable_irq(motg->irq);
 	host_bus_suspend = otg->host && !test_bit(ID, &motg->inputs);
+	device_bus_suspend = otg->gadget && test_bit(ID, &motg->inputs) &&
+		test_bit(A_BUS_SUSPEND, &motg->inputs) &&
+		motg->caps & ALLOW_LPM_ON_DEV_SUSPEND;
 	dcp = motg->chg_type == USB_DCP_CHARGER;
 	/*
 	 * Chipidea 45-nm PHY suspend sequence:
@@ -791,8 +808,8 @@
 	 * PMIC notifications are unavailable.
 	 */
 	cmd_val = readl_relaxed(USB_USBCMD);
-	if (host_bus_suspend || (motg->pdata->otg_control == OTG_PHY_CONTROL &&
-				dcp))
+	if (host_bus_suspend || device_bus_suspend ||
+		(motg->pdata->otg_control == OTG_PHY_CONTROL && dcp))
 		cmd_val |= ASYNC_INTR_CTRL | ULPI_STP_CTRL;
 	else
 		cmd_val |= ULPI_STP_CTRL;
@@ -802,7 +819,8 @@
 	 * BC1.2 spec mandates PD to enable VDP_SRC when charging from DCP.
 	 * PHY retention and collapse can not happen with VDP_SRC enabled.
 	 */
-	if (motg->caps & ALLOW_PHY_RETENTION && !host_bus_suspend && !dcp) {
+	if (motg->caps & ALLOW_PHY_RETENTION && !host_bus_suspend &&
+		!device_bus_suspend && !dcp) {
 		phy_ctrl_val = readl_relaxed(USB_PHY_CTRL);
 		if (motg->pdata->otg_control == OTG_PHY_CONTROL)
 			/* Enable PHY HV interrupts to wake MPM/Link */
@@ -2133,6 +2151,13 @@
 			 */
 			otg->host->is_b_host = 1;
 			msm_otg_start_host(otg, 1);
+		} else if (test_bit(A_BUS_SUSPEND, &motg->inputs) &&
+				   test_bit(B_SESS_VLD, &motg->inputs)) {
+			pr_debug("a_bus_suspend && b_sess_vld\n");
+			if (motg->caps & ALLOW_LPM_ON_DEV_SUSPEND) {
+				pm_runtime_put_noidle(otg->dev);
+				pm_runtime_suspend(otg->dev);
+			}
 		} else if (test_bit(ID_C, &motg->inputs)) {
 			msm_otg_notify_charger(motg, IDEV_ACA_CHG_MAX);
 		}
@@ -2569,6 +2594,8 @@
 		} else {
 			pr_debug("BSV clear\n");
 			clear_bit(B_SESS_VLD, &motg->inputs);
+			clear_bit(A_BUS_SUSPEND, &motg->inputs);
+
 			msm_chg_check_aca_intr(motg);
 		}
 		work = 1;
@@ -3389,6 +3416,9 @@
 			motg->caps = ALLOW_PHY_RETENTION;
 	}
 
+	if (motg->pdata->enable_lpm_on_dev_suspend)
+		motg->caps |= ALLOW_LPM_ON_DEV_SUSPEND;
+
 	wake_lock(&motg->wlock);
 	pm_runtime_set_active(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
diff --git a/drivers/video/msm/external_common.c b/drivers/video/msm/external_common.c
index 7f603dd..0212142 100644
--- a/drivers/video/msm/external_common.c
+++ b/drivers/video/msm/external_common.c
@@ -26,6 +26,8 @@
 #include "external_common.h"
 #include "mhl_api.h"
 
+#include "mdp.h"
+
 struct external_common_state_type *external_common_state;
 EXPORT_SYMBOL(external_common_state);
 DEFINE_MUTEX(external_common_state_hpd_mutex);
@@ -77,6 +79,23 @@
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF};
 #endif /* DEBUG_EDID */
 
+#define DMA_E_BASE 0xB0000
+void mdp_vid_quant_set(void)
+{
+	if ((external_common_state->video_resolution == \
+		HDMI_VFRMT_720x480p60_4_3) || \
+		(external_common_state->video_resolution == \
+		HDMI_VFRMT_720x480p60_16_9)) {
+		MDP_OUTP(MDP_BASE + DMA_E_BASE + 0x70, 0x00EB0010);
+		MDP_OUTP(MDP_BASE + DMA_E_BASE + 0x74, 0x00EB0010);
+		MDP_OUTP(MDP_BASE + DMA_E_BASE + 0x78, 0x00EB0010);
+	} else {
+		MDP_OUTP(MDP_BASE + DMA_E_BASE + 0x70, 0x00FF0000);
+		MDP_OUTP(MDP_BASE + DMA_E_BASE + 0x74, 0x00FF0000);
+		MDP_OUTP(MDP_BASE + DMA_E_BASE + 0x78, 0x00FF0000);
+	}
+}
+
 const char *video_format_2string(uint32 format)
 {
 	switch (format) {
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index 7f6585c..a372016 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -3641,8 +3641,8 @@
 	 0x10,	0x10,	0x10,	0x10,	0x10, 0x10, 0x10}, /*00*/
 	{0x18,	0x18,	0x28,	0x28,	0x28,	 0x28,	0x28,	0x28,	0x28,
 	 0x28,	0x28,	0x28,	0x28,	0x18, 0x28, 0x18}, /*01*/
-	{0x04,	0x04,	0x04,	0x04,	0x04,	 0x04,	0x04,	0x04,	0x04,
-	 0x04,	0x04,	0x04,	0x04,	0x88, 0x04, 0x04}, /*02*/
+	{0x00,	0x04,	0x04,	0x04,	0x04,	 0x04,	0x04,	0x04,	0x04,
+	 0x04,	0x04,	0x04,	0x04,	0x88, 0x00, 0x04}, /*02*/
 	{0x02,	0x06,	0x11,	0x15,	0x04,	 0x13,	0x10,	0x05,	0x1F,
 	 0x14,	0x20,	0x22,	0x21,	0x01, 0x03, 0x11}, /*03*/
 	{0x00,	0x01,	0x00,	0x01,	0x00,	 0x00,	0x00,	0x00,	0x00,
diff --git a/drivers/video/msm/logo.c b/drivers/video/msm/logo.c
index 1b5d7c5..57d754e 100644
--- a/drivers/video/msm/logo.c
+++ b/drivers/video/msm/logo.c
@@ -37,7 +37,7 @@
 }
 
 /* 565RLE image format: [count(2 bytes), rle(2 bytes)] */
-int load_565rle_image(char *filename)
+int load_565rle_image(char *filename, bool bf_supported)
 {
 	struct fb_info *info;
 	int fd, count, err = 0;
@@ -76,7 +76,7 @@
 
 	max = fb_width(info) * fb_height(info);
 	ptr = data;
-	if (info->node == 1 || info->node == 2) {
+	if (bf_supported && (info->node == 1 || info->node == 2)) {
 		err = -EPERM;
 		pr_err("%s:%d no info->creen_base on fb%d!\n",
 		       __func__, __LINE__, info->node);
diff --git a/drivers/video/msm/mdp.h b/drivers/video/msm/mdp.h
index 6224dba..40f62b9 100644
--- a/drivers/video/msm/mdp.h
+++ b/drivers/video/msm/mdp.h
@@ -836,4 +836,5 @@
 	unsigned long srcp0_addr, unsigned long srcp0_size,
 	unsigned long srcp1_addr, unsigned long srcp1_size);
 
+void mdp_vid_quant_set(void);
 #endif /* MDP_H */
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index 860209f..de254d0 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -766,6 +766,7 @@
 int mdp4_igc_lut_config(struct mdp_igc_lut_data *cfg);
 void mdp4_iommu_unmap(struct mdp4_overlay_pipe *pipe);
 void mdp4_iommu_attach(void);
+void mdp4_iommu_detach(void);
 int mdp4_v4l2_overlay_set(struct fb_info *info, struct mdp_overlay *req,
 		struct mdp4_overlay_pipe **ppipe);
 void mdp4_v4l2_overlay_clear(struct mdp4_overlay_pipe *pipe);
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index 2e69ea6..311599d 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -287,9 +287,7 @@
 		MDP_OUTP(MDP_BASE + 0xb3014, 0x1000080);
 		MDP_OUTP(MDP_BASE + 0xb4004, 0x67686970);
 	} else {
-		MDP_OUTP(MDP_BASE + 0xb0070, 0xff0000);
-		MDP_OUTP(MDP_BASE + 0xb0074, 0xff0000);
-		MDP_OUTP(MDP_BASE + 0xb0078, 0xff0000);
+		mdp_vid_quant_set();
 	}
 
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
@@ -670,12 +668,14 @@
 		case MDP_BGR_565:
 		case MDP_XRGB_8888:
 		case MDP_RGB_888:
+		case MDP_YCBCR_H1V1:
+		case MDP_YCRCB_H1V1:
 			*luma_off = pipe->src_x * pipe->bpp;
 			break;
 
 		default:
-			pr_err("Source format %u not supported for x offset adjustment\n",
-				pipe->src_format);
+			pr_err("%s: fmt %u not supported for adjustment\n",
+				__func__, pipe->src_format);
 			break;
 		}
 	}
@@ -1552,15 +1552,14 @@
 			       mixer, data, flush_bits);
 
 			outpdw(MDP_BASE + off, data); /* LAYERMIXER_IN_CFG */
-			if (pull_mode)
+			if (pull_mode) {
 				outpdw(MDP_BASE + 0x18000, flush_bits);
+			/* wait for vsync on both pull mode interfaces */
+				msleep(20);
+			}
 		}
 
 		if (ctrl->mixer_cfg[MDP4_MIXER2] != cfg[MDP4_MIXER2]) {
-			/* wait for vsync on both pull mode interfaces */
-			if (pull_mode)
-				msleep(20);
-
 			off = 0x100F0;
 			ctrl->mixer_cfg[MDP4_MIXER2] = cfg[MDP4_MIXER2];
 			data = cfg[MDP4_MIXER2];
@@ -2983,33 +2982,34 @@
 } msm_iommu_ctx_names[] = {
 	/* Display */
 	{
-		.name = "mdp_vg1",
+		.name = "mdp_port0_cb0",
 		.domain = DISPLAY_DOMAIN,
 	},
 	/* Display */
 	{
-		.name = "mdp_vg2",
+		.name = "mdp_port0_cb1",
 		.domain = DISPLAY_DOMAIN,
 	},
 	/* Display */
 	{
-		.name = "mdp_rgb1",
+		.name = "mdp_port1_cb0",
 		.domain = DISPLAY_DOMAIN,
 	},
 	/* Display */
 	{
-		.name = "mdp_rgb2",
+		.name = "mdp_port1_cb1",
 		.domain = DISPLAY_DOMAIN,
 	},
 };
 
+static int iommu_enabled;
+
 void mdp4_iommu_attach(void)
 {
-	static int done;
 	struct iommu_domain *domain;
 	int i;
 
-	if (!done) {
+	if (!iommu_enabled) {
 		for (i = 0; i < ARRAY_SIZE(msm_iommu_ctx_names); i++) {
 			int domain_idx;
 			struct device *ctx = msm_iommu_get_ctx(
@@ -3032,7 +3032,35 @@
 				continue;
 			}
 		}
-		done = 1;
+		pr_debug("Attached MDP IOMMU device\n");
+		iommu_enabled = 1;
+	}
+}
+
+void mdp4_iommu_detach(void)
+{
+	struct iommu_domain *domain;
+	int i;
+
+	if (iommu_enabled) {
+		for (i = 0; i < ARRAY_SIZE(msm_iommu_ctx_names); i++) {
+			int domain_idx;
+			struct device *ctx = msm_iommu_get_ctx(
+				msm_iommu_ctx_names[i].name);
+
+			if (!ctx)
+				continue;
+
+			domain_idx = msm_iommu_ctx_names[i].domain;
+
+			domain = msm_get_iommu_domain(domain_idx);
+			if (!domain)
+				continue;
+
+			iommu_detach_device(domain,	ctx);
+		}
+		pr_debug("Detached MDP IOMMU device\n");
+		iommu_enabled = 0;
 	}
 }
 
@@ -3121,10 +3149,12 @@
 	else
 		mdp4_overlay_rgb_setup(pipe);
 
+	if (ctrl->panel_mode & MDP4_PANEL_LCDC)
+		mdp4_overlay_reg_flush(pipe, 1);
+
 	mdp4_mixer_stage_up(pipe);
 
 	if (ctrl->panel_mode & MDP4_PANEL_LCDC) {
-		mdp4_overlay_reg_flush(pipe, 1);
 		mdp4_overlay_lcdc_vsync_push(mfd, pipe);
 	} else {
 #ifdef CONFIG_FB_MSM_MIPI_DSI
diff --git a/drivers/video/msm/mdp4_overlay_atv.c b/drivers/video/msm/mdp4_overlay_atv.c
index dd827aa..753ff23 100644
--- a/drivers/video/msm/mdp4_overlay_atv.c
+++ b/drivers/video/msm/mdp4_overlay_atv.c
@@ -113,11 +113,10 @@
 
 	mdp4_overlay_rgb_setup(pipe);
 
-	mdp4_mixer_stage_up(pipe);
-
 	mdp4_overlayproc_cfg(pipe);
 
 	mdp4_overlay_reg_flush(pipe, 1);
+	mdp4_mixer_stage_up(pipe);
 
 	if (ret == 0)
 		mdp_pipe_ctrl(MDP_OVERLAY1_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
@@ -185,8 +184,8 @@
 		pipe->srcp0_addr = (uint32)(buf + buf_offset);
 	}
 	mdp4_overlay_rgb_setup(pipe);
-	mdp4_mixer_stage_up(pipe);
 	mdp4_overlay_reg_flush(pipe, 0);
+	mdp4_mixer_stage_up(pipe);
 
 	printk(KERN_INFO "mdp4_atv_overlay: pipe=%x ndx=%d\n",
 					(int)pipe, pipe->pipe_ndx);
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
index 8ab12590..8bed42d 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -197,8 +197,6 @@
 
 	mdp4_overlay_rgb_setup(pipe);
 
-	mdp4_mixer_stage_up(pipe);
-
 	mdp4_overlayproc_cfg(pipe);
 
 	/*
@@ -275,6 +273,7 @@
 	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x30, dsi_hsync_skew);
 	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x38, ctrl_polarity);
 	mdp4_overlay_reg_flush(pipe, 1);
+	mdp4_mixer_stage_up(pipe);
 
 	mdp_histogram_ctrl_all(TRUE);
 
@@ -311,6 +310,7 @@
 		mdp4_iommu_unmap(dsi_pipe);
 	}
 
+	mdp4_iommu_detach();
 	return ret;
 }
 
@@ -386,6 +386,8 @@
 
 	mdp4_overlay_dmap_cfg(mfd, 1);
 
+	mdp4_overlay_reg_flush(pipe, 1);
+
 	mdp4_mixer_stage_up(pipe);
 
 	mb();
@@ -705,8 +707,8 @@
 	}
 
 	mdp4_overlay_rgb_setup(pipe);
-	mdp4_mixer_stage_up(pipe);
 	mdp4_overlay_reg_flush(pipe, 0);
+	mdp4_mixer_stage_up(pipe);
 	mdp4_overlay_dsi_video_start();
 	mdp4_overlay_dsi_video_vsync_push(mfd, pipe);
 	mdp4_iommu_unmap(pipe);
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index e3917e6..8692b09 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -343,8 +343,8 @@
 		mdp4_overlay_rgb_setup(pipe);
 	}
 
-	mdp4_mixer_stage_up(pipe);
 	mdp4_overlay_reg_flush(pipe, 1);
+	mdp4_mixer_stage_up(pipe);
 
 	dtv_pipe = pipe; /* keep it */
 }
@@ -693,8 +693,8 @@
 		pipe->srcp0_addr = (uint32) mfd->ibuf.buf;
 		mdp4_overlay_rgb_setup(pipe);
 	}
-	mdp4_mixer_stage_up(pipe);
 	mdp4_overlay_reg_flush(pipe, 0);
+	mdp4_mixer_stage_up(pipe);
 	mdp4_overlay_dtv_start();
 	mdp4_overlay_dtv_ov_done_push(mfd, pipe);
 	mdp4_iommu_unmap(pipe);
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index 3f90380..72722ef 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -159,8 +159,6 @@
 
 	mdp4_overlay_rgb_setup(pipe);
 
-	mdp4_mixer_stage_up(pipe);
-
 	mdp4_overlayproc_cfg(pipe);
 
 	/*
@@ -243,6 +241,7 @@
 	MDP_OUTP(MDP_BASE + LCDC_BASE + 0x24, active_v_end);
 
 	mdp4_overlay_reg_flush(pipe, 1);
+	mdp4_mixer_stage_up(pipe);
 
 #ifdef CONFIG_MSM_BUS_SCALING
 	mdp_bus_scale_update_request(2);
@@ -291,6 +290,7 @@
 	mdp_bus_scale_update_request(0);
 #endif
 
+	mdp4_iommu_detach();
 	return ret;
 }
 
@@ -597,8 +597,8 @@
 		pipe->srcp0_addr = (uint32)(buf + buf_offset);
 	}
 	mdp4_overlay_rgb_setup(pipe);
-	mdp4_mixer_stage_up(pipe);
 	mdp4_overlay_reg_flush(pipe, 0);
+	mdp4_mixer_stage_up(pipe);
 	mdp4_overlay_lcdc_start();
 	mdp4_overlay_lcdc_vsync_push(mfd, pipe);
 	mdp4_iommu_unmap(pipe);
diff --git a/drivers/video/msm/mdp4_overlay_writeback.c b/drivers/video/msm/mdp4_overlay_writeback.c
index 2fba83d..342f565 100644
--- a/drivers/video/msm/mdp4_overlay_writeback.c
+++ b/drivers/video/msm/mdp4_overlay_writeback.c
@@ -273,6 +273,7 @@
 	if (node) {
 		list_del(&(node->active_entry));
 		node->state = IN_BUSY_QUEUE;
+		mfd->writeback_active_cnt++;
 	}
 	mutex_unlock(&mfd->writeback_mutex);
 
@@ -295,6 +296,7 @@
 	mutex_lock(&mfd->writeback_mutex);
 	list_add_tail(&node->active_entry, &mfd->writeback_busy_queue);
 	mutex_unlock(&mfd->writeback_mutex);
+	mfd->writeback_active_cnt--;
 	mutex_unlock(&mfd->unregister_mutex);
 	wake_up(&mfd->wait_q);
 }
@@ -323,6 +325,7 @@
 	if (node) {
 		list_del(&(node->active_entry));
 		node->state = IN_BUSY_QUEUE;
+		mfd->writeback_active_cnt++;
 	}
 	mutex_unlock(&mfd->writeback_mutex);
 
@@ -367,6 +370,7 @@
 
 	mutex_lock(&mfd->writeback_mutex);
 	list_add_tail(&node->active_entry, &mfd->writeback_busy_queue);
+	mfd->writeback_active_cnt--;
 	mutex_unlock(&mfd->writeback_mutex);
 	wake_up(&mfd->wait_q);
 fail_no_blt_addr:
@@ -523,13 +527,26 @@
 	return rc;
 }
 
+static bool is_writeback_inactive(struct msm_fb_data_type *mfd)
+{
+	bool active;
+	mutex_lock(&mfd->writeback_mutex);
+	active = !mfd->writeback_active_cnt;
+	mutex_unlock(&mfd->writeback_mutex);
+	return active;
+}
 int mdp4_writeback_stop(struct fb_info *info)
 {
 	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
 	mutex_lock(&mfd->writeback_mutex);
 	mfd->writeback_state = WB_STOPING;
 	mutex_unlock(&mfd->writeback_mutex);
+	/* Wait for all pending writebacks to finish */
+	wait_event_interruptible(mfd->wait_q, is_writeback_inactive(mfd));
+
+	/* Wake up dequeue thread in case of no UI update*/
 	wake_up(&mfd->wait_q);
+
 	return 0;
 }
 int mdp4_writeback_init(struct fb_info *info)
@@ -549,8 +566,19 @@
 	struct list_head *ptr, *next;
 	struct msmfb_writeback_data_list *temp;
 	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	int rc = 0;
+
 	mutex_lock(&mfd->unregister_mutex);
 	mutex_lock(&mfd->writeback_mutex);
+
+	if (mfd->writeback_state != WB_STOPING &&
+		mfd->writeback_state != WB_STOP) {
+		pr_err("%s called without stopping\n", __func__);
+		rc = -EPERM;
+		goto terminate_err;
+
+	}
+
 	if (!list_empty(&mfd->writeback_register_queue)) {
 		list_for_each_safe(ptr, next,
 				&mfd->writeback_register_queue) {
@@ -564,7 +592,10 @@
 	INIT_LIST_HEAD(&mfd->writeback_register_queue);
 	INIT_LIST_HEAD(&mfd->writeback_busy_queue);
 	INIT_LIST_HEAD(&mfd->writeback_free_queue);
+
+
+terminate_err:
 	mutex_unlock(&mfd->writeback_mutex);
 	mutex_unlock(&mfd->unregister_mutex);
-	return 0;
+	return rc;
 }
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index ce8744b..ff08548 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -48,11 +48,6 @@
 #include "mdp.h"
 #include "mdp4.h"
 
-#ifdef CONFIG_FB_MSM_LOGO
-#define INIT_IMAGE_FILE "/initlogo.rle"
-extern int load_565rle_image(char *filename);
-#endif
-
 #ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
 #define MSM_FB_NUM	3
 #endif
@@ -60,6 +55,7 @@
 static unsigned char *fbram;
 static unsigned char *fbram_phys;
 static int fbram_size;
+static boolean bf_supported;
 
 static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
 static int pdev_list_cnt;
@@ -375,6 +371,9 @@
 #ifdef CONFIG_FB_MSM_OVERLAY
 	mfd->overlay_play_enable = 1;
 #endif
+
+	bf_supported = mdp4_overlay_borderfill_supported();
+
 	rc = msm_fb_register(mfd);
 	if (rc)
 		return rc;
@@ -1183,7 +1182,7 @@
 	 * calculate smem_len based on max size of two supplied modes.
 	 * Only fb0 has mem. fb1 and fb2 don't have mem.
 	 */
-	if (mfd->index == 0)
+	if (!bf_supported || mfd->index == 0)
 		fix->smem_len = MAX((msm_fb_line_length(mfd->index,
 							panel_info->xres,
 							bpp) *
@@ -1302,7 +1301,7 @@
 	fbram_phys += fbram_offset;
 	fbram_size -= fbram_offset;
 
-	if (mfd->index == 0)
+	if (!bf_supported || mfd->index == 0)
 		if (fbram_size < fix->smem_len) {
 			pr_err("error: no more framebuffer memory!\n");
 			return -ENOMEM;
@@ -1320,7 +1319,7 @@
 			fbi->fix.smem_start, mfd->map_buffer->iova[0],
 			mfd->map_buffer->iova[1]);
 	}
-	if (mfd->index == 0)
+	if (!bf_supported || mfd->index == 0)
 		memset(fbi->screen_base, 0x0, fix->smem_len);
 
 	mfd->op_enable = TRUE;
@@ -1366,7 +1365,9 @@
 	     mfd->index, fbi->var.xres, fbi->var.yres, fbi->fix.smem_len);
 
 #ifdef CONFIG_FB_MSM_LOGO
-	if (!load_565rle_image(INIT_IMAGE_FILE)) ;	/* Flip buffer */
+	/* Flip buffer */
+	if (!load_565rle_image(INIT_IMAGE_FILE, bf_supported))
+		;
 #endif
 	ret = 0;
 
@@ -1526,9 +1527,10 @@
 	}
 
 	if (!mfd->ref_cnt) {
-		if ((info->node != 1) && (info->node != 2)) {
+		if (!bf_supported ||
+			(info->node != 1 && info->node != 2))
 			mdp_set_dma_pan_info(info, NULL, TRUE);
-		} else
+		else
 			pr_debug("%s:%d no mdp_set_dma_pan_info %d\n",
 				__func__, __LINE__, info->node);
 
@@ -1581,7 +1583,8 @@
 	/*
 	 * If framebuffer is 1 or 2, io pen display is not allowed.
 	 */
-	if (info->node == 1 || info->node == 2) {
+	if (bf_supported &&
+		(info->node == 1 || info->node == 2)) {
 		pr_err("%s: no pan display for fb%d!",
 		       __func__, info->node);
 		return -EPERM;
@@ -1761,7 +1764,8 @@
 	if ((var->xres_virtual <= 0) || (var->yres_virtual <= 0))
 		return -EINVAL;
 
-	if ((info->node != 1) && (info->node != 2))
+	if (!bf_supported ||
+		(info->node != 1 && info->node != 2))
 		if (info->fix.smem_len <
 		    (var->xres_virtual*
 		     var->yres_virtual*
@@ -2619,7 +2623,8 @@
 	struct mdp_blit_req_list req_list_header;
 
 	int count, i, req_list_count;
-	if (info->node == 1 || info->node == 2) {
+	if (bf_supported &&
+		(info->node == 1 || info->node == 2)) {
 		pr_err("%s: no pan display for fb%d.",
 		       __func__, info->node);
 		return -EPERM;
diff --git a/drivers/video/msm/msm_fb.h b/drivers/video/msm/msm_fb.h
index b63c022..87753b2 100644
--- a/drivers/video/msm/msm_fb.h
+++ b/drivers/video/msm/msm_fb.h
@@ -184,6 +184,7 @@
 	u32 use_ov0_blt, ov0_blt_state;
 	u32 use_ov1_blt, ov1_blt_state;
 	u32 writeback_state;
+	bool writeback_active_cnt;
 	int cont_splash_done;
 };
 
@@ -214,4 +215,9 @@
 int msm_fb_check_frame_rate(struct msm_fb_data_type *mfd,
 				struct fb_info *info);
 
+#ifdef CONFIG_FB_MSM_LOGO
+#define INIT_IMAGE_FILE "/initlogo.rle"
+int load_565rle_image(char *filename, bool bf_supported);
+#endif
+
 #endif /* MSM_FB_H */
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
index 86f282e..ac1ff24 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
@@ -469,6 +469,8 @@
 u32  ddl_check_reconfig(struct ddl_client_context *ddl);
 void ddl_handle_reconfig(u32 res_change, struct ddl_client_context *ddl);
 void ddl_fill_dec_desc_buffer(struct ddl_client_context *ddl);
+void ddl_set_vidc_timeout(struct ddl_client_context *ddl);
+
 
 #ifdef DDL_BUF_LOG
 void ddl_list_buffers(struct ddl_client_context *ddl);
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h
index 41604b0..50c3696 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h
@@ -55,6 +55,13 @@
 #define DDL_HW_TIMEOUT_IN_MS             1000
 #define DDL_STREAMBUF_ALIGN_GUARD_BYTES  0x7FF
 
+#define DDL_VIDC_1080P_48MHZ			(48000000)
+#define DDL_VIDC_1080P_133MHZ			(133330000)
+#define DDL_VIDC_1080P_200MHZ			(200000000)
+#define DDL_VIDC_1080P_48MHZ_TIMEOUT_VALUE	(0xCB8)
+#define DDL_VIDC_1080P_133MHZ_TIMEOUT_VALUE	(0x2355)
+#define DDL_VIDC_1080P_200MHZ_TIMEOUT_VALUE	(0x3500)
+
 #define DDL_CONTEXT_MEMORY (1024 * 15 * (VCD_MAX_NO_CLIENT + 1))
 
 #define DDL_ENC_MIN_DPB_BUFFERS           2
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
index 6d3a05a..b480b42 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
@@ -744,11 +744,11 @@
 				memset(dec_bufs->desc.align_virtual_addr,
 					   0, buf_size.sz_desc);
 				msm_ion_do_cache_op(
-						ddl_context->video_ion_client,
-						dec_bufs->desc.alloc_handle,
-						dec_bufs->desc.alloc_handle,
-						dec_bufs->desc.buffer_size,
-						ION_IOC_CLEAN_INV_CACHES);
+					ddl_context->video_ion_client,
+					dec_bufs->desc.alloc_handle,
+					dec_bufs->desc.virtual_base_addr,
+					dec_bufs->desc.buffer_size,
+					ION_IOC_CLEAN_INV_CACHES);
 			}
 		}
 	}
@@ -1061,3 +1061,24 @@
 			   ip_bitstream->desc_buf,
 			   ip_bitstream->desc_size);
 }
+
+void ddl_set_vidc_timeout(struct ddl_client_context *ddl)
+{
+	unsigned long core_clk_rate;
+	u32 vidc_time_out = 0;
+	if (ddl->codec_data.decoder.idr_only_decoding) {
+		vidc_time_out = 2 * DDL_VIDC_1080P_200MHZ_TIMEOUT_VALUE;
+	} else {
+		res_trk_get_clk_rate(&core_clk_rate);
+		if (core_clk_rate == DDL_VIDC_1080P_48MHZ)
+			vidc_time_out = DDL_VIDC_1080P_48MHZ_TIMEOUT_VALUE;
+		else if (core_clk_rate == DDL_VIDC_1080P_133MHZ)
+			vidc_time_out = DDL_VIDC_1080P_133MHZ_TIMEOUT_VALUE;
+		else
+			vidc_time_out = DDL_VIDC_1080P_200MHZ_TIMEOUT_VALUE;
+	}
+	DDL_MSG_HIGH("%s Video core time out value = 0x%x"
+		 __func__, vidc_time_out);
+	vidc_sm_set_video_core_timeout_value(
+		&ddl->shared_mem[ddl->command_channel], vidc_time_out);
+}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
index ac81916..878db62 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
@@ -243,6 +243,10 @@
 
 #define VIDC_SM_NUM_STUFF_BYTES_CONSUME_ADDR    0X01ac
 
+#define VIDC_SM_TIMEOUT_VALUE_ADDR        0x0158
+#define VIDC_SM_TIMEOUT_VALUE_BMSK        0xffffffff
+#define VIDC_SM_TIMEOUT_VALUE_SHFT        0
+
 #define VIDC_SM_ENC_EXT_CTRL_CLOSED_GOP_ENABLE_BMSK	0x40
 #define VIDC_SM_ENC_EXT_CTRL_CLOSED_GOP_ENABLE_SHFT	6
 
@@ -862,3 +866,11 @@
 	*output_buffer_size = DDL_MEM_READ_32(shared_mem,
 			VIDC_SM_BATCH_OUTPUT_SIZE_ADDR);
 }
+
+void vidc_sm_set_video_core_timeout_value(struct ddl_buf_addr *shared_mem,
+	u32 timeout)
+{
+	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_TIMEOUT_VALUE_ADDR,
+			timeout);
+}
+
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
index 7d9896f..6cd75595 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
@@ -191,4 +191,6 @@
 				u32 output_buffer_size);
 void vidc_sm_get_encoder_batch_output_size(struct ddl_buf_addr *shared_mem,
 	u32 *output_buffer_size);
+void vidc_sm_set_video_core_timeout_value(struct ddl_buf_addr *shared_mem,
+	u32 timeout);
 #endif
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
index 97c8d0d..d0cf4e8 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
@@ -977,6 +977,7 @@
 		DDL_MSG_ERROR("STATE-CRITICAL");
 		return VCD_ERR_FAIL;
 	}
+	ddl_set_vidc_timeout(ddl);
 	ddl_vidc_decode_set_metadata_output(decoder);
 	if (decoder->dp_buf.no_of_dec_pic_buf <
 		decoder->client_output_buf_req.actual_count)
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
index e71259a..c8365ce 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
@@ -382,7 +382,7 @@
 	return status;
 }
 
-static u32 res_trk_get_clk_rate(unsigned long *phclk_rate)
+u32 res_trk_get_clk_rate(unsigned long *phclk_rate)
 {
 	u32 status = true;
 	mutex_lock(&resource_context.lock);
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h
index 99b123c..2ae2512 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h
@@ -49,4 +49,5 @@
 int res_trk_disable_footswitch(void);
 void res_trk_release_fw_addr(void);
 u32 res_trk_estimate_perf_level(u32 pn_perf_lvl);
+u32 res_trk_get_clk_rate(unsigned long *phclk_rate);
 #endif
diff --git a/include/linux/dvb/dmx.h b/include/linux/dvb/dmx.h
index 7f963e6..5abadb6 100644
--- a/include/linux/dvb/dmx.h
+++ b/include/linux/dvb/dmx.h
@@ -99,16 +99,40 @@
 } dmx_filter_t;
 
 
+/* Filter flags */
+#define DMX_CHECK_CRC		0x01
+#define DMX_ONESHOT		0x02
+#define DMX_IMMEDIATE_START	0x04
+#define DMX_ENABLE_INDEXING	0x08
+#define DMX_KERNEL_CLIENT	0x8000
+
 struct dmx_sct_filter_params
 {
 	__u16          pid;
 	dmx_filter_t   filter;
 	__u32          timeout;
 	__u32          flags;
-#define DMX_CHECK_CRC       1
-#define DMX_ONESHOT         2
-#define DMX_IMMEDIATE_START 4
-#define DMX_KERNEL_CLIENT   0x8000
+};
+
+
+/* Indexing: supported video standards */
+enum dmx_indexing_video_standard {
+	DMX_INDEXING_MPEG2,
+	DMX_INDEXING_H264,
+	DMX_INDEXING_VC1
+};
+
+/* Indexing: Supported video profiles */
+enum dmx_indexing_video_profile {
+	DMX_INDEXING_MPEG2_ANY,
+	DMX_INDEXING_H264_ANY,
+	DMX_INDEXING_VC1_ANY
+};
+
+/* Indexing: video configuration parameters */
+struct dmx_indexing_video_params {
+	enum dmx_indexing_video_standard standard;
+	enum dmx_indexing_video_profile profile;
 };
 
 
@@ -119,6 +143,8 @@
 	dmx_output_t   output;
 	dmx_pes_type_t pes_type;
 	__u32          flags;
+
+	struct dmx_indexing_video_params video_params;
 };
 
 struct dmx_buffer_status {
diff --git a/include/linux/input.h b/include/linux/input.h
index 6e7d6d9..191f7d7 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -817,7 +817,8 @@
 #define SW_ROTATE_LOCK		0x0c  /* set = rotate locked/disabled */
 #define SW_HPHL_OVERCURRENT	0x0d  /* set = over current on left hph */
 #define SW_HPHR_OVERCURRENT	0x0e  /* set = over current on right hph */
-#define SW_MAX			0x0f
+#define SW_UNSUPPORT_INSERT	0x0f  /* set = unsupported device inserted */
+#define SW_MAX			0x10
 #define SW_CNT			(SW_MAX+1)
 
 /*
diff --git a/include/linux/mfd/wcd9xxx/core.h b/include/linux/mfd/wcd9xxx/core.h
index fca9a94..7917d24 100644
--- a/include/linux/mfd/wcd9xxx/core.h
+++ b/include/linux/mfd/wcd9xxx/core.h
@@ -30,6 +30,13 @@
 	(((ver == TABLA_VERSION_1_0) || (ver == TABLA_VERSION_1_1)) ? 1 : 0)
 #define TABLA_IS_2_0(ver) ((ver == TABLA_VERSION_2_0) ? 1 : 0)
 
+#define SITAR_VERSION_1P0 0
+#define SITAR_VERSION_1P1 1
+#define SITAR_IS_1P0(ver) \
+	((ver == SITAR_VERSION_1P0) ? 1 : 0)
+#define SITAR_IS_1P1(ver) \
+	((ver == SITAR_VERSION_1P1) ? 1 : 0)
+
 enum {
 	TABLA_IRQ_SLIMBUS = 0,
 	TABLA_IRQ_MBHC_REMOVAL,
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index aa808dc..14f2d43 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -52,6 +52,9 @@
 	u8			part_config;
 	u8			cache_ctrl;
 	u8			rst_n_function;
+	u8			max_packed_writes;
+	u8			max_packed_reads;
+	u8			packed_event_en;
 	unsigned int		part_time;		/* Units: ms */
 	unsigned int		sa_timeout;		/* Units: 100ns */
 	unsigned int		generic_cmd6_time;	/* Units: 10ms */
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index c9a17de..2489bb5 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -249,7 +249,11 @@
 #define MMC_CAP2_HS200_1_2V_SDR	(1 << 6)        /* can support */
 #define MMC_CAP2_HS200		(MMC_CAP2_HS200_1_8V_SDR | \
 				 MMC_CAP2_HS200_1_2V_SDR)
-#define MMC_CAP2_DETECT_ON_ERR	(1 << 8)	/* On I/O err check card removal */
+#define MMC_CAP2_DETECT_ON_ERR	(1 << 7)	/* On I/O err check card removal */
+#define MMC_CAP2_PACKED_RD	(1 << 10)	/* Allow packed read */
+#define MMC_CAP2_PACKED_WR	(1 << 11)	/* Allow packed write */
+#define MMC_CAP2_PACKED_CMD	(MMC_CAP2_PACKED_RD | \
+				 MMC_CAP2_PACKED_WR) /* Allow packed commands */
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
 	unsigned int        power_notify_type;
 #define MMC_HOST_PW_NOTIFY_NONE		0
@@ -344,12 +348,8 @@
 #ifdef CONFIG_MMC_PERF_PROFILING
 	struct {
 
-		unsigned long rbytes_mmcq; /* Rd bytes MMC queue */
-		unsigned long wbytes_mmcq; /* Wr bytes MMC queue */
 		unsigned long rbytes_drv;  /* Rd bytes MMC Host  */
 		unsigned long wbytes_drv;  /* Wr bytes MMC Host  */
-		ktime_t rtime_mmcq;	   /* Rd time  MMC queue */
-		ktime_t wtime_mmcq;	   /* Wr time  MMC queue */
 		ktime_t rtime_drv;	   /* Rd time  MMC Host  */
 		ktime_t wtime_drv;	   /* Wr time  MMC Host  */
 		ktime_t start;
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index e124fbe..06539dff 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -140,6 +140,7 @@
 #define R1_READY_FOR_DATA	(1 << 8)	/* sx, a */
 #define R1_SWITCH_ERROR		(1 << 7)	/* sx, c */
 #define R1_APP_CMD		(1 << 5)	/* sr, c */
+#define R1_EXP_EVENT		(1 << 6)	/* sr, a */
 
 #define R1_STATE_IDLE	0
 #define R1_STATE_READY	1
@@ -275,6 +276,10 @@
 #define EXT_CSD_FLUSH_CACHE		32      /* W */
 #define EXT_CSD_CACHE_CTRL		33      /* R/W */
 #define EXT_CSD_POWER_OFF_NOTIFICATION	34	/* R/W */
+#define EXT_CSD_PACKED_FAILURE_INDEX	35	/* RO */
+#define EXT_CSD_PACKED_CMD_STATUS	36	/* RO */
+#define EXT_CSD_EXP_EVENTS_STATUS	54	/* RO, 2 bytes */
+#define EXT_CSD_EXP_EVENTS_CTRL	56	/* R/W, 2 bytes */
 #define EXT_CSD_PARTITION_ATTRIBUTE	156	/* R/W */
 #define EXT_CSD_PARTITION_SUPPORT	160	/* RO */
 #define EXT_CSD_HPI_MGMT		161	/* R/W */
@@ -314,6 +319,8 @@
 #define EXT_CSD_POWER_OFF_LONG_TIME	247	/* RO */
 #define EXT_CSD_GENERIC_CMD6_TIME	248	/* RO */
 #define EXT_CSD_CACHE_SIZE		249	/* RO, 4 bytes */
+#define EXT_CSD_MAX_PACKED_WRITES	500	/* RO */
+#define EXT_CSD_MAX_PACKED_READS	501	/* RO */
 #define EXT_CSD_HPI_FEATURES		503	/* RO */
 
 /*
@@ -426,6 +433,14 @@
 #define EXT_CSD_PWR_CL_4BIT_MASK	0x0F	/* 8 bit PWR CLS */
 #define EXT_CSD_PWR_CL_8BIT_SHIFT	4
 #define EXT_CSD_PWR_CL_4BIT_SHIFT	0
+
+#define EXT_CSD_PACKED_EVENT_EN	(1 << 3)
+
+#define EXT_CSD_PACKED_FAILURE	(1 << 3)
+
+#define EXT_CSD_PACKED_GENERIC_ERROR	(1 << 0)
+#define EXT_CSD_PACKED_INDEXED_ERROR	(1 << 1)
+
 /*
  * MMC_SWITCH access modes
  */
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index cb394e8..b4e14d2 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -292,7 +292,7 @@
 #define INPUT_DEVICE_ID_LED_MAX		0x0f
 #define INPUT_DEVICE_ID_SND_MAX		0x07
 #define INPUT_DEVICE_ID_FF_MAX		0x7f
-#define INPUT_DEVICE_ID_SW_MAX		0x0f
+#define INPUT_DEVICE_ID_SW_MAX		0x10
 
 #define INPUT_DEVICE_ID_MATCH_BUS	1
 #define INPUT_DEVICE_ID_MATCH_VENDOR	2
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 6e96f85..c68457e 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -177,6 +177,9 @@
  * @enable_dcd: Enable Data Contact Detection circuit. if not set
  *              wait for 600msec before proceeding to primary
  *              detection.
+ * @enable_lpm_on_suspend: Enable the USB core to go into Low
+ *              Power Mode, when USB bus is suspended but cable
+ *              is connected.
  * @bus_scale_table: parameters for bus bandwidth requirements
  */
 struct msm_otg_platform_data {
@@ -192,6 +195,7 @@
 	bool mhl_enable;
 	bool disable_reset_on_disconnect;
 	bool enable_dcd;
+	bool enable_lpm_on_dev_suspend;
 	struct msm_bus_scale_pdata *bus_scale_table;
 };
 
@@ -322,6 +326,11 @@
 	 * voltage regulator(VDDCX).
 	 */
 #define ALLOW_PHY_RETENTION		BIT(1)
+	  /*
+	   * Allow putting the core in Low Power mode, when
+	   * USB bus is suspended but cable is connected.
+	   */
+#define ALLOW_LPM_ON_DEV_SUSPEND	    BIT(2)
 	unsigned long lpm_flags;
 #define PHY_PWR_COLLAPSED		BIT(0)
 #define PHY_RETENTIONED			BIT(1)
diff --git a/include/media/vcap_fmt.h b/include/media/vcap_fmt.h
index 4a62bc3..e69f9b0 100644
--- a/include/media/vcap_fmt.h
+++ b/include/media/vcap_fmt.h
@@ -14,8 +14,8 @@
 #ifndef VCAP_FMT_H
 #define VCAP_FMT_H
 
-#define V4L2_BUF_TYPE_INTERLACED_IN_AFE (V4L2_BUF_TYPE_PRIVATE)
-#define V4L2_BUF_TYPE_INTERLACED_IN_DECODER (V4L2_BUF_TYPE_PRIVATE + 1)
+#define V4L2_BUF_TYPE_INTERLACED_IN_DECODER (V4L2_BUF_TYPE_PRIVATE)
+#define V4L2_BUF_TYPE_VP_OUT (V4L2_BUF_TYPE_PRIVATE + 1)
 
 enum hal_vcap_mode {
 	HAL_VCAP_MODE_PRO = 0,
@@ -32,87 +32,7 @@
 	HAL_VCAP_RGB,
 };
 
-enum hal_vcap_vc_fmt {
-	/* 1080p */
-	HAL_VCAP_YUV_1080p_60_RH = 0,
-	HAL_VCAP_YUV_1080p_60_FL,
-	HAL_VCAP_RGB_1080p_60_FL,
-	HAL_VCAP_YUV_1080p_24_FL,
-	HAL_VCAP_YUV_1080p_24_RH,
-	HAL_VCAP_YUV_1080p_24_RW,
-	HAL_VCAP_YUV_1080p_60_RW,
-	HAL_VCAP_YUV_1080p_50_FL,
-	HAL_VCAP_YUV_1080p_50_RH,
-	HAL_VCAP_YUV_1080p_25_FL,
-	HAL_VCAP_YUV_1080p_25_RH,
-	HAL_VCAP_YUV_1080p_30_RH,
-	HAL_VCAP_RGB_1080p_25_FL,
-	HAL_VCAP_RGB_1080p_25_RH,
-	/* 1080i */
-	HAL_VCAP_YUV_1080i_60_FL,
-	HAL_VCAP_YUV_1080i_60_RH,
-	HAL_VCAP_YUV_1080i_60_RW,
-	HAL_VCAP_YUV_1080i_50_FL,
-	HAL_VCAP_YUV_1080i_50_RH,
-	HAL_VCAP_YUV_1080i_50_RW,
-	HAL_VCAP_RGB_1080i_50_FL,
-	HAL_VCAP_RGB_1080i_50_RH,
-	/* 480i */
-	HAL_VCAP_YUV_480i_60_RH,
-	HAL_VCAP_YUV_480i_60_FL,
-	HAL_VCAP_YUV_480i_60_RW,
-	HAL_VCAP_YUV_2880_480i_60_FL,
-	HAL_VCAP_YUV_2880_480i_60_RH,
-	/* 480p */
-	HAL_VCAP_YUV_480p_60_RH,
-	HAL_VCAP_RGB_480p_60_RH,
-	HAL_VCAP_RGB_480p_60_FL,
-	HAL_VCAP_YUV_480p_60_FL,
-	HAL_VCAP_YUV_480p_60_RW,
-	HAL_VCAP_YUV_2880_480p_60_FL,
-	HAL_VCAP_YUV_2880_480p_60_RH,
-	/* 720p */
-	HAL_VCAP_YUV_720p_60_FL,
-	HAL_VCAP_RGB_720p_60_FL,
-	HAL_VCAP_YUV_720p_60_RW,
-	HAL_VCAP_YUV_720p_60_RH,
-	HAL_VCAP_YUV_720p_50_FL,
-	HAL_VCAP_YUV_720p_50_RW,
-	HAL_VCAP_YUV_720p_50_RH,
-	/* 576p */
-	HAL_VCAP_YUV_576p_50_FL,
-	HAL_VCAP_RGB_576p_50_FL,
-	HAL_VCAP_YUV_576p_50_RW,
-	HAL_VCAP_YUV_576p_50_RH,
-	HAL_VCAP_YUV_1440_576p_50_RH,
-	HAL_VCAP_YUV_2880_576p_50_FL,
-	HAL_VCAP_YUV_2880_576p_50_RH,
-	/* 576i */
-	HAL_VCAP_YUV_576i_50_FL,
-	HAL_VCAP_YUV_576i_50_RW,
-	HAL_VCAP_YUV_576i_50_RH,
-	/* XGA 1024x768 */
-	HAL_VCAP_YUV_XGA_FL,
-	HAL_VCAP_YUV_XGA_RH,
-	HAL_VCAP_YUV_XGA_RB,
-	/* SXGA 1280x1024 */
-	HAL_VCAP_YUV_SXGA_FL,
-	HAL_VCAP_RGB_SXGA_FL,
-	HAL_VCAP_YUV_SXGA_RH,
-	HAL_VCAP_YUV_SXGA_RB,
-	/* UXGA 1600x1200 */
-	HAL_VCAP_YUV_UXGA_FL,
-	HAL_VCAP_RGB_UXGA_FL,
-	HAL_VCAP_YUV_UXGA_RH,
-	HAL_VCAP_YUV_UXGA_RB,
-	/* test odd height */
-	HAL_VCAP_ODD_HEIGHT,
-	/* test odd width RGB only */
-	HAL_VCAP_ODD_WIDTH,
-};
-
 struct v4l2_format_vc_ext {
-	enum hal_vcap_vc_fmt   format;
 	enum hal_vcap_mode     mode;
 	enum hal_vcap_polar    h_polar;
 	enum hal_vcap_polar    v_polar;
@@ -136,5 +56,21 @@
 	uint32_t f2_vsync_h_end;
 	uint32_t f2_vsync_v_start;
 	uint32_t f2_vsync_v_end;
+	uint32_t sizeimage;
+	uint32_t bytesperline;
+};
+
+enum vcap_type {
+	VC_TYPE,
+	VP_IN_TYPE,
+	VP_OUT_TYPE,
+};
+
+struct vcap_priv_fmt {
+	enum vcap_type type;
+	union {
+		struct v4l2_format_vc_ext timing;
+		/* Once VP is created there will be another type in here */
+	} u;
 };
 #endif
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 5749293..47b856c 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -26,7 +26,7 @@
 #define __HCI_CORE_H
 
 #include <net/bluetooth/hci.h>
-
+#include <linux/wakelock.h>
 /* HCI upper protocols */
 #define HCI_PROTO_L2CAP	0
 #define HCI_PROTO_SCO	1
@@ -326,7 +326,7 @@
 
 	struct work_struct work_add;
 	struct work_struct work_del;
-
+	struct wake_lock idle_lock;
 	struct device	dev;
 	atomic_t	devref;
 
diff --git a/include/sound/jack.h b/include/sound/jack.h
index ccdc341..1b13cbb 100644
--- a/include/sound/jack.h
+++ b/include/sound/jack.h
@@ -35,24 +35,26 @@
  * sound/core/jack.c.
  */
 enum snd_jack_types {
-	SND_JACK_HEADPHONE	= 0x0001,
-	SND_JACK_MICROPHONE	= 0x0002,
+	SND_JACK_HEADPHONE	= 0x0000001,
+	SND_JACK_MICROPHONE	= 0x0000002,
 	SND_JACK_HEADSET	= SND_JACK_HEADPHONE | SND_JACK_MICROPHONE,
-	SND_JACK_LINEOUT	= 0x0004,
-	SND_JACK_MECHANICAL	= 0x0008, /* If detected separately */
-	SND_JACK_VIDEOOUT	= 0x0010,
+	SND_JACK_LINEOUT	= 0x0000004,
+	SND_JACK_MECHANICAL	= 0x0000008, /* If detected separately */
+	SND_JACK_VIDEOOUT	= 0x0000010,
 	SND_JACK_AVOUT		= SND_JACK_LINEOUT | SND_JACK_VIDEOOUT,
-	SND_JACK_OC_HPHL	= 0x0020,
-	SND_JACK_OC_HPHR	= 0x0040,
+	/* */
+	SND_JACK_OC_HPHL	= 0x0000020,
+	SND_JACK_OC_HPHR	= 0x0000040,
+	SND_JACK_UNSUPPORTED	= 0x0000080,
 	/* Kept separate from switches to facilitate implementation */
-	SND_JACK_BTN_0		= 0x4000,
-	SND_JACK_BTN_1		= 0x2000,
-	SND_JACK_BTN_2		= 0x1000,
-	SND_JACK_BTN_3		= 0x0800,
-	SND_JACK_BTN_4		= 0x0400,
-	SND_JACK_BTN_5		= 0x0200,
-	SND_JACK_BTN_6		= 0x0100,
-	SND_JACK_BTN_7		= 0x0080,
+	SND_JACK_BTN_0		= 0x4000000,
+	SND_JACK_BTN_1		= 0x2000000,
+	SND_JACK_BTN_2		= 0x1000000,
+	SND_JACK_BTN_3		= 0x0800000,
+	SND_JACK_BTN_4		= 0x0400000,
+	SND_JACK_BTN_5		= 0x0200000,
+	SND_JACK_BTN_6		= 0x0100000,
+	SND_JACK_BTN_7		= 0x0080000,
 };
 
 struct snd_jack {
diff --git a/include/sound/msm-dai-q6.h b/include/sound/msm-dai-q6.h
index 6328256..042aa6f 100644
--- a/include/sound/msm-dai-q6.h
+++ b/include/sound/msm-dai-q6.h
@@ -21,8 +21,7 @@
 #define MSM_MI2S_CAP_RX 0
 #define MSM_MI2S_CAP_TX 1
 
-struct msm_dai_auxpcm_pdata {
-	const char *clk;
+struct msm_dai_auxpcm_config {
 	u16 mode;
 	u16 sync;
 	u16 frame;
@@ -36,4 +35,11 @@
 	u16 rx_sd_lines;
 	u16 tx_sd_lines;
 };
+
+struct msm_dai_auxpcm_pdata {
+	const char *clk;
+	struct msm_dai_auxpcm_config mode_8k;
+	struct msm_dai_auxpcm_config mode_16k;
+};
+
 #endif
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 25b559b1..02ea082 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -448,6 +448,7 @@
 
 	conn->power_save = 1;
 	conn->disc_timeout = HCI_DISCONN_TIMEOUT;
+	wake_lock_init(&conn->idle_lock, WAKE_LOCK_SUSPEND, "bt_idle");
 
 	switch (type) {
 	case ACL_LINK:
@@ -521,6 +522,7 @@
 
 	/* Make sure no timers are running */
 	del_timer(&conn->idle_timer);
+	wake_lock_destroy(&conn->idle_lock);
 	del_timer(&conn->disc_timer);
 	del_timer(&conn->smp_timer);
 	__cancel_delayed_work(&conn->rssi_update_work);
@@ -962,9 +964,11 @@
 	}
 
 timer:
-	if (hdev->idle_timeout > 0)
+	if (hdev->idle_timeout > 0) {
 		mod_timer(&conn->idle_timer,
 			jiffies + msecs_to_jiffies(hdev->idle_timeout));
+		wake_lock(&conn->idle_lock);
+	}
 }
 
 static inline void hci_conn_stop_rssi_timer(struct hci_conn *conn)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 395a95c..9e545f3 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2556,6 +2556,9 @@
 			else
 				conn->power_save = 0;
 		}
+		if (conn->mode == HCI_CM_SNIFF)
+			if (wake_lock_active(&conn->idle_lock))
+				wake_unlock(&conn->idle_lock);
 
 		if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
 			hci_sco_setup(conn, ev->status);
diff --git a/sound/core/jack.c b/sound/core/jack.c
index 80453a9..675f45b 100644
--- a/sound/core/jack.c
+++ b/sound/core/jack.c
@@ -32,6 +32,7 @@
 	SW_VIDEOOUT_INSERT,
 	SW_HPHL_OVERCURRENT,
 	SW_HPHR_OVERCURRENT,
+	SW_UNSUPPORT_INSERT,
 };
 
 static int snd_jack_dev_free(struct snd_device *device)
diff --git a/sound/soc/codecs/wcd9304.c b/sound/soc/codecs/wcd9304.c
index 9041bd7..ff83197 100644
--- a/sound/soc/codecs/wcd9304.c
+++ b/sound/soc/codecs/wcd9304.c
@@ -1775,6 +1775,9 @@
 	{"HEADPHONE", NULL, "HPHL"},
 	{"HEADPHONE", NULL, "HPHR"},
 
+	{"HPHL DAC", NULL, "CP"},
+	{"HPHR DAC", NULL, "CP"},
+
 	{"HPHL", NULL, "HPHL DAC"},
 	{"HPHL DAC", "NULL", "DAC4 MUX"},
 	{"HPHR", NULL, "HPHR DAC"},
@@ -1950,9 +1953,11 @@
 
 static void sitar_codec_enable_audio_mode_bandgap(struct snd_soc_codec *codec)
 {
+	struct wcd9xxx *sitar_core = dev_get_drvdata(codec->dev->parent);
 
-	snd_soc_update_bits(codec, SITAR_A_LDO_H_MODE_1, 0x0C, 0x04);
-	snd_soc_update_bits(codec, SITAR_A_LDO_H_MODE_1, 0x80, 0x80);
+	if (SITAR_IS_1P0(sitar_core->version))
+		snd_soc_update_bits(codec, SITAR_A_LDO_H_MODE_1, 0x80, 0x80);
+
 	snd_soc_update_bits(codec, SITAR_A_BIAS_CURR_CTL_2, 0x0C, 0x08);
 	usleep_range(1000, 1000);
 	snd_soc_write(codec, SITAR_A_BIAS_REF_CTL, 0x1C);
@@ -1971,6 +1976,7 @@
 	enum sitar_bandgap_type choice)
 {
 	struct sitar_priv *sitar = snd_soc_codec_get_drvdata(codec);
+	struct wcd9xxx *sitar_core = dev_get_drvdata(codec->dev->parent);
 
 	/* TODO lock resources accessed by audio streams and threaded
 	* interrupt handlers
@@ -2005,7 +2011,9 @@
 	} else if (choice == SITAR_BANDGAP_OFF) {
 		snd_soc_update_bits(codec, SITAR_A_BIAS_CURR_CTL_2, 0x0C, 0x00);
 		snd_soc_write(codec, SITAR_A_BIAS_CENTRAL_BG_CTL, 0x50);
-		snd_soc_update_bits(codec, SITAR_A_LDO_H_MODE_1, 0xFF, 0x65);
+		if (SITAR_IS_1P0(sitar_core->version))
+			snd_soc_update_bits(codec, SITAR_A_LDO_H_MODE_1,
+								0xFF, 0x65);
 		usleep_range(1000, 1000);
 	} else {
 		pr_err("%s: Error, Invalid bandgap settings\n", __func__);
@@ -4327,6 +4335,8 @@
 	}
 
 	/* Set voltage level and always use LDO */
+	snd_soc_update_bits(codec, SITAR_A_LDO_H_MODE_1, 0x0C,
+		(pdata->micbias.ldoh_v << 2));
 
 	snd_soc_update_bits(codec, SITAR_A_MICB_CFILT_1_VAL, 0xFC,
 		(k1 << 2));
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index cad9907..5d77afd 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -3546,6 +3546,10 @@
 	if (tabla_is_digital_gain_register(reg))
 		return 1;
 
+	/* HPH status registers */
+	if (reg == TABLA_A_RX_HPH_L_STATUS || reg == TABLA_A_RX_HPH_R_STATUS)
+		return 1;
+
 	return 0;
 }
 
diff --git a/sound/soc/msm/apq8064.c b/sound/soc/msm/apq8064.c
index c8ef419..0c72880 100644
--- a/sound/soc/msm/apq8064.c
+++ b/sound/soc/msm/apq8064.c
@@ -58,6 +58,8 @@
 #define TABLA_MBHC_DEF_BUTTONS 8
 #define TABLA_MBHC_DEF_RLOADS 5
 
+#define JACK_DETECT_GPIO 38
+
 /* Shared channel numbers for Slimbus ports that connect APQ to MDM. */
 enum {
 	SLIM_1_RX_1 = 145, /* BT-SCO and USB TX */
@@ -97,6 +99,15 @@
 static struct snd_soc_jack hs_jack;
 static struct snd_soc_jack button_jack;
 
+static int apq8064_hs_detect_use_gpio = -1;
+module_param(apq8064_hs_detect_use_gpio, int, 0444);
+MODULE_PARM_DESC(apq8064_hs_detect_use_gpio, "Use GPIO for headset detection");
+
+static bool apq8064_hs_detect_use_firmware;
+module_param(apq8064_hs_detect_use_firmware, bool, 0444);
+MODULE_PARM_DESC(apq8064_hs_detect_use_firmware, "Use firmware for headset "
+		 "detection");
+
 static int msm_enable_codec_ext_clk(struct snd_soc_codec *codec, int enable,
 				    bool dapm);
 
@@ -108,7 +119,7 @@
 	.micbias = TABLA_MICBIAS2,
 	.mclk_cb_fn = msm_enable_codec_ext_clk,
 	.mclk_rate = TABLA_EXT_CLK_RATE,
-	.gpio = 0, /* MBHC GPIO is not configured */
+	.gpio = 0,
 	.gpio_irq = 0,
 	.gpio_level_insert = 1,
 };
@@ -1037,10 +1048,10 @@
 	return ret;
 }
 
-
 static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
 {
 	int err;
+	uint32_t revision;
 	struct snd_soc_codec *codec = rtd->codec;
 	struct snd_soc_dapm_context *dapm = &codec->dapm;
 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
@@ -1097,6 +1108,48 @@
 
 	codec_clk = clk_get(cpu_dai->dev, "osr_clk");
 
+	/* APQ8064 Rev 1.1 CDP and Liquid have mechanical switch */
+	revision = socinfo_get_version();
+	if (apq8064_hs_detect_use_gpio != -1) {
+		if (apq8064_hs_detect_use_gpio == 1)
+			pr_debug("%s: MBHC mechanical is enabled by request\n",
+				 __func__);
+		else if (apq8064_hs_detect_use_gpio == 0)
+			pr_debug("%s: MBHC mechanical is disabled by request\n",
+				 __func__);
+		else
+			pr_warn("%s: Invalid hs_detect_use_gpio %d\n", __func__,
+				apq8064_hs_detect_use_gpio);
+	} else if (SOCINFO_VERSION_MAJOR(revision) == 0) {
+		pr_warn("%s: Unknown HW revision detected %d.%d\n", __func__,
+			SOCINFO_VERSION_MAJOR(revision),
+			SOCINFO_VERSION_MINOR(revision));
+	} else if ((SOCINFO_VERSION_MAJOR(revision) == 1 &&
+		    SOCINFO_VERSION_MINOR(revision) >= 1 &&
+		    (machine_is_apq8064_cdp() ||
+		     machine_is_apq8064_liquid())) ||
+		   SOCINFO_VERSION_MAJOR(revision) > 1) {
+		pr_debug("%s: MBHC mechanical switch available APQ8064 "
+			 "detected\n", __func__);
+		apq8064_hs_detect_use_gpio = 1;
+	}
+
+	if (apq8064_hs_detect_use_gpio == 1) {
+		pr_debug("%s: Using MBHC mechanical switch\n", __func__);
+		mbhc_cfg.gpio = JACK_DETECT_GPIO;
+		mbhc_cfg.gpio_irq = gpio_to_irq(JACK_DETECT_GPIO);
+		err = gpio_request(mbhc_cfg.gpio, "MBHC_HS_DETECT");
+		if (err < 0) {
+			pr_err("%s: gpio_request %d failed %d\n", __func__,
+			       mbhc_cfg.gpio, err);
+			return err;
+		}
+		gpio_direction_input(JACK_DETECT_GPIO);
+	} else
+		pr_debug("%s: Not using MBHC mechanical switch\n", __func__);
+
+	mbhc_cfg.read_fw_bin = apq8064_hs_detect_use_firmware;
+
 	err = tabla_hs_detect(codec, &mbhc_cfg);
 
 	return err;
@@ -1119,7 +1172,8 @@
 	},
 };
 
-static struct snd_soc_dsp_link slimbus0_hl_media = {
+/* bi-directional media definition for hostless PCM device */
+static struct snd_soc_dsp_link bidir_hl_media = {
 	.playback = true,
 	.capture = true,
 	.trigger = {
@@ -1128,9 +1182,8 @@
 	},
 };
 
-static struct snd_soc_dsp_link int_fm_hl_media = {
+static struct snd_soc_dsp_link hdmi_rx_hl = {
 	.playback = true,
-	.capture = true,
 	.trigger = {
 		SND_SOC_DSP_TRIGGER_POST,
 		SND_SOC_DSP_TRIGGER_POST
@@ -1377,7 +1430,7 @@
 		.name = "MSM8960 Media2",
 		.stream_name = "MultiMedia2",
 		.cpu_dai_name	= "MultiMedia2",
-		.platform_name  = "msm-pcm-dsp",
+		.platform_name  = "msm-multi-ch-pcm-dsp",
 		.dynamic = 1,
 		.dsp_link = &fe_media,
 		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA2,
@@ -1418,7 +1471,7 @@
 		.cpu_dai_name	= "SLIMBUS0_HOSTLESS",
 		.platform_name  = "msm-pcm-hostless",
 		.dynamic = 1,
-		.dsp_link = &slimbus0_hl_media,
+		.dsp_link = &bidir_hl_media,
 		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
 		.ignore_suspend = 1,
 		/* .be_id = do not care */
@@ -1429,7 +1482,7 @@
 		.cpu_dai_name	= "INT_FM_HOSTLESS",
 		.platform_name  = "msm-pcm-hostless",
 		.dynamic = 1,
-		.dsp_link = &int_fm_hl_media,
+		.dsp_link = &bidir_hl_media,
 		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
 		.ignore_suspend = 1,
 		/* .be_id = do not care */
@@ -1453,6 +1506,37 @@
 		.ignore_suspend = 1,
 	},
 	{
+		.name = "MSM8960 Compr",
+		.stream_name = "COMPR",
+		.cpu_dai_name	= "MultiMedia4",
+		.platform_name  = "msm-compr-dsp",
+		.dynamic = 1,
+		.dsp_link = &lpa_fe_media,
+		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA4,
+	},
+	{
+		.name = "AUXPCM Hostless",
+		.stream_name = "AUXPCM Hostless",
+		.cpu_dai_name	= "AUXPCM_HOSTLESS",
+		.platform_name  = "msm-pcm-hostless",
+		.dynamic = 1,
+		.dsp_link = &bidir_hl_media,
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+	},
+	/* HDMI Hostless */
+	{
+		.name = "HDMI_RX_HOSTLESS",
+		.stream_name = "HDMI_RX_HOSTLESS",
+		.cpu_dai_name = "HDMI_HOSTLESS",
+		.platform_name = "msm-pcm-hostless",
+		.dynamic = 1,
+		.dsp_link = &hdmi_rx_hl,
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.no_codec = 1,
+		.ignore_suspend = 1,
+	},
+	{
 		.name = "Voice Stub",
 		.stream_name = "Voice Stub",
 		.cpu_dai_name = "VOICE_STUB",
@@ -1826,6 +1910,8 @@
 	}
 	msm_free_headset_mic_gpios();
 	platform_device_unregister(msm_snd_device);
+	if (mbhc_cfg.gpio)
+		gpio_free(mbhc_cfg.gpio);
 	kfree(mbhc_cfg.calibration);
 }
 module_exit(msm_audio_exit);
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 6c44cba..a050771 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -256,21 +256,21 @@
 	{
 		.playback = {
 			.stream_name = "AUXPCM Hostless Playback",
-			.rates = SNDRV_PCM_RATE_8000,
+			.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
 			.channels_min = 1,
 			.channels_max = 1,
 			.rate_min =     8000,
-			.rate_max =     8000,
+			.rate_max =     16000,
 		},
 		.capture = {
 			.stream_name = "AUXPCM Hostless Capture",
-			.rates = SNDRV_PCM_RATE_8000,
+			.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
 			.channels_min = 1,
 			.channels_max = 1,
 			.rate_min =     8000,
-			.rate_max =    48000,
+			.rate_max =    16000,
 		},
 		.ops = &msm_fe_dai_ops,
 		.name = "AUXPCM_HOSTLESS",
diff --git a/sound/soc/msm/msm-dai-q6.c b/sound/soc/msm/msm-dai-q6.c
index fb7756c..a62541a 100644
--- a/sound/soc/msm/msm-dai-q6.c
+++ b/sound/soc/msm/msm-dai-q6.c
@@ -532,17 +532,28 @@
 	}
 	dai_data->channels = params_channels(params);
 
-	if (params_rate(params) != 8000) {
-		dev_err(dai->dev, "AUX PCM supports only 8KHz sampling rate\n");
+	dai_data->rate = params_rate(params);
+	switch (dai_data->rate) {
+	case 8000:
+		dai_data->port_config.pcm.mode = auxpcm_pdata->mode_8k.mode;
+		dai_data->port_config.pcm.sync = auxpcm_pdata->mode_8k.sync;
+		dai_data->port_config.pcm.frame = auxpcm_pdata->mode_8k.frame;
+		dai_data->port_config.pcm.quant = auxpcm_pdata->mode_8k.quant;
+		dai_data->port_config.pcm.slot = auxpcm_pdata->mode_8k.slot;
+		dai_data->port_config.pcm.data = auxpcm_pdata->mode_8k.data;
+		break;
+	case 16000:
+		dai_data->port_config.pcm.mode = auxpcm_pdata->mode_16k.mode;
+		dai_data->port_config.pcm.sync = auxpcm_pdata->mode_16k.sync;
+		dai_data->port_config.pcm.frame = auxpcm_pdata->mode_16k.frame;
+		dai_data->port_config.pcm.quant = auxpcm_pdata->mode_16k.quant;
+		dai_data->port_config.pcm.slot = auxpcm_pdata->mode_16k.slot;
+		dai_data->port_config.pcm.data = auxpcm_pdata->mode_16k.data;
+		break;
+	default:
+		dev_err(dai->dev, "AUX PCM supports only 8kHz and 16kHz sampling rate\n");
 		return -EINVAL;
 	}
-	dai_data->rate = params_rate(params);
-	dai_data->port_config.pcm.mode = auxpcm_pdata->mode;
-	dai_data->port_config.pcm.sync = auxpcm_pdata->sync;
-	dai_data->port_config.pcm.frame = auxpcm_pdata->frame;
-	dai_data->port_config.pcm.quant = auxpcm_pdata->quant;
-	dai_data->port_config.pcm.slot = auxpcm_pdata->slot;
-	dai_data->port_config.pcm.data = auxpcm_pdata->data;
 
 	return 0;
 }
@@ -702,9 +713,9 @@
 {
 	struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
 	int rc = 0;
-
 	struct msm_dai_auxpcm_pdata *auxpcm_pdata =
 			(struct msm_dai_auxpcm_pdata *) dai->dev->platform_data;
+	unsigned long pcm_clk_rate;
 
 	mutex_lock(&aux_pcm_mutex);
 
@@ -753,8 +764,17 @@
 	afe_open(PCM_RX, &dai_data->port_config, dai_data->rate);
 
 	afe_open(PCM_TX, &dai_data->port_config, dai_data->rate);
+	if (dai_data->rate == 8000) {
+		pcm_clk_rate = auxpcm_pdata->mode_8k.pcm_clk_rate;
+	} else if (dai_data->rate == 16000) {
+		pcm_clk_rate = auxpcm_pdata->mode_8k.pcm_clk_rate;
+	} else {
+		dev_err(dai->dev, "%s: Invalid AUX PCM rate %d\n", __func__,
+			  dai_data->rate);
+		return -EINVAL;
+	}
 
-	rc = clk_set_rate(pcm_clk, auxpcm_pdata->pcm_clk_rate);
+	rc = clk_set_rate(pcm_clk, pcm_clk_rate);
 	if (rc < 0) {
 		pr_err("%s: clk_set_rate failed\n", __func__);
 		return rc;
@@ -1377,11 +1397,11 @@
 
 static struct snd_soc_dai_driver msm_dai_q6_aux_pcm_rx_dai = {
 	.playback = {
-		.rates = SNDRV_PCM_RATE_8000,
+		.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
 		.channels_min = 1,
 		.channels_max = 1,
-		.rate_max = 8000,
+		.rate_max = 16000,
 		.rate_min = 8000,
 	},
 	.ops = &msm_dai_q6_auxpcm_ops,
@@ -1391,11 +1411,11 @@
 
 static struct snd_soc_dai_driver msm_dai_q6_aux_pcm_tx_dai = {
 	.capture = {
-		.rates = SNDRV_PCM_RATE_8000,
+		.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
 		.channels_min = 1,
 		.channels_max = 1,
-		.rate_max = 8000,
+		.rate_max = 16000,
 		.rate_min = 8000,
 	},
 	.ops = &msm_dai_q6_auxpcm_ops,
diff --git a/sound/soc/msm/msm8930.c b/sound/soc/msm/msm8930.c
index b31ed65..2762bd6 100644
--- a/sound/soc/msm/msm8930.c
+++ b/sound/soc/msm/msm8930.c
@@ -39,6 +39,7 @@
 #define SPK_AMP_POS	0x1
 #define SPK_AMP_NEG	0x2
 #define SPKR_BOOST_GPIO 15
+#define DEFAULT_PMIC_SPK_GAIN 0x0D
 #define SITAR_EXT_CLK_RATE 12288000
 
 #define SITAR_MBHC_DEF_BUTTONS 3
@@ -47,6 +48,7 @@
 static int msm8930_spk_control;
 static int msm8930_slim_0_rx_ch = 1;
 static int msm8930_slim_0_tx_ch = 1;
+static int msm8930_pmic_spk_gain = DEFAULT_PMIC_SPK_GAIN;
 
 static int msm8930_ext_spk_pamp;
 static int msm8930_btsco_rate = BTSCO_RATE_8KHZ;
@@ -431,6 +433,39 @@
 	return 0;
 }
 
+static const char *pmic_spk_gain_text[] = {
+	"NEG_6_DB", "NEG_4_DB", "NEG_2_DB", "ZERO_DB", "POS_2_DB", "POS_4_DB",
+	"POS_6_DB", "POS_8_DB", "POS_10_DB", "POS_12_DB", "POS_14_DB",
+	"POS_16_DB", "POS_18_DB", "POS_20_DB", "POS_22_DB", "POS_24_DB"
+};
+
+static const struct soc_enum msm8960_pmic_spk_gain_enum[] = {
+	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(pmic_spk_gain_text),
+						pmic_spk_gain_text),
+};
+
+static int msm8930_pmic_gain_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	pr_debug("%s: msm8930_pmic_spk_gain = %d\n", __func__,
+			 msm8930_pmic_spk_gain);
+	ucontrol->value.integer.value[0] = msm8930_pmic_spk_gain;
+	return 0;
+}
+
+static int msm8930_pmic_gain_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	int ret = 0;
+	msm8930_pmic_spk_gain = ucontrol->value.integer.value[0];
+	ret = pm8xxx_spk_gain(msm8930_pmic_spk_gain);
+	pr_debug("%s: msm8930_pmic_spk_gain = %d"
+			 " ucontrol->value.integer.value[0] = %d\n", __func__,
+			 msm8930_pmic_spk_gain,
+			 (int) ucontrol->value.integer.value[0]);
+	return ret;
+}
+
 static const struct snd_kcontrol_new sitar_msm8930_controls[] = {
 	SOC_ENUM_EXT("Speaker Function", msm8930_enum[0], msm8930_get_spk,
 		msm8930_set_spk),
@@ -438,6 +473,8 @@
 		msm8930_slim_0_rx_ch_get, msm8930_slim_0_rx_ch_put),
 	SOC_ENUM_EXT("SLIM_0_TX Channels", msm8930_enum[2],
 		msm8930_slim_0_tx_ch_get, msm8930_slim_0_tx_ch_put),
+	SOC_ENUM_EXT("PMIC SPK Gain", msm8960_pmic_spk_gain_enum[0],
+		msm8930_pmic_gain_get, msm8930_pmic_gain_put),
 };
 
 static const struct snd_kcontrol_new int_btsco_rate_mixer_controls[] = {
@@ -642,6 +679,9 @@
 	mbhc_cfg.gpio_irq = gpio_to_irq(mbhc_cfg.gpio);
 	sitar_hs_detect(codec, &mbhc_cfg);
 
+	/* Initialize default PMIC speaker gain */
+	pm8xxx_spk_gain(DEFAULT_PMIC_SPK_GAIN);
+
 	return 0;
 }
 
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index f78f58d..9dfef92 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -41,8 +41,8 @@
 #define msm8960_SLIM_0_RX_MAX_CHANNELS		2
 #define msm8960_SLIM_0_TX_MAX_CHANNELS		4
 
-#define BTSCO_RATE_8KHZ 8000
-#define BTSCO_RATE_16KHZ 16000
+#define SAMPLE_RATE_8KHZ 8000
+#define SAMPLE_RATE_16KHZ 16000
 
 #define BOTTOM_SPK_AMP_POS	0x1
 #define BOTTOM_SPK_AMP_NEG	0x2
@@ -70,9 +70,11 @@
 static int msm8960_slim_0_rx_ch = 1;
 static int msm8960_slim_0_tx_ch = 1;
 
-static int msm8960_btsco_rate = BTSCO_RATE_8KHZ;
+static int msm8960_btsco_rate = SAMPLE_RATE_8KHZ;
 static int msm8960_btsco_ch = 1;
 
+static int msm8960_auxpcm_rate = SAMPLE_RATE_8KHZ;
+
 static struct clk *codec_clk;
 static int clk_users;
 
@@ -512,6 +514,11 @@
 		SOC_ENUM_SINGLE_EXT(2, btsco_rate_text),
 };
 
+static const char *auxpcm_rate_text[] = {"rate_8000", "rate_16000"};
+static const struct soc_enum msm8960_auxpcm_enum[] = {
+		SOC_ENUM_SINGLE_EXT(2, auxpcm_rate_text),
+};
+
 static int msm8960_slim_0_rx_ch_get(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
@@ -563,19 +570,49 @@
 {
 	switch (ucontrol->value.integer.value[0]) {
 	case 0:
-		msm8960_btsco_rate = BTSCO_RATE_8KHZ;
+		msm8960_btsco_rate = SAMPLE_RATE_8KHZ;
 		break;
 	case 1:
-		msm8960_btsco_rate = BTSCO_RATE_16KHZ;
+		msm8960_btsco_rate = SAMPLE_RATE_16KHZ;
 		break;
 	default:
-		msm8960_btsco_rate = BTSCO_RATE_8KHZ;
+		msm8960_btsco_rate = SAMPLE_RATE_8KHZ;
 		break;
 	}
 	pr_debug("%s: msm8960_btsco_rate = %d\n", __func__, msm8960_btsco_rate);
 	return 0;
 }
 
+static int msm8960_auxpcm_rate_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	pr_debug("%s: msm8960_auxpcm_rate  = %d", __func__,
+		msm8960_auxpcm_rate);
+	ucontrol->value.integer.value[0] = msm8960_auxpcm_rate;
+	return 0;
+}
+
+static int msm8960_auxpcm_rate_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	switch (ucontrol->value.integer.value[0]) {
+	case 0:
+		msm8960_auxpcm_rate = SAMPLE_RATE_8KHZ;
+		break;
+	case 1:
+		msm8960_auxpcm_rate = SAMPLE_RATE_16KHZ;
+		break;
+	default:
+		msm8960_auxpcm_rate = SAMPLE_RATE_8KHZ;
+		break;
+	}
+	pr_debug("%s: msm8960_auxpcm_rate = %d"
+		"ucontrol->value.integer.value[0] = %d\n", __func__,
+		msm8960_auxpcm_rate,
+		(int)ucontrol->value.integer.value[0]);
+	return 0;
+}
+
 static const struct snd_kcontrol_new tabla_msm8960_controls[] = {
 	SOC_ENUM_EXT("Speaker Function", msm8960_enum[0], msm8960_get_spk,
 		msm8960_set_spk),
@@ -590,6 +627,11 @@
 		msm8960_btsco_rate_get, msm8960_btsco_rate_put),
 };
 
+static const struct snd_kcontrol_new auxpcm_rate_mixer_controls[] = {
+	SOC_ENUM_EXT("AUX PCM SampleRate", msm8960_auxpcm_enum[0],
+		msm8960_auxpcm_rate_get, msm8960_auxpcm_rate_put),
+};
+
 static int msm8960_btsco_init(struct snd_soc_pcm_runtime *rtd)
 {
 	int err = 0;
@@ -603,6 +645,19 @@
 	return 0;
 }
 
+static int msm8960_auxpcm_init(struct snd_soc_pcm_runtime *rtd)
+{
+	int err = 0;
+	struct snd_soc_platform *platform = rtd->platform;
+
+	err = snd_soc_add_platform_controls(platform,
+		auxpcm_rate_mixer_controls,
+		ARRAY_SIZE(auxpcm_rate_mixer_controls));
+	if (err < 0)
+		return err;
+	return 0;
+}
+
 static void *def_tabla_mbhc_cal(void)
 {
 	void *tabla_cal;
@@ -951,8 +1006,8 @@
 	struct snd_interval *channels = hw_param_interval(params,
 					SNDRV_PCM_HW_PARAM_CHANNELS);
 
-	/* PCM only supports mono output with 8khz sample rate */
-	rate->min = rate->max = 8000;
+	rate->min = rate->max = msm8960_auxpcm_rate;
+	/* PCM only supports mono output */
 	channels->min = channels->max = 1;
 
 	return 0;
@@ -1279,6 +1334,7 @@
 		.platform_name = "msm-pcm-routing",
 		.codec_name = "msm-stub-codec.1",
 		.codec_dai_name = "msm-stub-rx",
+		.init = &msm8960_auxpcm_init,
 		.no_pcm = 1,
 		.be_id = MSM_BACKEND_DAI_AUXPCM_RX,
 		.be_hw_params_fixup = msm8960_auxpcm_be_params_fixup,
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index fc08febf..09bfd94 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -526,6 +526,7 @@
 						pr_err("%s: ION create client"
 						" for AUDIO failed\n",
 						__func__);
+						mutex_unlock(&ac->cmd_lock);
 						goto fail;
 					}
 					buf[cnt].handle = ion_alloc
@@ -536,6 +537,7 @@
 						pr_err("%s: ION memory"
 					" allocation for AUDIO failed\n",
 							__func__);
+						mutex_unlock(&ac->cmd_lock);
 						goto fail;
 					}
 
@@ -548,6 +550,7 @@
 						pr_err("%s: ION Get Physical"
 						" for AUDIO failed, rc = %d\n",
 							__func__, rc);
+						mutex_unlock(&ac->cmd_lock);
 						goto fail;
 					}
 
@@ -558,6 +561,7 @@
 						buf[cnt].data)) {
 						pr_err("%s: ION memory"
 				" mapping for AUDIO failed\n", __func__);
+						mutex_unlock(&ac->cmd_lock);
 						goto fail;
 					}
 					memset((void *)buf[cnt].data, 0, bufsz);
@@ -661,6 +665,7 @@
 	buf[0].client = msm_ion_client_create(UINT_MAX, "audio_client");
 	if (IS_ERR_OR_NULL((void *)buf[0].client)) {
 		pr_err("%s: ION create client for AUDIO failed\n", __func__);
+		mutex_unlock(&ac->cmd_lock);
 		goto fail;
 	}
 	buf[0].handle = ion_alloc(buf[0].client, bufsz * bufcnt, SZ_4K,
@@ -668,6 +673,7 @@
 	if (IS_ERR_OR_NULL((void *) buf[0].handle)) {
 		pr_err("%s: ION memory allocation for AUDIO failed\n",
 			__func__);
+		mutex_unlock(&ac->cmd_lock);
 		goto fail;
 	}
 
@@ -676,12 +682,14 @@
 	if (rc) {
 		pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n",
 			__func__, rc);
+		mutex_unlock(&ac->cmd_lock);
 		goto fail;
 	}
 
 	buf[0].data = ion_map_kernel(buf[0].client, buf[0].handle, 0);
 	if (IS_ERR_OR_NULL((void *) buf[0].data)) {
 		pr_err("%s: ION memory mapping for AUDIO failed\n", __func__);
+		mutex_unlock(&ac->cmd_lock);
 		goto fail;
 	}
 	memset((void *)buf[0].data, 0, (bufsz * bufcnt));
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 2284f19..b6ddcc8a 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -1543,10 +1543,17 @@
 
 			trace_snd_soc_dapm_widget_power(w, power);
 
-			if (power)
+			if (power) {
 				dapm_seq_insert(w, &up_list, true);
-			else
+				dev_dbg(w->dapm->dev,
+					"%s(): power up . widget  %s\n",
+					__func__, w->name);
+			} else {
 				dapm_seq_insert(w, &down_list, false);
+				dev_dbg(w->dapm->dev,
+					"%s(): power down . widget  %s\n",
+					__func__, w->name);
+			}
 
 			w->power = power;
 			break;