Merge "hwmon: epm_adc: Fix incorrect SPI writes"
diff --git a/AndroidKernel.mk b/AndroidKernel.mk
index 3ee63c0..717dd8c 100644
--- a/AndroidKernel.mk
+++ b/AndroidKernel.mk
@@ -11,11 +11,10 @@
 KERNEL_MODULES_OUT := $(TARGET_OUT)/lib/modules
 KERNEL_IMG=$(KERNEL_OUT)/arch/arm/boot/Image
 
-MSM_ARCH ?= $(shell $(PERL) -e 'while (<>) {$$a = $$1 if /CONFIG_ARCH_((?:MSM|QSD)[a-zA-Z0-9]+)=y/; $$r = $$1 if /CONFIG_MSM_SOC_REV_(?!NONE)(\w+)=y/;} print lc("$$a$$r\n");' $(KERNEL_CONFIG))
+DTS_NAMES ?= $(shell $(PERL) -e 'while (<>) {$$a = $$1 if /CONFIG_ARCH_((?:MSM|QSD)[a-zA-Z0-9]+)=y/; $$r = $$1 if /CONFIG_MSM_SOC_REV_(?!NONE)(\w+)=y/; $$arch = $$arch.lc("$$a$$r ") if /CONFIG_ARCH_((?:MSM|QSD)[a-zA-Z0-9]+)=y/} print $$arch;' $(KERNEL_CONFIG))
 KERNEL_USE_OF ?= $(shell $(PERL) -e '$$of = "n"; while (<>) { if (/CONFIG_USE_OF=y/) { $$of = "y"; break; } } print $$of;' kernel/arch/arm/configs/$(KERNEL_DEFCONFIG))
 
 ifeq "$(KERNEL_USE_OF)" "y"
-DTS_NAME ?= $(MSM_ARCH)
 DTS_FILES = $(wildcard $(TOP)/kernel/arch/arm/boot/dts/$(DTS_NAME)*.dts)
 DTS_FILE = $(lastword $(subst /, ,$(1)))
 DTB_FILE = $(addprefix $(KERNEL_OUT)/arch/arm/boot/,$(patsubst %.dts,%.dtb,$(call DTS_FILE,$(1))))
@@ -25,9 +24,10 @@
 
 define append-dtb
 mkdir -p $(KERNEL_OUT)/arch/arm/boot;\
-$(foreach d, $(DTS_FILES), \
-   $(DTC) -p 1024 -O dtb -o $(call DTB_FILE,$(d)) $(d); \
-   cat $(KERNEL_ZIMG) $(call DTB_FILE,$(d)) > $(call ZIMG_FILE,$(d));)
+$(foreach DTS_NAME, $(DTS_NAMES), \
+   $(foreach d, $(DTS_FILES), \
+      $(DTC) -p 1024 -O dtb -o $(call DTB_FILE,$(d)) $(d); \
+      cat $(KERNEL_ZIMG) $(call DTB_FILE,$(d)) > $(call ZIMG_FILE,$(d));))
 endef
 else
 
diff --git a/arch/arm/boot/dts/msm8226-camera.dtsi b/arch/arm/boot/dts/msm8226-camera.dtsi
new file mode 100644
index 0000000..2a9fdf2
--- /dev/null
+++ b/arch/arm/boot/dts/msm8226-camera.dtsi
@@ -0,0 +1,18 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/ {
+	qcom,cam_server {
+		compatible = "qcom,cam_server";
+		reg = <0xfd8C0000 0x10000>;
+	};
+};
diff --git a/arch/arm/boot/dts/msm8226-ion.dtsi b/arch/arm/boot/dts/msm8226-ion.dtsi
new file mode 100644
index 0000000..beaffe5
--- /dev/null
+++ b/arch/arm/boot/dts/msm8226-ion.dtsi
@@ -0,0 +1,23 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/ {
+	qcom,ion {
+		compatible = "qcom,msm-ion";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		qcom,ion-heap@30 { /* SYSTEM HEAP */
+			reg = <30>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/msm8226-sim.dts b/arch/arm/boot/dts/msm8226-sim.dts
new file mode 100644
index 0000000..4330849
--- /dev/null
+++ b/arch/arm/boot/dts/msm8226-sim.dts
@@ -0,0 +1,61 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/include/ "skeleton.dtsi"
+/include/ "msm8226-ion.dtsi"
+/include/ "msm8226-camera.dtsi"
+
+/ {
+	model = "Qualcomm MSM 8226 Simulator";
+	compatible = "qcom,msm8226-sim", "qcom,msm8226";
+	qcom,msm-id = <145 1 0>;
+	interrupt-parent = <&intc>;
+
+	chosen {
+		bootargs ="root=/dev/ram rw init=/init console=ttyHSL0,115200n8 initrd=0x00000000,0x00000000 mem=512M@0x00000000";
+	};
+
+	intc: interrupt-controller@f9000000 {
+		compatible = "qcom,msm-qgic2";
+		interrupt-controller;
+		#interrupt-cells = <3>;
+		reg = <0xF9000000 0x1000>,
+		      <0xF9002000 0x1000>;
+	};
+
+	msmgpio: gpio@fd510000 {
+		compatible = "qcom,msm-gpio";
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		reg = <0xfd510000 0x4000>;
+		#gpio-cells = <2>;
+	};
+
+	timer {
+		compatible = "qcom,msm-qtimer", "arm,armv7-timer";
+		interrupts = <1 2 0 1 3 0>;
+		clock-frequency = <19200000>;
+	};
+
+	serial@f991f000 {
+		compatible = "qcom,msm-lsuart-v14";
+		reg = <0xf991f000 0x1000>;
+		interrupts = <0 109 0>;
+	};
+
+	serial@f995e000 {
+		compatible = "qcom,msm-lsuart-v14";
+		reg = <0xf995e000 0x1000>;
+		interrupts = <0 114 0>;
+	};
+};
diff --git a/arch/arm/boot/dts/msm8974-liquid.dts b/arch/arm/boot/dts/msm8974-liquid.dts
new file mode 100644
index 0000000..5de2d43
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-liquid.dts
@@ -0,0 +1,27 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm8974.dtsi"
+
+/ {
+	model = "Qualcomm MSM 8974 LIQUID";
+	compatible = "qcom,msm8974-liquid", "qcom,msm8974";
+	qcom,msm-id = <126 9 0>;
+
+	serial@f991e000 {
+		status = "ok";
+	};
+};
+
+
diff --git a/arch/arm/boot/dts/msm8974-regulator.dtsi b/arch/arm/boot/dts/msm8974-regulator.dtsi
index 1fd96f9..de9e98c 100644
--- a/arch/arm/boot/dts/msm8974-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974-regulator.dtsi
@@ -58,6 +58,15 @@
 			status = "okay";
 			compatible = "qcom,rpm-regulator-smd";
 		};
+		pm8841_s1_so: regulator-s1-so {
+			regulator-name = "8841_s1_so";
+			qcom,set = <2>;
+			regulator-min-microvolt = <675000>;
+			regulator-max-microvolt = <1050000>;
+			qcom,init-voltage = <675000>;
+			status = "okay";
+			compatible = "qcom,rpm-regulator-smd";
+		};
 	};
 
 	rpm-regulator-smpb2 {
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index 25d97af..aeb59af 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -53,6 +53,8 @@
 CONFIG_PM8XXX_RPC_VIBRATOR=y
 CONFIG_MSM_SPM_V2=y
 CONFIG_MSM_MULTIMEDIA_USE_ION=y
+CONFIG_MSM_RTB=y
+CONFIG_MSM_RTB_SEPARATE_CPUS=y
 CONFIG_MSM_CPR=y
 CONFIG_MSM_VP_REGULATOR=y
 CONFIG_ARM_THUMBEE=y
@@ -379,4 +381,3 @@
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_USER=y
 CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 2c8f71e..b08869a 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -96,6 +96,7 @@
 CONFIG_MSM_L1_ERR_PANIC=y
 CONFIG_MSM_L1_ERR_LOG=y
 CONFIG_MSM_L2_ERP_2BIT_PANIC=y
+CONFIG_MSM_EVENT_TIMER=y
 CONFIG_MSM_DCVS=y
 CONFIG_MSM_HSIC_SYSMON=y
 CONFIG_STRICT_MEMORY_RWX=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index a2deab2..26e7f32 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -87,6 +87,7 @@
 CONFIG_MSM_RPM_RBCPR_STATS_LOG=y
 CONFIG_MSM_BUS_SCALING=y
 CONFIG_MSM_BUS_RPM_MULTI_TIER_ENABLED=y
+CONFIG_MSM_EVENT_TIMER=y
 CONFIG_MSM_WATCHDOG=y
 CONFIG_MSM_DLOAD_MODE=y
 CONFIG_MSM_RTB=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 53c2211..471ecd9 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -32,6 +32,7 @@
 CONFIG_EFI_PARTITION=y
 CONFIG_ARCH_MSM=y
 CONFIG_ARCH_MSM8974=y
+CONFIG_ARCH_MSM8226=y
 CONFIG_MSM_KRAIT_TBB_ABORT_HANDLER=y
 # CONFIG_MSM_STACKED_MEMORY is not set
 CONFIG_KERNEL_PMEM_EBI_REGION=y
@@ -77,7 +78,6 @@
 CONFIG_HIGHMEM=y
 CONFIG_VMALLOC_RESERVE=0x19000000
 CONFIG_USE_OF=y
-CONFIG_ARM_ATAG_DTB_COMPAT=y
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 7d26726..e46fd92 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -507,7 +507,7 @@
 		raw_spin_unlock(&stop_lock);
 	}
 
-	set_cpu_online(cpu, false);
+	set_cpu_active(cpu, false);
 
 	local_fiq_disable();
 	local_irq_disable();
@@ -657,10 +657,10 @@
 
 	/* Wait up to one second for other CPUs to stop */
 	timeout = USEC_PER_SEC;
-	while (num_online_cpus() > 1 && timeout--)
+	while (num_active_cpus() > 1 && timeout--)
 		udelay(1);
 
-	if (num_online_cpus() > 1)
+	if (num_active_cpus() > 1)
 		pr_warning("SMP: failed to stop secondary CPUs\n");
 
 	smp_kill_cpus(&mask);
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index badee85..c9b786c 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -2142,6 +2142,14 @@
 	depends on PM
 	bool
 
+config MSM_EVENT_TIMER
+	bool "Event timer"
+	help
+		This option enables a modules that manages a list of event timers that
+		need to be monitored by the PM. The enables the PM code to monitor
+		events that require the core to be awake and ready to handle the
+		event.
+
 config MSM_NOPM
 	default y if !PM
 	bool
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 505048c..d8e625a 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -116,6 +116,7 @@
 ifndef CONFIG_ARCH_MSM8X60
 ifndef CONFIG_ARCH_APQ8064
 ifndef CONFIG_ARCH_MSM8974
+ifndef CONFIG_ARCH_MSM8226
 ifndef CONFIG_ARCH_MSM9625
 ifndef CONFIG_ARCH_MPQ8092
 	obj-y += nand_partitions.o
@@ -125,6 +126,7 @@
 endif
 endif
 endif
+endif
 obj-$(CONFIG_MSM_SDIO_TTY) += sdio_tty.o
 obj-$(CONFIG_MSM_SMD_TTY) += smd_tty.o
 obj-$(CONFIG_MSM_SMD_QMI) += smd_qmi.o
@@ -290,7 +292,7 @@
 obj-$(CONFIG_MACH_APQ8064_CDP) += board-8064-all.o board-8064-regulator.o
 obj-$(CONFIG_MACH_APQ8064_MTP) += board-8064-all.o board-8064-regulator.o
 obj-$(CONFIG_MACH_APQ8064_LIQUID) += board-8064-all.o board-8064-regulator.o
-obj-$(CONFIG_MACH_MPQ8064_HRD) += board-8064-all.o board-8064-regulator.o
+obj-$(CONFIG_MACH_MPQ8064_HRD) += board-8064-all.o board-8064-regulator.o board-8064-bt.o
 obj-$(CONFIG_MACH_MPQ8064_DTV) += board-8064-all.o board-8064-regulator.o
 obj-$(CONFIG_ARCH_MSM9615) += board-9615.o devices-9615.o board-9615-regulator.o board-9615-gpiomux.o board-9615-storage.o board-9615-display.o
 obj-$(CONFIG_ARCH_MSM9615) += clock-local.o clock-9615.o acpuclock-9615.o clock-rpm.o clock-pll.o
@@ -302,6 +304,7 @@
 obj-$(CONFIG_ARCH_MSM9625) += board-9625.o board-9625-gpiomux.o
 obj-$(CONFIG_ARCH_MSM8930) += acpuclock-8930.o acpuclock-8627.o acpuclock-8930aa.o
 obj-$(CONFIG_ARCH_MPQ8092) += board-8092.o board-8092-gpiomux.o
+obj-$(CONFIG_ARCH_MSM8226) += board-8226.o board-8226-gpiomux.o
 
 obj-$(CONFIG_MACH_SAPPHIRE) += board-sapphire.o board-sapphire-gpio.o
 obj-$(CONFIG_MACH_SAPPHIRE) += board-sapphire-keypad.o board-sapphire-panel.o
@@ -340,6 +343,7 @@
 obj-$(CONFIG_MSM_BUSPM_DEV) += msm-buspm-dev.o
 
 obj-$(CONFIG_MSM_IOMMU)		+= devices-iommu.o iommu_domains.o
+obj-$(CONFIG_MSM_EVENT_TIMER)		+= event_timer.o
 
 ifdef CONFIG_VCM
 obj-$(CONFIG_ARCH_MSM8X60) += board-msm8x60-vcm.o
@@ -357,6 +361,7 @@
 obj-$(CONFIG_ARCH_MSM8974) += gpiomux-v2.o gpiomux.o
 obj-$(CONFIG_ARCH_MSM9625) += gpiomux-v2.o gpiomux.o
 obj-$(CONFIG_ARCH_MPQ8092) += gpiomux-v2.o gpiomux.o
+obj-$(CONFIG_ARCH_MSM8226) += gpiomux-v2.o gpiomux.o
 
 obj-$(CONFIG_MSM_SLEEP_STATS_DEVICE) += idle_stats_device.o
 obj-$(CONFIG_MSM_DCVS) += msm_dcvs_scm.o msm_dcvs.o msm_dcvs_idle.o
diff --git a/arch/arm/mach-msm/Makefile.boot b/arch/arm/mach-msm/Makefile.boot
index 437933e..526616a 100644
--- a/arch/arm/mach-msm/Makefile.boot
+++ b/arch/arm/mach-msm/Makefile.boot
@@ -54,6 +54,9 @@
 # MSM9625
    zreladdr-$(CONFIG_ARCH_MSM9625)	:= 0x20208000
 
+# MSM8226
+   zreladdr-$(CONFIG_ARCH_MSM8226)	:= 0x00008000
+
 # FSM9XXX
    zreladdr-$(CONFIG_ARCH_FSM9XXX)	:= 0x10008000
 params_phys-$(CONFIG_ARCH_FSM9XXX)	:= 0x10000100
diff --git a/arch/arm/mach-msm/acpuclock-7627.c b/arch/arm/mach-msm/acpuclock-7627.c
index 3bcba5f..7be3667 100644
--- a/arch/arm/mach-msm/acpuclock-7627.c
+++ b/arch/arm/mach-msm/acpuclock-7627.c
@@ -723,7 +723,7 @@
 			/* Make sure PLL4 is off before reprogramming */
 			if ((plls_enabled & (1 << tgt_s->pll))) {
 				clk_disable(pll_clk[tgt_s->pll].clk);
-				plls_enabled &= (0 << tgt_s->pll);
+				plls_enabled &= ~(1 << tgt_s->pll);
 			}
 			acpuclk_config_pll4(tgt_s->pll_rate);
 			pll_clk[tgt_s->pll].clk->rate = tgt_s->a11clk_khz*1000;
diff --git a/arch/arm/mach-msm/board-8064-bt.c b/arch/arm/mach-msm/board-8064-bt.c
new file mode 100644
index 0000000..a8ae9fa
--- /dev/null
+++ b/arch/arm/mach-msm/board-8064-bt.c
@@ -0,0 +1,547 @@
+/* Copyright (c) 2011-2012, Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/rfkill.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/mfd/marimba.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <mach/rpc_pmapp.h>
+#include <mach/msm_xo.h>
+#include <mach/socinfo.h>
+
+#include "board-8064.h"
+
+#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
+
+#define BAHAMA_SLAVE_ID_FM_ADDR  0x2A
+#define BAHAMA_SLAVE_ID_QMEMBIST_ADDR   0x7B
+
+struct bt_vreg_info {
+	const char *name;
+	unsigned int pmapp_id;
+	unsigned int min_level;
+	unsigned int max_level;
+	unsigned int is_pin_controlled;
+	struct regulator *reg;
+};
+
+struct bahama_config_register {
+	u8 reg;
+	u8 value;
+	u8 mask;
+};
+static struct bt_vreg_info bt_vregs[] = {
+	{"bha_vddxo",  2, 1800000, 1800000, 0, NULL},
+	{"bha_vddpx", 21, 1800000, 1800000, 0, NULL},
+	{"bha_vddpa", 21, 2900000, 3300000, 0, NULL}
+};
+
+static struct msm_xo_voter *bt_clock;
+
+static struct platform_device msm_bt_power_device = {
+	.name = "bt_power",
+	.id = -1,
+};
+
+static unsigned bt_config_pcm_on[] = {
+	/*PCM_DOUT*/
+	GPIO_CFG(43, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+	/*PCM_DIN*/
+	GPIO_CFG(44, 1, GPIO_CFG_INPUT,  GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+	/*PCM_SYNC*/
+	GPIO_CFG(45, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+	/*PCM_CLK*/
+	GPIO_CFG(46, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+};
+
+static unsigned bt_config_pcm_off[] = {
+	/*PCM_DOUT*/
+	GPIO_CFG(43, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+	/*PCM_DIN*/
+	GPIO_CFG(44, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+	/*PCM_SYNC*/
+	GPIO_CFG(45, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+	/*PCM_CLK*/
+	GPIO_CFG(46, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+};
+
+static int config_pcm(int mode)
+{
+	int pin, rc = 0;
+
+	if (mode == BT_PCM_ON) {
+		pr_err("%s mode =BT_PCM_ON", __func__);
+		for (pin = 0; pin < ARRAY_SIZE(bt_config_pcm_on);
+			pin++) {
+				rc = gpio_tlmm_config(bt_config_pcm_on[pin],
+					GPIO_CFG_ENABLE);
+				if (rc < 0)
+					return rc;
+		}
+	} else if (mode == BT_PCM_OFF) {
+		pr_err("%s mode =BT_PCM_OFF", __func__);
+		for (pin = 0; pin < ARRAY_SIZE(bt_config_pcm_off);
+			pin++) {
+				rc = gpio_tlmm_config(bt_config_pcm_off[pin],
+					GPIO_CFG_ENABLE);
+				if (rc < 0)
+					return rc;
+		}
+
+	}
+
+	return rc;
+}
+
+static int bahama_bt(int on)
+{
+	int rc = 0;
+	int i;
+
+	struct marimba config = { .mod_id =  SLAVE_ID_BAHAMA};
+
+	struct bahama_variant_register {
+		const size_t size;
+		const struct bahama_config_register *set;
+	};
+
+	const struct bahama_config_register *p;
+
+	u8 version;
+
+	const struct bahama_config_register v10_bt_on[] = {
+		{ 0xE9, 0x00, 0xFF },
+		{ 0xF4, 0x80, 0xFF },
+		{ 0xE4, 0x00, 0xFF },
+		{ 0xE5, 0x00, 0x0F },
+#ifdef CONFIG_WLAN
+		{ 0xE6, 0x38, 0x7F },
+		{ 0xE7, 0x06, 0xFF },
+#endif
+		{ 0xE9, 0x21, 0xFF },
+		{ 0x01, 0x0C, 0x1F },
+		{ 0x01, 0x08, 0x1F },
+	};
+
+	const struct bahama_config_register v20_bt_on_fm_off[] = {
+		{ 0x11, 0x0C, 0xFF },
+		{ 0x13, 0x01, 0xFF },
+		{ 0xF4, 0x80, 0xFF },
+		{ 0xF0, 0x00, 0xFF },
+		{ 0xE9, 0x00, 0xFF },
+#ifdef CONFIG_WLAN
+		{ 0x81, 0x00, 0x7F },
+		{ 0x82, 0x00, 0xFF },
+		{ 0xE6, 0x38, 0x7F },
+		{ 0xE7, 0x06, 0xFF },
+#endif
+		{ 0x8E, 0x15, 0xFF },
+		{ 0x8F, 0x15, 0xFF },
+		{ 0x90, 0x15, 0xFF },
+
+		{ 0xE9, 0x21, 0xFF },
+	};
+
+	const struct bahama_config_register v20_bt_on_fm_on[] = {
+		{ 0x11, 0x0C, 0xFF },
+		{ 0x13, 0x01, 0xFF },
+		{ 0xF4, 0x86, 0xFF },
+		{ 0xF0, 0x06, 0xFF },
+		{ 0xE9, 0x00, 0xFF },
+#ifdef CONFIG_WLAN
+		{ 0x81, 0x00, 0x7F },
+		{ 0x82, 0x00, 0xFF },
+		{ 0xE6, 0x38, 0x7F },
+		{ 0xE7, 0x06, 0xFF },
+#endif
+		{ 0xE9, 0x21, 0xFF },
+	};
+
+	const struct bahama_config_register v10_bt_off[] = {
+		{ 0xE9, 0x00, 0xFF },
+	};
+
+	const struct bahama_config_register v20_bt_off_fm_off[] = {
+		{ 0xF4, 0x84, 0xFF },
+		{ 0xF0, 0x04, 0xFF },
+		{ 0xE9, 0x00, 0xFF }
+	};
+
+	const struct bahama_config_register v20_bt_off_fm_on[] = {
+		{ 0xF4, 0x86, 0xFF },
+		{ 0xF0, 0x06, 0xFF },
+		{ 0xE9, 0x00, 0xFF }
+	};
+
+	const struct bahama_variant_register bt_bahama[2][3] = {
+	{
+		{ ARRAY_SIZE(v10_bt_off), v10_bt_off },
+		{ ARRAY_SIZE(v20_bt_off_fm_off), v20_bt_off_fm_off },
+		{ ARRAY_SIZE(v20_bt_off_fm_on), v20_bt_off_fm_on }
+	},
+	{
+		{ ARRAY_SIZE(v10_bt_on), v10_bt_on },
+		{ ARRAY_SIZE(v20_bt_on_fm_off), v20_bt_on_fm_off },
+		{ ARRAY_SIZE(v20_bt_on_fm_on), v20_bt_on_fm_on }
+	}
+	};
+
+	u8 offset = 0; /* index into bahama configs */
+	on = on ? 1 : 0;
+	version = marimba_read_bahama_ver(&config);
+	if ((int)version < 0 || version == BAHAMA_VER_UNSUPPORTED) {
+		dev_err(&msm_bt_power_device.dev,
+			"%s : Bahama version read Error, version = %d\n",
+			__func__, version);
+		return -EIO;
+	}
+	if (version == BAHAMA_VER_2_0) {
+		if (marimba_get_fm_status(&config))
+			offset = 0x01;
+	}
+
+	p = bt_bahama[on][version + offset].set;
+
+	dev_dbg(&msm_bt_power_device.dev,
+		"%s: found version %d\n", __func__, version);
+
+	for (i = 0; i < bt_bahama[on][version + offset].size; i++) {
+		u8 value = (p+i)->value;
+		rc = marimba_write_bit_mask(&config,
+			(p+i)->reg,
+			&value,
+			sizeof((p+i)->value),
+			(p+i)->mask);
+		if (rc < 0) {
+			dev_err(&msm_bt_power_device.dev,
+				"%s: reg %x write failed: %d\n",
+				__func__, (p+i)->reg, rc);
+			return rc;
+		}
+		dev_dbg(&msm_bt_power_device.dev,
+			"%s: reg 0x%02x write value 0x%02x mask 0x%02x\n",
+				__func__, (p+i)->reg,
+				value, (p+i)->mask);
+		value = 0;
+		rc = marimba_read_bit_mask(&config,
+				(p+i)->reg, &value,
+				sizeof((p+i)->value), (p+i)->mask);
+		if (rc < 0)
+			dev_err(&msm_bt_power_device.dev,
+				"%s marimba_read_bit_mask- error",
+				__func__);
+		dev_dbg(&msm_bt_power_device.dev,
+			"%s: reg 0x%02x read value 0x%02x mask 0x%02x\n",
+				__func__, (p+i)->reg,
+				value, (p+i)->mask);
+	}
+	/* Update BT Status */
+	if (on)
+		marimba_set_bt_status(&config, true);
+	else
+		marimba_set_bt_status(&config, false);
+	return rc;
+}
+
+static int bluetooth_switch_regulators(int on)
+{
+	int i, rc = 0;
+
+	for (i = 0; i < ARRAY_SIZE(bt_vregs); i++) {
+		if (IS_ERR_OR_NULL(bt_vregs[i].reg)) {
+			bt_vregs[i].reg =
+				regulator_get(&msm_bt_power_device.dev,
+						bt_vregs[i].name);
+			if (IS_ERR(bt_vregs[i].reg)) {
+				rc = PTR_ERR(bt_vregs[i].reg);
+				dev_err(&msm_bt_power_device.dev,
+					"%s: invalid regulator handle for %s: %d\n",
+						__func__, bt_vregs[i].name, rc);
+				goto reg_disable;
+			}
+		}
+		rc = on ? regulator_set_voltage(bt_vregs[i].reg,
+					bt_vregs[i].min_level,
+						bt_vregs[i].max_level) : 0;
+		if (rc) {
+			dev_err(&msm_bt_power_device.dev,
+				"%s: could not set voltage for %s: %d\n",
+					__func__, bt_vregs[i].name, rc);
+			goto reg_disable;
+		}
+
+		rc = on ? regulator_enable(bt_vregs[i].reg) : 0;
+		if (rc) {
+			dev_err(&msm_bt_power_device.dev,
+				"%s: could not %sable regulator %s: %d\n",
+					__func__, "en", bt_vregs[i].name, rc);
+			goto reg_disable;
+		}
+
+		rc = on ? 0 : regulator_disable(bt_vregs[i].reg);
+
+		if (rc) {
+			dev_err(&msm_bt_power_device.dev,
+				"%s: could not %sable regulator %s: %d\n",
+					__func__, "dis", bt_vregs[i].name, rc);
+			goto reg_disable;
+		}
+	}
+
+	return rc;
+reg_disable:
+	pr_err("bluetooth_switch_regulators - FAIL!!!!\n");
+	while (i) {
+		if (on) {
+			i--;
+			regulator_disable(bt_vregs[i].reg);
+			regulator_put(bt_vregs[i].reg);
+			bt_vregs[i].reg = NULL;
+		}
+	}
+	return rc;
+}
+
+static unsigned int msm_bahama_setup_power(void)
+{
+	int rc = 0;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(bt_vregs); i++) {
+		bt_vregs[i].reg = regulator_get(&msm_bt_power_device.dev,
+						bt_vregs[i].name);
+		if (IS_ERR(bt_vregs[i].reg)) {
+			rc = PTR_ERR(bt_vregs[i].reg);
+			pr_err("%s: could not get regulator %s: %d\n",
+					__func__, bt_vregs[i].name, rc);
+			goto reg_fail;
+		}
+		rc = regulator_set_voltage(bt_vregs[i].reg,
+					bt_vregs[i].min_level,
+						bt_vregs[i].max_level);
+		if (rc) {
+			pr_err("%s: could not set voltage for %s: %d\n",
+					__func__, bt_vregs[i].name, rc);
+			goto reg_fail;
+		}
+		rc = regulator_enable(bt_vregs[i].reg);
+		if (rc) {
+			pr_err("%s: could not enable regulator %s: %d\n",
+					__func__, bt_vregs[i].name, rc);
+			goto reg_fail;
+		}
+	}
+	return rc;
+reg_fail:
+	pr_err("msm_bahama_setup_power FAILED !!!\n");
+
+	while (i) {
+		i--;
+		regulator_disable(bt_vregs[i].reg);
+		regulator_put(bt_vregs[i].reg);
+		bt_vregs[i].reg = NULL;
+	}
+	return rc;
+}
+
+static unsigned int msm_bahama_shutdown_power(int value)
+{
+	int rc = 0;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(bt_vregs); i++) {
+		rc = regulator_disable(bt_vregs[i].reg);
+
+		if (rc < 0) {
+			pr_err("%s: could not disable regulator %s: %d\n",
+					__func__, bt_vregs[i].name, rc);
+			goto out;
+		}
+
+		regulator_put(bt_vregs[i].reg);
+		bt_vregs[i].reg = NULL;
+	}
+out:
+	return rc;
+}
+
+static unsigned int msm_bahama_core_config(int type)
+{
+	int rc = 0;
+
+	if (type == BAHAMA_ID) {
+		int i;
+		struct marimba config = { .mod_id =  SLAVE_ID_BAHAMA};
+		const struct bahama_config_register v20_init[] = {
+			/* reg, value, mask */
+			{ 0xF4, 0x84, 0xFF }, /* AREG */
+			{ 0xF0, 0x04, 0xFF } /* DREG */
+		};
+		if (marimba_read_bahama_ver(&config) == BAHAMA_VER_2_0) {
+			for (i = 0; i < ARRAY_SIZE(v20_init); i++) {
+				u8 value = v20_init[i].value;
+				rc = marimba_write_bit_mask(&config,
+					v20_init[i].reg,
+					&value,
+					sizeof(v20_init[i].value),
+					v20_init[i].mask);
+				if (rc < 0) {
+					pr_err("%s: reg %d write failed: %d\n",
+						__func__, v20_init[i].reg, rc);
+					return rc;
+				}
+				pr_debug("%s: reg 0x%02x value 0x%02x mask 0x%02x\n",
+					__func__, v20_init[i].reg,
+					v20_init[i].value, v20_init[i].mask);
+			}
+		}
+	}
+	pr_debug("core type: %d\n", type);
+	return rc;
+}
+
+static int bluetooth_power(int on)
+{
+	int rc = 0;
+	const char *id = "BTPW";
+	int cid = 0;
+
+	pr_debug("bluetooth_power entered....\n");
+	cid = adie_get_detected_connectivity_type();
+	if (cid != BAHAMA_ID) {
+		pr_err("%s: unexpected adie connectivity type: %d\n",
+					__func__, cid);
+		return -ENODEV;
+	}
+
+	if (on) {
+		rc = bluetooth_switch_regulators(on);
+		if (rc < 0) {
+			pr_err("%s: bluetooth_switch_regulators rc = %d",
+					__func__, rc);
+			goto exit;
+		}
+		/* UART GPIO configuration to be done by by UART module*/
+		/*Setup BT clocks*/
+		bt_clock = msm_xo_get(MSM_XO_TCXO_A2, id);
+		if (IS_ERR(bt_clock)) {
+			rc = PTR_ERR(bt_clock);
+			pr_err("%s: failed to get the handle for A2(%d)\n",
+					__func__, rc);
+		}
+		rc = msm_xo_mode_vote(bt_clock, MSM_XO_MODE_ON);
+		if (rc < 0) {
+			pr_err("%s: Failed to vote for TCXO_A2 ON\n", __func__);
+			goto fail_xo_vote;
+		}
+		msleep(20);
+
+		/*I2C config for Bahama*/
+		rc = bahama_bt(1);
+		if (rc < 0) {
+			pr_err("%s: bahama_bt rc = %d", __func__, rc);
+			goto fail_i2c;
+		}
+		msleep(20);
+
+		/*setup BT PCM lines*/
+		rc = config_pcm(BT_PCM_ON);
+		if (rc < 0) {
+			pr_err("%s: config_pcm , rc =%d\n",
+				__func__, rc);
+				goto fail_power;
+		}
+		/* TO DO - Enable PIN CTRL */
+		/*
+		rc = msm_xo_mode_vote(bt_clock, MSM_XO_MODE_PIN_CTRL);
+		if (rc < 0) {
+			pr_err("%s: Failed to vote for TCXO_A2 in PIN_CTRL\n",
+				__func__);
+			goto fail_xo_vote;
+		} */
+	} else {
+		rc = bahama_bt(0);
+		if (rc < 0)
+			pr_err("%s: bahama_bt rc = %d", __func__, rc);
+
+		rc = config_pcm(BT_PCM_OFF);
+		if (rc < 0) {
+			pr_err("%s: msm_bahama_setup_pcm_i2s, rc =%d\n",
+				__func__, rc);
+		}
+fail_i2c:
+		pr_err("bluetooth_power...FAIL_I2C\n");
+
+fail_xo_vote:
+		pr_err("bluetooth_power...FAIL_XO_VOTE\n");
+		msm_xo_put(bt_clock);
+fail_power:
+		pr_err("bluetooth_power...FAIL POWER\n");
+		rc = bluetooth_switch_regulators(0);
+		if (rc < 0) {
+			pr_err("%s: switch_regulators : rc = %d",\
+				__func__, rc);
+			goto exit;
+		}
+	}
+	return rc;
+exit:
+	pr_err("%s: failed with rc = %d", __func__, rc);
+	return rc;
+}
+
+static struct marimba_platform_data marimba_pdata = {
+	.slave_id[SLAVE_ID_BAHAMA_FM]	= BAHAMA_SLAVE_ID_FM_ADDR,
+	.slave_id[SLAVE_ID_BAHAMA_QMEMBIST] = BAHAMA_SLAVE_ID_QMEMBIST_ADDR,
+	.bahama_setup			= msm_bahama_setup_power,
+	.bahama_shutdown		= msm_bahama_shutdown_power,
+	.bahama_core_config		= msm_bahama_core_config,
+	.fm			        = NULL,
+};
+
+static struct i2c_board_info bahama_devices[] = {
+{
+	I2C_BOARD_INFO("marimba", 0xc),
+	.platform_data = &marimba_pdata,
+},
+};
+
+void __init apq8064_bt_power_init(void)
+{
+	int rc = 0;
+	struct device *dev;
+
+	rc = i2c_register_board_info(APQ_8064_GSBI5_QUP_I2C_BUS_ID,
+				bahama_devices,
+				ARRAY_SIZE(bahama_devices));
+	if (rc < 0) {
+		pr_err("%s: I2C Register failed\n", __func__);
+		return;
+	}
+	rc = platform_device_register(&msm_bt_power_device);
+	if (rc < 0) {
+		pr_err("%s: device register failed\n", __func__);
+		platform_device_unregister(&msm_bt_power_device);
+		return;
+	}
+
+	dev = &msm_bt_power_device.dev;
+	dev->platform_data = &bluetooth_power;
+
+	return;
+}
+#endif
diff --git a/arch/arm/mach-msm/board-8064-display.c b/arch/arm/mach-msm/board-8064-display.c
index d0f1e87..56c3241 100644
--- a/arch/arm/mach-msm/board-8064-display.c
+++ b/arch/arm/mach-msm/board-8064-display.c
@@ -16,7 +16,7 @@
 #include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/bootmem.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
 #include <asm/mach-types.h>
 #include <mach/msm_memtypes.h>
 #include <mach/board.h>
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index f4e9a8f..a08f45c 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -1477,9 +1477,9 @@
 		pr_err(KERN_ERR "msm_gpiomux_init failed %d\n", rc);
 		return;
 	}
-
-	msm_gpiomux_install(wcnss_5wire_interface,
-			ARRAY_SIZE(wcnss_5wire_interface));
+	if (!(machine_is_mpq8064_hrd()))
+		msm_gpiomux_install(wcnss_5wire_interface,
+				ARRAY_SIZE(wcnss_5wire_interface));
 
 	if (machine_is_mpq8064_cdp() || machine_is_mpq8064_hrd() ||
 		 machine_is_mpq8064_dtv()) {
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index c1798bf..bbb9a81 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -47,6 +47,7 @@
 	REGULATOR_SUPPLY("8921_l4",		NULL),
 	REGULATOR_SUPPLY("HSUSB_1p8",		"msm_otg"),
 	REGULATOR_SUPPLY("iris_vddxo",		"wcnss_wlan.0"),
+	REGULATOR_SUPPLY("bha_vddxo",		"bt_power"),
 };
 VREG_CONSUMERS(L5) = {
 	REGULATOR_SUPPLY("8921_l5",		NULL),
@@ -75,6 +76,7 @@
 VREG_CONSUMERS(L10) = {
 	REGULATOR_SUPPLY("8921_l10",		NULL),
 	REGULATOR_SUPPLY("iris_vddpa",		"wcnss_wlan.0"),
+	REGULATOR_SUPPLY("bha_vddpa",		"bt_power"),
 };
 VREG_CONSUMERS(L11) = {
 	REGULATOR_SUPPLY("8921_l11",		NULL),
@@ -182,6 +184,7 @@
 	REGULATOR_SUPPLY("CDC_VDDA_TX",		"0-000d"),
 	REGULATOR_SUPPLY("CDC_VDDA_RX",		"0-000d"),
 	REGULATOR_SUPPLY("riva_vddpx",		"wcnss_wlan.0"),
+	REGULATOR_SUPPLY("bha_vddpx",		"bt_power"),
 	REGULATOR_SUPPLY("vcc_i2c",		"3-005b"),
 	REGULATOR_SUPPLY("vcc_i2c",		"3-0024"),
 	REGULATOR_SUPPLY("vddp",		"0-0048"),
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index ec52d1a..8755f08 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -3443,6 +3443,11 @@
 #endif
 	}
 
+#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
+	if (machine_is_mpq8064_hrd())
+		apq8064_bt_power_init();
+#endif
+
 	if (machine_is_apq8064_cdp() || machine_is_apq8064_liquid())
 		platform_device_register(&cdp_kp_pdev);
 
diff --git a/arch/arm/mach-msm/board-8064.h b/arch/arm/mach-msm/board-8064.h
index 740fa39..5d6f988 100644
--- a/arch/arm/mach-msm/board-8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -110,6 +110,10 @@
 void apq8064_pm8xxx_gpio_mpp_init(void);
 void __init configure_apq8064_pm8917_power_grid(void);
 
+#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
+void __init apq8064_bt_power_init(void);
+#endif
+
 #define PLATFORM_IS_MPQ8064() \
 	(machine_is_mpq8064_hrd() || \
 	 machine_is_mpq8064_dtv() || \
diff --git a/arch/arm/mach-msm/board-8226-gpiomux.c b/arch/arm/mach-msm/board-8226-gpiomux.c
new file mode 100644
index 0000000..eb88ef4
--- /dev/null
+++ b/arch/arm/mach-msm/board-8226-gpiomux.c
@@ -0,0 +1,29 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+
+void __init msm8226_init_gpiomux(void)
+{
+	int rc;
+
+	rc = msm_gpiomux_init(NR_GPIO_IRQS);
+	if (rc) {
+		pr_err(KERN_ERR "msm_8226_init_gpiomux failed %d\n", rc);
+		return;
+	}
+}
diff --git a/arch/arm/mach-msm/board-8226.c b/arch/arm/mach-msm/board-8226.c
new file mode 100644
index 0000000..c845a3a
--- /dev/null
+++ b/arch/arm/mach-msm/board-8226.c
@@ -0,0 +1,114 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/of_fdt.h>
+#include <linux/of_irq.h>
+#include <linux/memory.h>
+#ifdef CONFIG_ANDROID_PMEM
+#include <linux/android_pmem.h>
+#endif
+#include <asm/mach/map.h>
+#include <asm/hardware/gic.h>
+#include <asm/arch_timer.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/board.h>
+#include <mach/gpiomux.h>
+#include <mach/msm_iomap.h>
+#ifdef CONFIG_ION_MSM
+#include <mach/ion.h>
+#endif
+#include <mach/msm_memtypes.h>
+#include <mach/socinfo.h>
+#include <mach/board.h>
+#include "clock.h"
+
+static struct clk_lookup msm_clocks_dummy[] = {
+	CLK_DUMMY("core_clk",   BLSP1_UART_CLK, "msm_serial_hsl.0", OFF),
+	CLK_DUMMY("iface_clk",  BLSP1_UART_CLK, "msm_serial_hsl.0", OFF),
+};
+
+struct clock_init_data msm_dummy_clock_init_data __initdata = {
+	.table = msm_clocks_dummy,
+	.size = ARRAY_SIZE(msm_clocks_dummy),
+};
+
+static struct of_device_id irq_match[] __initdata  = {
+	{ .compatible = "qcom,msm-qgic2", .data = gic_of_init, },
+	{ .compatible = "qcom,msm-gpio", .data = msm_gpio_of_init, },
+	{}
+};
+
+static struct of_dev_auxdata msm8226_auxdata_lookup[] __initdata = {
+	OF_DEV_AUXDATA("qcom,msm-lsuart-v14", 0xF991F000, \
+			"msm_serial_hsl.0", NULL),
+	{}
+};
+
+static void __init msm8226_dt_timer_init(void)
+{
+	arch_timer_of_register();
+}
+
+static struct sys_timer msm8226_dt_timer = {
+	.init = msm8226_dt_timer_init
+};
+
+void __init msm8226_init_irq(void)
+{
+	of_irq_init(irq_match);
+}
+
+void __init msm8226_init(struct of_dev_auxdata **adata)
+{
+	msm8226_init_gpiomux();
+
+	msm_clock_init(&msm_dummy_clock_init_data);
+
+	*adata = msm8226_auxdata_lookup;
+}
+
+void __init msm8226_dt_init(void)
+{
+	struct of_dev_auxdata *adata = NULL;
+	msm8226_init(&adata);
+
+	if (socinfo_init() < 0)
+		pr_err("%s: socinfo_init() failed\n", __func__);
+
+	of_platform_populate(NULL, of_default_bus_match_table, adata, NULL);
+}
+
+
+static const char *msm8226_dt_match[] __initconst = {
+	"qcom,msm8226",
+	NULL
+};
+
+DT_MACHINE_START(MSM8226_DT, "Qualcomm MSM 8226 (Flattened Device Tree)")
+	.map_io = msm_map_msm8226_io,
+	.init_irq = msm8226_init_irq,
+	.init_machine = msm8226_dt_init,
+	.handle_irq = gic_handle_irq,
+	.timer = &msm8226_dt_timer,
+	.dt_compat = msm8226_dt_match,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-8930-display.c b/arch/arm/mach-msm/board-8930-display.c
index b454184..a0bfabf 100644
--- a/arch/arm/mach-msm/board-8930-display.c
+++ b/arch/arm/mach-msm/board-8930-display.c
@@ -22,7 +22,7 @@
 #include <mach/board.h>
 #include <mach/gpiomux.h>
 #include <mach/socinfo.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
 #include <mach/ion.h>
 
 #include "devices.h"
diff --git a/arch/arm/mach-msm/board-8930-pmic.c b/arch/arm/mach-msm/board-8930-pmic.c
index cc5651d..59e4ba1 100644
--- a/arch/arm/mach-msm/board-8930-pmic.c
+++ b/arch/arm/mach-msm/board-8930-pmic.c
@@ -180,6 +180,8 @@
 
 /* Initial PM8917 MPP configurations */
 static struct pm8xxx_mpp_init pm8917_mpps[] __initdata = {
+	PM8917_MPP_INIT(PM8XXX_AMUX_MPP_3, A_INPUT,
+				PM8XXX_MPP_AIN_AMUX_CH8, DIN_TO_INT),
 };
 
 void __init msm8930_pm8038_gpio_mpp_init(void)
@@ -527,6 +529,8 @@
 		ADC_DECIMATION_TYPE2, ADC_SCALE_XOTHERM},
 	{"pa_therm0", ADC_MPP_1_AMUX3, CHAN_PATH_SCALING1, AMUX_RSV1,
 		ADC_DECIMATION_TYPE2, ADC_SCALE_PA_THERM},
+	{"pa_therm1", ADC_MPP_1_AMUX8, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_PA_THERM},
 };
 
 static struct pm8xxx_adc_properties pm8917_adc_data = {
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index a54c3e2..7c9f652 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -2120,7 +2120,7 @@
 	/* T6 Object */
 	0, 0, 0, 0, 0, 0,
 	/* T38 Object */
-	12, 4, 0, 5, 7, 12, 0, 0, 0, 0,
+	12, 5, 0, 28, 8, 12, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -2128,7 +2128,7 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0,
 	/* T7 Object */
-	100, 16, 50,
+	32, 16, 50,
 	/* T8 Object */
 	25, 0, 20, 20, 0, 0, 20, 50, 0, 0,
 	/* T9 Object */
@@ -2822,19 +2822,24 @@
 		msm_kgsl_3d0.dev.platform_data;
 	uint32_t soc_platform_version = socinfo_get_version();
 
+	/* Fixup data that needs to change based on GPU ID */
 	if (cpu_is_msm8960ab()) {
 		kgsl_3d0_pdata->chipid = ADRENO_CHIPID(3, 2, 1, 0);
 		/* 8960PRO nominal clock rate is 325Mhz instead of 320Mhz */
 		kgsl_3d0_pdata->pwrlevel[1].gpu_freq = 325000000;
-	} else if (SOCINFO_VERSION_MAJOR(soc_platform_version) == 1) {
-		kgsl_3d0_pdata->pwrlevel[0].gpu_freq = 320000000;
-		kgsl_3d0_pdata->pwrlevel[1].gpu_freq = 266667000;
-	} else if (SOCINFO_VERSION_MAJOR(soc_platform_version) >= 3) {
-		/* 8960v3 GPU registers returns 5 for patch release
-		 * but it should be 6, so dummy up the chipid here
-		 * based the platform type
-		 */
-		kgsl_3d0_pdata->chipid = ADRENO_CHIPID(2, 2, 0, 6);
+	} else {
+		kgsl_3d0_pdata->iommu_count = 1;
+		if (SOCINFO_VERSION_MAJOR(soc_platform_version) == 1) {
+			kgsl_3d0_pdata->pwrlevel[0].gpu_freq = 320000000;
+			kgsl_3d0_pdata->pwrlevel[1].gpu_freq = 266667000;
+		}
+		if (SOCINFO_VERSION_MAJOR(soc_platform_version) >= 3) {
+			/* 8960v3 GPU registers returns 5 for patch release
+			 * but it should be 6, so dummy up the chipid here
+			 * based the platform type
+			 */
+			kgsl_3d0_pdata->chipid = ADRENO_CHIPID(2, 2, 0, 6);
+		}
 	}
 
 	/* Register the 3D core */
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index d22690c..33782ab 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -3145,18 +3145,29 @@
 	},
 };
 
-static const struct kgsl_iommu_ctx kgsl_3d0_iommu_ctxs[] = {
+static const struct kgsl_iommu_ctx kgsl_3d0_iommu0_ctxs[] = {
 	{ "gfx3d_user", 0 },
 	{ "gfx3d_priv", 1 },
 };
 
+static const struct kgsl_iommu_ctx kgsl_3d0_iommu1_ctxs[] = {
+	{ "gfx3d1_user", 0 },
+	{ "gfx3d1_priv", 1 },
+};
+
 static struct kgsl_device_iommu_data kgsl_3d0_iommu_data[] = {
 	{
-		.iommu_ctxs = kgsl_3d0_iommu_ctxs,
-		.iommu_ctx_count = ARRAY_SIZE(kgsl_3d0_iommu_ctxs),
+		.iommu_ctxs = kgsl_3d0_iommu0_ctxs,
+		.iommu_ctx_count = ARRAY_SIZE(kgsl_3d0_iommu0_ctxs),
 		.physstart = 0x07C00000,
 		.physend = 0x07C00000 + SZ_1M - 1,
 	},
+	{
+		.iommu_ctxs = kgsl_3d0_iommu1_ctxs,
+		.iommu_ctx_count = ARRAY_SIZE(kgsl_3d0_iommu1_ctxs),
+		.physstart = 0x07D00000,
+		.physend = 0x07D00000 + SZ_1M - 1,
+	},
 };
 
 static struct kgsl_device_platform_data kgsl_3d0_pdata = {
diff --git a/arch/arm/mach-msm/event_timer.c b/arch/arm/mach-msm/event_timer.c
new file mode 100644
index 0000000..e06dad4
--- /dev/null
+++ b/arch/arm/mach-msm/event_timer.c
@@ -0,0 +1,318 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <mach/event_timer.h>
+
+#define __INIT_HEAD(x)	{ .head = RB_ROOT,\
+			.next = NULL, }
+
+#define DEFINE_TIME_HEAD(x) struct timerqueue_head x = __INIT_HEAD(x)
+
+/**
+ * struct event_timer_info - basic event timer structure
+ * @node: timerqueue node to track time ordered data structure
+ *        of event timers
+ * @timer: hrtimer created for this event.
+ * @function : callback function for event timer.
+ * @data : callback data for event timer.
+ */
+struct event_timer_info {
+	struct timerqueue_node node;
+	void (*function)(void *);
+	void *data;
+};
+
+
+static DEFINE_TIME_HEAD(timer_head);
+static DEFINE_SPINLOCK(event_timer_lock);
+static struct hrtimer event_hrtimer;
+static enum hrtimer_restart event_hrtimer_cb(struct hrtimer *hrtimer);
+
+static int msm_event_debug_mask;
+module_param_named(
+	debug_mask, msm_event_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP
+);
+
+enum {
+	MSM_EVENT_TIMER_DEBUG = 1U << 0,
+};
+
+
+/**
+ * add_event_timer() : Add a wakeup event. Intended to be called
+ *                     by clients once. Returns a handle to be used
+ *                     for future transactions.
+ * @function : The callback function will be called when event
+ *             timer expires.
+ * @data: callback data provided by client.
+ */
+struct event_timer_info *add_event_timer(void (*function)(void *), void *data)
+{
+	struct event_timer_info *event_info =
+			kzalloc(sizeof(struct event_timer_info), GFP_KERNEL);
+
+	if (!event_info)
+		return NULL;
+
+	event_info->function = function;
+	event_info->data = data;
+	/* Init rb node and hr timer */
+	timerqueue_init(&event_info->node);
+
+	return event_info;
+}
+
+/**
+ * is_event_next(): Helper function to check if the event is the next
+ *                   next expiring event
+ * @event : handle to the event to be checked.
+ */
+static bool is_event_next(struct event_timer_info *event)
+{
+	struct event_timer_info *next_event;
+	struct timerqueue_node *next;
+	bool ret = false;
+
+	next = timerqueue_getnext(&timer_head);
+	if (!next)
+		goto exit_is_next_event;
+
+	next_event = container_of(next, struct event_timer_info, node);
+	if (!next_event)
+		goto exit_is_next_event;
+
+	if (next_event == event)
+		ret = true;
+
+exit_is_next_event:
+	return ret;
+}
+
+/**
+ * is_event_active(): Helper function to check if the timer for a given event
+ *                    has been started.
+ * @event : handle to the event to be checked.
+ */
+static bool is_event_active(struct event_timer_info *event)
+{
+	struct timerqueue_node *next;
+	struct event_timer_info *next_event;
+	bool ret = false;
+
+	for (next = timerqueue_getnext(&timer_head); next;
+			next = timerqueue_iterate_next(next)) {
+		next_event = container_of(next, struct event_timer_info, node);
+
+		if (event == next_event) {
+			ret = true;
+			break;
+		}
+	}
+	return ret;
+}
+
+/**
+ * create_httimer(): Helper function to setup hrtimer.
+ */
+static void create_hrtimer(ktime_t expires)
+{
+	static bool timer_initialized;
+
+	if (!timer_initialized) {
+		hrtimer_init(&event_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+		timer_initialized = true;
+	}
+
+	event_hrtimer.function = event_hrtimer_cb;
+	hrtimer_start(&event_hrtimer, expires, HRTIMER_MODE_ABS);
+
+	if (msm_event_debug_mask && MSM_EVENT_TIMER_DEBUG)
+		pr_info("%s: Setting timer for %lu", __func__,
+			(unsigned long)ktime_to_ns(expires));
+}
+
+/**
+ * event_hrtimer_cb() : Callback function for hr timer.
+ *                      Make the client CB from here and remove the event
+ *                      from the time ordered queue.
+ */
+static enum hrtimer_restart event_hrtimer_cb(struct hrtimer *hrtimer)
+{
+	struct event_timer_info *event;
+	struct timerqueue_node *next;
+
+	next = timerqueue_getnext(&timer_head);
+
+	while (next && (ktime_to_ns(next->expires)
+		<= ktime_to_ns(hrtimer->node.expires))) {
+		if (!next)
+			goto hrtimer_cb_exit;
+
+		event = container_of(next, struct event_timer_info, node);
+		if (!event)
+			goto hrtimer_cb_exit;
+
+		if (msm_event_debug_mask && MSM_EVENT_TIMER_DEBUG)
+			pr_info("%s: Deleting event @ %lu", __func__,
+			(unsigned long)ktime_to_ns(next->expires));
+
+		timerqueue_del(&timer_head, &event->node);
+
+		if (event->function)
+			event->function(event->data);
+		next = timerqueue_getnext(&timer_head);
+	}
+
+	if (next)
+		create_hrtimer(next->expires);
+
+hrtimer_cb_exit:
+	return HRTIMER_NORESTART;
+}
+
+/**
+ * create_timer_smp(): Helper function used setting up timer on core 0.
+ */
+static void create_timer_smp(void *data)
+{
+	unsigned long flags;
+	struct event_timer_info *event =
+		(struct event_timer_info *)data;
+
+	local_irq_save(flags);
+	create_hrtimer(event->node.expires);
+	local_irq_restore(flags);
+}
+
+/**
+ *  setup_timer() : Helper function to setup timer on primary
+ *                  core during hrtimer callback.
+ *  @event: event handle causing the wakeup.
+ */
+static void setup_event_hrtimer(struct event_timer_info *event)
+{
+	struct timerqueue_node *next;
+	unsigned long flags;
+
+	spin_lock_irqsave(&event_timer_lock, flags);
+	if (is_event_active(event))
+		timerqueue_del(&timer_head, &event->node);
+
+	next = timerqueue_getnext(&timer_head);
+	timerqueue_add(&timer_head, &event->node);
+	spin_unlock_irqrestore(&event_timer_lock, flags);
+
+	if (!next ||
+		(next && (ktime_to_ns(event->node.expires) <
+				ktime_to_ns(next->expires)))) {
+		if (msm_event_debug_mask && MSM_EVENT_TIMER_DEBUG)
+			pr_info("%s: Setting timer for %lu", __func__,
+			(unsigned long)ktime_to_ns(event->node.expires));
+
+		smp_call_function_single(0, create_timer_smp, event, 1);
+		}
+}
+
+/**
+ * activate_event_timer() : Set the expiration time for an event in absolute
+ *                           ktime. This is a oneshot event timer, clients
+ *                           should call this again to set another expiration.
+ *  @event : event handle.
+ *  @event_time : event time in absolute ktime.
+ */
+void activate_event_timer(struct event_timer_info *event, ktime_t event_time)
+{
+	if (!event)
+		return;
+
+	if (msm_event_debug_mask && MSM_EVENT_TIMER_DEBUG)
+		pr_info("%s: Adding event timer @ %lu", __func__,
+				(unsigned long)ktime_to_us(event_time));
+
+	event->node.expires = event_time;
+	/* Start hr timer and add event to rb tree */
+	setup_event_hrtimer(event);
+}
+
+
+/**
+ * deactivate_event_timer() : Deactivate an event timer, this removes the event from
+ *                            the time ordered queue of event timers.
+ * @event: event handle.
+ */
+void deactivate_event_timer(struct event_timer_info *event)
+{
+	unsigned long flags;
+
+	if (msm_event_debug_mask && MSM_EVENT_TIMER_DEBUG)
+		pr_info("%s: Deactivate timer", __func__);
+
+	spin_lock_irqsave(&event_timer_lock, flags);
+	if (is_event_active(event)) {
+		if (is_event_next(event))
+			hrtimer_try_to_cancel(&event_hrtimer);
+
+		timerqueue_del(&timer_head, &event->node);
+	}
+	spin_unlock_irqrestore(&event_timer_lock, flags);
+}
+
+/**
+ * destroy_event_timer() : Free the event info data structure allocated during
+ *                         add_event_timer().
+ * @event: event handle.
+ */
+void destroy_event_timer(struct event_timer_info *event)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&event_timer_lock, flags);
+	if (is_event_active(event)) {
+		if (is_event_next(event))
+			hrtimer_try_to_cancel(&event_hrtimer);
+
+		timerqueue_del(&timer_head, &event->node);
+	}
+	spin_unlock_irqrestore(&event_timer_lock, flags);
+	kfree(event);
+}
+
+/**
+ * get_next_event_timer() - Get the next wakeup event. Returns
+ *                          a ktime value of the next expiring event.
+ */
+ktime_t get_next_event_time(void)
+{
+	unsigned long flags;
+	struct timerqueue_node *next;
+	ktime_t next_event = ns_to_ktime(0);
+
+	spin_lock_irqsave(&event_timer_lock, flags);
+	next = timerqueue_getnext(&timer_head);
+	spin_unlock_irqrestore(&event_timer_lock, flags);
+
+	if (!next)
+		return next_event;
+
+	next_event = hrtimer_get_remaining(&event_hrtimer);
+	if (msm_event_debug_mask && MSM_EVENT_TIMER_DEBUG)
+		pr_info("%s: Next Event %lu", __func__,
+			(unsigned long)ktime_to_us(next_event));
+
+	return next_event;
+}
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 306011a..5b8729a 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -583,6 +583,9 @@
 void msm9625_init_gpiomux(void);
 void msm_map_mpq8092_io(void);
 void mpq8092_init_gpiomux(void);
+void msm_map_msm8226_io(void);
+void msm8226_init_irq(void);
+void msm8226_init_gpiomux(void);
 
 struct mmc_platform_data;
 int msm_add_sdcc(unsigned int controller,
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 60ccded..cf36388 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -24,7 +24,7 @@
 
 #include <mach/board.h>
 #include <media/msm_camera.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
 #include <mach/iommu_domains.h>
 
 #define CONFIG_MSM_CAMERA_DEBUG
diff --git a/arch/arm/mach-msm/include/mach/event_timer.h b/arch/arm/mach-msm/include/mach/event_timer.h
new file mode 100644
index 0000000..7a00b23
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/event_timer.h
@@ -0,0 +1,77 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_EVENT_TIMER_H
+#define __ARCH_ARM_MACH_MSM_EVENT_TIMER_H
+
+#include <linux/hrtimer.h>
+
+struct event_timer_info;
+
+#ifdef CONFIG_MSM_EVENT_TIMER
+/**
+ * add_event_timer() : Add a wakeup event. Intended to be called
+ *                     by clients once. Returns a handle to be used
+ *                     for future transactions.
+ * @function : The callback function will be called when event
+ *             timer expires.
+ * @data : Callback data provided by client.
+ */
+struct event_timer_info *add_event_timer(void (*function)(void *), void *data);
+
+/** activate_event_timer() : Set the expiration time for an event in absolute
+ *                           ktime. This is a oneshot event timer, clients
+ *                           should call this again to set another expiration.
+ *  @event : Event handle.
+ *  @event_time : Event time in absolute ktime.
+ */
+void activate_event_timer(struct event_timer_info *event, ktime_t event_time);
+
+/**
+ * deactivate_event_timer() : Deactivate an event timer.
+ * @event: event handle.
+ */
+void deactivate_event_timer(struct event_timer_info *event);
+
+/**
+ * destroy_event_timer() : Free the event info data structure allocated during
+ * add_event_timer().
+ * @event: event handle.
+ */
+void destroy_event_timer(struct event_timer_info *event);
+
+/**
+ * get_next_event_timer() : Get the next wakeup event.
+ *                          returns a ktime value of the next
+ *                          expiring event.
+ */
+ktime_t get_next_event_time(void);
+#else
+static inline void *add_event_timer(void (*function)(void *), void *data)
+{
+	return NULL;
+}
+
+static inline void activate_event_timer(void *event, ktime_t event_time) {}
+
+static inline void deactivate_event_timer(void *event) {}
+
+static inline void destroy_event_timer(void *event) {}
+
+static inline ktime_t get_next_event_time(void)
+{
+	return ns_to_ktime(0);
+}
+
+#endif /* CONFIG_MSM_EVENT_TIMER_MANAGER */
+#endif /* __ARCH_ARM_MACH_MSM_EVENT_TIMER_H */
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8226.h b/arch/arm/mach-msm/include/mach/msm_iomap-8226.h
index c03b513..08bc981 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8226.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8226.h
@@ -45,4 +45,7 @@
 #define MSM_DEBUG_UART_PHYS	0xF991E000
 #endif
 
+#define MSM8226_DBG_IMEM_PHYS	0xFE805000
+#define MSM8226_DBG_IMEM_SIZE	SZ_4K
+
 #endif
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 9dff013..e0fec65 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -497,7 +497,7 @@
 
 void __init msm_map_mpq8092_io(void)
 {
-	msm_shared_ram_phys = MSM8974_MSM_SHARED_RAM_PHYS;
+	msm_shared_ram_phys = MSM8092_MSM_SHARED_RAM_PHYS;
 	msm_map_io(mpq8092_io_desc, ARRAY_SIZE(mpq8092_io_desc));
 }
 #endif /* CONFIG_ARCH_MPQ8092 */
@@ -509,12 +509,13 @@
 	MSM_CHIP_DEVICE(APCS_GCC, MSM8226),
 	MSM_CHIP_DEVICE(TLMM, MSM8226),
 	MSM_CHIP_DEVICE(IMEM, MSM8226),
+	MSM_CHIP_DEVICE(DBG_IMEM, MSM8226),
 	{
 		.virtual =  (unsigned long) MSM_SHARED_RAM_BASE,
 		.length =   MSM_SHARED_RAM_SIZE,
 		.type =     MT_DEVICE,
 	},
-#ifdef CONFIG_DEBUG_MPQ8226_UART
+#ifdef CONFIG_DEBUG_MSM8226_UART
 	MSM_DEVICE(DEBUG_UART),
 #endif
 };
diff --git a/arch/arm/mach-msm/pil-riva.c b/arch/arm/mach-msm/pil-riva.c
index 3040a31..ba0e242 100644
--- a/arch/arm/mach-msm/pil-riva.c
+++ b/arch/arm/mach-msm/pil-riva.c
@@ -21,6 +21,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/clk.h>
 
+#include <asm/mach-types.h>
 #include <mach/msm_iomap.h>
 
 #include "peripheral-loader.h"
@@ -358,12 +359,18 @@
 
 static int __init pil_riva_init(void)
 {
+	if (machine_is_mpq8064_hrd()) {
+		pr_err("pil_riva not supported on this target\n");
+		return 0;
+	}
 	return platform_driver_register(&pil_riva_driver);
 }
 module_init(pil_riva_init);
 
 static void __exit pil_riva_exit(void)
 {
+	if (machine_is_mpq8064_hrd())
+		return;
 	platform_driver_unregister(&pil_riva_driver);
 }
 module_exit(pil_riva_exit);
diff --git a/arch/arm/mach-msm/pil-venus.c b/arch/arm/mach-msm/pil-venus.c
index 49c39ec..1ccde72 100644
--- a/arch/arm/mach-msm/pil-venus.c
+++ b/arch/arm/mach-msm/pil-venus.c
@@ -328,6 +328,59 @@
 	.proxy_unvote = pil_venus_remove_proxy_vote,
 };
 
+static int pil_venus_init_image_trusted(struct pil_desc *pil,
+		const u8 *metadata, size_t size)
+{
+	return pas_init_image(PAS_VIDC, metadata, size);
+}
+
+static int pil_venus_reset_trusted(struct pil_desc *pil)
+{
+	int rc;
+	struct venus_data *drv = dev_get_drvdata(pil->dev);
+
+	/*
+	 * GDSC needs to remain on till Venus is shutdown. So, enable
+	 * the GDSC here again to make sure it remains on beyond the
+	 * expiry of the proxy vote timer.
+	 */
+	rc = regulator_enable(drv->gdsc);
+	if (rc) {
+		dev_err(pil->dev, "GDSC enable failed\n");
+		return rc;
+	}
+
+	rc = pas_auth_and_reset(PAS_VIDC);
+	if (rc)
+		regulator_disable(drv->gdsc);
+
+	return rc;
+}
+
+static int pil_venus_shutdown_trusted(struct pil_desc *pil)
+{
+	int rc;
+	struct venus_data *drv = dev_get_drvdata(pil->dev);
+
+	venus_clock_prepare_enable(pil->dev);
+
+	rc = pas_shutdown(PAS_VIDC);
+
+	venus_clock_disable_unprepare(pil->dev);
+
+	regulator_disable(drv->gdsc);
+
+	return rc;
+}
+
+static struct pil_reset_ops pil_venus_ops_trusted = {
+	.init_image = pil_venus_init_image_trusted,
+	.auth_and_reset = pil_venus_reset_trusted,
+	.shutdown = pil_venus_shutdown_trusted,
+	.proxy_vote = pil_venus_make_proxy_vote,
+	.proxy_unvote = pil_venus_remove_proxy_vote,
+};
+
 static int __devinit pil_venus_probe(struct platform_device *pdev)
 {
 	struct venus_data *drv;
@@ -422,9 +475,13 @@
 	desc->owner = THIS_MODULE;
 	desc->proxy_timeout = VENUS_PROXY_TIMEOUT;
 
-	/* TODO: need to add secure boot when the support is available */
-	desc->ops = &pil_venus_ops;
-	dev_info(&pdev->dev, "using non-secure boot\n");
+	if (pas_supported(PAS_VIDC) > 0) {
+		desc->ops = &pil_venus_ops_trusted;
+		dev_info(&pdev->dev, "using secure boot\n");
+	} else {
+		desc->ops = &pil_venus_ops;
+		dev_info(&pdev->dev, "using non-secure boot\n");
+	}
 
 	drv->pil = msm_pil_register(desc);
 	if (IS_ERR(drv->pil))
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index b2681b7..f6ed1ea 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -84,7 +84,8 @@
 	if (!base_ptr)
 		return -ENODEV;
 
-	if (machine_is_msm8974_sim() || machine_is_mpq8092_sim()) {
+	if (machine_is_msm8974_sim() || machine_is_mpq8092_sim() ||
+	    machine_is_msm8226_sim()) {
 		writel_relaxed(0x800, base_ptr+0x04);
 		writel_relaxed(0x3FFF, base_ptr+0x14);
 	}
@@ -159,7 +160,8 @@
 	if (cpu_is_msm8x60())
 		return scorpion_release_secondary();
 
-	if (machine_is_msm8974_sim() || machine_is_mpq8092_sim())
+	if (machine_is_msm8974_sim() || machine_is_mpq8092_sim() ||
+	    machine_is_msm8226_sim())
 		return krait_release_secondary_sim(0xf9088000, cpu);
 
 	if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm8930aa() ||
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_aac.c b/arch/arm/mach-msm/qdsp6v2/audio_aac.c
index 485234f..44ab611 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_aac.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_aac.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, The Linux Foundation. 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
@@ -81,7 +81,13 @@
 		aac_cfg.spectral_data_resilience =
 			aac_config->aac_spectral_data_resilience_flag;
 		aac_cfg.ch_cfg = audio->pcm_cfg.channel_count;
-		aac_cfg.sample_rate =  audio->pcm_cfg.sample_rate;
+		if (audio->feedback == TUNNEL_MODE) {
+			aac_cfg.sample_rate = aac_config->sample_rate;
+			aac_cfg.ch_cfg = aac_config->channel_configuration;
+		} else {
+			aac_cfg.sample_rate =  audio->pcm_cfg.sample_rate;
+			aac_cfg.ch_cfg = audio->pcm_cfg.channel_count;
+		}
 
 		pr_debug("%s:format=%x aot=%d  ch=%d sr=%d\n",
 			__func__, aac_cfg.format,
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c b/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c
index fbd94c5..b53edd9 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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
@@ -43,8 +43,13 @@
 		struct msm_audio_aac_config *aac_config;
 		uint32_t sbr_ps = 0x00;
 		aac_config = (struct msm_audio_aac_config *)audio->codec_cfg;
-		aac_cfg.ch_cfg = aac_config->channel_configuration;
-		aac_cfg.sample_rate =  audio->pcm_cfg.sample_rate;
+		if (audio->feedback == TUNNEL_MODE) {
+			aac_cfg.sample_rate = aac_config->sample_rate;
+			aac_cfg.ch_cfg = aac_config->channel_configuration;
+		} else {
+			aac_cfg.sample_rate =  audio->pcm_cfg.sample_rate;
+			aac_cfg.ch_cfg = audio->pcm_cfg.channel_count;
+		}
 		pr_debug("%s: AUDIO_START session_id[%d]\n", __func__,
 						audio->ac->session);
 		if (audio->feedback == NON_TUNNEL_MODE) {
diff --git a/arch/arm/mach-msm/restart.c b/arch/arm/mach-msm/restart.c
index 25723d5..53736ac 100644
--- a/arch/arm/mach-msm/restart.c
+++ b/arch/arm/mach-msm/restart.c
@@ -26,6 +26,7 @@
 #include <linux/mfd/pm8xxx/misc.h>
 
 #include <asm/mach-types.h>
+#include <asm/cacheflush.h>
 
 #include <mach/msm_iomap.h>
 #include <mach/restart.h>
@@ -221,6 +222,8 @@
 			__raw_writel(0x77665501, restart_reason);
 		}
 	}
+
+	flush_cache_all();
 }
 
 void msm_restart(char mode, const char *cmd)
diff --git a/arch/arm/mach-msm/scm-pas.c b/arch/arm/mach-msm/scm-pas.c
index 55ae2f8..43436e5 100644
--- a/arch/arm/mach-msm/scm-pas.c
+++ b/arch/arm/mach-msm/scm-pas.c
@@ -204,7 +204,11 @@
 		}
 	}
 
-	scm_perf_client = msm_bus_scale_register_client(&scm_pas_bus_pdata);
+	/* TODO : Remove once bus scaling driver is in place */
+	if (!cpu_is_msm8226())
+		scm_perf_client = msm_bus_scale_register_client(
+				&scm_pas_bus_pdata);
+
 	if (!scm_perf_client)
 		pr_warn("unable to register bus client\n");
 
diff --git a/arch/arm/mach-msm/wcnss-ssr-8960.c b/arch/arm/mach-msm/wcnss-ssr-8960.c
index cbf1d72..f014df9 100644
--- a/arch/arm/mach-msm/wcnss-ssr-8960.c
+++ b/arch/arm/mach-msm/wcnss-ssr-8960.c
@@ -20,6 +20,7 @@
 #include <linux/platform_device.h>
 #include <linux/wcnss_wlan.h>
 #include <linux/err.h>
+#include <asm/mach-types.h>
 #include <mach/irqs.h>
 #include <mach/scm.h>
 #include <mach/subsystem_restart.h>
@@ -180,13 +181,8 @@
 static void riva_crash_shutdown(const struct subsys_desc *subsys)
 {
 	pr_err("%s: crash shutdown : %d\n", MODULE_NAME, riva_crash);
-	if (riva_crash != true) {
+	if (riva_crash != true)
 		smsm_riva_reset();
-		/* give sufficient time for wcnss to finish it's error
-		 * fatal routine */
-		msleep(3000);
-	}
-
 }
 
 static struct subsys_desc riva_8960 = {
@@ -226,6 +222,11 @@
 {
 	int ret;
 
+	if (machine_is_mpq8064_hrd()) {
+		pr_err("Riva not supported on this target\n");
+		return 0;
+	}
+
 	ret = smsm_state_cb_register(SMSM_WCNSS_STATE, SMSM_RESET,
 					smsm_state_cb_hdlr, 0);
 	if (ret < 0) {
@@ -264,6 +265,8 @@
 
 static void __exit riva_ssr_module_exit(void)
 {
+	if (machine_is_mpq8064_hrd())
+		return;
 	subsys_unregister(riva_8960_dev);
 	free_irq(RIVA_APSS_WDOG_BITE_RESET_RDY_IRQ, NULL);
 }
diff --git a/drivers/base/sync.c b/drivers/base/sync.c
index 9bc0da5..c0690c8 100644
--- a/drivers/base/sync.c
+++ b/drivers/base/sync.c
@@ -218,8 +218,10 @@
 	spin_lock_irqsave(&obj->active_list_lock, flags);
 
 	err = _sync_pt_has_signaled(pt);
-	if (err != 0)
+	if (err != 0) {
+		sync_fence_signal_pt(pt);
 		goto out;
+	}
 
 	list_add_tail(&pt->active_list, &obj->active_list_head);
 
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index 1c14859..b18d709 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -279,12 +279,14 @@
 	struct diag_request *write_ptr_mdm;
 	/* HSIC variables */
 	int hsic_ch;
+	int hsic_inited;
 	int hsic_device_enabled;
 	int hsic_device_opened;
 	int hsic_suspend;
 	int in_busy_hsic_read_on_device;
 	int in_busy_hsic_write;
 	struct work_struct diag_read_hsic_work;
+	struct mutex bridge_mutex;
 	/* USB MDM channel variables */
 	int usb_mdm_connected;
 	int read_len_mdm;
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 7e827b9..59139dc 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -93,6 +93,9 @@
 	ret += length;						\
 } while (0)
 
+/* Identifier for data from MDM */
+#define MDM_TOKEN	-1
+
 static void drain_timer_func(unsigned long data)
 {
 	queue_work(driver->diag_wq , &(driver->diag_drain_work));
@@ -650,6 +653,10 @@
 {
 	int index = -1, i = 0, ret = 0;
 	int num_data = 0, data_type;
+#if defined(CONFIG_DIAG_SDIO_PIPE) || defined(CONFIG_DIAG_BRIDGE_CODE)
+	int mdm_token = MDM_TOKEN;
+#endif
+
 	for (i = 0; i < driver->num_clients; i++)
 		if (driver->client_map[i].pid == current->tgid)
 			index = i;
@@ -789,6 +796,8 @@
 		/* copy 9K data over SDIO */
 		if (driver->in_busy_sdio == 1) {
 			num_data++;
+			/*Copy the negative  token of data being passed*/
+			COPY_USER_SPACE_OR_EXIT(buf+ret, mdm_token, 4);
 			/*Copy the length of data being passed*/
 			COPY_USER_SPACE_OR_EXIT(buf+ret,
 				 (driver->write_ptr_mdm->length), 4);
@@ -818,6 +827,14 @@
 					 i, (unsigned int)hsic_buf_tbl[i].buf,
 					hsic_buf_tbl[i].length);
 				num_data++;
+
+				/* Copy the negative token */
+				if (copy_to_user(buf+ret, &mdm_token, 4)) {
+					num_data--;
+					goto drop_hsic;
+				}
+				ret += 4;
+
 				/* Copy the length of data being passed */
 				if (copy_to_user(buf+ret,
 					(void *)&(hsic_buf_tbl[i].length),
@@ -846,6 +863,21 @@
 				diagfwd_write_complete_hsic(NULL);
 			}
 		}
+		if (driver->in_busy_smux == 1) {
+			num_data++;
+
+			/* Copy the negative  token of data being passed */
+			COPY_USER_SPACE_OR_EXIT(buf+ret, mdm_token, 4);
+			/* Copy the length of data being passed */
+			COPY_USER_SPACE_OR_EXIT(buf+ret,
+					(driver->write_ptr_mdm->length), 4);
+			/* Copy the actual data being passed */
+			COPY_USER_SPACE_OR_EXIT(buf+ret,
+					*(driver->buf_in_smux),
+					driver->write_ptr_mdm->length);
+			pr_debug("diag: SMUX  data copied\n");
+			driver->in_busy_smux = 0;
+		}
 #endif
 		/* copy number of data fields */
 		COPY_USER_SPACE_OR_EXIT(buf+4, num_data, 4);
@@ -950,6 +982,7 @@
 			      size_t count, loff_t *ppos)
 {
 	int err, ret = 0, pkt_type;
+	bool mdm_mask = false;
 #ifdef DIAG_DEBUG
 	int length = 0, i;
 #endif
@@ -985,6 +1018,12 @@
 							 payload_size);
 		/* Check masks for On-Device logging */
 		if (driver->mask_check) {
+			/* Check if mask is for MDM or MSM */
+			if (*(int *)driver->user_space_data == MDM_TOKEN) {
+				mdm_mask = true;
+				driver->user_space_data += 4;
+				buf += 4;
+			}
 			if (!mask_request_validate(driver->user_space_data)) {
 				pr_alert("diag: mask request Invalid\n");
 				return -EFAULT;
@@ -998,7 +1037,7 @@
 #endif
 #ifdef CONFIG_DIAG_SDIO_PIPE
 		/* send masks to 9k too */
-		if (driver->sdio_ch) {
+		if (driver->sdio_ch && mdm_mask) {
 			wait_event_interruptible(driver->wait_q,
 				 (sdio_write_avail(driver->sdio_ch) >=
 					 payload_size));
@@ -1010,7 +1049,7 @@
 #endif
 #ifdef CONFIG_DIAG_BRIDGE_CODE
 		/* send masks to 9k too */
-		if (driver->hsic_ch && (payload_size > 0)) {
+		if (driver->hsic_ch && (payload_size > 0) && mdm_mask) {
 			/* wait sending mask updates if HSIC ch not ready */
 			if (driver->in_busy_hsic_write)
 				wait_event_interruptible(driver->wait_q,
@@ -1032,9 +1071,22 @@
 					driver->in_busy_hsic_write = 0;
 			}
 		}
+		if (driver->diag_smux_enabled && mdm_mask && driver->lcid) {
+			if (payload_size > 0) {
+				err = msm_smux_write(driver->lcid, NULL,
+						driver->user_space_data,
+						payload_size);
+				if (err) {
+					pr_err("diag:send mask to MDM err %d",
+							err);
+					return err;
+				}
+			}
+		}
 #endif
 		/* send masks to 8k now */
-		diag_process_hdlc((void *)(driver->user_space_data),
+		if (!mdm_mask)
+			diag_process_hdlc((void *)(driver->user_space_data),
 							 payload_size);
 		return 0;
 	}
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index 52fd673..e417d5a 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -558,6 +558,7 @@
 
 	ret = scnprintf(buf, DEBUG_BUF_SIZE,
 		"hsic ch: %d\n"
+		"hsic_inited: %d\n"
 		"hsic enabled: %d\n"
 		"hsic_opened: %d\n"
 		"hsic_suspend: %d\n"
@@ -575,6 +576,7 @@
 		"diag_disconnect_work: %d\n"
 		"diag_usb_read_complete_work: %d\n",
 		driver->hsic_ch,
+		driver->hsic_inited,
 		driver->hsic_device_enabled,
 		driver->hsic_device_opened,
 		driver->hsic_suspend,
diff --git a/drivers/char/diag/diagfwd_hsic.c b/drivers/char/diag/diagfwd_hsic.c
index 3878a82..56f2fae 100644
--- a/drivers/char/diag/diagfwd_hsic.c
+++ b/drivers/char/diag/diagfwd_hsic.c
@@ -236,20 +236,20 @@
 	.resume = diag_hsic_resume,
 };
 
-static int diag_hsic_close(void)
+static void diag_hsic_close(void)
 {
 	if (driver->hsic_device_enabled) {
 		driver->hsic_ch = 0;
 		if (driver->hsic_device_opened) {
 			driver->hsic_device_opened = 0;
 			diag_bridge_close();
+			pr_debug("diag: %s: closed successfully\n", __func__);
+		} else {
+			pr_debug("diag: %s: already closed\n", __func__);
 		}
-		pr_debug("diag: in %s: closed successfully\n", __func__);
 	} else {
-		pr_debug("diag: in %s: already closed\n", __func__);
+		pr_debug("diag: %s: HSIC device already removed\n", __func__);
 	}
-
-	return 0;
 }
 
 /* diagfwd_cancel_hsic is called to cancel outstanding read/writes */
@@ -257,6 +257,7 @@
 {
 	int err;
 
+	mutex_lock(&driver->bridge_mutex);
 	if (driver->hsic_device_enabled) {
 		if (driver->hsic_device_opened) {
 			driver->hsic_ch = 0;
@@ -274,6 +275,7 @@
 		}
 	}
 
+	mutex_unlock(&driver->bridge_mutex);
 	return 0;
 }
 
@@ -284,6 +286,7 @@
 
 	pr_debug("diag: in %s\n", __func__);
 
+	mutex_lock(&driver->bridge_mutex);
 	/* If the usb cable is being connected */
 	if (process_cable) {
 		err = usb_diag_alloc_req(driver->mdm_ch, N_MDM_WRITE,
@@ -301,6 +304,7 @@
 	} else if (driver->diag_smux_enabled) {
 		driver->in_busy_smux = 0;
 		diagfwd_connect_smux();
+		mutex_unlock(&driver->bridge_mutex);
 		return 0;
 	}
 
@@ -323,22 +327,24 @@
 		 * Turn on communication over usb mdm and hsic, if the hsic
 		 * device driver is enabled and opened
 		 */
-		if (driver->hsic_device_opened)
+		if (driver->hsic_device_opened) {
 			driver->hsic_ch = 1;
 
-		/* Poll USB mdm channel to check for data */
-		if (driver->logging_mode == USB_MODE)
-			queue_work(driver->diag_bridge_wq,
-					&driver->diag_read_mdm_work);
+			/* Poll USB mdm channel to check for data */
+			if (driver->logging_mode == USB_MODE)
+				queue_work(driver->diag_bridge_wq,
+						&driver->diag_read_mdm_work);
 
-		/* Poll HSIC channel to check for data */
-		queue_work(driver->diag_bridge_wq,
-				 &driver->diag_read_hsic_work);
+			/* Poll HSIC channel to check for data */
+			queue_work(driver->diag_bridge_wq,
+					 &driver->diag_read_hsic_work);
+		}
 	} else {
 		/* The hsic device driver has not yet been enabled */
 		pr_info("diag: HSIC channel not yet enabled\n");
 	}
 
+	mutex_unlock(&driver->bridge_mutex);
 	return 0;
 }
 
@@ -350,6 +356,8 @@
 {
 	pr_debug("diag: In %s, process_cable: %d\n", __func__, process_cable);
 
+	mutex_lock(&driver->bridge_mutex);
+
 	/* If the usb cable is being disconnected */
 	if (process_cable) {
 		driver->usb_mdm_connected = 0;
@@ -361,7 +369,7 @@
 		driver->in_busy_hsic_read_on_device = 1;
 		driver->in_busy_hsic_write = 1;
 		/* Turn off communication over usb mdm and hsic */
-		return diag_hsic_close();
+		diag_hsic_close();
 	} else if (driver->diag_smux_enabled &&
 		driver->logging_mode == USB_MODE) {
 		driver->in_busy_smux = 1;
@@ -370,6 +378,8 @@
 		/* Turn off communication over usb mdm and smux */
 		msm_smux_close(LCID_VALID);
 	}
+
+	mutex_unlock(&driver->bridge_mutex);
 	return 0;
 }
 
@@ -551,13 +561,15 @@
 {
 	int err = 0;
 	pr_debug("diag: in %s\n", __func__);
-	if (!driver->hsic_device_enabled) {
+	if (!driver->hsic_inited) {
 		diagmem_hsic_init(driver);
 		INIT_WORK(&(driver->diag_read_hsic_work),
 					 diag_read_hsic_work_fn);
-		driver->hsic_device_enabled = 1;
+		driver->hsic_inited = 1;
 	}
 
+	mutex_lock(&driver->bridge_mutex);
+
 	/*
 	 * The probe function was called after the usb was connected
 	 * on the legacy channel OR ODL is turned on. Communication over usb
@@ -565,11 +577,17 @@
 	 */
 	if (driver->usb_mdm_connected || (driver->logging_mode ==
 							 MEMORY_DEVICE_MODE)) {
-		/* The hsic (diag_bridge) platform device driver is enabled */
+		if (driver->hsic_device_opened) {
+			/* should not happen. close it before re-opening */
+			pr_warn("diag: HSIC channel already opened in probe\n");
+			diag_bridge_close();
+		}
+
 		err = diag_bridge_open(&hsic_diag_bridge_ops);
 		if (err) {
 			pr_err("diag: could not open HSIC, err: %d\n", err);
 			driver->hsic_device_opened = 0;
+			mutex_unlock(&driver->bridge_mutex);
 			return err;
 		}
 
@@ -591,13 +609,19 @@
 				 &driver->diag_read_hsic_work);
 	}
 
+	/* The hsic (diag_bridge) platform device driver is enabled */
+	driver->hsic_device_enabled = 1;
+	mutex_unlock(&driver->bridge_mutex);
 	return err;
 }
 
 static int diag_hsic_remove(struct platform_device *pdev)
 {
 	pr_debug("diag: %s called\n", __func__);
+	mutex_lock(&driver->bridge_mutex);
 	diag_hsic_close();
+	driver->hsic_device_enabled = 0;
+	mutex_unlock(&driver->bridge_mutex);
 	return 0;
 }
 
@@ -670,6 +694,7 @@
 	driver->itemsize_hsic_write = sizeof(struct diag_request);
 	driver->poolsize_hsic_write = N_MDM_WRITE;
 
+	mutex_init(&driver->bridge_mutex);
 #ifdef CONFIG_DIAG_OVER_USB
 	INIT_WORK(&(driver->diag_read_mdm_work), diag_read_mdm_work_fn);
 #endif
@@ -713,8 +738,9 @@
 	if (driver->hsic_device_enabled) {
 		diag_hsic_close();
 		driver->hsic_device_enabled = 0;
-		diagmem_exit(driver, POOL_TYPE_ALL);
 	}
+	driver->hsic_inited = 0;
+	diagmem_exit(driver, POOL_TYPE_ALL);
 	if (driver->diag_smux_enabled) {
 		driver->lcid = LCID_INVALID;
 		kfree(driver->buf_in_smux);
diff --git a/drivers/char/diag/diagmem.c b/drivers/char/diag/diagmem.c
index 82c47af..1a522d5 100644
--- a/drivers/char/diag/diagmem.c
+++ b/drivers/char/diag/diagmem.c
@@ -106,7 +106,7 @@
 			printk(KERN_ALERT "Unable to destroy STRUCT mempool");
 	}
 #ifdef CONFIG_DIAG_BRIDGE_CODE
-	if (driver->diag_hsic_pool && (driver->hsic_device_enabled == 0)) {
+	if (driver->diag_hsic_pool && (driver->hsic_inited == 0)) {
 		if (driver->count_hsic_pool == 0) {
 			mempool_destroy(driver->diag_hdlc_pool);
 			driver->diag_hdlc_pool = NULL;
@@ -114,8 +114,7 @@
 			pr_err("Unable to destroy HDLC mempool");
 	}
 
-	if (driver->diag_hsic_write_pool &&
-		(driver->hsic_device_enabled == 0)) {
+	if (driver->diag_hsic_write_pool && (driver->hsic_inited == 0)) {
 		/*
 		 * Free up struct pool ONLY if there are no outstanding
 		 * transactions(aggregation buffer) with USB
diff --git a/drivers/char/msm_rotator.c b/drivers/char/msm_rotator.c
index 6f3b79b..e1e3ff5 100644
--- a/drivers/char/msm_rotator.c
+++ b/drivers/char/msm_rotator.c
@@ -28,7 +28,7 @@
 #include <linux/file.h>
 #include <linux/major.h>
 #include <linux/regulator/consumer.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
 #ifdef CONFIG_MSM_BUS_SCALING
 #include <mach/msm_bus.h>
 #include <mach/msm_bus_board.h>
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 03fdc5a..c799c1f 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -556,7 +556,6 @@
 	  PMICs through RPC.
 
 config GPIO_QPNP_PIN
-	depends on ARCH_MSM8974
 	depends on SPMI
 	depends on OF_SPMI
 	depends on MSM_QPNP_INT
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index eb9598a..7f760ed 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -33,6 +33,7 @@
 #include <linux/uaccess.h>
 #include <linux/debugfs.h>
 #include <linux/dma-buf.h>
+#include <linux/msm_ion.h>
 
 #include <mach/iommu_domains.h>
 #include "ion_priv.h"
@@ -821,31 +822,6 @@
 }
 EXPORT_SYMBOL(ion_unmap_kernel);
 
-static int check_vaddr_bounds(unsigned long start, unsigned long end)
-{
-	struct mm_struct *mm = current->active_mm;
-	struct vm_area_struct *vma;
-	int ret = 1;
-
-	if (end < start)
-		goto out;
-
-	down_read(&mm->mmap_sem);
-	vma = find_vma(mm, start);
-	if (vma && vma->vm_start < end) {
-		if (start < vma->vm_start)
-			goto out_up;
-		if (end > vma->vm_end)
-			goto out_up;
-		ret = 0;
-	}
-
-out_up:
-	up_read(&mm->mmap_sem);
-out:
-	return ret;
-}
-
 int ion_do_cache_op(struct ion_client *client, struct ion_handle *handle,
 			void *uaddr, unsigned long offset, unsigned long len,
 			unsigned int cmd)
@@ -1415,8 +1391,10 @@
 				   sizeof(struct ion_fd_data)))
 			return -EFAULT;
 		data.handle = ion_import_dma_buf(client, data.fd);
-		if (IS_ERR(data.handle))
+		if (IS_ERR(data.handle)) {
+			ret = PTR_ERR(data.handle);
 			data.handle = NULL;
+		}
 		if (copy_to_user((void __user *)arg, &data,
 				 sizeof(struct ion_fd_data)))
 			return -EFAULT;
@@ -1437,65 +1415,17 @@
 		return dev->custom_ioctl(client, data.cmd, data.arg);
 	}
 	case ION_IOC_CLEAN_CACHES:
+		return client->dev->custom_ioctl(client,
+						ION_IOC_CLEAN_CACHES, arg);
 	case ION_IOC_INV_CACHES:
+		return client->dev->custom_ioctl(client,
+						ION_IOC_INV_CACHES, arg);
 	case ION_IOC_CLEAN_INV_CACHES:
-	{
-		struct ion_flush_data data;
-		unsigned long start, end;
-		struct ion_handle *handle = NULL;
-		int ret;
-
-		if (copy_from_user(&data, (void __user *)arg,
-				sizeof(struct ion_flush_data)))
-			return -EFAULT;
-
-		start = (unsigned long) data.vaddr;
-		end = (unsigned long) data.vaddr + data.length;
-
-		if (check_vaddr_bounds(start, end)) {
-			pr_err("%s: virtual address %p is out of bounds\n",
-				__func__, data.vaddr);
-			return -EINVAL;
-		}
-
-		if (!data.handle) {
-			handle = ion_import_dma_buf(client, data.fd);
-			if (IS_ERR(handle)) {
-				pr_info("%s: Could not import handle: %d\n",
-					__func__, (int)handle);
-				return -EINVAL;
-			}
-		}
-
-		ret = ion_do_cache_op(client,
-					data.handle ? data.handle : handle,
-					data.vaddr, data.offset, data.length,
-					cmd);
-
-		if (!data.handle)
-			ion_free(client, handle);
-
-		if (ret < 0)
-			return ret;
-		break;
-
-	}
+		return client->dev->custom_ioctl(client,
+						ION_IOC_CLEAN_INV_CACHES, arg);
 	case ION_IOC_GET_FLAGS:
-	{
-		struct ion_flag_data data;
-		int ret;
-		if (copy_from_user(&data, (void __user *)arg,
-				   sizeof(struct ion_flag_data)))
-			return -EFAULT;
-
-		ret = ion_handle_get_flags(client, data.handle, &data.flags);
-		if (ret < 0)
-			return ret;
-		if (copy_to_user((void __user *)arg, &data,
-				 sizeof(struct ion_flag_data)))
-			return -EFAULT;
-		break;
-	}
+		return client->dev->custom_ioctl(client,
+						ION_IOC_GET_FLAGS, arg);
 	default:
 		return -ENOTTY;
 	}
diff --git a/drivers/gpu/ion/ion_carveout_heap.c b/drivers/gpu/ion/ion_carveout_heap.c
index a591eb4..7d7ea36 100644
--- a/drivers/gpu/ion/ion_carveout_heap.c
+++ b/drivers/gpu/ion/ion_carveout_heap.c
@@ -31,6 +31,7 @@
 #include <mach/iommu_domains.h>
 #include <asm/mach/map.h>
 #include <asm/cacheflush.h>
+#include <linux/msm_ion.h>
 
 struct ion_carveout_heap {
 	struct ion_heap heap;
diff --git a/drivers/gpu/ion/ion_cp_heap.c b/drivers/gpu/ion/ion_cp_heap.c
index 23ccab3..9f33859 100644
--- a/drivers/gpu/ion/ion_cp_heap.c
+++ b/drivers/gpu/ion/ion_cp_heap.c
@@ -19,7 +19,7 @@
 #include <linux/err.h>
 #include <linux/genalloc.h>
 #include <linux/io.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
 #include <linux/mm.h>
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
diff --git a/drivers/gpu/ion/ion_heap.c b/drivers/gpu/ion/ion_heap.c
index 6ea49db..165a7bf 100644
--- a/drivers/gpu/ion/ion_heap.c
+++ b/drivers/gpu/ion/ion_heap.c
@@ -18,6 +18,7 @@
 #include <linux/err.h>
 #include <linux/ion.h>
 #include "ion_priv.h"
+#include <linux/msm_ion.h>
 
 struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data)
 {
diff --git a/drivers/gpu/ion/ion_iommu_heap.c b/drivers/gpu/ion/ion_iommu_heap.c
index d0f101c..345c07d 100644
--- a/drivers/gpu/ion/ion_iommu_heap.c
+++ b/drivers/gpu/ion/ion_iommu_heap.c
@@ -12,7 +12,7 @@
  */
 #include <linux/err.h>
 #include <linux/io.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
 #include <linux/mm.h>
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
index c79c184..ad2ef83 100644
--- a/drivers/gpu/ion/ion_system_heap.c
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -27,6 +27,7 @@
 #include "ion_priv.h"
 #include <mach/memory.h>
 #include <asm/cacheflush.h>
+#include <linux/msm_ion.h>
 
 static atomic_t system_heap_allocated;
 static atomic_t system_contig_heap_allocated;
diff --git a/drivers/gpu/ion/msm/ion_cp_common.h b/drivers/gpu/ion/msm/ion_cp_common.h
index 69dd19e..634473f 100644
--- a/drivers/gpu/ion/msm/ion_cp_common.h
+++ b/drivers/gpu/ion/msm/ion_cp_common.h
@@ -15,7 +15,7 @@
 #define ION_CP_COMMON_H
 
 #include <asm-generic/errno-base.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
 
 #define ION_CP_V1	1
 #define ION_CP_V2	2
diff --git a/drivers/gpu/ion/msm/msm_ion.c b/drivers/gpu/ion/msm/msm_ion.c
index c65a000..4c9be1d 100644
--- a/drivers/gpu/ion/msm/msm_ion.c
+++ b/drivers/gpu/ion/msm/msm_ion.c
@@ -13,12 +13,17 @@
 
 #include <linux/export.h>
 #include <linux/err.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/memory_alloc.h>
 #include <linux/fmem.h>
 #include <linux/of.h>
+#include <linux/mm.h>
+#include <linux/mm_types.h>
+#include <linux/sched.h>
+#include <linux/rwsem.h>
+#include <linux/uaccess.h>
 #include <mach/ion.h>
 #include <mach/msm_memtypes.h>
 #include "../ion_priv.h"
@@ -556,6 +561,102 @@
 	return ERR_PTR(ret);
 }
 
+static int check_vaddr_bounds(unsigned long start, unsigned long end)
+{
+	struct mm_struct *mm = current->active_mm;
+	struct vm_area_struct *vma;
+	int ret = 1;
+
+	if (end < start)
+		goto out;
+
+	down_read(&mm->mmap_sem);
+	vma = find_vma(mm, start);
+	if (vma && vma->vm_start < end) {
+		if (start < vma->vm_start)
+			goto out_up;
+		if (end > vma->vm_end)
+			goto out_up;
+		ret = 0;
+	}
+
+out_up:
+	up_read(&mm->mmap_sem);
+out:
+	return ret;
+}
+
+static long msm_ion_custom_ioctl(struct ion_client *client,
+				unsigned int cmd,
+				unsigned long arg)
+{
+	switch (cmd) {
+	case ION_IOC_CLEAN_CACHES:
+	case ION_IOC_INV_CACHES:
+	case ION_IOC_CLEAN_INV_CACHES:
+	{
+		struct ion_flush_data data;
+		unsigned long start, end;
+		struct ion_handle *handle = NULL;
+		int ret;
+
+		if (copy_from_user(&data, (void __user *)arg,
+					sizeof(struct ion_flush_data)))
+			return -EFAULT;
+
+		start = (unsigned long) data.vaddr;
+		end = (unsigned long) data.vaddr + data.length;
+
+		if (check_vaddr_bounds(start, end)) {
+			pr_err("%s: virtual address %p is out of bounds\n",
+				__func__, data.vaddr);
+			return -EINVAL;
+		}
+
+		if (!data.handle) {
+			handle = ion_import_dma_buf(client, data.fd);
+			if (IS_ERR(handle)) {
+				pr_info("%s: Could not import handle: %d\n",
+					__func__, (int)handle);
+				return -EINVAL;
+			}
+		}
+
+		ret = ion_do_cache_op(client,
+				data.handle ? data.handle : handle,
+				data.vaddr, data.offset, data.length,
+				cmd);
+
+		if (!data.handle)
+			ion_free(client, handle);
+
+		if (ret < 0)
+			return ret;
+		break;
+
+	}
+	case ION_IOC_GET_FLAGS:
+	{
+		struct ion_flag_data data;
+		int ret;
+		if (copy_from_user(&data, (void __user *)arg,
+					sizeof(struct ion_flag_data)))
+			return -EFAULT;
+
+		ret = ion_handle_get_flags(client, data.handle, &data.flags);
+		if (ret < 0)
+			return ret;
+		if (copy_to_user((void __user *)arg, &data,
+					sizeof(struct ion_flag_data)))
+			return -EFAULT;
+		break;
+	}
+	default:
+		return -ENOTTY;
+	}
+	return 0;
+}
+
 static int msm_ion_probe(struct platform_device *pdev)
 {
 	struct ion_platform_data *pdata;
@@ -583,7 +684,7 @@
 		goto out;
 	}
 
-	idev = ion_device_create(NULL);
+	idev = ion_device_create(msm_ion_custom_ioctl);
 	if (IS_ERR_OR_NULL(idev)) {
 		err = PTR_ERR(idev);
 		goto freeheaps;
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index e5cf660..b51342f 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -228,10 +228,6 @@
 
 	adreno_idle(device);
 
-	if (adreno_is_a20x(adreno_dev) && adreno_dev->drawctxt_active)
-		kgsl_setstate(&device->mmu, adreno_dev->drawctxt_active->id,
-			KGSL_MMUFLAGS_PTUPDATE);
-
 	kgsl_sharedmem_free(&drawctxt->gpustate);
 	kgsl_sharedmem_free(&drawctxt->context_gmem_shadow.gmemshadow);
 
diff --git a/drivers/media/dvb/mpq/video/mpq_dvb_video.c b/drivers/media/dvb/mpq/video/mpq_dvb_video.c
index 68653ba..3dc31bb 100644
--- a/drivers/media/dvb/mpq/video/mpq_dvb_video.c
+++ b/drivers/media/dvb/mpq/video/mpq_dvb_video.c
@@ -55,6 +55,8 @@
 
 static int mpq_int_vid_dec_decode_frame(struct video_client_ctx *client_ctx,
 				struct video_data_buffer *input_frame);
+static int mpq_int_vid_dec_get_buffer_req(struct video_client_ctx *client_ctx,
+				  struct video_buffer_req *vdec_buf_req);
 
 static struct mpq_dvb_video_dev *mpq_dvb_video_device;
 
@@ -819,11 +821,32 @@
 		return 0;
 }
 
+static int mpq_int_set_out_buffer_req(struct video_client_ctx *client_ctx,
+					struct video_buffer_req *vdec_buf_req)
+{
+	struct vcd_buffer_requirement buffer_req;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	buffer_req.actual_count = vdec_buf_req->num_output_buffers;
+	buffer_req.align = vdec_buf_req->output_buf_prop.alignment;
+	buffer_req.max_count = vdec_buf_req->num_output_buffers;
+	buffer_req.min_count = vdec_buf_req->num_output_buffers;
+	buffer_req.sz = vdec_buf_req->output_buf_prop.buf_size;
+
+	vcd_status = vcd_set_buffer_requirements(client_ctx->vcd_handle,
+			VCD_BUFFER_OUTPUT, &buffer_req);
+	if (vcd_status)
+		return -EFAULT;
+	else
+		return 0;
+}
+
 static int mpq_int_set_full_hd_frame_resolution(
 				struct video_client_ctx *client_ctx)
 {
 	struct vdec_picsize pic_res;
 	int rc;
+	struct video_buffer_req vdec_buf_req;
 
 	pic_res.frame_height = 1080;
 	pic_res.frame_width  = 1920;
@@ -841,6 +864,15 @@
 		DBG("Failed in mpq_int_vid_dec_set_cont_on_reconfig : %d\n",\
 			rc);
 
+	rc = mpq_int_vid_dec_get_buffer_req(client_ctx, &vdec_buf_req);
+	if (rc)
+		DBG("Failed in mpq_int_vid_dec_get_buffer_req : %d\n", rc);
+
+	vdec_buf_req.num_output_buffers = 15;
+	rc = mpq_int_set_out_buffer_req(client_ctx, &vdec_buf_req);
+	if (rc)
+		DBG("Failed in mpq_int_set_out_buffer_req (15) : %d\n", rc);
+
 	return rc;
 
 }
diff --git a/drivers/media/video/msm/gemini/msm_gemini_hw.h b/drivers/media/video/msm/gemini/msm_gemini_hw.h
index 233f082..248ba06 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_hw.h
+++ b/drivers/media/video/msm/gemini/msm_gemini_hw.h
@@ -15,7 +15,7 @@
 
 #include <media/msm_gemini.h>
 #include "msm_gemini_hw_reg.h"
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
 #include <mach/iommu_domains.h>
 
 struct msm_gemini_hw_buf {
diff --git a/drivers/media/video/msm/gemini/msm_gemini_platform.h b/drivers/media/video/msm/gemini/msm_gemini_platform.h
index eb6b9f0..d7f81aa 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_platform.h
+++ b/drivers/media/video/msm/gemini/msm_gemini_platform.h
@@ -15,7 +15,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
 #include <linux/iommu.h>
 void msm_gemini_platform_p2v(struct file  *file,
 				struct ion_handle **ionhandle);
diff --git a/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c b/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c
index 9549dcc..d508c1d 100644
--- a/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c
+++ b/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c
@@ -139,11 +139,11 @@
 	switch (perf_setting) {
 	case S_INIT:
 		add_axi_qos();
-		break;
-	case S_PREVIEW:
 		update_axi_qos(MSM_AXI_QOS_PREVIEW);
 		axi_allocate(AXI_FLOW_VIEWFINDER_HI);
 		break;
+	case S_PREVIEW:
+		break;
 	case S_VIDEO:
 		update_axi_qos(MSM_AXI_QOS_RECORDING);
 		break;
diff --git a/drivers/media/video/msm/mercury/msm_mercury_platform.h b/drivers/media/video/msm/mercury/msm_mercury_platform.h
index 8f4a7e3..9edbb30 100644
--- a/drivers/media/video/msm/mercury/msm_mercury_platform.h
+++ b/drivers/media/video/msm/mercury/msm_mercury_platform.h
@@ -15,7 +15,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
 
 int msm_mercury_platform_clk_enable(void);
 int msm_mercury_platform_clk_disable(void);
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index 1e1b4ae..cb59d68 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -33,7 +33,7 @@
 #include <mach/camera.h>
 #include <mach/iommu.h>
 #include <media/msm_isp.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
 #include <linux/iommu.h>
 #include <media/msm_gestures.h>
 
diff --git a/drivers/media/video/msm/msm_camera.c b/drivers/media/video/msm/msm_camera.c
index 2f1d1ab..dce3630 100644
--- a/drivers/media/video/msm/msm_camera.c
+++ b/drivers/media/video/msm/msm_camera.c
@@ -34,7 +34,7 @@
 #include <mach/camera.h>
 #include <linux/syscalls.h>
 #include <linux/hrtimer.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
 
 #include <mach/cpuidle.h>
 DEFINE_MUTEX(ctrl_cmd_lock);
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index 2613986..1e17c5c 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -555,6 +555,7 @@
 	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC:
 	case CMD_AXI_START:
 	case CMD_AXI_STOP:
+	case CMD_AXI_RESET:
 	case CMD_AXI_CFG_TERT1:
 	case CMD_AXI_CFG_TERT2:
 		/* Dont need to pass buffer information.
diff --git a/drivers/media/video/msm/sensors/ov5647_v4l2.c b/drivers/media/video/msm/sensors/ov5647_v4l2.c
index eb6a8b0..f6cf427 100644
--- a/drivers/media/video/msm/sensors/ov5647_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov5647_v4l2.c
@@ -23,6 +23,8 @@
 
 static struct msm_camera_i2c_reg_conf ov5647_start_settings[] = {
 	{0x4202, 0x00},  /* streaming on */
+	{0x0100, 0x01},
+	{0x4800, 0x04},
 };
 
 static struct msm_camera_i2c_reg_conf ov5647_stop_settings[] = {
diff --git a/drivers/media/video/msm/server/msm_cam_server.c b/drivers/media/video/msm/server/msm_cam_server.c
index bb9a9b7..b78e20d 100644
--- a/drivers/media/video/msm/server/msm_cam_server.c
+++ b/drivers/media/video/msm/server/msm_cam_server.c
@@ -1643,6 +1643,10 @@
 
 		rp = (struct msm_vfe_resp *)arg;
 		frame_info = rp->evt_msg.data;
+		if (!frame_info) {
+			interface = PIX_0;
+			break;
+		}
 		if (frame_info->inst_handle) {
 			vnode_id = GET_DEVID_MODE(frame_info->inst_handle);
 			if (vnode_id < MAX_NUM_ACTIVE_CAMERA &&
diff --git a/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c b/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
index 15c38af..9deae65 100644
--- a/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
+++ b/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
@@ -1561,6 +1561,11 @@
 	}
 		return 0;
 
+	case CMD_AXI_START:
+	case CMD_AXI_STOP:
+	case CMD_AXI_RESET:
+		return 0;
+
 	case CMD_CONFIG_FREE_BUF_ADDR: {
 		int path = *((int *)cmd->value);
 		struct buf_info *outch = vfe2x_get_ch(path);
@@ -1853,9 +1858,6 @@
 						flags);
 				if (op_mode & SNAPSHOT_MASK_MODE) {
 					vfe2x_ctrl->stop_pending = 0;
-					vfe2x_send_isp_msg(vfe2x_ctrl,
-						msgs_map[MSG_STOP_ACK].
-						isp_id);
 					spin_unlock_irqrestore(
 							&vfe2x_ctrl->table_lock,
 							flags);
diff --git a/drivers/media/video/msm_vidc/msm_smem.h b/drivers/media/video/msm_vidc/msm_smem.h
index 37816e1..c109abd 100644
--- a/drivers/media/video/msm_vidc/msm_smem.h
+++ b/drivers/media/video/msm_vidc/msm_smem.h
@@ -14,7 +14,7 @@
 #define _MSM_SMEM_H_
 
 #include <linux/types.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
 
 enum smem_type {
 	SMEM_ION,
diff --git a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
index dd2a207..a4c4b83 100644
--- a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
+++ b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
@@ -31,7 +31,6 @@
 #include "msm_smem.h"
 
 #define BASE_DEVICE_NUMBER 32
-#define MAX_EVENTS 30
 #define SHARED_QSIZE 0x1000000
 
 static struct msm_bus_vectors enc_ocmem_init_vectors[]  = {
@@ -47,7 +46,7 @@
 	{
 		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
 		.dst = MSM_BUS_SLAVE_OCMEM,
-		.ab = 414700000,
+		.ab = 138200000,
 		.ib = 1222000000,
 	},
 };
@@ -56,7 +55,7 @@
 	{
 		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
 		.dst = MSM_BUS_SLAVE_OCMEM,
-		.ab = 940000000,
+		.ab = 414700000,
 		.ib = 1222000000,
 	},
 };
@@ -65,7 +64,7 @@
 	{
 		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
 		.dst = MSM_BUS_SLAVE_OCMEM,
-		.ab = 1880000000,
+		.ab = 940000000,
 		.ib = 2444000000U,
 	},
 };
@@ -111,7 +110,7 @@
 	{
 		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
 		.dst = MSM_BUS_SLAVE_OCMEM,
-		.ab = 456200000,
+		.ab = 176900000,
 		.ib = 1556640000,
 	},
 };
@@ -120,7 +119,7 @@
 	{
 		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
 		.dst = MSM_BUS_SLAVE_OCMEM,
-		.ab = 864800000,
+		.ab = 456200000,
 		.ib = 1556640000,
 	},
 };
@@ -129,8 +128,8 @@
 	{
 		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
 		.dst = MSM_BUS_SLAVE_OCMEM,
-		.ab = 1729600000,
-		.ib = 3113280000U,
+		.ab = 864800000,
+		.ib = 1556640000,
 	},
 };
 
@@ -451,7 +450,7 @@
 };
 
 struct msm_v4l2_vid_inst {
-	struct msm_vidc_inst vidc_inst;
+	struct msm_vidc_inst *vidc_inst;
 	void *mem_client;
 	struct list_head registered_bufs;
 };
@@ -468,22 +467,7 @@
 	struct msm_vidc_inst *vidc_inst;
 	vidc_inst = container_of(filp->private_data,
 			struct msm_vidc_inst, event_handler);
-	return container_of((void *)vidc_inst,
-			struct msm_v4l2_vid_inst, vidc_inst);
-}
-
-static int msm_vidc_v4l2_setup_event_queue(void *inst,
-				struct video_device *pvdev)
-{
-	int rc = 0;
-	struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
-	spin_lock_init(&pvdev->fh_lock);
-	INIT_LIST_HEAD(&pvdev->fh_list);
-
-	v4l2_fh_init(&vidc_inst->event_handler, pvdev);
-	v4l2_fh_add(&vidc_inst->event_handler);
-
-	return rc;
+	return (struct msm_v4l2_vid_inst *)vidc_inst->priv;
 }
 
 struct buffer_info *get_registered_buf(struct list_head *list,
@@ -556,7 +540,8 @@
 		rc = -ENOMEM;
 		goto fail_mem_client;
 	}
-	rc = msm_vidc_open(&v4l2_inst->vidc_inst, core->id, vid_dev->type);
+
+	v4l2_inst->vidc_inst = msm_vidc_open(core->id, vid_dev->type);
 	if (rc) {
 		dprintk(VIDC_ERR,
 		"Failed to create video instance, core: %d, type = %d\n",
@@ -565,9 +550,9 @@
 		goto fail_open;
 	}
 	INIT_LIST_HEAD(&v4l2_inst->registered_bufs);
-	rc = msm_vidc_v4l2_setup_event_queue(&v4l2_inst->vidc_inst, vdev);
+	v4l2_inst->vidc_inst->priv = v4l2_inst;
 	clear_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags);
-	filp->private_data = &(v4l2_inst->vidc_inst.event_handler);
+	filp->private_data = &(v4l2_inst->vidc_inst->event_handler);
 	return rc;
 fail_open:
 	msm_smem_delete_client(v4l2_inst->mem_client);
@@ -667,7 +652,7 @@
 					buffer_info.m.planes[0].reserved[0],
 					buffer_info.m.planes[0].reserved[1],
 					buffer_info.m.planes[0].length);
-				rc = msm_vidc_release_buf(&v4l2_inst->vidc_inst,
+				rc = msm_vidc_release_buf(v4l2_inst->vidc_inst,
 					&buffer_info);
 				list_del(&bi->list);
 				if (bi->handle)
@@ -752,7 +737,7 @@
 		list_add_tail(&binfo->list, &v4l2_inst->registered_bufs);
 		b->m.planes[i].m.userptr = binfo->device_addr;
 	}
-	rc = msm_vidc_prepare_buf(&v4l2_inst->vidc_inst, b);
+	rc = msm_vidc_prepare_buf(v4l2_inst->vidc_inst, b);
 exit:
 	return rc;
 }
@@ -794,7 +779,7 @@
 			}
 		}
 	}
-	rc = msm_vidc_qbuf(&v4l2_inst->vidc_inst, b);
+	rc = msm_vidc_qbuf(v4l2_inst->vidc_inst, b);
 err_invalid_buff:
 	return rc;
 }
@@ -823,17 +808,17 @@
 static int msm_v4l2_subscribe_event(struct v4l2_fh *fh,
 				struct v4l2_event_subscription *sub)
 {
-	int rc = 0;
-	rc = v4l2_event_subscribe(fh, sub, MAX_EVENTS);
-	return rc;
+	struct msm_vidc_inst *vidc_inst = container_of(fh,
+			struct msm_vidc_inst, event_handler);
+	return msm_vidc_subscribe_event((void *)vidc_inst, sub);
 }
 
 static int msm_v4l2_unsubscribe_event(struct v4l2_fh *fh,
 				struct v4l2_event_subscription *sub)
 {
-	int rc = 0;
-	rc = v4l2_event_unsubscribe(fh, sub);
-	return rc;
+	struct msm_vidc_inst *vidc_inst = container_of(fh,
+			struct msm_vidc_inst, event_handler);
+	return msm_vidc_unsubscribe_event((void *)vidc_inst, sub);
 }
 
 static int msm_v4l2_decoder_cmd(struct file *file, void *fh,
@@ -936,7 +921,7 @@
 	struct msm_iova_layout layout;
 	int rc = 0;
 	int i;
-	struct iommu_info *io_map = core->resources.io_map;
+	struct msm_vidc_iommu_info *io_map = core->resources.io_map;
 	strlcpy(io_map[CP_MAP].name, "vidc-cp-map",
 			sizeof(io_map[CP_MAP].name));
 	strlcpy(io_map[CP_MAP].ctx, "venus_cp",
diff --git a/drivers/media/video/msm_vidc/msm_vdec.c b/drivers/media/video/msm_vidc/msm_vdec.c
index 8240890..be2e848 100644
--- a/drivers/media/video/msm_vidc/msm_vdec.c
+++ b/drivers/media/video/msm_vidc/msm_vdec.c
@@ -229,6 +229,14 @@
 		.type = OUTPUT_PORT,
 	},
 	{
+		.name = "VC1 SP",
+		.description = "VC-1 compressed format G",
+		.fourcc = V4L2_PIX_FMT_VC1_ANNEX_L,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_compressed,
+		.type = OUTPUT_PORT,
+	},
+	{
 		.name = "H264",
 		.description = "H264 compressed format",
 		.fourcc = V4L2_PIX_FMT_H264,
@@ -524,6 +532,8 @@
 			goto err_invalid_fmt;
 		}
 	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		inst->prop.width = f->fmt.pix_mp.width;
+		inst->prop.height = f->fmt.pix_mp.height;
 		fmt = msm_comm_get_pixel_fmt_fourcc(vdec_formats,
 			ARRAY_SIZE(vdec_formats), f->fmt.pix_mp.pixelformat,
 			OUTPUT_PORT);
diff --git a/drivers/media/video/msm_vidc/msm_vidc.c b/drivers/media/video/msm_vidc/msm_vidc.c
index 449dab2..c7269d3 100644
--- a/drivers/media/video/msm_vidc/msm_vidc.c
+++ b/drivers/media/video/msm_vidc/msm_vidc.c
@@ -21,6 +21,8 @@
 #include "msm_smem.h"
 #include <linux/delay.h>
 
+#define MAX_EVENTS 30
+
 int msm_vidc_poll(void *instance, struct file *filp,
 		struct poll_table_struct *wait)
 {
@@ -55,9 +57,28 @@
 	return rc;
 }
 
+int msm_vidc_get_iommu_maps(void *instance,
+		struct msm_vidc_iommu_info maps[MAX_MAP])
+{
+	struct msm_vidc_inst *inst = instance;
+	int c = 0;
+
+	if (!inst || !maps)
+		return -EINVAL;
+
+	for (c = 0; c < MAX_MAP; ++c)
+		maps[c] = inst->core->resources.io_map[c];
+
+	return 0;
+}
+
 int msm_vidc_querycap(void *instance, struct v4l2_capability *cap)
 {
 	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !cap)
+		return -EINVAL;
+
 	if (inst->session_type == MSM_VIDC_DECODER)
 		return msm_vdec_querycap(instance, cap);
 	else if (inst->session_type == MSM_VIDC_ENCODER)
@@ -67,6 +88,10 @@
 int msm_vidc_enum_fmt(void *instance, struct v4l2_fmtdesc *f)
 {
 	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !f)
+		return -EINVAL;
+
 	if (inst->session_type == MSM_VIDC_DECODER)
 		return msm_vdec_enum_fmt(instance, f);
 	else if (inst->session_type == MSM_VIDC_ENCODER)
@@ -76,6 +101,10 @@
 int msm_vidc_s_fmt(void *instance, struct v4l2_format *f)
 {
 	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !f)
+		return -EINVAL;
+
 	if (inst->session_type == MSM_VIDC_DECODER)
 		return msm_vdec_s_fmt(instance, f);
 	if (inst->session_type == MSM_VIDC_ENCODER)
@@ -85,6 +114,10 @@
 int msm_vidc_g_fmt(void *instance, struct v4l2_format *f)
 {
 	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !f)
+		return -EINVAL;
+
 	if (inst->session_type == MSM_VIDC_DECODER)
 		return msm_vdec_g_fmt(instance, f);
 	else if (inst->session_type == MSM_VIDC_ENCODER)
@@ -94,6 +127,10 @@
 int msm_vidc_s_ctrl(void *instance, struct v4l2_control *control)
 {
 	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !control)
+		return -EINVAL;
+
 	if (inst->session_type == MSM_VIDC_DECODER)
 		return msm_vdec_s_ctrl(instance, control);
 	if (inst->session_type == MSM_VIDC_ENCODER)
@@ -103,6 +140,10 @@
 int msm_vidc_g_ctrl(void *instance, struct v4l2_control *control)
 {
 	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !control)
+		return -EINVAL;
+
 	if (inst->session_type == MSM_VIDC_DECODER)
 		return msm_vdec_g_ctrl(instance, control);
 	if (inst->session_type == MSM_VIDC_ENCODER)
@@ -112,6 +153,10 @@
 int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b)
 {
 	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !b)
+		return -EINVAL;
+
 	if (inst->session_type == MSM_VIDC_DECODER)
 		return msm_vdec_reqbufs(instance, b);
 	if (inst->session_type == MSM_VIDC_ENCODER)
@@ -122,6 +167,10 @@
 int msm_vidc_prepare_buf(void *instance, struct v4l2_buffer *b)
 {
 	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !b)
+		return -EINVAL;
+
 	if (inst->session_type == MSM_VIDC_DECODER)
 		return msm_vdec_prepare_buf(instance, b);
 	if (inst->session_type == MSM_VIDC_ENCODER)
@@ -132,6 +181,10 @@
 int msm_vidc_release_buf(void *instance, struct v4l2_buffer *b)
 {
 	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !b)
+		return -EINVAL;
+
 	if (inst->session_type == MSM_VIDC_DECODER)
 		return msm_vdec_release_buf(instance, b);
 	return -EINVAL;
@@ -156,6 +209,10 @@
 int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
 {
 	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !b)
+		return -EINVAL;
+
 	if (inst->session_type == MSM_VIDC_DECODER)
 		return msm_vdec_qbuf(instance, b);
 	if (inst->session_type == MSM_VIDC_ENCODER)
@@ -166,6 +223,10 @@
 int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b)
 {
 	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !b)
+		return -EINVAL;
+
 	if (inst->session_type == MSM_VIDC_DECODER)
 		return msm_vdec_dqbuf(instance, b);
 	if (inst->session_type == MSM_VIDC_ENCODER)
@@ -176,6 +237,10 @@
 int msm_vidc_streamon(void *instance, enum v4l2_buf_type i)
 {
 	struct msm_vidc_inst *inst = instance;
+
+	if (!inst)
+		return -EINVAL;
+
 	if (inst->session_type == MSM_VIDC_DECODER)
 		return msm_vdec_streamon(instance, i);
 	if (inst->session_type == MSM_VIDC_ENCODER)
@@ -186,6 +251,10 @@
 int msm_vidc_streamoff(void *instance, enum v4l2_buf_type i)
 {
 	struct msm_vidc_inst *inst = instance;
+
+	if (!inst)
+		return -EINVAL;
+
 	if (inst->session_type == MSM_VIDC_DECODER)
 		return msm_vdec_streamoff(instance, i);
 	if (inst->session_type == MSM_VIDC_ENCODER)
@@ -193,13 +262,13 @@
 	return -EINVAL;
 }
 
-void *vidc_get_userptr(void *alloc_ctx, unsigned long vaddr,
+static void *vidc_get_userptr(void *alloc_ctx, unsigned long vaddr,
 				unsigned long size, int write)
 {
 	return (void *)0xdeadbeef;
 }
 
-void vidc_put_userptr(void *buf_priv)
+static void vidc_put_userptr(void *buf_priv)
 {
 }
 
@@ -232,9 +301,60 @@
 	return vb2_queue_init(q);
 }
 
-int msm_vidc_open(void *vidc_inst, int core_id, int session_type)
+static int setup_event_queue(void *inst,
+				struct video_device *pvdev)
 {
-	struct msm_vidc_inst *inst = (struct msm_vidc_inst *)vidc_inst;
+	int rc = 0;
+	struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
+	spin_lock_init(&pvdev->fh_lock);
+	INIT_LIST_HEAD(&pvdev->fh_list);
+
+	v4l2_fh_init(&vidc_inst->event_handler, pvdev);
+	v4l2_fh_add(&vidc_inst->event_handler);
+
+	return rc;
+}
+
+int msm_vidc_subscribe_event(void *inst, struct v4l2_event_subscription *sub)
+{
+	int rc = 0;
+	struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
+
+	if (!inst || !sub)
+		return -EINVAL;
+
+	rc = v4l2_event_subscribe(&vidc_inst->event_handler, sub, MAX_EVENTS);
+	return rc;
+}
+
+
+int msm_vidc_unsubscribe_event(void *inst, struct v4l2_event_subscription *sub)
+{
+	int rc = 0;
+	struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
+
+	if (!inst || !sub)
+		return -EINVAL;
+
+	rc = v4l2_event_unsubscribe(&vidc_inst->event_handler, sub);
+	return rc;
+}
+
+int msm_vidc_dqevent(void *inst, struct v4l2_event *event)
+{
+	int rc = 0;
+	struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
+
+	if (!inst || !event)
+		return -EINVAL;
+
+	rc = v4l2_event_dequeue(&vidc_inst->event_handler, event, false);
+	return rc;
+}
+
+void *msm_vidc_open(int core_id, int session_type)
+{
+	struct msm_vidc_inst *inst = NULL;
 	struct msm_vidc_core *core = NULL;
 	unsigned long flags;
 	int rc = 0;
@@ -252,6 +372,13 @@
 		goto err_invalid_core;
 	}
 
+	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+	if (!inst) {
+		pr_err("Failed to allocate memory\n")	;
+		rc = -ENOMEM;
+		goto err_invalid_core;
+	}
+
 	mutex_init(&inst->sync_lock);
 	spin_lock_init(&inst->lock);
 	inst->session_type = session_type;
@@ -276,6 +403,7 @@
 		msm_venc_inst_init(inst);
 		msm_venc_ctrl_init(inst);
 	}
+
 	rc = vb2_bufq_init(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
 			session_type);
 	if (rc) {
@@ -298,17 +426,20 @@
 	}
 	inst->debugfs_root =
 		msm_vidc_debugfs_init_inst(inst, core->debugfs_root);
+
+	setup_event_queue(inst, &core->vdev[core_id].vdev);
+
 	spin_lock_irqsave(&core->lock, flags);
 	list_add_tail(&inst->list, &core->instances);
 	spin_unlock_irqrestore(&core->lock, flags);
-	return rc;
+	return inst;
 fail_init:
 	msm_smem_delete_client(inst->mem_client);
 fail_mem_client:
 	kfree(inst);
 	inst = NULL;
 err_invalid_core:
-	return rc;
+	return inst;
 }
 
 static void cleanup_instance(struct msm_vidc_inst *inst)
@@ -360,6 +491,10 @@
 	struct msm_vidc_core *core;
 	struct list_head *ptr, *next;
 	int rc = 0;
+
+	if (!inst)
+		return -EINVAL;
+
 	core = inst->core;
 	mutex_lock(&core->sync_lock);
 	list_for_each_safe(ptr, next, &core->instances) {
@@ -373,6 +508,7 @@
 		dprintk(VIDC_ERR,
 			"Failed to move video instance to uninit state\n");
 	cleanup_instance(inst);
+	kfree(inst);
 	dprintk(VIDC_DBG, "Closed the instance\n");
 	return 0;
 }
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
index 5b83cfb..84552a4 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -166,7 +166,7 @@
 	int rc;
 	struct iommu_domain *domain;
 	int i;
-	struct iommu_info *io_map;
+	struct msm_vidc_iommu_info *io_map;
 	struct device *dev;
 	for (i = 0; i < MAX_MAP; i++) {
 		io_map = &core->resources.io_map[i];
@@ -202,7 +202,7 @@
 {
 	struct device *dev;
 	struct iommu_domain *domain;
-	struct iommu_info *io_map;
+	struct msm_vidc_iommu_info *io_map;
 	int i;
 	if (!core) {
 		dprintk(VIDC_ERR, "Invalid paramter: %p\n", core);
@@ -737,7 +737,7 @@
 		dprintk(VIDC_ERR, "Invalid args: %p\n", core);
 		return -EINVAL;
 	}
-	num_mbs_per_sec = 2 * msm_comm_get_load(core, MSM_VIDC_ENCODER);
+	num_mbs_per_sec = msm_comm_get_load(core, MSM_VIDC_ENCODER);
 	num_mbs_per_sec += msm_comm_get_load(core, MSM_VIDC_DECODER);
 	dprintk(VIDC_INFO, "num_mbs_per_sec = %d\n", num_mbs_per_sec);
 	rc = clk_set_rate(core->resources.clock[VCODEC_CLK].clk,
diff --git a/drivers/media/video/msm_vidc/msm_vidc_internal.h b/drivers/media/video/msm_vidc/msm_vidc_internal.h
index 55aec74..3c14123 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_internal.h
+++ b/drivers/media/video/msm_vidc/msm_vidc_internal.h
@@ -141,20 +141,6 @@
 	void *cookie;
 };
 
-struct iommu_info {
-	u32 addr_range[2];
-	char name[MAX_NAME_LENGTH];
-	char ctx[MAX_NAME_LENGTH];
-	int domain;
-	int partition;
-};
-
-enum io_maps {
-	CP_MAP,
-	NS_MAP,
-	MAX_MAP
-};
-
 enum vidc_clocks {
 	VCODEC_CLK,
 	VCODEC_AHB_CLK,
@@ -188,7 +174,7 @@
 
 struct msm_vidc_resources {
 	struct msm_vidc_fw fw;
-	struct iommu_info io_map[MAX_MAP];
+	struct msm_vidc_iommu_info io_map[MAX_MAP];
 	struct core_clock clock[VCODEC_MAX_CLKS];
 	struct vidc_bus_info bus_info;
 	struct on_chip_mem ocmem;
@@ -247,6 +233,7 @@
 	u32 ftb_count;
 	u32 fbd_count;
 	struct vb2_buffer *vb2_seq_hdr;
+	void *priv;
 };
 
 extern struct msm_vidc_drv *vidc_driver;
diff --git a/drivers/media/video/msm_vidc/vidc_hal.c b/drivers/media/video/msm_vidc/vidc_hal.c
index 12ba874..0639dea 100644
--- a/drivers/media/video/msm_vidc/vidc_hal.c
+++ b/drivers/media/video/msm_vidc/vidc_hal.c
@@ -608,6 +608,9 @@
 
 static void set_vbif_registers(struct hal_device *device)
 {
+	/*Disable Dynamic clock gating for Venus VBIF*/
+	write_register(device->hal_data->register_base_addr,
+				   VIDC_VENUS_VBIF_CLK_ON, 1, 0);
 	write_register(device->hal_data->register_base_addr,
 			VIDC_VBIF_OUT_AXI_AOOO_EN, 0x00000FFF, 0);
 	write_register(device->hal_data->register_base_addr,
@@ -636,6 +639,8 @@
 			VIDC_VBIF_OUT_WR_LIM_CONF0, 0x00001010, 0);
 	write_register(device->hal_data->register_base_addr,
 			VIDC_VBIF_ARB_CTL, 0x00000030, 0);
+	write_register(device->hal_data->register_base_addr,
+			VIDC_VENUS0_WRAPPER_VBIF_REQ_PRIORITY, 0x5555556, 0);
 }
 
 int vidc_hal_core_init(void *device, int domain)
@@ -654,10 +659,6 @@
 	INIT_LIST_HEAD(&dev->sess_head);
 	spin_lock_init(&dev->read_lock);
 	spin_lock_init(&dev->write_lock);
-
-	/*Disable Dynamic clock gating for Venus VBIF*/
-	write_register(dev->hal_data->register_base_addr,
-				   VIDC_VENUS_VBIF_CLK_ON, 1, 0);
 	set_vbif_registers(dev);
 	if (!dev->hal_client) {
 		dev->hal_client = msm_smem_new_client(SMEM_ION);
diff --git a/drivers/media/video/msm_vidc/vidc_hal_io.h b/drivers/media/video/msm_vidc/vidc_hal_io.h
index c4b1e0c..b85e015 100644
--- a/drivers/media/video/msm_vidc/vidc_hal_io.h
+++ b/drivers/media/video/msm_vidc/vidc_hal_io.h
@@ -124,9 +124,9 @@
 #define VIDC_VBIF_AT_NEW_BASE           (VIDC_VBIF_BASE_OFFS + 0xC10)
 #define VIDC_VBIF_AT_NEW_HIGH           (VIDC_VBIF_BASE_OFFS + 0xC18)
 
-#define VIDC_VENUS0_VENUS_WRAPPER_VBIF_REQ_PRIORITY \
+#define VIDC_VENUS0_WRAPPER_VBIF_REQ_PRIORITY \
 	(VIDC_WRAPPER_BASE_OFFS + 0x20)
-#define VIDC_VENUS0_VENUS_WRAPPER_VBIF_PRIORITY_LEVEL \
+#define VIDC_VENUS0_WRAPPER_VBIF_PRIORITY_LEVEL \
 	(VIDC_WRAPPER_BASE_OFFS + 0x24)
 #define VIDC_VENUS_VBIF_REQ_PRIORITY    (VIDC_WRAPPER_BASE_OFFS + 0x20)
 #define VIDC_VENUS_VBIF_PRIORITY_LEVEL  (VIDC_WRAPPER_BASE_OFFS + 0x24)
diff --git a/drivers/media/video/msm_wfd/enc-subdev.h b/drivers/media/video/msm_wfd/enc-subdev.h
index 5873e62..00eb6da 100644
--- a/drivers/media/video/msm_wfd/enc-subdev.h
+++ b/drivers/media/video/msm_wfd/enc-subdev.h
@@ -14,7 +14,7 @@
 #ifndef _WFD_ENC_SUBDEV_
 #define _WFD_ENC_SUBDEV_
 
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
 #include <media/v4l2-subdev.h>
 #include <media/videobuf2-core.h>
 #define VENC_MAGIC_IOCTL 'V'
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 52fd5e8..b153b27 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -5798,6 +5798,7 @@
 	mmc->caps2 |= MMC_CAP2_PACKED_WR_CONTROL;
 	mmc->caps2 |= (MMC_CAP2_BOOTPART_NOACC | MMC_CAP2_DETECT_ON_ERR);
 	mmc->caps2 |= MMC_CAP2_SANITIZE;
+	mmc->caps2 |= MMC_CAP2_CACHE_CTRL;
 
 	if (plat->nonremovable)
 		mmc->caps |= MMC_CAP_NONREMOVABLE;
diff --git a/drivers/platform/msm/qpnp-power-on.c b/drivers/platform/msm/qpnp-power-on.c
index 0119ebe..996456f 100644
--- a/drivers/platform/msm/qpnp-power-on.c
+++ b/drivers/platform/msm/qpnp-power-on.c
@@ -435,6 +435,14 @@
 		return -EINVAL;
 	}
 
+	/* mark the interrupts wakeable if they support linux-key */
+	if (cfg->key_code) {
+		enable_irq_wake(cfg->state_irq);
+		/* special handling for RESIN due to a hardware bug */
+		if (cfg->pon_type == PON_RESIN && cfg->support_reset)
+			enable_irq_wake(cfg->bark_irq);
+	}
+
 	return rc;
 }
 
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index 813e40a..28b641d 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -32,6 +32,7 @@
 #include <mach/msm_hsusb.h>
 
 #define CHG_BUCK_CLOCK_CTRL	0x14
+#define CHG_BUCK_CLOCK_CTRL_8038	0xD
 
 #define PBL_ACCESS1		0x04
 #define PBL_ACCESS2		0x05
@@ -3678,7 +3679,13 @@
 		return rc;
 	}
 	/* switch to a 3.2Mhz for the buck */
-	rc = pm8xxx_writeb(chip->dev->parent, CHG_BUCK_CLOCK_CTRL, 0x15);
+	if (pm8xxx_get_revision(chip->dev->parent) >= PM8XXX_REVISION_8038_1p0)
+		rc = pm8xxx_writeb(chip->dev->parent,
+			CHG_BUCK_CLOCK_CTRL_8038, 0x15);
+	else
+		rc = pm8xxx_writeb(chip->dev->parent,
+			CHG_BUCK_CLOCK_CTRL, 0x15);
+
 	if (rc) {
 		pr_err("Failed to switch buck clk rc=%d\n", rc);
 		return rc;
diff --git a/drivers/regulator/qpnp-regulator.c b/drivers/regulator/qpnp-regulator.c
index 44fdbc1..0549593 100644
--- a/drivers/regulator/qpnp-regulator.c
+++ b/drivers/regulator/qpnp-regulator.c
@@ -71,11 +71,18 @@
 	QPNP_REGULATOR_SUBTYPE_N300		= 0x03,
 	QPNP_REGULATOR_SUBTYPE_N600		= 0x04,
 	QPNP_REGULATOR_SUBTYPE_N1200		= 0x05,
+	QPNP_REGULATOR_SUBTYPE_N600_ST		= 0x06,
+	QPNP_REGULATOR_SUBTYPE_N1200_ST		= 0x07,
 	QPNP_REGULATOR_SUBTYPE_P50		= 0x08,
 	QPNP_REGULATOR_SUBTYPE_P150		= 0x09,
 	QPNP_REGULATOR_SUBTYPE_P300		= 0x0A,
 	QPNP_REGULATOR_SUBTYPE_P600		= 0x0B,
 	QPNP_REGULATOR_SUBTYPE_P1200		= 0x0C,
+	QPNP_REGULATOR_SUBTYPE_LV_P50		= 0x28,
+	QPNP_REGULATOR_SUBTYPE_LV_P150		= 0x29,
+	QPNP_REGULATOR_SUBTYPE_LV_P300		= 0x2A,
+	QPNP_REGULATOR_SUBTYPE_LV_P600		= 0x2B,
+	QPNP_REGULATOR_SUBTYPE_LV_P1200		= 0x2C,
 	QPNP_REGULATOR_SUBTYPE_LV100		= 0x01,
 	QPNP_REGULATOR_SUBTYPE_LV300		= 0x02,
 	QPNP_REGULATOR_SUBTYPE_MV300		= 0x08,
@@ -978,11 +985,20 @@
 	QPNP_VREG_MAP(LDO,   N1200,    0,   0, LDO,    ldo,    nldo2,   10000),
 	QPNP_VREG_MAP(LDO,   N600,     1, INF, LDO,    ldo,    nldo3,   10000),
 	QPNP_VREG_MAP(LDO,   N1200,    1, INF, LDO,    ldo,    nldo3,   10000),
+	QPNP_VREG_MAP(LDO,   N600_ST,  0,   0, LDO,    ldo,    nldo2,   10000),
+	QPNP_VREG_MAP(LDO,   N1200_ST, 0,   0, LDO,    ldo,    nldo2,   10000),
+	QPNP_VREG_MAP(LDO,   N600_ST,  1, INF, LDO,    ldo,    nldo3,   10000),
+	QPNP_VREG_MAP(LDO,   N1200_ST, 1, INF, LDO,    ldo,    nldo3,   10000),
 	QPNP_VREG_MAP(LDO,   P50,      0, INF, LDO,    ldo,    pldo,     5000),
 	QPNP_VREG_MAP(LDO,   P150,     0, INF, LDO,    ldo,    pldo,    10000),
 	QPNP_VREG_MAP(LDO,   P300,     0, INF, LDO,    ldo,    pldo,    10000),
 	QPNP_VREG_MAP(LDO,   P600,     0, INF, LDO,    ldo,    pldo,    10000),
 	QPNP_VREG_MAP(LDO,   P1200,    0, INF, LDO,    ldo,    pldo,    10000),
+	QPNP_VREG_MAP(LDO,   LV_P50,   0, INF, LDO,    ldo,    pldo,     5000),
+	QPNP_VREG_MAP(LDO,   LV_P150,  0, INF, LDO,    ldo,    pldo,    10000),
+	QPNP_VREG_MAP(LDO,   LV_P300,  0, INF, LDO,    ldo,    pldo,    10000),
+	QPNP_VREG_MAP(LDO,   LV_P600,  0, INF, LDO,    ldo,    pldo,    10000),
+	QPNP_VREG_MAP(LDO,   LV_P1200, 0, INF, LDO,    ldo,    pldo,    10000),
 	QPNP_VREG_MAP(VS,    LV100,    0, INF, VS,     vs,     none,        0),
 	QPNP_VREG_MAP(VS,    LV300,    0, INF, VS,     vs,     none,        0),
 	QPNP_VREG_MAP(VS,    MV300,    0, INF, VS,     vs,     none,        0),
diff --git a/drivers/spmi/Kconfig b/drivers/spmi/Kconfig
index 8724138..c32978e 100644
--- a/drivers/spmi/Kconfig
+++ b/drivers/spmi/Kconfig
@@ -21,7 +21,6 @@
 
 config MSM_QPNP_INT
 	depends on SPARSE_IRQ
-	depends on ARCH_MSM8974
 	depends on SPMI
 	depends on OF_SPMI
 	bool "MSM QPNP INT"
diff --git a/drivers/thermal/pm8xxx-tm.c b/drivers/thermal/pm8xxx-tm.c
index 50238f3..ec04369 100644
--- a/drivers/thermal/pm8xxx-tm.c
+++ b/drivers/thermal/pm8xxx-tm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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
@@ -65,10 +65,11 @@
 
 struct pm8xxx_tm_chip {
 	struct pm8xxx_tm_core_data	cdata;
-	struct work_struct		irq_work;
+	struct delayed_work		irq_work;
 	struct device			*dev;
 	struct thermal_zone_device	*tz_dev;
 	unsigned long			temp;
+	unsigned int			prev_stage;
 	enum thermal_device_mode	mode;
 	unsigned int			thresh;
 	unsigned int			stage;
@@ -82,6 +83,9 @@
 	SOFTWARE_OVERRIDE_ENABLED,
 };
 
+/* Delay between TEMP_STAT IRQ going high and status value changing in ms. */
+#define STATUS_REGISTER_DELAY_MS	40
+
 static inline int pm8xxx_tm_read_ctrl(struct pm8xxx_tm_chip *chip, u8 *reg)
 {
 	int rc;
@@ -312,6 +316,10 @@
 	if (!chip)
 		return -EINVAL;
 
+	/* Mask software override requests if they are not allowed. */
+	if (!chip->cdata.allow_software_override)
+		mode = THERMAL_DEVICE_DISABLED;
+
 	if (mode != chip->mode) {
 		if (mode == THERMAL_DEVICE_ENABLED)
 			pm8xxx_tm_shutdown_override(chip,
@@ -421,31 +429,18 @@
 
 static void pm8xxx_tm_work(struct work_struct *work)
 {
+	struct delayed_work *dwork
+		= container_of(work, struct delayed_work, work);
 	struct pm8xxx_tm_chip *chip
-		= container_of(work, struct pm8xxx_tm_chip, irq_work);
-	int rc;
+		= container_of(dwork, struct pm8xxx_tm_chip, irq_work);
+	unsigned long temp = 0;
+	int rc, stage, thresh;
 	u8 reg;
 
 	rc = pm8xxx_tm_read_ctrl(chip, &reg);
 	if (rc < 0)
 		goto bail;
 
-	if (chip->cdata.adc_type == PM8XXX_TM_ADC_NONE) {
-		rc = pm8xxx_tm_update_temp_no_adc(chip);
-		if (rc < 0)
-			goto bail;
-		pr_info("%s: Temp Alarm - stage=%u, threshold=%u, "
-			"temp=%lu mC\n", chip->cdata.tm_name, chip->stage,
-			chip->thresh, chip->temp);
-	} else {
-		chip->stage = (reg & TEMP_ALARM_CTRL_STATUS_MASK)
-				>> TEMP_ALARM_CTRL_STATUS_SHIFT;
-		chip->thresh = (reg & TEMP_ALARM_CTRL_THRESH_MASK)
-				>> TEMP_ALARM_CTRL_THRESH_SHIFT;
-		pr_info("%s: Temp Alarm - stage=%u, threshold=%u\n",
-			chip->cdata.tm_name, chip->stage, chip->thresh);
-	}
-
 	/* Clear status bits. */
 	if (reg & (TEMP_ALARM_CTRL_ST2_SD | TEMP_ALARM_CTRL_ST3_SD)) {
 		reg &= ~(TEMP_ALARM_CTRL_ST2_SD | TEMP_ALARM_CTRL_ST3_SD
@@ -454,24 +449,47 @@
 		pm8xxx_tm_write_ctrl(chip, reg);
 	}
 
+	stage = (reg & TEMP_ALARM_CTRL_STATUS_MASK)
+		>> TEMP_ALARM_CTRL_STATUS_SHIFT;
+	thresh = (reg & TEMP_ALARM_CTRL_THRESH_MASK)
+		>> TEMP_ALARM_CTRL_THRESH_SHIFT;
+
 	thermal_zone_device_update(chip->tz_dev);
 
-	/* Notify user space */
-	if (chip->mode == THERMAL_DEVICE_ENABLED)
-		kobject_uevent(&chip->tz_dev->device.kobj, KOBJ_CHANGE);
+	if (stage != chip->prev_stage) {
+		chip->prev_stage = stage;
+
+		switch (chip->cdata.adc_type) {
+		case PM8XXX_TM_ADC_NONE:
+			rc = pm8xxx_tz_get_temp_no_adc(chip->tz_dev, &temp);
+			break;
+		case PM8XXX_TM_ADC_PM8058_ADC:
+			rc = pm8xxx_tz_get_temp_pm8058_adc(chip->tz_dev, &temp);
+			break;
+		case PM8XXX_TM_ADC_PM8XXX_ADC:
+			rc = pm8xxx_tz_get_temp_pm8xxx_adc(chip->tz_dev, &temp);
+			break;
+		}
+		if (rc < 0)
+			goto bail;
+
+		pr_crit("%s: PMIC Temp Alarm - stage=%u, threshold=%u, temp=%lu mC\n",
+			chip->cdata.tm_name, stage, thresh, temp);
+
+		/* Notify user space */
+		sysfs_notify(&chip->tz_dev->device.kobj, NULL, "type");
+	}
 
 bail:
-	enable_irq(chip->tempstat_irq);
-	enable_irq(chip->overtemp_irq);
+	return;
 }
 
 static irqreturn_t pm8xxx_tm_isr(int irq, void *data)
 {
 	struct pm8xxx_tm_chip *chip = data;
 
-	disable_irq_nosync(chip->tempstat_irq);
-	disable_irq_nosync(chip->overtemp_irq);
-	schedule_work(&chip->irq_work);
+	schedule_delayed_work(&chip->irq_work,
+		msecs_to_jiffies(STATUS_REGISTER_DELAY_MS) + 1);
 
 	return IRQ_HANDLED;
 }
@@ -610,7 +628,7 @@
 	chip->mode = THERMAL_DEVICE_DISABLED;
 	thermal_zone_device_update(chip->tz_dev);
 
-	INIT_WORK(&chip->irq_work, pm8xxx_tm_work);
+	INIT_DELAYED_WORK(&chip->irq_work, pm8xxx_tm_work);
 
 	rc = request_irq(chip->tempstat_irq, pm8xxx_tm_isr, IRQF_TRIGGER_RISING,
 		chip->cdata.irq_name_temp_stat, chip);
@@ -635,7 +653,7 @@
 err_free_irq_tempstat:
 	free_irq(chip->tempstat_irq, chip);
 err_cancel_work:
-	cancel_work_sync(&chip->irq_work);
+	cancel_delayed_work_sync(&chip->irq_work);
 err_free_tz:
 	thermal_zone_device_unregister(chip->tz_dev);
 err_fail_adc:
@@ -651,7 +669,7 @@
 
 	if (chip) {
 		platform_set_drvdata(pdev, NULL);
-		cancel_work_sync(&chip->irq_work);
+		cancel_delayed_work_sync(&chip->irq_work);
 		free_irq(chip->overtemp_irq, chip);
 		free_irq(chip->tempstat_irq, chip);
 		pm8xxx_tm_shutdown_override(chip, SOFTWARE_OVERRIDE_DISABLED);
diff --git a/drivers/usb/gadget/ci13xxx_msm_hsic.c b/drivers/usb/gadget/ci13xxx_msm_hsic.c
index 6faaf78..b0b9468 100644
--- a/drivers/usb/gadget/ci13xxx_msm_hsic.c
+++ b/drivers/usb/gadget/ci13xxx_msm_hsic.c
@@ -67,6 +67,7 @@
 	struct work_struct	suspend_w;
 	struct msm_hsic_peripheral_platform_data *pdata;
 	enum usb_vdd_type	vdd_type;
+	bool connected;
 };
 
 static const int vdd_val[VDD_TYPE_MAX][VDD_VAL_MAX] = {
@@ -381,7 +382,7 @@
 	 */
 	mb();
 
-	if (!mhsic->pdata->core_clk_always_on_workaround) {
+	if (!mhsic->pdata->core_clk_always_on_workaround || !mhsic->connected) {
 		clk_disable(mhsic->iface_clk);
 		clk_disable(mhsic->core_clk);
 	}
@@ -438,7 +439,7 @@
 		dev_err(mhsic->dev, "%s failed to vote for TCXO %d\n",
 				__func__, ret);
 
-	if (!mhsic->pdata->core_clk_always_on_workaround) {
+	if (!mhsic->pdata->core_clk_always_on_workaround || !mhsic->connected) {
 		clk_enable(mhsic->iface_clk);
 		clk_enable(mhsic->core_clk);
 	}
@@ -598,22 +599,38 @@
 
 	switch (event) {
 	case CI13XXX_CONTROLLER_RESET_EVENT:
-		dev_dbg(dev, "CI13XXX_CONTROLLER_RESET_EVENT received\n");
+		dev_info(dev, "CI13XXX_CONTROLLER_RESET_EVENT received\n");
 		writel_relaxed(0, USB_AHBBURST);
 		writel_relaxed(0x08, USB_AHBMODE);
 		break;
 	case CI13XXX_CONTROLLER_CONNECT_EVENT:
-		dev_dbg(dev, "CI13XXX_CONTROLLER_CONNECT_EVENT received\n");
-		msm_hsic_start();
+		dev_info(dev, "CI13XXX_CONTROLLER_CONNECT_EVENT received\n");
+		msm_hsic_wakeup();
+		the_mhsic->connected = true;
 		break;
 	case CI13XXX_CONTROLLER_SUSPEND_EVENT:
-		dev_dbg(dev, "CI13XXX_CONTROLLER_SUSPEND_EVENT received\n");
+		dev_info(dev, "CI13XXX_CONTROLLER_SUSPEND_EVENT received\n");
 		queue_work(mhsic->wq, &mhsic->suspend_w);
 		break;
 	case CI13XXX_CONTROLLER_REMOTE_WAKEUP_EVENT:
-		dev_dbg(dev, "CI13XXX_CONTROLLER_REMOTE_WAKEUP_EVENT received\n");
+		dev_info(dev, "CI13XXX_CONTROLLER_REMOTE_WAKEUP_EVENT received\n");
 		msm_hsic_wakeup();
 		break;
+	case CI13XXX_CONTROLLER_UDC_STARTED_EVENT:
+		dev_info(dev, "CI13XXX_CONTROLLER_UDC_STARTED_EVENT received\n");
+		/*
+		 * UDC started, suspend the hsic device until it will be
+		 * connected by a pullup (CI13XXX_CONTROLLER_CONNECT_EVENT)
+		 * Before suspend, finish required configurations.
+		 */
+		hw_device_state(_udc->ep0out.qh.dma);
+		msm_hsic_start();
+		usleep(10000);
+
+		mhsic->connected = false;
+		pm_runtime_put_noidle(the_mhsic->dev);
+		pm_runtime_suspend(the_mhsic->dev);
+		break;
 	default:
 		dev_dbg(dev, "unknown ci13xxx_udc event\n");
 		break;
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 831e970..5b39336 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -3205,6 +3205,11 @@
 	spin_unlock_irqrestore(udc->lock, flags);
 	if (retval || put)
 		pm_runtime_put_sync(&udc->gadget.dev);
+
+	if (udc->udc_driver->notify_event)
+			udc->udc_driver->notify_event(udc,
+				CI13XXX_CONTROLLER_UDC_STARTED_EVENT);
+
 	return retval;
 }
 
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h
index 6527b76..3162e15 100644
--- a/drivers/usb/gadget/ci13xxx_udc.h
+++ b/drivers/usb/gadget/ci13xxx_udc.h
@@ -126,6 +126,8 @@
 #define CI13XXX_CONTROLLER_REMOTE_WAKEUP_EVENT	3
 #define CI13XXX_CONTROLLER_RESUME_EVENT	        4
 #define CI13XXX_CONTROLLER_DISCONNECT_EVENT	    5
+#define CI13XXX_CONTROLLER_UDC_STARTED_EVENT	    6
+
 	void	(*notify_event) (struct ci13xxx *udc, unsigned event);
 };
 
diff --git a/drivers/usb/gadget/u_bam.c b/drivers/usb/gadget/u_bam.c
index a9e5d91..45dfb87 100644
--- a/drivers/usb/gadget/u_bam.c
+++ b/drivers/usb/gadget/u_bam.c
@@ -640,26 +640,6 @@
 	clear_bit(BAM_CH_OPENED, &d->flags);
 }
 
-static void gbam2bam_disconnect_work(struct work_struct *w)
-{
-	struct gbam_port *port =
-			container_of(w, struct gbam_port, disconnect_w);
-	unsigned long		flags;
-
-	spin_lock_irqsave(&port->port_lock_ul, flags);
-	spin_lock(&port->port_lock_dl);
-	port->port_usb = 0;
-	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)
 {
 	struct gbam_port *port = container_of(w, struct gbam_port, connect_w);
@@ -699,29 +679,6 @@
 	struct bam_ch_info *d = &port->data_ch;
 	u32 sps_params;
 	int ret;
-	unsigned long flags;
-
-	ret = usb_ep_enable(port->gr->in);
-	if (ret) {
-		pr_err("%s: usb_ep_enable failed eptype:IN ep:%p",
-				__func__, port->gr->in);
-		return;
-	}
-	port->gr->in->driver_data = port;
-
-	ret = usb_ep_enable(port->gr->out);
-	if (ret) {
-		pr_err("%s: usb_ep_enable failed eptype:OUT ep:%p",
-				__func__, port->gr->out);
-		port->gr->in->driver_data = 0;
-		return;
-	}
-	port->gr->out->driver_data = port;
-	spin_lock_irqsave(&port->port_lock_ul, flags);
-	spin_lock(&port->port_lock_dl);
-	port->port_usb = port->gr;
-	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,
 						  &d->dst_pipe_idx);
@@ -916,7 +873,6 @@
 	spin_lock_init(&port->port_lock_dl);
 
 	INIT_WORK(&port->connect_w, gbam2bam_connect_work);
-	INIT_WORK(&port->disconnect_w, gbam2bam_disconnect_work);
 
 	/* data ch */
 	d = &port->data_ch;
@@ -1071,7 +1027,7 @@
 	d = &port->data_ch;
 	port->gr = gr;
 
-	if (trans == USB_GADGET_XPORT_BAM) {
+	if (trans == USB_GADGET_XPORT_BAM)
 		gbam_free_buffers(port);
 
 	spin_lock_irqsave(&port->port_lock_ul, flags);
@@ -1081,12 +1037,15 @@
 	spin_unlock(&port->port_lock_dl);
 	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 
-		/* disable endpoints */
-		usb_ep_disable(gr->out);
-		usb_ep_disable(gr->in);
-	}
+	/* disable endpoints */
+	usb_ep_disable(gr->out);
+	usb_ep_disable(gr->in);
 
-	queue_work(gbam_wq, &port->disconnect_w);
+	gr->in->driver_data = NULL;
+	gr->out->driver_data = NULL;
+
+	if (trans == USB_GADGET_XPORT_BAM)
+		queue_work(gbam_wq, &port->disconnect_w);
 }
 
 int gbam_connect(struct grmnet *gr, u8 port_num,
@@ -1121,36 +1080,37 @@
 
 	d = &port->data_ch;
 
-	if (trans == USB_GADGET_XPORT_BAM) {
-		ret = usb_ep_enable(gr->in);
-		if (ret) {
-			pr_err("%s: usb_ep_enable failed eptype:IN ep:%p",
-					__func__, gr->in);
-			return ret;
-		}
-		gr->in->driver_data = port;
+	ret = usb_ep_enable(gr->in);
+	if (ret) {
+		pr_err("%s: usb_ep_enable failed eptype:IN ep:%p",
+			__func__, gr->in);
+		return ret;
+	}
+	gr->in->driver_data = port;
 
-		ret = usb_ep_enable(gr->out);
-		if (ret) {
-			pr_err("%s: usb_ep_enable failed eptype:OUT ep:%p",
-					__func__, gr->out);
-			gr->in->driver_data = 0;
-			return ret;
-		}
-		gr->out->driver_data = port;
+	ret = usb_ep_enable(gr->out);
+	if (ret) {
+		pr_err("%s: usb_ep_enable failed eptype:OUT ep:%p",
+			__func__, gr->out);
+		gr->in->driver_data = 0;
+		return ret;
+	}
+	gr->out->driver_data = port;
 
 	spin_lock_irqsave(&port->port_lock_ul, flags);
 	spin_lock(&port->port_lock_dl);
 	port->port_usb = gr;
 
+	if (trans == USB_GADGET_XPORT_BAM) {
 		d->to_host = 0;
 		d->to_modem = 0;
 		d->pending_with_bam = 0;
 		d->tohost_drp_cnt = 0;
 		d->tomodem_drp_cnt = 0;
+	}
+
 	spin_unlock(&port->port_lock_dl);
 	spin_unlock_irqrestore(&port->port_lock_ul, flags);
-	}
 
 	if (trans == USB_GADGET_XPORT_BAM2BAM) {
 		port->gr = gr;
diff --git a/drivers/usb/misc/diag_bridge.c b/drivers/usb/misc/diag_bridge.c
index cad411d..b1b7763 100644
--- a/drivers/usb/misc/diag_bridge.c
+++ b/drivers/usb/misc/diag_bridge.c
@@ -60,6 +60,11 @@
 		return -ENODEV;
 	}
 
+	if (dev->ops) {
+		pr_err("bridge already opened");
+		return -EALREADY;
+	}
+
 	dev->ops = ops;
 	dev->err = 0;
 
@@ -82,6 +87,16 @@
 {
 	struct diag_bridge	*dev = __dev;
 
+	if (!dev) {
+		pr_err("dev is null");
+		return;
+	}
+
+	if (!dev->ops) {
+		pr_err("can't close bridge that was not open");
+		return;
+	}
+
 	dev_dbg(&dev->ifc->dev, "%s:\n", __func__);
 
 	usb_kill_anchored_urbs(&dev->submitted);
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index a6d8c17..5637f19 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -67,6 +67,8 @@
 #define USB_PHY_VDD_DIG_VOL_MIN	1045000 /* uV */
 #define USB_PHY_VDD_DIG_VOL_MAX	1320000 /* uV */
 
+#define USB_SUSPEND_DELAY_TIME	(500 * HZ/1000) /* 500 msec */
+
 static DECLARE_COMPLETION(pmic_vbus_init);
 static struct msm_otg *the_msm_otg;
 static bool debug_aca_enabled;
@@ -686,7 +688,8 @@
 	if (aca_enabled())
 		return 0;
 
-	if (atomic_read(&motg->in_lpm) == suspend)
+	if (atomic_read(&motg->in_lpm) == suspend &&
+		!atomic_read(&motg->suspend_work_pending))
 		return 0;
 
 	if (suspend) {
@@ -705,7 +708,9 @@
 			if (!(motg->caps & ALLOW_LPM_ON_DEV_SUSPEND))
 				break;
 			set_bit(A_BUS_SUSPEND, &motg->inputs);
-			queue_work(system_nrt_wq, &motg->sm_work);
+			atomic_set(&motg->suspend_work_pending, 1);
+			queue_delayed_work(system_nrt_wq, &motg->suspend_work,
+				USB_SUSPEND_DELAY_TIME);
 			break;
 
 		default:
@@ -2752,6 +2757,14 @@
 		queue_work(system_nrt_wq, &motg->sm_work);
 }
 
+static void msm_otg_suspend_work(struct work_struct *w)
+{
+	struct msm_otg *motg =
+		container_of(w, struct msm_otg, suspend_work.work);
+	atomic_set(&motg->suspend_work_pending, 0);
+	msm_otg_sm_work(&motg->sm_work);
+}
+
 static irqreturn_t msm_otg_irq(int irq, void *data)
 {
 	struct msm_otg *motg = data;
@@ -3629,6 +3642,7 @@
 	INIT_WORK(&motg->sm_work, msm_otg_sm_work);
 	INIT_DELAYED_WORK(&motg->chg_work, msm_chg_detect_work);
 	INIT_DELAYED_WORK(&motg->pmic_id_status_work, msm_pmic_id_status_w);
+	INIT_DELAYED_WORK(&motg->suspend_work, msm_otg_suspend_work);
 	setup_timer(&motg->id_timer, msm_otg_id_timer_func,
 				(unsigned long) motg);
 	ret = request_irq(motg->irq, msm_otg_irq, IRQF_SHARED,
@@ -3791,6 +3805,7 @@
 	msm_otg_debugfs_cleanup();
 	cancel_delayed_work_sync(&motg->chg_work);
 	cancel_delayed_work_sync(&motg->pmic_id_status_work);
+	cancel_delayed_work_sync(&motg->suspend_work);
 	cancel_work_sync(&motg->sm_work);
 
 	pm_runtime_resume(&pdev->dev);
diff --git a/drivers/video/msm/mdp.h b/drivers/video/msm/mdp.h
index 2825f87..1397507 100644
--- a/drivers/video/msm/mdp.h
+++ b/drivers/video/msm/mdp.h
@@ -24,7 +24,7 @@
 #include <linux/msm_mdp.h>
 #include <linux/memory_alloc.h>
 #include <mach/hardware.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
 
 #ifdef CONFIG_MSM_BUS_SCALING
 #include <mach/msm_bus.h>
diff --git a/drivers/video/msm/mdp4_overlay_writeback.c b/drivers/video/msm/mdp4_overlay_writeback.c
index 487e5d5..ee7e9ce 100644
--- a/drivers/video/msm/mdp4_overlay_writeback.c
+++ b/drivers/video/msm/mdp4_overlay_writeback.c
@@ -294,6 +294,7 @@
 	mdp4_mixer_stage_commit(pipe->mixer_num);
 
 	mdp4_writeback_overlay_kickoff(mfd, pipe);
+	mdp4_writeback_dma_busy_wait(mfd);
 
 	/* move current committed iommu to freelist */
 	mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 0);
diff --git a/drivers/video/msm/mdss/mdss.h b/drivers/video/msm/mdss/mdss.h
index 5613398..6f42565 100644
--- a/drivers/video/msm/mdss/mdss.h
+++ b/drivers/video/msm/mdss/mdss.h
@@ -14,7 +14,7 @@
 #ifndef MDSS_H
 #define MDSS_H
 
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
 #include <linux/msm_mdp.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 5432df0..06d8769 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -1137,6 +1137,31 @@
 	return 0;
 }
 
+static int mdss_fb_handle_pp_ioctl(void __user *argp)
+{
+	int ret;
+	struct msmfb_mdp_pp mdp_pp;
+	u32 copyback = 0;
+
+	ret = copy_from_user(&mdp_pp, argp, sizeof(mdp_pp));
+	if (ret)
+		return ret;
+
+	switch (mdp_pp.op) {
+	case mdp_op_pa_cfg:
+		ret = mdss_mdp_pa_config(&mdp_pp.data.pa_cfg_data,
+				&copyback);
+		break;
+	default:
+		pr_err("Unsupported request to MDP_PP IOCTL.\n");
+		ret = -EINVAL;
+		break;
+	}
+	if ((ret == 0) && copyback)
+		ret = copy_to_user(argp, &mdp_pp, sizeof(struct msmfb_mdp_pp));
+	return ret;
+}
+
 static int mdss_fb_ioctl(struct fb_info *info, unsigned int cmd,
 			 unsigned long arg)
 {
@@ -1163,6 +1188,10 @@
 			return ret;
 		break;
 
+	case MSMFB_MDP_PP:
+		ret = mdss_fb_handle_pp_ioctl(argp);
+		break;
+
 	default:
 		if (mfd->ioctl_handler)
 			ret = mfd->ioctl_handler(mfd, cmd, argp);
diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h
index 342ebb8..a10e5e4 100644
--- a/drivers/video/msm/mdss/mdss_fb.h
+++ b/drivers/video/msm/mdss/mdss_fb.h
@@ -14,7 +14,7 @@
 #ifndef MDSS_FB_H
 #define MDSS_FB_H
 
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
 #include <linux/list.h>
 #include <linux/msm_mdp.h>
 #include <linux/types.h>
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index 80e056f..3fb70bd 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -846,10 +846,17 @@
 		pr_err("unable to initialize mdss mdp resources\n");
 		goto probe_done;
 	}
+	rc = mdss_mdp_pp_init(&pdev->dev);
+	if (rc) {
+		pr_err("unable to initialize mdss pp resources\n");
+		goto probe_done;
+	}
 	rc = mdss_mdp_bus_scale_register(mdata);
 probe_done:
-	if (IS_ERR_VALUE(rc))
+	if (IS_ERR_VALUE(rc)) {
 		mdss_res = NULL;
+		mdss_mdp_pp_term(&pdev->dev);
+	}
 
 	return rc;
 }
@@ -942,6 +949,7 @@
 	if (!mdata)
 		return -ENODEV;
 	pm_runtime_disable(&pdev->dev);
+	mdss_mdp_pp_term(&pdev->dev);
 	mdss_mdp_bus_scale_unregister(mdata);
 	return 0;
 }
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index a77c18e..610c132 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -295,7 +295,7 @@
 int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg);
 
 int mdss_mdp_csc_setup(u32 block, u32 blk_idx, u32 tbl_idx, u32 csc_type);
-int mdss_mdp_dspp_setup(struct mdss_mdp_ctl *ctl, struct mdss_mdp_mixer *mixer);
+int mdss_mdp_pp_setup(struct mdss_mdp_ctl *ctl);
 
 struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_pnum(u32 pnum);
 struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_locked(u32 type);
@@ -318,4 +318,9 @@
 int mdss_mdp_wb_kickoff(struct mdss_mdp_ctl *ctl);
 int mdss_mdp_wb_ioctl_handler(struct msm_fb_data_type *mfd, u32 cmd, void *arg);
 
+int mdss_mdp_pp_init(struct device *dev);
+void mdss_mdp_pp_term(struct device *dev);
+int mdss_mdp_pa_config(struct mdp_pa_cfg_data *config, u32 *copyback);
+
+int mdss_mdp_get_ctl_mixers(u32 fb_num, u32 *mixer_id);
 #endif /* MDSS_MDP_H */
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 1486779..26fbca1 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -20,8 +20,8 @@
 #include "mdss_fb.h"
 #include "mdss_mdp.h"
 
-/* 1.10 bus fudge factor */
-#define MDSS_MDP_BUS_FUDGE_FACTOR(val) ALIGN((((val) * 11) / 10), SZ_16M)
+/* 1.5 bus fudge factor */
+#define MDSS_MDP_BUS_FUDGE_FACTOR(val) ALIGN((((val) * 3) / 2), SZ_16M)
 /* 1.25 clock fudge factor */
 #define MDSS_MDP_CLK_FUDGE_FACTOR(val) (((val) * 5) / 4)
 
@@ -63,7 +63,6 @@
 		}
 	}
 	if (flags & MDSS_MDP_PERF_UPDATE_BUS) {
-		bus_ab_quota = MDSS_MDP_BUS_FUDGE_FACTOR(bus_ab_quota);
 		bus_ib_quota = MDSS_MDP_BUS_FUDGE_FACTOR(bus_ib_quota);
 		mdss_mdp_bus_scale_set_quota(bus_ab_quota, bus_ib_quota);
 	}
@@ -808,9 +807,6 @@
 {
 	mixer->params_changed = 0;
 
-	if (mixer->type == MDSS_MDP_MIXER_TYPE_INTF)
-		mdss_mdp_dspp_setup(mixer->ctl, mixer);
-
 	/* skip mixer setup for rotator */
 	if (!mixer->rotator_mode)
 		mdss_mdp_mixer_setup(mixer->ctl, mixer);
@@ -864,6 +860,8 @@
 		ctl->flush_bits |= BIT(17);	/* CTL */
 	}
 
+	/* postprocessing setup, including dspp */
+	mdss_mdp_pp_setup(ctl);
 	mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_FLUSH, ctl->flush_bits);
 	wmb();
 	ctl->flush_bits = 0;
@@ -885,3 +883,30 @@
 
 	return ret;
 }
+
+int mdss_mdp_get_ctl_mixers(u32 fb_num, u32 *mixer_id)
+{
+	int i;
+	struct mdss_mdp_ctl *ctl;
+	u32 mixer_cnt = 0;
+	mutex_lock(&mdss_mdp_ctl_lock);
+	for (i = 0; i < MDSS_MDP_MAX_CTL; i++) {
+		ctl = &mdss_mdp_ctl_list[i];
+		if ((ctl->power_on) &&
+			(ctl->mfd->index == fb_num)) {
+			if (ctl->mixer_left) {
+				mixer_id[mixer_cnt] = ctl->mixer_left->num;
+				mixer_cnt++;
+			}
+			if (mixer_cnt && ctl->mixer_right) {
+				mixer_id[mixer_cnt] = ctl->mixer_right->num;
+				mixer_cnt++;
+			}
+			if (mixer_cnt)
+				break;
+		}
+	}
+	mutex_unlock(&mdss_mdp_ctl_lock);
+	return mixer_cnt;
+}
+
diff --git a/drivers/video/msm/mdss/mdss_mdp_hwio.h b/drivers/video/msm/mdss/mdss_mdp_hwio.h
index 8825cc6..0139afd 100644
--- a/drivers/video/msm/mdss/mdss_mdp_hwio.h
+++ b/drivers/video/msm/mdss/mdss_mdp_hwio.h
@@ -321,6 +321,10 @@
 	MDSS_MDP_MAX_DSPP
 };
 
+#define MDSS_MDP_REG_DSPP_OFFSET(pipe)	(0x4600 + ((pipe) * 0x400))
+#define MDSS_MDP_REG_DSPP_OP_MODE			0x000
+#define MDSS_MDP_REG_DSPP_PA_BASE			0x238
+
 enum mdss_mpd_intf_index {
 	MDSS_MDP_NO_INTF,
 	MDSS_MDP_INTF0,
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index db840a8..7ab3b01 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -13,6 +13,7 @@
 
 #define pr_fmt(fmt)	"%s: " fmt, __func__
 
+#include "mdss_fb.h"
 #include "mdss_mdp.h"
 
 struct mdp_csc_cfg mdp_csc_convert[MDSS_MDP_MAX_CSC] = {
@@ -71,6 +72,27 @@
 #define CSC_LV_OFF	0x14
 #define CSC_POST_OFF	0xC
 
+#define MDSS_BLOCK_DISP_NUM	(MDP_BLOCK_MAX - MDP_LOGICAL_BLOCK_DISP_0)
+
+struct pp_sts_type {
+	u32 pa_sts;
+};
+
+#define PP_FLAGS_DIRTY_PA	0x1
+
+#define PP_STS_ENABLE	0x1
+
+struct mdss_pp_res_type {
+	/* logical info */
+	u32 pp_disp_flags[MDSS_BLOCK_DISP_NUM];
+	struct mdp_pa_cfg_data pa_disp_cfg[MDSS_BLOCK_DISP_NUM];
+	/* physical info */
+	struct pp_sts_type pp_dspp_sts[MDSS_MDP_MAX_DSPP];
+};
+
+static DEFINE_MUTEX(mdss_pp_mutex);
+static struct mdss_pp_res_type *mdss_pp_res;
+
 static int mdss_mdp_csc_setup_data(u32 block, u32 blk_idx, u32 tbl_idx,
 				   struct mdp_csc_cfg *data)
 {
@@ -160,16 +182,147 @@
 	return mdss_mdp_csc_setup_data(block, blk_idx, tbl_idx, data);
 }
 
-int mdss_mdp_dspp_setup(struct mdss_mdp_ctl *ctl, struct mdss_mdp_mixer *mixer)
+static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_ctl *ctl,
+		struct mdss_mdp_mixer *mixer)
 {
-	int dspp_num;
-
-	if (!ctl || !mixer)
-		return -EINVAL;
+	u32 flags, base, offset, dspp_num, opmode = 0;
+	struct mdp_pa_cfg_data *pa_config;
+	struct pp_sts_type *pp_sts;
 
 	dspp_num = mixer->num;
+	/* no corresponding dspp */
+	if ((mixer->type != MDSS_MDP_MIXER_TYPE_INTF) ||
+		(dspp_num >= MDSS_MDP_MAX_DSPP))
+		return 0;
 
-	ctl->flush_bits |= BIT(13 + dspp_num);	/* DSPP */
+	if (disp_num < MDSS_BLOCK_DISP_NUM)
+		flags = mdss_pp_res->pp_disp_flags[disp_num];
+	else
+		flags = 0;
+
+	/* nothing to update */
+	if (!flags)
+		return 0;
+	pp_sts = &mdss_pp_res->pp_dspp_sts[dspp_num];
+	base = MDSS_MDP_REG_DSPP_OFFSET(dspp_num);
+	if (flags & PP_FLAGS_DIRTY_PA) {
+		pa_config = &mdss_pp_res->pa_disp_cfg[disp_num];
+		if (pa_config->flags & MDP_PP_OPS_WRITE) {
+			offset = base + MDSS_MDP_REG_DSPP_PA_BASE;
+			MDSS_MDP_REG_WRITE(offset, pa_config->hue_adj);
+			offset += 4;
+			MDSS_MDP_REG_WRITE(offset, pa_config->sat_adj);
+			offset += 4;
+			MDSS_MDP_REG_WRITE(offset, pa_config->val_adj);
+			offset += 4;
+			MDSS_MDP_REG_WRITE(offset, pa_config->cont_adj);
+		}
+		if (pa_config->flags & MDP_PP_OPS_DISABLE)
+			pp_sts->pa_sts &= ~PP_STS_ENABLE;
+		else if (pa_config->flags & MDP_PP_OPS_ENABLE)
+			pp_sts->pa_sts |= PP_STS_ENABLE;
+	}
+	if (pp_sts->pa_sts & PP_STS_ENABLE)
+		opmode |= (1 << 20); /* PA_EN */
+	MDSS_MDP_REG_WRITE(base + MDSS_MDP_REG_DSPP_OP_MODE, opmode);
+	ctl->flush_bits |= BIT(13 + dspp_num); /* DSPP */
+	return 0;
+
+}
+int mdss_mdp_pp_setup(struct mdss_mdp_ctl *ctl)
+{
+	u32 disp_num;
+	if ((!ctl->mfd) || (!mdss_pp_res))
+		return -EINVAL;
+
+	/* treat fb_num the same as block logical id*/
+	disp_num = ctl->mfd->index;
+
+	mutex_lock(&mdss_pp_mutex);
+	if (ctl->mixer_left)
+		pp_dspp_setup(disp_num, ctl, ctl->mixer_left);
+	if (ctl->mixer_right)
+		pp_dspp_setup(disp_num, ctl, ctl->mixer_right);
+	/* clear dirty flag */
+	if (disp_num < MDSS_BLOCK_DISP_NUM)
+		mdss_pp_res->pp_disp_flags[disp_num] = 0;
+	mutex_unlock(&mdss_pp_mutex);
 
 	return 0;
 }
+
+int mdss_mdp_pp_init(struct device *dev)
+{
+	int ret = 0;
+	mutex_lock(&mdss_pp_mutex);
+	if (!mdss_pp_res) {
+		mdss_pp_res = devm_kzalloc(dev, sizeof(*mdss_pp_res),
+				GFP_KERNEL);
+		if (mdss_pp_res == NULL) {
+			pr_err("%s mdss_pp_res allocation failed!", __func__);
+			ret = -ENOMEM;
+		}
+	}
+	mutex_unlock(&mdss_pp_mutex);
+	return ret;
+}
+void mdss_mdp_pp_term(struct device *dev)
+{
+	if (!mdss_pp_res) {
+		mutex_lock(&mdss_pp_mutex);
+		devm_kfree(dev, mdss_pp_res);
+		mdss_pp_res = NULL;
+		mutex_unlock(&mdss_pp_mutex);
+	}
+}
+
+int mdss_mdp_pa_config(struct mdp_pa_cfg_data *config, u32 *copyback)
+{
+	int i, ret = 0;
+	u32 pa_offset, disp_num, mixer_cnt;
+	u32 mixer_id[MDSS_MDP_MAX_LAYERMIXER];
+
+	if ((config->block < MDP_LOGICAL_BLOCK_DISP_0) ||
+		(config->block >= MDP_BLOCK_MAX))
+		return -EINVAL;
+
+	mutex_lock(&mdss_pp_mutex);
+	disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
+
+	if (config->flags & MDP_PP_OPS_READ) {
+		mixer_cnt = mdss_mdp_get_ctl_mixers(disp_num, mixer_id);
+		if (!mixer_cnt) {
+			ret = -EPERM;
+			goto pa_config_exit;
+		}
+		/* only read the first mixer */
+		for (i = 0; i < mixer_cnt; i++) {
+			if (mixer_id[i] < MDSS_MDP_MAX_DSPP)
+				break;
+		}
+		if (i >= mixer_cnt) {
+			ret = -EPERM;
+			goto pa_config_exit;
+		}
+		mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+		pa_offset = MDSS_MDP_REG_DSPP_OFFSET(mixer_id[i]) +
+			  MDSS_MDP_REG_DSPP_PA_BASE;
+
+		config->hue_adj = MDSS_MDP_REG_READ(pa_offset);
+		pa_offset += 4;
+		config->sat_adj = MDSS_MDP_REG_READ(pa_offset);
+		pa_offset += 4;
+		config->val_adj = MDSS_MDP_REG_READ(pa_offset);
+		pa_offset += 4;
+		config->cont_adj = MDSS_MDP_REG_READ(pa_offset);
+		*copyback = 1;
+		mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+	} else {
+		mdss_pp_res->pa_disp_cfg[disp_num] = *config;
+		mdss_pp_res->pp_disp_flags[disp_num] |= PP_FLAGS_DIRTY_PA;
+	}
+
+pa_config_exit:
+	mutex_unlock(&mdss_pp_mutex);
+	return ret;
+}
diff --git a/drivers/video/msm/mdss/mdss_mdp_util.c b/drivers/video/msm/mdss/mdss_mdp_util.c
index 50cc025..57e8441 100644
--- a/drivers/video/msm/mdss/mdss_mdp_util.c
+++ b/drivers/video/msm/mdss/mdss_mdp_util.c
@@ -16,7 +16,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/errno.h>
 #include <linux/file.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
 #include <linux/iommu.h>
 #include <linux/msm_kgsl.h>
 #include <linux/spinlock.h>
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
index 3620f1a..2af76f3 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
@@ -70,7 +70,6 @@
 	case VIDC_1080P_ERROR_MEM_ALLOCATION_FAILED:
 	case VIDC_1080P_ERROR_INSUFFICIENT_CONTEXT_SIZE:
 	case VIDC_1080P_ERROR_DIVIDE_BY_ZERO:
-	case VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY:
 	case VIDC_1080P_ERROR_DMA_TX_NOT_COMPLETE:
 	case VIDC_1080P_ERROR_VSP_NOT_READY:
 	case VIDC_1080P_ERROR_BUFFER_FULL_STATE:
@@ -242,6 +241,7 @@
 	case VIDC_1080P_ERROR_HEADER_NOT_FOUND:
 	case VIDC_1080P_ERROR_SLICE_PARSE_ERROR:
 	case VIDC_1080P_ERROR_NON_PAIRED_FIELD_NOT_SUPPORTED:
+	case VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY:
 		vcd_status = VCD_ERR_BITSTREAM_ERR;
 		DDL_MSG_ERROR("VIDC_BIT_STREAM_ERR");
 		break;
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
index bfc27dc..4f19de9 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
@@ -364,7 +364,7 @@
 				ddl->command_channel);
 		} else {
 			u32 seq_hdr_only_frame = false;
-			u32 need_reconfig = false;
+			u32 need_reconfig = false, eos_present = 0;
 			struct vcd_frame_data *input_vcd_frm =
 				&ddl->input_frame.vcd_frm;
 			need_reconfig = ddl_check_reconfig(ddl);
@@ -380,15 +380,25 @@
 				input_vcd_frm->offset +=
 					seq_hdr_info.dec_frm_size;
 				input_vcd_frm->data_len = 0;
-				input_vcd_frm->flags |=
-					VCD_FRAME_FLAG_CODECCONFIG;
-				ddl->input_frame.frm_trans_end =
-					!need_reconfig;
-				ddl_context->ddl_callback(
+				eos_present =
+				input_vcd_frm->flags & VCD_FRAME_FLAG_EOS;
+				if (!eos_present) {
+					input_vcd_frm->flags |=
+						VCD_FRAME_FLAG_CODECCONFIG;
+					ddl->input_frame.frm_trans_end =
+						!need_reconfig;
+					ddl_context->ddl_callback(
 					VCD_EVT_RESP_INPUT_DONE,
 					VCD_S_SUCCESS, &ddl->input_frame,
 					sizeof(struct ddl_frame_data_tag),
 					(u32 *) ddl, ddl->client_data);
+				} else {
+					input_vcd_frm->flags &=
+					~(VCD_FRAME_FLAG_CODECCONFIG);
+					seq_hdr_only_frame = false;
+					pr_err("%s() Codec config buffer with eos\n",
+						__func__);
+				}
 			} else {
 				if (decoder->codec.codec ==
 					VCD_CODEC_VC1_RCV) {
diff --git a/include/linux/mfd/pm8xxx/tm.h b/include/linux/mfd/pm8xxx/tm.h
index 6974754..74b77ec 100644
--- a/include/linux/mfd/pm8xxx/tm.h
+++ b/include/linux/mfd/pm8xxx/tm.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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
@@ -22,21 +22,55 @@
 
 #define PM8XXX_TM_DEV_NAME	"pm8xxx-tm"
 
+/**
+ * enum pm8xxx_tm_adc_type - support ADC API types for PMIC thermal manager
+ * %PM8XXX_TM_ADC_NONE:		Do not call any ADC API and instead estimate
+ *				PMIC temerature based on over temperature stage.
+ * %PM8XXX_TM_ADC_PM8058_ADC:	Use the pmic8058-xoadc ADC API
+ * %PM8XXX_TM_ADC_PM8XXX_ADC:	Use the pm8xxx-adc ADC API
+ */
 enum pm8xxx_tm_adc_type {
-	PM8XXX_TM_ADC_NONE,	/* Estimates temp based on overload level. */
+	PM8XXX_TM_ADC_NONE,
 	PM8XXX_TM_ADC_PM8058_ADC,
 	PM8XXX_TM_ADC_PM8XXX_ADC,
 };
 
+/**
+ * struct pm8xxx_tm_core_data - PM8XXX thermal manager core data
+ * @tm_name:			Thermal zone name for the device
+ * @irq_name_temp_stat:		String name used to identify TEMP_STAT IRQ
+ * @irq_name_over_temp:		String name used to identify OVER_TEMP IRQ
+ * @reg_addr_temp_alarm_ctrl:	PMIC SSBI address for temp alarm control
+ *				register
+ * @reg_addr_temp_alarm_pwm:	PMIC SSBI address for temp alarm pwm register
+ * @adc_type:			Determines which ADC API to use in order to read
+ *				the PMIC die temperature.
+ * @adc_channel:		ADC channel identifier
+ *				If adc_type == PM8XXX_TM_ADC_PM8XXX_ADC, then
+ *				use a value from enum pm8xxx_adc_channels.
+ *				If adc_type == PM8XXX_TM_ADC_PM8058_ADC, then
+ *				use a channel value specified in
+ *				<linux/pmic8058-xoadc.h>
+ * @default_no_adc_temp:	Default temperature in millicelcius to report
+ *				while stage == 0 and stage has never been
+ *				greater than 0 if adc_type == PM8XXX_TM_ADC_NONE
+ * @allow_software_override:	true --> writing "enabled" to thermalfs mode
+ *				file results in software override of PMIC
+ *				automatic over temperature shutdown
+ *				false --> PMIC automatic over temperature
+ *				shutdown always enabled.  mode file cannot be
+ *				set to "enabled".
+ */
 struct pm8xxx_tm_core_data {
-	int				adc_channel;
-	unsigned long			default_no_adc_temp;
-	enum pm8xxx_tm_adc_type		adc_type;
-	u16				reg_addr_temp_alarm_ctrl;
-	u16				reg_addr_temp_alarm_pwm;
-	char				*tm_name;
-	char				*irq_name_temp_stat;
-	char				*irq_name_over_temp;
+	char			*tm_name;
+	char			*irq_name_temp_stat;
+	char			*irq_name_over_temp;
+	u16			reg_addr_temp_alarm_ctrl;
+	u16			reg_addr_temp_alarm_pwm;
+	enum pm8xxx_tm_adc_type	adc_type;
+	int			adc_channel;
+	unsigned long		default_no_adc_temp;
+	bool			allow_software_override;
 };
 
 #endif
diff --git a/include/linux/msm_audio_aac.h b/include/linux/msm_audio_aac.h
index 620e5ab..ee71c3e 100644
--- a/include/linux/msm_audio_aac.h
+++ b/include/linux/msm_audio_aac.h
@@ -60,6 +60,7 @@
 	unsigned short sbr_ps_on_flag;
 	unsigned short dual_mono_mode;
 	unsigned short channel_configuration;
+	unsigned short sample_rate;
 };
 
 struct msm_audio_aac_enc_config {
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index c9f9d74..d03ecfa 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -272,8 +272,10 @@
 	struct msmfb_img img;
 };
 
+#define MDP_PP_OPS_ENABLE 0x1
 #define MDP_PP_OPS_READ 0x2
 #define MDP_PP_OPS_WRITE 0x4
+#define MDP_PP_OPS_DISABLE 0x8
 
 struct mdp_qseed_cfg {
 	uint32_t table_num;
@@ -473,12 +475,22 @@
 	uint32_t scale;
 };
 
+struct mdp_pa_cfg_data {
+	uint32_t block;
+	uint32_t flags;
+	uint32_t hue_adj;
+	uint32_t sat_adj;
+	uint32_t val_adj;
+	uint32_t cont_adj;
+};
+
 enum {
 	mdp_op_pcc_cfg,
 	mdp_op_csc_cfg,
 	mdp_op_lut_cfg,
 	mdp_op_qseed_cfg,
 	mdp_bl_scale_cfg,
+	mdp_op_pa_cfg,
 	mdp_op_max,
 };
 
@@ -490,6 +502,7 @@
 		struct mdp_lut_cfg_data lut_cfg_data;
 		struct mdp_qseed_cfg_data qseed_cfg_data;
 		struct mdp_bl_scale_data bl_scale_data;
+		struct mdp_pa_cfg_data pa_cfg_data;
 	} data;
 };
 
diff --git a/include/linux/sync.h b/include/linux/sync.h
index 943f414..4c00f04 100644
--- a/include/linux/sync.h
+++ b/include/linux/sync.h
@@ -24,6 +24,7 @@
 struct sync_timeline;
 struct sync_pt;
 struct sync_fence;
+struct seq_file;
 
 /**
  * struct sync_timeline_ops - sync object implementation ops
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 82f9107..adcc450 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -328,10 +328,12 @@
 	bool sm_work_pending;
 	atomic_t pm_suspended;
 	atomic_t in_lpm;
+	atomic_t suspend_work_pending;
 	int async_int;
 	unsigned cur_power;
 	struct delayed_work chg_work;
 	struct delayed_work pmic_id_status_work;
+	struct delayed_work suspend_work;
 	enum usb_chg_state chg_state;
 	enum usb_chg_type chg_type;
 	u8 dcd_retries;
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 0ace67a..ed9af2c 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -28,7 +28,7 @@
 #include <linux/time.h>
 #endif
 
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
 
 #define BIT(nr)   (1UL << (nr))
 
diff --git a/include/media/msm_vidc.h b/include/media/msm_vidc.h
index 2efe31c..cfca799 100644
--- a/include/media/msm_vidc.h
+++ b/include/media/msm_vidc.h
@@ -14,8 +14,8 @@
 #ifndef _MSM_VIDC_H_
 #define _MSM_VIDC_H_
 
-#include <linux/videodev2.h>
 #include <linux/poll.h>
+#include <linux/videodev2.h>
 
 enum core_id {
 	MSM_VIDC_CORE_0 = 0,
@@ -28,7 +28,21 @@
 	MSM_VIDC_MAX_DEVICES,
 };
 
-int msm_vidc_open(void *vidc_inst, int core_id, int session_type);
+struct msm_vidc_iommu_info {
+	u32 addr_range[2];
+	char name[64];
+	char ctx[64];
+	int domain;
+	int partition;
+};
+
+enum msm_vidc_io_maps {
+	CP_MAP,
+	NS_MAP,
+	MAX_MAP
+};
+
+void *msm_vidc_open(int core_id, int session_type);
 int msm_vidc_close(void *instance);
 int msm_vidc_querycap(void *instance, struct v4l2_capability *cap);
 int msm_vidc_enum_fmt(void *instance, struct v4l2_fmtdesc *f);
@@ -47,4 +61,11 @@
 int msm_vidc_encoder_cmd(void *instance, struct v4l2_encoder_cmd *enc);
 int msm_vidc_poll(void *instance, struct file *filp,
 		struct poll_table_struct *pt);
+int msm_vidc_get_iommu_maps(void *instance,
+		struct msm_vidc_iommu_info maps[MAX_MAP]);
+int msm_vidc_subscribe_event(void *instance,
+		struct v4l2_event_subscription *sub);
+int msm_vidc_unsubscribe_event(void *instance,
+		struct v4l2_event_subscription *sub);
+int msm_vidc_dqevent(void *instance, struct v4l2_event *event);
 #endif
diff --git a/include/media/videobuf2-msm-mem.h b/include/media/videobuf2-msm-mem.h
index 5285997..f80ddcd 100644
--- a/include/media/videobuf2-msm-mem.h
+++ b/include/media/videobuf2-msm-mem.h
@@ -17,7 +17,7 @@
 
 #include <media/videobuf2-core.h>
 #include <mach/iommu_domains.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
 
 struct videobuf2_mapping {
 	unsigned int count;
diff --git a/sound/soc/msm/apq8064.c b/sound/soc/msm/apq8064.c
index e46064b..9bc565e 100644
--- a/sound/soc/msm/apq8064.c
+++ b/sound/soc/msm/apq8064.c
@@ -1739,6 +1739,48 @@
 		.ignore_pmdown_time = 1,
 		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA5,
 	},
+	{
+		.name = "MSM8960 Media6",
+		.stream_name = "MultiMedia6",
+		.cpu_dai_name   = "MultiMedia6",
+		.platform_name  = "msm-multi-ch-pcm-dsp",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+					SND_SOC_DPCM_TRIGGER_POST},
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1, /* this dailink has playback support */
+		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA6
+	},
+	{
+		.name = "MSM8960 Compr2",
+		.stream_name = "COMPR2",
+		.cpu_dai_name   = "MultiMedia7",
+		.platform_name  = "msm-compr-dsp",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+					SND_SOC_DPCM_TRIGGER_POST},
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1, /* this dailink has playback support */
+		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA7,
+	},
+	{
+		.name = "MSM8960 Compr3",
+		.stream_name = "COMPR3",
+		.cpu_dai_name   = "MultiMedia8",
+		.platform_name  = "msm-compr-dsp",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+					SND_SOC_DPCM_TRIGGER_POST},
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1, /* this dailink has playback support */
+		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA8,
+	},
 	/* Backend DAI Links */
 	{
 		.name = LPASS_BE_SLIMBUS_0_RX,
@@ -2036,7 +2078,8 @@
 	int ret;
 	u32	version = socinfo_get_platform_version();
 	if (!cpu_is_apq8064() || (socinfo_get_id() == 130) ||
-		SOCINFO_VERSION_MINOR(version) == 1) {
+		(machine_is_apq8064_mtp() &&
+		(SOCINFO_VERSION_MINOR(version) == 1))) {
 		pr_info("%s: Not APQ8064 in SLIMBUS mode\n", __func__);
 		return -ENODEV;
 	}
diff --git a/sound/soc/msm/mpq8064.c b/sound/soc/msm/mpq8064.c
index 333f73e..499e4b6 100644
--- a/sound/soc/msm/mpq8064.c
+++ b/sound/soc/msm/mpq8064.c
@@ -54,7 +54,7 @@
 #define GPIO_SEC_I2S_RX_WS   48
 #define GPIO_SEC_I2S_RX_DOUT 49
 #define GPIO_SEC_I2S_RX_MCLK 50
-#define I2S_MCLK_RATE 1536000
+#define I2S_MCLK_RATE 12288000
 
 #define GPIO_MI2S_WS     27
 #define GPIO_MI2S_SCLK   28
@@ -813,14 +813,11 @@
 static int msm_be_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
 			struct snd_pcm_hw_params *params)
 {
-	struct snd_interval *rate = hw_param_interval(params,
-					SNDRV_PCM_HW_PARAM_RATE);
 
 	struct snd_interval *channels = hw_param_interval(params,
 					SNDRV_PCM_HW_PARAM_CHANNELS);
 
 	pr_debug("%s()\n", __func__);
-	rate->min = rate->max = 48000;
 	channels->min =  channels->max = 2;
 
 	return 0;
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index b76160e..78b3abc 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -354,13 +354,14 @@
 
 	switch (compr->info.codec_param.codec.id) {
 	case SND_AUDIOCODEC_MP3:
+		pr_debug("%s: SND_AUDIOCODEC_MP3\n", __func__);
 		ret = q6asm_media_format_block(prtd->audio_client,
 				compr->codec);
 		if (ret < 0)
 			pr_info("%s: CMD Format block failed\n", __func__);
 		break;
 	case SND_AUDIOCODEC_AAC:
-		pr_debug("SND_AUDIOCODEC_AAC\n");
+		pr_debug("%s: SND_AUDIOCODEC_AAC\n", __func__);
 		memset(&aac_cfg, 0x0, sizeof(struct asm_aac_cfg));
 		aac_cfg.aot = AAC_ENC_MODE_EAAC_P;
 		aac_cfg.format = 0x03;
@@ -578,7 +579,9 @@
 		pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 			if (compr->info.codec_param.codec.id ==
-					SND_AUDIOCODEC_AC3_PASS_THROUGH) {
+					SND_AUDIOCODEC_AC3_PASS_THROUGH ||
+					compr->info.codec_param.codec.id ==
+					SND_AUDIOCODEC_DTS_PASS_THROUGH) {
 				msm_pcm_routing_reg_psthr_stream(
 					soc_prtd->dai_link->be_id,
 					prtd->session_id, substream->stream,
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 6456b2a..41f259d 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -74,6 +74,9 @@
 static const DECLARE_TLV_DB_LINEAR(compressed_rx_vol_gain, 0,
 			INT_RX_VOL_MAX_STEPS);
 
+static int msm_route_compressed2_vol_control;
+static const DECLARE_TLV_DB_LINEAR(compressed2_rx_vol_gain, 0,
+			INT_RX_VOL_MAX_STEPS);
 static int msm_route_ec_ref_rx;
 
 /* Equal to Frontend after last of the MULTIMEDIA SESSIONS */
@@ -271,8 +274,10 @@
 	}
 
 	mutex_lock(&routing_lock);
-
-	fe_dai_map[fedai_id][session_type] = dspst_id;
+	if (enable)
+		fe_dai_map[fedai_id][session_type] = dspst_id;
+	else
+		fe_dai_map[fedai_id][session_type] = INVALID_SESSION;
 	for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
 		if (!is_be_dai_extproc(i) &&
 		   (afe_get_port_type(msm_bedais[i].port_id) == port_type) &&
@@ -867,6 +872,22 @@
 	return 0;
 }
 
+static int msm_routing_get_compressed2_vol_mixer(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	ucontrol->value.integer.value[0] = msm_route_compressed2_vol_control;
+	return 0;
+}
+
+static int msm_routing_set_compressed2_vol_mixer(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	if (!compressed_set_volume(ucontrol->value.integer.value[0]))
+		msm_route_compressed2_vol_control =
+			ucontrol->value.integer.value[0];
+	return 0;
+}
+
 static int msm_routing_get_srs_trumedia_control(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
@@ -1431,6 +1452,9 @@
 	SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
 	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("AUX_PCM_TX", MSM_BACKEND_DAI_AUXPCM_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 
@@ -1833,6 +1857,12 @@
 	msm_routing_set_compressed_vol_mixer, compressed_rx_vol_gain),
 };
 
+static const struct snd_kcontrol_new compressed2_vol_mixer_controls[] = {
+	SOC_SINGLE_EXT_TLV("COMPRESSED2 RX Volume", SND_SOC_NOPM, 0,
+	INT_RX_VOL_GAIN, 0, msm_routing_get_compressed2_vol_mixer,
+	msm_routing_set_compressed2_vol_mixer, compressed2_rx_vol_gain),
+};
+
 static const struct snd_kcontrol_new lpa_SRS_trumedia_controls[] = {
 	{.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "SRS TruMedia",
@@ -2359,6 +2389,7 @@
 	{"MultiMedia4 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
 	{"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
 	{"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
+	{"MultiMedia5 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"},
 	{"MultiMedia1 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
 
 	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -2774,6 +2805,9 @@
 	snd_soc_add_platform_controls(platform,
 				compressed_vol_mixer_controls,
 			ARRAY_SIZE(compressed_vol_mixer_controls));
+	snd_soc_add_platform_controls(platform,
+				compressed2_vol_mixer_controls,
+			ARRAY_SIZE(compressed2_vol_mixer_controls));
 
 	snd_soc_add_platform_controls(platform,
 				lpa_SRS_trumedia_controls,
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index 6bd6adc..1338e2f 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -1372,6 +1372,48 @@
 		.ignore_pmdown_time = 1,
 		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA5,
 	},
+	{
+		.name = "MSM8960 Media6",
+		.stream_name = "MultiMedia6",
+		.cpu_dai_name   = "MultiMedia6",
+		.platform_name  = "msm-multi-ch-pcm-dsp",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+					SND_SOC_DPCM_TRIGGER_POST},
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1, /* this dailink has playback support */
+		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA6
+	},
+	{
+		.name = "MSM8960 Compr2",
+		.stream_name = "COMPR2",
+		.cpu_dai_name   = "MultiMedia7",
+		.platform_name  = "msm-compr-dsp",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+					SND_SOC_DPCM_TRIGGER_POST},
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1, /* this dailink has playback support */
+		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA7,
+	},
+	{
+		.name = "MSM8960 Compr3",
+		.stream_name = "COMPR3",
+		.cpu_dai_name   = "MultiMedia8",
+		.platform_name  = "msm-compr-dsp",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+					SND_SOC_DPCM_TRIGGER_POST},
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1, /* this dailink has playback support */
+		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA8,
+	},
 	/* Backend BT/FM DAI Links */
 	{
 		.name = LPASS_BE_INT_BT_SCO_RX,