Merge "ARM: Disable the external caches during restart" into msm-3.0
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index 162fc04..83d0828 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -273,6 +273,7 @@
 CONFIG_MMC=y
 CONFIG_MMC_PERF_PROFILING=y
 CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
 CONFIG_MMC_PARANOID_SD_INIT=y
 CONFIG_MMC_BLOCK_MINORS=32
 # CONFIG_MMC_BLOCK_BOUNCE is not set
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index d19fa3d..dcbca79 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -268,6 +268,7 @@
 CONFIG_MMC=y
 CONFIG_MMC_PERF_PROFILING=y
 CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
 CONFIG_MMC_PARANOID_SD_INIT=y
 CONFIG_MMC_BLOCK_MINORS=32
 # CONFIG_MMC_BLOCK_BOUNCE is not set
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index 4275140..67d0057 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -44,6 +44,10 @@
 CONFIG_MSM_BAM_DMUX=y
 CONFIG_MSM_IPC_ROUTER=y
 CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
+CONFIG_MSM_SUBSYSTEM_RESTART=y
+# CONFIG_MSM_SYSMON_COMM is not set
+CONFIG_MSM_MODEM_8960=y
+CONFIG_MSM_LPASS_8960=y
 CONFIG_MSM_DIRECT_SCLK_ACCESS=y
 CONFIG_MSM_WATCHDOG=y
 CONFIG_MSM_DLOAD_MODE=y
diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h
index 6e55bf3..c86fad9 100644
--- a/arch/arm/include/asm/mach/mmc.h
+++ b/arch/arm/include/asm/mach/mmc.h
@@ -140,7 +140,6 @@
 	bool nonremovable;
 	bool pclk_src_dfab;
 	int (*cfg_mpm_sdiowakeup)(struct device *, unsigned);
-	bool sdcc_v4_sup;
 	unsigned int wpswitch_gpio;
 	unsigned char wpswitch_polarity;
 	struct msm_mmc_slot_reg_data *vreg_data;
diff --git a/arch/arm/kernel/perf_event_msm.c b/arch/arm/kernel/perf_event_msm.c
index fb53650..579cd3b 100644
--- a/arch/arm/kernel/perf_event_msm.c
+++ b/arch/arm/kernel/perf_event_msm.c
@@ -215,15 +215,15 @@
 	[C(BPU)] = {
 		[C(OP_READ)] = {
 			[C(RESULT_ACCESS)]
-					= ARMV7_PERFCTR_PC_BRANCH_MIS_USED,
+					= ARMV7_PERFCTR_PC_BRANCH_PRED,
 			[C(RESULT_MISS)]
-					= ARMV7_PERFCTR_PC_BRANCH_MIS_USED,
+					= ARMV7_PERFCTR_PC_BRANCH_PRED,
 		},
 		[C(OP_WRITE)] = {
 			[C(RESULT_ACCESS)]
-					= ARMV7_PERFCTR_PC_BRANCH_MIS_USED,
+					= ARMV7_PERFCTR_PC_BRANCH_PRED,
 			[C(RESULT_MISS)]
-					= ARMV7_PERFCTR_PC_BRANCH_MIS_USED,
+					= ARMV7_PERFCTR_PC_BRANCH_PRED,
 		},
 		[C(OP_PREFETCH)] = {
 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
diff --git a/arch/arm/kernel/perf_event_msm_krait.c b/arch/arm/kernel/perf_event_msm_krait.c
index 62509b4..1e77489 100644
--- a/arch/arm/kernel/perf_event_msm_krait.c
+++ b/arch/arm/kernel/perf_event_msm_krait.c
@@ -122,15 +122,15 @@
 	[C(BPU)] = {
 		[C(OP_READ)] = {
 			[C(RESULT_ACCESS)]
-					= ARMV7_PERFCTR_PC_BRANCH_MIS_USED,
+					= ARMV7_PERFCTR_PC_BRANCH_PRED,
 			[C(RESULT_MISS)]
-					= ARMV7_PERFCTR_PC_BRANCH_MIS_USED,
+					= ARMV7_PERFCTR_PC_BRANCH_PRED,
 		},
 		[C(OP_WRITE)] = {
 			[C(RESULT_ACCESS)]
-					= ARMV7_PERFCTR_PC_BRANCH_MIS_USED,
+					= ARMV7_PERFCTR_PC_BRANCH_PRED,
 			[C(RESULT_MISS)]
-					= ARMV7_PERFCTR_PC_BRANCH_MIS_USED,
+					= ARMV7_PERFCTR_PC_BRANCH_PRED,
 		},
 		[C(OP_PREFETCH)] = {
 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
@@ -365,7 +365,7 @@
 
 static struct arm_pmu krait_pmu = {
 	.handle_irq		= armv7pmu_handle_irq,
-#ifdef CONFIG_MSM_SMP
+#ifdef CONFIG_SMP
 	.secondary_enable       = scorpion_secondary_enable,
 	.secondary_disable      = scorpion_secondary_disable,
 #endif
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 4960686..01b1145 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -17,17 +17,23 @@
  */
 
 #ifdef CONFIG_CPU_V7
-/* Common ARMv7 event types */
+/*
+ * Common ARMv7 event types
+ *
+ * Note: An implementation may not be able to count all of these events
+ * but the encodings are considered to be `reserved' in the case that
+ * they are not available.
+ */
 enum armv7_perf_types {
 	ARMV7_PERFCTR_PMNC_SW_INCR		= 0x00,
 	ARMV7_PERFCTR_IFETCH_MISS		= 0x01,
 	ARMV7_PERFCTR_ITLB_MISS			= 0x02,
-	ARMV7_PERFCTR_DCACHE_REFILL		= 0x03,
-	ARMV7_PERFCTR_DCACHE_ACCESS		= 0x04,
+	ARMV7_PERFCTR_DCACHE_REFILL		= 0x03,	/* L1 */
+	ARMV7_PERFCTR_DCACHE_ACCESS		= 0x04,	/* L1 */
 	ARMV7_PERFCTR_DTLB_REFILL		= 0x05,
 	ARMV7_PERFCTR_DREAD			= 0x06,
 	ARMV7_PERFCTR_DWRITE			= 0x07,
-
+	ARMV7_PERFCTR_INSTR_EXECUTED		= 0x08,
 	ARMV7_PERFCTR_EXC_TAKEN			= 0x09,
 	ARMV7_PERFCTR_EXC_EXECUTED		= 0x0A,
 	ARMV7_PERFCTR_CID_WRITE			= 0x0B,
@@ -39,21 +45,30 @@
 	 */
 	ARMV7_PERFCTR_PC_WRITE			= 0x0C,
 	ARMV7_PERFCTR_PC_IMM_BRANCH		= 0x0D,
+	ARMV7_PERFCTR_PC_PROC_RETURN		= 0x0E,
 	ARMV7_PERFCTR_UNALIGNED_ACCESS		= 0x0F,
+
+	/* These events are defined by the PMUv2 supplement (ARM DDI 0457A). */
 	ARMV7_PERFCTR_PC_BRANCH_MIS_PRED	= 0x10,
 	ARMV7_PERFCTR_CLOCK_CYCLES		= 0x11,
-
-	ARMV7_PERFCTR_PC_BRANCH_MIS_USED	= 0x12,
+	ARMV7_PERFCTR_PC_BRANCH_PRED		= 0x12,
+	ARMV7_PERFCTR_MEM_ACCESS		= 0x13,
+	ARMV7_PERFCTR_L1_ICACHE_ACCESS		= 0x14,
+	ARMV7_PERFCTR_L1_DCACHE_WB		= 0x15,
+	ARMV7_PERFCTR_L2_DCACHE_ACCESS		= 0x16,
+	ARMV7_PERFCTR_L2_DCACHE_REFILL		= 0x17,
+	ARMV7_PERFCTR_L2_DCACHE_WB		= 0x18,
+	ARMV7_PERFCTR_BUS_ACCESS		= 0x19,
+	ARMV7_PERFCTR_MEMORY_ERROR		= 0x1A,
+	ARMV7_PERFCTR_INSTR_SPEC		= 0x1B,
+	ARMV7_PERFCTR_TTBR_WRITE		= 0x1C,
+	ARMV7_PERFCTR_BUS_CYCLES		= 0x1D,
 
 	ARMV7_PERFCTR_CPU_CYCLES		= 0xFF
 };
 
 /* ARMv7 Cortex-A8 specific event types */
 enum armv7_a8_perf_types {
-	ARMV7_PERFCTR_INSTR_EXECUTED		= 0x08,
-
-	ARMV7_PERFCTR_PC_PROC_RETURN		= 0x0E,
-
 	ARMV7_PERFCTR_WRITE_BUFFER_FULL		= 0x40,
 	ARMV7_PERFCTR_L2_STORE_MERGED		= 0x41,
 	ARMV7_PERFCTR_L2_STORE_BUFF		= 0x42,
@@ -207,11 +222,6 @@
 		},
 	},
 	[C(DTLB)] = {
-		/*
-		 * Only ITLB misses and DTLB refills are supported.
-		 * If users want the DTLB refills misses a raw counter
-		 * must be used.
-		 */
 		[C(OP_READ)] = {
 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DTLB_REFILL,
@@ -323,11 +333,6 @@
 		},
 	},
 	[C(DTLB)] = {
-		/*
-		 * Only ITLB misses and DTLB refills are supported.
-		 * If users want the DTLB refills misses a raw counter
-		 * must be used.
-		 */
 		[C(OP_READ)] = {
 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DTLB_REFILL,
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index db2eda5..2d681fa 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -712,28 +712,52 @@
 		bool "6.2.20 + New ADSP"
 endchoice
 
-config MSM_DEBUG_UART
-	int
-	default 1 if MSM_DEBUG_UART1
-	default 2 if MSM_DEBUG_UART2
-	default 3 if MSM_DEBUG_UART3
+config DEBUG_MSM8930_UART
+	bool "Kernel low-level debugging messages via MSM 8930 UART"
+	depends on ARCH_MSM8930 && DEBUG_LL
+	help
+	  Say Y here if you want the debug print routines to direct
+	  their output to the serial port on MSM 8930 devices.
 
 choice
 	prompt "Debug UART"
+	depends on DEBUG_LL
 
-	default MSM_DEBUG_UART_NONE
+	config DEBUG_MSM_UART1
+		bool "Kernel low-level debugging messages via MSM UART1"
+		depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
+		help
+		  Say Y here if you want the debug print routines to direct
+		  their output to the first serial port on MSM devices.
 
-	config MSM_DEBUG_UART_NONE
-		bool "None"
+	config DEBUG_MSM_UART2
+		bool "Kernel low-level debugging messages via MSM UART2"
+		depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
+		help
+		  Say Y here if you want the debug print routines to direct
+		  their output to the second serial port on MSM devices.
 
-	config MSM_DEBUG_UART1
-		bool "UART1"
+	config DEBUG_MSM_UART3
+		bool "Kernel low-level debugging messages via MSM UART3"
+		depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
+		help
+		  Say Y here if you want the debug print routines to direct
+		  their output to the third serial port on MSM devices.
 
-	config MSM_DEBUG_UART2
-		bool "UART2"
+	config DEBUG_MSM8660_UART
+		bool "Kernel low-level debugging messages via MSM 8660 UART"
+		depends on ARCH_MSM8X60
+		help
+		  Say Y here if you want the debug print routines to direct
+		  their output to the serial port on MSM 8660 devices.
 
-	config MSM_DEBUG_UART3
-		bool "UART3"
+	config DEBUG_MSM8960_UART
+		bool "Kernel low-level debugging messages via MSM 8960 UART"
+		depends on ARCH_MSM8960
+		select DEBUG_MSM8930_UART
+		help
+		  Say Y here if you want the debug print routines to direct
+		  their output to the serial port on MSM 8960 devices.
 endchoice
 
 choice
@@ -1518,7 +1542,7 @@
 
 config MSM_SUBSYSTEM_RESTART
 	bool "MSM Subsystem Restart Driver"
-	depends on (ARCH_MSM8X60 || ARCH_MSM8960)
+	depends on (ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_MSM9615)
 	default n
 	help
 	  This option enables the MSM subsystem restart driver, which provides
@@ -1535,19 +1559,19 @@
 
 config MSM_MODEM_8960
 	bool "MSM 8960 Modem driver"
-	depends on (ARCH_MSM8960)
+	depends on (ARCH_MSM8960 || ARCH_MSM9615)
 	help
-	 This option enables the modem driver for the MSM8960, which monitors
+	 This option enables the modem driver for the MSM8960 and MSM9615, which monitors
 	 modem hardware watchdog interrupt lines and plugs into the subsystem
-	 restart and PIL drivers.
+	 restart and PIL drivers. For MSM9615, it only supports a full chip reset.
 
 config MSM_LPASS_8960
 	tristate "MSM 8960 Lpass driver"
-	depends on (ARCH_MSM8960)
+	depends on (ARCH_MSM8960 || ARCH_MSM9615)
 	help
-	 This option enables the lpass driver for the MSM8960, which monitors
+	 This option enables the lpass driver for the MSM8960 and MSM9615. This monitors
 	 lpass hardware watchdog interrupt lines and plugs into the subsystem
-	 restart and PIL drivers.
+	 restart and PIL drivers. For MSM9615, it only supports a full chip reset.
 
 config MSM_WCNSS_SSR_8960
 	tristate "MSM 8960 WCNSS restart module"
diff --git a/arch/arm/mach-msm/acpuclock-7x30.c b/arch/arm/mach-msm/acpuclock-7x30.c
index 24c910e..7ee4e5b 100644
--- a/arch/arm/mach-msm/acpuclock-7x30.c
+++ b/arch/arm/mach-msm/acpuclock-7x30.c
@@ -231,8 +231,7 @@
 	 * increasing the ACPU frequency, since voting for high AXI rates
 	 * implicitly takes care of increasing the MSMC1 voltage, as needed. */
 	if (tgt_s->axi_clk_hz > strt_s->axi_clk_hz) {
-		rc = clk_set_min_rate(drv_state.ebi1_clk,
-					tgt_s->axi_clk_hz);
+		rc = clk_set_rate(drv_state.ebi1_clk, tgt_s->axi_clk_hz);
 		if (rc < 0) {
 			pr_err("Setting AXI min rate failed (%d)\n", rc);
 			goto out;
@@ -277,8 +276,7 @@
 
 	/* Decrease the AXI bus frequency if we can. */
 	if (tgt_s->axi_clk_hz < strt_s->axi_clk_hz) {
-		res = clk_set_min_rate(drv_state.ebi1_clk,
-					tgt_s->axi_clk_hz);
+		res = clk_set_rate(drv_state.ebi1_clk, tgt_s->axi_clk_hz);
 		if (res < 0)
 			pr_warning("Setting AXI min rate failed (%d)\n", res);
 	}
@@ -385,7 +383,7 @@
 	if (s->src >= 0)
 		clk_enable(acpuclk_sources[s->src]);
 
-	res = clk_set_min_rate(drv_state.ebi1_clk, s->axi_clk_hz);
+	res = clk_set_rate(drv_state.ebi1_clk, s->axi_clk_hz);
 	if (res < 0)
 		pr_warning("Setting AXI min rate failed!\n");
 
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index d82a6bf..cb0406f 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -523,12 +523,18 @@
 	int rc = 0;
 
 	DBG("%s: opening ch %d\n", __func__, id);
-	if (!bam_mux_initialized)
+	if (!bam_mux_initialized) {
+		DBG("%s: not inititialized\n", __func__);
 		return -ENODEV;
-	if (id >= BAM_DMUX_NUM_CHANNELS)
+	}
+	if (id >= BAM_DMUX_NUM_CHANNELS) {
+		pr_err("%s: invalid channel id %d\n", __func__, id);
 		return -EINVAL;
-	if (notify == NULL)
+	}
+	if (notify == NULL) {
+		pr_err("%s: notify function is NULL\n", __func__);
 		return -EINVAL;
+	}
 
 	hdr = kmalloc(sizeof(struct bam_mux_hdr), GFP_KERNEL);
 	if (hdr == NULL) {
@@ -546,8 +552,7 @@
 		DBG("%s: Remote not open; ch: %d\n", __func__, id);
 		spin_unlock_irqrestore(&bam_ch[id].lock, flags);
 		kfree(hdr);
-		rc = -ENODEV;
-		goto open_done;
+		return -ENODEV;
 	}
 
 	bam_ch[id].notify = notify;
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index 7ee30ef..d863b5d 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -301,7 +301,6 @@
 		 * This is a gpio-regulator and does not support
 		 * regulator_set_voltage and regulator_set_optimum_mode
 		 */
-		.set_voltage_sup = false,
 		.high_vol_level = 2950000,
 		.low_vol_level = 2950000,
 		.hpm_uA = 600000, /* 600mA */
@@ -313,7 +312,6 @@
 	/* SDCC1 : External card slot connected */
 	[SDCC1] = {
 		.name = "sdc_vddp",
-		.set_voltage_sup = true,
 		.high_vol_level = 2950000,
 		.low_vol_level = 1850000,
 		.always_on = true,
@@ -501,7 +499,6 @@
 	.sup_clk_table	= sdc1_sup_clk_rates,
 	.sup_clk_cnt	= ARRAY_SIZE(sdc1_sup_clk_rates),
 	.pclk_src_dfab	= true,
-	.sdcc_v4_sup    = true,
 	.vreg_data	= &mmc_slot_vreg_data[SDCC1],
 	.pin_data	= &mmc_slot_pin_data[SDCC1],
 #ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
@@ -529,7 +526,6 @@
 	.sup_clk_table	= sdc2_sup_clk_rates,
 	.sup_clk_cnt	= ARRAY_SIZE(sdc2_sup_clk_rates),
 	.pclk_src_dfab	= 1,
-	.sdcc_v4_sup    = true,
 	.pin_data	= &mmc_slot_pin_data[SDCC2],
 #ifdef CONFIG_MMC_MSM_SDIO_SUPPORT
 	.sdiowakeup_irq = MSM_GPIO_TO_INT(GPIO_SDC2_DAT1_WAKEUP),
@@ -701,7 +697,6 @@
 	pm8018_platform_data.num_regulators = msm_pm8018_regulator_pdata_len;
 
 	msm_device_otg.dev.platform_data = &msm_otg_pdata;
-	msm_device_gadget_peripheral.dev.parent = &msm_device_otg.dev;
 	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
 
 	msm_clock_init(&msm9615_clock_init_data);
diff --git a/arch/arm/mach-msm/board-apq8064.c b/arch/arm/mach-msm/board-apq8064.c
index 5ae388f..b131989 100644
--- a/arch/arm/mach-msm/board-apq8064.c
+++ b/arch/arm/mach-msm/board-apq8064.c
@@ -228,7 +228,6 @@
 	/* SDCC1 : eMMC card connected */
 	[SDCC1] = {
 		.name = "sdc_vdd",
-		.set_voltage_sup = 1,
 		.high_vol_level = 2950000,
 		.low_vol_level = 2950000,
 		.always_on = 1,
@@ -239,7 +238,6 @@
 	/* SDCC3 : External card slot connected */
 	[SDCC3] = {
 		.name = "sdc_vdd",
-		.set_voltage_sup = 1,
 		.high_vol_level = 2950000,
 		.low_vol_level = 2950000,
 		.hpm_uA = 600000, /* 600mA */
@@ -251,7 +249,6 @@
 	/* SDCC1 : eMMC card connected */
 	[SDCC1] = {
 		.name = "sdc_vccq",
-		.set_voltage_sup = 1,
 		.always_on = 1,
 		.high_vol_level = 1800000,
 		.low_vol_level = 1800000,
@@ -264,7 +261,6 @@
 	/* SDCC3 : External card slot connected */
 	[SDCC3] = {
 		.name = "sdc_vddp",
-		.set_voltage_sup = 1,
 		.high_vol_level = 2950000,
 		.low_vol_level = 1850000,
 		.always_on = 1,
@@ -405,7 +401,6 @@
 	.sup_clk_cnt	= ARRAY_SIZE(sdc1_sup_clk_rates),
 	.pin_data	= &mmc_slot_pin_data[SDCC1],
 	.vreg_data	= &mmc_slot_vreg_data[SDCC1],
-	.sdcc_v4_sup	= true,
 };
 static struct mmc_platform_data *apq8064_sdc1_pdata = &sdc1_data;
 #else
@@ -424,7 +419,6 @@
 	.sup_clk_cnt	= ARRAY_SIZE(sdc3_sup_clk_rates),
 	.pin_data	= &mmc_slot_pin_data[SDCC3],
 	.vreg_data	= &mmc_slot_vreg_data[SDCC3],
-	.sdcc_v4_sup	= true,
 };
 static struct mmc_platform_data *apq8064_sdc3_pdata = &sdc3_data;
 #else
@@ -760,7 +754,6 @@
 	apq8064_device_ssbi_pmic2.dev.platform_data =
 				&apq8064_ssbi_pm8821_pdata;
 	apq8064_device_otg.dev.platform_data = &msm_otg_pdata;
-	apq8064_device_gadget_peripheral.dev.parent = &apq8064_device_otg.dev;
 	apq8064_pm8921_platform_data.num_regulators =
 					msm8064_pm8921_regulator_pdata_len;
 	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-msm8960.c
index cf74c66..ab45aca 100644
--- a/arch/arm/mach-msm/board-msm8960.c
+++ b/arch/arm/mach-msm/board-msm8960.c
@@ -2840,7 +2840,6 @@
 	/* SDCC1 : eMMC card connected */
 	[SDCC1] = {
 		.name = "sdc_vdd",
-		.set_voltage_sup = 1,
 		.high_vol_level = 2950000,
 		.low_vol_level = 2950000,
 		.always_on = 1,
@@ -2851,7 +2850,6 @@
 	/* SDCC3 : External card slot connected */
 	[SDCC3] = {
 		.name = "sdc_vdd",
-		.set_voltage_sup = 1,
 		.high_vol_level = 2950000,
 		.low_vol_level = 2950000,
 		.hpm_uA = 600000, /* 600mA */
@@ -2863,7 +2861,6 @@
 	/* SDCC1 : eMMC card connected */
 	[SDCC1] = {
 		.name = "sdc_vccq",
-		.set_voltage_sup = 1,
 		.always_on = 1,
 		.high_vol_level = 1800000,
 		.low_vol_level = 1800000,
@@ -2876,7 +2873,6 @@
 	/* SDCC3 : External card slot connected */
 	[SDCC3] = {
 		.name = "sdc_vddp",
-		.set_voltage_sup = 1,
 		.high_vol_level = 2950000,
 		.low_vol_level = 1850000,
 		.always_on = 1,
@@ -3031,7 +3027,6 @@
 	.sup_clk_cnt	= ARRAY_SIZE(sdc1_sup_clk_rates),
 	.pclk_src_dfab	= 1,
 	.nonremovable	= 1,
-	.sdcc_v4_sup	= true,
 	.vreg_data	= &mmc_slot_vreg_data[SDCC1],
 	.pin_data	= &mmc_slot_pin_data[SDCC1]
 };
@@ -3047,7 +3042,6 @@
 #ifdef CONFIG_MMC_MSM_SDC3_WP_SUPPORT
 	.wpswitch_gpio	= PM8921_GPIO_PM_TO_SYS(16),
 #endif
-	.sdcc_v4_sup	= true,
 	.vreg_data	= &mmc_slot_vreg_data[SDCC3],
 	.pin_data	= &mmc_slot_pin_data[SDCC3],
 #ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
@@ -4739,8 +4733,6 @@
 	pm8921_platform_data.keypad_pdata = &keypad_data_sim;
 
 	msm8960_device_otg.dev.platform_data = &msm_otg_pdata;
-	msm8960_device_gadget_peripheral.dev.parent = &msm8960_device_otg.dev;
-	msm_device_hsusb_host.dev.parent = &msm8960_device_otg.dev;
 	gpiomux_init();
 	msm8960_i2c_init();
 	msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
@@ -4817,8 +4809,6 @@
 	if (machine_is_msm8960_liquid())
 		msm_otg_pdata.mhl_enable = true;
 	msm8960_device_otg.dev.platform_data = &msm_otg_pdata;
-	msm8960_device_gadget_peripheral.dev.parent = &msm8960_device_otg.dev;
-	msm_device_hsusb_host.dev.parent = &msm8960_device_otg.dev;
 #ifdef CONFIG_USB_EHCI_MSM_HSIC
 	if (machine_is_msm8960_liquid()) {
 		if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 2)
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index b217b41..b394710 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -993,6 +993,7 @@
 static struct regulator *ldo7_1p8;
 static struct regulator *vdd_cx;
 #define PMICID_INT		PM8058_GPIO_IRQ(PM8058_IRQ_BASE, 36)
+#define PMIC_ID_GPIO		36
 notify_vbus_state notify_vbus_state_func_ptr;
 static int usb_phy_susp_dig_vol = 750000;
 static int pmic_id_notif_supported;
@@ -1031,10 +1032,42 @@
 	return IRQ_HANDLED;
 }
 
+static int msm_hsusb_phy_id_setup_init(int init)
+{
+	unsigned ret;
+
+	if (init) {
+		ret = pm8901_mpp_config_digital_out(1,
+			PM8901_MPP_DIG_LEVEL_L5, 1);
+		if (ret < 0)
+			pr_err("%s:MPP2 configuration failed\n", __func__);
+	} else {
+		ret = pm8901_mpp_config_digital_out(1,
+			PM8901_MPP_DIG_LEVEL_L5, 0);
+		if (ret < 0)
+			pr_err("%s:MPP2 un config failed\n", __func__);
+	}
+	return ret;
+}
+
 static int msm_hsusb_pmic_id_notif_init(void (*callback)(int online), int init)
 {
 	unsigned ret = -ENODEV;
 
+	struct pm8058_gpio pmic_id_cfg = {
+		.direction	= PM_GPIO_DIR_IN,
+		.pull		= PM_GPIO_PULL_UP_1P5,
+		.function	= PM_GPIO_FUNC_NORMAL,
+		.vin_sel	= 2,
+		.inv_int_pol	= 0,
+	};
+	struct pm8058_gpio pmic_id_uncfg = {
+		.direction	= PM_GPIO_DIR_IN,
+		.pull		= PM_GPIO_PULL_NO,
+		.function	= PM_GPIO_FUNC_NORMAL,
+		.vin_sel	= 2,
+		.inv_int_pol	= 0,
+	};
 	if (!callback)
 		return -EINVAL;
 
@@ -1058,37 +1091,34 @@
 
 	if (init) {
 		notify_vbus_state_func_ptr = callback;
-		ret = pm8901_mpp_config_digital_out(1,
-			PM8901_MPP_DIG_LEVEL_L5, 1);
-		if (ret) {
-			pr_err("%s: MPP2 configuration failed\n", __func__);
-			return -ENODEV;
-		}
 		INIT_DELAYED_WORK(&pmic_id_det, pmic_id_detect);
+		ret = pm8058_gpio_config(PMIC_ID_GPIO, &pmic_id_cfg);
+		if (ret) {
+			pr_err("%s:return val of pm8058_gpio_config: %d\n",
+						__func__,  ret);
+			return ret;
+		}
 		ret = request_threaded_irq(PMICID_INT, NULL, pmic_id_on_irq,
 			(IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING),
 						"msm_otg_id", NULL);
 		if (ret) {
-			pm8901_mpp_config_digital_out(1,
-					PM8901_MPP_DIG_LEVEL_L5, 0);
 			pr_err("%s:pmic_usb_id interrupt registration failed",
 					__func__);
 			return ret;
 		}
-		/* Notify the initial Id status */
-		pmic_id_detect(&pmic_id_det.work);
 		msm_otg_pdata.pmic_id_irq = PMICID_INT;
 	} else {
+		usb_phy_susp_dig_vol = 750000;
 		free_irq(PMICID_INT, 0);
+		ret = pm8058_gpio_config(PMIC_ID_GPIO, &pmic_id_uncfg);
+		if (ret) {
+			pr_err("%s: return val of pm8058_gpio_config: %d\n",
+						__func__,  ret);
+			return ret;
+		}
 		msm_otg_pdata.pmic_id_irq = 0;
 		cancel_delayed_work_sync(&pmic_id_det);
 		notify_vbus_state_func_ptr = NULL;
-		ret = pm8901_mpp_config_digital_out(1,
-			PM8901_MPP_DIG_LEVEL_L5, 0);
-		if (ret) {
-			pr_err("%s:MPP2 configuration failed\n", __func__);
-			return -ENODEV;
-		}
 	}
 	return 0;
 }
@@ -1393,6 +1423,7 @@
 	.bam_disable		 = 1,
 #ifdef CONFIG_USB_EHCI_MSM_72K
 	.pmic_id_notif_init = msm_hsusb_pmic_id_notif_init,
+	.phy_id_setup_init = msm_hsusb_phy_id_setup_init,
 #endif
 #ifdef CONFIG_USB_EHCI_MSM_72K
 	.vbus_power = msm_hsusb_vbus_power,
@@ -5429,7 +5460,7 @@
 			36,
 			{
 				.direction	= PM_GPIO_DIR_IN,
-				.pull		= PM_GPIO_PULL_UP_1P5,
+				.pull		= PM_GPIO_PULL_NO,
 				.function	= PM_GPIO_FUNC_NORMAL,
 				.vin_sel	= 2,
 				.inv_int_pol	= 0,
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index dbceae8..95b69e6 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -51,6 +51,7 @@
 #include "devices-msm7x2xa.h"
 #include "pm.h"
 #include "timer.h"
+#include "pm-boot.h"
 
 #define PMEM_KERNEL_EBI1_SIZE	0x3A000
 #define MSM_PMEM_AUDIO_SIZE	0x5B000
@@ -2531,6 +2532,9 @@
 #endif
 	msm_pm_set_platform_data(msm7627a_pm_data,
 				ARRAY_SIZE(msm7627a_pm_data));
+	BUG_ON(msm_pm_boot_init(MSM_PM_BOOT_CONFIG_RESET_VECTOR,
+				ioremap(0, PAGE_SIZE)));
+
 	msm_fb_add_devices();
 
 #if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index 8ff9725..cd028e4 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -1277,6 +1277,7 @@
 static DEFINE_CLK_VOTER(dfab_sdc1_clk, &dfab_clk.c);
 static DEFINE_CLK_VOTER(dfab_sdc2_clk, &dfab_clk.c);
 static DEFINE_CLK_VOTER(dfab_sps_clk, &dfab_clk.c);
+static DEFINE_CLK_VOTER(dfab_bam_dmux_clk, &dfab_clk.c);
 static DEFINE_CLK_VOTER(ebi1_msmbus_clk, &ebi1_clk.c);
 
 /*
@@ -1585,7 +1586,7 @@
 	CLK_LOOKUP("bus_clk",		dfab_sdc1_clk.c,	"msm_sdcc.1"),
 	CLK_LOOKUP("bus_clk",		dfab_sdc2_clk.c,	"msm_sdcc.2"),
 	CLK_LOOKUP("dfab_clk",		dfab_sps_clk.c,		"msm_sps"),
-
+	CLK_LOOKUP("bus_clk",		dfab_bam_dmux_clk.c,	"BAM_RMNT"),
 	CLK_LOOKUP("ebi1_msmbus_clk",	ebi1_msmbus_clk.c, NULL),
 	CLK_LOOKUP("mem_clk",		ebi1_adm_clk.c, "msm_dmov"),
 
diff --git a/arch/arm/mach-msm/include/mach/debug-macro.S b/arch/arm/mach-msm/include/mach/debug-macro.S
index 905a254..5112888 100644
--- a/arch/arm/mach-msm/include/mach/debug-macro.S
+++ b/arch/arm/mach-msm/include/mach/debug-macro.S
@@ -1,4 +1,4 @@
-/* arch/arm/mach-msm7200/include/mach/debug-macro.S
+/*
  *
  * Copyright (C) 2007 Google, Inc.
  * Author: Brian Swetland <swetland@google.com>
@@ -19,7 +19,7 @@
 #include <mach/hardware.h>
 #include <mach/msm_iomap.h>
 
-#ifdef CONFIG_MSM_DEBUG_UART
+#ifdef MSM_DEBUG_UART_PHYS
        .macro  addruart, rp, rv
 	ldr     \rp, =MSM_DEBUG_UART_PHYS
 	ldr     \rv, =MSM_DEBUG_UART_BASE
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h
index 5cd7013..d5a2ed4 100644
--- a/arch/arm/mach-msm/include/mach/iommu.h
+++ b/arch/arm/mach-msm/include/mach/iommu.h
@@ -17,15 +17,7 @@
 #include <linux/clk.h>
 #include <mach/socinfo.h>
 
-/* Sharability attributes of MSM IOMMU mappings */
-#define MSM_IOMMU_ATTR_NON_SH		0x0
-#define MSM_IOMMU_ATTR_SH		0x4
-
-/* Cacheability attributes of MSM IOMMU mappings */
-#define MSM_IOMMU_ATTR_NONCACHED	0x0
-#define MSM_IOMMU_ATTR_CACHED_WB_WA	0x1
-#define MSM_IOMMU_ATTR_CACHED_WB_NWA	0x2
-#define MSM_IOMMU_ATTR_CACHED_WT	0x3
+extern pgprot_t     pgprot_kernel;
 
 /* Domain attributes */
 #define MSM_IOMMU_DOMAIN_PT_CACHEABLE	0x1
diff --git a/arch/arm/mach-msm/include/mach/irqs-9615.h b/arch/arm/mach-msm/include/mach/irqs-9615.h
index 8b62632..74e5847 100644
--- a/arch/arm/mach-msm/include/mach/irqs-9615.h
+++ b/arch/arm/mach-msm/include/mach/irqs-9615.h
@@ -71,8 +71,8 @@
 #define MSMC_SC_PRI_CE_IRQ			(GIC_SPI_START + 32)
 #define SLIMBUS0_CORE_EE1_IRQ			(GIC_SPI_START + 33)
 #define SLIMBUS0_BAM_EE1_IRQ			(GIC_SPI_START + 34)
-#define Q6FW_WDOG_EXPIRED			(GIC_SPI_START + 35)
-#define Q6SW_WDOG_EXPIRED			(GIC_SPI_START + 36)
+#define Q6FW_WDOG_EXPIRED_IRQ			(GIC_SPI_START + 35)
+#define Q6SW_WDOG_EXPIRED_IRQ			(GIC_SPI_START + 36)
 #define MSS_TO_APPS_IRQ_0			(GIC_SPI_START + 37)
 #define MSS_TO_APPS_IRQ_1			(GIC_SPI_START + 38)
 #define MSS_TO_APPS_IRQ_2			(GIC_SPI_START + 39)
diff --git a/arch/arm/mach-msm/include/mach/msm72k_otg.h b/arch/arm/mach-msm/include/mach/msm72k_otg.h
index 43f487a..4509dad 100644
--- a/arch/arm/mach-msm/include/mach/msm72k_otg.h
+++ b/arch/arm/mach-msm/include/mach/msm72k_otg.h
@@ -25,6 +25,7 @@
 
 #define OTGSC_BSVIE            (1 << 27)
 #define OTGSC_IDIE             (1 << 24)
+#define OTGSC_IDPU             (1 << 5)
 #define OTGSC_BSVIS            (1 << 19)
 #define OTGSC_ID               (1 << 8)
 #define OTGSC_IDIS             (1 << 16)
@@ -148,7 +149,6 @@
 	struct wake_lock wlock;
 	unsigned long b_last_se0_sess; /* SRP initial condition check */
 	unsigned long inputs;
-	int pmic_id_status;
 	unsigned long tmouts;
 	u8 active_tmout;
 	struct hrtimer timer;
diff --git a/arch/arm/mach-msm/include/mach/msm_hsusb.h b/arch/arm/mach-msm/include/mach/msm_hsusb.h
index 26f1cdd..3e8ab55 100644
--- a/arch/arm/mach-msm/include/mach/msm_hsusb.h
+++ b/arch/arm/mach-msm/include/mach/msm_hsusb.h
@@ -158,6 +158,7 @@
 	/* pmic notfications apis */
 	int (*pmic_vbus_notif_init) (void (*callback)(int online), int init);
 	int (*pmic_id_notif_init) (void (*callback)(int online), int init);
+	int (*phy_id_setup_init) (int init);
 	int (*pmic_register_vbus_sn) (void (*callback)(int online));
 	void (*pmic_unregister_vbus_sn) (void (*callback)(int online));
 	int (*pmic_enable_ldo) (int);
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h
index d1aef0a..333df32 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h
@@ -83,18 +83,6 @@
 #define MSM_UART3_PHYS        0xA9C00000
 #define MSM_UART3_SIZE        SZ_4K
 
-#ifdef CONFIG_MSM_DEBUG_UART
-#define MSM_DEBUG_UART_BASE   0xF9000000
-#if CONFIG_MSM_DEBUG_UART == 1
-#define MSM_DEBUG_UART_PHYS   MSM_UART1_PHYS
-#elif CONFIG_MSM_DEBUG_UART == 2
-#define MSM_DEBUG_UART_PHYS   MSM_UART2_PHYS
-#elif CONFIG_MSM_DEBUG_UART == 3
-#define MSM_DEBUG_UART_PHYS   MSM_UART3_PHYS
-#endif
-#define MSM_DEBUG_UART_SIZE   SZ_4K
-#endif
-
 #define MSM_SDC1_PHYS         0xA0400000
 #define MSM_SDC1_SIZE         SZ_4K
 
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
index e49e870..acd668b 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
@@ -91,18 +91,6 @@
 #define MSM_UART3_PHYS        0xACC00000
 #define MSM_UART3_SIZE        SZ_4K
 
-#ifdef CONFIG_MSM_DEBUG_UART
-#define MSM_DEBUG_UART_BASE   0xFB000000
-#if CONFIG_MSM_DEBUG_UART == 1
-#define MSM_DEBUG_UART_PHYS   MSM_UART1_PHYS
-#elif CONFIG_MSM_DEBUG_UART == 2
-#define MSM_DEBUG_UART_PHYS   MSM_UART2_PHYS
-#elif CONFIG_MSM_DEBUG_UART == 3
-#define MSM_DEBUG_UART_PHYS   MSM_UART3_PHYS
-#endif
-#define MSM_DEBUG_UART_SIZE   SZ_4K
-#endif
-
 #define MSM_MDC_BASE	      IOMEM(0xFA200000)
 #define MSM_MDC_PHYS	      0xAA500000
 #define MSM_MDC_SIZE	      SZ_1M
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h b/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h
index d7dc4f4..d545a5f 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h
@@ -79,18 +79,6 @@
 #define MSM_UART3_PHYS        0xA9C00000
 #define MSM_UART3_SIZE        SZ_4K
 
-#ifdef CONFIG_MSM_DEBUG_UART
-#define MSM_DEBUG_UART_BASE   0xFB000000
-#if CONFIG_MSM_DEBUG_UART == 1
-#define MSM_DEBUG_UART_PHYS   MSM_UART1_PHYS
-#elif CONFIG_MSM_DEBUG_UART == 2
-#define MSM_DEBUG_UART_PHYS   MSM_UART2_PHYS
-#elif CONFIG_MSM_DEBUG_UART == 3
-#define MSM_DEBUG_UART_PHYS   MSM_UART3_PHYS
-#endif
-#define MSM_DEBUG_UART_SIZE   SZ_4K
-#endif
-
 #define MSM_MDC_BASE	      IOMEM(0xFA200000)
 #define MSM_MDC_PHYS	      0xAA500000
 #define MSM_MDC_SIZE	      SZ_1M
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8930.h b/arch/arm/mach-msm/include/mach/msm_iomap-8930.h
index 8e50824..f3f8b8f 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8930.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8930.h
@@ -101,14 +101,10 @@
 #define MSM8930_HDMI_PHYS		0x04A00000
 #define MSM8930_HDMI_SIZE		SZ_4K
 
-#ifdef CONFIG_MSM_DEBUG_UART
+#ifdef CONFIG_DEBUG_MSM8930_UART
 #define MSM_DEBUG_UART_BASE		IOMEM(0xFA740000)
-#define MSM_DEBUG_UART_SIZE		SZ_4K
-
-#ifdef CONFIG_MSM_DEBUG_UART1
 #define MSM_DEBUG_UART_PHYS		0x16440000
 #endif
-#endif
 
 #define MSM8930_QFPROM_PHYS		0x00700000
 #define MSM8930_QFPROM_SIZE		SZ_4K
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8960.h b/arch/arm/mach-msm/include/mach/msm_iomap-8960.h
index 24505ae..b70cacc 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8960.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8960.h
@@ -98,14 +98,10 @@
 #define MSM8960_HDMI_PHYS		0x04A00000
 #define MSM8960_HDMI_SIZE		SZ_4K
 
-#ifdef CONFIG_MSM_DEBUG_UART
+#ifdef CONFIG_DEBUG_MSM8960_UART
 #define MSM_DEBUG_UART_BASE		IOMEM(0xFA740000)
-#define MSM_DEBUG_UART_SIZE		SZ_4K
-
-#ifdef CONFIG_MSM_DEBUG_UART1
 #define MSM_DEBUG_UART_PHYS		0x16440000
 #endif
-#endif
 
 #define MSM8960_QFPROM_PHYS		0x00700000
 #define MSM8960_QFPROM_SIZE		SZ_4K
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
index a073d6a..a1b32ec 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
@@ -83,18 +83,6 @@
 #define MSM_UART3_PHYS        0xA9C00000
 #define MSM_UART3_SIZE        SZ_4K
 
-#ifdef CONFIG_MSM_DEBUG_UART
-#define MSM_DEBUG_UART_BASE   0xFB000000
-#if CONFIG_MSM_DEBUG_UART == 1
-#define MSM_DEBUG_UART_PHYS   MSM_UART1_PHYS
-#elif CONFIG_MSM_DEBUG_UART == 2
-#define MSM_DEBUG_UART_PHYS   MSM_UART2_PHYS
-#elif CONFIG_MSM_DEBUG_UART == 3
-#define MSM_DEBUG_UART_PHYS   MSM_UART3_PHYS
-#endif
-#define MSM_DEBUG_UART_SIZE   SZ_4K
-#endif
-
 #define MSM_MDC_BASE	      IOMEM(0xFA200000)
 #define MSM_MDC_PHYS	      0xAA500000
 #define MSM_MDC_SIZE	      SZ_1M
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
index c1cf221..723f3d8 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
@@ -126,11 +126,9 @@
 #define MSM_HDMI_PHYS		0x04A00000
 #define MSM_HDMI_SIZE		SZ_4K
 
-#ifdef CONFIG_MSM_DEBUG_UART
-
+#ifdef CONFIG_DEBUG_MSM8660_UART
 #define MSM_DEBUG_UART_BASE	0xFBC40000
 #define MSM_DEBUG_UART_PHYS	0x19C40000
-#define MSM_DEBUG_UART_SIZE	SZ_4K
-
 #endif
+
 #endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-fsm9xxx.h b/arch/arm/mach-msm/include/mach/msm_iomap-fsm9xxx.h
index 57bfd58..c30c9e4 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-fsm9xxx.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-fsm9xxx.h
@@ -81,14 +81,4 @@
 #define MSM_UART2_PHYS        0x94100000
 #define MSM_UART2_SIZE        SZ_4K
 
-#ifdef CONFIG_MSM_DEBUG_UART
-#define MSM_DEBUG_UART_BASE   0xFB000000
-#if CONFIG_MSM_DEBUG_UART == 1
-#define MSM_DEBUG_UART_PHYS   MSM_UART1_PHYS
-#elif CONFIG_MSM_DEBUG_UART == 2
-#define MSM_DEBUG_UART_PHYS   MSM_UART2_PHYS
-#endif
-#define MSM_DEBUG_UART_SIZE   SZ_4K
-#endif
-
 #endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index 256099b..dd01c62 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -43,6 +43,8 @@
 #define IOMEM(x)	((void __force __iomem *)(x))
 #endif
 
+#define MSM_DEBUG_UART_SIZE	SZ_4K
+
 #if defined(CONFIG_ARCH_MSM8960) || defined(CONFIG_ARCH_APQ8064) || \
 	defined(CONFIG_ARCH_MSM8930) || defined(CONFIG_ARCH_MSM9615) || \
 	defined(CONFIG_ARCH_MSMCOPPER)
@@ -103,6 +105,17 @@
 #include "msm_iomap-7xxx.h"
 #endif
 
+#if defined(CONFIG_DEBUG_MSM_UART1)
+#define MSM_DEBUG_UART_BASE	0xFB000000
+#define MSM_DEBUG_UART_PHYS	MSM_UART1_PHYS
+#elif defined(CONFIG_DEBUG_MSM_UART2)
+#define MSM_DEBUG_UART_BASE	0xFB000000
+#define MSM_DEBUG_UART_PHYS	MSM_UART2_PHYS
+#elif defined(CONFIG_DEBUG_MSM_UART3)
+#define MSM_DEBUG_UART_BASE	0xFB000000
+#define MSM_DEBUG_UART_PHYS	MSM_UART3_PHYS
+#endif
+
 #endif
 
 #endif
diff --git a/arch/arm/mach-msm/include/mach/sps.h b/arch/arm/mach-msm/include/mach/sps.h
index 1514497..34729b3 100644
--- a/arch/arm/mach-msm/include/mach/sps.h
+++ b/arch/arm/mach-msm/include/mach/sps.h
@@ -1135,4 +1135,36 @@
 		   struct sps_timer_ctrl *timer_ctrl,
 		   struct sps_timer_result *timer_result);
 
+/**
+ * Find the handle of a BAM device based on the physical address
+ *
+ * This function finds a BAM device in the BAM registration list that
+ * matches the specified physical address, and returns its handle.
+ *
+ * @phys_addr - physical address of the BAM
+ *
+ * @h - device handle of the BAM
+ *
+ * @return 0 on success, negative value on error
+ *
+ */
+int sps_phy2h(u32 phys_addr, u32 *handle);
+
+/**
+ * Setup desc/data FIFO for bam-to-bam connection
+ *
+ * @mem_buffer - Pointer to struct for allocated memory properties.
+ *
+ * @addr - address of FIFO
+ *
+ * @size - FIFO size
+ *
+ * @use_offset - use address offset instead of absolute address
+ *
+ * @return 0 on success, negative value on error
+ *
+ */
+int sps_setup_bam2bam_fifo(struct sps_mem_buffer *mem_buffer,
+		  u32 addr, u32 size, int use_offset);
+
 #endif /* _SPS_H_ */
diff --git a/arch/arm/mach-msm/include/mach/uncompress.h b/arch/arm/mach-msm/include/mach/uncompress.h
index c8513b2..74cbda1 100644
--- a/arch/arm/mach-msm/include/mach/uncompress.h
+++ b/arch/arm/mach-msm/include/mach/uncompress.h
@@ -22,33 +22,30 @@
 
 #include <mach/msm_iomap.h>
 
-bool msm_serial_hsl;
-
 #ifndef CONFIG_DEBUG_ICEDCC
 static void putc(int c)
 {
 #if defined(MSM_DEBUG_UART_PHYS)
 	unsigned long base = MSM_DEBUG_UART_PHYS;
 
-	if (msm_serial_hsl) {
-		/*
-		 * Wait for TX_READY to be set; but skip it if we have a
-		 * TX underrun.
-		 */
-		if (__raw_readl(base + 0x08) & 0x08)
-			while (!(__raw_readl(base + 0x14) & 0x80))
-				cpu_relax();
-
-		__raw_writel(0x300, base + 0x10);
-		__raw_writel(0x1, base + 0x40);
-		__raw_writel(c, base + 0x70);
-
-	} else {
-		/* Wait for TX_READY to be set */
-		while (!(__raw_readl(base + 0x08) & 0x04))
+#ifdef CONFIG_SERIAL_MSM_HSL
+	/*
+	 * Wait for TX_READY to be set; but skip it if we have a
+	 * TX underrun.
+	 */
+	if (__raw_readl(base + 0x08) & 0x08)
+		while (!(__raw_readl(base + 0x14) & 0x80))
 			cpu_relax();
-		__raw_writel(c, base + 0x0c);
-	}
+
+	__raw_writel(0x300, base + 0x10);
+	__raw_writel(0x1, base + 0x40);
+	__raw_writel(c, base + 0x70);
+#else
+	/* Wait for TX_READY to be set */
+	while (!(__raw_readl(base + 0x08) & 0x04))
+		cpu_relax();
+	__raw_writel(c, base + 0x0c);
+#endif
 #endif
 }
 #endif
@@ -57,28 +54,8 @@
 {
 }
 
-#define DEBUG_LL_HS_ENTRY(machine)		\
-	if (machine_is_##machine()) {		\
-		msm_serial_hsl = true;		\
-		break;				\
-	}
-
 static inline void arch_decomp_setup(void)
 {
-	do {
-		DEBUG_LL_HS_ENTRY(msm8x60_fluid);
-		DEBUG_LL_HS_ENTRY(msm8x60_surf);
-		DEBUG_LL_HS_ENTRY(msm8x60_ffa);
-		DEBUG_LL_HS_ENTRY(msm8x60_fusion);
-		DEBUG_LL_HS_ENTRY(msm8x60_fusn_ffa);
-		DEBUG_LL_HS_ENTRY(msm8x60_qrdc);
-		DEBUG_LL_HS_ENTRY(msm8x60_qt);
-		DEBUG_LL_HS_ENTRY(msm8960_cdp);
-		DEBUG_LL_HS_ENTRY(msm8960_mtp);
-		DEBUG_LL_HS_ENTRY(msm8960_fluid);
-		DEBUG_LL_HS_ENTRY(msm8960_apq);
-		DEBUG_LL_HS_ENTRY(msm8960_liquid);
-	} while (0);
 }
 
 static inline void arch_decomp_wdog(void)
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 65f5da0..8a79af7 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -66,7 +66,8 @@
 	MSM_DEVICE(CLK_CTL),
 	MSM_DEVICE(AD5),
 	MSM_DEVICE(MDC),
-#ifdef CONFIG_MSM_DEBUG_UART
+#if defined(CONFIG_DEBUG_MSM_UART1) || defined(CONFIG_DEBUG_MSM_UART2) || \
+	defined(CONFIG_DEBUG_MSM_UART3)
 	MSM_DEVICE(DEBUG_UART),
 #endif
 #ifdef CONFIG_CACHE_L2X0
@@ -113,7 +114,8 @@
 	MSM_DEVICE(AD5),
 	MSM_DEVICE(MDC),
 	MSM_DEVICE(TCSR),
-#ifdef CONFIG_MSM_DEBUG_UART
+#if defined(CONFIG_DEBUG_MSM_UART1) || defined(CONFIG_DEBUG_MSM_UART2) || \
+	defined(CONFIG_DEBUG_MSM_UART3)
 	MSM_DEVICE(DEBUG_UART),
 #endif
 	{
@@ -151,7 +153,7 @@
 	MSM_DEVICE(TCSR),
 	MSM_DEVICE(IMEM),
 	MSM_DEVICE(HDMI),
-#ifdef CONFIG_MSM_DEBUG_UART
+#ifdef CONFIG_DEBUG_MSM8660_UART
 	MSM_DEVICE(DEBUG_UART),
 #endif
 	MSM_DEVICE(SIC_NON_SECURE),
@@ -196,7 +198,7 @@
 		.length =   MSM_SHARED_RAM_SIZE,
 		.type =     MT_DEVICE,
 	},
-#ifdef CONFIG_MSM_DEBUG_UART
+#ifdef CONFIG_DEBUG_MSM8960_UART
 	MSM_DEVICE(DEBUG_UART),
 #endif
 	MSM_CHIP_DEVICE(QFPROM, MSM8960),
@@ -235,7 +237,7 @@
 		.length =   MSM_SHARED_RAM_SIZE,
 		.type =     MT_DEVICE,
 	},
-#ifdef CONFIG_MSM_DEBUG_UART
+#ifdef CONFIG_DEBUG_MSM8930_UART
 	MSM_DEVICE(DEBUG_UART),
 #endif
 	MSM_CHIP_DEVICE(QFPROM, MSM8930),
@@ -307,7 +309,8 @@
 	MSM_DEVICE(SAW),
 	MSM_DEVICE(GCC),
 	MSM_DEVICE(TCSR),
-#ifdef CONFIG_MSM_DEBUG_UART
+#if defined(CONFIG_DEBUG_MSM_UART1) || defined(CONFIG_DEBUG_MSM_UART2) || \
+	defined(CONFIG_DEBUG_MSM_UART3)
 	MSM_DEVICE(DEBUG_UART),
 #endif
 	{
@@ -337,7 +340,8 @@
 	MSM_DEVICE(GRFC),
 	MSM_DEVICE(QFP_FUSE),
 	MSM_DEVICE(HH),
-#ifdef CONFIG_MSM_DEBUG_UART
+#if defined(CONFIG_DEBUG_MSM_UART1) || defined(CONFIG_DEBUG_MSM_UART2) || \
+	defined(CONFIG_DEBUG_MSM_UART3)
 	MSM_DEVICE(DEBUG_UART),
 #endif
 	{
diff --git a/arch/arm/mach-msm/iommu.c b/arch/arm/mach-msm/iommu.c
index e874663..16c0790 100644
--- a/arch/arm/mach-msm/iommu.c
+++ b/arch/arm/mach-msm/iommu.c
@@ -38,6 +38,17 @@
 #define RCP15_PRRR(reg)		MRC(reg, p15, 0, c10, c2, 0)
 #define RCP15_NMRR(reg)		MRC(reg, p15, 0, c10, c2, 1)
 
+/* Sharability attributes of MSM IOMMU mappings */
+#define MSM_IOMMU_ATTR_NON_SH		0x0
+#define MSM_IOMMU_ATTR_SH		0x4
+
+/* Cacheability attributes of MSM IOMMU mappings */
+#define MSM_IOMMU_ATTR_NONCACHED	0x0
+#define MSM_IOMMU_ATTR_CACHED_WB_WA	0x1
+#define MSM_IOMMU_ATTR_CACHED_WB_NWA	0x2
+#define MSM_IOMMU_ATTR_CACHED_WT	0x3
+
+
 static inline void clean_pte(unsigned long *start, unsigned long *end)
 {
 	dmac_flush_range(start, end);
@@ -407,21 +418,23 @@
 static int __get_pgprot(int prot, int len)
 {
 	unsigned int pgprot;
-	int tex, sh;
+	int tex;
 
-	sh = (prot & MSM_IOMMU_ATTR_SH) ? 1 : 0;
-	tex = msm_iommu_tex_class[prot & MSM_IOMMU_CP_MASK];
+	if (prot & IOMMU_CACHE)
+		tex = (pgprot_kernel >> 2) & 0x07;
+	else
+		tex = msm_iommu_tex_class[MSM_IOMMU_ATTR_NONCACHED];
 
 	if (tex < 0 || tex > NUM_TEX_CLASS - 1)
 		return 0;
 
 	if (len == SZ_16M || len == SZ_1M) {
-		pgprot = sh ? FL_SHARED : 0;
+		pgprot = FL_SHARED;
 		pgprot |= tex & 0x01 ? FL_BUFFERABLE : 0;
 		pgprot |= tex & 0x02 ? FL_CACHEABLE : 0;
 		pgprot |= tex & 0x04 ? FL_TEX0 : 0;
 	} else	{
-		pgprot = sh ? SL_SHARED : 0;
+		pgprot = SL_SHARED;
 		pgprot |= tex & 0x01 ? SL_BUFFERABLE : 0;
 		pgprot |= tex & 0x02 ? SL_CACHEABLE : 0;
 		pgprot |= tex & 0x04 ? SL_TEX0 : 0;
diff --git a/arch/arm/mach-msm/lpass-8960.c b/arch/arm/mach-msm/lpass-8960.c
index 0f2559e..294e9c0 100644
--- a/arch/arm/mach-msm/lpass-8960.c
+++ b/arch/arm/mach-msm/lpass-8960.c
@@ -178,7 +178,7 @@
 		ret = -ENOMEM;
 		goto out;
 	}
-	pr_info("%s: 8960 lpass SSR driver init'ed.\n", __func__);
+	pr_info("%s: lpass SSR driver init'ed.\n", __func__);
 out:
 	return ret;
 }
diff --git a/arch/arm/mach-msm/modem-8960.c b/arch/arm/mach-msm/modem-8960.c
index 7bcd844..f0aa13c 100644
--- a/arch/arm/mach-msm/modem-8960.c
+++ b/arch/arm/mach-msm/modem-8960.c
@@ -26,7 +26,6 @@
 #include <mach/peripheral-loader.h>
 #include <mach/subsystem_restart.h>
 #include <mach/subsystem_notif.h>
-#include <mach/irqs-8960.h>
 #include <mach/socinfo.h>
 
 #include "smd_private.h"
@@ -227,7 +226,7 @@
 {
 	int ret;
 
-	if (!cpu_is_msm8960() && !cpu_is_msm8930())
+	if (!cpu_is_msm8960() && !cpu_is_msm8930() && !cpu_is_msm9615())
 		return -ENODEV;
 
 	ret = smsm_state_cb_register(SMSM_MODEM_STATE, SMSM_RESET,
@@ -266,7 +265,7 @@
 
 	ret = modem_debugfs_init();
 
-	pr_info("%s: 8960 modem fatal driver init'ed.\n", __func__);
+	pr_info("%s: modem fatal driver init'ed.\n", __func__);
 out:
 	return ret;
 }
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
index 1747425..fd82111 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
@@ -17,7 +17,6 @@
 #include <linux/module.h>
 #include <linux/clk.h>
 #include <linux/radix-tree.h>
-#include <mach/clk.h>
 #include <mach/board.h>
 #include <mach/rpm.h>
 #include "msm_bus_core.h"
@@ -344,7 +343,7 @@
 	int i, status = 0;
 	for (i = 0; i < NUM_CTX; i++)
 		if (info->nodeclk[i].dirty) {
-			status = clk_set_min_rate(info->nodeclk[i].clk, info->
+			status = clk_set_rate(info->nodeclk[i].clk, info->
 				nodeclk[i].rate);
 			if (enable && !(info->nodeclk[i].enable)) {
 				clk_enable(info->nodeclk[i].clk);
@@ -359,7 +358,7 @@
 		}
 
 	if (info->memclk.dirty) {
-		status = clk_set_min_rate(info->memclk.clk, info->memclk.rate);
+		status = clk_set_rate(info->memclk.clk, info->memclk.rate);
 		if (enable && !(info->memclk.enable)) {
 			clk_enable(info->memclk.clk);
 			info->memclk.dirty = false;
diff --git a/arch/arm/mach-msm/sdio_al.c b/arch/arm/mach-msm/sdio_al.c
index 891d655..356ce90 100644
--- a/arch/arm/mach-msm/sdio_al.c
+++ b/arch/arm/mach-msm/sdio_al.c
@@ -1223,7 +1223,7 @@
 		   We need to keep reading mailbox to wait for the appropriate
 		   write avail and cannot sleep. Ignore SMEM channel that has
 		   only one direction. */
-		if (strcmp(ch->name, "SDIO_SMEM"))
+		if (strncmp(ch->name, "SDIO_SMEM", CHANNEL_NAME_SIZE))
 			any_write_pending |=
 			(new_write_avail < ch->ch_config.max_tx_threshold);
 	}
@@ -2686,7 +2686,8 @@
 			if (sdio_al_dev->channel[i].state ==
 					SDIO_CHANNEL_STATE_INVALID)
 				continue;
-			if (strcmp(sdio_al_dev->channel[i].name, name) == 0) {
+			if (strncmp(sdio_al_dev->channel[i].name, name,
+					CHANNEL_NAME_SIZE) == 0) {
 				ch = &sdio_al_dev->channel[i];
 				break;
 			}
diff --git a/arch/arm/mach-msm/subsystem_restart.c b/arch/arm/mach-msm/subsystem_restart.c
index 54607d0..37469f8 100644
--- a/arch/arm/mach-msm/subsystem_restart.c
+++ b/arch/arm/mach-msm/subsystem_restart.c
@@ -139,6 +139,11 @@
 	int ret;
 	int old_val = restart_level;
 
+	if (cpu_is_msm9615()) {
+		pr_err("Only Phase 1 subsystem restart is supported\n");
+		return -EINVAL;
+	}
+
 	ret = param_set_int(val, kp);
 	if (ret)
 		return ret;
@@ -571,7 +576,7 @@
 		n_restart_orders = ARRAY_SIZE(orders_8x60_all);
 	}
 
-	if (cpu_is_msm8960() || cpu_is_msm8930()) {
+	if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm9615()) {
 		restart_orders = restart_orders_8960;
 		n_restart_orders = ARRAY_SIZE(restart_orders_8960);
 	}
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 7809054..8f24d81 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -1008,6 +1008,8 @@
 		gpt->freq = 32765;
 		gpt_hz = 32765;
 		sclk_hz = 32765;
+		gpt->flags |= MSM_CLOCK_FLAGS_UNSTABLE_COUNT;
+		dgt->flags |= MSM_CLOCK_FLAGS_UNSTABLE_COUNT;
 	} else if (cpu_is_msm8960() || cpu_is_apq8064() || cpu_is_msm8930()) {
 		global_timer_offset = MSM_TMR0_BASE - MSM_TMR_BASE;
 		dgt->freq = 6750000;
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 5550d47..46729ee 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -294,11 +294,18 @@
  */
 __v7_ca5mp_setup:
 __v7_ca9mp_setup:
-#if defined(CONFIG_SMP)
-	mrc	p15, 0, r0, c1, c0, 1
+	mov     r10, #(1 << 0)                  @ TLB ops broadcasting
+	b       1f
+__v7_ca15mp_setup:
+	mov     r10, #0
+1:
+#ifdef CONFIG_SMP
+	ALT_SMP(mrc     p15, 0, r0, c1, c0, 1)
+	ALT_UP(mov      r0, #(1 << 6))          @ fake it for UP
 	tst	r0, #(1 << 6)			@ SMP/nAMP mode enabled?
-	orreq	r0, r0, #(1 << 6) | (1 << 0)	@ Enable SMP/nAMP mode and
-	mcreq	p15, 0, r0, c1, c0, 1		@ TLB ops broadcasting
+	orreq   r0, r0, #(1 << 6)               @ Enable SMP/nAMP mode
+	orreq   r0, r0, r10                     @ Enable CPU-specific SMP bits
+	mcreq   p15, 0, r0, c1, c0, 1
 #endif
 __v7_setup:
 	adr	r12, __v7_setup_stack		@ the local stack
@@ -526,6 +533,16 @@
 	__v7_proc __v7_ca9mp_setup
 	.size	__v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info
 
+        /*
+	 * ARM Ltd. Cortex A15 processor.
+	 */
+	.type   __v7_ca15mp_proc_info, #object
+__v7_ca15mp_proc_info:
+	.long   0x410fc0f0
+	.long   0xff0ffff0
+	__v7_proc __v7_ca15mp_setup, hwcaps = HWCAP_IDIV
+	.size   __v7_ca15mp_proc_info, . - __v7_ca15mp_proc_info
+
 	/*
 	 * Match any ARMv7 processor core.
 	 */
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 3554500..a8a8925 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -612,7 +612,6 @@
 				elf_hwcap |= HWCAP_VFPv3D16;
 		}
 #endif
-#ifdef CONFIG_NEON
 		/*
 		 * Check for the presence of the Advanced SIMD
 		 * load/store instructions, integer and single
@@ -620,10 +619,13 @@
 		 * for NEON if the hardware has the MVFR registers.
 		 */
 		if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
+#ifdef CONFIG_NEON
 			if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100)
 				elf_hwcap |= HWCAP_NEON;
-		}
 #endif
+			if ((fmrx(MVFR1) & 0xf0000000) == 0x10000000)
+				elf_hwcap |= HWCAP_VFPv4;
+		}
 	}
 	return 0;
 }
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 30365a3..e4e561c 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -262,12 +262,12 @@
 	iommu_virt_addr = memdesc->gpuaddr;
 
 	ret = iommu_map_range(domain, iommu_virt_addr, memdesc->sg,
-				memdesc->size, MSM_IOMMU_ATTR_NONCACHED);
+				memdesc->size, 0);
 	if (ret) {
 		KGSL_CORE_ERR("iommu_map_range(%p, %x, %p, %d, %d) "
 				"failed with err: %d\n", domain,
 				iommu_virt_addr, memdesc->sg, memdesc->size,
-				MSM_IOMMU_ATTR_NONCACHED, ret);
+				0, ret);
 		return ret;
 	}
 
diff --git a/drivers/media/video/msm/msm_camera.c b/drivers/media/video/msm/msm_camera.c
index 565c724..7f43136 100644
--- a/drivers/media/video/msm/msm_camera.c
+++ b/drivers/media/video/msm/msm_camera.c
@@ -34,6 +34,7 @@
 #include <mach/camera.h>
 #include <linux/syscalls.h>
 #include <linux/hrtimer.h>
+#include <linux/ion.h>
 DEFINE_MUTEX(ctrl_cmd_lock);
 
 #define CAMERA_STOP_VIDEO 58
@@ -56,6 +57,8 @@
 static enum msm_camera_type camera_type[MSM_MAX_CAMERA_SENSORS];
 static uint32_t sensor_mount_angle[MSM_MAX_CAMERA_SENSORS];
 
+struct ion_client *client_for_ion;
+
 static const char *vfe_config_cmd[] = {
 	"CMD_GENERAL",  /* 0 */
 	"CMD_AXI_CFG_OUT1",
@@ -293,29 +296,41 @@
 	struct msm_pmem_info *info, spinlock_t* pmem_spinlock,
 	struct msm_sync *sync)
 {
-	struct file *file;
 	unsigned long paddr;
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
+	struct file *file;
 	unsigned long kvstart;
+#endif
 	unsigned long len;
-	int rc;
+	int rc = -ENOMEM;
 	struct msm_pmem_region *region;
 	unsigned long flags;
 
-
+	region = kmalloc(sizeof(struct msm_pmem_region), GFP_KERNEL);
+	if (!region)
+		goto out;
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		region->handle = ion_import_fd(client_for_ion, info->fd);
+		if (IS_ERR_OR_NULL(region->handle))
+			goto out1;
+		ion_phys(client_for_ion, region->handle,
+			&paddr, (size_t *)&len);
+#else
 	rc = get_pmem_file(info->fd, &paddr, &kvstart, &len, &file);
 	if (rc < 0) {
 		pr_err("%s: get_pmem_file fd %d error %d\n",
 			__func__,
 			info->fd, rc);
-		return rc;
+		goto out1;
 	}
-
+	region->file = file;
+#endif
 	if (!info->len)
 		info->len = len;
 
 	rc = check_pmem_info(info, len);
 	if (rc < 0)
-		return rc;
+		goto out2;
 
 	paddr += info->offset;
 	len = info->len;
@@ -323,29 +338,33 @@
 	spin_lock_irqsave(pmem_spinlock, flags);
 	if (check_overlap(ptype, paddr, len) < 0) {
 		spin_unlock_irqrestore(pmem_spinlock, flags);
-		return -EINVAL;
+		rc = -EINVAL;
+		goto out2;
 	}
 	spin_unlock_irqrestore(pmem_spinlock, flags);
 
-
-	region = kmalloc(sizeof(struct msm_pmem_region), GFP_KERNEL);
-	if (!region)
-		return -ENOMEM;
-
 	spin_lock_irqsave(pmem_spinlock, flags);
 	INIT_HLIST_NODE(&region->list);
 
 	region->paddr = paddr;
 	region->len = len;
-	region->file = file;
 	memcpy(&region->info, info, sizeof(region->info));
 
 	hlist_add_head(&(region->list), ptype);
 	spin_unlock_irqrestore(pmem_spinlock, flags);
 	CDBG("%s: type %d, paddr 0x%lx, vaddr 0x%lx\n",
 		__func__, info->type, paddr, (unsigned long)info->vaddr);
-
 	return 0;
+out2:
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	ion_free(client_for_ion, region->handle);
+#else
+	put_pmem_file(region->file);
+#endif
+out1:
+	kfree(region);
+out:
+	return rc;
 }
 
 /* return of 0 means failure */
@@ -616,7 +635,11 @@
 					pinfo->vaddr == region->info.vaddr &&
 					pinfo->fd == region->info.fd) {
 				hlist_del(node);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+				ion_free(client_for_ion, region->handle);
+#else
 				put_pmem_file(region->file);
+#endif
 				kfree(region);
 				CDBG("%s: type %d, vaddr  0x%p\n",
 					__func__, pinfo->type, pinfo->vaddr);
@@ -636,7 +659,11 @@
 				pinfo->vaddr == region->info.vaddr &&
 				pinfo->fd == region->info.fd) {
 				hlist_del(node);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+				ion_free(client_for_ion, region->handle);
+#else
 				put_pmem_file(region->file);
+#endif
 				kfree(region);
 				CDBG("%s: type %d, vaddr  0x%p\n",
 					__func__, pinfo->type, pinfo->vaddr);
@@ -655,7 +682,11 @@
 					pinfo->vaddr == region->info.vaddr &&
 					pinfo->fd == region->info.fd) {
 				hlist_del(node);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+				ion_free(client_for_ion, region->handle);
+#else
 				put_pmem_file(region->file);
+#endif
 				kfree(region);
 				CDBG("%s: type %d, vaddr  0x%p\n",
 					__func__, pinfo->type, pinfo->vaddr);
@@ -3013,14 +3044,22 @@
 		hlist_for_each_entry_safe(region, hnode, n,
 				&sync->pmem_frames, list) {
 			hlist_del(hnode);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+				ion_free(client_for_ion, region->handle);
+#else
 			put_pmem_file(region->file);
+#endif
 			kfree(region);
 		}
 		CDBG("%s, free stats pmem region\n", __func__);
 		hlist_for_each_entry_safe(region, hnode, n,
 				&sync->pmem_stats, list) {
 			hlist_del(hnode);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+				ion_free(client_for_ion, region->handle);
+#else
 			put_pmem_file(region->file);
+#endif
 			kfree(region);
 		}
 		msm_queue_drain(&sync->pict_q, list_pict);
@@ -3031,6 +3070,7 @@
 		sync->core_powered_on = 0;
 	}
 	mutex_unlock(&sync->lock);
+	ion_client_destroy(client_for_ion);
 
 	return 0;
 }
@@ -3733,6 +3773,7 @@
 		sync->core_powered_on = 1;
 	}
 	sync->opencnt++;
+	client_for_ion = msm_ion_client_create(-1, "camera");
 
 msm_open_done:
 	mutex_unlock(&sync->lock);
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index e639815..1ce089d 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -244,7 +244,7 @@
 
 static void msmsdcc_reset_and_restore(struct msmsdcc_host *host)
 {
-	if (host->plat->sdcc_v4_sup) {
+	if (host->sdcc_version) {
 		if (host->is_sps_mode) {
 			/* Reset DML first */
 			msmsdcc_dml_reset(host);
@@ -345,7 +345,7 @@
 	mb();
 	udelay(host->reg_write_delay);
 
-	if (host->plat->sdcc_v4_sup &&
+	if (host->sdcc_version &&
 		(readl_relaxed(host->base + MCI_STATUS2) &
 			MCI_MCLK_REG_WR_ACTIVE)) {
 		start = ktime_get();
@@ -1631,7 +1631,7 @@
 	if (mrq->data && (mrq->data->flags & MMC_DATA_WRITE)) {
 		if (mrq->cmd->opcode == SD_IO_RW_EXTENDED ||
 			mrq->cmd->opcode == 54) {
-			if (!host->plat->sdcc_v4_sup)
+			if (!host->sdcc_version)
 				host->dummy_52_needed = 1;
 			else
 				/*
@@ -1716,7 +1716,12 @@
 		rc = PTR_ERR(vreg->reg);
 		pr_err("%s: regulator_get(%s) failed. rc=%d\n",
 			__func__, vreg->name, rc);
+		goto out;
 	}
+
+	if (regulator_count_voltages(vreg->reg) > 0)
+		vreg->set_voltage_sup = 1;
+
 out:
 	return rc;
 }
@@ -3696,6 +3701,14 @@
 	host->clk_rate = clk_get_rate(host->clk);
 	if (!host->clk_rate)
 		dev_err(&pdev->dev, "Failed to read MCLK\n");
+
+	/*
+	* Lookup the Controller Version, to identify the supported features
+	* Version number read as 0 would indicate SDCC3 or earlier versions
+	*/
+	host->sdcc_version = readl_relaxed(host->base + MCI_VERSION);
+	pr_info("%s: mci-version: %x\n", mmc_hostname(host->mmc),
+		host->sdcc_version);
 	/*
 	 * Set the register write delay according to min. clock frequency
 	 * supported and update later when the host->clk_rate changes.
@@ -3747,7 +3760,7 @@
 	 * status is to use the AUTO_PROG_DONE status provided by SDCC4
 	 * controller. So let's enable the CMD23 for SDCC4 only.
 	 */
-	if (!plat->disable_cmd23 && host->plat->sdcc_v4_sup)
+	if (!plat->disable_cmd23 && host->sdcc_version)
 		mmc->caps |= MMC_CAP_CMD23;
 
 	mmc->caps |= plat->uhs_caps;
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index 12aa54b..2019913 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -168,6 +168,7 @@
 
 #define MMCIMASK1		0x040
 #define MMCIFIFOCNT		0x044
+#define MCI_VERSION		0x050
 #define MCICCSTIMER		0x058
 #define MCI_DLL_CONFIG		0x060
 #define MCI_DLL_EN		(1 << 16)
@@ -316,6 +317,7 @@
 
 	u32			pwr;
 	struct mmc_platform_data *plat;
+	u32			sdcc_version;
 
 	unsigned int		oldstat;
 
diff --git a/drivers/platform/msm/sps/sps.c b/drivers/platform/msm/sps/sps.c
index cb453e0..e43166e 100644
--- a/drivers/platform/msm/sps/sps.c
+++ b/drivers/platform/msm/sps/sps.c
@@ -425,6 +425,85 @@
 }
 
 /**
+ * Find the handle of a BAM device based on the physical address
+ *
+ * This function finds a BAM device in the BAM registration list that
+ * matches the specified physical address, and returns its handle.
+ *
+ * @phys_addr - physical address of the BAM
+ *
+ * @h - device handle of the BAM
+ *
+ * @return 0 on success, negative value on error
+ *
+ */
+int sps_phy2h(u32 phys_addr, u32 *handle)
+{
+	struct sps_bam *bam;
+
+	list_for_each_entry(bam, &sps->bams_q, list) {
+		if (bam->props.phys_addr == phys_addr) {
+			*handle = (u32) bam;
+			return 0;
+		}
+	}
+
+	SPS_INFO("sps: BAM device 0x%x is not registered yet.\n", phys_addr);
+
+	return -ENODEV;
+}
+EXPORT_SYMBOL(sps_phy2h);
+
+/**
+ * Setup desc/data FIFO for bam-to-bam connection
+ *
+ * @mem_buffer - Pointer to struct for allocated memory properties.
+ *
+ * @addr - address of FIFO
+ *
+ * @size - FIFO size
+ *
+ * @use_offset - use address offset instead of absolute address
+ *
+ * @return 0 on success, negative value on error
+ *
+ */
+int sps_setup_bam2bam_fifo(struct sps_mem_buffer *mem_buffer,
+		  u32 addr, u32 size, int use_offset)
+{
+	if ((mem_buffer == NULL) || (size == 0))
+		return SPS_ERROR;
+
+	if (use_offset) {
+		if ((addr + size) <= sps->pipemem_size)
+			mem_buffer->phys_base = sps->pipemem_phys_base + addr;
+		else {
+			SPS_ERR("sps: requested mem is out of "
+					"pipe mem range.\n");
+			return SPS_ERROR;
+		}
+	} else {
+		if (addr >= sps->pipemem_phys_base &&
+			(addr + size) <= (sps->pipemem_phys_base
+						+ sps->pipemem_size))
+			mem_buffer->phys_base = addr;
+		else {
+			SPS_ERR("sps: requested mem is out of "
+					"pipe mem range.\n");
+			return SPS_ERROR;
+		}
+	}
+
+	mem_buffer->base = spsi_get_mem_ptr(mem_buffer->phys_base);
+	mem_buffer->size = size;
+
+	memset(mem_buffer->base, 0, mem_buffer->size);
+
+	return 0;
+}
+EXPORT_SYMBOL(sps_setup_bam2bam_fifo);
+
+/**
  * Find the BAM device from the handle
  *
  * This function finds a BAM device in the BAM registration list that
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index 2d0f7cd..d7cf3a8 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -89,6 +89,12 @@
 	DECLARE_BITMAP(enabled_irqs, PM_BMS_MAX_INTS);
 	spinlock_t		bms_output_lock;
 	struct single_row_lut	*adjusted_fcc_temp_lut;
+	unsigned int		charging_began;
+	unsigned int		start_percent;
+	unsigned int		end_percent;
+
+	uint16_t		ocv_reading_at_100;
+	int			cc_reading_at_100;
 };
 
 static struct pm8921_bms_chip *the_chip;
@@ -484,6 +490,9 @@
 	}
 	*result = msw << 16 | lsw;
 	pr_debug("msw = %04x lsw = %04x cc = %d\n", msw, lsw, *result);
+	*result = *result - chip->cc_reading_at_100;
+	pr_debug("cc = %d after subtracting %d\n",
+					*result, chip->cc_reading_at_100);
 	return 0;
 }
 
@@ -497,12 +506,29 @@
 		pr_err("fail to read LAST_GOOD_OCV_VALUE rc = %d\n", rc);
 		return rc;
 	}
-	*result = xoadc_reading_to_microvolt(reading);
-	pr_debug("raw = %04x ocv_uV = %u\n", reading, *result);
-	*result = adjust_xo_vbatt_reading(chip, *result);
-	pr_debug("after adj ocv_uV = %u\n", *result);
-	if (*result != 0)
-		last_ocv_uv = *result;
+
+	if (chip->ocv_reading_at_100 != reading) {
+		chip->ocv_reading_at_100 = 0;
+		chip->cc_reading_at_100 = 0;
+		*result = xoadc_reading_to_microvolt(reading);
+		pr_debug("raw = %04x ocv_uV = %u\n", reading, *result);
+		*result = adjust_xo_vbatt_reading(chip, *result);
+		pr_debug("after adj ocv_uV = %u\n", *result);
+		if (*result != 0)
+			last_ocv_uv = *result;
+	} else {
+		/*
+		 * force 100% ocv by selecting the highest profiled ocv
+		 * This is the first row last column entry in the ocv
+		 * lookup table
+		 */
+		int cols = chip->pc_temp_ocv_lut->cols;
+
+		pr_debug("Forcing max voltage %d\n",
+				1000 * chip->pc_temp_ocv_lut->ocv[0][cols-1]);
+		*result = 1000 * chip->pc_temp_ocv_lut->ocv[0][cols-1];
+	}
+
 	return 0;
 }
 
@@ -628,18 +654,33 @@
 static int interpolate_scalingfactor_fcc(struct pm8921_bms_chip *chip,
 								int cycles)
 {
-	return interpolate_single_lut(chip->fcc_sf_lut, cycles);
+	/*
+	 * sf table could be null when no battery aging data is available, in
+	 * that case return 100%
+	 */
+	if (chip->fcc_sf_lut)
+		return interpolate_single_lut(chip->fcc_sf_lut, cycles);
+	else
+		return 100;
 }
 
 static int interpolate_scalingfactor_pc(struct pm8921_bms_chip *chip,
 				int cycles, int pc)
 {
 	int i, scalefactorrow1, scalefactorrow2, scalefactor;
+	int rows, cols;
 	int row1 = 0;
 	int row2 = 0;
-	int rows = chip->pc_sf_lut->rows;
-	int cols = chip->pc_sf_lut->cols;
 
+	/*
+	 * sf table could be null when no battery aging data is available, in
+	 * that case return 100%
+	 */
+	if (!chip->pc_sf_lut)
+		return 100;
+
+	rows = chip->pc_sf_lut->rows;
+	cols = chip->pc_sf_lut->cols;
 	if (pc > chip->pc_sf_lut->percent[0]) {
 		pr_debug("pc %d greater than known pc ranges for sfd\n", pc);
 		row1 = 0;
@@ -1016,10 +1057,10 @@
 
 	/* calculate cc milli_volt_hour */
 	calculate_cc_mah(chip, cc_mah, &coulumb_counter);
+	pr_debug("cc_mah = %lldmAh cc = %d\n", *cc_mah, coulumb_counter);
 
 	pm_bms_unlock_output_data(chip);
 	spin_unlock_irqrestore(&chip->bms_output_lock, flags);
-	pr_debug("cc_mah = %lldmAh cc = %d\n", *cc_mah, coulumb_counter);
 }
 
 static int calculate_real_fcc(struct pm8921_bms_chip *chip,
@@ -1037,7 +1078,8 @@
 						&cc_mah);
 
 	real_fcc = remaining_charge - cc_mah;
-
+	pr_debug("real_fcc = %d, RC = %d CC = %lld\n",
+			real_fcc, remaining_charge, cc_mah);
 	return real_fcc;
 }
 /*
@@ -1102,9 +1144,23 @@
 		update_userspace = 0;
 	}
 
-	if (update_userspace) {
-		last_soc = soc;
+	if (last_soc == -EINVAL || soc <= last_soc) {
+		last_soc = update_userspace ? soc : last_soc;
+		return soc;
 	}
+
+	/*
+	 * soc > last_soc
+	 * the device must be charging for reporting a higher soc, if not ignore
+	 * this soc and continue reporting the last_soc
+	 */
+	if (the_chip->start_percent != 0) {
+		last_soc = soc;
+	} else {
+		pr_debug("soc = %d reporting last_soc = %d\n", soc, last_soc);
+		soc = last_soc;
+	}
+
 	return soc;
 }
 
@@ -1645,19 +1701,18 @@
 }
 EXPORT_SYMBOL_GPL(pm8921_bms_get_fcc);
 
-static int start_percent;
-static int end_percent;
 void pm8921_bms_charging_began(void)
 {
-	start_percent = pm8921_bms_get_percent_charge();
-	pr_debug("start_percent = %u%%\n", start_percent);
+	the_chip->start_percent = pm8921_bms_get_percent_charge();
+	pr_debug("start_percent = %u%%\n", the_chip->start_percent);
 }
 EXPORT_SYMBOL_GPL(pm8921_bms_charging_began);
 
 void pm8921_bms_charging_end(int is_battery_full)
 {
 	if (is_battery_full && the_chip != NULL) {
-		int batt_temp, rc;
+		unsigned long flags;
+		int batt_temp, rc, cc_reading;
 		struct pm8921_adc_chan_result result;
 
 		rc = pm8921_adc_read(the_chip->batt_temp_channel, &result);
@@ -1673,12 +1728,25 @@
 						batt_temp, last_chargecycles);
 		last_real_fcc_batt_temp = batt_temp;
 		readjust_fcc_table();
+
+		spin_lock_irqsave(&the_chip->bms_output_lock, flags);
+		pm_bms_lock_output_data(the_chip);
+		pm_bms_read_output_data(the_chip, LAST_GOOD_OCV_VALUE,
+						&the_chip->ocv_reading_at_100);
+		read_cc(the_chip, &cc_reading);
+		pm_bms_unlock_output_data(the_chip);
+		spin_unlock_irqrestore(&the_chip->bms_output_lock, flags);
+		the_chip->cc_reading_at_100 = cc_reading;
+		pr_debug("EOC ocv_reading = 0x%x cc_reading = %d\n",
+				the_chip->ocv_reading_at_100,
+				the_chip->cc_reading_at_100);
 	}
 
 charge_cycle_calculation:
-	end_percent = pm8921_bms_get_percent_charge();
-	if (end_percent > start_percent) {
-		last_charge_increase = end_percent - start_percent;
+	the_chip->end_percent = pm8921_bms_get_percent_charge();
+	if (the_chip->end_percent > the_chip->start_percent) {
+		last_charge_increase =
+			the_chip->end_percent - the_chip->start_percent;
 		if (last_charge_increase > 100) {
 			last_chargecycles++;
 			last_charge_increase = last_charge_increase % 100;
@@ -1686,9 +1754,11 @@
 	}
 	pr_debug("end_percent = %u%% last_charge_increase = %d"
 			"last_chargecycles = %d\n",
-			end_percent,
+			the_chip->end_percent,
 			last_charge_increase,
 			last_chargecycles);
+	the_chip->start_percent = 0;
+	the_chip->end_percent = 0;
 }
 EXPORT_SYMBOL_GPL(pm8921_bms_charging_end);
 
diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c
index 1e4302b..6aa111c 100644
--- a/drivers/slimbus/slim-msm-ctrl.c
+++ b/drivers/slimbus/slim-msm-ctrl.c
@@ -21,6 +21,7 @@
 #include <linux/delay.h>
 #include <linux/kthread.h>
 #include <linux/clk.h>
+#include <linux/pm_runtime.h>
 #include <mach/sps.h>
 
 /* Per spec.max 40 bytes per received message */
@@ -44,6 +45,7 @@
 #define MSM_SLIM_PERF_SUMM_THRESHOLD	0x8000
 #define MSM_SLIM_NCHANS			32
 #define MSM_SLIM_NPORTS			24
+#define MSM_SLIM_AUTOSUSPEND		MSEC_PER_SEC
 
 /*
  * Need enough descriptors to receive present messages from slaves
@@ -80,6 +82,7 @@
 #define QC_DEVID_SAT1	0x3
 #define QC_DEVID_SAT2	0x4
 #define QC_DEVID_PGD	0x5
+#define QC_MSM_DEVS	5
 
 /* Component registers */
 enum comp_reg {
@@ -184,6 +187,12 @@
 	REF_CLK_GEAR	= 15,
 };
 
+enum msm_ctrl_state {
+	MSM_CTRL_AWAKE,
+	MSM_CTRL_SLEEPING,
+	MSM_CTRL_ASLEEP,
+};
+
 struct msm_slim_sps_bam {
 	u32			hdl;
 	void __iomem		*base;
@@ -226,10 +235,11 @@
 	struct mutex		tx_lock;
 	u8			pgdla;
 	bool			use_rx_msgqs;
-	int			suspended;
 	int			pipe_b;
 	struct completion	reconf;
 	bool			reconf_busy;
+	bool			chan_active;
+	enum msm_ctrl_state	state;
 };
 
 struct msm_slim_sat {
@@ -241,6 +251,8 @@
 	u16			*satch;
 	u8			nsatch;
 	bool			sent_capability;
+	bool			pending_reconf;
+	bool			pending_capability;
 	int			shead;
 	int			stail;
 	spinlock_t lock;
@@ -322,6 +334,16 @@
 	return false;
 }
 
+static void msm_slim_get_ctrl(struct msm_slim_ctrl *dev)
+{
+	pm_runtime_get_sync(dev->dev);
+}
+static void msm_slim_put_ctrl(struct msm_slim_ctrl *dev)
+{
+	pm_runtime_mark_last_busy(dev->dev);
+	pm_runtime_put(dev->dev);
+}
+
 static irqreturn_t msm_slim_interrupt(int irq, void *d)
 {
 	struct msm_slim_ctrl *dev = d;
@@ -450,6 +472,10 @@
 		 * before exiting ISR
 		 */
 		mb();
+		if (dev->ctrl.sched.usedslots == 0 && dev->chan_active) {
+			dev->chan_active = false;
+			msm_slim_put_ctrl(dev);
+		}
 		complete(&dev->reconf);
 	}
 	pstat = readl_relaxed(dev->base + PGD_PORT_INT_ST_EEn + (16 * dev->ee));
@@ -649,17 +675,37 @@
 	u8 *puc;
 	int timeout;
 	u8 la = txn->la;
+	u8 mc = (u8)(txn->mc & 0xFF);
+	/*
+	 * Voting for runtime PM: Slimbus has 2 possible use cases:
+	 * 1. messaging
+	 * 2. Data channels
+	 * Messaging case goes through messaging slots and data channels
+	 * use their own slots
+	 * This "get" votes for messaging bandwidth
+	 */
+	if (!(txn->mc & SLIM_MSG_CLK_PAUSE_SEQ_FLG))
+		msm_slim_get_ctrl(dev);
 	mutex_lock(&dev->tx_lock);
+	if (dev->state == MSM_CTRL_ASLEEP) {
+		dev_err(dev->dev, "runtime or system PM suspended state");
+		mutex_unlock(&dev->tx_lock);
+		if (!(txn->mc & SLIM_MSG_CLK_PAUSE_SEQ_FLG))
+			msm_slim_put_ctrl(dev);
+		return -EBUSY;
+	}
 	if (txn->mt == SLIM_MSG_MT_CORE &&
-		txn->mc == SLIM_MSG_MC_BEGIN_RECONFIGURATION &&
-		dev->reconf_busy) {
+		mc == SLIM_MSG_MC_BEGIN_RECONFIGURATION) {
+		if (dev->reconf_busy) {
 			wait_for_completion(&dev->reconf);
 			dev->reconf_busy = false;
-	}
-	if (dev->suspended) {
-		dev_err(dev->dev, "No transaction in suspended state");
-		mutex_unlock(&dev->tx_lock);
-		return -EBUSY;
+		}
+		/* This "get" votes for data channels */
+		if (dev->ctrl.sched.usedslots != 0 &&
+			!dev->chan_active) {
+			dev->chan_active = true;
+			msm_slim_get_ctrl(dev);
+		}
 	}
 	txn->rl--;
 	pbuf = msm_get_msg_buf(ctrl, txn->rl);
@@ -668,19 +714,19 @@
 
 	if (txn->dt == SLIM_MSG_DEST_ENUMADDR) {
 		mutex_unlock(&dev->tx_lock);
+		if (!(txn->mc & SLIM_MSG_CLK_PAUSE_SEQ_FLG))
+			msm_slim_put_ctrl(dev);
 		return -EPROTONOSUPPORT;
 	}
 	if (txn->mt == SLIM_MSG_MT_CORE && txn->la == 0xFF &&
-		(txn->mc == SLIM_MSG_MC_CONNECT_SOURCE ||
-		 txn->mc == SLIM_MSG_MC_CONNECT_SINK ||
-		 txn->mc == SLIM_MSG_MC_DISCONNECT_PORT))
+		(mc == SLIM_MSG_MC_CONNECT_SOURCE ||
+		 mc == SLIM_MSG_MC_CONNECT_SINK ||
+		 mc == SLIM_MSG_MC_DISCONNECT_PORT))
 		la = dev->pgdla;
 	if (txn->dt == SLIM_MSG_DEST_LOGICALADDR)
-		*pbuf = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt, txn->mc,
-					0, la);
+		*pbuf = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt, mc, 0, la);
 	else
-		*pbuf = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt, txn->mc,
-					1, la);
+		*pbuf = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt, mc, 1, la);
 	if (txn->dt == SLIM_MSG_DEST_LOGICALADDR)
 		puc = ((u8 *)pbuf) + 3;
 	else
@@ -688,20 +734,20 @@
 	if (txn->rbuf)
 		*(puc++) = txn->tid;
 	if ((txn->mt == SLIM_MSG_MT_CORE) &&
-		((txn->mc >= SLIM_MSG_MC_REQUEST_INFORMATION &&
-		txn->mc <= SLIM_MSG_MC_REPORT_INFORMATION) ||
-		(txn->mc >= SLIM_MSG_MC_REQUEST_VALUE &&
-		 txn->mc <= SLIM_MSG_MC_CHANGE_VALUE))) {
+		((mc >= SLIM_MSG_MC_REQUEST_INFORMATION &&
+		mc <= SLIM_MSG_MC_REPORT_INFORMATION) ||
+		(mc >= SLIM_MSG_MC_REQUEST_VALUE &&
+		 mc <= SLIM_MSG_MC_CHANGE_VALUE))) {
 		*(puc++) = (txn->ec & 0xFF);
 		*(puc++) = (txn->ec >> 8)&0xFF;
 	}
 	if (txn->wbuf)
 		memcpy(puc, txn->wbuf, txn->len);
 	if (txn->mt == SLIM_MSG_MT_CORE && txn->la == 0xFF &&
-		(txn->mc == SLIM_MSG_MC_CONNECT_SOURCE ||
-		 txn->mc == SLIM_MSG_MC_CONNECT_SINK ||
-		 txn->mc == SLIM_MSG_MC_DISCONNECT_PORT)) {
-		if (txn->mc != SLIM_MSG_MC_DISCONNECT_PORT)
+		(mc == SLIM_MSG_MC_CONNECT_SOURCE ||
+		 mc == SLIM_MSG_MC_CONNECT_SINK ||
+		 mc == SLIM_MSG_MC_DISCONNECT_PORT)) {
+		if (mc != SLIM_MSG_MC_DISCONNECT_PORT)
 			dev->err = msm_slim_connect_pipe_port(dev, *puc);
 		else {
 			struct msm_slim_endp *endpoint = &dev->pipes[*puc];
@@ -715,25 +761,49 @@
 			 */
 			dev->pipes[*puc].connected = false;
 			mutex_unlock(&dev->tx_lock);
+			msm_slim_put_ctrl(dev);
 			return 0;
 		}
 		if (dev->err) {
 			dev_err(dev->dev, "pipe-port connect err:%d", dev->err);
 			mutex_unlock(&dev->tx_lock);
+			msm_slim_put_ctrl(dev);
 			return dev->err;
 		}
 		*(puc) = *(puc) + dev->pipe_b;
 	}
 	if (txn->mt == SLIM_MSG_MT_CORE &&
-		txn->mc == SLIM_MSG_MC_BEGIN_RECONFIGURATION)
+		mc == SLIM_MSG_MC_BEGIN_RECONFIGURATION)
 		dev->reconf_busy = true;
 	dev->wr_comp = &done;
 	msm_send_msg_buf(ctrl, pbuf, txn->rl);
 	timeout = wait_for_completion_timeout(&done, HZ);
+
+	if ((txn->mc == (SLIM_MSG_MC_RECONFIGURE_NOW |
+				SLIM_MSG_CLK_PAUSE_SEQ_FLG)) && timeout) {
+		timeout = wait_for_completion_timeout(&dev->reconf, HZ);
+		dev->reconf_busy = false;
+		if (timeout) {
+			clk_disable(dev->rclk);
+			disable_irq(dev->irq);
+		}
+	}
+	if ((txn->mc == (SLIM_MSG_MC_RECONFIGURE_NOW |
+				SLIM_MSG_CLK_PAUSE_SEQ_FLG)) && !timeout) {
+		dev->reconf_busy = false;
+		dev_err(dev->dev, "clock pause failed");
+		mutex_unlock(&dev->tx_lock);
+		return -ETIMEDOUT;
+	}
+
+	mutex_unlock(&dev->tx_lock);
+	if (!txn->rbuf && !(txn->mc & SLIM_MSG_CLK_PAUSE_SEQ_FLG))
+		msm_slim_put_ctrl(dev);
+
 	if (!timeout)
 		dev_err(dev->dev, "TX timed out:MC:0x%x,mt:0x%x", txn->mc,
 					txn->mt);
-	mutex_unlock(&dev->tx_lock);
+
 	return timeout ? dev->err : -ETIMEDOUT;
 }
 
@@ -763,6 +833,7 @@
 static int msm_clk_pause_wakeup(struct slim_controller *ctrl)
 {
 	struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
+	enable_irq(dev->irq);
 	clk_enable(dev->rclk);
 	writel_relaxed(1, dev->base + FRM_WAKEUP);
 	/* Make sure framer wakeup write goes through before exiting function */
@@ -921,6 +992,9 @@
 				e_addr[1] == QC_DEVID_PGD &&
 				e_addr[2] != QC_CHIPID_SL)
 				dev->pgdla = laddr;
+			if (!ret && !pm_runtime_enabled(dev->dev) &&
+				laddr == (QC_MSM_DEVS - 1))
+				pm_runtime_enable(dev->dev);
 
 		} else if (mc == SLIM_MSG_MC_REPLY_INFORMATION ||
 				mc == SLIM_MSG_MC_REPLY_VALUE) {
@@ -928,6 +1002,7 @@
 			dev_dbg(dev->dev, "tid:%d, len:%d\n", tid, len - 4);
 			slim_msg_response(&dev->ctrl, &buf[4], tid,
 						len - 4);
+			msm_slim_put_ctrl(dev);
 		} else if (mc == SLIM_MSG_MC_REPORT_INFORMATION) {
 			u8 l_addr = buf[2];
 			u16 ele = (u16)buf[4] << 4;
@@ -980,11 +1055,26 @@
 			for (i = 0; i < 6; i++)
 				e_addr[i] = buf[7-i];
 
+			if (pm_runtime_enabled(dev->dev)) {
+				msm_slim_get_ctrl(dev);
+				sat->pending_capability = true;
+			}
 			slim_assign_laddr(&dev->ctrl, e_addr, 6, &laddr);
 			sat->satcl.laddr = laddr;
-		}
+		} else if (mt != SLIM_MSG_MT_CORE &&
+				mc != SLIM_MSG_MC_REPORT_PRESENT)
+			msm_slim_get_ctrl(dev);
 		switch (mc) {
 		case SLIM_MSG_MC_REPORT_PRESENT:
+			/* Remove runtime_pm vote once satellite acks */
+			if (mt != SLIM_MSG_MT_CORE) {
+				if (pm_runtime_enabled(dev->dev) &&
+					sat->pending_capability) {
+					msm_slim_put_ctrl(dev);
+					sat->pending_capability = false;
+				}
+				continue;
+			}
 			/* send a Manager capability msg */
 			if (sat->sent_capability)
 				continue;
@@ -1040,11 +1130,19 @@
 					"SAT define_ch returned:%d",
 					ret);
 			}
+			if (!sat->pending_reconf) {
+				msm_slim_get_ctrl(dev);
+				sat->pending_reconf = true;
+			}
 			break;
 		case SLIM_USR_MC_RECONFIG_NOW:
 			tid = buf[3];
 			gen_ack = true;
 			ret = slim_reconfigure_now(&sat->satcl);
+			if (sat->pending_reconf) {
+				msm_slim_put_ctrl(dev);
+				sat->pending_reconf = false;
+			}
 			break;
 		case SLIM_USR_MC_REQ_BW:
 			/* what we get is in SLOTS */
@@ -1085,8 +1183,12 @@
 		default:
 			break;
 		}
-		if (!gen_ack)
+		if (!gen_ack) {
+			if (mc != SLIM_MSG_MC_REPORT_PRESENT)
+				msm_slim_put_ctrl(dev);
 			continue;
+		}
+
 		wbuf[0] = tid;
 		if (!ret)
 			wbuf[1] = MSM_SAT_SUCCSS;
@@ -1099,6 +1201,7 @@
 		txn.wbuf = wbuf;
 		txn.mt = SLIM_MSG_MT_SRC_REFERRED_USER;
 		msm_xfer_msg(&dev->ctrl, &txn);
+		msm_slim_put_ctrl(dev);
 	}
 }
 
@@ -1606,11 +1709,7 @@
 		dev->framer.rootfreq / SLIM_CL_PER_SUPERFRAME_DIV8;
 	dev->ctrl.a_framer = &dev->framer;
 	dev->ctrl.clkgear = SLIM_MAX_CLK_GEAR;
-	ret = slim_add_numbered_controller(&dev->ctrl);
-	if (ret) {
-		dev_err(dev->dev, "error adding controller\n");
-		goto err_ctrl_failed;
-	}
+	dev->ctrl.dev.parent = &pdev->dev;
 
 	ret = request_irq(dev->irq, msm_slim_interrupt, IRQF_TRIGGER_HIGH,
 				"msm_slim_irq", dev);
@@ -1702,14 +1801,24 @@
 	 * function
 	 */
 	mb();
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, MSM_SLIM_AUTOSUSPEND);
+	pm_runtime_set_active(&pdev->dev);
+
+	ret = slim_add_numbered_controller(&dev->ctrl);
+	if (ret) {
+		dev_err(dev->dev, "error adding controller\n");
+		goto err_ctrl_failed;
+	}
 	dev_dbg(dev->dev, "MSM SB controller is up!\n");
 	return 0;
 
+err_ctrl_failed:
+	writel_relaxed(0, dev->base + COMP_CFG);
+	kfree(dev->satd);
 err_sat_failed:
 	free_irq(dev->irq, dev);
 err_request_irq_failed:
-	slim_del_controller(&dev->ctrl);
-err_ctrl_failed:
 	clk_disable(dev->rclk);
 	clk_put(dev->rclk);
 err_clk_get_failed:
@@ -1735,12 +1844,13 @@
 	struct resource *slew_mem = dev->slew_mem;
 	struct msm_slim_sat *sat = dev->satd;
 	slim_remove_device(&sat->satcl);
+	pm_runtime_disable(&pdev->dev);
+	pm_runtime_set_suspended(&pdev->dev);
 	kfree(sat->satch);
 	destroy_workqueue(sat->wq);
 	kfree(sat);
 	free_irq(dev->irq, dev);
 	slim_del_controller(&dev->ctrl);
-	clk_disable(dev->rclk);
 	clk_put(dev->rclk);
 	msm_slim_sps_exit(dev);
 	kthread_stop(dev->rx_msgq_thread);
@@ -1760,79 +1870,89 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM
-static int msm_slim_suspend(struct device *device)
+#ifdef CONFIG_PM_RUNTIME
+static int msm_slim_runtime_idle(struct device *device)
+{
+	dev_dbg(device, "pm_runtime: idle...\n");
+	pm_request_autosuspend(device);
+	return -EAGAIN;
+}
+#endif
+
+/*
+ * If PM_RUNTIME is not defined, these 2 functions become helper
+ * functions to be called from system suspend/resume. So they are not
+ * inside ifdef CONFIG_PM_RUNTIME
+ */
+static int msm_slim_runtime_suspend(struct device *device)
 {
 	struct platform_device *pdev = to_platform_device(device);
 	struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
-	int ret = slim_ctrl_clk_pause(&dev->ctrl, false, SLIM_CLK_UNSPECIFIED);
-	/* Make sure clock pause goes through */
-	mutex_lock(&dev->tx_lock);
-	if (!ret && dev->reconf_busy) {
-		wait_for_completion(&dev->reconf);
-		dev->reconf_busy = false;
+	int ret;
+	dev_dbg(device, "pm_runtime: suspending...\n");
+	dev->state = MSM_CTRL_SLEEPING;
+	ret = slim_ctrl_clk_pause(&dev->ctrl, false, SLIM_CLK_UNSPECIFIED);
+	if (ret)
+		dev->state = MSM_CTRL_AWAKE;
+	else
+		dev->state = MSM_CTRL_ASLEEP;
+	return ret;
+}
+
+static int msm_slim_runtime_resume(struct device *device)
+{
+	struct platform_device *pdev = to_platform_device(device);
+	struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
+	int ret = 0;
+	dev_dbg(device, "pm_runtime: resuming...\n");
+	if (dev->state == MSM_CTRL_ASLEEP)
+		ret = slim_ctrl_clk_pause(&dev->ctrl, true, 0);
+	if (ret)
+		dev->state = MSM_CTRL_ASLEEP;
+	else
+		dev->state = MSM_CTRL_AWAKE;
+	return ret;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int msm_slim_suspend(struct device *dev)
+{
+	int ret = 0;
+	if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) {
+		dev_dbg(dev, "system suspend");
+		ret = msm_slim_runtime_suspend(dev);
 	}
-	mutex_unlock(&dev->tx_lock);
-	if (!ret) {
-		clk_disable(dev->rclk);
-		disable_irq(dev->irq);
-		dev->suspended = 1;
-	} else if (ret == -EBUSY) {
+	if (ret == -EBUSY) {
 		/*
-		 * If the clock pause failed due to active channels, there is
-		 * a possibility that some audio stream is active during suspend
-		 * We dont want to return suspend failure in that case so that
-		 * display and relevant components can still go to suspend.
-		 * If there is some other error, then it should be passed-on
-		 * to system level suspend
-		 */
+		* If the clock pause failed due to active channels, there is
+		* a possibility that some audio stream is active during suspend
+		* We dont want to return suspend failure in that case so that
+		* display and relevant components can still go to suspend.
+		* If there is some other error, then it should be passed-on
+		* to system level suspend
+		*/
 		ret = 0;
 	}
 	return ret;
 }
 
-static int msm_slim_resume(struct device *device)
+static int msm_slim_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(device);
-	struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
-	mutex_lock(&dev->tx_lock);
-	if (dev->suspended) {
-		dev->suspended = 0;
-		mutex_unlock(&dev->tx_lock);
-		enable_irq(dev->irq);
-		return slim_ctrl_clk_pause(&dev->ctrl, true, 0);
+	/* If runtime_pm is enabled, this resume shouldn't do anything */
+	if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) {
+		int ret;
+		dev_dbg(dev, "system resume");
+		ret = msm_slim_runtime_resume(dev);
+		if (!ret) {
+			pm_runtime_mark_last_busy(dev);
+			pm_request_autosuspend(dev);
+		}
+		return ret;
+
 	}
-	mutex_unlock(&dev->tx_lock);
 	return 0;
 }
-#else
-#define msm_slim_suspend NULL
-#define msm_slim_resume NULL
-#endif /* CONFIG_PM */
-
-#ifdef CONFIG_PM_RUNTIME
-static int msm_slim_runtime_idle(struct device *dev)
-{
-	dev_dbg(dev, "pm_runtime: idle...\n");
-	return 0;
-}
-
-static int msm_slim_runtime_suspend(struct device *dev)
-{
-	dev_dbg(dev, "pm_runtime: suspending...\n");
-	return 0;
-}
-
-static int msm_slim_runtime_resume(struct device *dev)
-{
-	dev_dbg(dev, "pm_runtime: resuming...\n");
-	return 0;
-}
-#else
-#define msm_slim_runtime_idle NULL
-#define msm_slim_runtime_suspend NULL
-#define msm_slim_runtime_resume NULL
-#endif
+#endif /* CONFIG_PM_SLEEP */
 
 static const struct dev_pm_ops msm_slim_dev_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(
diff --git a/drivers/slimbus/slimbus.c b/drivers/slimbus/slimbus.c
index 3b79129..d8003bf 100644
--- a/drivers/slimbus/slimbus.c
+++ b/drivers/slimbus/slimbus.c
@@ -377,7 +377,6 @@
 	dev_set_name(&ctrl->dev, "sb-%d", ctrl->nr);
 	ctrl->dev.bus = &slimbus_type;
 	ctrl->dev.type = &slim_ctrl_type;
-	ctrl->dev.parent = &slimbus_dev;
 	ctrl->num_dev = 0;
 	if (!ctrl->min_cg)
 		ctrl->min_cg = SLIM_MIN_CLK_GEAR;
@@ -581,7 +580,7 @@
 }
 EXPORT_SYMBOL_GPL(slim_msg_response);
 
-static int slim_processtxn(struct slim_controller *ctrl, u8 dt, u8 mc, u16 ec,
+static int slim_processtxn(struct slim_controller *ctrl, u8 dt, u16 mc, u16 ec,
 			u8 mt, u8 *rbuf, const u8 *wbuf, u8 len, u8 mlen,
 			struct completion *comp, u8 la, u8 *tid)
 {
@@ -870,7 +869,7 @@
  * All controllers may not support broadcast
  */
 int slim_xfer_msg(struct slim_controller *ctrl, struct slim_device *sbdev,
-			struct slim_ele_access *msg, u8 mc, u8 *rbuf,
+			struct slim_ele_access *msg, u16 mc, u8 *rbuf,
 			const u8 *wbuf, u8 len)
 {
 	DECLARE_COMPLETION_ONSTACK(complete);
@@ -892,10 +891,6 @@
 	cur = slim_slicecodefromsize(sl);
 	ec = ((sl | (1 << 3)) | ((msg->start_offset & 0xFFF) << 4));
 
-	ret = slim_ctrl_clk_pause(ctrl, true, 0);
-	if (ret)
-		return ret;
-
 	if (wbuf)
 		mlen += len;
 	if (rbuf) {
@@ -1069,7 +1064,7 @@
 				enum slim_port_flow flow)
 {
 	int ret;
-	u8 mc;
+	u16 mc;
 	u8 buf[2];
 	u32 la = SLIM_HDL_TO_LA(ph);
 	u8 pn = (u8)SLIM_HDL_TO_PORT(ph);
@@ -1093,7 +1088,7 @@
 static int disconnect_port_ch(struct slim_controller *ctrl, u32 ph)
 {
 	int ret;
-	u8 mc;
+	u16 mc;
 	u32 la = SLIM_HDL_TO_LA(ph);
 	u8 pn = (u8)SLIM_HDL_TO_PORT(ph);
 
@@ -1127,10 +1122,6 @@
 	u8 chan = (u8)(chanh & 0xFF);
 	struct slim_ich *slc = &ctrl->chans[chan];
 
-	ret = slim_ctrl_clk_pause(ctrl, true, 0);
-	if (ret)
-		return ret;
-
 	mutex_lock(&ctrl->m_ctrl);
 	/* Make sure the channel is not already pending reconf. or active */
 	if (slc->state >= SLIM_CH_PENDING_ACTIVE) {
@@ -1193,11 +1184,8 @@
 int slim_disconnect_ports(struct slim_device *sb, u32 *ph, int nph)
 {
 	struct slim_controller *ctrl = sb->ctrl;
-	int i, ret;
+	int i;
 
-	ret = slim_ctrl_clk_pause(ctrl, true, 0);
-	if (ret)
-		return ret;
 	mutex_lock(&ctrl->m_ctrl);
 
 	for (i = 0; i < nph; i++)
@@ -2389,10 +2377,6 @@
 	u32 segdist;
 	struct slim_pending_ch *pch;
 
-	ret = slim_ctrl_clk_pause(ctrl, true, 0);
-	if (ret)
-		return ret;
-
 	mutex_lock(&ctrl->sched.m_reconf);
 	mutex_lock(&ctrl->m_ctrl);
 	ctrl->sched.pending_msgsl += sb->pending_msgsl - sb->cur_msgsl;
@@ -2785,20 +2769,20 @@
 	}
 
 	ret = slim_processtxn(ctrl, SLIM_MSG_DEST_BROADCAST,
-			SLIM_MSG_MC_BEGIN_RECONFIGURATION, 0, SLIM_MSG_MT_CORE,
-			NULL, NULL, 0, 3, NULL, 0, NULL);
-	if (ret)
-		goto clk_pause_ret;
-
-		ret = slim_processtxn(ctrl, SLIM_MSG_DEST_BROADCAST,
-			SLIM_MSG_MC_NEXT_PAUSE_CLOCK, 0, SLIM_MSG_MT_CORE,
-			NULL, &restart, 1, 4, NULL, 0, NULL);
+		SLIM_MSG_CLK_PAUSE_SEQ_FLG | SLIM_MSG_MC_BEGIN_RECONFIGURATION,
+		0, SLIM_MSG_MT_CORE, NULL, NULL, 0, 3, NULL, 0, NULL);
 	if (ret)
 		goto clk_pause_ret;
 
 	ret = slim_processtxn(ctrl, SLIM_MSG_DEST_BROADCAST,
-			SLIM_MSG_MC_RECONFIGURE_NOW, 0, SLIM_MSG_MT_CORE,
-			NULL, NULL, 0, 3, NULL, 0, NULL);
+		SLIM_MSG_CLK_PAUSE_SEQ_FLG | SLIM_MSG_MC_NEXT_PAUSE_CLOCK, 0,
+		SLIM_MSG_MT_CORE, NULL, &restart, 1, 4, NULL, 0, NULL);
+	if (ret)
+		goto clk_pause_ret;
+
+	ret = slim_processtxn(ctrl, SLIM_MSG_DEST_BROADCAST,
+		SLIM_MSG_CLK_PAUSE_SEQ_FLG | SLIM_MSG_MC_RECONFIGURE_NOW, 0,
+		SLIM_MSG_MT_CORE, NULL, NULL, 0, 3, NULL, 0, NULL);
 	if (ret)
 		goto clk_pause_ret;
 
diff --git a/drivers/usb/gadget/f_rmnet.c b/drivers/usb/gadget/f_rmnet.c
index 6f0fb07..7686bf2 100644
--- a/drivers/usb/gadget/f_rmnet.c
+++ b/drivers/usb/gadget/f_rmnet.c
@@ -487,7 +487,7 @@
 	}
 
 	spin_lock_irqsave(&dev->lock, flags);
-	list_add(&cpkt->list, &dev->cpkt_resp_q);
+	list_add_tail(&cpkt->list, &dev->cpkt_resp_q);
 	spin_unlock_irqrestore(&dev->lock, flags);
 
 	frmnet_ctrl_response_available(dev);
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index 350f286..ec303b9 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -400,8 +400,6 @@
 		dev_err(mehci->dev, "Unable to suspend PHY\n");
 		msm_hsic_config_gpios(mehci, 0);
 		msm_hsic_reset(mehci);
-		enable_irq(hcd->irq);
-		return -ETIMEDOUT;
 	}
 
 	/*
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c
index 411fa97..f45f257 100644
--- a/drivers/usb/host/ehci-msm.c
+++ b/drivers/usb/host/ehci-msm.c
@@ -177,11 +177,6 @@
 	}
 
 	device_init_wakeup(&pdev->dev, 1);
-	/*
-	 * OTG device parent of HCD takes care of putting
-	 * hardware into low power mode.
-	 */
-	pm_runtime_no_callbacks(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
 
 	return 0;
@@ -212,7 +207,31 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_RUNTIME
+static int ehci_msm_runtime_idle(struct device *dev)
+{
+	dev_dbg(dev, "ehci runtime idle\n");
+	return 0;
+}
+
+static int ehci_msm_runtime_suspend(struct device *dev)
+{
+	dev_dbg(dev, "ehci runtime suspend\n");
+	/*
+	 * Notify OTG about suspend.  It takes care of
+	 * putting the hardware in LPM.
+	 */
+	return otg_set_suspend(otg, 1);
+}
+
+static int ehci_msm_runtime_resume(struct device *dev)
+{
+	dev_dbg(dev, "ehci runtime resume\n");
+	return otg_set_suspend(otg, 0);
+}
+#endif
+
+#ifdef CONFIG_PM_SLEEP
 static int ehci_msm_pm_suspend(struct device *dev)
 {
 	struct usb_hcd *hcd = dev_get_drvdata(dev);
@@ -236,7 +255,7 @@
 				wakeup);
 	}
 
-	return 0;
+	return otg_set_suspend(otg, 1);
 }
 
 static int ehci_msm_pm_resume(struct device *dev)
@@ -250,16 +269,14 @@
 
 	ehci_prepare_ports_for_controller_resume(hcd_to_ehci(hcd));
 
-	return 0;
+	return otg_set_suspend(otg, 0);
 }
-#else
-#define ehci_msm_pm_suspend	NULL
-#define ehci_msm_pm_resume	NULL
 #endif
 
 static const struct dev_pm_ops ehci_msm_dev_pm_ops = {
-	.suspend         = ehci_msm_pm_suspend,
-	.resume          = ehci_msm_pm_resume,
+	SET_SYSTEM_SLEEP_PM_OPS(ehci_msm_pm_suspend, ehci_msm_pm_resume)
+	SET_RUNTIME_PM_OPS(ehci_msm_runtime_suspend, ehci_msm_runtime_resume,
+				ehci_msm_runtime_idle)
 };
 
 static struct platform_driver ehci_msm_driver = {
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig
index 71f36f2..8864f32 100644
--- a/drivers/usb/otg/Kconfig
+++ b/drivers/usb/otg/Kconfig
@@ -161,7 +161,7 @@
 config USB_MSM_STANDARD_ACA
 	bool "Support for Standard ACA"
 	depends on USB_MSM_ACA
-	default y
+	default USB_MSM_OTG_72K
 	help
 	  A Standard ACA has a Standard-A receptacle on the Accessory Port,
 	  and can only be attached to a B-device.  RID_A and RID_GND states
diff --git a/drivers/usb/otg/msm72k_otg.c b/drivers/usb/otg/msm72k_otg.c
index fccd357..714099a 100644
--- a/drivers/usb/otg/msm72k_otg.c
+++ b/drivers/usb/otg/msm72k_otg.c
@@ -37,7 +37,13 @@
 #define DRIVER_NAME	"msm_otg"
 static void otg_reset(struct otg_transceiver *xceiv, int phy_reset);
 static void msm_otg_set_vbus_state(int online);
-static void msm_otg_set_id_state(int online);
+#ifdef CONFIG_USB_EHCI_MSM_72K
+static void msm_otg_set_id_state(int id);
+#else
+static void msm_otg_set_id_state(int id)
+{
+}
+#endif
 
 struct msm_otg *the_msm_otg;
 
@@ -45,9 +51,7 @@
 {
 	struct msm_otg *dev = the_msm_otg;
 
-	if (dev->pmic_id_notif_supp)
-		return dev->pmic_id_status ? 0 : 1;
-	else if (dev->pdata->otg_mode == OTG_ID)
+	if (dev->pdata->otg_mode == OTG_ID)
 		return (OTGSC_ID & readl(USB_OTGSC)) ? 0 : 1;
 	else
 		return !test_bit(ID, &dev->inputs);
@@ -135,24 +139,38 @@
 #ifdef CONFIG_USB_EHCI_MSM_72K
 static void enable_idgnd(struct msm_otg *dev)
 {
+	unsigned temp;
+
 	/* Do nothing if instead of ID pin, USER controls mode switch */
 	if (dev->pdata->otg_mode == OTG_USER_CONTROL)
 		return;
 
 	ulpi_write(dev, (1<<4), 0x0E);
 	ulpi_write(dev, (1<<4), 0x11);
-	writel_relaxed(readl_relaxed(USB_OTGSC) | OTGSC_IDIE, USB_OTGSC);
+	ulpi_write(dev, (1<<0), 0x0B);
+	temp = OTGSC_IDIE | OTGSC_IDPU;
+	writel_relaxed(readl_relaxed(USB_OTGSC) | temp, USB_OTGSC);
 }
 
 static void disable_idgnd(struct msm_otg *dev)
 {
+	unsigned temp;
+
 	/* Do nothing if instead of ID pin, USER controls mode switch */
 	if (dev->pdata->otg_mode == OTG_USER_CONTROL)
 		return;
-
+	temp = OTGSC_IDIE | OTGSC_IDPU;
+	writel_relaxed(readl_relaxed(USB_OTGSC) & ~temp, USB_OTGSC);
 	ulpi_write(dev, (1<<4), 0x0F);
 	ulpi_write(dev, (1<<4), 0x12);
-	writel_relaxed(readl_relaxed(USB_OTGSC) & ~OTGSC_IDIE, USB_OTGSC);
+	ulpi_write(dev, (1<<0), 0x0C);
+}
+#else
+static void enable_idgnd(struct msm_otg *dev)
+{
+}
+static void disable_idgnd(struct msm_otg *dev)
+{
 }
 #endif
 
@@ -224,6 +242,9 @@
 #define get_aca_bmaxpower(dev)		(dev->b_max_power)
 #define set_aca_bmaxpower(dev, power)	(dev->b_max_power = power)
 #else
+static void set_aca_id_inputs(struct msm_otg *dev)
+{
+}
 #define get_aca_bmaxpower(dev)		0
 #define set_aca_bmaxpower(dev, power)
 #endif
@@ -692,6 +713,31 @@
 	 * 4. peripheral is supported, but, vbus is not routed to pmic
 	 */
 	host_bus_suspend = dev->otg.host && is_host();
+
+	/*
+	 *  Configure the PMIC ID only in case of cable disconnect.
+	 *  PMIC doesn't generate interrupt for ID_GND to ID_A
+	 *  transistion. hence use the PHY ID cricuit.
+	 */
+	if (dev->pdata->pmic_id_notif_init && !host_bus_suspend &&
+		!test_bit(ID_A, &dev->inputs)) {
+		disable_idgnd(dev);
+		ret = dev->pdata->pmic_id_notif_init(
+			&msm_otg_set_id_state, 1);
+		if (!ret) {
+			dev->pmic_id_notif_supp = 1;
+			if (dev->pdata->pmic_id_irq)
+				dev->id_irq = dev->pdata->pmic_id_irq;
+		} else if (ret == -ENOTSUPP) {
+			pr_debug("%s:USB ID is not routed to pmic",
+			__func__);
+			enable_idgnd(dev);
+		} else {
+			pr_err("%s: pmic_id_ notif_init failed err:%d",
+				__func__, ret);
+		}
+	}
+
 	if ((dev->otg.gadget && chg_type == USB_CHG_TYPE__WALLCHARGER) ||
 		host_bus_suspend ||
 		(dev->otg.host && !dev->pmic_id_notif_supp) ||
@@ -760,7 +806,8 @@
 	 * that there is no harm with this. Till hw folks confirms this
 	 * put regulators in lpm.
 	 */
-	if (!host_bus_suspend && dev->pmic_vbus_notif_supp) {
+	 if (!host_bus_suspend && dev->pmic_vbus_notif_supp &&
+		!test_bit(ID_A, &dev->inputs)) {
 		pr_debug("phy can power collapse: (%d)\n",
 			can_phy_power_collapse(dev));
 		if (can_phy_power_collapse(dev) && dev->pdata->ldo_enable) {
@@ -881,9 +928,35 @@
 	}
 
 phy_resumed:
+	/*
+	 * It is observed that BSVIS may get set immediatly
+	 * after PHY becomes active upon micro-B cable connect.
+	 * But BSVIS might get cleared by below enable_idgnd
+	 * function which causes hw to not generate the BSV interrupt.
+	 * Hence check for BSV interrupt explictly and schedule the
+	 * work.
+	 */
+	if (readl_relaxed(USB_OTGSC) & OTGSC_BSVIS) {
+		set_bit(B_SESS_VLD, &dev->inputs);
+		queue_work(dev->wq, &dev->sm_work);
+	}
+	if (dev->pmic_id_notif_supp) {
+		dev->pdata->pmic_id_notif_init(&msm_otg_set_id_state, 0);
+		dev->pmic_id_notif_supp = 0;
+		enable_idgnd(dev);
+	}
+
 	/* Enable Idabc interrupts as these were disabled before entering LPM */
 	enable_idabc(dev);
 
+	/*
+	 * There is corner case where host won't be resumed
+	 * while transitioning from ID_GND to ID_A. In that
+	 * IDGND might have cleared and ID_A might not have updated
+	 * yet. Hence update the ACA states explicitly.
+	 */
+	set_aca_id_inputs(dev);
+
 	/* If resume signalling finishes before lpm exit, PCD is not set in
 	 * USBSTS register. Drive resume signal to the downstream device now
 	 * so that host driver can process the upcoming port change interrupt.*/
@@ -996,6 +1069,12 @@
 			}
 			udelay(10);
 		}
+		if (dev->pmic_id_notif_supp) {
+			dev->pdata->pmic_id_notif_init(
+				&msm_otg_set_id_state, 0);
+			dev->pmic_id_notif_supp = 0;
+			enable_idgnd(dev);
+		}
 out:
 		enable_idabc(dev);
 		enable_irq(dev->irq);
@@ -1119,23 +1198,20 @@
 #endif
 	return 0;
 }
-#endif
 
-void msm_otg_set_id_state(int id)
+static void msm_otg_set_id_state(int id)
 {
 	struct msm_otg *dev = the_msm_otg;
 	unsigned long flags;
 
-	if (id == dev->pmic_id_status)
+	if (!atomic_read(&dev->in_lpm))
 		return;
 
 	if (id) {
 		set_bit(ID, &dev->inputs);
-		dev->pmic_id_status = 1;
 	} else {
 		clear_bit(ID, &dev->inputs);
 		set_bit(A_BUS_REQ, &dev->inputs);
-		dev->pmic_id_status = 0;
 	}
 	spin_lock_irqsave(&dev->lock, flags);
 	if (dev->otg.state != OTG_STATE_UNDEFINED) {
@@ -1144,6 +1220,7 @@
 	}
 	spin_unlock_irqrestore(&dev->lock, flags);
 }
+#endif
 
 void msm_otg_set_vbus_state(int online)
 {
@@ -1973,6 +2050,7 @@
 		} else if (test_bit(ID_A, &dev->inputs)) {
 			dev->pdata->vbus_power(USB_PHY_INTEGRATED, 0);
 		} else if (!test_bit(ID, &dev->inputs)) {
+			msm_otg_set_power(&dev->otg, 0);
 			dev->pdata->vbus_power(USB_PHY_INTEGRATED, 1);
 		}
 		break;
@@ -2687,12 +2765,10 @@
 		}
 	}
 
-	if (dev->pdata->pmic_id_notif_init) {
-		ret = dev->pdata->pmic_id_notif_init(&msm_otg_set_id_state, 1);
-		if (!ret) {
-			dev->pmic_id_notif_supp = 1;
-		} else if (ret != -ENOTSUPP) {
-			pr_err("%s: pmic_id_ notif_init failed err:%d",
+	if (dev->pdata->phy_id_setup_init) {
+		ret = dev->pdata->phy_id_setup_init(1);
+		if (ret) {
+			pr_err("%s: phy_id_setup_init failed err:%d",
 					__func__, ret);
 			goto free_pmic_vbus_notif;
 		}
@@ -2700,8 +2776,6 @@
 
 	if (dev->pdata->pmic_vbus_irq)
 		dev->vbus_on_irq = dev->pdata->pmic_vbus_irq;
-	if (dev->pdata->pmic_id_irq)
-		dev->id_irq = dev->pdata->pmic_id_irq;
 
 	/* vote for vddcx, as PHY cannot tolerate vddcx below 1.0V */
 	if (dev->pdata->init_vddcx) {
@@ -2709,7 +2783,7 @@
 		if (ret) {
 			pr_err("%s: unable to enable vddcx digital core:%d\n",
 				__func__, ret);
-			goto free_pmic_id_notif;
+			goto free_phy_id_setup;
 		}
 	}
 
@@ -2819,9 +2893,9 @@
 free_config_vddcx:
 	if (dev->pdata->init_vddcx)
 		dev->pdata->init_vddcx(0);
-free_pmic_id_notif:
-	if (dev->pdata->pmic_id_notif_init && dev->pmic_id_notif_supp)
-		dev->pdata->pmic_id_notif_init(&msm_otg_set_id_state, 0);
+free_phy_id_setup:
+	if (dev->pdata->phy_id_setup_init)
+		dev->pdata->phy_id_setup_init(0);
 free_pmic_vbus_notif:
 	if (dev->pdata->pmic_vbus_notif_init && dev->pmic_vbus_notif_supp)
 		dev->pdata->pmic_vbus_notif_init(&msm_otg_set_vbus_state, 0);
@@ -2890,6 +2964,9 @@
 	if (dev->pmic_vbus_notif_supp)
 		dev->pdata->pmic_vbus_notif_init(&msm_otg_set_vbus_state, 0);
 
+	if (dev->pdata->phy_id_setup_init)
+		dev->pdata->phy_id_setup_init(0);
+
 	if (dev->pmic_id_notif_supp)
 		dev->pdata->pmic_id_notif_init(&msm_otg_set_id_state, 0);
 
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index d16fcda..1eb8511 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -41,27 +41,7 @@
 #define MSM_USB_BASE	(motg->regs)
 #define DRIVER_NAME	"msm_otg"
 
-#ifdef CONFIG_USB_MSM_ACA
-static void msm_chg_enable_aca_det(struct msm_otg *motg);
-static void msm_chg_enable_aca_intr(struct msm_otg *motg);
-#else
-static inline bool msm_chg_aca_detect(struct msm_otg *motg)
-{
-	return false;
-}
-
-static inline void msm_chg_enable_aca_det(struct msm_otg *motg)
-{
-}
-static inline void msm_chg_enable_aca_intr(struct msm_otg *motg)
-{
-}
-static inline bool msm_chg_check_aca_intr(struct msm_otg *motg)
-{
-	return false;
-}
-#endif
-
+#define ID_TIMER_FREQ		(jiffies + msecs_to_jiffies(2000))
 #define ULPI_IO_TIMEOUT_USEC	(10 * 1000)
 
 #define USB_PHY_3P3_VOL_MIN	3050000 /* uV */
@@ -78,11 +58,21 @@
 #define USB_PHY_VDD_DIG_VOL_MAX	1320000 /* uV */
 
 static struct msm_otg *the_msm_otg;
+static bool debug_aca_enabled;
 
 static struct regulator *hsusb_3p3;
 static struct regulator *hsusb_1p8;
 static struct regulator *hsusb_vddcx;
 
+static inline bool aca_enabled(void)
+{
+#ifdef CONFIG_USB_MSM_ACA
+	return true;
+#else
+	return debug_aca_enabled;
+#endif
+}
+
 static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init)
 {
 	int ret = 0;
@@ -477,11 +467,32 @@
 }
 
 #define LINK_RESET_TIMEOUT_USEC		(250 * 1000)
+static int msm_otg_link_reset(struct msm_otg *motg)
+{
+	int cnt = 0;
+
+	writel_relaxed(USBCMD_RESET, USB_USBCMD);
+	while (cnt < LINK_RESET_TIMEOUT_USEC) {
+		if (!(readl_relaxed(USB_USBCMD) & USBCMD_RESET))
+			break;
+		udelay(1);
+		cnt++;
+	}
+	if (cnt >= LINK_RESET_TIMEOUT_USEC)
+		return -ETIMEDOUT;
+
+	/* select ULPI phy */
+	writel_relaxed(0x80000000, USB_PORTSC);
+	writel_relaxed(0x0, USB_AHBBURST);
+	writel_relaxed(0x00, USB_AHBMODE);
+
+	return 0;
+}
+
 static int msm_otg_reset(struct otg_transceiver *otg)
 {
 	struct msm_otg *motg = container_of(otg, struct msm_otg, otg);
 	struct msm_otg_platform_data *pdata = motg->pdata;
-	int cnt = 0;
 	int ret;
 	u32 val = 0;
 	u32 ulpi_val = 0;
@@ -495,26 +506,15 @@
 
 	ulpi_init(motg);
 
-	writel(USBCMD_RESET, USB_USBCMD);
-	while (cnt < LINK_RESET_TIMEOUT_USEC) {
-		if (!(readl(USB_USBCMD) & USBCMD_RESET))
-			break;
-		udelay(1);
-		cnt++;
+	ret = msm_otg_link_reset(motg);
+	if (ret) {
+		dev_err(otg->dev, "link reset failed\n");
+		return ret;
 	}
-	if (cnt >= LINK_RESET_TIMEOUT_USEC)
-		return -ETIMEDOUT;
-
-	/* select ULPI phy */
-	writel(0x80000000, USB_PORTSC);
-
 	msleep(100);
-
-	writel(0x0, USB_AHBBURST);
-	writel(0x00, USB_AHBMODE);
-
 	/* Ensure that RESET operation is completed before turning off clock */
 	mb();
+
 	clk_disable(motg->clk);
 
 	val = readl_relaxed(USB_OTGSC);
@@ -529,8 +529,27 @@
 	ulpi_write(otg, ulpi_val, ULPI_USB_INT_EN_RISE);
 	ulpi_write(otg, ulpi_val, ULPI_USB_INT_EN_FALL);
 
-	msm_chg_enable_aca_det(motg);
-	msm_chg_enable_aca_intr(motg);
+	return 0;
+}
+
+static int msm_otg_set_suspend(struct otg_transceiver *otg, int suspend)
+{
+	struct msm_otg *motg = container_of(otg, struct msm_otg, otg);
+
+	/*
+	 * Allow bus suspend only for host mode.  Device mode bus suspend
+	 * is not implemented yet.
+	 */
+	if (!test_bit(ID, &motg->inputs) || test_bit(ID_A, &motg->inputs)) {
+		/*
+		 * ID_GND --> ID_A transition can not be detected in LPM.
+		 * Disallow host bus suspend when ACA is enabled.
+		 */
+		if (suspend && !aca_enabled())
+			pm_runtime_put(otg->dev);
+		else
+			pm_runtime_resume(otg->dev);
+	}
 
 	return 0;
 }
@@ -743,9 +762,13 @@
 
 	atomic_set(&motg->in_lpm, 0);
 
+	if (aca_enabled() && !irq_read_line(motg->pdata->pmic_id_irq)) {
+		clear_bit(ID, &motg->inputs);
+		schedule_work(&motg->sm_work);
+	}
+
 	if (motg->async_int) {
 		motg->async_int = 0;
-		pm_runtime_put(otg->dev);
 		enable_irq(motg->irq);
 	}
 
@@ -757,6 +780,13 @@
 
 static void msm_otg_notify_charger(struct msm_otg *motg, unsigned mA)
 {
+	if ((motg->chg_type == USB_ACA_DOCK_CHARGER ||
+		motg->chg_type == USB_ACA_A_CHARGER ||
+		motg->chg_type == USB_ACA_B_CHARGER ||
+		motg->chg_type == USB_ACA_C_CHARGER) &&
+			mA > IDEV_ACA_CHG_LIMIT)
+		mA = IDEV_ACA_CHG_LIMIT;
+
 	if (motg->cur_power == mA)
 		return;
 
@@ -808,6 +838,9 @@
 		dev_dbg(otg->dev, "host off\n");
 
 		usb_remove_hcd(hcd);
+		/* HCD core reset all bits of PORTSC. select ULPI phy */
+		writel_relaxed(0x80000000, USB_PORTSC);
+
 		if (pdata->setup_gpio)
 			pdata->setup_gpio(OTG_STATE_UNDEFINED);
 	}
@@ -817,32 +850,45 @@
 			unsigned long action, void *priv)
 {
 	struct msm_otg *motg = container_of(self, struct msm_otg, usbdev_nb);
-	struct usb_device *udev;
+	struct usb_device *udev = priv;
+
+	if (!aca_enabled())
+		goto out;
+
+	if (action == USB_BUS_ADD || action == USB_BUS_REMOVE)
+		goto out;
+
+	if (udev->bus != motg->otg.host)
+		goto out;
+	/*
+	 * Interested in devices connected directly to the root hub.
+	 * ACA dock can supply IDEV_CHG irrespective devices connected
+	 * on the accessory port.
+	 */
+	if (!udev->parent || udev->parent->parent ||
+			motg->chg_type == USB_ACA_DOCK_CHARGER)
+		goto out;
 
 	switch (action) {
 	case USB_DEVICE_ADD:
+		usb_disable_autosuspend(udev);
+		/* fall through */
 	case USB_DEVICE_CONFIG:
-		udev = priv;
-		/*
-		 * Interested in devices connected directly to the root hub.
-		 * ACA dock can supply IDEV_CHG irrespective devices connected
-		 * on the accessory port.
-		 */
-		if (!udev->parent || udev->parent->parent ||
-				motg->chg_type == USB_ACA_DOCK_CHARGER)
-			break;
 		if (udev->actconfig)
 			motg->mA_port = udev->actconfig->desc.bMaxPower * 2;
 		else
 			motg->mA_port = IUNIT;
-
-		if (test_bit(ID_A, &motg->inputs))
-			msm_otg_notify_charger(motg, IDEV_CHG_MIN -
-					motg->mA_port);
+		break;
+	case USB_DEVICE_REMOVE:
+		motg->mA_port = IUNIT;
 		break;
 	default:
 		break;
 	}
+	if (test_bit(ID_A, &motg->inputs))
+		msm_otg_notify_charger(motg, IDEV_ACA_CHG_MAX -
+				motg->mA_port);
+out:
 	return NOTIFY_OK;
 }
 
@@ -966,13 +1012,15 @@
 	return 0;
 }
 
-#ifdef CONFIG_USB_MSM_ACA
 static bool msm_chg_aca_detect(struct msm_otg *motg)
 {
 	struct otg_transceiver *otg = &motg->otg;
 	u32 int_sts;
 	bool ret = false;
 
+	if (!aca_enabled())
+		goto out;
+
 	if (motg->pdata->phy_type == CI_45NM_INTEGRATED_PHY)
 		goto out;
 
@@ -985,6 +1033,7 @@
 			motg->chg_state = USB_CHG_STATE_DETECTED;
 			clear_bit(ID_B, &motg->inputs);
 			clear_bit(ID_C, &motg->inputs);
+			set_bit(ID, &motg->inputs);
 			ret = true;
 		}
 		break;
@@ -995,6 +1044,7 @@
 			motg->chg_state = USB_CHG_STATE_DETECTED;
 			clear_bit(ID_A, &motg->inputs);
 			clear_bit(ID_C, &motg->inputs);
+			set_bit(ID, &motg->inputs);
 			ret = true;
 		}
 		break;
@@ -1005,15 +1055,28 @@
 			motg->chg_state = USB_CHG_STATE_DETECTED;
 			clear_bit(ID_A, &motg->inputs);
 			clear_bit(ID_B, &motg->inputs);
+			set_bit(ID, &motg->inputs);
+			ret = true;
+		}
+		break;
+	case 0x04:
+		if (test_and_clear_bit(ID, &motg->inputs)) {
+			dev_dbg(otg->dev, "ID_GND\n");
+			motg->chg_type = USB_INVALID_CHARGER;
+			motg->chg_state = USB_CHG_STATE_UNDEFINED;
+			clear_bit(ID_A, &motg->inputs);
+			clear_bit(ID_B, &motg->inputs);
+			clear_bit(ID_C, &motg->inputs);
 			ret = true;
 		}
 		break;
 	default:
 		ret = test_and_clear_bit(ID_A, &motg->inputs) |
 			test_and_clear_bit(ID_B, &motg->inputs) |
-			test_and_clear_bit(ID_C, &motg->inputs);
+			test_and_clear_bit(ID_C, &motg->inputs) |
+			!test_and_set_bit(ID, &motg->inputs);
 		if (ret) {
-			dev_dbg(otg->dev, "ID A/B/C is no more\n");
+			dev_dbg(otg->dev, "ID A/B/C/GND is no more\n");
 			motg->chg_type = USB_INVALID_CHARGER;
 			motg->chg_state = USB_CHG_STATE_UNDEFINED;
 		}
@@ -1026,9 +1089,18 @@
 {
 	struct otg_transceiver *otg = &motg->otg;
 
+	if (!aca_enabled())
+		return;
+
 	switch (motg->pdata->phy_type) {
 	case SNPS_28NM_INTEGRATED_PHY:
-		/* ACA ID pin resistance detection enable */
+		/* Disable ID_GND in link and PHY */
+		writel_relaxed(readl_relaxed(USB_OTGSC) & ~(OTGSC_IDPU |
+				OTGSC_IDIE), USB_OTGSC);
+		ulpi_write(otg, 0x01, 0x0C);
+		ulpi_write(otg, 0x10, 0x0F);
+		ulpi_write(otg, 0x10, 0x12);
+		/* Enable ACA ID detection */
 		ulpi_write(otg, 0x20, 0x85);
 		break;
 	default:
@@ -1040,10 +1112,29 @@
 {
 	struct otg_transceiver *otg = &motg->otg;
 
+	if (!aca_enabled())
+		return;
+
 	switch (motg->pdata->phy_type) {
 	case SNPS_28NM_INTEGRATED_PHY:
-		/* Enables ACA Detection interrupt (on any RID change) */
-		ulpi_write(otg, 0x20, 0x94);
+		/* Enable ACA Detection interrupt (on any RID change) */
+		ulpi_write(otg, 0x01, 0x94);
+		break;
+	default:
+		break;
+	}
+}
+
+static void msm_chg_disable_aca_intr(struct msm_otg *motg)
+{
+	struct otg_transceiver *otg = &motg->otg;
+
+	if (!aca_enabled())
+		return;
+
+	switch (motg->pdata->phy_type) {
+	case SNPS_28NM_INTEGRATED_PHY:
+		ulpi_write(otg, 0x01, 0x95);
 		break;
 	default:
 		break;
@@ -1055,6 +1146,9 @@
 	struct otg_transceiver *otg = &motg->otg;
 	bool ret = false;
 
+	if (!aca_enabled())
+		return ret;
+
 	switch (motg->pdata->phy_type) {
 	case SNPS_28NM_INTEGRATED_PHY:
 		if (ulpi_read(otg, 0x91) & 1) {
@@ -1067,7 +1161,28 @@
 	}
 	return ret;
 }
-#endif
+
+static void msm_otg_id_timer_func(unsigned long data)
+{
+	struct msm_otg *motg = (struct msm_otg *) data;
+
+	if (!aca_enabled())
+		return;
+
+	if (atomic_read(&motg->in_lpm)) {
+		dev_dbg(motg->otg.dev, "timer: in lpm\n");
+		return;
+	}
+
+	if (msm_chg_check_aca_intr(motg)) {
+		dev_dbg(motg->otg.dev, "timer: aca work\n");
+		schedule_work(&motg->sm_work);
+	}
+
+	if (!test_bit(ID, &motg->inputs) || test_bit(ID_A, &motg->inputs))
+		mod_timer(&motg->id_timer, ID_TIMER_FREQ);
+}
+
 static bool msm_chg_check_secondary_det(struct msm_otg *motg)
 {
 	struct otg_transceiver *otg = &motg->otg;
@@ -1260,7 +1375,7 @@
 		break;
 	case SNPS_28NM_INTEGRATED_PHY:
 		/* Clear charger detecting control bits */
-		ulpi_write(otg, 0x3F, 0x86);
+		ulpi_write(otg, 0x1F, 0x86);
 		/* Clear alt interrupt latch and enable bits */
 		ulpi_write(otg, 0x1F, 0x92);
 		ulpi_write(otg, 0x1F, 0x95);
@@ -1329,7 +1444,6 @@
 	dev_dbg(otg->dev, "chg detection work\n");
 	switch (motg->chg_state) {
 	case USB_CHG_STATE_UNDEFINED:
-		pm_runtime_get_sync(otg->dev);
 		msm_chg_block_on(motg);
 		msm_chg_enable_dcd(motg);
 		msm_chg_enable_aca_det(motg);
@@ -1364,18 +1478,23 @@
 		break;
 	case USB_CHG_STATE_DCD_DONE:
 		vout = msm_chg_check_primary_det(motg);
-		is_aca = msm_chg_aca_detect(motg);
-		if (is_aca) {
-			if (vout && test_bit(ID_A, &motg->inputs))
-				motg->chg_type = USB_ACA_DOCK_CHARGER;
-			delay = 0;
-			break;
-		}
 		if (vout) {
+			if (test_bit(ID_A, &motg->inputs)) {
+				motg->chg_type = USB_ACA_DOCK_CHARGER;
+				motg->chg_state = USB_CHG_STATE_DETECTED;
+				delay = 0;
+				break;
+			}
 			msm_chg_enable_secondary_det(motg);
 			delay = MSM_CHG_SECONDARY_DET_TIME;
 			motg->chg_state = USB_CHG_STATE_PRIMARY_DONE;
 		} else {
+			if (test_bit(ID_A, &motg->inputs)) {
+				motg->chg_type = USB_ACA_A_CHARGER;
+				motg->chg_state = USB_CHG_STATE_DETECTED;
+				delay = 0;
+				break;
+			}
 			motg->chg_type = USB_SDP_CHARGER;
 			motg->chg_state = USB_CHG_STATE_DETECTED;
 			delay = 0;
@@ -1431,10 +1550,18 @@
 				clear_bit(B_SESS_VLD, &motg->inputs);
 			}
 		} else {
-			if (otgsc & OTGSC_ID)
-				set_bit(ID, &motg->inputs);
-			else
-				clear_bit(ID, &motg->inputs);
+			if (aca_enabled()) {
+				if (irq_read_line(motg->pdata->pmic_id_irq))
+					set_bit(ID, &motg->inputs);
+				else
+					clear_bit(ID, &motg->inputs);
+
+			} else {
+				if (otgsc & OTGSC_ID)
+					set_bit(ID, &motg->inputs);
+				else
+					clear_bit(ID, &motg->inputs);
+			}
 
 			if (otgsc & OTGSC_BSV)
 				set_bit(B_SESS_VLD, &motg->inputs);
@@ -1462,6 +1589,7 @@
 	struct msm_otg *motg = container_of(w, struct msm_otg, sm_work);
 	struct otg_transceiver *otg = &motg->otg;
 
+	pm_runtime_resume(otg->dev);
 	switch (otg->state) {
 	case OTG_STATE_UNDEFINED:
 		dev_dbg(otg->dev, "OTG_STATE_UNDEFINED state\n");
@@ -1473,15 +1601,26 @@
 		dev_dbg(otg->dev, "OTG_STATE_B_IDLE state\n");
 		if ((!test_bit(ID, &motg->inputs) ||
 				test_bit(ID_A, &motg->inputs)) && otg->host) {
-			/* disable BSV bit */
-			writel(readl(USB_OTGSC) & ~OTGSC_BSVIE, USB_OTGSC);
 			if (motg->chg_type == USB_ACA_DOCK_CHARGER)
 				msm_otg_notify_charger(motg,
-						IDEV_CHG_MAX);
-			else if (!test_bit(ID_A, &motg->inputs) &&
-					motg->pdata->vbus_power)
+						IDEV_ACA_CHG_MAX);
+			else if (test_bit(ID_A, &motg->inputs))
+				msm_otg_notify_charger(motg,
+						IDEV_ACA_CHG_MAX - IUNIT);
+			else if (motg->pdata->vbus_power)
 				motg->pdata->vbus_power(1);
 			msm_otg_start_host(otg, 1);
+			/*
+			 * Link can not generate PHY_ALT interrupt
+			 * in host mode when no device is attached
+			 * to the port.  It is also observed PHY_ALT
+			 * interrupt missing upon Micro-A cable disconnect.
+			 * Hence disable PHY_ALT interrupt and perform
+			 * polling to detect RID change.
+			 */
+			msm_chg_enable_aca_det(motg);
+			msm_chg_disable_aca_intr(motg);
+			mod_timer(&motg->id_timer, ID_TIMER_FREQ);
 			otg->state = OTG_STATE_A_HOST;
 		} else if (test_bit(B_SESS_VLD, &motg->inputs)) {
 			switch (motg->chg_state) {
@@ -1491,17 +1630,31 @@
 			case USB_CHG_STATE_DETECTED:
 				switch (motg->chg_type) {
 				case USB_DCP_CHARGER:
+					msm_otg_notify_charger(motg,
+							IDEV_CHG_MAX);
+					pm_runtime_put_noidle(otg->dev);
+					pm_runtime_suspend(otg->dev);
+					break;
 				case USB_ACA_B_CHARGER:
 					msm_otg_notify_charger(motg,
-							IDEV_CHG_MAX);
+							IDEV_ACA_CHG_MAX);
+					/*
+					 * (ID_B --> ID_C) PHY_ALT interrupt can
+					 * not be detected in LPM.
+					 */
 					break;
 				case USB_CDP_CHARGER:
-				case USB_ACA_C_CHARGER:
 					msm_otg_notify_charger(motg,
 							IDEV_CHG_MAX);
 					msm_otg_start_peripheral(otg, 1);
 					otg->state = OTG_STATE_B_PERIPHERAL;
 					break;
+				case USB_ACA_C_CHARGER:
+					msm_otg_notify_charger(motg,
+							IDEV_ACA_CHG_MAX);
+					msm_otg_start_peripheral(otg, 1);
+					otg->state = OTG_STATE_B_PERIPHERAL;
+					break;
 				case USB_SDP_CHARGER:
 					msm_otg_notify_charger(motg, IUNIT);
 					msm_otg_start_peripheral(otg, 1);
@@ -1515,39 +1668,25 @@
 				break;
 			}
 		} else {
-			/*
-			 * If charger detection work is pending, decrement
-			 * the pm usage counter to balance with the one that
-			 * is incremented in charger detection work.
-			 */
-			if (cancel_delayed_work_sync(&motg->chg_work)) {
-				pm_runtime_put_sync(otg->dev);
-				msm_otg_reset(otg);
-			}
+			cancel_delayed_work_sync(&motg->chg_work);
 			msm_otg_notify_charger(motg, 0);
 			motg->chg_state = USB_CHG_STATE_UNDEFINED;
 			motg->chg_type = USB_INVALID_CHARGER;
+			msm_otg_reset(otg);
+			pm_runtime_put_noidle(otg->dev);
+			pm_runtime_suspend(otg->dev);
 		}
-		pm_runtime_put_sync(otg->dev);
 		break;
 	case OTG_STATE_B_PERIPHERAL:
 		dev_dbg(otg->dev, "OTG_STATE_B_PERIPHERAL state\n");
 		if (!test_bit(B_SESS_VLD, &motg->inputs) ||
 				!test_bit(ID, &motg->inputs) ||
 				!test_bit(ID_C, &motg->inputs)) {
-			msm_otg_notify_charger(motg, 0);
 			msm_otg_start_peripheral(otg, 0);
-			if (!test_bit(ID_B, &motg->inputs) &&
-				!test_bit(ID_A, &motg->inputs)) {
-				motg->chg_state = USB_CHG_STATE_UNDEFINED;
-				motg->chg_type = USB_INVALID_CHARGER;
-			}
 			otg->state = OTG_STATE_B_IDLE;
-			msm_otg_reset(otg);
 			schedule_work(w);
 		} else if (test_bit(ID_C, &motg->inputs)) {
-			msm_otg_notify_charger(motg, IDEV_CHG_MAX);
-			pm_runtime_put_sync(otg->dev);
+			msm_otg_notify_charger(motg, IDEV_ACA_CHG_MAX);
 		}
 		break;
 	case OTG_STATE_A_HOST:
@@ -1555,29 +1694,39 @@
 		if (test_bit(ID, &motg->inputs) &&
 				!test_bit(ID_A, &motg->inputs)) {
 			msm_otg_start_host(otg, 0);
-			writel(readl(USB_OTGSC) & ~OTGSC_BSVIE, USB_OTGSC);
-			if (motg->pdata->vbus_power)
+			if (motg->pdata->vbus_power) {
 				motg->pdata->vbus_power(0);
-			motg->chg_state = USB_CHG_STATE_UNDEFINED;
-			motg->chg_type = USB_INVALID_CHARGER;
+				msleep(100); /* TA_WAIT_VFALL */
+			}
+			/*
+			 * Exit point of host mode.
+			 *
+			 * 1. Micro-A cable disconnect: Just schedule
+			 * the work. PHY is reset in B_IDLE and LPM
+			 * is allowed.
+			 * 2. ID_GND --> ID_B: No need to reset the PHY.
+			 * HCD core clears all PORTSC bits and initializes
+			 * the controller to host mode in remove_hcd.
+			 * Restore PORTSC transceiver select bits (ULPI)
+			 * and reset the controller to change MODE bits.
+			 * PHY_ALT interrupt can not occur in host mode.
+			 */
+			del_timer_sync(&motg->id_timer);
+			if (motg->chg_state != USB_CHG_STATE_UNDEFINED) {
+				msm_otg_link_reset(motg);
+				msm_chg_enable_aca_intr(motg);
+			}
 			otg->state = OTG_STATE_B_IDLE;
-			msm_otg_reset(otg);
 			schedule_work(w);
 		} else if (test_bit(ID_A, &motg->inputs)) {
-			writel(readl(USB_OTGSC) & ~OTGSC_BSVIE, USB_OTGSC);
 			if (motg->pdata->vbus_power)
 				motg->pdata->vbus_power(0);
 			msm_otg_notify_charger(motg,
-					IDEV_CHG_MIN - motg->mA_port);
-			pm_runtime_put_sync(otg->dev);
+					IDEV_ACA_CHG_MAX - motg->mA_port);
 		} else if (!test_bit(ID, &motg->inputs)) {
-			motg->chg_state = USB_CHG_STATE_UNDEFINED;
-			motg->chg_type = USB_INVALID_CHARGER;
 			msm_otg_notify_charger(motg, 0);
-			writel(readl(USB_OTGSC) & ~OTGSC_BSVIE, USB_OTGSC);
 			if (motg->pdata->vbus_power)
 				motg->pdata->vbus_power(1);
-			pm_runtime_put_sync(otg->dev);
 		}
 		break;
 	default:
@@ -1594,15 +1743,16 @@
 	if (atomic_read(&motg->in_lpm)) {
 		disable_irq_nosync(irq);
 		motg->async_int = 1;
-		pm_runtime_get(otg->dev);
+		pm_request_resume(otg->dev);
 		return IRQ_HANDLED;
 	}
 
 	usbsts = readl(USB_USBSTS);
 	if ((usbsts & PHY_ALT_INT)) {
+		dev_dbg(otg->dev, "PHY_ALT interrupt\n");
 		writel(PHY_ALT_INT, USB_USBSTS);
 		if (msm_chg_check_aca_intr(motg)) {
-			pm_runtime_get_noresume(otg->dev);
+			dev_dbg(otg->dev, "ACA work from IRQ\n");
 			schedule_work(&motg->sm_work);
 		}
 		return IRQ_HANDLED;
@@ -1613,21 +1763,25 @@
 		return IRQ_NONE;
 
 	if ((otgsc & OTGSC_IDIS) && (otgsc & OTGSC_IDIE)) {
-		if (otgsc & OTGSC_ID)
+		if (otgsc & OTGSC_ID) {
+			dev_dbg(otg->dev, "ID set\n");
 			set_bit(ID, &motg->inputs);
-		else
+		} else {
+			dev_dbg(otg->dev, "ID clear\n");
 			clear_bit(ID, &motg->inputs);
-		dev_dbg(otg->dev, "ID set/clear\n");
+			msm_chg_enable_aca_det(motg);
+		}
 		schedule_work(&motg->sm_work);
-		pm_runtime_get_noresume(otg->dev);
 	} else if ((otgsc & OTGSC_BSVIS) && (otgsc & OTGSC_BSVIE)) {
-		if (otgsc & OTGSC_BSV)
+		if (otgsc & OTGSC_BSV) {
+			dev_dbg(otg->dev, "BSV set\n");
 			set_bit(B_SESS_VLD, &motg->inputs);
-		else
+		} else {
+			dev_dbg(otg->dev, "BSV clear\n");
 			clear_bit(B_SESS_VLD, &motg->inputs);
-		dev_dbg(otg->dev, "BSV set/clear\n");
+			msm_chg_check_aca_intr(motg);
+		}
 		schedule_work(&motg->sm_work);
-		pm_runtime_get_noresume(otg->dev);
 	}
 
 	writel(otgsc, USB_OTGSC);
@@ -1749,7 +1903,7 @@
 		goto out;
 	}
 
-	pm_runtime_get_sync(otg->dev);
+	pm_runtime_resume(otg->dev);
 	schedule_work(&motg->sm_work);
 out:
 	return status;
@@ -1783,9 +1937,51 @@
 	.release = single_release,
 };
 
+static int msm_otg_aca_show(struct seq_file *s, void *unused)
+{
+	if (debug_aca_enabled)
+		seq_printf(s, "enabled\n");
+	else
+		seq_printf(s, "disabled\n");
+
+	return 0;
+}
+
+static int msm_otg_aca_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, msm_otg_aca_show, inode->i_private);
+}
+
+static ssize_t msm_otg_aca_write(struct file *file, const char __user *ubuf,
+				size_t count, loff_t *ppos)
+{
+	char buf[8];
+
+	memset(buf, 0x00, sizeof(buf));
+
+	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
+		return -EFAULT;
+
+	if (!strncmp(buf, "enable", 6))
+		debug_aca_enabled = true;
+	else
+		debug_aca_enabled = false;
+
+	return count;
+}
+
+const struct file_operations msm_otg_aca_fops = {
+	.open = msm_otg_aca_open,
+	.read = seq_read,
+	.write = msm_otg_aca_write,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
 static struct dentry *msm_otg_dbg_root;
 static struct dentry *msm_otg_dbg_mode;
 static struct dentry *msm_otg_chg_type;
+static struct dentry *msm_otg_dbg_aca;
 
 static int msm_otg_debugfs_init(struct msm_otg *motg)
 {
@@ -1814,10 +2010,16 @@
 		&msm_otg_chg_fops);
 
 	if (!msm_otg_chg_type) {
-		debugfs_remove(msm_otg_dbg_mode);
-		debugfs_remove(msm_otg_dbg_root);
-		msm_otg_dbg_root = NULL;
-		msm_otg_dbg_mode = NULL;
+		debugfs_remove_recursive(msm_otg_dbg_root);
+		return -ENODEV;
+	}
+
+	msm_otg_dbg_aca = debugfs_create_file("aca", S_IRUGO | S_IWUSR,
+		msm_otg_dbg_root, motg,
+		&msm_otg_aca_fops);
+
+	if (!msm_otg_dbg_aca) {
+		debugfs_remove_recursive(msm_otg_dbg_root);
 		return -ENODEV;
 	}
 
@@ -1853,6 +2055,17 @@
 	otg = &motg->otg;
 	otg->dev = &pdev->dev;
 
+	/*
+	 * ACA ID_GND threshold range is overlapped with OTG ID_FLOAT.  Hence
+	 * PHY treat ACA ID_GND as float and no interrupt is generated.  But
+	 * PMIC can detect ACA ID_GND and generate an interrupt.
+	 */
+	if (aca_enabled() && motg->pdata->otg_control != OTG_PMIC_CONTROL) {
+		dev_err(&pdev->dev, "ACA can not be enabled without PMIC\n");
+		ret = -EINVAL;
+		goto free_motg;
+	}
+
 	/* Some targets don't support PHY clock. */
 	motg->phy_reset_clk = clk_get(&pdev->dev, "usb_phy_clk");
 	if (IS_ERR(motg->phy_reset_clk))
@@ -1962,6 +2175,8 @@
 	wake_lock_init(&motg->wlock, WAKE_LOCK_SUSPEND, "msm_otg");
 	INIT_WORK(&motg->sm_work, msm_otg_sm_work);
 	INIT_DELAYED_WORK(&motg->chg_work, msm_chg_detect_work);
+	setup_timer(&motg->id_timer, msm_otg_id_timer_func,
+				(unsigned long) motg);
 	ret = request_irq(motg->irq, msm_otg_irq, IRQF_SHARED,
 					"msm_otg", motg);
 	if (ret) {
@@ -1973,6 +2188,7 @@
 	otg->set_host = msm_otg_set_host;
 	otg->set_peripheral = msm_otg_set_peripheral;
 	otg->set_power = msm_otg_set_power;
+	otg->set_suspend = msm_otg_set_suspend;
 
 	otg->io_ops = &msm_otg_io_ops;
 
@@ -2059,7 +2275,7 @@
 put_phy_reset_clk:
 	if (!IS_ERR(motg->phy_reset_clk))
 		clk_put(motg->phy_reset_clk);
-
+free_motg:
 	kfree(motg);
 	return ret;
 }
@@ -2145,16 +2361,10 @@
 
 	dev_dbg(dev, "OTG runtime idle\n");
 
-	/*
-	 * It is observed some times that a spurious interrupt
-	 * comes when PHY is put into LPM immediately after PHY reset.
-	 * This 1 sec delay also prevents entering into LPM immediately
-	 * after asynchronous interrupt.
-	 */
-	if (otg->state != OTG_STATE_UNDEFINED)
-		pm_schedule_suspend(dev, 1000);
-
-	return -EAGAIN;
+	if (otg->state == OTG_STATE_UNDEFINED)
+		return -EAGAIN;
+	else
+		return 0;
 }
 
 static int msm_otg_runtime_suspend(struct device *dev)
@@ -2170,6 +2380,7 @@
 	struct msm_otg *motg = dev_get_drvdata(dev);
 
 	dev_dbg(dev, "OTG runtime resume\n");
+	pm_runtime_get_noresume(dev);
 	return msm_otg_resume(motg);
 }
 #endif
@@ -2177,10 +2388,18 @@
 #ifdef CONFIG_PM_SLEEP
 static int msm_otg_pm_suspend(struct device *dev)
 {
-	struct msm_otg *motg = dev_get_drvdata(dev);
+	int ret;
 
 	dev_dbg(dev, "OTG PM suspend\n");
-	return msm_otg_suspend(motg);
+
+#ifdef CONFIG_PM_RUNTIME
+	ret = pm_runtime_suspend(dev);
+	if (ret > 0)
+		ret = 0;
+#else
+	ret =  msm_otg_suspend(dev_get_drvdata(dev));
+#endif
+	return ret;
 }
 
 static int msm_otg_pm_resume(struct device *dev)
diff --git a/drivers/video/msm/mdp.h b/drivers/video/msm/mdp.h
index c12a250..8817213 100644
--- a/drivers/video/msm/mdp.h
+++ b/drivers/video/msm/mdp.h
@@ -737,6 +737,10 @@
 {
 	/* empty */
 }
+static inline int mdp4_overlay_dsi_state_get(void)
+{
+	return 0;
+}
 #endif
 
 #endif /* MDP_H */
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index d757b5d..0aeb91e 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -410,6 +410,7 @@
 void mdp4_overlay0_done_dsi_cmd(struct mdp_dma_data *dma);
 void mdp4_dsi_cmd_overlay(struct msm_fb_data_type *mfd);
 void mdp4_overlay_dsi_state_set(int state);
+int mdp4_overlay_dsi_state_get(void);
 void mdp4_overlay_rgb_setup(struct mdp4_overlay_pipe *pipe);
 void mdp4_overlay_reg_flush(struct mdp4_overlay_pipe *pipe, int all);
 void mdp4_mixer_blend_setup(struct mdp4_overlay_pipe *pipe);
diff --git a/drivers/video/msm/mdp4_overlay_dsi_cmd.c b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
index 0020fd5..07322dc 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_cmd.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
@@ -56,6 +56,11 @@
 	spin_unlock_irqrestore(&mdp_spin_lock, flag);
 }
 
+int mdp4_overlay_dsi_state_get(void)
+{
+	return dsi_state;
+}
+
 static void dsi_clock_tout(unsigned long data)
 {
 	if (mipi_dsi_clk_on) {
@@ -530,6 +535,7 @@
 	/* mutex holded by caller */
 	if (dsi_mfd && dsi_pipe) {
 		mdp4_dsi_cmd_dma_busy_wait(dsi_mfd);
+		mipi_dsi_mdp_busy_wait(dsi_mfd);
 		mdp4_overlay_update_dsi_cmd(dsi_mfd);
 
 		if (dsi_pipe->blt_addr)
diff --git a/drivers/video/msm/mipi_dsi.c b/drivers/video/msm/mipi_dsi.c
index 00256e6..aa210f1 100644
--- a/drivers/video/msm/mipi_dsi.c
+++ b/drivers/video/msm/mipi_dsi.c
@@ -137,7 +137,7 @@
 	else
 		up(&mfd->dma->mutex);
 
-	pr_debug("%s:\n", __func__);
+	pr_debug("%s-:\n", __func__);
 
 	return ret;
 }
@@ -171,11 +171,6 @@
 	clk_rate = mfd->fbi->var.pixclock;
 	clk_rate = min(clk_rate, mfd->panel_info.clk_max);
 
-
-#ifndef CONFIG_FB_MSM_MDP303
-	mdp4_overlay_dsi_state_set(ST_DSI_RESUME);
-#endif
-
 	MIPI_OUTP(MIPI_DSI_BASE + 0x114, 1);
 	MIPI_OUTP(MIPI_DSI_BASE + 0x114, 0);
 
@@ -266,6 +261,11 @@
 		wmb();
 	}
 
+	if (mdp_rev >= MDP_REV_41)
+		mutex_lock(&mfd->dma->ov_mutex);
+	else
+		down(&mfd->dma->mutex);
+
 	ret = panel_next_on(pdev);
 
 	mipi_dsi_op_mode_config(mipi->mode);
@@ -320,6 +320,16 @@
 #ifdef CONFIG_MSM_BUS_SCALING
 	mdp_bus_scale_update_request(2);
 #endif
+
+	mdp4_overlay_dsi_state_set(ST_DSI_RESUME);
+
+	if (mdp_rev >= MDP_REV_41)
+		mutex_unlock(&mfd->dma->ov_mutex);
+	else
+		up(&mfd->dma->mutex);
+
+	pr_debug("%s-:\n", __func__);
+
 	return ret;
 }
 
diff --git a/drivers/video/msm/mipi_novatek.c b/drivers/video/msm/mipi_novatek.c
index cb4bd1b..5e2e515 100644
--- a/drivers/video/msm/mipi_novatek.c
+++ b/drivers/video/msm/mipi_novatek.c
@@ -439,6 +439,10 @@
 		return;
 
 	mutex_lock(&mfd->dma->ov_mutex);
+	if (mdp4_overlay_dsi_state_get() <= ST_DSI_SUSPEND) {
+		mutex_unlock(&mfd->dma->ov_mutex);
+		return;
+	}
 	/* mdp4_dsi_cmd_busy_wait: will turn on dsi clock also */
 	mdp4_dsi_cmd_dma_busy_wait(mfd);
 	mdp4_dsi_blt_dmap_busy_wait(mfd);
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h
index c388407..e5a5a84 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h
@@ -195,6 +195,7 @@
 	struct vcd_buffer_requirement actual_output_buf_req;
 	struct vcd_buffer_requirement min_output_buf_req;
 	struct vcd_buffer_requirement client_output_buf_req;
+	u32 idr_only_decoding;
 };
 
 union ddl_codec_data {
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c
index ad2fd37..e17107e 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c
@@ -356,6 +356,11 @@
 	case ACTIVE_SPS_NOT_PRESENT:
 	case ACTIVE_PPS_NOT_PRESENT:
 		{
+			if (ddl->codec_data.decoder.idr_only_decoding) {
+				DBG("Consider warnings as errors in idr mode");
+				ddl_client_fatal_cb(ddl_context);
+				return true;
+			}
 			vcd_status = VCD_ERR_BITSTREAM_ERR;
 			break;
 		}
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c
index 6343202..f09bd71 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c
@@ -807,8 +807,13 @@
 		}
 	case VCD_CODEC_H264:
 		{
-			comv_buf_no =
-			    decoder->client_output_buf_req.actual_count;
+			if (decoder->idr_only_decoding)
+				comv_buf_no = decoder->min_dpb_num;
+			else
+				comv_buf_no =
+					decoder->
+					client_output_buf_req.
+					actual_count;
 			break;
 		}
 	}
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c
index 2899df6..2ec8419 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c
@@ -124,6 +124,7 @@
 	u32 loopc;
 	struct ddl_frame_data_tag *found_frame = NULL;
 	struct ddl_mask *dpb_mask = &decoder->dpb_mask;
+	u32 temp_mask;
 
 	switch (operation) {
 	case DDL_DPB_OP_MARK_BUSY:
@@ -145,13 +146,17 @@
 
 			if (found_frame) {
 				if (operation == DDL_DPB_OP_MARK_BUSY) {
-					dpb_mask->hw_mask &=
-					    (~(0x1 << loopc));
+					temp_mask = (~(0x1 << loopc));
+					if (decoder->idr_only_decoding)
+						temp_mask = ~(0xffffffff);
+					dpb_mask->hw_mask &= temp_mask;
 					*in_out_frame = *found_frame;
 				} else if (operation ==
 					DDL_DPB_OP_MARK_FREE) {
-					dpb_mask->client_mask |=
-					    (0x1 << loopc);
+					temp_mask = (0x1 << loopc);
+					if (decoder->idr_only_decoding)
+						temp_mask = 0xffffffff;
+					dpb_mask->client_mask |= temp_mask;
 					*found_frame = *in_out_frame;
 				}
 			} else {
@@ -172,29 +177,35 @@
 		}
 	case DDL_DPB_OP_INIT:
 		{
-			u32 dpb_size;
+			u32 dpb_size, index, num_dpb;
 			dpb_size = (!decoder->meta_data_offset) ?
 			    decoder->dp_buf.dec_pic_buffers[0].vcd_frm.
 			    alloc_len : decoder->meta_data_offset;
-			vidc_720p_decode_set_dpb_details(decoder->dp_buf.
-						  no_of_dec_pic_buf,
+			if (decoder->idr_only_decoding)
+				num_dpb = decoder->min_dpb_num;
+			else
+				num_dpb = decoder->dp_buf.no_of_dec_pic_buf;
+			vidc_720p_decode_set_dpb_details(
+						  num_dpb,
 						  dpb_size,
 						  decoder->ref_buffer.
 						  align_physical_addr);
-			for (loopc = 0;
-			     loopc < decoder->dp_buf.no_of_dec_pic_buf;
-			     ++loopc) {
+			for (loopc = 0; loopc < num_dpb; ++loopc) {
+				if (decoder->idr_only_decoding)
+					index = 0;
+				else
+					index = loopc;
 				vidc_720p_decode_set_dpb_buffers(loopc,
 							  (u32 *)
 							  decoder->
 							  dp_buf.
 							  dec_pic_buffers
-							  [loopc].
+							  [index].
 							  vcd_frm.
 							  physical);
-				VIDC_LOG1("DEC_DPB_BUFn_SIZE",
+				VIDC_LOG1("DEC_DPB_BUFn_SIZE=%d",
 					   decoder->dp_buf.
-					   dec_pic_buffers[loopc].vcd_frm.
+					   dec_pic_buffers[index].vcd_frm.
 					   alloc_len);
 			}
 			break;
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c
index 17c2028..d1b1952 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c
@@ -365,6 +365,18 @@
 			}
 			break;
 		}
+	case VCD_I_DEC_PICTYPE:
+		{
+			if ((sizeof(u32) == property_hdr->sz) &&
+				DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) {
+				decoder->idr_only_decoding =
+					*(u32 *)property_value;
+				ddl_set_default_decoder_buffer_req(
+						decoder, true);
+				vcd_status = VCD_S_SUCCESS;
+			}
+		}
+		break;
 	case VCD_I_FRAME_RATE:
 		{
 			vcd_status = VCD_S_SUCCESS;
@@ -1462,6 +1474,7 @@
 	decoder->client_frame_size.stride = 176;
 	decoder->client_frame_size.scan_lines = 144;
 	decoder->progressive_only = 1;
+	decoder->idr_only_decoding = 0;
 	decoder->profile.profile = VCD_PROFILE_UNKNOWN;
 	decoder->level.level = VCD_LEVEL_UNKNOWN;
 	decoder->output_order = VCD_DEC_ORDER_DISPLAY;
@@ -1689,18 +1702,24 @@
 		min_dpb = decoder->min_dpb_num;
 	}
 
+	if (decoder->idr_only_decoding)
+		min_dpb = 1;
+
 	memset(output_buf_req, 0, sizeof(struct vcd_buffer_requirement));
 
 	output_buf_req->min_count = min_dpb;
 
 	num_mb = DDL_NO_OF_MB(frame_size->width, frame_size->height);
-	if (num_mb >= DDL_WVGA_MBS) {
-		output_buf_req->actual_count = min_dpb + 2;
-		if (output_buf_req->actual_count < 10)
-			output_buf_req->actual_count = 10;
-	} else
-		output_buf_req->actual_count = min_dpb + 5;
-
+	if (decoder->idr_only_decoding) {
+		output_buf_req->actual_count = output_buf_req->min_count;
+	} else {
+		if (num_mb >= DDL_WVGA_MBS) {
+			output_buf_req->actual_count = min_dpb + 2;
+			if (output_buf_req->actual_count < 10)
+				output_buf_req->actual_count = 10;
+		} else
+			output_buf_req->actual_count = min_dpb + 5;
+	}
 	output_buf_req->max_count = DDL_MAX_BUFFER_COUNT;
 	output_buf_req->sz = y_cb_cr_size;
 	if (decoder->buf_format.buffer_format != VCD_BUFFER_FORMAT_NV12)
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
index f8fb0fa..4c477cb 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -523,8 +523,8 @@
 		config->map_dev_base_addr
 		|| dev_ctxt->config.un_map_dev_base_addr !=
 		config->un_map_dev_base_addr) {
-		VCD_MSG_ERROR("Device config mismatch");
-		VCD_MSG_HIGH("VCD will be using config from 1st vcd_init");
+		VCD_MSG_HIGH("Device config mismatch. "
+			"VCD will be using config from 1st vcd_init");
 	}
 
 	*driver_handle = 0;
diff --git a/include/linux/slimbus/slimbus.h b/include/linux/slimbus/slimbus.h
index 26ca79a..2b5adb3 100644
--- a/include/linux/slimbus/slimbus.h
+++ b/include/linux/slimbus/slimbus.h
@@ -83,6 +83,12 @@
 #define SLIM_MSG_MC_NEXT_REMOVE_CHANNEL          0x58
 #define SLIM_MSG_MC_RECONFIGURE_NOW              0x5F
 
+/*
+ * Clock pause flag to indicate that the reconfig message
+ * corresponds to clock pause sequence
+ */
+#define SLIM_MSG_CLK_PAUSE_SEQ_FLG		(1U << 8)
+
 /* Value management messages */
 #define SLIM_MSG_MC_REQUEST_VALUE                0x60
 #define SLIM_MSG_MC_REQUEST_CHANGE_VALUE         0x61
@@ -150,7 +156,9 @@
  * For the header information, refer to Table 34-36.
  * @rl: Header field. remaining length.
  * @mt: Header field. Message type.
- * @mc: Header field. Message code for type mt.
+ * @mc: Header field. LSB is message code for type mt. Framework will set MSB to
+ *	SLIM_MSG_CLK_PAUSE_SEQ_FLG in case "mc" in the reconfiguration sequence
+ *	is for pausing the clock.
  * @dt: Header field. Destination type.
  * @ec: Element size. Used for elemental access APIs.
  * @len: Length of payload. (excludes ec)
@@ -166,7 +174,7 @@
 struct slim_msg_txn {
 	u8			rl;
 	u8			mt;
-	u8			mc;
+	u16			mc;
 	u8			dt;
 	u16			ec;
 	u8			len;
@@ -670,7 +678,7 @@
  */
 extern int slim_xfer_msg(struct slim_controller *ctrl,
 			struct slim_device *sbdev, struct slim_ele_access *msg,
-			u8 mc, u8 *rbuf, const u8 *wbuf, u8 len);
+			u16 mc, u8 *rbuf, const u8 *wbuf, u8 len);
 /* end of message apis */
 
 /* Port management for manager device APIs */
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 955d229..2ee6632 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -72,6 +72,9 @@
 #define IDEV_CHG_MIN	500
 #define IUNIT		100
 
+#define IDEV_ACA_CHG_MAX	1500
+#define IDEV_ACA_CHG_LIMIT	500
+
 /**
  * Different states involved in USB charger detection.
  *
@@ -185,6 +188,7 @@
  *             connected. Useful only when ACA_A charger is
  *             connected.
  * @mA_port: The amount of current drawn by the attached B-device.
+ * @id_timer: The timer used for polling ID line to detect ACA states.
  */
 struct msm_otg {
 	struct otg_transceiver otg;
@@ -214,6 +218,7 @@
 	struct wake_lock wlock;
 	struct notifier_block usbdev_nb;
 	unsigned mA_port;
+	struct timer_list id_timer;
 	unsigned long caps;
 	/*
 	 * Allowing PHY power collpase turns off the HSUSB 3.3v and 1.8v
diff --git a/include/linux/usb/msm_hsusb_hw.h b/include/linux/usb/msm_hsusb_hw.h
index 79b0415..9cb8356 100644
--- a/include/linux/usb/msm_hsusb_hw.h
+++ b/include/linux/usb/msm_hsusb_hw.h
@@ -54,6 +54,7 @@
 
 /* OTG definitions */
 #define OTGSC_INTSTS_MASK	(0x7f << 16)
+#define OTGSC_IDPU		(1 << 5)
 #define OTGSC_ID		(1 << 8)
 #define OTGSC_BSV		(1 << 11)
 #define OTGSC_IDIS		(1 << 16)
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 384c3ca..65ca534 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -13,6 +13,9 @@
 #include <linux/time.h>
 #endif
 
+#ifdef __KERNEL__
+#include <linux/ion.h>
+#endif
 #define MSM_CAM_IOCTL_MAGIC 'm'
 
 #define MSM_CAM_IOCTL_GET_SENSOR_INFO \
@@ -522,6 +525,9 @@
 	uint32_t frame_id;
 	int stcam_quality_ind;
 	uint32_t stcam_conv_value;
+
+	struct ion_allocation_data ion_alloc;
+	struct ion_fd_data fd_data;
 };
 
 enum msm_st_frame_packing {
diff --git a/sound/soc/msm/msm-pcm-afe.c b/sound/soc/msm/msm-pcm-afe.c
index a34b774..01b8463 100644
--- a/sound/soc/msm/msm-pcm-afe.c
+++ b/sound/soc/msm/msm-pcm-afe.c
@@ -149,8 +149,6 @@
 			}
 			case AFE_EVENT_RTPORT_STOP:
 				pr_debug("%s: event!=0\n", __func__);
-				prtd->start = 0;
-				snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
 				break;
 			case AFE_EVENT_RTPORT_LOW_WM:
 				pr_debug("%s: Underrun\n", __func__);
@@ -215,8 +213,6 @@
 		}
 		case AFE_EVENT_RTPORT_STOP:
 			pr_debug("%s: event!=0\n", __func__);
-			prtd->start = 0;
-			snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
 			break;
 		case AFE_EVENT_RTPORT_LOW_WM:
 			pr_debug("%s: Underrun\n", __func__);
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index dbd02e8..97d0760 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -761,6 +761,15 @@
 	msm_routing_put_voice_mixer),
 };
 
+static const struct snd_kcontrol_new hdmi_rx_voice_mixer_controls[] = {
+	SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_HDMI_RX,
+	MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
+	msm_routing_put_voice_mixer),
+	SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_HDMI_RX,
+	MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
+	msm_routing_put_voice_mixer),
+};
+
 static const struct snd_kcontrol_new tx_voice_mixer_controls[] = {
 	SOC_SINGLE_EXT("PRI_TX_Voice", MSM_BACKEND_DAI_PRI_I2S_TX,
 	MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
@@ -1077,6 +1086,10 @@
 				SND_SOC_NOPM, 0, 0,
 				aux_pcm_rx_voice_mixer_controls,
 				ARRAY_SIZE(aux_pcm_rx_voice_mixer_controls)),
+	SND_SOC_DAPM_MIXER("HDMI_RX_Voice Mixer",
+				SND_SOC_NOPM, 0, 0,
+				hdmi_rx_voice_mixer_controls,
+				ARRAY_SIZE(hdmi_rx_voice_mixer_controls)),
 	SND_SOC_DAPM_MIXER("Voice_Tx Mixer",
 				SND_SOC_NOPM, 0, 0, tx_voice_mixer_controls,
 				ARRAY_SIZE(tx_voice_mixer_controls)),
@@ -1162,6 +1175,10 @@
 	{"AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
 	{"AUX_PCM_RX", NULL, "AUX_PCM_RX_Voice Mixer"},
 
+	{"HDMI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
+	{"HDMI_RX_Voice Mixer", "Voip", "VOIP_DL"},
+	{"HDMI", NULL, "HDMI_RX_Voice Mixer"},
+
 	{"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"},
 	{"Voice_Tx Mixer", "SLIM_0_TX_Voice", "SLIMBUS_0_TX"},
 	{"Voice_Tx Mixer", "INTERNAL_BT_SCO_TX_Voice", "INT_BT_SCO_TX"},