Merge "msm: smd: fix legacy DS port registration" into msm-3.0
diff --git a/Documentation/devicetree/bindings/spi/spi_qsd.txt b/Documentation/devicetree/bindings/spi/spi_qsd.txt
new file mode 100644
index 0000000..5839f63
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/spi_qsd.txt
@@ -0,0 +1,16 @@
+Qualcomm Serial Peripheral Interface (SPI)
+
+Required properties:
+- compatible : should be "qcom,spi-qup-v2".
+- reg : offset and length of the QUP register map.
+- interrupts : should contain the QUP core interrupt.
+- spi-max-frequency : specifies maximum SPI clock frequency, Units - Hz.
+
+Example:
+	spi@f9924000 {
+		compatible = "qcom,spi-qup-v2";
+		reg = <0xf9924000 0x1000>;
+		interrupts = <96>;
+		spi-max-frequency = <24000000>;
+	};
+
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index d79aead..b1db115 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -266,3 +266,6 @@
   pcim_iounmap()
   pcim_iomap_table()	: array of mapped addresses indexed by BAR
   pcim_iomap_regions()	: do request_region() and iomap() on multiple BARs
+
+REGULATOR
+  devm_regulator_get()
diff --git a/arch/arm/boot/dts/msmcopper.dts b/arch/arm/boot/dts/msmcopper.dts
index 6561c71..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,9 +65,15 @@
 		compatible = "qcom,msm_sps";
 		reg = <0xF9984000 0x15000>,
 		      <0xF9999000 0xB000>;
-		interrupts = <94>;
+		interrupts = <0 94 0>;
 
 		qcom,bam-dma-res-pipes = <6>;
 	};
 
+	spi@f9924000 {
+		compatible = "qcom,spi-qup-v2";
+		reg = <0xf9924000 0x1000>;
+		interrupts = <96>;
+		spi-max-frequency = <24000000>;
+	};
 };
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/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index ca974b2..00ff580 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -45,6 +45,7 @@
 CONFIG_MSM7X27A_AUDIO=y
 CONFIG_MSM_DMA_TEST=y
 # CONFIG_MSM_JTAG_V7 is not set
+CONFIG_MSM_SLEEP_STATS_DEVICE=y
 CONFIG_BT_MSM_PINTEST=y
 CONFIG_MSM_RPC_VIBRATOR=y
 CONFIG_PM8XXX_RPC_VIBRATOR=y
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index cfa06a8..3cf01a1 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -45,6 +45,7 @@
 CONFIG_MSM7X27A_AUDIO=y
 CONFIG_MSM_DMA_TEST=y
 # CONFIG_MSM_JTAG_V7 is not set
+CONFIG_MSM_SLEEP_STATS_DEVICE=y
 CONFIG_BT_MSM_PINTEST=y
 CONFIG_MSM_RPC_VIBRATOR=y
 CONFIG_PM8XXX_RPC_VIBRATOR=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 00202ee..0780d20 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -321,6 +321,7 @@
 CONFIG_FB_MSM_OVERLAY0_WRITEBACK=y
 CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
 CONFIG_FB_MSM_HDMI_MSM_PANEL=y
+CONFIG_FB_MSM_WRITEBACK_MSM_PANEL=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_SOUND=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index bac1123..5f9bd89 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
@@ -324,6 +327,7 @@
 CONFIG_FB_MSM_OVERLAY0_WRITEBACK=y
 CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
 CONFIG_FB_MSM_HDMI_MSM_PANEL=y
+CONFIG_FB_MSM_WRITEBACK_MSM_PANEL=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_SOUND=y
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/kernel/smp.c b/arch/arm/kernel/smp.c
index 0faa7ea..4328ac3 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -383,8 +383,7 @@
 	 */
 	if (max_cpus > ncores)
 		max_cpus = ncores;
-
-	if (max_cpus > 1) {
+	if (ncores > 1 && max_cpus) {
 		/*
 		 * Enable the local timer or broadcast device for the
 		 * boot CPU, but only if we have more than one CPU.
@@ -392,6 +391,14 @@
 		percpu_timer_setup();
 
 		/*
+		 * Initialise the present map, which describes the set of CPUs
+		 * actually populated at the present time. A platform should
+		 * re-initialize the map in platform_smp_prepare_cpus() if
+		 * present != possible (e.g. physical hotplug).
+		 */
+		init_cpu_present(&cpu_possible_map);
+
+		/*
 		 * Initialise the SCU if there are more than one CPU
 		 * and let them know where to start.
 		 */
diff --git a/arch/arm/mach-exynos4/platsmp.c b/arch/arm/mach-exynos4/platsmp.c
index c5e65a0..b68d5bd 100644
--- a/arch/arm/mach-exynos4/platsmp.c
+++ b/arch/arm/mach-exynos4/platsmp.c
@@ -154,14 +154,6 @@
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 {
-	int i;
-
-	/*
-	 * Initialise the present map, which describes the set of CPUs
-	 * actually populated at the present time.
-	 */
-	for (i = 0; i < max_cpus; i++)
-		set_cpu_present(i, true);
 
 	scu_enable(scu_base_addr());
 
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index ee9b2de..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
@@ -1845,6 +1862,9 @@
 	depends on CPU_IDLE
 	default n
 
+config MSM_SLEEP_STATS_DEVICE
+	bool "Enable exporting of MSM sleep device stats to userspace"
+
 config MSM_STANDALONE_POWER_COLLAPSE
        bool "Enable standalone power collapse"
        default n
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index bae4678..8b866d8 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -301,7 +301,8 @@
 endif
 endif
 
-obj-$(CONFIG_MSM_SLEEP_STATS) += msm_rq_stats.o idle_stats.o idle_stats_device.o
+obj-$(CONFIG_MSM_SLEEP_STATS) += msm_rq_stats.o idle_stats.o
+obj-$(CONFIG_MSM_SLEEP_STATS_DEVICE) += idle_stats_device.o
 obj-$(CONFIG_MSM_SHOW_RESUME_IRQ) += msm_show_resume_irq.o
 obj-$(CONFIG_BT_MSM_PINTEST)  += btpintest.o
 obj-$(CONFIG_MSM_FAKE_BATTERY) += fish_battery.o
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index bfe4f81..d001282 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -63,6 +63,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 +97,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 {
@@ -551,16 +557,16 @@
 	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);
 		list_del(&pkt->list_node);
 		DBG_INC_TX_SPS_FAILURE_CNT();
 		spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
 		kfree(pkt);
+	} else {
+		spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
 	}
 
 	ul_packet_written = 1;
@@ -718,12 +724,10 @@
 	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);
 		list_del(&pkt->list_node);
 		DBG_INC_TX_SPS_FAILURE_CNT();
 		spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
@@ -731,6 +735,7 @@
 		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);
@@ -1124,10 +1129,12 @@
 	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",
 			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
 			);
 
 	return i;
@@ -1241,9 +1248,25 @@
 				struct dentry *dent,
 				int (*fill)(char *buf, int max))
 {
-	debugfs_create_file(name, mode, dent, fill, &debug_ops);
+	struct dentry *file;
+
+	file = debugfs_create_file(name, mode, dent, fill, &debug_ops);
+	if (IS_ERR(file))
+		pr_err("%s: debugfs create failed %d\n", __func__,
+				(int)PTR_ERR(file));
 }
 
+static void debug_create_multiple(const char *name, mode_t mode,
+				struct dentry *dent,
+				int (*fill)(char *buf, int max, loff_t *ppos))
+{
+	struct dentry *file;
+
+	file = debugfs_create_file(name, mode, dent, fill, &debug_ops_multiple);
+	if (IS_ERR(file))
+		pr_err("%s: debugfs create failed %d\n", __func__,
+				(int)PTR_ERR(file));
+}
 #endif
 
 static void notify_all(int event, unsigned long data)
@@ -1336,6 +1359,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;
@@ -1370,7 +1408,7 @@
 		else
 			called_before = 1;
 		if (wait_for_dfab) {
-			ret = wait_for_completion_interruptible_timeout(
+			ret = wait_for_completion_timeout(
 					&dfab_unvote_completion, HZ);
 			BUG_ON(ret == 0);
 		}
@@ -1389,7 +1427,7 @@
 	 */
 	if (wait_for_ack) {
 		bam_dmux_log("%s waiting for previous ack\n", __func__);
-		ret = wait_for_completion_interruptible_timeout(
+		ret = wait_for_completion_timeout(
 					&ul_wakeup_ack_completion, HZ);
 		BUG_ON(ret == 0);
 		wait_for_ack = 0;
@@ -1397,12 +1435,10 @@
 	INIT_COMPLETION(ul_wakeup_ack_completion);
 	power_vote(1);
 	bam_dmux_log("%s waiting for wakeup ack\n", __func__);
-	ret = wait_for_completion_interruptible_timeout(
-						&ul_wakeup_ack_completion, HZ);
+	ret = wait_for_completion_timeout(&ul_wakeup_ack_completion, HZ);
 	BUG_ON(ret == 0);
 	bam_dmux_log("%s waiting completion\n", __func__);
-	ret = wait_for_completion_interruptible_timeout(
-						&bam_connection_completion, HZ);
+	ret = wait_for_completion_timeout(&bam_connection_completion, HZ);
 	BUG_ON(ret == 0);
 
 	bam_is_connected = 1;
@@ -1497,7 +1533,7 @@
 		mutex_unlock(&dfab_status_lock);
 		return;
 	}
-	rc = clk_enable(dfab_clk);
+	rc = clk_prepare_enable(dfab_clk);
 	if (rc)
 		DMUX_LOG_KERR("bam_dmux vote for dfab failed rc = %d\n", rc);
 	dfab_is_on = 1;
@@ -1514,7 +1550,7 @@
 		mutex_unlock(&dfab_status_lock);
 		return;
 	}
-	clk_disable(dfab_clk);
+	clk_disable_unprepare(dfab_clk);
 	dfab_is_on = 0;
 	mutex_unlock(&dfab_status_lock);
 }
@@ -1625,6 +1661,7 @@
 	int ret;
 	void *a2_virt_addr;
 	int i;
+	int skip_iounmap = 0;
 
 	vote_dfab();
 	/* init BAM */
@@ -1772,7 +1809,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;
@@ -1811,6 +1856,7 @@
 	return 0;
 
 register_bam_failed:
+	iounmap(a2_virt_addr);
 ioremap_failed:
 	return ret;
 }
@@ -1986,8 +2032,7 @@
 		debug_create("tbl", 0444, dent, debug_tbl);
 		debug_create("ul_pkt_cnt", 0444, dent, debug_ul_pkt_cnt);
 		debug_create("stats", 0444, dent, debug_stats);
-		debugfs_create_file("log", 0444, dent, debug_log,
-				&debug_ops_multiple);
+		debug_create_multiple("log", 0444, dent, debug_log);
 	}
 #endif
 	ret = kfifo_alloc(&bam_dmux_state_log, PAGE_SIZE, GFP_KERNEL);
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 9f66e5d..a582260 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -22,6 +22,7 @@
 #include <linux/spi/spi.h>
 #include <linux/dma-mapping.h>
 #include <linux/platform_data/qcom_crypto_device.h>
+#include <linux/ion.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/hardware/gic.h>
@@ -29,6 +30,7 @@
 
 #include <mach/board.h>
 #include <mach/msm_iomap.h>
+#include <mach/ion.h>
 #include <linux/usb/msm_hsusb.h>
 #include <linux/usb/android.h>
 #include <mach/socinfo.h>
@@ -37,36 +39,48 @@
 #include "devices.h"
 #include <mach/gpio.h>
 #include <mach/gpiomux.h>
+#ifdef CONFIG_ANDROID_PMEM
 #include <linux/android_pmem.h>
+#endif
 #include <mach/msm_memtypes.h>
 #include <linux/bootmem.h>
 #include <asm/setup.h>
 #include <mach/dma.h>
+#include <mach/msm_bus_board.h>
 
 #include "msm_watchdog.h"
 #include "board-8064.h"
 
-#define MSM_PMEM_KERNEL_EBI1_SIZE  0x600000
-#define MSM_PMEM_ADSP_SIZE         0x3800000
+#define MSM_PMEM_ADSP_SIZE         0x7800000
 #define MSM_PMEM_AUDIO_SIZE        0x2B4000
-#define MSM_PMEM_SIZE 0x1800000 /* 24 Mbytes */
+#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
+#define MSM_PMEM_SIZE 0x4000000 /* 64 Mbytes */
+#else
+#define MSM_PMEM_SIZE 0x2800000 /* 40 Mbytes */
+#endif
 
-static struct memtype_reserve apq8064_reserve_table[] __initdata = {
-	[MEMTYPE_SMI] = {
-	},
-	[MEMTYPE_EBI0] = {
-		.flags	=	MEMTYPE_FLAGS_1M_ALIGN,
-	},
-	[MEMTYPE_EBI1] = {
-		.flags	=	MEMTYPE_FLAGS_1M_ALIGN,
-	},
-};
+#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_SIZE		MSM_PMEM_ADSP_SIZE
+#define MSM_ION_MFC_SIZE	SZ_8K
+#define MSM_ION_HEAP_NUM	5
+#else
+#define MSM_PMEM_KERNEL_EBI1_SIZE  0x110C000
+#define MSM_ION_HEAP_NUM	1
+#endif
 
-static int apq8064_paddr_to_memtype(unsigned int paddr)
+#ifdef CONFIG_KERNEL_PMEM_EBI_REGION
+static unsigned pmem_kernel_ebi1_size = MSM_PMEM_KERNEL_EBI1_SIZE;
+static int __init pmem_kernel_ebi1_size_setup(char *p)
 {
-	return MEMTYPE_EBI1;
+	pmem_kernel_ebi1_size = memparse(p, NULL);
+	return 0;
 }
+early_param("pmem_kernel_ebi1_size", pmem_kernel_ebi1_size_setup);
+#endif
 
+#ifdef CONFIG_ANDROID_PMEM
 static unsigned pmem_size = MSM_PMEM_SIZE;
 static int __init pmem_size_setup(char *p)
 {
@@ -92,7 +106,10 @@
 	return 0;
 }
 early_param("pmem_audio_size", pmem_audio_size_setup);
+#endif
 
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 static struct android_pmem_platform_data android_pmem_pdata = {
 	.name = "pmem",
 	.allocator_type = PMEM_ALLOCATORTYPE_ALLORNOTHING,
@@ -112,20 +129,12 @@
 	.cached = 0,
 	.memory_type = MEMTYPE_EBI1,
 };
-
-static unsigned pmem_kernel_ebi1_size = MSM_PMEM_KERNEL_EBI1_SIZE;
-static int __init pmem_kernel_ebi1_size_setup(char *p)
-{
-	pmem_kernel_ebi1_size = memparse(p, NULL);
-	return 0;
-}
-early_param("pmem_kernel_ebi1_size", pmem_kernel_ebi1_size_setup);
-
 static struct platform_device android_pmem_adsp_device = {
 	.name = "android_pmem",
 	.id = 2,
 	.dev = { .platform_data = &android_pmem_adsp_pdata },
 };
+#endif
 
 static struct android_pmem_platform_data android_pmem_audio_pdata = {
 	.name = "pmem_audio",
@@ -139,12 +148,28 @@
 	.id = 4,
 	.dev = { .platform_data = &android_pmem_audio_pdata },
 };
+#endif
+
+static struct memtype_reserve apq8064_reserve_table[] __initdata = {
+	[MEMTYPE_SMI] = {
+	},
+	[MEMTYPE_EBI0] = {
+		.flags	=	MEMTYPE_FLAGS_1M_ALIGN,
+	},
+	[MEMTYPE_EBI1] = {
+		.flags	=	MEMTYPE_FLAGS_1M_ALIGN,
+	},
+};
 
 static void __init size_pmem_devices(void)
 {
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 	android_pmem_adsp_pdata.size = pmem_adsp_size;
 	android_pmem_pdata.size = pmem_size;
+#endif
 	android_pmem_audio_pdata.size = MSM_PMEM_AUDIO_SIZE;
+#endif
 }
 
 static void __init reserve_memory_for(struct android_pmem_platform_data *p)
@@ -154,16 +179,97 @@
 
 static void __init reserve_pmem_memory(void)
 {
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 	reserve_memory_for(&android_pmem_adsp_pdata);
 	reserve_memory_for(&android_pmem_pdata);
+#endif
 	reserve_memory_for(&android_pmem_audio_pdata);
 	apq8064_reserve_table[MEMTYPE_EBI1].size += pmem_kernel_ebi1_size;
+#endif
+}
+
+static int apq8064_paddr_to_memtype(unsigned int paddr)
+{
+	return MEMTYPE_EBI1;
+}
+
+#ifdef CONFIG_ION_MSM
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+static struct ion_cp_heap_pdata cp_mm_ion_pdata = {
+	.permission_type = IPT_TYPE_MM_CARVEOUT,
+};
+
+static struct ion_cp_heap_pdata cp_mfc_ion_pdata = {
+	.permission_type = IPT_TYPE_MFC_SHAREDMEM,
+};
+
+static struct ion_co_heap_pdata co_ion_pdata = {
+};
+#endif
+static struct ion_platform_data ion_pdata = {
+	.nr = MSM_ION_HEAP_NUM,
+	.heaps = {
+		{
+			.id	= ION_SYSTEM_HEAP_ID,
+			.type	= ION_HEAP_TYPE_SYSTEM,
+			.name	= ION_VMALLOC_HEAP_NAME,
+		},
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		{
+			.id	= ION_SF_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_SF_HEAP_NAME,
+			.size	= MSM_ION_SF_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.extra_data = (void *) &co_ion_pdata,
+		},
+		{
+			.id	= ION_CP_MM_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CP,
+			.name	= ION_MM_HEAP_NAME,
+			.size	= MSM_ION_MM_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.extra_data = (void *) &cp_mm_ion_pdata,
+		},
+		{
+			.id	= ION_CP_MFC_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CP,
+			.name	= ION_MFC_HEAP_NAME,
+			.size	= MSM_ION_MFC_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.extra_data = (void *) &cp_mfc_ion_pdata,
+		},
+		{
+			.id	= ION_IOMMU_HEAP_ID,
+			.type	= ION_HEAP_TYPE_IOMMU,
+			.name	= ION_IOMMU_HEAP_NAME,
+		},
+#endif
+	}
+};
+
+static struct platform_device ion_dev = {
+	.name = "ion-msm",
+	.id = 1,
+	.dev = { .platform_data = &ion_pdata },
+};
+#endif
+
+static void reserve_ion_memory(void)
+{
+#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_SF_SIZE;
+	apq8064_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MFC_SIZE;
+#endif
 }
 
 static void __init apq8064_calculate_reserve_sizes(void)
 {
 	size_pmem_devices();
 	reserve_pmem_memory();
+	reserve_ion_memory();
 }
 
 static struct reserve_info apq8064_reserve_info __initdata = {
@@ -453,6 +559,22 @@
 	},
 };
 
+static void __init apq8064_init_buses(void)
+{
+	msm_bus_rpm_set_mt_mask();
+	msm_bus_8064_apps_fabric_pdata.rpm_enabled = 1;
+	msm_bus_8064_sys_fabric_pdata.rpm_enabled = 1;
+	msm_bus_8064_mm_fabric_pdata.rpm_enabled = 1;
+	msm_bus_8064_apps_fabric.dev.platform_data =
+		&msm_bus_8064_apps_fabric_pdata;
+	msm_bus_8064_sys_fabric.dev.platform_data =
+		&msm_bus_8064_sys_fabric_pdata;
+	msm_bus_8064_mm_fabric.dev.platform_data =
+		&msm_bus_8064_mm_fabric_pdata;
+	msm_bus_8064_sys_fpb.dev.platform_data = &msm_bus_8064_sys_fpb_pdata;
+	msm_bus_8064_cpss_fpb.dev.platform_data = &msm_bus_8064_cpss_fpb_pdata;
+}
+
 static struct platform_device *common_devices[] __initdata = {
 	&apq8064_device_dmov,
 	&apq8064_device_qup_i2c_gsbi4,
@@ -464,9 +586,16 @@
 	&apq8064_device_otg,
 	&apq8064_device_gadget_peripheral,
 	&android_usb_device,
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 	&android_pmem_device,
 	&android_pmem_adsp_device,
+#endif
 	&android_pmem_audio_device,
+#endif
+#ifdef CONFIG_ION_MSM
+	&ion_dev,
+#endif
 	&msm8064_device_watchdog,
 	&msm8064_device_saw_regulator_core0,
 	&msm8064_device_saw_regulator_core1,
@@ -507,6 +636,11 @@
 	&apq_pcm_afe,
 	&apq_cpudai_auxpcm_rx,
 	&apq_cpudai_auxpcm_tx,
+	&msm_bus_8064_apps_fabric,
+	&msm_bus_8064_sys_fabric,
+	&msm_bus_8064_mm_fabric,
+	&msm_bus_8064_sys_fpb,
+	&msm_bus_8064_cpss_fpb,
 };
 
 static struct platform_device *sim_devices[] __initdata = {
@@ -519,6 +653,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,
 };
@@ -600,6 +739,7 @@
 						&apq8064_qup_spi_gsbi5_pdata;
 	apq8064_init_pmic();
 	apq8064_device_otg.dev.platform_data = &msm_otg_pdata;
+	apq8064_init_buses();
 	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
 	apq8064_init_mmc();
 	slim_register_board_info(apq8064_slim_devices,
@@ -624,6 +764,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,
@@ -642,3 +790,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-gpiomux.c b/arch/arm/mach-msm/board-8930-gpiomux.c
index fc64ed2..84dbea8 100644
--- a/arch/arm/mach-msm/board-8930-gpiomux.c
+++ b/arch/arm/mach-msm/board-8930-gpiomux.c
@@ -156,29 +156,22 @@
 	.pull = GPIOMUX_PULL_DOWN,
 };
 #ifdef MSM8930_PHASE_2
-static struct gpiomux_setting hsusb_act_cfg = {
-	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_8MA,
-	.pull = GPIOMUX_PULL_UP,
-};
-
 static struct gpiomux_setting hsusb_sus_cfg = {
 	.func = GPIOMUX_FUNC_GPIO,
 	.drv = GPIOMUX_DRV_2MA,
-	.pull = GPIOMUX_PULL_DOWN,
+	.pull = GPIOMUX_PULL_NONE,
+	.dir = GPIOMUX_OUT_LOW,
 };
 static struct msm_gpiomux_config msm8930_hsusb_configs[] = {
 	{
 		.gpio = 63,     /* HSUSB_EXTERNAL_5V_LDO_EN */
 		.settings = {
-			[GPIOMUX_ACTIVE] = &hsusb_act_cfg,
 			[GPIOMUX_SUSPENDED] = &hsusb_sus_cfg,
 		},
 	},
 	{
 		.gpio = 97,     /* HSUSB_5V_EN */
 		.settings = {
-			[GPIOMUX_ACTIVE] = &hsusb_act_cfg,
 			[GPIOMUX_SUSPENDED] = &hsusb_sus_cfg,
 		},
 	},
diff --git a/arch/arm/mach-msm/board-8930-pmic.c b/arch/arm/mach-msm/board-8930-pmic.c
index 6cb69f6..2f59d9d 100644
--- a/arch/arm/mach-msm/board-8930-pmic.c
+++ b/arch/arm/mach-msm/board-8930-pmic.c
@@ -198,10 +198,49 @@
 	.wakeup			= 1,
 };
 
+static int pm8921_therm_mitigation[] = {
+	1100,
+	700,
+	600,
+	325,
+};
+
+#define MAX_VOLTAGE_MV		4200
+static struct pm8921_charger_platform_data pm8921_chg_pdata __devinitdata = {
+	.safety_time		= 180,
+	.update_time		= 60000,
+	.max_voltage		= MAX_VOLTAGE_MV,
+	.min_voltage		= 3200,
+	.resume_voltage_delta	= 100,
+	.term_current		= 100,
+	.cool_temp		= 10,
+	.warm_temp		= 40,
+	.temp_check_period	= 1,
+	.max_bat_chg_current	= 1100,
+	.cool_bat_chg_current	= 350,
+	.warm_bat_chg_current	= 350,
+	.cool_bat_voltage	= 4100,
+	.warm_bat_voltage	= 4100,
+	.thermal_mitigation	= pm8921_therm_mitigation,
+	.thermal_levels		= ARRAY_SIZE(pm8921_therm_mitigation),
+};
+
+static struct pm8xxx_ccadc_platform_data pm8xxx_ccadc_pdata = {
+	.r_sense		= 10,
+};
+
 static struct pm8xxx_misc_platform_data pm8xxx_misc_pdata = {
 	.priority		= 0,
 };
 
+static struct pm8921_bms_platform_data pm8921_bms_pdata __devinitdata = {
+	.r_sense		= 10,
+	.i_test			= 2500,
+	.v_failure		= 3000,
+	.calib_delay_ms		= 600000,
+	.max_voltage_uv		= MAX_VOLTAGE_MV * 1000,
+};
+
 static struct pm8038_platform_data pm8038_platform_data __devinitdata = {
 	.irq_pdata		= &pm8xxx_irq_pdata,
 	.gpio_pdata		= &pm8xxx_gpio_pdata,
@@ -210,7 +249,10 @@
 	.pwrkey_pdata		= &pm8xxx_pwrkey_pdata,
 	.misc_pdata		= &pm8xxx_misc_pdata,
 	.regulator_pdatas	= msm8930_pm8038_regulator_pdata,
+	.charger_pdata		= &pm8921_chg_pdata,
+	.bms_pdata		= &pm8921_bms_pdata,
 	.adc_pdata		= &pm8xxx_adc_pdata,
+	.ccadc_pdata		= &pm8xxx_ccadc_pdata,
 };
 
 static struct msm_ssbi_platform_data msm8930_ssbi_pm8038_pdata __devinitdata = {
diff --git a/arch/arm/mach-msm/board-8930-regulator.c b/arch/arm/mach-msm/board-8930-regulator.c
index cf7d6a9..fc9b58f 100644
--- a/arch/arm/mach-msm/board-8930-regulator.c
+++ b/arch/arm/mach-msm/board-8930-regulator.c
@@ -42,9 +42,11 @@
 };
 VREG_CONSUMERS(L5) = {
 	REGULATOR_SUPPLY("8038_l5",		NULL),
+	REGULATOR_SUPPLY("sdc_vdd",		"msm_sdcc.1"),
 };
 VREG_CONSUMERS(L6) = {
 	REGULATOR_SUPPLY("8038_l6",		NULL),
+	REGULATOR_SUPPLY("sdc_vdd",		"msm_sdcc.3"),
 };
 VREG_CONSUMERS(L7) = {
 	REGULATOR_SUPPLY("8038_l7",		NULL),
@@ -67,6 +69,7 @@
 	REGULATOR_SUPPLY("vdd_dig",		"3-004a"),
 	REGULATOR_SUPPLY("iris_vddio",		"wcnss_wlan.0"),
 	REGULATOR_SUPPLY("riva_vddpx",		"wcnss_wlan.0"),
+	REGULATOR_SUPPLY("sdc_vccq",		"msm_sdcc.1"),
 };
 VREG_CONSUMERS(L12) = {
 	REGULATOR_SUPPLY("8038_l12",		NULL),
@@ -99,6 +102,7 @@
 };
 VREG_CONSUMERS(L22) = {
 	REGULATOR_SUPPLY("8038_l22",		NULL),
+	REGULATOR_SUPPLY("sdc_vddp",		"msm_sdcc.3"),
 };
 VREG_CONSUMERS(L23) = {
 	REGULATOR_SUPPLY("8038_l23",		NULL),
diff --git a/arch/arm/mach-msm/board-8930-storage.c b/arch/arm/mach-msm/board-8930-storage.c
index d655ead..eee6d09 100644
--- a/arch/arm/mach-msm/board-8930-storage.c
+++ b/arch/arm/mach-msm/board-8930-storage.c
@@ -250,6 +250,8 @@
 /*TODO: Insert right replacement for PM8038 */
 #ifndef MSM8930_PHASE_2
 	.wpswitch_gpio	= PM8921_GPIO_PM_TO_SYS(16),
+#else
+	.wpswitch_gpio	= 66,
 #endif
 #endif
 	.vreg_data	= &mmc_slot_vreg_data[SDCC3],
@@ -259,6 +261,9 @@
 #ifndef MSM8930_PHASE_2
 	.status_gpio	= PM8921_GPIO_PM_TO_SYS(26),
 	.status_irq	= PM8921_GPIO_IRQ(PM8921_IRQ_BASE, 26),
+#else
+	.status_gpio	= 94,
+	.status_irq	= MSM_GPIO_TO_INT(94),
 #endif
 	.irq_flags	= IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 	.is_status_gpio_active_low = true,
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 533d4f7..fe125e3 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -117,21 +117,24 @@
 
 #endif
 
-#define MSM_PMEM_ADSP_SIZE         0x3800000
+#define MSM_PMEM_ADSP_SIZE         0x7800000
 #define MSM_PMEM_AUDIO_SIZE        0x2B4000
 #ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
 #define MSM_PMEM_SIZE 0x4000000 /* 64 Mbytes */
 #else
-#define MSM_PMEM_SIZE 0x1C00000 /* 28 Mbytes */
+#define MSM_PMEM_SIZE 0x2800000 /* 40 Mbytes */
 #endif
 
 
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 #define MSM_PMEM_KERNEL_EBI1_SIZE  0xB0C000
-#define MSM_ION_SF_SIZE		0x1800000 /* 24MB */
-#define MSM_ION_MM_SIZE		0x4000000 /* (64MB) */
+#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
@@ -285,12 +288,20 @@
 #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 = {
@@ -308,7 +319,7 @@
 			.name	= ION_SF_HEAP_NAME,
 			.size	= MSM_ION_SF_SIZE,
 			.memory_type = ION_EBI_TYPE,
-			.extra_data = &co_ion_pdata,
+			.extra_data = (void *) &co_ion_pdata,
 		},
 		{
 			.id	= ION_CP_MM_HEAP_ID,
@@ -319,6 +330,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,
@@ -331,6 +350,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
 	}
 };
@@ -347,7 +382,10 @@
 #if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
 	msm8930_reserve_table[MEMTYPE_EBI1].size += MSM_ION_SF_SIZE;
 	msm8930_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MM_SIZE;
+	msm8930_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MM_FW_SIZE;
 	msm8930_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MFC_SIZE;
+	msm8930_reserve_table[MEMTYPE_EBI1].size += MSM_ION_QSECOM_SIZE;
+	msm8930_reserve_table[MEMTYPE_EBI1].size += MSM_ION_AUDIO_SIZE;
 #endif
 }
 
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index b19445d..598e18d 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -130,7 +130,7 @@
 
 #endif
 
-#define MSM_PMEM_ADSP_SIZE         0x4200000
+#define MSM_PMEM_ADSP_SIZE         0x7800000
 #define MSM_PMEM_AUDIO_SIZE        0x2B4000
 #ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
 #define MSM_PMEM_SIZE 0x4000000 /* 64 Mbytes */
@@ -141,10 +141,13 @@
 
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 #define MSM_PMEM_KERNEL_EBI1_SIZE  0xB0C000
-#define MSM_ION_SF_SIZE		0x2800000 /* (40MB) */
-#define MSM_ION_MM_SIZE		0x4000000 /* (64MB) */
+#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
 #define MSM_LIQUID_ION_MM_SIZE (MSM_ION_MM_SIZE + 0x600000)
 static unsigned int msm_ion_cp_mm_size = MSM_ION_MM_SIZE;
 #else
@@ -312,16 +315,24 @@
 #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 = {
 	.nr = MSM_ION_HEAP_NUM,
 	.heaps = {
@@ -337,7 +348,7 @@
 			.name	= ION_SF_HEAP_NAME,
 			.size	= MSM_ION_SF_SIZE,
 			.memory_type = ION_EBI_TYPE,
-			.extra_data = &co_ion_pdata,
+			.extra_data = (void *) &co_ion_pdata,
 		},
 		{
 			.id	= ION_CP_MM_HEAP_ID,
@@ -348,6 +359,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,
@@ -360,6 +379,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
 	}
 };
@@ -394,8 +429,11 @@
 		}
 	}
 	msm8960_reserve_table[MEMTYPE_EBI1].size += msm_ion_cp_mm_size;
+	msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MM_FW_SIZE;
 	msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_SF_SIZE;
 	msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MFC_SIZE;
+	msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_QSECOM_SIZE;
+	msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_AUDIO_SIZE;
 #endif
 }
 
diff --git a/arch/arm/mach-msm/board-copper.c b/arch/arm/mach-msm/board-copper.c
index a372eb6..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[] = {
@@ -77,6 +74,8 @@
 	CLK_DUMMY("dfab_clk",	DFAB_CLK,	NULL, 0),
 	CLK_DUMMY("dma_bam_pclk",	DMA_BAM_P_CLK,	NULL, 0),
 	CLK_DUMMY("mem_clk",	NULL,	NULL, 0),
+	CLK_DUMMY("core_clk",	SPI_CLK,	"spi_qsd.1",	OFF),
+	CLK_DUMMY("iface_clk",	SPI_P_CLK,	"spi_qsd.1",	OFF),
 };
 
 struct clock_init_data msm_dummy_clock_init_data __initdata = {
@@ -89,6 +88,8 @@
 			"msm_serial_hsl.0", NULL),
 	OF_DEV_AUXDATA("qcom,hsusb-otg", 0xF9A55000, \
 			"msm_otg", NULL),
+	OF_DEV_AUXDATA("qcom,spi-qup-v2", 0xF9924000, \
+			"spi_qsd.1", NULL),
 	{}
 };
 
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-bt.c b/arch/arm/mach-msm/board-msm7627a-bt.c
index d4f06fa..8b3b606 100644
--- a/arch/arm/mach-msm/board-msm7627a-bt.c
+++ b/arch/arm/mach-msm/board-msm7627a-bt.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
@@ -677,11 +677,9 @@
 		pr_err("%s: could not enable regulator: %d\n", __func__, rc);
 		goto reg_fail;
 	}
-	if (machine_is_msm7627a_qrd1())
-		gpio_tlmm_config(GPIO_CFG(gpio_bt_sys_rest_en, 0,
-			GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
-			GPIO_CFG_2MA), GPIO_CFG_ENABLE);
-
+	gpio_tlmm_config(GPIO_CFG(gpio_bt_sys_rest_en, 0,
+				GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+				GPIO_CFG_2MA), GPIO_CFG_ENABLE);
 
 	/*setup Bahama_sys_reset_n*/
 	rc = gpio_request(gpio_bt_sys_rest_en, "bahama sys_rst_n");
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index df04bb2..7699aa8 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -2672,12 +2672,13 @@
 
 #define MSM_ION_SF_SIZE		0x1800000 /* 24MB */
 #define MSM_ION_CAMERA_SIZE     MSM_PMEM_ADSP_SIZE
-#define MSM_ION_MM_SIZE		0x3800000 /* 56MB */
+#define MSM_ION_MM_FW_SIZE	0x200000 /* (2MB) */
+#define MSM_ION_MM_SIZE		0x3600000 /* (54MB) */
 #define MSM_ION_MFC_SIZE	SZ_8K
 #define MSM_ION_WB_SIZE		0x600000 /* 6MB */
 
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-#define MSM_ION_HEAP_NUM	6
+#define MSM_ION_HEAP_NUM	7
 #else
 #define MSM_ION_HEAP_NUM	1
 #endif
@@ -5242,6 +5243,7 @@
 #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,
 	.request_region = request_smi_region,
 	.release_region = release_smi_region,
 	.setup_region = setup_smi_region,
@@ -5249,6 +5251,7 @@
 
 static struct ion_cp_heap_pdata cp_mfc_ion_pdata = {
 	.permission_type = IPT_TYPE_MFC_SHAREDMEM,
+	.align = PAGE_SIZE,
 	.request_region = request_smi_region,
 	.release_region = release_smi_region,
 	.setup_region = setup_smi_region,
@@ -5256,9 +5259,17 @@
 
 static struct ion_cp_heap_pdata cp_wb_ion_pdata = {
 	.permission_type = IPT_TYPE_MDP_WRITEBACK,
+	.align = PAGE_SIZE,
+};
+
+static struct ion_co_heap_pdata fw_co_ion_pdata = {
+	.adjacent_mem_id = ION_CP_MM_HEAP_ID,
+	.align = SZ_128K,
 };
 
 static struct ion_co_heap_pdata co_ion_pdata = {
+	.adjacent_mem_id = INVALID_HEAP_ID,
+	.align = PAGE_SIZE,
 };
 #endif
 static struct ion_platform_data ion_pdata = {
@@ -5276,7 +5287,7 @@
 			.name	= ION_SF_HEAP_NAME,
 			.size	= MSM_ION_SF_SIZE,
 			.memory_type = ION_EBI_TYPE,
-			.extra_data = &co_ion_pdata,
+			.extra_data = (void *)&co_ion_pdata,
 		},
 		{
 			.id	= ION_CP_MM_HEAP_ID,
@@ -5287,6 +5298,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_SMI_TYPE,
+			.extra_data = (void *) &fw_co_ion_pdata,
+		},
+		{
 			.id	= ION_CAMERA_HEAP_ID,
 			.type	= ION_HEAP_TYPE_CARVEOUT,
 			.name	= ION_CAMERA_HEAP_NAME,
@@ -5353,6 +5372,7 @@
 {
 #if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
 	msm8x60_reserve_table[MEMTYPE_EBI1].size += MSM_ION_SF_SIZE;
+	msm8x60_reserve_table[MEMTYPE_SMI].size += MSM_ION_MM_FW_SIZE;
 	msm8x60_reserve_table[MEMTYPE_SMI].size += MSM_ION_MM_SIZE;
 	msm8x60_reserve_table[MEMTYPE_SMI].size += MSM_ION_MFC_SIZE;
 	msm8x60_reserve_table[MEMTYPE_EBI1].size += MSM_ION_CAMERA_SIZE;
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 295c7d9..09f70f1 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -4450,11 +4450,7 @@
 static DEFINE_CLK_VOTER(dfab_scm_clk, &dfab_clk.c);
 
 static DEFINE_CLK_VOTER(ebi1_msmbus_clk, &ebi1_clk.c);
-/*
- * TODO: replace dummy_clk below with ebi1_clk.c once the
- * bus driver starts voting on ebi1 rates.
- */
-static DEFINE_CLK_VOTER(ebi1_adm_clk,    &dummy_clk);
+static DEFINE_CLK_VOTER(ebi1_adm_clk, &ebi1_clk.c);
 
 #ifdef CONFIG_DEBUG_FS
 struct measure_sel {
@@ -5313,6 +5309,13 @@
 	CLK_LOOKUP("core_clk",		gfx3d_clk.c,		"msm_iommu.9"),
 	CLK_LOOKUP("core_clk",		gfx2d0_clk.c,		"msm_iommu.10"),
 	CLK_LOOKUP("core_clk",		gfx2d1_clk.c,		"msm_iommu.11"),
+
+	CLK_LOOKUP("mdp_iommu_clk", mdp_axi_clk.c,	"msm_vidc.0"),
+	CLK_LOOKUP("rot_iommu_clk",	rot_axi_clk.c,	"msm_vidc.0"),
+	CLK_LOOKUP("vcodec_iommu0_clk", vcodec_axi_a_clk.c, "msm_vidc.0"),
+	CLK_LOOKUP("vcodec_iommu1_clk", vcodec_axi_b_clk.c, "msm_vidc.0"),
+	CLK_LOOKUP("smmu_iface_clk", smmu_p_clk.c,	"msm_vidc.0"),
+
 	CLK_LOOKUP("dfab_dsps_clk",	dfab_dsps_clk.c, NULL),
 	CLK_LOOKUP("core_clk",		dfab_usb_hs_clk.c,	"msm_otg"),
 	CLK_LOOKUP("bus_clk",		dfab_sdc1_clk.c, "msm_sdcc.1"),
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index c33daf7..3e57ebc 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -1671,6 +1671,11 @@
 	CLK_LOOKUP("core_clk",	     usb_hsic_sys_clk.c,       "msm_hsic_host"),
 	CLK_LOOKUP("iface_clk",	     usb_hsic_p_clk.c,	       "msm_hsic_host"),
 	CLK_LOOKUP("phy_clk",        usb_hsic_clk.c,	       "msm_hsic_host"),
+	CLK_LOOKUP("alt_core_clk",  usb_hsic_xcvr_clk.c, "msm_hsic_peripheral"),
+	CLK_LOOKUP("cal_clk",  usb_hsic_hsio_cal_clk.c,  "msm_hsic_peripheral"),
+	CLK_LOOKUP("core_clk",      usb_hsic_sys_clk.c,  "msm_hsic_peripheral"),
+	CLK_LOOKUP("iface_clk",     usb_hsic_p_clk.c,    "msm_hsic_peripheral"),
+	CLK_LOOKUP("phy_clk",       usb_hsic_clk.c,      "msm_hsic_peripheral"),
 
 	CLK_LOOKUP("iface_clk",		sdc1_p_clk.c,		"msm_sdcc.1"),
 	CLK_LOOKUP("iface_clk",		sdc2_p_clk.c,		"msm_sdcc.2"),
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 12a00e6..9c77f3d 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -24,6 +24,7 @@
 #include <mach/dma.h>
 #include <sound/msm-dai-q6.h>
 #include <sound/apr_audio.h>
+#include <mach/msm_bus_board.h>
 #include "clock.h"
 #include "devices.h"
 #include "msm_watchdog.h"
@@ -694,6 +695,27 @@
 	},
 };
 
+struct platform_device msm_bus_8064_sys_fabric = {
+	.name  = "msm_bus_fabric",
+	.id    =  MSM_BUS_FAB_SYSTEM,
+};
+struct platform_device msm_bus_8064_apps_fabric = {
+	.name  = "msm_bus_fabric",
+	.id    = MSM_BUS_FAB_APPSS,
+};
+struct platform_device msm_bus_8064_mm_fabric = {
+	.name  = "msm_bus_fabric",
+	.id    = MSM_BUS_FAB_MMSS,
+};
+struct platform_device msm_bus_8064_sys_fpb = {
+	.name  = "msm_bus_fabric",
+	.id    = MSM_BUS_FAB_SYSTEM_FPB,
+};
+struct platform_device msm_bus_8064_cpss_fpb = {
+	.name  = "msm_bus_fabric",
+	.id    = MSM_BUS_FAB_CPSS_FPB,
+};
+
 static struct msm_sps_platform_data msm_sps_pdata = {
 	.bamdma_restricted_pipes = 0x06,
 };
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 33a543d..5d28fa9 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -264,3 +264,9 @@
 extern struct platform_device msm_funnel_device;
 extern struct platform_device msm_ptm_device;
 #endif
+
+extern struct platform_device msm_bus_8064_apps_fabric;
+extern struct platform_device msm_bus_8064_sys_fabric;
+extern struct platform_device msm_bus_8064_mm_fabric;
+extern struct platform_device msm_bus_8064_sys_fpb;
+extern struct platform_device msm_bus_8064_cpss_fpb;
diff --git a/arch/arm/mach-msm/idle_stats_device.c b/arch/arm/mach-msm/idle_stats_device.c
index 5c4b6a3..c28cf94 100644
--- a/arch/arm/mach-msm/idle_stats_device.c
+++ b/arch/arm/mach-msm/idle_stats_device.c
@@ -137,8 +137,7 @@
 		device->stats = &device->stats_vector[1];
 	else
 		device->stats = &device->stats_vector[0];
-	device->stats->event = (stats->event &
-			MSM_IDLE_STATS_EVENT_BUSY_TIMER_EXPIRED);
+	device->stats->event = 0;
 	device->stats->nr_collected = 0;
 	spin_unlock(&device->lock);
 	if (stats->nr_collected >= MSM_IDLE_STATS_NR_MAX_INTERVALS) {
@@ -217,7 +216,7 @@
 		device->remaining_time =
 				hrtimer_get_remaining(&device->busy_timer);
 		if (ktime_to_us(device->remaining_time) <= 0)
-			device->remaining_time = us_to_ktime(1);
+			device->remaining_time = us_to_ktime(0);
 	} else {
 		device->remaining_time = us_to_ktime(0);
 	}
@@ -228,8 +227,11 @@
 void msm_idle_stats_idle_end(struct msm_idle_stats_device *device,
 				struct msm_idle_pulse *pulse)
 {
+	u32 idle_time = 0;
 	spin_lock(&device->lock);
 	if (ktime_to_us(device->idle_start) != 0) {
+		idle_time = ktime_to_us(ktime_get())
+			- ktime_to_us(device->idle_start);
 		device->idle_start = us_to_ktime(0);
 	    msm_idle_stats_add_sample(device, pulse);
 		if (device->stats->event &
@@ -240,7 +242,10 @@
 				MSM_IDLE_STATS_EVENT_BUSY_TIMER_EXPIRED_RESET);
 		} else if (ktime_to_us(device->busy_timer_interval) > 0) {
 			ktime_t busy_timer = device->busy_timer_interval;
-			if ((pulse->wait_interval > 0) &&
+			/* if it is serialized, it would be full busy,
+			 * checking 80%
+			 */
+			if ((pulse->wait_interval*5 >= idle_time*4) &&
 				(ktime_to_us(device->remaining_time) > 0) &&
 				(ktime_to_us(device->remaining_time) <
 				 ktime_to_us(busy_timer)))
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index fd282d5..8961c79 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -155,8 +155,12 @@
 
 struct msm_vpe_phy_info {
 	uint32_t sbuf_phy;
-	uint32_t y_phy;
-	uint32_t cbcr_phy;
+	uint32_t planar0_off;
+	uint32_t planar1_off;
+	uint32_t planar2_off;
+	uint32_t p0_phy;
+	uint32_t p1_phy;
+	uint32_t p2_phy;
 	uint8_t  output_id; /* VFE31_OUTPUT_MODE_PT/S/V */
 	uint32_t frame_id;
 };
@@ -193,6 +197,7 @@
 #define VFE31_OUTPUT_MODE_V (0x1 << 2)
 #define VFE31_OUTPUT_MODE_P (0x1 << 3)
 #define VFE31_OUTPUT_MODE_T (0x1 << 4)
+#define VFE31_OUTPUT_MODE_P_ALL_CHNLS (0x1 << 5)
 
 #define CSI_EMBED_DATA 0x12
 #define CSI_YUV422_8  0x1E
@@ -206,8 +211,12 @@
 
 struct msm_vfe_phy_info {
 	uint32_t sbuf_phy;
-	uint32_t y_phy;
-	uint32_t cbcr_phy;
+	uint32_t planar0_off;
+	uint32_t planar1_off;
+	uint32_t planar2_off;
+	uint32_t p0_phy;
+	uint32_t p1_phy;
+	uint32_t p2_phy;
 	uint8_t  output_id; /* VFE31_OUTPUT_MODE_PT/S/V */
 	uint32_t frame_id;
 };
@@ -238,8 +247,8 @@
 };
 
 struct msm_vpe_buf_info {
-	uint32_t y_phy;
-	uint32_t cbcr_phy;
+	uint32_t p0_phy;
+	uint32_t p1_phy;
 	struct   timespec ts;
 	uint32_t frame_id;
 	struct	 video_crop_t vpe_crop;
@@ -303,7 +312,7 @@
 struct msm_camvpe_fn {
 	int (*vpe_reg)(struct msm_vpe_callback *);
 	int (*vpe_cfg_update) (void *);
-	void (*send_frame_to_vpe) (uint32_t y_phy, uint32_t cbcr_phy,
+	void (*send_frame_to_vpe) (uint32_t planar0_off, uint32_t planar1_off,
 		struct timespec *ts, int output_id);
 	int (*vpe_config)(struct msm_vpe_cfg_cmd *, void *);
 	void (*vpe_cfg_offset)(int frame_pack, uint32_t pyaddr,
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/memory.h b/arch/arm/mach-msm/include/mach/memory.h
index 9cd73db..e1fc054 100644
--- a/arch/arm/mach-msm/include/mach/memory.h
+++ b/arch/arm/mach-msm/include/mach/memory.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/include/mach/memory.h
  *
  * 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
@@ -23,8 +23,13 @@
 #define MAX_PHYSMEM_BITS 32
 #define SECTION_SIZE_BITS 28
 
-/* Maximum number of Memory Regions */
-#define MAX_NR_REGIONS 4
+/* Maximum number of Memory Regions
+*  The largest system can have 4 memory banks, each divided into 8 regions
+*/
+#define MAX_NR_REGIONS 32
+
+/* The number of regions each memory bank is divided into */
+#define NR_REGIONS_PER_BANK 8
 
 /* Certain configurations of MSM7x30 have multiple memory banks.
 *  One or more of these banks can contain holes in the memory map as well.
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 7f5bd75..15b2856 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8064.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8064.h
@@ -77,4 +77,25 @@
 #define APQ8064_IMEM_PHYS		0x2A03F000
 #define APQ8064_IMEM_SIZE		SZ_4K
 
+#define APQ8064_RPM_PHYS		0x00108000
+#define APQ8064_RPM_SIZE		SZ_4K
+
+#define APQ8064_RPM_MPM_PHYS		0x00200000
+#define APQ8064_RPM_MPM_SIZE		SZ_4K
+
+#define APQ8064_SAW0_PHYS		0x02089000
+#define APQ8064_SAW0_SIZE		SZ_4K
+
+#define APQ8064_SAW1_PHYS		0x02099000
+#define APQ8064_SAW1_SIZE		SZ_4K
+
+#define APQ8064_SAW2_PHYS		0x020A9000
+#define APQ8064_SAW2_SIZE		SZ_4K
+
+#define APQ8064_SAW3_PHYS		0x020B9000
+#define APQ8064_SAW3_SIZE		SZ_4K
+
+#define APQ8064_SAW_L2_PHYS		0x02012000
+#define APQ8064_SAW_L2_SIZE		SZ_4K
+
 #endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index dd01c62..ff0b368 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -75,8 +75,10 @@
 #define MSM_RPM_BASE		IOMEM(0xFA801000)	/*  4K	*/
 #define MSM_RPM_MPM_BASE	IOMEM(0xFA802000)	/*  4K	*/
 #define MSM_QFPROM_BASE		IOMEM(0xFA700000)	/*  4K  */
-#define MSM_L2CC_BASE		IOMEM(0xFA701000)	/* 4K */
-#define MSM_APCS_GLB_BASE	IOMEM(0xFA702000)	/* 4K */
+#define MSM_L2CC_BASE		IOMEM(0xFA701000)	/*  4K  */
+#define MSM_APCS_GLB_BASE	IOMEM(0xFA702000)	/*  4K  */
+#define MSM_SAW2_BASE		IOMEM(0xFA703000)	/*  4k  */
+#define MSM_SAW3_BASE		IOMEM(0xFA704000)	/*  4k  */
 
 #if defined(CONFIG_ARCH_MSM9615)
 #define MSM_SHARED_RAM_SIZE	SZ_1M
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 2d5b0a4..9622a4c 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -265,6 +265,13 @@
 	MSM_CHIP_DEVICE(MMSS_CLK_CTL, APQ8064),
 	MSM_CHIP_DEVICE(LPASS_CLK_CTL, APQ8064),
 	MSM_CHIP_DEVICE(APCS_GCC, APQ8064),
+	MSM_CHIP_DEVICE(RPM, APQ8064),
+	MSM_CHIP_DEVICE(RPM_MPM, APQ8064),
+	MSM_CHIP_DEVICE(SAW0, APQ8064),
+	MSM_CHIP_DEVICE(SAW1, APQ8064),
+	MSM_CHIP_DEVICE(SAW2, APQ8064),
+	MSM_CHIP_DEVICE(SAW3, APQ8064),
+	MSM_CHIP_DEVICE(SAW_L2, APQ8064),
 	MSM_CHIP_DEVICE(IMEM, APQ8064),
 	{
 		.virtual =  (unsigned long) MSM_SHARED_RAM_BASE,
diff --git a/arch/arm/mach-msm/memory_topology.c b/arch/arm/mach-msm/memory_topology.c
index 5854a23..6208a0d 100644
--- a/arch/arm/mach-msm/memory_topology.c
+++ b/arch/arm/mach-msm/memory_topology.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
@@ -31,11 +31,11 @@
 	/* reserved for future use */
 	u64 num_partitions;
 	int state;
-	int mask;
-	struct mutex state_mutex;
 } mem_regions[MAX_NR_REGIONS];
 
+static struct mutex mem_regions_mutex;
 static unsigned int nr_mem_regions;
+static int mem_regions_mask;
 
 enum {
 	STATE_POWER_DOWN = 0x0,
@@ -43,14 +43,6 @@
 	STATE_DEFAULT = STATE_ACTIVE
 };
 
-enum {
-	MEM_NO_CHANGE = 0x0,
-	MEM_DEEP_POWER_DOWN,
-	MEM_SELF_REFRESH,
-};
-
-static unsigned int dmm_mode;
-
 static int default_mask = ~0x0;
 
 /* Return the number of chipselects populated with a memory bank */
@@ -111,50 +103,55 @@
 	}
 }
 
-static int switch_memory_state(int id, int new_state)
+static int switch_memory_state(int mask, int new_state, int start_region,
+				int end_region)
 {
-	int mask = 0;
-	int power_down_masks[MAX_NR_REGIONS] = { 0xFFFFFF00, 0xFFFF00FF,
-						0xFF00FFFF, 0x00FFFFFF };
-	int self_refresh_masks[MAX_NR_REGIONS] = { 0xFFFFFFF0, 0xFFFFFF0F,
-						0xFFFFF0FF, 0xFFFF0FFF };
-	mutex_lock(&mem_regions[id].state_mutex);
+	int final_mask = 0;
+	int i;
 
-	if (new_state == mem_regions[id].state)
-		goto no_change;
+	mutex_lock(&mem_regions_mutex);
 
-	pr_info("request memory %d state switch (%d->%d) mode %d\n", id,
-			mem_regions[id].state, new_state, dmm_mode);
-	if (new_state == STATE_POWER_DOWN) {
-		if (dmm_mode == MEM_DEEP_POWER_DOWN)
-			mask = mem_regions[id].mask & power_down_masks[id];
-		else
-			mask = mem_regions[id].mask & self_refresh_masks[id];
-	} else if (new_state == STATE_ACTIVE) {
-		if (dmm_mode == MEM_DEEP_POWER_DOWN)
-			mask = mem_regions[id].mask | (~power_down_masks[id]);
-		else
-			mask = mem_regions[id].mask | (~self_refresh_masks[id]);
+	for (i = start_region; i <= end_region; i++) {
+		if (new_state == mem_regions[i].state)
+			goto no_change;
+		/* All region states must be the same to change them */
+		if (mem_regions[i].state != mem_regions[start_region].state)
+			goto no_change;
 	}
 
-	if (rpm_change_memory_state(mask, mask) == 0) {
-		mem_regions[id].state = new_state;
-		mem_regions[id].mask = mask;
-		pr_info("completed memory %d state switch to %d mode %d\n",
-				id, new_state, dmm_mode);
-		mutex_unlock(&mem_regions[id].state_mutex);
+	if (new_state == STATE_POWER_DOWN)
+		final_mask = mem_regions_mask & mask;
+	else if (new_state == STATE_ACTIVE)
+		final_mask = mem_regions_mask | ~mask;
+	else
+		goto no_change;
+
+	pr_info("request memory %d to %d state switch (%d->%d)\n",
+		start_region, end_region, mem_regions[start_region].state,
+		new_state);
+	if (rpm_change_memory_state(final_mask, final_mask) == 0) {
+		for (i = start_region; i <= end_region; i++)
+			mem_regions[i].state = new_state;
+		mem_regions_mask = final_mask;
+
+		pr_info("completed memory %d to %d state switch to %d\n",
+			start_region, end_region, new_state);
+		mutex_unlock(&mem_regions_mutex);
 		return 0;
 	}
 
-	pr_err("failed memory %d state switch (%d->%d) mode %d\n", id,
-			mem_regions[id].state, new_state, dmm_mode);
+	pr_err("failed memory %d to %d state switch (%d->%d)\n",
+		start_region, end_region, mem_regions[start_region].state,
+		new_state);
+
 no_change:
-	mutex_unlock(&mem_regions[id].state_mutex);
+	mutex_unlock(&mem_regions_mutex);
 	return -EINVAL;
 }
 #else
 
-static int switch_memory_state(int id, int new_state)
+static int switch_memory_state(int mask, int new_state, int start_region,
+				int end_region)
 {
 	return -EINVAL;
 }
@@ -165,29 +162,34 @@
 */
 int soc_change_memory_power(u64 start, u64 size, int change)
 {
-
 	int i = 0;
-	int match = 0;
-
-	/* Find the memory region starting just below start */
-	for (i = 0; i < nr_mem_regions; i++) {
-		if (mem_regions[i].start <= start &&
-			mem_regions[i].start >= mem_regions[match].start) {
-				match = i;
-		}
-	}
-
-	if (start + size > mem_regions[match].start + mem_regions[match].size) {
-		pr_info("passed size exceeds size of memory bank\n");
-		return 0;
-	}
+	int mask = default_mask;
+	u64 end = start + size;
+	int start_region = 0;
+	int end_region = 0;
 
 	if (change != STATE_ACTIVE && change != STATE_POWER_DOWN) {
 		pr_info("requested state transition invalid\n");
 		return 0;
 	}
+	/* Find the memory regions that fall within the range */
+	for (i = 0; i < nr_mem_regions; i++) {
+		if (mem_regions[i].start <= start &&
+			mem_regions[i].start >=
+			mem_regions[start_region].start) {
+			start_region = i;
+		}
+		if (end <= mem_regions[i].start + mem_regions[i].size) {
+			end_region = i;
+			break;
+		}
+	}
 
-	if (!switch_memory_state(match, change))
+	/* Set the bitmask for each region in the range */
+	for (i = start_region; i <= end_region; i++)
+		mask &= ~(0x1 << i);
+
+	if (!switch_memory_state(mask, change, start_region, end_region))
 		return size;
 	else
 		return 0;
@@ -212,9 +214,10 @@
 
 int __init meminfo_init(unsigned int type, unsigned int min_bank_size)
 {
-	unsigned int i;
+	unsigned int i, j;
 	unsigned long bank_size;
 	unsigned long bank_start;
+	unsigned long region_size;
 	struct smem_ram_ptable *ram_ptable;
 	/* physical memory banks */
 	unsigned int nr_mem_banks = 0;
@@ -229,40 +232,35 @@
 		return -EINVAL;
 	}
 
-	/* Determine power control mode based on the hw version */
-	/* This check will be removed when PASR is fully supported */
-	if (cpu_is_msm8960() &&
-		SOCINFO_VERSION_MAJOR(socinfo_get_version()) < 2)
-		dmm_mode = MEM_DEEP_POWER_DOWN;
-	else
-		dmm_mode = MEM_SELF_REFRESH;
-
 	pr_info("meminfo_init: smem ram ptable found: ver: %d len: %d\n",
 			ram_ptable->version, ram_ptable->len);
 
 	for (i = 0; i < ram_ptable->len; i++) {
+		/* A bank is valid only if is greater than min_bank_size. If
+		 * non-valid memory (e.g. modem memory) became greater than
+		 * min_bank_size, there is currently no way to differentiate.
+		 */
 		if (ram_ptable->parts[i].type == type &&
 			ram_ptable->parts[i].size >= min_bank_size) {
 			bank_start = ram_ptable->parts[i].start;
 			bank_size = ram_ptable->parts[i].size;
-			/* Divide into logical memory regions of same size */
-			while (bank_size) {
+			region_size = bank_size / NR_REGIONS_PER_BANK;
+
+			for (j = 0; j < NR_REGIONS_PER_BANK; j++) {
 				mem_regions[nr_mem_regions].start =
 					bank_start;
 				mem_regions[nr_mem_regions].size =
-					MIN_MEMORY_BLOCK_SIZE;
-				mutex_init(&mem_regions[nr_mem_regions]
-							.state_mutex);
+					region_size;
 				mem_regions[nr_mem_regions].state =
 							STATE_DEFAULT;
-				mem_regions[nr_mem_regions].mask = default_mask;
-				bank_start += MIN_MEMORY_BLOCK_SIZE;
-				bank_size -= MIN_MEMORY_BLOCK_SIZE;
+				bank_start += region_size;
 				nr_mem_regions++;
 			}
 			nr_mem_banks++;
 		}
 	}
+	mutex_init(&mem_regions_mutex);
+	mem_regions_mask = default_mask;
 	pr_info("Found %d memory banks grouped into %d memory regions\n",
 			nr_mem_banks, nr_mem_regions);
 	return 0;
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/platsmp.c b/arch/arm/mach-msm/platsmp.c
index d73d4a0..f1c6c48 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -31,13 +31,8 @@
 
 int pen_release = -1;
 
-/* Initialize the present map (cpu_set(i, cpu_present_map)). */
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 {
-	int i;
-
-	for (i = 0; i < max_cpus; i++)
-		cpu_set(i, cpu_present_map);
 }
 
 void __init smp_init_cpus(void)
diff --git a/arch/arm/mach-msm/sdio_al_test.c b/arch/arm/mach-msm/sdio_al_test.c
index a71aae3..c97588f 100644
--- a/arch/arm/mach-msm/sdio_al_test.c
+++ b/arch/arm/mach-msm/sdio_al_test.c
@@ -146,7 +146,6 @@
 	SDIO_DIAG,
 	SDIO_DUN,
 	SDIO_SMEM,
-	SDIO_CIQ,
 	SDIO_CSVT,
 	SDIO_MAX_CHANNELS
 };
@@ -250,7 +249,7 @@
 	struct dentry *rpc_sender_rmnet_a2_perf_test;
 	struct dentry *all_channels_test;
 	struct dentry *host_sender_no_lp_diag_test;
-	struct dentry *host_sender_no_lp_diag_rpc_ciq_test;
+	struct dentry *host_sender_no_lp_diag_rpc_test;
 	struct dentry *rmnet_small_packets_test;
 	struct dentry *rmnet_rtt_test;
 	struct dentry *csvt_rtt_test;
@@ -297,7 +296,6 @@
 	u8 *smem_buf;
 	uint32_t smem_counter;
 
-	struct platform_device *ciq_app_pdev;
 	struct platform_device *csvt_app_pdev;
 
 	wait_queue_head_t   wait_q;
@@ -1181,7 +1179,6 @@
 		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_RMNT]);
 		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_DUN]);
 		set_params_smem_test(test_ctx->test_ch_arr[SDIO_SMEM]);
-		set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_CIQ]);
 		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_CSVT]);
 
 		ret = test_start();
@@ -1284,8 +1281,8 @@
 	.read = host_sender_no_lp_diag_test_read,
 };
 
-/* HOST SENDER NO LP DIAG, RPC, CIQ TEST */
-static ssize_t host_sender_no_lp_diag_rpc_ciq_test_write(
+/* HOST SENDER NO LP DIAG, RPC TEST */
+static ssize_t host_sender_no_lp_diag_rpc_test_write(
 						 struct file *file,
 						 const char __user *buf,
 						 size_t count,
@@ -1295,8 +1292,8 @@
 	int i = 0;
 	int number = -1;
 
-	pr_info(TEST_MODULE_NAME "-- HOST SENDER NO LP FOR DIAG, RPC, "
-		"CIQ TEST --");
+	pr_info(TEST_MODULE_NAME "-- HOST SENDER NO LP FOR DIAG, RPC "
+		"TEST --");
 
 	number = sdio_al_test_extract_number(buf, count);
 
@@ -1313,7 +1310,6 @@
 		sdio_al_test_initial_dev_and_chan(test_ctx);
 
 		set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_DIAG]);
-		set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_CIQ]);
 		set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_RPC]);
 
 		ret = test_start();
@@ -1325,7 +1321,7 @@
 	return count;
 }
 
-static ssize_t host_sender_no_lp_diag_rpc_ciq_test_read(
+static ssize_t host_sender_no_lp_diag_rpc_test_read(
 						 struct file *file,
 						 char __user *buffer,
 						 size_t count,
@@ -1334,7 +1330,7 @@
 	memset((void *)buffer, 0, count);
 
 	snprintf(buffer, count,
-		 "\nHOST_SENDER_NO_LP_DIAG_RPC_CIQ_TEST\n"
+		 "\nHOST_SENDER_NO_LP_DIAG_RPC_TEST\n"
 		 "===================================\n"
 		 "Description:\n"
 		 "TBD\n");
@@ -1347,10 +1343,10 @@
 	}
 }
 
-const struct file_operations host_sender_no_lp_diag_rpc_ciq_test_ops = {
+const struct file_operations host_sender_no_lp_diag_rpc_test_ops = {
 	.open = sdio_al_test_open,
-	.write = host_sender_no_lp_diag_rpc_ciq_test_write,
-	.read = host_sender_no_lp_diag_rpc_ciq_test_read,
+	.write = host_sender_no_lp_diag_rpc_test_write,
+	.read = host_sender_no_lp_diag_rpc_test_read,
 };
 
 /* RMNET SMALL PACKETS TEST */
@@ -1774,7 +1770,6 @@
 
 		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RMNT]);
 		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DUN]);
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_CIQ]);
 
 		ret = test_start();
 
@@ -1844,7 +1839,6 @@
 		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DIAG]);
 		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RMNT]);
 		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DUN]);
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_CIQ]);
 
 		ret = test_start();
 
@@ -1910,7 +1904,6 @@
 		sdio_al_test_initial_dev_and_chan(test_ctx);
 
 		set_params_loopback_9k_close(ch_arr[SDIO_DIAG]);
-		set_params_loopback_9k_close(ch_arr[SDIO_CIQ]);
 		set_params_loopback_9k_close(ch_arr[SDIO_RPC]);
 		set_params_loopback_9k_close(ch_arr[SDIO_SMEM]);
 		set_params_loopback_9k_close(ch_arr[SDIO_QMI]);
@@ -1924,9 +1917,8 @@
 			break;
 
 		pr_info(TEST_MODULE_NAME " -- correctness test for"
-				"DIAG, CIQ ");
+				"DIAG ");
 		set_params_loopback_9k(ch_arr[SDIO_DIAG]);
-		set_params_loopback_9k(ch_arr[SDIO_CIQ]);
 
 		ret = test_start();
 
@@ -1950,7 +1942,7 @@
 		 "Description:\n"
 		 "In this test the host sends 5k packets to the modem in the "
 		 "following sequence: Send a random burst of packets on "
-		 "Diag, CIQ and Rmnet channels, read 0 or a random number "
+		 "Diag and Rmnet channels, read 0 or a random number "
 		 "of packets, close and re-open the channel. At the end of the "
 		 "test, the channel is verified by running a loopback test\n\n"
 		 "END OF DESCRIPTION\n");
@@ -2373,8 +2365,6 @@
 
 		set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
 				    SDIO_TEST_LPM_RANDOM, 0);
-		set_params_lpm_test(test_ctx->test_ch_arr[SDIO_CIQ],
-				    SDIO_TEST_LPM_RANDOM, 0);
 		set_params_lpm_test(test_ctx->test_ch_arr[SDIO_DIAG],
 				    SDIO_TEST_LPM_RANDOM, 0);
 		set_params_lpm_test(test_ctx->test_ch_arr[SDIO_QMI],
@@ -2403,7 +2393,7 @@
 		 "Description:\n"
 		 "In this test, the HOST and CLIENT "
 		 "send messages to each other,\n"
-		 "random in time, over RPC, QMI, DIAG AND CIQ channels\n"
+		 "random in time, over RPC, QMI AND DIAG channels\n"
 		 "(i.e, on both SDIO devices).\n"
 		 "All events are being recorded, and later on,\n"
 		 "they are being analysed by the HOST and by the CLIENT,\n"
@@ -2545,12 +2535,12 @@
 				    NULL,
 				    &host_sender_no_lp_diag_test_ops);
 
-	test_ctx->debug.host_sender_no_lp_diag_rpc_ciq_test =
-		debugfs_create_file("170_host_sender_no_lp_diag_rpc_ciq_test",
+	test_ctx->debug.host_sender_no_lp_diag_rpc_test =
+		debugfs_create_file("170_host_sender_no_lp_diag_rpc_test",
 				     S_IRUGO | S_IWUGO,
 				     test_ctx->debug.debug_root,
 				     NULL,
-				     &host_sender_no_lp_diag_rpc_ciq_test_ops);
+				     &host_sender_no_lp_diag_rpc_test_ops);
 
 	test_ctx->debug.rmnet_small_packets_test =
 		debugfs_create_file("180_rmnet_small_packets_test",
@@ -2697,9 +2687,6 @@
 	else if (!strncmp(name, "SDIO_SMEM_TEST",
 			  strnlen("SDIO_SMEM_TEST", TEST_CH_NAME_SIZE)))
 		return SDIO_SMEM;
-	else if (!strncmp(name, "SDIO_CIQ_TEST",
-			  strnlen("SDIO_CIQ_TEST", TEST_CH_NAME_SIZE)))
-		return SDIO_CIQ;
 	else if (!strncmp(name, "SDIO_CSVT_TEST",
 			  strnlen("SDIO_CSVT_TEST", TEST_CH_NAME_SIZE)))
 		return SDIO_CSVT;
@@ -5829,7 +5816,6 @@
 	case SDIO_RPC:
 		tch->packet_length = 128; /* max is 2K*/
 		break;
-	case SDIO_CIQ:
 	case SDIO_DIAG:
 	case SDIO_RMNT:
 	default:
@@ -6297,34 +6283,6 @@
 
 }
 
-static int sdio_test_channel_ciq_probe(struct platform_device *pdev)
-{
-	int ret = 0;
-
-	if (!pdev)
-		return -ENODEV;
-
-	test_ctx->ciq_app_pdev = platform_device_alloc("SDIO_CIQ_TEST_APP", -1);
-	ret = platform_device_add(test_ctx->ciq_app_pdev);
-		if (ret) {
-			pr_err(MODULE_NAME ":platform_device_add failed, "
-					   "ret=%d\n", ret);
-			return ret;
-		}
-
-	return sdio_test_channel_probe(pdev);
-}
-
-static int sdio_test_channel_ciq_remove(struct platform_device *pdev)
-{
-	if (!pdev)
-		return -ENODEV;
-
-	platform_device_unregister(test_ctx->ciq_app_pdev);
-
-	return sdio_test_channel_remove(pdev);
-}
-
 static int sdio_test_channel_csvt_probe(struct platform_device *pdev)
 {
 	int ret = 0;
@@ -6408,15 +6366,6 @@
 	},
 };
 
-static struct platform_driver sdio_ciq_drv = {
-	.probe		= sdio_test_channel_ciq_probe,
-	.remove		= sdio_test_channel_ciq_remove,
-	.driver		= {
-		.name	= "SDIO_CIQ_TEST",
-		.owner	= THIS_MODULE,
-	},
-};
-
 static struct platform_driver sdio_csvt_drv = {
 	.probe		= sdio_test_channel_csvt_probe,
 	.remove		= sdio_test_channel_csvt_remove,
@@ -6494,7 +6443,6 @@
 	platform_driver_register(&sdio_smem_drv);
 	platform_driver_register(&sdio_rmnt_drv);
 	platform_driver_register(&sdio_dun_drv);
-	platform_driver_register(&sdio_ciq_drv);
 	platform_driver_register(&sdio_csvt_drv);
 
 	return ret;
@@ -6523,7 +6471,6 @@
 	platform_driver_unregister(&sdio_smem_drv);
 	platform_driver_unregister(&sdio_rmnt_drv);
 	platform_driver_unregister(&sdio_dun_drv);
-	platform_driver_unregister(&sdio_ciq_drv);
 	platform_driver_unregister(&sdio_csvt_drv);
 
 	for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
diff --git a/arch/arm/mach-msm/sdio_tty.c b/arch/arm/mach-msm/sdio_tty.c
index 2aaa41e..41bc270 100644
--- a/arch/arm/mach-msm/sdio_tty.c
+++ b/arch/arm/mach-msm/sdio_tty.c
@@ -30,11 +30,6 @@
 #define MAX_SDIO_TTY_DEV_NAME_SIZE	25
 
 /* Configurations per channel device */
-/* CIQ */
-#define SDIO_TTY_CIQ_DEV		"sdio_tty_ciq_0"
-#define SDIO_TTY_CIQ_TEST_DEV		"sdio_tty_ciq_test_0"
-#define SDIO_TTY_CH_CIQ			"SDIO_CIQ"
-
 /* CSVT */
 #define SDIO_TTY_CSVT_DEV		"sdio_tty_csvt_0"
 #define SDIO_TTY_CSVT_TEST_DEV		"sdio_tty_csvt_test_0"
@@ -48,15 +43,11 @@
 };
 
 enum sdio_tty_devices {
-	SDIO_CIQ,
-	SDIO_CIQ_TEST_APP,
 	SDIO_CSVT,
 	SDIO_CSVT_TEST_APP,
 };
 
 static const struct platform_device_id sdio_tty_id_table[] = {
-	{ "SDIO_CIQ",		SDIO_CIQ },
-	{ "SDIO_CIQ_TEST_APP",	SDIO_CIQ_TEST_APP },
 	{ "SDIO_CSVT",		SDIO_CSVT },
 	{ "SDIO_CSVT_TEST_APP",	SDIO_CSVT_TEST_APP },
 	{ },
@@ -95,8 +86,6 @@
  * Enable sdio_tty debug messages
  * By default the sdio_tty debug messages are turned off
  */
-static int ciq_debug_msg_on;
-module_param(ciq_debug_msg_on, int, 0);
 static int csvt_debug_msg_on;
 module_param(csvt_debug_msg_on, int, 0);
 
@@ -677,16 +666,6 @@
 	pr_debug(SDIO_TTY_MODULE_NAME ": %s for %s", __func__, pdev->name);
 
 	switch (device_id) {
-	case SDIO_CIQ:
-		device_name = SDIO_TTY_CIQ_DEV;
-		channel_name = SDIO_TTY_CH_CIQ;
-		debug_msg_on = ciq_debug_msg_on;
-		break;
-	case SDIO_CIQ_TEST_APP:
-		device_name = SDIO_TTY_CIQ_TEST_DEV;
-		channel_name = SDIO_TTY_CH_CIQ;
-		debug_msg_on = ciq_debug_msg_on;
-		break;
 	case SDIO_CSVT:
 		device_name = SDIO_TTY_CSVT_DEV;
 		channel_name = SDIO_TTY_CH_CSVT;
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index ecfe93c..ce65e93 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -125,14 +125,6 @@
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 {
-	int i;
-
-	/*
-	 * Initialise the present map, which describes the set of CPUs
-	 * actually populated at the present time.
-	 */
-	for (i = 0; i < max_cpus; i++)
-		set_cpu_present(i, true);
 
 	/*
 	 * Initialise the SCU and wake up the secondary core using
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index 963bf0d..4ae943b 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -68,14 +68,6 @@
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 {
-	int i;
-
-	/*
-	 * Initialise the present map, which describes the set of CPUs
-	 * actually populated at the present time.
-	 */
-	for (i = 0; i < max_cpus; i++)
-		set_cpu_present(i, true);
 
 	scu_enable(scu_base_addr());
 
diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c
index f3888fe..66f9806 100644
--- a/arch/arm/mach-shmobile/platsmp.c
+++ b/arch/arm/mach-shmobile/platsmp.c
@@ -64,10 +64,5 @@
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 {
-	int i;
-
-	for (i = 0; i < max_cpus; i++)
-		set_cpu_present(i, true);
-
 	shmobile_smp_prepare_cpus();
 }
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index b8ae3c9..1a594dc 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -129,14 +129,6 @@
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 {
-	int i;
-
-	/*
-	 * Initialise the present map, which describes the set of CPUs
-	 * actually populated at the present time.
-	 */
-	for (i = 0; i < max_cpus; i++)
-		set_cpu_present(i, true);
 
 	scu_enable(scu_base);
 }
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
index 0c527fe..a33df5f 100644
--- a/arch/arm/mach-ux500/platsmp.c
+++ b/arch/arm/mach-ux500/platsmp.c
@@ -172,14 +172,6 @@
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 {
-	int i;
-
-	/*
-	 * Initialise the present map, which describes the set of CPUs
-	 * actually populated at the present time.
-	 */
-	for (i = 0; i < max_cpus; i++)
-		set_cpu_present(i, true);
 
 	scu_enable(scu_base_addr());
 	wakeup_secondary();
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index 765a71f..bfd32f5 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -229,10 +229,6 @@
 
 static void ct_ca9x4_smp_enable(unsigned int max_cpus)
 {
-	int i;
-	for (i = 0; i < max_cpus; i++)
-		set_cpu_present(i, true);
-
 	scu_enable(MMIO_P2V(A9_MPCORE_SCU));
 }
 #endif
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/char/msm_rotator.c b/drivers/char/msm_rotator.c
index 529d9dd..bd48925 100644
--- a/drivers/char/msm_rotator.c
+++ b/drivers/char/msm_rotator.c
@@ -569,11 +569,18 @@
 			      unsigned int in_paddr,
 			      unsigned int out_paddr,
 			      unsigned int use_imem,
-			      int new_session)
+			      int new_session,
+			      unsigned int out_chroma_paddr)
 {
 	int bpp;
+	uint32_t dst_format;
 
-	if (info->src.format != info->dst.format)
+	if (info->src.format == MDP_YCRYCB_H2V1)
+		dst_format = MDP_Y_CRCB_H2V1;
+	else
+		return -EINVAL;
+
+	if (info->dst.format != dst_format)
 		return -EINVAL;
 
 	bpp = get_bpp(info->src.format);
@@ -584,15 +591,25 @@
 	iowrite32(out_paddr +
 			((info->dst_y * info->dst.width) + info->dst_x),
 		  MSM_ROTATOR_OUTP0_ADDR);
+	iowrite32(out_chroma_paddr +
+			((info->dst_y * info->dst.width)/2 + info->dst_x),
+		  MSM_ROTATOR_OUTP1_ADDR);
 
 	if (new_session) {
-		iowrite32(info->src.width,
+		iowrite32(info->src.width * bpp,
 			  MSM_ROTATOR_SRC_YSTRIDE1);
-		iowrite32(info->dst.width,
-			  MSM_ROTATOR_OUT_YSTRIDE1);
+		if (info->rotations & MDP_ROT_90)
+			iowrite32(info->dst.width |
+				  (info->dst.width*2) << 16,
+				  MSM_ROTATOR_OUT_YSTRIDE1);
+		else
+			iowrite32(info->dst.width |
+				  (info->dst.width) << 16,
+				  MSM_ROTATOR_OUT_YSTRIDE1);
+
 		iowrite32(GET_PACK_PATTERN(CLR_Y, CLR_CR, CLR_Y, CLR_CB, 8),
 			  MSM_ROTATOR_SRC_UNPACK_PATTERN1);
-		iowrite32(GET_PACK_PATTERN(CLR_Y, CLR_CR, CLR_Y, CLR_CB, 8),
+		iowrite32(GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8),
 			  MSM_ROTATOR_OUT_PACK_PATTERN1);
 		iowrite32((1  << 18) | 		/* chroma sampling 1=H2V1 */
 			  (ROTATIONS_TO_BITMASK(info->rotations) << 9) |
@@ -1036,7 +1053,8 @@
 	case MDP_YCRYCB_H2V1:
 		rc = msm_rotator_ycrycb(msm_rotator_dev->img_info[s],
 				in_paddr, out_paddr, use_imem,
-				msm_rotator_dev->last_session_idx != s);
+				msm_rotator_dev->last_session_idx != s,
+				out_chroma_paddr);
 		break;
 	default:
 		rc = -EINVAL;
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 4168c88..c44cde8 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -2,3 +2,6 @@
 config CLKDEV_LOOKUP
 	bool
 	select HAVE_CLK
+
+config HAVE_CLK_PREPARE
+	bool
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index d436ef4..386593f5 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -77,7 +77,7 @@
 	struct rb_root handles;
 	struct mutex lock;
 	unsigned int heap_mask;
-	const char *name;
+	char *name;
 	struct task_struct *task;
 	pid_t pid;
 	struct dentry *debug_root;
@@ -365,6 +365,11 @@
 	struct ion_device *dev = client->dev;
 	struct ion_buffer *buffer = NULL;
 	unsigned long secure_allocation = flags & ION_SECURE;
+	const unsigned int MAX_DBG_STR_LEN = 64;
+	char dbg_str[MAX_DBG_STR_LEN];
+	unsigned int dbg_str_idx = 0;
+
+	dbg_str[0] = '\0';
 
 	/*
 	 * traverse the list of heaps available in this system in priority
@@ -387,11 +392,31 @@
 		buffer = ion_buffer_create(heap, dev, len, align, flags);
 		if (!IS_ERR_OR_NULL(buffer))
 			break;
+		if (dbg_str_idx < MAX_DBG_STR_LEN) {
+			unsigned int len_left = MAX_DBG_STR_LEN-dbg_str_idx-1;
+			int ret_value = snprintf(&dbg_str[dbg_str_idx],
+						len_left, "%s ", heap->name);
+			if (ret_value >= len_left) {
+				/* overflow */
+				dbg_str[MAX_DBG_STR_LEN-1] = '\0';
+				dbg_str_idx = MAX_DBG_STR_LEN;
+			} else if (ret_value >= 0) {
+				dbg_str_idx += ret_value;
+			} else {
+				/* error */
+				dbg_str[MAX_DBG_STR_LEN-1] = '\0';
+			}
+		}
 	}
 	mutex_unlock(&dev->lock);
 
-	if (IS_ERR_OR_NULL(buffer))
+	if (IS_ERR_OR_NULL(buffer)) {
+		pr_debug("ION is unable to allocate 0x%x bytes (alignment: "
+			 "0x%x) from heap(s) %sfor client %s with heap "
+			 "mask 0x%x\n",
+			len, align, dbg_str, client->name, client->heap_mask);
 		return ERR_PTR(PTR_ERR(buffer));
+	}
 
 	handle = ion_handle_create(client, buffer);
 
@@ -984,6 +1009,7 @@
 	struct rb_node *parent = NULL;
 	struct ion_client *entry;
 	pid_t pid;
+	unsigned int name_len = strnlen(name, 64);
 
 	get_task_struct(current->group_leader);
 	task_lock(current->group_leader);
@@ -1017,7 +1043,17 @@
 	client->dev = dev;
 	client->handles = RB_ROOT;
 	mutex_init(&client->lock);
-	client->name = name;
+
+	client->name = kzalloc(sizeof(name_len+1), GFP_KERNEL);
+	if (!client->name) {
+		put_task_struct(current->group_leader);
+		kfree(client);
+		return ERR_PTR(-ENOMEM);
+	} else {
+		strncpy(client->name, name, name_len);
+		client->name[name_len] = '\0';
+	}
+
 	client->heap_mask = heap_mask;
 	client->task = task;
 	client->pid = pid;
@@ -1083,6 +1119,7 @@
 	debugfs_remove_recursive(client->debug_root);
 	mutex_unlock(&dev->lock);
 
+	kfree(client->name);
 	kfree(client);
 }
 
@@ -1278,12 +1315,14 @@
 	/* now map it to userspace */
 	ret = buffer->heap->ops->map_user(buffer->heap, buffer, vma,
 						flags);
-	mutex_unlock(&buffer->lock);
+
+	buffer->umap_cnt++;
 	if (ret) {
 		pr_err("%s: failure mapping buffer to userspace\n",
 		       __func__);
 		goto err2;
 	}
+	mutex_unlock(&buffer->lock);
 
 	vma->vm_ops = &ion_vm_ops;
 	/* move the handle into the vm_private_data so we can access it from
@@ -1298,6 +1337,7 @@
 
 err2:
 	buffer->umap_cnt--;
+	mutex_unlock(&buffer->lock);
 	/* drop the reference to the handle */
 err1:
 	ion_handle_put(handle);
@@ -1568,30 +1608,8 @@
 		seq_printf(s, "%16.s %16u %16x\n", client->name, client->pid,
 			   size);
 	}
-	if (heap->ops->get_allocated) {
-		seq_printf(s, "total bytes currently allocated: %lx\n",
-			heap->ops->get_allocated(heap));
-	}
-	if (heap->ops->get_total) {
-		seq_printf(s, "total heap size: %lx\n",
-			heap->ops->get_total(heap));
-	}
-	if (heap->ops->get_alloc_cnt) {
-		seq_printf(s, "allocation count: %lx\n",
-			heap->ops->get_alloc_cnt(heap));
-	}
-	if (heap->ops->get_umap_cnt) {
-		seq_printf(s, "umapping count: %lx\n",
-			heap->ops->get_umap_cnt(heap));
-	}
-	if (heap->ops->get_kmap_cnt) {
-		seq_printf(s, "kmapping count: %lx\n",
-			heap->ops->get_kmap_cnt(heap));
-	}
-	if (heap->ops->get_secured) {
-		seq_printf(s, "secured heap: %s\n",
-			heap->ops->get_secured(heap) ? "Yes" : "No");
-	}
+	if (heap->ops->print_debug)
+		heap->ops->print_debug(heap, s);
 	return 0;
 }
 
diff --git a/drivers/gpu/ion/ion_carveout_heap.c b/drivers/gpu/ion/ion_carveout_heap.c
index 1c35f5c..ad0c7b1 100644
--- a/drivers/gpu/ion/ion_carveout_heap.c
+++ b/drivers/gpu/ion/ion_carveout_heap.c
@@ -25,6 +25,7 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/iommu.h>
+#include <linux/seq_file.h>
 #include "ion_priv.h"
 
 #include <mach/iommu_domains.h>
@@ -131,28 +132,55 @@
 		vfree(buffer->sglist);
 }
 
+static int ion_carveout_request_region(struct ion_carveout_heap *carveout_heap)
+{
+	int ret_value = 0;
+	if (atomic_inc_return(&carveout_heap->map_count) == 1) {
+		if (carveout_heap->request_region) {
+			ret_value = carveout_heap->request_region(
+						carveout_heap->bus_id);
+			if (ret_value) {
+				pr_err("Unable to request SMI region");
+				atomic_dec(&carveout_heap->map_count);
+			}
+		}
+	}
+	return ret_value;
+}
+
+static int ion_carveout_release_region(struct ion_carveout_heap *carveout_heap)
+{
+	int ret_value = 0;
+	if (atomic_dec_and_test(&carveout_heap->map_count)) {
+		if (carveout_heap->release_region) {
+			ret_value = carveout_heap->release_region(
+						carveout_heap->bus_id);
+			if (ret_value)
+				pr_err("Unable to release SMI region");
+		}
+	}
+	return ret_value;
+}
+
 void *ion_carveout_heap_map_kernel(struct ion_heap *heap,
 				   struct ion_buffer *buffer,
 				   unsigned long flags)
 {
 	struct ion_carveout_heap *carveout_heap =
 		container_of(heap, struct ion_carveout_heap, heap);
+	void *ret_value;
 
-	if (atomic_inc_return(&carveout_heap->map_count) == 1) {
-		if (carveout_heap->request_region) {
-			int ret = carveout_heap->request_region(
-						carveout_heap->bus_id);
-			if (ret) {
-				pr_err("Unable to request SMI region");
-				atomic_dec(&carveout_heap->map_count);
-				return NULL;
-			}
-		}
-	}
+	if (ion_carveout_request_region(carveout_heap))
+		return NULL;
+
 	if (ION_IS_CACHED(flags))
-		return ioremap_cached(buffer->priv_phys, buffer->size);
+		ret_value = ioremap_cached(buffer->priv_phys, buffer->size);
 	else
-		return ioremap(buffer->priv_phys, buffer->size);
+		ret_value = ioremap(buffer->priv_phys, buffer->size);
+
+	if (!ret_value)
+		ion_carveout_release_region(carveout_heap);
+	return ret_value;
 }
 
 void ion_carveout_heap_unmap_kernel(struct ion_heap *heap,
@@ -164,15 +192,7 @@
 	__arch_iounmap(buffer->vaddr);
 	buffer->vaddr = NULL;
 
-	if (atomic_dec_and_test(&carveout_heap->map_count)) {
-		if (carveout_heap->release_region) {
-			int ret = carveout_heap->release_region(
-						carveout_heap->bus_id);
-			if (ret)
-				pr_err("Unable to release SMI region");
-		}
-	}
-
+	ion_carveout_release_region(carveout_heap);
 	return;
 }
 
@@ -181,29 +201,25 @@
 {
 	struct ion_carveout_heap *carveout_heap =
 		container_of(heap, struct ion_carveout_heap, heap);
+	int ret_value = 0;
 
-	if (atomic_inc_return(&carveout_heap->map_count) == 1) {
-		if (carveout_heap->request_region) {
-			int ret = carveout_heap->request_region(
-						carveout_heap->bus_id);
-			if (ret) {
-				pr_err("Unable to request SMI region");
-				atomic_dec(&carveout_heap->map_count);
-				return -EINVAL;
-			}
-		}
-	}
+	if (ion_carveout_request_region(carveout_heap))
+		return -EINVAL;
 
 	if (ION_IS_CACHED(flags))
-		return remap_pfn_range(vma, vma->vm_start,
+		ret_value = remap_pfn_range(vma, vma->vm_start,
 			       __phys_to_pfn(buffer->priv_phys) + vma->vm_pgoff,
 			       vma->vm_end - vma->vm_start,
 			       vma->vm_page_prot);
 	else
-		return remap_pfn_range(vma, vma->vm_start,
+		ret_value = remap_pfn_range(vma, vma->vm_start,
 			       __phys_to_pfn(buffer->priv_phys) + vma->vm_pgoff,
 					vma->vm_end - vma->vm_start,
 					pgprot_noncached(vma->vm_page_prot));
+
+	if (ret_value)
+		ion_carveout_release_region(carveout_heap);
+	return ret_value;
 }
 
 void ion_carveout_heap_unmap_user(struct ion_heap *heap,
@@ -211,15 +227,7 @@
 {
 	struct ion_carveout_heap *carveout_heap =
 		container_of(heap, struct ion_carveout_heap, heap);
-
-	if (atomic_dec_and_test(&carveout_heap->map_count)) {
-		if (carveout_heap->release_region) {
-			int ret = carveout_heap->release_region(
-						carveout_heap->bus_id);
-			if (ret)
-				pr_err("Unable to release SMI region");
-		}
-	}
+	ion_carveout_release_region(carveout_heap);
 }
 
 int ion_carveout_cache_ops(struct ion_heap *heap, struct ion_buffer *buffer,
@@ -248,20 +256,16 @@
 	return 0;
 }
 
-static unsigned long ion_carveout_get_allocated(struct ion_heap *heap)
+static int ion_carveout_print_debug(struct ion_heap *heap, struct seq_file *s)
 {
 	struct ion_carveout_heap *carveout_heap =
 		container_of(heap, struct ion_carveout_heap, heap);
 
-	return carveout_heap->allocated_bytes;
-}
+	seq_printf(s, "total bytes currently allocated: %lx\n",
+		carveout_heap->allocated_bytes);
+	seq_printf(s, "total heap size: %lx\n", carveout_heap->total_size);
 
-static unsigned long ion_carveout_get_total(struct ion_heap *heap)
-{
-	struct ion_carveout_heap *carveout_heap =
-		container_of(heap, struct ion_carveout_heap, heap);
-
-	return carveout_heap->total_size;
+	return 0;
 }
 
 int ion_carveout_heap_map_iommu(struct ion_buffer *buffer,
@@ -377,8 +381,7 @@
 	.map_dma = ion_carveout_heap_map_dma,
 	.unmap_dma = ion_carveout_heap_unmap_dma,
 	.cache_op = ion_carveout_cache_ops,
-	.get_allocated = ion_carveout_get_allocated,
-	.get_total = ion_carveout_get_total,
+	.print_debug = ion_carveout_print_debug,
 	.map_iommu = ion_carveout_heap_map_iommu,
 	.unmap_iommu = ion_carveout_heap_unmap_iommu,
 };
diff --git a/drivers/gpu/ion/ion_cp_heap.c b/drivers/gpu/ion/ion_cp_heap.c
index 5737d21..16ace6f 100644
--- a/drivers/gpu/ion/ion_cp_heap.c
+++ b/drivers/gpu/ion/ion_cp_heap.c
@@ -25,6 +25,7 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/memory_alloc.h>
+#include <linux/seq_file.h>
 #include <mach/msm_memtypes.h>
 #include <mach/scm.h>
 #include "ion_priv.h"
@@ -39,6 +40,8 @@
  * @base:	the base address of the memory pool.
  * @permission_type:	Identifier for the memory used by SCM for protecting
  *			and unprotecting memory.
+ * @secure_base:	Base address used when securing a heap that is shared.
+ * @secure_size:	Size used when securing a heap that is shared.
  * @lock:	mutex to protect shared access.
  * @heap_secured:	Identifies the heap_id as secure or not.
  * @allocated_bytes:	the total number of allocated bytes from the pool.
@@ -59,6 +62,8 @@
 	struct gen_pool *pool;
 	ion_phys_addr_t base;
 	unsigned int permission_type;
+	ion_phys_addr_t secure_base;
+	size_t secure_size;
 	struct mutex lock;
 	unsigned int heap_secured;
 	unsigned long allocated_bytes;
@@ -94,14 +99,14 @@
 	int ret_value = 0;
 
 	if (cp_heap->heap_secured == NON_SECURED_HEAP) {
-		int ret_value = ion_cp_protect_mem(cp_heap->base,
-				cp_heap->total_size, cp_heap->permission_type);
+		int ret_value = ion_cp_protect_mem(cp_heap->secure_base,
+				cp_heap->secure_size, cp_heap->permission_type);
 		if (ret_value) {
 			pr_err("Failed to protect memory for heap %s - "
-				"error code: %d", heap->name, ret_value);
+				"error code: %d\n", heap->name, ret_value);
 		} else {
 			cp_heap->heap_secured = SECURED_HEAP;
-			pr_debug("Protected heap %s @ 0x%x",
+			pr_debug("Protected heap %s @ 0x%x\n",
 				heap->name, (unsigned int) cp_heap->base);
 		}
 	}
@@ -119,14 +124,14 @@
 
 	if (cp_heap->heap_secured == SECURED_HEAP) {
 		int error_code = ion_cp_unprotect_mem(
-			cp_heap->base, cp_heap->total_size,
+			cp_heap->secure_base, cp_heap->secure_size,
 			cp_heap->permission_type);
 		if (error_code) {
 			pr_err("Failed to un-protect memory for heap %s - "
-				"error code: %d", heap->name, error_code);
+				"error code: %d\n", heap->name, error_code);
 		} else  {
 			cp_heap->heap_secured = NON_SECURED_HEAP;
-			pr_debug("Un-protected heap %s @ 0x%x", heap->name,
+			pr_debug("Un-protected heap %s @ 0x%x\n", heap->name,
 				(unsigned int) cp_heap->base);
 		}
 	}
@@ -148,14 +153,14 @@
 	if (!secure_allocation && cp_heap->heap_secured == SECURED_HEAP) {
 		mutex_unlock(&cp_heap->lock);
 		pr_err("ION cannot allocate un-secure memory from protected"
-			" heap %s", heap->name);
+			" heap %s\n", heap->name);
 		return ION_CP_ALLOCATE_FAIL;
 	}
 
 	if (secure_allocation && cp_heap->umap_count > 0) {
 		mutex_unlock(&cp_heap->lock);
 		pr_err("ION cannot allocate secure memory from heap with "
-			"outstanding user space mappings for heap %s",
+			"outstanding user space mappings for heap %s\n",
 			heap->name);
 		return ION_CP_ALLOCATE_FAIL;
 	}
@@ -178,7 +183,7 @@
 		      cp_heap->allocated_bytes) > size)
 			pr_debug("%s: heap %s has enough memory (%lx) but"
 				" the allocation of size %lx still failed."
-				" Memory is probably fragmented.",
+				" Memory is probably fragmented.\n",
 				__func__, heap->name,
 				cp_heap->total_size -
 				cp_heap->allocated_bytes, size);
@@ -328,7 +333,7 @@
 	mutex_lock(&cp_heap->lock);
 
 	if (cp_heap->heap_secured == SECURED_HEAP && ION_IS_CACHED(flags)) {
-		pr_err("Unable to map secured heap %s as cached", heap->name);
+		pr_err("Unable to map secured heap %s as cached\n", heap->name);
 		mutex_unlock(&cp_heap->lock);
 		return NULL;
 	}
@@ -450,77 +455,34 @@
 	return 0;
 }
 
-static unsigned long ion_cp_get_allocated(struct ion_heap *heap)
+static int ion_cp_print_debug(struct ion_heap *heap, struct seq_file *s)
 {
-	struct ion_cp_heap *cp_heap =
-		container_of(heap, struct ion_cp_heap, heap);
-	unsigned long allocated_bytes;
-
-	mutex_lock(&cp_heap->lock);
-	allocated_bytes = cp_heap->allocated_bytes;
-	mutex_unlock(&cp_heap->lock);
-
-	return allocated_bytes;
-}
-
-static unsigned long ion_cp_get_total(struct ion_heap *heap)
-{
-	struct ion_cp_heap *cp_heap =
-		container_of(heap, struct ion_cp_heap, heap);
-
-	return cp_heap->total_size;
-}
-
-static unsigned long ion_cp_get_umap_count(struct ion_heap *heap)
-{
-	struct ion_cp_heap *cp_heap =
-		container_of(heap, struct ion_cp_heap, heap);
-	unsigned long umap_count;
-
-	mutex_lock(&cp_heap->lock);
-	umap_count = cp_heap->umap_count;
-	mutex_unlock(&cp_heap->lock);
-
-	return umap_count;
-}
-
-static unsigned long ion_cp_get_kmap_count(struct ion_heap *heap)
-{
-	struct ion_cp_heap *cp_heap =
-		container_of(heap, struct ion_cp_heap, heap);
-	unsigned long kmap_count;
-
-	mutex_lock(&cp_heap->lock);
-	kmap_count = cp_heap->kmap_count;
-	mutex_unlock(&cp_heap->lock);
-
-	return kmap_count;
-}
-
-static unsigned long ion_cp_get_alloc_count(struct ion_heap *heap)
-{
-	struct ion_cp_heap *cp_heap =
-		container_of(heap, struct ion_cp_heap, heap);
+	unsigned long total_alloc;
+	unsigned long total_size;
 	unsigned long alloc_count;
-
-	mutex_lock(&cp_heap->lock);
-	alloc_count = cp_heap->alloc_count;
-	mutex_unlock(&cp_heap->lock);
-
-	return alloc_count;
-}
-
-static unsigned long ion_cp_get_secured(struct ion_heap *heap)
-{
+	unsigned long umap_count;
+	unsigned long kmap_count;
+	unsigned long heap_secured;
 	struct ion_cp_heap *cp_heap =
 		container_of(heap, struct ion_cp_heap, heap);
-	unsigned long secured_heap = 0;
 
 	mutex_lock(&cp_heap->lock);
-	secured_heap = cp_heap->heap_secured == SECURED_HEAP;
+	total_alloc = cp_heap->allocated_bytes;
+	total_size = cp_heap->total_size;
+	alloc_count = cp_heap->alloc_count;
+	umap_count = cp_heap->umap_count;
+	kmap_count = cp_heap->kmap_count;
+	heap_secured = cp_heap->heap_secured == SECURED_HEAP;
 	mutex_unlock(&cp_heap->lock);
 
-	return secured_heap;
+	seq_printf(s, "total bytes currently allocated: %lx\n", total_alloc);
+	seq_printf(s, "total heap size: %lx\n", total_size);
+	seq_printf(s, "allocation count: %lx\n", alloc_count);
+	seq_printf(s, "umapping count: %lx\n", umap_count);
+	seq_printf(s, "kmapping count: %lx\n", kmap_count);
+	seq_printf(s, "secured heap: %s\n", heap_secured ? "Yes" : "No");
+
+	return 0;
 }
 
 int ion_cp_secure_heap(struct ion_heap *heap)
@@ -557,32 +519,11 @@
 	.map_dma = ion_cp_heap_map_dma,
 	.unmap_dma = ion_cp_heap_unmap_dma,
 	.cache_op = ion_cp_cache_ops,
-	.get_allocated = ion_cp_get_allocated,
-	.get_total = ion_cp_get_total,
-	.get_umap_cnt = ion_cp_get_umap_count,
-	.get_kmap_cnt = ion_cp_get_kmap_count,
-	.get_alloc_cnt = ion_cp_get_alloc_count,
-	.get_secured = ion_cp_get_secured,
+	.print_debug = ion_cp_print_debug,
 	.secure_heap = ion_cp_secure_heap,
 	.unsecure_heap = ion_cp_unsecure_heap,
 };
 
-static unsigned long ion_cp_get_base(unsigned long size, int memory_type)
-{
-	switch (memory_type) {
-	case ION_EBI_TYPE:
-		return allocate_contiguous_ebi_nomap(size, PAGE_SIZE);
-		break;
-	case ION_SMI_TYPE:
-		return allocate_contiguous_memory_nomap(size, MEMTYPE_SMI,
-							PAGE_SIZE);
-		break;
-	default:
-		return 0;
-	}
-}
-
-
 struct ion_heap *ion_cp_heap_create(struct ion_platform_heap *heap_data)
 {
 	struct ion_cp_heap *cp_heap;
@@ -592,15 +533,6 @@
 	if (!cp_heap)
 		return ERR_PTR(-ENOMEM);
 
-	heap_data->base = ion_cp_get_base(heap_data->size,
-					heap_data->memory_type);
-	if (!heap_data->base) {
-		pr_err("%s: could not get memory for heap %s"
-			" (id %x)\n", __func__, heap_data->name,
-			heap_data->id);
-		goto free_heap;
-	}
-
 	mutex_init(&cp_heap->lock);
 
 	cp_heap->pool = gen_pool_create(12, -1);
@@ -620,10 +552,16 @@
 	cp_heap->heap.ops = &cp_heap_ops;
 	cp_heap->heap.type = ION_HEAP_TYPE_CP;
 	cp_heap->heap_secured = NON_SECURED_HEAP;
+	cp_heap->secure_base = cp_heap->base;
+	cp_heap->secure_size = heap_data->size;
 	if (heap_data->extra_data) {
 		struct ion_cp_heap_pdata *extra_data =
 				heap_data->extra_data;
 		cp_heap->permission_type = extra_data->permission_type;
+		if (extra_data->secure_size) {
+			cp_heap->secure_base = extra_data->secure_base;
+			cp_heap->secure_size = extra_data->secure_size;
+		}
 		if (extra_data->setup_region)
 			cp_heap->bus_id = extra_data->setup_region();
 		if (extra_data->request_region)
@@ -664,7 +602,7 @@
 	unsigned int end;
 	unsigned int permission_type;
 	unsigned char lock;
-};
+} __attribute__ ((__packed__));
 
 
 static int ion_cp_protect_mem(unsigned int phy_base, unsigned int size,
diff --git a/drivers/gpu/ion/ion_priv.h b/drivers/gpu/ion/ion_priv.h
index 98709b6..78dfe6e 100644
--- a/drivers/gpu/ion/ion_priv.h
+++ b/drivers/gpu/ion/ion_priv.h
@@ -139,8 +139,6 @@
 	int (*cache_op)(struct ion_heap *heap, struct ion_buffer *buffer,
 			void *vaddr, unsigned int offset,
 			unsigned int length, unsigned int cmd);
-	unsigned long (*get_allocated)(struct ion_heap *heap);
-	unsigned long (*get_total)(struct ion_heap *heap);
 	int (*map_iommu)(struct ion_buffer *buffer,
 				struct ion_iommu_map *map_data,
 				unsigned int domain_num,
@@ -149,10 +147,7 @@
 				unsigned long iova_length,
 				unsigned long flags);
 	void (*unmap_iommu)(struct ion_iommu_map *data);
-	unsigned long (*get_umap_cnt)(struct ion_heap *heap);
-	unsigned long (*get_kmap_cnt)(struct ion_heap *heap);
-	unsigned long (*get_alloc_cnt)(struct ion_heap *heap);
-	unsigned long (*get_secured)(struct ion_heap *heap);
+	int (*print_debug)(struct ion_heap *heap, struct seq_file *s);
 	int (*secure_heap)(struct ion_heap *heap);
 	int (*unsecure_heap)(struct ion_heap *heap);
 };
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
index 5957658..316740e 100644
--- a/drivers/gpu/ion/ion_system_heap.c
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -2,7 +2,7 @@
  * drivers/gpu/ion/ion_system_heap.c
  *
  * Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/iommu.h>
+#include <linux/seq_file.h>
 #include <mach/iommu_domains.h>
 #include "ion_priv.h"
 #include <mach/memory.h>
@@ -189,9 +190,12 @@
 	return 0;
 }
 
-static unsigned long ion_system_heap_get_allocated(struct ion_heap *heap)
+static int ion_system_print_debug(struct ion_heap *heap, struct seq_file *s)
 {
-	return atomic_read(&system_heap_allocated);
+	seq_printf(s, "total bytes currently allocated: %lx\n",
+			(unsigned long) atomic_read(&system_heap_allocated));
+
+	return 0;
 }
 
 int ion_system_heap_map_iommu(struct ion_buffer *buffer,
@@ -274,7 +278,7 @@
 	.unmap_kernel = ion_system_heap_unmap_kernel,
 	.map_user = ion_system_heap_map_user,
 	.cache_op = ion_system_heap_cache_ops,
-	.get_allocated = ion_system_heap_get_allocated,
+	.print_debug = ion_system_print_debug,
 	.map_iommu = ion_system_heap_map_iommu,
 	.unmap_iommu = ion_system_heap_unmap_iommu,
 };
@@ -387,9 +391,13 @@
 	return 0;
 }
 
-static unsigned long ion_system_contig_heap_get_allocated(struct ion_heap *heap)
+static int ion_system_contig_print_debug(struct ion_heap *heap,
+					 struct seq_file *s)
 {
-	return atomic_read(&system_contig_heap_allocated);
+	seq_printf(s, "total bytes currently allocated: %lx\n",
+		(unsigned long) atomic_read(&system_contig_heap_allocated));
+
+	return 0;
 }
 
 int ion_system_contig_heap_map_iommu(struct ion_buffer *buffer,
@@ -470,7 +478,7 @@
 	.unmap_kernel = ion_system_heap_unmap_kernel,
 	.map_user = ion_system_contig_heap_map_user,
 	.cache_op = ion_system_contig_heap_cache_ops,
-	.get_allocated = ion_system_contig_heap_get_allocated,
+	.print_debug = ion_system_contig_print_debug,
 	.map_iommu = ion_system_contig_heap_map_iommu,
 	.unmap_iommu = ion_system_heap_unmap_iommu,
 };
diff --git a/drivers/gpu/ion/msm/msm_ion.c b/drivers/gpu/ion/msm/msm_ion.c
index 3df2b53..f71f514 100644
--- a/drivers/gpu/ion/msm/msm_ion.c
+++ b/drivers/gpu/ion/msm/msm_ion.c
@@ -42,21 +42,119 @@
 }
 EXPORT_SYMBOL(msm_ion_unsecure_heap);
 
-static unsigned long msm_ion_get_base(unsigned long size, int memory_type)
+static unsigned long msm_ion_get_base(unsigned long size, int memory_type,
+				    unsigned int align)
 {
 	switch (memory_type) {
 	case ION_EBI_TYPE:
-		return allocate_contiguous_ebi_nomap(size, PAGE_SIZE);
+		return allocate_contiguous_ebi_nomap(size, align);
 		break;
 	case ION_SMI_TYPE:
 		return allocate_contiguous_memory_nomap(size, MEMTYPE_SMI,
-							PAGE_SIZE);
+							align);
 		break;
 	default:
+		pr_err("%s: Unknown memory type %d\n", __func__, memory_type);
 		return 0;
 	}
 }
 
+static struct ion_platform_heap *find_heap(const struct ion_platform_heap
+					   heap_data[],
+					   unsigned int nr_heaps,
+					   int heap_id)
+{
+	unsigned int i;
+	for (i = 0; i < nr_heaps; ++i) {
+		const struct ion_platform_heap *heap = &heap_data[i];
+		if (heap->id == heap_id)
+			return (struct ion_platform_heap *) heap;
+	}
+	return 0;
+}
+
+static void allocate_co_memory(struct ion_platform_heap *heap,
+			       struct ion_platform_heap heap_data[],
+			       unsigned int nr_heaps)
+{
+	struct ion_co_heap_pdata *co_heap_data =
+		(struct ion_co_heap_pdata *) heap->extra_data;
+	if (co_heap_data->adjacent_mem_id != INVALID_HEAP_ID) {
+		struct ion_platform_heap *shared_heap =
+			find_heap(heap_data, nr_heaps,
+				  co_heap_data->adjacent_mem_id);
+		if (shared_heap) {
+			struct ion_cp_heap_pdata *cp_data =
+			   (struct ion_cp_heap_pdata *) shared_heap->extra_data;
+			heap->base = msm_ion_get_base(
+				heap->size + shared_heap->size,
+				shared_heap->memory_type,
+				co_heap_data->align);
+			if (heap->base) {
+				shared_heap->base = heap->base + heap->size;
+				cp_data->secure_base = heap->base;
+				cp_data->secure_size =
+						heap->size + shared_heap->size;
+			} else {
+				pr_err("%s: could not get memory for heap %s "
+				   "(id %x)\n", __func__, heap->name, heap->id);
+			}
+
+		}
+	}
+}
+
+/* Fixup heaps in board file to support two heaps being adjacent to each other.
+ * A flag (adjacent_mem_id) in the platform data tells us that the heap phy
+ * memory location must be adjacent to the specified heap. We do this by
+ * carving out memory for both heaps and then splitting up the memory to the
+ * two heaps. The heap specifying the "adjacent_mem_id" get the base of the
+ * memory while heap specified in "adjacent_mem_id" get base+size as its
+ * base address.
+ * Note: Modifies platform data and allocates memory.
+ */
+static void msm_ion_heap_fixup(struct ion_platform_heap heap_data[],
+			       unsigned int nr_heaps)
+{
+	unsigned int i;
+
+	for (i = 0; i < nr_heaps; i++) {
+		struct ion_platform_heap *heap = &heap_data[i];
+		if (!heap->base && heap->type == ION_HEAP_TYPE_CARVEOUT) {
+			if (heap->extra_data)
+				allocate_co_memory(heap, heap_data, nr_heaps);
+		}
+	}
+}
+
+static void msm_ion_allocate(struct ion_platform_heap *heap)
+{
+
+	if (!heap->base && heap->extra_data) {
+		unsigned int align = 0;
+		switch (heap->type) {
+		case ION_HEAP_TYPE_CARVEOUT:
+			align =
+			((struct ion_co_heap_pdata *) heap->extra_data)->align;
+			break;
+		case ION_HEAP_TYPE_CP:
+			align =
+			((struct ion_cp_heap_pdata *) heap->extra_data)->align;
+			break;
+		default:
+			break;
+		}
+		if (align) {
+			heap->base = msm_ion_get_base(heap->size,
+						      heap->memory_type,
+						      align);
+			if (!heap->base)
+				pr_err("%s: could not get memory for heap %s "
+				   "(id %x)\n", __func__, heap->name, heap->id);
+		}
+	}
+}
+
 static int msm_ion_probe(struct platform_device *pdev)
 {
 	struct ion_platform_data *pdata = pdev->dev.platform_data;
@@ -78,28 +176,26 @@
 		goto freeheaps;
 	}
 
+	msm_ion_heap_fixup(pdata->heaps, num_heaps);
+
 	/* create the heaps as specified in the board file */
 	for (i = 0; i < num_heaps; i++) {
 		struct ion_platform_heap *heap_data = &pdata->heaps[i];
-
-		if (heap_data->type == ION_HEAP_TYPE_CARVEOUT) {
-			heap_data->base = msm_ion_get_base(heap_data->size,
-							heap_data->memory_type);
-			if (!heap_data->base) {
-				pr_err("%s: could not get memory for heap %s"
-					" (id %x)\n", __func__, heap_data->name,
-					heap_data->id);
-				continue;
-			}
-		}
+		msm_ion_allocate(heap_data);
 
 		heaps[i] = ion_heap_create(heap_data);
 		if (IS_ERR_OR_NULL(heaps[i])) {
-			pr_err("%s: could not create ion heap %s"
-				" (id %x)\n", __func__, heap_data->name,
-				heap_data->id);
 			heaps[i] = 0;
 			continue;
+		} else {
+			if (heap_data->size)
+				pr_info("ION heap %s created at %lx "
+					"with size %x\n", heap_data->name,
+							  heap_data->base,
+							  heap_data->size);
+			else
+				pr_info("ION heap %s created\n",
+							  heap_data->name);
 		}
 
 		ion_device_add_heap(idev, heaps[i]);
diff --git a/drivers/gpu/msm/Makefile b/drivers/gpu/msm/Makefile
index 39a7b04..908b63d 100644
--- a/drivers/gpu/msm/Makefile
+++ b/drivers/gpu/msm/Makefile
@@ -14,7 +14,7 @@
 msm_kgsl_core-$(CONFIG_MSM_KGSL_CFF_DUMP) += kgsl_cffdump.o
 msm_kgsl_core-$(CONFIG_MSM_KGSL_DRM) += kgsl_drm.o
 msm_kgsl_core-$(CONFIG_MSM_SCM) += kgsl_pwrscale_trustzone.o
-msm_kgsl_core-$(CONFIG_MSM_SLEEP_STATS) += kgsl_pwrscale_idlestats.o
+msm_kgsl_core-$(CONFIG_MSM_SLEEP_STATS_DEVICE) += kgsl_pwrscale_idlestats.o
 
 msm_adreno-y += \
 	adreno_ringbuffer.o \
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index c29da39..6ab9534 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -631,9 +631,33 @@
 void kgsl_pre_hwaccess(struct kgsl_device *device)
 {
 	BUG_ON(!mutex_is_locked(&device->mutex));
-	if (device->state & (KGSL_STATE_SLEEP | KGSL_STATE_NAP |
-				KGSL_STATE_SLUMBER))
+	switch (device->state) {
+	case KGSL_STATE_ACTIVE:
+		return;
+	case KGSL_STATE_NAP:
+	case KGSL_STATE_SLEEP:
+	case KGSL_STATE_SLUMBER:
 		kgsl_pwrctrl_wake(device);
+		break;
+	case KGSL_STATE_SUSPEND:
+		kgsl_check_suspended(device);
+		break;
+	case KGSL_STATE_INIT:
+	case KGSL_STATE_HUNG:
+	case KGSL_STATE_DUMP_AND_RECOVER:
+		if (test_bit(KGSL_PWRFLAGS_CLK_ON,
+					 &device->pwrctrl.power_flags))
+			break;
+		else
+			KGSL_PWR_ERR(device,
+					"hw access while clocks off from state %d\n",
+					device->state);
+		break;
+	default:
+		KGSL_PWR_ERR(device, "hw access while in unknown state %d\n",
+					 device->state);
+		break;
+	}
 }
 EXPORT_SYMBOL(kgsl_pre_hwaccess);
 
diff --git a/drivers/gpu/msm/kgsl_pwrscale.c b/drivers/gpu/msm/kgsl_pwrscale.c
index 55e5383..4c9a239 100644
--- a/drivers/gpu/msm/kgsl_pwrscale.c
+++ b/drivers/gpu/msm/kgsl_pwrscale.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
@@ -42,7 +42,7 @@
 #ifdef CONFIG_MSM_SCM
 	&kgsl_pwrscale_policy_tz,
 #endif
-#ifdef CONFIG_MSM_SLEEP_STATS
+#ifdef CONFIG_MSM_SLEEP_STATS_DEVICE
 	&kgsl_pwrscale_policy_idlestats,
 #endif
 	NULL
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 3c98a75..2453b6b 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -306,6 +306,12 @@
 	u8 t7_data[T7_DATA_SIZE];
 	u16 t7_start_addr;
 	u8 t9_ctrl;
+	u32 keyarray_old;
+	u32 keyarray_new;
+	u8 t9_max_reportid;
+	u8 t9_min_reportid;
+	u8 t15_max_reportid;
+	u8 t15_min_reportid;
 };
 
 static bool mxt_object_readable(unsigned int type)
@@ -670,16 +676,48 @@
 	mxt_input_report(data, id);
 }
 
+static void mxt_handle_key_array(struct mxt_data *data,
+				struct mxt_message *message)
+{
+	u32 keys_changed;
+	int i;
+
+	if (!data->pdata->key_codes) {
+		dev_err(&data->client->dev, "keyarray is not supported\n");
+		return;
+	}
+
+	data->keyarray_new = message->message[1] |
+				(message->message[2] << 8) |
+				(message->message[3] << 16) |
+				(message->message[4] << 24);
+
+	keys_changed = data->keyarray_old ^ data->keyarray_new;
+
+	if (!keys_changed) {
+		dev_dbg(&data->client->dev, "no keys changed\n");
+		return;
+	}
+
+	for (i = 0; i < MXT_KEYARRAY_MAX_KEYS; i++) {
+		if (!(keys_changed & (1 << i)))
+			continue;
+
+		input_report_key(data->input_dev, data->pdata->key_codes[i],
+					(data->keyarray_new & (1 << i)));
+		input_sync(data->input_dev);
+	}
+
+	data->keyarray_old = data->keyarray_new;
+}
+
 static irqreturn_t mxt_interrupt(int irq, void *dev_id)
 {
 	struct mxt_data *data = dev_id;
 	struct mxt_message message;
-	struct mxt_object *object;
 	struct device *dev = &data->client->dev;
 	int id;
 	u8 reportid;
-	u8 max_reportid;
-	u8 min_reportid;
 
 	do {
 		if (mxt_read_message(data, &message)) {
@@ -688,16 +726,20 @@
 		}
 		reportid = message.reportid;
 
-		/* whether reportid is thing of MXT_TOUCH_MULTI_T9 */
-		object = mxt_get_object(data, MXT_TOUCH_MULTI_T9);
-		if (!object)
-			goto end;
-		max_reportid = object->max_reportid;
-		min_reportid = max_reportid - object->num_report_ids + 1;
-		id = reportid - min_reportid;
+		if (!reportid) {
+			dev_dbg(dev, "Report id 0 is reserved\n");
+			continue;
+		}
 
-		if (reportid >= min_reportid && reportid <= max_reportid)
+		/* check whether report id is part of T9 or T15 */
+		id = reportid - data->t9_min_reportid;
+
+		if (reportid >= data->t9_min_reportid &&
+					reportid <= data->t9_max_reportid)
 			mxt_input_touchevent(data, &message, id);
+		else if (reportid >= data->t15_min_reportid &&
+					reportid <= data->t15_max_reportid)
+			mxt_handle_key_array(data, &message);
 		else
 			mxt_dump_message(dev, &message);
 	} while (reportid != 0xff);
@@ -857,6 +899,8 @@
 	u8 val;
 	u8 command_register;
 	struct mxt_object *t7_object;
+	struct mxt_object *t9_object;
+	struct mxt_object *t15_object;
 
 	error = mxt_get_info(data);
 	if (error)
@@ -903,6 +947,28 @@
 		goto free_object_table;
 	}
 
+	/* Store T9, T15's min and max report ids */
+	t9_object = mxt_get_object(data, MXT_TOUCH_MULTI_T9);
+	if (!t9_object) {
+		dev_err(&client->dev, "Failed to get T9 object\n");
+		error = -EINVAL;
+		goto free_object_table;
+	}
+	data->t9_max_reportid = t9_object->max_reportid;
+	data->t9_min_reportid = t9_object->max_reportid -
+					t9_object->num_report_ids + 1;
+
+	if (data->pdata->key_codes) {
+		t15_object = mxt_get_object(data, MXT_TOUCH_KEYARRAY_T15);
+		if (!t15_object)
+			dev_dbg(&client->dev, "T15 object is not available\n");
+		else {
+			data->t15_max_reportid = t15_object->max_reportid;
+			data->t15_min_reportid = t15_object->max_reportid -
+						t15_object->num_report_ids + 1;
+		}
+	}
+
 	/* Backup to memory */
 	mxt_write_object(data, MXT_GEN_COMMAND_T6,
 			MXT_COMMAND_BACKUPNV,
@@ -1562,7 +1628,7 @@
 	const struct mxt_platform_data *pdata = client->dev.platform_data;
 	struct mxt_data *data;
 	struct input_dev *input_dev;
-	int error;
+	int error, i;
 
 	if (!pdata)
 		return -EINVAL;
@@ -1608,6 +1674,15 @@
 	input_set_abs_params(input_dev, ABS_MT_PRESSURE,
 			     0, 255, 0, 0);
 
+	/* set key array supported keys */
+	if (pdata->key_codes) {
+		for (i = 0; i < MXT_KEYARRAY_MAX_KEYS; i++) {
+			if (pdata->key_codes[i])
+				input_set_capability(input_dev, EV_KEY,
+							pdata->key_codes[i]);
+		}
+	}
+
 	input_set_drvdata(input_dev, data);
 	i2c_set_clientdata(client, data);
 
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index 835f8c4..ff0e00d 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -97,6 +97,7 @@
 	struct hci_fm_riva_poke   riva_data_req;
 	struct hci_fm_ssbi_req    ssbi_data_accs;
 	struct hci_fm_ssbi_peek   ssbi_peek_reg;
+	struct hci_fm_sig_threshold_rsp sig_th;
 };
 
 static struct video_device *priv_videodev;
@@ -1587,13 +1588,11 @@
 {
 	struct hci_fm_sig_threshold_rsp  *rsp = (void *)skb->data;
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
-	struct v4l2_control *v4l_ctl = radio->g_ctl;
 
 	if (rsp->status)
 		return;
 
-	v4l_ctl->value = rsp->sig_threshold;
-
+	memcpy(&radio->sig_th, rsp, sizeof(struct hci_fm_sig_threshold_rsp));
 	radio_hci_req_complete(hdev, rsp->status);
 }
 
@@ -2086,7 +2085,8 @@
 	struct sk_buff *skb)
 {
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
-	if (radio->fm_st_rsp.station_rsp.serv_avble)
+	u8 serv_avble = skb->data[0];
+	if (serv_avble)
 		iris_q_event(radio, IRIS_EVT_ABOVE_TH);
 	else
 		iris_q_event(radio, IRIS_EVT_BELOW_TH);
@@ -2432,6 +2432,11 @@
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SIGNAL_TH:
 		retval = hci_cmd(HCI_FM_GET_SIGNAL_TH_CMD, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Error in get signal threshold %d\n", retval);
+			return retval;
+		}
+		ctrl->value = radio->sig_th.sig_threshold;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SRCH_PTY:
 		ctrl->value = radio->srch_rds.srch_pty;
diff --git a/drivers/media/video/msm/msm_camera.c b/drivers/media/video/msm/msm_camera.c
index 65b33c2..dbf0eae 100644
--- a/drivers/media/video/msm/msm_camera.c
+++ b/drivers/media/video/msm/msm_camera.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -279,16 +279,18 @@
 {
 	if (info->offset < len &&
 	    info->offset + info->len <= len &&
-	    info->y_off < len &&
-	    info->cbcr_off < len)
+	    info->planar0_off < len &&
+	    info->planar1_off < len &&
+	    info->planar2_off < len)
 		return 0;
 
-	pr_err("%s: check failed: off %d len %d y %d cbcr %d (total len %d)\n",
+	pr_err("%s: check failed: off %d len %d y 0x%x cbcr_p1 0x%x p2_add 0x%x(total len %d)\n",
 		__func__,
 		info->offset,
 		info->len,
-		info->y_off,
-		info->cbcr_off,
+		info->planar0_off,
+		info->planar1_off,
+		info->planar2_off,
 		len);
 	return -EINVAL;
 }
@@ -352,8 +354,10 @@
 
 	hlist_add_head(&(region->list), ptype);
 	spin_unlock_irqrestore(pmem_spinlock, flags);
-	CDBG("%s: type %d, paddr 0x%lx, vaddr 0x%lx\n",
-		__func__, info->type, paddr, (unsigned long)info->vaddr);
+	CDBG("%s: type %d, paddr 0x%lx, vaddr 0x%lx p0_add = 0x%x"
+		"p1_addr = 0x%x p2_addr = 0x%x\n",
+		__func__, info->type, paddr, (unsigned long)info->vaddr,
+		info->planar0_off, info->planar1_off, info->planar2_off);
 	return 0;
 out2:
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
@@ -439,8 +443,9 @@
 }
 
 static int msm_pmem_frame_ptov_lookup(struct msm_sync *sync,
-		unsigned long pyaddr,
-		unsigned long pcbcraddr,
+		unsigned long p0addr,
+		unsigned long p1addr,
+		unsigned long p2addr,
 		struct msm_pmem_info *pmem_info,
 		int clear_active)
 {
@@ -450,10 +455,10 @@
 
 	spin_lock_irqsave(&sync->pmem_frame_spinlock, flags);
 	hlist_for_each_entry_safe(region, node, n, &sync->pmem_frames, list) {
-		if (pyaddr == (region->paddr + region->info.y_off) &&
-				pcbcraddr == (region->paddr +
-						region->info.cbcr_off) &&
-				region->info.active) {
+		if (p0addr == (region->paddr + region->info.planar0_off) &&
+			p1addr == (region->paddr + region->info.planar1_off) &&
+			p2addr == (region->paddr + region->info.planar2_off) &&
+			region->info.active) {
 			/* offset since we could pass vaddr inside
 			 * a registerd pmem buffer
 			 */
@@ -466,12 +471,13 @@
 		}
 	}
 	/* After lookup failure, dump all the list entries... */
-	pr_err("%s, for pyaddr 0x%lx, pcbcraddr 0x%lx\n",
-			__func__, pyaddr, pcbcraddr);
+	pr_err("%s, for plane0 addr = 0x%lx, plane1 addr = 0x%lx  plane2 addr = 0x%lx\n",
+			__func__, p0addr, p1addr, p2addr);
 	hlist_for_each_entry_safe(region, node, n, &sync->pmem_frames, list) {
-		pr_err("listed pyaddr 0x%lx, pcbcraddr 0x%lx, active = %d",
-				(region->paddr + region->info.y_off),
-				(region->paddr + region->info.cbcr_off),
+		pr_err("listed p0addr 0x%lx, p1addr 0x%lx, p2addr 0x%lx, active = %d",
+				(region->paddr + region->info.planar0_off),
+				(region->paddr + region->info.planar1_off),
+				(region->paddr + region->info.planar2_off),
 				region->info.active);
 	}
 
@@ -480,7 +486,7 @@
 }
 
 static int msm_pmem_frame_ptov_lookup2(struct msm_sync *sync,
-		unsigned long pyaddr,
+		unsigned long p0_phy,
 		struct msm_pmem_info *pmem_info,
 		int clear_active)
 {
@@ -490,7 +496,7 @@
 
 	spin_lock_irqsave(&sync->pmem_frame_spinlock, flags);
 	hlist_for_each_entry_safe(region, node, n, &sync->pmem_frames, list) {
-		if (pyaddr == (region->paddr + region->info.y_off) &&
+		if (p0_phy == (region->paddr + region->info.planar0_off) &&
 				region->info.active) {
 			/* offset since we could pass vaddr inside
 			 * a registerd pmem buffer
@@ -541,8 +547,8 @@
 }
 
 static unsigned long msm_pmem_frame_vtop_lookup(struct msm_sync *sync,
-		unsigned long buffer,
-		uint32_t yoff, uint32_t cbcroff, int fd, int change_flag)
+		unsigned long buffer, uint32_t p0_off, uint32_t p1_off,
+		uint32_t p2_off, int fd, int change_flag)
 {
 	struct msm_pmem_region *region;
 	struct hlist_node *node, *n;
@@ -552,8 +558,9 @@
 	hlist_for_each_entry_safe(region,
 		node, n, &sync->pmem_frames, list) {
 		if (((unsigned long)(region->info.vaddr) == buffer) &&
-				(region->info.y_off == yoff) &&
-				(region->info.cbcr_off == cbcroff) &&
+				(region->info.planar0_off == p0_off) &&
+				(region->info.planar1_off == p1_off) &&
+				(region->info.planar2_off == p2_off) &&
 				(region->info.fd == fd) &&
 				(region->info.active == 0)) {
 			if (change_flag)
@@ -564,13 +571,16 @@
 		}
 	}
 	/* After lookup failure, dump all the list entries... */
-	pr_err("%s, failed for vaddr 0x%lx, yoff %d cbcroff %d\n",
-			__func__, buffer, yoff, cbcroff);
+	pr_err("%s, failed for vaddr 0x%lx, p0_off %d p1_off %d\n",
+			__func__, buffer, p0_off, p1_off);
 	hlist_for_each_entry_safe(region, node, n, &sync->pmem_frames, list) {
-		pr_err("listed vaddr 0x%p, cbcroff %d, active = %d",
-				(region->info.vaddr),
-				(region->info.cbcr_off),
-				region->info.active);
+		pr_err("%s, listed vaddr 0x%lx, r_p0 = 0x%x p0_off 0x%x"
+			"r_p1 = 0x%x, p1_off 0x%x, r_p2 = 0x%x, p2_off = 0x%x"
+			" active = %d\n", __func__, buffer,
+			region->info.planar0_off,
+			p0_off, region->info.planar1_off,
+			p1_off, region->info.planar2_off, p2_off,
+			region->info.active);
 	}
 
 	spin_unlock_irqrestore(&sync->pmem_frame_spinlock, flags);
@@ -741,33 +751,36 @@
 
 	vdata = (struct msm_vfe_resp *)(qcmd->command);
 	pphy = &vdata->phy;
+	CDBG("%s, pphy->p2_phy = 0x%x\n", __func__, pphy->p2_phy);
 
 	rc = msm_pmem_frame_ptov_lookup(sync,
-			pphy->y_phy,
-			pphy->cbcr_phy,
+			pphy->p0_phy,
+			pphy->p1_phy,
+			pphy->p2_phy,
 			&pmem_info,
 			1); /* Clear the active flag */
 
 	if (rc < 0) {
-		pr_err("%s: cannot get frame, invalid lookup address "
-			"y %x cbcr %x\n",
-			__func__,
-			pphy->y_phy,
-			pphy->cbcr_phy);
+		pr_err("%s: cannot get frame, invalid lookup address"
+		"plane0 add %x plane1 add %x plane2 add%x\n",
+		__func__,
+		pphy->p0_phy,
+		pphy->p1_phy,
+		pphy->p2_phy);
 		goto err;
 	}
 
 	frame->ts = qcmd->ts;
 	frame->buffer = (unsigned long)pmem_info.vaddr;
-	frame->y_off = pmem_info.y_off;
-	frame->cbcr_off = pmem_info.cbcr_off;
+	frame->planar0_off = pmem_info.planar0_off;
+	frame->planar1_off = pmem_info.planar1_off;
+	frame->planar2_off = pmem_info.planar2_off;
 	frame->fd = pmem_info.fd;
 	frame->path = vdata->phy.output_id;
 	frame->frame_id = vdata->phy.frame_id;
-
-	CDBG("%s: y %x, cbcr %x, qcmd %x, virt_addr %x\n",
-		__func__,
-		pphy->y_phy, pphy->cbcr_phy, (int) qcmd, (int) frame->buffer);
+	CDBG("%s: plane0 %x, plane1 %x, plane2 %x,qcmd %x, virt_addr %x\n",
+		__func__, pphy->p0_phy, pphy->p1_phy, pphy->p2_phy,
+		(int) qcmd, (int) frame->buffer);
 
 err:
 	free_qcmd(qcmd);
@@ -1078,8 +1091,8 @@
 		return -EINVAL;
 	}
 
-	rc = msm_pmem_frame_ptov_lookup(sync, data->phy.y_phy,
-			data->phy.cbcr_phy, &pinfo,
+	rc = msm_pmem_frame_ptov_lookup(sync, data->phy.p0_phy,
+			data->phy.p1_phy, data->phy.p2_phy, &pinfo,
 			0); /* do not clear the active flag */
 
 	if (rc < 0) {
@@ -1088,8 +1101,8 @@
 	}
 
 	buf.fmain.buffer = (unsigned long)pinfo.vaddr;
-	buf.fmain.y_off = pinfo.y_off;
-	buf.fmain.cbcr_off = pinfo.cbcr_off;
+	buf.fmain.planar0_off = pinfo.planar0_off;
+	buf.fmain.planar1_off = pinfo.planar1_off;
 	buf.fmain.fd = pinfo.fd;
 
 	CDBG("%s: buf 0x%x fd %d\n", __func__, (unsigned int)buf.fmain.buffer,
@@ -1119,14 +1132,14 @@
 		buf.type = OUTPUT_TYPE_ST_R;
 	} else {
 		if (se->resptype == MSM_CAM_RESP_STEREO_OP_1) {
-			rc = msm_pmem_frame_ptov_lookup(sync, data->phy.y_phy,
-					data->phy.cbcr_phy, &pinfo,
-					1);  /* do clear the active flag */
+			rc = msm_pmem_frame_ptov_lookup(sync, data->phy.p0_phy,
+				data->phy.p1_phy, data->phy.p2_phy, &pinfo,
+				1);  /* do clear the active flag */
 			buf.buf_info.path = path;
 		} else if (se->resptype == MSM_CAM_RESP_STEREO_OP_2) {
-			rc = msm_pmem_frame_ptov_lookup(sync, data->phy.y_phy,
-					data->phy.cbcr_phy, &pinfo,
-					0); /* do not clear the active flag */
+			rc = msm_pmem_frame_ptov_lookup(sync, data->phy.p0_phy,
+				data->phy.p1_phy, data->phy.p2_phy, &pinfo,
+				0); /* do not clear the active flag */
 			buf.buf_info.path = path;
 		} else
 			CDBG("%s: Invalid resptype = %d\n", __func__,
@@ -1184,8 +1197,9 @@
 
 		buf.buf_info.buffer = (unsigned long)pinfo.vaddr;
 		buf.buf_info.phy_offset = pinfo.offset;
-		buf.buf_info.y_off = pinfo.y_off;
-		buf.buf_info.cbcr_off = pinfo.cbcr_off;
+		buf.buf_info.planar0_off = pinfo.planar0_off;
+		buf.buf_info.planar1_off = pinfo.planar1_off;
+		buf.buf_info.planar2_off = pinfo.planar2_off;
 		buf.buf_info.fd = pinfo.fd;
 
 		CDBG("%s: buf 0x%x fd %d\n", __func__,
@@ -1837,6 +1851,7 @@
 		}
 		break;
 
+	case CMD_AXI_CFG_VIDEO_ALL_CHNLS:
 	case CMD_AXI_CFG_VIDEO:
 		pmem_type = MSM_PMEM_PREVIEW;
 		axi_data.bufnum1 =
@@ -1889,6 +1904,7 @@
 		}
 		break;
 
+	case CMD_AXI_CFG_ZSL_ALL_CHNLS:
 	case CMD_AXI_CFG_ZSL:
 		CDBG("%s, CMD_AXI_CFG_ZSL, type = %d\n", __func__,
 			cfgcmd->cmd_type);
@@ -2044,7 +2060,7 @@
 	/* Change the active flag. */
 	pphy = msm_pmem_frame_vtop_lookup(sync,
 		pb->buffer,
-		pb->y_off, pb->cbcr_off, pb->fd, 1);
+		pb->planar0_off, pb->planar1_off, pb->planar2_off, pb->fd, 1);
 
 	if (pphy != 0) {
 		CDBG("%s: rel: vaddr %lx, paddr %lx\n",
@@ -2072,7 +2088,7 @@
 
 	pphy = msm_pmem_frame_vtop_lookup(sync,
 		pb->buffer,
-		pb->y_off, pb->cbcr_off, pb->fd, 1);
+		pb->planar0_off, pb->planar1_off, pb->planar2_off, pb->fd, 1);
 
 	if (pphy != 0) {
 		CDBG("%s: rel: vaddr %lx, paddr %lx\n",
@@ -2295,6 +2311,8 @@
 	case CMD_AXI_CFG_SNAP:
 	case CMD_RAW_PICT_AXI_CFG:
 	case CMD_AXI_CFG_ZSL:
+	case CMD_AXI_CFG_VIDEO_ALL_CHNLS:
+	case CMD_AXI_CFG_ZSL_ALL_CHNLS:
 		CDBG("%s, cfgcmd.cmd_type = %d\n", __func__, cfgcmd.cmd_type);
 		return msm_frame_axi_cfg(sync, &cfgcmd);
 
@@ -2340,21 +2358,21 @@
 		pphy = &vdata->phy;
 
 		rc = msm_pmem_frame_ptov_lookup2(sync,
-				pphy->y_phy,
+				pphy->p0_phy,
 				&pmem_info,
 				1); /* mark pic frame in use */
 
 		if (rc < 0) {
 			pr_err("%s: cannot get pic frame, invalid lookup"
-				" address y %x cbcr %x\n",
-				__func__, pphy->y_phy, pphy->cbcr_phy);
+				" address p0_phy add  %x p1_phy add%x\n",
+				__func__, pphy->p0_phy, pphy->p1_phy);
 			goto err;
 		}
 
 		frame->ts = qcmd->ts;
 		frame->buffer = (unsigned long)pmem_info.vaddr;
-		frame->y_off = pmem_info.y_off;
-		frame->cbcr_off = pmem_info.cbcr_off;
+		frame->planar0_off = pmem_info.planar0_off;
+		frame->planar1_off = pmem_info.planar1_off;
 		frame->fd = pmem_info.fd;
 		if (sync->stereocam_enabled &&
 			sync->stereo_state != STEREO_RAW_SNAP_STARTED) {
@@ -2365,20 +2383,20 @@
 		} else
 			frame->path = vdata->phy.output_id;
 
-		CDBG("%s: y %x, cbcr %x, qcmd %x, virt_addr %x\n",
-			__func__, pphy->y_phy,
-			pphy->cbcr_phy, (int) qcmd, (int) frame->buffer);
+		CDBG("%s:p0_phy add %x, p0_phy add %x, qcmd %x, virt_addr %x\n",
+			__func__, pphy->p0_phy,
+			pphy->p1_phy, (int) qcmd, (int) frame->buffer);
 	} else { /* PP */
 		pframe = (struct msm_frame *)(qcmd->command);
 		frame->ts = qcmd->ts;
 		frame->buffer = pframe->buffer;
-		frame->y_off = pframe->y_off;
-		frame->cbcr_off = pframe->cbcr_off;
+		frame->planar0_off = pframe->planar0_off;
+		frame->planar1_off = pframe->planar1_off;
 		frame->fd = pframe->fd;
 		frame->path = pframe->path;
 		CDBG("%s: PP y_off %x, cbcr_off %x, path %d vaddr 0x%x\n",
-			__func__, frame->y_off, frame->cbcr_off, frame->path,
-			(int) frame->buffer);
+		__func__, frame->planar0_off, frame->planar1_off, frame->path,
+		(int) frame->buffer);
 	}
 
 err:
@@ -2604,13 +2622,13 @@
 			vfe_rp = (struct msm_vfe_resp *)qcmd->command;
 
 			CDBG("%s: Left Py = 0x%x y_off = %d cbcr_off = %d\n",
-				__func__, vfe_rp->phy.y_phy,
-				stereo_frame_half.L.buf_y_off,
-				stereo_frame_half.L.buf_cbcr_off);
+				__func__, vfe_rp->phy.p0_phy,
+				stereo_frame_half.L.buf_p0_off,
+				stereo_frame_half.L.buf_p1_off);
 
 			sync->vpefn.vpe_cfg_offset(stereo_frame_half.packing,
-			vfe_rp->phy.y_phy + stereo_frame_half.L.buf_y_off,
-			vfe_rp->phy.y_phy + stereo_frame_half.L.buf_cbcr_off,
+			vfe_rp->phy.p0_phy + stereo_frame_half.L.buf_p0_off,
+			vfe_rp->phy.p1_phy + stereo_frame_half.L.buf_p1_off,
 			&(qcmd->ts), OUTPUT_TYPE_ST_L, stereo_frame_half.L,
 			stereo_frame_half.frame_id);
 
@@ -2626,14 +2644,15 @@
 
 			st_pphy = msm_pmem_frame_vtop_lookup(sync,
 				stereo_frame_half.buf_info.buffer,
-				stereo_frame_half.buf_info.y_off,
-				stereo_frame_half.buf_info.cbcr_off,
+				stereo_frame_half.buf_info.planar0_off,
+				stereo_frame_half.buf_info.planar1_off,
+				stereo_frame_half.buf_info.planar2_off,
 				stereo_frame_half.buf_info.fd,
 				0); /* Do not change the active flag. */
 
 			sync->vpefn.vpe_cfg_offset(stereo_frame_half.packing,
-				st_pphy + stereo_frame_half.R.buf_y_off,
-				st_pphy + stereo_frame_half.R.buf_cbcr_off,
+				st_pphy + stereo_frame_half.R.buf_p0_off,
+				st_pphy + stereo_frame_half.R.buf_p1_off,
 				NULL, OUTPUT_TYPE_ST_R, stereo_frame_half.R,
 				stereo_frame_half.frame_id);
 
@@ -3332,10 +3351,10 @@
 	switch (vdata->type) {
 	case VFE_MSG_OUTPUT_P:
 		if (sync->pp_mask & PP_PREV) {
-			CDBG("%s: PP_PREV in progress: phy_y %x phy_cbcr %x\n",
+			CDBG("%s: PP_PREV in progress: p0_add %x p1_add %x\n",
 				__func__,
-				vdata->phy.y_phy,
-				vdata->phy.cbcr_phy);
+				vdata->phy.p0_phy,
+				vdata->phy.p1_phy);
 			spin_lock_irqsave(&pp_prev_spinlock, flags);
 			if (sync->pp_prev)
 				CDBG("%s: overwriting pp_prev!\n",
@@ -3493,8 +3512,8 @@
 					vdata->vpe_bf.vpe_crop =
 				*(struct video_crop_t *)(sync->cropinfo);
 
-				vdata->vpe_bf.y_phy = vdata->phy.y_phy;
-				vdata->vpe_bf.cbcr_phy = vdata->phy.cbcr_phy;
+				vdata->vpe_bf.p0_phy = vdata->phy.p0_phy;
+				vdata->vpe_bf.p1_phy = vdata->phy.p1_phy;
 				vdata->vpe_bf.ts = (qcmd->ts);
 				vdata->vpe_bf.frame_id = vdata->phy.frame_id;
 				qcmd->command = vdata;
@@ -3506,8 +3525,8 @@
 					"= %ld\n", __func__, qcmd->ts.tv_nsec);
 
 				sync->vpefn.send_frame_to_vpe(
-					vdata->phy.y_phy,
-					vdata->phy.cbcr_phy,
+					vdata->phy.p0_phy,
+					vdata->phy.p1_phy,
 					&(qcmd->ts), OUTPUT_TYPE_V);
 
 				free_qcmd(qcmd);
diff --git a/drivers/media/video/msm/msm_mem.c b/drivers/media/video/msm/msm_mem.c
index c13e7e5..b631981 100644
--- a/drivers/media/video/msm/msm_mem.c
+++ b/drivers/media/video/msm/msm_mem.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
@@ -84,16 +84,16 @@
 {
 	if (info->offset < len &&
 		info->offset + info->len <= len &&
-		info->y_off < len &&
-		info->cbcr_off < len)
+		info->planar0_off < len &&
+		info->planar1_off < len)
 		return 0;
 
 	pr_err("%s: check failed: off %d len %d y %d cbcr %d (total len %d)\n",
 						__func__,
 						info->offset,
 						info->len,
-						info->y_off,
-						info->cbcr_off,
+						info->planar0_off,
+						info->planar1_off,
 						len);
 	return -EINVAL;
 }
diff --git a/drivers/media/video/msm/msm_vfe31.c b/drivers/media/video/msm/msm_vfe31.c
index b22b6c5..2b3732c 100644
--- a/drivers/media/video/msm/msm_vfe31.c
+++ b/drivers/media/video/msm/msm_vfe31.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
@@ -337,10 +337,12 @@
 			break;
 		}
 		pinfo->output_id = outid;
-		pinfo->y_phy =
-			((struct vfe_message *)data)->_u.msgOut.yBuffer;
-		pinfo->cbcr_phy =
-			((struct vfe_message *)data)->_u.msgOut.cbcrBuffer;
+		pinfo->p0_phy =
+			((struct vfe_message *)data)->_u.msgOut.p0_addr;
+		pinfo->p1_phy =
+			((struct vfe_message *)data)->_u.msgOut.p1_addr;
+		pinfo->p2_phy =
+			((struct vfe_message *)data)->_u.msgOut.p2_addr;
 
 		pinfo->frame_id =
 		((struct vfe_message *)data)->_u.msgOut.frameCounter;
@@ -458,8 +460,8 @@
 		GFP_ATOMIC);
 }
 
-static void vfe_send_outmsg(uint8_t msgid, uint32_t pyaddr,
-	uint32_t pcbcraddr)
+static void vfe_send_outmsg(uint8_t msgid, uint32_t p0_addr,
+	uint32_t p1_addr, uint32_t p2_addr)
 {
 	struct vfe_message msg;
 	uint8_t outid;
@@ -485,9 +487,10 @@
 		break;
 	}
 	msg._u.msgOut.output_id   = msgid;
-	msg._u.msgOut.yBuffer     = pyaddr;
-	msg._u.msgOut.cbcrBuffer  = pcbcraddr;
-
+	msg._u.msgOut.p0_addr     = p0_addr;
+	msg._u.msgOut.p1_addr     = p1_addr;
+	msg._u.msgOut.p2_addr     = p2_addr;
+	CDBG("%s p2_addr = 0x%x\n", __func__, p2_addr);
 	vfe31_proc_ops(msgid, &msg, sizeof(struct vfe_message));
 	return;
 }
@@ -542,7 +545,7 @@
 }
 
 static int vfe31_add_free_buf2(struct vfe31_output_ch *outch,
-	uint32_t paddr, uint32_t y_off, uint32_t cbcr_off)
+	uint32_t paddr, uint32_t p0_off, uint32_t p1_off, uint32_t p2_off)
 {
 	struct vfe31_free_buf *free_buf = NULL;
 	unsigned long flags = 0;
@@ -552,20 +555,23 @@
 
 	spin_lock_irqsave(&outch->free_buf_lock, flags);
 	free_buf->paddr = paddr;
-	free_buf->y_off = y_off;
-	free_buf->cbcr_off = cbcr_off;
+	free_buf->planar0_off = p0_off;
+	free_buf->planar1_off = p1_off;
+	free_buf->planar2_off = p2_off;
 	list_add_tail(&free_buf->node, &outch->free_buf_head);
 
 	CDBG("%s: free_buf paddr = 0x%x, y_off = %d, cbcr_off = %d\n",
-		__func__, free_buf->paddr, free_buf->y_off,
-		free_buf->cbcr_off);
+		__func__, free_buf->paddr, free_buf->planar0_off,
+		free_buf->planar1_off);
 	spin_unlock_irqrestore(&outch->free_buf_lock, flags);
 	return 0;
 }
 
 #define vfe31_add_free_buf(outch, regptr) \
-	vfe31_add_free_buf2(outch, regptr->paddr, regptr->info.y_off,	\
-		regptr->info.cbcr_off)
+	vfe31_add_free_buf2(outch, regptr->paddr, \
+	regptr->info.planar0_off,	\
+	regptr->info.planar1_off,	\
+	regptr->info.planar2_off)
 
 #define vfe31_free_buf_available(outch) \
 	(!list_empty(&outch.free_buf_head))
@@ -662,10 +668,10 @@
 
 		for (i = 0; i < 2; i++) {
 			p1 = ao + 6 + i;    /* wm0 for y  */
-			*p1 = (regp1->paddr + regp1->info.y_off);
+			*p1 = (regp1->paddr + regp1->info.planar0_off);
 
 			p1 = ao + 12 + i;  /* wm1 for cbcr */
-			*p1 = (regp1->paddr + regp1->info.cbcr_off);
+			*p1 = (regp1->paddr + regp1->info.planar1_off);
 			regp1++;
 		}
 		ret = vfe31_add_free_buf(outp1, regp1);
@@ -694,47 +700,47 @@
 		/*  Parse the buffers!!! */
 		if (ad->bufnum2 == 1) {	/* assuming bufnum1 = bufnum2 */
 			p1 = ao + 6;   /* wm0 ping */
-			*p1++ = (regp1->paddr + regp1->info.y_off);
+			*p1++ = (regp1->paddr + regp1->info.planar0_off);
 
 			/* this is to duplicate ping address to pong.*/
-			*p1 = (regp1->paddr + regp1->info.y_off);
+			*p1 = (regp1->paddr + regp1->info.planar0_off);
 
 			p1 = ao + 30;  /* wm4 ping */
-			*p1++ = (regp1->paddr + regp1->info.cbcr_off);
+			*p1++ = (regp1->paddr + regp1->info.planar1_off);
 			CDBG("%s: regp1->info.cbcr_off = 0x%x\n", __func__,
-						 regp1->info.cbcr_off);
+						 regp1->info.planar1_off);
 
 			/* this is to duplicate ping address to pong.*/
-			*p1 = (regp1->paddr + regp1->info.cbcr_off);
+			*p1 = (regp1->paddr + regp1->info.planar1_off);
 
 			p1 = ao + 12;   /* wm1 ping */
-			*p1++ = (regp2->paddr + regp2->info.y_off);
+			*p1++ = (regp2->paddr + regp2->info.planar0_off);
 
 			/* pong = ping,*/
-			*p1 = (regp2->paddr + regp2->info.y_off);
+			*p1 = (regp2->paddr + regp2->info.planar0_off);
 
 			p1 = ao + 36;  /* wm5 */
-			*p1++ = (regp2->paddr + regp2->info.cbcr_off);
+			*p1++ = (regp2->paddr + regp2->info.planar1_off);
 			CDBG("%s: regp2->info.cbcr_off = 0x%x\n", __func__,
-						 regp2->info.cbcr_off);
+						 regp2->info.planar1_off);
 
 			/* pong = ping,*/
-			*p1 = (regp2->paddr + regp2->info.cbcr_off);
+			*p1 = (regp2->paddr + regp2->info.planar1_off);
 		} else { /* more than one snapshot */
 			/* first fill ping & pong */
 			for (i = 0; i < 2; i++) {
 				p1 = ao + 6 + i;    /* wm0 for y  */
-				*p1 = (regp1->paddr + regp1->info.y_off);
+				*p1 = (regp1->paddr + regp1->info.planar0_off);
 				p1 = ao + 30 + i;  /* wm4 for cbcr */
-				*p1 = (regp1->paddr + regp1->info.cbcr_off);
+				*p1 = (regp1->paddr + regp1->info.planar1_off);
 				regp1--;
 			}
 
 			for (i = 0; i < 2; i++) {
 				p2 = ao + 12 + i;    /* wm1 for y  */
-				*p2 = (regp2->paddr + regp2->info.y_off);
+				*p2 = (regp2->paddr + regp2->info.planar0_off);
 				p2 = ao + 36 + i;  /* wm5 for cbcr */
-				*p2 = (regp2->paddr + regp2->info.cbcr_off);
+				*p2 = (regp2->paddr + regp2->info.planar1_off);
 				regp2--;
 			}
 
@@ -783,25 +789,25 @@
 		/* first fill ping & pong */
 		for (i = 0; i < 2; i++) {
 			p1 = ao + 6 + i;    /* wm0 for y  */
-			*p1 = (regp1->paddr + regp1->info.y_off);
+			*p1 = (regp1->paddr + regp1->info.planar0_off);
 			p1 = ao + 30 + i;  /* wm4 for cbcr */
-			*p1 = (regp1->paddr + regp1->info.cbcr_off);
+			*p1 = (regp1->paddr + regp1->info.planar1_off);
 			regp1++;
 		}
 
 		for (i = 0; i < 2; i++) {
 			p2 = ao + 12 + i;    /* wm1 for y  */
-			*p2 = (regp2->paddr + regp2->info.y_off);
+			*p2 = (regp2->paddr + regp2->info.planar0_off);
 			p2 = ao + 36 + i;  /* wm5 for cbcr */
-			*p2 = (regp2->paddr + regp2->info.cbcr_off);
+			*p2 = (regp2->paddr + regp2->info.planar1_off);
 			regp2++;
 		}
 
 		for (i = 0; i < 2; i++) {
 			p3 = ao + 18 + i;    /* wm2 for y  */
-			*p3 = (regp3->paddr + regp3->info.y_off);
+			*p3 = (regp3->paddr + regp3->info.planar0_off);
 			p3 = ao + 42 + i;  /* wm6 for cbcr */
-			*p3 = (regp3->paddr + regp3->info.cbcr_off);
+			*p3 = (regp3->paddr + regp3->info.planar1_off);
 			regp3++;
 		}
 
@@ -827,6 +833,80 @@
 		}
 		break;
 
+	case OUTPUT_ZSL_ALL_CHNLS:
+		CDBG("%s: OUTPUT_ZSL_ALL_CHNLS", __func__);
+		CDBG("%s: %d %d %d", __func__, ad->bufnum1, ad->bufnum2,
+			ad->bufnum3);
+		/* use wm0& 4 for postview, wm1&5 for preview.*/
+		/* use wm2& 6 for main img */
+		if ((ad->bufnum1 < 1) || (ad->bufnum2 < 1) || (ad->bufnum3 < 1))
+			return -EINVAL;
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_S;  /* main image.*/
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_P_ALL_CHNLS;  /* preview. */
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_T;  /* thumbnail. */
+
+		/* this is preview buffer. */
+		regp1 = &(ad->region[0]);
+		/* this is thumbnail buffer. */
+		regp2 = &(ad->region[ad->bufnum1]);
+		/* this is main image buffer. */
+		regp3 = &(ad->region[ad->bufnum1+ad->bufnum2]);
+		outp1 = &(vfe31_ctrl->outpath.out0);
+		outp2 = &(vfe31_ctrl->outpath.out1);
+		outp3 = &(vfe31_ctrl->outpath.out2);
+
+		/*  Parse the buffers!!! */
+		/* first fill ping & pong */
+		for (i = 0; i < 2; i++) {
+			p1 = ao + 6 + i;    /* wm0 for y  */
+			*p1 = (regp2->paddr + regp2->info.planar0_off);
+			p1 = ao + 12 + i;  /* wm1 for cbcr */
+			*p1 = (regp2->paddr + regp2->info.planar1_off);
+			regp2++;
+		}
+
+		for (i = 0; i < 2; i++) {
+			p2 = ao + 30 + i;    /* wm4 for y  */
+			*p2 = (regp1->paddr + regp1->info.planar0_off);
+			p2 = ao + 36 + i;  /* wm5 for cbcr */
+			*p2 = (regp1->paddr + regp1->info.planar1_off);
+			p2 = ao + 42 + i;  /* wm5 for cbcr */
+			*p2 = (regp1->paddr + regp1->info.planar2_off);
+			regp1++;
+		}
+
+		for (i = 0; i < 2; i++) {
+			p3 = ao + 18 + i;    /* wm2 for y  */
+			*p3 = (regp3->paddr + regp3->info.planar0_off);
+			p3 = ao + 24 + i;  /* wm3 for cbcr */
+			*p3 = (regp3->paddr + regp3->info.planar1_off);
+			regp3++;
+		}
+		for (i = 2; i < ad->bufnum1; i++) {
+			ret = vfe31_add_free_buf(outp1, regp1);
+			if (ret < 0)
+				return ret;
+			regp1++;
+		}
+
+		for (i = 2; i < ad->bufnum2; i++) {
+			ret = vfe31_add_free_buf(outp2, regp2);
+			if (ret < 0)
+				return ret;
+			regp2++;
+		}
+
+		for (i = 2; i < ad->bufnum3; i++) {
+			ret = vfe31_add_free_buf(outp3, regp3);
+			if (ret < 0)
+				return ret;
+			regp3++;
+		}
+		break;
+
 	case OUTPUT_1_AND_3: {
 		/* use wm0&4 for preview, wm1&5 for video.*/
 		if ((ad->bufnum1 < 2) || (ad->bufnum2 < 2))
@@ -849,19 +929,19 @@
 
 		for (i = 0; i < 2; i++) {
 			p1 = ao + 6 + i;    /* wm0 for y  */
-			*p1 = (regp1->paddr + regp1->info.y_off);
+			*p1 = (regp1->paddr + regp1->info.planar0_off);
 
 			p1 = ao + 30 + i;  /* wm4 for cbcr */
-			*p1 = (regp1->paddr + regp1->info.cbcr_off);
+			*p1 = (regp1->paddr + regp1->info.planar1_off);
 			regp1++;
 		}
 
 		for (i = 0; i < 2; i++) {
 			p2 = ao + 12 + i;    /* wm1 for y  */
-			*p2 = (regp2->paddr + regp2->info.y_off);
+			*p2 = (regp2->paddr + regp2->info.planar0_off);
 
 			p2 = ao + 36 + i;  /* wm5 for cbcr */
-			*p2 = (regp2->paddr + regp2->info.cbcr_off);
+			*p2 = (regp2->paddr + regp2->info.planar1_off);
 			regp2++;
 		}
 		for (i = 2; i < ad->bufnum1; i++) {
@@ -879,6 +959,52 @@
 		}
 	}
 		break;
+
+	case OUTPUT_VIDEO_ALL_CHNLS: {
+		/* use wm0&4 for preview, wm1&5 for video.*/
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_V;  /* video*/
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_P_ALL_CHNLS;
+		regp1 = &(ad->region[0]);
+		regp2 = &(ad->region[ad->bufnum1]);
+		outp1 = &(vfe31_ctrl->outpath.out0);
+		outp2 = &(vfe31_ctrl->outpath.out2);
+
+		for (i = 0; i < 2; i++) {
+			p1 = ao + 6 + i;    /* wm0 for y  */
+			*p1 = (regp1->paddr + regp1->info.planar0_off);
+
+			p1 = ao + 12 + i;  /* wm1 for cbcr */
+			*p1 = (regp1->paddr + regp1->info.planar1_off);
+
+			p1 = ao + 18 + i;  /* wm2 for cbcr */
+			*p1 = (regp1->paddr + regp1->info.planar2_off);
+			regp1++;
+		}
+		for (i = 0; i < 2; i++) {
+			p2 = ao + 30 + i;    /* wm4 for y  */
+			*p2 = (regp2->paddr + regp2->info.planar0_off);
+
+			p2 = ao + 36 + i;  /* wm5 for cbcr */
+			*p2 = (regp2->paddr + regp2->info.planar1_off);
+			regp2++;
+		}
+		for (i = 2; i < ad->bufnum1; i++) {
+			ret = vfe31_add_free_buf(outp1, regp1);
+			if (ret < 0)
+				return ret;
+			regp1++;
+		}
+		for (i = 2; i < ad->bufnum2; i++) {
+			ret = vfe31_add_free_buf(outp2, regp2);
+			if (ret < 0)
+				return ret;
+			regp2++;
+		}
+	}
+		break;
+
 	case CAMIF_TO_AXI_VIA_OUTPUT_2: {  /* use wm0 only */
 		if (ad->bufnum2 < 1)
 			return -EINVAL;
@@ -887,7 +1013,7 @@
 		regp1 = &(ad->region[ad->bufnum1]);
 		vfe31_ctrl->outpath.output_mode |= VFE31_OUTPUT_MODE_S;
 		p1 = ao + 6;    /* wm0 for y  */
-		*p1 = (regp1->paddr + regp1->info.y_off);
+		*p1 = (regp1->paddr + regp1->info.planar0_off);
 		if (p_sync->stereocam_enabled)
 			p_sync->stereo_state = STEREO_RAW_SNAP_IDLE;
 	}
@@ -1193,6 +1319,11 @@
 			irq_comp_mask |=
 				((0x1 << (vfe31_ctrl->outpath.out0.ch0)) |
 				(0x1 << (vfe31_ctrl->outpath.out0.ch1)));
+		} else if (vfe31_ctrl->outpath.output_mode &
+				VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
+			irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
+				0x1 << vfe31_ctrl->outpath.out0.ch1 |
+				0x1 << vfe31_ctrl->outpath.out0.ch2);
 		}
 		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_T) {
 			irq_comp_mask |=
@@ -1209,6 +1340,14 @@
 				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
 			msm_io_w(1, vfe31_ctrl->vfebase +
 				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+		} else if (vfe31_ctrl->outpath.output_mode &
+				VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
+			msm_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+			msm_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+			msm_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
 		}
 		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_T) {
 			msm_io_w(1, vfe31_ctrl->vfebase +
@@ -1302,12 +1441,22 @@
 	if ((vfe31_ctrl->operation_mode != VFE_MODE_OF_OPERATION_CONTINUOUS) &&
 		(vfe31_ctrl->operation_mode != VFE_MODE_OF_OPERATION_VIDEO))
 		return 0;
-	irq_comp_mask	=
+	irq_comp_mask =
 		msm_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
 
 	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PT) {
 		irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
 			0x1 << vfe31_ctrl->outpath.out0.ch1);
+			if (vfe31_ctrl->outpath.out0.ch2 >= 0)
+				irq_comp_mask |=
+					(0x1 << vfe31_ctrl->outpath.out0.ch0 |
+					0x1 << vfe31_ctrl->outpath.out0.ch1 |
+					0x1 << vfe31_ctrl->outpath.out0.ch2);
+	} else if (vfe31_ctrl->outpath.output_mode &
+		VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
+			irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
+				0x1 << vfe31_ctrl->outpath.out0.ch1 |
+				0x1 << vfe31_ctrl->outpath.out0.ch2);
 	}
 
 	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_V) {
@@ -1323,7 +1472,19 @@
 			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
 		msm_io_w(1, vfe31_ctrl->vfebase +
 			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+		if (vfe31_ctrl->outpath.out0.ch2 >= 0)
+			msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
+	} else if (vfe31_ctrl->outpath.output_mode &
+		VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
+		msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+		msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+		msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
 	}
+
 	if (p_sync->stereocam_enabled)
 		msm_camio_set_perf_lvl(S_STEREO_VIDEO);
 	else
@@ -2240,7 +2401,8 @@
 			break;
 		}
 
-		ret = vfe31_add_free_buf2(outch, p, b->y_off, b->cbcr_off);
+		ret = vfe31_add_free_buf2(outch, p, b->planar0_off,
+			b->planar1_off, b->planar2_off);
 		if (ret < 0)
 			return ret;
 		break;
@@ -2267,7 +2429,8 @@
 		} else
 			return -EFAULT;
 
-		ret = vfe31_add_free_buf2(outch, p, b->y_off, b->cbcr_off);
+		ret = vfe31_add_free_buf2(outch, p, b->planar0_off,
+			b->planar1_off,	b->planar2_off);
 		if (ret < 0)
 			return ret;
 		break;
@@ -2403,6 +2566,32 @@
 	}
 		break;
 
+	case CMD_AXI_CFG_ZSL_ALL_CHNLS: {
+		struct axidata *axid;
+		uint32_t *axio;
+		CDBG("%s, CMD_AXI_CFG_ZSL\n", __func__);
+		axid = data;
+		if (!axid)
+			return -EFAULT;
+		axio =
+			kmalloc(vfe31_cmd[V31_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe31_cmd[V31_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe31_config_axi(OUTPUT_ZSL_ALL_CHNLS, axid, axio);
+		kfree(axio);
+	}
+		break;
+
 	case CMD_AXI_CFG_VIDEO: {
 		struct axidata *axid;
 		uint32_t *axio = NULL;
@@ -2431,6 +2620,34 @@
 		break;
 	}
 
+	case CMD_AXI_CFG_VIDEO_ALL_CHNLS: {
+		struct axidata *axid;
+		uint32_t *axio = NULL;
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			break;
+		}
+
+		axio =
+			kmalloc(vfe31_cmd[V31_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe31_cmd[V31_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe31_config_axi(OUTPUT_VIDEO_ALL_CHNLS, axid, axio);
+		kfree(axio);
+		break;
+	}
+
 	default:
 		break;
 	}
@@ -2804,7 +3021,7 @@
 
 static void vfe31_process_output_path_irq_0(uint32_t ping_pong)
 {
-	uint32_t pyaddr, pcbcraddr;
+	uint32_t p0_addr, p1_addr, p2_addr;
 #ifdef CONFIG_MSM_CAMERA_V4L2
 	uint32_t pyaddr_ping, pcbcraddr_ping, pyaddr_pong, pcbcraddr_pong;
 #endif
@@ -2816,26 +3033,37 @@
 
 	if (free_buf) {
 		/* Y channel */
-		pyaddr = vfe31_get_ch_addr(ping_pong,
+		p0_addr = vfe31_get_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out0.ch0);
 		/* Chroma channel */
-		pcbcraddr = vfe31_get_ch_addr(ping_pong,
+		p1_addr = vfe31_get_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out0.ch1);
-
-		CDBG("output path 0, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
-			 pyaddr, pcbcraddr);
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
+			p2_addr = vfe31_get_ch_addr(ping_pong,
+				vfe31_ctrl->outpath.out0.ch2);
+		} else {
+			p2_addr = p0_addr;
+		}
+		CDBG("Output path 0, p0_addr = 0x%x, p1_addr = 0x%x,"
+			 "p2_addr = 0x%x\n", p0_addr, p1_addr, p2_addr);
 		/* Y channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out0.ch0,
-			free_buf->paddr + free_buf->y_off);
+			free_buf->paddr + free_buf->planar0_off);
 		/* Chroma channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out0.ch1,
-			free_buf->paddr + free_buf->cbcr_off);
-
-		kfree(free_buf);
-		/* if continuous mode, for display. (preview) */
-		vfe_send_outmsg(MSG_ID_OUTPUT_P, pyaddr, pcbcraddr);
+			free_buf->paddr + free_buf->planar1_off);
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_P_ALL_CHNLS)
+			vfe31_put_ch_addr(ping_pong,
+				vfe31_ctrl->outpath.out0.ch2,
+			free_buf->paddr + free_buf->planar2_off);
+			kfree(free_buf);
+			/* if continuous mode, for display. (preview) */
+			vfe_send_outmsg(MSG_ID_OUTPUT_P,  p0_addr, p1_addr,
+				p2_addr);
 	} else {
 		vfe31_ctrl->outpath.out0.frame_drop_cnt++;
 		pr_warning("path_irq_0 - no free buffer!\n");
@@ -2880,54 +3108,54 @@
 
 static void vfe31_process_snapshot_frame(uint32_t ping_pong)
 {
-	uint32_t pyaddr, pcbcraddr;
+	uint32_t p0_addr, p1_addr;
 	struct vfe31_free_buf *free_buf = NULL;
 	/* Y channel- Main Image */
-	pyaddr = vfe31_get_ch_addr(ping_pong,
+	p0_addr = vfe31_get_ch_addr(ping_pong,
 		vfe31_ctrl->outpath.out1.ch0);
 	/* Chroma channel - TN Image */
-	pcbcraddr = vfe31_get_ch_addr(ping_pong,
+	p1_addr = vfe31_get_ch_addr(ping_pong,
 		vfe31_ctrl->outpath.out1.ch1);
 
 	free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out1);
-	CDBG("%s: snapshot main, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
-		__func__, pyaddr, pcbcraddr);
+	CDBG("%s: snapshot main, p0_addr = 0x%x, p1_addr = 0x%x\n",
+		__func__, p0_addr, p1_addr);
 	if (free_buf) {
 		/* Y channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out1.ch0,
-			free_buf->paddr + free_buf->y_off);
+			free_buf->paddr + free_buf->planar0_off);
 		/* Chroma channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out1.ch1,
-			free_buf->paddr + free_buf->cbcr_off);
+			free_buf->paddr + free_buf->planar1_off);
 		kfree(free_buf);
 	}
-	vfe_send_outmsg(MSG_ID_OUTPUT_S, pyaddr, pcbcraddr);
+	vfe_send_outmsg(MSG_ID_OUTPUT_S, p0_addr, p1_addr, p0_addr);
 
 	/* Y channel- TN Image */
-	pyaddr = vfe31_get_ch_addr(ping_pong,
+	p0_addr = vfe31_get_ch_addr(ping_pong,
 		vfe31_ctrl->outpath.out0.ch0);
 	/* Chroma channel - TN Image */
-	pcbcraddr = vfe31_get_ch_addr(ping_pong,
+	p1_addr = vfe31_get_ch_addr(ping_pong,
 		vfe31_ctrl->outpath.out0.ch1);
 
 	free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out0);
-	CDBG("%s: snapshot TN, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
-		__func__, pyaddr, pcbcraddr);
+	CDBG("%s: snapshot TN, p0_addr = 0x%x, p1_addr = 0x%x\n",
+		__func__, p0_addr, p1_addr);
 	if (free_buf) {
 		/* Y channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out0.ch0,
-			free_buf->paddr + free_buf->y_off);
+			free_buf->paddr + free_buf->planar0_off);
 		/* Chroma channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out0.ch1,
-			free_buf->paddr + free_buf->cbcr_off);
+			free_buf->paddr + free_buf->planar1_off);
 		kfree(free_buf);
 	}
 
-	vfe_send_outmsg(MSG_ID_OUTPUT_T, pyaddr, pcbcraddr);
+	vfe_send_outmsg(MSG_ID_OUTPUT_T, p0_addr, p1_addr, p0_addr);
 
 	/* in snapshot mode if done then send
 		snapshot done message */
@@ -2964,14 +3192,14 @@
 		/* Y channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out1.ch0,
-			free_buf->paddr + free_buf->y_off);
+			free_buf->paddr + free_buf->planar0_off);
 		/* Chroma channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out1.ch1,
-			free_buf->paddr + free_buf->cbcr_off);
+			free_buf->paddr + free_buf->planar1_off);
 		kfree(free_buf);
 	}
-	 vfe_send_outmsg(MSG_ID_OUTPUT_S, pyaddr, pcbcraddr);
+	 vfe_send_outmsg(MSG_ID_OUTPUT_S, pyaddr, pcbcraddr, 0);
 
 	/* in snapshot mode if done then send
 		snapshot done message */
@@ -2986,54 +3214,54 @@
 }
 static void vfe31_process_zsl_frame(uint32_t ping_pong)
 {
-	uint32_t pyaddr, pcbcraddr;
+	uint32_t p0_addr, p1_addr;
 	struct vfe31_free_buf *free_buf = NULL;
 	/* Y channel- Main Image */
-	pyaddr = vfe31_get_ch_addr(ping_pong,
+	p0_addr = vfe31_get_ch_addr(ping_pong,
 		vfe31_ctrl->outpath.out2.ch0);
 	/* Chroma channel - Main Image */
-	pcbcraddr = vfe31_get_ch_addr(ping_pong,
+	p1_addr = vfe31_get_ch_addr(ping_pong,
 		vfe31_ctrl->outpath.out2.ch1);
 
 	free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out2);
 	CDBG("%s: snapshot main, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
-		__func__, pyaddr, pcbcraddr);
+		__func__, p0_addr, p1_addr);
 	if (free_buf) {
 		/* Y channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out2.ch0,
-			free_buf->paddr + free_buf->y_off);
+			free_buf->paddr + free_buf->planar0_off);
 		/* Chroma channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out2.ch1,
-			free_buf->paddr + free_buf->cbcr_off);
+			free_buf->paddr + free_buf->planar1_off);
 		kfree(free_buf);
 	}
-	 vfe_send_outmsg(MSG_ID_OUTPUT_S, pyaddr, pcbcraddr);
+	 vfe_send_outmsg(MSG_ID_OUTPUT_S, p0_addr, p1_addr, p0_addr);
 
 	/* Y channel- TN Image */
-	pyaddr = vfe31_get_ch_addr(ping_pong,
+	p0_addr = vfe31_get_ch_addr(ping_pong,
 		vfe31_ctrl->outpath.out1.ch0);
 	/* Chroma channel - TN Image */
-	pcbcraddr = vfe31_get_ch_addr(ping_pong,
+	p1_addr = vfe31_get_ch_addr(ping_pong,
 		vfe31_ctrl->outpath.out1.ch1);
 
 	free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out1);
 	CDBG("%s: snapshot TN, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
-		__func__, pyaddr, pcbcraddr);
+		__func__, p0_addr, p1_addr);
 	if (free_buf) {
 		/* Y channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out1.ch0,
-			free_buf->paddr + free_buf->y_off);
+			free_buf->paddr + free_buf->planar0_off);
 		/* Chroma channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out1.ch1,
-			free_buf->paddr + free_buf->cbcr_off);
+			free_buf->paddr + free_buf->planar1_off);
 		kfree(free_buf);
 	}
 
-	vfe_send_outmsg(MSG_ID_OUTPUT_T, pyaddr, pcbcraddr);
+	vfe_send_outmsg(MSG_ID_OUTPUT_T, p0_addr, p1_addr, p0_addr);
 }
 
 static void vfe31_process_output_path_irq_1(uint32_t ping_pong)
@@ -3105,7 +3333,7 @@
 
 static void vfe31_process_output_path_irq_2(uint32_t ping_pong)
 {
-	uint32_t pyaddr, pcbcraddr;
+	uint32_t p0_addr, p1_addr, p2_addr;
 	struct vfe31_free_buf *free_buf = NULL;
 
 #ifdef CONFIG_MSM_CAMERA_V4L2
@@ -3135,25 +3363,25 @@
 
 	if (free_buf) {
 		/* Y channel */
-		pyaddr = vfe31_get_ch_addr(ping_pong,
+		p0_addr = vfe31_get_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out2.ch0);
 		/* Chroma channel */
-		pcbcraddr = vfe31_get_ch_addr(ping_pong,
+		p1_addr = vfe31_get_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out2.ch1);
-
+		p2_addr = p0_addr;
 		CDBG("video output, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
-			pyaddr, pcbcraddr);
+			p0_addr, p1_addr);
 
 		/* Y channel */
 		vfe31_put_ch_addr(ping_pong,
 		vfe31_ctrl->outpath.out2.ch0,
-		free_buf->paddr + free_buf->y_off);
+		free_buf->paddr + free_buf->planar0_off);
 		/* Chroma channel */
 		vfe31_put_ch_addr(ping_pong,
 		vfe31_ctrl->outpath.out2.ch1,
-		free_buf->paddr + free_buf->cbcr_off);
+		free_buf->paddr + free_buf->planar1_off);
 		kfree(free_buf);
-		vfe_send_outmsg(MSG_ID_OUTPUT_V, pyaddr, pcbcraddr);
+		vfe_send_outmsg(MSG_ID_OUTPUT_V, p0_addr, p1_addr, p2_addr);
 	} else {
 		vfe31_ctrl->outpath.out2.frame_drop_cnt++;
 		pr_warning("path_irq_2 - no free buffer!\n");
diff --git a/drivers/media/video/msm/msm_vfe31.h b/drivers/media/video/msm/msm_vfe31.h
index c47c7de..d1df2dd 100644
--- a/drivers/media/video/msm/msm_vfe31.h
+++ b/drivers/media/video/msm/msm_vfe31.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
@@ -842,8 +842,9 @@
 
 struct vfe_msg_output {
 	uint8_t   output_id;
-	uint32_t  yBuffer;
-	uint32_t  cbcrBuffer;
+	uint32_t  p0_addr;
+	uint32_t  p1_addr;
+	uint32_t  p2_addr;
 	struct vfe_frame_bpc_info bpcInfo;
 	struct vfe_frame_asf_info asfInfo;
 	uint32_t  frameCounter;
@@ -878,7 +879,9 @@
 struct vfe31_free_buf {
 	struct list_head node;
 	uint32_t paddr;
-	uint32_t y_off;
+	uint32_t planar0_off;
+	uint32_t planar1_off;
+	uint32_t planar2_off;
 	uint32_t cbcr_off;
 };
 
diff --git a/drivers/media/video/msm/msm_vfe7x.c b/drivers/media/video/msm/msm_vfe7x.c
index 316aacf..d74bebc 100644
--- a/drivers/media/video/msm/msm_vfe7x.c
+++ b/drivers/media/video/msm/msm_vfe7x.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -72,14 +72,14 @@
 {
 	switch (type) {
 	case VFE_MSG_OUTPUT_P: {
-		pinfo->y_phy = ((struct vfe_endframe *)data)->y_address;
-		pinfo->cbcr_phy =
+		pinfo->p0_phy = ((struct vfe_endframe *)data)->y_address;
+		pinfo->p1_phy =
 			((struct vfe_endframe *)data)->cbcr_address;
-
+		pinfo->p2_phy = pinfo->p0_phy;
 		pinfo->output_id = OUTPUT_TYPE_P;
 
 		CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
-				 pinfo->y_phy, pinfo->cbcr_phy);
+				 pinfo->p0_phy, pinfo->p1_phy);
 
 		((struct vfe_frame_extra *)extdata)->bl_evencol =
 		((struct vfe_endframe *)data)->blacklevelevencolumn;
@@ -99,20 +99,22 @@
 		break;
 
 	case VFE_MSG_OUTPUT_S: {
-		pinfo->y_phy = paddr_s_y;
-		pinfo->cbcr_phy = paddr_s_cbcr;
+		pinfo->p0_phy = paddr_s_y;
+		pinfo->p1_phy = paddr_s_cbcr;
+		pinfo->p2_phy = pinfo->p0_phy;
 		pinfo->output_id = OUTPUT_TYPE_S;
 		CDBG("vfe_7x_convert: y_phy = 0x%x cbcr_phy = 0x%x\n",
-					pinfo->y_phy, pinfo->cbcr_phy);
+					pinfo->p0_phy, pinfo->p1_phy);
 	}
 		break;
 
 	case VFE_MSG_OUTPUT_T: {
-		pinfo->y_phy = paddr_t_y;
-		pinfo->cbcr_phy = paddr_t_cbcr;
+		pinfo->p0_phy = paddr_t_y;
+		pinfo->p1_phy = paddr_t_cbcr;
+		pinfo->p2_phy = pinfo->p0_phy;
 		pinfo->output_id = OUTPUT_TYPE_T;
 		CDBG("vfe_7x_convert: y_phy = 0x%x cbcr_phy = 0x%x\n",
-					pinfo->y_phy, pinfo->cbcr_phy);
+					pinfo->p0_phy, pinfo->p1_phy);
 	}
 		break;
 
@@ -372,19 +374,19 @@
 
 		CDBG("bufnum1 = %d\n", ad->bufnum1);
 		if (mode == OUTPUT_1_AND_2) {
-			paddr_t_y = regptr->paddr + regptr->info.y_off;
-			paddr_t_cbcr = regptr->paddr +  regptr->info.cbcr_off;
+			paddr_t_y = regptr->paddr + regptr->info.planar0_off;
+			paddr_t_cbcr = regptr->paddr + regptr->info.planar1_off;
 		}
 
 		CDBG("config_axi1: O1, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
-			regptr->paddr, regptr->info.y_off,
-			regptr->info.cbcr_off);
+			regptr->paddr, regptr->info.planar0_off,
+			regptr->info.planar1_off);
 
 		bptr = &ao->output1buffer1_y_phy;
 		for (cnt = 0; cnt < ad->bufnum1; cnt++) {
-			*bptr = regptr->paddr + regptr->info.y_off;
+			*bptr = regptr->paddr + regptr->info.planar0_off;
 			bptr++;
-			*bptr = regptr->paddr + regptr->info.cbcr_off;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
 
 			bptr++;
 			regptr++;
@@ -392,9 +394,9 @@
 
 		regptr--;
 		for (cnt = 0; cnt < (8 - ad->bufnum1); cnt++) {
-			*bptr = regptr->paddr + regptr->info.y_off;
+			*bptr = regptr->paddr + regptr->info.planar0_off;
 			bptr++;
-			*bptr = regptr->paddr + regptr->info.cbcr_off;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
 			bptr++;
 		}
 	} /* if OUTPUT1 or Both */
@@ -403,16 +405,17 @@
 		regptr = &(ad->region[ad->bufnum1]);
 
 		CDBG("bufnum2 = %d\n", ad->bufnum2);
-		paddr_s_y = regptr->paddr +  regptr->info.y_off;
-		paddr_s_cbcr = regptr->paddr +  regptr->info.cbcr_off;
+		paddr_s_y = regptr->paddr +  regptr->info.planar0_off;
+		paddr_s_cbcr = regptr->paddr +  regptr->info.planar1_off;
 		CDBG("config_axi2: O2, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
-		     regptr->paddr, regptr->info.y_off, regptr->info.cbcr_off);
+			regptr->paddr, regptr->info.planar0_off,
+			regptr->info.planar1_off);
 
 		bptr = &ao->output2buffer1_y_phy;
 		for (cnt = 0; cnt < ad->bufnum2; cnt++) {
-			*bptr = regptr->paddr + regptr->info.y_off;
+			*bptr = regptr->paddr + regptr->info.planar0_off;
 			bptr++;
-			*bptr = regptr->paddr + regptr->info.cbcr_off;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
 
 			bptr++;
 			regptr++;
@@ -420,9 +423,9 @@
 
 		regptr--;
 		for (cnt = 0; cnt < (8 - ad->bufnum2); cnt++) {
-			*bptr = regptr->paddr + regptr->info.y_off;
+			*bptr = regptr->paddr + regptr->info.planar0_off;
 			bptr++;
-			*bptr = regptr->paddr + regptr->info.cbcr_off;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
 			bptr++;
 		}
 	}
@@ -584,10 +587,10 @@
 		fack.header = VFE_FRAME_ACK;
 
 		fack.output2newybufferaddress =
-			(void *)(p + b->y_off);
+			(void *)(p + b->planar0_off);
 
 		fack.output2newcbcrbufferaddress =
-			(void *)(p + b->cbcr_off);
+			(void *)(p + b->planar1_off);
 
 		vfecmd->queue = QDSP_CMDQUEUE;
 		vfecmd->length = sizeof(struct vfe_outputack);
diff --git a/drivers/media/video/msm/msm_vfe7x27a.c b/drivers/media/video/msm/msm_vfe7x27a.c
index 9f7dff7..337085d 100644
--- a/drivers/media/video/msm/msm_vfe7x27a.c
+++ b/drivers/media/video/msm/msm_vfe7x27a.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
@@ -72,14 +72,14 @@
 {
 	switch (type) {
 	case VFE_MSG_OUTPUT_P: {
-		pinfo->y_phy = ((struct vfe_endframe *)data)->y_address;
-		pinfo->cbcr_phy =
+		pinfo->p0_phy = ((struct vfe_endframe *)data)->y_address;
+		pinfo->p1_phy =
 			((struct vfe_endframe *)data)->cbcr_address;
-
+		pinfo->p2_phy = pinfo->p0_phy;
 		pinfo->output_id = OUTPUT_TYPE_P;
 
 		CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
-				 pinfo->y_phy, pinfo->cbcr_phy);
+				 pinfo->p0_phy, pinfo->p1_phy);
 
 		memcpy(((struct vfe_frame_extra *)extdata),
 			&((struct vfe_endframe *)data)->extra,
@@ -92,19 +92,21 @@
 	}
 		break;
 	case VFE_MSG_OUTPUT_S: {
-		pinfo->y_phy = paddr_s_y;
-		pinfo->cbcr_phy = paddr_s_cbcr;
+		pinfo->p0_phy = paddr_s_y;
+		pinfo->p1_phy = paddr_s_cbcr;
+		pinfo->p2_phy = pinfo->p0_phy;
 		pinfo->output_id = OUTPUT_TYPE_S;
 		CDBG("vfe_7x_convert: y_phy = 0x%x cbcr_phy = 0x%x\n",
-					pinfo->y_phy, pinfo->cbcr_phy);
+					pinfo->p0_phy, pinfo->p1_phy);
 	}
 		break;
 	case VFE_MSG_OUTPUT_T: {
-		pinfo->y_phy = paddr_t_y;
-		pinfo->cbcr_phy = paddr_t_cbcr;
+		pinfo->p0_phy = paddr_t_y;
+		pinfo->p1_phy = paddr_t_cbcr;
+		pinfo->p2_phy = pinfo->p0_phy;
 		pinfo->output_id = OUTPUT_TYPE_T;
 		CDBG("vfe_7x_convert: y_phy = 0x%x cbcr_phy = 0x%x\n",
-					pinfo->y_phy, pinfo->cbcr_phy);
+					pinfo->p0_phy, pinfo->p1_phy);
 	}
 		break;
 	case VFE_MSG_STATS_AF:
@@ -354,19 +356,20 @@
 
 		CDBG("bufnum1 = %d\n", ad->bufnum1);
 		if (mode == OUTPUT_1_AND_2) {
-			paddr_t_y = regptr->paddr + regptr->info.y_off;
-			paddr_t_cbcr = regptr->paddr +  regptr->info.cbcr_off;
+			paddr_t_y = regptr->paddr + regptr->info.planar0_off;
+			paddr_t_cbcr = regptr->paddr +
+			regptr->info.planar1_off;
 		}
 
 		CDBG("config_axi1: O1, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
-			regptr->paddr, regptr->info.y_off,
-			regptr->info.cbcr_off);
+			regptr->paddr, regptr->info.planar0_off,
+			regptr->info.planar1_off);
 
 		bptr = &ao->output1buffer1_y_phy;
 		for (cnt = 0; cnt < ad->bufnum1; cnt++) {
-			*bptr = regptr->paddr + regptr->info.y_off;
+			*bptr = regptr->paddr + regptr->info.planar0_off;
 			bptr++;
-			*bptr = regptr->paddr + regptr->info.cbcr_off;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
 
 			bptr++;
 			regptr++;
@@ -374,9 +377,9 @@
 
 		regptr--;
 		for (cnt = 0; cnt < (8 - ad->bufnum1); cnt++) {
-			*bptr = regptr->paddr + regptr->info.y_off;
+			*bptr = regptr->paddr + regptr->info.planar0_off;
 			bptr++;
-			*bptr = regptr->paddr + regptr->info.cbcr_off;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
 			bptr++;
 		}
 	}
@@ -385,17 +388,18 @@
 		regptr = &(ad->region[ad->bufnum1]);
 
 		CDBG("bufnum2 = %d\n", ad->bufnum2);
-		paddr_s_y = regptr->paddr +  regptr->info.y_off;
-		paddr_s_cbcr = regptr->paddr +  regptr->info.cbcr_off;
+		paddr_s_y = regptr->paddr +  regptr->info.planar0_off;
+		paddr_s_cbcr = regptr->paddr +  regptr->info.planar1_off;
 
 		CDBG("config_axi2: O2, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
-		     regptr->paddr, regptr->info.y_off, regptr->info.cbcr_off);
+			regptr->paddr, regptr->info.planar0_off,
+			regptr->info.planar1_off);
 
 		bptr = &ao->output2buffer1_y_phy;
 		for (cnt = 0; cnt < ad->bufnum2; cnt++) {
-			*bptr = regptr->paddr + regptr->info.y_off;
+			*bptr = regptr->paddr + regptr->info.planar0_off;
 			bptr++;
-			*bptr = regptr->paddr + regptr->info.cbcr_off;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
 
 			bptr++;
 			regptr++;
@@ -403,9 +407,9 @@
 
 		regptr--;
 		for (cnt = 0; cnt < (8 - ad->bufnum2); cnt++) {
-			*bptr = regptr->paddr + regptr->info.y_off;
+			*bptr = regptr->paddr + regptr->info.planar0_off;
 			bptr++;
-			*bptr = regptr->paddr + regptr->info.cbcr_off;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
 			bptr++;
 		}
 	}
@@ -563,10 +567,10 @@
 		fack.header = VFE_FRAME_ACK;
 
 		fack.output2newybufferaddress =
-			(void *)(p + b->y_off);
+			(void *)(p + b->planar0_off);
 
 		fack.output2newcbcrbufferaddress =
-			(void *)(p + b->cbcr_off);
+			(void *)(p + b->planar1_off);
 
 		vfecmd->queue = QDSP_CMDQUEUE;
 		vfecmd->length = sizeof(struct vfe_outputack);
diff --git a/drivers/media/video/msm/msm_vfe8x.c b/drivers/media/video/msm/msm_vfe8x.c
index 0bf1785..a99c6f1 100644
--- a/drivers/media/video/msm/msm_vfe8x.c
+++ b/drivers/media/video/msm/msm_vfe8x.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -122,10 +122,10 @@
 
 			for (j = 0; j < ao->output1.fragmentCount; j++) {
 
-				*p1 = regptr->paddr + regptr->info.y_off;
+				*p1 = regptr->paddr + regptr->info.planar0_off;
 				p1++;
 
-				*p2 = regptr->paddr + regptr->info.cbcr_off;
+				*p2 = regptr->paddr + regptr->info.planar1_off;
 				p2++;
 			}
 			regptr++;
@@ -144,15 +144,16 @@
 
 			CDBG("config_axi: O2, phy = 0x%lx, y_off = %d, "\
 			     "cbcr_off = %d\n", regptr->paddr,
-			     regptr->info.y_off, regptr->info.cbcr_off);
+				regptr->info.planar0_off,
+				regptr->info.planar1_off);
 
 			for (j = 0; j < ao->output2.fragmentCount; j++) {
 
-				*p1 = regptr->paddr + regptr->info.y_off;
+				*p1 = regptr->paddr + regptr->info.planar0_off;
 				CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
 				p1++;
 
-				*p2 = regptr->paddr + regptr->info.cbcr_off;
+				*p2 = regptr->paddr + regptr->info.planar1_off;
 				CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
 				p2++;
 			}
@@ -174,15 +175,15 @@
 
 		CDBG("config_axi: O1, phy = 0x%lx, y_off = %d, "\
 			 "cbcr_off = %d\n", regptr->paddr,
-			 regptr->info.y_off, regptr->info.cbcr_off);
+			 regptr->info.planar0_off, regptr->info.planar1_off);
 
 			for (j = 0; j < ao->output1.fragmentCount; j++) {
 
-				*p1 = regptr->paddr + regptr->info.y_off;
+				*p1 = regptr->paddr + regptr->info.planar0_off;
 				CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
 				p1++;
 
-				*p2 = regptr->paddr + regptr->info.cbcr_off;
+				*p2 = regptr->paddr + regptr->info.planar1_off;
 				CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
 				p2++;
 			}
@@ -194,15 +195,15 @@
 
 		CDBG("config_axi: O2, phy = 0x%lx, y_off = %d, "\
 			 "cbcr_off = %d\n", regptr1->paddr,
-			 regptr1->info.y_off, regptr1->info.cbcr_off);
+			 regptr1->info.planar0_off, regptr1->info.planar1_off);
 
 			for (j = 0; j < ao->output2.fragmentCount; j++) {
-
-				*p1 = regptr1->paddr + regptr1->info.y_off;
+				*p1 = regptr1->paddr +
+					regptr1->info.planar0_off;
 				CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
 				p1++;
-
-				*p2 = regptr1->paddr + regptr1->info.cbcr_off;
+				*p2 = regptr1->paddr +
+					r1->info.planar1_off;
 				CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
 				p2++;
 			}
@@ -689,9 +690,9 @@
 		b = (struct msm_frame *)(cmd->value);
 		p = *(unsigned long *)data;
 
-			fack.ybufaddr[0] = (uint32_t) (p + b->y_off);
+			fack.ybufaddr[0] = (uint32_t) (p + b->planar0_off);
 
-			fack.chromabufaddr[0] = (uint32_t) (p + b->cbcr_off);
+			fack.chromabufaddr[0] = (uint32_t) (p + b->planar1_off);
 
 		if (b->path == OUTPUT_TYPE_P)
 			vfe_output_p_ack(&fack);
diff --git a/drivers/media/video/msm/msm_vfe8x_proc.c b/drivers/media/video/msm/msm_vfe8x_proc.c
index 9764557..055b244 100644
--- a/drivers/media/video/msm/msm_vfe8x_proc.c
+++ b/drivers/media/video/msm/msm_vfe8x_proc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -608,11 +608,12 @@
 	switch (type) {
 	case VFE_MSG_OUTPUT_P:
 	case VFE_MSG_OUTPUT_V:{
-		pinfo->y_phy =
+		pinfo->planar0_off =
 			((struct vfe_message *)data)->_u.msgOutput2.yBuffer;
-		pinfo->cbcr_phy =
+		pinfo->planar1_off =
 			((struct vfe_message *)data)->_u.msgOutput2.
 			cbcrBuffer;
+		pinfo->planar2_off = pinfo->planar0_off;
 		ctrl->extdata.bpcInfo =
 			((struct vfe_message *)data)->_u.msgOutput2.bpcInfo;
 		ctrl->extdata.asfInfo =
diff --git a/drivers/media/video/msm/msm_vpe.c b/drivers/media/video/msm/msm_vpe.c
index 3a7faa2..fcf2495 100644
--- a/drivers/media/video/msm/msm_vpe.c
+++ b/drivers/media/video/msm/msm_vpe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
@@ -466,6 +466,11 @@
 	struct msm_vpe_resp rp;
 	memset(&rp, 0, sizeof(rp));
 	spin_lock_irqsave(&vpe_ctrl->lock, flags);
+	if (vpe_ctrl->state == VPE_STATE_IDLE) {
+		pr_err("%s VPE is in IDLE state. Ignore the ack msg", __func__);
+		spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
+		return;
+	}
 	rp.type = vpe_ctrl->pp_frame_info->pp_frame_cmd.path;
 	rp.extdata = (void *)vpe_ctrl->pp_frame_info;
 	rp.extlen = sizeof(*vpe_ctrl->pp_frame_info);
@@ -558,7 +563,6 @@
 		spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
 		return rc;
 	}
-	vpe_ctrl->state = VPE_STATE_IDLE;
 	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
 
 	msm_cam_clk_enable(&vpe_ctrl->pdev->dev, vpe_clk_info,
@@ -569,6 +573,9 @@
 	vpe_ctrl->fs_vpe = NULL;
 	disable_irq(vpe_ctrl->vpeirq->start);
 	tasklet_kill(&vpe_tasklet);
+	spin_lock_irqsave(&vpe_ctrl->lock, flags);
+	vpe_ctrl->state = VPE_STATE_IDLE;
+	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
 	return rc;
 }
 
diff --git a/drivers/media/video/msm/msm_vpe1.c b/drivers/media/video/msm/msm_vpe1.c
index 891816f..5f128e1 100644
--- a/drivers/media/video/msm/msm_vpe1.c
+++ b/drivers/media/video/msm/msm_vpe1.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
@@ -709,15 +709,15 @@
 	return 1;
 }
 
-void msm_send_frame_to_vpe(uint32_t pyaddr, uint32_t pcbcraddr,
+void msm_send_frame_to_vpe(uint32_t p0_phy_add, uint32_t p1_phy_add,
 		struct timespec *ts, int output_type)
 {
 	uint32_t temp_pyaddr = 0, temp_pcbcraddr = 0;
 
-	CDBG("vpe input, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
-		pyaddr, pcbcraddr);
-	msm_io_w(pyaddr, vpe_device->vpebase + VPE_SRCP0_ADDR_OFFSET);
-	msm_io_w(pcbcraddr, vpe_device->vpebase + VPE_SRCP1_ADDR_OFFSET);
+	CDBG("vpe input, p0_phy_add = 0x%x, p1_phy_add = 0x%x\n",
+		p0_phy_add, p1_phy_add);
+	msm_io_w(p0_phy_add, vpe_device->vpebase + VPE_SRCP0_ADDR_OFFSET);
+	msm_io_w(p1_phy_add, vpe_device->vpebase + VPE_SRCP1_ADDR_OFFSET);
 
 	if (vpe_ctrl->state == VPE_STATE_ACTIVE)
 		CDBG(" =====VPE is busy!!!  Wrong!========\n");
@@ -881,7 +881,7 @@
 		vpe_update_scaler_with_dis(&(vpe_buf->vpe_crop),
 					&(vpe_ctrl->dis_offset));
 
-		msm_send_frame_to_vpe(vpe_buf->y_phy, vpe_buf->cbcr_phy,
+		msm_send_frame_to_vpe(vpe_buf->p0_phy, vpe_buf->p1_phy,
 						&(vpe_buf->ts), OUTPUT_TYPE_V);
 
 		if (!qcmd || !atomic_read(&qcmd->on_heap)) {
@@ -919,10 +919,10 @@
 
 	CDBG("In vpe_addr_convert output_id = %d\n", pinfo->output_id);
 
-	pinfo->y_phy =
-		((struct vpe_message *)data)->_u.msgOut.yBuffer;
-	pinfo->cbcr_phy =
-		((struct vpe_message *)data)->_u.msgOut.cbcrBuffer;
+	pinfo->p0_phy =
+		((struct vpe_message *)data)->_u.msgOut.p0_Buffer;
+	pinfo->p1_phy =
+		((struct vpe_message *)data)->_u.msgOut.p1_Buffer;
 	*ext  = vpe_ctrl->extdata;
 	*elen = vpe_ctrl->extlen;
 }
@@ -987,10 +987,10 @@
 
 	regp1 = &(ad->region[0]);
 	/* for video  Y address */
-	p1 = (regp1->paddr + regp1->info.y_off);
+	p1 = (regp1->paddr + regp1->info.planar0_off);
 	msm_io_w(p1, vpe_device->vpebase + VPE_OUTP0_ADDR_OFFSET);
 	/* for video  CbCr address */
-	p1 = (regp1->paddr + regp1->info.cbcr_off);
+	p1 = (regp1->paddr + regp1->info.planar1_off);
 	msm_io_w(p1, vpe_device->vpebase + VPE_OUTP1_ADDR_OFFSET);
 
 	return 0;
@@ -1048,8 +1048,8 @@
 	vpe_ctrl->frame_pack = frame_pack;
 	vpe_ctrl->output_type = output_id;
 
-	input_stride = (st_half.buf_cbcr_stride * (1<<16)) +
-		st_half.buf_y_stride;
+	input_stride = (st_half.buf_p1_stride * (1<<16)) +
+		st_half.buf_p0_stride;
 
 	msm_io_w(input_stride, vpe_device->vpebase + VPE_SRC_YSTRIDE1_OFFSET);
 
@@ -1059,15 +1059,16 @@
 	msm_send_frame_to_vpe(pyaddr, pcbcraddr, ts, output_id);
 }
 
-static void vpe_send_outmsg(uint8_t msgid, uint32_t pyaddr,
-	uint32_t pcbcraddr)
+static void vpe_send_outmsg(uint8_t msgid, uint32_t p0_addr,
+	uint32_t p1_addr, uint32_t p2_addr)
 {
 	struct vpe_message msg;
 	uint8_t outid;
 	msg._d = outid = msgid;
 	msg._u.msgOut.output_id   = msgid;
-	msg._u.msgOut.yBuffer     = pyaddr;
-	msg._u.msgOut.cbcrBuffer  = pcbcraddr;
+	msg._u.msgOut.p0_Buffer = p0_addr;
+	msg._u.msgOut.p1_Buffer = p1_addr;
+	msg._u.msgOut.p2_Buffer = p2_addr;
 	vpe_proc_ops(outid, &msg, sizeof(struct vpe_message));
 	return;
 }
@@ -1203,10 +1204,11 @@
 		if (vpe_ctrl->output_type == OUTPUT_TYPE_ST_R) {
 			CDBG("vpe send out R msg.\n");
 			vpe_send_outmsg(MSG_ID_VPE_OUTPUT_ST_R, pyaddr,
-				pcbcraddr);
+				pcbcraddr, pyaddr);
 		} else if (vpe_ctrl->output_type == OUTPUT_TYPE_V) {
 			CDBG("vpe send out V msg.\n");
-			vpe_send_outmsg(MSG_ID_VPE_OUTPUT_V, pyaddr, pcbcraddr);
+			vpe_send_outmsg(MSG_ID_VPE_OUTPUT_V, pyaddr,
+				pcbcraddr, pyaddr);
 		}
 
 		vpe_ctrl->output_type = 0;
diff --git a/drivers/media/video/msm/msm_vpe1.h b/drivers/media/video/msm/msm_vpe1.h
index ed7112e..f4d328d 100644
--- a/drivers/media/video/msm/msm_vpe1.h
+++ b/drivers/media/video/msm/msm_vpe1.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 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
@@ -212,8 +212,9 @@
 
 struct vpe_msg_output {
 	uint8_t   output_id;
-	uint32_t  yBuffer;
-	uint32_t  cbcrBuffer;
+	uint32_t  p0_Buffer;
+	uint32_t  p1_Buffer;
+	uint32_t  p2_Buffer;
 	uint32_t  frameCounter;
 };
 
diff --git a/drivers/mfd/pm8038-core.c b/drivers/mfd/pm8038-core.c
index c90ea16..8a9d289 100644
--- a/drivers/mfd/pm8038-core.c
+++ b/drivers/mfd/pm8038-core.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
@@ -21,6 +21,7 @@
 #include <linux/msm_ssbi.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/pm8xxx/pm8038.h>
+#include <linux/mfd/pm8xxx/pm8921.h>
 #include <linux/mfd/pm8xxx/core.h>
 #include <linux/mfd/pm8xxx/regulator.h>
 
@@ -155,6 +156,63 @@
 	.num_resources	= ARRAY_SIZE(adc_cell_resources),
 };
 
+static const struct resource charger_cell_resources[] __devinitconst = {
+	SINGLE_IRQ_RESOURCE("USBIN_VALID_IRQ", PM8921_USBIN_VALID_IRQ),
+	SINGLE_IRQ_RESOURCE("USBIN_OV_IRQ", PM8921_USBIN_OV_IRQ),
+	SINGLE_IRQ_RESOURCE("BATT_INSERTED_IRQ", PM8921_BATT_INSERTED_IRQ),
+	SINGLE_IRQ_RESOURCE("VBATDET_LOW_IRQ", PM8921_VBATDET_LOW_IRQ),
+	SINGLE_IRQ_RESOURCE("USBIN_UV_IRQ", PM8921_USBIN_UV_IRQ),
+	SINGLE_IRQ_RESOURCE("VBAT_OV_IRQ", PM8921_VBAT_OV_IRQ),
+	SINGLE_IRQ_RESOURCE("CHGWDOG_IRQ", PM8921_CHGWDOG_IRQ),
+	SINGLE_IRQ_RESOURCE("VCP_IRQ", PM8921_VCP_IRQ),
+	SINGLE_IRQ_RESOURCE("ATCDONE_IRQ", PM8921_ATCDONE_IRQ),
+	SINGLE_IRQ_RESOURCE("ATCFAIL_IRQ", PM8921_ATCFAIL_IRQ),
+	SINGLE_IRQ_RESOURCE("CHGDONE_IRQ", PM8921_CHGDONE_IRQ),
+	SINGLE_IRQ_RESOURCE("CHGFAIL_IRQ", PM8921_CHGFAIL_IRQ),
+	SINGLE_IRQ_RESOURCE("CHGSTATE_IRQ", PM8921_CHGSTATE_IRQ),
+	SINGLE_IRQ_RESOURCE("LOOP_CHANGE_IRQ", PM8921_LOOP_CHANGE_IRQ),
+	SINGLE_IRQ_RESOURCE("FASTCHG_IRQ", PM8921_FASTCHG_IRQ),
+	SINGLE_IRQ_RESOURCE("TRKLCHG_IRQ", PM8921_TRKLCHG_IRQ),
+	SINGLE_IRQ_RESOURCE("BATT_REMOVED_IRQ", PM8921_BATT_REMOVED_IRQ),
+	SINGLE_IRQ_RESOURCE("BATTTEMP_HOT_IRQ", PM8921_BATTTEMP_HOT_IRQ),
+	SINGLE_IRQ_RESOURCE("CHGHOT_IRQ", PM8921_CHGHOT_IRQ),
+	SINGLE_IRQ_RESOURCE("BATTTEMP_COLD_IRQ", PM8921_BATTTEMP_COLD_IRQ),
+	SINGLE_IRQ_RESOURCE("CHG_GONE_IRQ", PM8921_CHG_GONE_IRQ),
+	SINGLE_IRQ_RESOURCE("BAT_TEMP_OK_IRQ", PM8921_BAT_TEMP_OK_IRQ),
+	SINGLE_IRQ_RESOURCE("COARSE_DET_LOW_IRQ", PM8921_COARSE_DET_LOW_IRQ),
+	SINGLE_IRQ_RESOURCE("VDD_LOOP_IRQ", PM8921_VDD_LOOP_IRQ),
+	SINGLE_IRQ_RESOURCE("VREG_OV_IRQ", PM8921_VREG_OV_IRQ),
+	SINGLE_IRQ_RESOURCE("VBATDET_IRQ", PM8921_VBATDET_IRQ),
+	SINGLE_IRQ_RESOURCE("BATFET_IRQ", PM8921_BATFET_IRQ),
+	SINGLE_IRQ_RESOURCE("PSI_IRQ", PM8921_PSI_IRQ),
+	SINGLE_IRQ_RESOURCE("DCIN_VALID_IRQ", PM8921_DCIN_VALID_IRQ),
+	SINGLE_IRQ_RESOURCE("DCIN_OV_IRQ", PM8921_DCIN_OV_IRQ),
+	SINGLE_IRQ_RESOURCE("DCIN_UV_IRQ", PM8921_DCIN_UV_IRQ),
+};
+
+static const struct resource bms_cell_resources[] __devinitconst = {
+	SINGLE_IRQ_RESOURCE("PM8921_BMS_SBI_WRITE_OK", PM8921_BMS_SBI_WRITE_OK),
+	SINGLE_IRQ_RESOURCE("PM8921_BMS_CC_THR", PM8921_BMS_CC_THR),
+	SINGLE_IRQ_RESOURCE("PM8921_BMS_VSENSE_THR", PM8921_BMS_VSENSE_THR),
+	SINGLE_IRQ_RESOURCE("PM8921_BMS_VSENSE_FOR_R", PM8921_BMS_VSENSE_FOR_R),
+	SINGLE_IRQ_RESOURCE("PM8921_BMS_OCV_FOR_R", PM8921_BMS_OCV_FOR_R),
+	SINGLE_IRQ_RESOURCE("PM8921_BMS_GOOD_OCV", PM8921_BMS_GOOD_OCV),
+	SINGLE_IRQ_RESOURCE("PM8921_BMS_VSENSE_AVG", PM8921_BMS_VSENSE_AVG),
+};
+
+static struct mfd_cell charger_cell __devinitdata = {
+	.name		= PM8921_CHARGER_DEV_NAME,
+	.id		= -1,
+	.resources	= charger_cell_resources,
+	.num_resources	= ARRAY_SIZE(charger_cell_resources),
+};
+
+static struct mfd_cell bms_cell __devinitdata = {
+	.name		= PM8921_BMS_DEV_NAME,
+	.id		= -1,
+	.resources	= bms_cell_resources,
+	.num_resources	= ARRAY_SIZE(bms_cell_resources),
+};
 static const struct resource mpp_cell_resources[] __devinitconst = {
 	{
 		.start	= PM8038_IRQ_BLOCK_BIT(PM8038_MPP_BLOCK_START, 0),
@@ -470,6 +528,39 @@
 		}
 	}
 
+	if (pdata->charger_pdata) {
+		pdata->charger_pdata->charger_cdata.vbat_channel = CHANNEL_VBAT;
+		pdata->charger_pdata->charger_cdata.batt_temp_channel
+						= CHANNEL_BATT_THERM;
+		pdata->charger_pdata->charger_cdata.batt_id_channel
+						= CHANNEL_BATT_ID;
+		charger_cell.platform_data = pdata->charger_pdata;
+		charger_cell.pdata_size =
+				sizeof(struct pm8921_charger_platform_data);
+		ret = mfd_add_devices(pmic->dev, 0, &charger_cell, 1, NULL,
+					irq_base);
+		if (ret) {
+			pr_err("Failed to add charger subdevice ret=%d\n", ret);
+			goto bail;
+		}
+	}
+
+	if (pdata->bms_pdata) {
+		pdata->bms_pdata->bms_cdata.batt_temp_channel
+						= CHANNEL_BATT_THERM;
+		pdata->bms_pdata->bms_cdata.vbat_channel = CHANNEL_VBAT;
+		pdata->bms_pdata->bms_cdata.ref625mv_channel = CHANNEL_625MV;
+		pdata->bms_pdata->bms_cdata.ref1p25v_channel = CHANNEL_125V;
+		pdata->bms_pdata->bms_cdata.batt_id_channel = CHANNEL_BATT_ID;
+		bms_cell.platform_data = pdata->bms_pdata;
+		bms_cell.pdata_size = sizeof(struct pm8921_bms_platform_data);
+		ret = mfd_add_devices(pmic->dev, 0, &bms_cell, 1, NULL,
+					irq_base);
+		if (ret) {
+			pr_err("Failed to add bms subdevice ret=%d\n", ret);
+			goto bail;
+		}
+	}
 	return 0;
 bail:
 	if (pmic->irq_chip) {
diff --git a/drivers/mfd/timpani-codec.c b/drivers/mfd/timpani-codec.c
index d2c2eb4..4b9aef2 100644
--- a/drivers/mfd/timpani-codec.c
+++ b/drivers/mfd/timpani-codec.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
@@ -2819,7 +2819,7 @@
 	u8 reg_mask = 0;
 	int rc = 0;
 
-	for (i = 0; i < 0xEF; i++) {
+	for (i = 0; i < ARRAY_SIZE(timpani_regset); i++) {
 		if (timpani_regset[i].reg_addr == reg) {
 			for (j = 0; j < TIMPANI_MAX_FIELDS; j++) {
 				fld_mask = timpani_regset[i].fld_ref_cnt[j].mask
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/misc/tzcom.c b/drivers/misc/tzcom.c
index ba03064..e662f43 100644
--- a/drivers/misc/tzcom.c
+++ b/drivers/misc/tzcom.c
@@ -1,6 +1,6 @@
 /* Qualcomm TrustZone communicator driver
  *
- * 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
@@ -28,6 +28,7 @@
 #include <linux/mutex.h>
 #include <linux/android_pmem.h>
 #include <linux/io.h>
+#include <linux/ion.h>
 #include <mach/scm.h>
 #include <mach/peripheral-loader.h>
 #include <linux/tzcom.h>
@@ -53,7 +54,7 @@
 static struct class *driver_class;
 static dev_t tzcom_device_no;
 static struct cdev tzcom_cdev;
-
+struct ion_client *ion_clnt;
 static u8 *sb_in_virt;
 static s32 sb_in_phys;
 static size_t sb_in_length = 20 * SZ_1K;
@@ -280,13 +281,13 @@
  *      _________________________________________________________
  *                              OUTPUT SHARED BUFFER
  */
-static int tzcom_send_cmd(struct tzcom_data_t *data, void __user *argp)
+static int __tzcom_send_cmd(struct tzcom_data_t *data,
+			struct tzcom_send_cmd_op_req *req)
 {
 	int ret = 0;
 	unsigned long flags;
 	u32 reqd_len_sb_in = 0;
 	u32 reqd_len_sb_out = 0;
-	struct tzcom_send_cmd_op_req req;
 	struct tzcom_command cmd;
 	struct tzcom_response resp;
 	struct tzcom_callback *next_callback;
@@ -296,30 +297,24 @@
 	size_t new_entry_len = 0;
 	struct tzcom_registered_svc_list *ptr_svc;
 
-	ret = copy_from_user(&req, argp, sizeof(req));
-	if (ret) {
-		PERR("copy_from_user failed");
-		return ret;
-	}
-
-	if (req.cmd_buf == NULL || req.resp_buf == NULL) {
+	if (req->cmd_buf == NULL || req->resp_buf == NULL) {
 		PERR("cmd buffer or response buffer is null");
 		return -EINVAL;
 	}
 
-	if (req.cmd_len <= 0 || req.resp_len <= 0 ||
-		req.cmd_len > sb_in_length || req.resp_len > sb_in_length) {
+	if (req->cmd_len <= 0 || req->resp_len <= 0 ||
+		req->cmd_len > sb_in_length || req->resp_len > sb_in_length) {
 		PERR("cmd buffer length or "
 				"response buffer length not valid");
 		return -EINVAL;
 	}
 	PDEBUG("received cmd_req.req: 0x%p",
-				req.cmd_buf);
+				req->cmd_buf);
 	PDEBUG("received cmd_req.rsp size: %u, ptr: 0x%p",
-			req.resp_len,
-			req.resp_buf);
+			req->resp_len,
+			req->resp_buf);
 
-	reqd_len_sb_in = req.cmd_len + req.resp_len;
+	reqd_len_sb_in = req->cmd_len + req->resp_len;
 	if (reqd_len_sb_in > sb_in_length) {
 		PDEBUG("Not enough memory to fit cmd_buf and "
 				"resp_buf. Required: %u, Available: %u",
@@ -327,23 +322,25 @@
 		return -ENOMEM;
 	}
 
-	/* Copy req.cmd_buf to SB in and set req.resp_buf to SB in + cmd_len */
+	/* Copy req->cmd_buf to SB in and set
+	 * req->resp_buf to SB in + cmd_len
+	 */
 	mutex_lock(&sb_in_lock);
 	PDEBUG("Before memcpy on sb_in");
-	memcpy(sb_in_virt, req.cmd_buf, req.cmd_len);
+	memcpy(sb_in_virt, req->cmd_buf, req->cmd_len);
 	PDEBUG("After memcpy on sb_in");
 
 	/* cmd_type will always be a new here */
 	cmd.cmd_type = TZ_SCHED_CMD_NEW;
 	cmd.sb_in_cmd_addr = (u8 *) tzcom_virt_to_phys(sb_in_virt);
-	cmd.sb_in_cmd_len = req.cmd_len;
+	cmd.sb_in_cmd_len = req->cmd_len;
 
 	resp.cmd_status = TZ_SCHED_STATUS_INCOMPLETE;
 	resp.sb_in_rsp_addr = (u8 *) tzcom_virt_to_phys(sb_in_virt +
-			req.cmd_len);
-	resp.sb_in_rsp_len = req.resp_len;
+			req->cmd_len);
+	resp.sb_in_rsp_len = req->resp_len;
 
-	PDEBUG("before call tzcom_scm_call, cmd_id = : %u", req.cmd_id);
+	PDEBUG("before call tzcom_scm_call, cmd_id = : %u", req->cmd_id);
 	PDEBUG("before call tzcom_scm_call, sizeof(cmd) = : %u", sizeof(cmd));
 
 	ret = tzcom_scm_call((const void *) &cmd, sizeof(cmd),
@@ -442,13 +439,31 @@
 
 	mutex_lock(&sb_in_lock);
 	resp.sb_in_rsp_addr = sb_in_virt + cmd.sb_in_cmd_len;
-	resp.sb_in_rsp_len = req.resp_len;
-	memcpy(req.resp_buf, resp.sb_in_rsp_addr, resp.sb_in_rsp_len);
+	resp.sb_in_rsp_len = req->resp_len;
+	memcpy(req->resp_buf, resp.sb_in_rsp_addr, resp.sb_in_rsp_len);
 	/* Zero out memory for security purpose */
 	memset(sb_in_virt, 0, reqd_len_sb_in);
 	mutex_unlock(&sb_in_lock);
 
-	PDEBUG("sending cmd_req.rsp "
+	return ret;
+}
+
+
+static int tzcom_send_cmd(struct tzcom_data_t *data, void __user *argp)
+{
+	int ret = 0;
+	struct tzcom_send_cmd_op_req req;
+
+	ret = copy_from_user(&req, argp, sizeof(req));
+	if (ret) {
+		PERR("copy_from_user failed");
+		return ret;
+	}
+	ret = __tzcom_send_cmd(data, &req);
+	if (ret)
+		return ret;
+
+	PDEBUG("sending cmd_req->rsp "
 			"size: %u, ptr: 0x%p", req.resp_len,
 			req.resp_buf);
 	ret = copy_to_user(argp, &req, sizeof(req));
@@ -456,7 +471,99 @@
 		PDEBUG("copy_to_user failed");
 		return ret;
 	}
+	return ret;
+}
 
+static int __tzcom_send_cmd_req_clean_up(
+			struct tzcom_send_cmd_fd_op_req *req)
+{
+	char *field;
+	uint32_t *update;
+	int ret = 0;
+	int i = 0;
+
+	for (i = 0; i < MAX_ION_FD; i++) {
+		if (req->ifd_data[i].fd != 0) {
+			field = (char *)req->cmd_buf +
+					req->ifd_data[i].cmd_buf_offset;
+			update = (uint32_t *) field;
+			*update = 0;
+		}
+	}
+	return ret;
+}
+
+static int __tzcom_update_with_phy_addr(
+			struct tzcom_send_cmd_fd_op_req *req)
+{
+	struct ion_handle *ihandle;
+	char *field;
+	uint32_t *update;
+	ion_phys_addr_t pa;
+	int ret = 0;
+	int i = 0;
+	uint32_t length;
+
+	for (i = 0; i < MAX_ION_FD; i++) {
+		if (req->ifd_data[i].fd != 0) {
+			/* Get the handle of the shared fd */
+			ihandle = ion_import_fd(ion_clnt, req->ifd_data[i].fd);
+			if (ihandle == NULL) {
+				PERR("Ion client can't retrieve the handle\n");
+				return -ENOMEM;
+			}
+			field = (char *) req->cmd_buf +
+						req->ifd_data[i].cmd_buf_offset;
+			update = (uint32_t *) field;
+
+			/* Populate the cmd data structure with the phys_addr */
+			ret = ion_phys(ion_clnt, ihandle, &pa, &length);
+			if (ret)
+				return -ENOMEM;
+
+			*update = (uint32_t)pa;
+			ion_free(ion_clnt, ihandle);
+		}
+	}
+	return ret;
+}
+
+static int tzcom_send_cmd_with_fd(struct tzcom_data_t *data,
+					void __user *argp)
+{
+	int ret = 0;
+	struct tzcom_send_cmd_fd_op_req req;
+	struct tzcom_send_cmd_op_req send_cmd_req;
+
+	ret = copy_from_user(&req, argp, sizeof(req));
+	if (ret) {
+		PERR("copy_from_user failed");
+		return ret;
+	}
+
+	send_cmd_req.cmd_id = req.cmd_id;
+	send_cmd_req.cmd_buf = req.cmd_buf;
+	send_cmd_req.cmd_len = req.cmd_len;
+	send_cmd_req.resp_buf = req.resp_buf;
+	send_cmd_req.resp_len = req.resp_len;
+
+	ret = __tzcom_update_with_phy_addr(&req);
+	if (ret)
+		return ret;
+	ret = __tzcom_send_cmd(data, &send_cmd_req);
+	__tzcom_send_cmd_req_clean_up(&req);
+
+	if (ret)
+		return ret;
+
+	PDEBUG("sending cmd_req->rsp "
+			"size: %u, ptr: 0x%p", req.resp_len,
+			req.resp_buf);
+	ret = copy_to_user(argp, &req, sizeof(req));
+	if (ret) {
+		PDEBUG("copy_to_user failed");
+		return ret;
+	}
 	return ret;
 }
 
@@ -713,6 +820,19 @@
 			PERR("failed tzcom_send_cmd: %d", ret);
 		break;
 	}
+	case TZCOM_IOCTL_SEND_CMD_FD_REQ: {
+		PDEBUG("ioctl send_cmd_req()");
+		/* Only one client allowed here at a time */
+		mutex_lock(&send_cmd_lock);
+		atomic_inc(&tzcom_data->ioctl_count);
+		ret = tzcom_send_cmd_with_fd(tzcom_data, argp);
+		atomic_dec(&tzcom_data->ioctl_count);
+		wake_up_interruptible(&tzcom_data->abort_wq);
+		mutex_unlock(&send_cmd_lock);
+		if (ret)
+			PERR("failed tzcom_send_cmd: %d", ret);
+		break;
+	}
 	case TZCOM_IOCTL_READ_NEXT_CMD_REQ: {
 		PDEBUG("ioctl read_next_cmd_req()");
 		atomic_inc(&tzcom_data->ioctl_count);
@@ -971,7 +1091,7 @@
 	}
 	PDEBUG("sb_out virt address: %p, phys address: 0x%x",
 			sb_out_virt, tzcom_virt_to_phys(sb_out_virt));
-
+	ion_clnt = msm_ion_client_create(0x03, "tzcom");
 	/* Initialized in tzcom_open */
 	pil = NULL;
 
@@ -1012,6 +1132,7 @@
 	device_destroy(driver_class, tzcom_device_no);
 	class_destroy(driver_class);
 	unregister_chrdev_region(tzcom_device_no, 1);
+	ion_client_destroy(ion_clnt);
 }
 
 
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index dce8d6d..c3a756d 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -234,7 +234,6 @@
 	if (!skb->protocol)
 		skb->protocol = eth_type_trans(skb, dev->net);
 
-	skb->protocol = eth_type_trans (skb, dev->net);
 	dev->net->stats.rx_packets++;
 	dev->net->stats.rx_bytes += skb->len;
 
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 9f689f1..19c0115 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -19,10 +19,12 @@
  */
 
 #include <linux/errno.h>
+#include <linux/list.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 
 /* For archs that don't support NO_IRQ (such as x86), provide a dummy value */
 #ifndef NO_IRQ
@@ -386,3 +388,110 @@
 
 	return i;
 }
+
+struct intc_desc {
+	struct list_head	list;
+	struct device_node	*dev;
+	struct device_node	*interrupt_parent;
+};
+
+/**
+ * of_irq_init - Scan and init matching interrupt controllers in DT
+ * @matches: 0 terminated array of nodes to match and init function to call
+ *
+ * This function scans the device tree for matching interrupt controller nodes,
+ * and calls their initialization functions in order with parents first.
+ */
+void __init of_irq_init(const struct of_device_id *matches)
+{
+	struct device_node *np, *parent = NULL;
+	struct intc_desc *desc, *temp_desc;
+	struct list_head intc_desc_list, intc_parent_list;
+
+	INIT_LIST_HEAD(&intc_desc_list);
+	INIT_LIST_HEAD(&intc_parent_list);
+
+	for_each_matching_node(np, matches) {
+		if (!of_find_property(np, "interrupt-controller", NULL))
+			continue;
+		/*
+		 * Here, we allocate and populate an intc_desc with the node
+		 * pointer, interrupt-parent device_node etc.
+		 */
+		desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+		if (WARN_ON(!desc))
+			goto err;
+
+		desc->dev = np;
+		desc->interrupt_parent = of_irq_find_parent(np);
+		if (desc->interrupt_parent == np)
+			desc->interrupt_parent = NULL;
+		list_add_tail(&desc->list, &intc_desc_list);
+	}
+
+	/*
+	 * The root irq controller is the one without an interrupt-parent.
+	 * That one goes first, followed by the controllers that reference it,
+	 * followed by the ones that reference the 2nd level controllers, etc.
+	 */
+	while (!list_empty(&intc_desc_list)) {
+		/*
+		 * Process all controllers with the current 'parent'.
+		 * First pass will be looking for NULL as the parent.
+		 * The assumption is that NULL parent means a root controller.
+		 */
+		list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
+			const struct of_device_id *match;
+			int ret;
+			of_irq_init_cb_t irq_init_cb;
+
+			if (desc->interrupt_parent != parent)
+				continue;
+
+			list_del(&desc->list);
+			match = of_match_node(matches, desc->dev);
+			if (WARN(!match->data,
+			    "of_irq_init: no init function for %s\n",
+			    match->compatible)) {
+				kfree(desc);
+				continue;
+			}
+
+			pr_debug("of_irq_init: init %s @ %p, parent %p\n",
+				 match->compatible,
+				 desc->dev, desc->interrupt_parent);
+			irq_init_cb = match->data;
+			ret = irq_init_cb(desc->dev, desc->interrupt_parent);
+			if (ret) {
+				kfree(desc);
+				continue;
+			}
+
+			/*
+			 * This one is now set up; add it to the parent list so
+			 * its children can get processed in a subsequent pass.
+			 */
+			list_add_tail(&desc->list, &intc_parent_list);
+		}
+
+		/* Get the next pending parent that might have children */
+		desc = list_first_entry(&intc_parent_list, typeof(*desc), list);
+		if (list_empty(&intc_parent_list) || !desc) {
+			pr_err("of_irq_init: children remain, but no parents\n");
+			break;
+		}
+		list_del(&desc->list);
+		parent = desc->dev;
+		kfree(desc);
+	}
+
+	list_for_each_entry_safe(desc, temp_desc, &intc_parent_list, list) {
+		list_del(&desc->list);
+		kfree(desc);
+	}
+err:
+	list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
+		list_del(&desc->list);
+		kfree(desc);
+	}
+}
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 5b2328d..2b58215 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1319,6 +1319,40 @@
 }
 EXPORT_SYMBOL_GPL(regulator_get);
 
+static void devm_regulator_release(struct device *dev, void *res)
+{
+	regulator_put(*(struct regulator **)res);
+}
+
+/**
+ * devm_regulator_get - Resource managed regulator_get()
+ * @dev: device for regulator "consumer"
+ * @id: Supply name or regulator ID.
+ *
+ * Managed regulator_get(). Regulators returned from this function are
+ * automatically regulator_put() on driver detach. See regulator_get() for more
+ * information.
+ */
+struct regulator *devm_regulator_get(struct device *dev, const char *id)
+{
+	struct regulator **ptr, *regulator;
+
+	ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+
+	regulator = regulator_get(dev, id);
+	if (!IS_ERR(regulator)) {
+		*ptr = regulator;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return regulator;
+}
+EXPORT_SYMBOL_GPL(devm_regulator_get);
+
 /**
  * regulator_get_exclusive - obtain exclusive access to a regulator.
  * @dev: device for regulator "consumer"
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index e13b4c4..a0763da 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -3,6 +3,7 @@
  * Android IPC Subsystem
  *
  * Copyright (C) 2007-2008 Google, Inc.
+ * Copyright (c) 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
@@ -97,9 +98,9 @@
 	BINDER_DEBUG_BUFFER_ALLOC           = 1U << 13,
 	BINDER_DEBUG_PRIORITY_CAP           = 1U << 14,
 	BINDER_DEBUG_BUFFER_ALLOC_ASYNC     = 1U << 15,
+	BINDER_DEBUG_TOP_ERRORS             = 1U << 16,
 };
-static uint32_t binder_debug_mask = BINDER_DEBUG_USER_ERROR |
-	BINDER_DEBUG_FAILED_TRANSACTION | BINDER_DEBUG_DEAD_TRANSACTION;
+static uint32_t binder_debug_mask;
 module_param_named(debug_mask, binder_debug_mask, uint, S_IWUSR | S_IRUGO);
 
 static int binder_debug_no_lock;
@@ -638,7 +639,8 @@
 		goto free_range;
 
 	if (vma == NULL) {
-		printk(KERN_ERR "binder: %d: binder_alloc_buf failed to "
+		binder_debug(BINDER_DEBUG_TOP_ERRORS,
+		       "binder: %d: binder_alloc_buf failed to "
 		       "map pages in userspace, no vma\n", proc->pid);
 		goto err_no_vma;
 	}
@@ -651,7 +653,8 @@
 		BUG_ON(*page);
 		*page = alloc_page(GFP_KERNEL | __GFP_ZERO);
 		if (*page == NULL) {
-			printk(KERN_ERR "binder: %d: binder_alloc_buf failed "
+			binder_debug(BINDER_DEBUG_TOP_ERRORS,
+			       "binder: %d: binder_alloc_buf failed "
 			       "for page at %p\n", proc->pid, page_addr);
 			goto err_alloc_page_failed;
 		}
@@ -660,7 +663,8 @@
 		page_array_ptr = page;
 		ret = map_vm_area(&tmp_area, PAGE_KERNEL, &page_array_ptr);
 		if (ret) {
-			printk(KERN_ERR "binder: %d: binder_alloc_buf failed "
+			binder_debug(BINDER_DEBUG_TOP_ERRORS,
+			       "binder: %d: binder_alloc_buf failed "
 			       "to map page at %p in kernel\n",
 			       proc->pid, page_addr);
 			goto err_map_kernel_failed;
@@ -669,7 +673,8 @@
 			(uintptr_t)page_addr + proc->user_buffer_offset;
 		ret = vm_insert_page(vma, user_page_addr, page[0]);
 		if (ret) {
-			printk(KERN_ERR "binder: %d: binder_alloc_buf failed "
+			binder_debug(BINDER_DEBUG_TOP_ERRORS,
+			       "binder: %d: binder_alloc_buf failed "
 			       "to map page at %lx in userspace\n",
 			       proc->pid, user_page_addr);
 			goto err_vm_insert_page_failed;
@@ -718,7 +723,8 @@
 	size_t size;
 
 	if (proc->vma == NULL) {
-		printk(KERN_ERR "binder: %d: binder_alloc_buf, no vma\n",
+		binder_debug(BINDER_DEBUG_TOP_ERRORS,
+		       "binder: %d: binder_alloc_buf, no vma\n",
 		       proc->pid);
 		return NULL;
 	}
@@ -756,7 +762,8 @@
 		}
 	}
 	if (best_fit == NULL) {
-		printk(KERN_ERR "binder: %d: binder_alloc_buf size %zd failed, "
+		binder_debug(BINDER_DEBUG_TOP_ERRORS,
+		       "binder: %d: binder_alloc_buf size %zd failed, "
 		       "no address space\n", proc->pid, size);
 		return NULL;
 	}
@@ -991,7 +998,8 @@
 			    node->internal_strong_refs == 0 &&
 			    !(node == binder_context_mgr_node &&
 			    node->has_strong_ref)) {
-				printk(KERN_ERR "binder: invalid inc strong "
+				binder_debug(BINDER_DEBUG_TOP_ERRORS,
+					"binder: invalid inc strong "
 					"node for %d\n", node->debug_id);
 				return -EINVAL;
 			}
@@ -1007,7 +1015,8 @@
 			node->local_weak_refs++;
 		if (!node->has_weak_ref && list_empty(&node->work.entry)) {
 			if (target_list == NULL) {
-				printk(KERN_ERR "binder: invalid inc weak node "
+				binder_debug(BINDER_DEBUG_TOP_ERRORS,
+					"binder: invalid inc weak node "
 					"for %d\n", node->debug_id);
 				return -EINVAL;
 			}
@@ -1044,7 +1053,7 @@
 			if (node->proc) {
 				rb_erase(&node->rb_node, &node->proc->nodes);
 				binder_debug(BINDER_DEBUG_INTERNAL_REFS,
-					     "binder: refless node %d deleted\n",
+					    "binder: refless node %d deleted\n",
 					     node->debug_id);
 			} else {
 				hlist_del(&node->dead_node);
@@ -1263,14 +1272,16 @@
 				binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
 					     "binder: send failed reply for "
 					     "transaction %d to %d:%d\n",
-					      t->debug_id, target_thread->proc->pid,
+					      t->debug_id,
+					      target_thread->proc->pid,
 					      target_thread->pid);
 
 				binder_pop_transaction(target_thread, t);
 				target_thread->return_error = error_code;
 				wake_up_interruptible(&target_thread->wait);
 			} else {
-				printk(KERN_ERR "binder: reply failed, target "
+				binder_debug(BINDER_DEBUG_TOP_ERRORS,
+					"binder: reply failed, target "
 					"thread, %d:%d, has error code %d "
 					"already\n", target_thread->proc->pid,
 					target_thread->pid,
@@ -1308,14 +1319,15 @@
 	int debug_id = buffer->debug_id;
 
 	binder_debug(BINDER_DEBUG_TRANSACTION,
-		     "binder: %d buffer release %d, size %zd-%zd, failed at %p\n",
-		     proc->pid, buffer->debug_id,
+		     "binder: %d buffer release %d, size %zd-%zd, failed at"
+		     " %p\n", proc->pid, buffer->debug_id,
 		     buffer->data_size, buffer->offsets_size, failed_at);
 
 	if (buffer->target_node)
 		binder_dec_node(buffer->target_node, 1, 0);
 
-	offp = (size_t *)(buffer->data + ALIGN(buffer->data_size, sizeof(void *)));
+	offp = (size_t *)(buffer->data + ALIGN(buffer->data_size,
+				sizeof(void *)));
 	if (failed_at)
 		off_end = failed_at;
 	else
@@ -1325,7 +1337,8 @@
 		if (*offp > buffer->data_size - sizeof(*fp) ||
 		    buffer->data_size < sizeof(*fp) ||
 		    !IS_ALIGNED(*offp, sizeof(void *))) {
-			printk(KERN_ERR "binder: transaction release %d bad"
+			binder_debug(BINDER_DEBUG_TOP_ERRORS,
+					"binder: transaction release %d bad"
 					"offset %zd, size %zd\n", debug_id,
 					*offp, buffer->data_size);
 			continue;
@@ -1334,29 +1347,35 @@
 		switch (fp->type) {
 		case BINDER_TYPE_BINDER:
 		case BINDER_TYPE_WEAK_BINDER: {
-			struct binder_node *node = binder_get_node(proc, fp->binder);
+			struct binder_node *node = binder_get_node(proc,
+								fp->binder);
 			if (node == NULL) {
-				printk(KERN_ERR "binder: transaction release %d"
+				binder_debug(BINDER_DEBUG_TOP_ERRORS,
+					"binder: transaction release %d"
 				       " bad node %p\n", debug_id, fp->binder);
 				break;
 			}
 			binder_debug(BINDER_DEBUG_TRANSACTION,
 				     "        node %d u%p\n",
 				     node->debug_id, node->ptr);
-			binder_dec_node(node, fp->type == BINDER_TYPE_BINDER, 0);
+			binder_dec_node(node, fp->type == BINDER_TYPE_BINDER,
+									0);
 		} break;
 		case BINDER_TYPE_HANDLE:
 		case BINDER_TYPE_WEAK_HANDLE: {
-			struct binder_ref *ref = binder_get_ref(proc, fp->handle);
+			struct binder_ref *ref = binder_get_ref(proc,
+								fp->handle);
 			if (ref == NULL) {
-				printk(KERN_ERR "binder: transaction release %d"
+				binder_debug(BINDER_DEBUG_TOP_ERRORS,
+					"binder: transaction release %d"
 				       " bad handle %ld\n", debug_id,
 				       fp->handle);
 				break;
 			}
 			binder_debug(BINDER_DEBUG_TRANSACTION,
 				     "        ref %d desc %d (node %d)\n",
-				     ref->debug_id, ref->desc, ref->node->debug_id);
+				     ref->debug_id, ref->desc,
+				     ref->node->debug_id);
 			binder_dec_ref(ref, fp->type == BINDER_TYPE_HANDLE);
 		} break;
 
@@ -1368,7 +1387,8 @@
 			break;
 
 		default:
-			printk(KERN_ERR "binder: transaction release %d bad "
+			binder_debug(BINDER_DEBUG_TOP_ERRORS,
+				"binder: transaction release %d bad "
 			       "object type %lx\n", debug_id, fp->type);
 			break;
 		}
@@ -1594,15 +1614,19 @@
 		case BINDER_TYPE_BINDER:
 		case BINDER_TYPE_WEAK_BINDER: {
 			struct binder_ref *ref;
-			struct binder_node *node = binder_get_node(proc, fp->binder);
+			struct binder_node *node = binder_get_node(proc,
+								fp->binder);
 			if (node == NULL) {
-				node = binder_new_node(proc, fp->binder, fp->cookie);
+				node = binder_new_node(proc, fp->binder,
+								fp->cookie);
 				if (node == NULL) {
 					return_error = BR_FAILED_REPLY;
 					goto err_binder_new_node_failed;
 				}
-				node->min_priority = fp->flags & FLAT_BINDER_FLAG_PRIORITY_MASK;
-				node->accept_fds = !!(fp->flags & FLAT_BINDER_FLAG_ACCEPTS_FDS);
+				node->min_priority = fp->flags &
+						FLAT_BINDER_FLAG_PRIORITY_MASK;
+				node->accept_fds = !!(fp->flags &
+						FLAT_BINDER_FLAG_ACCEPTS_FDS);
 			}
 			if (fp->cookie != node->cookie) {
 				binder_user_error("binder: %d:%d sending u%p "
@@ -1632,7 +1656,8 @@
 		} break;
 		case BINDER_TYPE_HANDLE:
 		case BINDER_TYPE_WEAK_HANDLE: {
-			struct binder_ref *ref = binder_get_ref(proc, fp->handle);
+			struct binder_ref *ref = binder_get_ref(proc,
+								fp->handle);
 			if (ref == NULL) {
 				binder_user_error("binder: %d:%d got "
 					"transaction with invalid "
@@ -1648,24 +1673,31 @@
 					fp->type = BINDER_TYPE_WEAK_BINDER;
 				fp->binder = ref->node->ptr;
 				fp->cookie = ref->node->cookie;
-				binder_inc_node(ref->node, fp->type == BINDER_TYPE_BINDER, 0, NULL);
+				binder_inc_node(ref->node, fp->type ==
+						BINDER_TYPE_BINDER, 0, NULL);
 				binder_debug(BINDER_DEBUG_TRANSACTION,
-					     "        ref %d desc %d -> node %d u%p\n",
-					     ref->debug_id, ref->desc, ref->node->debug_id,
-					     ref->node->ptr);
+				      "        ref %d desc %d -> node %d u%p\n",
+				     ref->debug_id, ref->desc,
+				    ref->node->debug_id,
+				     ref->node->ptr);
 			} else {
 				struct binder_ref *new_ref;
-				new_ref = binder_get_ref_for_node(target_proc, ref->node);
+				new_ref = binder_get_ref_for_node(target_proc,
+								ref->node);
 				if (new_ref == NULL) {
 					return_error = BR_FAILED_REPLY;
 					goto err_binder_get_ref_for_node_failed;
 				}
 				fp->handle = new_ref->desc;
-				binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL);
+				binder_inc_ref(new_ref, fp->type ==
+						BINDER_TYPE_HANDLE, NULL);
 				binder_debug(BINDER_DEBUG_TRANSACTION,
-					     "        ref %d desc %d -> ref %d desc %d (node %d)\n",
-					     ref->debug_id, ref->desc, new_ref->debug_id,
-					     new_ref->desc, ref->node->debug_id);
+					     "        ref %d desc %d -> ref %d"
+					     " desc %d (node %d)\n",
+					     ref->debug_id, ref->desc,
+					     new_ref->debug_id,
+					     new_ref->desc,
+					     ref->node->debug_id);
 			}
 		} break;
 
@@ -1675,13 +1707,19 @@
 
 			if (reply) {
 				if (!(in_reply_to->flags & TF_ACCEPT_FDS)) {
-					binder_user_error("binder: %d:%d got reply with fd, %ld, but target does not allow fds\n",
-						proc->pid, thread->pid, fp->handle);
+					binder_user_error("binder: %d:%d got"
+						" reply with fd, %ld, but"
+						" target does not allow fds\n",
+						proc->pid, thread->pid,
+						fp->handle);
 					return_error = BR_FAILED_REPLY;
 					goto err_fd_not_allowed;
 				}
 			} else if (!target_node->accept_fds) {
-				binder_user_error("binder: %d:%d got transaction with fd, %ld, but target does not allow fds\n",
+				binder_user_error(
+						"binder: %d:%d got transaction"
+						" with fd, %ld, but target does"
+						" not allow fds\n",
 					proc->pid, thread->pid, fp->handle);
 				return_error = BR_FAILED_REPLY;
 				goto err_fd_not_allowed;
@@ -1689,12 +1727,15 @@
 
 			file = fget(fp->handle);
 			if (file == NULL) {
-				binder_user_error("binder: %d:%d got transaction with invalid fd, %ld\n",
+				binder_user_error(
+						"binder: %d:%d got transaction"
+						" with invalid fd, %ld\n",
 					proc->pid, thread->pid, fp->handle);
 				return_error = BR_FAILED_REPLY;
 				goto err_fget_failed;
 			}
-			target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC);
+			target_fd = task_get_unused_fd_flags(target_proc,
+								O_CLOEXEC);
 			if (target_fd < 0) {
 				fput(file);
 				return_error = BR_FAILED_REPLY;
@@ -1702,7 +1743,8 @@
 			}
 			task_fd_install(target_proc, target_fd, file);
 			binder_debug(BINDER_DEBUG_TRANSACTION,
-				     "        fd %ld -> %d\n", fp->handle, target_fd);
+				     "        fd %ld -> %d\n", fp->handle,
+								target_fd);
 			/* TODO: fput? */
 			fp->handle = target_fd;
 		} break;
@@ -1851,9 +1893,11 @@
 				break;
 			}
 			binder_debug(BINDER_DEBUG_USER_REFS,
-				     "binder: %d:%d %s ref %d desc %d s %d w %d for node %d\n",
-				     proc->pid, thread->pid, debug_string, ref->debug_id,
-				     ref->desc, ref->strong, ref->weak, ref->node->debug_id);
+				     "binder: %d:%d %s ref %d desc %d s %d w %d"
+				     " for node %d\n", proc->pid, thread->pid,
+				     debug_string, ref->debug_id, ref->desc,
+				     ref->strong, ref->weak,
+				     ref->node->debug_id);
 			break;
 		}
 		case BC_INCREFS_DONE:
@@ -1914,15 +1958,19 @@
 			binder_debug(BINDER_DEBUG_USER_REFS,
 				     "binder: %d:%d %s node %d ls %d lw %d\n",
 				     proc->pid, thread->pid,
-				     cmd == BC_INCREFS_DONE ? "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE",
-				     node->debug_id, node->local_strong_refs, node->local_weak_refs);
+				     cmd == BC_INCREFS_DONE ? "BC_INCREFS_DONE"
+							: "BC_ACQUIRE_DONE",
+				     node->debug_id, node->local_strong_refs,
+							node->local_weak_refs);
 			break;
 		}
 		case BC_ATTEMPT_ACQUIRE:
-			printk(KERN_ERR "binder: BC_ATTEMPT_ACQUIRE not supported\n");
+			binder_debug(BINDER_DEBUG_TOP_ERRORS,
+				"binder: BC_ATTEMPT_ACQUIRE not supported\n");
 			return -EINVAL;
 		case BC_ACQUIRE_RESULT:
-			printk(KERN_ERR "binder: BC_ACQUIRE_RESULT not supported\n");
+			binder_debug(BINDER_DEBUG_TOP_ERRORS,
+				"binder: BC_ACQUIRE_RESULT not supported\n");
 			return -EINVAL;
 
 		case BC_FREE_BUFFER: {
@@ -1948,9 +1996,11 @@
 				break;
 			}
 			binder_debug(BINDER_DEBUG_FREE_BUFFER,
-				     "binder: %d:%d BC_FREE_BUFFER u%p found buffer %d for %s transaction\n",
-				     proc->pid, thread->pid, data_ptr, buffer->debug_id,
-				     buffer->transaction ? "active" : "finished");
+				     "binder: %d:%d BC_FREE_BUFFER u%p found"
+				     " buffer %d for %s transaction\n",
+				     proc->pid, thread->pid, data_ptr,
+				     buffer->debug_id, buffer->transaction ?
+				     "active" : "finished");
 
 			if (buffer->transaction) {
 				buffer->transaction->buffer = NULL;
@@ -2047,13 +2097,15 @@
 			}
 
 			binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION,
-				     "binder: %d:%d %s %p ref %d desc %d s %d w %d for node %d\n",
+				     "binder: %d:%d %s %p ref %d desc %d s %d"
+				     " w %d for node %d\n",
 				     proc->pid, thread->pid,
 				     cmd == BC_REQUEST_DEATH_NOTIFICATION ?
 				     "BC_REQUEST_DEATH_NOTIFICATION" :
 				     "BC_CLEAR_DEATH_NOTIFICATION",
 				     cookie, ref->debug_id, ref->desc,
-				     ref->strong, ref->weak, ref->node->debug_id);
+				     ref->strong, ref->weak,
+				     ref->node->debug_id);
 
 			if (cmd == BC_REQUEST_DEATH_NOTIFICATION) {
 				if (ref->death) {
@@ -2067,10 +2119,12 @@
 				death = kzalloc(sizeof(*death), GFP_KERNEL);
 				if (death == NULL) {
 					thread->return_error = BR_ERROR;
-					binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
-						     "binder: %d:%d "
-						     "BC_REQUEST_DEATH_NOTIFICATION failed\n",
-						     proc->pid, thread->pid);
+					binder_debug(
+						BINDER_DEBUG_FAILED_TRANSACTION,
+						"binder: %d:%d "
+						"BC_REQUEST_DEATH_NOTIFICATION"
+						" failed\n",
+						proc->pid, thread->pid);
 					break;
 				}
 				binder_stats_created(BINDER_STAT_DEATH);
@@ -2159,7 +2213,8 @@
 		} break;
 
 		default:
-			printk(KERN_ERR "binder: %d:%d unknown command %d\n",
+			binder_debug(BINDER_DEBUG_TOP_ERRORS,
+			      "binder: %d:%d unknown command %d\n",
 			       proc->pid, thread->pid, cmd);
 			return -EINVAL;
 		}
@@ -2629,9 +2684,11 @@
 	unsigned int size = _IOC_SIZE(cmd);
 	void __user *ubuf = (void __user *)arg;
 
-	/*printk(KERN_INFO "binder_ioctl: %d:%d %x %lx\n", proc->pid, current->pid, cmd, arg);*/
+	/*binder_debug(BINDER_DEBUG_TOP_ERRORS, "binder_ioctl: %d:%d %x %lx\n",
+					proc->pid, current->pid, cmd, arg);*/
 
-	ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
+	ret = wait_event_interruptible(binder_user_error_wait,
+						binder_stop_on_user_error < 2);
 	if (ret)
 		return ret;
 
@@ -2688,20 +2745,23 @@
 		break;
 	}
 	case BINDER_SET_MAX_THREADS:
-		if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads))) {
+		if (copy_from_user(&proc->max_threads, ubuf,
+					sizeof(proc->max_threads))) {
 			ret = -EINVAL;
 			goto err;
 		}
 		break;
 	case BINDER_SET_CONTEXT_MGR:
 		if (binder_context_mgr_node != NULL) {
-			printk(KERN_ERR "binder: BINDER_SET_CONTEXT_MGR already set\n");
+			binder_debug(BINDER_DEBUG_TOP_ERRORS,
+				"binder: BINDER_SET_CONTEXT_MGR already set\n");
 			ret = -EBUSY;
 			goto err;
 		}
 		if (binder_context_mgr_uid != -1) {
 			if (binder_context_mgr_uid != current->cred->euid) {
-				printk(KERN_ERR "binder: BINDER_SET_"
+				binder_debug(BINDER_DEBUG_TOP_ERRORS,
+				       "binder: BINDER_SET_"
 				       "CONTEXT_MGR bad uid %d != %d\n",
 				       current->cred->euid,
 				       binder_context_mgr_uid);
@@ -2747,7 +2807,9 @@
 	mutex_unlock(&binder_lock);
 	wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
 	if (ret && ret != -ERESTARTSYS)
-		printk(KERN_INFO "binder: %d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret);
+		binder_debug(BINDER_DEBUG_TOP_ERRORS,
+				"binder: %d:%d ioctl %x %lx returned %d\n",
+				proc->pid, current->pid, cmd, arg, ret);
 	return ret;
 }
 
@@ -2821,7 +2883,9 @@
 #ifdef CONFIG_CPU_CACHE_VIPT
 	if (cache_is_vipt_aliasing()) {
 		while (CACHE_COLOUR((vma->vm_start ^ (uint32_t)proc->buffer))) {
-			printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p bad alignment\n", proc->pid, vma->vm_start, vma->vm_end, proc->buffer);
+			binder_debug(BINDER_DEBUG_TOP_ERRORS,
+			"binder_mmap: %d %lx-%lx maps %p bad alignment\n",
+			proc->pid, vma->vm_start, vma->vm_end, proc->buffer);
 			vma->vm_start += PAGE_SIZE;
 		}
 	}
@@ -2852,7 +2916,8 @@
 	proc->files = get_files_struct(current);
 	proc->vma = vma;
 
-	/*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n",
+	/*binder_debug(BINDER_DEBUG_TOP_ERRORS,
+		"binder_mmap: %d %lx-%lx maps %p\n",
 		 proc->pid, vma->vm_start, vma->vm_end, proc->buffer);*/
 	return 0;
 
@@ -2865,7 +2930,8 @@
 err_get_vm_area_failed:
 err_already_mapped:
 err_bad_arg:
-	printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n",
+	binder_debug(BINDER_DEBUG_TOP_ERRORS,
+		"binder_mmap: %d %lx-%lx %s failed %d\n",
 	       proc->pid, vma->vm_start, vma->vm_end, failure_string, ret);
 	return ret;
 }
@@ -3020,7 +3086,8 @@
 		if (t) {
 			t->buffer = NULL;
 			buffer->transaction = NULL;
-			printk(KERN_ERR "binder: release proc %d, "
+			binder_debug(BINDER_DEBUG_TOP_ERRORS,
+				"binder: release proc %d, "
 			       "transaction %d, not freed\n",
 			       proc->pid, t->debug_id);
 			/*BUG();*/
diff --git a/drivers/staging/qcache/qcache-main.c b/drivers/staging/qcache/qcache-main.c
index b6de268..f6838d1 100644
--- a/drivers/staging/qcache/qcache-main.c
+++ b/drivers/staging/qcache/qcache-main.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2010,2011, Dan Magenheimer, Oracle Corp.
  * Copyright (c) 2010,2011, Nitin Gupta
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * Qcache provides an in-kernel "host implementation" for transcendent memory
  * and, thus indirectly, for cleancache and frontswap.  Qcache includes a
@@ -230,7 +230,6 @@
 	budnum = zbud_budnum(zh);
 	BUG_ON(size == 0 || size > zbud_max_buddy_size());
 	zbpg = container_of(zh, struct zbud_page, buddy[budnum]);
-	ASSERT_SPINLOCK(&zbpg->lock);
 	p = (char *)zbpg;
 	if (budnum == 0)
 		p += ((sizeof(struct zbud_page) + CHUNK_SIZE - 1) &
@@ -270,7 +269,6 @@
 
 	ASSERT_SENTINEL(zbpg, ZBPG);
 	BUG_ON(!list_empty(&zbpg->bud_list));
-	ASSERT_SPINLOCK(&zbpg->lock);
 	BUG_ON(zh0->size != 0 || tmem_oid_valid(&zh0->oid));
 	BUG_ON(zh1->size != 0 || tmem_oid_valid(&zh1->oid));
 	INVERT_SENTINEL(zbpg, ZBPG);
@@ -312,7 +310,6 @@
 		return;
 	}
 	size = zbud_free(zh);
-	ASSERT_SPINLOCK(&zbpg->lock);
 	zh_other = &zbpg->buddy[(budnum == 0) ? 1 : 0];
 	if (zh_other->size == 0) { /* was unbuddied: unlist and free */
 		chunks = zbud_size_to_chunks(size) ;
@@ -372,7 +369,6 @@
 	goto init_zh;
 
 found_unbuddied:
-	ASSERT_SPINLOCK(&zbpg->lock);
 	zh0 = &zbpg->buddy[0]; zh1 = &zbpg->buddy[1];
 	BUG_ON(!((zh0->size == 0) ^ (zh1->size == 0)));
 	if (zh0->size != 0) { /* buddy0 in use, buddy1 is vacant */
diff --git a/drivers/staging/qcache/tmem.h b/drivers/staging/qcache/tmem.h
index 344561f..9f6bfbb 100644
--- a/drivers/staging/qcache/tmem.h
+++ b/drivers/staging/qcache/tmem.h
@@ -4,7 +4,7 @@
  * Transcendent memory
  *
  * Copyright (c) 2009-2011, Dan Magenheimer, Oracle Corp.
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  */
 
 #ifndef _TMEM_H_
@@ -49,8 +49,6 @@
 #define ASSERT_INVERTED_SENTINEL(_x, _y) do { } while (0)
 #endif
 
-#define ASSERT_SPINLOCK(_l)	WARN_ON(!spin_is_locked(_l))
-
 /*
  * A pool is the highest-level data structure managed by tmem and
  * usually corresponds to a large independent set of pages such as
diff --git a/drivers/thermal/msm8960_tsens.c b/drivers/thermal/msm8960_tsens.c
index 63d8666..a616ffc 100644
--- a/drivers/thermal/msm8960_tsens.c
+++ b/drivers/thermal/msm8960_tsens.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
@@ -81,7 +81,7 @@
 /* Initial temperature threshold values */
 #define TSENS_LOWER_LIMIT_TH				0x50
 #define TSENS_UPPER_LIMIT_TH				0xdf
-#define TSENS_MIN_LIMIT_TH				0x38
+#define TSENS_MIN_LIMIT_TH				0x0
 #define TSENS_MAX_LIMIT_TH				0xff
 
 #define TSENS_S0_STATUS_ADDR			(MSM_CLK_CTL_BASE + 0x00003628)
@@ -424,6 +424,15 @@
 	return tsens_tz_get_trip_temp(thermal, TSENS_TRIP_STAGE3, temp);
 }
 
+static int tsens_tz_notify(struct thermal_zone_device *thermal,
+				int count, enum thermal_trip_type type)
+{
+	/* TSENS driver does not shutdown the device.
+	   All Thermal notification are sent to the
+	   thermal daemon to take appropriate action */
+	return 1;
+}
+
 static int tsens_tz_set_trip_temp(struct thermal_zone_device *thermal,
 				   int trip, long temp)
 {
@@ -519,6 +528,7 @@
 	.get_trip_temp = tsens_tz_get_trip_temp,
 	.set_trip_temp = tsens_tz_set_trip_temp,
 	.get_crit_temp = tsens_tz_get_crit_temp,
+	.notify = tsens_tz_notify,
 };
 
 static void notify_uspace_tsens_fn(struct work_struct *work)
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/gadget/f_diag.c b/drivers/usb/gadget/f_diag.c
index f492143..10a9256 100644
--- a/drivers/usb/gadget/f_diag.c
+++ b/drivers/usb/gadget/f_diag.c
@@ -2,7 +2,7 @@
  * Diag Function Device - Route ARM9 and ARM11 DIAG messages
  * between HOST and DEVICE.
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -525,6 +525,7 @@
 	if (rc) {
 		ERROR(dev->cdev, "can't enable %s, result %d\n",
 						dev->in->name, rc);
+		dev->in->driver_data = NULL;
 		return rc;
 	}
 	dev->out->driver_data = dev;
@@ -533,6 +534,8 @@
 		ERROR(dev->cdev, "can't enable %s, result %d\n",
 						dev->out->name, rc);
 		usb_ep_disable(dev->in);
+		dev->in->driver_data = NULL;
+		dev->out->driver_data = NULL;
 		return rc;
 	}
 	schedule_work(&dev->config_work);
diff --git a/drivers/usb/gadget/f_rmnet.c b/drivers/usb/gadget/f_rmnet.c
index cbcf5ac..177176e 100644
--- a/drivers/usb/gadget/f_rmnet.c
+++ b/drivers/usb/gadget/f_rmnet.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
@@ -435,6 +435,7 @@
 	pr_debug("%s: port#%d\n", __func__, dev->port_num);
 
 	usb_ep_disable(dev->notify);
+	dev->notify->driver_data = NULL;
 
 	atomic_set(&dev->online, 0);
 
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
index de8c8ed..d9a901b 100644
--- a/drivers/usb/gadget/f_serial.c
+++ b/drivers/usb/gadget/f_serial.c
@@ -477,6 +477,7 @@
 	if (gser->notify->driver_data) {
 		DBG(cdev, "reset generic ctl ttyGS%d\n", gser->port_num);
 		usb_ep_disable(gser->notify);
+		gser->notify->driver_data = NULL;
 	}
 	gser->notify_desc = ep_choose(cdev->gadget,
 			gser->hs.notify,
@@ -519,6 +520,7 @@
 #ifdef CONFIG_MODEM_SUPPORT
 	usb_ep_fifo_flush(gser->notify);
 	usb_ep_disable(gser->notify);
+	gser->notify->driver_data = NULL;
 #endif
 	gser->online = 0;
 }
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index 0360f56..ca298cd 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -2766,14 +2766,17 @@
 	if (fsg->bulk_in_enabled) {
 		usb_ep_disable(fsg->bulk_in);
 		fsg->bulk_in_enabled = 0;
+		fsg_bulk_in->driver_data = NULL;
 	}
 	if (fsg->bulk_out_enabled) {
 		usb_ep_disable(fsg->bulk_out);
 		fsg->bulk_out_enabled = 0;
+		fsg_bulk_out->driver_data = NULL;
 	}
 	if (fsg->intr_in_enabled) {
 		usb_ep_disable(fsg->intr_in);
 		fsg->intr_in_enabled = 0;
+		fsg_intr_in->driver_data = NULL;
 	}
 
 	fsg->running = 0;
diff --git a/drivers/usb/gadget/u_bam.c b/drivers/usb/gadget/u_bam.c
index 13965de..23e0da8 100644
--- a/drivers/usb/gadget/u_bam.c
+++ b/drivers/usb/gadget/u_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
@@ -602,7 +602,7 @@
 	struct bam_ch_info	*d;
 
 	spin_lock_irqsave(&port->port_lock_ul, flags);
-	spin_lock_irqsave(&port->port_lock_dl, flags);
+	spin_lock(&port->port_lock_dl);
 
 	if (!port || !port->port_usb)
 		goto free_buf_out;
@@ -619,7 +619,7 @@
 		dev_kfree_skb_any(skb);
 
 free_buf_out:
-	spin_unlock_irqrestore(&port->port_lock_dl, flags);
+	spin_unlock(&port->port_lock_dl);
 	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 }
 
@@ -643,15 +643,17 @@
 	unsigned long		flags;
 
 	spin_lock_irqsave(&port->port_lock_ul, flags);
-	spin_lock_irqsave(&port->port_lock_dl, flags);
+	spin_lock(&port->port_lock_dl);
 	port->port_usb = 0;
-	spin_unlock_irqrestore(&port->port_lock_dl, flags);
+	spin_unlock(&port->port_lock_dl);
 	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 
 	/* disable endpoints */
 	usb_ep_disable(port->gr->out);
 	usb_ep_disable(port->gr->in);
 
+	port->gr->in->driver_data = NULL;
+	port->gr->out->driver_data = NULL;
 }
 
 static void gbam_connect_work(struct work_struct *w)
@@ -662,13 +664,13 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&port->port_lock_ul, flags);
-	spin_lock_irqsave(&port->port_lock_dl, flags);
+	spin_lock(&port->port_lock_dl);
 	if (!port->port_usb) {
-		spin_unlock_irqrestore(&port->port_lock_dl, flags);
+		spin_unlock(&port->port_lock_dl);
 		spin_unlock_irqrestore(&port->port_lock_ul, flags);
 		return;
 	}
-	spin_unlock_irqrestore(&port->port_lock_dl, flags);
+	spin_unlock(&port->port_lock_dl);
 	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 
 	if (!test_bit(BAM_CH_READY, &d->flags))
@@ -712,9 +714,9 @@
 	}
 	port->gr->out->driver_data = port;
 	spin_lock_irqsave(&port->port_lock_ul, flags);
-	spin_lock_irqsave(&port->port_lock_dl, flags);
+	spin_lock(&port->port_lock_dl);
 	port->port_usb = port->gr;
-	spin_unlock_irqrestore(&port->port_lock_dl, flags);
+	spin_unlock(&port->port_lock_dl);
 	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 
 	ret = usb_bam_connect(d->connection_idx, &d->src_pipe_idx,
@@ -773,10 +775,10 @@
 
 			/* if usb is online, try opening bam_ch */
 			spin_lock_irqsave(&port->port_lock_ul, flags);
-			spin_lock_irqsave(&port->port_lock_dl, flags);
+			spin_lock(&port->port_lock_dl);
 			if (port->port_usb)
 				queue_work(gbam_wq, &port->connect_w);
-			spin_unlock_irqrestore(&port->port_lock_dl, flags);
+			spin_unlock(&port->port_lock_dl);
 			spin_unlock_irqrestore(&port->port_lock_ul, flags);
 
 			break;
@@ -805,12 +807,12 @@
 			d = &port->data_ch;
 
 			spin_lock_irqsave(&port->port_lock_ul, flags);
-			spin_lock_irqsave(&port->port_lock_dl, flags);
+			spin_lock(&port->port_lock_dl);
 			if (port->port_usb) {
 				ep_in = port->port_usb->in;
 				ep_out = port->port_usb->out;
 			}
-			spin_unlock_irqrestore(&port->port_lock_dl, flags);
+			spin_unlock(&port->port_lock_dl);
 			spin_unlock_irqrestore(&port->port_lock_ul, flags);
 
 			if (ep_in)
@@ -944,7 +946,7 @@
 		if (!port)
 			continue;
 		spin_lock_irqsave(&port->port_lock_ul, flags);
-		spin_lock_irqsave(&port->port_lock_dl, flags);
+		spin_lock(&port->port_lock_dl);
 
 		d = &port->data_ch;
 
@@ -967,7 +969,7 @@
 				test_bit(BAM_CH_OPENED, &d->flags),
 				test_bit(BAM_CH_READY, &d->flags));
 
-		spin_unlock_irqrestore(&port->port_lock_dl, flags);
+		spin_unlock(&port->port_lock_dl);
 		spin_unlock_irqrestore(&port->port_lock_ul, flags);
 	}
 
@@ -992,7 +994,7 @@
 			continue;
 
 		spin_lock_irqsave(&port->port_lock_ul, flags);
-		spin_lock_irqsave(&port->port_lock_dl, flags);
+		spin_lock(&port->port_lock_dl);
 
 		d = &port->data_ch;
 
@@ -1002,7 +1004,7 @@
 		d->tohost_drp_cnt = 0;
 		d->tomodem_drp_cnt = 0;
 
-		spin_unlock_irqrestore(&port->port_lock_dl, flags);
+		spin_unlock(&port->port_lock_dl);
 		spin_unlock_irqrestore(&port->port_lock_ul, flags);
 	}
 	return count;
@@ -1069,10 +1071,10 @@
 		gbam_free_buffers(port);
 
 	spin_lock_irqsave(&port->port_lock_ul, flags);
-	spin_lock_irqsave(&port->port_lock_dl, flags);
+	spin_lock(&port->port_lock_dl);
 	port->port_usb = 0;
 	n_tx_req_queued = 0;
-	spin_unlock_irqrestore(&port->port_lock_dl, flags);
+	spin_unlock(&port->port_lock_dl);
 	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 
 		/* disable endpoints */
@@ -1134,7 +1136,7 @@
 		gr->out->driver_data = port;
 
 	spin_lock_irqsave(&port->port_lock_ul, flags);
-	spin_lock_irqsave(&port->port_lock_dl, flags);
+	spin_lock(&port->port_lock_dl);
 	port->port_usb = gr;
 
 		d->to_host = 0;
@@ -1142,7 +1144,7 @@
 		d->pending_with_bam = 0;
 		d->tohost_drp_cnt = 0;
 		d->tomodem_drp_cnt = 0;
-	spin_unlock_irqrestore(&port->port_lock_dl, flags);
+	spin_unlock(&port->port_lock_dl);
 	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 	}
 
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 1066f38..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;
@@ -1713,11 +1716,12 @@
 			else
 				clear_bit(B_SESS_VLD, &motg->inputs);
 		} else if (pdata->otg_control == OTG_PMIC_CONTROL) {
-			if (irq_read_line(motg->pdata->pmic_id_irq))
-				set_bit(ID, &motg->inputs);
-			else
-				clear_bit(ID, &motg->inputs);
-
+			if (pdata->pmic_id_irq) {
+				if (irq_read_line(pdata->pmic_id_irq))
+					set_bit(ID, &motg->inputs);
+				else
+					clear_bit(ID, &motg->inputs);
+			}
 			/*
 			 * VBUS initial state is reported after PMIC
 			 * driver initialization. Wait for it.
@@ -1730,10 +1734,18 @@
 		break;
 	case USB_PERIPHERAL:
 		set_bit(ID, &motg->inputs);
-		if (otgsc & OTGSC_BSV)
-			set_bit(B_SESS_VLD, &motg->inputs);
-		else
-			clear_bit(B_SESS_VLD, &motg->inputs);
+		if (pdata->otg_control == OTG_PHY_CONTROL) {
+			if (otgsc & OTGSC_BSV)
+				set_bit(B_SESS_VLD, &motg->inputs);
+			else
+				clear_bit(B_SESS_VLD, &motg->inputs);
+		} else if (pdata->otg_control == OTG_PMIC_CONTROL) {
+			/*
+			 * VBUS initial state is reported after PMIC
+			 * driver initialization. Wait for it.
+			 */
+			wait_for_completion(&pmic_vbus_init);
+		}
 		break;
 	default:
 		break;
@@ -2511,7 +2523,8 @@
 		goto free_irq;
 	}
 
-	if (motg->pdata->otg_control == OTG_PMIC_CONTROL) {
+	if (motg->pdata->mode == USB_OTG &&
+		motg->pdata->otg_control == OTG_PMIC_CONTROL) {
 		if (motg->pdata->pmic_id_irq) {
 			ret = request_irq(motg->pdata->pmic_id_irq,
 						msm_pmic_id_irq,
@@ -2545,7 +2558,8 @@
 
 	if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY) {
 		if (motg->pdata->otg_control == OTG_PMIC_CONTROL &&
-			motg->pdata->pmic_id_irq)
+			(!(motg->pdata->mode == USB_OTG) ||
+			 motg->pdata->pmic_id_irq))
 			motg->caps = ALLOW_PHY_POWER_COLLAPSE |
 				ALLOW_PHY_RETENTION |
 				ALLOW_PHY_COMP_DISABLE;
diff --git a/drivers/video/msm/external_common.h b/drivers/video/msm/external_common.h
index c795a94..2a243cd 100644
--- a/drivers/video/msm/external_common.h
+++ b/drivers/video/msm/external_common.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 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
@@ -136,10 +136,10 @@
 	 480, 10, 2, 33, TRUE, 25200, 60000, FALSE, TRUE}
 #define HDMI_SETTINGS_720x480p60_4_3					\
 	{HDMI_VFRMT_720x480p60_4_3,      720,  16,  62,  60,  TRUE,	\
-	 480, 9, 6, 30,  TRUE, 27027, 60000, FALSE, TRUE}
+	 480, 9, 6, 30,  TRUE, 27030, 60000, FALSE, TRUE}
 #define HDMI_SETTINGS_720x480p60_16_9					\
 	{HDMI_VFRMT_720x480p60_16_9,     720,  16,  62,  60,  TRUE,	\
-	 480, 9, 6, 30,  TRUE, 27027, 60000, FALSE, TRUE}
+	 480, 9, 6, 30,  TRUE, 27030, 60000, FALSE, TRUE}
 #define HDMI_SETTINGS_1280x720p60_16_9					\
 	{HDMI_VFRMT_1280x720p60_16_9,    1280, 110, 40,  220, FALSE,	\
 	 720, 5, 5, 20, FALSE, 74250, 60000, FALSE, TRUE}
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index aaad2df..fc6054f 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.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
@@ -2324,29 +2324,6 @@
 
 		msm_hdmi_init_ddc();
 
-		/* Read Bksv 5 bytes at 0x00 in HDCP port */
-		ret = hdmi_msm_ddc_read(0x74, 0x00, bksv, 5, 5, "Bksv", TRUE);
-		if (ret) {
-			DEV_ERR("%s(%d): Read BKSV failed", __func__, __LINE__);
-			goto error;
-		}
-		/* check there are 20 ones in BKSV */
-		if (hdmi_msm_count_one(bksv, 5) != 20) {
-			DEV_ERR("HDCP: BKSV read from Sink doesn't have "
-				"20 1's and 20 0's, FAIL (BKSV="
-				"%02x%02x%02x%02x%02x)\n",
-				bksv[4], bksv[3], bksv[2], bksv[1], bksv[0]);
-			ret = -EINVAL;
-			goto error;
-		}
-
-		link0_bksv_0 = bksv[3];
-		link0_bksv_0 = (link0_bksv_0 << 8) | bksv[2];
-		link0_bksv_0 = (link0_bksv_0 << 8) | bksv[1];
-		link0_bksv_0 = (link0_bksv_0 << 8) | bksv[0];
-		link0_bksv_1 = bksv[4];
-		DEV_DBG("HDCP: BKSV=%02x%08x\n", link0_bksv_1, link0_bksv_0);
-
 		/* read Bcaps at 0x40 in HDCP Port */
 		ret = hdmi_msm_ddc_read(0x74, 0x40, &bcaps, 1, 5, "Bcaps",
 			TRUE);
@@ -2494,6 +2471,29 @@
 		DEV_DBG("HDCP: Link0-AKSV=%02x%08x\n",
 			link0_aksv_1 & 0xFF, link0_aksv_0);
 
+		/* Read Bksv 5 bytes at 0x00 in HDCP port */
+		ret = hdmi_msm_ddc_read(0x74, 0x00, bksv, 5, 5, "Bksv", TRUE);
+		if (ret) {
+			DEV_ERR("%s(%d): Read BKSV failed", __func__, __LINE__);
+			goto error;
+		}
+		/* check there are 20 ones in BKSV */
+		if (hdmi_msm_count_one(bksv, 5) != 20) {
+			DEV_ERR("HDCP: BKSV read from Sink doesn't have "
+				"20 1's and 20 0's, FAIL (BKSV="
+				"%02x%02x%02x%02x%02x)\n",
+				bksv[4], bksv[3], bksv[2], bksv[1], bksv[0]);
+			ret = -EINVAL;
+			goto error;
+		}
+
+		link0_bksv_0 = bksv[3];
+		link0_bksv_0 = (link0_bksv_0 << 8) | bksv[2];
+		link0_bksv_0 = (link0_bksv_0 << 8) | bksv[1];
+		link0_bksv_0 = (link0_bksv_0 << 8) | bksv[0];
+		link0_bksv_1 = bksv[4];
+		DEV_DBG("HDCP: BKSV=%02x%08x\n", link0_bksv_1, link0_bksv_0);
+
 		/* 0x0134 HDCP_RCVPORT_DATA0
 		   [31:0] LINK0_BKSV_0 */
 		HDMI_OUTP(0x0134, link0_bksv_0);
@@ -3073,7 +3073,7 @@
 		{4096, 27000}, {6272, 30000}, {6144, 27000}, {12544, 30000},
 		{12288, 27000}, {25088, 30000}, {24576, 27000} }),
 	/*  27.027MHz */
-	HDMI_MSM_AUDIO_ARCS(27027, {
+	HDMI_MSM_AUDIO_ARCS(27030, {
 		{4096, 27027}, {6272, 30030}, {6144, 27027}, {12544, 30030},
 		{12288, 27027}, {25088, 30030}, {24576, 27027} }),
 	/*  74.250MHz */
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 7c7ece2..db60546 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -1642,8 +1642,8 @@
 			if (mdp_version < 0x04030303) {
 				pr_err("%s: writeback panel not supprted\n",
 					 __func__);
-				rc = -ENODEV;
-				goto mdp_probe_err;
+				platform_device_put(msm_fb_dev);
+				return -ENODEV;
 			}
 			pdata->on = mdp4_overlay_writeback_on;
 			pdata->off = mdp4_overlay_writeback_off;
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index 645a0c3..ecb0a24 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -418,6 +418,7 @@
 	char *rgb_base;
 	uint32 src_size, src_xy, dst_size, dst_xy;
 	uint32 format, pattern;
+	uint32 offset = 0;
 
 	rgb_base = MDP_BASE + MDP4_RGB_BASE;
 	rgb_base += (MDP4_RGB_OFF * pipe->pipe_num);
@@ -427,6 +428,16 @@
 	dst_size = ((pipe->dst_h << 16) | pipe->dst_w);
 	dst_xy = ((pipe->dst_y << 16) | pipe->dst_x);
 
+	if ((pipe->src_x + pipe->src_w) > 0x7FF) {
+		offset += pipe->src_x * pipe->bpp;
+		src_xy &= 0xFFFF0000;
+	}
+
+	if ((pipe->src_y + pipe->src_h) > 0x7FF) {
+		offset += pipe->src_y * pipe->src_width * pipe->bpp;
+		src_xy &= 0x0000FFFF;
+	}
+
 	format = mdp4_overlay_format(pipe);
 	pattern = mdp4_overlay_unpack_pattern(pipe);
 
@@ -443,7 +454,7 @@
 	outpdw(rgb_base + 0x0008, dst_size);	/* MDP_RGB_DST_SIZE */
 	outpdw(rgb_base + 0x000c, dst_xy);	/* MDP_RGB_DST_XY */
 
-	outpdw(rgb_base + 0x0010, pipe->srcp0_addr);
+	outpdw(rgb_base + 0x0010, pipe->srcp0_addr + offset);
 	outpdw(rgb_base + 0x0040, pipe->srcp0_ystride);
 
 	outpdw(rgb_base + 0x0050, format);/* MDP_RGB_SRC_FORMAT */
@@ -548,6 +559,21 @@
 
 	mdp4_scale_setup(pipe);
 
+	luma_offset = 0;
+	chroma_offset = 0;
+
+	if (ptype == OVERLAY_TYPE_RGB) {
+		if ((pipe->src_y + pipe->src_h) > 0x7FF) {
+			luma_offset = pipe->src_y * pipe->src_width * pipe->bpp;
+			src_xy &= 0x0000FFFF;
+		}
+
+		if ((pipe->src_x + pipe->src_w) > 0x7FF) {
+			luma_offset += pipe->src_x * pipe->bpp;
+			src_xy &= 0xFFFF0000;
+		}
+	}
+
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 
 	outpdw(vg_base + 0x0000, src_size);	/* MDP_RGB_SRC_SIZE */
@@ -567,9 +593,6 @@
 	if (ptype != OVERLAY_TYPE_RGB) {
 		mdp4_overlay_vg_get_src_offset(pipe, vg_base, &luma_offset,
 			&chroma_offset);
-	} else {
-		luma_offset = 0;
-		chroma_offset = 0;
 	}
 
 	/* luma component plane */
@@ -1804,8 +1827,8 @@
 
 	}
 
-	pipe->src_width = req->src.width & 0x07ff;	/* source img width */
-	pipe->src_height = req->src.height & 0x07ff;	/* source img height */
+	pipe->src_width = req->src.width & 0x1fff;	/* source img width */
+	pipe->src_height = req->src.height & 0x1fff;	/* source img height */
 	pipe->src_h = req->src_rect.h & 0x07ff;
 	pipe->src_w = req->src_rect.w & 0x07ff;
 	pipe->src_y = req->src_rect.y & 0x07ff;
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index a905ec0..5ad6de3f 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -451,6 +451,29 @@
 	complete(&dma->comp);
 }
 
+static void mdp4_overlay_lcdc_prefill(struct msm_fb_data_type *mfd)
+{
+	unsigned long flag;
+
+	if (lcdc_pipe->blt_addr) {
+		mdp4_overlay_lcdc_dma_busy_wait(mfd);
+
+		mdp4_lcdc_blt_ov_update(lcdc_pipe);
+		lcdc_pipe->ov_cnt++;
+
+		spin_lock_irqsave(&mdp_spin_lock, flag);
+		outp32(MDP_INTR_CLEAR, INTR_OVERLAY0_DONE);
+		mdp_intr_mask |= INTR_OVERLAY0_DONE;
+		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+		mdp_enable_irq(MDP_OVERLAY0_TERM);
+		mfd->dma->busy = TRUE;
+		mb();	/* make sure all registers updated */
+		spin_unlock_irqrestore(&mdp_spin_lock, flag);
+		outpdw(MDP_BASE + 0x0004, 0); /* kickoff overlay engine */
+		mdp4_stat.kickoff_ov0++;
+		mb();
+	}
+}
 /*
  * make sure the MIPI_DSI_WRITEBACK_SIZE defined at boardfile
  * has enough space h * w * 3 * 2
@@ -490,6 +513,10 @@
 	msleep(20);
 	mdp4_overlayproc_cfg(lcdc_pipe);
 	mdp4_overlay_dmap_xy(lcdc_pipe);
+	if (lcdc_pipe->blt_addr) {
+		mdp4_overlay_lcdc_prefill(mfd);
+		mdp4_overlay_lcdc_prefill(mfd);
+	}
 	MDP_OUTP(MDP_BASE + LCDC_BASE, 1);	/* start lcdc */
 }
 
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 6025139..89ccbb9 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -2556,6 +2556,7 @@
 	int	ret;
 	struct msmfb_overlay_data req;
 	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	struct msm_fb_panel_data *pdata;
 
 	if (mfd->overlay_play_enable == 0)	/* nothing to do */
 		return 0;
@@ -2579,6 +2580,19 @@
 
 	ret = mdp4_overlay_play(info, &req);
 
+	if (unset_bl_level && !bl_updated) {
+		pdata = (struct msm_fb_panel_data *)mfd->pdev->
+			dev.platform_data;
+		if ((pdata) && (pdata->set_backlight)) {
+			down(&mfd->sem);
+			mfd->bl_level = unset_bl_level;
+			pdata->set_backlight(mfd);
+			bl_level_old = unset_bl_level;
+			up(&mfd->sem);
+		}
+		bl_updated = 1;
+	}
+
 	return ret;
 }
 
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
index f69a471..7ccf4c2 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.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
@@ -24,8 +24,6 @@
 static struct time_data proc_time[MAX_TIME_DATA];
 #define DDL_MSG_TIME(x...) printk(KERN_DEBUG x)
 
-#define DDL_FW_CHANGE_ENDIAN
-
 static unsigned int vidc_mmu_subsystem[] =	{
 		MSM_SUBSYSTEM_VIDEO, MSM_SUBSYSTEM_VIDEO_FWARE};
 
@@ -65,7 +63,7 @@
 		}
 		addr->alloc_handle = ion_alloc(
 		ddl_context->video_ion_client, alloc_size, SZ_4K,
-			(1<<res_trk_get_mem_type()));
+			res_trk_get_mem_type());
 		if (IS_ERR_OR_NULL(addr->alloc_handle)) {
 			DDL_MSG_ERROR("%s() :DDL ION alloc failed\n",
 						 __func__);
@@ -289,23 +287,6 @@
 }
 #endif
 
-#ifdef DDL_FW_CHANGE_ENDIAN
-static void ddl_fw_change_endian(u8 *fw, u32 fw_size)
-{
-	u32 i = 0;
-	u8  temp;
-	for (i = 0; i < fw_size; i = i + 4) {
-		temp = fw[i];
-		fw[i] = fw[i+3];
-		fw[i+3] = temp;
-		temp = fw[i+1];
-		fw[i+1] = fw[i+2];
-		fw[i+2] = temp;
-	}
-	return;
-}
-#endif
-
 u32 ddl_fw_init(struct ddl_buf_addr *dram_base)
 {
 
@@ -319,9 +300,6 @@
 		vidc_video_codec_fw_size);
 	memcpy(dest_addr, vidc_video_codec_fw,
 		vidc_video_codec_fw_size);
-#ifdef DDL_FW_CHANGE_ENDIAN
-	ddl_fw_change_endian(dest_addr, vidc_video_codec_fw_size);
-#endif
 	return true;
 }
 
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
index 9c2e5d1..795d1e3 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
@@ -28,16 +28,152 @@
 static unsigned int vidc_clk_table[3] = {
 	48000000, 133330000, 200000000
 };
+static unsigned int restrk_mmu_subsystem[] =	{
+		MSM_SUBSYSTEM_VIDEO, MSM_SUBSYSTEM_VIDEO_FWARE};
 static struct res_trk_context resource_context;
 
 #define VIDC_FW	"vidc_1080p.fw"
 #define VIDC_FW_SIZE SZ_1M
 
+struct res_trk_vidc_mmu_clk {
+	char *mmu_clk_name;
+	struct clk *mmu_clk;
+};
+
+static struct res_trk_vidc_mmu_clk vidc_mmu_clks[] = {
+	{"mdp_iommu_clk"}, {"rot_iommu_clk"},
+	{"vcodec_iommu0_clk"}, {"vcodec_iommu1_clk"},
+	{"smmu_iface_clk"}
+};
+
 unsigned char *vidc_video_codec_fw;
 u32 vidc_video_codec_fw_size;
 static u32 res_trk_get_clk(void);
 static void res_trk_put_clk(void);
 
+static void *res_trk_pmem_map
+	(struct ddl_buf_addr *addr, size_t sz, u32 alignment)
+{
+	u32 offset = 0, flags = 0;
+	u32 index = 0;
+	struct ddl_context *ddl_context;
+	struct msm_mapped_buffer *mapped_buffer = NULL;
+	ddl_context = ddl_get_context();
+	if (!addr->alloced_phys_addr) {
+		pr_err(" %s() alloced addres NULL", __func__);
+		goto bail_out;
+	}
+	flags = MSM_SUBSYSTEM_MAP_IOVA | MSM_SUBSYSTEM_MAP_KADDR;
+	if (alignment == DDL_KILO_BYTE(128))
+			index = 1;
+	else if (alignment > SZ_4K)
+		flags |= MSM_SUBSYSTEM_ALIGN_IOVA_8K;
+
+	addr->mapped_buffer =
+	msm_subsystem_map_buffer((unsigned long)addr->alloced_phys_addr,
+	sz, flags, &restrk_mmu_subsystem[index],
+	sizeof(restrk_mmu_subsystem[index])/sizeof(unsigned int));
+	if (IS_ERR(addr->mapped_buffer)) {
+		pr_err(" %s() buffer map failed", __func__);
+		goto bail_out;
+	}
+	mapped_buffer = addr->mapped_buffer;
+	if (!mapped_buffer->vaddr || !mapped_buffer->iova[0]) {
+		pr_err("%s() map buffers failed\n", __func__);
+		goto bail_out;
+	}
+	addr->physical_base_addr = (u8 *)mapped_buffer->iova[0];
+	addr->virtual_base_addr = mapped_buffer->vaddr;
+	addr->align_physical_addr = (u8 *) DDL_ALIGN((u32)
+		addr->physical_base_addr, alignment);
+	offset = (u32)(addr->align_physical_addr -
+			addr->physical_base_addr);
+	addr->align_virtual_addr = addr->virtual_base_addr + offset;
+	addr->buffer_size = sz;
+	return addr->virtual_base_addr;
+bail_out:
+	return NULL;
+}
+
+static void *res_trk_pmem_alloc
+	(struct ddl_buf_addr *addr, size_t sz, u32 alignment)
+{
+	u32 alloc_size;
+	struct ddl_context *ddl_context;
+	int rc = -EINVAL;
+	ion_phys_addr_t phyaddr = 0;
+	size_t len = 0;
+	DBG_PMEM("\n%s() IN: Requested alloc size(%u)", __func__, (u32)sz);
+	if (!addr) {
+		DDL_MSG_ERROR("\n%s() Invalid Parameters", __func__);
+		goto bail_out;
+	}
+	ddl_context = ddl_get_context();
+	res_trk_set_mem_type(addr->mem_type);
+	alloc_size = (sz + alignment);
+	if (res_trk_get_enable_ion()) {
+		if (!ddl_context->video_ion_client)
+			ddl_context->video_ion_client =
+				res_trk_get_ion_client();
+		if (!ddl_context->video_ion_client) {
+			DDL_MSG_ERROR("%s() :DDL ION Client Invalid handle\n",
+						 __func__);
+			goto bail_out;
+		}
+		addr->alloc_handle = ion_alloc(
+		ddl_context->video_ion_client, alloc_size, SZ_4K,
+			res_trk_get_mem_type());
+		if (IS_ERR_OR_NULL(addr->alloc_handle)) {
+			DDL_MSG_ERROR("%s() :DDL ION alloc failed\n",
+						 __func__);
+			goto bail_out;
+		}
+		rc = ion_phys(ddl_context->video_ion_client,
+				addr->alloc_handle, &phyaddr,
+				 &len);
+		if (rc || !phyaddr) {
+			DDL_MSG_ERROR("%s():DDL ION client physical failed\n",
+						 __func__);
+			goto free_acm_ion_alloc;
+		}
+		addr->alloced_phys_addr = phyaddr;
+	} else {
+		addr->alloced_phys_addr = (phys_addr_t)
+		allocate_contiguous_memory_nomap(alloc_size,
+			res_trk_get_mem_type(), SZ_4K);
+		if (!addr->alloced_phys_addr) {
+			DDL_MSG_ERROR("%s() : acm alloc failed (%d)\n",
+					 __func__, alloc_size);
+			goto bail_out;
+		}
+	}
+
+	addr->buffer_size = sz;
+	return (void *)addr->alloced_phys_addr;
+
+free_acm_ion_alloc:
+	if (ddl_context->video_ion_client) {
+		if (addr->alloc_handle) {
+			ion_free(ddl_context->video_ion_client,
+				addr->alloc_handle);
+			addr->alloc_handle = NULL;
+		}
+	}
+bail_out:
+	return NULL;
+}
+
+static void res_trk_pmem_unmap(struct ddl_buf_addr *addr)
+{
+	if (!addr) {
+		pr_err("%s() invalid args\n", __func__);
+		return;
+	}
+	if (addr->mapped_buffer)
+		msm_subsystem_unmap_buffer(addr->mapped_buffer);
+	addr->mapped_buffer = NULL;
+}
+
 static u32 res_trk_get_clk()
 {
 	if (resource_context.vcodec_clk ||
@@ -252,6 +388,7 @@
 u32 res_trk_power_down(void)
 {
 	VCDRES_MSG_LOW("clk_regime_rail_disable");
+	res_trk_pmem_unmap(&resource_context.firmware_addr);
 #ifdef CONFIG_MSM_BUS_SCALING
 	msm_bus_scale_client_update_request(resource_context.pcl, 0);
 	msm_bus_scale_unregister_client(resource_context.pcl);
@@ -299,7 +436,6 @@
 
 	if (dev_ctxt->reqd_perf_lvl + dev_ctxt->curr_perf_lvl == 0)
 		bus_clk_index = 2;
-
 	bus_clk_index = (bus_clk_index << 1) + (client_type + 1);
 	VCDRES_MSG_LOW("%s(), bus_clk_index = %d", __func__, bus_clk_index);
 	VCDRES_MSG_LOW("%s(),context.pcl = %x", __func__, resource_context.pcl);
@@ -415,6 +551,7 @@
 	} else {
 		memset(&resource_context, 0, sizeof(resource_context));
 		mutex_init(&resource_context.lock);
+		mutex_init(&resource_context.secure_lock);
 		resource_context.device = device;
 		resource_context.irq_num = irq;
 		resource_context.vidc_platform_data =
@@ -435,7 +572,7 @@
 					return;
 				}
 				resource_context.fw_mem_type =
-				resource_context.vidc_platform_data->memtype;
+				ION_MM_FIRMWARE_HEAP_ID;
 				resource_context.cmd_mem_type =
 				ION_CP_MFC_HEAP_ID;
 			}
@@ -454,12 +591,12 @@
 		}
 		resource_context.core_type = VCD_CORE_1080P;
 		resource_context.firmware_addr.mem_type = DDL_FW_MEM;
-		if (!ddl_pmem_alloc(&resource_context.firmware_addr,
+		if (!res_trk_pmem_alloc(&resource_context.firmware_addr,
 			VIDC_FW_SIZE, DDL_KILO_BYTE(128))) {
 			pr_err("%s() Firmware buffer allocation failed",
 				   __func__);
 			memset(&resource_context.firmware_addr, 0,
-				   sizeof(resource_context.firmware_addr));
+			   sizeof(resource_context.firmware_addr));
 		}
 	}
 }
@@ -470,27 +607,48 @@
 
 u32 res_trk_get_firmware_addr(struct ddl_buf_addr *firm_addr)
 {
-	int status = -1;
-	if (resource_context.firmware_addr.mapped_buffer) {
-		memcpy(firm_addr, &resource_context.firmware_addr,
-			   sizeof(struct ddl_buf_addr));
-		status = 0;
+	if (!firm_addr || resource_context.firmware_addr.mapped_buffer) {
+		pr_err("%s() invalid params", __func__);
+		return -EINVAL;
 	}
-	return status;
+	if (!res_trk_pmem_map(&resource_context.firmware_addr,
+		resource_context.firmware_addr.buffer_size,
+		DDL_KILO_BYTE(128))) {
+		pr_err("%s() Firmware buffer mapping failed",
+			   __func__);
+		return -EINVAL;
+	}
+	memcpy(firm_addr, &resource_context.firmware_addr,
+		sizeof(struct ddl_buf_addr));
+	return 0;
 }
 
-u32 res_trk_get_mem_type(void)
+int res_trk_get_mem_type(void)
 {
+	int mem_type = -1;
 	switch (resource_context.res_mem_type) {
 	case DDL_FW_MEM:
-		return resource_context.fw_mem_type;
+		mem_type = resource_context.fw_mem_type;
+		break;
 	case DDL_MM_MEM:
-		return resource_context.memtype;
+		mem_type = resource_context.memtype;
+		break;
 	case DDL_CMD_MEM:
-		return resource_context.memtype;
+		if (res_trk_check_for_sec_session())
+			mem_type = resource_context.cmd_mem_type;
+		else
+			mem_type = resource_context.memtype;
+		break;
 	default:
-		return 0;
+		return mem_type;
 	}
+	if (resource_context.vidc_platform_data->enable_ion) {
+		if (res_trk_check_for_sec_session())
+			mem_type = (ION_HEAP(mem_type) | ION_SECURE);
+		else
+			mem_type = ION_HEAP(mem_type);
+	}
+	return mem_type;
 }
 
 u32 res_trk_get_enable_ion(void)
@@ -520,3 +678,109 @@
 {
 	return resource_context.disable_fullhd;
 }
+
+int res_trk_enable_iommu_clocks(void)
+{
+	int ret = 0, i;
+	if (resource_context.mmu_clks_on) {
+		pr_err(" %s: Clocks are already on", __func__);
+		return -EINVAL;
+	}
+	resource_context.mmu_clks_on = 1;
+	for (i = 0; i < ARRAY_SIZE(vidc_mmu_clks); i++) {
+		vidc_mmu_clks[i].mmu_clk = clk_get(resource_context.device,
+			vidc_mmu_clks[i].mmu_clk_name);
+		if (IS_ERR(vidc_mmu_clks[i].mmu_clk)) {
+			pr_err(" %s: Get failed for clk %s", __func__,
+				   vidc_mmu_clks[i].mmu_clk_name);
+			ret = PTR_ERR(vidc_mmu_clks[i].mmu_clk);
+		}
+		if (!ret) {
+			ret = clk_enable(vidc_mmu_clks[i].mmu_clk);
+			if (ret) {
+				clk_put(vidc_mmu_clks[i].mmu_clk);
+				vidc_mmu_clks[i].mmu_clk = NULL;
+			}
+		}
+		if (ret) {
+			for (i--; i >= 0; i--) {
+				clk_disable(vidc_mmu_clks[i].mmu_clk);
+				clk_put(vidc_mmu_clks[i].mmu_clk);
+				vidc_mmu_clks[i].mmu_clk = NULL;
+			}
+			resource_context.mmu_clks_on = 0;
+			pr_err("%s() clocks enable failed", __func__);
+			break;
+		}
+	}
+	return ret;
+}
+
+int res_trk_disable_iommu_clocks(void)
+{
+	int i;
+	if (!resource_context.mmu_clks_on) {
+		pr_err(" %s: clks are already off", __func__);
+		return -EINVAL;
+	}
+	resource_context.mmu_clks_on = 0;
+	for (i = 0; i < ARRAY_SIZE(vidc_mmu_clks); i++) {
+		clk_disable(vidc_mmu_clks[i].mmu_clk);
+		clk_put(vidc_mmu_clks[i].mmu_clk);
+		vidc_mmu_clks[i].mmu_clk = NULL;
+	}
+	return 0;
+}
+
+int res_trk_check_for_sec_session()
+{
+	int rc;
+	mutex_lock(&resource_context.secure_lock);
+	rc = (resource_context.secure_session) ? -EBUSY : 0;
+	mutex_unlock(&resource_context.secure_lock);
+	return rc;
+}
+int res_trk_open_secure_session()
+{
+	int rc;
+	mutex_lock(&resource_context.secure_lock);
+	if (resource_context.secure_session) {
+		pr_err("Secure session already open");
+		rc = -EBUSY;
+		goto error_open;
+	}
+	resource_context.secure_session = 1;
+	rc = res_trk_enable_iommu_clocks();
+	if (rc) {
+		pr_err("IOMMU clock enabled failed while open");
+		goto error_open;
+	}
+	msm_ion_secure_heap(ION_HEAP(resource_context.memtype));
+	msm_ion_secure_heap(ION_HEAP(resource_context.cmd_mem_type));
+	res_trk_disable_iommu_clocks();
+	mutex_unlock(&resource_context.secure_lock);
+	return 0;
+error_open:
+	mutex_unlock(&resource_context.secure_lock);
+	return rc;
+}
+
+int res_trk_close_secure_session()
+{
+	int rc;
+	mutex_lock(&resource_context.secure_lock);
+	rc = res_trk_enable_iommu_clocks();
+	if (rc) {
+		pr_err("IOMMU clock enabled failed while close");
+		goto error_close;
+	}
+	msm_ion_unsecure_heap(ION_HEAP(resource_context.memtype));
+	msm_ion_unsecure_heap(ION_HEAP(resource_context.cmd_mem_type));
+	res_trk_disable_iommu_clocks();
+	resource_context.secure_session = 0;
+	mutex_unlock(&resource_context.secure_lock);
+	return 0;
+error_close:
+	mutex_unlock(&resource_context.secure_lock);
+	return rc;
+}
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h
index be5045f..bf8607d 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h
@@ -28,6 +28,7 @@
 
 #define RESTRK_1080P_MIN_PERF_LEVEL RESTRK_1080P_VGA_PERF_LEVEL
 #define RESTRK_1080P_MAX_PERF_LEVEL RESTRK_1080P_1080P_PERF_LEVEL
+
 struct res_trk_context {
 	struct device *device;
 	u32 irq_num;
@@ -52,6 +53,9 @@
 	u32 disable_dmx;
 	u32 disable_fullhd;
 	enum ddl_mem_area res_mem_type;
+	u32 mmu_clks_on;
+	u32 secure_session;
+	struct mutex secure_lock;
 };
 
 #if DEBUG
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h
index fd4ca3e..f91ddb5 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h
@@ -29,10 +29,15 @@
 u32 res_trk_download_firmware(void);
 u32 res_trk_get_core_type(void);
 u32 res_trk_get_firmware_addr(struct ddl_buf_addr *firm_addr);
-u32 res_trk_get_mem_type(void);
+int res_trk_get_mem_type(void);
 u32 res_trk_get_enable_ion(void);
 u32 res_trk_get_disable_fullhd(void);
 struct ion_client *res_trk_get_ion_client(void);
 u32 res_trk_get_disable_dmx(void);
 void res_trk_set_mem_type(enum ddl_mem_area mem_type);
+int res_trk_enable_iommu_clocks(void);
+int res_trk_disable_iommu_clocks(void);
+int res_trk_check_for_sec_session(void);
+int res_trk_open_secure_session(void);
+int res_trk_close_secure_session(void);
 #endif
diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c
index ee76ff1..7c3325a 100644
--- a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c
+++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c
@@ -728,3 +728,18 @@
 {
 	return 0;
 }
+
+int res_trk_check_for_sec_session()
+{
+	return 0;
+}
+
+int res_trk_open_secure_session()
+{
+	return -EINVAL;
+}
+
+int res_trk_close_secure_session()
+{
+	return 0;
+}
diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h
index 3012858..2b92a42 100644
--- a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h
+++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.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
@@ -35,6 +35,7 @@
 	struct msm_vidc_platform_data *vidc_platform_data;
 	u32 core_type;
 	int memtype;
+	u32 secure_session;
 };
 
 #if DEBUG
diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h
index 34f2103..237d143 100644
--- a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h
+++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h
@@ -32,4 +32,7 @@
 u32 res_trk_get_enable_ion(void);
 struct ion_client *res_trk_get_ion_client(void);
 void res_trk_set_mem_type(enum ddl_mem_area mem_type);
+int res_trk_check_for_sec_session(void);
+int res_trk_open_secure_session(void);
+int res_trk_close_secure_session(void);
 #endif
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
index b90248e..980ec21 100644
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.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
@@ -29,6 +29,7 @@
 #include <linux/clk.h>
 #include <linux/timer.h>
 #include <mach/msm_subsystem_map.h>
+#include "vcd_res_tracker_api.h"
 #include "vidc_type.h"
 #include "vcd_api.h"
 #include "vdec_internal.h"
@@ -40,11 +41,13 @@
 #define INFO(x...) pr_info(x)
 #define ERR(x...) pr_err(x)
 
-#define VID_DEC_NAME		"msm_vidc_dec"
+#define VID_DEC_NAME "msm_vidc_dec"
 
+static char *node_name[2] = {"", "_sec"};
 static struct vid_dec_dev *vid_dec_device_p;
 static dev_t vid_dec_dev_num;
 static struct class *vid_dec_class;
+
 static unsigned int vidc_mmu_subsystem[] = {
 	MSM_SUBSYSTEM_VIDEO};
 static s32 vid_dec_get_empty_client_index(void)
@@ -1958,34 +1961,30 @@
 	return true;
 }
 
-static int vid_dec_open(struct inode *inode, struct file *file)
+struct video_client_ctx *vid_dec_open_client(void)
 {
 	s32 client_index;
 	struct video_client_ctx *client_ctx;
 	u32 vcd_status = VCD_ERR_FAIL;
-	u8 client_count = 0;
-
-	DBG("msm_vidc_dec: Inside %s()", __func__);
-	mutex_lock(&vid_dec_device_p->lock);
+	u8 client_count;
 
 	client_count = vcd_get_num_of_clients();
 	if (client_count == VIDC_MAX_NUM_CLIENTS) {
 		ERR("ERROR : vid_dec_open() max number of clients"
-		    "limit reached\n");
-		mutex_unlock(&vid_dec_device_p->lock);
-		return -ENODEV;
+			"limit reached\n");
+		goto client_failure;
 	}
 
 	DBG(" Virtual Address of ioremap is %p\n", vid_dec_device_p->virt_base);
 	if (!vid_dec_device_p->num_clients) {
 		if (!vidc_load_firmware())
-			return -ENODEV;
+			goto client_failure;
 	}
 
 	client_index = vid_dec_get_empty_client_index();
 	if (client_index == -1) {
 		ERR("%s() : No free clients client_index == -1\n", __func__);
-		return -ENODEV;
+		goto client_failure;
 	}
 	client_ctx = &vid_dec_device_p->vdec_clients[client_index];
 	vid_dec_device_p->num_clients++;
@@ -2002,30 +2001,84 @@
 		client_ctx->user_ion_client = vcd_get_ion_client();
 		if (!client_ctx->user_ion_client) {
 			ERR("vcd_open ion client get failed");
-			return -EFAULT;
+			goto client_failure;
 		}
 	}
 	vcd_status = vcd_open(vid_dec_device_p->device_handle, true,
-			      vid_dec_vcd_cb, client_ctx);
+				  vid_dec_vcd_cb, client_ctx);
 	if (!vcd_status) {
 		wait_for_completion(&client_ctx->event);
 		if (client_ctx->event_status) {
 			ERR("callback for vcd_open returned error: %u",
 				client_ctx->event_status);
-			mutex_unlock(&vid_dec_device_p->lock);
-			return -EFAULT;
+			goto client_failure;
 		}
 	} else {
 		ERR("vcd_open returned error: %u", vcd_status);
-		mutex_unlock(&vid_dec_device_p->lock);
-		return -EFAULT;
+		goto client_failure;
 	}
 	client_ctx->seq_header_set = false;
-	file->private_data = client_ctx;
+	return client_ctx;
+client_failure:
+	return NULL;
+}
+
+static int vid_dec_open_secure(struct inode *inode, struct file *file)
+{
+	mutex_lock(&vid_dec_device_p->lock);
+	if (res_trk_check_for_sec_session() || vcd_get_num_of_clients()) {
+		ERR("Secure session present return failure\n");
+		mutex_unlock(&vid_dec_device_p->lock);
+		return -ENODEV;
+	}
+	if (res_trk_open_secure_session()) {
+		ERR("Secure session operation failure\n");
+		mutex_unlock(&vid_dec_device_p->lock);
+		return -ENODEV;
+	}
+	file->private_data = vid_dec_open_client();
+	if (!file->private_data) {
+		res_trk_close_secure_session();
+		mutex_unlock(&vid_dec_device_p->lock);
+		return -ENODEV;
+	}
 	mutex_unlock(&vid_dec_device_p->lock);
 	return 0;
 }
 
+static int vid_dec_open(struct inode *inode, struct file *file)
+{
+	INFO("msm_vidc_dec: Inside %s()", __func__);
+	mutex_lock(&vid_dec_device_p->lock);
+	if (res_trk_check_for_sec_session()) {
+		ERR("Secure session present return failure\n");
+		mutex_unlock(&vid_dec_device_p->lock);
+		return -ENODEV;
+	}
+	file->private_data = vid_dec_open_client();
+	if (!file->private_data) {
+		mutex_unlock(&vid_dec_device_p->lock);
+		return -ENODEV;
+	}
+	mutex_unlock(&vid_dec_device_p->lock);
+	return 0;
+}
+
+static int vid_dec_release_secure(struct inode *inode, struct file *file)
+{
+	struct video_client_ctx *client_ctx = file->private_data;
+
+	INFO("msm_vidc_dec: Inside %s()", __func__);
+	res_trk_close_secure_session();
+	vid_dec_close_client(client_ctx);
+	vidc_release_firmware();
+#ifndef USE_RES_TRACKER
+	vidc_disable_clk();
+#endif
+	INFO("msm_vidc_dec: Return from %s()", __func__);
+	return 0;
+}
+
 static int vid_dec_release(struct inode *inode, struct file *file)
 {
 	struct video_client_ctx *client_ctx = file->private_data;
@@ -2040,11 +2093,20 @@
 	return 0;
 }
 
-static const struct file_operations vid_dec_fops = {
-	.owner = THIS_MODULE,
-	.open = vid_dec_open,
-	.release = vid_dec_release,
-	.unlocked_ioctl = vid_dec_ioctl,
+static const struct file_operations vid_dec_fops[2] = {
+	{
+		.owner = THIS_MODULE,
+		.open = vid_dec_open,
+		.release = vid_dec_release,
+		.unlocked_ioctl = vid_dec_ioctl,
+	},
+	{
+		.owner = THIS_MODULE,
+		.open = vid_dec_open_secure,
+		.release = vid_dec_release_secure,
+		.unlocked_ioctl = vid_dec_ioctl,
+	},
+
 };
 
 void vid_dec_interrupt_deregister(void)
@@ -2110,7 +2172,7 @@
 
 static int __init vid_dec_init(void)
 {
-	int rc = 0;
+	int rc = 0, i = 0, j = 0;
 	struct device *class_devp;
 
 	DBG("msm_vidc_dec: Inside %s()", __func__);
@@ -2121,7 +2183,8 @@
 		return -ENOMEM;
 	}
 
-	rc = alloc_chrdev_region(&vid_dec_dev_num, 0, 1, VID_DEC_NAME);
+	rc = alloc_chrdev_region(&vid_dec_dev_num, 0, NUM_OF_DRIVER_NODES,
+		VID_DEC_NAME);
 	if (rc < 0) {
 		ERR("%s: alloc_chrdev_region Failed rc = %d\n",
 		       __func__, rc);
@@ -2136,49 +2199,59 @@
 
 		goto error_vid_dec_class_create;
 	}
+	for (i = 0; i < NUM_OF_DRIVER_NODES; i++) {
+		class_devp = device_create(vid_dec_class, NULL,
+						(vid_dec_dev_num + i),
+						NULL, VID_DEC_NAME "%s",
+						node_name[i]);
 
-	class_devp = device_create(vid_dec_class, NULL, vid_dec_dev_num, NULL,
-				   VID_DEC_NAME);
+		if (IS_ERR(class_devp)) {
+			rc = PTR_ERR(class_devp);
+			ERR("%s: class device_create failed %d\n",
+				   __func__, rc);
+			if (!i)
+				goto error_vid_dec_class_device_create;
+			else
+				goto error_vid_dec_cdev_add;
+		}
 
-	if (IS_ERR(class_devp)) {
-		rc = PTR_ERR(class_devp);
-		ERR("%s: class device_create failed %d\n",
-		       __func__, rc);
-		goto error_vid_dec_class_device_create;
-	}
+	  vid_dec_device_p->device[i] = class_devp;
 
-  vid_dec_device_p->device = class_devp;
+		cdev_init(&vid_dec_device_p->cdev[i], &vid_dec_fops[i]);
+		vid_dec_device_p->cdev[i].owner = THIS_MODULE;
+		rc = cdev_add(&(vid_dec_device_p->cdev[i]),
+				(vid_dec_dev_num+i), 1);
 
-	cdev_init(&vid_dec_device_p->cdev, &vid_dec_fops);
-	vid_dec_device_p->cdev.owner = THIS_MODULE;
-	rc = cdev_add(&(vid_dec_device_p->cdev), vid_dec_dev_num, 1);
-
-	if (rc < 0) {
-		ERR("%s: cdev_add failed %d\n", __func__, rc);
-		goto error_vid_dec_cdev_add;
+		if (rc < 0) {
+			ERR("%s: cdev_add failed %d\n", __func__, rc);
+			goto error_vid_dec_cdev_add;
+		}
 	}
 	vid_dec_vcd_init();
 	return 0;
 
 error_vid_dec_cdev_add:
+	for (j = i-1; j >= 0; j--)
+		cdev_del(&(vid_dec_device_p->cdev[j]));
 	device_destroy(vid_dec_class, vid_dec_dev_num);
 error_vid_dec_class_device_create:
 	class_destroy(vid_dec_class);
 error_vid_dec_class_create:
-	unregister_chrdev_region(vid_dec_dev_num, 1);
+	unregister_chrdev_region(vid_dec_dev_num, NUM_OF_DRIVER_NODES);
 error_vid_dec_alloc_chrdev_region:
 	kfree(vid_dec_device_p);
-
 	return rc;
 }
 
 static void __exit vid_dec_exit(void)
 {
-	DBG("msm_vidc_dec: Inside %s()", __func__);
-	cdev_del(&(vid_dec_device_p->cdev));
+	int i = 0;
+	INFO("msm_vidc_dec: Inside %s()", __func__);
+	for (i = 0; i < NUM_OF_DRIVER_NODES; i++)
+		cdev_del(&(vid_dec_device_p->cdev[i]));
 	device_destroy(vid_dec_class, vid_dec_dev_num);
 	class_destroy(vid_dec_class);
-	unregister_chrdev_region(vid_dec_dev_num, 1);
+	unregister_chrdev_region(vid_dec_dev_num, NUM_OF_DRIVER_NODES);
 	kfree(vid_dec_device_p);
 	DBG("msm_vidc_dec: Return from %s()", __func__);
 }
diff --git a/drivers/video/msm/vidc/common/dec/vdec_internal.h b/drivers/video/msm/vidc/common/dec/vdec_internal.h
index 867c3b3..f310e25 100644
--- a/drivers/video/msm/vidc/common/dec/vdec_internal.h
+++ b/drivers/video/msm/vidc/common/dec/vdec_internal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 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
@@ -18,14 +18,16 @@
 #include <linux/cdev.h>
 #include "vidc_init.h"
 
+#define NUM_OF_DRIVER_NODES 2
+
 struct vid_dec_msg {
 	struct list_head list;
 	struct vdec_msginfo vdec_msg_info;
 };
 
 struct vid_dec_dev {
-	struct cdev cdev;
-	struct device *device;
+	struct cdev cdev[NUM_OF_DRIVER_NODES];
+	struct device *device[NUM_OF_DRIVER_NODES];
 	resource_size_t phys_base;
 	void __iomem *virt_base;
 	unsigned int irq;
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index 3cd4e76..97fc758 100644
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.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
@@ -32,6 +32,7 @@
 #include "vcd_api.h"
 #include "venc_internal.h"
 #include "vidc_init.h"
+#include "vcd_res_tracker_api.h"
 
 #define VID_ENC_NAME	"msm_vidc_enc"
 
@@ -516,9 +517,10 @@
 
 	stop_cmd = 0;
 	client_count = vcd_get_num_of_clients();
-	if (client_count == VIDC_MAX_NUM_CLIENTS) {
+	if (client_count == VIDC_MAX_NUM_CLIENTS ||
+		res_trk_check_for_sec_session()) {
 		ERR("ERROR : vid_enc_open() max number of clients"
-		    "limit reached\n");
+		    "limit reached or secure session is open\n");
 		mutex_unlock(&vid_enc_device_p->lock);
 		return -ENODEV;
 	}
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c
index e4bd50d..1709cc2 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.c
+++ b/drivers/video/msm/vidc/common/init/vidc_init.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
@@ -502,7 +502,7 @@
 		} else {
 			buff_ion_handle = ion_import_fd(
 				client_ctx->user_ion_client, pmem_fd);
-			if (!buff_ion_handle) {
+			if (IS_ERR_OR_NULL(buff_ion_handle)) {
 				ERR("%s(): get_ION_handle failed\n",
 				 __func__);
 				goto ion_error;
@@ -558,7 +558,7 @@
 ion_error:
 	if (*kernel_vaddr)
 		ion_unmap_kernel(client_ctx->user_ion_client, buff_ion_handle);
-	if (buff_ion_handle)
+	if (!IS_ERR_OR_NULL(buff_ion_handle))
 		ion_free(client_ctx->user_ion_client, buff_ion_handle);
 bail_out_add:
 	mutex_unlock(&client_ctx->enrty_queue_lock);
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_api.c b/drivers/video/msm/vidc/common/vcd/vcd_api.c
index 4889761..5e9fd55 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_api.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_api.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
@@ -89,7 +89,10 @@
 
 		return VCD_ERR_ILLEGAL_PARM;
 	}
-
+	if (res_trk_check_for_sec_session() && vcd_get_num_of_clients()) {
+		VCD_MSG_ERROR("Secure session in progress");
+		return VCD_ERR_BAD_STATE;
+	}
 	drv_ctxt = vcd_get_drv_context();
 	mutex_lock(&drv_ctxt->dev_mutex);
 
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_sub.c b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
index bb3e652..b5fcc1c 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_sub.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
@@ -69,7 +69,7 @@
 	} else {
 		map_buffer->alloc_handle = ion_alloc(
 			    cctxt->vcd_ion_client, sz, SZ_4K,
-			    (1<<memtype));
+			    memtype);
 		if (!map_buffer->alloc_handle) {
 			pr_err("%s() ION alloc failed", __func__);
 			goto bailout;
diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h
index d61b934..9aa557a 100644
--- a/include/linux/i2c/atmel_mxt_ts.h
+++ b/include/linux/i2c/atmel_mxt_ts.h
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2010 Samsung Electronics Co.Ltd
  * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- * 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 as published by the
@@ -26,6 +26,9 @@
 #define MXT_ROTATED_180		0x6
 #define MXT_DIAGONAL_COUNTER	0x7
 
+/* MXT_TOUCH_KEYARRAY_T15 */
+#define MXT_KEYARRAY_MAX_KEYS	32
+
 /* The platform data for the Atmel maXTouch touchscreen driver */
 struct mxt_platform_data {
 	const u8 *config;
@@ -38,6 +41,7 @@
 	bool	digital_pwr_regulator;
 	int reset_gpio;
 	int irq_gpio;
+	int *key_codes;
 
 	u8(*read_chg) (void);
 	int (*init_hw) (bool);
diff --git a/include/linux/ion.h b/include/linux/ion.h
index fa5017a..41f99e4 100644
--- a/include/linux/ion.h
+++ b/include/linux/ion.h
@@ -63,14 +63,17 @@
  */
 
 enum ion_heap_ids {
+	INVALID_HEAP_ID = -1,
 	ION_IOMMU_HEAP_ID = 4,
 	ION_CP_MM_HEAP_ID = 8,
 	ION_CP_MFC_HEAP_ID = 12,
 	ION_CP_WB_HEAP_ID = 16, /* 8660 only */
 	ION_CAMERA_HEAP_ID = 20, /* 8660 only */
 	ION_SF_HEAP_ID = 24,
+	ION_QSECOM_HEAP_ID = 27,
 	ION_AUDIO_HEAP_ID = 28,
 
+	ION_MM_FIRMWARE_HEAP_ID = 29,
 	ION_SYSTEM_HEAP_ID = 30,
 
 	ION_HEAP_ID_RESERVED = 31 /** Bit reserved for ION_SECURE flag */
@@ -94,6 +97,8 @@
 #define ION_IOMMU_HEAP_NAME	"iommu"
 #define ION_MFC_HEAP_NAME	"mfc"
 #define ION_WB_HEAP_NAME	"wb"
+#define ION_MM_FIRMWARE_HEAP_NAME	"mm_fw"
+#define ION_QSECOM_HEAP_NAME	"qsecom"
 
 #define CACHED          1
 #define UNCACHED        0
@@ -149,12 +154,17 @@
 
 struct ion_cp_heap_pdata {
 	enum ion_permission_type permission_type;
+	unsigned int align;
+	ion_phys_addr_t secure_base; /* Base addr used when heap is shared */
+	size_t secure_size; /* Size used for securing heap when heap is shared*/
 	int (*request_region)(void *);
 	int (*release_region)(void *);
 	void *(*setup_region)(void);
 };
 
 struct ion_co_heap_pdata {
+	int adjacent_mem_id;
+	unsigned int align;
 	int (*request_region)(void *);
 	int (*release_region)(void *);
 	void *(*setup_region)(void);
diff --git a/include/linux/mfd/pm8xxx/pm8038.h b/include/linux/mfd/pm8xxx/pm8038.h
index e733842..203095a 100644
--- a/include/linux/mfd/pm8xxx/pm8038.h
+++ b/include/linux/mfd/pm8xxx/pm8038.h
@@ -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
@@ -28,6 +28,9 @@
 #include <linux/mfd/pm8xxx/misc.h>
 #include <linux/regulator/pm8xxx-regulator.h>
 #include <linux/mfd/pm8xxx/pm8xxx-adc.h>
+#include <linux/mfd/pm8xxx/pm8921-charger.h>
+#include <linux/mfd/pm8xxx/pm8921-bms.h>
+#include <linux/mfd/pm8xxx/ccadc.h>
 
 #define PM8038_CORE_DEV_NAME "pm8038-core"
 
@@ -69,7 +72,10 @@
 	struct pm8xxx_misc_platform_data	*misc_pdata;
 	struct pm8xxx_regulator_platform_data	*regulator_pdatas;
 	int					num_regulators;
+	struct pm8921_charger_platform_data	*charger_pdata;
+	struct pm8921_bms_platform_data		*bms_pdata;
 	struct pm8xxx_adc_platform_data		*adc_pdata;
+	struct pm8xxx_ccadc_platform_data	*ccadc_pdata;
 };
 
 #endif
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
index cd2e61c..d0307ee 100644
--- a/include/linux/of_irq.h
+++ b/include/linux/of_irq.h
@@ -33,6 +33,8 @@
 	u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
 };
 
+typedef int (*of_irq_init_cb_t)(struct device_node *, struct device_node *);
+
 /*
  * Workarounds only applied to 32bit powermac machines
  */
@@ -73,6 +75,7 @@
 		struct resource *res, int nr_irqs);
 extern struct device_node *of_irq_find_parent(struct device_node *child);
 
+extern void of_irq_init(const struct of_device_id *matches);
 
 #endif /* CONFIG_OF_IRQ */
 #endif /* CONFIG_OF */
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index fb5d4e4..f46449a 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -135,6 +135,8 @@
 /* regulator get and put */
 struct regulator *__must_check regulator_get(struct device *dev,
 					     const char *id);
+struct regulator *__must_check devm_regulator_get(struct device *dev,
+					     const char *id);
 struct regulator *__must_check regulator_get_exclusive(struct device *dev,
 						       const char *id);
 void regulator_put(struct regulator *regulator);
@@ -202,6 +204,13 @@
 	 */
 	return NULL;
 }
+
+static inline struct regulator *__must_check
+devm_regulator_get(struct device *dev, const char *id)
+{
+	return NULL;
+}
+
 static inline void regulator_put(struct regulator *regulator)
 {
 }
diff --git a/include/linux/tzcom.h b/include/linux/tzcom.h
index a1b3dfc..448ab2a 100644
--- a/include/linux/tzcom.h
+++ b/include/linux/tzcom.h
@@ -6,6 +6,7 @@
 #include <linux/types.h>
 #include <linux/ioctl.h>
 
+#define MAX_ION_FD  4
 /**
  * struct tzcom_register_svc_op_req - for register service ioctl request
  * @svc_id - service id (shared between userspace and TZ)
@@ -49,6 +50,8 @@
 /**
  * struct tzcom_send_cmd_op_req - for send command ioctl request
  * @cmd_id - command to execute on TZBSP side
+ * @ifd_data_fd - ion handle to some memory allocated in user space
+ * @cmd_buf_offset - command buffer offset
  * @cmd_len - command buffer length
  * @cmd_buf - command buffer
  * @resp_len - response buffer length
@@ -63,6 +66,34 @@
 };
 
 /**
+ * struct tzcom_ion_fd_info - ion fd handle data information
+ * @fd - ion handle to some memory allocated in user space
+ * @cmd_buf_offset - command buffer offset
+ */
+struct tzcom_ion_fd_info {
+	int32_t fd;
+	uint32_t cmd_buf_offset;
+};
+
+/**
+ * struct tzcom_send_cmd_op_req - for send command ioctl request
+ * @cmd_id - command to execute on TZBSP side
+ * @ifd_data_fd - ion handle to some memory allocated in user space
+ * @cmd_buf_offset - command buffer offset
+ * @cmd_len - command buffer length
+ * @cmd_buf - command buffer
+ * @resp_len - response buffer length
+ * @resp_buf - response buffer
+ */
+struct tzcom_send_cmd_fd_op_req {
+	uint32_t cmd_id; /* in */
+	struct tzcom_ion_fd_info ifd_data[MAX_ION_FD];
+	unsigned int cmd_len; /* in */
+	void *cmd_buf; /* in */
+	unsigned int resp_len; /* in/out */
+	void *resp_buf; /* in/out */
+};
+/**
  * struct tzcom_cont_cmd_op_req - for continue command ioctl request. used
  * as a trigger from HLOS service to notify TZCOM that it's done with its
  * operation and provide the response for TZCOM can continue the incomplete
@@ -99,5 +130,7 @@
 	_IOWR(TZCOM_IOC_MAGIC, 5, struct tzcom_cont_cmd_op_req)
 
 #define TZCOM_IOCTL_ABORT_REQ _IO(TZCOM_IOC_MAGIC, 6)
-
+/* For TZ service */
+#define TZCOM_IOCTL_SEND_CMD_FD_REQ \
+	_IOWR(TZCOM_IOC_MAGIC, 7, struct tzcom_send_cmd_fd_op_req)
 #endif /* __TZCOM_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/media/msm_camera.h b/include/media/msm_camera.h
index 423a849..a984943 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -396,11 +396,11 @@
 #define CMD_AXI_CFG_ZSL 43
 #define CMD_AXI_CFG_SNAP_VPE 44
 #define CMD_AXI_CFG_SNAP_THUMB_VPE 45
-#define CMD_AXI_CFG_VIDEO_ALL_CHNLS  46
-#define CMD_AXI_CFG_ZSL_ALL_CHNLS  47
-#define CMD_CONFIG_PING_ADDR 48
-#define CMD_CONFIG_PONG_ADDR 49
-#define CMD_CONFIG_FREE_BUF_ADDR 50
+#define CMD_CONFIG_PING_ADDR 46
+#define CMD_CONFIG_PONG_ADDR 47
+#define CMD_CONFIG_FREE_BUF_ADDR 48
+#define CMD_AXI_CFG_ZSL_ALL_CHNLS 49
+#define CMD_AXI_CFG_VIDEO_ALL_CHNLS 50
 
 /* vfe config command: config command(from config thread)*/
 struct msm_vfe_cfg_cmd {
@@ -467,6 +467,9 @@
 	uint32_t len;
 	uint32_t y_off;
 	uint32_t cbcr_off;
+	uint32_t planar0_off;
+	uint32_t planar1_off;
+	uint32_t planar2_off;
 	uint8_t active;
 };
 
@@ -487,8 +490,9 @@
 #define OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1 6
 #define OUTPUT_1_2_AND_3 7
 #define OUTPUT_ALL_CHNLS 8
-#define OUTPUT_ZSL_ALL_CHNLS 9
-#define LAST_AXI_OUTPUT_MODE_ENUM  OUTPUT_ZSL_ALL_CHNLS
+#define OUTPUT_VIDEO_ALL_CHNLS 9
+#define OUTPUT_ZSL_ALL_CHNLS 10
+#define LAST_AXI_OUTPUT_MODE_ENUM = OUTPUT_ZSL_ALL_CHNLS
 
 #define MSM_FRAME_PREV_1	0
 #define MSM_FRAME_PREV_2	1
@@ -528,6 +532,9 @@
 	uint32_t phy_offset;
 	uint32_t y_off;
 	uint32_t cbcr_off;
+	uint32_t planar0_off;
+	uint32_t planar1_off;
+	uint32_t planar2_off;
 	int fd;
 
 	void *cropinfo;
@@ -557,10 +564,10 @@
 };
 
 struct msm_st_half {
-	uint32_t buf_y_off;
-	uint32_t buf_cbcr_off;
-	uint32_t buf_y_stride;
-	uint32_t buf_cbcr_stride;
+	uint32_t buf_p0_off;
+	uint32_t buf_p1_off;
+	uint32_t buf_p0_stride;
+	uint32_t buf_p1_stride;
 	uint32_t pix_x_off;
 	uint32_t pix_y_off;
 	struct msm_st_crop stCropInfo;
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 30536a2..312de3f 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -294,8 +294,6 @@
 
 struct l2cap_conf_prm {
 	__u8       fcs;
-	__le16     retrans_timeout;
-	__le16     monitor_timeout;
 	__le32     flush_to;
 };
 
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index cf6cf59..ded74dc 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3212,6 +3212,44 @@
 	return chan;
 }
 
+static void l2cap_get_ertm_timeouts(struct l2cap_conf_rfc *rfc,
+						struct l2cap_pinfo *pi)
+{
+	if (pi->amp_id && pi->ampcon) {
+		u64 ertm_to = pi->ampcon->hdev->amp_be_flush_to;
+
+		/* Class 1 devices have must have ERTM timeouts
+		 * exceeding the Link Supervision Timeout.  The
+		 * default Link Supervision Timeout for AMP
+		 * controllers is 10 seconds.
+		 *
+		 * Class 1 devices use 0xffffffff for their
+		 * best-effort flush timeout, so the clamping logic
+		 * will result in a timeout that meets the above
+		 * requirement.  ERTM timeouts are 16-bit values, so
+		 * the maximum timeout is 65.535 seconds.
+		 */
+
+		/* Convert timeout to milliseconds and round */
+		ertm_to = div_u64(ertm_to + 999, 1000);
+
+		/* This is the recommended formula for class 2 devices
+		 * that start ERTM timers when packets are sent to the
+		 * controller.
+		 */
+		ertm_to = 3 * ertm_to + 500;
+
+		if (ertm_to > 0xffff)
+			ertm_to = 0xffff;
+
+		rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
+		rfc->monitor_timeout = rfc->retrans_timeout;
+	} else {
+		rfc->retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
+		rfc->monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
+	}
+}
+
 int l2cap_build_conf_req(struct sock *sk, void *data)
 {
 	struct l2cap_pinfo *pi = l2cap_pi(sk);
@@ -3262,10 +3300,10 @@
 			rfc.txwin_size = L2CAP_TX_WIN_MAX_ENHANCED;
 		else
 			rfc.txwin_size = pi->tx_win;
-		rfc.max_transmit    = pi->max_tx;
-		rfc.retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
-		rfc.monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
-		rfc.max_pdu_size    = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
+		rfc.max_transmit = pi->max_tx;
+		rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
+		l2cap_get_ertm_timeouts(&rfc, pi);
+
 		if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->imtu)
 			rfc.max_pdu_size = cpu_to_le16(pi->imtu);
 
@@ -3337,30 +3375,16 @@
 	struct l2cap_conf_req *req = data;
 	struct l2cap_conf_rfc rfc = { .mode = pi->mode };
 	void *ptr = req->data;
-	u32 be_flush_to;
 
 	BT_DBG("sk %p", sk);
 
-	/* convert to milliseconds, round up */
-	be_flush_to = (pi->conn->hcon->hdev->amp_be_flush_to + 999) / 1000;
-
 	switch (pi->mode) {
 	case L2CAP_MODE_ERTM:
 		rfc.mode            = L2CAP_MODE_ERTM;
 		rfc.txwin_size      = pi->tx_win;
 		rfc.max_transmit    = pi->max_tx;
-		if (pi->amp_move_id) {
-			rfc.retrans_timeout =
-					cpu_to_le16((3 * be_flush_to) + 500);
-			rfc.monitor_timeout =
-					cpu_to_le16((3 * be_flush_to) + 500);
-		} else {
-			rfc.retrans_timeout =
-					cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
-			rfc.monitor_timeout =
-					cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
-		}
 		rfc.max_pdu_size    = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
+		l2cap_get_ertm_timeouts(&rfc, pi);
 		if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->imtu)
 			rfc.max_pdu_size = cpu_to_le16(pi->imtu);
 
@@ -3374,17 +3398,16 @@
 						(unsigned long) &rfc);
 
 	if (pi->conn->feat_mask & L2CAP_FEAT_FCS) {
-
 		/* TODO assign fcs for br/edr based on socket config option */
-		if (pi->amp_move_id)
+		/* FCS is not used with AMP because it is redundant - lower
+		 * layers already include a checksum. */
+		if (pi->amp_id)
 			pi->local_conf.fcs = L2CAP_FCS_NONE;
 		else
 			pi->local_conf.fcs = L2CAP_FCS_CRC16;
 
-			l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
-						pi->local_conf.fcs);
-
-			pi->fcs = pi->local_conf.fcs | pi->remote_conf.fcs;
+		l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->local_conf.fcs);
+		pi->fcs = pi->local_conf.fcs | pi->remote_conf.fcs;
 	}
 
 	req->dcid  = cpu_to_le16(pi->dcid);
@@ -3546,15 +3569,9 @@
 		case L2CAP_MODE_ERTM:
 			if (!(pi->conf_state & L2CAP_CONF_EXT_WIN_RECV))
 				pi->remote_tx_win = rfc.txwin_size;
-
 			pi->remote_max_tx = rfc.max_transmit;
-
 			pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
-
-			rfc.retrans_timeout =
-				cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
-			rfc.monitor_timeout =
-				cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
+			l2cap_get_ertm_timeouts(&rfc, pi);
 
 			pi->conf_state |= L2CAP_CONF_MODE_DONE;
 
@@ -3660,9 +3677,6 @@
 		case L2CAP_CONF_RFC:
 			if (olen == sizeof(rfc))
 				memcpy(&rfc, (void *) val, olen);
-				if (pi->mode != rfc.mode ||
-					rfc.mode == L2CAP_MODE_BASIC)
-					result = L2CAP_CONF_UNACCEPT;
 			break;
 
 		case L2CAP_CONF_FCS:
@@ -3698,6 +3712,9 @@
 	BT_DBG("result 0x%2.2x cur mode 0x%2.2x req  mode 0x%2.2x",
 		result, pi->mode, rfc.mode);
 
+	if (pi->mode != rfc.mode || rfc.mode == L2CAP_MODE_BASIC)
+		result = L2CAP_CONF_UNACCEPT;
+
 	if (result == L2CAP_CONF_SUCCESS) {
 		/* Configure output options and let the other side know
 		 * which ones we don't like. */
@@ -3717,38 +3734,26 @@
 					pi->remote_tx_win);
 		}
 
+		pi->remote_mps = rfc.max_pdu_size;
+
 		if (rfc.mode == L2CAP_MODE_ERTM) {
-			pi->remote_conf.retrans_timeout =
-				le16_to_cpu(rfc.retrans_timeout);
-			pi->remote_conf.monitor_timeout =
-				le16_to_cpu(rfc.monitor_timeout);
-
-			BT_DBG("remote conf monitor timeout %d",
-					pi->remote_conf.monitor_timeout);
-
-			l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
-					sizeof(rfc), (unsigned long) &rfc);
+			l2cap_get_ertm_timeouts(&rfc, pi);
+		} else {
+			rfc.retrans_timeout = 0;
+			rfc.monitor_timeout = 0;
 		}
 
+		l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
+					sizeof(rfc), (unsigned long) &rfc);
 	}
 
 	if (result != L2CAP_CONF_SUCCESS)
 		goto done;
 
-	pi->fcs = pi->remote_conf.fcs | pi->local_conf.fcs ;
+	pi->fcs = pi->remote_conf.fcs | pi->local_conf.fcs;
 
-	if (pi->rx_state == L2CAP_ERTM_RX_STATE_WAIT_F_FLAG) {
+	if (pi->rx_state == L2CAP_ERTM_RX_STATE_WAIT_F_FLAG)
 		pi->flush_to = pi->remote_conf.flush_to;
-		pi->retrans_timeout = pi->remote_conf.retrans_timeout;
-
-		if (pi->amp_move_id)
-			pi->monitor_timeout = pi->remote_conf.monitor_timeout;
-		else
-			pi->monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
-		BT_DBG("mode %d monitor timeout %d",
-			pi->mode, pi->monitor_timeout);
-
-	}
 
 done:
 	rsp->scid   = cpu_to_le16(pi->dcid);
@@ -3972,34 +3977,41 @@
 			if (type == L2CAP_CONF_RFC) {
 				if (olen == sizeof(rfc))
 					memcpy(&rfc, (void *)val, olen);
-				if (rfc.mode != pi->mode &&
-					rfc.mode != L2CAP_MODE_ERTM) {
-					err = -ECONNREFUSED;
-					goto done;
+
+				if (rfc.mode != pi->mode) {
+					l2cap_send_disconn_req(pi->conn, sk,
+								ECONNRESET);
+					return -ECONNRESET;
 				}
-				break;
+
+				goto done;
 			}
 		}
 	}
 
+	BT_ERR("Expected RFC option was missing, using existing values");
+
+	rfc.mode = pi->mode;
+	rfc.retrans_timeout = cpu_to_le16(pi->retrans_timeout);
+	rfc.monitor_timeout = cpu_to_le16(pi->monitor_timeout);
+
 done:
 	l2cap_ertm_stop_ack_timer(pi);
 	l2cap_ertm_stop_retrans_timer(pi);
 	l2cap_ertm_stop_monitor_timer(pi);
 
+	pi->mps = le16_to_cpu(rfc.max_pdu_size);
+	if (pi->mode == L2CAP_MODE_ERTM) {
+		pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
+		pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
+	}
+
 	if (l2cap_pi(sk)->reconf_state == L2CAP_RECONF_ACC) {
 		l2cap_pi(sk)->reconf_state = L2CAP_RECONF_NONE;
 
 		/* Respond to poll */
 		err = l2cap_answer_move_poll(sk);
-
 	} else if (l2cap_pi(sk)->reconf_state == L2CAP_RECONF_INT) {
-
-		/* If moving to BR/EDR, use default timeout defined by
-		 * the spec */
-		if (pi->amp_move_id == 0)
-			pi->monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
-
 		if (pi->mode == L2CAP_MODE_ERTM) {
 			l2cap_ertm_tx(sk, NULL, NULL,
 					L2CAP_ERTM_EVENT_EXPLICIT_POLL);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 93e7b04..94cacde 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (C) 2000-2001 Qualcomm Incorporated
+   Copyright (c) 2000-2001, 2011-2012 Code Aurora Forum.  All rights reserved.
    Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
    Copyright (C) 2010 Google Inc.
 
@@ -1123,8 +1123,6 @@
 static void set_default_config(struct l2cap_conf_prm *conf_prm)
 {
 	conf_prm->fcs = L2CAP_FCS_CRC16;
-	conf_prm->retrans_timeout = 0;
-	conf_prm->monitor_timeout = 0;
 	conf_prm->flush_to = L2CAP_DEFAULT_FLUSH_TO;
 }
 
@@ -1186,14 +1184,6 @@
 	pi->extended_control = 0;
 
 	pi->local_conf.fcs = pi->fcs;
-	if (pi->mode == L2CAP_MODE_BASIC) {
-		pi->local_conf.retrans_timeout = 0;
-		pi->local_conf.monitor_timeout = 0;
-	} else {
-		pi->local_conf.retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
-		pi->local_conf.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
-	}
-
 	pi->local_conf.flush_to = pi->flush_to;
 
 	set_default_config(&pi->remote_conf);
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index 472fcae..cec01f1 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -41,6 +41,8 @@
 #define TABLA_TX_DAI_ID 2
 #define TABLA_CFILT_FAST_MODE 0x00
 #define TABLA_CFILT_SLOW_MODE 0x40
+#define MBHC_FW_READ_ATTEMPTS 15
+#define MBHC_FW_READ_TIMEOUT 2000000
 
 #define TABLA_JACK_MASK (SND_JACK_HEADSET | SND_JACK_OC_HPHL | SND_JACK_OC_HPHR)
 
@@ -104,6 +106,7 @@
 	u16 dce_mb;
 	u16 sta_z;
 	u16 sta_mb;
+	u32 t_sta_dce;
 	u32 t_dce;
 	u32 t_sta;
 	u32 micb_mv;
@@ -186,6 +189,10 @@
 
 	/* Callback function to enable MCLK */
 	int (*mclk_cb) (struct snd_soc_codec*, int);
+
+	/* Work to perform MBHC Firmware Read */
+	struct delayed_work mbhc_firmware_dwork;
+	const struct firmware *mbhc_fw;
 };
 
 #ifdef CONFIG_DEBUG_FS
@@ -3075,6 +3082,8 @@
 		snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_CLK_CTL, 0x8, 0x8);
 		snd_soc_write(codec, TABLA_A_CDC_MBHC_EN_CTL, 0x4);
 		snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_CLK_CTL, 0x8, 0x0);
+		usleep_range(tabla->mbhc_data.t_sta_dce,
+			     tabla->mbhc_data.t_sta_dce);
 		snd_soc_write(codec, TABLA_A_CDC_MBHC_EN_CTL, 0x4);
 		usleep_range(tabla->mbhc_data.t_dce,
 			     tabla->mbhc_data.t_dce);
@@ -3083,7 +3092,8 @@
 		snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_CLK_CTL, 0x8, 0x8);
 		snd_soc_write(codec, TABLA_A_CDC_MBHC_EN_CTL, 0x2);
 		snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_CLK_CTL, 0x8, 0x0);
-		usleep_range(50, 50);
+		usleep_range(tabla->mbhc_data.t_sta_dce,
+			     tabla->mbhc_data.t_sta_dce);
 		snd_soc_write(codec, TABLA_A_CDC_MBHC_EN_CTL, 0x2);
 		usleep_range(tabla->mbhc_data.t_sta,
 			     tabla->mbhc_data.t_sta);
@@ -3380,19 +3390,8 @@
 	nmeas = TABLA_MBHC_CAL_BTN_DET_PTR(tabla->calibration)->n_meas;
 	navg = TABLA_MBHC_CAL_GENERAL_PTR(tabla->calibration)->mbhc_navg;
 	mclk_rate = tabla->mclk_freq;
-	dce_wait = (1000 * 512 * ncic * nmeas) / (mclk_rate / 1000);
-	if (tabla->mclk_freq == TABLA_MCLK_RATE_12288KHZ)
-		dce_wait = dce_wait + 10000;
-	else if (tabla->mclk_freq == TABLA_MCLK_RATE_9600KHZ)
-		dce_wait = dce_wait + 9810;
-	else
-		WARN(1, "Unsupported mclk freq %d\n", tabla->mclk_freq);
-
-	sta_wait = (1000 * 128 * navg) / (mclk_rate / 1000);
-
-	/* Add 10 microseconds to handle error margin */
-	dce_wait = dce_wait + 10;
-	sta_wait = sta_wait + 10;
+	dce_wait = (1000 * 512 * ncic * (nmeas + 1)) / (mclk_rate / 1000);
+	sta_wait = (1000 * 128 * (navg + 1)) / (mclk_rate / 1000);
 
 	tabla->mbhc_data.t_dce = dce_wait;
 	tabla->mbhc_data.t_sta = sta_wait;
@@ -3509,8 +3508,11 @@
 		tabla->mbhc_data.nready = 2;
 		tabla->mbhc_data.npoll = 7;
 		tabla->mbhc_data.nbounce_wait = 23;
-	}
+	} else
+		WARN(1, "Unsupported mclk freq %d\n", tabla->mclk_freq);
 
+	tabla->mbhc_data.t_sta_dce = ((1000 * 256) / (tabla->mclk_freq / 1000) *
+				      tabla->mbhc_data.nready) + 10;
 	tabla->mbhc_data.v_ins_hu =
 	    tabla_codec_v_sta_dce(codec, STA, plug_type->v_hs_max);
 	tabla->mbhc_data.v_ins_h =
@@ -3592,6 +3594,91 @@
 	snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_B1_CTL, 0x02, 0x02);
 }
 
+static bool tabla_mbhc_fw_validate(const struct firmware *fw)
+{
+	u32 cfg_offset;
+	struct tabla_mbhc_imped_detect_cfg *imped_cfg;
+	struct tabla_mbhc_btn_detect_cfg *btn_cfg;
+
+	if (fw->size < TABLA_MBHC_CAL_MIN_SIZE)
+		return false;
+
+	/* previous check guarantees that there is enough fw data up
+	 * to num_btn
+	 */
+	btn_cfg = TABLA_MBHC_CAL_BTN_DET_PTR(fw->data);
+	cfg_offset = (u32) ((void *) btn_cfg - (void *) fw->data);
+	if (fw->size < (cfg_offset + TABLA_MBHC_CAL_BTN_SZ(btn_cfg)))
+		return false;
+
+	/* previous check guarantees that there is enough fw data up
+	 * to start of impedance detection configuration
+	 */
+	imped_cfg = TABLA_MBHC_CAL_IMPED_DET_PTR(fw->data);
+	cfg_offset = (u32) ((void *) imped_cfg - (void *) fw->data);
+
+	if (fw->size < (cfg_offset + TABLA_MBHC_CAL_IMPED_MIN_SZ))
+		return false;
+
+	if (fw->size < (cfg_offset + TABLA_MBHC_CAL_IMPED_SZ(imped_cfg)))
+		return false;
+
+	return true;
+}
+static void mbhc_fw_read(struct work_struct *work)
+{
+	struct delayed_work *dwork;
+	struct tabla_priv *tabla;
+	struct snd_soc_codec *codec;
+	const struct firmware *fw;
+	int ret = -1, retry = 0, rc;
+
+	dwork = to_delayed_work(work);
+	tabla = container_of(dwork, struct tabla_priv,
+				mbhc_firmware_dwork);
+	codec = tabla->codec;
+
+	while (retry < MBHC_FW_READ_ATTEMPTS) {
+		retry++;
+		pr_info("%s:Attempt %d to request MBHC firmware\n",
+			__func__, retry);
+		ret = request_firmware(&fw, "wcd9310/wcd9310_mbhc.bin",
+					codec->dev);
+
+		if (ret != 0) {
+			usleep_range(MBHC_FW_READ_TIMEOUT,
+					MBHC_FW_READ_TIMEOUT);
+		} else {
+			pr_info("%s: MBHC Firmware read succesful\n", __func__);
+			break;
+		}
+	}
+
+	if (ret != 0) {
+		pr_err("%s: Cannot load MBHC firmware use default cal\n",
+			__func__);
+	} else if (tabla_mbhc_fw_validate(fw) == false) {
+		pr_err("%s: Invalid MBHC cal data size use default cal\n",
+			 __func__);
+		release_firmware(fw);
+	} else {
+		tabla->calibration = (void *)fw->data;
+		tabla->mbhc_fw = fw;
+	}
+
+	tabla->mclk_cb(codec, 1);
+	tabla_mbhc_init(codec);
+	tabla_mbhc_cal(codec);
+	tabla_mbhc_calc_thres(codec);
+	tabla->mclk_cb(codec, 0);
+	tabla_codec_calibrate_hs_polling(codec);
+	rc = tabla_codec_enable_hs_detect(codec, 1);
+
+	if (IS_ERR_VALUE(rc))
+		pr_err("%s: Failed to setup MBHC detection\n", __func__);
+
+}
+
 int tabla_hs_detect(struct snd_soc_codec *codec,
 		    struct snd_soc_jack *headset_jack,
 		    struct snd_soc_jack *button_jack,
@@ -3600,7 +3687,7 @@
 		    int read_fw_bin, u32 mclk_rate)
 {
 	struct tabla_priv *tabla;
-	int rc;
+	int rc = 0;
 
 	if (!codec || !calibration) {
 		pr_err("Error: no codec or calibration\n");
@@ -3618,7 +3705,7 @@
 	/* Put CFILT in fast mode by default */
 	snd_soc_update_bits(codec, tabla->mbhc_bias_regs.cfilt_ctl,
 		0x40, TABLA_CFILT_FAST_MODE);
-
+	INIT_DELAYED_WORK(&tabla->mbhc_firmware_dwork, mbhc_fw_read);
 	INIT_DELAYED_WORK(&tabla->btn0_dwork, btn0_lpress_fn);
 	INIT_WORK(&tabla->hphlocp_work, hphlocp_off_report);
 	INIT_WORK(&tabla->hphrocp_work, hphrocp_off_report);
@@ -3632,8 +3719,8 @@
 		tabla_codec_calibrate_hs_polling(codec);
 		rc =  tabla_codec_enable_hs_detect(codec, 1);
 	} else {
-		pr_err("%s: MBHC firmware read not supported\n", __func__);
-		rc = -EINVAL;
+		schedule_delayed_work(&tabla->mbhc_firmware_dwork,
+				usecs_to_jiffies(MBHC_FW_READ_TIMEOUT));
 	}
 
 	if (!IS_ERR_VALUE(rc)) {
@@ -4386,6 +4473,7 @@
 	/* Make sure mbhc intenal calibration data is zeroed out */
 	memset(&tabla->mbhc_data, 0,
 		sizeof(struct mbhc_internal_cal_data));
+	tabla->mbhc_data.t_sta_dce = DEFAULT_DCE_STA_WAIT;
 	tabla->mbhc_data.t_dce = DEFAULT_DCE_WAIT;
 	tabla->mbhc_data.t_sta = DEFAULT_STA_WAIT;
 	snd_soc_codec_set_drvdata(codec, tabla);
@@ -4552,6 +4640,8 @@
 	tabla_free_irq(codec->control_data, TABLA_IRQ_MBHC_INSERTION, tabla);
 	tabla_codec_disable_clock_block(codec);
 	tabla_codec_enable_bandgap(codec, TABLA_BANDGAP_OFF);
+	if (tabla->mbhc_fw)
+		release_firmware(tabla->mbhc_fw);
 	kfree(tabla);
 	return 0;
 }
diff --git a/sound/soc/codecs/wcd9310.h b/sound/soc/codecs/wcd9310.h
index 66c3e39..77bfc73 100644
--- a/sound/soc/codecs/wcd9310.h
+++ b/sound/soc/codecs/wcd9310.h
@@ -21,7 +21,7 @@
 
 #define TABLA_REG_VAL(reg, val)		{reg, 0, val}
 
-
+#define DEFAULT_DCE_STA_WAIT 55
 #define DEFAULT_DCE_WAIT 60000
 #define DEFAULT_STA_WAIT 5000
 
@@ -197,3 +197,29 @@
 	       sizeof(TABLA_MBHC_CAL_BTN_DET_PTR(cali)->_v_btn_high[0])))) \
 	)
 
+/* minimum size of calibration data assuming there is only one button and
+ * one rload.
+ */
+#define TABLA_MBHC_CAL_MIN_SIZE ( \
+	sizeof(struct tabla_mbhc_general_cfg) + \
+	sizeof(struct tabla_mbhc_plug_detect_cfg) + \
+	sizeof(struct tabla_mbhc_plug_type_cfg) + \
+	sizeof(struct tabla_mbhc_btn_detect_cfg) + \
+	sizeof(struct tabla_mbhc_imped_detect_cfg) + \
+	(sizeof(u16) * 2))
+
+#define TABLA_MBHC_CAL_BTN_SZ(cfg_ptr) ( \
+	    sizeof(struct tabla_mbhc_btn_detect_cfg) + \
+	    (cfg_ptr->num_btn * (sizeof(cfg_ptr->_v_btn_low[0]) + \
+				 sizeof(cfg_ptr->_v_btn_high[0]))))
+
+#define TABLA_MBHC_CAL_IMPED_MIN_SZ ( \
+	    sizeof(struct tabla_mbhc_imped_detect_cfg) + \
+	    sizeof(u16) * 2)
+
+#define TABLA_MBHC_CAL_IMPED_SZ(cfg_ptr) ( \
+	    sizeof(struct tabla_mbhc_imped_detect_cfg) + \
+	    (cfg_ptr->_n_rload * (sizeof(cfg_ptr->_rload[0]) + \
+				 sizeof(cfg_ptr->_alpha[0]))))
+
+
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index 590d4af..d0497b1 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -47,10 +47,10 @@
 	.channels_min =	 1,
 	.channels_max =	 2,
 	.buffer_bytes_max =     1200 * 1024 * 2,
-	.period_bytes_min =	60 * 1024,
+	.period_bytes_min =	4800,
 	.period_bytes_max =     1200 * 1024,
 	.periods_min =	  2,
-	.periods_max =	  40,
+	.periods_max =	  512,
 	.fifo_size =	    0,
 };
 
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/q6afe.c b/sound/soc/msm/qdsp6/q6afe.c
index 21bbcf2..74a66945 100644
--- a/sound/soc/msm/qdsp6/q6afe.c
+++ b/sound/soc/msm/qdsp6/q6afe.c
@@ -56,6 +56,7 @@
 		pr_debug("task_name = %s pid = %d\n",
 			this_afe.task->comm, this_afe.task->pid);
 		send_sig(SIGUSR1, this_afe.task, 0);
+		return 0;
 	}
 	if (data->payload_size) {
 		uint32_t *payload;
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index ab7f9f7..62168d2 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -515,6 +515,7 @@
 						pr_err("%s:map_buffer failed,"
 							"error = %ld\n",
 				__func__, PTR_ERR((void *)buf[cnt].mem_buffer));
+						mutex_unlock(&ac->cmd_lock);
 						goto fail;
 					}
 					buf[cnt].data =
@@ -522,6 +523,7 @@
 					if (!buf[cnt].data) {
 						pr_err("%s:invalid vaddr,"
 						" iomap failed\n", __func__);
+						mutex_unlock(&ac->cmd_lock);
 						goto fail;
 					}
 					buf[cnt].used = 1;
@@ -944,6 +946,7 @@
 		idx = port->cpu_buf;
 		if (port->buf == NULL) {
 			pr_debug("%s:Buffer pointer null\n", __func__);
+			mutex_unlock(&port->lock);
 			return NULL;
 		}
 		/*  dir 0: used = 0 means buf in use