Merge "usb: mdm_bridge: Do not submit subsequent tx URBs in case of -EPROTO" into msm-3.0
diff --git a/arch/arm/boot/dts/msmcopper.dts b/arch/arm/boot/dts/msmcopper.dts
index b00237a..fea1c52 100644
--- a/arch/arm/boot/dts/msmcopper.dts
+++ b/arch/arm/boot/dts/msmcopper.dts
@@ -10,26 +10,26 @@
 	intc: interrupt-controller@F9000000 {
 		compatible = "qcom,msm-qgic2";
 		interrupt-controller;
-		#interrupt-cells = <1>;
+		#interrupt-cells = <3>;
 		reg = <0xF9000000 0x1000>,
 		      <0xF9002000 0x1000>;
 	};
 
 	timer {
 		compatible = "qcom,msm-qtimer";
-		interrupts = <18>;
+		interrupts = <1 2 0>;
 	};
 
 	serial@F991F000 {
 		compatible = "qcom,msm-lsuart-v14";
 		reg = <0xF991F000 0x1000>;
-		interrupts = <109>;
+		interrupts = <0 109 0>;
 	};
 
 	usb@F9A55000 {
 		compatible = "qcom,hsusb-otg";
 		reg = <0xF9A55000 0x400>;
-		interrupts = <134>;
+		interrupts = <0 134 0>;
 
 		qcom,hsusb-otg-phy-type = <2>;
 		qcom,hsusb-otg-mode = <1>;
@@ -40,7 +40,7 @@
 		cell-index = <1>;
 		compatible = "qcom,msm-sdcc";
 		reg = <0xF980B000 0x1000>;
-		interrupts = <123>;
+		interrupts = <0 123 0>;
 
 		qcom,sdcc-clk-rates = <400000 24000000 48000000>;
 		qcom,sdcc-sup-voltages = <3300 3300>;
@@ -53,7 +53,7 @@
 		cell-index = <3>;
 		compatible = "qcom,msm-sdcc";
 		reg = <0xF984B000 0x1000>;
-		interrupts = <127>;
+		interrupts = <0 127 0>;
 
 		qcom,sdcc-clk-rates = <400000 24000000 48000000>;
 		qcom,sdcc-sup-voltages = <3300 3300>;
@@ -65,7 +65,7 @@
 		compatible = "qcom,msm_sps";
 		reg = <0xF9984000 0x15000>,
 		      <0xF9999000 0xB000>;
-		interrupts = <94>;
+		interrupts = <0 94 0>;
 
 		qcom,bam-dma-res-pipes = <6>;
 	};
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index d69305c..3421fa1 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -1,6 +1,7 @@
 CONFIG_EXPERIMENTAL=y
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SYSVIPC=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_CGROUPS=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 0780d20..21800fb 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -303,6 +303,7 @@
 CONFIG_MSM_CAMERA_FLASH_SC628A=y
 CONFIG_MSM_CAMERA_SENSOR=y
 CONFIG_MSM_ACTUATOR=y
+CONFIG_S5K3L1YX=y
 CONFIG_MSM_GEMINI=y
 CONFIG_RADIO_IRIS=y
 CONFIG_RADIO_IRIS_TRANSPORT=m
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index bd92fe3..6be8772 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -49,6 +49,9 @@
 CONFIG_MACH_MSM8627_MTP=y
 CONFIG_MACH_APQ8064_SIM=y
 CONFIG_MACH_APQ8064_RUMI3=y
+CONFIG_MACH_APQ8064_CDP=y
+CONFIG_MACH_APQ8064_MTP=y
+CONFIG_MACH_APQ8064_LIQUID=y
 # CONFIG_MSM_STACKED_MEMORY is not set
 CONFIG_KERNEL_PMEM_EBI_REGION=y
 # CONFIG_MSM_FIQ_SUPPORT is not set
@@ -306,6 +309,7 @@
 CONFIG_MSM_CAMERA_FLASH_SC628A=y
 CONFIG_MSM_CAMERA_SENSOR=y
 CONFIG_MSM_ACTUATOR=y
+CONFIG_S5K3L1YX=y
 CONFIG_MSM_GEMINI=y
 CONFIG_RADIO_IRIS=y
 CONFIG_RADIO_IRIS_TRANSPORT=m
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index b44f46f..bd6df88 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -21,7 +21,7 @@
 	const char		**dt_compat;	/* array of device tree
 						 * 'compatible' strings	*/
 
-	unsigned int		nr_irqs;	/* number of IRQs */
+	int			nr_irqs;	/* number of IRQs */
 
 	unsigned int		video_start;	/* start of video RAM	*/
 	unsigned int		video_end;	/* end of video RAM	*/
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 4468153..7561081 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -134,8 +134,18 @@
 #ifdef CONFIG_SPARSE_IRQ
 int __init arch_probe_nr_irqs(void)
 {
-	nr_irqs = machine_desc->nr_irqs ? machine_desc->nr_irqs : NR_IRQS;
-	return nr_irqs;
+	/*
+	 * machine_desc->nr_irqs < 0 is a special case that
+	 * specifies not to preallocate any irq_descs.
+	 */
+	if (machine_desc->nr_irqs < 0) {
+		nr_irqs = 0;
+		return nr_irqs;
+	} else {
+		nr_irqs = machine_desc->nr_irqs ?
+			  machine_desc->nr_irqs : NR_IRQS;
+		return nr_irqs;
+	}
 }
 #endif
 
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 9df90cd..f77e883 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -198,7 +198,6 @@
 config ARCH_APQ8064
 	bool "APQ8064"
 	select ARCH_MSM_KRAITMP
-	select MACH_APQ8064_SIM if !MACH_APQ8064_RUMI3
 	select MSM_V2_TLMM
 	select ARM_GIC
 	select CPU_V7
@@ -675,6 +674,24 @@
 	help
 	  Support for the Qualcomm APQ8064 RUMI3 emulator.
 
+config MACH_APQ8064_CDP
+	depends on ARCH_APQ8064
+	bool "APQ8064 CDP"
+	help
+	  Support for the Qualcomm APQ8064 CDP device.
+
+config MACH_APQ8064_MTP
+	depends on ARCH_APQ8064
+	bool "APQ8064 MTP"
+	help
+	  Support for the Qualcomm APQ8064 MTP device.
+
+config MACH_APQ8064_LIQUID
+	depends on ARCH_APQ8064
+	bool "APQ8064 LIQUID"
+	help
+	  Support for the Qualcomm APQ8064 LIQUID device.
+
 config MACH_FSM9XXX_SURF
 	depends on ARCH_FSM9XXX
 	depends on !MSM_STACKED_MEMORY
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 8b866d8..53b7dab 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -219,10 +219,10 @@
 obj-$(CONFIG_MACH_MSM7X27_SURF) += board-msm7x27.o devices-msm7x27.o
 obj-$(CONFIG_MACH_MSM7X27_FFA) += board-msm7x27.o devices-msm7x27.o
 obj-$(CONFIG_ARCH_MSM7X27A) += clock-pcom-lookup.o devices-msm7x27a.o
-obj-$(CONFIG_MACH_MSM7X27A_RUMI3) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o
-obj-$(CONFIG_MACH_MSM7X27A_SURF) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o
-obj-$(CONFIG_MACH_MSM7X27A_FFA) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o
-obj-$(CONFIG_MACH_MSM7627A_QRD1) += board-qrd7627a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o
+obj-$(CONFIG_MACH_MSM7X27A_RUMI3) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o
+obj-$(CONFIG_MACH_MSM7X27A_SURF) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o
+obj-$(CONFIG_MACH_MSM7X27A_FFA) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o
+obj-$(CONFIG_MACH_MSM7627A_QRD1) += board-qrd7627a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o
 obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o memory_topology.o
 obj-$(CONFIG_ARCH_MSM7X30) += clock-local.o clock-7x30.o acpuclock-7x30.o
 obj-$(CONFIG_MACH_MSM7X25_SURF) += board-msm7x27.o devices-msm7x25.o
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index 87c5047..9082b07 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -741,20 +741,18 @@
 {
 	int rc;
 
-	if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm8627()) {
-		rc = rpm_vreg_set_voltage(sc->vreg[VREG_HFPLL_A].rpm_vreg_id,
-				sc->vreg[VREG_HFPLL_A].rpm_vreg_voter, 2100000,
-				sc->vreg[VREG_HFPLL_A].max_vdd, 0);
-		if (rc)
-			pr_err("%s regulator enable failed (%d)\n",
-				sc->vreg[VREG_HFPLL_A].name, rc);
-		rc = rpm_vreg_set_voltage(sc->vreg[VREG_HFPLL_B].rpm_vreg_id,
-				sc->vreg[VREG_HFPLL_B].rpm_vreg_voter, 1800000,
-				sc->vreg[VREG_HFPLL_B].max_vdd, 0);
-		if (rc)
-			pr_err("%s regulator enable failed (%d)\n",
-				sc->vreg[VREG_HFPLL_B].name, rc);
-	}
+	rc = rpm_vreg_set_voltage(sc->vreg[VREG_HFPLL_A].rpm_vreg_id,
+			sc->vreg[VREG_HFPLL_A].rpm_vreg_voter, 2100000,
+			sc->vreg[VREG_HFPLL_A].max_vdd, 0);
+	if (rc)
+		pr_err("%s regulator enable failed (%d)\n",
+			sc->vreg[VREG_HFPLL_A].name, rc);
+	rc = rpm_vreg_set_voltage(sc->vreg[VREG_HFPLL_B].rpm_vreg_id,
+			sc->vreg[VREG_HFPLL_B].rpm_vreg_voter, 1800000,
+			sc->vreg[VREG_HFPLL_B].max_vdd, 0);
+	if (rc)
+		pr_err("%s regulator enable failed (%d)\n",
+			sc->vreg[VREG_HFPLL_B].name, rc);
 
 	/* Disable PLL bypass mode. */
 	writel_relaxed(0x2, sc->hfpll_base + HFPLL_MODE);
@@ -788,20 +786,18 @@
 	 */
 	writel_relaxed(0, sc->hfpll_base + HFPLL_MODE);
 
-	if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm8627()) {
-		rc = rpm_vreg_set_voltage(sc->vreg[VREG_HFPLL_B].rpm_vreg_id,
-				sc->vreg[VREG_HFPLL_B].rpm_vreg_voter, 0,
-				0, 0);
-		if (rc)
-			pr_err("%s regulator enable failed (%d)\n",
-				sc->vreg[VREG_HFPLL_B].name, rc);
-		rc = rpm_vreg_set_voltage(sc->vreg[VREG_HFPLL_A].rpm_vreg_id,
-				sc->vreg[VREG_HFPLL_A].rpm_vreg_voter, 0,
-				0, 0);
-		if (rc)
-			pr_err("%s regulator enable failed (%d)\n",
-				sc->vreg[VREG_HFPLL_A].name, rc);
-	}
+	rc = rpm_vreg_set_voltage(sc->vreg[VREG_HFPLL_B].rpm_vreg_id,
+			sc->vreg[VREG_HFPLL_B].rpm_vreg_voter, 0,
+			0, 0);
+	if (rc)
+		pr_err("%s regulator enable failed (%d)\n",
+			sc->vreg[VREG_HFPLL_B].name, rc);
+	rc = rpm_vreg_set_voltage(sc->vreg[VREG_HFPLL_A].rpm_vreg_id,
+			sc->vreg[VREG_HFPLL_A].rpm_vreg_voter, 0,
+			0, 0);
+	if (rc)
+		pr_err("%s regulator enable failed (%d)\n",
+			sc->vreg[VREG_HFPLL_A].name, rc);
 }
 
 /* Program the HFPLL rate. Assumes HFPLL is already disabled. */
@@ -1459,3 +1455,7 @@
 struct acpuclk_soc_data acpuclk_8930_soc_data __initdata = {
 	.init = acpuclk_8960_init,
 };
+
+struct acpuclk_soc_data acpuclk_8064_soc_data __initdata = {
+	.init = acpuclk_8960_init,
+};
diff --git a/arch/arm/mach-msm/acpuclock.h b/arch/arm/mach-msm/acpuclock.h
index 6ea691b..ef6c359 100644
--- a/arch/arm/mach-msm/acpuclock.h
+++ b/arch/arm/mach-msm/acpuclock.h
@@ -2,7 +2,7 @@
  * MSM architecture CPU clock driver header
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
  * Author: San Mehat <san@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -109,5 +109,6 @@
 extern struct acpuclk_soc_data acpuclk_9xxx_soc_data;
 extern struct acpuclk_soc_data acpuclk_9615_soc_data;
 extern struct acpuclk_soc_data acpuclk_8930_soc_data;
+extern struct acpuclk_soc_data acpuclk_8064_soc_data;
 
 #endif
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index 0e4c756..fa82e34 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -33,6 +33,7 @@
 #include <mach/msm_smsm.h>
 #include <mach/subsystem_notif.h>
 #include <mach/socinfo.h>
+#include <mach/subsystem_restart.h>
 
 #define BAM_CH_LOCAL_OPEN       0x1
 #define BAM_CH_REMOTE_OPEN      0x2
@@ -63,6 +64,7 @@
 static uint32_t bam_dmux_write_cpy_cnt;
 static uint32_t bam_dmux_write_cpy_bytes;
 static uint32_t bam_dmux_tx_sps_failure_cnt;
+static uint32_t bam_dmux_tx_stall_cnt;
 
 #define DBG(x...) do {		                 \
 		if (msm_bam_dmux_debug_enable)  \
@@ -96,12 +98,17 @@
 		bam_dmux_tx_sps_failure_cnt++;		\
 } while (0)
 
+#define DBG_INC_TX_STALL_CNT() do { \
+	bam_dmux_tx_stall_cnt++; \
+} while (0)
+
 #else
 #define DBG(x...) do { } while (0)
 #define DBG_INC_READ_CNT(x...) do { } while (0)
 #define DBG_INC_WRITE_CNT(x...) do { } while (0)
 #define DBG_INC_WRITE_CPY(x...) do { } while (0)
 #define DBG_INC_TX_SPS_FAILURE_CNT() do { } while (0)
+#define DBG_INC_TX_STALL_CNT() do { } while (0)
 #endif
 
 struct bam_ch_info {
@@ -158,6 +165,7 @@
 
 static LIST_HEAD(bam_rx_pool);
 static DEFINE_MUTEX(bam_rx_pool_mutexlock);
+static int bam_rx_pool_len;
 static LIST_HEAD(bam_tx_pool);
 static DEFINE_SPINLOCK(bam_tx_pool_spinlock);
 
@@ -355,36 +363,78 @@
 {
 	void *ptr;
 	struct rx_pkt_info *info;
-
-	if (in_global_reset)
-		return;
-
-	info = kmalloc(sizeof(struct rx_pkt_info), GFP_KERNEL);
-	if (!info) {
-		pr_err("%s: unable to alloc rx_pkt_info\n", __func__);
-		return;
-	}
-
-	INIT_WORK(&info->work, handle_bam_mux_cmd);
-
-	info->skb = __dev_alloc_skb(BUFFER_SIZE, GFP_KERNEL);
-	if (info->skb == NULL) {
-		pr_err("%s: unable to alloc skb\n", __func__);
-		kfree(info);
-		return;
-	}
-	ptr = skb_put(info->skb, BUFFER_SIZE);
+	int ret;
+	int rx_len_cached;
 
 	mutex_lock(&bam_rx_pool_mutexlock);
-	list_add_tail(&info->list_node, &bam_rx_pool);
+	rx_len_cached = bam_rx_pool_len;
 	mutex_unlock(&bam_rx_pool_mutexlock);
 
-	/* need a way to handle error case */
-	info->dma_address = dma_map_single(NULL, ptr, BUFFER_SIZE,
-						DMA_FROM_DEVICE);
-	sps_transfer_one(bam_rx_pipe, info->dma_address,
-				BUFFER_SIZE, info,
-				SPS_IOVEC_FLAG_INT | SPS_IOVEC_FLAG_EOT);
+	while (rx_len_cached < NUM_BUFFERS) {
+		if (in_global_reset)
+			goto fail;
+
+		info = kmalloc(sizeof(struct rx_pkt_info), GFP_KERNEL);
+		if (!info) {
+			pr_err("%s: unable to alloc rx_pkt_info\n", __func__);
+			goto fail;
+		}
+
+		INIT_WORK(&info->work, handle_bam_mux_cmd);
+
+		info->skb = __dev_alloc_skb(BUFFER_SIZE, GFP_KERNEL);
+		if (info->skb == NULL) {
+			DMUX_LOG_KERR("%s: unable to alloc skb\n", __func__);
+			goto fail_info;
+		}
+		ptr = skb_put(info->skb, BUFFER_SIZE);
+
+		info->dma_address = dma_map_single(NULL, ptr, BUFFER_SIZE,
+							DMA_FROM_DEVICE);
+		if (info->dma_address == 0 || info->dma_address == ~0) {
+			DMUX_LOG_KERR("%s: dma_map_single failure %p for %p\n",
+				__func__, (void *)info->dma_address, ptr);
+			goto fail_skb;
+		}
+
+		mutex_lock(&bam_rx_pool_mutexlock);
+		list_add_tail(&info->list_node, &bam_rx_pool);
+		rx_len_cached = ++bam_rx_pool_len;
+		mutex_unlock(&bam_rx_pool_mutexlock);
+
+		ret = sps_transfer_one(bam_rx_pipe, info->dma_address,
+			BUFFER_SIZE, info,
+			SPS_IOVEC_FLAG_INT | SPS_IOVEC_FLAG_EOT);
+
+		if (ret) {
+			DMUX_LOG_KERR("%s: sps_transfer_one failed %d\n",
+				__func__, ret);
+			goto fail_transfer;
+		}
+	}
+	return;
+
+fail_transfer:
+	mutex_lock(&bam_rx_pool_mutexlock);
+	list_del(&info->list_node);
+	--bam_rx_pool_len;
+	rx_len_cached = bam_rx_pool_len;
+	mutex_unlock(&bam_rx_pool_mutexlock);
+
+	dma_unmap_single(NULL, info->dma_address, BUFFER_SIZE,
+				DMA_FROM_DEVICE);
+
+fail_skb:
+	dev_kfree_skb_any(info->skb);
+
+fail_info:
+	kfree(info);
+
+fail:
+	if (rx_len_cached == 0) {
+		DMUX_LOG_KERR("%s: RX queue failure\n", __func__);
+		in_global_reset = 1;
+	}
 }
 
 static void bam_mux_process_data(struct sk_buff *rx_skb)
@@ -551,16 +601,20 @@
 	INIT_WORK(&pkt->work, bam_mux_write_done);
 	spin_lock_irqsave(&bam_tx_pool_spinlock, flags);
 	list_add_tail(&pkt->list_node, &bam_tx_pool);
-	spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
 	rc = sps_transfer_one(bam_tx_pipe, dma_address, len,
 				pkt, SPS_IOVEC_FLAG_INT | SPS_IOVEC_FLAG_EOT);
 	if (rc) {
-		DBG("%s sps_transfer_one failed rc=%d\n", __func__, rc);
-		spin_lock_irqsave(&bam_tx_pool_spinlock, flags);
+		DMUX_LOG_KERR("%s sps_transfer_one failed rc=%d\n",
+			__func__, rc);
 		list_del(&pkt->list_node);
 		DBG_INC_TX_SPS_FAILURE_CNT();
 		spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
+		dma_unmap_single(NULL, pkt->dma_address,
+					pkt->len,
+					DMA_TO_DEVICE);
 		kfree(pkt);
+	} else {
+		spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
 	}
 
 	ul_packet_written = 1;
@@ -662,6 +716,8 @@
 	if (!bam_is_connected) {
 		read_unlock(&ul_wakeup_lock);
 		ul_wakeup();
+		if (unlikely(in_global_reset == 1))
+			return -EFAULT;
 		read_lock(&ul_wakeup_lock);
 		notify_all(BAM_DMUX_UL_CONNECTED, (unsigned long)(NULL));
 	}
@@ -718,19 +774,21 @@
 	INIT_WORK(&pkt->work, bam_mux_write_done);
 	spin_lock_irqsave(&bam_tx_pool_spinlock, flags);
 	list_add_tail(&pkt->list_node, &bam_tx_pool);
-	spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
 	rc = sps_transfer_one(bam_tx_pipe, dma_address, skb->len,
 				pkt, SPS_IOVEC_FLAG_INT | SPS_IOVEC_FLAG_EOT);
 	if (rc) {
-		DBG("%s sps_transfer_one failed rc=%d\n", __func__, rc);
-		spin_lock_irqsave(&bam_tx_pool_spinlock, flags);
+		DMUX_LOG_KERR("%s sps_transfer_one failed rc=%d\n",
+			__func__, rc);
 		list_del(&pkt->list_node);
 		DBG_INC_TX_SPS_FAILURE_CNT();
 		spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
+		dma_unmap_single(NULL, pkt->dma_address,
+					pkt->skb->len,	DMA_TO_DEVICE);
 		kfree(pkt);
 		if (new_skb)
 			dev_kfree_skb_any(new_skb);
 	} else {
+		spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
 		spin_lock_irqsave(&bam_ch[id].lock, flags);
 		bam_ch[id].num_tx_pkts++;
 		spin_unlock_irqrestore(&bam_ch[id].lock, flags);
@@ -800,6 +858,8 @@
 	if (!bam_is_connected) {
 		read_unlock(&ul_wakeup_lock);
 		ul_wakeup();
+		if (unlikely(in_global_reset == 1))
+			return -EFAULT;
 		read_lock(&ul_wakeup_lock);
 		notify_all(BAM_DMUX_UL_CONNECTED, (unsigned long)(NULL));
 	}
@@ -835,6 +895,8 @@
 	if (!bam_is_connected && !bam_ch_is_in_reset(id)) {
 		read_unlock(&ul_wakeup_lock);
 		ul_wakeup();
+		if (unlikely(in_global_reset == 1))
+			return -EFAULT;
 		read_lock(&ul_wakeup_lock);
 		notify_all(BAM_DMUX_UL_CONNECTED, (unsigned long)(NULL));
 	}
@@ -965,7 +1027,12 @@
 		info = list_first_entry(&bam_rx_pool, struct rx_pkt_info,
 							list_node);
 		list_del(&info->list_node);
+		--bam_rx_pool_len;
 		mutex_unlock(&bam_rx_pool_mutexlock);
+		if (info->dma_address != iov.addr)
+			DMUX_LOG_KERR("%s: iovec %p != dma %p\n",
+				__func__,
+				(void *)info->dma_address, (void *)iov.addr);
 		handle_bam_mux_cmd(&info->work);
 	}
 	return;
@@ -1004,6 +1071,7 @@
 			}
 			info = list_first_entry(&bam_rx_pool,
 					struct rx_pkt_info,	list_node);
+			--bam_rx_pool_len;
 			list_del(&info->list_node);
 			mutex_unlock(&bam_rx_pool_mutexlock);
 			handle_bam_mux_cmd(&info->work);
@@ -1124,10 +1192,14 @@
 	i += scnprintf(buf + i, max - i,
 			"skb copy cnt:    %u\n"
 			"skb copy bytes:  %u\n"
-			"sps tx failures: %u\n",
+			"sps tx failures: %u\n"
+			"sps tx stalls:   %u\n"
+			"rx queue len:    %d\n",
 			bam_dmux_write_cpy_cnt,
 			bam_dmux_write_cpy_bytes,
-			bam_dmux_tx_sps_failure_cnt
+			bam_dmux_tx_sps_failure_cnt,
+			bam_dmux_tx_stall_cnt,
+			bam_rx_pool_len
 			);
 
 	return i;
@@ -1281,6 +1353,8 @@
 	if (!bam_is_connected) {
 		read_unlock(&ul_wakeup_lock);
 		ul_wakeup();
+		if (unlikely(in_global_reset == 1))
+			return;
 		read_lock(&ul_wakeup_lock);
 		ul_packet_written = 1;
 		notify_all(BAM_DMUX_UL_CONNECTED, (unsigned long)(NULL));
@@ -1352,6 +1426,21 @@
 		return;
 	}
 	if (bam_is_connected) {
+		if (!ul_packet_written) {
+			spin_lock(&bam_tx_pool_spinlock);
+			if (!list_empty(&bam_tx_pool)) {
+				struct tx_pkt_info *info;
+
+				info = list_first_entry(&bam_tx_pool,
+						struct tx_pkt_info, list_node);
+				DMUX_LOG_KERR("%s: UL delayed ts=%u.%09lu\n",
+					__func__, info->ts_sec, info->ts_nsec);
+				DBG_INC_TX_STALL_CNT();
+				ul_packet_written = 1;
+			}
+			spin_unlock(&bam_tx_pool_spinlock);
+		}
+
 		if (ul_packet_written) {
 			bam_dmux_log("%s: packet written\n", __func__);
 			ul_packet_written = 0;
@@ -1364,6 +1453,26 @@
 	write_unlock_irqrestore(&ul_wakeup_lock, flags);
 	ul_powerdown_finish();
 }
+
+static int ssrestart_check(void)
+{
+	/*
+	 * if the restart level is RESET_SOC, SSR is not on
+	 * so the crashed modem will end up crashing the system
+	 * anyways, so use BUG() to report the error
+	 * else prepare for the restart event which should
+	 * happen soon
+	 */
+	DMUX_LOG_KERR("%s: modem timeout\n", __func__);
+	if (get_restart_level() <= RESET_SOC) {
+		BUG();
+		return 0;
+	} else {
+		in_global_reset = 1;
+		return 1;
+	}
+}
+
 static void ul_wakeup(void)
 {
 	int ret;
@@ -1407,17 +1516,29 @@
 		bam_dmux_log("%s waiting for previous ack\n", __func__);
 		ret = wait_for_completion_timeout(
 					&ul_wakeup_ack_completion, HZ);
-		BUG_ON(ret == 0);
 		wait_for_ack = 0;
+		if (unlikely(ret == 0) && ssrestart_check()) {
+			mutex_unlock(&wakeup_lock);
+			bam_dmux_log("%s timeout previous ack\n", __func__);
+			return;
+		}
 	}
 	INIT_COMPLETION(ul_wakeup_ack_completion);
 	power_vote(1);
 	bam_dmux_log("%s waiting for wakeup ack\n", __func__);
 	ret = wait_for_completion_timeout(&ul_wakeup_ack_completion, HZ);
-	BUG_ON(ret == 0);
+	if (unlikely(ret == 0) && ssrestart_check()) {
+		mutex_unlock(&wakeup_lock);
+		bam_dmux_log("%s timeout wakeup ack\n", __func__);
+		return;
+	}
 	bam_dmux_log("%s waiting completion\n", __func__);
 	ret = wait_for_completion_timeout(&bam_connection_completion, HZ);
-	BUG_ON(ret == 0);
+	if (unlikely(ret == 0) && ssrestart_check()) {
+		mutex_unlock(&wakeup_lock);
+		bam_dmux_log("%s timeout power on\n", __func__);
+		return;
+	}
 
 	bam_is_connected = 1;
 	bam_dmux_log("%s complete\n", __func__);
@@ -1453,8 +1574,7 @@
 	if (polling_mode)
 		rx_switch_to_interrupt_mode();
 
-	for (i = 0; i < NUM_BUFFERS; ++i)
-		queue_rx();
+	queue_rx();
 
 	toggle_apps_ack();
 	complete_all(&bam_connection_completion);
@@ -1495,6 +1615,7 @@
 		dev_kfree_skb_any(info->skb);
 		kfree(info);
 	}
+	bam_rx_pool_len = 0;
 	mutex_unlock(&bam_rx_pool_mutexlock);
 
 	verify_tx_queue_is_empty(__func__);
@@ -1588,6 +1709,11 @@
 		ul_powerdown();
 		wait_for_ack = 0;
 	}
+	/*
+	 * if modem crash during ul_wakeup(), power_vote is 1, needs to be
+	 * reset to 0.  harmless if bam_is_connected check above passes
+	 */
+	power_vote(0);
 	write_unlock_irqrestore(&ul_wakeup_lock, flags);
 	ul_powerdown_finish();
 	a2_pc_disabled = 0;
@@ -1638,7 +1764,7 @@
 	dma_addr_t dma_addr;
 	int ret;
 	void *a2_virt_addr;
-	int i;
+	int skip_iounmap = 0;
 
 	vote_dfab();
 	/* init BAM */
@@ -1763,8 +1889,7 @@
 	}
 
 	bam_mux_initialized = 1;
-	for (i = 0; i < NUM_BUFFERS; ++i)
-		queue_rx();
+	queue_rx();
 	toggle_apps_ack();
 	bam_connection_is_active = 1;
 	complete_all(&bam_connection_completion);
@@ -1786,7 +1911,15 @@
 	sps_free_endpoint(bam_tx_pipe);
 tx_mem_failed:
 	sps_deregister_bam_device(h);
+	/*
+	 * sps_deregister_bam_device() calls iounmap.  calling iounmap on the
+	 * same handle below will cause a crash, so skip it if we've freed
+	 * the handle here.
+	 */
+	skip_iounmap = 1;
 register_bam_failed:
+	if (!skip_iounmap)
+		iounmap(a2_virt_addr);
 ioremap_failed:
 	/*destroy_workqueue(bam_mux_workqueue);*/
 	return ret;
@@ -1825,6 +1958,7 @@
 	return 0;
 
 register_bam_failed:
+	iounmap(a2_virt_addr);
 ioremap_failed:
 	return ret;
 }
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index 47b20e4..0808a54 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -39,6 +39,7 @@
 	REGULATOR_SUPPLY("HSUSB_1p8",		"msm_otg"),
 	REGULATOR_SUPPLY("HSUSB_1p8",		"msm_ehci_host.0"),
 	REGULATOR_SUPPLY("HSUSB_1p8",		"msm_ehci_host.1"),
+	REGULATOR_SUPPLY("iris_vddxo",		"wcnss_wlan.0"),
 };
 VREG_CONSUMERS(L5) = {
 	REGULATOR_SUPPLY("8921_l5",		NULL),
@@ -60,6 +61,7 @@
 };
 VREG_CONSUMERS(L10) = {
 	REGULATOR_SUPPLY("8921_l10",		NULL),
+	REGULATOR_SUPPLY("iris_vddpa",		"wcnss_wlan.0"),
 };
 VREG_CONSUMERS(L11) = {
 	REGULATOR_SUPPLY("8921_l11",		NULL),
@@ -90,6 +92,7 @@
 };
 VREG_CONSUMERS(L24) = {
 	REGULATOR_SUPPLY("8921_l24",		NULL),
+	REGULATOR_SUPPLY("riva_vddmx",		"wcnss_wlan.0"),
 };
 VREG_CONSUMERS(L25) = {
 	REGULATOR_SUPPLY("8921_l25",		NULL),
@@ -110,12 +113,14 @@
 };
 VREG_CONSUMERS(S2) = {
 	REGULATOR_SUPPLY("8921_s2",		NULL),
+	REGULATOR_SUPPLY("iris_vddrfa",		"wcnss_wlan.0"),
 };
 VREG_CONSUMERS(S3) = {
 	REGULATOR_SUPPLY("8921_s3",		NULL),
 	REGULATOR_SUPPLY("HSUSB_VDDCX",		"msm_otg"),
 	REGULATOR_SUPPLY("HSUSB_VDDCX",		"msm_ehci_host.0"),
 	REGULATOR_SUPPLY("HSUSB_VDDCX",		"msm_ehci_host.1"),
+	REGULATOR_SUPPLY("riva_vddcx",		"wcnss_wlan.0"),
 };
 VREG_CONSUMERS(S4) = {
 	REGULATOR_SUPPLY("8921_s4",		NULL),
@@ -124,21 +129,26 @@
 	REGULATOR_SUPPLY("CDC_VDD_CP",		"tabla-slim"),
 	REGULATOR_SUPPLY("CDC_VDDA_TX",		"tabla-slim"),
 	REGULATOR_SUPPLY("CDC_VDDA_RX",		"tabla-slim"),
+	REGULATOR_SUPPLY("riva_vddpx",		"wcnss_wlan.0"),
 };
 VREG_CONSUMERS(S5) = {
 	REGULATOR_SUPPLY("8921_s5",		NULL),
+	REGULATOR_SUPPLY("krait0",		NULL),
 };
 VREG_CONSUMERS(S6) = {
 	REGULATOR_SUPPLY("8921_s6",		NULL),
+	REGULATOR_SUPPLY("krait1",		NULL),
 };
 VREG_CONSUMERS(S7) = {
 	REGULATOR_SUPPLY("8921_s7",		NULL),
 };
 VREG_CONSUMERS(LVS1) = {
 	REGULATOR_SUPPLY("8921_lvs1",		NULL),
+	REGULATOR_SUPPLY("iris_vddio",		"wcnss_wlan.0"),
 };
 VREG_CONSUMERS(LVS2) = {
 	REGULATOR_SUPPLY("8921_lvs2",		NULL),
+	REGULATOR_SUPPLY("iris_vdddig",		"wcnss_wlan.0"),
 };
 VREG_CONSUMERS(LVS3) = {
 	REGULATOR_SUPPLY("8921_lvs3",		NULL),
@@ -166,9 +176,11 @@
 };
 VREG_CONSUMERS(8821_S0) = {
 	REGULATOR_SUPPLY("8821_s0",		NULL),
+	REGULATOR_SUPPLY("krait2",		NULL),
 };
 VREG_CONSUMERS(8821_S1) = {
 	REGULATOR_SUPPLY("8821_s1",		NULL),
+	REGULATOR_SUPPLY("krait3",		NULL),
 };
 
 #define PM8XXX_VREG_INIT(_id, _name, _min_uV, _max_uV, _modes, _ops, \
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 0ba7434..187b92e 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -23,6 +23,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/platform_data/qcom_crypto_device.h>
 #include <linux/ion.h>
+#include <linux/memory.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/hardware/gic.h>
@@ -50,6 +51,7 @@
 
 #include "msm_watchdog.h"
 #include "board-8064.h"
+#include "acpuclock.h"
 
 #define MSM_PMEM_ADSP_SIZE         0x7800000
 #define MSM_PMEM_AUDIO_SIZE        0x2B4000
@@ -62,9 +64,12 @@
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 #define MSM_PMEM_KERNEL_EBI1_SIZE  0xB0C000
 #define MSM_ION_SF_SIZE		MSM_PMEM_SIZE
+#define MSM_ION_MM_FW_SIZE	0x200000 /* (2MB) */
 #define MSM_ION_MM_SIZE		MSM_PMEM_ADSP_SIZE
+#define MSM_ION_QSECOM_SIZE	0x100000 /* (1MB) */
 #define MSM_ION_MFC_SIZE	SZ_8K
-#define MSM_ION_HEAP_NUM	5
+#define MSM_ION_AUDIO_SIZE	MSM_PMEM_AUDIO_SIZE
+#define MSM_ION_HEAP_NUM	8
 #else
 #define MSM_PMEM_KERNEL_EBI1_SIZE  0x110C000
 #define MSM_ION_HEAP_NUM	1
@@ -198,13 +203,22 @@
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 static struct ion_cp_heap_pdata cp_mm_ion_pdata = {
 	.permission_type = IPT_TYPE_MM_CARVEOUT,
+	.align = PAGE_SIZE,
 };
 
 static struct ion_cp_heap_pdata cp_mfc_ion_pdata = {
 	.permission_type = IPT_TYPE_MFC_SHAREDMEM,
+	.align = PAGE_SIZE,
 };
 
 static struct ion_co_heap_pdata co_ion_pdata = {
+	.adjacent_mem_id = INVALID_HEAP_ID,
+	.align = PAGE_SIZE,
+};
+
+static struct ion_co_heap_pdata fw_co_ion_pdata = {
+	.adjacent_mem_id = ION_CP_MM_HEAP_ID,
+	.align = SZ_128K,
 };
 #endif
 static struct ion_platform_data ion_pdata = {
@@ -233,6 +247,14 @@
 			.extra_data = (void *) &cp_mm_ion_pdata,
 		},
 		{
+			.id	= ION_MM_FIRMWARE_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_MM_FIRMWARE_HEAP_NAME,
+			.size	= MSM_ION_MM_FW_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.extra_data = (void *) &fw_co_ion_pdata,
+		},
+		{
 			.id	= ION_CP_MFC_HEAP_ID,
 			.type	= ION_HEAP_TYPE_CP,
 			.name	= ION_MFC_HEAP_NAME,
@@ -245,6 +267,22 @@
 			.type	= ION_HEAP_TYPE_IOMMU,
 			.name	= ION_IOMMU_HEAP_NAME,
 		},
+		{
+			.id	= ION_QSECOM_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_QSECOM_HEAP_NAME,
+			.size	= MSM_ION_QSECOM_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.extra_data = (void *) &co_ion_pdata,
+		},
+		{
+			.id	= ION_AUDIO_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_AUDIO_HEAP_NAME,
+			.size	= MSM_ION_AUDIO_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.extra_data = (void *) &co_ion_pdata,
+		},
 #endif
 	}
 };
@@ -260,8 +298,11 @@
 {
 #if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
 	apq8064_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MM_SIZE;
+	apq8064_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MM_FW_SIZE;
 	apq8064_reserve_table[MEMTYPE_EBI1].size += MSM_ION_SF_SIZE;
 	apq8064_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MFC_SIZE;
+	apq8064_reserve_table[MEMTYPE_EBI1].size += MSM_ION_QSECOM_SIZE;
+	apq8064_reserve_table[MEMTYPE_EBI1].size += MSM_ION_AUDIO_SIZE;
 #endif
 }
 
@@ -292,12 +333,19 @@
 	bank_size = apq8064_memory_bank_size();
 	low = meminfo.bank[0].start;
 	high = mb->start + mb->size;
+
+	/* Check if 32 bit overflow occured */
+	if (high < mb->start)
+		high = ~0UL;
+
 	low &= ~(bank_size - 1);
 
 	if (high - low <= bank_size)
 		return;
-	apq8064_reserve_info.low_unstable_address = low + bank_size;
-	apq8064_reserve_info.max_unstable_size = high - low - bank_size;
+	apq8064_reserve_info.low_unstable_address = mb->start -
+					MIN_MEMORY_BLOCK_SIZE + mb->size;
+	apq8064_reserve_info.max_unstable_size = MIN_MEMORY_BLOCK_SIZE;
+
 	apq8064_reserve_info.bank_size = bank_size;
 	pr_info("low unstable address %lx max size %lx bank size %lx\n",
 		apq8064_reserve_info.low_unstable_address,
@@ -653,6 +701,11 @@
 	&msm_device_sps_apq8064,
 };
 
+static struct platform_device *cdp_devices[] __initdata = {
+	&apq8064_device_uart_gsbi1,
+	&msm_device_sps_apq8064,
+};
+
 static struct msm_spi_platform_data apq8064_qup_spi_gsbi5_pdata = {
 	.max_clock_speed = 24000000,
 };
@@ -739,6 +792,7 @@
 	apq8064_init_mmc();
 	slim_register_board_info(apq8064_slim_devices,
 		ARRAY_SIZE(apq8064_slim_devices));
+	acpuclk_init(&acpuclk_8064_soc_data);
 }
 
 static void __init apq8064_sim_init(void)
@@ -759,6 +813,14 @@
 	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
 }
 
+static void __init apq8064_cdp_init(void)
+{
+	apq8064_common_init();
+	ethernet_init();
+	platform_add_devices(cdp_devices, ARRAY_SIZE(cdp_devices));
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+}
+
 MACHINE_START(APQ8064_SIM, "QCT APQ8064 SIMULATOR")
 	.map_io = apq8064_map_io,
 	.reserve = apq8064_reserve,
@@ -777,3 +839,30 @@
 	.init_machine = apq8064_rumi3_init,
 MACHINE_END
 
+MACHINE_START(APQ8064_CDP, "QCT APQ8064 CDP")
+	.map_io = apq8064_map_io,
+	.reserve = apq8064_reserve,
+	.init_irq = apq8064_init_irq,
+	.handle_irq = gic_handle_irq,
+	.timer = &msm_timer,
+	.init_machine = apq8064_cdp_init,
+MACHINE_END
+
+MACHINE_START(APQ8064_MTP, "QCT APQ8064 MTP")
+	.map_io = apq8064_map_io,
+	.reserve = apq8064_reserve,
+	.init_irq = apq8064_init_irq,
+	.handle_irq = gic_handle_irq,
+	.timer = &msm_timer,
+	.init_machine = apq8064_cdp_init,
+MACHINE_END
+
+MACHINE_START(APQ8064_LIQUID, "QCT APQ8064 LIQUID")
+	.map_io = apq8064_map_io,
+	.reserve = apq8064_reserve,
+	.init_irq = apq8064_init_irq,
+	.handle_irq = gic_handle_irq,
+	.timer = &msm_timer,
+	.init_machine = apq8064_cdp_init,
+MACHINE_END
+
diff --git a/arch/arm/mach-msm/board-8930-regulator.c b/arch/arm/mach-msm/board-8930-regulator.c
index fc9b58f..765bd45 100644
--- a/arch/arm/mach-msm/board-8930-regulator.c
+++ b/arch/arm/mach-msm/board-8930-regulator.c
@@ -76,6 +76,7 @@
 };
 VREG_CONSUMERS(L14) = {
 	REGULATOR_SUPPLY("8038_l14",		NULL),
+	REGULATOR_SUPPLY("pa_therm",		"pm8xxx-adc"),
 };
 VREG_CONSUMERS(L15) = {
 	REGULATOR_SUPPLY("8038_l15",		NULL),
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 598e18d..f7ff370 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -480,8 +480,8 @@
 
 	if (high - low <= bank_size)
 		return;
-	msm8960_reserve_info.low_unstable_address = high -
-						MIN_MEMORY_BLOCK_SIZE;
+	msm8960_reserve_info.low_unstable_address = mb->start -
+					MIN_MEMORY_BLOCK_SIZE + mb->size;
 	msm8960_reserve_info.max_unstable_size = MIN_MEMORY_BLOCK_SIZE;
 
 	msm8960_reserve_info.bank_size = bank_size;
diff --git a/arch/arm/mach-msm/board-copper.c b/arch/arm/mach-msm/board-copper.c
index f26187e..5f31f88 100644
--- a/arch/arm/mach-msm/board-copper.c
+++ b/arch/arm/mach-msm/board-copper.c
@@ -18,6 +18,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
+#include <linux/of_irq.h>
 #include <asm/mach/map.h>
 #include <asm/hardware/gic.h>
 #include <mach/board.h>
@@ -43,24 +44,20 @@
 {
 }
 
-static struct of_device_id msm_copper_gic_match[] __initdata = {
-	{ .compatible = "qcom,msm-qgic2", },
+static struct of_device_id irq_match[] __initdata  = {
+	{ .compatible = "qcom,msm-qgic2", .data = gic_of_init, },
 	{}
 };
 
 void __init msm_copper_init_irq(void)
 {
-	gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE,
-			(void *)MSM_QGIC_CPU_BASE);
-
 	/* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */
 	writel_relaxed(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4);
 
 	writel_relaxed(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET);
 	mb();
 
-	irq_domain_generate_simple(msm_copper_gic_match,
-		COPPER_QGIC_DIST_PHYS, GIC_SPI_START);
+	of_irq_init(irq_match);
 }
 
 static struct clk_lookup msm_clocks_dummy[] = {
diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-msm/board-dt.c
index 19f54cf..6c5f74a 100644
--- a/arch/arm/mach-msm/board-dt.c
+++ b/arch/arm/mach-msm/board-dt.c
@@ -28,7 +28,7 @@
 {
 	struct device_node *node;
 	struct resource res;
-	struct of_irq oirq;
+	int rc;
 
 	node = of_find_compatible_node(NULL, NULL, "qcom,msm-qtimer");
 	if (!node) {
@@ -36,13 +36,12 @@
 		return;
 	}
 
-	if (of_irq_map_one(node, 0, &oirq)) {
+	rc = of_irq_to_resource(node, 0, &res);
+	if (rc < 0)
 		pr_err("interrupt not specified in timer node\n");
-	} else {
-		res.start = res.end = oirq.specifier[0];
-		res.flags = IORESOURCE_IRQ;
+	else
 		arch_timer_register(&res, 1);
-	}
+
 	of_node_put(node);
 }
 
@@ -98,4 +97,5 @@
 	.handle_irq = gic_handle_irq,
 	.timer = &msm_dt_timer,
 	.dt_compat = msm_dt_match,
+	.nr_irqs = -1,
 MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm7627a-display.c b/arch/arm/mach-msm/board-msm7627a-display.c
new file mode 100644
index 0000000..32d29b2
--- /dev/null
+++ b/arch/arm/mach-msm/board-msm7627a-display.c
@@ -0,0 +1,701 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/bootmem.h>
+#include <linux/regulator/consumer.h>
+#include <asm/mach-types.h>
+#include <asm/io.h>
+#include <mach/msm_bus_board.h>
+#include <mach/msm_memtypes.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+#include <mach/socinfo.h>
+#include <mach/rpc_pmapp.h>
+#include "devices.h"
+#include "board-msm7627a.h"
+
+#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
+#define MSM_FB_SIZE	     0x260000
+#define MSM7x25A_MSM_FB_SIZE    0xE1000
+#else
+#define MSM_FB_SIZE	     0x195000
+#define MSM7x25A_MSM_FB_SIZE    0x96000
+#endif
+
+static unsigned fb_size = MSM_FB_SIZE;
+static int __init fb_size_setup(char *p)
+{
+	fb_size = memparse(p, NULL);
+	return 0;
+}
+
+early_param("fb_size", fb_size_setup);
+
+static struct regulator_bulk_data regs_lcdc[] = {
+	{ .supply = "gp2",   .min_uV = 2850000, .max_uV = 2850000 },
+	{ .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
+};
+static uint32_t lcdc_gpio_initialized;
+
+static void lcdc_toshiba_gpio_init(void)
+{
+	int rc = 0;
+	if (!lcdc_gpio_initialized) {
+		if (gpio_request(GPIO_SPI_CLK, "spi_clk")) {
+			pr_err("failed to request gpio spi_clk\n");
+			return;
+		}
+		if (gpio_request(GPIO_SPI_CS0_N, "spi_cs")) {
+			pr_err("failed to request gpio spi_cs0_N\n");
+			goto fail_gpio6;
+		}
+		if (gpio_request(GPIO_SPI_MOSI, "spi_mosi")) {
+			pr_err("failed to request gpio spi_mosi\n");
+			goto fail_gpio5;
+		}
+		if (gpio_request(GPIO_SPI_MISO, "spi_miso")) {
+			pr_err("failed to request gpio spi_miso\n");
+			goto fail_gpio4;
+		}
+		if (gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr")) {
+			pr_err("failed to request gpio_disp_pwr\n");
+			goto fail_gpio3;
+		}
+		if (gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en")) {
+			pr_err("failed to request gpio_bkl_en\n");
+			goto fail_gpio2;
+		}
+		pmapp_disp_backlight_init();
+
+		rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_lcdc),
+					regs_lcdc);
+		if (rc) {
+			pr_err("%s: could not get regulators: %d\n",
+					__func__, rc);
+			goto fail_gpio1;
+		}
+
+		rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_lcdc),
+				regs_lcdc);
+		if (rc) {
+			pr_err("%s: could not set voltages: %d\n",
+					__func__, rc);
+			goto fail_vreg;
+		}
+		lcdc_gpio_initialized = 1;
+	}
+	return;
+fail_vreg:
+	regulator_bulk_free(ARRAY_SIZE(regs_lcdc), regs_lcdc);
+fail_gpio1:
+	gpio_free(GPIO_BACKLIGHT_EN);
+fail_gpio2:
+	gpio_free(GPIO_DISPLAY_PWR_EN);
+fail_gpio3:
+	gpio_free(GPIO_SPI_MISO);
+fail_gpio4:
+	gpio_free(GPIO_SPI_MOSI);
+fail_gpio5:
+	gpio_free(GPIO_SPI_CS0_N);
+fail_gpio6:
+	gpio_free(GPIO_SPI_CLK);
+	lcdc_gpio_initialized = 0;
+}
+
+static uint32_t lcdc_gpio_table[] = {
+	GPIO_SPI_CLK,
+	GPIO_SPI_CS0_N,
+	GPIO_SPI_MOSI,
+	GPIO_DISPLAY_PWR_EN,
+	GPIO_BACKLIGHT_EN,
+	GPIO_SPI_MISO,
+};
+
+static void config_lcdc_gpio_table(uint32_t *table, int len, unsigned enable)
+{
+	int n;
+
+	if (lcdc_gpio_initialized) {
+		/* All are IO Expander GPIOs */
+		for (n = 0; n < (len - 1); n++)
+			gpio_direction_output(table[n], 1);
+	}
+}
+
+static void lcdc_toshiba_config_gpios(int enable)
+{
+	config_lcdc_gpio_table(lcdc_gpio_table,
+		ARRAY_SIZE(lcdc_gpio_table), enable);
+}
+
+static int msm_fb_lcdc_power_save(int on)
+{
+	int rc = 0;
+	/* Doing the init of the LCDC GPIOs very late as they are from
+		an I2C-controlled IO Expander */
+	lcdc_toshiba_gpio_init();
+
+	if (lcdc_gpio_initialized) {
+		gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
+		gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
+
+		rc = on ? regulator_bulk_enable(
+				ARRAY_SIZE(regs_lcdc), regs_lcdc) :
+			  regulator_bulk_disable(
+				ARRAY_SIZE(regs_lcdc), regs_lcdc);
+
+		if (rc)
+			pr_err("%s: could not %sable regulators: %d\n",
+					__func__, on ? "en" : "dis", rc);
+	}
+
+	return rc;
+}
+
+static int lcdc_toshiba_set_bl(int level)
+{
+	int ret;
+
+	ret = pmapp_disp_backlight_set_brightness(level);
+	if (ret)
+		pr_err("%s: can't set lcd backlight!\n", __func__);
+
+	return ret;
+}
+
+static struct lcdc_platform_data lcdc_pdata = {
+	.lcdc_gpio_config = NULL,
+	.lcdc_power_save   = msm_fb_lcdc_power_save,
+};
+
+static int lcd_panel_spi_gpio_num[] = {
+		GPIO_SPI_MOSI,  /* spi_sdi */
+		GPIO_SPI_MISO,  /* spi_sdoi */
+		GPIO_SPI_CLK,   /* spi_clk */
+		GPIO_SPI_CS0_N, /* spi_cs  */
+};
+
+static struct msm_panel_common_pdata lcdc_toshiba_panel_data = {
+	.panel_config_gpio = lcdc_toshiba_config_gpios,
+	.pmic_backlight = lcdc_toshiba_set_bl,
+	.gpio_num	 = lcd_panel_spi_gpio_num,
+};
+
+static struct platform_device lcdc_toshiba_panel_device = {
+	.name   = "lcdc_toshiba_fwvga_pt",
+	.id     = 0,
+	.dev    = {
+		.platform_data = &lcdc_toshiba_panel_data,
+	}
+};
+
+static struct resource msm_fb_resources[] = {
+	{
+		.flags  = IORESOURCE_DMA,
+	}
+};
+
+#define PANEL_NAME_MAX_LEN      30
+#define LCDC_TOSHIBA_FWVGA_PANEL_NAME   "lcdc_toshiba_fwvga_pt"
+#define MIPI_CMD_RENESAS_FWVGA_PANEL_NAME       "mipi_cmd_renesas_fwvga"
+
+static int msm_fb_detect_panel(const char *name)
+{
+	int ret = -ENODEV;
+
+	if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
+		if (!strncmp(name, "lcdc_toshiba_fwvga_pt", 21) ||
+				!strncmp(name, "mipi_cmd_renesas_fwvga", 22))
+			ret = 0;
+	} else if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa()) {
+		if (!strncmp(name, "mipi_cmd_renesas_fwvga", 22))
+			ret = 0;
+	} else if (machine_is_msm7627a_qrd1()) {
+		if (!strncmp(name, "mipi_video_truly_wvga", 21))
+			ret = 0;
+	}
+
+#if !defined(CONFIG_FB_MSM_LCDC_AUTO_DETECT) && \
+	!defined(CONFIG_FB_MSM_MIPI_PANEL_AUTO_DETECT) && \
+	!defined(CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT)
+		if (machine_is_msm7x27a_surf() ||
+			machine_is_msm7625a_surf()) {
+			if (!strncmp(name, LCDC_TOSHIBA_FWVGA_PANEL_NAME,
+				strnlen(LCDC_TOSHIBA_FWVGA_PANEL_NAME,
+					PANEL_NAME_MAX_LEN)))
+				return 0;
+		}
+#endif
+
+	return ret;
+}
+
+static int mipi_truly_set_bl(int on)
+{
+	gpio_set_value_cansleep(QRD_GPIO_BACKLIGHT_EN, !!on);
+
+	return 1;
+}
+
+static struct msm_fb_platform_data msm_fb_pdata = {
+	.detect_client = msm_fb_detect_panel,
+};
+
+static struct platform_device msm_fb_device = {
+	.name   = "msm_fb",
+	.id     = 0,
+	.num_resources  = ARRAY_SIZE(msm_fb_resources),
+	.resource       = msm_fb_resources,
+	.dev    = {
+		.platform_data = &msm_fb_pdata,
+	}
+};
+
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+static int mipi_renesas_set_bl(int level)
+{
+	int ret;
+
+	ret = pmapp_disp_backlight_set_brightness(level);
+
+	if (ret)
+		pr_err("%s: can't set lcd backlight!\n", __func__);
+
+	return ret;
+}
+
+static struct msm_panel_common_pdata mipi_renesas_pdata = {
+	.pmic_backlight = mipi_renesas_set_bl,
+};
+
+
+static struct platform_device mipi_dsi_renesas_panel_device = {
+	.name = "mipi_renesas",
+	.id = 0,
+	.dev    = {
+		.platform_data = &mipi_renesas_pdata,
+	}
+};
+#endif
+
+static struct msm_panel_common_pdata mipi_truly_pdata = {
+	.pmic_backlight = mipi_truly_set_bl,
+};
+
+static struct platform_device mipi_dsi_truly_panel_device = {
+	.name   = "mipi_truly",
+	.id     = 0,
+	.dev    = {
+		.platform_data = &mipi_truly_pdata,
+	}
+};
+
+static struct platform_device *msm_fb_devices[] __initdata = {
+	&msm_fb_device,
+	&lcdc_toshiba_panel_device,
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+	&mipi_dsi_renesas_panel_device,
+#endif
+};
+
+static struct platform_device *qrd_fb_devices[] __initdata = {
+	&msm_fb_device,
+	&mipi_dsi_truly_panel_device,
+};
+
+void __init msm_msm7627a_allocate_memory_regions(void)
+{
+	void *addr;
+	unsigned long fb_size;
+
+	if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa())
+		fb_size = MSM7x25A_MSM_FB_SIZE;
+	else
+		fb_size = MSM_FB_SIZE;
+	addr = alloc_bootmem_align(fb_size, 0x1000);
+	msm_fb_resources[0].start = __pa(addr);
+	msm_fb_resources[0].end = msm_fb_resources[0].start + fb_size - 1;
+	pr_info("allocating %lu bytes at %p (%lx physical) for fb\n", fb_size,
+						addr, __pa(addr));
+}
+
+static struct msm_panel_common_pdata mdp_pdata = {
+	.gpio = 97,
+	.mdp_rev = MDP_REV_303,
+};
+
+#define GPIO_LCDC_BRDG_PD	128
+#define GPIO_LCDC_BRDG_RESET_N	129
+#define GPIO_LCD_DSI_SEL	125
+#define LCDC_RESET_PHYS		0x90008014
+
+static  void __iomem *lcdc_reset_ptr;
+
+static unsigned mipi_dsi_gpio[] = {
+		GPIO_CFG(GPIO_LCDC_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT,
+		GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* LCDC_BRDG_RESET_N */
+		GPIO_CFG(GPIO_LCDC_BRDG_PD, 0, GPIO_CFG_OUTPUT,
+		GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* LCDC_BRDG_PD */
+};
+
+static unsigned lcd_dsi_sel_gpio[] = {
+	GPIO_CFG(GPIO_LCD_DSI_SEL, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
+			GPIO_CFG_2MA),
+};
+
+enum {
+	DSI_SINGLE_LANE = 1,
+	DSI_TWO_LANES,
+};
+
+static int msm_fb_get_lane_config(void)
+{
+	/* For MSM7627A SURF/FFA and QRD */
+	int rc = DSI_TWO_LANES;
+	if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
+		rc = DSI_SINGLE_LANE;
+		pr_info("DSI_SINGLE_LANES\n");
+	} else {
+		pr_info("DSI_TWO_LANES\n");
+	}
+	return rc;
+}
+
+static int msm_fb_dsi_client_msm_reset(void)
+{
+	int rc = 0;
+
+	rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
+	if (rc < 0) {
+		pr_err("failed to request lcd brdg reset_n\n");
+		return rc;
+	}
+
+	rc = gpio_request(GPIO_LCDC_BRDG_PD, "lcdc_brdg_pd");
+	if (rc < 0) {
+		pr_err("failed to request lcd brdg pd\n");
+		return rc;
+	}
+
+	rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
+	if (rc) {
+		pr_err("Failed to enable LCDC Bridge reset enable\n");
+		goto gpio_error;
+	}
+
+	rc = gpio_tlmm_config(mipi_dsi_gpio[1], GPIO_CFG_ENABLE);
+	if (rc) {
+		pr_err("Failed to enable LCDC Bridge pd enable\n");
+		goto gpio_error2;
+	}
+
+	rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
+	rc |= gpio_direction_output(GPIO_LCDC_BRDG_PD, 1);
+	gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
+
+	if (!rc) {
+		if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
+			lcdc_reset_ptr = ioremap_nocache(LCDC_RESET_PHYS,
+				sizeof(uint32_t));
+
+			if (!lcdc_reset_ptr)
+				return 0;
+		}
+		return rc;
+	} else {
+		goto gpio_error;
+	}
+
+gpio_error2:
+	pr_err("Failed GPIO bridge pd\n");
+	gpio_free(GPIO_LCDC_BRDG_PD);
+
+gpio_error:
+	pr_err("Failed GPIO bridge reset\n");
+	gpio_free(GPIO_LCDC_BRDG_RESET_N);
+	return rc;
+}
+
+static int mipi_truly_sel_mode(int video_mode)
+{
+	int rc = 0;
+
+	rc = gpio_request(GPIO_LCD_DSI_SEL, "lcd_dsi_sel");
+	if (rc < 0)
+		goto gpio_error;
+
+	rc = gpio_tlmm_config(lcd_dsi_sel_gpio[0], GPIO_CFG_ENABLE);
+	if (rc)
+		goto gpio_error;
+
+	rc = gpio_direction_output(GPIO_LCD_DSI_SEL, 1);
+	if (!rc) {
+		gpio_set_value_cansleep(GPIO_LCD_DSI_SEL, video_mode);
+		return rc;
+	} else {
+		goto gpio_error;
+	}
+
+gpio_error:
+	pr_err("mipi_truly_sel_mode failed\n");
+	gpio_free(GPIO_LCD_DSI_SEL);
+	return rc;
+}
+
+static int msm_fb_dsi_client_qrd1_reset(void)
+{
+	int rc = 0;
+
+	rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
+	if (rc < 0) {
+		pr_err("failed to request lcd brdg reset_n\n");
+		return rc;
+	}
+
+	rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
+	if (rc < 0) {
+		pr_err("Failed to enable LCDC Bridge reset enable\n");
+		return rc;
+	}
+
+	rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
+	if (rc < 0) {
+		pr_err("Failed GPIO bridge pd\n");
+		gpio_free(GPIO_LCDC_BRDG_RESET_N);
+		return rc;
+	}
+
+	mipi_truly_sel_mode(1);
+
+	return rc;
+}
+
+static int msm_fb_dsi_client_reset(void)
+{
+	int rc = 0;
+
+	if (machine_is_msm7627a_qrd1())
+		rc = msm_fb_dsi_client_qrd1_reset();
+	else
+		rc = msm_fb_dsi_client_msm_reset();
+
+	return rc;
+
+}
+
+static struct regulator_bulk_data regs_dsi[] = {
+	{ .supply = "gp2",   .min_uV = 2850000, .max_uV = 2850000 },
+	{ .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
+};
+
+static int dsi_gpio_initialized;
+
+static int mipi_dsi_panel_msm_power(int on)
+{
+	int rc = 0;
+	uint32_t lcdc_reset_cfg;
+
+	/* I2C-controlled GPIO Expander -init of the GPIOs very late */
+	if (unlikely(!dsi_gpio_initialized)) {
+		pmapp_disp_backlight_init();
+
+		rc = gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr");
+		if (rc < 0) {
+			pr_err("failed to request gpio_disp_pwr\n");
+			return rc;
+		}
+
+		if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
+			rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, 1);
+			if (rc < 0) {
+				pr_err("failed to enable display pwr\n");
+				goto fail_gpio1;
+			}
+
+			rc = gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en");
+			if (rc < 0) {
+				pr_err("failed to request gpio_bkl_en\n");
+				goto fail_gpio1;
+			}
+
+			rc = gpio_direction_output(GPIO_BACKLIGHT_EN, 1);
+			if (rc < 0) {
+				pr_err("failed to enable backlight\n");
+				goto fail_gpio2;
+			}
+		}
+
+		rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_dsi), regs_dsi);
+		if (rc) {
+			pr_err("%s: could not get regulators: %d\n",
+					__func__, rc);
+			goto fail_gpio2;
+		}
+
+		rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_dsi),
+						regs_dsi);
+		if (rc) {
+			pr_err("%s: could not set voltages: %d\n",
+					__func__, rc);
+			goto fail_vreg;
+		}
+		if (pmapp_disp_backlight_set_brightness(100))
+			pr_err("backlight set brightness failed\n");
+
+		dsi_gpio_initialized = 1;
+	}
+	if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
+		gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
+		gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
+	} else if (machine_is_msm7x27a_ffa() ||
+			 machine_is_msm7625a_ffa()) {
+		if (on) {
+			/* This line drives an active low pin on FFA */
+			rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, !on);
+			if (rc < 0)
+				pr_err("failed to set direction for "
+					"display pwr\n");
+		} else {
+			gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, !on);
+			rc = gpio_direction_input(GPIO_DISPLAY_PWR_EN);
+			if (rc < 0)
+				pr_err("failed to set direction for "
+					"display pwr\n");
+		}
+	}
+
+	if (on) {
+		gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
+
+		if (machine_is_msm7x27a_surf() ||
+				 machine_is_msm7625a_surf()) {
+			lcdc_reset_cfg = readl_relaxed(lcdc_reset_ptr);
+			rmb();
+			lcdc_reset_cfg &= ~1;
+
+			writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
+			msleep(20);
+			wmb();
+			lcdc_reset_cfg |= 1;
+			writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
+		} else {
+			gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
+			msleep(20);
+			gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
+		}
+	} else {
+		gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 1);
+
+		if (pmapp_disp_backlight_set_brightness(0))
+			pr_err("backlight set brightness failed\n");
+	}
+
+	rc = on ? regulator_bulk_enable(ARRAY_SIZE(regs_dsi), regs_dsi) :
+		  regulator_bulk_disable(ARRAY_SIZE(regs_dsi), regs_dsi);
+
+	if (rc)
+		pr_err("%s: could not %sable regulators: %d\n",
+				__func__, on ? "en" : "dis", rc);
+
+	return rc;
+fail_vreg:
+	regulator_bulk_free(ARRAY_SIZE(regs_dsi), regs_dsi);
+fail_gpio2:
+	gpio_free(GPIO_BACKLIGHT_EN);
+fail_gpio1:
+	gpio_free(GPIO_DISPLAY_PWR_EN);
+	dsi_gpio_initialized = 0;
+	return rc;
+}
+
+static int mipi_dsi_panel_qrd1_power(int on)
+{
+	int rc = 0;
+
+	if (!dsi_gpio_initialized) {
+		rc = gpio_request(QRD_GPIO_BACKLIGHT_EN, "gpio_bkl_en");
+		if (rc < 0)
+			return rc;
+
+		rc = gpio_tlmm_config(GPIO_CFG(QRD_GPIO_BACKLIGHT_EN, 0,
+			GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+			GPIO_CFG_ENABLE);
+		if (rc < 0) {
+			pr_err("failed GPIO_BACKLIGHT_EN tlmm config\n");
+			return rc;
+		}
+
+		rc = gpio_direction_output(QRD_GPIO_BACKLIGHT_EN, 1);
+		if (rc < 0) {
+			pr_err("failed to enable backlight\n");
+			gpio_free(QRD_GPIO_BACKLIGHT_EN);
+			return rc;
+		}
+		dsi_gpio_initialized = 1;
+	}
+
+	gpio_set_value_cansleep(QRD_GPIO_BACKLIGHT_EN, !!on);
+
+	if (!on) {
+		gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
+		msleep(20);
+		gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
+		msleep(20);
+		gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
+
+	}
+
+	return rc;
+}
+
+static int mipi_dsi_panel_power(int on)
+{
+	int rc = 0;
+
+	if (machine_is_msm7627a_qrd1())
+		rc = mipi_dsi_panel_qrd1_power(on);
+	else
+		rc = mipi_dsi_panel_msm_power(on);
+	return rc;
+}
+
+#define MDP_303_VSYNC_GPIO 97
+
+#ifdef CONFIG_FB_MSM_MDP303
+static struct mipi_dsi_platform_data mipi_dsi_pdata = {
+	.vsync_gpio		= MDP_303_VSYNC_GPIO,
+	.dsi_power_save		= mipi_dsi_panel_power,
+	.dsi_client_reset       = msm_fb_dsi_client_reset,
+	.get_lane_config	= msm_fb_get_lane_config,
+};
+#endif
+
+void __init msm_fb_add_devices(void)
+{
+	if (machine_is_msm7627a_qrd1())
+		platform_add_devices(qrd_fb_devices,
+				ARRAY_SIZE(qrd_fb_devices));
+	else
+		platform_add_devices(msm_fb_devices,
+				ARRAY_SIZE(msm_fb_devices));
+
+	msm_fb_register_device("mdp", &mdp_pdata);
+	if (machine_is_msm7625a_surf() || machine_is_msm7x27a_surf())
+		msm_fb_register_device("lcdc", &lcdc_pdata);
+#ifdef CONFIG_FB_MSM_MDP303
+	msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
+#endif
+}
diff --git a/arch/arm/mach-msm/board-msm7627a.h b/arch/arm/mach-msm/board-msm7627a.h
index 7d7da4f..b0481a0 100644
--- a/arch/arm/mach-msm/board-msm7627a.h
+++ b/arch/arm/mach-msm/board-msm7627a.h
@@ -15,6 +15,9 @@
 
 void __init msm7627a_init_mmc(void);
 
+void __init msm_msm7627a_allocate_memory_regions(void);
+void __init msm_fb_add_devices(void);
+
 enum {
 	GPIO_EXPANDER_IRQ_BASE  = NR_MSM_IRQS + NR_GPIO_IRQS,
 	GPIO_EXPANDER_GPIO_BASE = NR_MSM_GPIOS,
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 5bcd749..77db796 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -157,16 +157,6 @@
 #define MSM_PMEM_ADSP_SIZE      0x1100000
 #define MSM7x25A_MSM_PMEM_ADSP_SIZE      0xB91000
 
-
-#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
-#define MSM_FB_SIZE		0x260000
-#define MSM7x25A_MSM_FB_SIZE	0xE1000
-#else
-#define MSM_FB_SIZE		0x195000
-#define MSM7x25A_MSM_FB_SIZE	0x96000
-
-#endif
-
 #endif
 
 static struct android_usb_platform_data android_usb_pdata = {
@@ -400,253 +390,6 @@
 
 early_param("pmem_adsp_size", pmem_adsp_size_setup);
 
-static unsigned fb_size = MSM_FB_SIZE;
-static int __init fb_size_setup(char *p)
-{
-	fb_size = memparse(p, NULL);
-	return 0;
-}
-
-early_param("fb_size", fb_size_setup);
-
-static struct regulator_bulk_data regs_lcdc[] = {
-	{ .supply = "gp2",   .min_uV = 2850000, .max_uV = 2850000 },
-	{ .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
-};
-
-static uint32_t lcdc_gpio_initialized;
-
-static void lcdc_toshiba_gpio_init(void)
-{
-	int rc = 0;
-	if (!lcdc_gpio_initialized) {
-		if (gpio_request(GPIO_SPI_CLK, "spi_clk")) {
-			pr_err("failed to request gpio spi_clk\n");
-			return;
-		}
-		if (gpio_request(GPIO_SPI_CS0_N, "spi_cs")) {
-			pr_err("failed to request gpio spi_cs0_N\n");
-			goto fail_gpio6;
-		}
-		if (gpio_request(GPIO_SPI_MOSI, "spi_mosi")) {
-			pr_err("failed to request gpio spi_mosi\n");
-			goto fail_gpio5;
-		}
-		if (gpio_request(GPIO_SPI_MISO, "spi_miso")) {
-			pr_err("failed to request gpio spi_miso\n");
-			goto fail_gpio4;
-		}
-		if (gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr")) {
-			pr_err("failed to request gpio_disp_pwr\n");
-			goto fail_gpio3;
-		}
-		if (gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en")) {
-			pr_err("failed to request gpio_bkl_en\n");
-			goto fail_gpio2;
-		}
-		pmapp_disp_backlight_init();
-
-		rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_lcdc), regs_lcdc);
-		if (rc) {
-			pr_err("%s: could not get regulators: %d\n",
-					__func__, rc);
-			goto fail_gpio1;
-		}
-
-		rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_lcdc),
-				regs_lcdc);
-		if (rc) {
-			pr_err("%s: could not set voltages: %d\n",
-					__func__, rc);
-			goto fail_vreg;
-		}
-		lcdc_gpio_initialized = 1;
-	}
-	return;
-fail_vreg:
-	regulator_bulk_free(ARRAY_SIZE(regs_lcdc), regs_lcdc);
-fail_gpio1:
-	gpio_free(GPIO_BACKLIGHT_EN);
-fail_gpio2:
-	gpio_free(GPIO_DISPLAY_PWR_EN);
-fail_gpio3:
-	gpio_free(GPIO_SPI_MISO);
-fail_gpio4:
-	gpio_free(GPIO_SPI_MOSI);
-fail_gpio5:
-	gpio_free(GPIO_SPI_CS0_N);
-fail_gpio6:
-	gpio_free(GPIO_SPI_CLK);
-	lcdc_gpio_initialized = 0;
-}
-
-static uint32_t lcdc_gpio_table[] = {
-	GPIO_SPI_CLK,
-	GPIO_SPI_CS0_N,
-	GPIO_SPI_MOSI,
-	GPIO_DISPLAY_PWR_EN,
-	GPIO_BACKLIGHT_EN,
-	GPIO_SPI_MISO,
-};
-
-static void config_lcdc_gpio_table(uint32_t *table, int len, unsigned enable)
-{
-	int n;
-
-	if (lcdc_gpio_initialized) {
-		/* All are IO Expander GPIOs */
-		for (n = 0; n < (len - 1); n++)
-			gpio_direction_output(table[n], 1);
-	}
-}
-
-static void lcdc_toshiba_config_gpios(int enable)
-{
-	config_lcdc_gpio_table(lcdc_gpio_table,
-		ARRAY_SIZE(lcdc_gpio_table), enable);
-}
-
-static int msm_fb_lcdc_power_save(int on)
-{
-	int rc = 0;
-	/* Doing the init of the LCDC GPIOs very late as they are from
-		an I2C-controlled IO Expander */
-	lcdc_toshiba_gpio_init();
-
-	if (lcdc_gpio_initialized) {
-		gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
-		gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
-
-		rc = on ? regulator_bulk_enable(
-				ARRAY_SIZE(regs_lcdc), regs_lcdc) :
-			  regulator_bulk_disable(
-				ARRAY_SIZE(regs_lcdc), regs_lcdc);
-
-		if (rc)
-			pr_err("%s: could not %sable regulators: %d\n",
-					__func__, on ? "en" : "dis", rc);
-	}
-
-	return rc;
-}
-
-
-static int lcdc_toshiba_set_bl(int level)
-{
-	int ret;
-
-	ret = pmapp_disp_backlight_set_brightness(level);
-	if (ret)
-		pr_err("%s: can't set lcd backlight!\n", __func__);
-
-	return ret;
-}
-
-
-static struct lcdc_platform_data lcdc_pdata = {
-	.lcdc_gpio_config = NULL,
-	.lcdc_power_save   = msm_fb_lcdc_power_save,
-};
-
-static int lcd_panel_spi_gpio_num[] = {
-		GPIO_SPI_MOSI,  /* spi_sdi */
-		GPIO_SPI_MISO,  /* spi_sdoi */
-		GPIO_SPI_CLK,   /* spi_clk */
-		GPIO_SPI_CS0_N, /* spi_cs  */
-};
-
-static struct msm_panel_common_pdata lcdc_toshiba_panel_data = {
-	.panel_config_gpio = lcdc_toshiba_config_gpios,
-	.pmic_backlight = lcdc_toshiba_set_bl,
-	.gpio_num	  = lcd_panel_spi_gpio_num,
-};
-
-static struct platform_device lcdc_toshiba_panel_device = {
-	.name   = "lcdc_toshiba_fwvga_pt",
-	.id     = 0,
-	.dev    = {
-		.platform_data = &lcdc_toshiba_panel_data,
-	}
-};
-
-static struct resource msm_fb_resources[] = {
-	{
-		.flags  = IORESOURCE_DMA,
-	}
-};
-
-#define PANEL_NAME_MAX_LEN	30
-#define LCDC_TOSHIBA_FWVGA_PANEL_NAME	"lcdc_toshiba_fwvga_pt"
-#define MIPI_CMD_RENESAS_FWVGA_PANEL_NAME	"mipi_cmd_renesas_fwvga"
-
-static int msm_fb_detect_panel(const char *name)
-{
-	int ret = -ENODEV;
-
-	if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
-		if (!strncmp(name, "lcdc_toshiba_fwvga_pt", 21) ||
-				!strncmp(name, "mipi_cmd_renesas_fwvga", 22))
-			ret = 0;
-	} else if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa()) {
-		if (!strncmp(name, "mipi_cmd_renesas_fwvga", 22))
-			ret = 0;
-	}
-
-#if !defined(CONFIG_FB_MSM_LCDC_AUTO_DETECT) && \
-	!defined(CONFIG_FB_MSM_MIPI_PANEL_AUTO_DETECT) && \
-	!defined(CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT)
-		if (machine_is_msm7x27a_surf() ||
-			machine_is_msm7625a_surf()) {
-			if (!strncmp(name, LCDC_TOSHIBA_FWVGA_PANEL_NAME,
-				strnlen(LCDC_TOSHIBA_FWVGA_PANEL_NAME,
-					PANEL_NAME_MAX_LEN)))
-				return 0;
-		}
-#endif
-	return ret;
-}
-
-static struct msm_fb_platform_data msm_fb_pdata = {
-	.detect_client = msm_fb_detect_panel,
-};
-
-static struct platform_device msm_fb_device = {
-	.name   = "msm_fb",
-	.id     = 0,
-	.num_resources  = ARRAY_SIZE(msm_fb_resources),
-	.resource       = msm_fb_resources,
-	.dev    = {
-		.platform_data = &msm_fb_pdata,
-	}
-};
-
-#ifdef CONFIG_FB_MSM_MIPI_DSI
-static int mipi_renesas_set_bl(int level)
-{
-	int ret;
-
-	ret = pmapp_disp_backlight_set_brightness(level);
-
-	if (ret)
-		pr_err("%s: can't set lcd backlight!\n", __func__);
-
-	return ret;
-}
-
-static struct msm_panel_common_pdata mipi_renesas_pdata = {
-	.pmic_backlight = mipi_renesas_set_bl,
-};
-
-
-static struct platform_device mipi_dsi_renesas_panel_device = {
-	.name = "mipi_renesas",
-	.id = 0,
-	.dev    = {
-		.platform_data = &mipi_renesas_pdata,
-	}
-};
-#endif
-
 #define SND(desc, num) { .name = #desc, .id = num }
 static struct snd_endpoint snd_endpoints_list[] = {
 	SND(HANDSET, 0),
@@ -951,13 +694,8 @@
 	&android_pmem_audio_device,
 	&msm_device_snd,
 	&msm_device_adspdec,
-	&msm_fb_device,
-	&lcdc_toshiba_panel_device,
 	&msm_batt_device,
 	&smsc911x_device,
-#ifdef CONFIG_FB_MSM_MIPI_DSI
-	&mipi_dsi_renesas_panel_device,
-#endif
 	&msm_kgsl_3d0,
 #ifdef CONFIG_BT
 	&msm_bt_power_device,
@@ -983,24 +721,6 @@
 }
 early_param("pmem_audio_size", pmem_audio_size_setup);
 
-static void __init msm_msm7x2x_allocate_memory_regions(void)
-{
-	void *addr;
-	unsigned long size;
-
-	if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa())
-		fb_size = MSM7x25A_MSM_FB_SIZE;
-	else
-		fb_size = MSM_FB_SIZE;
-
-	size = fb_size;
-	addr = alloc_bootmem_align(size, 0x1000);
-	msm_fb_resources[0].start = __pa(addr);
-	msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1;
-	pr_info("allocating %lu bytes at %p (%lx physical) for fb\n",
-		size, addr, __pa(addr));
-}
-
 static struct memtype_reserve msm7x27a_reserve_table[] __initdata = {
 	[MEMTYPE_SMI] = {
 	},
@@ -1074,247 +794,6 @@
 	msm_gsbi1_qup_i2c_device.dev.platform_data = &msm_gsbi1_qup_i2c_pdata;
 }
 
-static struct msm_panel_common_pdata mdp_pdata = {
-	.gpio = 97,
-	.mdp_rev = MDP_REV_303,
-};
-
-
-#ifdef CONFIG_FB_MSM
-#define GPIO_LCDC_BRDG_PD	128
-#define GPIO_LCDC_BRDG_RESET_N	129
-
-#define LCDC_RESET_PHYS		0x90008014
-
-static	void __iomem *lcdc_reset_ptr;
-
-static unsigned mipi_dsi_gpio[] = {
-	GPIO_CFG(GPIO_LCDC_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
-		GPIO_CFG_2MA),       /* LCDC_BRDG_RESET_N */
-	GPIO_CFG(GPIO_LCDC_BRDG_PD, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
-		GPIO_CFG_2MA),       /* LCDC_BRDG_RESET_N */
-};
-
-enum {
-	DSI_SINGLE_LANE = 1,
-	DSI_TWO_LANES,
-};
-
-static int msm_fb_get_lane_config(void)
-{
-	int rc = DSI_TWO_LANES;
-
-	if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
-		rc = DSI_SINGLE_LANE;
-		pr_info("DSI Single Lane\n");
-	} else {
-		pr_info("DSI Two Lanes\n");
-	}
-	return rc;
-}
-
-static int msm_fb_dsi_client_reset(void)
-{
-	int rc = 0;
-
-	rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
-	if (rc < 0) {
-		pr_err("failed to request lcd brdg reset_n\n");
-		return rc;
-	}
-
-	rc = gpio_request(GPIO_LCDC_BRDG_PD, "lcdc_brdg_pd");
-	if (rc < 0) {
-		pr_err("failed to request lcd brdg pd\n");
-		return rc;
-	}
-
-	rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
-	if (rc) {
-		pr_err("Failed to enable LCDC Bridge reset enable\n");
-		goto gpio_error;
-	}
-
-	rc = gpio_tlmm_config(mipi_dsi_gpio[1], GPIO_CFG_ENABLE);
-	if (rc) {
-		pr_err("Failed to enable LCDC Bridge pd enable\n");
-		goto gpio_error2;
-	}
-
-	rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
-	rc |= gpio_direction_output(GPIO_LCDC_BRDG_PD, 1);
-	gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
-
-	if (!rc) {
-		if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
-			lcdc_reset_ptr = ioremap_nocache(LCDC_RESET_PHYS,
-				sizeof(uint32_t));
-
-			if (!lcdc_reset_ptr)
-				return 0;
-		}
-		return rc;
-	} else {
-		goto gpio_error;
-	}
-
-gpio_error2:
-	pr_err("Failed GPIO bridge pd\n");
-	gpio_free(GPIO_LCDC_BRDG_PD);
-
-gpio_error:
-	pr_err("Failed GPIO bridge reset\n");
-	gpio_free(GPIO_LCDC_BRDG_RESET_N);
-	return rc;
-}
-
-static struct regulator_bulk_data regs_dsi[] = {
-	{ .supply = "gp2",   .min_uV = 2850000, .max_uV = 2850000 },
-	{ .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
-};
-
-static int dsi_gpio_initialized;
-
-static int mipi_dsi_panel_power(int on)
-{
-	int rc = 0;
-	uint32_t lcdc_reset_cfg;
-
-	/* I2C-controlled GPIO Expander -init of the GPIOs very late */
-	if (unlikely(!dsi_gpio_initialized)) {
-		pmapp_disp_backlight_init();
-
-		rc = gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr");
-		if (rc < 0) {
-			pr_err("failed to request gpio_disp_pwr\n");
-			return rc;
-		}
-
-		if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
-			rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, 1);
-			if (rc < 0) {
-				pr_err("failed to enable display pwr\n");
-				goto fail_gpio1;
-			}
-
-			rc = gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en");
-			if (rc < 0) {
-				pr_err("failed to request gpio_bkl_en\n");
-				goto fail_gpio1;
-			}
-
-			rc = gpio_direction_output(GPIO_BACKLIGHT_EN, 1);
-			if (rc < 0) {
-				pr_err("failed to enable backlight\n");
-				goto fail_gpio2;
-			}
-		}
-
-		rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_dsi), regs_dsi);
-		if (rc) {
-			pr_err("%s: could not get regulators: %d\n",
-					__func__, rc);
-			goto fail_gpio2;
-		}
-
-		rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_dsi), regs_dsi);
-		if (rc) {
-			pr_err("%s: could not set voltages: %d\n",
-					__func__, rc);
-			goto fail_vreg;
-		}
-		if (pmapp_disp_backlight_set_brightness(100))
-			pr_err("backlight set brightness failed\n");
-
-		dsi_gpio_initialized = 1;
-	}
-
-	if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
-		gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
-		gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
-	} else if (machine_is_msm7x27a_ffa() ||
-			 machine_is_msm7625a_ffa()) {
-		if (on) {
-			/* This line drives an active low pin on FFA */
-			rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, !on);
-			if (rc < 0)
-				pr_err("failed to set direction for "
-					"display pwr\n");
-		} else {
-			gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, !on);
-			rc = gpio_direction_input(GPIO_DISPLAY_PWR_EN);
-			if (rc < 0)
-				pr_err("failed to set direction for "
-					"display pwr\n");
-		}
-	}
-
-	if (on) {
-		gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
-
-		if (machine_is_msm7x27a_surf() ||
-				 machine_is_msm7625a_surf()) {
-			lcdc_reset_cfg = readl_relaxed(lcdc_reset_ptr);
-			rmb();
-			lcdc_reset_cfg &= ~1;
-
-			writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
-			msleep(20);
-			wmb();
-			lcdc_reset_cfg |= 1;
-			writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
-		} else {
-			gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
-			msleep(20);
-			gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
-		}
-	} else {
-		gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 1);
-
-		if (pmapp_disp_backlight_set_brightness(0))
-			pr_err("backlight set brightness failed\n");
-	}
-
-	rc = on ? regulator_bulk_enable(ARRAY_SIZE(regs_dsi), regs_dsi) :
-		  regulator_bulk_disable(ARRAY_SIZE(regs_dsi), regs_dsi);
-
-	if (rc)
-		pr_err("%s: could not %sable regulators: %d\n",
-				__func__, on ? "en" : "dis", rc);
-
-	return rc;
-
-fail_vreg:
-	regulator_bulk_free(ARRAY_SIZE(regs_dsi), regs_dsi);
-fail_gpio2:
-	gpio_free(GPIO_BACKLIGHT_EN);
-fail_gpio1:
-	gpio_free(GPIO_DISPLAY_PWR_EN);
-	dsi_gpio_initialized = 0;
-	return rc;
-}
-#endif
-
-#define MDP_303_VSYNC_GPIO 97
-
-#ifdef CONFIG_FB_MSM_MDP303
-static struct mipi_dsi_platform_data mipi_dsi_pdata = {
-	.vsync_gpio = MDP_303_VSYNC_GPIO,
-	.dsi_power_save   = mipi_dsi_panel_power,
-	.dsi_client_reset = msm_fb_dsi_client_reset,
-	.get_lane_config = msm_fb_get_lane_config,
-};
-#endif
-
-static void __init msm_fb_add_devices(void)
-{
-	msm_fb_register_device("mdp", &mdp_pdata);
-	msm_fb_register_device("lcdc", &lcdc_pdata);
-#ifdef CONFIG_FB_MSM_MDP303
-	msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
-#endif
-}
-
 #define MSM_EBI2_PHYS			0xa0d00000
 #define MSM_EBI2_XMEM_CS2_CFG1		0xa0d10030
 
@@ -1678,7 +1157,7 @@
 
 static void __init msm7x2x_init_early(void)
 {
-	msm_msm7x2x_allocate_memory_regions();
+	msm_msm7627a_allocate_memory_regions();
 }
 
 MACHINE_START(MSM7X27A_RUMI3, "QCT MSM7x27a RUMI3")
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index 9d4818a..e3664a4 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -124,13 +124,6 @@
 #ifdef CONFIG_ARCH_MSM7X27A
 #define MSM_PMEM_MDP_SIZE       0x1DD1000
 #define MSM_PMEM_ADSP_SIZE      0x1000000
-
-#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
-#define MSM_FB_SIZE		0x260000
-#else
-#define MSM_FB_SIZE		0x195000
-#endif
-
 #endif
 
 #if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C) || \
@@ -474,66 +467,6 @@
 
 early_param("pmem_adsp_size", pmem_adsp_size_setup);
 
-static unsigned fb_size = MSM_FB_SIZE;
-static int __init fb_size_setup(char *p)
-{
-	fb_size = memparse(p, NULL);
-	return 0;
-}
-
-early_param("fb_size", fb_size_setup);
-
-static struct resource msm_fb_resources[] = {
-	{
-		.flags	= IORESOURCE_DMA,
-	}
-};
-
-static int msm_fb_detect_panel(const char *name)
-{
-	int ret;
-
-	if (!strncmp(name, "mipi_video_truly_wvga", 21))
-		ret = 0;
-	else
-		ret = -ENODEV;
-
-	return ret;
-}
-
-static int mipi_truly_set_bl(int on)
-{
-	gpio_set_value_cansleep(QRD_GPIO_BACKLIGHT_EN, !!on);
-
-	return 1;
-}
-
-static struct msm_fb_platform_data msm_fb_pdata = {
-	.detect_client = msm_fb_detect_panel,
-};
-
-static struct platform_device msm_fb_device = {
-	.name   = "msm_fb",
-	.id     = 0,
-	.num_resources  = ARRAY_SIZE(msm_fb_resources),
-	.resource       = msm_fb_resources,
-	.dev    = {
-		.platform_data = &msm_fb_pdata,
-	}
-};
-
-static struct msm_panel_common_pdata mipi_truly_pdata = {
-	.pmic_backlight = mipi_truly_set_bl,
-};
-
-static struct platform_device mipi_dsi_truly_panel_device = {
-	.name	= "mipi_truly",
-	.id	= 0,
-	.dev	= {
-		.platform_data = &mipi_truly_pdata,
-	}
-};
-
 #define SND(desc, num) { .name = #desc, .id = num }
 static struct snd_endpoint snd_endpoints_list[] = {
 	SND(HANDSET, 0),
@@ -737,7 +670,6 @@
 	&android_usb_device,
 	&android_pmem_device,
 	&android_pmem_adsp_device,
-	&msm_fb_device,
 	&android_pmem_audio_device,
 	&msm_device_snd,
 	&msm_device_adspdec,
@@ -746,7 +678,6 @@
 #ifdef CONFIG_BT
 	&msm_bt_power_device,
 #endif
-	&mipi_dsi_truly_panel_device,
 	&msm_wlan_ar6000_pm_device,
 	&asoc_msm_pcm,
 	&asoc_msm_dai0,
@@ -769,19 +700,6 @@
 }
 early_param("pmem_audio_size", pmem_audio_size_setup);
 
-static void __init msm_msm7627a_allocate_memory_regions(void)
-{
-	void *addr;
-	unsigned long size;
-
-	size = fb_size ? : MSM_FB_SIZE;
-	addr = alloc_bootmem_align(size, 0x1000);
-	msm_fb_resources[0].start = __pa(addr);
-	msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1;
-	pr_info("allocating %lu bytes at %p (%lx physical) for fb\n", size,
-						addr, __pa(addr));
-}
-
 static struct memtype_reserve msm7627a_reserve_table[] __initdata = {
 	[MEMTYPE_SMI] = {
 	},
@@ -793,167 +711,6 @@
 	},
 };
 
-static struct msm_panel_common_pdata mdp_pdata = {
-	.gpio = 97,
-	.mdp_rev = MDP_REV_303,
-};
-
-#define GPIO_LCDC_BRDG_PD      128
-#define GPIO_LCDC_BRDG_RESET_N 129
-#define GPIO_LCD_DSI_SEL 125
-
-static unsigned mipi_dsi_gpio[] = {
-		GPIO_CFG(GPIO_LCDC_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT,
-		GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* LCDC_BRDG_RESET_N */
-		GPIO_CFG(GPIO_LCDC_BRDG_PD, 0, GPIO_CFG_OUTPUT,
-		GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* LCDC_BRDG_PD */
-};
-
-static unsigned lcd_dsi_sel_gpio[] = {
-	GPIO_CFG(GPIO_LCD_DSI_SEL, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
-			GPIO_CFG_2MA),
-};
-
-enum {
-	DSI_SINGLE_LANE = 1,
-	DSI_TWO_LANES,
-};
-
-static int msm_fb_get_lane_config(void)
-{
-	pr_info("DSI_TWO_LANES\n");
-	return DSI_TWO_LANES;
-}
-
-static int mipi_truly_sel_mode(int video_mode)
-{
-	int rc = 0;
-
-	rc = gpio_request(GPIO_LCD_DSI_SEL, "lcd_dsi_sel");
-	if (rc < 0)
-		goto gpio_error;
-
-	rc = gpio_tlmm_config(lcd_dsi_sel_gpio[0], GPIO_CFG_ENABLE);
-	if (rc)
-		goto gpio_error;
-
-	rc = gpio_direction_output(GPIO_LCD_DSI_SEL, 1);
-	if (!rc) {
-		gpio_set_value_cansleep(GPIO_LCD_DSI_SEL, video_mode);
-		return rc;
-	} else {
-		goto gpio_error;
-	}
-
-gpio_error:
-	pr_err("mipi_truly_sel_mode failed\n");
-	gpio_free(GPIO_LCD_DSI_SEL);
-	return rc;
-}
-
-static int msm_fb_dsi_client_qrd1_reset(void)
-{
-	int rc = 0;
-
-	rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
-	if (rc < 0) {
-		pr_err("failed to request lcd brdg reset_n\n");
-		return rc;
-	}
-
-	rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
-	if (rc < 0) {
-		pr_err("Failed to enable LCDC Bridge reset enable\n");
-		return rc;
-	}
-
-	rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
-	if (rc < 0) {
-		pr_err("Failed GPIO bridge pd\n");
-		gpio_free(GPIO_LCDC_BRDG_RESET_N);
-		return rc;
-	}
-
-	mipi_truly_sel_mode(1);
-
-	return rc;
-}
-
-static int msm_fb_dsi_client_reset(void)
-{
-	int rc = 0;
-
-	rc = msm_fb_dsi_client_qrd1_reset();
-	return rc;
-}
-
-static int dsi_gpio_initialized;
-
-static int mipi_dsi_panel_qrd1_power(int on)
-{
-	int rc = 0;
-
-	if (!dsi_gpio_initialized) {
-		rc = gpio_request(QRD_GPIO_BACKLIGHT_EN, "gpio_bkl_en");
-		if (rc < 0)
-			return rc;
-
-		rc = gpio_tlmm_config(GPIO_CFG(QRD_GPIO_BACKLIGHT_EN, 0,
-			GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
-			GPIO_CFG_ENABLE);
-		if (rc < 0) {
-			pr_err("failed GPIO_BACKLIGHT_EN tlmm config\n");
-			return rc;
-		}
-
-		rc = gpio_direction_output(QRD_GPIO_BACKLIGHT_EN, 1);
-		if (rc < 0) {
-			pr_err("failed to enable backlight\n");
-			gpio_free(QRD_GPIO_BACKLIGHT_EN);
-			return rc;
-		}
-		dsi_gpio_initialized = 1;
-	}
-
-	gpio_set_value_cansleep(QRD_GPIO_BACKLIGHT_EN, !!on);
-
-	if (!on) {
-		gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
-		msleep(20);
-		gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
-		msleep(20);
-		gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
-
-	}
-
-	return rc;
-}
-
-static int mipi_dsi_panel_power(int on)
-{
-	int rc = 0;
-
-	rc = mipi_dsi_panel_qrd1_power(on);
-	return rc;
-}
-
-#define MDP_303_VSYNC_GPIO 97
-
-#ifdef CONFIG_FB_MSM_MDP303
-static struct mipi_dsi_platform_data mipi_dsi_pdata = {
-	.vsync_gpio		= MDP_303_VSYNC_GPIO,
-	.dsi_power_save		= mipi_dsi_panel_power,
-	.dsi_client_reset	= msm_fb_dsi_client_reset,
-	.get_lane_config	= msm_fb_get_lane_config,
-};
-#endif
-
-static void __init msm_fb_add_devices(void)
-{
-	msm_fb_register_device("mdp", &mdp_pdata);
-	msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
-}
-
 static void __init size_pmem_devices(void)
 {
 #ifdef CONFIG_ANDROID_PMEM
diff --git a/arch/arm/mach-msm/cpufreq.c b/arch/arm/mach-msm/cpufreq.c
index 2477221..9bc8eb3 100644
--- a/arch/arm/mach-msm/cpufreq.c
+++ b/arch/arm/mach-msm/cpufreq.c
@@ -3,7 +3,7 @@
  * MSM architecture cpufreq driver
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
  * Author: Mike A. Chan <mikechan@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -173,9 +173,6 @@
 	struct cpufreq_work_struct *cpu_work = NULL;
 #endif
 
-	if (cpu_is_apq8064())
-		return -ENODEV;
-
 	table = cpufreq_frequency_get_table(policy->cpu);
 	if (cpufreq_frequency_table_cpuinfo(policy, table)) {
 #ifdef CONFIG_MSM_CPU_FREQ_SET_MIN_MAX
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 4fa3e92..8fdcbdd 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -2065,7 +2065,7 @@
 		.src = MSM_BUS_MASTER_GRAPHICS_3D,
 		.dst = MSM_BUS_SLAVE_EBI_CH0,
 		.ab = 0,
-		.ib = KGSL_CONVERT_TO_MBPS(1200),
+		.ib = KGSL_CONVERT_TO_MBPS(1000),
 	},
 };
 
@@ -2139,7 +2139,7 @@
 		.src = MSM_BUS_MASTER_GRAPHICS_2D_CORE0,
 		.dst = MSM_BUS_SLAVE_EBI_CH0,
 		.ab = 0,
-		.ib = KGSL_CONVERT_TO_MBPS(1200),
+		.ib = KGSL_CONVERT_TO_MBPS(1000),
 	},
 };
 
@@ -2187,7 +2187,7 @@
 		.src = MSM_BUS_MASTER_GRAPHICS_2D_CORE1,
 		.dst = MSM_BUS_SLAVE_EBI_CH0,
 		.ab = 0,
-		.ib = KGSL_CONVERT_TO_MBPS(1200),
+		.ib = KGSL_CONVERT_TO_MBPS(1000),
 	},
 };
 
diff --git a/arch/arm/mach-msm/footswitch-8x60.c b/arch/arm/mach-msm/footswitch-8x60.c
index 7f63dc8..cd6e582 100644
--- a/arch/arm/mach-msm/footswitch-8x60.c
+++ b/arch/arm/mach-msm/footswitch-8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -103,7 +103,8 @@
 					clock->name, clock->rate);
 				for (clock--; clock >= fs->clk_data; clock--) {
 					if (clock->enabled)
-						clk_disable(clock->clk);
+						clk_disable_unprepare(
+								clock->clk);
 					clk_set_rate(clock->clk, clock->rate);
 				}
 				return rc;
@@ -115,7 +116,7 @@
 		 * we don't try to disable them later and crash due to
 		 * unbalanced calls.
 		 */
-		clock->enabled = !clk_enable(clock->clk);
+		clock->enabled = !clk_prepare_enable(clock->clk);
 	}
 
 	return 0;
@@ -128,7 +129,7 @@
 	/* Restore clocks to their orignal states before setup_clocks(). */
 	for (clock = fs->clk_data; clock->clk; clock++) {
 		if (clock->enabled)
-			clk_disable(clock->clk);
+			clk_disable_unprepare(clock->clk);
 		if (clock->rate && clk_set_rate(clock->clk, clock->rate))
 			pr_err("Failed to restore %s rate to %lu Hz.\n",
 				clock->name, clock->rate);
@@ -327,7 +328,7 @@
 	}
 
 	/* Disable core clock. */
-	clk_disable(fs->core_clk);
+	clk_disable_unprepare(fs->core_clk);
 
 	/*
 	 * (Re-)Assert resets for all clocks in the clock domain, since
@@ -357,7 +358,7 @@
 	udelay(RESET_DELAY_US);
 
 	/* Re-enable core clock. */
-	clk_enable(fs->core_clk);
+	clk_prepare_enable(fs->core_clk);
 
 	/* Return clocks to their state before this function. */
 	restore_clocks(fs);
@@ -396,7 +397,7 @@
 	}
 
 	/* Disable core clock. */
-	clk_disable(fs->core_clk);
+	clk_disable_unprepare(fs->core_clk);
 
 	/*
 	 * Assert resets for all clocks in the clock domain so that
@@ -421,7 +422,7 @@
 	writel_relaxed(regval, fs->gfs_ctl_reg);
 
 	/* Re-enable core clock. */
-	clk_enable(fs->core_clk);
+	clk_prepare_enable(fs->core_clk);
 
 	/* Return clocks to their state before this function. */
 	restore_clocks(fs);
diff --git a/arch/arm/mach-msm/footswitch-pcom.c b/arch/arm/mach-msm/footswitch-pcom.c
index 8eec807..c48c141 100644
--- a/arch/arm/mach-msm/footswitch-pcom.c
+++ b/arch/arm/mach-msm/footswitch-pcom.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -92,10 +92,10 @@
 	fs->is_rate_set = !!(clk_get_rate(fs->src_clk));
 	if (!fs->is_rate_set)
 		clk_set_rate(fs->src_clk, fs->src_clk_init_rate);
-	clk_enable(fs->core_clk);
+	clk_prepare_enable(fs->core_clk);
 
 	if (fs->ahb_clk)
-		clk_enable(fs->ahb_clk);
+		clk_prepare_enable(fs->ahb_clk);
 
 	return 0;
 }
@@ -103,8 +103,8 @@
 static void disable_clocks(struct footswitch *fs)
 {
 	if (fs->ahb_clk)
-		clk_disable(fs->ahb_clk);
-	clk_disable(fs->core_clk);
+		clk_disable_unprepare(fs->ahb_clk);
+	clk_disable_unprepare(fs->core_clk);
 }
 
 static int footswitch_is_enabled(struct regulator_dev *rdev)
diff --git a/arch/arm/mach-msm/include/mach/irqs-copper.h b/arch/arm/mach-msm/include/mach/irqs-copper.h
index 24da0a4..821eaeb 100644
--- a/arch/arm/mach-msm/include/mach/irqs-copper.h
+++ b/arch/arm/mach-msm/include/mach/irqs-copper.h
@@ -34,7 +34,7 @@
 #define TLMM_MSM_SUMMARY_IRQ		(GIC_SPI_START + 16)
 #define SPS_BAM_DMA_IRQ			(GIC_SPI_START + 105)
 
-#define NR_MSM_IRQS 256
+#define NR_MSM_IRQS 1020 /* Should be 256 - but higher due to bug in sim */
 #define NR_GPIO_IRQS 156
 #define NR_BOARD_IRQS 100
 #define NR_TLMM_MSM_DIR_CONN_IRQ 8
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8064.h b/arch/arm/mach-msm/include/mach/msm_iomap-8064.h
index 15b2856..c584c66 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8064.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8064.h
@@ -97,5 +97,7 @@
 
 #define APQ8064_SAW_L2_PHYS		0x02012000
 #define APQ8064_SAW_L2_SIZE		SZ_4K
+#define APQ8064_QFPROM_PHYS		0x00700000
+#define APQ8064_QFPROM_SIZE		SZ_4K
 
 #endif
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h
index 16751fe..a55dee6 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -28,9 +28,15 @@
 	uint32_t		cal_paddr;
 };
 
+struct acdb_atomic_cal_block {
+	atomic_t		cal_size;
+	atomic_t		cal_kvaddr;
+	atomic_t		cal_paddr;
+};
+
 struct acdb_cal_data {
-	uint32_t		num_cal_blocks;
-	struct acdb_cal_block	*cal_blocks;
+	uint32_t			num_cal_blocks;
+	struct acdb_atomic_cal_block	*cal_blocks;
 };
 
 uint32_t get_voice_rx_topology(void);
@@ -44,6 +50,7 @@
 void get_all_vocstrm_cal(struct acdb_cal_block *cal_block);
 void get_all_vocvol_cal(struct acdb_cal_block *cal_block);
 void get_anc_cal(struct acdb_cal_block *cal_block);
+void get_afe_cal(int32_t path, struct acdb_cal_block *cal_block);
 void get_audproc_cal(int32_t path, struct acdb_cal_block *cal_block);
 void get_audstrm_cal(int32_t path, struct acdb_cal_block *cal_block);
 void get_audvol_cal(int32_t path, struct acdb_cal_block *cal_block);
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 9622a4c..0f9d707 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -278,6 +278,7 @@
 		.length =   MSM_SHARED_RAM_SIZE,
 		.type =     MT_DEVICE,
 	},
+	MSM_CHIP_DEVICE(QFPROM, APQ8064),
 };
 
 void __init msm_map_apq8064_io(void)
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_arb.c b/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
index 8175738..feabe04 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -305,7 +305,13 @@
 	*info->link_info.sel_bw += add_bw;
 
 	info->pnode[index].sel_bw = &info->pnode[index].bw[ctx];
-	info->pnode[index].sel_clk = &info->pnode[index].clk[ctx];
+
+	/**
+	 * To select the right clock, AND the context with
+	 * client active flag.
+	 */
+	info->pnode[index].sel_clk = &info->pnode[index].clk[ctx &
+		cl_active_flag];
 	*info->pnode[index].sel_bw += add_bw;
 
 	info->link_info.num_tiers = info->node_info->num_tiers;
@@ -345,7 +351,8 @@
 		*hop->link_info.sel_bw += add_bw;
 
 		hop->pnode[index].sel_bw = &hop->pnode[index].bw[ctx];
-		hop->pnode[index].sel_clk = &hop->pnode[index].clk[ctx];
+		hop->pnode[index].sel_clk = &hop->pnode[index].clk[ctx &
+			cl_active_flag];
 
 		if (!hop->node_info->buswidth) {
 			MSM_BUS_WARN("No bus width found. Using default\n");
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 b06e5dd..3b178b5 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -216,6 +216,13 @@
 	struct msm_bus_fabric *fabric = to_msm_bus_fabric(fabdev);
 	struct nodeclk *nodeclk;
 
+	/**
+	 * Integration for clock rates is not required if context is not
+	 * same as client's active-only flag
+	 */
+	if (ctx != cl_active_flag)
+		goto skip_set_clks;
+
 	/* Maximum for this gateway */
 	for (i = 0; i <= slave->num_pnodes; i++) {
 		if (i == index && (req_clk_hz < curr_clk_hz))
@@ -272,13 +279,7 @@
 
 	if (clk_flag) {
 		nodeclk = &fabric->info.nodeclk[ctx];
-		/**
-		 * Send a clock request only when the client requests in active
-		 * context and the ACTIVE_CTX clock rate is selected OR the
-		 * client request is in normal context and normal clock rate
-		 * is selected.
-		 */
-		if (nodeclk->clk && (!((ctx == ACTIVE_CTX) ^ cl_active_flag))) {
+		if (nodeclk->clk) {
 			MSM_BUS_DBG("clks: id: %d set-clk: %lu bwsum_hz:%lu\n",
 			fabric->fabdev.id, *pclk, bwsum_hz);
 			if (nodeclk->rate != *pclk) {
@@ -289,7 +290,7 @@
 		}
 	} else {
 		nodeclk = &slave->nodeclk[ctx];
-		if (nodeclk->clk && (!((ctx == ACTIVE_CTX) ^ cl_active_flag))) {
+		if (nodeclk->clk) {
 			rate = *pclk;
 			MSM_BUS_DBG("AXI_clks: id: %d set-clk: %lu "
 			"bwsum_hz: %lu\n" , slave->node_info->priv_id, rate,
@@ -299,8 +300,7 @@
 				nodeclk->rate = rate;
 			}
 		}
-		if (!status && slave->memclk.clk &&
-			(!((ctx == ACTIVE_CTX) ^ cl_active_flag))) {
+		if (!status && slave->memclk.clk) {
 			rate = *slave->link_info.sel_clk;
 			if (slave->memclk.rate != rate) {
 				slave->memclk.rate = rate;
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
index 37a6900..2e61e90 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
@@ -22,43 +22,52 @@
 
 #define MAX_NETWORKS		12
 
+struct sidetone_atomic_cal {
+	atomic_t	enable;
+	atomic_t	gain;
+};
+
+
 struct acdb_data {
 	struct mutex		acdb_mutex;
 
 	/* ANC Cal */
-	struct acdb_cal_block	anc_cal;
+	struct acdb_atomic_cal_block	anc_cal;
 
 	/* AudProc Cal */
-	uint32_t		asm_topology;
-	uint32_t		adm_topology[MAX_AUDPROC_TYPES];
-	struct acdb_cal_block	audproc_cal[MAX_AUDPROC_TYPES];
-	struct acdb_cal_block	audstrm_cal[MAX_AUDPROC_TYPES];
-	struct acdb_cal_block	audvol_cal[MAX_AUDPROC_TYPES];
+	atomic_t			asm_topology;
+	atomic_t			adm_topology[MAX_AUDPROC_TYPES];
+	struct acdb_atomic_cal_block	audproc_cal[MAX_AUDPROC_TYPES];
+	struct acdb_atomic_cal_block	audstrm_cal[MAX_AUDPROC_TYPES];
+	struct acdb_atomic_cal_block	audvol_cal[MAX_AUDPROC_TYPES];
 
 	/* VocProc Cal */
-	uint32_t                voice_rx_topology;
-	uint32_t                voice_tx_topology;
-	struct acdb_cal_block	vocproc_cal[MAX_NETWORKS];
-	struct acdb_cal_block	vocstrm_cal[MAX_NETWORKS];
-	struct acdb_cal_block	vocvol_cal[MAX_NETWORKS];
+	atomic_t			voice_rx_topology;
+	atomic_t			voice_tx_topology;
+	struct acdb_atomic_cal_block	vocproc_cal[MAX_NETWORKS];
+	struct acdb_atomic_cal_block	vocstrm_cal[MAX_NETWORKS];
+	struct acdb_atomic_cal_block	vocvol_cal[MAX_NETWORKS];
 	/* size of cal block tables above*/
-	uint32_t		vocproc_cal_size;
-	uint32_t		vocstrm_cal_size;
-	uint32_t		vocvol_cal_size;
+	atomic_t			vocproc_cal_size;
+	atomic_t			vocstrm_cal_size;
+	atomic_t			vocvol_cal_size;
 	/* Total size of cal data for all networks */
-	uint32_t		vocproc_total_cal_size;
-	uint32_t		vocstrm_total_cal_size;
-	uint32_t		vocvol_total_cal_size;
+	atomic_t			vocproc_total_cal_size;
+	atomic_t			vocstrm_total_cal_size;
+	atomic_t			vocvol_total_cal_size;
+
+	/* AFE cal */
+	struct acdb_atomic_cal_block	afe_cal[MAX_AUDPROC_TYPES];
 
 	/* Sidetone Cal */
-	struct sidetone_cal	sidetone_cal;
+	struct sidetone_atomic_cal	sidetone_cal;
 
 	/* PMEM information */
-	int			pmem_fd;
-	unsigned long		paddr;
-	unsigned long		kvaddr;
-	unsigned long		pmem_len;
-	struct file		*file;
+	atomic_t			pmem_fd;
+	atomic64_t			paddr;
+	atomic64_t			kvaddr;
+	atomic64_t			pmem_len;
+	struct file			*file;
 
 };
 
@@ -67,90 +76,105 @@
 
 uint32_t get_voice_rx_topology(void)
 {
-	return acdb_data.voice_rx_topology;
+	return atomic_read(&acdb_data.voice_rx_topology);
 }
 
 void store_voice_rx_topology(uint32_t topology)
 {
-	acdb_data.voice_rx_topology = topology;
+	atomic_set(&acdb_data.voice_rx_topology, topology);
 }
 
 uint32_t get_voice_tx_topology(void)
 {
-	return acdb_data.voice_tx_topology;
+	return atomic_read(&acdb_data.voice_tx_topology);
 }
 
 void store_voice_tx_topology(uint32_t topology)
 {
-	acdb_data.voice_tx_topology = topology;
+	atomic_set(&acdb_data.voice_tx_topology, topology);
 }
 
 uint32_t get_adm_rx_topology(void)
 {
-	return acdb_data.adm_topology[RX_CAL];
+	return atomic_read(&acdb_data.adm_topology[RX_CAL]);
 }
 
 void store_adm_rx_topology(uint32_t topology)
 {
-	acdb_data.adm_topology[RX_CAL] = topology;
+	atomic_set(&acdb_data.adm_topology[RX_CAL], topology);
 }
 
 uint32_t get_adm_tx_topology(void)
 {
-	return acdb_data.adm_topology[TX_CAL];
+	return atomic_read(&acdb_data.adm_topology[TX_CAL]);
 }
 
 void store_adm_tx_topology(uint32_t topology)
 {
-	acdb_data.adm_topology[TX_CAL] = topology;
+	atomic_set(&acdb_data.adm_topology[TX_CAL], topology);
 }
 
 uint32_t get_asm_topology(void)
 {
-	return acdb_data.asm_topology;
+	return atomic_read(&acdb_data.asm_topology);
 }
 
 void store_asm_topology(uint32_t topology)
 {
-	acdb_data.asm_topology = topology;
+	atomic_set(&acdb_data.asm_topology, topology);
 }
 
 void get_all_voice_cal(struct acdb_cal_block *cal_block)
 {
-	cal_block->cal_kvaddr = acdb_data.vocproc_cal[0].cal_kvaddr;
-	cal_block->cal_paddr = acdb_data.vocproc_cal[0].cal_paddr;
-	cal_block->cal_size = acdb_data.vocproc_total_cal_size +
-				acdb_data.vocstrm_total_cal_size +
-				acdb_data.vocvol_total_cal_size;
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.vocproc_cal[0].cal_kvaddr);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.vocproc_cal[0].cal_paddr);
+	cal_block->cal_size =
+		atomic_read(&acdb_data.vocproc_total_cal_size) +
+		atomic_read(&acdb_data.vocstrm_total_cal_size) +
+		atomic_read(&acdb_data.vocvol_total_cal_size);
 }
 
 void get_all_cvp_cal(struct acdb_cal_block *cal_block)
 {
-	cal_block->cal_kvaddr = acdb_data.vocproc_cal[0].cal_kvaddr;
-	cal_block->cal_paddr = acdb_data.vocproc_cal[0].cal_paddr;
-	cal_block->cal_size = acdb_data.vocproc_total_cal_size +
-				acdb_data.vocvol_total_cal_size;
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.vocproc_cal[0].cal_kvaddr);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.vocproc_cal[0].cal_paddr);
+	cal_block->cal_size =
+		atomic_read(&acdb_data.vocproc_total_cal_size) +
+		atomic_read(&acdb_data.vocvol_total_cal_size);
 }
 
 void get_all_vocproc_cal(struct acdb_cal_block *cal_block)
 {
-	cal_block->cal_kvaddr = acdb_data.vocproc_cal[0].cal_kvaddr;
-	cal_block->cal_paddr = acdb_data.vocproc_cal[0].cal_paddr;
-	cal_block->cal_size = acdb_data.vocproc_total_cal_size;
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.vocproc_cal[0].cal_kvaddr);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.vocproc_cal[0].cal_paddr);
+	cal_block->cal_size =
+		atomic_read(&acdb_data.vocproc_total_cal_size);
 }
 
 void get_all_vocstrm_cal(struct acdb_cal_block *cal_block)
 {
-	cal_block->cal_kvaddr = acdb_data.vocstrm_cal[0].cal_kvaddr;
-	cal_block->cal_paddr = acdb_data.vocstrm_cal[0].cal_paddr;
-	cal_block->cal_size = acdb_data.vocstrm_total_cal_size;
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.vocstrm_cal[0].cal_kvaddr);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.vocstrm_cal[0].cal_paddr);
+	cal_block->cal_size =
+		atomic_read(&acdb_data.vocstrm_total_cal_size);
 }
 
 void get_all_vocvol_cal(struct acdb_cal_block *cal_block)
 {
-	cal_block->cal_kvaddr = acdb_data.vocvol_cal[0].cal_kvaddr;
-	cal_block->cal_paddr = acdb_data.vocvol_cal[0].cal_paddr;
-	cal_block->cal_size = acdb_data.vocvol_total_cal_size;
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.vocvol_cal[0].cal_kvaddr);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.vocvol_cal[0].cal_paddr);
+	cal_block->cal_size =
+		atomic_read(&acdb_data.vocvol_total_cal_size);
 }
 
 void get_anc_cal(struct acdb_cal_block *cal_block)
@@ -162,13 +186,12 @@
 		goto done;
 	}
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	cal_block->cal_kvaddr = acdb_data.anc_cal.cal_kvaddr;
-	cal_block->cal_paddr = acdb_data.anc_cal.cal_paddr;
-	cal_block->cal_size = acdb_data.anc_cal.cal_size;
-
-	mutex_unlock(&acdb_data.acdb_mutex);
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.anc_cal.cal_kvaddr);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.anc_cal.cal_paddr);
+	cal_block->cal_size =
+		atomic_read(&acdb_data.anc_cal.cal_size);
 done:
 	return;
 }
@@ -177,23 +200,69 @@
 {
 	pr_debug("%s,\n", __func__);
 
-	if (cal_block->cal_offset > acdb_data.pmem_len) {
+	if (cal_block->cal_offset > atomic64_read(&acdb_data.pmem_len)) {
 		pr_err("%s: offset %d is > pmem_len %ld\n",
 			__func__, cal_block->cal_offset,
-			acdb_data.pmem_len);
+			(long)atomic64_read(&acdb_data.pmem_len));
 		goto done;
 	}
 
-	mutex_lock(&acdb_data.acdb_mutex);
+	atomic_set(&acdb_data.anc_cal.cal_kvaddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+	atomic_set(&acdb_data.anc_cal.cal_paddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+	atomic_set(&acdb_data.anc_cal.cal_size,
+		cal_block->cal_size);
+done:
+	return;
+}
 
-	acdb_data.anc_cal.cal_kvaddr =
-		cal_block->cal_offset + acdb_data.kvaddr;
-	acdb_data.anc_cal.cal_paddr =
-		cal_block->cal_offset + acdb_data.paddr;
-	acdb_data.anc_cal.cal_size =
-		cal_block->cal_size;
+void store_afe_cal(int32_t path, struct cal_block *cal_block)
+{
+	pr_debug("%s, path = %d\n", __func__, path);
 
-	mutex_unlock(&acdb_data.acdb_mutex);
+	if (cal_block->cal_offset > atomic64_read(&acdb_data.pmem_len)) {
+		pr_err("%s: offset %d is > pmem_len %ld\n",
+			__func__, cal_block->cal_offset,
+			(long)atomic64_read(&acdb_data.pmem_len));
+		goto done;
+	}
+	if ((path >= MAX_AUDPROC_TYPES) || (path < 0)) {
+		pr_err("ACDB=> Bad path sent to %s, path: %d\n",
+			__func__, path);
+		goto done;
+	}
+
+	atomic_set(&acdb_data.afe_cal[path].cal_kvaddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+	atomic_set(&acdb_data.afe_cal[path].cal_paddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+	atomic_set(&acdb_data.afe_cal[path].cal_size,
+		cal_block->cal_size);
+done:
+	return;
+}
+
+void get_afe_cal(int32_t path, struct acdb_cal_block *cal_block)
+{
+	pr_debug("%s, path = %d\n", __func__, path);
+
+	if (cal_block == NULL) {
+		pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+		goto done;
+	}
+	if ((path >= MAX_AUDPROC_TYPES) || (path < 0)) {
+		pr_err("ACDB=> Bad path sent to %s, path: %d\n",
+			__func__, path);
+		goto done;
+	}
+
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.afe_cal[path].cal_kvaddr);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.afe_cal[path].cal_paddr);
+	cal_block->cal_size =
+		atomic_read(&acdb_data.afe_cal[path].cal_size);
 done:
 	return;
 }
@@ -202,12 +271,10 @@
 {
 	pr_debug("%s, path = %d\n", __func__, path);
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	if (cal_block->cal_offset > acdb_data.pmem_len) {
+	if (cal_block->cal_offset > atomic64_read(&acdb_data.pmem_len)) {
 		pr_err("%s: offset %d is > pmem_len %ld\n",
 			__func__, cal_block->cal_offset,
-			acdb_data.pmem_len);
+			(long)atomic64_read(&acdb_data.pmem_len));
 		goto done;
 	}
 	if (path >= MAX_AUDPROC_TYPES) {
@@ -216,15 +283,13 @@
 		goto done;
 	}
 
-	acdb_data.audproc_cal[path].cal_kvaddr =
-		cal_block->cal_offset + acdb_data.kvaddr;
-	acdb_data.audproc_cal[path].cal_paddr =
-		cal_block->cal_offset + acdb_data.paddr;
-	acdb_data.audproc_cal[path].cal_size =
-		cal_block->cal_size;
-
+	atomic_set(&acdb_data.audproc_cal[path].cal_kvaddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+	atomic_set(&acdb_data.audproc_cal[path].cal_paddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+	atomic_set(&acdb_data.audproc_cal[path].cal_size,
+		cal_block->cal_size);
 done:
-	mutex_unlock(&acdb_data.acdb_mutex);
 	return;
 }
 
@@ -242,13 +307,12 @@
 		goto done;
 	}
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	cal_block->cal_kvaddr = acdb_data.audproc_cal[path].cal_kvaddr;
-	cal_block->cal_paddr = acdb_data.audproc_cal[path].cal_paddr;
-	cal_block->cal_size = acdb_data.audproc_cal[path].cal_size;
-
-	mutex_unlock(&acdb_data.acdb_mutex);
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.audproc_cal[path].cal_kvaddr);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.audproc_cal[path].cal_paddr);
+	cal_block->cal_size =
+		atomic_read(&acdb_data.audproc_cal[path].cal_size);
 done:
 	return;
 }
@@ -257,12 +321,10 @@
 {
 	pr_debug("%s, path = %d\n", __func__, path);
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	if (cal_block->cal_offset > acdb_data.pmem_len) {
+	if (cal_block->cal_offset > atomic64_read(&acdb_data.pmem_len)) {
 		pr_err("%s: offset %d is > pmem_len %ld\n",
 			__func__, cal_block->cal_offset,
-			acdb_data.pmem_len);
+			(long)atomic64_read(&acdb_data.pmem_len));
 		goto done;
 	}
 	if (path >= MAX_AUDPROC_TYPES) {
@@ -271,15 +333,13 @@
 		goto done;
 	}
 
-	acdb_data.audstrm_cal[path].cal_kvaddr =
-		cal_block->cal_offset + acdb_data.kvaddr;
-	acdb_data.audstrm_cal[path].cal_paddr =
-		cal_block->cal_offset + acdb_data.paddr;
-	acdb_data.audstrm_cal[path].cal_size =
-		cal_block->cal_size;
-
+	atomic_set(&acdb_data.audstrm_cal[path].cal_kvaddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+	atomic_set(&acdb_data.audstrm_cal[path].cal_paddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+	atomic_set(&acdb_data.audstrm_cal[path].cal_size,
+		cal_block->cal_size);
 done:
-	mutex_unlock(&acdb_data.acdb_mutex);
 	return;
 }
 
@@ -297,13 +357,12 @@
 		goto done;
 	}
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	cal_block->cal_kvaddr = acdb_data.audstrm_cal[path].cal_kvaddr;
-	cal_block->cal_paddr = acdb_data.audstrm_cal[path].cal_paddr;
-	cal_block->cal_size = acdb_data.audstrm_cal[path].cal_size;
-
-	mutex_unlock(&acdb_data.acdb_mutex);
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.audstrm_cal[path].cal_kvaddr);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.audstrm_cal[path].cal_paddr);
+	cal_block->cal_size =
+		atomic_read(&acdb_data.audstrm_cal[path].cal_size);
 done:
 	return;
 }
@@ -312,12 +371,10 @@
 {
 	pr_debug("%s, path = %d\n", __func__, path);
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	if (cal_block->cal_offset > acdb_data.pmem_len) {
+	if (cal_block->cal_offset > atomic64_read(&acdb_data.pmem_len)) {
 		pr_err("%s: offset %d is > pmem_len %ld\n",
 			__func__, cal_block->cal_offset,
-			acdb_data.pmem_len);
+			(long)atomic64_read(&acdb_data.pmem_len));
 		goto done;
 	}
 	if (path >= MAX_AUDPROC_TYPES) {
@@ -326,15 +383,13 @@
 		goto done;
 	}
 
-	acdb_data.audvol_cal[path].cal_kvaddr =
-		cal_block->cal_offset + acdb_data.kvaddr;
-	acdb_data.audvol_cal[path].cal_paddr =
-		cal_block->cal_offset + acdb_data.paddr;
-	acdb_data.audvol_cal[path].cal_size =
-		cal_block->cal_size;
-
+	atomic_set(&acdb_data.audvol_cal[path].cal_kvaddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+	atomic_set(&acdb_data.audvol_cal[path].cal_paddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+	atomic_set(&acdb_data.audvol_cal[path].cal_size,
+		cal_block->cal_size);
 done:
-	mutex_unlock(&acdb_data.acdb_mutex);
 	return;
 }
 
@@ -352,13 +407,12 @@
 		goto done;
 	}
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	cal_block->cal_kvaddr = acdb_data.audvol_cal[path].cal_kvaddr;
-	cal_block->cal_paddr = acdb_data.audvol_cal[path].cal_paddr;
-	cal_block->cal_size = acdb_data.audvol_cal[path].cal_size;
-
-	mutex_unlock(&acdb_data.acdb_mutex);
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.audvol_cal[path].cal_kvaddr);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.audvol_cal[path].cal_paddr);
+	cal_block->cal_size =
+		atomic_read(&acdb_data.audvol_cal[path].cal_size);
 done:
 	return;
 }
@@ -375,31 +429,28 @@
 		goto done;
 	}
 
-
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	acdb_data.vocproc_total_cal_size = 0;
+	atomic_set(&acdb_data.vocproc_total_cal_size, 0);
 	for (i = 0; i < len; i++) {
-		if (cal_blocks[i].cal_offset > acdb_data.pmem_len) {
+		if (cal_blocks[i].cal_offset >
+					atomic64_read(&acdb_data.pmem_len)) {
 			pr_err("%s: offset %d is > pmem_len %ld\n",
 				__func__, cal_blocks[i].cal_offset,
-				acdb_data.pmem_len);
-			acdb_data.vocproc_cal[i].cal_size = 0;
+				(long)atomic64_read(&acdb_data.pmem_len));
+			atomic_set(&acdb_data.vocproc_cal[i].cal_size, 0);
 		} else {
-			acdb_data.vocproc_total_cal_size +=
-				cal_blocks[i].cal_size;
-			acdb_data.vocproc_cal[i].cal_size =
-				cal_blocks[i].cal_size;
-			acdb_data.vocproc_cal[i].cal_paddr =
+			atomic_add(cal_blocks[i].cal_size,
+				&acdb_data.vocproc_total_cal_size);
+			atomic_set(&acdb_data.vocproc_cal[i].cal_size,
+				cal_blocks[i].cal_size);
+			atomic_set(&acdb_data.vocproc_cal[i].cal_paddr,
 				cal_blocks[i].cal_offset +
-				acdb_data.paddr;
-			acdb_data.vocproc_cal[i].cal_kvaddr =
+				atomic64_read(&acdb_data.paddr));
+			atomic_set(&acdb_data.vocproc_cal[i].cal_kvaddr,
 				cal_blocks[i].cal_offset +
-				acdb_data.kvaddr;
+				atomic64_read(&acdb_data.kvaddr));
 		}
 	}
-	acdb_data.vocproc_cal_size = len;
-	mutex_unlock(&acdb_data.acdb_mutex);
+	atomic_set(&acdb_data.vocproc_cal_size, len);
 done:
 	return;
 }
@@ -413,12 +464,8 @@
 		goto done;
 	}
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	cal_data->num_cal_blocks = acdb_data.vocproc_cal_size;
+	cal_data->num_cal_blocks = atomic_read(&acdb_data.vocproc_cal_size);
 	cal_data->cal_blocks = &acdb_data.vocproc_cal[0];
-
-	mutex_unlock(&acdb_data.acdb_mutex);
 done:
 	return;
 }
@@ -434,30 +481,28 @@
 		goto done;
 	}
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	acdb_data.vocstrm_total_cal_size = 0;
+	atomic_set(&acdb_data.vocstrm_total_cal_size, 0);
 	for (i = 0; i < len; i++) {
-		if (cal_blocks[i].cal_offset > acdb_data.pmem_len) {
+		if (cal_blocks[i].cal_offset >
+					atomic64_read(&acdb_data.pmem_len)) {
 			pr_err("%s: offset %d is > pmem_len %ld\n",
 				__func__, cal_blocks[i].cal_offset,
-				acdb_data.pmem_len);
-			acdb_data.vocstrm_cal[i].cal_size = 0;
+				(long)atomic64_read(&acdb_data.pmem_len));
+			atomic_set(&acdb_data.vocstrm_cal[i].cal_size, 0);
 		} else {
-			acdb_data.vocstrm_total_cal_size +=
-				cal_blocks[i].cal_size;
-			acdb_data.vocstrm_cal[i].cal_size =
-				cal_blocks[i].cal_size;
-			acdb_data.vocstrm_cal[i].cal_paddr =
+			atomic_add(cal_blocks[i].cal_size,
+				&acdb_data.vocstrm_total_cal_size);
+			atomic_set(&acdb_data.vocstrm_cal[i].cal_size,
+				cal_blocks[i].cal_size);
+			atomic_set(&acdb_data.vocstrm_cal[i].cal_paddr,
 				cal_blocks[i].cal_offset +
-				acdb_data.paddr;
-			acdb_data.vocstrm_cal[i].cal_kvaddr =
+				atomic64_read(&acdb_data.paddr));
+			atomic_set(&acdb_data.vocstrm_cal[i].cal_kvaddr,
 				cal_blocks[i].cal_offset +
-				acdb_data.kvaddr;
+				atomic64_read(&acdb_data.kvaddr));
 		}
 	}
-	acdb_data.vocstrm_cal_size = len;
-	mutex_unlock(&acdb_data.acdb_mutex);
+	atomic_set(&acdb_data.vocstrm_cal_size, len);
 done:
 	return;
 }
@@ -471,12 +516,8 @@
 		goto done;
 	}
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	cal_data->num_cal_blocks = acdb_data.vocstrm_cal_size;
+	cal_data->num_cal_blocks = atomic_read(&acdb_data.vocstrm_cal_size);
 	cal_data->cal_blocks = &acdb_data.vocstrm_cal[0];
-
-	mutex_unlock(&acdb_data.acdb_mutex);
 done:
 	return;
 }
@@ -492,30 +533,28 @@
 		goto done;
 	}
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	acdb_data.vocvol_total_cal_size = 0;
+	atomic_set(&acdb_data.vocvol_total_cal_size, 0);
 	for (i = 0; i < len; i++) {
-		if (cal_blocks[i].cal_offset > acdb_data.pmem_len) {
+		if (cal_blocks[i].cal_offset >
+					atomic64_read(&acdb_data.pmem_len)) {
 			pr_err("%s: offset %d is > pmem_len %ld\n",
 				__func__, cal_blocks[i].cal_offset,
-				acdb_data.pmem_len);
-			acdb_data.vocvol_cal[i].cal_size = 0;
+				(long)atomic64_read(&acdb_data.pmem_len));
+			atomic_set(&acdb_data.vocvol_cal[i].cal_size, 0);
 		} else {
-			acdb_data.vocvol_total_cal_size +=
-				cal_blocks[i].cal_size;
-			acdb_data.vocvol_cal[i].cal_size =
-				cal_blocks[i].cal_size;
-			acdb_data.vocvol_cal[i].cal_paddr =
+			atomic_add(cal_blocks[i].cal_size,
+				&acdb_data.vocvol_total_cal_size);
+			atomic_set(&acdb_data.vocvol_cal[i].cal_size,
+				cal_blocks[i].cal_size);
+			atomic_set(&acdb_data.vocvol_cal[i].cal_paddr,
 				cal_blocks[i].cal_offset +
-				acdb_data.paddr;
-			acdb_data.vocvol_cal[i].cal_kvaddr =
+				atomic64_read(&acdb_data.paddr));
+			atomic_set(&acdb_data.vocvol_cal[i].cal_kvaddr,
 				cal_blocks[i].cal_offset +
-				acdb_data.kvaddr;
+				atomic64_read(&acdb_data.kvaddr));
 		}
 	}
-	acdb_data.vocvol_cal_size = len;
-	mutex_unlock(&acdb_data.acdb_mutex);
+	atomic_set(&acdb_data.vocvol_cal_size, len);
 done:
 	return;
 }
@@ -529,12 +568,8 @@
 		goto done;
 	}
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	cal_data->num_cal_blocks = acdb_data.vocvol_cal_size;
+	cal_data->num_cal_blocks = atomic_read(&acdb_data.vocvol_cal_size);
 	cal_data->cal_blocks = &acdb_data.vocvol_cal[0];
-
-	mutex_unlock(&acdb_data.acdb_mutex);
 done:
 	return;
 }
@@ -543,12 +578,8 @@
 {
 	pr_debug("%s\n", __func__);
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	acdb_data.sidetone_cal.enable = cal_data->enable;
-	acdb_data.sidetone_cal.gain = cal_data->gain;
-
-	mutex_unlock(&acdb_data.acdb_mutex);
+	atomic_set(&acdb_data.sidetone_cal.enable, cal_data->enable);
+	atomic_set(&acdb_data.sidetone_cal.gain, cal_data->gain);
 }
 
 
@@ -561,12 +592,8 @@
 		goto done;
 	}
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	cal_data->enable = acdb_data.sidetone_cal.enable;
-	cal_data->gain = acdb_data.sidetone_cal.gain;
-
-	mutex_unlock(&acdb_data.acdb_mutex);
+	cal_data->enable = atomic_read(&acdb_data.sidetone_cal.enable);
+	cal_data->gain = atomic_read(&acdb_data.sidetone_cal.gain);
 done:
 	return;
 }
@@ -574,14 +601,12 @@
 static int acdb_open(struct inode *inode, struct file *f)
 {
 	s32 result = 0;
-	pr_info("%s\n", __func__);
+	pr_debug("%s\n", __func__);
 
-	mutex_lock(&acdb_data.acdb_mutex);
-	if (acdb_data.pmem_fd) {
-		pr_info("%s: ACDB opened but PMEM allocated, using existing PMEM!\n",
+	if (atomic_read(&acdb_data.pmem_fd)) {
+		pr_debug("%s: ACDB opened but PMEM allocated, using existing PMEM!\n",
 			__func__);
 	}
-	mutex_unlock(&acdb_data.acdb_mutex);
 
 	atomic_inc(&usage_count);
 	return result;
@@ -589,9 +614,11 @@
 
 static int deregister_pmem(void)
 {
-	if (acdb_data.pmem_fd) {
+	if (atomic_read(&acdb_data.pmem_fd)) {
+		mutex_lock(&acdb_data.acdb_mutex);
 		put_pmem_file(acdb_data.file);
-		acdb_data.pmem_fd = 0;
+		mutex_unlock(&acdb_data.acdb_mutex);
+		atomic_set(&acdb_data.pmem_fd, 0);
 	}
 	return 0;
 }
@@ -599,19 +626,30 @@
 static int register_pmem(void)
 {
 	int result;
+	unsigned long paddr;
+	unsigned long kvaddr;
+	unsigned long pmem_len;
 
-	result = get_pmem_file(acdb_data.pmem_fd, &acdb_data.paddr,
-				&acdb_data.kvaddr, &acdb_data.pmem_len,
+	mutex_lock(&acdb_data.acdb_mutex);
+	result = get_pmem_file(atomic_read(&acdb_data.pmem_fd),
+				&paddr, &kvaddr, &pmem_len,
 				&acdb_data.file);
+	mutex_unlock(&acdb_data.acdb_mutex);
 	if (result != 0) {
-		acdb_data.pmem_fd = 0;
+		atomic_set(&acdb_data.pmem_fd, 0);
+		atomic64_set(&acdb_data.pmem_len, 0);
 		pr_err("%s: Could not register PMEM!!!\n", __func__);
 		goto done;
 	}
 
+	atomic64_set(&acdb_data.paddr, paddr);
+	atomic64_set(&acdb_data.kvaddr, kvaddr);
+	atomic64_set(&acdb_data.pmem_len, pmem_len);
 	pr_debug("AUDIO_REGISTER_PMEM done! paddr = 0x%lx, "
-		"kvaddr = 0x%lx, len = x%lx\n", acdb_data.paddr,
-		acdb_data.kvaddr, acdb_data.pmem_len);
+		"kvaddr = 0x%lx, len = x%lx\n",
+		(long)atomic64_read(&acdb_data.paddr),
+		(long)atomic64_read(&acdb_data.kvaddr),
+		(long)atomic64_read(&acdb_data.pmem_len));
 
 done:
 	return result;
@@ -619,37 +657,33 @@
 static long acdb_ioctl(struct file *f,
 		unsigned int cmd, unsigned long arg)
 {
-	s32			result = 0;
-	s32			audproc_path;
-	s32			size;
-	u32			topology;
+	int32_t			result = 0;
+	int32_t			size;
+	int32_t			pmem_fd;
+	uint32_t		topology;
 	struct cal_block	data[MAX_NETWORKS];
 	pr_debug("%s\n", __func__);
 
 	switch (cmd) {
 	case AUDIO_REGISTER_PMEM:
 		pr_debug("AUDIO_REGISTER_PMEM\n");
-		mutex_lock(&acdb_data.acdb_mutex);
-		if (acdb_data.pmem_fd) {
+		if (atomic_read(&acdb_data.pmem_fd)) {
 			deregister_pmem();
-			pr_info("Remove the existing PMEM\n");
+			pr_debug("Remove the existing PMEM\n");
 		}
 
-		if (copy_from_user(&acdb_data.pmem_fd, (void *)arg,
-					sizeof(acdb_data.pmem_fd))) {
+		if (copy_from_user(&pmem_fd, (void *)arg, sizeof(pmem_fd))) {
 			pr_err("%s: fail to copy pmem handle!\n", __func__);
 			result = -EFAULT;
 		} else {
+			atomic_set(&acdb_data.pmem_fd, pmem_fd);
 			result = register_pmem();
 		}
-		mutex_unlock(&acdb_data.acdb_mutex);
 		goto done;
 
 	case AUDIO_DEREGISTER_PMEM:
 		pr_debug("AUDIO_DEREGISTER_PMEM\n");
-		mutex_lock(&acdb_data.acdb_mutex);
 		deregister_pmem();
-		mutex_unlock(&acdb_data.acdb_mutex);
 		goto done;
 	case AUDIO_SET_VOICE_RX_TOPOLOGY:
 		if (copy_from_user(&topology, (void *)arg,
@@ -721,45 +755,51 @@
 
 	switch (cmd) {
 	case AUDIO_SET_AUDPROC_TX_CAL:
-		audproc_path = TX_CAL;
 		if (size > sizeof(struct cal_block))
 			pr_err("%s: More Audproc Cal then expected, "
 				"size received: %d\n", __func__, size);
-		store_audproc_cal(audproc_path, data);
+		store_audproc_cal(TX_CAL, data);
 		break;
 	case AUDIO_SET_AUDPROC_RX_CAL:
-		audproc_path = RX_CAL;
 		if (size > sizeof(struct cal_block))
 			pr_err("%s: More Audproc Cal then expected, "
 				"size received: %d\n", __func__, size);
-		store_audproc_cal(audproc_path, data);
+		store_audproc_cal(RX_CAL, data);
 		break;
 	case AUDIO_SET_AUDPROC_TX_STREAM_CAL:
-		audproc_path = TX_CAL;
 		if (size > sizeof(struct cal_block))
 			pr_err("%s: More Audproc Cal then expected, "
 				"size received: %d\n", __func__, size);
-		store_audstrm_cal(audproc_path, data);
+		store_audstrm_cal(TX_CAL, data);
 		break;
 	case AUDIO_SET_AUDPROC_RX_STREAM_CAL:
-		audproc_path = RX_CAL;
 		if (size > sizeof(struct cal_block))
 			pr_err("%s: More Audproc Cal then expected, "
 				"size received: %d\n", __func__, size);
-		store_audstrm_cal(audproc_path, data);
+		store_audstrm_cal(RX_CAL, data);
 		break;
 	case AUDIO_SET_AUDPROC_TX_VOL_CAL:
-		audproc_path = TX_CAL;
 		if (size > sizeof(struct cal_block))
 			pr_err("%s: More Audproc Cal then expected, "
 				"size received: %d\n", __func__, size);
-		store_audvol_cal(audproc_path, data);
+		store_audvol_cal(TX_CAL, data);
 	case AUDIO_SET_AUDPROC_RX_VOL_CAL:
-		audproc_path = RX_CAL;
 		if (size > sizeof(struct cal_block))
 			pr_err("%s: More Audproc Cal then expected, "
 				"size received: %d\n", __func__, size);
-		store_audvol_cal(audproc_path, data);
+		store_audvol_cal(RX_CAL, data);
+		break;
+	case AUDIO_SET_AFE_TX_CAL:
+		if (size > sizeof(struct cal_block))
+			pr_err("%s: More AFE Cal then expected, "
+				"size received: %d\n", __func__, size);
+		store_afe_cal(TX_CAL, data);
+		break;
+	case AUDIO_SET_AFE_RX_CAL:
+		if (size > sizeof(struct cal_block))
+			pr_err("%s: More AFE Cal then expected, "
+				"size received: %d\n", __func__, size);
+		store_afe_cal(RX_CAL, data);
 		break;
 	case AUDIO_SET_VOCPROC_CAL:
 		store_vocproc_cal(size / sizeof(struct cal_block), data);
@@ -794,14 +834,13 @@
 
 	pr_debug("%s\n", __func__);
 
-	mutex_lock(&acdb_data.acdb_mutex);
-	if (acdb_data.pmem_fd) {
-		if (size <= acdb_data.pmem_len) {
+	if (atomic_read(&acdb_data.pmem_fd)) {
+		if (size <= atomic64_read(&acdb_data.pmem_len)) {
 			vma->vm_page_prot = pgprot_noncached(
 						vma->vm_page_prot);
 			result = remap_pfn_range(vma,
 				vma->vm_start,
-				acdb_data.paddr >> PAGE_SHIFT,
+				atomic64_read(&acdb_data.paddr) >> PAGE_SHIFT,
 				size,
 				vma->vm_page_prot);
 		} else {
@@ -812,7 +851,6 @@
 		pr_err("%s: PMEM is not allocated, yet!\n", __func__);
 		result = -ENODEV;
 	}
-	mutex_unlock(&acdb_data.acdb_mutex);
 
 	return result;
 }
@@ -824,16 +862,13 @@
 	atomic_dec(&usage_count);
 	atomic_read(&usage_count);
 
-	pr_info("%s: ref count %d!\n", __func__,
+	pr_debug("%s: ref count %d!\n", __func__,
 		atomic_read(&usage_count));
 
-	if (atomic_read(&usage_count) >= 1) {
+	if (atomic_read(&usage_count) >= 1)
 		result = -EBUSY;
-	} else {
-		mutex_lock(&acdb_data.acdb_mutex);
+	else
 		result = deregister_pmem();
-		mutex_unlock(&acdb_data.acdb_mutex);
-	}
 
 	return result;
 }
diff --git a/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c b/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c
index 51a209d..997fdf8 100644
--- a/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c
+++ b/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -2699,7 +2699,10 @@
 
 		platform_add_devices(snd_devices_fluid,
 		ARRAY_SIZE(snd_devices_fluid));
-	} else if (machine_is_msm8x60_surf()) {
+	}
+	if (machine_is_msm8x60_surf() || machine_is_msm8x60_ffa()
+		|| machine_is_msm8x60_fusion()
+		|| machine_is_msm8x60_fusn_ffa()) {
 		for (i = 0; i < ARRAY_SIZE(snd_devices_ftm); i++)
 			snd_devices_ftm[i]->id = dev_id++;
 
diff --git a/arch/arm/mach-msm/qdsp6v2/q6voice.c b/arch/arm/mach-msm/qdsp6v2/q6voice.c
index 34169c0..12a02c5 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6voice.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6voice.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -791,7 +791,7 @@
 	struct apr_hdr cvs_cal_cmd_hdr;
 	uint32_t *cmd_buf;
 	struct acdb_cal_data cal_data;
-	struct acdb_cal_block *cal_blk;
+	struct acdb_atomic_cal_block *cal_blk;
 	int32_t cal_size_per_network;
 	uint32_t *cal_data_per_network;
 	int index = 0;
@@ -830,11 +830,12 @@
 	pr_debug("cal_blk =%x\n", (uint32_t)cal_data.cal_blocks);
 
 	for (; index < cal_data.num_cal_blocks; index++) {
-		cal_size_per_network = cal_blk[index].cal_size;
+		cal_size_per_network = atomic_read(&cal_blk[index].cal_size);
 		pr_debug(" cal size =%d\n", cal_size_per_network);
 		if (cal_size_per_network >= BUFFER_PAYLOAD_SIZE)
 			pr_err("Cal size is too big\n");
-		cal_data_per_network = (u32 *)cal_blk[index].cal_kvaddr;
+		cal_data_per_network =
+			(u32 *)atomic_read(&cal_blk[index].cal_kvaddr);
 		pr_debug(" cal data=%x\n", (uint32_t)cal_data_per_network);
 		cvs_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 			cal_size_per_network);
@@ -868,7 +869,7 @@
 	struct apr_hdr cvp_cal_cmd_hdr;
 	uint32_t *cmd_buf;
 	struct acdb_cal_data cal_data;
-	struct acdb_cal_block *cal_blk;
+	struct acdb_atomic_cal_block *cal_blk;
 	int32_t cal_size_per_network;
 	uint32_t *cal_data_per_network;
 	int index = 0;
@@ -907,11 +908,12 @@
 	pr_debug(" cal_blk =%x\n", (uint32_t)cal_data.cal_blocks);
 
 	for (; index < cal_data.num_cal_blocks; index++) {
-		cal_size_per_network = cal_blk[index].cal_size;
+		cal_size_per_network = atomic_read(&cal_blk[index].cal_size);
 		if (cal_size_per_network >= BUFFER_PAYLOAD_SIZE)
 			pr_err("Cal size is too big\n");
 		pr_debug(" cal size =%d\n", cal_size_per_network);
-		cal_data_per_network = (u32 *)cal_blk[index].cal_kvaddr;
+		cal_data_per_network =
+			(u32 *)atomic_read(&cal_blk[index].cal_kvaddr);
 		pr_debug(" cal data=%x\n", (uint32_t)cal_data_per_network);
 
 		cvp_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
@@ -945,11 +947,9 @@
 	struct apr_hdr cvp_vol_cal_cmd_hdr;
 	uint32_t *cmd_buf;
 	struct acdb_cal_data cal_data;
-	struct acdb_cal_block *cal_blk;
+	struct acdb_atomic_cal_block *cal_blk;
 	int32_t cal_size_per_network;
 	uint32_t *cal_data_per_network;
-	uint32_t num_volume_steps;
-	int offset = 0;
 	int index = 0;
 	int ret = 0;
 	void *apr_cvp = voice_get_apr_cvp();
@@ -986,27 +986,18 @@
 	pr_debug("Cal_blk =%x\n", (uint32_t)cal_data.cal_blocks);
 
 	for (; index < cal_data.num_cal_blocks; index++) {
-		cal_size_per_network = cal_blk[index].cal_size;
-		cal_data_per_network = (u32 *)cal_blk[index].cal_kvaddr;
-
-		/* Number of volume steps are only included in the */
-		/* first block, need to be inserted into the rest */
-		if (index != 0) {
-			offset = sizeof(num_volume_steps);
-			memcpy(cmd_buf + (APR_HDR_SIZE / sizeof(uint32_t)),
-				&num_volume_steps, offset);
-		} else {
-			num_volume_steps = *cal_data_per_network;
-		}
+		cal_size_per_network = atomic_read(&cal_blk[index].cal_size);
+		cal_data_per_network =
+			(u32 *)atomic_read(&cal_blk[index].cal_kvaddr);
 
 		pr_debug("Cal size =%d, index=%d\n", cal_size_per_network,
 			index);
 		pr_debug("Cal data=%x\n", (uint32_t)cal_data_per_network);
 		cvp_vol_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
-			cal_size_per_network + offset);
+			cal_size_per_network);
 		memcpy(cmd_buf, &cvp_vol_cal_cmd_hdr,  APR_HDR_SIZE);
-		memcpy(cmd_buf + (APR_HDR_SIZE / sizeof(uint32_t)) +
-			offset, cal_data_per_network, cal_size_per_network);
+		memcpy(cmd_buf + (APR_HDR_SIZE / sizeof(uint32_t)),
+			cal_data_per_network, cal_size_per_network);
 		pr_debug("Send vol table\n");
 
 		v->cvp_state = CMD_STATUS_FAIL;
diff --git a/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h b/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h
index e747957..7096669 100644
--- a/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h
+++ b/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -888,7 +888,7 @@
 	{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFF, 0xC5)}, \
 	{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4C, 0xFF, 0x29)}, \
 	{ADIE_CODEC_ACTION_DELAY_WAIT, 0xBB8}, \
-	{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFF, 0xF5)}, \
+	{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFF, 0xC5)}, \
 	{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0xAC)}, \
 	{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0xAC)}, \
 	{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0x27, 0x20)}, \
diff --git a/arch/arm/mach-msm/smd_tty.c b/arch/arm/mach-msm/smd_tty.c
index c8248a7..4248be4 100644
--- a/arch/arm/mach-msm/smd_tty.c
+++ b/arch/arm/mach-msm/smd_tty.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/smd_tty.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -552,8 +552,11 @@
 			legacy_ds |= cpu_is_msm7x01() || cpu_is_msm7x25();
 			legacy_ds |= cpu_is_msm7x27() || cpu_is_msm7x30();
 			legacy_ds |= cpu_is_qsd8x50() || cpu_is_msm8x55();
+			/*
+			 * use legacy mode for 8660 Standalone (subtype 0)
+			 */
 			legacy_ds |= cpu_is_msm8x60() &&
-					(socinfo_get_platform_subtype() == 0x1);
+					(socinfo_get_platform_subtype() == 0x0);
 
 			if (!legacy_ds)
 				continue;
diff --git a/drivers/bluetooth/hci_smd.c b/drivers/bluetooth/hci_smd.c
index 101697f..4e78152 100644
--- a/drivers/bluetooth/hci_smd.c
+++ b/drivers/bluetooth/hci_smd.c
@@ -2,7 +2,7 @@
  *  HCI_SMD (HCI Shared Memory Driver) is Qualcomm's Shared memory driver
  *  for the BT HCI protocol.
  *
- *  Copyright (c) 2000-2001, 2011 Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2000-2001, 2011-2012 Code Aurora Forum. All rights reserved.
  *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
  *  Copyright (C) 2004-2006  Marcel Holtmann <marcel@holtmann.org>
  *
@@ -51,8 +51,7 @@
 	struct wake_lock wake_lock_tx;
 	struct wake_lock wake_lock_rx;
 	struct timer_list rx_q_timer;
-	struct tasklet_struct hci_event_task;
-	struct tasklet_struct hci_data_task;
+	struct tasklet_struct rx_task;
 };
 static struct hci_smd_data hs;
 
@@ -129,111 +128,95 @@
 		kfree(hdev->driver_data);
 }
 
-static void hci_smd_recv_data(unsigned long arg)
+static void hci_smd_recv_data(void)
 {
 	int len = 0;
 	int rc = 0;
 	struct sk_buff *skb = NULL;
-	unsigned  char *buf = NULL;
 	struct hci_smd_data *hsmd = &hs;
 	wake_lock(&hs.wake_lock_rx);
 
 	len = smd_read_avail(hsmd->data_channel);
 	if (len > HCI_MAX_FRAME_SIZE) {
-		BT_ERR("Frame larger than the allowed size");
+		BT_ERR("Frame larger than the allowed size, flushing frame");
+		smd_read(hsmd->data_channel, NULL, len);
 		goto out_data;
 	}
-	while (len > 0) {
-		skb = bt_skb_alloc(len, GFP_ATOMIC);
-		if (!skb) {
-			BT_ERR("Error in allocating  socket buffer");
-			goto out_data;
-		}
 
-		buf = kmalloc(len, GFP_ATOMIC);
-		if (!buf)  {
-			BT_ERR("Error in allocating  buffer");
-			rc = -ENOMEM;
-			goto out_data;
-		}
+	if (len <= 0)
+		goto out_data;
 
-		rc = smd_read(hsmd->data_channel, (void *)buf, len);
-		if (rc < len) {
-			BT_ERR("Error in reading from the channel");
-			goto out_data;
-		}
-
-		memcpy(skb_put(skb, len), buf, len);
-		skb->dev = (void *)hsmd->hdev;
-		bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
-
-		skb_orphan(skb);
-
-		rc = hci_recv_frame(skb);
-		if (rc < 0) {
-			BT_ERR("Error in passing the packet to HCI Layer");
-			/*
-			 * skb is getting freed in hci_recv_frame, making it
-			 * to null to avoid multiple access
-			 */
-			skb = NULL;
-			goto out_data;
-		}
-
-		kfree(buf);
-		buf = NULL;
-		len = smd_read_avail(hsmd->data_channel);
-		/*
-		 * Start the timer to monitor whether the Rx queue is
-		 * empty for releasing the Rx wake lock
-		 */
-		BT_DBG("Rx Timer is starting");
-		mod_timer(&hsmd->rx_q_timer,
-				jiffies + msecs_to_jiffies(RX_Q_MONITOR));
+	skb = bt_skb_alloc(len, GFP_ATOMIC);
+	if (!skb) {
+		BT_ERR("Error in allocating socket buffer");
+		smd_read(hsmd->data_channel, NULL, len);
+		goto out_data;
 	}
+
+	rc = smd_read(hsmd->data_channel, skb_put(skb, len), len);
+	if (rc < len) {
+		BT_ERR("Error in reading from the channel");
+		goto out_data;
+	}
+
+	skb->dev = (void *)hsmd->hdev;
+	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
+	skb_orphan(skb);
+
+	rc = hci_recv_frame(skb);
+	if (rc < 0) {
+		BT_ERR("Error in passing the packet to HCI Layer");
+		/*
+		 * skb is getting freed in hci_recv_frame, making it
+		 * to null to avoid multiple access
+		 */
+		skb = NULL;
+		goto out_data;
+	}
+
+	/*
+	 * Start the timer to monitor whether the Rx queue is
+	 * empty for releasing the Rx wake lock
+	 */
+	BT_DBG("Rx Timer is starting");
+	mod_timer(&hsmd->rx_q_timer,
+			jiffies + msecs_to_jiffies(RX_Q_MONITOR));
+
 out_data:
 	release_lock();
-	if (rc) {
-		if (skb)
-			kfree_skb(skb);
-		kfree(buf);
-	}
+	if (rc)
+		kfree_skb(skb);
 }
 
-static void hci_smd_recv_event(unsigned long arg)
+static void hci_smd_recv_event(void)
 {
 	int len = 0;
 	int rc = 0;
 	struct sk_buff *skb = NULL;
-	unsigned  char *buf = NULL;
 	struct hci_smd_data *hsmd = &hs;
 	wake_lock(&hs.wake_lock_rx);
 
 	len = smd_read_avail(hsmd->event_channel);
 	if (len > HCI_MAX_FRAME_SIZE) {
-		BT_ERR("Frame larger than the allowed size");
+		BT_ERR("Frame larger than the allowed size, flushing frame");
+		rc = smd_read(hsmd->event_channel, NULL, len);
 		goto out_event;
 	}
 
 	while (len > 0) {
 		skb = bt_skb_alloc(len, GFP_ATOMIC);
 		if (!skb) {
-			BT_ERR("Error in allocating  socket buffer");
+			BT_ERR("Error in allocating socket buffer");
+			smd_read(hsmd->event_channel, NULL, len);
 			goto out_event;
 		}
-		buf = kmalloc(len, GFP_ATOMIC);
-		if (!buf) {
-			BT_ERR("Error in allocating  buffer");
-			rc = -ENOMEM;
-			goto out_event;
-		}
-		rc = smd_read(hsmd->event_channel, (void *)buf, len);
+
+		rc = smd_read(hsmd->event_channel, skb_put(skb, len), len);
 		if (rc < len) {
 			BT_ERR("Error in reading from the event channel");
 			goto out_event;
 		}
 
-		memcpy(skb_put(skb, len), buf, len);
 		skb->dev = (void *)hsmd->hdev;
 		bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
 
@@ -250,8 +233,6 @@
 			goto out_event;
 		}
 
-		kfree(buf);
-		buf = NULL;
 		len = smd_read_avail(hsmd->event_channel);
 		/*
 		 * Start the timer to monitor whether the Rx queue is
@@ -263,11 +244,8 @@
 	}
 out_event:
 	release_lock();
-	if (rc) {
-		if (skb)
-			kfree_skb(skb);
-		kfree(buf);
-	}
+	if (rc)
+		kfree_skb(skb);
 }
 
 static int hci_smd_send_frame(struct sk_buff *skb)
@@ -314,6 +292,16 @@
 	return ret;
 }
 
+static void hci_smd_rx(unsigned long arg)
+{
+	struct hci_smd_data *hsmd = &hs;
+
+	while ((smd_read_avail(hsmd->event_channel) > 0) ||
+				(smd_read_avail(hsmd->data_channel) > 0)) {
+		hci_smd_recv_event();
+		hci_smd_recv_data();
+	}
+}
 
 static void hci_smd_notify_event(void *data, unsigned int event)
 {
@@ -330,7 +318,7 @@
 	case SMD_EVENT_DATA:
 		len = smd_read_avail(hsmd->event_channel);
 		if (len > 0)
-			tasklet_hi_schedule(&hs.hci_event_task);
+			tasklet_hi_schedule(&hs.rx_task);
 		else if (len < 0)
 			BT_ERR("Failed to read event from smd %d", len);
 
@@ -355,7 +343,7 @@
 	int len = 0;
 
 	if (!hdev) {
-		BT_ERR("HCI device (hdev=NULL)");
+		BT_ERR("Frame for unknown HCI device (hdev=NULL)");
 		return;
 	}
 
@@ -363,7 +351,7 @@
 	case SMD_EVENT_DATA:
 		len = smd_read_avail(hsmd->data_channel);
 		if (len > 0)
-			tasklet_hi_schedule(&hs.hci_data_task);
+			tasklet_hi_schedule(&hs.rx_task);
 		else if (len < 0)
 			BT_ERR("Failed to read data from smd %d", len);
 		break;
@@ -402,10 +390,9 @@
 	hdev->destruct = hci_smd_destruct;
 	hdev->owner = THIS_MODULE;
 
-	tasklet_init(&hsmd->hci_event_task,
-			hci_smd_recv_event, (unsigned long) hsmd);
-	tasklet_init(&hsmd->hci_data_task,
-			hci_smd_recv_data, (unsigned long) hsmd);
+
+	tasklet_init(&hsmd->rx_task,
+			hci_smd_rx, (unsigned long) hsmd);
 	/*
 	 * Setup the timer to monitor whether the Rx queue is empty,
 	 * to control the wake lock release
@@ -445,6 +432,8 @@
 
 static void hci_smd_deregister_dev(struct hci_smd_data *hsmd)
 {
+	tasklet_kill(&hs.rx_task);
+
 	if (hsmd->hdev) {
 		if (hci_unregister_dev(hsmd->hdev) < 0)
 			BT_ERR("Can't unregister HCI device %s",
@@ -468,9 +457,6 @@
 		hs.rx_q_timer.function = NULL;
 		hs.rx_q_timer.data = 0;
 	}
-
-	tasklet_kill(&hs.hci_event_task);
-	tasklet_kill(&hs.hci_data_task);
 }
 
 static int hcismd_set_enable(const char *val, struct kernel_param *kp)
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 4079850..9c1473f 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -808,6 +808,9 @@
 		mutex_lock(&dbs_mutex);
 		mutex_destroy(&this_dbs_info->timer_mutex);
 		dbs_enable--;
+		/* If device is being removed, policy is no longer
+		 * valid. */
+		this_dbs_info->cur_policy = NULL;
 		if (!cpu)
 			input_unregister_handler(&dbs_input_handler);
 		mutex_unlock(&dbs_mutex);
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index e9c3f08..c6e78dd 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -497,8 +497,8 @@
 					struct kgsl_device, display_off);
 	KGSL_PWR_WARN(device, "early suspend start\n");
 	mutex_lock(&device->mutex);
-	kgsl_pwrctrl_request_state(device, KGSL_STATE_SLUMBER);
 	kgsl_pwrctrl_stop_work(device);
+	kgsl_pwrctrl_request_state(device, KGSL_STATE_SLUMBER);
 	kgsl_pwrctrl_sleep(device);
 	mutex_unlock(&device->mutex);
 	KGSL_PWR_WARN(device, "early suspend end\n");
@@ -1318,8 +1318,7 @@
 	int sglen = PAGE_ALIGN(size) / PAGE_SIZE;
 	unsigned long paddr = (unsigned long) addr;
 
-	memdesc->sg = kmalloc(sglen * sizeof(struct scatterlist),
-		GFP_KERNEL);
+	memdesc->sg = vmalloc(sglen * sizeof(struct scatterlist));
 	if (memdesc->sg == NULL)
 		return -ENOMEM;
 
@@ -1359,7 +1358,7 @@
 
 err:
 	spin_unlock(&current->mm->page_table_lock);
-	kfree(memdesc->sg);
+	vfree(memdesc->sg);
 	memdesc->sg = NULL;
 
 	return -EINVAL;
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 6ab9534..60bd232 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -622,7 +622,10 @@
 
 	KGSL_PWR_INFO(device, "idle timer expired device %d\n", device->id);
 	if (device->requested_state == KGSL_STATE_NONE) {
-		kgsl_pwrctrl_request_state(device, KGSL_STATE_SLEEP);
+		if (device->pwrctrl.restore_slumber)
+			kgsl_pwrctrl_request_state(device, KGSL_STATE_SLUMBER);
+		else
+			kgsl_pwrctrl_request_state(device, KGSL_STATE_SLEEP);
 		/* Have work run in a non-interrupt context. */
 		queue_work(device->work_queue, &device->idle_check_ws);
 	}
@@ -788,17 +791,10 @@
 	/* Work through the legal state transitions */
 	switch (device->requested_state) {
 	case KGSL_STATE_NAP:
-		if (device->pwrctrl.restore_slumber) {
-			kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
-			break;
-		}
 		status = _nap(device);
 		break;
 	case KGSL_STATE_SLEEP:
-		if (device->pwrctrl.restore_slumber)
-			status = _slumber(device);
-		else
-			status = _sleep(device);
+		status = _sleep(device);
 		break;
 	case KGSL_STATE_SLUMBER:
 		status = _slumber(device);
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index ec91b39..7211879 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -421,7 +421,7 @@
 	memdesc->ops = &kgsl_vmalloc_ops;
 	memdesc->hostptr = (void *) ptr;
 
-	memdesc->sg = kmalloc(sglen * sizeof(struct scatterlist), GFP_KERNEL);
+	memdesc->sg = vmalloc(sglen * sizeof(struct scatterlist));
 	if (memdesc->sg == NULL) {
 		ret = -ENOMEM;
 		goto done;
@@ -554,7 +554,7 @@
 	if (memdesc->ops && memdesc->ops->free)
 		memdesc->ops->free(memdesc);
 
-	kfree(memdesc->sg);
+	vfree(memdesc->sg);
 
 	memset(memdesc, 0, sizeof(*memdesc));
 }
diff --git a/drivers/gpu/msm/kgsl_sharedmem.h b/drivers/gpu/msm/kgsl_sharedmem.h
index d345ff3..67a1c2d 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.h
+++ b/drivers/gpu/msm/kgsl_sharedmem.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -15,6 +15,7 @@
 
 #include <linux/slab.h>
 #include <linux/dma-mapping.h>
+#include <linux/vmalloc.h>
 #include "kgsl_mmu.h"
 
 struct kgsl_device;
@@ -81,7 +82,7 @@
 {
 	struct page *page = phys_to_page(physaddr);
 
-	memdesc->sg = kmalloc(sizeof(struct scatterlist) * 1, GFP_KERNEL);
+	memdesc->sg = vmalloc(sizeof(struct scatterlist) * 1);
 	if (memdesc->sg == NULL)
 		return -ENOMEM;
 
diff --git a/drivers/mfd/pm8xxx-misc.c b/drivers/mfd/pm8xxx-misc.c
index 7314c7e..283f985 100644
--- a/drivers/mfd/pm8xxx-misc.c
+++ b/drivers/mfd/pm8xxx-misc.c
@@ -944,6 +944,63 @@
 }
 EXPORT_SYMBOL(pm8xxx_uart_gpio_mux_ctrl);
 
+static int __pm8901_preload_dVdd(struct pm8xxx_misc_chip *chip)
+{
+	int rc;
+
+	rc = pm8xxx_writeb(chip->dev->parent, 0x0BD, 0x0F);
+	if (rc)
+		pr_err("pm8xxx_writeb failed for 0x0BD, rc=%d\n", rc);
+
+	rc = pm8xxx_writeb(chip->dev->parent, 0x001, 0xB4);
+	if (rc)
+		pr_err("pm8xxx_writeb failed for 0x001, rc=%d\n", rc);
+
+	pr_info("dVdd preloaded\n");
+
+	return rc;
+}
+
+/**
+ * pm8xxx_preload_dVdd - preload the dVdd regulator during off state.
+ *
+ * This can help to reduce fluctuations in the dVdd voltage during startup
+ * at the cost of additional off state current draw.
+ *
+ * This API should only be called if dVdd startup issues are suspected.
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_preload_dVdd(void)
+{
+	struct pm8xxx_misc_chip *chip;
+	unsigned long flags;
+	int rc = 0;
+
+	spin_lock_irqsave(&pm8xxx_misc_chips_lock, flags);
+
+	/* Loop over all attached PMICs and call specific functions for them. */
+	list_for_each_entry(chip, &pm8xxx_misc_chips, link) {
+		switch (chip->version) {
+		case PM8XXX_VERSION_8901:
+			rc = __pm8901_preload_dVdd(chip);
+			break;
+		default:
+			/* PMIC doesn't have preload_dVdd; do nothing. */
+			break;
+		}
+		if (rc) {
+			pr_err("preload_dVdd failed, rc=%d\n", rc);
+			break;
+		}
+	}
+
+	spin_unlock_irqrestore(&pm8xxx_misc_chips_lock, flags);
+
+	return rc;
+}
+EXPORT_SYMBOL_GPL(pm8xxx_preload_dVdd);
+
 static int __devinit pm8xxx_misc_probe(struct platform_device *pdev)
 {
 	const struct pm8xxx_misc_platform_data *pdata = pdev->dev.platform_data;
diff --git a/drivers/misc/pmem.c b/drivers/misc/pmem.c
index 7ee7c11..f0d523e 100644
--- a/drivers/misc/pmem.c
+++ b/drivers/misc/pmem.c
@@ -1,7 +1,7 @@
 /* drivers/android/pmem.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -2594,6 +2594,7 @@
 {
 	int i, index = 0, id;
 	struct vm_struct *pmem_vma = NULL;
+	struct page *page;
 
 	if (id_count >= PMEM_MAX_DEVICES) {
 		pr_alert("pmem: %s: unable to register driver(%s) - no more "
@@ -2794,6 +2795,11 @@
 
 	pmem[id].base = allocate_contiguous_memory_nomap(pmem[id].size,
 		pmem[id].memory_type, PAGE_SIZE);
+	if (!pmem[id].base) {
+		pr_err("pmem: Cannot allocate from reserved memory for %s\n",
+		 pdata->name);
+		goto err_misc_deregister;
+	}
 
 	pr_info("allocating %lu bytes at %p (%lx physical) for %s\n",
 		pmem[id].size, pmem[id].vbase, pmem[id].base, pmem[id].name);
@@ -2810,7 +2816,7 @@
 			if (!pmem_vma) {
 				pr_err("pmem: Failed to allocate virtual space for "
 					"%s\n", pdata->name);
-				goto out_put_kobj;
+				goto err_free;
 			}
 			pr_err("pmem: Reserving virtual address range %lx - %lx for"
 				" %s\n", (unsigned long) pmem_vma->addr,
@@ -2821,7 +2827,12 @@
 	} else
 		pmem[id].area = NULL;
 
-	pmem[id].garbage_pfn = page_to_pfn(alloc_page(GFP_KERNEL));
+	page = alloc_page(GFP_KERNEL);
+	if (!page) {
+		pr_err("pmem: Failed to allocate page for %s\n", pdata->name);
+		goto cleanup_vm;
+	}
+	pmem[id].garbage_pfn = page_to_pfn(page);
 	atomic_set(&pmem[id].allocation_cnt, 0);
 
 	if (pdata->setup_region)
@@ -2835,6 +2846,12 @@
 
 	return 0;
 
+cleanup_vm:
+	remove_vm_area(pmem_vma);
+err_free:
+	free_contiguous_memory_by_paddr(pmem[id].base);
+err_misc_deregister:
+	misc_deregister(&pmem[id].dev);
 err_cant_register_device:
 out_put_kobj:
 	kobject_put(&pmem[id].kobj);
@@ -2872,6 +2889,19 @@
 	int id = pdev->id;
 	__free_page(pfn_to_page(pmem[id].garbage_pfn));
 	pm_runtime_disable(&pdev->dev);
+	if (pmem[id].vbase)
+		iounmap(pmem[id].vbase);
+	if (pmem[id].map_on_demand && !pmem[id].reusable && pmem[id].area)
+		free_vm_area(pmem[id].area);
+	if (pmem[id].base)
+		free_contiguous_memory_by_paddr(pmem[id].base);
+	kobject_put(&pmem[id].kobj);
+	if (pmem[id].allocator_type == PMEM_ALLOCATORTYPE_BUDDYBESTFIT)
+		kfree(pmem[id].allocator.buddy_bestfit.buddy_bitmap);
+	else if (pmem[id].allocator_type == PMEM_ALLOCATORTYPE_BITMAP) {
+		kfree(pmem[id].allocator.bitmap.bitmap);
+		kfree(pmem[id].allocator.bitmap.bitm_alloc);
+	}
 	misc_deregister(&pmem[id].dev);
 	return 0;
 }
diff --git a/drivers/net/msm_rmnet_bam.c b/drivers/net/msm_rmnet_bam.c
index a0924ed..f11fb60 100644
--- a/drivers/net/msm_rmnet_bam.c
+++ b/drivers/net/msm_rmnet_bam.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -311,7 +311,7 @@
 	/* if write() succeeds, skb access is unsafe in this process */
 	bam_ret = msm_bam_dmux_write(p->ch_id, skb);
 
-	if (bam_ret != 0 && bam_ret != -EAGAIN) {
+	if (bam_ret != 0 && bam_ret != -EAGAIN && bam_ret != -EFAULT) {
 		pr_err("[%s] %s: write returned error %d",
 			dev->name, __func__, bam_ret);
 		return -EPERM;
@@ -464,6 +464,16 @@
 	if (ret == -EPERM)
 		return NETDEV_TX_BUSY;
 
+	/*
+	 * detected SSR a bit early.  shut some things down now, and leave
+	 * the rest to the main ssr handling code when that happens later
+	 */
+	if (ret == -EFAULT) {
+		netif_carrier_off(dev);
+		dev_kfree_skb_any(skb);
+		return 0;
+	}
+
 	if (ret == -EAGAIN) {
 		/*
 		 * This should not happen
@@ -690,6 +700,7 @@
 
 	p = netdev_priv(netdevs[i]);
 	p->in_reset = 1;
+	p->waiting_for_ul = 0;
 	msm_bam_dmux_close(p->ch_id);
 	netif_carrier_off(netdevs[i]);
 	netif_stop_queue(netdevs[i]);
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index 9dc4044..ee7a2a9 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -2,7 +2,7 @@
  * Gadget Driver for Android
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  * Author: Mike Lockwood <lockwood@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -1472,13 +1472,23 @@
 	return 0;
 }
 
+static void android_destroy_device(struct android_dev *dev)
+{
+	struct device_attribute **attrs = android_usb_attributes;
+	struct device_attribute *attr;
+
+	while ((attr = *attrs++))
+		device_remove_file(dev->dev, attr);
+	device_destroy(android_class, dev->dev->devt);
+}
+
 static int __devinit android_probe(struct platform_device *pdev)
 {
 	struct android_usb_platform_data *pdata = pdev->dev.platform_data;
 	struct android_dev *dev = _android_dev;
 
 	dev->pdata = pdata;
-	
+
 	return 0;
 }
 
@@ -1489,36 +1499,55 @@
 static int __init init(void)
 {
 	struct android_dev *dev;
-	int err;
+	int ret;
 
 	android_class = class_create(THIS_MODULE, "android_usb");
 	if (IS_ERR(android_class))
 		return PTR_ERR(android_class);
 
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-	if (!dev)
+	if (!dev) {
+		pr_err("%s(): Failed to alloc memory for android_dev\n",
+				__func__);
+		class_destroy(android_class);
 		return -ENOMEM;
-
+	}
 	dev->functions = supported_functions;
 	INIT_LIST_HEAD(&dev->enabled_functions);
 	INIT_WORK(&dev->work, android_work);
 
-	err = android_create_device(dev);
-	if (err) {
-		class_destroy(android_class);
-		kfree(dev);
-		return err;
+	ret = android_create_device(dev);
+	if (ret) {
+		pr_err("%s(): android_create_device failed\n", __func__);
+		goto err_dev;
 	}
-
 	_android_dev = dev;
 
 	/* Override composite driver functions */
 	composite_driver.setup = android_setup;
 	composite_driver.disconnect = android_disconnect;
 
-	platform_driver_probe(&android_platform_driver, android_probe);
+	ret = platform_driver_probe(&android_platform_driver, android_probe);
+	if (ret) {
+		pr_err("%s(): Failed to register android"
+				 "platform driver\n", __func__);
+		goto err_probe;
+	}
+	ret = usb_composite_probe(&android_usb_driver, android_bind);
+	if (ret) {
+		pr_err("%s(): Failed to register android"
+				 "composite driver\n", __func__);
+		platform_driver_unregister(&android_platform_driver);
+		goto err_probe;
+	}
+	return ret;
 
-	return usb_composite_probe(&android_usb_driver, android_bind);
+err_probe:
+	android_destroy_device(dev);
+err_dev:
+	kfree(dev);
+	class_destroy(android_class);
+	return ret;
 }
 module_init(init);
 
diff --git a/drivers/usb/misc/mdm_ctrl_bridge.c b/drivers/usb/misc/mdm_ctrl_bridge.c
index 11d388c..584503a 100644
--- a/drivers/usb/misc/mdm_ctrl_bridge.c
+++ b/drivers/usb/misc/mdm_ctrl_bridge.c
@@ -333,6 +333,7 @@
 
 static void ctrl_write_callback(struct urb *urb)
 {
+	struct ctrl_bridge	*dev = urb->context;
 
 	if (urb->status) {
 		pr_debug("Write status/size %d/%d\n",
@@ -342,6 +343,7 @@
 	kfree(urb->transfer_buffer);
 	kfree(urb->setup_packet);
 	usb_free_urb(urb);
+	usb_autopm_put_interface_async(dev->intf);
 }
 
 int ctrl_bridge_write(unsigned int id, char *data, size_t size)
@@ -406,7 +408,7 @@
 				 usb_sndctrlpipe(udev, 0),
 				 (unsigned char *)out_ctlreq,
 				 (void *)data, size,
-				 ctrl_write_callback, NULL);
+				 ctrl_write_callback, dev);
 
 	result = usb_autopm_get_interface_async(dev->intf);
 	if (result < 0) {
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index ec9ac24..787514c 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -1592,14 +1592,15 @@
 {
 	struct msm_otg *motg = container_of(w, struct msm_otg, chg_work.work);
 	struct otg_transceiver *otg = &motg->otg;
-	bool is_dcd, tmout, vout, is_aca;
+	bool is_dcd = false, tmout, vout, is_aca;
 	unsigned long delay;
 
 	dev_dbg(otg->dev, "chg detection work\n");
 	switch (motg->chg_state) {
 	case USB_CHG_STATE_UNDEFINED:
 		msm_chg_block_on(motg);
-		msm_chg_enable_dcd(motg);
+		if (motg->pdata->enable_dcd)
+			msm_chg_enable_dcd(motg);
 		msm_chg_enable_aca_det(motg);
 		motg->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
 		motg->dcd_retries = 0;
@@ -1619,10 +1620,12 @@
 				break;
 			}
 		}
-		is_dcd = msm_chg_check_dcd(motg);
+		if (motg->pdata->enable_dcd)
+			is_dcd = msm_chg_check_dcd(motg);
 		tmout = ++motg->dcd_retries == MSM_CHG_DCD_MAX_RETRIES;
 		if (is_dcd || tmout) {
-			msm_chg_disable_dcd(motg);
+			if (motg->pdata->enable_dcd)
+				msm_chg_disable_dcd(motg);
 			msm_chg_enable_primary_det(motg);
 			delay = MSM_CHG_PRIMARY_DET_TIME;
 			motg->chg_state = USB_CHG_STATE_DCD_DONE;
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
index de6bf1a..448194a 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -301,6 +301,13 @@
 	---help---
 	  Support for MDP4 OVERLAY0 write back mode
 
+
+config FB_MSM_OVERLAY1_WRITEBACK
+        depends on FB_MSM_OVERLAY
+        bool "MDP overlay1 write back mode enable"
+        ---help---
+          Support for MDP4 OVERLAY1 write back mode
+
 config FB_MSM_WRITEBACK_MSM_PANEL
 	depends on FB_MSM_OVERLAY
         bool "MDP overlay write back panel enable"
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index 1a4ce91..7b5f464 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -320,6 +320,7 @@
 	uint32 blt_cnt;
 	uint32 ov_cnt;
 	uint32 dmap_cnt;
+	uint32 dmae_cnt;
 	uint32 blt_end;
 	uint32 luma_align_size;
 	struct mdp4_hsic_regs hsic_regs;
@@ -409,8 +410,6 @@
 uint32 mdp4_overlay_op_mode(struct mdp4_overlay_pipe *pipe);
 void mdp4_lcdc_overlay(struct msm_fb_data_type *mfd);
 #ifdef CONFIG_FB_MSM_DTV
-void mdp4_overlay_dtv_vsync_push(struct msm_fb_data_type *mfd,
-			struct mdp4_overlay_pipe *pipe);
 void mdp4_overlay_dtv_ov_done_push(struct msm_fb_data_type *mfd,
 			struct mdp4_overlay_pipe *pipe);
 void mdp4_overlay_dtv_wait_for_ov(struct msm_fb_data_type *mfd,
@@ -420,11 +419,6 @@
 int mdp4_overlay_dtv_unset(struct msm_fb_data_type *mfd,
 			struct mdp4_overlay_pipe *pipe);
 #else
-static inline void mdp4_overlay_dtv_vsync_push(struct msm_fb_data_type *mfd,
-	struct mdp4_overlay_pipe *pipe)
-{
-	/* empty */
-}
 static inline void  mdp4_overlay_dtv_ov_done_push(struct msm_fb_data_type *mfd,
 			struct mdp4_overlay_pipe *pipe)
 {
@@ -612,6 +606,8 @@
 					struct msmfb_overlay_blt *req);
 void mdp4_lcdc_overlay_blt_start(struct msm_fb_data_type *mfd);
 void mdp4_lcdc_overlay_blt_stop(struct msm_fb_data_type *mfd);
+void mdp4_dtv_overlay_blt_start(struct msm_fb_data_type *mfd);
+void mdp4_dtv_overlay_blt_stop(struct msm_fb_data_type *mfd);
 
 int mdp4_mddi_overlay_blt_offset(int *off);
 void mdp4_mddi_overlay_blt(ulong addr);
@@ -687,6 +683,7 @@
 		struct mdp4_overlay_pipe *pipe);
 void mdp4_writeback_dma_busy_wait(struct msm_fb_data_type *mfd);
 void mdp4_overlay1_done_writeback(struct mdp_dma_data *dma);
+void mdp4_dma_e_done_dtv(void);
 
 int mdp4_writeback_start(struct fb_info *info);
 int mdp4_writeback_stop(struct fb_info *info);
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index ecb0a24..1fd0766 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -239,13 +239,27 @@
 
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 
-	/* dma_p source */
 	MDP_OUTP(MDP_BASE + 0xb0004,
 			(pipe->src_height << 16 | pipe->src_width));
-	MDP_OUTP(MDP_BASE + 0xb0008, pipe->srcp0_addr);
-	MDP_OUTP(MDP_BASE + 0xb000c, pipe->srcp0_ystride);
-
-	/* dma_p dest */
+	if (pipe->blt_addr) {
+		uint32 off, bpp;
+#ifdef BLT_RGB565
+		bpp = 2; /* overlay ouput is RGB565 */
+#else
+		bpp = 3; /* overlay ouput is RGB888 */
+#endif
+		off = 0;
+		if (pipe->ov_cnt & 0x01)
+			off = pipe->src_height * pipe->src_width * bpp;
+		MDP_OUTP(MDP_BASE + 0xb0008, pipe->blt_addr + off);
+		/* RGB888, output of overlay blending */
+		MDP_OUTP(MDP_BASE + 0xb000c, pipe->src_width * bpp);
+	} else {
+		/* dma_e source */
+		MDP_OUTP(MDP_BASE + 0xb0008, pipe->srcp0_addr);
+		MDP_OUTP(MDP_BASE + 0xb000c, pipe->srcp0_ystride);
+	}
+	/* dma_e dest */
 	MDP_OUTP(MDP_BASE + 0xb0010, (pipe->dst_y << 16 | pipe->dst_x));
 
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
@@ -1114,7 +1128,7 @@
 		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 
 	/*
-	 * BLT only siupport at primary display
+	 * BLT support both primary and external external
 	 */
 	if (pipe->blt_addr) {
 		int off, bpp;
@@ -1127,7 +1141,8 @@
 		data <<= 16;
 		data |= pipe->src_width;
 		outpdw(overlay_base + 0x0008, data); /* ROI, height + width */
-		if (pipe->mixer_num == MDP4_MIXER0) {
+		if (pipe->mixer_num == MDP4_MIXER0 ||
+		    pipe->mixer_num == MDP4_MIXER1) {
 			off = 0;
 			if (pipe->ov_cnt & 0x01)
 				off = pipe->src_height * pipe->src_width * bpp;
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index f2065fd..f454d89 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -264,36 +264,6 @@
 	return ret;
 }
 
-static void mdp4_overlay_dtv_wait4vsync(struct msm_fb_data_type *mfd)
-{
-	unsigned long flag;
-
-	/* enable irq */
-	spin_lock_irqsave(&mdp_spin_lock, flag);
-	mdp_enable_irq(MDP_OVERLAY1_TERM);
-	INIT_COMPLETION(dtv_pipe->comp);
-	mfd->dma->waiting = TRUE;
-	outp32(MDP_INTR_CLEAR, INTR_EXTERNAL_VSYNC);
-	mdp_intr_mask |= INTR_EXTERNAL_VSYNC;
-	outp32(MDP_INTR_ENABLE, mdp_intr_mask);
-	spin_unlock_irqrestore(&mdp_spin_lock, flag);
-	wait_for_completion_killable(&dtv_pipe->comp);
-	mdp_disable_irq(MDP_OVERLAY1_TERM);
-}
-
-void mdp4_overlay_dtv_vsync_push(struct msm_fb_data_type *mfd,
-			struct mdp4_overlay_pipe *pipe)
-{
-	mdp4_overlay_reg_flush(pipe, 1);
-	if (pipe->flags & MDP_OV_PLAY_NOWAIT)
-		return;
-
-	mdp4_overlay_dtv_wait4vsync(mfd);
-
-	/* change mdp clk while mdp is idle` */
-	mdp4_set_perf_level();
-}
-
 static void mdp4_overlay_dtv_alloc_pipe(struct msm_fb_data_type *mfd,
 		int32 ptype)
 {
@@ -406,6 +376,54 @@
 	return result;
 }
 
+static void mdp4_dtv_blt_ov_update(struct mdp4_overlay_pipe *pipe)
+{
+	uint32 off, addr;
+	int bpp;
+	char *overlay_base;
+
+	if (pipe->blt_addr == 0)
+		return;
+#ifdef BLT_RGB565
+	bpp = 2; /* overlay ouput is RGB565 */
+#else
+	bpp = 3; /* overlay ouput is RGB888 */
+#endif
+	off = (pipe->ov_cnt & 0x01) ?
+		pipe->src_height * pipe->src_width * bpp : 0;
+
+	addr = pipe->blt_addr + off;
+	pr_debug("%s overlay addr 0x%x\n", __func__, addr);
+	/* overlay 1 */
+	overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
+	outpdw(overlay_base + 0x000c, addr);
+	outpdw(overlay_base + 0x001c, addr);
+}
+
+static inline void mdp4_dtv_blt_dmae_update(struct mdp4_overlay_pipe *pipe)
+{
+	uint32 off, addr;
+	int bpp;
+
+	if (pipe->blt_addr == 0)
+		return;
+
+#ifdef BLT_RGB565
+	bpp = 2; /* overlay ouput is RGB565 */
+#else
+	bpp = 3; /* overlay ouput is RGB888 */
+#endif
+	off =  (pipe->dmae_cnt & 0x01) ?
+		pipe->src_height * pipe->src_width * bpp : 0;
+	addr = pipe->blt_addr + off;
+	MDP_OUTP(MDP_BASE + 0xb0008, addr);
+}
+
+static inline void mdp4_overlay_dtv_ov_kick_start(void)
+{
+	outpdw(MDP_BASE + 0x0008, 0);
+}
+
 static void mdp4_overlay_dtv_ov_start(struct msm_fb_data_type *mfd)
 {
 	unsigned long flag;
@@ -414,6 +432,12 @@
 	if (mfd->ov_start)
 		return;
 
+	if (dtv_pipe->blt_addr) {
+		mdp4_dtv_blt_ov_update(dtv_pipe);
+		dtv_pipe->ov_cnt++;
+		mdp4_overlay_dtv_ov_kick_start();
+	}
+
 	spin_lock_irqsave(&mdp_spin_lock, flag);
 	mdp_enable_irq(MDP_OVERLAY1_TERM);
 	INIT_COMPLETION(dtv_pipe->comp);
@@ -444,6 +468,7 @@
 void mdp4_overlay_dtv_ov_done_push(struct msm_fb_data_type *mfd,
 			struct mdp4_overlay_pipe *pipe)
 {
+
 	mdp4_overlay_reg_flush(pipe, 1);
 	mdp4_overlay_dtv_ov_start(mfd);
 
@@ -463,6 +488,11 @@
 	mdp4_set_perf_level();
 }
 
+void mdp4_dma_e_done_dtv()
+{
+	complete(&dtv_pipe->comp);
+}
+
 void mdp4_external_vsync_dtv()
 {
 	complete_all(&dtv_pipe->comp);
@@ -473,6 +503,10 @@
  */
 void mdp4_overlay1_done_dtv()
 {
+	if (dtv_pipe->blt_addr) {
+		mdp4_dtv_blt_dmae_update(dtv_pipe);
+		dtv_pipe->dmae_cnt++;
+	}
 	complete_all(&dtv_pipe->comp);
 }
 
@@ -506,6 +540,70 @@
 }
 #endif
 
+static void mdp4_overlay_dtv_wait4dmae(struct msm_fb_data_type *mfd)
+{
+	unsigned long flag;
+
+	/* enable irq */
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	mdp_enable_irq(MDP_DMA_E_TERM);
+	INIT_COMPLETION(dtv_pipe->comp);
+	mfd->dma->waiting = TRUE;
+	outp32(MDP_INTR_CLEAR, INTR_DMA_E_DONE);
+	mdp_intr_mask |= INTR_DMA_E_DONE;
+	outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+	wait_for_completion_killable(&dtv_pipe->comp);
+	mdp_disable_irq(MDP_DMA_E_TERM);
+}
+
+static void mdp4_dtv_do_blt(struct msm_fb_data_type *mfd, int enable)
+{
+	unsigned long flag;
+	int change = 0;
+
+	if (!mfd->ov1_wb_buf->phys_addr) {
+		pr_debug("%s: no writeback buf assigned\n", __func__);
+		return;
+	}
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	if (enable && dtv_pipe->blt_addr == 0) {
+		dtv_pipe->blt_addr = mfd->ov1_wb_buf->phys_addr;
+		change++;
+		dtv_pipe->ov_cnt = 0;
+		dtv_pipe->dmae_cnt = 0;
+	} else if (enable == 0 && dtv_pipe->blt_addr) {
+		dtv_pipe->blt_addr = 0;
+		change++;
+	}
+	pr_debug("%s: blt_addr=%x\n", __func__, (int)dtv_pipe->blt_addr);
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+
+	if (!change)
+		return;
+
+	mdp4_overlay_dtv_wait4dmae(mfd);
+
+	MDP_OUTP(MDP_BASE + DTV_BASE, 0);	/* stop dtv */
+	msleep(20);
+	mdp4_overlayproc_cfg(dtv_pipe);
+	mdp4_overlay_dmae_xy(dtv_pipe);
+	MDP_OUTP(MDP_BASE + DTV_BASE, 1);	/* start dtv */
+}
+
+void mdp4_dtv_overlay_blt_start(struct msm_fb_data_type *mfd)
+{
+	mdp4_allocate_writeback_buf(mfd, MDP4_MIXER1);
+	mdp4_dtv_do_blt(mfd, 1);
+}
+
+void mdp4_dtv_overlay_blt_stop(struct msm_fb_data_type *mfd)
+{
+	mdp4_free_writeback_buf(mfd, MDP4_MIXER1);
+	mdp4_dtv_do_blt(mfd, 0);
+}
+
 void mdp4_dtv_overlay(struct msm_fb_data_type *mfd)
 {
 	struct mdp4_overlay_pipe *pipe;
diff --git a/drivers/video/msm/mdp4_util.c b/drivers/video/msm/mdp4_util.c
index bd8ec55..ba6c746 100644
--- a/drivers/video/msm/mdp4_util.c
+++ b/drivers/video/msm/mdp4_util.c
@@ -554,7 +554,7 @@
 		mdp_intr_mask &= ~INTR_DMA_E_DONE;
 		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
 		dma->busy = FALSE;
-
+		mdp4_dma_e_done_dtv();
 		if (dma->waiting) {
 			dma->waiting = FALSE;
 			complete(&dma->comp);
diff --git a/include/linux/mfd/pm8xxx/misc.h b/include/linux/mfd/pm8xxx/misc.h
index 32189b2..f9fc498 100644
--- a/include/linux/mfd/pm8xxx/misc.h
+++ b/include/linux/mfd/pm8xxx/misc.h
@@ -160,6 +160,18 @@
  */
 int pm8xxx_stay_on(void);
 
+/**
+ * pm8xxx_preload_dVdd - preload the dVdd regulator during off state.
+ *
+ * This can help to reduce fluctuations in the dVdd voltage during startup
+ * at the cost of additional off state current draw.
+ *
+ * This API should only be called if dVdd startup issues are suspected.
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_preload_dVdd(void);
+
 #else
 
 static inline int pm8xxx_reset_pwr_off(int reset)
@@ -196,6 +208,10 @@
 {
 	return -ENODEV;
 }
+static inline int pm8xxx_preload_dVdd(void)
+{
+	return -ENODEV;
+}
 #endif
 
 #endif
diff --git a/include/linux/msm_audio_acdb.h b/include/linux/msm_audio_acdb.h
index 3d756c2..e7f06b5 100644
--- a/include/linux/msm_audio_acdb.h
+++ b/include/linux/msm_audio_acdb.h
@@ -35,6 +35,13 @@
 			(AUDIO_MAX_COMMON_IOCTL_NUM+14), unsigned)
 #define AUDIO_SET_ASM_TOPOLOGY	_IOW(AUDIO_IOCTL_MAGIC, \
 			(AUDIO_MAX_COMMON_IOCTL_NUM+15), unsigned)
+#define AUDIO_SET_AFE_TX_CAL		_IOW(AUDIO_IOCTL_MAGIC, \
+			(AUDIO_MAX_COMMON_IOCTL_NUM+16), unsigned)
+#define AUDIO_SET_AFE_RX_CAL		_IOW(AUDIO_IOCTL_MAGIC, \
+			(AUDIO_MAX_COMMON_IOCTL_NUM+17), unsigned)
+
+
+#define	AUDIO_MAX_ACDB_IOCTL	(AUDIO_MAX_COMMON_IOCTL_NUM+30)
 
 /* ACDB structures */
 struct cal_block {
@@ -49,25 +56,26 @@
 
 /* For Real-Time Audio Calibration */
 #define AUDIO_GET_RTAC_ADM_INFO		_IOR(AUDIO_IOCTL_MAGIC, \
-			(AUDIO_MAX_COMMON_IOCTL_NUM+16), unsigned)
+			(AUDIO_MAX_ACDB_IOCTL+1), unsigned)
 #define AUDIO_GET_RTAC_VOICE_INFO	_IOR(AUDIO_IOCTL_MAGIC, \
-			(AUDIO_MAX_COMMON_IOCTL_NUM+17), unsigned)
+			(AUDIO_MAX_ACDB_IOCTL+2), unsigned)
 #define AUDIO_GET_RTAC_ADM_CAL	_IOWR(AUDIO_IOCTL_MAGIC, \
-			(AUDIO_MAX_COMMON_IOCTL_NUM+18), unsigned)
+			(AUDIO_MAX_ACDB_IOCTL+3), unsigned)
 #define AUDIO_SET_RTAC_ADM_CAL	_IOWR(AUDIO_IOCTL_MAGIC, \
-			(AUDIO_MAX_COMMON_IOCTL_NUM+19), unsigned)
+			(AUDIO_MAX_ACDB_IOCTL+4), unsigned)
 #define AUDIO_GET_RTAC_ASM_CAL	_IOWR(AUDIO_IOCTL_MAGIC, \
-			(AUDIO_MAX_COMMON_IOCTL_NUM+20), unsigned)
+			(AUDIO_MAX_ACDB_IOCTL+5), unsigned)
 #define AUDIO_SET_RTAC_ASM_CAL	_IOWR(AUDIO_IOCTL_MAGIC, \
-			(AUDIO_MAX_COMMON_IOCTL_NUM+21), unsigned)
+			(AUDIO_MAX_ACDB_IOCTL+6), unsigned)
 #define AUDIO_GET_RTAC_CVS_CAL	_IOWR(AUDIO_IOCTL_MAGIC, \
-			(AUDIO_MAX_COMMON_IOCTL_NUM+22), unsigned)
+			(AUDIO_MAX_ACDB_IOCTL+7), unsigned)
 #define AUDIO_SET_RTAC_CVS_CAL	_IOWR(AUDIO_IOCTL_MAGIC, \
-			(AUDIO_MAX_COMMON_IOCTL_NUM+23), unsigned)
+			(AUDIO_MAX_ACDB_IOCTL+8), unsigned)
 #define AUDIO_GET_RTAC_CVP_CAL	_IOWR(AUDIO_IOCTL_MAGIC, \
-			(AUDIO_MAX_COMMON_IOCTL_NUM+24), unsigned)
+			(AUDIO_MAX_ACDB_IOCTL+9), unsigned)
 #define AUDIO_SET_RTAC_CVP_CAL	_IOWR(AUDIO_IOCTL_MAGIC, \
-			(AUDIO_MAX_COMMON_IOCTL_NUM+25), unsigned)
+			(AUDIO_MAX_ACDB_IOCTL+10), unsigned)
 
+#define	AUDIO_MAX_RTAC_IOCTL	(AUDIO_MAX_ACDB_IOCTL+20)
 
 #endif /* __MSM_AUDIO_ACDB_H */
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 9373064..e03944d 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -160,6 +160,9 @@
  * @disable_reset_on_disconnect: perform USB PHY and LINK reset
  *              on USB cable disconnection.
  * @swfi_latency: miminum latency to allow swfi.
+ * @enable_dcd: Enable Data Contact Detection circuit. if not set
+ *              wait for 600msec before proceeding to primary
+ *              detection.
  */
 struct msm_otg_platform_data {
 	int *phy_init_seq;
@@ -174,6 +177,7 @@
 	bool mhl_enable;
 	bool disable_reset_on_disconnect;
 	u32 swfi_latency;
+	bool enable_dcd;
 };
 
 /**
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 857f654..8e66a25 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1047,6 +1047,8 @@
 /* LE SMP Management interface */
 int le_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, void *cp);
 int mgmt_remote_class(u16 index, bdaddr_t *bdaddr, u8 dev_class[3]);
+int mgmt_remote_version(u16 index, bdaddr_t *bdaddr, u8 ver, u16 mnf,
+							u16 sub_ver);
 
 /* HCI info for socket */
 #define hci_pi(sk) ((struct hci_pinfo *) sk)
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index de61c32..9e79fb3 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -347,3 +347,11 @@
 	bdaddr_t bdaddr;
 	__u8 dev_class[3];
 } __packed;
+
+#define MGMT_EV_REMOTE_VERSION		0x0018
+struct mgmt_ev_remote_version {
+	bdaddr_t bdaddr;
+	__u8	lmp_ver;
+	__u16	manufacturer;
+	__u16	lmp_subver;
+} __packed;
diff --git a/include/sound/apr_audio.h b/include/sound/apr_audio.h
index 798ed89..30f1a7c 100644
--- a/include/sound/apr_audio.h
+++ b/include/sound/apr_audio.h
@@ -1,7 +1,6 @@
-
 /*
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -353,6 +352,12 @@
 	struct afe_param_payload payload;
 } __attribute__ ((packed));
 
+struct afe_port_cmd_set_param_no_payload {
+	struct apr_hdr hdr;
+	u16 port_id;
+	u16 payload_size;
+	u32 payload_address;
+} __packed;
 
 #define AFE_EVENT_GET_ACTIVE_PORTS 0x00010100
 struct afe_get_active_ports_rsp {
diff --git a/include/sound/q6afe.h b/include/sound/q6afe.h
index 6206838..2d0f53f 100644
--- a/include/sound/q6afe.h
+++ b/include/sound/q6afe.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -76,7 +76,9 @@
 int afe_start_pseudo_port(u16 port_id);
 int afe_stop_pseudo_port(u16 port_id);
 int afe_cmd_memory_map(u32 dma_addr_p, u32 dma_buf_sz);
+int afe_cmd_memory_map_nowait(u32 dma_addr_p, u32 dma_buf_sz);
 int afe_cmd_memory_unmap(u32 dma_addr_p);
+int afe_cmd_memory_unmap_nowait(u32 dma_addr_p);
 
 int afe_register_get_events(u16 port_id,
 		void (*cb) (uint32_t opcode,
diff --git a/mm/ashmem.c b/mm/ashmem.c
index bc977ee..e4aab56 100644
--- a/mm/ashmem.c
+++ b/mm/ashmem.c
@@ -673,10 +673,28 @@
 	void (*cache_func)(unsigned long vstart, unsigned long length,
 				unsigned long pstart))
 {
+	int ret = 0;
+	struct vm_area_struct *vma;
 #ifdef CONFIG_OUTER_CACHE
 	unsigned long vaddr;
 #endif
-	mutex_lock(&ashmem_mutex);
+	if (!asma->vm_start)
+		return -EINVAL;
+
+	down_read(&current->mm->mmap_sem);
+	vma = find_vma(current->mm, asma->vm_start);
+	if (!vma) {
+		ret = -EINVAL;
+		goto done;
+	}
+	if (vma->vm_file != asma->file) {
+		ret = -EINVAL;
+		goto done;
+	}
+	if ((asma->vm_start + asma->size) > (vma->vm_start + vma->vm_end)) {
+		ret = -EINVAL;
+		goto done;
+	}
 #ifndef CONFIG_OUTER_CACHE
 	cache_func(asma->vm_start, asma->size, 0);
 #else
@@ -689,8 +707,11 @@
 		cache_func(vaddr, PAGE_SIZE, physaddr);
 	}
 #endif
-	mutex_unlock(&ashmem_mutex);
-	return 0;
+done:
+	up_read(&current->mm->mmap_sem);
+	if (ret)
+		asma->vm_start = 0;
+	return ret;
 }
 
 static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index f98a90e..675b34f 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1606,12 +1606,12 @@
 		if (test_bit(HCI_ENCRYPT, &hdev->flags))
 			conn->link_mode |= HCI_LM_ENCRYPT;
 
-		/* Get remote features */
+		/* Get remote version */
 		if (conn->type == ACL_LINK) {
-			struct hci_cp_read_remote_features cp;
+			struct hci_cp_read_remote_version cp;
 			cp.handle = ev->handle;
-			hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
-							sizeof(cp), &cp);
+			hci_send_cmd(hdev, HCI_OP_READ_REMOTE_VERSION,
+				sizeof(cp), &cp);
 		}
 
 		/* Set packet type for incoming connection */
@@ -1959,7 +1959,24 @@
 
 static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	BT_DBG("%s", hdev->name);
+	struct hci_ev_remote_version *ev = (void *) skb->data;
+	struct hci_cp_read_remote_features cp;
+	struct hci_conn *conn;
+	BT_DBG("%s status %d", hdev->name, ev->status);
+
+	hci_dev_lock(hdev);
+	cp.handle = ev->handle;
+	hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
+				sizeof(cp), &cp);
+
+	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
+	if (!conn)
+		goto unlock;
+	if (!ev->status)
+		mgmt_remote_version(hdev->id, &conn->dst, ev->lmp_ver,
+				ev->manufacturer, ev->lmp_subver);
+unlock:
+	hci_dev_unlock(hdev);
 }
 
 static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 67a2900..74b1d2d 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2893,3 +2893,18 @@
 
 	return mgmt_event(MGMT_EV_REMOTE_CLASS, index, &ev, sizeof(ev), NULL);
 }
+
+int mgmt_remote_version(u16 index, bdaddr_t *bdaddr, u8 ver, u16 mnf,
+							u16 sub_ver)
+{
+	struct mgmt_ev_remote_version ev;
+
+	memset(&ev, 0, sizeof(ev));
+
+	bacpy(&ev.bdaddr, bdaddr);
+	ev.lmp_ver = ver;
+	ev.manufacturer = mnf;
+	ev.lmp_subver = sub_ver;
+
+	return mgmt_event(MGMT_EV_REMOTE_VERSION, index, &ev, sizeof(ev), NULL);
+}
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index cec01f1..8de9dec 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -2640,6 +2640,7 @@
 {
 	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
 
+	pr_debug("%s: enable = %d\n", __func__, enable);
 	if (enable) {
 		snd_soc_update_bits(codec, TABLA_A_CONFIG_MODE_FREQ, 0x10, 0);
 		snd_soc_write(codec, TABLA_A_BIAS_CONFIG_MODE_BG_CTL, 0x17);
@@ -2656,6 +2657,7 @@
 		snd_soc_update_bits(codec, TABLA_A_BIAS_CONFIG_MODE_BG_CTL, 0x1,
 			0);
 		snd_soc_update_bits(codec, TABLA_A_CONFIG_MODE_FREQ, 0x80, 0);
+		snd_soc_update_bits(codec, TABLA_A_CLK_BUFF_EN1, 0x08, 0x00);
 	}
 	tabla->config_mode_active = enable ? true : false;
 
@@ -2667,7 +2669,7 @@
 {
 	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
 
-	pr_debug("%s\n", __func__);
+	pr_debug("%s: config_mode = %d\n", __func__, config_mode);
 
 	if (config_mode) {
 		tabla_codec_enable_config_mode(codec, 1);
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 16d149e..fea11d9 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -236,6 +236,19 @@
 		.ops = &msm_fe_dai_ops,
 		.name = "AFE-PROXY",
 	},
+	{
+		.playback = {
+			.stream_name = "HDMI_Rx Hostless Playback",
+			.rates = SNDRV_PCM_RATE_8000_48000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.channels_min = 1,
+			.channels_max = 2,
+			.rate_min = 8000,
+			.rate_max = 48000,
+		},
+		.ops = &msm_fe_dai_ops,
+		.name = "HDMI_HOSTLESS"
+	},
 };
 
 static __devinit int msm_fe_dai_dev_probe(struct platform_device *pdev)
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 2815daa..1331ebf 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -1128,6 +1128,8 @@
 		0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("INTFM_UL_HL", "INT_FM_HOSTLESS Capture",
 		0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_IN("HDMI_DL_HL", "HDMI_HOSTLESS Playback", 0, 0, 0, 0),
+
 	/* Backend AIF */
 	/* Stream name equals to backend dai link stream name
 	 */
@@ -1312,6 +1314,7 @@
 	{"HDMI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
 	{"HDMI_RX_Voice Mixer", "Voip", "VOIP_DL"},
 	{"HDMI", NULL, "HDMI_RX_Voice Mixer"},
+	{"HDMI", NULL, "HDMI_DL_HL"},
 
 	{"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"},
 	{"Voice_Tx Mixer", "SLIM_0_TX_Voice", "SLIMBUS_0_TX"},
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index 60fa5f3..0dc3b57 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -724,6 +724,14 @@
 	},
 };
 
+static struct snd_soc_dsp_link hdmi_rx_hl = {
+	.playback = true,
+	.trigger = {
+		SND_SOC_DSP_TRIGGER_POST,
+		SND_SOC_DSP_TRIGGER_POST
+	},
+};
+
 static int msm8960_slim_0_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
 			struct snd_pcm_hw_params *params)
 {
@@ -1010,6 +1018,18 @@
 		.dsp_link = &lpa_fe_media,
 		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA4,
 	},
+	/* HDMI Hostless */
+	{
+		.name = "HDMI_RX_HOSTLESS",
+		.stream_name = "HDMI_RX_HOSTLESS",
+		.cpu_dai_name = "HDMI_HOSTLESS",
+		.platform_name = "msm-pcm-hostless",
+		.dynamic = 1,
+		.dsp_link = &hdmi_rx_hl,
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.no_codec = 1,
+		.ignore_suspend = 1,
+	},
 	/* Backend DAI Links */
 	{
 		.name = LPASS_BE_SLIMBUS_0_RX,
diff --git a/sound/soc/msm/qdsp6/q6adm.c b/sound/soc/msm/qdsp6/q6adm.c
index 18dfc01..d8d9c64 100644
--- a/sound/soc/msm/qdsp6/q6adm.c
+++ b/sound/soc/msm/qdsp6/q6adm.c
@@ -457,7 +457,7 @@
 	int     i = 0;
 	int     cmd_size = 0;
 
-	pr_info("%s\n", __func__);
+	pr_debug("%s\n", __func__);
 	if (this_adm.apr == NULL) {
 		this_adm.apr = apr_register("ADSP", "ADM", adm_callback,
 						0xFFFFFFFF, &this_adm);
@@ -532,7 +532,7 @@
 	int     i = 0;
 	int     cmd_size = 0;
 
-	pr_info("%s\n", __func__);
+	pr_debug("%s\n", __func__);
 
 	if (this_adm.apr == NULL) {
 		pr_err("%s APR handle NULL\n", __func__);
diff --git a/sound/soc/msm/qdsp6/q6afe.c b/sound/soc/msm/qdsp6/q6afe.c
index 74a66945..a214529 100644
--- a/sound/soc/msm/qdsp6/q6afe.c
+++ b/sound/soc/msm/qdsp6/q6afe.c
@@ -1,4 +1,4 @@
-/*  Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -17,6 +17,7 @@
 #include <linux/wait.h>
 #include <linux/jiffies.h>
 #include <linux/sched.h>
+#include <mach/qdsp6v2/audio_acdb.h>
 #include <sound/apr_audio.h>
 #include <sound/q6afe.h>
 
@@ -36,6 +37,8 @@
 
 static struct afe_ctl this_afe;
 
+static uint32_t afe_cal_addr[MAX_AUDPROC_TYPES];
+
 #define TIMEOUT_MS 1000
 #define Q6AFE_MAX_VOLUME 0x3FFF
 
@@ -314,6 +317,63 @@
 	return ret;
 }
 
+static void afe_send_cal_block(int32_t path, u16 port_id)
+{
+	int						result = 0;
+	struct acdb_cal_block				cal_block;
+	struct afe_port_cmd_set_param_no_payload	afe_cal;
+	pr_debug("%s: path %d\n", __func__, path);
+
+	get_afe_cal(path, &cal_block);
+	if (cal_block.cal_size <= 0) {
+		pr_debug("%s: No AFE cal to send!\n", __func__);
+		goto done;
+	}
+
+	if (afe_cal_addr[path] != cal_block.cal_paddr) {
+		if (afe_cal_addr[path] != 0)
+			afe_cmd_memory_unmap_nowait(afe_cal_addr[path]);
+		afe_cmd_memory_map_nowait(cal_block.cal_paddr,
+						cal_block.cal_size);
+		afe_cal_addr[path] = cal_block.cal_paddr;
+	}
+
+	afe_cal.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	afe_cal.hdr.pkt_size = sizeof(afe_cal);
+	afe_cal.hdr.src_port = 0;
+	afe_cal.hdr.dest_port = 0;
+	afe_cal.hdr.token = 0;
+	afe_cal.hdr.opcode = AFE_PORT_CMD_SET_PARAM;
+	afe_cal.port_id = port_id;
+	afe_cal.payload_size = cal_block.cal_size;
+	afe_cal.payload_address = cal_block.cal_paddr;
+
+	pr_debug("%s: AFE cal sent for device port = %d, path = %d, "
+		"cal size = %d, cal addr = 0x%x\n", __func__,
+		port_id, path, cal_block.cal_size, cal_block.cal_paddr);
+
+	result = apr_send_pkt(this_afe.apr, (uint32_t *) &afe_cal);
+	if (result < 0) {
+		pr_err("%s: AFE cal for port %d failed\n",
+			__func__, port_id);
+	}
+
+	pr_debug("%s: AFE cal sent for path %d device!\n", __func__, path);
+done:
+	return;
+}
+
+void afe_send_cal(u16 port_id)
+{
+	pr_debug("%s\n", __func__);
+
+	if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX)
+		afe_send_cal_block(TX_CAL, port_id);
+	else if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX)
+		afe_send_cal_block(RX_CAL, port_id);
+}
+
 int afe_port_start_nowait(u16 port_id, union afe_port_config *afe_config,
 	u32 rate) /* This function is no blocking */
 {
@@ -365,6 +425,10 @@
 		ret = -EINVAL;
 		goto fail_cmd;
 	}
+
+	/* send AFE cal */
+	afe_send_cal(port_id);
+
 	start.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	start.hdr.pkt_size = sizeof(start);
@@ -875,6 +939,45 @@
 	return 0;
 }
 
+int afe_cmd_memory_map_nowait(u32 dma_addr_p, u32 dma_buf_sz)
+{
+	int ret = 0;
+	struct afe_cmd_memory_map mregion;
+
+	pr_debug("%s:\n", __func__);
+
+	if (this_afe.apr == NULL) {
+		this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
+					0xFFFFFFFF, &this_afe);
+		pr_debug("%s: Register AFE\n", __func__);
+		if (this_afe.apr == NULL) {
+			pr_err("%s: Unable to register AFE\n", __func__);
+			ret = -ENODEV;
+			return ret;
+		}
+	}
+
+	mregion.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	mregion.hdr.pkt_size = sizeof(mregion);
+	mregion.hdr.src_port = 0;
+	mregion.hdr.dest_port = 0;
+	mregion.hdr.token = 0;
+	mregion.hdr.opcode = AFE_SERVICE_CMD_MEMORY_MAP;
+	mregion.phy_addr = dma_addr_p;
+	mregion.mem_sz = dma_buf_sz;
+	mregion.mem_id = 0;
+	mregion.rsvd = 0;
+
+	ret = apr_send_pkt(this_afe.apr, (uint32_t *) &mregion);
+	if (ret < 0) {
+		pr_err("%s: AFE memory map cmd failed %d\n",
+			__func__, ret);
+		ret = -EINVAL;
+	}
+	return 0;
+}
+
 int afe_cmd_memory_unmap(u32 dma_addr_p)
 {
 	int ret = 0;
@@ -905,7 +1008,7 @@
 	atomic_set(&this_afe.state, 1);
 	ret = apr_send_pkt(this_afe.apr, (uint32_t *) &mregion);
 	if (ret < 0) {
-		pr_err("%s: AFE memory map cmd failed %d\n",
+		pr_err("%s: AFE memory unmap cmd failed %d\n",
 		       __func__, ret);
 		ret = -EINVAL;
 		return ret;
@@ -919,7 +1022,42 @@
 		ret = -EINVAL;
 		return ret;
 	}
+	return 0;
+}
 
+int afe_cmd_memory_unmap_nowait(u32 dma_addr_p)
+{
+	int ret = 0;
+	struct afe_cmd_memory_unmap mregion;
+
+	pr_debug("%s:\n", __func__);
+
+	if (this_afe.apr == NULL) {
+		this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
+					0xFFFFFFFF, &this_afe);
+		pr_debug("%s: Register AFE\n", __func__);
+		if (this_afe.apr == NULL) {
+			pr_err("%s: Unable to register AFE\n", __func__);
+			ret = -ENODEV;
+			return ret;
+		}
+	}
+
+	mregion.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	mregion.hdr.pkt_size = sizeof(mregion);
+	mregion.hdr.src_port = 0;
+	mregion.hdr.dest_port = 0;
+	mregion.hdr.token = 0;
+	mregion.hdr.opcode = AFE_SERVICE_CMD_MEMORY_UNMAP;
+	mregion.phy_addr = dma_addr_p;
+
+	ret = apr_send_pkt(this_afe.apr, (uint32_t *) &mregion);
+	if (ret < 0) {
+		pr_err("%s: AFE memory unmap cmd failed %d\n",
+			__func__, ret);
+		ret = -EINVAL;
+	}
 	return 0;
 }
 
@@ -1389,12 +1527,17 @@
 
 static void __exit afe_exit(void)
 {
+	int i;
 #ifdef CONFIG_DEBUG_FS
 	if (debugfs_afelb)
 		debugfs_remove(debugfs_afelb);
 	if (debugfs_afelb_gain)
 		debugfs_remove(debugfs_afelb_gain);
 #endif
+	for (i = 0; i < MAX_AUDPROC_TYPES; i++) {
+		if (afe_cal_addr[i] != 0)
+			afe_cmd_memory_unmap_nowait(afe_cal_addr[i]);
+	}
 }
 
 device_initcall(afe_init);