Merge "defconfig: Enable CPUFreq for msm-copper" into msm-3.0
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index 5b55f99..1cf5df3 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -303,7 +303,6 @@
 # CONFIG_MMC_BLOCK_BOUNCE is not set
 CONFIG_MMC_TEST=m
 CONFIG_MMC_MSM=y
-CONFIG_MMC_MSM_SDIO_SUPPORT=y
 CONFIG_MMC_MSM_CARD_HW_DETECTION=y
 CONFIG_MMC_MSM_SDC3_SUPPORT=y
 CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT=y
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index 7f9c54d..8d31ee6 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -304,7 +304,6 @@
 # CONFIG_MMC_BLOCK_BOUNCE is not set
 CONFIG_MMC_TEST=m
 CONFIG_MMC_MSM=y
-CONFIG_MMC_MSM_SDIO_SUPPORT=y
 CONFIG_MMC_MSM_CARD_HW_DETECTION=y
 CONFIG_MMC_MSM_SDC3_SUPPORT=y
 CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT=y
diff --git a/arch/arm/configs/msm7630-perf_defconfig b/arch/arm/configs/msm7630-perf_defconfig
index 3ee4132..736f2bb 100644
--- a/arch/arm/configs/msm7630-perf_defconfig
+++ b/arch/arm/configs/msm7630-perf_defconfig
@@ -334,7 +334,6 @@
 # CONFIG_MMC_BLOCK_BOUNCE is not set
 CONFIG_MMC_TEST=m
 CONFIG_MMC_MSM=y
-CONFIG_MMC_MSM_SDIO_SUPPORT=y
 CONFIG_MMC_MSM_CARD_HW_DETECTION=y
 # CONFIG_MMC_MSM_SDC1_SUPPORT is not set
 CONFIG_MMC_MSM_SDC2_8_BIT_SUPPORT=y
diff --git a/arch/arm/configs/msm7630_defconfig b/arch/arm/configs/msm7630_defconfig
index 1e037ea..bc464b4 100644
--- a/arch/arm/configs/msm7630_defconfig
+++ b/arch/arm/configs/msm7630_defconfig
@@ -333,7 +333,6 @@
 # CONFIG_MMC_BLOCK_BOUNCE is not set
 CONFIG_MMC_TEST=m
 CONFIG_MMC_MSM=y
-CONFIG_MMC_MSM_SDIO_SUPPORT=y
 CONFIG_MMC_MSM_CARD_HW_DETECTION=y
 # CONFIG_MMC_MSM_SDC1_SUPPORT is not set
 CONFIG_MMC_MSM_SDC2_8_BIT_SUPPORT=y
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index 8c2e3a6..e7f1a67 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -388,7 +388,6 @@
 # CONFIG_MMC_BLOCK_BOUNCE is not set
 CONFIG_MMC_TEST=m
 CONFIG_MMC_MSM=y
-CONFIG_MMC_MSM_SDIO_SUPPORT=y
 CONFIG_MMC_MSM_CARD_HW_DETECTION=y
 CONFIG_MMC_MSM_SDC1_8_BIT_SUPPORT=y
 CONFIG_MMC_MSM_SDC2_8_BIT_SUPPORT=y
diff --git a/arch/arm/configs/msm8660_defconfig b/arch/arm/configs/msm8660_defconfig
index 0e83888..c8dfd7a 100644
--- a/arch/arm/configs/msm8660_defconfig
+++ b/arch/arm/configs/msm8660_defconfig
@@ -389,7 +389,6 @@
 # CONFIG_MMC_BLOCK_BOUNCE is not set
 CONFIG_MMC_TEST=m
 CONFIG_MMC_MSM=y
-CONFIG_MMC_MSM_SDIO_SUPPORT=y
 CONFIG_MMC_MSM_CARD_HW_DETECTION=y
 CONFIG_MMC_MSM_SDC1_8_BIT_SUPPORT=y
 CONFIG_MMC_MSM_SDC2_8_BIT_SUPPORT=y
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index 70cba0f..601f235 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -245,7 +245,6 @@
 # CONFIG_MMC_BLOCK_BOUNCE is not set
 CONFIG_MMC_TEST=m
 CONFIG_MMC_MSM=y
-CONFIG_MMC_MSM_SDIO_SUPPORT=y
 CONFIG_MMC_MSM_CARD_HW_DETECTION=y
 CONFIG_MMC_MSM_SPS_SUPPORT=y
 CONFIG_NEW_LEDS=y
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 2609aca..b465da5 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -258,6 +258,11 @@
 obj-$(CONFIG_PM8921_BMS) += bms-batterydata.o bms-batterydata-desay.o
 obj-$(CONFIG_MACH_APQ8064_SIM) += board-8064-all.o board-8064-regulator.o
 obj-$(CONFIG_MACH_APQ8064_RUMI3) += board-8064-all.o board-8064-regulator.o
+obj-$(CONFIG_MACH_APQ8064_CDP) += board-8064-all.o board-8064-regulator.o
+obj-$(CONFIG_MACH_APQ8064_MTP) += board-8064-all.o board-8064-regulator.o
+obj-$(CONFIG_MACH_APQ8064_LIQUID) += board-8064-all.o board-8064-regulator.o
+obj-$(CONFIG_MACH_MPQ8064_HRD) += board-8064-all.o board-8064-regulator.o
+obj-$(CONFIG_MACH_MPQ8064_DTV) += board-8064-all.o board-8064-regulator.o
 obj-$(CONFIG_ARCH_MSM9615) += board-9615.o devices-9615.o board-9615-regulator.o board-9615-gpiomux.o board-9615-storage.o board-9615-display.o
 obj-$(CONFIG_ARCH_MSM9615) += clock-local.o clock-9615.o acpuclock-9615.o clock-rpm.o
 obj-$(CONFIG_ARCH_MSMCOPPER) += board-copper.o board-dt.o board-copper-regulator.o
diff --git a/arch/arm/mach-msm/acpuclock-7201.c b/arch/arm/mach-msm/acpuclock-7201.c
index 35e8eba..b6c0b26 100644
--- a/arch/arm/mach-msm/acpuclock-7201.c
+++ b/arch/arm/mach-msm/acpuclock-7201.c
@@ -171,7 +171,7 @@
 	{ 1, 320000, ACPU_PLL_0, 4, 2, 40000, 3, 4, 122880 },
 	{ 0, 400000, ACPU_PLL_4, 6, 1, 50000, 3, 4, 122880 },
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
-	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
+	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 160000 },
 	{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
@@ -186,7 +186,7 @@
 	{ 1, 320000, ACPU_PLL_0, 4, 2, 40000, 3, 4, 120000 },
 	{ 0, 400000, ACPU_PLL_4, 6, 1, 50000, 3, 4, 120000 },
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 120000 },
-	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
+	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 160000 },
 	{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
@@ -200,8 +200,8 @@
 	{ 0, 300000, ACPU_PLL_2, 2, 3, 37500, 3, 4, 122880 },
 	{ 1, 320000, ACPU_PLL_0, 4, 2, 40000, 3, 4, 122880 },
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
-	{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
-	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
+	{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 160000 },
+	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 160000 },
 	{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
@@ -215,8 +215,8 @@
 	{ 0, 300000, ACPU_PLL_2, 2, 3, 37500, 3, 4, 122880 },
 	{ 1, 320000, ACPU_PLL_0, 4, 2, 40000, 3, 4, 122880 },
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
-	{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
-	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
+	{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 160000 },
+	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 160000 },
 	{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
@@ -229,8 +229,8 @@
 	{ 1, 245760, ACPU_PLL_1, 1, 0, 30720, 3, 3, 61440 },
 	{ 1, 320000, ACPU_PLL_0, 4, 2, 40000, 3, 4, 122880 },
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
-	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
-	{ 0, 604800, ACPU_PLL_4, 6, 1, 75600, 3, 6, 200000 },
+	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 160000 },
+	{ 0, 604800, ACPU_PLL_4, 6, 1, 75600, 3, 6, 160000 },
 	{ 1, 1209600, ACPU_PLL_4, 6, 0, 151200, 3, 7, 200000},
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
@@ -243,8 +243,8 @@
 	{ 1, 196608, ACPU_PLL_1, 1, 0, 24576, 3, 3, 98304 },
 	{ 1, 320000, ACPU_PLL_0, 4, 2, 40000, 3, 4, 122880 },
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
-	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
-	{ 0, 604800, ACPU_PLL_4, 6, 1, 75600, 3, 6, 200000 },
+	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 160000 },
+	{ 0, 604800, ACPU_PLL_4, 6, 1, 75600, 3, 6, 160000 },
 	{ 1, 1209600, ACPU_PLL_4, 6, 0, 151200, 3, 7, 200000},
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
@@ -273,7 +273,7 @@
 	{ 1, 320000, ACPU_PLL_0, 4, 2, 40000, 3, 4, 122880 },
 	{ 0, 400000, ACPU_PLL_4, 6, 1, 50000, 3, 4, 122880 },
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
-	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
+	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 160000 },
 	{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
@@ -288,7 +288,7 @@
 	{ 1, 320000, ACPU_PLL_0, 4, 2, 40000, 3, 4, 120000 },
 	{ 0, 400000, ACPU_PLL_4, 6, 1, 50000, 3, 4, 120000 },
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 120000 },
-	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
+	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 160000 },
 	{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
@@ -302,8 +302,8 @@
 	{ 0, 300000, ACPU_PLL_2, 2, 3, 37500, 3, 4, 122880 },
 	{ 1, 320000, ACPU_PLL_0, 4, 2, 40000, 3, 4, 122880 },
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
-	{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
-	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
+	{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 160000 },
+	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 160000 },
 	{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
@@ -317,8 +317,8 @@
 	{ 0, 300000, ACPU_PLL_2, 2, 3, 37500, 3, 4, 122880 },
 	{ 1, 320000, ACPU_PLL_0, 4, 2, 40000, 3, 4, 122880 },
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
-	{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
-	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
+	{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 160000 },
+	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 160000 },
 	{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
@@ -468,6 +468,10 @@
 	reg_clksel ^= 1;
 	writel_relaxed(reg_clksel, A11S_CLK_SEL_ADDR);
 
+	/* Wait for the clock switch to complete */
+	mb();
+	udelay(50);
+
 	/*
 	 * If the new clock divider is lower than the previous, then
 	 * program the divider after switching the clock
@@ -619,8 +623,6 @@
 		/* Adjust the global one */
 		loops_per_jiffy = cur_s->lpj;
 
-		mb();
-		udelay(50);
 	}
 
 	/* Nothing else to do for SWFI. */
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index 89d7fc9..6361d6d 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -982,11 +982,13 @@
 
 int msm_bam_dmux_is_ch_low(uint32_t id)
 {
+	unsigned long flags;
 	int ret;
 
 	if (id >= BAM_DMUX_NUM_CHANNELS)
 		return -EINVAL;
 
+	spin_lock_irqsave(&bam_ch[id].lock, flags);
 	bam_ch[id].use_wm = 1;
 	ret = bam_ch[id].num_tx_pkts <= LOW_WATERMARK;
 	DBG("%s: ch %d num tx pkts=%d, LWM=%d\n", __func__,
@@ -995,6 +997,7 @@
 		ret = -ENODEV;
 		pr_err("%s: port not open: %d\n", __func__, bam_ch[id].status);
 	}
+	spin_unlock_irqrestore(&bam_ch[id].lock, flags);
 
 	return ret;
 }
diff --git a/arch/arm/mach-msm/board-8064-camera.c b/arch/arm/mach-msm/board-8064-camera.c
index 9080e60..c7b3af5 100644
--- a/arch/arm/mach-msm/board-8064-camera.c
+++ b/arch/arm/mach-msm/board-8064-camera.c
@@ -499,6 +499,41 @@
 	.sensor_type = BAYER_SENSOR,
 };
 
+static struct camera_vreg_t apq_8064_s5k3l1yx_vreg[] = {
+	{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+	{"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+	{"cam_vio", REG_VS, 0, 0, 0},
+	{"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
+};
+
+static struct msm_camera_sensor_flash_data flash_s5k3l1yx = {
+	.flash_type	= MSM_CAMERA_FLASH_NONE,
+};
+
+static struct msm_camera_csi_lane_params s5k3l1yx_csi_lane_params = {
+	.csi_lane_assign = 0xE4,
+	.csi_lane_mask = 0xF,
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_s5k3l1yx = {
+	.mount_angle	= 90,
+	.cam_vreg = apq_8064_s5k3l1yx_vreg,
+	.num_vreg = ARRAY_SIZE(apq_8064_s5k3l1yx_vreg),
+	.gpio_conf = &apq8064_back_cam_gpio_conf,
+	.i2c_conf = &apq8064_back_cam_i2c_conf,
+	.csi_lane_params = &s5k3l1yx_csi_lane_params,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_s5k3l1yx_data = {
+	.sensor_name	= "s5k3l1yx",
+	.pdata	= &msm_camera_csi_device_data[0],
+	.flash_data	= &flash_s5k3l1yx,
+	.sensor_platform_info = &sensor_board_info_s5k3l1yx,
+	.csi_if	= 1,
+	.camera_type = BACK_CAMERA_2D,
+	.sensor_type = BAYER_SENSOR,
+};
+
 static struct camera_vreg_t apq_8064_mt9m114_vreg[] = {
 	{"cam_vio", REG_VS, 0, 0, 0},
 	{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
@@ -603,6 +638,10 @@
 	I2C_BOARD_INFO("imx091", 0x34),
 	.platform_data = &msm_camera_sensor_imx091_data,
 	},
+	{
+	I2C_BOARD_INFO("s5k3l1yx", 0x20),
+	.platform_data = &msm_camera_sensor_s5k3l1yx_data,
+	},
 };
 
 struct msm_camera_board_info apq8064_camera_board_info = {
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index 24df393..ae2de20 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -62,6 +62,7 @@
 	REGULATOR_SUPPLY("cam_vana",		"4-0048"),
 	REGULATOR_SUPPLY("cam_vana",		"4-006c"),
 	REGULATOR_SUPPLY("cam_vana",		"4-0034"),
+	REGULATOR_SUPPLY("cam_vana",		"4-0020"),
 };
 VREG_CONSUMERS(L9) = {
 	REGULATOR_SUPPLY("8921_l9",		NULL),
@@ -80,6 +81,7 @@
 	REGULATOR_SUPPLY("cam_vdig",		"4-0048"),
 	REGULATOR_SUPPLY("cam_vdig",		"4-006c"),
 	REGULATOR_SUPPLY("cam_vdig",		"4-0034"),
+	REGULATOR_SUPPLY("cam_vdig",		"4-0020"),
 	REGULATOR_SUPPLY("8921_l12",		NULL),
 };
 VREG_CONSUMERS(L14) = {
@@ -94,6 +96,7 @@
 	REGULATOR_SUPPLY("cam_vaf",		"4-0048"),
 	REGULATOR_SUPPLY("cam_vaf",		"4-006c"),
 	REGULATOR_SUPPLY("cam_vaf",		"4-0034"),
+	REGULATOR_SUPPLY("cam_vaf",		"4-0020"),
 };
 VREG_CONSUMERS(L17) = {
 	REGULATOR_SUPPLY("8921_l17",		NULL),
@@ -197,6 +200,7 @@
 	REGULATOR_SUPPLY("cam_vio",		"4-0048"),
 	REGULATOR_SUPPLY("cam_vio",		"4-006c"),
 	REGULATOR_SUPPLY("cam_vio",		"4-0034"),
+	REGULATOR_SUPPLY("cam_vio",		"4-0020"),
 };
 VREG_CONSUMERS(LVS6) = {
 	REGULATOR_SUPPLY("8921_lvs6",		NULL),
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index d06b5bd..3f4266f 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -588,6 +588,12 @@
 	.name = "usb",
 };
 
+static int phy_init_seq[] = {
+	0x38, 0x81, /* update DC voltage level */
+	0x24, 0x82, /* set pre-emphasis and rise/fall time */
+	-1
+};
+
 static struct msm_otg_platform_data msm_otg_pdata = {
 	.mode			= USB_OTG,
 	.otg_control		= OTG_PMIC_CONTROL,
@@ -595,6 +601,7 @@
 	.pmic_id_irq		= PM8921_USB_ID_IN_IRQ(PM8921_IRQ_BASE),
 	.power_budget		= 750,
 	.bus_scale_table	= &usb_bus_scale_pdata,
+	.phy_init_seq		= phy_init_seq,
 };
 
 static struct msm_usb_host_platform_data msm_ehci_host_pdata3 = {
diff --git a/arch/arm/mach-msm/board-8960-gpiomux.c b/arch/arm/mach-msm/board-8960-gpiomux.c
index 5b632bd..bfb8be3 100644
--- a/arch/arm/mach-msm/board-8960-gpiomux.c
+++ b/arch/arm/mach-msm/board-8960-gpiomux.c
@@ -55,7 +55,7 @@
 	.pull = GPIOMUX_PULL_NONE,
 };
 
-static struct gpiomux_setting gsbi5 = {
+static struct gpiomux_setting gsbi_uart = {
 	.func = GPIOMUX_FUNC_1,
 	.drv = GPIOMUX_DRV_8MA,
 	.pull = GPIOMUX_PULL_NONE,
@@ -327,30 +327,6 @@
 		},
 	},
 	{
-		.gpio      = 22,	/* GSBI5 UART2 */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gsbi5,
-		},
-	},
-	{
-		.gpio      = 23,	/* GSBI5 UART2 */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gsbi5,
-		},
-	},
-	{
-		.gpio      = 24,	/* GSBI5 UART2 */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gsbi5,
-		},
-	},
-	{
-		.gpio      = 25,	/* GSBI5 UART2 */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gsbi5,
-		},
-	},
-	{
 		.gpio      = 44,	/* GSBI12 I2C QUP SDA */
 		.settings = {
 			[GPIOMUX_SUSPENDED] = &gsbi12,
@@ -376,6 +352,60 @@
 	},
 };
 
+static struct msm_gpiomux_config msm8960_gsbi5_uart_configs[] __initdata = {
+	{
+		.gpio      = 22,        /* GSBI5 UART2 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi_uart,
+		},
+	},
+	{
+		.gpio      = 23,        /* GSBI5 UART2 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi_uart,
+		},
+	},
+	{
+		.gpio      = 24,        /* GSBI5 UART2 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi_uart,
+		},
+	},
+	{
+		.gpio      = 25,        /* GSBI5 UART2 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi_uart,
+		},
+	},
+};
+
+static struct msm_gpiomux_config msm8960_gsbi8_uart_configs[] __initdata = {
+	{
+		.gpio      = 34,        /* GSBI8 UART3 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi_uart,
+		},
+	},
+	{
+		.gpio      = 35,        /* GSBI8 UART3 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi_uart,
+		},
+	},
+	{
+		.gpio      = 36,        /* GSBI8 UART3 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi_uart,
+		},
+	},
+	{
+		.gpio      = 37,        /* GSBI8 UART3 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi_uart,
+		},
+	},
+};
+
 static struct msm_gpiomux_config msm8960_slimbus_config[] __initdata = {
 	{
 		.gpio	= 60,		/* slimbus data */
@@ -686,5 +716,12 @@
 	msm_gpiomux_install(msm8960_mdp_vsync_configs,
 			ARRAY_SIZE(msm8960_mdp_vsync_configs));
 
+	if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE)
+		msm_gpiomux_install(msm8960_gsbi8_uart_configs,
+			ARRAY_SIZE(msm8960_gsbi8_uart_configs));
+	else
+		msm_gpiomux_install(msm8960_gsbi5_uart_configs,
+			ARRAY_SIZE(msm8960_gsbi5_uart_configs));
+
 	return 0;
 }
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 257b27f..f462c7a 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -2192,7 +2192,6 @@
 static struct platform_device *common_devices[] __initdata = {
 	&msm8960_device_dmov,
 	&msm_device_smd,
-	&msm8960_device_uart_gsbi5,
 	&msm_device_uart_dm6,
 	&msm_device_saw_core0,
 	&msm_device_saw_core1,
@@ -2275,6 +2274,7 @@
 };
 
 static struct platform_device *sim_devices[] __initdata = {
+	&msm8960_device_uart_gsbi5,
 	&msm8960_device_otg,
 	&msm8960_device_gadget_peripheral,
 	&msm_device_hsusb_host,
@@ -2320,6 +2320,7 @@
 };
 
 static struct platform_device *rumi3_devices[] __initdata = {
+	&msm8960_device_uart_gsbi5,
 	&msm_kgsl_3d0,
 	&msm_kgsl_2d0,
 	&msm_kgsl_2d1,
@@ -2900,6 +2901,12 @@
 		platform_device_register(&msm8960_device_ext_3p3v_vreg);
 	if (machine_is_msm8960_cdp())
 		platform_device_register(&msm8960_device_ext_l2_vreg);
+
+	if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE)
+		platform_device_register(&msm8960_device_uart_gsbi8);
+	else
+		platform_device_register(&msm8960_device_uart_gsbi5);
+
 	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
 	msm8960_pm8921_gpio_mpp_init();
 	platform_add_devices(cdp_devices, ARRAY_SIZE(cdp_devices));
diff --git a/arch/arm/mach-msm/board-9615-storage.c b/arch/arm/mach-msm/board-9615-storage.c
index 5a795c0..c73e5a9 100644
--- a/arch/arm/mach-msm/board-9615-storage.c
+++ b/arch/arm/mach-msm/board-9615-storage.c
@@ -202,9 +202,7 @@
 	.sup_clk_cnt	= ARRAY_SIZE(sdc2_sup_clk_rates),
 	.pclk_src_dfab	= 1,
 	.pin_data	= &mmc_slot_pin_data[SDCC2],
-#ifdef CONFIG_MMC_MSM_SDIO_SUPPORT
 	.sdiowakeup_irq = MSM_GPIO_TO_INT(GPIO_SDC2_DAT1_WAKEUP),
-#endif
 };
 static struct mmc_platform_data *msm9615_sdc2_pdata = &sdc2_data;
 #else
diff --git a/arch/arm/mach-msm/board-msm7627a-display.c b/arch/arm/mach-msm/board-msm7627a-display.c
index e96284a..e2076f8 100644
--- a/arch/arm/mach-msm/board-msm7627a-display.c
+++ b/arch/arm/mach-msm/board-msm7627a-display.c
@@ -28,7 +28,7 @@
 #include "board-msm7627a.h"
 
 #ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
-#define MSM_FB_SIZE	     0x261000
+#define MSM_FB_SIZE		0x2FD000
 #define MSM7x25A_MSM_FB_SIZE    0xE1000
 #else
 #define MSM_FB_SIZE	     0x196000
@@ -684,6 +684,18 @@
 	}
 };
 
+static struct msm_panel_common_pdata mipi_NT35516_pdata = {
+	.pmic_backlight = NULL,
+};
+
+static struct platform_device mipi_dsi_NT35516_panel_device = {
+	.name   = "mipi_truly_tft540960_1_e",
+	.id     = 0,
+	.dev    = {
+		.platform_data = &mipi_NT35516_pdata,
+	}
+};
+
 static struct platform_device *msm_fb_devices[] __initdata = {
 	&msm_fb_device,
 	&lcdc_toshiba_panel_device,
@@ -708,6 +720,7 @@
 static struct platform_device *evb_fb_devices[] __initdata = {
 	&msm_fb_device,
 	&mipi_dsi_NT35510_panel_device,
+	&mipi_dsi_NT35516_panel_device,
 };
 
 void __init msm_msm7627a_allocate_memory_regions(void)
diff --git a/arch/arm/mach-msm/board-msm7627a-storage.c b/arch/arm/mach-msm/board-msm7627a-storage.c
index 564c59d..11d9a21 100644
--- a/arch/arm/mach-msm/board-msm7627a-storage.c
+++ b/arch/arm/mach-msm/board-msm7627a-storage.c
@@ -293,9 +293,7 @@
 	.ocr_mask       = MMC_VDD_28_29 | MMC_VDD_165_195,
 	.translate_vdd  = msm_sdcc_setup_power,
 	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
-#ifdef CONFIG_MMC_MSM_SDIO_SUPPORT
 	.sdiowakeup_irq = MSM_GPIO_TO_INT(66),
-#endif
 	.msmsdcc_fmin   = 144000,
 	.msmsdcc_fmid   = 24576000,
 	.msmsdcc_fmax   = 49152000,
diff --git a/arch/arm/mach-msm/board-msm7x27.c b/arch/arm/mach-msm/board-msm7x27.c
index 34ae4c8..f1ff49a 100644
--- a/arch/arm/mach-msm/board-msm7x27.c
+++ b/arch/arm/mach-msm/board-msm7x27.c
@@ -1518,9 +1518,7 @@
 	.ocr_mask	= MMC_VDD_28_29,
 	.translate_vdd	= msm_sdcc_setup_power,
 	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
-#ifdef CONFIG_MMC_MSM_SDIO_SUPPORT
 	.sdiowakeup_irq = MSM_GPIO_TO_INT(66),
-#endif
 	.msmsdcc_fmin	= 144000,
 	.msmsdcc_fmid	= 24576000,
 	.msmsdcc_fmax	= 49152000,
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index 972cb22..cf608ad 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -6103,9 +6103,7 @@
 	.ocr_mask	= MMC_VDD_27_28 | MMC_VDD_28_29,
 	.translate_vdd	= msm_sdcc_setup_power,
 	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
-#ifdef CONFIG_MMC_MSM_SDIO_SUPPORT
 	.sdiowakeup_irq = MSM_GPIO_TO_INT(118),
-#endif
 	.msmsdcc_fmin	= 144000,
 	.msmsdcc_fmid	= 24576000,
 	.msmsdcc_fmax	= 49152000,
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index b9050cd..5db8de4 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -2882,7 +2882,7 @@
 	.id = 2,
 	.dev = { .platform_data = &android_pmem_adsp_pdata },
 };
-#endif
+
 static struct android_pmem_platform_data android_pmem_audio_pdata = {
 	.name = "pmem_audio",
 	.allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
@@ -2895,7 +2895,7 @@
 	.id = 4,
 	.dev = { .platform_data = &android_pmem_audio_pdata },
 };
-
+#endif /*CONFIG_MSM_MULTIMEDIA_USE_ION*/
 #define PMEM_BUS_WIDTH(_bw) \
 	{ \
 		.vectors = &(struct msm_bus_vectors){ \
@@ -2954,8 +2954,8 @@
 	.id = 7,
 	.dev = { .platform_data = &android_pmem_smipool_pdata },
 };
-#endif
-#endif
+#endif /*CONFIG_MSM_MULTIMEDIA_USE_ION*/
+#endif /*CONFIG_ANDROID_PMEM*/
 
 #define GPIO_DONGLE_PWR_EN 258
 static void setup_display_power(void);
@@ -4264,9 +4264,9 @@
 	&android_pmem_device,
 	&android_pmem_adsp_device,
 	&android_pmem_smipool_device,
-#endif
 	&android_pmem_audio_device,
-#endif
+#endif /*CONFIG_MSM_MULTIMEDIA_USE_ION*/
+#endif /*CONFIG_ANDROID_PMEM*/
 #ifdef CONFIG_MSM_ROTATOR
 	&msm_rotator_device,
 #endif
@@ -5195,9 +5195,9 @@
 	&android_pmem_device,
 	&android_pmem_adsp_device,
 	&android_pmem_smipool_device,
-#endif
 	&android_pmem_audio_device,
-#endif
+#endif /*CONFIG_MSM_MULTIMEDIA_USE_ION*/
+#endif /*CONFIG_ANDROID_PMEM*/
 #ifdef CONFIG_MSM_ROTATOR
 	&msm_rotator_device,
 #endif
@@ -5491,15 +5491,19 @@
 	if (hdmi_is_primary)
 		pmem_sf_size = MSM_HDMI_PRIM_PMEM_SF_SIZE;
 	android_pmem_pdata.size = pmem_sf_size;
-#endif
 	android_pmem_audio_pdata.size = MSM_PMEM_AUDIO_SIZE;
-#endif
+#endif /*CONFIG_MSM_MULTIMEDIA_USE_ION*/
+#endif /*CONFIG_ANDROID_PMEM*/
 }
 
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 static void __init reserve_memory_for(struct android_pmem_platform_data *p)
 {
 	msm8x60_reserve_table[p->memory_type].size += p->size;
 }
+#endif /*CONFIG_MSM_MULTIMEDIA_USE_ION*/
+#endif /*CONFIG_ANDROID_PMEM*/
 
 static void __init reserve_pmem_memory(void)
 {
@@ -5508,10 +5512,10 @@
 	reserve_memory_for(&android_pmem_adsp_pdata);
 	reserve_memory_for(&android_pmem_smipool_pdata);
 	reserve_memory_for(&android_pmem_pdata);
-#endif
 	reserve_memory_for(&android_pmem_audio_pdata);
+#endif /*CONFIG_MSM_MULTIMEDIA_USE_ION*/
 	msm8x60_reserve_table[MEMTYPE_EBI1].size += pmem_kernel_ebi1_size;
-#endif
+#endif /*CONFIG_ANDROID_PMEM*/
 }
 
 static void __init reserve_mdp_memory(void);
@@ -8496,10 +8500,8 @@
 	if (machine_is_msm8x60_fusion())
 		msm8x60_sdc2_data.msmsdcc_fmax = 24000000;
 	if (machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa()) {
-#ifdef CONFIG_MMC_MSM_SDIO_SUPPORT
 		msm8x60_sdc2_data.sdiowakeup_irq = gpio_to_irq(144);
 		msm_sdcc_setup_gpio(2, 1);
-#endif
 		msm_add_sdcc(2, &msm8x60_sdc2_data);
 	}
 #endif
@@ -8560,10 +8562,8 @@
 	if (machine_is_msm8x60_fusion())
 		msm8x60_sdc5_data.msmsdcc_fmax = 24000000;
 	if (machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa()) {
-#ifdef CONFIG_MMC_MSM_SDIO_SUPPORT
 		msm8x60_sdc5_data.sdiowakeup_irq = gpio_to_irq(99);
 		msm_sdcc_setup_gpio(5, 1);
-#endif
 		msm_add_sdcc(5, &msm8x60_sdc5_data);
 	}
 #endif
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index 60457cc..7b27c4e 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -797,9 +797,9 @@
 				ARRAY_SIZE(qrd7627a_devices));
 	}
 
-	if (machine_is_msm7627a_qrd3())
+	if (machine_is_msm7627a_qrd3() || machine_is_msm7627a_evb())
 		platform_add_devices(qrd3_devices,
-			ARRAY_SIZE(qrd3_devices));
+				ARRAY_SIZE(qrd3_devices));
 
 	platform_add_devices(common_devices,
 			ARRAY_SIZE(common_devices));
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index af8f0af..7d1bcf3 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5007,6 +5007,7 @@
 	CLK_LOOKUP("core_clk",		amp_clk.c,		""),
 	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-001a"),
 	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-0034"),
+	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-0020"),
 	CLK_LOOKUP("cam_clk",		cam1_clk.c,	"4-0048"),
 	CLK_LOOKUP("cam_clk",		cam1_clk.c,	"4-006c"),
 	CLK_LOOKUP("csi_src_clk",	csi0_src_clk.c,		"msm_csid.0"),
@@ -5231,7 +5232,7 @@
 	CLK_LOOKUP("core_clk",		gsbi5_uart_clk.c, "msm_serial_hsl.0"),
 	CLK_LOOKUP("core_clk",		gsbi6_uart_clk.c, "msm_serial_hs.0"),
 	CLK_LOOKUP("core_clk",		gsbi7_uart_clk.c,	""),
-	CLK_LOOKUP("core_clk",		gsbi8_uart_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi8_uart_clk.c, "msm_serial_hsl.1"),
 	CLK_LOOKUP("core_clk",		gsbi9_uart_clk.c,	""),
 	CLK_LOOKUP("core_clk",		gsbi10_uart_clk.c,	""),
 	CLK_LOOKUP("core_clk",		gsbi11_uart_clk.c,	""),
@@ -5284,7 +5285,7 @@
 	CLK_LOOKUP("iface_clk",		gsbi5_p_clk.c,	"msm_serial_hsl.0"),
 	CLK_LOOKUP("iface_clk",		gsbi6_p_clk.c,  "msm_serial_hs.0"),
 	CLK_LOOKUP("iface_clk",		gsbi7_p_clk.c,		""),
-	CLK_LOOKUP("iface_clk",		gsbi8_p_clk.c,		""),
+	CLK_LOOKUP("iface_clk",		gsbi8_p_clk.c,	"msm_serial_hsl.1"),
 	CLK_LOOKUP("iface_clk",		gsbi9_p_clk.c,		""),
 	CLK_LOOKUP("iface_clk",		gsbi10_p_clk.c,		"qup_i2c.10"),
 	CLK_LOOKUP("iface_clk",		gsbi11_p_clk.c,		""),
diff --git a/arch/arm/mach-msm/clock-voter.c b/arch/arm/mach-msm/clock-voter.c
index 9ad653d..8ff4878 100644
--- a/arch/arm/mach-msm/clock-voter.c
+++ b/arch/arm/mach-msm/clock-voter.c
@@ -29,7 +29,7 @@
 	list_for_each_entry(clk, &parent->children, siblings) {
 		struct clk_voter *v = to_clk_voter(clk);
 		if (v->enabled)
-			rate = max(v->rate, rate);
+			rate = max(clk->rate, rate);
 	}
 	return rate;
 }
@@ -54,10 +54,10 @@
 		list_for_each_entry(clkp, &parent->children, siblings) {
 			clkh = to_clk_voter(clkp);
 			if (clkh->enabled && clkh != v)
-				other_rate = max(clkh->rate, other_rate);
+				other_rate = max(clkp->rate, other_rate);
 		}
 
-		cur_rate = max(other_rate, v->rate);
+		cur_rate = max(other_rate, clk->rate);
 		new_rate = max(other_rate, rate);
 
 		if (new_rate != cur_rate) {
@@ -66,7 +66,7 @@
 				goto unlock;
 		}
 	}
-	v->rate = rate;
+	clk->rate = rate;
 unlock:
 	spin_unlock_irqrestore(&voter_clk_lock, flags);
 
@@ -89,8 +89,8 @@
 	 * than the current rate.
 	 */
 	cur_rate = voter_clk_aggregate_rate(parent);
-	if (v->rate > cur_rate) {
-		ret = clk_set_rate(parent, v->rate);
+	if (clk->rate > cur_rate) {
+		ret = clk_set_rate(parent, clk->rate);
 		if (ret)
 			goto out;
 	}
@@ -116,7 +116,7 @@
 	 */
 	v->enabled = false;
 	new_rate = voter_clk_aggregate_rate(parent);
-	cur_rate = max(new_rate, v->rate);
+	cur_rate = max(new_rate, clk->rate);
 
 	if (new_rate < cur_rate)
 		clk_set_rate(parent, new_rate);
@@ -124,18 +124,6 @@
 	spin_unlock_irqrestore(&voter_clk_lock, flags);
 }
 
-static unsigned long voter_clk_get_rate(struct clk *clk)
-{
-	unsigned long rate, flags;
-	struct clk_voter *v = to_clk_voter(clk);
-
-	spin_lock_irqsave(&voter_clk_lock, flags);
-	rate = v->rate;
-	spin_unlock_irqrestore(&voter_clk_lock, flags);
-
-	return rate;
-}
-
 static int voter_clk_is_enabled(struct clk *clk)
 {
 	struct clk_voter *v = to_clk_voter(clk);
@@ -163,7 +151,6 @@
 	.enable = voter_clk_enable,
 	.disable = voter_clk_disable,
 	.set_rate = voter_clk_set_rate,
-	.get_rate = voter_clk_get_rate,
 	.is_enabled = voter_clk_is_enabled,
 	.round_rate = voter_clk_round_rate,
 	.get_parent = voter_clk_get_parent,
diff --git a/arch/arm/mach-msm/clock-voter.h b/arch/arm/mach-msm/clock-voter.h
index 10353d4..de17894 100644
--- a/arch/arm/mach-msm/clock-voter.h
+++ b/arch/arm/mach-msm/clock-voter.h
@@ -19,7 +19,6 @@
 
 struct clk_voter {
 	bool enabled;
-	unsigned long rate;
 	struct clk *parent;
 	struct clk c;
 };
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 029fc6f3..3255248 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -36,6 +36,7 @@
 #include <sound/apr_audio.h>
 #include <mach/msm_tsif.h>
 #include <mach/qdss.h>
+#include <mach/msm_serial_hs_lite.h>
 #include "clock.h"
 #include "devices.h"
 #include "devices-msm8x60.h"
@@ -72,6 +73,7 @@
 #define MSM_UART2DM_PHYS	(MSM_GSBI2_PHYS + 0x40000)
 #define MSM_UART5DM_PHYS	(MSM_GSBI5_PHYS + 0x40000)
 #define MSM_UART6DM_PHYS	(MSM_GSBI6_PHYS + 0x40000)
+#define MSM_UART8DM_PHYS	(MSM_GSBI8_PHYS + 0x40000)
 
 /* GSBI QUP devices */
 #define MSM_GSBI1_QUP_PHYS	(MSM_GSBI1_PHYS + 0x80000)
@@ -308,6 +310,39 @@
 	.num_resources	= ARRAY_SIZE(resources_uart_gsbi5),
 	.resource	= resources_uart_gsbi5,
 };
+
+static struct msm_serial_hslite_platform_data uart_gsbi8_pdata = {
+	.line		= 0,
+};
+
+static struct resource resources_uart_gsbi8[] = {
+	{
+		.start	= GSBI8_UARTDM_IRQ,
+		.end	= GSBI8_UARTDM_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= MSM_UART8DM_PHYS,
+		.end	= MSM_UART8DM_PHYS + PAGE_SIZE - 1,
+		.name	= "uartdm_resource",
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= MSM_GSBI8_PHYS,
+		.end	= MSM_GSBI8_PHYS + PAGE_SIZE - 1,
+		.name	= "gsbi_resource",
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+struct platform_device msm8960_device_uart_gsbi8 = {
+	.name	= "msm_serial_hsl",
+	.id	= 1,
+	.num_resources	   = ARRAY_SIZE(resources_uart_gsbi8),
+	.resource	   = resources_uart_gsbi8,
+	.dev.platform_data = &uart_gsbi8_pdata,
+};
+
 /* MSM Video core device */
 #ifdef CONFIG_MSM_BUS_SCALING
 static struct msm_bus_vectors vidc_init_vectors[] = {
diff --git a/arch/arm/mach-msm/devices-msm7x27.c b/arch/arm/mach-msm/devices-msm7x27.c
index 77314e7..5ec339e 100644
--- a/arch/arm/mach-msm/devices-msm7x27.c
+++ b/arch/arm/mach-msm/devices-msm7x27.c
@@ -855,6 +855,7 @@
 	.num_levels = 1,
 	.set_grp_async = NULL,
 	.idle_timeout = HZ,
+	.strtstp_sleepwake = true,
 	.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE | KGSL_CLK_MEM,
 };
 
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 4575166..70f1c2c 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -809,6 +809,7 @@
 	.num_levels = 3,
 	.set_grp_async = set_grp_xbar_async,
 	.idle_timeout = HZ,
+	.strtstp_sleepwake = true,
 	.nap_allowed = false,
 	.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE | KGSL_CLK_MEM,
 };
@@ -836,8 +837,10 @@
 
 void __init msm8x25_kgsl_3d0_init(void)
 {
-	if (cpu_is_msm8625())
+	if (cpu_is_msm8625()) {
 		kgsl_3d0_pdata.idle_timeout = HZ/5;
+		kgsl_3d0_pdata.strtstp_sleepwake = false;
+	}
 }
 
 static void __init msm_register_device(struct platform_device *pdev, void *data)
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 5758dc4..078e931 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -55,6 +55,7 @@
 
 extern struct platform_device msm8960_device_uart_gsbi2;
 extern struct platform_device msm8960_device_uart_gsbi5;
+extern struct platform_device msm8960_device_uart_gsbi8;
 extern struct platform_device msm8960_device_ssbi_pmic;
 extern struct platform_device msm8960_device_qup_i2c_gsbi3;
 extern struct platform_device msm8960_device_qup_i2c_gsbi4;
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
index 087227c..b055f4e 100644
--- a/arch/arm/mach-msm/dma.c
+++ b/arch/arm/mach-msm/dma.c
@@ -61,16 +61,17 @@
 	size_t sd_size;
 	struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
 	struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
-	spinlock_t lock;
+	struct mutex lock;
+	spinlock_t list_lock;
 	unsigned int irq;
 	struct clk *clk;
 	struct clk *pclk;
 	struct clk *ebiclk;
 	unsigned int clk_ctl;
-	struct timer_list timer;
+	struct delayed_work work;
 };
 
-static void msm_dmov_clock_timer(unsigned long);
+static void msm_dmov_clock_work(struct work_struct *);
 static int msm_dmov_clk_toggle(int, int);
 
 #ifdef CONFIG_ARCH_MSM8X60
@@ -163,15 +164,19 @@
 	{
 		.crci_conf = adm0_crci_conf,
 		.chan_conf = adm0_chan_conf,
-		.lock = __SPIN_LOCK_UNLOCKED(dmov_lock),
+		.lock = __MUTEX_INITIALIZER(dmov_conf[0].lock),
+		.list_lock = __SPIN_LOCK_UNLOCKED(dmov_list_lock),
 		.clk_ctl = CLK_DIS,
-		.timer = TIMER_INITIALIZER(msm_dmov_clock_timer, 0, 0),
+		.work = __DELAYED_WORK_INITIALIZER(dmov_conf[0].work,
+				msm_dmov_clock_work),
 	}, {
 		.crci_conf = adm1_crci_conf,
 		.chan_conf = adm1_chan_conf,
-		.lock = __SPIN_LOCK_UNLOCKED(dmov_lock),
+		.lock = __MUTEX_INITIALIZER(dmov_conf[1].lock),
+		.list_lock = __SPIN_LOCK_UNLOCKED(dmov_list_lock),
 		.clk_ctl = CLK_DIS,
-		.timer = TIMER_INITIALIZER(msm_dmov_clock_timer, 0, 1),
+		.work = __DELAYED_WORK_INITIALIZER(dmov_conf[1].work,
+				msm_dmov_clock_work),
 	}
 };
 #else
@@ -179,9 +184,11 @@
 	{
 		.crci_conf = NULL,
 		.chan_conf = NULL,
-		.lock = __SPIN_LOCK_UNLOCKED(dmov_lock),
+		.lock = __MUTEX_INITIALIZER(dmov_conf[0].lock),
+		.list_lock = __SPIN_LOCK_UNLOCKED(dmov_list_lock),
 		.clk_ctl = CLK_DIS,
-		.timer = TIMER_INITIALIZER(msm_dmov_clock_timer, 0, 0),
+		.work = __DELAYED_WORK_INITIALIZER(dmov_conf[0].work,
+				msm_dmov_clock_work),
 	}
 };
 #endif
@@ -257,16 +264,18 @@
 	return ret;
 }
 
-static void msm_dmov_clock_timer(unsigned long adm)
+static void msm_dmov_clock_work(struct work_struct *work)
 {
-	unsigned long irq_flags;
-	spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
-	if (dmov_conf[adm].clk_ctl == CLK_TO_BE_DIS) {
-		BUG_ON(dmov_conf[adm].channel_active);
+	struct msm_dmov_conf *conf =
+		container_of(to_delayed_work(work), struct msm_dmov_conf, work);
+	int adm = DMOV_IRQ_TO_ADM(conf->irq);
+	mutex_lock(&conf->lock);
+	if (conf->clk_ctl == CLK_TO_BE_DIS) {
+		BUG_ON(conf->channel_active);
 		msm_dmov_clk_toggle(adm, 0);
-		dmov_conf[adm].clk_ctl = CLK_DIS;
+		conf->clk_ctl = CLK_DIS;
 	}
-	spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
+	mutex_unlock(&conf->lock);
 }
 
 void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful)
@@ -278,48 +287,83 @@
 }
 EXPORT_SYMBOL(msm_dmov_stop_cmd);
 
-void msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd)
+/* Caller must hold the list lock */
+static void start_ready_cmd(unsigned ch, int adm)
 {
-	unsigned long irq_flags;
-	unsigned int status;
+	struct msm_dmov_cmd *cmd;
+
+	if (list_empty(&dmov_conf[adm].ready_commands[ch]))
+		return;
+
+	cmd = list_entry(dmov_conf[adm].ready_commands[ch].next, typeof(*cmd),
+			 list);
+	list_del(&cmd->list);
+	if (cmd->exec_func)
+		cmd->exec_func(cmd);
+	list_add_tail(&cmd->list, &dmov_conf[adm].active_commands[ch]);
+	if (!dmov_conf[adm].channel_active)
+		enable_irq(dmov_conf[adm].irq);
+	dmov_conf[adm].channel_active |= BIT(ch);
+	PRINT_IO("msm dmov enqueue command %x\n", cmd->cmdptr);
+	writel_relaxed(cmd->cmdptr, DMOV_REG(DMOV_CMD_PTR(ch), adm));
+}
+
+static void msm_dmov_enqueue_cmd_ext_work(struct work_struct *work)
+{
+	struct msm_dmov_cmd *cmd =
+		container_of(work, struct msm_dmov_cmd, work);
+	unsigned id = cmd->id;
+	unsigned status;
+	unsigned long flags;
 	int adm = DMOV_ID_TO_ADM(id);
 	int ch = DMOV_ID_TO_CHAN(id);
 
-	spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
+	mutex_lock(&dmov_conf[adm].lock);
 	if (dmov_conf[adm].clk_ctl == CLK_DIS) {
 		status = msm_dmov_clk_toggle(adm, 1);
 		if (status != 0)
 			goto error;
 	} else if (dmov_conf[adm].clk_ctl == CLK_TO_BE_DIS)
-		del_timer(&dmov_conf[adm].timer);
+		cancel_delayed_work_sync(&dmov_conf[adm].work);
 	dmov_conf[adm].clk_ctl = CLK_EN;
 
+	spin_lock_irqsave(&dmov_conf[adm].list_lock, flags);
+
 	status = readl_relaxed(DMOV_REG(DMOV_STATUS(ch), adm));
 	if (status & DMOV_STATUS_CMD_PTR_RDY) {
 		PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n",
 			id, status);
-		if (cmd->exec_func)
-			cmd->exec_func(cmd);
-		list_add_tail(&cmd->list, &dmov_conf[adm].active_commands[ch]);
-		if (!dmov_conf[adm].channel_active)
-			enable_irq(dmov_conf[adm].irq);
-		dmov_conf[adm].channel_active |= 1U << ch;
-		PRINT_IO("Writing %x exactly to register", cmd->cmdptr);
-		writel_relaxed(cmd->cmdptr, DMOV_REG(DMOV_CMD_PTR(ch), adm));
+		start_ready_cmd(ch, adm);
 	} else {
-		if (!dmov_conf[adm].channel_active) {
-			dmov_conf[adm].clk_ctl = CLK_TO_BE_DIS;
-			mod_timer(&dmov_conf[adm].timer, jiffies + HZ);
-		}
-		if (list_empty(&dmov_conf[adm].active_commands[ch]))
+		if (list_empty(&dmov_conf[adm].active_commands[ch]) &&
+		    !list_empty(&dmov_conf[adm].ready_commands[ch]))
 			PRINT_ERROR("msm_dmov_enqueue_cmd_ext(%d), stalled, "
 				"status %x\n", id, status);
 		PRINT_IO("msm_dmov_enqueue_cmd(%d), enqueue command, status "
 		    "%x\n", id, status);
-		list_add_tail(&cmd->list, &dmov_conf[adm].ready_commands[ch]);
 	}
+	if (!dmov_conf[adm].channel_active) {
+		dmov_conf[adm].clk_ctl = CLK_TO_BE_DIS;
+		schedule_delayed_work(&dmov_conf[adm].work, HZ);
+	}
+	spin_unlock_irqrestore(&dmov_conf[adm].list_lock, flags);
 error:
-	spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
+	mutex_unlock(&dmov_conf[adm].lock);
+}
+
+void msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd)
+{
+	int adm = DMOV_ID_TO_ADM(id);
+	int ch = DMOV_ID_TO_CHAN(id);
+	unsigned long flags;
+	cmd->id = id;
+	INIT_WORK(&cmd->work, msm_dmov_enqueue_cmd_ext_work);
+
+	spin_lock_irqsave(&dmov_conf[adm].list_lock, flags);
+	list_add_tail(&cmd->list, &dmov_conf[adm].ready_commands[ch]);
+	spin_unlock_irqrestore(&dmov_conf[adm].list_lock, flags);
+
+	schedule_work(&cmd->work);
 }
 EXPORT_SYMBOL(msm_dmov_enqueue_cmd_ext);
 
@@ -337,14 +381,14 @@
 	unsigned long irq_flags;
 	int ch = DMOV_ID_TO_CHAN(id);
 	int adm = DMOV_ID_TO_ADM(id);
-	spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
+	spin_lock_irqsave(&dmov_conf[adm].list_lock, irq_flags);
 	/* XXX not checking if flush cmd sent already */
 	if (!list_empty(&dmov_conf[adm].active_commands[ch])) {
 		PRINT_IO("msm_dmov_flush(%d), send flush cmd\n", id);
 		writel_relaxed(DMOV_FLUSH_TYPE, DMOV_REG(DMOV_FLUSH0(ch), adm));
 	}
 	/* spin_unlock_irqrestore has the necessary barrier */
-	spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
+	spin_unlock_irqrestore(&dmov_conf[adm].list_lock, irq_flags);
 }
 EXPORT_SYMBOL(msm_dmov_flush);
 
@@ -406,7 +450,7 @@
 	errdata->flush[5] = readl_relaxed(DMOV_REG(DMOV_FLUSH5(ch), adm));
 }
 
-static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
+static irqreturn_t msm_dmov_isr(int irq, void *dev_id)
 {
 	unsigned int int_status;
 	unsigned int mask;
@@ -419,11 +463,12 @@
 	struct msm_dmov_cmd *cmd;
 	int adm = DMOV_IRQ_TO_ADM(irq);
 
-	spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
+	mutex_lock(&dmov_conf[adm].lock);
 	/* read and clear isr */
 	int_status = readl_relaxed(DMOV_REG(DMOV_ISR, adm));
 	PRINT_FLOW("msm_datamover_irq_handler: DMOV_ISR %x\n", int_status);
 
+	spin_lock_irqsave(&dmov_conf[adm].list_lock, irq_flags);
 	while (int_status) {
 		mask = int_status & -int_status;
 		ch = fls(mask) - 1;
@@ -491,50 +536,40 @@
 			ch_status = readl_relaxed(DMOV_REG(DMOV_STATUS(ch),
 						  adm));
 			PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
-			if ((ch_status & DMOV_STATUS_CMD_PTR_RDY) &&
-			    !list_empty(&dmov_conf[adm].ready_commands[ch])) {
-				cmd = list_entry(dmov_conf[adm].
-					ready_commands[ch].next, typeof(*cmd),
-					list);
-				list_del(&cmd->list);
-				if (cmd->exec_func)
-					cmd->exec_func(cmd);
-				list_add_tail(&cmd->list,
-					&dmov_conf[adm].active_commands[ch]);
+			if (ch_status & DMOV_STATUS_CMD_PTR_RDY) {
+				start_ready_cmd(ch, adm);
 				PRINT_FLOW("msm_datamover_irq_handler id %d, start command\n", id);
-				writel_relaxed(cmd->cmdptr,
-					       DMOV_REG(DMOV_CMD_PTR(ch), adm));
 			}
 		} while (ch_status & DMOV_STATUS_RSLT_VALID);
 		if (list_empty(&dmov_conf[adm].active_commands[ch]) &&
-				list_empty(&dmov_conf[adm].ready_commands[ch]))
+		    list_empty(&dmov_conf[adm].ready_commands[ch]))
 			dmov_conf[adm].channel_active &= ~(1U << ch);
 		PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
 	}
+	spin_unlock_irqrestore(&dmov_conf[adm].list_lock, irq_flags);
 
 	if (!dmov_conf[adm].channel_active && valid) {
 		disable_irq_nosync(dmov_conf[adm].irq);
 		dmov_conf[adm].clk_ctl = CLK_TO_BE_DIS;
-		mod_timer(&dmov_conf[adm].timer, jiffies + HZ);
+		schedule_delayed_work(&dmov_conf[adm].work, HZ);
 	}
 
-	spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
+	mutex_unlock(&dmov_conf[adm].lock);
 	return valid ? IRQ_HANDLED : IRQ_NONE;
 }
 
 static int msm_dmov_suspend_late(struct device *dev)
 {
-	unsigned long irq_flags;
 	struct platform_device *pdev = to_platform_device(dev);
 	int adm = (pdev->id >= 0) ? pdev->id : 0;
-	spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
+	mutex_lock(&dmov_conf[adm].lock);
 	if (dmov_conf[adm].clk_ctl == CLK_TO_BE_DIS) {
 		BUG_ON(dmov_conf[adm].channel_active);
-		del_timer(&dmov_conf[adm].timer);
+		cancel_delayed_work_sync(&dmov_conf[adm].work);
 		msm_dmov_clk_toggle(adm, 0);
 		dmov_conf[adm].clk_ctl = CLK_DIS;
 	}
-	spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
+	mutex_unlock(&dmov_conf[adm].lock);
 	return 0;
 }
 
@@ -649,8 +684,8 @@
 	if (!dmov_conf[adm].base)
 		return -ENOMEM;
 
-	ret = request_irq(dmov_conf[adm].irq, msm_datamover_irq_handler,
-		0, "msmdatamover", NULL);
+	ret = request_threaded_irq(dmov_conf[adm].irq, NULL, msm_dmov_isr,
+				   IRQF_ONESHOT, "msmdatamover", NULL);
 	if (ret) {
 		PRINT_ERROR("Requesting ADM%d irq %d failed\n", adm,
 			dmov_conf[adm].irq);
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h
index d170f5f..6e58ebe 100644
--- a/arch/arm/mach-msm/include/mach/dma.h
+++ b/arch/arm/mach-msm/include/mach/dma.h
@@ -1,7 +1,7 @@
 /* linux/include/asm-arm/arch-msm/dma.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -35,6 +35,8 @@
 			      unsigned int result,
 			      struct msm_dmov_errdata *err);
 	void (*exec_func)(struct msm_dmov_cmd *cmd);
+	struct work_struct work;
+	unsigned id;    /* For internal use */
 	void *user;	/* Pointer for caller's reference */
 };
 
diff --git a/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
index 57f2d37..af82fd9 100644
--- a/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
+++ b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
@@ -57,8 +57,9 @@
 #define FL_TYPE_TABLE		(1 << 0)
 #define FL_TYPE_SECT		(2 << 0)
 #define FL_SUPERSECTION		(1 << 18)
-#define FL_AP_WRITE		(1 << 10)
-#define FL_AP_READ		(1 << 11)
+#define FL_AP0			(1 << 10)
+#define FL_AP1			(1 << 11)
+#define FL_AP2			(1 << 15)
 #define FL_SHARED		(1 << 16)
 #define FL_BUFFERABLE		(1 << 2)
 #define FL_CACHEABLE		(1 << 3)
@@ -73,6 +74,7 @@
 #define SL_TYPE_SMALL		(2 << 0)
 #define SL_AP0			(1 << 4)
 #define SL_AP1			(2 << 4)
+#define SL_AP2			(1 << 9)
 #define SL_SHARED		(1 << 10)
 #define SL_BUFFERABLE		(1 << 2)
 #define SL_CACHEABLE		(1 << 3)
diff --git a/arch/arm/mach-msm/include/mach/msm_rtb.h b/arch/arm/mach-msm/include/mach/msm_rtb.h
index 5eea63f..74ddfbd 100644
--- a/arch/arm/mach-msm/include/mach/msm_rtb.h
+++ b/arch/arm/mach-msm/include/mach/msm_rtb.h
@@ -15,7 +15,7 @@
 
 /*
  * These numbers are used from the kernel command line and sysfs
- * to control filtering. Remove items from here with extreme caution
+ * to control filtering. Remove items from here with extreme caution.
  */
 enum logk_event_type {
 	LOGK_NONE = 0,
@@ -24,9 +24,11 @@
 	LOGK_LOGBUF = 3,
 	LOGK_HOTPLUG = 4,
 	LOGK_CTXID = 5,
-	LOGK_OTHER = 31,
+	LOGK_TIMESTAMP = 6,
 };
 
+#define LOGTYPE_NOPC 0x80
+
 struct msm_rtb_platform_data {
 	unsigned int size;
 };
diff --git a/arch/arm/mach-msm/include/mach/msm_smsm.h b/arch/arm/mach-msm/include/mach/msm_smsm.h
index 772c9f6..5c3307e 100644
--- a/arch/arm/mach-msm/include/mach/msm_smsm.h
+++ b/arch/arm/mach-msm/include/mach/msm_smsm.h
@@ -100,6 +100,21 @@
 void *smem_get_entry(unsigned id, unsigned *size);
 int smsm_change_state(uint32_t smsm_entry,
 		      uint32_t clear_mask, uint32_t set_mask);
+
+/*
+ * Changes the global interrupt mask.  The set and clear masks are re-applied
+ * every time the global interrupt mask is updated for callback registration
+ * and de-registration.
+ *
+ * The clear mask is applied first, so if a bit is set to 1 in both the clear
+ * mask and the set mask, the result will be that the interrupt is set.
+ *
+ * @smsm_entry  SMSM entry to change
+ * @clear_mask  1 = clear bit, 0 = no-op
+ * @set_mask    1 = set bit, 0 = no-op
+ *
+ * @returns 0 for success, < 0 for error
+ */
 int smsm_change_intr_mask(uint32_t smsm_entry,
 			  uint32_t clear_mask, uint32_t set_mask);
 int smsm_get_intr_mask(uint32_t smsm_entry, uint32_t *intr_mask);
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h b/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h
index dd5ddd8..bd303b2 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h
@@ -135,6 +135,8 @@
 	uint16_t event_types;
 	/* Input event source */
 	enum us_input_event_src_type event_src;
+	/* Bitmap of types of events from devs, conflicting with USF */
+	uint16_t conflicting_event_types;
 };
 
 struct us_tx_info_type {
@@ -208,6 +210,8 @@
 /* Time (sec) to wait for data or special values: */
 /* USF_NO_WAIT_TIMEOUT, USF_INFINITIVE_TIMEOUT, USF_DEFAULT_TIMEOUT */
 	uint32_t timeout;
+/* Events (from conflicting devs) to be disabled/enabled */
+	uint16_t event_filters;
 
 /* Input  transparent data: */
 /* Parameters size */
diff --git a/arch/arm/mach-msm/include/mach/socinfo.h b/arch/arm/mach-msm/include/mach/socinfo.h
index 99bf212..aee562e 100644
--- a/arch/arm/mach-msm/include/mach/socinfo.h
+++ b/arch/arm/mach-msm/include/mach/socinfo.h
@@ -44,6 +44,8 @@
 #define machine_is_copper_sim()	0
 #endif
 
+#define PLATFORM_SUBTYPE_SGLTE	6
+
 enum msm_cpu {
 	MSM_CPU_UNKNOWN = 0,
 	MSM_CPU_7X01,
diff --git a/arch/arm/mach-msm/iommu.c b/arch/arm/mach-msm/iommu.c
index d495c1b..19e1684 100644
--- a/arch/arm/mach-msm/iommu.c
+++ b/arch/arm/mach-msm/iommu.c
@@ -421,6 +421,16 @@
 	unsigned int pgprot;
 	int tex;
 
+	if (!(prot & (IOMMU_READ | IOMMU_WRITE))) {
+		prot |= IOMMU_READ | IOMMU_WRITE;
+		WARN_ONCE(1, "No attributes in iommu mapping; assuming RW\n");
+	}
+
+	if ((prot & IOMMU_WRITE) && !(prot & IOMMU_READ)) {
+		prot |= IOMMU_READ;
+		WARN_ONCE(1, "Write-only iommu mappings unsupported; falling back to RW\n");
+	}
+
 	if (prot & IOMMU_CACHE)
 		tex = (pgprot_kernel >> 2) & 0x07;
 	else
@@ -434,11 +444,15 @@
 		pgprot |= tex & 0x01 ? FL_BUFFERABLE : 0;
 		pgprot |= tex & 0x02 ? FL_CACHEABLE : 0;
 		pgprot |= tex & 0x04 ? FL_TEX0 : 0;
+		pgprot |= FL_AP0 | FL_AP1;
+		pgprot |= prot & IOMMU_WRITE ? 0 : FL_AP2;
 	} else	{
 		pgprot = SL_SHARED;
 		pgprot |= tex & 0x01 ? SL_BUFFERABLE : 0;
 		pgprot |= tex & 0x02 ? SL_CACHEABLE : 0;
 		pgprot |= tex & 0x04 ? SL_TEX0 : 0;
+		pgprot |= SL_AP0 | SL_AP1;
+		pgprot |= prot & IOMMU_WRITE ? 0 : SL_AP2;
 	}
 
 	return pgprot;
@@ -501,9 +515,8 @@
 			}
 
 		for (i = 0; i < 16; i++)
-			*(fl_pte+i) = (pa & 0xFF000000) | FL_SUPERSECTION |
-				  FL_AP_READ | FL_AP_WRITE | FL_TYPE_SECT |
-				  FL_SHARED | FL_NG | pgprot;
+			*(fl_pte+i) = (pa & 0xFF000000) | FL_SUPERSECTION
+				  | FL_TYPE_SECT | FL_SHARED | FL_NG | pgprot;
 		if (!priv->redirect)
 			clean_pte(fl_pte, fl_pte + 16);
 	}
@@ -514,8 +527,8 @@
 			goto fail;
 		}
 
-		*fl_pte = (pa & 0xFFF00000) | FL_AP_READ | FL_AP_WRITE | FL_NG |
-					    FL_TYPE_SECT | FL_SHARED | pgprot;
+		*fl_pte = (pa & 0xFFF00000) | FL_NG | FL_TYPE_SECT | FL_SHARED
+					    | pgprot;
 		if (!priv->redirect)
 			clean_pte(fl_pte, fl_pte + 1);
 	}
@@ -558,8 +571,8 @@
 			goto fail;
 		}
 
-		*sl_pte = (pa & SL_BASE_MASK_SMALL) | SL_AP0 | SL_AP1 | SL_NG |
-					  SL_SHARED | SL_TYPE_SMALL | pgprot;
+		*sl_pte = (pa & SL_BASE_MASK_SMALL) | SL_NG | SL_SHARED
+						    | SL_TYPE_SMALL | pgprot;
 		if (!priv->redirect)
 			clean_pte(sl_pte, sl_pte + 1);
 	}
@@ -574,8 +587,8 @@
 			}
 
 		for (i = 0; i < 16; i++)
-			*(sl_pte+i) = (pa & SL_BASE_MASK_LARGE) | SL_AP0 |
-			    SL_NG | SL_AP1 | SL_SHARED | SL_TYPE_LARGE | pgprot;
+			*(sl_pte+i) = (pa & SL_BASE_MASK_LARGE) | SL_NG
+					  | SL_SHARED | SL_TYPE_LARGE | pgprot;
 
 		if (!priv->redirect)
 			clean_pte(sl_pte, sl_pte + 16);
@@ -776,8 +789,7 @@
 		while (offset < len && sl_offset < NUM_SL_PTE) {
 			pa = chunk_pa + chunk_offset;
 			sl_table[sl_offset] = (pa & SL_BASE_MASK_SMALL) |
-					      pgprot | SL_AP0 | SL_AP1 | SL_NG |
-					      SL_SHARED | SL_TYPE_SMALL;
+				     pgprot | SL_NG | SL_SHARED | SL_TYPE_SMALL;
 			sl_offset++;
 			offset += SZ_4K;
 
diff --git a/arch/arm/mach-msm/msm_rtb.c b/arch/arm/mach-msm/msm_rtb.c
index 3f56d1a..403c13d 100644
--- a/arch/arm/mach-msm/msm_rtb.c
+++ b/arch/arm/mach-msm/msm_rtb.c
@@ -20,6 +20,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/string.h>
+#include <linux/atomic.h>
 #include <asm/io.h>
 #include <asm-generic/sizes.h>
 #include <mach/memory.h>
@@ -76,7 +77,7 @@
 int msm_rtb_event_should_log(enum logk_event_type log_type)
 {
 	return msm_rtb.initialized && msm_rtb.enabled &&
-		((1 << log_type) & msm_rtb.filter);
+		((1 << (log_type & ~LOGTYPE_NOPC)) & msm_rtb.filter);
 }
 EXPORT_SYMBOL(msm_rtb_event_should_log);
 
@@ -109,10 +110,39 @@
 	start->data = data;
 }
 
+static void uncached_logk_pc_idx(enum logk_event_type log_type, void *caller,
+				 void *data, int idx)
+{
+	struct msm_rtb_layout *start;
+
+	start = &msm_rtb.rtb[idx & (msm_rtb.nentries - 1)];
+
+	msm_rtb_emit_sentinel(start);
+	msm_rtb_write_type(log_type, start);
+	msm_rtb_write_caller(caller, start);
+	msm_rtb_write_idx(idx, start);
+	msm_rtb_write_data(data, start);
+	mb();
+
+	return;
+}
+
+static void uncached_logk_timestamp(int idx)
+{
+	unsigned long long timestamp;
+	void *timestamp_upper, *timestamp_lower;
+	timestamp = sched_clock();
+	timestamp_lower = (void *)lower_32_bits(timestamp);
+	timestamp_upper = (void *)upper_32_bits(timestamp);
+
+	uncached_logk_pc_idx(LOGK_TIMESTAMP|LOGTYPE_NOPC, timestamp_lower,
+			     timestamp_upper, idx);
+}
+
 #if defined(CONFIG_MSM_RTB_SEPARATE_CPUS)
 static int msm_rtb_get_idx(void)
 {
-	int cpu, i;
+	int cpu, i, offset;
 	atomic_t *index;
 
 	/*
@@ -126,16 +156,34 @@
 	i = atomic_add_return(msm_rtb.step_size, index);
 	i -= msm_rtb.step_size;
 
+	/* Check if index has wrapped around */
+	offset = (i & (msm_rtb.nentries - 1)) -
+		 ((i - msm_rtb.step_size) & (msm_rtb.nentries - 1));
+	if (offset < 0) {
+		uncached_logk_timestamp(i);
+		i = atomic_add_return(msm_rtb.step_size, index);
+		i -= msm_rtb.step_size;
+	}
+
 	return i;
 }
 #else
 static int msm_rtb_get_idx(void)
 {
-	int i;
+	int i, offset;
 
 	i = atomic_inc_return(&msm_rtb_idx);
 	i--;
 
+	/* Check if index has wrapped around */
+	offset = (i & (msm_rtb.nentries - 1)) -
+		 ((i - 1) & (msm_rtb.nentries - 1));
+	if (offset < 0) {
+		uncached_logk_timestamp(i);
+		i = atomic_inc_return(&msm_rtb_idx);
+		i--;
+	}
+
 	return i;
 }
 #endif
@@ -144,21 +192,13 @@
 				void *data)
 {
 	int i;
-	struct msm_rtb_layout *start;
 
 	if (!msm_rtb_event_should_log(log_type))
 		return 0;
 
 	i = msm_rtb_get_idx();
 
-	start = &msm_rtb.rtb[i & (msm_rtb.nentries - 1)];
-
-	msm_rtb_emit_sentinel(start);
-	msm_rtb_write_type(log_type, start);
-	msm_rtb_write_caller(caller, start);
-	msm_rtb_write_idx(i, start);
-	msm_rtb_write_data(data, start);
-	mb();
+	uncached_logk_pc_idx(log_type, caller, data, i);
 
 	return 1;
 }
diff --git a/arch/arm/mach-msm/qdsp6v2/apr.c b/arch/arm/mach-msm/qdsp6v2/apr.c
index b5f071f..2403c02 100644
--- a/arch/arm/mach-msm/qdsp6v2/apr.c
+++ b/arch/arm/mach-msm/qdsp6v2/apr.c
@@ -371,14 +371,11 @@
 	mutex_lock(&q6.lock);
 	if (q6.state == APR_Q6_NOIMG) {
 		q6.pil = pil_get("q6");
-		if (!q6.pil) {
-			pr_err("APR: Unable to load q6 image\n");
+		if (IS_ERR(q6.pil)) {
+			rc = PTR_ERR(q6.pil);
+			pr_err("APR: Unable to load q6 image, error:%d\n", rc);
 			mutex_unlock(&q6.lock);
-			/* Return failure if not intended for simulator */
-			if (!machine_is_apq8064_sim()) {
-				pr_debug("APR: Not apq8064 sim\n");
-				return svc;
-			}
+			return svc;
 		}
 		q6.state = APR_Q6_LOADED;
 	}
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/Makefile b/arch/arm/mach-msm/qdsp6v2/ultrasound/Makefile
index 540119b..0be1303 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/Makefile
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/Makefile
@@ -1,2 +1,2 @@
-obj-y += q6usm.o usf.o
+obj-y += q6usm.o usf.o usfcdev.o
 EXTRA_CFLAGS += -I$(src)/..
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
index 64f70c5..b4a0a7f 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
@@ -24,9 +24,10 @@
 #include <sound/apr_audio.h>
 #include <mach/qdsp6v2/usf.h>
 #include "q6usm.h"
+#include "usfcdev.h"
 
 /* The driver version*/
-#define DRV_VERSION "1.2"
+#define DRV_VERSION "1.3"
 
 /* Standard timeout in the asynchronous ops */
 #define USF_TIMEOUT_JIFFIES (3*HZ) /* 3 sec */
@@ -111,6 +112,10 @@
 	struct input_dev *input_if;
 	/*  The event source */
 	int event_src;
+	/* Bitmap of types of events, conflicting to USF's ones */
+	uint16_t conflicting_event_types;
+	/* Bitmap of types of events from devs, conflicting with USF */
+	uint16_t conflicting_event_filters;
 };
 
 /* The MAX number of the supported devices */
@@ -126,6 +131,9 @@
 /* The opened devices container */
 static int s_opened_devs[MAX_DEVS_NUMBER];
 
+#define USF_NAME_PREFIX "USF_"
+#define USF_NAME_PREFIX_SIZE 4
+
 static void usf_rx_cb(uint32_t opcode, uint32_t token,
 		      uint32_t *payload, void *priv)
 {
@@ -316,11 +324,70 @@
 	return rc;
 }
 
+static bool usf_match(uint16_t event_type_ind, struct input_dev *dev)
+{
+	bool rc = false;
+
+	rc = (event_type_ind < MAX_EVENT_TYPE_NUM) &&
+		((dev->name == NULL) ||
+		strncmp(dev->name, USF_NAME_PREFIX, USF_NAME_PREFIX_SIZE));
+	pr_debug("%s: name=[%s]; rc=%d\n",
+		 __func__, dev->name, rc);
+
+	return rc;
+}
+
+static bool usf_register_conflicting_events(uint16_t event_types)
+{
+	bool rc = true;
+	uint16_t ind = 0;
+	uint16_t mask = 1;
+
+	for (ind = 0; ind < MAX_EVENT_TYPE_NUM; ++ind) {
+		if (event_types & mask) {
+			rc = usfcdev_register(ind, usf_match);
+			if (!rc)
+				break;
+		}
+		mask = mask << 1;
+	}
+
+	return rc;
+}
+
+static void usf_unregister_conflicting_events(uint16_t event_types)
+{
+	uint16_t ind = 0;
+	uint16_t mask = 1;
+
+	for (ind = 0; ind < MAX_EVENT_TYPE_NUM; ++ind) {
+		if (event_types & mask)
+			usfcdev_unregister(ind);
+		mask = mask << 1;
+	}
+}
+
+static void usf_set_event_filters(struct usf_type *usf, uint16_t event_filters)
+{
+	uint16_t ind = 0;
+	uint16_t mask = 1;
+
+	if (usf->conflicting_event_filters != event_filters) {
+		for (ind = 0; ind < MAX_EVENT_TYPE_NUM; ++ind) {
+			if (usf->conflicting_event_types & mask)
+				usfcdev_set_filter(ind, event_filters&mask);
+			mask = mask << 1;
+		}
+		usf->conflicting_event_filters = event_filters;
+	}
+}
+
 static int register_input_device(struct usf_type *usf_info,
 				 struct us_input_info_type *input_info)
 {
 	int rc = 0;
 	struct input_dev *input_dev = NULL;
+	bool ret = true;
 
 	if ((usf_info == NULL) ||
 	    (input_info == NULL) ||
@@ -417,6 +484,11 @@
 		usf_info->event_types = input_info->event_types;
 		pr_debug("%s: input device[%s] was registered\n",
 			__func__, input_dev->name);
+		ret = usf_register_conflicting_events(
+					input_info->conflicting_event_types);
+		if (ret)
+			usf_info->conflicting_event_types =
+				input_info->conflicting_event_types;
 	}
 
 	return rc;
@@ -826,6 +898,7 @@
 	}
 
 	if (!usf_xx->user_upd_info_na) {
+		usf_set_event_filters(usf, upd_tx_info.event_filters);
 		handle_input_event(usf,
 				   upd_tx_info.event_counter,
 				   upd_tx_info.event);
@@ -963,16 +1036,23 @@
 	return rc;
 } /* usf_set_rx_update */
 
+static void usf_release_input(struct usf_type *usf)
+{
+	if (usf->input_if != NULL) {
+		usf_unregister_conflicting_events(
+						usf->conflicting_event_types);
+		usf->conflicting_event_types = 0;
+		input_unregister_device(usf->input_if);
+		usf->input_if = NULL;
+		pr_debug("%s input_unregister_device\n",  __func__);
+	}
+} /* usf_release_input */
+
 static int usf_stop_tx(struct usf_type *usf)
 {
 	struct usf_xx_type *usf_xx =  &usf->usf_tx;
 
-	if (usf->input_if != NULL) {
-		input_unregister_device(usf->input_if);
-		usf->input_if = NULL;
-		pr_debug("%s input_unregister_device",
-			__func__);
-	}
+	usf_release_input(usf);
 	usf_disable(usf_xx);
 
 	return 0;
@@ -1225,18 +1305,13 @@
 	return 0;
 }
 
-
 static int usf_release(struct inode *inode, struct file *file)
 {
 	struct usf_type *usf = file->private_data;
 
 	pr_debug("%s: release entry\n", __func__);
 
-	if (usf->input_if != NULL) {
-		input_unregister_device(usf->input_if);
-		usf->input_if = NULL;
-		pr_debug("%s input_unregister_device\n",  __func__);
-	}
+	usf_release_input(usf);
 
 	usf_disable(&usf->usf_tx);
 	usf_disable(&usf->usf_rx);
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.c
new file mode 100644
index 0000000..b99a9b0
--- /dev/null
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.c
@@ -0,0 +1,236 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include "usfcdev.h"
+
+struct usfcdev_event {
+	bool (*match_cb)(uint16_t, struct input_dev *dev);
+	bool registered_event;
+	bool filter;
+};
+static struct usfcdev_event s_usfcdev_events[MAX_EVENT_TYPE_NUM];
+
+static bool usfcdev_filter(struct input_handle *handle,
+			 unsigned int type, unsigned int code, int value);
+static bool usfcdev_match(struct input_handler *handler,
+				struct input_dev *dev);
+static int usfcdev_connect(struct input_handler *handler,
+				struct input_dev *dev,
+				const struct input_device_id *id);
+static void usfcdev_disconnect(struct input_handle *handle);
+
+static const struct input_device_id usfc_tsc_ids[] = {
+	{
+		.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+			INPUT_DEVICE_ID_MATCH_KEYBIT |
+			INPUT_DEVICE_ID_MATCH_ABSBIT,
+		.evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) },
+		.keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
+		.absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) },
+	},
+	{ } /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(input, usfc_tsc_ids);
+
+static struct input_handler s_usfc_handlers[MAX_EVENT_TYPE_NUM] = {
+	{ /* TSC handler */
+		.filter         = usfcdev_filter,
+		.match          = usfcdev_match,
+		.connect        = usfcdev_connect,
+		.disconnect     = usfcdev_disconnect,
+		/* .minor can be used as index in the container, */
+		/*  because .fops isn't supported */
+		.minor          = TSC_EVENT_TYPE_IND,
+		.name           = "usfc_tsc_handler",
+		.id_table       = usfc_tsc_ids,
+	},
+};
+
+/* For each event type, one conflicting device (and handle) is supported */
+static struct input_handle s_usfc_handles[MAX_EVENT_TYPE_NUM] = {
+	{ /* TSC handle */
+		.handler	= &s_usfc_handlers[TSC_EVENT_TYPE_IND],
+		.name		= "usfc_tsc_handle",
+	},
+};
+
+static bool usfcdev_match(struct input_handler *handler, struct input_dev *dev)
+{
+	bool rc = false;
+	int ind = handler->minor;
+
+	pr_debug("%s: name=[%s]; ind=%d\n", __func__, dev->name, ind);
+	if (s_usfcdev_events[ind].registered_event &&
+			s_usfcdev_events[ind].match_cb) {
+		rc = (*s_usfcdev_events[ind].match_cb)((uint16_t)ind, dev);
+		pr_debug("%s: [%s]; rc=%d\n", __func__, dev->name, rc);
+	}
+
+	return rc;
+}
+
+static int usfcdev_connect(struct input_handler *handler, struct input_dev *dev,
+				const struct input_device_id *id)
+{
+	int ret = 0;
+	uint16_t ind = handler->minor;
+
+	s_usfc_handles[ind].dev = dev;
+	ret = input_register_handle(&s_usfc_handles[ind]);
+	if (ret) {
+		pr_err("%s: input_register_handle[%d] failed: ret=%d\n",
+			__func__,
+			ind,
+			ret);
+	} else {
+		ret = input_open_device(&s_usfc_handles[ind]);
+		if (ret) {
+			pr_err("%s: input_open_device[%d] failed: ret=%d\n",
+				__func__,
+				ind,
+				ret);
+			input_unregister_handle(&s_usfc_handles[ind]);
+		} else
+			pr_debug("%s: device[%d] is opened\n",
+				__func__,
+				ind);
+	}
+
+	return ret;
+}
+
+static void usfcdev_disconnect(struct input_handle *handle)
+{
+	input_unregister_handle(handle);
+	pr_debug("%s: handle[%d] is disconnect\n",
+		__func__,
+		handle->handler->minor);
+}
+
+static bool usfcdev_filter(struct input_handle *handle,
+			unsigned int type, unsigned int code, int value)
+{
+	uint16_t ind = (uint16_t)handle->handler->minor;
+
+	pr_debug("%s: event_type=%d; filter=%d\n",
+		__func__,
+		ind,
+		s_usfcdev_events[ind].filter);
+
+	return s_usfcdev_events[ind].filter;
+}
+
+bool usfcdev_register(
+	uint16_t event_type_ind,
+	bool (*match_cb)(uint16_t, struct input_dev *dev))
+{
+	int ret = 0;
+	bool rc = false;
+
+	if ((event_type_ind >= MAX_EVENT_TYPE_NUM) || !match_cb) {
+		pr_err("%s: wrong input: event_type_ind=%d; match_cb=0x%p\n",
+			__func__,
+			event_type_ind,
+			match_cb);
+		return false;
+	}
+
+	if (s_usfcdev_events[event_type_ind].registered_event) {
+		pr_info("%s: handler[%d] was already registered\n",
+			__func__,
+			event_type_ind);
+		return true;
+	}
+
+	s_usfcdev_events[event_type_ind].registered_event = true;
+	s_usfcdev_events[event_type_ind].match_cb = match_cb;
+	s_usfcdev_events[event_type_ind].filter = false;
+	ret = input_register_handler(&s_usfc_handlers[event_type_ind]);
+	if (!ret) {
+		rc = true;
+		pr_debug("%s: handler[%d] was registered\n",
+			__func__,
+			event_type_ind);
+	} else {
+		s_usfcdev_events[event_type_ind].registered_event = false;
+		s_usfcdev_events[event_type_ind].match_cb = NULL;
+		pr_err("%s: handler[%d] registration failed: ret=%d\n",
+			__func__,
+			event_type_ind,
+			ret);
+	}
+
+	return rc;
+}
+
+void usfcdev_unregister(uint16_t event_type_ind)
+{
+	if (event_type_ind >= MAX_EVENT_TYPE_NUM) {
+		pr_err("%s: wrong input: event_type_ind=%d\n",
+			__func__,
+			event_type_ind);
+		return;
+	}
+	if (s_usfcdev_events[event_type_ind].registered_event) {
+		input_unregister_handler(&s_usfc_handlers[event_type_ind]);
+		pr_debug("%s: handler[%d] was unregistered\n",
+			__func__,
+			event_type_ind);
+		s_usfcdev_events[event_type_ind].registered_event = false;
+		s_usfcdev_events[event_type_ind].match_cb = NULL;
+		s_usfcdev_events[event_type_ind].filter = false;
+	}
+}
+
+bool usfcdev_set_filter(uint16_t event_type_ind, bool filter)
+{
+	bool rc = true;
+
+	if (event_type_ind >= MAX_EVENT_TYPE_NUM) {
+		pr_err("%s: wrong input: event_type_ind=%d\n",
+			__func__,
+			event_type_ind);
+		return false;
+	}
+
+	if (s_usfcdev_events[event_type_ind].registered_event) {
+		s_usfcdev_events[event_type_ind].filter = filter;
+		pr_debug("%s: event_type[%d]; filter=%d\n",
+			__func__,
+			event_type_ind,
+			filter
+			);
+	} else {
+		pr_err("%s: event_type[%d] isn't registered\n",
+			__func__,
+			event_type_ind);
+		rc = false;
+	}
+
+	return rc;
+}
+
+static int __init usfcdev_init(void)
+{
+	return 0;
+}
+
+device_initcall(usfcdev_init);
+
+MODULE_DESCRIPTION("Handle of events from devices, conflicting with USF");
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.h b/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.h
new file mode 100644
index 0000000..042b293
--- /dev/null
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.h
@@ -0,0 +1,28 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __USFCDEV_H__
+#define __USFCDEV_H__
+
+#include <linux/input.h>
+
+/* TSC event type index in the containers of the handlers & handles */
+#define TSC_EVENT_TYPE_IND 0
+/* Number of supported event types to be filtered */
+#define MAX_EVENT_TYPE_NUM 1
+
+bool usfcdev_register(
+	uint16_t event_type_ind,
+	bool (*match_cb)(uint16_t, struct input_dev *dev));
+void usfcdev_unregister(uint16_t event_type_ind);
+bool usfcdev_set_filter(uint16_t event_type_ind, bool filter);
+#endif /* __USFCDEV_H__ */
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index d00dd1a..839f932 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -71,6 +71,10 @@
 uint32_t SMSM_NUM_ENTRIES = 8;
 uint32_t SMSM_NUM_HOSTS = 3;
 
+/* Legacy SMSM interrupt notifications */
+#define LEGACY_MODEM_SMSM_MASK (SMSM_RESET | SMSM_INIT | SMSM_SMDINIT \
+			| SMSM_RUN | SMSM_SYSTEM_DOWNLOAD)
+
 enum {
 	MSM_SMD_DEBUG = 1U << 0,
 	MSM_SMSM_DEBUG = 1U << 1,
@@ -108,6 +112,8 @@
 struct smsm_state_info {
 	struct list_head callbacks;
 	uint32_t last_value;
+	uint32_t intr_mask_set;
+	uint32_t intr_mask_clear;
 };
 
 struct interrupt_config_item {
@@ -2246,6 +2252,8 @@
 	for (n = 0; n < SMSM_NUM_ENTRIES; n++) {
 		state_info = &smsm_states[n];
 		state_info->last_value = __raw_readl(SMSM_STATE_ADDR(n));
+		state_info->intr_mask_set = 0x0;
+		state_info->intr_mask_clear = 0x0;
 		INIT_LIST_HEAD(&state_info->callbacks);
 	}
 	mutex_unlock(&smsm_lock);
@@ -2302,10 +2310,16 @@
 						  SMSM_NUM_HOSTS *
 						  sizeof(uint32_t));
 
-		if (smsm_info.intr_mask)
+		if (smsm_info.intr_mask) {
 			for (i = 0; i < SMSM_NUM_ENTRIES; i++)
-				__raw_writel(0xffffffff,
-				       SMSM_INTR_MASK_ADDR(i, SMSM_APPS));
+				__raw_writel(0x0,
+					SMSM_INTR_MASK_ADDR(i, SMSM_APPS));
+
+			/* Configure legacy modem bits */
+			__raw_writel(LEGACY_MODEM_SMSM_MASK,
+				SMSM_INTR_MASK_ADDR(SMSM_MODEM_STATE,
+					SMSM_APPS));
+		}
 	}
 
 	if (!smsm_info.intr_mux)
@@ -2539,6 +2553,20 @@
 	return smsm_irq_handler(irq, data);
 }
 
+/*
+ * Changes the global interrupt mask.  The set and clear masks are re-applied
+ * every time the global interrupt mask is updated for callback registration
+ * and de-registration.
+ *
+ * The clear mask is applied first, so if a bit is set to 1 in both the clear
+ * mask and the set mask, the result will be that the interrupt is set.
+ *
+ * @smsm_entry  SMSM entry to change
+ * @clear_mask  1 = clear bit, 0 = no-op
+ * @set_mask    1 = set bit, 0 = no-op
+ *
+ * @returns 0 for success, < 0 for error
+ */
 int smsm_change_intr_mask(uint32_t smsm_entry,
 			  uint32_t clear_mask, uint32_t set_mask)
 {
@@ -2557,6 +2585,8 @@
 	}
 
 	spin_lock_irqsave(&smem_lock, flags);
+	smsm_states[smsm_entry].intr_mask_clear = clear_mask;
+	smsm_states[smsm_entry].intr_mask_set = set_mask;
 
 	old_mask = __raw_readl(SMSM_INTR_MASK_ADDR(smsm_entry, SMSM_APPS));
 	new_mask = (old_mask & ~clear_mask) | set_mask;
@@ -2733,8 +2763,10 @@
 int smsm_state_cb_register(uint32_t smsm_entry, uint32_t mask,
 		void (*notify)(void *, uint32_t, uint32_t), void *data)
 {
+	struct smsm_state_info *state;
 	struct smsm_state_cb_info *cb_info;
 	struct smsm_state_cb_info *cb_found = 0;
+	uint32_t new_mask = 0;
 	int ret = 0;
 
 	if (smsm_entry >= SMSM_NUM_ENTRIES)
@@ -2748,15 +2780,16 @@
 		goto cleanup;
 	}
 
+	state = &smsm_states[smsm_entry];
 	list_for_each_entry(cb_info,
-			&smsm_states[smsm_entry].callbacks, cb_list) {
-		if ((cb_info->notify == notify) &&
+			&state->callbacks, cb_list) {
+		if (!ret && (cb_info->notify == notify) &&
 				(cb_info->data == data)) {
 			cb_info->mask |= mask;
 			cb_found = cb_info;
 			ret = 1;
-			break;
 		}
+		new_mask |= cb_info->mask;
 	}
 
 	if (!cb_found) {
@@ -2772,7 +2805,24 @@
 		cb_info->data = data;
 		INIT_LIST_HEAD(&cb_info->cb_list);
 		list_add_tail(&cb_info->cb_list,
-			&smsm_states[smsm_entry].callbacks);
+			&state->callbacks);
+		new_mask |= mask;
+	}
+
+	/* update interrupt notification mask */
+	if (smsm_entry == SMSM_MODEM_STATE)
+		new_mask |= LEGACY_MODEM_SMSM_MASK;
+
+	if (smsm_info.intr_mask) {
+		unsigned long flags;
+
+		spin_lock_irqsave(&smem_lock, flags);
+		new_mask = (new_mask & ~state->intr_mask_clear)
+				| state->intr_mask_set;
+		__raw_writel(new_mask,
+				SMSM_INTR_MASK_ADDR(smsm_entry, SMSM_APPS));
+		wmb();
+		spin_unlock_irqrestore(&smem_lock, flags);
 	}
 
 cleanup:
@@ -2800,6 +2850,9 @@
 		void (*notify)(void *, uint32_t, uint32_t), void *data)
 {
 	struct smsm_state_cb_info *cb_info;
+	struct smsm_state_cb_info *cb_tmp;
+	struct smsm_state_info *state;
+	uint32_t new_mask = 0;
 	int ret = 0;
 
 	if (smsm_entry >= SMSM_NUM_ENTRIES)
@@ -2813,9 +2866,10 @@
 		return -ENODEV;
 	}
 
-	list_for_each_entry(cb_info,
-		&smsm_states[smsm_entry].callbacks, cb_list) {
-		if ((cb_info->notify == notify) &&
+	state = &smsm_states[smsm_entry];
+	list_for_each_entry_safe(cb_info, cb_tmp,
+		&state->callbacks, cb_list) {
+		if (!ret && (cb_info->notify == notify) &&
 			(cb_info->data == data)) {
 			cb_info->mask &= ~mask;
 			ret = 1;
@@ -2824,9 +2878,26 @@
 				list_del(&cb_info->cb_list);
 				kfree(cb_info);
 				ret = 2;
+				continue;
 			}
-			break;
 		}
+		new_mask |= cb_info->mask;
+	}
+
+	/* update interrupt notification mask */
+	if (smsm_entry == SMSM_MODEM_STATE)
+		new_mask |= LEGACY_MODEM_SMSM_MASK;
+
+	if (smsm_info.intr_mask) {
+		unsigned long flags;
+
+		spin_lock_irqsave(&smem_lock, flags);
+		new_mask = (new_mask & ~state->intr_mask_clear)
+				| state->intr_mask_set;
+		__raw_writel(new_mask,
+				SMSM_INTR_MASK_ADDR(smsm_entry, SMSM_APPS));
+		wmb();
+		spin_unlock_irqrestore(&smem_lock, flags);
 	}
 
 	mutex_unlock(&smsm_lock);
diff --git a/arch/arm/mach-msm/smd_tty.c b/arch/arm/mach-msm/smd_tty.c
index 28850d0..68e0f41 100644
--- a/arch/arm/mach-msm/smd_tty.c
+++ b/arch/arm/mach-msm/smd_tty.c
@@ -83,6 +83,8 @@
 	{2, "APPS_RIVA_BT_ACL", NULL, SMD_APPS_WCNSS},
 	{3, "APPS_RIVA_BT_CMD", NULL, SMD_APPS_WCNSS},
 	{4, "MBALBRIDGE", NULL, SMD_APPS_MODEM},
+	{5, "APPS_RIVA_ANT_CMD", NULL, SMD_APPS_WCNSS},
+	{6, "APPS_RIVA_ANT_DATA", NULL, SMD_APPS_WCNSS},
 	{7, "DATA1", NULL, SMD_APPS_MODEM},
 	{11, "DATA11", NULL, SMD_APPS_MODEM},
 	{21, "DATA21", NULL, SMD_APPS_MODEM},
diff --git a/drivers/base/base.h b/drivers/base/base.h
index a34dca0..9641309 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -105,6 +105,7 @@
 
 extern void driver_detach(struct device_driver *drv);
 extern int driver_probe_device(struct device_driver *drv, struct device *dev);
+extern void driver_deferred_probe_del(struct device *dev);
 static inline int driver_match_device(struct device_driver *drv,
 				      struct device *dev)
 {
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 78445f4..14cdf13 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -589,6 +589,7 @@
 {
 	dev->kobj.kset = devices_kset;
 	kobject_init(&dev->kobj, &device_ktype);
+	INIT_LIST_HEAD(&dev->deferred_probe);
 	INIT_LIST_HEAD(&dev->dma_pools);
 	mutex_init(&dev->mutex);
 	lockdep_set_novalidate_class(&dev->mutex);
@@ -1120,6 +1121,7 @@
 	device_remove_file(dev, &uevent_attr);
 	device_remove_attrs(dev);
 	bus_remove_device(dev);
+	driver_deferred_probe_del(dev);
 
 	/*
 	 * Some platform devices are driven without driver attached
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 6658da7..455b502 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -28,6 +28,133 @@
 #include "base.h"
 #include "power/power.h"
 
+/*
+ * Deferred Probe infrastructure.
+ *
+ * Sometimes driver probe order matters, but the kernel doesn't always have
+ * dependency information which means some drivers will get probed before a
+ * resource it depends on is available.  For example, an SDHCI driver may
+ * first need a GPIO line from an i2c GPIO controller before it can be
+ * initialized.  If a required resource is not available yet, a driver can
+ * request probing to be deferred by returning -EPROBE_DEFER from its probe hook
+ *
+ * Deferred probe maintains two lists of devices, a pending list and an active
+ * list.  A driver returning -EPROBE_DEFER causes the device to be added to the
+ * pending list.  A successful driver probe will trigger moving all devices
+ * from the pending to the active list so that the workqueue will eventually
+ * retry them.
+ *
+ * The deferred_probe_mutex must be held any time the deferred_probe_*_list
+ * of the (struct device*)->deferred_probe pointers are manipulated
+ */
+static DEFINE_MUTEX(deferred_probe_mutex);
+static LIST_HEAD(deferred_probe_pending_list);
+static LIST_HEAD(deferred_probe_active_list);
+static struct workqueue_struct *deferred_wq;
+
+/**
+ * deferred_probe_work_func() - Retry probing devices in the active list.
+ */
+static void deferred_probe_work_func(struct work_struct *work)
+{
+	struct device *dev;
+	/*
+	 * This block processes every device in the deferred 'active' list.
+	 * Each device is removed from the active list and passed to
+	 * bus_probe_device() to re-attempt the probe.  The loop continues
+	 * until every device in the active list is removed and retried.
+	 *
+	 * Note: Once the device is removed from the list and the mutex is
+	 * released, it is possible for the device get freed by another thread
+	 * and cause a illegal pointer dereference.  This code uses
+	 * get/put_device() to ensure the device structure cannot disappear
+	 * from under our feet.
+	 */
+	mutex_lock(&deferred_probe_mutex);
+	while (!list_empty(&deferred_probe_active_list)) {
+		dev = list_first_entry(&deferred_probe_active_list,
+					typeof(*dev), deferred_probe);
+		list_del_init(&dev->deferred_probe);
+
+		get_device(dev);
+
+		/* Drop the mutex while probing each device; the probe path
+		 * may manipulate the deferred list */
+		mutex_unlock(&deferred_probe_mutex);
+		dev_dbg(dev, "Retrying from deferred list\n");
+		bus_probe_device(dev);
+		mutex_lock(&deferred_probe_mutex);
+
+		put_device(dev);
+	}
+	mutex_unlock(&deferred_probe_mutex);
+}
+static DECLARE_WORK(deferred_probe_work, deferred_probe_work_func);
+
+static void driver_deferred_probe_add(struct device *dev)
+{
+	mutex_lock(&deferred_probe_mutex);
+	if (list_empty(&dev->deferred_probe)) {
+		dev_dbg(dev, "Added to deferred list\n");
+		list_add(&dev->deferred_probe, &deferred_probe_pending_list);
+	}
+	mutex_unlock(&deferred_probe_mutex);
+}
+
+void driver_deferred_probe_del(struct device *dev)
+{
+	mutex_lock(&deferred_probe_mutex);
+	if (!list_empty(&dev->deferred_probe)) {
+		dev_dbg(dev, "Removed from deferred list\n");
+		list_del_init(&dev->deferred_probe);
+	}
+	mutex_unlock(&deferred_probe_mutex);
+}
+
+static bool driver_deferred_probe_enable = false;
+/**
+ * driver_deferred_probe_trigger() - Kick off re-probing deferred devices
+ *
+ * This functions moves all devices from the pending list to the active
+ * list and schedules the deferred probe workqueue to process them.  It
+ * should be called anytime a driver is successfully bound to a device.
+ */
+static void driver_deferred_probe_trigger(void)
+{
+	if (!driver_deferred_probe_enable)
+		return;
+
+	/* A successful probe means that all the devices in the pending list
+	 * should be triggered to be reprobed.  Move all the deferred devices
+	 * into the active list so they can be retried by the workqueue */
+	mutex_lock(&deferred_probe_mutex);
+	list_splice_tail_init(&deferred_probe_pending_list,
+			      &deferred_probe_active_list);
+	mutex_unlock(&deferred_probe_mutex);
+
+	/* Kick the re-probe thread.  It may already be scheduled, but
+	 * it is safe to kick it again. */
+	queue_work(deferred_wq, &deferred_probe_work);
+}
+
+/**
+ * deferred_probe_initcall() - Enable probing of deferred devices
+ *
+ * We don't want to get in the way when the bulk of drivers are getting probed.
+ * Instead, this initcall makes sure that deferred probing is delayed until
+ * late_initcall time.
+ */
+static int deferred_probe_initcall(void)
+{
+	deferred_wq = create_singlethread_workqueue("deferwq");
+	if (WARN_ON(!deferred_wq))
+		return -ENOMEM;
+
+	driver_deferred_probe_enable = true;
+	driver_deferred_probe_trigger();
+	return 0;
+}
+late_initcall(deferred_probe_initcall);
 
 static void driver_bound(struct device *dev)
 {
@@ -42,6 +169,11 @@
 
 	klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);
 
+	/* Make sure the device is no longer in one of the deferred lists
+	 * and kick off retrying all pending devices */
+	driver_deferred_probe_del(dev);
+	driver_deferred_probe_trigger();
+
 	if (dev->bus)
 		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
 					     BUS_NOTIFY_BOUND_DRIVER, dev);
@@ -142,7 +274,11 @@
 	driver_sysfs_remove(dev);
 	dev->driver = NULL;
 
-	if (ret != -ENODEV && ret != -ENXIO) {
+	if (ret == -EPROBE_DEFER) {
+		/* Driver requested deferred probing */
+		dev_info(dev, "Driver %s requests probe deferral\n", drv->name);
+		driver_deferred_probe_add(dev);
+	} else if (ret != -ENODEV && ret != -ENXIO) {
 		/* driver matched but the probe failed */
 		printk(KERN_WARNING
 		       "%s: probe of %s failed with error %d\n",
diff --git a/drivers/gpu/msm/a3xx_reg.h b/drivers/gpu/msm/a3xx_reg.h
index 4f5c783..fdf7304 100644
--- a/drivers/gpu/msm/a3xx_reg.h
+++ b/drivers/gpu/msm/a3xx_reg.h
@@ -46,6 +46,7 @@
 #define A3XX_RBBM_HW_VERSION 0x000
 #define A3XX_RBBM_HW_RELEASE 0x001
 #define A3XX_RBBM_HW_CONFIGURATION 0x002
+#define A3XX_RBBM_SP_HYST_CNT 0x012
 #define A3XX_RBBM_SW_RESET_CMD 0x018
 #define A3XX_RBBM_AHB_CTL0 0x020
 #define A3XX_RBBM_AHB_CTL1 0x021
@@ -54,6 +55,7 @@
 #define A3XX_RBBM_GPR0_CTL 0x02E
 /* This the same register as on A2XX, just in a different place */
 #define A3XX_RBBM_STATUS 0x030
+#define A3XX_RBBM_WAIT_IDLE_CLOCKS_CTL 0x33
 #define A3XX_RBBM_INTERFACE_HANG_INT_CTL 0x50
 #define A3XX_RBBM_INTERFACE_HANG_MASK_CTL0 0x51
 #define A3XX_RBBM_INTERFACE_HANG_MASK_CTL1 0x54
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index c01e676..2761b60 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -2576,6 +2576,10 @@
 	/* Make all blocks contribute to the GPU BUSY perf counter */
 	adreno_regwrite(device, A3XX_RBBM_GPU_BUSY_MASKED, 0xFFFFFFFF);
 
+	/* Tune the hystersis counters for SP and CP idle detection */
+	adreno_regwrite(device, A3XX_RBBM_SP_HYST_CNT, 0x10);
+	adreno_regwrite(device, A3XX_RBBM_WAIT_IDLE_CLOCKS_CTL, 0x10);
+
 	/* Enable the RBBM error reporting bits.  This lets us get
 	   useful information on failure */
 
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 6f575ec..d960eaf 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -509,6 +509,7 @@
 	pwr->nap_allowed = pdata->nap_allowed;
 	pwr->idle_needed = pdata->idle_needed;
 	pwr->interval_timeout = pdata->idle_timeout;
+	pwr->strtstp_sleepwake = pdata->strtstp_sleepwake;
 	pwr->ebi1_clk = clk_get(&pdev->dev, "bus_clk");
 	if (IS_ERR(pwr->ebi1_clk))
 		pwr->ebi1_clk = NULL;
@@ -629,7 +630,8 @@
 
 	KGSL_PWR_INFO(device, "idle timer expired device %d\n", device->id);
 	if (device->requested_state != KGSL_STATE_SUSPEND) {
-		if (device->pwrctrl.restore_slumber)
+		if (device->pwrctrl.restore_slumber ||
+					device->pwrctrl.strtstp_sleepwake)
 			kgsl_pwrctrl_request_state(device, KGSL_STATE_SLUMBER);
 		else
 			kgsl_pwrctrl_request_state(device, KGSL_STATE_SLEEP);
@@ -770,7 +772,9 @@
 	case KGSL_STATE_NAP:
 	case KGSL_STATE_SLEEP:
 		del_timer_sync(&device->idle_timer);
-		kgsl_pwrctrl_pwrlevel_change(device, KGSL_PWRLEVEL_NOMINAL);
+		if (!device->pwrctrl.strtstp_sleepwake)
+			kgsl_pwrctrl_pwrlevel_change(device,
+					KGSL_PWRLEVEL_NOMINAL);
 		device->pwrctrl.restore_slumber = true;
 		device->ftbl->suspend_context(device);
 		device->ftbl->stop(device);
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h
index 2222cdf..7dd429f 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.h
+++ b/drivers/gpu/msm/kgsl_pwrctrl.h
@@ -48,6 +48,7 @@
 	int thermal_pwrlevel;
 	unsigned int num_pwrlevels;
 	unsigned int interval_timeout;
+	bool strtstp_sleepwake;
 	struct regulator *gpu_reg;
 	uint32_t pcl;
 	unsigned int nap_allowed;
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 39c158d..bda7cb2 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -274,6 +274,10 @@
 #define T7_DATA_SIZE		3
 #define MXT_MAX_RW_TRIES	3
 #define MXT_BLOCK_SIZE		256
+#define MXT_CFG_VERSION_LEN	3
+#define MXT_CFG_VERSION_EQUAL	0
+#define MXT_CFG_VERSION_LESS	1
+#define MXT_CFG_VERSION_GREATER	2
 
 #define MXT_DEBUGFS_DIR		"atmel_mxt_ts"
 #define MXT_DEBUGFS_FILE	"object"
@@ -340,8 +344,10 @@
 	u8 t9_min_reportid;
 	u8 t15_max_reportid;
 	u8 t15_min_reportid;
-	u8 curr_cfg_version;
+	u8 cfg_version[MXT_CFG_VERSION_LEN];
 	int cfg_version_idx;
+	int t38_start_addr;
+	bool update_cfg;
 	const char *fw_name;
 };
 
@@ -1047,8 +1053,10 @@
 		/* Calculate index for config major version in config array.
 		 * Major version is the first byte in object T38.
 		 */
-		if (object->type == MXT_SPT_USERDATA_T38)
+		if (object->type == MXT_SPT_USERDATA_T38) {
+			data->t38_start_addr = object->start_address;
 			found_t38 = true;
+		}
 		if (!found_t38 && mxt_object_writable(object->type))
 			data->cfg_version_idx += object->size + 1;
 	}
@@ -1056,14 +1064,85 @@
 	return 0;
 }
 
-static int mxt_search_config_array(struct mxt_data *data, bool version_match)
+static int compare_versions(const u8 *v1, const u8 *v2)
+{
+	int i;
+
+	if (!v1 || !v2)
+		return -EINVAL;
+
+	/* The major version number stays the same across different versions for
+	 * a particular controller on a target. The minor and sub-minor version
+	 * numbers indicate which version is newer.
+	 */
+	if (v1[0] != v2[0])
+		return -EINVAL;
+
+	for (i = 1; i < MXT_CFG_VERSION_LEN; i++) {
+		if (v1[i] > v2[i])
+			return MXT_CFG_VERSION_LESS;	/* v2 is older */
+
+		if (v1[i] < v2[i])
+			return MXT_CFG_VERSION_GREATER;	/* v2 is newer */
+	}
+
+	return MXT_CFG_VERSION_EQUAL;	/* v1 and v2 are equal */
+}
+
+static void mxt_check_config_version(struct mxt_data *data,
+			const struct mxt_config_info *cfg_info,
+			bool match_major,
+			const u8 **cfg_version_found,
+			bool *found_cfg_major_match)
+{
+	const u8 *cfg_version;
+	int result = -EINVAL;
+
+	cfg_version = cfg_info->config + data->cfg_version_idx;
+
+	if (*cfg_version_found)
+		result = compare_versions(*cfg_version_found, cfg_version);
+
+	if (match_major) {
+		if (result >= MXT_CFG_VERSION_EQUAL)
+			*found_cfg_major_match = true;
+
+		if (result == MXT_CFG_VERSION_EQUAL ||
+			result == MXT_CFG_VERSION_GREATER) {
+			data->config_info = cfg_info;
+			data->fw_name = cfg_info->fw_name;
+			*cfg_version_found = cfg_version;
+		}
+
+		if (result == MXT_CFG_VERSION_GREATER)
+			data->update_cfg = true;
+	} else if (!*cfg_version_found || result == MXT_CFG_VERSION_GREATER) {
+		data->config_info = cfg_info;
+		data->fw_name = cfg_info->fw_name;
+		data->update_cfg = true;
+		*cfg_version_found = cfg_version;
+	}
+}
+
+/* If the controller's config version has a non-zero major number, call this
+ * function with match_major = true to look for the latest config present in
+ * the pdata based on matching family id, variant id, f/w version, build, and
+ * config major number. If the controller is programmed with wrong config data
+ * previously, call this function with match_major = false to look for latest
+ * config based on based on matching family id, variant id, f/w version and
+ * build only.
+ */
+static int mxt_search_config_array(struct mxt_data *data, bool match_major)
 {
 
 	const struct mxt_platform_data *pdata = data->pdata;
 	const struct mxt_config_info *cfg_info;
-	struct mxt_info *info = &data->info;
+	const struct mxt_info *info = &data->info;
+	const u8 *cfg_version_found;
+	bool found_cfg_major_match = false;
 	int i;
-	u8 cfg_version;
+
+	cfg_version_found = match_major ? data->cfg_version : NULL;
 
 	for (i = 0; i < pdata->config_array_size; i++) {
 
@@ -1077,22 +1156,17 @@
 			info->version == cfg_info->version &&
 			info->build == cfg_info->build) {
 
-			cfg_version = cfg_info->config[data->cfg_version_idx];
-			if (data->curr_cfg_version == cfg_version ||
-				!version_match) {
-				data->config_info = cfg_info;
-				data->fw_name = pdata->config_array[i].fw_name;
-				return 0;
-			}
+			mxt_check_config_version(data, cfg_info, match_major,
+				&cfg_version_found, &found_cfg_major_match);
 		}
 	}
 
+	if (data->config_info || found_cfg_major_match)
+		return 0;
+
+	data->config_info = NULL;
 	data->fw_name = NULL;
-	dev_info(&data->client->dev,
-		"Config not found: F: %d, V: %d, FW: %d.%d.%d, CFG: %d\n",
-		info->family_id, info->variant_id,
-		info->version >> 4, info->version & 0xF, info->build,
-		data->curr_cfg_version);
+
 	return -EINVAL;
 }
 
@@ -1115,24 +1189,40 @@
 		return -EINVAL;
 	}
 
-	error = mxt_read_reg(data->client, object->start_address,
-				&data->curr_cfg_version);
+	error = __mxt_read_reg(data->client, object->start_address,
+				sizeof(data->cfg_version), data->cfg_version);
 	if (error) {
 		dev_err(dev, "Unable to read config version\n");
 		return error;
 	}
+	dev_info(dev, "Current config version on the controller is %d.%d.%d\n",
+			data->cfg_version[0], data->cfg_version[1],
+			data->cfg_version[2]);
 
 	/* It is possible that the config data on the controller is not
 	 * versioned and the version number returns 0. In this case,
 	 * find a match without the config version checking.
 	 */
 	error = mxt_search_config_array(data,
-				data->curr_cfg_version != 0 ? true : false);
-	if (error)
-		return error;
+				data->cfg_version[0] != 0 ? true : false);
+	if (error) {
+		/* If a match wasn't found for a non-zero config version,
+		 * it means the controller has the wrong config data. Search
+		 * for a best match based on controller and firmware version,
+		 * but not config version.
+		 */
+		if (data->cfg_version[0])
+			error = mxt_search_config_array(data, false);
+		if (error) {
+			dev_err(dev,
+				"Unable to find matching config in pdata\n");
+			return error;
+		}
+	}
 
 	return 0;
 }
+
 static void mxt_reset_delay(struct mxt_data *data)
 {
 	struct mxt_info *info = &data->info;
@@ -1152,17 +1242,104 @@
 	}
 }
 
+static int mxt_backup_nv(struct mxt_data *data)
+{
+	int error;
+	u8 command_register;
+	int timeout_counter = 0;
+
+	/* Backup to memory */
+	mxt_write_object(data, MXT_GEN_COMMAND_T6,
+			MXT_COMMAND_BACKUPNV,
+			MXT_BACKUP_VALUE);
+	msleep(MXT_BACKUP_TIME);
+
+	do {
+		error = mxt_read_object(data, MXT_GEN_COMMAND_T6,
+					MXT_COMMAND_BACKUPNV,
+					&command_register);
+		if (error)
+			return error;
+
+		usleep_range(1000, 2000);
+
+	} while ((command_register != 0) && (++timeout_counter <= 100));
+
+	if (timeout_counter > 100) {
+		dev_err(&data->client->dev, "No response after backup!\n");
+		return -EIO;
+	}
+
+	/* Soft reset */
+	mxt_write_object(data, MXT_GEN_COMMAND_T6, MXT_COMMAND_RESET, 1);
+
+	mxt_reset_delay(data);
+
+	return 0;
+}
+
+static int mxt_save_objects(struct mxt_data *data)
+{
+	struct i2c_client *client = data->client;
+	struct mxt_object *t7_object;
+	struct mxt_object *t9_object;
+	struct mxt_object *t15_object;
+	int error;
+
+	/* Store T7 and T9 locally, used in suspend/resume operations */
+	t7_object = mxt_get_object(data, MXT_GEN_POWER_T7);
+	if (!t7_object) {
+		dev_err(&client->dev, "Failed to get T7 object\n");
+		return -EINVAL;
+	}
+
+	data->t7_start_addr = t7_object->start_address;
+	error = __mxt_read_reg(client, data->t7_start_addr,
+				T7_DATA_SIZE, data->t7_data);
+	if (error < 0) {
+		dev_err(&client->dev,
+			"Failed to save current power state\n");
+		return error;
+	}
+
+	error = mxt_read_object(data, MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL,
+			&data->t9_ctrl);
+	if (error < 0) {
+		dev_err(&client->dev, "Failed to save current touch object\n");
+		return error;
+	}
+
+	/* Store T9, T15's min and max report ids */
+	t9_object = mxt_get_object(data, MXT_TOUCH_MULTI_T9);
+	if (!t9_object) {
+		dev_err(&client->dev, "Failed to get T9 object\n");
+		return -EINVAL;
+	}
+	data->t9_max_reportid = t9_object->max_reportid;
+	data->t9_min_reportid = t9_object->max_reportid -
+					t9_object->num_report_ids + 1;
+
+	if (data->pdata->key_codes) {
+		t15_object = mxt_get_object(data, MXT_TOUCH_KEYARRAY_T15);
+		if (!t15_object)
+			dev_dbg(&client->dev, "T15 object is not available\n");
+		else {
+			data->t15_max_reportid = t15_object->max_reportid;
+			data->t15_min_reportid = t15_object->max_reportid -
+						t15_object->num_report_ids + 1;
+		}
+	}
+
+	return 0;
+}
+
 static int mxt_initialize(struct mxt_data *data)
 {
 	struct i2c_client *client = data->client;
 	struct mxt_info *info = &data->info;
 	int error;
-	int timeout_counter = 0;
 	u8 val;
-	u8 command_register;
-	struct mxt_object *t7_object;
-	struct mxt_object *t9_object;
-	struct mxt_object *t15_object;
+	const u8 *cfg_ver;
 
 	error = mxt_get_info(data);
 	if (error) {
@@ -1209,81 +1386,40 @@
 		dev_dbg(&client->dev, "Config info not found.\n");
 
 	/* Check register init values */
-	error = mxt_check_reg_init(data);
+	if (data->config_info && data->config_info->config) {
+		if (data->update_cfg) {
+			error = mxt_check_reg_init(data);
+			if (error) {
+				dev_err(&client->dev,
+					"Failed to check reg init value\n");
+				goto free_object_table;
+			}
+
+			error = mxt_backup_nv(data);
+			if (error) {
+				dev_err(&client->dev, "Failed to back up NV\n");
+				goto free_object_table;
+			}
+
+			cfg_ver = data->config_info->config +
+							data->cfg_version_idx;
+			dev_info(&client->dev,
+				"Config updated from %d.%d.%d to %d.%d.%d\n",
+				data->cfg_version[0], data->cfg_version[1],
+				data->cfg_version[2],
+				cfg_ver[0], cfg_ver[1], cfg_ver[2]);
+
+			memcpy(data->cfg_version, cfg_ver, MXT_CFG_VERSION_LEN);
+		}
+	} else {
+		dev_info(&client->dev,
+			"No cfg data defined, skipping check reg init\n");
+	}
+
+	error = mxt_save_objects(data);
 	if (error)
 		goto free_object_table;
 
-	/* Store T7 and T9 locally, used in suspend/resume operations */
-	t7_object = mxt_get_object(data, MXT_GEN_POWER_T7);
-	if (!t7_object) {
-		dev_err(&client->dev, "Failed to get T7 object\n");
-		error = -EINVAL;
-		goto free_object_table;
-	}
-
-	data->t7_start_addr = t7_object->start_address;
-	error = __mxt_read_reg(client, data->t7_start_addr,
-				T7_DATA_SIZE, data->t7_data);
-	if (error < 0) {
-		dev_err(&client->dev,
-			"Failed to save current power state\n");
-		goto free_object_table;
-	}
-	error = mxt_read_object(data, MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL,
-			&data->t9_ctrl);
-	if (error < 0) {
-		dev_err(&client->dev, "Failed to save current touch object\n");
-		goto free_object_table;
-	}
-
-	/* Store T9, T15's min and max report ids */
-	t9_object = mxt_get_object(data, MXT_TOUCH_MULTI_T9);
-	if (!t9_object) {
-		dev_err(&client->dev, "Failed to get T9 object\n");
-		error = -EINVAL;
-		goto free_object_table;
-	}
-	data->t9_max_reportid = t9_object->max_reportid;
-	data->t9_min_reportid = t9_object->max_reportid -
-					t9_object->num_report_ids + 1;
-
-	if (data->pdata->key_codes) {
-		t15_object = mxt_get_object(data, MXT_TOUCH_KEYARRAY_T15);
-		if (!t15_object)
-			dev_dbg(&client->dev, "T15 object is not available\n");
-		else {
-			data->t15_max_reportid = t15_object->max_reportid;
-			data->t15_min_reportid = t15_object->max_reportid -
-						t15_object->num_report_ids + 1;
-		}
-	}
-
-	/* Backup to memory */
-	mxt_write_object(data, MXT_GEN_COMMAND_T6,
-			MXT_COMMAND_BACKUPNV,
-			MXT_BACKUP_VALUE);
-	msleep(MXT_BACKUP_TIME);
-	do {
-		error =  mxt_read_object(data, MXT_GEN_COMMAND_T6,
-					MXT_COMMAND_BACKUPNV,
-					&command_register);
-		if (error)
-			goto free_object_table;
-		usleep_range(1000, 2000);
-	} while ((command_register != 0) && (++timeout_counter <= 100));
-	if (timeout_counter > 100) {
-		dev_err(&client->dev, "No response after backup!\n");
-		error = -EIO;
-		goto free_object_table;
-	}
-
-
-	/* Soft reset */
-	mxt_write_object(data, MXT_GEN_COMMAND_T6,
-			MXT_COMMAND_RESET, 1);
-
-	mxt_reset_delay(data);
-
 	/* Update matrix size at info struct */
 	error = mxt_read_reg(client, MXT_MATRIX_X_SIZE, &val);
 	if (error)
@@ -1518,6 +1654,7 @@
 	int error;
 	const char *fw_name;
 	u8 bootldr_id;
+	u8 cfg_version[MXT_CFG_VERSION_LEN] = {0};
 
 	/* If fw_name is set, then the existing firmware has an upgrade */
 	if (!data->fw_name) {
@@ -1566,6 +1703,13 @@
 		kfree(data->object_table);
 		data->object_table = NULL;
 		data->cfg_version_idx = 0;
+		data->update_cfg = false;
+
+		error = __mxt_write_reg(data->client, data->t38_start_addr,
+				sizeof(cfg_version), cfg_version);
+		if (error)
+			dev_err(dev,
+			"Unable to zero out config version after fw upgrade\n");
 
 		mxt_initialize(data);
 	}
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index c8827ff..ba510a2 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -18,7 +18,6 @@
 #include <linux/crypto.h>
 #include <linux/workqueue.h>
 #include <linux/backing-dev.h>
-#include <linux/percpu.h>
 #include <asm/atomic.h>
 #include <linux/scatterlist.h>
 #include <asm/page.h>
@@ -44,7 +43,8 @@
 	unsigned int idx_in;
 	unsigned int idx_out;
 	sector_t sector;
-	atomic_t pending;
+	atomic_t cc_pending;
+	struct ablkcipher_request *req;
 };
 
 /*
@@ -57,7 +57,7 @@
 
 	struct convert_context ctx;
 
-	atomic_t pending;
+	atomic_t io_pending;
 	int error;
 	sector_t sector;
 	struct dm_crypt_io *base_io;
@@ -106,18 +106,7 @@
 enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID };
 
 /*
- * Duplicated per-CPU state for cipher.
- */
-struct crypt_cpu {
-	struct ablkcipher_request *req;
-	/* ESSIV: struct crypto_cipher *essiv_tfm */
-	void *iv_private;
-	struct crypto_ablkcipher *tfms[0];
-};
-
-/*
  * The fields in here must be read only after initialization,
- * changing state should be in crypt_cpu.
  */
 struct crypt_config {
 	struct dm_dev *dev;
@@ -147,11 +136,9 @@
 	sector_t iv_offset;
 	unsigned int iv_size;
 
-	/*
-	 * Duplicated per cpu state. Access through
-	 * per_cpu_ptr() only.
-	 */
-	struct crypt_cpu __percpu *cpu;
+	/* ESSIV: struct crypto_cipher *essiv_tfm */
+	void *iv_private;
+	struct crypto_ablkcipher **tfms;
 	unsigned tfms_count;
 
 	/*
@@ -185,17 +172,12 @@
 static void kcryptd_queue_crypt(struct dm_crypt_io *io);
 static u8 *iv_of_dmreq(struct crypt_config *cc, struct dm_crypt_request *dmreq);
 
-static struct crypt_cpu *this_crypt_config(struct crypt_config *cc)
-{
-	return this_cpu_ptr(cc->cpu);
-}
-
 /*
  * Use this to access cipher attributes that are the same for each CPU.
  */
 static struct crypto_ablkcipher *any_tfm(struct crypt_config *cc)
 {
-	return __this_cpu_ptr(cc->cpu)->tfms[0];
+	return cc->tfms[0];
 }
 
 /*
@@ -260,7 +242,7 @@
 	struct hash_desc desc;
 	struct scatterlist sg;
 	struct crypto_cipher *essiv_tfm;
-	int err, cpu;
+	int err;
 
 	sg_init_one(&sg, cc->key, cc->key_size);
 	desc.tfm = essiv->hash_tfm;
@@ -270,14 +252,12 @@
 	if (err)
 		return err;
 
-	for_each_possible_cpu(cpu) {
-		essiv_tfm = per_cpu_ptr(cc->cpu, cpu)->iv_private,
+	essiv_tfm = cc->iv_private;
 
-		err = crypto_cipher_setkey(essiv_tfm, essiv->salt,
-				    crypto_hash_digestsize(essiv->hash_tfm));
-		if (err)
-			return err;
-	}
+	err = crypto_cipher_setkey(essiv_tfm, essiv->salt,
+			    crypto_hash_digestsize(essiv->hash_tfm));
+	if (err)
+		return err;
 
 	return 0;
 }
@@ -288,16 +268,14 @@
 	struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv;
 	unsigned salt_size = crypto_hash_digestsize(essiv->hash_tfm);
 	struct crypto_cipher *essiv_tfm;
-	int cpu, r, err = 0;
+	int r, err = 0;
 
 	memset(essiv->salt, 0, salt_size);
 
-	for_each_possible_cpu(cpu) {
-		essiv_tfm = per_cpu_ptr(cc->cpu, cpu)->iv_private;
-		r = crypto_cipher_setkey(essiv_tfm, essiv->salt, salt_size);
-		if (r)
-			err = r;
-	}
+	essiv_tfm = cc->iv_private;
+	r = crypto_cipher_setkey(essiv_tfm, essiv->salt, salt_size);
+	if (r)
+		err = r;
 
 	return err;
 }
@@ -337,8 +315,6 @@
 
 static void crypt_iv_essiv_dtr(struct crypt_config *cc)
 {
-	int cpu;
-	struct crypt_cpu *cpu_cc;
 	struct crypto_cipher *essiv_tfm;
 	struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv;
 
@@ -348,15 +324,13 @@
 	kzfree(essiv->salt);
 	essiv->salt = NULL;
 
-	for_each_possible_cpu(cpu) {
-		cpu_cc = per_cpu_ptr(cc->cpu, cpu);
-		essiv_tfm = cpu_cc->iv_private;
+	essiv_tfm = cc->iv_private;
 
-		if (essiv_tfm)
-			crypto_free_cipher(essiv_tfm);
+	if (essiv_tfm)
+		crypto_free_cipher(essiv_tfm);
 
-		cpu_cc->iv_private = NULL;
-	}
+	cc->iv_private = NULL;
+
 }
 
 static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti,
@@ -365,7 +339,7 @@
 	struct crypto_cipher *essiv_tfm = NULL;
 	struct crypto_hash *hash_tfm = NULL;
 	u8 *salt = NULL;
-	int err, cpu;
+	int err;
 
 	if (!opts) {
 		ti->error = "Digest algorithm missing for ESSIV mode";
@@ -390,15 +364,13 @@
 	cc->iv_gen_private.essiv.salt = salt;
 	cc->iv_gen_private.essiv.hash_tfm = hash_tfm;
 
-	for_each_possible_cpu(cpu) {
-		essiv_tfm = setup_essiv_cpu(cc, ti, salt,
-					crypto_hash_digestsize(hash_tfm));
-		if (IS_ERR(essiv_tfm)) {
-			crypt_iv_essiv_dtr(cc);
-			return PTR_ERR(essiv_tfm);
-		}
-		per_cpu_ptr(cc->cpu, cpu)->iv_private = essiv_tfm;
+	essiv_tfm = setup_essiv_cpu(cc, ti, salt,
+				crypto_hash_digestsize(hash_tfm));
+	if (IS_ERR(essiv_tfm)) {
+		crypt_iv_essiv_dtr(cc);
+		return PTR_ERR(essiv_tfm);
 	}
+	cc->iv_private = essiv_tfm;
 
 	return 0;
 
@@ -412,7 +384,8 @@
 static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv,
 			      struct dm_crypt_request *dmreq)
 {
-	struct crypto_cipher *essiv_tfm = this_crypt_config(cc)->iv_private;
+
+	struct crypto_cipher *essiv_tfm = cc->iv_private;
 
 	memset(iv, 0, cc->iv_size);
 	*(u64 *)iv = cpu_to_le64(dmreq->iv_sector);
@@ -750,16 +723,15 @@
 static void crypt_alloc_req(struct crypt_config *cc,
 			    struct convert_context *ctx)
 {
-	struct crypt_cpu *this_cc = this_crypt_config(cc);
 	unsigned key_index = ctx->sector & (cc->tfms_count - 1);
 
-	if (!this_cc->req)
-		this_cc->req = mempool_alloc(cc->req_pool, GFP_NOIO);
+	if (!ctx->req)
+		ctx->req = mempool_alloc(cc->req_pool, GFP_NOIO);
 
-	ablkcipher_request_set_tfm(this_cc->req, this_cc->tfms[key_index]);
-	ablkcipher_request_set_callback(this_cc->req,
+	ablkcipher_request_set_tfm(ctx->req, cc->tfms[key_index]);
+	ablkcipher_request_set_callback(ctx->req,
 	    CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
-	    kcryptd_async_done, dmreq_of_req(cc, this_cc->req));
+	    kcryptd_async_done, dmreq_of_req(cc, ctx->req));
 }
 
 /*
@@ -768,19 +740,18 @@
 static int crypt_convert(struct crypt_config *cc,
 			 struct convert_context *ctx)
 {
-	struct crypt_cpu *this_cc = this_crypt_config(cc);
 	int r;
 
-	atomic_set(&ctx->pending, 1);
+	atomic_set(&ctx->cc_pending, 1);
 
 	while(ctx->idx_in < ctx->bio_in->bi_vcnt &&
 	      ctx->idx_out < ctx->bio_out->bi_vcnt) {
 
 		crypt_alloc_req(cc, ctx);
 
-		atomic_inc(&ctx->pending);
+		atomic_inc(&ctx->cc_pending);
 
-		r = crypt_convert_block(cc, ctx, this_cc->req);
+		r = crypt_convert_block(cc, ctx, ctx->req);
 
 		switch (r) {
 		/* async */
@@ -789,20 +760,20 @@
 			INIT_COMPLETION(ctx->restart);
 			/* fall through*/
 		case -EINPROGRESS:
-			this_cc->req = NULL;
+			ctx->req = NULL;
 			ctx->sector++;
 			continue;
 
 		/* sync */
 		case 0:
-			atomic_dec(&ctx->pending);
+			atomic_dec(&ctx->cc_pending);
 			ctx->sector++;
 			cond_resched();
 			continue;
 
 		/* error */
 		default:
-			atomic_dec(&ctx->pending);
+			atomic_dec(&ctx->cc_pending);
 			return r;
 		}
 	}
@@ -853,8 +824,7 @@
 		 * return a partially allocated bio, the caller will then try
 		 * to allocate additional bios while submitting this partial bio
 		 */
-		if (i == (MIN_BIO_PAGES - 1))
-			gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT;
+		gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT;
 
 		len = (size > PAGE_SIZE) ? PAGE_SIZE : size;
 
@@ -899,14 +869,15 @@
 	io->sector = sector;
 	io->error = 0;
 	io->base_io = NULL;
-	atomic_set(&io->pending, 0);
+	io->ctx.req = NULL;
+	atomic_set(&io->io_pending, 0);
 
 	return io;
 }
 
 static void crypt_inc_pending(struct dm_crypt_io *io)
 {
-	atomic_inc(&io->pending);
+	atomic_inc(&io->io_pending);
 }
 
 /*
@@ -921,9 +892,11 @@
 	struct dm_crypt_io *base_io = io->base_io;
 	int error = io->error;
 
-	if (!atomic_dec_and_test(&io->pending))
+	if (!atomic_dec_and_test(&io->io_pending))
 		return;
 
+	if (io->ctx.req)
+		mempool_free(io->ctx.req, cc->req_pool);
 	mempool_free(io, cc->io_pool);
 
 	if (likely(!base_io))
@@ -1047,16 +1020,14 @@
 	queue_work(cc->io_queue, &io->work);
 }
 
-static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io,
-					  int error, int async)
+static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io, int async)
 {
 	struct bio *clone = io->ctx.bio_out;
 	struct crypt_config *cc = io->target->private;
 
-	if (unlikely(error < 0)) {
+	if (unlikely(io->error < 0)) {
 		crypt_free_buffer_pages(cc, clone);
 		bio_put(clone);
-		io->error = -EIO;
 		crypt_dec_pending(io);
 		return;
 	}
@@ -1108,11 +1079,13 @@
 
 		crypt_inc_pending(io);
 		r = crypt_convert(cc, &io->ctx);
-		crypt_finished = atomic_dec_and_test(&io->ctx.pending);
+		if (r < 0)
+			io->error = -EIO;
+		crypt_finished = atomic_dec_and_test(&io->ctx.cc_pending);
 
 		/* Encryption was already finished, submit io now */
 		if (crypt_finished) {
-			kcryptd_crypt_write_io_submit(io, r, 0);
+			kcryptd_crypt_write_io_submit(io, 0);
 
 			/*
 			 * If there was an error, do not try next fragments.
@@ -1163,11 +1136,8 @@
 	crypt_dec_pending(io);
 }
 
-static void kcryptd_crypt_read_done(struct dm_crypt_io *io, int error)
+static void kcryptd_crypt_read_done(struct dm_crypt_io *io)
 {
-	if (unlikely(error < 0))
-		io->error = -EIO;
-
 	crypt_dec_pending(io);
 }
 
@@ -1183,8 +1153,11 @@
 
 	r = crypt_convert(cc, &io->ctx);
 
-	if (atomic_dec_and_test(&io->ctx.pending))
-		kcryptd_crypt_read_done(io, r);
+	if (r < 0)
+		io->error = -EIO;
+
+	if (atomic_dec_and_test(&io->ctx.cc_pending))
+		kcryptd_crypt_read_done(io);
 
 	crypt_dec_pending(io);
 }
@@ -1205,15 +1178,18 @@
 	if (!error && cc->iv_gen_ops && cc->iv_gen_ops->post)
 		error = cc->iv_gen_ops->post(cc, iv_of_dmreq(cc, dmreq), dmreq);
 
+	if (error < 0)
+		io->error = -EIO;
+
 	mempool_free(req_of_dmreq(cc, dmreq), cc->req_pool);
 
-	if (!atomic_dec_and_test(&ctx->pending))
+	if (!atomic_dec_and_test(&ctx->cc_pending))
 		return;
 
 	if (bio_data_dir(io->base_bio) == READ)
-		kcryptd_crypt_read_done(io, error);
+		kcryptd_crypt_read_done(io);
 	else
-		kcryptd_crypt_write_io_submit(io, error, 1);
+		kcryptd_crypt_write_io_submit(io, 1);
 }
 
 static void kcryptd_crypt(struct work_struct *work)
@@ -1275,29 +1251,35 @@
 	}
 }
 
-static void crypt_free_tfms(struct crypt_config *cc, int cpu)
+static void crypt_free_tfms(struct crypt_config *cc)
 {
-	struct crypt_cpu *cpu_cc = per_cpu_ptr(cc->cpu, cpu);
 	unsigned i;
 
+	if (!cc->tfms)
+		return;
+
 	for (i = 0; i < cc->tfms_count; i++)
-		if (cpu_cc->tfms[i] && !IS_ERR(cpu_cc->tfms[i])) {
-			crypto_free_ablkcipher(cpu_cc->tfms[i]);
-			cpu_cc->tfms[i] = NULL;
+		if (cc->tfms[i] && !IS_ERR(cc->tfms[i])) {
+			crypto_free_ablkcipher(cc->tfms[i]);
+			cc->tfms[i] = NULL;
 		}
 }
 
-static int crypt_alloc_tfms(struct crypt_config *cc, int cpu, char *ciphermode)
+static int crypt_alloc_tfms(struct crypt_config *cc, char *ciphermode)
 {
-	struct crypt_cpu *cpu_cc = per_cpu_ptr(cc->cpu, cpu);
 	unsigned i;
 	int err;
 
+	cc->tfms = kmalloc(cc->tfms_count * sizeof(struct crypto_ablkcipher *),
+			   GFP_KERNEL);
+	if (!cc->tfms)
+		return -ENOMEM;
+
 	for (i = 0; i < cc->tfms_count; i++) {
-		cpu_cc->tfms[i] = crypto_alloc_ablkcipher(ciphermode, 0, 0);
-		if (IS_ERR(cpu_cc->tfms[i])) {
-			err = PTR_ERR(cpu_cc->tfms[i]);
-			crypt_free_tfms(cc, cpu);
+		cc->tfms[i] = crypto_alloc_ablkcipher(ciphermode, 0, 0);
+		if (IS_ERR(cc->tfms[i])) {
+			err = PTR_ERR(cc->tfms[i]);
+			crypt_free_tfms(cc);
 			return err;
 		}
 	}
@@ -1308,15 +1290,14 @@
 static int crypt_setkey_allcpus(struct crypt_config *cc)
 {
 	unsigned subkey_size = cc->key_size >> ilog2(cc->tfms_count);
-	int cpu, err = 0, i, r;
+	int err = 0, i, r;
 
-	for_each_possible_cpu(cpu) {
-		for (i = 0; i < cc->tfms_count; i++) {
-			r = crypto_ablkcipher_setkey(per_cpu_ptr(cc->cpu, cpu)->tfms[i],
-						     cc->key + (i * subkey_size), subkey_size);
-			if (r)
-				err = r;
-		}
+	for (i = 0; i < cc->tfms_count; i++) {
+		r = crypto_ablkcipher_setkey(cc->tfms[i],
+					     cc->key + (i * subkey_size),
+					     subkey_size);
+		if (r)
+			err = r;
 	}
 
 	return err;
@@ -1360,8 +1341,6 @@
 static void crypt_dtr(struct dm_target *ti)
 {
 	struct crypt_config *cc = ti->private;
-	struct crypt_cpu *cpu_cc;
-	int cpu;
 
 	ti->private = NULL;
 
@@ -1373,13 +1352,7 @@
 	if (cc->crypt_queue)
 		destroy_workqueue(cc->crypt_queue);
 
-	if (cc->cpu)
-		for_each_possible_cpu(cpu) {
-			cpu_cc = per_cpu_ptr(cc->cpu, cpu);
-			if (cpu_cc->req)
-				mempool_free(cpu_cc->req, cc->req_pool);
-			crypt_free_tfms(cc, cpu);
-		}
+	crypt_free_tfms(cc);
 
 	if (cc->bs)
 		bioset_free(cc->bs);
@@ -1397,9 +1370,6 @@
 	if (cc->dev)
 		dm_put_device(ti, cc->dev);
 
-	if (cc->cpu)
-		free_percpu(cc->cpu);
-
 	kzfree(cc->cipher);
 	kzfree(cc->cipher_string);
 
@@ -1413,7 +1383,7 @@
 	struct crypt_config *cc = ti->private;
 	char *tmp, *cipher, *chainmode, *ivmode, *ivopts, *keycount;
 	char *cipher_api = NULL;
-	int cpu, ret = -EINVAL;
+	int ret = -EINVAL;
 
 	/* Convert to crypto api definition? */
 	if (strchr(cipher_in, '(')) {
@@ -1453,14 +1423,6 @@
 	if (tmp)
 		DMWARN("Ignoring unexpected additional cipher options");
 
-	cc->cpu = __alloc_percpu(sizeof(*(cc->cpu)) +
-				 cc->tfms_count * sizeof(*(cc->cpu->tfms)),
-				 __alignof__(struct crypt_cpu));
-	if (!cc->cpu) {
-		ti->error = "Cannot allocate per cpu state";
-		goto bad_mem;
-	}
-
 	/*
 	 * For compatibility with the original dm-crypt mapping format, if
 	 * only the cipher name is supplied, use cbc-plain.
@@ -1487,12 +1449,10 @@
 	}
 
 	/* Allocate cipher */
-	for_each_possible_cpu(cpu) {
-		ret = crypt_alloc_tfms(cc, cpu, cipher_api);
-		if (ret < 0) {
-			ti->error = "Error allocating crypto tfm";
-			goto bad;
-		}
+	ret = crypt_alloc_tfms(cc, cipher_api);
+	if (ret < 0) {
+		ti->error = "Error allocating crypto tfm";
+		goto bad;
 	}
 
 	/* Initialize and set key */
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index ab732b2..a276e84 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -99,6 +99,7 @@
 	struct hci_fm_ssbi_peek   ssbi_peek_reg;
 	struct hci_fm_sig_threshold_rsp sig_th;
 	struct hci_fm_ch_det_threshold ch_det_threshold;
+	struct hci_fm_data_rd_rsp default_data;
 };
 
 static struct video_device *priv_videodev;
@@ -1769,23 +1770,15 @@
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 	__u8 status = *((__u8 *) skb->data);
 	__u8 len;
-	char *data;
 
 	if (status)
 		return;
 	len = skb->data[1];
-	data = kmalloc(len+2, GFP_ATOMIC);
-	if (!data) {
-		FMDERR("Memory allocation failed");
-		return;
-	}
 
-	data[0] = status;
-	data[1] = len;
-	memcpy(&data[2], &skb->data[DEFAULT_DATA_OFFSET], len);
-	iris_q_evt_data(radio, data, len+2, IRIS_BUF_RD_DEFAULT);
+	memset(&radio->default_data, 0 , sizeof(struct hci_fm_data_rd_rsp));
+	memcpy(&radio->default_data, &skb->data[0], len+2);
+	iris_q_evt_data(radio, &skb->data[0], len+2, IRIS_BUF_RD_DEFAULT);
 	radio_hci_req_complete(hdev, status);
-	kfree(data);
 }
 
 static void hci_cc_ssbi_peek_rsp(struct radio_hci_dev *hdev,
@@ -2773,6 +2766,8 @@
 	unsigned long arg = 0;
 	struct hci_fm_tx_ps tx_ps = {0};
 	struct hci_fm_tx_rt tx_rt = {0};
+	struct hci_fm_def_data_rd_req rd_txgain;
+	struct hci_fm_def_data_wr_req wr_txgain;
 
 	switch (ctrl->id) {
 	case V4L2_CID_PRIVATE_IRIS_TX_TONE:
@@ -3055,6 +3050,32 @@
 		radio->ps_repeatcount = ctrl->value;
 		break;
 	case V4L2_CID_TUNE_POWER_LEVEL:
+		if (ctrl->value > FM_TX_PWR_LVL_MAX)
+			ctrl->value = FM_TX_PWR_LVL_MAX;
+		if (ctrl->value < FM_TX_PWR_LVL_0)
+			ctrl->value = FM_TX_PWR_LVL_0;
+		rd_txgain.mode = FM_TX_PHY_CFG_MODE;
+		rd_txgain.length = FM_TX_PHY_CFG_LEN;
+		rd_txgain.param_len = 0x00;
+		rd_txgain.param = 0x00;
+
+		retval = hci_def_data_read(&rd_txgain, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Default data read failed for PHY_CFG %d\n",
+			retval);
+			break;
+		}
+		memset(&wr_txgain, 0, sizeof(wr_txgain));
+		wr_txgain.mode = FM_TX_PHY_CFG_MODE;
+		wr_txgain.length = FM_TX_PHY_CFG_LEN;
+		memcpy(&wr_txgain.data, &radio->default_data.data,
+					radio->default_data.ret_data_len);
+		wr_txgain.data[FM_TX_PWR_GAIN_OFFSET] =
+				(ctrl->value) * FM_TX_PWR_LVL_STEP_SIZE;
+		retval = hci_def_data_write(&wr_txgain, radio->fm_hdev);
+		if (retval < 0)
+			FMDERR("Default write failed for PHY_TXGAIN %d\n",
+			retval);
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SOFT_MUTE:
 		radio->mute_mode.soft_mute = ctrl->value;
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 8d59590..d12d65e 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -484,8 +484,11 @@
 	uint8_t ctrl_data[max_control_command_size];
 
 	WARN_ON(ctrl == NULL);
-
-	if (ctrl && ctrl->id == MSM_V4L2_PID_CTRL_CMD)
+	if (ctrl == NULL) {
+		pr_err("%s Invalid control\n", __func__);
+		return -EINVAL;
+	}
+	if (ctrl->id == MSM_V4L2_PID_CTRL_CMD)
 		return msm_server_proc_ctrl_cmd(pcam, ctrl, 1);
 
 	memset(ctrl_data, 0, sizeof(ctrl_data));
@@ -512,7 +515,11 @@
 	uint8_t ctrl_data[max_control_command_size];
 
 	WARN_ON(ctrl == NULL);
-	if (ctrl && ctrl->id == MSM_V4L2_PID_CTRL_CMD)
+	if (ctrl == NULL) {
+		pr_err("%s Invalid control\n", __func__);
+		return -EINVAL;
+	}
+	if (ctrl->id == MSM_V4L2_PID_CTRL_CMD)
 		return msm_server_proc_ctrl_cmd(pcam, ctrl, 0);
 
 	memset(ctrl_data, 0, sizeof(ctrl_data));
@@ -2322,7 +2329,7 @@
 	if (IS_ERR(device_config)) {
 		rc = PTR_ERR(device_config);
 		pr_err("%s: error creating device: %d\n", __func__, rc);
-		return rc;
+		goto config_setup_fail;
 	}
 
 	cdev_init(&config_cam->config_cdev,
@@ -2333,7 +2340,7 @@
 	if (rc < 0) {
 		pr_err("%s: error adding cdev: %d\n", __func__, rc);
 		device_destroy(msm_class, devno);
-		return rc;
+		goto config_setup_fail;
 	}
 	g_server_dev.config_info.config_dev_name[dev_num]
 		= dev_name(device_config);
@@ -2345,16 +2352,23 @@
 	config_cam->config_stat_event_queue.pvdev = video_device_alloc();
 	if (config_cam->config_stat_event_queue.pvdev == NULL) {
 		pr_err("%s: video_device_alloc failed\n", __func__);
-		return -ENOMEM;
+		goto config_setup_fail;
 	}
 
 	rc = msm_setup_v4l2_event_queue(
 		&config_cam->config_stat_event_queue.eventHandle,
 		config_cam->config_stat_event_queue.pvdev);
-	if (rc < 0)
+	if (rc < 0) {
 		pr_err("%s failed to initialize event queue\n", __func__);
+		goto config_setup_fail;
+	}
 
 	return rc;
+
+config_setup_fail:
+	kfree(config_cam);
+	return rc;
+
 }
 
 static int msm_setup_server_dev(int node, char *device_name)
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index 7c26947..deb35cc 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -159,11 +159,16 @@
 	} fmt;
 };
 
-static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+struct v4l2_create_buffers32 {
+	__u32			index;		/* output: buffers index...index + count - 1 have been created */
+	__u32			count;
+	enum v4l2_memory        memory;
+	struct v4l2_format32	format;		/* filled in by the user, plane sizes calculated by the driver */
+	__u32			reserved[8];
+};
+
+static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
 {
-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
-			get_user(kp->type, &up->type))
-			return -EFAULT;
 	switch (kp->type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -192,11 +197,24 @@
 	}
 }
 
-static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
 {
-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
-		put_user(kp->type, &up->type))
-		return -EFAULT;
+	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
+			get_user(kp->type, &up->type))
+			return -EFAULT;
+	return __get_v4l2_format32(kp, up);
+}
+
+static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+{
+	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
+	    copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format.fmt)))
+			return -EFAULT;
+	return __get_v4l2_format32(&kp->format, &up->format);
+}
+
+static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+{
 	switch (kp->type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -225,6 +243,22 @@
 	}
 }
 
+static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+{
+	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
+		put_user(kp->type, &up->type))
+		return -EFAULT;
+	return __put_v4l2_format32(kp, up);
+}
+
+static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+{
+	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) ||
+	    copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format.fmt)))
+			return -EFAULT;
+	return __put_v4l2_format32(&kp->format, &up->format);
+}
+
 struct v4l2_standard32 {
 	__u32		     index;
 	__u32		     id[2]; /* __u64 would get the alignment wrong */
@@ -675,6 +709,8 @@
 #define VIDIOC_G_EXT_CTRLS32    _IOWR('V', 71, struct v4l2_ext_controls32)
 #define VIDIOC_S_EXT_CTRLS32    _IOWR('V', 72, struct v4l2_ext_controls32)
 #define VIDIOC_TRY_EXT_CTRLS32  _IOWR('V', 73, struct v4l2_ext_controls32)
+#define VIDIOC_CREATE_BUFS32	_IOWR('V', 92, struct v4l2_create_buffers32)
+#define VIDIOC_PREPARE_BUF32	_IOWR('V', 93, struct v4l2_buffer32)
 
 #define VIDIOC_OVERLAY32	_IOW ('V', 14, s32)
 #define VIDIOC_STREAMON32	_IOW ('V', 18, s32)
@@ -693,6 +729,7 @@
 		struct v4l2_input v2i;
 		struct v4l2_standard v2s;
 		struct v4l2_ext_controls v2ecs;
+		struct v4l2_create_buffers v2crt;
 		unsigned long vx;
 		int vi;
 	} karg;
@@ -722,6 +759,8 @@
 	case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break;
 	case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break;
 	case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break;
+	case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break;
+	case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break;
 	}
 
 	switch (cmd) {
@@ -746,6 +785,12 @@
 		compatible_arg = 0;
 		break;
 
+	case VIDIOC_CREATE_BUFS:
+		err = get_v4l2_create32(&karg.v2crt, up);
+		compatible_arg = 0;
+		break;
+
+	case VIDIOC_PREPARE_BUF:
 	case VIDIOC_QUERYBUF:
 	case VIDIOC_QBUF:
 	case VIDIOC_DQBUF:
@@ -824,6 +869,10 @@
 		err = put_v4l2_format32(&karg.v2f, up);
 		break;
 
+	case VIDIOC_CREATE_BUFS:
+		err = put_v4l2_create32(&karg.v2crt, up);
+		break;
+
 	case VIDIOC_QUERYBUF:
 	case VIDIOC_QBUF:
 	case VIDIOC_DQBUF:
@@ -922,6 +971,8 @@
 	case VIDIOC_DQEVENT:
 	case VIDIOC_SUBSCRIBE_EVENT:
 	case VIDIOC_UNSUBSCRIBE_EVENT:
+	case VIDIOC_CREATE_BUFS32:
+	case VIDIOC_PREPARE_BUF32:
 		ret = do_video_ioctl(file, cmd, arg);
 		break;
 
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index bda252f..5e44c90 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -259,6 +259,8 @@
 	[_IOC_NR(VIDIOC_DQEVENT)]	   = "VIDIOC_DQEVENT",
 	[_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)]  = "VIDIOC_SUBSCRIBE_EVENT",
 	[_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT",
+	[_IOC_NR(VIDIOC_CREATE_BUFS)]      = "VIDIOC_CREATE_BUFS",
+	[_IOC_NR(VIDIOC_PREPARE_BUF)]      = "VIDIOC_PREPARE_BUF",
 };
 #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
 
@@ -2196,6 +2198,40 @@
 		dbgarg(cmd, "type=0x%8.8x", sub->type);
 		break;
 	}
+	case VIDIOC_CREATE_BUFS:
+	{
+		struct v4l2_create_buffers *create = arg;
+
+		if (!ops->vidioc_create_bufs)
+			break;
+		/*if (ret_prio) {
+			ret = ret_prio;
+			break;
+		}*/
+		ret = check_fmt(ops, create->format.type);
+		if (ret)
+			break;
+
+		ret = ops->vidioc_create_bufs(file, fh, create);
+
+		dbgarg(cmd, "count=%d @ %d\n", create->count, create->index);
+		break;
+	}
+	case VIDIOC_PREPARE_BUF:
+	{
+		struct v4l2_buffer *b = arg;
+
+		if (!ops->vidioc_prepare_buf)
+			break;
+		ret = check_fmt(ops, b->type);
+		if (ret)
+			break;
+
+		ret = ops->vidioc_prepare_buf(file, fh, b);
+
+		dbgarg(cmd, "index=%d", b->index);
+		break;
+	}
 	default:
 	{
 		bool valid_prio = true;
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index ddb3881..14d8b75 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -449,12 +449,6 @@
 	  This provides support for the SD/MMC cell found in the
           MSM and QSD SOCs from Qualcomm.
 
-config MMC_MSM_SDIO_SUPPORT
-	boolean "Qualcomm MSM SDIO support"
-	depends on MMC_MSM
-	help
-	  This enables SDIO support in the msm_sdcc driver.
-
 config MMC_MSM_CARD_HW_DETECTION
 	boolean "Qualcomm MMC Hardware detection support"
 	depends on MMC_MSM
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index f03aeac..b4d2edc 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -1666,13 +1666,11 @@
 		msmsdcc_print_status(host, "irq0-p", status);
 #endif
 
-#ifdef CONFIG_MMC_MSM_SDIO_SUPPORT
 		if (status & MCI_SDIOINTROPE) {
 			if (host->sdcc_suspending)
 				wake_lock(&host->sdio_suspend_wlock);
 			mmc_signal_sdio_irq(host->mmc);
 		}
-#endif
 		data = host->curr.data;
 
 		if (host->dummy_52_sent) {
@@ -2741,7 +2739,6 @@
 	return status;
 }
 
-#ifdef CONFIG_MMC_MSM_SDIO_SUPPORT
 static void msmsdcc_enable_sdio_irq(struct mmc_host *mmc, int enable)
 {
 	struct msmsdcc_host *host = mmc_priv(mmc);
@@ -2771,7 +2768,6 @@
 		}
 	}
 }
-#endif /* CONFIG_MMC_MSM_SDIO_SUPPORT */
 
 #ifdef CONFIG_PM_RUNTIME
 static int msmsdcc_enable(struct mmc_host *mmc)
@@ -3421,9 +3417,7 @@
 	.request	= msmsdcc_request,
 	.set_ios	= msmsdcc_set_ios,
 	.get_ro		= msmsdcc_get_ro,
-#ifdef CONFIG_MMC_MSM_SDIO_SUPPORT
 	.enable_sdio_irq = msmsdcc_enable_sdio_irq,
-#endif
 	.start_signal_voltage_switch = msmsdcc_start_signal_voltage_switch,
 	.execute_tuning = msmsdcc_execute_tuning
 };
@@ -4550,9 +4544,7 @@
 
 	if (plat->nonremovable)
 		mmc->caps |= MMC_CAP_NONREMOVABLE;
-#ifdef CONFIG_MMC_MSM_SDIO_SUPPORT
 	mmc->caps |= MMC_CAP_SDIO_IRQ;
-#endif
 
 	if (plat->is_sdio_al_client)
 		mmc->pm_flags |= MMC_PM_IGNORE_PM_NOTIFY;
diff --git a/drivers/net/msm_rmnet_bam.c b/drivers/net/msm_rmnet_bam.c
index 401b63c..bbcf3c4 100644
--- a/drivers/net/msm_rmnet_bam.c
+++ b/drivers/net/msm_rmnet_bam.c
@@ -79,6 +79,7 @@
 #endif
 	struct sk_buff *waiting_for_ul_skb;
 	spinlock_t lock;
+	spinlock_t tx_queue_lock;
 	struct tasklet_struct tsklt;
 	u32 operation_mode; /* IOCTL specified mode (protocol, QoS header) */
 	uint8_t device_up;
@@ -321,6 +322,7 @@
 {
 	struct rmnet_private *p = netdev_priv(dev);
 	u32 opmode = p->operation_mode;
+	unsigned long flags;
 
 	DBG1("%s: write complete\n", __func__);
 	if (RMNET_IS_MODE_IP(opmode) ||
@@ -335,12 +337,15 @@
 	    ((struct net_device *)(dev))->name, p->stats.tx_packets,
 	    skb->len, skb->mark);
 	dev_kfree_skb_any(skb);
+
+	spin_lock_irqsave(&p->tx_queue_lock, flags);
 	if (netif_queue_stopped(dev) &&
 	    msm_bam_dmux_is_ch_low(p->ch_id)) {
 		DBG0("%s: Low WM hit, waking queue=%p\n",
 		      __func__, skb);
 		netif_wake_queue(dev);
 	}
+	spin_unlock_irqrestore(&p->tx_queue_lock, flags);
 }
 
 static void bam_notify(void *dev, int event, unsigned long data)
@@ -509,10 +514,12 @@
 		goto exit;
 	}
 
+	spin_lock_irqsave(&p->tx_queue_lock, flags);
 	if (msm_bam_dmux_is_ch_full(p->ch_id)) {
 		netif_stop_queue(dev);
 		DBG0("%s: High WM hit, stopping queue=%p\n",    __func__, skb);
 	}
+	spin_unlock_irqrestore(&p->tx_queue_lock, flags);
 
 exit:
 	msm_bam_dmux_ul_power_unvote();
@@ -770,6 +777,7 @@
 		p->waiting_for_ul_skb = NULL;
 		p->in_reset = 0;
 		spin_lock_init(&p->lock);
+		spin_lock_init(&p->tx_queue_lock);
 #ifdef CONFIG_MSM_RMNET_DEBUG
 		p->timeout_us = timeout_us;
 		p->wakeups_xmit = p->wakeups_rcv = 0;
diff --git a/drivers/power/pm8xxx-ccadc.c b/drivers/power/pm8xxx-ccadc.c
index 65bc654..ce72a5b 100644
--- a/drivers/power/pm8xxx-ccadc.c
+++ b/drivers/power/pm8xxx-ccadc.c
@@ -214,8 +214,8 @@
 			break;
 	}
 	if (i == ADC_WAIT_COUNT) {
-		pr_err("waited too long for offset eoc\n");
-		return rc;
+		pr_err("waited too long for offset eoc returning -EBUSY\n");
+		return -EBUSY;
 	}
 
 	rc = pm8xxx_readb(chip->dev->parent, ADC_ARB_SECP_DATA0, &data_lsb);
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 80f50de..0e121d1 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -440,7 +440,6 @@
 	int ret;
 	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
 
-	wake_lock(&msm_uport->dma_wake_lock);
 	/* Set up the MREG/NREG/DREG/MNDREG */
 	ret = clk_set_rate(msm_uport->clk, uport->uartclk);
 	if (ret) {
@@ -456,6 +455,7 @@
 	if (msm_uport->pclk) {
 		ret = clk_enable(msm_uport->pclk);
 		if (ret) {
+			clk_disable(msm_uport->clk);
 			dev_err(uport->dev,
 				"Error could not turn on UART pclk\n");
 			return ret;
@@ -1578,10 +1578,14 @@
 	tx->dma_base = dma_map_single(uport->dev, tx_buf->buf, UART_XMIT_SIZE,
 				      DMA_TO_DEVICE);
 
+	wake_lock(&msm_uport->dma_wake_lock);
 	/* turn on uart clk */
 	ret = msm_hs_init_clk(uport);
-	if (unlikely(ret))
+	if (unlikely(ret)) {
+		pr_err("Turning ON uartclk error\n");
+		wake_unlock(&msm_uport->dma_wake_lock);
 		return ret;
+	}
 
 	/* Set auto RFR Level */
 	data = msm_hs_read(uport, UARTDM_MR1_ADDR);
@@ -1646,20 +1650,26 @@
 
 	if (use_low_power_wakeup(msm_uport)) {
 		ret = irq_set_irq_wake(msm_uport->wakeup.irq, 1);
-		if (unlikely(ret))
-			return ret;
+		if (unlikely(ret)) {
+			pr_err("%s():Err setting wakeup irq\n", __func__);
+			goto deinit_uart_clk;
+		}
 	}
 
 	ret = request_irq(uport->irq, msm_hs_isr, IRQF_TRIGGER_HIGH,
 			  "msm_hs_uart", msm_uport);
-	if (unlikely(ret))
-		return ret;
+	if (unlikely(ret)) {
+		pr_err("%s():Error getting uart irq\n", __func__);
+		goto free_wake_irq;
+	}
 	if (use_low_power_wakeup(msm_uport)) {
 		ret = request_irq(msm_uport->wakeup.irq, msm_hs_wakeup_isr,
 				  IRQF_TRIGGER_FALLING,
 				  "msm_hs_wakeup", msm_uport);
-		if (unlikely(ret))
-			return ret;
+		if (unlikely(ret)) {
+			pr_err("%s():Err getting uart wakeup_irq\n", __func__);
+			goto free_uart_irq;
+		}
 		disable_irq(msm_uport->wakeup.irq);
 	}
 
@@ -1673,8 +1683,19 @@
 		dev_err(uport->dev, "set active error:%d\n", ret);
 	pm_runtime_enable(uport->dev);
 
-
 	return 0;
+
+free_uart_irq:
+	free_irq(uport->irq, msm_uport);
+free_wake_irq:
+	irq_set_irq_wake(msm_uport->wakeup.irq, 0);
+deinit_uart_clk:
+	clk_disable(msm_uport->clk);
+	if (msm_uport->pclk)
+		clk_disable(msm_uport->pclk);
+	wake_unlock(&msm_uport->dma_wake_lock);
+
+	return ret;
 }
 
 /* Initialize tx and rx data structures */
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 9cbfad8..8e0bef0 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -2710,6 +2710,12 @@
 	return 0;
 }
 
+static int is_sps_req(struct ci13xxx_req *mReq)
+{
+	return (CI13XX_REQ_VENDOR_ID(mReq->req.udc_priv) == MSM_VENDOR_ID &&
+			mReq->req.udc_priv & MSM_SPS_MODE);
+}
+
 /**
  * ep_set_halt: sets the endpoint halt feature
  *
@@ -2731,7 +2737,9 @@
 #ifndef STALL_IN
 	/* g_file_storage MS compliant but g_zero fails chapter 9 compliance */
 	if (value && mEp->type == USB_ENDPOINT_XFER_BULK && mEp->dir == TX &&
-	    !list_empty(&mEp->qh.queue)) {
+		!list_empty(&mEp->qh.queue) &&
+		!is_sps_req(list_entry(mEp->qh.queue.next, struct ci13xxx_req,
+							   queue))){
 		spin_unlock_irqrestore(mEp->lock, flags);
 		return -EAGAIN;
 	}
diff --git a/drivers/usb/gadget/f_rmnet.c b/drivers/usb/gadget/f_rmnet.c
index cc26c85..b086428 100644
--- a/drivers/usb/gadget/f_rmnet.c
+++ b/drivers/usb/gadget/f_rmnet.c
@@ -488,20 +488,16 @@
 	}
 	dev->notify->driver_data = dev;
 
-	if (dev->port.in->driver_data) {
-		pr_debug("%s: reset port:%d\n", __func__, dev->port_num);
-		gport_rmnet_disconnect(dev);
+	if (!dev->port.in->driver_data) {
+		if (config_ep_by_speed(cdev->gadget, f, dev->port.in) ||
+			config_ep_by_speed(cdev->gadget, f, dev->port.out)) {
+				dev->port.in->desc = NULL;
+				dev->port.out->desc = NULL;
+				return -EINVAL;
+		}
+		ret = gport_rmnet_connect(dev);
 	}
 
-	if (config_ep_by_speed(cdev->gadget, f, dev->port.in) ||
-	    config_ep_by_speed(cdev->gadget, f, dev->port.out)) {
-			dev->port.in->desc = NULL;
-			dev->port.out->desc = NULL;
-			return -EINVAL;
-	}
-
-	ret = gport_rmnet_connect(dev);
-
 	atomic_set(&dev->online, 1);
 
 	return ret;
diff --git a/drivers/video/msm/external_common.c b/drivers/video/msm/external_common.c
index 061e69c..29d500a 100644
--- a/drivers/video/msm/external_common.c
+++ b/drivers/video/msm/external_common.c
@@ -343,6 +343,86 @@
 	return ret;
 }
 
+static ssize_t hdmi_common_wta_vendor_name(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	uint8 *s = (uint8 *) buf;
+	uint8 *d = external_common_state->spd_vendor_name;
+	ssize_t ret = strnlen(buf, PAGE_SIZE);
+	ret = (ret > 8) ? 8 : ret;
+
+	memset(external_common_state->spd_vendor_name, 0, 8);
+	while (*s) {
+		if (*s & 0x60 && *s ^ 0x7f) {
+			*d = *s;
+		} else {
+			/* stop copying if control character found */
+			break;
+		}
+
+		if (++s > (uint8 *) (buf + ret))
+			break;
+
+		d++;
+	}
+
+	DEV_DBG("%s: '%s'\n", __func__,
+			external_common_state->spd_vendor_name);
+
+	return ret;
+}
+
+static ssize_t hdmi_common_rda_vendor_name(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	ssize_t ret = snprintf(buf, PAGE_SIZE, "%s\n",
+		external_common_state->spd_vendor_name);
+	DEV_DBG("%s: '%s'\n", __func__,
+			external_common_state->spd_vendor_name);
+
+	return ret;
+}
+
+static ssize_t hdmi_common_wta_product_description(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	uint8 *s = (uint8 *) buf;
+	uint8 *d = external_common_state->spd_product_description;
+	ssize_t ret = strnlen(buf, PAGE_SIZE);
+	ret = (ret > 16) ? 16 : ret;
+
+	memset(external_common_state->spd_product_description, 0, 16);
+	while (*s) {
+		if (*s & 0x60 && *s ^ 0x7f) {
+			*d = *s;
+		} else {
+			/* stop copying if control character found */
+			break;
+		}
+
+		if (++s > (uint8 *) (buf + ret))
+			break;
+
+		d++;
+	}
+
+	DEV_DBG("%s: '%s'\n", __func__,
+			external_common_state->spd_product_description);
+
+	return ret;
+}
+
+static ssize_t hdmi_common_rda_product_description(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	ssize_t ret = snprintf(buf, PAGE_SIZE, "%s\n",
+		external_common_state->spd_product_description);
+	DEV_DBG("%s: '%s'\n", __func__,
+			external_common_state->spd_product_description);
+
+	return ret;
+}
+
 static ssize_t hdmi_common_rda_hdcp(struct device *dev,
 	struct device_attribute *attr, char *buf)
 {
@@ -711,6 +791,11 @@
 	hdmi_common_rda_edid_physical_address, NULL);
 static DEVICE_ATTR(scan_info, S_IRUGO,
 	hdmi_common_rda_edid_scan_info, NULL);
+static DEVICE_ATTR(vendor_name, S_IRUGO | S_IWUSR, hdmi_common_rda_vendor_name,
+	hdmi_common_wta_vendor_name);
+static DEVICE_ATTR(product_description, S_IRUGO | S_IWUSR,
+	hdmi_common_rda_product_description,
+	hdmi_common_wta_product_description);
 static DEVICE_ATTR(3d_present, S_IRUGO, hdmi_common_rda_3d_present, NULL);
 static DEVICE_ATTR(hdcp_present, S_IRUGO, hdmi_common_rda_hdcp_present, NULL);
 #endif
@@ -731,6 +816,8 @@
 	&dev_attr_hpd.attr,
 	&dev_attr_pa.attr,
 	&dev_attr_scan_info.attr,
+	&dev_attr_vendor_name.attr,
+	&dev_attr_product_description.attr,
 	&dev_attr_3d_present.attr,
 	&dev_attr_hdcp_present.attr,
 #endif
diff --git a/drivers/video/msm/external_common.h b/drivers/video/msm/external_common.h
index b8d2e5f..0f44da5 100644
--- a/drivers/video/msm/external_common.h
+++ b/drivers/video/msm/external_common.h
@@ -221,6 +221,8 @@
 	uint8 pt_scan_info;
 	uint8 it_scan_info;
 	uint8 ce_scan_info;
+	uint8 spd_vendor_name[8];
+	uint8 spd_product_description[16];
 	boolean present_3d;
 	boolean present_hdcp;
 	uint32 audio_data_blocks[16];
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index d3bb4c7..354add7 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -3937,6 +3937,137 @@
 }
 #endif
 
+#define IFRAME_CHECKSUM_32(d) \
+	((d & 0xff) + ((d >> 8) & 0xff) + \
+	((d >> 16) & 0xff) + ((d >> 24) & 0xff))
+
+static void hdmi_msm_spd_infoframe_packetsetup(void)
+{
+	uint32 packet_header  = 0;
+	uint32 check_sum      = 0;
+	uint32 packet_payload = 0;
+	uint32 packet_control = 0;
+
+	uint8 *vendor_name = external_common_state->spd_vendor_name;
+	uint8 *product_description =
+		external_common_state->spd_product_description;
+
+	/* 0x00A4 GENERIC1_HDR
+	 *   HB0             7:0  NUM
+	 *   HB1            15:8  NUM
+	 *   HB2           23:16  NUM */
+	/* Setup Packet header and payload */
+	/* 0x83 InfoFrame Type Code
+	   0x01 InfoFrame Version Number
+	   0x19 Length of Source Product Description InfoFrame
+	*/
+	packet_header  = 0x83 | (0x01 << 8) | (0x19 << 16);
+	HDMI_OUTP(0x00A4, packet_header);
+	check_sum += IFRAME_CHECKSUM_32(packet_header);
+
+	/* Vendor Name (7bit ASCII code) */
+	/* 0x00A8 GENERIC1_0
+	 *   BYTE0           7:0  CheckSum
+	 *   BYTE1          15:8  VENDOR_NAME[0]
+	 *   BYTE2         23:16  VENDOR_NAME[1]
+	 *   BYTE3         31:24  VENDOR_NAME[2] */
+	packet_payload = ((vendor_name[0] & 0x7f) << 8)
+		| ((vendor_name[1] & 0x7f) << 16)
+		| ((vendor_name[2] & 0x7f) << 24);
+	check_sum += IFRAME_CHECKSUM_32(packet_payload);
+	packet_payload |= ((0x100 - (0xff & check_sum)) & 0xff);
+	HDMI_OUTP(0x00A8, packet_payload);
+
+	/* 0x00AC GENERIC1_1
+	 *   BYTE4           7:0  VENDOR_NAME[3]
+	 *   BYTE5          15:8  VENDOR_NAME[4]
+	 *   BYTE6         23:16  VENDOR_NAME[5]
+	 *   BYTE7         31:24  VENDOR_NAME[6] */
+	packet_payload = (vendor_name[3] & 0x7f)
+		| ((vendor_name[4] & 0x7f) << 8)
+		| ((vendor_name[5] & 0x7f) << 16)
+		| ((vendor_name[6] & 0x7f) << 24);
+	HDMI_OUTP(0x00AC, packet_payload);
+	check_sum += IFRAME_CHECKSUM_32(packet_payload);
+
+	/* Product Description (7-bit ASCII code) */
+	/* 0x00B0 GENERIC1_2
+	 *   BYTE8           7:0  VENDOR_NAME[7]
+	 *   BYTE9          15:8  PRODUCT_NAME[ 0]
+	 *   BYTE10        23:16  PRODUCT_NAME[ 1]
+	 *   BYTE11        31:24  PRODUCT_NAME[ 2] */
+	packet_payload = (vendor_name[7] & 0x7f)
+		| ((product_description[0] & 0x7f) << 8)
+		| ((product_description[1] & 0x7f) << 16)
+		| ((product_description[2] & 0x7f) << 24);
+	HDMI_OUTP(0x00B0, packet_payload);
+	check_sum += IFRAME_CHECKSUM_32(packet_payload);
+
+	/* 0x00B4 GENERIC1_3
+	 *   BYTE12          7:0  PRODUCT_NAME[ 3]
+	 *   BYTE13         15:8  PRODUCT_NAME[ 4]
+	 *   BYTE14        23:16  PRODUCT_NAME[ 5]
+	 *   BYTE15        31:24  PRODUCT_NAME[ 6] */
+	packet_payload = (product_description[3] & 0x7f)
+		| ((product_description[4] & 0x7f) << 8)
+		| ((product_description[5] & 0x7f) << 16)
+		| ((product_description[6] & 0x7f) << 24);
+	HDMI_OUTP(0x00B4, packet_payload);
+	check_sum += IFRAME_CHECKSUM_32(packet_payload);
+
+	/* 0x00B8 GENERIC1_4
+	 *   BYTE16          7:0  PRODUCT_NAME[ 7]
+	 *   BYTE17         15:8  PRODUCT_NAME[ 8]
+	 *   BYTE18        23:16  PRODUCT_NAME[ 9]
+	 *   BYTE19        31:24  PRODUCT_NAME[10] */
+	packet_payload = (product_description[7] & 0x7f)
+		| ((product_description[8] & 0x7f) << 8)
+		| ((product_description[9] & 0x7f) << 16)
+		| ((product_description[10] & 0x7f) << 24);
+	HDMI_OUTP(0x00B8, packet_payload);
+	check_sum += IFRAME_CHECKSUM_32(packet_payload);
+
+	/* 0x00BC GENERIC1_5
+	 *   BYTE20          7:0  PRODUCT_NAME[11]
+	 *   BYTE21         15:8  PRODUCT_NAME[12]
+	 *   BYTE22        23:16  PRODUCT_NAME[13]
+	 *   BYTE23        31:24  PRODUCT_NAME[14] */
+	packet_payload = (product_description[11] & 0x7f)
+		| ((product_description[12] & 0x7f) << 8)
+		| ((product_description[13] & 0x7f) << 16)
+		| ((product_description[14] & 0x7f) << 24);
+	HDMI_OUTP(0x00BC, packet_payload);
+	check_sum += IFRAME_CHECKSUM_32(packet_payload);
+
+	/* 0x00C0 GENERIC1_6
+	 *   BYTE24          7:0  PRODUCT_NAME[15]
+	 *   BYTE25         15:8  Source Device Information
+	 *   BYTE26        23:16  NUM
+	 *   BYTE27        31:24  NUM */
+	/* Source Device Information
+	 * 00h unknown
+	 * 01h Digital STB
+	 * 02h DVD
+	 * 03h D-VHS
+	 * 04h HDD Video
+	 * 05h DVC
+	 * 06h DSC
+	 * 07h Video CD
+	 * 08h Game
+	 * 09h PC general */
+	packet_payload = (product_description[15] & 0x7f) | 0x00 << 8;
+	HDMI_OUTP(0x00C0, packet_payload);
+	check_sum += IFRAME_CHECKSUM_32(packet_payload);
+
+	/* GENERIC1_LINE | GENERIC1_CONT | GENERIC1_SEND
+	 * Setup HDMI TX generic packet control
+	 * Enable this packet to transmit every frame
+	 * Enable HDMI TX engine to transmit Generic packet 1 */
+	packet_control = HDMI_INP_ND(0x0034);
+	packet_control |= ((0x1 << 24) | (1 << 5) | (1 << 4));
+	HDMI_OUTP(0x0034, packet_control);
+}
+
 int hdmi_msm_clk(int on)
 {
 	int rc;
@@ -4012,6 +4143,7 @@
 #ifdef CONFIG_FB_MSM_HDMI_3D
 	hdmi_msm_vendor_infoframe_packetsetup();
 #endif
+	hdmi_msm_spd_infoframe_packetsetup();
 
 	/* set timeout to 4.1ms (max) for hardware debounce */
 	hpd_ctrl = (HDMI_INP(0x0258) & ~0xFFF) | 0xFFF;
@@ -4587,6 +4719,10 @@
 #ifdef CONFIG_FB_MSM_HDMI_3D
 	external_common_state->switch_3d = hdmi_msm_switch_3d;
 #endif
+	memset(external_common_state->spd_vendor_name, 0,
+			sizeof(external_common_state->spd_vendor_name));
+	memset(external_common_state->spd_product_description, 0,
+			sizeof(external_common_state->spd_product_description));
 
 #ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
 	hdmi_msm_state->cec_queue_start =
diff --git a/include/linux/device.h b/include/linux/device.h
index e4f62d8..b44a3b1 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -506,6 +506,10 @@
  * @mutex:	Mutex to synchronize calls to its driver.
  * @bus:	Type of bus device is on.
  * @driver:	Which driver has allocated this
+ * @deferred_probe: entry in deferred_probe_list which is used to retry the
+ * 		binding of drivers which were unable to get all the resources
+ * 		needed by the device; typically because it depends on another
+ * 		driver getting probed first.
  * @platform_data: Platform data specific to the device.
  * 		Example: For devices on custom boards, as typical of embedded
  * 		and SOC based hardware, Linux often uses platform_data to point
@@ -564,6 +568,7 @@
 	struct bus_type	*bus;		/* type of bus device is on */
 	struct device_driver *driver;	/* which driver has allocated this
 					   device */
+	struct list_head	deferred_probe;
 	void		*platform_data;	/* Platform specific data, device
 					   core doesn't touch it */
 	struct dev_pm_info	power;
diff --git a/include/linux/errno.h b/include/linux/errno.h
index 4668583..2d09bfa 100644
--- a/include/linux/errno.h
+++ b/include/linux/errno.h
@@ -16,6 +16,7 @@
 #define ERESTARTNOHAND	514	/* restart if no handler.. */
 #define ENOIOCTLCMD	515	/* No ioctl command */
 #define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */
+#define EPROBE_DEFER	517	/* Driver requests probe retry */
 
 /* Defined for the NFSv3 protocol */
 #define EBADHANDLE	521	/* Illegal NFS file handle */
diff --git a/include/linux/msm_kgsl.h b/include/linux/msm_kgsl.h
index 672468e..8739122 100644
--- a/include/linux/msm_kgsl.h
+++ b/include/linux/msm_kgsl.h
@@ -164,6 +164,7 @@
 	int num_levels;
 	int (*set_grp_async)(void);
 	unsigned int idle_timeout;
+	bool strtstp_sleepwake;
 	unsigned int nap_allowed;
 	unsigned int clk_map;
 	unsigned int idle_needed;
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 175b54f..0a0fb1b 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -652,6 +652,10 @@
 #define V4L2_BUF_FLAG_ERROR	0x0040
 #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
 #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
+#define V4L2_BUF_FLAG_PREPARED	0x0400	/* Buffer is prepared for queuing */
+/* Cache handling flags */
+#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0800
+#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x1000
 
 /*
  *	O V E R L A Y   P R E V I E W
@@ -2035,6 +2039,15 @@
 	__u32 revision;    /* chip revision, chip specific */
 } __attribute__ ((packed));
 
+/* VIDIOC_CREATE_BUFS */
+struct v4l2_create_buffers {
+	__u32			index;		/* output: buffers index...index + count - 1 have been created */
+	__u32			count;
+	enum v4l2_memory        memory;
+	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
+	__u32			reserved[8];
+};
+
 /*
  *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
  *
@@ -2125,6 +2138,11 @@
 #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
 #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
 
+/* Experimental, the below two ioctls may change over the next couple of kernel
+   versions */
+#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
+#define VIDIOC_PREPARE_BUF	_IOWR('V', 93, struct v4l2_buffer)
+
 /* Reminder: when adding new ioctls please add support for them to
    drivers/media/video/v4l2-compat-ioctl32.c as well! */
 
diff --git a/include/media/radio-iris.h b/include/media/radio-iris.h
index de2b356..dfad18d 100644
--- a/include/media/radio-iris.h
+++ b/include/media/radio-iris.h
@@ -44,7 +44,14 @@
 /* default data access */
 #define DEFAULT_DATA_OFFSET 2
 #define DEFAULT_DATA_SIZE 249
-
+/* Power levels are 0-7, but SOC will expect values from 0-255
+ * So the each level step size will be 255/7 = 36 */
+#define FM_TX_PWR_LVL_STEP_SIZE 36
+#define FM_TX_PWR_LVL_0         0 /* Lowest power lvl that can be set for Tx */
+#define FM_TX_PWR_LVL_MAX       7 /* Max power lvl for Tx */
+#define FM_TX_PHY_CFG_MODE   0x3c
+#define FM_TX_PHY_CFG_LEN    0x10
+#define FM_TX_PWR_GAIN_OFFSET 14
 /* HCI timeouts */
 #define RADIO_HCI_TIMEOUT	(10000)	/* 10 seconds */
 
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index dd9f1e7..4d1c74a 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -122,6 +122,8 @@
 	int (*vidioc_qbuf)    (struct file *file, void *fh, struct v4l2_buffer *b);
 	int (*vidioc_dqbuf)   (struct file *file, void *fh, struct v4l2_buffer *b);
 
+	int (*vidioc_create_bufs)(struct file *file, void *fh, struct v4l2_create_buffers *b);
+	int (*vidioc_prepare_buf)(struct file *file, void *fh, struct v4l2_buffer *b);
 
 	int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i);
 	int (*vidioc_g_fbuf)   (struct file *file, void *fh,
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index f57113b..74d0851 100755
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2783,6 +2783,12 @@
 		if (!conn->ssp_mode && conn->auth_initiator &&
 			(conn->pending_sec_level == BT_SECURITY_HIGH))
 			conn->pending_sec_level = BT_SECURITY_MEDIUM;
+
+		if (conn->ssp_mode && conn->auth_initiator &&
+			conn->io_capability != 0x03) {
+			conn->pending_sec_level = BT_SECURITY_HIGH;
+			conn->auth_type = HCI_AT_DEDICATED_BONDING_MITM;
+		}
 	}
 
 	if (conn->state != BT_CONFIG)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 52c1fe6..bcd0dd7 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1614,13 +1614,9 @@
 	hci_dev_lock_bh(hdev);
 
 	io_cap = cp->io_cap;
-	if (io_cap == 0x03) {
-		sec_level = BT_SECURITY_MEDIUM;
-		auth_type = HCI_AT_DEDICATED_BONDING;
-	} else {
-		sec_level = BT_SECURITY_HIGH;
-		auth_type = HCI_AT_DEDICATED_BONDING_MITM;
-	}
+
+	sec_level = BT_SECURITY_MEDIUM;
+	auth_type = HCI_AT_DEDICATED_BONDING;
 
 	entry = hci_find_adv_entry(hdev, &cp->bdaddr);
 	if (entry && entry->flags & 0x04) {