Merge "msm: camera: Add some error checks" into msm-3.0
diff --git a/Documentation/devicetree/bindings/media/video/msm-vidc.txt b/Documentation/devicetree/bindings/media/video/msm-vidc.txt
new file mode 100644
index 0000000..11af7a9
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/video/msm-vidc.txt
@@ -0,0 +1,15 @@
+* Qualcomm MSM VIDC
+
+Required properties:
+- compatible : one of:
+	- "qcom,msm-vidc"
+- reg : offset and length of the register set for the device.
+- interrupts : should contain the vidc interrupt.
+
+Example:
+
+	qcom,vidc@fdc00000 {
+		compatible = "qcom,msm-vidc";
+		reg = <0xfdc00000 0xff000>;
+		interrupts = <0 44 0>;
+	};
diff --git a/arch/arm/boot/dts/msmcopper-regulator.dtsi b/arch/arm/boot/dts/msmcopper-regulator.dtsi
index 393d48b..48d5720 100644
--- a/arch/arm/boot/dts/msmcopper-regulator.dtsi
+++ b/arch/arm/boot/dts/msmcopper-regulator.dtsi
@@ -358,4 +358,36 @@
 			};
 		};
 	};
+
+	krait0_vreg: regulator@f9088000 {
+		compatible = "qcom,krait-regulator";
+		regulator-name = "krait0";
+		reg = <0xf9088000 0x1000>;
+		regulator-min-microvolt = <500000>;
+		regulator-max-microvolt = <1100000>;
+	};
+
+	krait1_vreg: regulator@f9098000 {
+		compatible = "qcom,krait-regulator";
+		regulator-name = "krait1";
+		reg = <0xf9098000 0x1000>;
+		regulator-min-microvolt = <500000>;
+		regulator-max-microvolt = <1100000>;
+	};
+
+	krait2_vreg: regulator@f90a8000 {
+		compatible = "qcom,krait-regulator";
+		regulator-name = "krait2";
+		reg = <0xf90a8000 0x1000>;
+		regulator-min-microvolt = <500000>;
+		regulator-max-microvolt = <1100000>;
+	};
+
+	krait3_vreg: regulator@f90b8000 {
+		compatible = "qcom,krait-regulator";
+		regulator-name = "krait3";
+		reg = <0xf90b8000 0x1000>;
+		regulator-min-microvolt = <500000>;
+		regulator-max-microvolt = <1100000>;
+	};
 };
diff --git a/arch/arm/boot/dts/msmcopper.dtsi b/arch/arm/boot/dts/msmcopper.dtsi
index db44d13..89a726e 100644
--- a/arch/arm/boot/dts/msmcopper.dtsi
+++ b/arch/arm/boot/dts/msmcopper.dtsi
@@ -44,6 +44,12 @@
 		clock-frequency = <19200000>;
 	};
 
+	qcom,vidc@fdc00000 {
+		compatible = "qcom,msm-vidc";
+		reg = <0xfdc00000 0xff000>;
+		interrupts = <0 44 0>;
+	};
+
 	serial@f991f000 {
 		compatible = "qcom,msm-lsuart-v14";
 		reg = <0xf991f000 0x1000>;
@@ -265,4 +271,8 @@
 
 		qcom,firmware-name = "wcnss";
 	};
+
+	qcom,ocmem@fdd00000 {
+		compatible = "qcom,msm_ocmem";
+	};
 };
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index 64451eb..eb2c2c8 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -44,6 +44,7 @@
 # CONFIG_MSM_HW3D is not set
 CONFIG_MSM_PIL_LPASS_QDSP6V5=y
 CONFIG_MSM_DIRECT_SCLK_ACCESS=y
+CONFIG_MSM_OCMEM=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_SMP=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index c39b301..fb5cff7 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -311,6 +311,7 @@
 CONFIG_MFD_PM8921_CORE=y
 CONFIG_MFD_PM8821_CORE=y
 CONFIG_MFD_PM8038_CORE=y
+CONFIG_MFD_PM8XXX_SPK=y
 CONFIG_MFD_PM8XXX_BATT_ALARM=y
 CONFIG_WCD9304_CODEC=y
 CONFIG_WCD9310_CODEC=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index dedef45..5c01299 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -320,6 +320,7 @@
 CONFIG_MFD_PM8921_CORE=y
 CONFIG_MFD_PM8821_CORE=y
 CONFIG_MFD_PM8038_CORE=y
+CONFIG_MFD_PM8XXX_SPK=y
 CONFIG_MFD_PM8XXX_BATT_ALARM=y
 CONFIG_WCD9304_CODEC=y
 CONFIG_WCD9310_CODEC=y
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index e6b7b79..ac9f465 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -240,6 +240,7 @@
 CONFIG_MMC_EMBEDDED_SDIO=y
 CONFIG_MMC_PARANOID_SD_INIT=y
 CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_CLKGATE=y
 # CONFIG_MMC_BLOCK_BOUNCE is not set
 CONFIG_MMC_TEST=m
 CONFIG_MMC_MSM=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index c294d59..4ecc3a4 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -302,6 +302,18 @@
 	select MULTI_IRQ_HANDLER
 	select ARM_TICKET_LOCKS
 	select MSM_RUN_QUEUE_STATS
+
+config ARCH_MSM9625
+	bool "MSM9625"
+	select ARM_GIC
+	select GIC_SECURE
+	select ARCH_MSM_CORTEX_A5
+	select SMP
+	select MSM_SMP
+	select CPU_V7
+	select MULTI_IRQ_HANDLER
+	select MSM_V2_TLMM
+
 endmenu
 
 choice
@@ -869,6 +881,7 @@
 	default "0x80200000" if ARCH_MSM8930
 	default "0x20200000" if ARCH_MSMCOPPER
 	default "0x10000000" if ARCH_FSM9XXX
+	default "0x20200000" if ARCH_MSM9625
 	default "0x00200000" if !MSM_STACKED_MEMORY
 	default "0x00000000" if ARCH_QSD8X50 && MSM_SOC_REV_A
 	default "0x20000000" if ARCH_QSD8X50
@@ -2224,6 +2237,12 @@
 	  instead of pmem. Selecting this may also involve userspace
 	  dependencies as well.
 
+config MSM_OCMEM
+	bool "MSM On-Chip memory driver (OCMEM)"
+	help
+	  Enable support for On-Chip Memory available on certain MSM chipsets.
+	  OCMEM is a low latency, high performance pool shared by subsystems.
+
 config MSM_RTB
 	bool "Register tracing"
 	help
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 000cf43..d633aa7 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -318,6 +318,7 @@
 ifdef CONFIG_VCM
 obj-$(CONFIG_ARCH_MSM8X60) += board-msm8x60-vcm.o
 endif
+obj-$(CONFIG_MSM_OCMEM) += ocmem.o
 
 obj-$(CONFIG_ARCH_MSM7X27) += gpiomux-7x27.o gpiomux-v1.o gpiomux.o
 obj-$(CONFIG_ARCH_MSM7X30) += gpiomux-7x30.o gpiomux-v1.o gpiomux.o
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index be539d0..ed17cc4 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -427,6 +427,7 @@
 	apq8064_fmem_pdata.size = 0;
 	apq8064_fmem_pdata.reserved_size_low = 0;
 	apq8064_fmem_pdata.reserved_size_high = 0;
+	apq8064_fmem_pdata.align = PAGE_SIZE;
 	fixed_low_size = 0;
 	fixed_middle_size = 0;
 	fixed_high_size = 0;
@@ -2252,6 +2253,11 @@
 	},
 };
 
+static struct platform_device rc_input_loopback_pdev = {
+	.name	= "rc-user-input",
+	.id	= -1,
+};
+
 static struct platform_device *mpq_devices[] __initdata = {
 	&msm_device_sps_apq8064,
 	&mpq8064_device_qup_i2c_gsbi5,
@@ -2268,6 +2274,7 @@
 #ifdef CONFIG_MSM_VCAP
 	&msm8064_device_vcap,
 #endif
+	&rc_input_loopback_pdev,
 };
 
 static struct msm_spi_platform_data apq8064_qup_spi_gsbi5_pdata = {
diff --git a/arch/arm/mach-msm/board-8930-storage.c b/arch/arm/mach-msm/board-8930-storage.c
index ecebfa9..9171749 100644
--- a/arch/arm/mach-msm/board-8930-storage.c
+++ b/arch/arm/mach-msm/board-8930-storage.c
@@ -284,6 +284,10 @@
 #endif
 #ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
 	/* SDC3: External card slot */
+	if (!machine_is_msm8930_cdp()) {
+		msm8960_sdc3_data.wpswitch_gpio = 0;
+		msm8960_sdc3_data.wpswitch_polarity = 0;
+	}
 	msm_add_sdcc(3, &msm8960_sdc3_data);
 #endif
 }
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 28499dd..1c4251c 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -488,6 +488,7 @@
 	msm8930_fmem_pdata.size = 0;
 	msm8930_fmem_pdata.reserved_size_low = 0;
 	msm8930_fmem_pdata.reserved_size_high = 0;
+	msm8930_fmem_pdata.align = PAGE_SIZE;
 	fixed_low_size = 0;
 	fixed_middle_size = 0;
 	fixed_high_size = 0;
diff --git a/arch/arm/mach-msm/board-8960-pmic.c b/arch/arm/mach-msm/board-8960-pmic.c
index c9a5f77..ea1ab58 100644
--- a/arch/arm/mach-msm/board-8960-pmic.c
+++ b/arch/arm/mach-msm/board-8960-pmic.c
@@ -471,7 +471,7 @@
 	{
 		.name		= "led:blue",
 		.flags		= PM8XXX_ID_LED_2,
-		.default_trigger	= "dc-online",
+		.default_trigger	= "notification",
 	},
 };
 
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index a8602d3..da9ce67 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -310,7 +310,7 @@
 		.name = "tabla-slave",
 		.e_addr = {0, 0, 0x60, 0, 0x17, 2},
 	},
-	.irq = 85,
+	.irq = MSM_GPIO_TO_INT(85),
 	.irq_base = TABLA_INTERRUPT_BASE,
 	.num_irqs = NR_WCD9XXX_IRQS,
 	.reset_gpio = 84,
diff --git a/arch/arm/mach-msm/board-copper.c b/arch/arm/mach-msm/board-copper.c
index eff5490..14efac4 100644
--- a/arch/arm/mach-msm/board-copper.c
+++ b/arch/arm/mach-msm/board-copper.c
@@ -409,6 +409,7 @@
  */
 void __init msm_copper_add_drivers(void)
 {
+	msm_smd_init();
 	msm_spm_device_init();
 	regulator_stub_init();
 }
diff --git a/arch/arm/mach-msm/board-msm7627a-io.c b/arch/arm/mach-msm/board-msm7627a-io.c
index 49945d0..bfd9379 100644
--- a/arch/arm/mach-msm/board-msm7627a-io.c
+++ b/arch/arm/mach-msm/board-msm7627a-io.c
@@ -241,7 +241,7 @@
 	/* T6 Object */
 	0, 0, 0, 0, 0, 0,
 	/* T38 Object */
-	16, 0, 0, 0, 0, 0, 0, 0,
+	16, 1, 0, 0, 0, 0, 0, 0,
 	/* T7 Object */
 	32, 16, 50,
 	/* T8 Object */
diff --git a/arch/arm/mach-msm/board-msm7627a-storage.c b/arch/arm/mach-msm/board-msm7627a-storage.c
index 93a430b..43937b8 100644
--- a/arch/arm/mach-msm/board-msm7627a-storage.c
+++ b/arch/arm/mach-msm/board-msm7627a-storage.c
@@ -152,7 +152,6 @@
 {
 	if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()
 					|| machine_is_msm8625_evb()
-					|| machine_is_msm8625_evt()
 					|| machine_is_msm7627a_qrd3()
 					|| machine_is_msm8625_qrd7())
 		gpio_sdc1_hw_det = 42;
@@ -257,7 +256,6 @@
 			if (machine_is_msm7627a_qrd1() ||
 					machine_is_msm7627a_evb() ||
 					machine_is_msm8625_evb()  ||
-					machine_is_msm8625_evt()  ||
 					machine_is_msm7627a_qrd3() ||
 					machine_is_msm8625_qrd7())
 				status = !gpio_get_value(gpio_sdc1_hw_det);
@@ -384,7 +382,14 @@
 	gpio_sdc1_config();
 	if (mmc_regulator_init(1, "mmc", 2850000))
 		return;
-	sdc1_plat_data.status_irq = MSM_GPIO_TO_INT(gpio_sdc1_hw_det);
+#ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
+	/* 8x25 EVT do not use hw detector */
+	if (!(machine_is_msm8625_evt()))
+		sdc1_plat_data.status_irq = MSM_GPIO_TO_INT(gpio_sdc1_hw_det);
+	if (machine_is_msm8625_evt())
+		sdc1_plat_data.status = NULL;
+#endif
+
 	msm_add_sdcc(1, &sdc1_plat_data);
 #endif
 	/* SDIO WLAN slot */
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index df4ca83..803550a 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -883,6 +883,7 @@
 	android_pmem_audio_pdata.size = pmem_audio_size;
 
 	fmem_pdata.size = 0;
+	fmem_pdata.align = PAGE_SIZE;
 
 	/* Find pmem devices that should use FMEM (reusable) memory.
 	 */
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 4860d42..3a0b87e 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -49,6 +49,7 @@
 #define CE3_CORE_CLK_CTL_REG			REG(0x36CC)
 #define CE3_CLK_SRC_NS_REG			REG(0x36C0)
 #define DMA_BAM_HCLK_CTL			REG(0x25C0)
+#define CLK_HALT_AFAB_SFAB_STATEA_REG		REG(0x2FC0)
 #define CLK_HALT_AFAB_SFAB_STATEB_REG		REG(0x2FC4)
 #define CLK_HALT_CFPB_STATEA_REG		REG(0x2FCC)
 #define CLK_HALT_CFPB_STATEB_REG		REG(0x2FD0)
@@ -142,7 +143,9 @@
 #define USB_HSIC_XCVR_FS_CLK_NS_REG		REG(0x2928)
 #define USB_PHY0_RESET_REG			REG(0x2E20)
 #define PCIE_ALT_REF_CLK_NS_REG			REG(0x3860)
+#define PCIE_ACLK_CTL_REG			REG(0x22C0)
 #define PCIE_HCLK_CTL_REG			REG(0x22CC)
+#define PCIE_PCLK_CTL_REG			REG(0x22D0)
 #define GPLL1_MODE_REG				REG(0x3160)
 #define GPLL1_L_VAL_REG				REG(0x3164)
 #define GPLL1_M_VAL_REG				REG(0x3168)
@@ -1952,6 +1955,34 @@
 	},
 };
 
+static struct branch_clk pcie_phy_ref_clk = {
+	.b = {
+		.ctl_reg = PCIE_PCLK_CTL_REG,
+		.en_mask = BIT(4),
+		.halt_reg = CLK_HALT_MSS_SMPSS_MISC_STATE_REG,
+		.halt_bit = 29,
+	},
+	.c = {
+		.dbg_name = "pcie_phy_ref_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(pcie_phy_ref_clk.c),
+	},
+};
+
+static struct branch_clk pcie_a_clk = {
+	.b = {
+		.ctl_reg = PCIE_ACLK_CTL_REG,
+		.en_mask = BIT(4),
+		.halt_reg = CLK_HALT_AFAB_SFAB_STATEA_REG,
+		.halt_bit = 13,
+	},
+	.c = {
+		.dbg_name = "pcie_a_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(pcie_a_clk.c),
+	},
+};
+
 static struct branch_clk dma_bam_p_clk = {
 	.b = {
 		.ctl_reg = DMA_BAM_HCLK_CTL,
@@ -4575,6 +4606,8 @@
 	{ TEST_PER_HS(0x26), &q6sw_clk },
 	{ TEST_PER_HS(0x27), &q6fw_clk },
 	{ TEST_PER_HS(0x2A), &adm0_clk.c },
+	{ TEST_PER_HS(0x2D), &pcie_phy_ref_clk.c },
+	{ TEST_PER_HS(0x32), &pcie_a_clk.c },
 	{ TEST_PER_HS(0x34), &ebi1_clk.c },
 	{ TEST_PER_HS(0x34), &ebi1_a_clk.c },
 	{ TEST_PER_HS(0x50), &usb_hsic_hsic_clk.c },
@@ -4960,6 +4993,8 @@
 	CLK_LOOKUP("iface_clk",		sdc3_p_clk.c,		"msm_sdcc.3"),
 	CLK_LOOKUP("iface_clk",		sdc4_p_clk.c,		"msm_sdcc.4"),
 	CLK_LOOKUP("iface_clk",		pcie_p_clk.c,		""),
+	CLK_LOOKUP("ref_clk",		pcie_phy_ref_clk.c,	""),
+	CLK_LOOKUP("bus_clk",		pcie_a_clk.c,		""),
 	CLK_LOOKUP("core_clk",		adm0_clk.c,		"msm_dmov"),
 	CLK_LOOKUP("iface_clk",		adm0_p_clk.c,		"msm_dmov"),
 	CLK_LOOKUP("iface_clk",		pmic_arb0_p_clk.c,	""),
diff --git a/arch/arm/mach-msm/clock-copper.c b/arch/arm/mach-msm/clock-copper.c
index 7123ffa..03667d7 100644
--- a/arch/arm/mach-msm/clock-copper.c
+++ b/arch/arm/mach-msm/clock-copper.c
@@ -102,6 +102,7 @@
 #define MMSS_DEBUG_CLK_CTL_REG         0x0900
 #define LPASS_DEBUG_CLK_CTL_REG        0x29000
 #define LPASS_LPA_PLL_VOTE_APPS_REG    0x2000
+#define MSS_DEBUG_CLK_CTL_REG          0x0078
 
 #define USB30_MASTER_CMD_RCGR          0x03D4
 #define USB30_MOCK_UTMI_CMD_RCGR       0x03E8
@@ -230,6 +231,7 @@
 #define BLSP2_UART5_BCR           0x0BC0
 #define BLSP2_QUP6_BCR            0x0C00
 #define BLSP2_UART6_BCR           0x0C40
+#define BOOT_ROM_BCR              0x0E00
 #define PDM_BCR                   0x0CC0
 #define PRNG_BCR                  0x0D00
 #define BAM_DMA_BCR               0x0D40
@@ -280,6 +282,8 @@
 #define OXILICX_AXI_CBCR          0x4038
 #define OXILI_BCR                 0x4020
 #define OXILICX_BCR               0x4030
+#define LPASS_Q6SS_BCR            0x6000
+#define MSS_Q6SS_BCR              0x1068
 
 #define OCMEM_SYS_NOC_AXI_CBCR                   0x0244
 #define OCMEM_NOC_CFG_AHB_CBCR                   0x0248
@@ -327,6 +331,7 @@
 #define BLSP1_UART6_APPS_CBCR                    0x0904
 #define BLSP1_UART6_SIM_CBCR                     0x0908
 #define BLSP2_AHB_CBCR                           0x0944
+#define BOOT_ROM_AHB_CBCR                        0x0E04
 #define BLSP2_QUP1_SPI_APPS_CBCR                 0x0984
 #define BLSP2_QUP1_I2C_APPS_CBCR                 0x0988
 #define BLSP2_UART1_APPS_CBCR                    0x09C4
@@ -469,6 +474,11 @@
 #define MMSS_MISC_AHB_CBCR                       0x502C
 #define MMSS_S0_AXI_CBCR                         0x5064
 #define OCMEMNOC_CBCR                            0x50B4
+#define LPASS_Q6SS_AHB_LFABIF_CBCR               0x22000
+#define LPASS_Q6SS_XO_CBCR                       0x26000
+#define MSS_XO_Q6_CBCR                           0x108C
+#define MSS_BUS_Q6_CBCR                          0x10A4
+#define MSS_CFG_AHB_CBCR                         0x0280
 
 #define APCS_CLOCK_BRANCH_ENA_VOTE 0x1484
 #define APCS_CLOCK_SLEEP_ENA_VOTE  0x1488
@@ -1625,6 +1635,19 @@
 	},
 };
 
+static struct local_vote_clk gcc_boot_rom_ahb_clk = {
+	.cbcr_reg = BOOT_ROM_AHB_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(10),
+	.bcr_reg = BOOT_ROM_BCR,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_boot_rom_ahb_clk",
+		.ops = &clk_ops_vote,
+		CLK_INIT(gcc_boot_rom_ahb_clk.c),
+	},
+};
+
 static struct local_vote_clk gcc_blsp2_ahb_clk = {
 	.cbcr_reg = BLSP2_AHB_CBCR,
 	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
@@ -2225,6 +2248,17 @@
 	},
 };
 
+static struct branch_clk gcc_mss_cfg_ahb_clk = {
+	.cbcr_reg = MSS_CFG_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_mss_cfg_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_mss_cfg_ahb_clk.c),
+	},
+};
+
 static struct clk_freq_tbl ftbl_mmss_ahb_clk[] = {
 	F_MM(19200000,    cxo,   1,   0,   0),
 	F_MM(40000000,  gpll0,  15,   0,   0),
@@ -4291,6 +4325,55 @@
 	},
 };
 
+static struct branch_clk q6ss_ahb_lfabif_clk = {
+	.cbcr_reg = LPASS_Q6SS_AHB_LFABIF_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "q6ss_ahb_lfabif_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(q6ss_ahb_lfabif_clk.c),
+	},
+};
+
+static struct branch_clk q6ss_xo_clk = {
+	.cbcr_reg = LPASS_Q6SS_XO_CBCR,
+	.bcr_reg = LPASS_Q6SS_BCR,
+	.has_sibling = 1,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "q6ss_xo_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(q6ss_xo_clk.c),
+	},
+};
+
+static struct branch_clk mss_xo_q6_clk = {
+	.cbcr_reg = MSS_XO_Q6_CBCR,
+	.bcr_reg = MSS_Q6SS_BCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MSS_BASE],
+	.c = {
+		.dbg_name = "mss_xo_q6_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(mss_xo_q6_clk.c),
+		.depends = &gcc_mss_cfg_ahb_clk.c,
+	},
+};
+
+static struct branch_clk mss_bus_q6_clk = {
+	.cbcr_reg = MSS_BUS_Q6_CBCR,
+	.bcr_reg = MSS_Q6SS_BCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MSS_BASE],
+	.c = {
+		.dbg_name = "mss_bus_q6_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(mss_bus_q6_clk.c),
+		.depends = &gcc_mss_cfg_ahb_clk.c,
+	},
+};
+
 #ifdef CONFIG_DEBUG_FS
 
 struct measure_mux_entry {
@@ -4339,6 +4422,8 @@
 	{&gcc_blsp2_uart4_apps_clk.c,		GCC_BASE, 0x00c2},
 	{&gcc_blsp2_uart5_apps_clk.c,		GCC_BASE, 0x00c6},
 	{&gcc_blsp2_uart6_apps_clk.c,		GCC_BASE, 0x00cb},
+	{&gcc_boot_rom_ahb_clk.c,		GCC_BASE, 0x0100},
+	{&gcc_mss_cfg_ahb_clk.c,		GCC_BASE, 0x0030},
 	{&gcc_ce1_clk.c,			GCC_BASE, 0x0140},
 	{&gcc_ce2_clk.c,			GCC_BASE, 0x0148},
 	{&gcc_pdm2_clk.c,			GCC_BASE, 0x00da},
@@ -4438,6 +4523,11 @@
 	{&audio_core_lpaif_pcm1_clk_src.c,	LPASS_BASE, 0x0012},
 	{&audio_core_slimbus_core_clk.c,	LPASS_BASE, 0x003d},
 	{&audio_core_slimbus_lfabif_clk.c,	LPASS_BASE, 0x003e},
+	{&q6ss_xo_clk.c,			LPASS_BASE, 0x002b},
+	{&q6ss_ahb_lfabif_clk.c,		LPASS_BASE, 0x001e},
+	{&mss_bus_q6_clk.c,			MSS_BASE, 0x003c},
+	{&mss_xo_q6_clk.c,			MSS_BASE, 0x0007},
+
 	{&dummy_clk,				N_BASES,   0x0000},
 };
 
@@ -4465,6 +4555,7 @@
 	clk->sample_ticks = 0x10000;
 	clk->multiplier = 1;
 
+	writel_relaxed(0, MSS_REG_BASE(MSS_DEBUG_CLK_CTL_REG));
 	writel_relaxed(0, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL_REG));
 	writel_relaxed(0, MMSS_REG_BASE(MMSS_DEBUG_CLK_CTL_REG));
 	writel_relaxed(0, GCC_REG_BASE(GCC_DEBUG_CLK_CTL_REG));
@@ -4495,6 +4586,12 @@
 		writel_relaxed(regval, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL_REG));
 		break;
 
+	case MSS_BASE:
+		clk_sel = 0x32;
+		regval = BVAL(5, 0, measure_mux[i].debug_mux);
+		writel_relaxed(regval, MSS_REG_BASE(MSS_DEBUG_CLK_CTL_REG));
+		break;
+
 	default:
 		return -EINVAL;
 	}
@@ -4807,6 +4904,13 @@
 	CLK_LOOKUP("ebit_clk", audio_core_lpaif_pcm1_ebit_clk.c, ""),
 	CLK_LOOKUP("ibit_clk", audio_core_lpaif_pcm1_ibit_clk.c, ""),
 
+	CLK_LOOKUP("core_clk",       mss_xo_q6_clk.c, ""),
+	CLK_LOOKUP("bus_clk",       mss_bus_q6_clk.c, ""),
+	CLK_LOOKUP("core_clk",         q6ss_xo_clk.c, ""),
+	CLK_LOOKUP("bus_clk",  q6ss_ahb_lfabif_clk.c, ""),
+	CLK_LOOKUP("mem_clk", gcc_boot_rom_ahb_clk.c, ""),
+	CLK_LOOKUP("bus_clk",  gcc_mss_cfg_ahb_clk.c, ""),
+
 	/* TODO: Remove dummy clocks as soon as they become unnecessary */
 	CLK_DUMMY("phy_clk",       NULL,    "msm_otg", OFF),
 	CLK_DUMMY("core_clk",      NULL,    "msm_otg", OFF),
@@ -5048,6 +5152,9 @@
 #define LPASS_CC_PHYS	0xFE000000
 #define LPASS_CC_SIZE	SZ_256K
 
+#define MSS_CC_PHYS	0xFC980000
+#define MSS_CC_SIZE	SZ_16K
+
 static void __init msmcopper_clock_pre_init(void)
 {
 	virt_bases[GCC_BASE] = ioremap(GCC_CC_PHYS, GCC_CC_SIZE);
@@ -5062,6 +5169,10 @@
 	if (!virt_bases[LPASS_BASE])
 		panic("clock-copper: Unable to ioremap LPASS_CC memory!");
 
+	virt_bases[MSS_BASE] = ioremap(MSS_CC_PHYS, MSS_CC_SIZE);
+	if (!virt_bases[MSS_BASE])
+		panic("clock-copper: Unable to ioremap MSS_CC memory!");
+
 	clk_ops_local_pll.enable = copper_pll_clk_enable;
 
 	reg_init();
diff --git a/arch/arm/mach-msm/devices-8930.c b/arch/arm/mach-msm/devices-8930.c
index f8cb345..4ad73f9 100644
--- a/arch/arm/mach-msm/devices-8930.c
+++ b/arch/arm/mach-msm/devices-8930.c
@@ -686,6 +686,7 @@
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 	.memtype = ION_CP_MM_HEAP_ID,
 	.enable_ion = 1,
+	.cp_enabled = 1,
 #else
 	.memtype = MEMTYPE_EBI1,
 	.enable_ion = 0,
diff --git a/arch/arm/mach-msm/include/mach/irqs-9625.h b/arch/arm/mach-msm/include/mach/irqs-9625.h
new file mode 100644
index 0000000..91b4d07
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/irqs-9625.h
@@ -0,0 +1,36 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ASM_ARCH_MSM_IRQS_9625_H
+#define __ASM_ARCH_MSM_IRQS_9625_H
+
+/* MSM ACPU Interrupt Numbers */
+
+/*
+ * 0-15:  STI/SGI (software triggered/generated interrupts)
+ * 16-31: PPI (private peripheral interrupts)
+ * 32+:   SPI (shared peripheral interrupts)
+ */
+
+
+#define APCC_QGICL2PERFMONIRPTREQ	(GIC_SPI_START + 1)
+#define SC_SICL2PERFMONIRPTREQ		APCC_QGICL2PERFMONIRPTREQ
+#define TLMM_MSM_SUMMARY_IRQ		(GIC_SPI_START + 16)
+#define SPS_BAM_DMA_IRQ			(GIC_SPI_START + 208)
+
+#define NR_MSM_IRQS 288
+#define NR_GPIO_IRQS 88
+#define NR_BOARD_IRQS 0
+#define NR_TLMM_MSM_DIR_CONN_IRQ 8 /*Need to Verify this Count*/
+#define NR_MSM_GPIOS NR_GPIO_IRQS
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/irqs.h b/arch/arm/mach-msm/include/mach/irqs.h
index e3904b4..bf766f4 100644
--- a/arch/arm/mach-msm/include/mach/irqs.h
+++ b/arch/arm/mach-msm/include/mach/irqs.h
@@ -62,6 +62,8 @@
 #include "irqs-copper.h"
 #elif defined(CONFIG_ARCH_MSM9615)
 #include "irqs-9615.h"
+#elif defined(CONFIG_ARCH_MSM9625)
+#include "irqs-9625.h"
 #elif defined(CONFIG_ARCH_MSM7X30)
 #include "irqs-7x30.h"
 #elif defined(CONFIG_ARCH_QSD8X50)
diff --git a/arch/arm/mach-msm/include/mach/msm_smd.h b/arch/arm/mach-msm/include/mach/msm_smd.h
index 2966509..dc633fb 100644
--- a/arch/arm/mach-msm/include/mach/msm_smd.h
+++ b/arch/arm/mach-msm/include/mach/msm_smd.h
@@ -295,6 +295,14 @@
  *      -EINVAL - NULL parameter or non-packet based channel provided
  */
 int smd_is_pkt_avail(smd_channel_t *ch);
+
+/*
+ * SMD initialization function that registers for a SMD platform driver.
+ *
+ * returns success on successful driver registration.
+ */
+int __init msm_smd_init(void);
+
 #else
 
 static inline int smd_open(const char *name, smd_channel_t **ch, void *priv,
@@ -411,6 +419,11 @@
 {
 	return -ENODEV;
 }
+
+static inline int __init msm_smd_init(void)
+{
+	return 0;
+}
 #endif
 
 #endif
diff --git a/arch/arm/mach-msm/include/mach/ocmem.h b/arch/arm/mach-msm/include/mach/ocmem.h
new file mode 100644
index 0000000..bf7c338
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/ocmem.h
@@ -0,0 +1,109 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _ARCH_ARM_MACH_MSM_OCMEM_H
+#define _ARCH_ARM_MACH_MSM_OCMEM_H
+
+#include <asm/page.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+
+#define OCMEM_MIN_ALLOC SZ_64K
+#define OCMEM_MIN_ALIGN SZ_64K
+
+/* Maximum number of slots in DM */
+#define OCMEM_MAX_CHUNKS 32
+#define MIN_CHUNK_SIZE (SZ_1K/8)
+
+struct ocmem_buf {
+	unsigned long addr;
+	unsigned long len;
+};
+
+struct ocmem_buf_attr {
+	unsigned long paddr;
+	unsigned long len;
+};
+
+struct ocmem_chunk {
+	bool ro;
+	unsigned long ddr_paddr;
+	unsigned long size;
+};
+
+struct ocmem_map_list {
+	int num_chunks;
+	struct ocmem_chunk chunks[OCMEM_MAX_CHUNKS];
+};
+
+/* List of clients that allocate/interact with OCMEM */
+/* Must be in sync with client_names */
+enum ocmem_client {
+	/* GMEM clients */
+	OCMEM_GRAPHICS = 0x0,
+	/* TCMEM clients */
+	OCMEM_VIDEO,
+	OCMEM_CAMERA,
+	/* Dummy Clients */
+	OCMEM_HP_AUDIO,
+	OCMEM_VOICE,
+	/* IMEM Clients */
+	OCMEM_LP_AUDIO,
+	OCMEM_SENSORS,
+	OCMEM_BLAST,
+	OCMEM_CLIENT_MAX,
+};
+
+/**
+ * List of OCMEM notification events which will be broadcasted
+ * to clients that optionally register for these notifications
+ * on a per allocation basis.
+ **/
+enum ocmem_notif_type {
+	OCMEM_MAP_DONE = 1,
+	OCMEM_MAP_FAIL,
+	OCMEM_UNMAP_DONE,
+	OCMEM_UNMAP_FAIL,
+	OCMEM_ALLOC_GROW,
+	OCMEM_ALLOC_SHRINK,
+	OCMEM_NOTIF_TYPE_COUNT,
+};
+
+/* APIS */
+/* Notification APIs */
+void *ocmem_notifier_register(int client_id, struct notifier_block *nb);
+
+int ocmem_notifier_unregister(void *notif_hndl, struct notifier_block *nb);
+
+/* Allocation APIs */
+struct ocmem_buf *ocmem_allocate(int client_id, unsigned long size);
+
+struct ocmem_buf *ocmem_allocate_nb(int client_id, unsigned long size);
+
+struct ocmem_buf *ocmem_allocate_range(int client_id, unsigned long min,
+			unsigned long goal, unsigned long step);
+
+/* Free APIs */
+int ocmem_free(int client_id, struct ocmem_buf *buf);
+
+/* Dynamic Resize APIs */
+int ocmem_shrink(int client_id, struct ocmem_buf *buf,
+			unsigned long new_size);
+
+int ocmem_expand(int client_id, struct ocmem_buf *buf,
+			unsigned long new_size);
+
+/* Priority Enforcement APIs */
+int ocmem_evict(int client_id);
+
+int ocmem_restore(int client_id);
+#endif
diff --git a/arch/arm/mach-msm/include/mach/ocmem_priv.h b/arch/arm/mach-msm/include/mach/ocmem_priv.h
new file mode 100644
index 0000000..32d46b4
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/ocmem_priv.h
@@ -0,0 +1,77 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _ARCH_ARM_MACH_MSM_OCMEM_CORE_H
+#define _ARCH_ARM_MACH_MSM_OCMEM_CORE_H
+
+/** All interfaces in this header should only be used by OCMEM driver
+ *  Client drivers should use wrappers available in ocmem.h
+ **/
+
+#include "ocmem.h"
+#include <mach/msm_iomap.h>
+#include <asm/io.h>
+
+#define OCMEM_PHYS_BASE 0xFEC00000
+#define OCMEM_PHYS_SIZE 0x180000
+
+struct ocmem_zone;
+
+struct ocmem_zone_ops {
+	unsigned long (*allocate) (struct ocmem_zone *, unsigned long);
+	int (*free) (struct ocmem_zone *, unsigned long, unsigned long);
+};
+
+struct ocmem_zone {
+	int owner;
+	int active_regions;
+	int max_regions;
+	struct list_head region_list;
+	unsigned long z_start;
+	unsigned long z_end;
+	unsigned long z_head;
+	unsigned long z_tail;
+	unsigned long z_free;
+	struct gen_pool *z_pool;
+	struct ocmem_zone_ops *z_ops;
+};
+
+struct ocmem_req {
+	struct rw_semaphore rw_sem;
+	/* Chain in sched queue */
+	struct list_head sched_list;
+	/* Chain in zone list */
+	struct list_head zone_list;
+	int owner;
+	int prio;
+	uint32_t req_id;
+	unsigned long req_min;
+	unsigned long req_max;
+	unsigned long req_step;
+	/* reverse pointers */
+	struct ocmem_zone *zone;
+	struct ocmem_buf *buffer;
+	unsigned long state;
+	/* Request assignments */
+	unsigned long req_start;
+	unsigned long req_end;
+	unsigned long req_sz;
+};
+
+struct ocmem_handle {
+	struct ocmem_buf buffer;
+	struct mutex handle_mutex;
+	struct ocmem_req *req;
+};
+
+struct ocmem_zone *get_zone(unsigned);
+#endif
diff --git a/arch/arm/mach-msm/iommu.c b/arch/arm/mach-msm/iommu.c
index 0652f3b..49a3e6f 100644
--- a/arch/arm/mach-msm/iommu.c
+++ b/arch/arm/mach-msm/iommu.c
@@ -49,9 +49,11 @@
 #define MSM_IOMMU_ATTR_CACHED_WT	0x3
 
 
-static inline void clean_pte(unsigned long *start, unsigned long *end)
+static inline void clean_pte(unsigned long *start, unsigned long *end,
+			     int redirect)
 {
-	dmac_flush_range(start, end);
+	if (!redirect)
+		dmac_flush_range(start, end);
 }
 
 static int msm_iommu_tex_class[4];
@@ -292,6 +294,9 @@
 
 	memset(priv->pgtable, 0, SZ_16K);
 	domain->priv = priv;
+
+	clean_pte(priv->pgtable, priv->pgtable + NUM_FL_PTE, priv->redirect);
+
 	return 0;
 
 fail_nomem:
@@ -518,8 +523,7 @@
 		for (i = 0; i < 16; i++)
 			*(fl_pte+i) = (pa & 0xFF000000) | FL_SUPERSECTION
 				  | FL_TYPE_SECT | FL_SHARED | FL_NG | pgprot;
-		if (!priv->redirect)
-			clean_pte(fl_pte, fl_pte + 16);
+		clean_pte(fl_pte, fl_pte + 16, priv->redirect);
 	}
 
 	if (len == SZ_1M) {
@@ -530,8 +534,7 @@
 
 		*fl_pte = (pa & 0xFFF00000) | FL_NG | FL_TYPE_SECT | FL_SHARED
 					    | pgprot;
-		if (!priv->redirect)
-			clean_pte(fl_pte, fl_pte + 1);
+		clean_pte(fl_pte, fl_pte + 1, priv->redirect);
 	}
 
 	/* Need a 2nd level table */
@@ -548,12 +551,12 @@
 				goto fail;
 			}
 			memset(sl, 0, SZ_4K);
+			clean_pte(sl, sl + NUM_SL_PTE, priv->redirect);
 
 			*fl_pte = ((((int)__pa(sl)) & FL_BASE_MASK) | \
 						      FL_TYPE_TABLE);
 
-			if (!priv->redirect)
-				clean_pte(fl_pte, fl_pte + 1);
+			clean_pte(fl_pte, fl_pte + 1, priv->redirect);
 		}
 
 		if (!(*fl_pte & FL_TYPE_TABLE)) {
@@ -574,8 +577,7 @@
 
 		*sl_pte = (pa & SL_BASE_MASK_SMALL) | SL_NG | SL_SHARED
 						    | SL_TYPE_SMALL | pgprot;
-		if (!priv->redirect)
-			clean_pte(sl_pte, sl_pte + 1);
+		clean_pte(sl_pte, sl_pte + 1, priv->redirect);
 	}
 
 	if (len == SZ_64K) {
@@ -591,8 +593,7 @@
 			*(sl_pte+i) = (pa & SL_BASE_MASK_LARGE) | SL_NG
 					  | SL_SHARED | SL_TYPE_LARGE | pgprot;
 
-		if (!priv->redirect)
-			clean_pte(sl_pte, sl_pte + 16);
+		clean_pte(sl_pte, sl_pte + 16, priv->redirect);
 	}
 
 	ret = __flush_iotlb_va(domain, va);
@@ -652,15 +653,13 @@
 		for (i = 0; i < 16; i++)
 			*(fl_pte+i) = 0;
 
-		if (!priv->redirect)
-			clean_pte(fl_pte, fl_pte + 16);
+		clean_pte(fl_pte, fl_pte + 16, priv->redirect);
 	}
 
 	if (len == SZ_1M) {
 		*fl_pte = 0;
 
-		if (!priv->redirect)
-			clean_pte(fl_pte, fl_pte + 1);
+		clean_pte(fl_pte, fl_pte + 1, priv->redirect);
 	}
 
 	sl_table = (unsigned long *) __va(((*fl_pte) & FL_BASE_MASK));
@@ -671,15 +670,13 @@
 		for (i = 0; i < 16; i++)
 			*(sl_pte+i) = 0;
 
-		if (!priv->redirect)
-			clean_pte(sl_pte, sl_pte + 16);
+		clean_pte(sl_pte, sl_pte + 16, priv->redirect);
 	}
 
 	if (len == SZ_4K) {
 		*sl_pte = 0;
 
-		if (!priv->redirect)
-			clean_pte(sl_pte, sl_pte + 1);
+		clean_pte(sl_pte, sl_pte + 1, priv->redirect);
 	}
 
 	if (len == SZ_4K || len == SZ_64K) {
@@ -692,8 +689,7 @@
 			free_page((unsigned long)sl_table);
 			*fl_pte = 0;
 
-			if (!priv->redirect)
-				clean_pte(fl_pte, fl_pte + 1);
+			clean_pte(fl_pte, fl_pte + 1, priv->redirect);
 		}
 	}
 
@@ -773,10 +769,12 @@
 			}
 
 			memset(sl_table, 0, SZ_4K);
+			clean_pte(sl_table, sl_table + NUM_SL_PTE,
+				  priv->redirect);
+
 			*fl_pte = ((((int)__pa(sl_table)) & FL_BASE_MASK) |
 							    FL_TYPE_TABLE);
-			if (!priv->redirect)
-				clean_pte(fl_pte, fl_pte + 1);
+			clean_pte(fl_pte, fl_pte + 1, priv->redirect);
 		} else
 			sl_table = (unsigned long *)
 					       __va(((*fl_pte) & FL_BASE_MASK));
@@ -809,8 +807,8 @@
 			}
 		}
 
-		if (!priv->redirect)
-			clean_pte(sl_table + sl_start, sl_table + sl_offset);
+		clean_pte(sl_table + sl_start, sl_table + sl_offset,
+			  priv->redirect);
 
 		fl_pte++;
 		sl_offset = 0;
@@ -854,8 +852,8 @@
 			sl_end = NUM_SL_PTE;
 
 		memset(sl_table + sl_start, 0, (sl_end - sl_start) * 4);
-		if (!priv->redirect)
-			clean_pte(sl_table + sl_start, sl_table + sl_end);
+		clean_pte(sl_table + sl_start, sl_table + sl_end,
+			  priv->redirect);
 
 		offset += (sl_end - sl_start) * SZ_4K;
 
@@ -879,8 +877,7 @@
 			free_page((unsigned long)sl_table);
 			*fl_pte = 0;
 
-			if (!priv->redirect)
-				clean_pte(fl_pte, fl_pte + 1);
+			clean_pte(fl_pte, fl_pte + 1, priv->redirect);
 		}
 
 		sl_start = 0;
diff --git a/arch/arm/mach-msm/ipc_socket.c b/arch/arm/mach-msm/ipc_socket.c
index 6e8c99e..085b87a 100644
--- a/arch/arm/mach-msm/ipc_socket.c
+++ b/arch/arm/mach-msm/ipc_socket.c
@@ -21,6 +21,10 @@
 #include <linux/gfp.h>
 #include <linux/msm_ipc.h>
 
+#ifdef CONFIG_ANDROID_PARANOID_NETWORK
+#include <linux/android_aid.h>
+#endif
+
 #include <asm/string.h>
 #include <asm/atomic.h>
 
@@ -39,6 +43,21 @@
 static struct proto msm_ipc_proto;
 static const struct proto_ops msm_ipc_proto_ops;
 
+#ifdef CONFIG_ANDROID_PARANOID_NETWORK
+static inline int check_permissions(void)
+{
+	int rc = 0;
+	if (!current_euid() || in_egroup_p(AID_NET_RAW))
+		rc = 1;
+	return rc;
+}
+# else
+static inline int check_permissions(void)
+{
+	return 1;
+}
+#endif
+
 static void msm_ipc_router_unload_modem(void *pil)
 {
 	if (pil)
@@ -214,6 +233,11 @@
 	struct msm_ipc_port *port_ptr;
 	void *pil;
 
+	if (!check_permissions()) {
+		pr_err("%s: Do not have permissions\n", __func__);
+		return -EPERM;
+	}
+
 	if (unlikely(protocol != 0)) {
 		pr_err("%s: Protocol not supported\n", __func__);
 		return -EPROTONOSUPPORT;
diff --git a/arch/arm/mach-msm/lpass-8960.c b/arch/arm/mach-msm/lpass-8960.c
index 7775740..c58b0e1 100644
--- a/arch/arm/mach-msm/lpass-8960.c
+++ b/arch/arm/mach-msm/lpass-8960.c
@@ -31,6 +31,7 @@
 
 #define SCM_Q6_NMI_CMD                  0x1
 #define MODULE_NAME			"lpass_8960"
+#define MAX_BUF_SIZE			0x51
 
 /* Subsystem restart: QDSP6 data, functions */
 static void lpass_fatal_fn(struct work_struct *);
@@ -86,10 +87,39 @@
 	.notifier_call = modem_notifier_cb,
 };
 
+static void lpass_log_failure_reason(void)
+{
+	char *reason;
+	char buffer[MAX_BUF_SIZE];
+	unsigned size;
+
+	reason = smem_get_entry(SMEM_SSR_REASON_LPASS0, &size);
+
+	if (!reason) {
+		pr_err("%s: subsystem failure reason: (unknown, smem_get_entry failed).",
+			 MODULE_NAME);
+		return;
+	}
+
+	if (reason[0] == '\0') {
+		pr_err("%s: subsystem failure reason: (unknown, init value found)",
+			 MODULE_NAME);
+		return;
+	}
+
+	size = size < MAX_BUF_SIZE ? size : (MAX_BUF_SIZE-1);
+	memcpy(buffer, reason, size);
+	buffer[size] = '\0';
+	pr_err("%s: subsystem failure reason: %s", MODULE_NAME, buffer);
+	memset((void *)reason, 0x0, size);
+	wmb();
+}
+
 static void lpass_fatal_fn(struct work_struct *work)
 {
 	pr_err("%s %s: Watchdog bite received from Q6!\n", MODULE_NAME,
 		__func__);
+	lpass_log_failure_reason();
 	panic(MODULE_NAME ": Resetting the SoC");
 }
 
@@ -104,6 +134,7 @@
 		pr_err("%s: LPASS SMSM state changed to SMSM_RESET,"
 			" new_state = 0x%x, old_state = 0x%x\n", __func__,
 			new_state, old_state);
+		lpass_log_failure_reason();
 		panic(MODULE_NAME ": Resetting the SoC");
 	}
 }
diff --git a/arch/arm/mach-msm/msm_cache_dump.c b/arch/arm/mach-msm/msm_cache_dump.c
index 404c8f0..b21412f 100644
--- a/arch/arm/mach-msm/msm_cache_dump.c
+++ b/arch/arm/mach-msm/msm_cache_dump.c
@@ -26,7 +26,7 @@
 #include <mach/memory.h>
 #include <mach/msm_iomap.h>
 
-#define L2C_IMEM_ADDR 0x2a03f014
+#define L2_DUMP_OFFSET 0x14
 
 static unsigned long msm_cache_dump_addr;
 
@@ -43,6 +43,11 @@
 				unsigned long event, void *ptr)
 {
 #ifdef CONFIG_MSM_CACHE_DUMP_ON_PANIC
+	/*
+	 * Clear the bootloader magic so the dumps aren't overwritten
+	 */
+	__raw_writel(0, MSM_IMEM_BASE + L2_DUMP_OFFSET);
+
 	scm_call_atomic1(L1C_SERVICE_ID, CACHE_BUFFER_DUMP_COMMAND_ID, 2);
 	scm_call_atomic1(L1C_SERVICE_ID, CACHE_BUFFER_DUMP_COMMAND_ID, 1);
 #endif
@@ -66,9 +71,6 @@
 		unsigned long buf;
 		unsigned long size;
 	} l1_cache_data;
-#ifndef CONFIG_MSM_CACHE_DUMP_ON_PANIC
-	unsigned int *imem_loc;
-#endif
 	void *temp;
 	unsigned long total_size = d->l1_size + d->l2_size;
 
@@ -104,11 +106,9 @@
 	if (ret)
 		pr_err("%s: could not register L2 buffer ret = %d.\n",
 			__func__, ret);
-#else
-	imem_loc = ioremap(L2C_IMEM_ADDR, SZ_4K);
-	__raw_writel(msm_cache_dump_addr + d->l1_size, imem_loc);
-	iounmap(imem_loc);
 #endif
+	__raw_writel(msm_cache_dump_addr + d->l1_size,
+			MSM_IMEM_BASE + L2_DUMP_OFFSET);
 
 	atomic_notifier_chain_register(&panic_notifier_list,
 						&msm_cache_dump_blk);
diff --git a/arch/arm/mach-msm/ocmem.c b/arch/arm/mach-msm/ocmem.c
new file mode 100644
index 0000000..af39dc3
--- /dev/null
+++ b/arch/arm/mach-msm/ocmem.c
@@ -0,0 +1,304 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <mach/ocmem_priv.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/rbtree.h>
+#include <linux/genalloc.h>
+#include <linux/of.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+struct ocmem_partition {
+	const char *name;
+	int id;
+	unsigned long p_start;
+	unsigned long p_size;
+	unsigned long p_min;
+};
+
+struct ocmem_plat_data {
+	void __iomem *vbase;
+	unsigned long size;
+	unsigned long base;
+	struct ocmem_partition *parts;
+	int nr_parts;
+};
+
+struct ocmem_zone zones[OCMEM_CLIENT_MAX];
+
+struct ocmem_zone *get_zone(unsigned id)
+{
+	if (id < OCMEM_GRAPHICS || id >= OCMEM_CLIENT_MAX)
+		return NULL;
+	else
+		return &zones[id];
+}
+
+static struct ocmem_plat_data *ocmem_pdata;
+
+#define CLIENT_NAME_MAX 10
+/* Must be in sync with enum ocmem_client */
+static const char *client_names[OCMEM_CLIENT_MAX] = {
+	"graphics",
+	"video",
+	"camera",
+	"hp_audio",
+	"voice",
+	"lp_audio",
+	"sensors",
+	"blast",
+};
+
+struct ocmem_quota_table {
+	const char *name;
+	int id;
+	unsigned long start;
+	unsigned long size;
+	unsigned long min;
+};
+
+/* This static table will go away with device tree support */
+static struct ocmem_quota_table qt[OCMEM_CLIENT_MAX] = {
+	/* name,	id,	start,	size,	min */
+	{ "graphics", OCMEM_GRAPHICS, 0x0, 0x100000, 0x80000},
+	{ "video", OCMEM_VIDEO, 0x100000, 0x80000, 0x55000},
+	{ "camera", OCMEM_CAMERA, 0x0, 0x0, 0x0},
+	{ "voice", OCMEM_VOICE,  0x0, 0x0, 0x0 },
+	{ "hp_audio", OCMEM_HP_AUDIO, 0x0, 0x0, 0x0},
+	{ "lp_audio", OCMEM_LP_AUDIO, 0x80000, 0xA0000, 0xA0000},
+	{ "blast", OCMEM_BLAST, 0x120000, 0x20000, 0x20000},
+	{ "sensors", OCMEM_SENSORS, 0x140000, 0x40000, 0x40000},
+};
+
+static inline int get_id(const char *name)
+{
+	int i = 0;
+	for (i = 0 ; i < OCMEM_CLIENT_MAX; i++) {
+		if (strncmp(name, client_names[i], CLIENT_NAME_MAX) == 0)
+			return i;
+	}
+	return -EINVAL;
+}
+
+static struct ocmem_plat_data *parse_static_config(struct platform_device *pdev)
+{
+	struct ocmem_plat_data *pdata = NULL;
+	struct ocmem_partition *parts = NULL;
+	struct device   *dev = &pdev->dev;
+	int nr_parts;
+	int i;
+	int j;
+
+	pdata = devm_kzalloc(dev, sizeof(struct ocmem_plat_data),
+			GFP_KERNEL);
+
+	if (!pdata) {
+		dev_err(dev, "Unable to allocate memory for"
+			" platform data\n");
+		return NULL;
+	}
+
+	for (i = 0 ; i < ARRAY_SIZE(qt); i++)
+		if (qt[i].size != 0x0)
+			nr_parts++;
+
+	if (nr_parts == 0x0) {
+		dev_err(dev, "No valid ocmem partitions\n");
+		return NULL;
+	} else
+		dev_info(dev, "Total partitions = %d\n", nr_parts);
+
+	parts = devm_kzalloc(dev, sizeof(struct ocmem_partition) * nr_parts,
+				 GFP_KERNEL);
+
+	if (!parts) {
+		dev_err(dev, "Unable to allocate memory for"
+			" partition data\n");
+		return NULL;
+	}
+
+	for (i = 0, j = 0; i < ARRAY_SIZE(qt); i++) {
+		if (qt[i].size == 0x0) {
+			dev_dbg(dev, "Skipping creation of pool for %s\n",
+						qt[i].name);
+			continue;
+		}
+		parts[j].id = qt[i].id;
+		parts[j].p_size = qt[i].size;
+		parts[j].p_start = qt[i].start;
+		parts[j].p_min = qt[i].min;
+		j++;
+	}
+	BUG_ON(j != nr_parts);
+	pdata->nr_parts = nr_parts;
+	pdata->parts = parts;
+	pdata->base = OCMEM_PHYS_BASE;
+	pdata->size = OCMEM_PHYS_SIZE;
+	return pdata;
+}
+
+static struct ocmem_plat_data *parse_dt_config(struct platform_device *pdev)
+{
+	return NULL;
+}
+
+static int ocmem_zone_init(struct platform_device *pdev)
+{
+
+	int ret = -1;
+	int i = 0;
+	unsigned active_zones = 0;
+
+	struct ocmem_zone *zone = NULL;
+	struct ocmem_zone_ops *z_ops = NULL;
+	struct device   *dev = &pdev->dev;
+	unsigned long start;
+	struct ocmem_plat_data *pdata = NULL;
+
+	pdata = platform_get_drvdata(pdev);
+
+	for (i = 0; i < pdata->nr_parts; i++) {
+		struct ocmem_partition *part = &pdata->parts[i];
+		zone = get_zone(part->id);
+
+		dev_dbg(dev, "Partition %d, start %lx, size %lx for %s\n",
+				i, part->p_start, part->p_size,
+				client_names[part->id]);
+
+		if (part->p_size > pdata->size) {
+			dev_alert(dev, "Quota > ocmem_size for id:%d\n",
+					part->id);
+			continue;
+		}
+
+		zone->z_pool = gen_pool_create(PAGE_SHIFT, -1);
+
+		if (!zone->z_pool) {
+			dev_alert(dev, "Creating pool failed for id:%d\n",
+					part->id);
+			return -EBUSY;
+		}
+
+		start = pdata->base + part->p_start;
+		ret = gen_pool_add(zone->z_pool, start,
+					part->p_size, -1);
+
+		if (ret < 0) {
+			gen_pool_destroy(zone->z_pool);
+			dev_alert(dev, "Unable to back pool %d with "
+				"buffer:%lx\n", part->id, part->p_size);
+			return -EBUSY;
+		}
+
+		/* Initialize zone allocators */
+		z_ops = devm_kzalloc(dev, sizeof(struct ocmem_zone_ops),
+				GFP_KERNEL);
+		if (!z_ops) {
+			pr_alert("ocmem: Unable to allocate memory for"
+					"zone ops:%d\n", i);
+			return -EBUSY;
+		}
+
+		/* Initialize zone parameters */
+		zone->z_start = start;
+		zone->z_head = zone->z_start;
+		zone->z_end = start + part->p_size;
+		zone->z_tail = zone->z_end;
+		zone->z_free = part->p_size;
+		zone->owner = part->id;
+		zone->active_regions = 0;
+		zone->max_regions = 0;
+		INIT_LIST_HEAD(&zone->region_list);
+		zone->z_ops = z_ops;
+		active_zones++;
+
+		if (active_zones == 1)
+			pr_info("Physical OCMEM zone layout:\n");
+
+		pr_info(" zone %s\t: 0x%08lx - 0x%08lx (%4ld KB)\n",
+				client_names[part->id], zone->z_start,
+				zone->z_end, part->p_size/SZ_1K);
+	}
+
+	dev_info(dev, "Total active zones = %d\n", active_zones);
+	return 0;
+}
+
+static int __devinit msm_ocmem_probe(struct platform_device *pdev)
+{
+	struct device   *dev = &pdev->dev;
+
+	if (!pdev->dev.of_node->child) {
+		dev_info(dev, "Missing Configuration in Device Tree\n");
+		ocmem_pdata = parse_static_config(pdev);
+	} else {
+		ocmem_pdata = parse_dt_config(pdev);
+	}
+
+	/* Check if we have some configuration data to start */
+	if (!ocmem_pdata)
+		return -ENODEV;
+
+	/* Sanity Checks */
+	BUG_ON(!IS_ALIGNED(ocmem_pdata->size, PAGE_SIZE));
+	BUG_ON(!IS_ALIGNED(ocmem_pdata->base, PAGE_SIZE));
+
+	platform_set_drvdata(pdev, ocmem_pdata);
+
+	if (ocmem_zone_init(pdev))
+		return -EBUSY;
+
+	dev_info(dev, "initialized successfully\n");
+	return 0;
+}
+
+static int __devexit msm_ocmem_remove(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static struct of_device_id msm_ocmem_dt_match[] = {
+	{       .compatible = "qcom,msm_ocmem",
+	},
+	{}
+};
+
+static struct platform_driver msm_ocmem_driver = {
+	.probe = msm_ocmem_probe,
+	.remove = __devexit_p(msm_ocmem_remove),
+	.driver = {
+		.name = "msm_ocmem",
+		.owner = THIS_MODULE,
+		.of_match_table = msm_ocmem_dt_match,
+	},
+};
+
+static int __init ocmem_init(void)
+{
+	return platform_driver_register(&msm_ocmem_driver);
+}
+subsys_initcall(ocmem_init);
+
+static void __exit ocmem_exit(void)
+{
+	platform_driver_unregister(&msm_ocmem_driver);
+}
+module_exit(ocmem_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Support for On-Chip Memory on MSM");
diff --git a/arch/arm/mach-msm/qdsp5/audio_lpa.c b/arch/arm/mach-msm/qdsp5/audio_lpa.c
index 8dfba0b..a7c2543 100644
--- a/arch/arm/mach-msm/qdsp5/audio_lpa.c
+++ b/arch/arm/mach-msm/qdsp5/audio_lpa.c
@@ -552,7 +552,9 @@
 	struct audpcm_buffer_node *buf_node;
 	struct list_head *ptr, *next;
 	union msm_audio_event_payload payload;
+	unsigned long flags;
 
+	spin_lock_irqsave(&audio->dsp_lock, flags);
 	MM_DBG("\n"); /* Macro prints the file name and function */
 	list_for_each_safe(ptr, next, &audio->out_queue) {
 		buf_node = list_entry(ptr, struct audpcm_buffer_node, list);
@@ -565,6 +567,7 @@
 	audio->drv_status &= ~ADRV_STATUS_OBUF_GIVEN;
 	audio->out_needed = 0;
 	atomic_set(&audio->out_bytes, 0);
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 }
 static void audio_ioport_reset(struct audio *audio)
 {
diff --git a/arch/arm/mach-msm/qdsp5/audio_mp3.c b/arch/arm/mach-msm/qdsp5/audio_mp3.c
index 5abdf85..7f72e25 100644
--- a/arch/arm/mach-msm/qdsp5/audio_mp3.c
+++ b/arch/arm/mach-msm/qdsp5/audio_mp3.c
@@ -836,7 +836,9 @@
 	struct audmp3_buffer_node *buf_node;
 	struct list_head *ptr, *next;
 	union msm_audio_event_payload payload;
+	unsigned long flags;
 
+	spin_lock_irqsave(&audio->dsp_lock, flags);
 	MM_DBG("\n"); /* Macro prints the file name and function */
 	list_for_each_safe(ptr, next, &audio->out_queue) {
 		buf_node = list_entry(ptr, struct audmp3_buffer_node, list);
@@ -849,6 +851,7 @@
 	audio->drv_status &= ~ADRV_STATUS_OBUF_GIVEN;
 	audio->out_needed = 0;
 	atomic_set(&audio->out_bytes, 0);
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 }
 
 static void audio_flush(struct audio *audio)
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_a2dp_in.c b/arch/arm/mach-msm/qdsp5v2/audio_a2dp_in.c
index 60b5c20..733b7a1 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_a2dp_in.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_a2dp_in.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * sbc/pcm audio input driver
  * Based on the pcm input driver in arch/arm/mach-msm/qdsp5v2/audio_pcm_in.c
@@ -41,7 +41,6 @@
 #include <mach/iommu_domains.h>
 #include <mach/msm_adsp.h>
 #include <mach/msm_memtypes.h>
-#include <mach/msm_subsystem_map.h>
 #include <mach/socinfo.h>
 #include <mach/qdsp5v2/qdsp5audreccmdi.h>
 #include <mach/qdsp5v2/qdsp5audrecmsg.h>
@@ -108,7 +107,7 @@
 	/* data allocated for various buffers */
 	char *data;
 	dma_addr_t phys;
-	struct msm_mapped_buffer *msm_map;
+	void *msm_map;
 
 	int opened;
 	int enabled;
@@ -849,7 +848,7 @@
 	audio->audrec = NULL;
 	audio->opened = 0;
 	if (audio->data) {
-		msm_subsystem_unmap_buffer(audio->msm_map);
+		iounmap(audio->msm_map);
 		free_contiguous_memory_by_paddr(audio->phys);
 		audio->data = NULL;
 	}
@@ -871,9 +870,7 @@
 
 	audio->phys = allocate_contiguous_ebi_nomap(DMASZ, SZ_4K);
 	if (audio->phys) {
-		audio->msm_map = msm_subsystem_map_buffer(
-					audio->phys, DMASZ,
-					MSM_SUBSYSTEM_MAP_KADDR, NULL, 0);
+		audio->msm_map = ioremap(audio->phys, DMASZ);
 		if (IS_ERR(audio->msm_map)) {
 			MM_ERR("could not map the phys address to kernel"
 							"space\n");
@@ -881,7 +878,7 @@
 			free_contiguous_memory_by_paddr(audio->phys);
 			goto done;
 		}
-		audio->data = (u8 *)audio->msm_map->vaddr;
+		audio->data = (u8 *)audio->msm_map;
 	} else {
 		MM_ERR("could not allocate DMA buffers\n");
 		rc = -ENOMEM;
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_aac.c b/arch/arm/mach-msm/qdsp5v2/audio_aac.c
index 9069426..32053bf 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_aac.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_aac.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -38,7 +38,6 @@
 #include <mach/msm_adsp.h>
 #include <mach/iommu.h>
 #include <mach/iommu_domains.h>
-#include <mach/msm_subsystem_map.h>
 #include <mach/qdsp5v2/qdsp5audppmsg.h>
 #include <mach/qdsp5v2/qdsp5audplaycmdi.h>
 #include <mach/qdsp5v2/qdsp5audplaymsg.h>
@@ -142,8 +141,8 @@
 	/* data allocated for various buffers */
 	char *data;
 	int32_t phys; /* physical address of write buffer */
-	struct msm_mapped_buffer *map_v_read;
-	struct msm_mapped_buffer *map_v_write;
+	void *map_v_read;
+	void *map_v_write;
 
 	int mfield; /* meta field embedded in data */
 	int rflush; /* Read  flush */
@@ -1629,9 +1628,9 @@
 	audio->event_abort = 1;
 	wake_up(&audio->event_wait);
 	audaac_reset_event_queue(audio);
-	msm_subsystem_unmap_buffer(audio->map_v_write);
+	iounmap(audio->map_v_write);
 	free_contiguous_memory_by_paddr(audio->phys);
-	msm_subsystem_unmap_buffer(audio->map_v_read);
+	iounmap(audio->map_v_read);
 	free_contiguous_memory_by_paddr(audio->read_phys);
 	mutex_unlock(&audio->lock);
 #ifdef CONFIG_DEBUG_FS
@@ -1821,10 +1820,8 @@
 		audio->phys = allocate_contiguous_ebi_nomap(pmem_sz, SZ_4K);
 		if (audio->phys) {
 			audio->map_v_write =
-					msm_subsystem_map_buffer(audio->phys,
-						pmem_sz,
-						MSM_SUBSYSTEM_MAP_KADDR,
-						NULL, 0);
+					ioremap(audio->phys,
+						pmem_sz);
 			if (IS_ERR(audio->map_v_write)) {
 				MM_ERR("could not map write phys address, \
 						freeing instance 0x%08x\n",
@@ -1835,7 +1832,7 @@
 				kfree(audio);
 				goto done;
 			}
-			audio->data = (u8 *)audio->map_v_write->vaddr;
+			audio->data = (u8 *)audio->map_v_write;
 			MM_DBG("write buf: phy addr 0x%08x kernel addr \
 				0x%08x\n", audio->phys, (int)audio->data);
 			break;
@@ -1857,28 +1854,26 @@
 		MM_ERR("could not allocate read buffers, freeing instance \
 				0x%08x\n", (int)audio);
 		rc = -ENOMEM;
-		msm_subsystem_unmap_buffer(audio->map_v_write);
+		iounmap(audio->map_v_write);
 		free_contiguous_memory_by_paddr(audio->phys);
 		audpp_adec_free(audio->dec_id);
 		kfree(audio);
 		goto done;
 	}
-	audio->map_v_read = msm_subsystem_map_buffer(
-				audio->read_phys,
-				PCM_BUFSZ_MIN * PCM_BUF_MAX_COUNT,
-				MSM_SUBSYSTEM_MAP_KADDR, NULL, 0);
+	audio->map_v_read = ioremap(audio->read_phys,
+				PCM_BUFSZ_MIN * PCM_BUF_MAX_COUNT);
 	if (IS_ERR(audio->map_v_read)) {
 		MM_ERR("could not map read phys address, freeing instance \
 				0x%08x\n", (int)audio);
 		rc = -ENOMEM;
-		msm_subsystem_unmap_buffer(audio->map_v_write);
+		iounmap(audio->map_v_write);
 		free_contiguous_memory_by_paddr(audio->phys);
 		free_contiguous_memory_by_paddr(audio->read_phys);
 		audpp_adec_free(audio->dec_id);
 		kfree(audio);
 		goto done;
 	}
-	audio->read_data = audio->map_v_read->vaddr;
+	audio->read_data = audio->map_v_read;
 	MM_DBG("read buf: phy addr 0x%08x kernel addr 0x%08x\n",
 				audio->read_phys, (int)audio->read_data);
 
@@ -2000,9 +1995,9 @@
 event_err:
 	msm_adsp_put(audio->audplay);
 err:
-	msm_subsystem_unmap_buffer(audio->map_v_write);
+	iounmap(audio->map_v_write);
 	free_contiguous_memory_by_paddr(audio->phys);
-	msm_subsystem_unmap_buffer(audio->map_v_read);
+	iounmap(audio->map_v_read);
 	free_contiguous_memory_by_paddr(audio->read_phys);
 	audpp_adec_free(audio->dec_id);
 	kfree(audio);
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_aac_in.c b/arch/arm/mach-msm/qdsp5v2/audio_aac_in.c
index 010fd90..d2b4407 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_aac_in.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_aac_in.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -32,7 +32,6 @@
 
 #include <mach/msm_adsp.h>
 #include <mach/iommu.h>
-#include <mach/msm_subsystem_map.h>
 #include <mach/iommu_domains.h>
 #include <mach/qdsp5v2/qdsp5audreccmdi.h>
 #include <mach/qdsp5v2/qdsp5audrecmsg.h>
@@ -97,8 +96,8 @@
 	wait_queue_head_t write_wait;
 	int32_t out_phys; /* physical address of write buffer */
 	char *out_data;
-	struct msm_mapped_buffer *map_v_read;
-	struct msm_mapped_buffer *map_v_write;
+	void *map_v_read;
+	void *map_v_write;
 
 	int mfield; /* meta field embedded in data */
 	int wflush; /*write flush */
@@ -1292,12 +1291,12 @@
 	audio->audrec = NULL;
 	audio->opened = 0;
 	if (audio->data) {
-		msm_subsystem_unmap_buffer(audio->map_v_read);
+		iounmap(audio->map_v_read);
 		free_contiguous_memory_by_paddr(audio->phys);
 		audio->data = NULL;
 	}
 	if (audio->out_data) {
-		msm_subsystem_unmap_buffer(audio->map_v_write);
+		iounmap(audio->map_v_write);
 		free_contiguous_memory_by_paddr(audio->out_phys);
 		audio->out_data = NULL;
 	}
@@ -1320,16 +1319,14 @@
 	}
 	audio->phys = allocate_contiguous_ebi_nomap(DMASZ, SZ_4K);
 	if (audio->phys) {
-		audio->map_v_read = msm_subsystem_map_buffer(
-					audio->phys, DMASZ,
-					MSM_SUBSYSTEM_MAP_KADDR, NULL, 0);
+		audio->map_v_read = ioremap(audio->phys, DMASZ);
 		if (IS_ERR(audio->map_v_read)) {
 			MM_ERR("could not map DMA buffers\n");
 			rc = -ENOMEM;
 			free_contiguous_memory_by_paddr(audio->phys);
 			goto done;
 		}
-		audio->data = audio->map_v_read->vaddr;
+		audio->data = audio->map_v_read;
 	} else {
 		MM_ERR("could not allocate DMA buffers\n");
 		rc = -ENOMEM;
@@ -1398,16 +1395,15 @@
 		rc = -ENOMEM;
 		goto evt_error;
 	} else {
-		audio->map_v_write = msm_subsystem_map_buffer(
-					audio->out_phys, BUFFER_SIZE,
-					MSM_SUBSYSTEM_MAP_KADDR, NULL, 0);
+		audio->map_v_write = ioremap(
+					audio->out_phys, BUFFER_SIZE);
 		if (IS_ERR(audio->map_v_write)) {
 			MM_ERR("could not map write phys address\n");
 			rc = -ENOMEM;
 			free_contiguous_memory_by_paddr(audio->out_phys);
 			goto evt_error;
 		}
-		audio->out_data = audio->map_v_write->vaddr;
+		audio->out_data = audio->map_v_write;
 		MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n",
 				audio->out_phys, (int)audio->out_data);
 	}
@@ -1434,7 +1430,7 @@
 					aac_in_listener, (void *) audio);
 	if (rc) {
 		MM_ERR("failed to register device event listener\n");
-		msm_subsystem_unmap_buffer(audio->map_v_write);
+		iounmap(audio->map_v_write);
 		free_contiguous_memory_by_paddr(audio->out_phys);
 		goto evt_error;
 	}
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_acdb.c b/arch/arm/mach-msm/qdsp5v2/audio_acdb.c
index 90373f9..89957a4 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_acdb.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_acdb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -28,7 +28,6 @@
 #include <mach/dal.h>
 #include <mach/iommu.h>
 #include <mach/iommu_domains.h>
-#include <mach/msm_subsystem_map.h>
 #include <mach/qdsp5v2/audio_dev_ctl.h>
 #include <mach/qdsp5v2/audpp.h>
 #include <mach/socinfo.h>
@@ -111,7 +110,7 @@
 	u16 *pbe_enable_flag;
 	u32 fluence_extbuff;
 	u8 *fluence_extbuff_virt;
-	struct msm_mapped_buffer *map_v_fluence;
+	void *map_v_fluence;
 
 	struct acdb_pbe_block *pbe_blk;
 
@@ -130,7 +129,7 @@
 	/* pmem for get acdb blk */
 	unsigned long	get_blk_paddr;
 	u8		*get_blk_kvaddr;
-	struct msm_mapped_buffer *map_v_get_blk;
+	void *map_v_get_blk;
 	char *build_id;
 };
 
@@ -140,7 +139,7 @@
 	u32 node_status;
 	s32 stream_id;
 	u32 phys_addr_acdb_values;
-	struct msm_mapped_buffer *map_v_addr;
+	void *map_v_addr;
 	u8 *virt_addr_acdb_values;
 	struct auddev_evt_audcal_info device_info;
 };
@@ -237,7 +236,7 @@
 struct rtc_acdb_pmem {
 	u8 *viraddr;
 	int32_t phys;
-	struct msm_mapped_buffer *map_v_rtc;
+	void *map_v_rtc;
 };
 
 struct rtc_acdb_data {
@@ -1087,11 +1086,11 @@
 	rtc_acdb.valid_abid = false;
 
 	if (rtc_read->viraddr != NULL || ((void *)rtc_read->phys) != NULL) {
-		msm_subsystem_unmap_buffer(rtc_read->map_v_rtc);
+		iounmap(rtc_read->map_v_rtc);
 		free_contiguous_memory_by_paddr(rtc_read->phys);
 	}
 	if (rtc_write->viraddr != NULL || ((void *)rtc_write->phys) != NULL) {
-		msm_subsystem_unmap_buffer(rtc_write->map_v_rtc);
+		iounmap(rtc_write->map_v_rtc);
 		free_contiguous_memory_by_paddr(rtc_write->phys);
 	}
 }
@@ -1141,17 +1140,15 @@
 		result = -ENOMEM;
 		goto error;
 	}
-	rtc_read->map_v_rtc = msm_subsystem_map_buffer(
-				rtc_read->phys,
-				PMEM_RTC_ACDB_QUERY_MEM,
-				MSM_SUBSYSTEM_MAP_KADDR, NULL, 0);
+	rtc_read->map_v_rtc = ioremap(rtc_read->phys,
+				PMEM_RTC_ACDB_QUERY_MEM);
 
 	if (IS_ERR(rtc_read->map_v_rtc)) {
 		MM_ERR("ACDB Could not map physical address\n");
 		result = -ENOMEM;
 		goto error;
 	}
-	rtc_read->viraddr = rtc_read->map_v_rtc->vaddr;
+	rtc_read->viraddr = rtc_read->map_v_rtc;
 	memset(rtc_read->viraddr, 0, PMEM_RTC_ACDB_QUERY_MEM);
 
 	rtc_write->phys = allocate_contiguous_ebi_nomap(PMEM_RTC_ACDB_QUERY_MEM,
@@ -1162,16 +1159,15 @@
 		result = -ENOMEM;
 		goto error;
 	}
-	rtc_write->map_v_rtc = msm_subsystem_map_buffer(
-				rtc_write->phys, PMEM_RTC_ACDB_QUERY_MEM,
-				MSM_SUBSYSTEM_MAP_KADDR, NULL, 0);
+	rtc_write->map_v_rtc = ioremap(rtc_write->phys,
+				PMEM_RTC_ACDB_QUERY_MEM);
 
 	if (IS_ERR(rtc_write->map_v_rtc)) {
 		MM_ERR("ACDB Could not map physical address\n");
 		result = -ENOMEM;
 		goto error;
 	}
-	rtc_write->viraddr = rtc_write->map_v_rtc->vaddr;
+	rtc_write->viraddr = rtc_write->map_v_rtc;
 	memset(rtc_write->viraddr, 0, PMEM_RTC_ACDB_QUERY_MEM);
 	init_waitqueue_head(&rtc_acdb.wait);
 	return true;
@@ -1187,11 +1183,11 @@
 		debugfs_remove(get_set_abid_data_dentry);
 	}
 	if (rtc_read->viraddr != NULL || ((void *)rtc_read->phys) != NULL) {
-		msm_subsystem_unmap_buffer(rtc_read->map_v_rtc);
+		iounmap(rtc_read->map_v_rtc);
 		free_contiguous_memory_by_paddr(rtc_read->phys);
 	}
 	if (rtc_write->viraddr != NULL || ((void *)rtc_write->phys) != NULL) {
-		msm_subsystem_unmap_buffer(rtc_write->map_v_rtc);
+		iounmap(rtc_write->map_v_rtc);
 		free_contiguous_memory_by_paddr(rtc_write->phys);
 	}
 	return false;
@@ -2544,11 +2540,9 @@
 			result = -ENOMEM;
 			goto error;
 		}
-		acdb_cache_tx[i].map_v_addr =
-					msm_subsystem_map_buffer(
+		acdb_cache_tx[i].map_v_addr = ioremap(
 					acdb_cache_tx[i].phys_addr_acdb_values,
-						ACDB_BUF_SIZE,
-					MSM_SUBSYSTEM_MAP_KADDR, NULL, 0);
+						ACDB_BUF_SIZE);
 		if (IS_ERR(acdb_cache_tx[i].map_v_addr)) {
 			MM_ERR("ACDB=> Could not map physical address\n");
 			result = -ENOMEM;
@@ -2557,15 +2551,14 @@
 			goto error;
 		}
 		acdb_cache_tx[i].virt_addr_acdb_values =
-					acdb_cache_tx[i].map_v_addr->vaddr;
+					acdb_cache_tx[i].map_v_addr;
 		memset(acdb_cache_tx[i].virt_addr_acdb_values, 0,
 						ACDB_BUF_SIZE);
 	}
 	return result;
 error:
 	for (err = 0; err < i; err++) {
-		msm_subsystem_unmap_buffer(
-				acdb_cache_tx[err].map_v_addr);
+		iounmap(acdb_cache_tx[err].map_v_addr);
 		free_contiguous_memory_by_paddr(
 				acdb_cache_tx[err].phys_addr_acdb_values);
 	}
@@ -2590,11 +2583,8 @@
 			goto error;
 		}
 		acdb_cache_rx[i].map_v_addr =
-				msm_subsystem_map_buffer(
-					acdb_cache_rx[i].phys_addr_acdb_values,
-					ACDB_BUF_SIZE,
-					MSM_SUBSYSTEM_MAP_KADDR,
-					NULL, 0);
+				ioremap(acdb_cache_rx[i].phys_addr_acdb_values,
+					ACDB_BUF_SIZE);
 		if (IS_ERR(acdb_cache_rx[i].map_v_addr)) {
 			MM_ERR("ACDB=> Could not map physical address\n");
 			result = -ENOMEM;
@@ -2603,15 +2593,14 @@
 			goto error;
 		}
 		acdb_cache_rx[i].virt_addr_acdb_values =
-					acdb_cache_rx[i].map_v_addr->vaddr;
+					acdb_cache_rx[i].map_v_addr;
 		memset(acdb_cache_rx[i].virt_addr_acdb_values, 0,
 						ACDB_BUF_SIZE);
 	}
 	return result;
 error:
 	for (err = 0; err < i; err++) {
-		msm_subsystem_unmap_buffer(
-					acdb_cache_rx[err].map_v_addr);
+		iounmap(acdb_cache_rx[err].map_v_addr);
 		free_contiguous_memory_by_paddr(
 				acdb_cache_rx[err].phys_addr_acdb_values);
 	}
@@ -2628,10 +2617,8 @@
 		result = -ENOMEM;
 		goto error;
 	}
-	acdb_data.map_v_get_blk = msm_subsystem_map_buffer(
-					acdb_data.get_blk_paddr,
-					ACDB_BUF_SIZE,
-					MSM_SUBSYSTEM_MAP_KADDR, NULL, 0);
+	acdb_data.map_v_get_blk = ioremap(acdb_data.get_blk_paddr,
+					ACDB_BUF_SIZE);
 	if (IS_ERR(acdb_data.map_v_get_blk)) {
 		MM_ERR("ACDB=> Could not map physical address\n");
 		result = -ENOMEM;
@@ -2639,7 +2626,7 @@
 					acdb_data.get_blk_paddr);
 		goto error;
 	}
-	acdb_data.get_blk_kvaddr = acdb_data.map_v_get_blk->vaddr;
+	acdb_data.get_blk_kvaddr = acdb_data.map_v_get_blk;
 	memset(acdb_data.get_blk_kvaddr, 0, ACDB_BUF_SIZE);
 error:
 	return result;
@@ -2650,7 +2637,7 @@
 	u32 i = 0;
 
 	for (i = 0; i < MAX_COPP_NODE_SUPPORTED; i++) {
-		msm_subsystem_unmap_buffer(acdb_cache_rx[i].map_v_addr);
+		iounmap(acdb_cache_rx[i].map_v_addr);
 		free_contiguous_memory_by_paddr(
 				acdb_cache_rx[i].phys_addr_acdb_values);
 	}
@@ -2661,7 +2648,7 @@
 	u32 i = 0;
 
 	for (i = 0; i < MAX_AUDREC_SESSIONS; i++) {
-		msm_subsystem_unmap_buffer(acdb_cache_tx[i].map_v_addr);
+		iounmap(acdb_cache_tx[i].map_v_addr);
 		free_contiguous_memory_by_paddr(
 				acdb_cache_tx[i].phys_addr_acdb_values);
 	}
@@ -2669,7 +2656,7 @@
 
 static void free_memory_acdb_get_blk(void)
 {
-	msm_subsystem_unmap_buffer(acdb_data.map_v_get_blk);
+	iounmap(acdb_data.map_v_get_blk);
 	free_contiguous_memory_by_paddr(acdb_data.get_blk_paddr);
 }
 
@@ -2827,11 +2814,9 @@
 		result = -ENOMEM;
 		goto done;
 	}
-	acdb_data.map_v_fluence =
-			msm_subsystem_map_buffer(
+	acdb_data.map_v_fluence = ioremap(
 				acdb_data.fluence_extbuff,
-				FLUENCE_BUF_SIZE,
-				MSM_SUBSYSTEM_MAP_KADDR, NULL, 0);
+				FLUENCE_BUF_SIZE);
 	if (IS_ERR(acdb_data.map_v_fluence)) {
 		MM_ERR("ACDB=> Could not map physical address\n");
 		free_memory_acdb_get_blk();
@@ -2852,7 +2837,7 @@
 		goto done;
 	} else
 		acdb_data.fluence_extbuff_virt =
-					acdb_data.map_v_fluence->vaddr;
+					acdb_data.map_v_fluence;
 done:
 	return result;
 }
@@ -3431,11 +3416,11 @@
 
 	for (i = 0; i < MAX_COPP_NODE_SUPPORTED; i++) {
 		if (i < MAX_AUDREC_SESSIONS) {
-			msm_subsystem_unmap_buffer(acdb_cache_tx[i].map_v_addr);
+			iounmap(acdb_cache_tx[i].map_v_addr);
 			free_contiguous_memory_by_paddr(
 					acdb_cache_tx[i].phys_addr_acdb_values);
 		}
-		msm_subsystem_unmap_buffer(acdb_cache_rx[i].map_v_addr);
+		iounmap(acdb_cache_rx[i].map_v_addr);
 		free_contiguous_memory_by_paddr(
 					acdb_cache_rx[i].phys_addr_acdb_values);
 	}
@@ -3446,7 +3431,7 @@
 	kfree(acdb_data.preproc_iir);
 	free_contiguous_memory_by_paddr(
 				(int32_t)acdb_data.pbe_extbuff);
-	msm_subsystem_unmap_buffer(acdb_data.map_v_fluence);
+	iounmap(acdb_data.map_v_fluence);
 	free_contiguous_memory_by_paddr(
 			(int32_t)acdb_data.fluence_extbuff);
 	mutex_destroy(&acdb_data.acdb_mutex);
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c b/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c
index 4b8b7a6..a53128d 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c
@@ -43,7 +43,6 @@
 #include <mach/msm_adsp.h>
 #include <mach/iommu.h>
 #include <mach/iommu_domains.h>
-#include <mach/msm_subsystem_map.h>
 #include <mach/qdsp5v2/qdsp5audppmsg.h>
 #include <mach/qdsp5v2/qdsp5audplaycmdi.h>
 #include <mach/qdsp5v2/qdsp5audplaymsg.h>
@@ -139,8 +138,8 @@
 	/* data allocated for various buffers */
 	char *data;
 	int32_t phys; /* physical address of write buffer */
-	struct msm_mapped_buffer *map_v_read;
-	struct msm_mapped_buffer *map_v_write;
+	void *map_v_read;
+	void *map_v_write;
 	int mfield; /* meta field embedded in data */
 	int rflush; /* Read  flush */
 	int wflush; /* Write flush */
@@ -1023,12 +1022,10 @@
 					rc = -ENOMEM;
 					break;
 				}
-				audio->map_v_read = msm_subsystem_map_buffer(
+				audio->map_v_read = ioremap(
 							audio->read_phys,
 							config.buffer_size *
-							config.buffer_count,
-							MSM_SUBSYSTEM_MAP_KADDR
-							, NULL, 0);
+							config.buffer_count);
 				if (IS_ERR(audio->map_v_read)) {
 					MM_ERR("read buf map fail\n");
 					rc = -ENOMEM;
@@ -1038,7 +1035,7 @@
 					uint8_t index;
 					uint32_t offset = 0;
 					audio->read_data =
-						audio->map_v_read->vaddr;
+						audio->map_v_read;
 					audio->buf_refresh = 0;
 					audio->pcm_buf_count =
 					    config.buffer_count;
@@ -1420,10 +1417,10 @@
 	audio->event_abort = 1;
 	wake_up(&audio->event_wait);
 	audadpcm_reset_event_queue(audio);
-	msm_subsystem_unmap_buffer(audio->map_v_write);
+	iounmap(audio->map_v_write);
 	free_contiguous_memory_by_paddr(audio->phys);
 	if (audio->read_data) {
-		msm_subsystem_unmap_buffer(audio->map_v_read);
+		iounmap(audio->map_v_read);
 		free_contiguous_memory_by_paddr(audio->read_phys);
 	}
 	mutex_unlock(&audio->lock);
@@ -1615,10 +1612,7 @@
 		audio->phys = allocate_contiguous_ebi_nomap(pmem_sz,
 									SZ_4K);
 		if (audio->phys) {
-			audio->map_v_write = msm_subsystem_map_buffer(
-						audio->phys, pmem_sz,
-						MSM_SUBSYSTEM_MAP_KADDR,
-						NULL, 0);
+			audio->map_v_write = ioremap(audio->phys, pmem_sz);
 			if (IS_ERR(audio->map_v_write)) {
 				MM_ERR("could not map write phys address, \
 						freeing instance 0x%08x\n",
@@ -1629,7 +1623,7 @@
 				kfree(audio);
 				goto done;
 			}
-			audio->data = audio->map_v_write->vaddr;
+			audio->data = audio->map_v_write;
 			MM_DBG("write buf: phy addr 0x%08x kernel addr \
 				0x%08x\n", audio->phys, (int)audio->data);
 			break;
@@ -1729,7 +1723,7 @@
 event_err:
 	msm_adsp_put(audio->audplay);
 err:
-	msm_subsystem_unmap_buffer(audio->map_v_write);
+	iounmap(audio->map_v_write);
 	free_contiguous_memory_by_paddr(audio->phys);
 	audpp_adec_free(audio->dec_id);
 	kfree(audio);
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c b/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c
index a09b71b..5f288dd 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c
@@ -44,7 +44,6 @@
 #include <mach/msm_adsp.h>
 #include <mach/iommu.h>
 #include <mach/iommu_domains.h>
-#include <mach/msm_subsystem_map.h>
 #include <mach/qdsp5v2/audio_dev_ctl.h>
 #include <mach/qdsp5v2/qdsp5audppmsg.h>
 #include <mach/qdsp5v2/qdsp5audplaycmdi.h>
@@ -132,8 +131,8 @@
 	/* data allocated for various buffers */
 	char *data;
 	int32_t phys; /* physical address of write buffer */
-	struct msm_mapped_buffer *map_v_read;
-	struct msm_mapped_buffer *map_v_write;
+	void *map_v_read;
+	void *map_v_write;
 
 	int mfield; /* meta field embedded in data */
 	int rflush; /* Read  flush */
@@ -993,12 +992,10 @@
 					rc = -ENOMEM;
 					break;
 			}
-			audio->map_v_read = msm_subsystem_map_buffer(
+			audio->map_v_read = ioremap(
 						audio->read_phys,
 						config.buffer_size *
-						config.buffer_count,
-						MSM_SUBSYSTEM_MAP_KADDR,
-						NULL, 0);
+						config.buffer_count);
 			if (IS_ERR(audio->map_v_read)) {
 				MM_ERR("failed to map read phys address\n");
 				rc = -ENOMEM;
@@ -1007,7 +1004,7 @@
 			} else {
 				uint8_t index;
 				uint32_t offset = 0;
-				audio->read_data = audio->map_v_read->vaddr;
+				audio->read_data = audio->map_v_read;
 				audio->buf_refresh = 0;
 				audio->pcm_buf_count =
 					config.buffer_count;
@@ -1317,10 +1314,10 @@
 	audio->event_abort = 1;
 	wake_up(&audio->event_wait);
 	audamrnb_reset_event_queue(audio);
-	msm_subsystem_unmap_buffer(audio->map_v_write);
+	iounmap(audio->map_v_write);
 	free_contiguous_memory_by_paddr(audio->phys);
 	if (audio->read_data) {
-		msm_subsystem_unmap_buffer(audio->map_v_read);
+		iounmap(audio->map_v_read);
 		free_contiguous_memory_by_paddr(audio->read_phys);
 	}
 	mutex_unlock(&audio->lock);
@@ -1512,9 +1509,7 @@
 		kfree(audio);
 		goto done;
 	} else {
-		audio->map_v_write = msm_subsystem_map_buffer(
-					audio->phys, DMASZ,
-					MSM_SUBSYSTEM_MAP_KADDR, NULL, 0);
+		audio->map_v_write = ioremap(audio->phys, DMASZ);
 		if (IS_ERR(audio->map_v_write)) {
 			MM_ERR("could not map write phys address, freeing \
 					instance 0x%08x\n", (int)audio);
@@ -1525,7 +1520,7 @@
 			kfree(audio);
 			goto done;
 		}
-		audio->data = audio->map_v_write->vaddr;
+		audio->data = audio->map_v_write;
 		MM_DBG("write buf: phy addr 0x%08x kernel addr \
 				0x%08x\n", audio->phys, (int)audio->data);
 	}
@@ -1610,7 +1605,7 @@
 event_err:
 	msm_adsp_put(audio->audplay);
 err:
-	msm_subsystem_unmap_buffer(audio->map_v_write);
+	iounmap(audio->map_v_write);
 	free_contiguous_memory_by_paddr(audio->phys);
 	audpp_adec_free(audio->dec_id);
 	kfree(audio);
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_amrnb_in.c b/arch/arm/mach-msm/qdsp5v2/audio_amrnb_in.c
index bdb5bb1..790c510 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_amrnb_in.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_amrnb_in.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -32,7 +32,6 @@
 
 #include <mach/iommu.h>
 #include <mach/iommu_domains.h>
-#include <mach/msm_subsystem_map.h>
 #include <mach/msm_adsp.h>
 #include <mach/socinfo.h>
 #include <mach/qdsp5v2/qdsp5audreccmdi.h>
@@ -99,7 +98,7 @@
 	/* data allocated for various buffers */
 	char *data;
 	dma_addr_t phys;
-	struct msm_mapped_buffer *map_v_read;
+	void *map_v_read;
 
 	int opened;
 	int enabled;
@@ -767,7 +766,7 @@
 	audio->audrec = NULL;
 	audio->opened = 0;
 	if (audio->data) {
-		msm_subsystem_unmap_buffer(audio->map_v_read);
+		iounmap(audio->map_v_read);
 		free_contiguous_memory_by_paddr(audio->phys);
 		audio->data = NULL;
 	}
@@ -788,16 +787,14 @@
 	}
 	audio->phys = allocate_contiguous_ebi_nomap(DMASZ, SZ_4K);
 	if (audio->phys) {
-		audio->map_v_read = msm_subsystem_map_buffer(
-					audio->phys, DMASZ,
-					MSM_SUBSYSTEM_MAP_KADDR, NULL, 0);
+		audio->map_v_read = ioremap(audio->phys, DMASZ);
 		if (IS_ERR(audio->map_v_read)) {
 			MM_ERR("could not map DMA buffers\n");
 			rc = -ENOMEM;
 			free_contiguous_memory_by_paddr(audio->phys);
 			goto done;
 		}
-		audio->data = audio->map_v_read->vaddr;
+		audio->data = audio->map_v_read;
 	} else {
 		MM_ERR("could not allocate DMA buffers\n");
 		rc = -ENOMEM;
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c b/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c
index 48e9a9f..b74c054 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c
@@ -45,7 +45,6 @@
 #include <mach/msm_adsp.h>
 #include <mach/iommu.h>
 #include <mach/iommu_domains.h>
-#include <mach/msm_subsystem_map.h>
 #include <mach/qdsp5v2/qdsp5audppmsg.h>
 #include <mach/qdsp5v2/qdsp5audplaycmdi.h>
 #include <mach/qdsp5v2/qdsp5audplaymsg.h>
@@ -136,8 +135,8 @@
 	char *data;
 	int32_t phys; /* physical address of write buffer */
 
-	struct msm_mapped_buffer *map_v_read;
-	struct msm_mapped_buffer *map_v_write;
+	void *map_v_read;
+	void *map_v_write;
 
 	int mfield; /* meta field embedded in data */
 	int rflush; /* Read  flush */
@@ -1003,12 +1002,10 @@
 					rc = -ENOMEM;
 					break;
 			}
-			audio->map_v_read = msm_subsystem_map_buffer(
+			audio->map_v_read = ioremap(
 						audio->read_phys,
 						config.buffer_size *
-						config.buffer_count,
-						MSM_SUBSYSTEM_MAP_KADDR,
-						NULL, 0);
+						config.buffer_count);
 			if (IS_ERR(audio->map_v_read)) {
 				MM_ERR("Error could not map read"
 							" phys address\n");
@@ -1018,7 +1015,7 @@
 			} else {
 				uint8_t index;
 				uint32_t offset = 0;
-				audio->read_data = audio->map_v_read->vaddr;
+				audio->read_data = audio->map_v_read;
 				audio->pcm_feedback = 1;
 				audio->buf_refresh = 0;
 				audio->pcm_buf_count =
@@ -1401,10 +1398,10 @@
 	audio->event_abort = 1;
 	wake_up(&audio->event_wait);
 	audamrwb_reset_event_queue(audio);
-	msm_subsystem_unmap_buffer(audio->map_v_write);
+	iounmap(audio->map_v_write);
 	free_contiguous_memory_by_paddr(audio->phys);
 	if (audio->read_data) {
-		msm_subsystem_unmap_buffer(audio->map_v_read);
+		iounmap(audio->map_v_read);
 		free_contiguous_memory_by_paddr(audio->read_phys);
 	}
 	mutex_unlock(&audio->lock);
@@ -1591,9 +1588,7 @@
 		kfree(audio);
 		goto done;
 	} else {
-		audio->map_v_write = msm_subsystem_map_buffer(
-					audio->phys, DMASZ,
-					MSM_SUBSYSTEM_MAP_KADDR, NULL, 0);
+		audio->map_v_write = ioremap(audio->phys, DMASZ);
 		if (IS_ERR(audio->map_v_write)) {
 			MM_ERR("could not map write phys buffers, freeing \
 					instance 0x%08x\n", (int)audio);
@@ -1603,7 +1598,7 @@
 			kfree(audio);
 			goto done;
 		}
-		audio->data = audio->map_v_write->vaddr;
+		audio->data = audio->map_v_write;
 		MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n",
 				audio->phys, (int)audio->data);
 	}
@@ -1692,7 +1687,7 @@
 event_err:
 	msm_adsp_put(audio->audplay);
 err:
-	msm_subsystem_unmap_buffer(audio->map_v_write);
+	iounmap(audio->map_v_write);
 	free_contiguous_memory_by_paddr(audio->phys);
 	audpp_adec_free(audio->dec_id);
 	kfree(audio);
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_evrc.c b/arch/arm/mach-msm/qdsp5v2/audio_evrc.c
index 9b5694d..8818cbd 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_evrc.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_evrc.c
@@ -40,7 +40,6 @@
 #include <mach/msm_adsp.h>
 #include <mach/iommu.h>
 #include <mach/iommu_domains.h>
-#include <mach/msm_subsystem_map.h>
 #include <mach/qdsp5v2/audio_dev_ctl.h>
 #include <mach/qdsp5v2/qdsp5audppmsg.h>
 #include <mach/qdsp5v2/qdsp5audplaycmdi.h>
@@ -132,8 +131,8 @@
 	/* data allocated for various buffers */
 	char *data;
 	int32_t phys;  /* physical address of write buffer */
-	struct msm_mapped_buffer *map_v_read;
-	struct msm_mapped_buffer *map_v_write;
+	void *map_v_read;
+	void *map_v_write;
 
 	int mfield; /* meta field embedded in data */
 	int rflush; /* Read  flush */
@@ -982,12 +981,10 @@
 					rc = -ENOMEM;
 					break;
 				}
-				audio->map_v_read = msm_subsystem_map_buffer(
+				audio->map_v_read = ioremap(
 							audio->read_phys,
 							config.buffer_size *
-							config.buffer_count,
-							MSM_SUBSYSTEM_MAP_KADDR
-							, NULL, 0);
+							config.buffer_count);
 				if (IS_ERR(audio->map_v_read)) {
 					MM_ERR("failed to map read"
 							" phy address\n");
@@ -998,7 +995,7 @@
 					uint8_t index;
 					uint32_t offset = 0;
 					audio->read_data =
-						audio->map_v_read->vaddr;
+						audio->map_v_read;
 					audio->buf_refresh = 0;
 					audio->pcm_buf_count =
 					    config.buffer_count;
@@ -1311,10 +1308,10 @@
 	audio->event_abort = 1;
 	wake_up(&audio->event_wait);
 	audevrc_reset_event_queue(audio);
-	msm_subsystem_unmap_buffer(audio->map_v_write);
+	iounmap(audio->map_v_write);
 	free_contiguous_memory_by_paddr(audio->phys);
 	if (audio->read_data) {
-		msm_subsystem_unmap_buffer(audio->map_v_read);
+		iounmap(audio->map_v_read);
 		free_contiguous_memory_by_paddr(audio->read_phys);
 	}
 	mutex_unlock(&audio->lock);
@@ -1505,9 +1502,7 @@
 		kfree(audio);
 		goto done;
 	} else {
-		audio->map_v_write = msm_subsystem_map_buffer(
-					audio->phys, DMASZ,
-					MSM_SUBSYSTEM_MAP_KADDR, NULL, 0);
+		audio->map_v_write = ioremap(audio->phys, DMASZ);
 		if (IS_ERR(audio->map_v_write)) {
 			MM_ERR("failed to map write physical address, freeing \
 					instance 0x%08x\n", (int)audio);
@@ -1517,7 +1512,7 @@
 			kfree(audio);
 			goto done;
 		}
-		audio->data = audio->map_v_write->vaddr;
+		audio->data = audio->map_v_write;
 		MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n",
 				audio->phys, (int)audio->data);
 	}
@@ -1604,7 +1599,7 @@
 event_err:
 	msm_adsp_put(audio->audplay);
 err:
-	msm_subsystem_unmap_buffer(audio->map_v_write);
+	iounmap(audio->map_v_write);
 	free_contiguous_memory_by_paddr(audio->phys);
 	audpp_adec_free(audio->dec_id);
 	kfree(audio);
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c b/arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c
index 50621c9..150e476 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -33,7 +33,6 @@
 #include <mach/msm_adsp.h>
 #include <mach/iommu.h>
 #include <mach/iommu_domains.h>
-#include <mach/msm_subsystem_map.h>
 #include <mach/socinfo.h>
 #include <mach/qdsp5v2/qdsp5audreccmdi.h>
 #include <mach/qdsp5v2/qdsp5audrecmsg.h>
@@ -131,8 +130,8 @@
 	/* data allocated for various buffers */
 	char *data;
 	dma_addr_t phys;
-	struct msm_mapped_buffer *map_v_read;
-	struct msm_mapped_buffer *map_v_write;
+	void *map_v_read;
+	void *map_v_write;
 	int opened;
 	int enabled;
 	int running;
@@ -1319,12 +1318,12 @@
 	audio->audrec = NULL;
 	audio->opened = 0;
 	if (audio->data) {
-		msm_subsystem_unmap_buffer(audio->map_v_read);
+		iounmap(audio->map_v_read);
 		free_contiguous_memory_by_paddr(audio->phys);
 		audio->data = NULL;
 	}
 	if (audio->out_data) {
-		msm_subsystem_unmap_buffer(audio->map_v_write);
+		iounmap(audio->map_v_write);
 		free_contiguous_memory_by_paddr(audio->out_phys);
 		audio->out_data = NULL;
 	}
@@ -1346,17 +1345,14 @@
 	}
 	audio->phys = allocate_contiguous_ebi_nomap(DMASZ, SZ_4K);
 	if (audio->phys) {
-		audio->map_v_read = msm_subsystem_map_buffer(
-						audio->phys, DMASZ,
-						MSM_SUBSYSTEM_MAP_KADDR,
-						NULL, 0);
+		audio->map_v_read = ioremap(audio->phys, DMASZ);
 		if (IS_ERR(audio->map_v_read)) {
 			MM_ERR("failed to map read physical address\n");
 			rc = -ENOMEM;
 			free_contiguous_memory_by_paddr(audio->phys);
 			goto done;
 		}
-		audio->data = audio->map_v_read->vaddr;
+		audio->data = audio->map_v_read;
 	} else {
 		MM_ERR("could not allocate DMA buffers\n");
 		rc = -ENOMEM;
@@ -1425,17 +1421,14 @@
 		rc = -ENOMEM;
 		goto evt_error;
 	} else {
-		audio->map_v_write = msm_subsystem_map_buffer(
-						audio->out_phys, BUFFER_SIZE,
-						MSM_SUBSYSTEM_MAP_KADDR,
-						NULL, 0);
+		audio->map_v_write = ioremap(audio->out_phys, BUFFER_SIZE);
 		if (IS_ERR(audio->map_v_write)) {
 			MM_ERR("could map write buffers\n");
 			rc = -ENOMEM;
 			free_contiguous_memory_by_paddr(audio->out_phys);
 			goto evt_error;
 		}
-		audio->out_data = audio->map_v_write->vaddr;
+		audio->out_data = audio->map_v_write;
 		MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n",
 				audio->out_phys, (int)audio->out_data);
 	}
@@ -1461,7 +1454,7 @@
 					evrc_in_listener, (void *) audio);
 	if (rc) {
 		MM_ERR("failed to register device event listener\n");
-		msm_subsystem_unmap_buffer(audio->map_v_write);
+		iounmap(audio->map_v_write);
 		free_contiguous_memory_by_paddr(audio->out_phys);
 		goto evt_error;
 	}
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_mp3.c b/arch/arm/mach-msm/qdsp5v2/audio_mp3.c
index c639833..a4fc3e3 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_mp3.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_mp3.c
@@ -37,7 +37,6 @@
 
 #include <mach/iommu.h>
 #include <mach/iommu_domains.h>
-#include <mach/msm_subsystem_map.h>
 #include <mach/qdsp5v2/audio_dev_ctl.h>
 #include <mach/qdsp5v2/qdsp5audppmsg.h>
 #include <mach/qdsp5v2/qdsp5audplaycmdi.h>
@@ -198,8 +197,8 @@
 	/* data allocated for various buffers */
 	char *data;
 	int32_t phys; /* physical address of write buffer */
-	struct msm_mapped_buffer *map_v_read;
-	struct msm_mapped_buffer *map_v_write;
+	void *map_v_read;
+	void *map_v_write;
 
 	uint32_t drv_status;
 	int mfield; /* meta field embedded in data */
@@ -1609,12 +1608,10 @@
 					rc = -ENOMEM;
 					break;
 				}
-				audio->map_v_read = msm_subsystem_map_buffer(
+				audio->map_v_read = ioremap(
 							audio->read_phys,
 							config.buffer_size *
-							config.buffer_count,
-							MSM_SUBSYSTEM_MAP_KADDR
-							, NULL, 0);
+							config.buffer_count);
 				if (IS_ERR(audio->map_v_read)) {
 					MM_ERR("failed to map read buffer"
 							" physical address\n");
@@ -1625,7 +1622,7 @@
 					uint8_t index;
 					uint32_t offset = 0;
 					audio->read_data =
-						audio->map_v_read->vaddr;
+						audio->map_v_read;
 					audio->buf_refresh = 0;
 					audio->pcm_buf_count =
 					    config.buffer_count;
@@ -2145,11 +2142,11 @@
 	wake_up(&audio->event_wait);
 	audmp3_reset_event_queue(audio);
 	if (audio->data) {
-		msm_subsystem_unmap_buffer(audio->map_v_write);
+		iounmap(audio->map_v_write);
 		free_contiguous_memory_by_paddr(audio->phys);
 	}
 	if (audio->read_data) {
-		msm_subsystem_unmap_buffer(audio->map_v_read);
+		iounmap(audio->map_v_read);
 		free_contiguous_memory_by_paddr(audio->read_phys);
 	}
 	mutex_unlock(&audio->lock);
@@ -2353,10 +2350,8 @@
 			audio->phys = allocate_contiguous_ebi_nomap(pmem_sz,
 									SZ_4K);
 			if (audio->phys) {
-				audio->map_v_write = msm_subsystem_map_buffer(
-							audio->phys, pmem_sz,
-							MSM_SUBSYSTEM_MAP_KADDR
-							, NULL, 0);
+				audio->map_v_write = ioremap(
+							audio->phys, pmem_sz);
 				if (IS_ERR(audio->map_v_write)) {
 					MM_ERR("failed to map write physical"
 						" address , freeing instance"
@@ -2368,7 +2363,7 @@
 					kfree(audio);
 					goto done;
 				}
-				audio->data = audio->map_v_write->vaddr;
+				audio->data = audio->map_v_write;
 				MM_DBG("write buf: phy addr 0x%08x kernel addr\
 					0x%08x\n", audio->phys,\
 					(int)audio->data);
@@ -2485,7 +2480,7 @@
 	msm_adsp_put(audio->audplay);
 err:
 	if (audio->data) {
-		msm_subsystem_unmap_buffer(audio->map_v_write);
+		iounmap(audio->map_v_write);
 		free_contiguous_memory_by_paddr(audio->phys);
 	}
 	audpp_adec_free(audio->dec_id);
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_mvs.c b/arch/arm/mach-msm/qdsp5v2/audio_mvs.c
index dc41bf4..fae2401 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_mvs.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_mvs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -276,7 +276,7 @@
 struct audio_mvs_dl_reply {
 	struct rpc_reply_hdr reply_hdr;
 
-	uint32_t voc_pkt[MVS_MAX_VOC_PKT_SIZE/4];
+	uint32_t voc_pkt[Q5V2_MVS_MAX_VOC_PKT_SIZE/4];
 
 	uint32_t valid_frame_info_ptr;
 	uint32_t frame_mode;
@@ -288,7 +288,7 @@
 
 struct audio_mvs_buf_node {
 	struct list_head list;
-	struct msm_audio_mvs_frame frame;
+	struct q5v2_msm_audio_mvs_frame frame;
 };
 
 /* Each buffer is 20 ms, queue holds 200 ms of data. */
@@ -933,10 +933,15 @@
 
 				pr_debug("%s: UL AMR frame_type %d\n",
 					 __func__, be32_to_cpu(*args));
-			} else if ((frame_mode == MVS_FRAME_MODE_PCM_UL) ||
-				   (frame_mode == MVS_FRAME_MODE_VOC_TX)) {
-				/* PCM and EVRC don't have frame_type */
+			} else if (frame_mode == MVS_FRAME_MODE_PCM_UL) {
+				/* PCM don't have frame_type */
 				buf_node->frame.frame_type = 0;
+			} else if (frame_mode == MVS_FRAME_MODE_VOC_TX) {
+				/* Extracting EVRC current buffer frame rate*/
+				buf_node->frame.frame_type = be32_to_cpu(*args);
+
+				pr_debug("%s: UL EVRC frame_type %d\n",
+					__func__, be32_to_cpu(*args));
 			} else if (frame_mode == MVS_FRAME_MODE_G711_UL) {
 				/* Extract G711 frame type. */
 				buf_node->frame.frame_type = be32_to_cpu(*args);
@@ -1065,7 +1070,7 @@
 					cpu_to_be32(AUDIO_MVS_PKT_NORMAL);
 			} else if (frame_mode == MVS_FRAME_MODE_VOC_RX) {
 				dl_reply.cdc_param.gnr_arg.param1 =
-						cpu_to_be32(audio->rate_type);
+				cpu_to_be32(buf_node->frame.frame_type);
 				dl_reply.cdc_param.gnr_arg.param2 = 0;
 				dl_reply.cdc_param.\
 						gnr_arg.valid_pkt_status_ptr =
@@ -1427,7 +1432,7 @@
 		if ((audio->state == AUDIO_MVS_STARTED) &&
 		    (!list_empty(&audio->out_queue))) {
 
-			if (count >= sizeof(struct msm_audio_mvs_frame)) {
+			if (count >= sizeof(struct q5v2_msm_audio_mvs_frame)) {
 				buf_node = list_first_entry(&audio->out_queue,
 						struct audio_mvs_buf_node,
 						list);
@@ -1435,7 +1440,8 @@
 
 				rc = copy_to_user(buf,
 					&buf_node->frame,
-					sizeof(struct msm_audio_mvs_frame));
+					sizeof(struct q5v2_msm_audio_mvs_frame)
+					);
 
 				if (rc == 0) {
 					rc = buf_node->frame.len +
@@ -1453,7 +1459,7 @@
 			} else {
 				pr_err("%s: Read count %d < sizeof(frame) %d",
 				       __func__, count,
-				       sizeof(struct msm_audio_mvs_frame));
+				       sizeof(struct q5v2_msm_audio_mvs_frame));
 
 				rc = -ENOMEM;
 			}
@@ -1491,7 +1497,7 @@
 
 	mutex_lock(&audio->in_lock);
 	if (audio->state == AUDIO_MVS_STARTED) {
-		if (count <= sizeof(struct msm_audio_mvs_frame)) {
+		if (count <= sizeof(struct q5v2_msm_audio_mvs_frame)) {
 			if (!list_empty(&audio->free_in_queue)) {
 				buf_node =
 					list_first_entry(&audio->free_in_queue,
@@ -1511,7 +1517,7 @@
 		} else {
 			pr_err("%s: Write count %d < sizeof(frame) %d",
 			       __func__, count,
-			       sizeof(struct msm_audio_mvs_frame));
+			       sizeof(struct q5v2_msm_audio_mvs_frame));
 
 			rc = -ENOMEM;
 		}
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_out.c b/arch/arm/mach-msm/qdsp5v2/audio_out.c
index 9a93185..930de03 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_out.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_out.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -36,7 +36,6 @@
 #include <mach/msm_adsp.h>
 #include <mach/iommu.h>
 #include <mach/iommu_domains.h>
-#include <mach/msm_subsystem_map.h>
 #include <mach/qdsp5v2/qdsp5audppcmdi.h>
 #include <mach/qdsp5v2/qdsp5audppmsg.h>
 #include <mach/qdsp5v2/audio_dev_ctl.h>
@@ -86,7 +85,7 @@
 	/* data allocated for various buffers */
 	char *data;
 	dma_addr_t phys;
-	struct msm_mapped_buffer *map_v_write;
+	void *map_v_write;
 	int teos; /* valid only if tunnel mode & no data left for decoder */
 	int opened;
 	int enabled;
@@ -704,16 +703,13 @@
 {
 	the_audio.phys = allocate_contiguous_ebi_nomap(DMASZ, SZ_4K);
 	if (the_audio.phys) {
-		the_audio.map_v_write = msm_subsystem_map_buffer(
-						the_audio.phys, DMASZ,
-						MSM_SUBSYSTEM_MAP_KADDR,
-						NULL, 0);
+		the_audio.map_v_write = ioremap(the_audio.phys, DMASZ);
 		if (IS_ERR(the_audio.map_v_write)) {
 			MM_ERR("could not map physical buffers\n");
 			free_contiguous_memory_by_paddr(the_audio.phys);
 			return -ENOMEM;
 		}
-		the_audio.data = the_audio.map_v_write->vaddr;
+		the_audio.data = the_audio.map_v_write;
 	} else {
 			MM_ERR("could not allocate physical buffers\n");
 			return -ENOMEM;
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_pcm.c b/arch/arm/mach-msm/qdsp5v2/audio_pcm.c
index b22820b..613ee57 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_pcm.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_pcm.c
@@ -40,7 +40,6 @@
 
 #include <mach/iommu.h>
 #include <mach/iommu_domains.h>
-#include <mach/msm_subsystem_map.h>
 #include <mach/qdsp5v2/qdsp5audppcmdi.h>
 #include <mach/qdsp5v2/qdsp5audppmsg.h>
 #include <mach/qdsp5v2/qdsp5audplaycmdi.h>
@@ -172,7 +171,7 @@
 	/* data allocated for various buffers */
 	char *data;
 	int32_t phys;
-	struct msm_mapped_buffer *map_v_write;
+	void *map_v_write;
 	uint32_t drv_status;
 	int wflush; /* Write flush */
 	int opened;
@@ -1382,7 +1381,7 @@
 	wake_up(&audio->event_wait);
 	audpcm_reset_event_queue(audio);
 	if (audio->data) {
-		msm_subsystem_unmap_buffer(audio->map_v_write);
+		iounmap(audio->map_v_write);
 		free_contiguous_memory_by_paddr(audio->phys);
 	}
 	mutex_unlock(&audio->lock);
@@ -1560,10 +1559,8 @@
 			audio->phys = allocate_contiguous_ebi_nomap(pmem_sz,
 								SZ_4K);
 			if (audio->phys) {
-				audio->map_v_write = msm_subsystem_map_buffer(
-							audio->phys, pmem_sz,
-							MSM_SUBSYSTEM_MAP_KADDR
-							, NULL, 0);
+				audio->map_v_write = ioremap(
+							audio->phys, pmem_sz);
 				if (IS_ERR(audio->map_v_write)) {
 					MM_ERR("could not map write phys\
 						address freeing instance \
@@ -1575,7 +1572,7 @@
 					kfree(audio);
 					goto done;
 				}
-				audio->data = audio->map_v_write->vaddr;
+				audio->data = audio->map_v_write;
 				MM_DBG("write buf: phy addr 0x%08x \
 						kernel addr 0x%08x\n",
 						audio->phys, (int)audio->data);
@@ -1679,7 +1676,7 @@
 	msm_adsp_put(audio->audplay);
 err:
 	if (audio->data) {
-		msm_subsystem_unmap_buffer(audio->map_v_write);
+		iounmap(audio->map_v_write);
 		free_contiguous_memory_by_paddr(audio->phys);
 	}
 	audpp_adec_free(audio->dec_id);
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_pcm_in.c b/arch/arm/mach-msm/qdsp5v2/audio_pcm_in.c
index a5a9bd2..ce67ebb 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_pcm_in.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_pcm_in.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -33,7 +33,6 @@
 
 #include <mach/iommu.h>
 #include <mach/iommu_domains.h>
-#include <mach/msm_subsystem_map.h>
 
 #include <mach/msm_adsp.h>
 #include <mach/socinfo.h>
@@ -113,7 +112,7 @@
 	/* data allocated for various buffers */
 	char *data;
 	dma_addr_t phys;
-	struct msm_mapped_buffer *map_v_read;
+	void *map_v_read;
 
 	int opened;
 	int enabled;
@@ -843,7 +842,7 @@
 	audio->audrec = NULL;
 	audio->opened = 0;
 	if (audio->data) {
-		msm_subsystem_unmap_buffer(audio->map_v_read);
+		iounmap(audio->map_v_read);
 		free_contiguous_memory_by_paddr(audio->phys);
 		audio->data = NULL;
 	}
@@ -864,16 +863,14 @@
 	}
 	audio->phys = allocate_contiguous_ebi_nomap(DMASZ, SZ_4K);
 	if (audio->phys) {
-		audio->map_v_read = msm_subsystem_map_buffer(
-					audio->phys, DMASZ,
-					MSM_SUBSYSTEM_MAP_KADDR, NULL, 0);
+		audio->map_v_read = ioremap(audio->phys, DMASZ);
 		if (IS_ERR(audio->map_v_read)) {
 			MM_ERR("could not map read phys buffers\n");
 			rc = -ENOMEM;
 			free_contiguous_memory_by_paddr(audio->phys);
 			goto done;
 		}
-		audio->data = audio->map_v_read->vaddr;
+		audio->data = audio->map_v_read;
 	} else {
 		MM_ERR("could not allocate read buffers\n");
 		rc = -ENOMEM;
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c b/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c
index ce5d421..c4851d9 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c
@@ -41,7 +41,6 @@
 #include <mach/msm_adsp.h>
 #include <mach/iommu.h>
 #include <mach/iommu_domains.h>
-#include <mach/msm_subsystem_map.h>
 #include <mach/qdsp5v2/qdsp5audppmsg.h>
 #include <mach/qdsp5v2/qdsp5audplaycmdi.h>
 #include <mach/qdsp5v2/qdsp5audplaymsg.h>
@@ -128,8 +127,8 @@
 	/* data allocated for various buffers */
 	char *data;
 	int32_t phys; /* physical address of write buffer */
-	struct msm_mapped_buffer *map_v_read;
-	struct msm_mapped_buffer *map_v_write;
+	void *map_v_read;
+	void *map_v_write;
 
 	int mfield; /* meta field embedded in data */
 	int rflush; /* Read  flush */
@@ -984,12 +983,10 @@
 					rc = -ENOMEM;
 					break;
 				}
-				audio->map_v_read = msm_subsystem_map_buffer(
+				audio->map_v_read = ioremap(
 							audio->read_phys,
 							config.buffer_size *
-							config.buffer_count,
-							MSM_SUBSYSTEM_MAP_KADDR
-							, NULL, 0);
+							config.buffer_count);
 				if (IS_ERR(audio->map_v_read)) {
 					MM_ERR("failed to map read buf\n");
 					rc = -ENOMEM;
@@ -999,7 +996,7 @@
 					uint8_t index;
 					uint32_t offset = 0;
 					audio->read_data =
-						audio->map_v_read->vaddr;
+						audio->map_v_read;
 					audio->buf_refresh = 0;
 					audio->pcm_buf_count =
 						config.buffer_count;
@@ -1313,10 +1310,10 @@
 	audio->event_abort = 1;
 	wake_up(&audio->event_wait);
 	audqcelp_reset_event_queue(audio);
-	msm_subsystem_unmap_buffer(audio->map_v_write);
+	iounmap(audio->map_v_write);
 	free_contiguous_memory_by_paddr(audio->phys);
 	if (audio->read_data) {
-		msm_subsystem_unmap_buffer(audio->map_v_read);
+		iounmap(audio->map_v_read);
 		free_contiguous_memory_by_paddr(audio->read_phys);
 	}
 	mutex_unlock(&audio->lock);
@@ -1505,9 +1502,7 @@
 		kfree(audio);
 		goto done;
 	} else {
-		audio->map_v_write = msm_subsystem_map_buffer(
-					audio->phys, DMASZ,
-					MSM_SUBSYSTEM_MAP_KADDR, NULL, 0);
+		audio->map_v_write = ioremap(audio->phys, DMASZ);
 		if (IS_ERR(audio->map_v_write)) {
 			MM_ERR("could not map write phys address, freeing \
 					instance 0x%08x\n", (int)audio);
@@ -1517,7 +1512,7 @@
 			kfree(audio);
 			goto done;
 		}
-		audio->data = audio->map_v_write->vaddr;
+		audio->data = audio->map_v_write;
 		MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n",
 				audio->phys, (int)audio->data);
 	}
@@ -1604,7 +1599,7 @@
 event_err:
 	msm_adsp_put(audio->audplay);
 err:
-	msm_subsystem_unmap_buffer(audio->map_v_write);
+	iounmap(audio->map_v_write);
 	free_contiguous_memory_by_paddr(audio->phys);
 	audpp_adec_free(audio->dec_id);
 	kfree(audio);
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c b/arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c
index d34499d..7041bde 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -33,7 +33,6 @@
 #include <mach/msm_adsp.h>
 #include <mach/iommu.h>
 #include <mach/iommu_domains.h>
-#include <mach/msm_subsystem_map.h>
 #include <mach/socinfo.h>
 #include <mach/qdsp5v2/qdsp5audreccmdi.h>
 #include <mach/qdsp5v2/qdsp5audrecmsg.h>
@@ -133,8 +132,8 @@
 	/* data allocated for various buffers */
 	char *data;
 	dma_addr_t phys;
-	struct msm_mapped_buffer *map_v_read;
-	struct msm_mapped_buffer *map_v_write;
+	void *map_v_read;
+	void *map_v_write;
 
 	int opened;
 	int enabled;
@@ -1325,12 +1324,12 @@
 	audio->audrec = NULL;
 	audio->opened = 0;
 	if (audio->data) {
-		msm_subsystem_unmap_buffer(audio->map_v_read);
+		iounmap(audio->map_v_read);
 		free_contiguous_memory_by_paddr(audio->phys);
 		audio->data = NULL;
 	}
 	if (audio->out_data) {
-		msm_subsystem_unmap_buffer(audio->map_v_write);
+		iounmap(audio->map_v_write);
 		free_contiguous_memory_by_paddr(audio->out_phys);
 		audio->out_data = NULL;
 	}
@@ -1352,16 +1351,14 @@
 	}
 	audio->phys = allocate_contiguous_ebi_nomap(DMASZ, SZ_4K);
 	if (audio->phys) {
-		audio->map_v_read = msm_subsystem_map_buffer(
-					audio->phys, DMASZ,
-					MSM_SUBSYSTEM_MAP_KADDR, NULL, 0);
+		audio->map_v_read = ioremap(audio->phys, DMASZ);
 		if (IS_ERR(audio->map_v_read)) {
 			MM_ERR("could not map DMA buffers\n");
 			rc = -ENOMEM;
 			free_contiguous_memory_by_paddr(audio->phys);
 			goto done;
 		}
-		audio->data = audio->map_v_read->vaddr;
+		audio->data = audio->map_v_read;
 	} else {
 		MM_ERR("could not allocate DMA buffers\n");
 		rc = -ENOMEM;
@@ -1431,16 +1428,14 @@
 		rc = -ENOMEM;
 		goto evt_error;
 	} else {
-		audio->map_v_write = msm_subsystem_map_buffer(
-					audio->out_phys, BUFFER_SIZE,
-					MSM_SUBSYSTEM_MAP_KADDR, NULL, 0);
+		audio->map_v_write = ioremap(audio->out_phys, BUFFER_SIZE);
 		if (IS_ERR(audio->map_v_write)) {
 			MM_ERR("could not map write buffers\n");
 			rc = -ENOMEM;
 			free_contiguous_memory_by_paddr(audio->out_phys);
 			goto evt_error;
 		}
-		audio->out_data = audio->map_v_write->vaddr;
+		audio->out_data = audio->map_v_write;
 		MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n",
 				audio->out_phys, (int)audio->out_data);
 	}
@@ -1466,7 +1461,7 @@
 					qcelp_in_listener, (void *) audio);
 	if (rc) {
 		MM_ERR("failed to register device event listener\n");
-		msm_subsystem_unmap_buffer(audio->map_v_write);
+		iounmap(audio->map_v_write);
 		free_contiguous_memory_by_paddr(audio->out_phys);
 		goto evt_error;
 	}
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_wma.c b/arch/arm/mach-msm/qdsp5v2/audio_wma.c
index f29b078..79439e1 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_wma.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_wma.c
@@ -45,7 +45,6 @@
 #include <mach/msm_adsp.h>
 #include <mach/iommu.h>
 #include <mach/iommu_domains.h>
-#include <mach/msm_subsystem_map.h>
 #include <mach/qdsp5v2/qdsp5audppmsg.h>
 #include <mach/qdsp5v2/qdsp5audplaycmdi.h>
 #include <mach/qdsp5v2/qdsp5audplaymsg.h>
@@ -141,8 +140,8 @@
 	/* data allocated for various buffers */
 	char *data;
 	int32_t phys; /* physical address of write buffer */
-	struct msm_mapped_buffer *map_v_read;
-	struct msm_mapped_buffer *map_v_write;
+	void *map_v_read;
+	void *map_v_write;
 
 	int mfield; /* meta field embedded in data */
 	int rflush; /* Read  flush */
@@ -1062,12 +1061,10 @@
 					rc = -ENOMEM;
 					break;
 				}
-				audio->map_v_read = msm_subsystem_map_buffer(
+				audio->map_v_read = ioremap(
 							audio->read_phys,
 							config.buffer_size *
-							config.buffer_count,
-							MSM_SUBSYSTEM_MAP_KADDR
-							, NULL, 0);
+							config.buffer_count);
 				if (IS_ERR(audio->map_v_read)) {
 					MM_ERR("read buf alloc fail\n");
 					rc = -ENOMEM;
@@ -1077,7 +1074,7 @@
 					uint8_t index;
 					uint32_t offset = 0;
 					audio->read_data =
-						audio->map_v_read->vaddr;
+						audio->map_v_read;
 					audio->buf_refresh = 0;
 					audio->pcm_buf_count =
 					    config.buffer_count;
@@ -1458,10 +1455,10 @@
 	audio->event_abort = 1;
 	wake_up(&audio->event_wait);
 	audwma_reset_event_queue(audio);
-	msm_subsystem_unmap_buffer(audio->map_v_write);
+	iounmap(audio->map_v_write);
 	free_contiguous_memory_by_paddr(audio->phys);
 	if (audio->read_data) {
-		msm_subsystem_unmap_buffer(audio->map_v_read);
+		iounmap(audio->map_v_read);
 		free_contiguous_memory_by_paddr(audio->read_phys);
 	}
 	mutex_unlock(&audio->lock);
@@ -1652,10 +1649,7 @@
 		MM_DBG("pmemsz = %d\n", pmem_sz);
 		audio->phys = allocate_contiguous_ebi_nomap(pmem_sz, SZ_4K);
 		if (audio->phys) {
-			audio->map_v_write = msm_subsystem_map_buffer(
-						audio->phys, pmem_sz,
-						MSM_SUBSYSTEM_MAP_KADDR,
-						NULL, 0);
+			audio->map_v_write = ioremap(audio->phys, pmem_sz);
 			if (IS_ERR(audio->map_v_write)) {
 				MM_ERR("could not allocate write buffers, \
 						freeing instance 0x%08x\n",
@@ -1666,7 +1660,7 @@
 				kfree(audio);
 				goto done;
 			}
-			audio->data = audio->map_v_write->vaddr;
+			audio->data = audio->map_v_write;
 			MM_DBG("write buf: phy addr 0x%08x kernel addr \
 				0x%08x\n", audio->phys, (int)audio->data);
 			break;
@@ -1772,7 +1766,7 @@
 event_err:
 	msm_adsp_put(audio->audplay);
 err:
-	msm_subsystem_unmap_buffer(audio->map_v_write);
+	iounmap(audio->map_v_write);
 	free_contiguous_memory_by_paddr(audio->phys);
 	audpp_adec_free(audio->dec_id);
 	kfree(audio);
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c b/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c
index cf25359..6672ca0 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c
@@ -44,7 +44,6 @@
 #include <mach/msm_adsp.h>
 #include <mach/iommu.h>
 #include <mach/iommu_domains.h>
-#include <mach/msm_subsystem_map.h>
 #include <mach/qdsp5v2/qdsp5audppmsg.h>
 #include <mach/qdsp5v2/qdsp5audplaycmdi.h>
 #include <mach/qdsp5v2/qdsp5audplaymsg.h>
@@ -141,8 +140,8 @@
 	/* data allocated for various buffers */
 	char *data;
 	int32_t phys; /* physical address of write buffer */
-	struct msm_mapped_buffer *map_v_read;
-	struct msm_mapped_buffer *map_v_write;
+	void *map_v_read;
+	void *map_v_write;
 
 	int mfield; /* meta field embedded in data */
 	int rflush; /* Read  flush */
@@ -1074,12 +1073,10 @@
 					rc = -ENOMEM;
 					break;
 				}
-				audio->map_v_read = msm_subsystem_map_buffer(
+				audio->map_v_read = ioremap(
 							audio->read_phys,
 							config.buffer_size *
-							config.buffer_count,
-							MSM_SUBSYSTEM_MAP_KADDR
-							, NULL, 0);
+							config.buffer_count);
 				if (IS_ERR(audio->map_v_read)) {
 					MM_ERR("read buf map fail\n");
 					rc = -ENOMEM;
@@ -1089,7 +1086,7 @@
 					uint8_t index;
 					uint32_t offset = 0;
 					audio->read_data =
-						audio->map_v_read->vaddr;
+						audio->map_v_read;
 					audio->pcm_feedback = 1;
 					audio->buf_refresh = 0;
 					audio->pcm_buf_count =
@@ -1471,10 +1468,10 @@
 	audio->event_abort = 1;
 	wake_up(&audio->event_wait);
 	audwmapro_reset_event_queue(audio);
-	msm_subsystem_unmap_buffer(audio->map_v_write);
+	iounmap(audio->map_v_write);
 	free_contiguous_memory_by_paddr(audio->phys);
 	if (audio->read_data) {
-		msm_subsystem_unmap_buffer(audio->map_v_read);
+		iounmap(audio->map_v_read);
 		free_contiguous_memory_by_paddr(audio->read_phys);
 	}
 	mutex_unlock(&audio->lock);
@@ -1665,10 +1662,7 @@
 		MM_DBG("pmemsz = %d\n", pmem_sz);
 		audio->phys = allocate_contiguous_ebi_nomap(pmem_sz, SZ_4K);
 		if (audio->phys) {
-			audio->map_v_write = msm_subsystem_map_buffer(
-						audio->phys, pmem_sz,
-						MSM_SUBSYSTEM_MAP_KADDR,
-						NULL, 0);
+			audio->map_v_write = ioremap(audio->phys, pmem_sz);
 			if (IS_ERR(audio->map_v_write)) {
 				MM_ERR("could not map write buffers, \
 						freeing instance 0x%08x\n",
@@ -1679,7 +1673,7 @@
 				kfree(audio);
 				goto done;
 			}
-			audio->data = audio->map_v_write->vaddr;
+			audio->data = audio->map_v_write;
 			MM_DBG("write buf: phy addr 0x%08x kernel addr \
 				0x%08x\n", audio->phys, (int)audio->data);
 			break;
@@ -1790,7 +1784,7 @@
 event_err:
 	msm_adsp_put(audio->audplay);
 err:
-	msm_subsystem_unmap_buffer(audio->map_v_write);
+	iounmap(audio->map_v_write);
 	free_contiguous_memory_by_paddr(audio->phys);
 	audpp_adec_free(audio->dec_id);
 	kfree(audio);
diff --git a/arch/arm/mach-msm/qdsp6v2/dsp_debug.c b/arch/arm/mach-msm/qdsp6v2/dsp_debug.c
index 1d8195e..1fa0876 100644
--- a/arch/arm/mach-msm/qdsp6v2/dsp_debug.c
+++ b/arch/arm/mach-msm/qdsp6v2/dsp_debug.c
@@ -27,7 +27,6 @@
 
 #include "../proc_comm.h"
 #include <mach/debug_mm.h>
-#include <mach/msm_subsystem_map.h>
 #include <mach/qdsp6v2/dsp_debug.h>
 
 static wait_queue_head_t dsp_wait;
@@ -72,8 +71,7 @@
 {
 	char cmd[32];
 	void __iomem *ptr;
-	unsigned int flags = MSM_SUBSYSTEM_MAP_KADDR | MSM_SUBSYSTEM_MAP_CACHED;
-	struct msm_mapped_buffer *mem_buffer;
+	void *mem_buffer;
 
 	if (count >= sizeof(cmd))
 		return -EINVAL;
@@ -96,21 +94,19 @@
 			}
 		}
 		/* assert DSP NMI */
-		mem_buffer = msm_subsystem_map_buffer(DSP_NMI_ADDR, 0x16, flags,
-							NULL, 0);
+		mem_buffer = ioremap(DSP_NMI_ADDR, 0x16);
 		if (IS_ERR((void *)mem_buffer)) {
 			pr_err("%s:map_buffer failed, error = %ld\n", __func__,
 				   PTR_ERR((void *)mem_buffer));
 			return -ENOMEM;
 		}
-		ptr = mem_buffer->vaddr;
+		ptr = mem_buffer;
 		if (!ptr) {
 			pr_err("Unable to map DSP NMI\n");
 			return -EFAULT;
 		}
 		writel(0x1, (void *)ptr);
-		if (msm_subsystem_unmap_buffer(mem_buffer) < 0)
-			pr_err("%s:unmap buffer failed\n", __func__);
+		iounmap(mem_buffer);
 	} else if (!strcmp(cmd, "boom")) {
 		q6audio_dsp_not_responding();
 	} else if (!strcmp(cmd, "continue-crash")) {
@@ -135,8 +131,7 @@
 	size_t mapsize = PAGE_SIZE;
 	unsigned addr;
 	void __iomem *ptr;
-	unsigned int flags = MSM_SUBSYSTEM_MAP_KADDR | MSM_SUBSYSTEM_MAP_CACHED;
-	struct msm_mapped_buffer *mem_buffer;
+	void *mem_buffer;
 
 	if ((dsp_ram_base == 0) || (dsp_ram_size == 0)) {
 		pr_err("[%s:%s] Memory Invalid or not initialized, Base = 0x%x,"
@@ -158,29 +153,26 @@
 		mapsize *= 2;
 
 	while (count >= PAGE_SIZE) {
-		mem_buffer = msm_subsystem_map_buffer(addr, mapsize, flags,
-							NULL, 0);
+		mem_buffer = ioremap(addr, mapsize);
 		if (IS_ERR((void *)mem_buffer)) {
 			pr_err("%s:map_buffer failed, error = %ld\n",
 				__func__, PTR_ERR((void *)mem_buffer));
 			return -ENOMEM;
 		}
-		ptr = mem_buffer->vaddr;
+		ptr = mem_buffer;
 		if (!ptr) {
 			pr_err("[%s:%s] map error @ %x\n", __MM_FILE__,
 					__func__, addr);
 			return -EFAULT;
 		}
 		if (copy_to_user(buf, ptr, PAGE_SIZE)) {
-			if (msm_subsystem_unmap_buffer(mem_buffer) < 0)
-				pr_err("%s: unmap buffer failed\n", __func__);
+			iounmap(mem_buffer);
 			pr_err("[%s:%s] copy error @ %p\n", __MM_FILE__,
 					__func__, buf);
 			return -EFAULT;
 		}
 		copy_ok_count += PAGE_SIZE;
-		if (msm_subsystem_unmap_buffer(mem_buffer) < 0)
-			pr_err("%s: unmap buffer failed\n", __func__);
+		iounmap(mem_buffer);
 		addr += PAGE_SIZE;
 		buf += PAGE_SIZE;
 		actual += PAGE_SIZE;
diff --git a/arch/arm/mach-msm/scm-boot.h b/arch/arm/mach-msm/scm-boot.h
index b14c968..221ffca 100644
--- a/arch/arm/mach-msm/scm-boot.h
+++ b/arch/arm/mach-msm/scm-boot.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -21,6 +21,10 @@
 #define SCM_FLAG_WARMBOOT_CPU2		0x10
 #define SCM_FLAG_WARMBOOT_CPU3		0x40
 
+#ifdef CONFIG_MSM_SCM
 int scm_set_boot_addr(void *addr, int flags);
+#else
+static inline int scm_set_boot_addr(void *addr, int flags) { return 0; }
+#endif
 
 #endif
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index dac0a37..ddc3a8d 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -3483,8 +3483,14 @@
 	},
 };
 
-static int __init msm_smd_init(void)
+int __init msm_smd_init(void)
 {
+	static bool registered;
+
+	if (registered)
+		return 0;
+
+	registered = true;
 	return platform_driver_register(&msm_smd_driver);
 }
 
diff --git a/drivers/char/msm_rotator.c b/drivers/char/msm_rotator.c
index b457a00..81a9fa7 100644
--- a/drivers/char/msm_rotator.c
+++ b/drivers/char/msm_rotator.c
@@ -393,6 +393,8 @@
 	case MDP_RGB_565:
 	case MDP_BGR_565:
 	case MDP_YCRYCB_H2V1:
+	case MDP_YCBCR_H1V1:
+	case MDP_YCRCB_H1V1:
 		p->num_planes = 1;
 		p->plane_size[0] = w * h * get_bpp(format);
 		break;
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index bd7729b..9597d18 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -1493,21 +1493,28 @@
 		mutex_unlock(&client->lock);
 		if (copy_to_user((void __user *)arg, &data, sizeof(data)))
 			return -EFAULT;
+		if (data.fd < 0)
+			return data.fd;
 		break;
 	}
 	case ION_IOC_IMPORT:
 	{
 		struct ion_fd_data data;
+		int ret = 0;
 		if (copy_from_user(&data, (void __user *)arg,
 				   sizeof(struct ion_fd_data)))
 			return -EFAULT;
 
 		data.handle = ion_import_fd(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;
+		if (ret < 0)
+			return ret;
 		break;
 	}
 	case ION_IOC_CUSTOM:
@@ -1561,6 +1568,8 @@
 		if (!data.handle)
 			ion_free(client, handle);
 
+		if (ret < 0)
+			return ret;
 		break;
 
 	}
diff --git a/drivers/gpu/ion/msm/msm_ion.c b/drivers/gpu/ion/msm/msm_ion.c
index 15c0ec5..c8bfce3 100644
--- a/drivers/gpu/ion/msm/msm_ion.c
+++ b/drivers/gpu/ion/msm/msm_ion.c
@@ -213,6 +213,45 @@
 	}
 }
 
+static int is_heap_overlapping(const struct ion_platform_heap *heap1,
+				const struct ion_platform_heap *heap2)
+{
+	unsigned long heap1_base = heap1->base;
+	unsigned long heap2_base = heap2->base;
+	unsigned long heap1_end = heap1->base + heap1->size - 1;
+	unsigned long heap2_end = heap2->base + heap2->size - 1;
+
+	if (heap1_base == heap2_base)
+		return 1;
+	if (heap1_base < heap2_base && heap1_end >= heap2_base)
+		return 1;
+	if (heap2_base < heap1_base && heap2_end >= heap1_base)
+		return 1;
+	return 0;
+}
+
+static void check_for_heap_overlap(const struct ion_platform_heap heap_list[],
+				   unsigned long nheaps)
+{
+	unsigned long i;
+	unsigned long j;
+
+	for (i = 0; i < nheaps; ++i) {
+		const struct ion_platform_heap *heap1 = &heap_list[i];
+		if (!heap1->base)
+			continue;
+		for (j = i + 1; j < nheaps; ++j) {
+			const struct ion_platform_heap *heap2 = &heap_list[j];
+			if (!heap2->base)
+				continue;
+			if (is_heap_overlapping(heap1, heap2)) {
+				panic("Memory in heap %s overlaps with heap %s\n",
+					heap1->name, heap2->name);
+			}
+		}
+	}
+}
+
 static int msm_ion_probe(struct platform_device *pdev)
 {
 	struct ion_platform_data *pdata = pdev->dev.platform_data;
@@ -258,6 +297,8 @@
 
 		ion_device_add_heap(idev, heaps[i]);
 	}
+
+	check_for_heap_overlap(pdata->heaps, num_heaps);
 	platform_set_drvdata(pdev, idev);
 	return 0;
 
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 9479302..96390ac 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -69,10 +69,9 @@
 
 static struct adreno_device device_3d0 = {
 	.dev = {
+		KGSL_DEVICE_COMMON_INIT(device_3d0.dev),
 		.name = DEVICE_3D0_NAME,
 		.id = KGSL_DEVICE_3D0,
-		.ver_major = DRIVER_VERSION_MAJOR,
-		.ver_minor = DRIVER_VERSION_MINOR,
 		.mh = {
 			.mharb  = ADRENO_CFG_MHARB,
 			/* Remove 1k boundary check in z470 to avoid a GPU
@@ -92,9 +91,6 @@
 		.pwrctrl = {
 			.irq_name = KGSL_3D0_IRQ,
 		},
-		.mutex = __MUTEX_INITIALIZER(device_3d0.dev.mutex),
-		.state = KGSL_STATE_INIT,
-		.active_cnt = 0,
 		.iomemname = KGSL_3D0_REG_MEMORY,
 		.ftbl = &adreno_functable,
 #ifdef CONFIG_HAS_EARLYSUSPEND
@@ -280,7 +276,7 @@
 
 			/* set page table base */
 			*cmds++ = cp_type0_packet(MH_MMU_PT_BASE, 1);
-			*cmds++ = kgsl_pt_get_base_addr(
+			*cmds++ = kgsl_mmu_pt_get_base_addr(
 					device->mmu.hwpagetable);
 			sizedwords += 4;
 		}
@@ -482,8 +478,6 @@
 	adreno_dev = ADRENO_DEVICE(device);
 	device->parentdev = &pdev->dev;
 
-	init_completion(&device->recovery_gate);
-
 	status = adreno_ringbuffer_init(device);
 	if (status != 0)
 		goto error;
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 2ce2f2b..adf2772 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -25,6 +25,8 @@
 #include <linux/ashmem.h>
 #include <linux/major.h>
 #include <linux/ion.h>
+#include <linux/io.h>
+#include <mach/socinfo.h>
 
 #include "kgsl.h"
 #include "kgsl_debugfs.h"
@@ -385,7 +387,7 @@
 	idr_remove(&dev_priv->device->context_idr, id);
 }
 
-static void kgsl_timestamp_expired(struct work_struct *work)
+void kgsl_timestamp_expired(struct work_struct *work)
 {
 	struct kgsl_device *device = container_of(work, struct kgsl_device,
 		ts_expired_ws);
@@ -415,6 +417,7 @@
 
 	mutex_unlock(&device->mutex);
 }
+EXPORT_SYMBOL(kgsl_timestamp_expired);
 
 static void kgsl_check_idle_locked(struct kgsl_device *device)
 {
@@ -2334,7 +2337,7 @@
 };
 EXPORT_SYMBOL(kgsl_driver);
 
-void kgsl_unregister_device(struct kgsl_device *device)
+static void _unregister_device(struct kgsl_device *device)
 {
 	int minor;
 
@@ -2343,43 +2346,15 @@
 		if (device == kgsl_driver.devp[minor])
 			break;
 	}
-
-	mutex_unlock(&kgsl_driver.devlock);
-
-	if (minor == KGSL_DEVICE_MAX)
-		return;
-
-	kgsl_device_snapshot_close(device);
-
-	kgsl_cffdump_close(device->id);
-	kgsl_pwrctrl_uninit_sysfs(device);
-
-	wake_lock_destroy(&device->idle_wakelock);
-	pm_qos_remove_request(&device->pm_qos_req_dma);
-
-	idr_destroy(&device->context_idr);
-
-	if (device->memstore.hostptr)
-		kgsl_sharedmem_free(&device->memstore);
-
-	kgsl_mmu_close(device);
-
-	if (device->work_queue) {
-		destroy_workqueue(device->work_queue);
-		device->work_queue = NULL;
+	if (minor != KGSL_DEVICE_MAX) {
+		device_destroy(kgsl_driver.class,
+				MKDEV(MAJOR(kgsl_driver.major), minor));
+		kgsl_driver.devp[minor] = NULL;
 	}
-
-	device_destroy(kgsl_driver.class,
-		       MKDEV(MAJOR(kgsl_driver.major), minor));
-
-	mutex_lock(&kgsl_driver.devlock);
-	kgsl_driver.devp[minor] = NULL;
 	mutex_unlock(&kgsl_driver.devlock);
 }
-EXPORT_SYMBOL(kgsl_unregister_device);
 
-int
-kgsl_register_device(struct kgsl_device *device)
+static int _register_device(struct kgsl_device *device)
 {
 	int minor, ret;
 	dev_t dev;
@@ -2393,7 +2368,6 @@
 			break;
 		}
 	}
-
 	mutex_unlock(&kgsl_driver.devlock);
 
 	if (minor == KGSL_DEVICE_MAX) {
@@ -2409,75 +2383,17 @@
 				    device->name);
 
 	if (IS_ERR(device->dev)) {
+		mutex_lock(&kgsl_driver.devlock);
+		kgsl_driver.devp[minor] = NULL;
+		mutex_unlock(&kgsl_driver.devlock);
 		ret = PTR_ERR(device->dev);
 		KGSL_CORE_ERR("device_create(%s): %d\n", device->name, ret);
-		goto err_devlist;
+		return ret;
 	}
 
 	dev_set_drvdata(device->parentdev, device);
-
-	/* Generic device initialization */
-	init_waitqueue_head(&device->wait_queue);
-
-	kgsl_cffdump_open(device->id);
-
-	init_completion(&device->hwaccess_gate);
-	init_completion(&device->suspend_gate);
-
-	ATOMIC_INIT_NOTIFIER_HEAD(&device->ts_notifier_list);
-
-	setup_timer(&device->idle_timer, kgsl_timer, (unsigned long) device);
-	ret = kgsl_create_device_workqueue(device);
-	if (ret)
-		goto err_devlist;
-
-	INIT_WORK(&device->idle_check_ws, kgsl_idle_check);
-	INIT_WORK(&device->ts_expired_ws, kgsl_timestamp_expired);
-
-	INIT_LIST_HEAD(&device->events);
-
-	device->last_expired_ctxt_id = KGSL_CONTEXT_INVALID;
-
-	ret = kgsl_mmu_init(device);
-	if (ret != 0)
-		goto err_dest_work_q;
-
-	ret = kgsl_allocate_contiguous(&device->memstore, KGSL_MEMSTORE_SIZE);
-	if (ret != 0)
-		goto err_close_mmu;
-
-	wake_lock_init(&device->idle_wakelock, WAKE_LOCK_IDLE, device->name);
-	pm_qos_add_request(&device->pm_qos_req_dma, PM_QOS_CPU_DMA_LATENCY,
-				PM_QOS_DEFAULT_VALUE);
-
-	idr_init(&device->context_idr);
-
-	/* Initalize the snapshot engine */
-	kgsl_device_snapshot_init(device);
-
-	/* sysfs and debugfs initalization - failure here is non fatal */
-
-	/* Initialize logging */
-	kgsl_device_debugfs_init(device);
-
-	/* Initialize common sysfs entries */
-	kgsl_pwrctrl_init_sysfs(device);
-
 	return 0;
-
-err_close_mmu:
-	kgsl_mmu_close(device);
-err_dest_work_q:
-	destroy_workqueue(device->work_queue);
-	device->work_queue = NULL;
-err_devlist:
-	mutex_lock(&kgsl_driver.devlock);
-	kgsl_driver.devp[minor] = NULL;
-	mutex_unlock(&kgsl_driver.devlock);
-
-	return ret;
 }
-EXPORT_SYMBOL(kgsl_register_device);
 
 int kgsl_device_platform_probe(struct kgsl_device *device)
 {
@@ -2487,7 +2403,12 @@
 	struct platform_device *pdev =
 		container_of(device->parentdev, struct platform_device, dev);
 
-	pm_runtime_enable(device->parentdev);
+	status = _register_device(device);
+	if (status)
+		return status;
+
+	/* Initialize logging first, so that failures below actually print. */
+	kgsl_device_debugfs_init(device);
 
 	status = kgsl_pwrctrl_init(device);
 	if (status)
@@ -2512,29 +2433,40 @@
 	device->reg_phys = res->start;
 	device->reg_len = resource_size(res);
 
-	if (!request_mem_region(device->reg_phys, device->reg_len,
-		device->name)) {
+	if (!devm_request_mem_region(device->dev, device->reg_phys,
+				device->reg_len, device->name)) {
 		KGSL_DRV_ERR(device, "request_mem_region failed\n");
 		status = -ENODEV;
 		goto error_pwrctrl_close;
 	}
 
-	device->reg_virt = ioremap(device->reg_phys, device->reg_len);
+	device->reg_virt = devm_ioremap(device->dev, device->reg_phys,
+					device->reg_len);
 
 	if (device->reg_virt == NULL) {
 		KGSL_DRV_ERR(device, "ioremap failed\n");
 		status = -ENODEV;
-		goto error_release_mem;
+		goto error_pwrctrl_close;
+	}
+	/*acquire interrupt */
+	device->pwrctrl.interrupt_num =
+		platform_get_irq_byname(pdev, device->pwrctrl.irq_name);
+
+	if (device->pwrctrl.interrupt_num <= 0) {
+		KGSL_DRV_ERR(device, "platform_get_irq_byname failed: %d\n",
+					 device->pwrctrl.interrupt_num);
+		status = -EINVAL;
+		goto error_pwrctrl_close;
 	}
 
-	status = request_irq(device->pwrctrl.interrupt_num, kgsl_irq_handler,
-			     IRQF_TRIGGER_HIGH, device->name, device);
+	status = devm_request_irq(device->dev, device->pwrctrl.interrupt_num,
+				  kgsl_irq_handler, IRQF_TRIGGER_HIGH,
+				  device->name, device);
 	if (status) {
 		KGSL_DRV_ERR(device, "request_irq(%d) failed: %d\n",
 			      device->pwrctrl.interrupt_num, status);
-		goto error_iounmap;
+		goto error_pwrctrl_close;
 	}
-	device->pwrctrl.have_irq = 1;
 	disable_irq(device->pwrctrl.interrupt_num);
 
 	KGSL_DRV_INFO(device,
@@ -2544,38 +2476,78 @@
 
 	result = kgsl_drm_init(pdev);
 	if (result)
-		goto error_iounmap;
+		goto error_pwrctrl_close;
 
-	status = kgsl_register_device(device);
-	if (!status)
-		return status;
+	kgsl_cffdump_open(device->id);
 
-	free_irq(device->pwrctrl.interrupt_num, NULL);
-	device->pwrctrl.have_irq = 0;
-error_iounmap:
-	iounmap(device->reg_virt);
-	device->reg_virt = NULL;
-error_release_mem:
-	release_mem_region(device->reg_phys, device->reg_len);
+	setup_timer(&device->idle_timer, kgsl_timer, (unsigned long) device);
+	status = kgsl_create_device_workqueue(device);
+	if (status)
+		goto error_pwrctrl_close;
+
+	status = kgsl_mmu_init(device);
+	if (status != 0) {
+		KGSL_DRV_ERR(device, "kgsl_mmu_init failed %d\n", status);
+		goto error_dest_work_q;
+	}
+
+	status = kgsl_allocate_contiguous(&device->memstore,
+		sizeof(struct kgsl_devmemstore));
+
+	if (status != 0) {
+		KGSL_DRV_ERR(device, "kgsl_allocate_contiguous failed %d\n",
+				status);
+		goto error_close_mmu;
+	}
+
+	wake_lock_init(&device->idle_wakelock, WAKE_LOCK_IDLE, device->name);
+	pm_qos_add_request(&device->pm_qos_req_dma, PM_QOS_CPU_DMA_LATENCY,
+				PM_QOS_DEFAULT_VALUE);
+
+	/* Initalize the snapshot engine */
+	kgsl_device_snapshot_init(device);
+
+	/* Initialize common sysfs entries */
+	kgsl_pwrctrl_init_sysfs(device);
+
+	return 0;
+
+error_close_mmu:
+	kgsl_mmu_close(device);
+error_dest_work_q:
+	destroy_workqueue(device->work_queue);
+	device->work_queue = NULL;
 error_pwrctrl_close:
 	kgsl_pwrctrl_close(device);
 error:
+	_unregister_device(device);
 	return status;
 }
 EXPORT_SYMBOL(kgsl_device_platform_probe);
 
 void kgsl_device_platform_remove(struct kgsl_device *device)
 {
-	kgsl_unregister_device(device);
+	kgsl_device_snapshot_close(device);
 
-	if (device->reg_virt != NULL) {
-		iounmap(device->reg_virt);
-		device->reg_virt = NULL;
-		release_mem_region(device->reg_phys, device->reg_len);
+	kgsl_cffdump_close(device->id);
+	kgsl_pwrctrl_uninit_sysfs(device);
+
+	wake_lock_destroy(&device->idle_wakelock);
+	pm_qos_remove_request(&device->pm_qos_req_dma);
+
+	idr_destroy(&device->context_idr);
+
+	kgsl_sharedmem_free(&device->memstore);
+
+	kgsl_mmu_close(device);
+
+	if (device->work_queue) {
+		destroy_workqueue(device->work_queue);
+		device->work_queue = NULL;
 	}
 	kgsl_pwrctrl_close(device);
 
-	pm_runtime_disable(device->parentdev);
+	_unregister_device(device);
 }
 EXPORT_SYMBOL(kgsl_device_platform_remove);
 
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index b42e606..0964458 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -199,6 +199,26 @@
 	s64 on_time;
 };
 
+void kgsl_timestamp_expired(struct work_struct *work);
+
+#define KGSL_DEVICE_COMMON_INIT(_dev) \
+	.hwaccess_gate = COMPLETION_INITIALIZER((_dev).hwaccess_gate),\
+	.suspend_gate = COMPLETION_INITIALIZER((_dev).suspend_gate),\
+	.recovery_gate = COMPLETION_INITIALIZER((_dev).recovery_gate),\
+	.ts_notifier_list = ATOMIC_NOTIFIER_INIT((_dev).ts_notifier_list),\
+	.idle_check_ws = __WORK_INITIALIZER((_dev).idle_check_ws,\
+			kgsl_idle_check),\
+	.ts_expired_ws  = __WORK_INITIALIZER((_dev).ts_expired_ws,\
+			kgsl_timestamp_expired),\
+	.context_idr = IDR_INIT((_dev).context_idr),\
+	.events = LIST_HEAD_INIT((_dev).events),\
+	.wait_queue = __WAIT_QUEUE_HEAD_INITIALIZER((_dev).wait_queue),\
+	.mutex = __MUTEX_INITIALIZER((_dev).mutex),\
+	.state = KGSL_STATE_INIT,\
+	.ver_major = DRIVER_VERSION_MAJOR,\
+	.ver_minor = DRIVER_VERSION_MINOR,\
+	.last_expired_ctxt_id = KGSL_CONTEXT_INVALID
+
 struct kgsl_context {
 	uint32_t id;
 
diff --git a/drivers/gpu/msm/kgsl_gpummu.c b/drivers/gpu/msm/kgsl_gpummu.c
index 880fde1..ab47f40 100644
--- a/drivers/gpu/msm/kgsl_gpummu.c
+++ b/drivers/gpu/msm/kgsl_gpummu.c
@@ -708,6 +708,13 @@
 	return ptbase;
 }
 
+static unsigned int
+kgsl_gpummu_pt_get_base_addr(struct kgsl_pagetable *pt)
+{
+	struct kgsl_gpummu_pt *gpummu_pt = pt->priv;
+	return gpummu_pt->base.gpuaddr;
+}
+
 struct kgsl_mmu_ops gpummu_ops = {
 	.mmu_init = kgsl_gpummu_init,
 	.mmu_close = kgsl_gpummu_close,
@@ -719,6 +726,9 @@
 	.mmu_get_current_ptbase = kgsl_gpummu_get_current_ptbase,
 	.mmu_enable_clk = NULL,
 	.mmu_disable_clk = NULL,
+	.mmu_get_hwpagetable_asid = NULL,
+	.mmu_get_pt_lsb = NULL,
+	.mmu_get_reg_map_desc = NULL,
 };
 
 struct kgsl_mmu_pt_ops gpummu_pt_ops = {
@@ -727,4 +737,5 @@
 	.mmu_create_pagetable = kgsl_gpummu_create_pagetable,
 	.mmu_destroy_pagetable = kgsl_gpummu_destroy_pagetable,
 	.mmu_pt_equal = kgsl_gpummu_pt_equal,
+	.mmu_pt_get_base_addr = kgsl_gpummu_pt_get_base_addr,
 };
diff --git a/drivers/gpu/msm/kgsl_gpummu.h b/drivers/gpu/msm/kgsl_gpummu.h
index c61a8b2..caa5df1 100644
--- a/drivers/gpu/msm/kgsl_gpummu.h
+++ b/drivers/gpu/msm/kgsl_gpummu.h
@@ -75,9 +75,4 @@
 void *kgsl_gpummu_ptpool_init(int entries);
 void kgsl_gpummu_ptpool_destroy(void *ptpool);
 
-static inline unsigned int kgsl_pt_get_base_addr(struct kgsl_pagetable *pt)
-{
-	struct kgsl_gpummu_pt *gpummu_pt = pt->priv;
-	return gpummu_pt->base.gpuaddr;
-}
 #endif /* __KGSL_GPUMMU_H */
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 4f27e6c..2f83a40 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -96,27 +96,77 @@
 	return ret;
 }
 
+/*
+ * kgsl_iommu_pt_equal - Check if pagetables are equal
+ * @pt - Pointer to pagetable
+ * @pt_base - Address of a pagetable that the IOMMU register is
+ * programmed with
+ *
+ * Checks whether the pt_base is equal to the base address of
+ * the pagetable which is contained in the pt structure
+ * Return - Non-zero if the pagetable addresses are equal else 0
+ */
 static int kgsl_iommu_pt_equal(struct kgsl_pagetable *pt,
 					unsigned int pt_base)
 {
-	struct iommu_domain *domain = pt ? pt->priv : NULL;
-	return domain && pt_base && ((unsigned int)domain == pt_base);
+	struct kgsl_iommu_pt *iommu_pt = pt ? pt->priv : NULL;
+	unsigned int domain_ptbase = iommu_pt ?
+				iommu_get_pt_base_addr(iommu_pt->domain) : 0;
+	/* Only compare the valid address bits of the pt_base */
+	domain_ptbase &= (KGSL_IOMMU_TTBR0_PA_MASK <<
+				KGSL_IOMMU_TTBR0_PA_SHIFT);
+	pt_base &= (KGSL_IOMMU_TTBR0_PA_MASK <<
+				KGSL_IOMMU_TTBR0_PA_SHIFT);
+	return domain_ptbase && pt_base &&
+		(domain_ptbase == pt_base);
 }
 
+/*
+ * kgsl_iommu_destroy_pagetable - Free up reaources help by a pagetable
+ * @mmu_specific_pt - Pointer to pagetable which is to be freed
+ *
+ * Return - void
+ */
 static void kgsl_iommu_destroy_pagetable(void *mmu_specific_pt)
 {
-	struct iommu_domain *domain = mmu_specific_pt;
-	if (domain)
-		iommu_domain_free(domain);
+	struct kgsl_iommu_pt *iommu_pt = mmu_specific_pt;
+	if (iommu_pt->domain)
+		iommu_domain_free(iommu_pt->domain);
+	if (iommu_pt->iommu) {
+		if ((KGSL_IOMMU_ASID_REUSE == iommu_pt->asid) &&
+			iommu_pt->iommu->asid_reuse)
+			iommu_pt->iommu->asid_reuse--;
+		if (!iommu_pt->iommu->asid_reuse ||
+			(KGSL_IOMMU_ASID_REUSE != iommu_pt->asid))
+			clear_bit(iommu_pt->asid, iommu_pt->iommu->asids);
+	}
+	kfree(iommu_pt);
 }
 
+/*
+ * kgsl_iommu_create_pagetable - Create a IOMMU pagetable
+ *
+ * Allocate memory to hold a pagetable and allocate the IOMMU
+ * domain which is the actual IOMMU pagetable
+ * Return - void
+ */
 void *kgsl_iommu_create_pagetable(void)
 {
-	struct iommu_domain *domain = iommu_domain_alloc(0);
-	if (!domain)
-		KGSL_CORE_ERR("Failed to create iommu domain\n");
+	struct kgsl_iommu_pt *iommu_pt;
 
-	return domain;
+	iommu_pt = kzalloc(sizeof(struct kgsl_iommu_pt), GFP_KERNEL);
+	if (!iommu_pt) {
+		KGSL_CORE_ERR("kzalloc(%d) failed\n",
+				sizeof(struct kgsl_iommu_pt));
+		return NULL;
+	}
+	iommu_pt->domain = iommu_domain_alloc(0);
+	if (!iommu_pt->domain) {
+		KGSL_CORE_ERR("Failed to create iommu domain\n");
+		kfree(iommu_pt);
+		return NULL;
+	}
+	return iommu_pt;
 }
 
 /*
@@ -133,25 +183,25 @@
  */
 static void kgsl_detach_pagetable_iommu_domain(struct kgsl_mmu *mmu)
 {
-	struct iommu_domain *domain;
+	struct kgsl_iommu_pt *iommu_pt;
 	struct kgsl_iommu *iommu = mmu->priv;
 	int i, j;
 
 	BUG_ON(mmu->hwpagetable == NULL);
 	BUG_ON(mmu->hwpagetable->priv == NULL);
 
-	domain = mmu->hwpagetable->priv;
+	iommu_pt = mmu->hwpagetable->priv;
 
 	for (i = 0; i < iommu->unit_count; i++) {
 		struct kgsl_iommu_unit *iommu_unit = &iommu->iommu_units[i];
 		for (j = 0; j < iommu_unit->dev_count; j++) {
 			if (iommu_unit->dev[j].attached) {
-				iommu_detach_device(domain,
+				iommu_detach_device(iommu_pt->domain,
 						iommu_unit->dev[j].dev);
 				iommu_unit->dev[j].attached = false;
 				KGSL_MEM_INFO(mmu->device, "iommu %p detached "
 					"from user dev of MMU: %p\n",
-					domain, mmu);
+					iommu_pt->domain, mmu);
 			}
 		}
 	}
@@ -172,14 +222,14 @@
  */
 static int kgsl_attach_pagetable_iommu_domain(struct kgsl_mmu *mmu)
 {
-	struct iommu_domain *domain;
+	struct kgsl_iommu_pt *iommu_pt;
 	struct kgsl_iommu *iommu = mmu->priv;
 	int i, j, ret = 0;
 
 	BUG_ON(mmu->hwpagetable == NULL);
 	BUG_ON(mmu->hwpagetable->priv == NULL);
 
-	domain = mmu->hwpagetable->priv;
+	iommu_pt = mmu->hwpagetable->priv;
 
 	/*
 	 * Loop through all the iommu devcies under all iommu units and
@@ -189,7 +239,7 @@
 		struct kgsl_iommu_unit *iommu_unit = &iommu->iommu_units[i];
 		for (j = 0; j < iommu_unit->dev_count; j++) {
 			if (!iommu_unit->dev[j].attached) {
-				ret = iommu_attach_device(domain,
+				ret = iommu_attach_device(iommu_pt->domain,
 							iommu_unit->dev[j].dev);
 				if (ret) {
 					KGSL_MEM_ERR(mmu->device,
@@ -200,8 +250,8 @@
 				iommu_unit->dev[j].attached = true;
 				KGSL_MEM_INFO(mmu->device,
 				"iommu pt %p attached to dev %p, ctx_id %d\n",
-					domain, iommu_unit->dev[j].dev,
-					iommu_unit->dev[j].ctx_id);
+				iommu_pt->domain, iommu_unit->dev[j].dev,
+				iommu_unit->dev[j].ctx_id);
 			}
 		}
 	}
@@ -352,19 +402,66 @@
 	return ret;
 }
 
+/*
+ * kgsl_iommu_pt_get_base_addr - Get the address of the pagetable that the
+ * IOMMU ttbr0 register is programmed with
+ * @pt - kgsl pagetable pointer that contains the IOMMU domain pointer
+ *
+ * Return - actual pagetable address that the ttbr0 register is programmed
+ * with
+ */
+static unsigned int kgsl_iommu_pt_get_base_addr(struct kgsl_pagetable *pt)
+{
+	struct kgsl_iommu_pt *iommu_pt = pt->priv;
+	return iommu_get_pt_base_addr(iommu_pt->domain);
+}
+
+/*
+ * kgsl_iommu_get_pt_lsb - Return the lsb of the ttbr0 IOMMU register
+ * @mmu - Pointer to mmu structure
+ * @hostptr - Pointer to the IOMMU register map. This is used to match
+ * the iommu device whose lsb value is to be returned
+ * @ctx_id - The context bank whose lsb valus is to be returned
+ * Return - returns the lsb which is the last 14 bits of the ttbr0 IOMMU
+ * register. ttbr0 is the actual PTBR for of the IOMMU. The last 14 bits
+ * are only programmed once in the beginning when a domain is attached
+ * does not change.
+ */
+static int kgsl_iommu_get_pt_lsb(struct kgsl_mmu *mmu,
+				unsigned int unit_id,
+				enum kgsl_iommu_context_id ctx_id)
+{
+	struct kgsl_iommu *iommu = mmu->priv;
+	int i, j;
+	for (i = 0; i < iommu->unit_count; i++) {
+		struct kgsl_iommu_unit *iommu_unit = &iommu->iommu_units[i];
+		for (j = 0; j < iommu_unit->dev_count; j++)
+			if (unit_id == i &&
+				ctx_id == iommu_unit->dev[j].ctx_id)
+				return iommu_unit->dev[j].pt_lsb;
+	}
+	return 0;
+}
+
 static void kgsl_iommu_setstate(struct kgsl_mmu *mmu,
 				struct kgsl_pagetable *pagetable)
 {
 	if (mmu->flags & KGSL_FLAGS_STARTED) {
+		struct kgsl_iommu *iommu = mmu->priv;
+		struct kgsl_iommu_pt *iommu_pt = pagetable->priv;
 		/* page table not current, then setup mmu to use new
 		 *  specified page table
 		 */
 		if (mmu->hwpagetable != pagetable) {
-			kgsl_idle(mmu->device, KGSL_TIMEOUT_DEFAULT);
-			kgsl_detach_pagetable_iommu_domain(mmu);
+			unsigned int flags = 0;
 			mmu->hwpagetable = pagetable;
-			if (mmu->hwpagetable)
-				kgsl_attach_pagetable_iommu_domain(mmu);
+			/* force tlb flush if asid is reused */
+			if (iommu->asid_reuse &&
+				(KGSL_IOMMU_ASID_REUSE == iommu_pt->asid))
+				flags |= KGSL_MMUFLAGS_TLBFLUSH;
+			flags |= kgsl_mmu_pt_get_flags(mmu->hwpagetable,
+							mmu->device->id);
+			kgsl_setstate(mmu, KGSL_MMUFLAGS_PTUPDATE | flags);
 		}
 	}
 }
@@ -385,6 +482,14 @@
 				sizeof(struct kgsl_iommu));
 		return -ENOMEM;
 	}
+	iommu->asids = kzalloc(BITS_TO_LONGS(KGSL_IOMMU_MAX_ASIDS) *
+				sizeof(unsigned long), GFP_KERNEL);
+	if (!iommu->asids) {
+		KGSL_CORE_ERR("kzalloc(%d) failed\n",
+				sizeof(struct kgsl_iommu));
+		status = -ENOMEM;
+		goto done;
+	}
 
 	mmu->priv = iommu;
 	status = kgsl_get_iommu_ctxt(mmu);
@@ -398,6 +503,7 @@
 			__func__);
 done:
 	if (status) {
+		kfree(iommu->asids);
 		kfree(iommu);
 		mmu->priv = NULL;
 	}
@@ -418,6 +524,7 @@
 	int status = 0;
 	int i = 0;
 	struct kgsl_iommu *iommu = mmu->priv;
+	struct kgsl_iommu_pt *iommu_pt;
 
 	mmu->defaultpagetable = kgsl_mmu_getpagetable(KGSL_MMU_GLOBAL_PT);
 	/* Return error if the default pagetable doesn't exist */
@@ -437,6 +544,14 @@
 			goto err;
 		}
 	}
+	/*
+	 * The dafault pagetable always has asid 0 assigned by the iommu driver
+	 * and asid 1 is assigned to the private context.
+	 */
+	iommu_pt = mmu->defaultpagetable->priv;
+	iommu_pt->asid = 0;
+	set_bit(0, iommu->asids);
+	set_bit(1, iommu->asids);
 	return status;
 err:
 	for (i--; i >= 0; i--) {
@@ -454,6 +569,8 @@
 static int kgsl_iommu_start(struct kgsl_mmu *mmu)
 {
 	int status;
+	struct kgsl_iommu *iommu = mmu->priv;
+	int i, j;
 
 	if (mmu->flags & KGSL_FLAGS_STARTED)
 		return 0;
@@ -474,7 +591,42 @@
 		kgsl_detach_pagetable_iommu_domain(mmu);
 		mmu->hwpagetable = NULL;
 	}
+	status = kgsl_iommu_enable_clk(mmu, KGSL_IOMMU_CONTEXT_USER);
+	if (status) {
+		KGSL_CORE_ERR("clk enable failed\n");
+		goto done;
+	}
+	status = kgsl_iommu_enable_clk(mmu, KGSL_IOMMU_CONTEXT_PRIV);
+	if (status) {
+		KGSL_CORE_ERR("clk enable failed\n");
+		goto done;
+	}
+	/* Get the lsb value of pagetables set in the IOMMU ttbr0 register as
+	 * that value should not change when we change pagetables, so while
+	 * changing pagetables we can use this lsb value of the pagetable w/o
+	 * having to read it again
+	 */
+	for (i = 0; i < iommu->unit_count; i++) {
+		struct kgsl_iommu_unit *iommu_unit = &iommu->iommu_units[i];
+		for (j = 0; j < iommu_unit->dev_count; j++)
+			iommu_unit->dev[j].pt_lsb = KGSL_IOMMMU_PT_LSB(
+						KGSL_IOMMU_GET_IOMMU_REG(
+						iommu_unit->reg_map.hostptr,
+						iommu_unit->dev[j].ctx_id,
+						TTBR0));
+	}
+	iommu->asid = KGSL_IOMMU_GET_IOMMU_REG(
+				iommu->iommu_units[0].reg_map.hostptr,
+				KGSL_IOMMU_CONTEXT_USER,
+				CONTEXTIDR);
 
+	kgsl_iommu_disable_clk(mmu);
+
+done:
+	if (status) {
+		kgsl_iommu_disable_clk(mmu);
+		kgsl_detach_pagetable_iommu_domain(mmu);
+	}
 	return status;
 }
 
@@ -484,8 +636,7 @@
 {
 	int ret;
 	unsigned int range = memdesc->size;
-	struct iommu_domain *domain = (struct iommu_domain *)
-					mmu_specific_pt;
+	struct kgsl_iommu_pt *iommu_pt = mmu_specific_pt;
 
 	/* All GPU addresses as assigned are page aligned, but some
 	   functions purturb the gpuaddr with an offset, so apply the
@@ -496,10 +647,10 @@
 	if (range == 0 || gpuaddr == 0)
 		return 0;
 
-	ret = iommu_unmap_range(domain, gpuaddr, range);
+	ret = iommu_unmap_range(iommu_pt->domain, gpuaddr, range);
 	if (ret)
 		KGSL_CORE_ERR("iommu_unmap_range(%p, %x, %d) failed "
-			"with err: %d\n", domain, gpuaddr,
+			"with err: %d\n", iommu_pt->domain, gpuaddr,
 			range, ret);
 
 	return 0;
@@ -513,20 +664,20 @@
 {
 	int ret;
 	unsigned int iommu_virt_addr;
-	struct iommu_domain *domain = mmu_specific_pt;
+	struct kgsl_iommu_pt *iommu_pt = mmu_specific_pt;
 
-	BUG_ON(NULL == domain);
+	BUG_ON(NULL == iommu_pt);
 
 
 	iommu_virt_addr = memdesc->gpuaddr;
 
-	ret = iommu_map_range(domain, iommu_virt_addr, memdesc->sg,
+	ret = iommu_map_range(iommu_pt->domain, iommu_virt_addr, memdesc->sg,
 				memdesc->size, (IOMMU_READ | IOMMU_WRITE));
 	if (ret) {
 		KGSL_CORE_ERR("iommu_map_range(%p, %x, %p, %d, %d) "
-				"failed with err: %d\n", domain,
+				"failed with err: %d\n", iommu_pt->domain,
 				iommu_virt_addr, memdesc->sg, memdesc->size,
-				0, ret);
+				(IOMMU_READ | IOMMU_WRITE), ret);
 		return ret;
 	}
 
@@ -573,6 +724,8 @@
 	}
 	if (mmu->defaultpagetable)
 		kgsl_mmu_putpagetable(mmu->defaultpagetable);
+	kfree(iommu->asids);
+	kfree(iommu);
 
 	return 0;
 }
@@ -592,17 +745,168 @@
 				KGSL_IOMMU_TTBR0_PA_SHIFT);
 }
 
+/*
+ * kgsl_iommu_get_hwpagetable_asid - Returns asid(application space ID) for a
+ * pagetable
+ * @mmu - Pointer to mmu structure
+ *
+ * Allocates an asid to a IOMMU domain if it does not already have one. asid's
+ * are unique identifiers for pagetable that can be used to selectively flush
+ * tlb entries of the IOMMU unit.
+ * Return - asid to be used with the IOMMU domain
+ */
+static int kgsl_iommu_get_hwpagetable_asid(struct kgsl_mmu *mmu)
+{
+	struct kgsl_iommu *iommu = mmu->priv;
+	struct kgsl_iommu_pt *iommu_pt = mmu->hwpagetable->priv;
+
+	/*
+	 * If the iommu pagetable does not have any asid assigned and is not the
+	 * default pagetable then assign asid.
+	 */
+	if (!iommu_pt->asid && iommu_pt != mmu->defaultpagetable->priv) {
+		iommu_pt->asid = find_first_zero_bit(iommu->asids,
+							KGSL_IOMMU_MAX_ASIDS);
+		/* No free bits means reuse asid */
+		if (iommu_pt->asid >= KGSL_IOMMU_MAX_ASIDS) {
+			iommu_pt->asid = KGSL_IOMMU_ASID_REUSE;
+			iommu->asid_reuse++;
+		}
+		set_bit(iommu_pt->asid, iommu->asids);
+		/*
+		 * Store pointer to asids list so that during pagetable destroy
+		 * the asid assigned to this pagetable may be cleared
+		 */
+		iommu_pt->iommu = iommu;
+	}
+	/* Return the asid + the constant part of asid that never changes */
+	return (iommu_pt->asid & (KGSL_IOMMU_CONTEXTIDR_ASID_MASK <<
+				KGSL_IOMMU_CONTEXTIDR_ASID_SHIFT)) +
+		(iommu->asid & ~(KGSL_IOMMU_CONTEXTIDR_ASID_MASK <<
+				KGSL_IOMMU_CONTEXTIDR_ASID_SHIFT));
+}
+
+/*
+ * kgsl_iommu_default_setstate - Change the IOMMU pagetable or flush IOMMU tlb
+ * of the primary context bank
+ * @mmu - Pointer to mmu structure
+ * @flags - Flags indicating whether pagetable has to chnage or tlb is to be
+ * flushed or both
+ *
+ * Based on flags set the new pagetable fo the IOMMU unit or flush it's tlb or
+ * do both by doing direct register writes to the IOMMu registers through the
+ * cpu
+ * Return - void
+ */
+static void kgsl_iommu_default_setstate(struct kgsl_mmu *mmu,
+					uint32_t flags)
+{
+	struct kgsl_iommu *iommu = mmu->priv;
+	int temp;
+	int i;
+	unsigned int pt_base = kgsl_iommu_pt_get_base_addr(
+					mmu->hwpagetable);
+	unsigned int pt_val;
+
+	if (kgsl_iommu_enable_clk(mmu, KGSL_IOMMU_CONTEXT_USER)) {
+		KGSL_DRV_ERR(mmu->device, "Failed to enable iommu clocks\n");
+		return;
+	}
+	/* Mask off the lsb of the pt base address since lsb will not change */
+	pt_base &= (KGSL_IOMMU_TTBR0_PA_MASK << KGSL_IOMMU_TTBR0_PA_SHIFT);
+	if (flags & KGSL_MMUFLAGS_PTUPDATE) {
+		kgsl_idle(mmu->device, KGSL_TIMEOUT_DEFAULT);
+		for (i = 0; i < iommu->unit_count; i++) {
+			/* get the lsb value which should not change when
+			 * changing ttbr0 */
+			pt_val = kgsl_iommu_get_pt_lsb(mmu, i,
+						KGSL_IOMMU_CONTEXT_USER);
+			pt_val += pt_base;
+
+			KGSL_IOMMU_SET_IOMMU_REG(
+				iommu->iommu_units[i].reg_map.hostptr,
+				KGSL_IOMMU_CONTEXT_USER, TTBR0, pt_val);
+
+			mb();
+			temp = KGSL_IOMMU_GET_IOMMU_REG(
+				iommu->iommu_units[i].reg_map.hostptr,
+				KGSL_IOMMU_CONTEXT_USER, TTBR0);
+			/* Set asid */
+			KGSL_IOMMU_SET_IOMMU_REG(
+				iommu->iommu_units[i].reg_map.hostptr,
+				KGSL_IOMMU_CONTEXT_USER, CONTEXTIDR,
+				kgsl_iommu_get_hwpagetable_asid(mmu));
+			mb();
+			temp = KGSL_IOMMU_GET_IOMMU_REG(
+					iommu->iommu_units[i].reg_map.hostptr,
+					KGSL_IOMMU_CONTEXT_USER, CONTEXTIDR);
+		}
+	}
+	/* Flush tlb */
+	if (flags & KGSL_MMUFLAGS_TLBFLUSH) {
+		for (i = 0; i < iommu->unit_count; i++) {
+			KGSL_IOMMU_SET_IOMMU_REG(
+				iommu->iommu_units[i].reg_map.hostptr,
+				KGSL_IOMMU_CONTEXT_USER, CTX_TLBIASID,
+				kgsl_iommu_get_hwpagetable_asid(mmu));
+			mb();
+		}
+	}
+	/* Disable smmu clock */
+	kgsl_iommu_disable_clk(mmu);
+}
+
+/*
+ * kgsl_iommu_get_reg_map_desc - Returns an array of pointers that contain
+ * the address of memory descriptors which map the IOMMU registers
+ * @mmu - Pointer to mmu structure
+ * @reg_map_desc - Out parameter in which the address of the array containing
+ * pointers to register map descriptors is returned. The caller is supposed
+ * to free this array
+ *
+ * Return - The number of iommu units which is also the number of register
+ * mapped descriptor arrays which the out parameter will have
+ */
+static int kgsl_iommu_get_reg_map_desc(struct kgsl_mmu *mmu,
+					void **reg_map_desc)
+{
+	struct kgsl_iommu *iommu = mmu->priv;
+	void **reg_desc_ptr;
+	int i;
+
+	/*
+	 * Alocate array of pointers that will hold address of the register map
+	 * descriptors
+	 */
+	reg_desc_ptr = kmalloc(iommu->unit_count *
+			sizeof(struct kgsl_memdesc *), GFP_KERNEL);
+	if (!reg_desc_ptr) {
+		KGSL_CORE_ERR("Failed to kmalloc(%d)\n",
+			iommu->unit_count * sizeof(struct kgsl_memdesc *));
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < iommu->unit_count; i++)
+		reg_desc_ptr[i] = &(iommu->iommu_units[i].reg_map);
+
+	*reg_map_desc = reg_desc_ptr;
+	return i;
+}
+
 struct kgsl_mmu_ops iommu_ops = {
 	.mmu_init = kgsl_iommu_init,
 	.mmu_close = kgsl_iommu_close,
 	.mmu_start = kgsl_iommu_start,
 	.mmu_stop = kgsl_iommu_stop,
 	.mmu_setstate = kgsl_iommu_setstate,
-	.mmu_device_setstate = NULL,
+	.mmu_device_setstate = kgsl_iommu_default_setstate,
 	.mmu_pagefault = NULL,
 	.mmu_get_current_ptbase = kgsl_iommu_get_current_ptbase,
 	.mmu_enable_clk = kgsl_iommu_enable_clk,
 	.mmu_disable_clk = kgsl_iommu_disable_clk,
+	.mmu_get_hwpagetable_asid = kgsl_iommu_get_hwpagetable_asid,
+	.mmu_get_pt_lsb = kgsl_iommu_get_pt_lsb,
+	.mmu_get_reg_map_desc = kgsl_iommu_get_reg_map_desc,
 };
 
 struct kgsl_mmu_pt_ops iommu_pt_ops = {
@@ -611,4 +915,5 @@
 	.mmu_create_pagetable = kgsl_iommu_create_pagetable,
 	.mmu_destroy_pagetable = kgsl_iommu_destroy_pagetable,
 	.mmu_pt_equal = kgsl_iommu_pt_equal,
+	.mmu_pt_get_base_addr = kgsl_iommu_pt_get_base_addr,
 };
diff --git a/drivers/gpu/msm/kgsl_iommu.h b/drivers/gpu/msm/kgsl_iommu.h
index 5a92f513..c2e84a6 100644
--- a/drivers/gpu/msm/kgsl_iommu.h
+++ b/drivers/gpu/msm/kgsl_iommu.h
@@ -26,6 +26,10 @@
 #define KGSL_IOMMU_CONTEXTIDR_ASID_SHIFT	0
 #define KGSL_IOMMU_CTX_TLBIASID			0x804
 #define KGSL_IOMMU_CTX_SHIFT			12
+
+#define KGSL_IOMMU_MAX_ASIDS			256
+#define KGSL_IOMMU_ASID_REUSE			2
+
 /*
  * Max number of iommu units that the gpu core can have
  * On APQ8064, KGSL can control a maximum of 2 IOMMU units.
@@ -35,6 +39,22 @@
 /* Max number of iommu contexts per IOMMU unit */
 #define KGSL_IOMMU_MAX_DEVS_PER_UNIT 2
 
+/* Macros to read/write IOMMU registers */
+#define KGSL_IOMMU_SET_IOMMU_REG(base_addr, ctx, REG, val)		\
+		writel_relaxed(val, base_addr +				\
+				(ctx << KGSL_IOMMU_CTX_SHIFT) +		\
+				KGSL_IOMMU_##REG)
+
+#define KGSL_IOMMU_GET_IOMMU_REG(base_addr, ctx, REG)			\
+		readl_relaxed(base_addr +				\
+			(ctx << KGSL_IOMMU_CTX_SHIFT) +			\
+			KGSL_IOMMU_##REG)
+
+/* Gets the lsb value of pagetable */
+#define KGSL_IOMMMU_PT_LSB(pt_val)					\
+		(pt_val & ~(KGSL_IOMMU_TTBR0_PA_MASK <<			\
+				KGSL_IOMMU_TTBR0_PA_SHIFT))
+
 /*
  * struct kgsl_iommu_device - Structure holding data about iommu contexts
  * @dev: Device pointer to iommu context
@@ -81,6 +101,7 @@
  * @asids: A bit structure indicating which id's are presently used
  * @asid: Contains the initial value of IOMMU_CONTEXTIDR when a domain
  * is first attached
+ * asid_reuse: Holds the number of times the reuse asid is reused
  */
 struct kgsl_iommu {
 	struct kgsl_iommu_unit iommu_units[KGSL_IOMMU_MAX_UNITS];
@@ -89,7 +110,19 @@
 	struct kgsl_device *device;
 	unsigned long *asids;
 	unsigned int asid;
-	unsigned int active_ctx;
+	unsigned int asid_reuse;
+};
+
+/*
+ * struct kgsl_iommu_pt - Iommu pagetable structure private to kgsl driver
+ * @domain: Pointer to the iommu domain that contains the iommu pagetable
+ * @iommu: Pointer to iommu structure
+ * @asid: The asid assigned to this domain
+ */
+struct kgsl_iommu_pt {
+	struct iommu_domain *domain;
+	struct kgsl_iommu *iommu;
+	unsigned int asid;
 };
 
 #endif
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
index 5fdc182..606d861 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -521,11 +521,8 @@
 	if (KGSL_MMU_TYPE_NONE == kgsl_mmu_type)
 		return (void *)(-1);
 
-#ifdef CONFIG_KGSL_PER_PROCESS_PAGE_TABLE
-	if (KGSL_MMU_TYPE_IOMMU == kgsl_mmu_type)
-		name = KGSL_MMU_GLOBAL_PT;
-#else
-		name = KGSL_MMU_GLOBAL_PT;
+#ifndef CONFIG_KGSL_PER_PROCESS_PAGE_TABLE
+	name = KGSL_MMU_GLOBAL_PT;
 #endif
 	pt = kgsl_get_pagetable(name);
 
@@ -546,7 +543,8 @@
 	struct kgsl_device *device = mmu->device;
 	if (KGSL_MMU_TYPE_NONE == kgsl_mmu_type)
 		return;
-	else if (device->ftbl->setstate)
+	else if (device->ftbl->setstate && (KGSL_MMU_TYPE_IOMMU !=
+						kgsl_mmu_type))
 		device->ftbl->setstate(device, flags);
 	else if (mmu->mmu_ops->mmu_device_setstate)
 		mmu->mmu_ops->mmu_device_setstate(mmu, flags);
diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h
index fc64629..df4a64b 100644
--- a/drivers/gpu/msm/kgsl_mmu.h
+++ b/drivers/gpu/msm/kgsl_mmu.h
@@ -134,6 +134,12 @@
 		(struct kgsl_mmu *mmu);
 	int (*mmu_enable_clk)
 		(struct kgsl_mmu *mmu, int ctx_id);
+	int (*mmu_get_hwpagetable_asid)(struct kgsl_mmu *mmu);
+	int (*mmu_get_pt_lsb)(struct kgsl_mmu *mmu,
+				unsigned int unit_id,
+				enum kgsl_iommu_context_id ctx_id);
+	int (*mmu_get_reg_map_desc)(struct kgsl_mmu *mmu,
+				void **reg_map_desc);
 };
 
 struct kgsl_mmu_pt_ops {
@@ -147,6 +153,8 @@
 	void (*mmu_destroy_pagetable) (void *pt);
 	int (*mmu_pt_equal) (struct kgsl_pagetable *pt,
 			unsigned int pt_base);
+	unsigned int (*mmu_pt_get_base_addr)
+			(struct kgsl_pagetable *pt);
 };
 
 struct kgsl_mmu {
@@ -236,4 +244,21 @@
 		return pt->pt_ops->mmu_pt_equal(pt, pt_base);
 }
 
+static inline unsigned int kgsl_mmu_pt_get_base_addr(struct kgsl_pagetable *pt)
+{
+	if (KGSL_MMU_TYPE_NONE == kgsl_mmu_get_mmutype())
+		return 0;
+	else
+		return pt->pt_ops->mmu_pt_get_base_addr(pt);
+}
+
+static inline int kgsl_mmu_get_reg_map_desc(struct kgsl_mmu *mmu,
+						void **reg_map_desc)
+{
+	if (mmu->mmu_ops && mmu->mmu_ops->mmu_get_reg_map_desc)
+		return mmu->mmu_ops->mmu_get_reg_map_desc(mmu, reg_map_desc);
+	else
+		return 0;
+}
+
 #endif /* __KGSL_MMU_H */
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 9365772..3a29d71 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -11,6 +11,7 @@
  *
  */
 #include <linux/interrupt.h>
+#include <linux/pm_runtime.h>
 #include <mach/msm_iomap.h>
 #include <mach/msm_bus.h>
 
@@ -552,17 +553,8 @@
 		}
 	}
 
-	/*acquire interrupt */
-	pwr->interrupt_num =
-		platform_get_irq_byname(pdev, pwr->irq_name);
 
-	if (pwr->interrupt_num <= 0) {
-		KGSL_PWR_ERR(device, "platform_get_irq_byname failed: %d\n",
-					 pwr->interrupt_num);
-		result = -EINVAL;
-		goto done;
-	}
-
+	pm_runtime_enable(device->parentdev);
 	register_early_suspend(&device->display_off);
 	return result;
 
@@ -582,16 +574,9 @@
 
 	KGSL_PWR_INFO(device, "close device %d\n", device->id);
 
+	pm_runtime_disable(device->parentdev);
 	unregister_early_suspend(&device->display_off);
 
-	if (pwr->interrupt_num > 0) {
-		if (pwr->have_irq) {
-			free_irq(pwr->interrupt_num, NULL);
-			pwr->have_irq = 0;
-		}
-		pwr->interrupt_num = 0;
-	}
-
 	clk_put(pwr->ebi1_clk);
 
 	if (pwr->pcl)
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h
index 6325b66..1e5c21c 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.h
+++ b/drivers/gpu/msm/kgsl_pwrctrl.h
@@ -39,7 +39,6 @@
 
 struct kgsl_pwrctrl {
 	int interrupt_num;
-	int have_irq;
 	struct clk *ebi1_clk;
 	struct clk *grp_clks[KGSL_MAX_CLKS];
 	unsigned long power_flags;
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index 240de9a..846a9a1 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -132,10 +132,9 @@
 
 static struct z180_device device_2d0 = {
 	.dev = {
+		KGSL_DEVICE_COMMON_INIT(device_2d0.dev),
 		.name = DEVICE_2D0_NAME,
 		.id = KGSL_DEVICE_2D0,
-		.ver_major = DRIVER_VERSION_MAJOR,
-		.ver_minor = DRIVER_VERSION_MINOR,
 		.mh = {
 			.mharb = Z180_CFG_MHARB,
 			.mh_intf_cfg1 = 0x00032f07,
@@ -152,20 +151,17 @@
 		.pwrctrl = {
 			.irq_name = KGSL_2D0_IRQ,
 		},
-		.mutex = __MUTEX_INITIALIZER(device_2d0.dev.mutex),
-		.state = KGSL_STATE_INIT,
-		.active_cnt = 0,
 		.iomemname = KGSL_2D0_REG_MEMORY,
 		.ftbl = &z180_functable,
 	},
+	.cmdwin_lock = __SPIN_LOCK_INITIALIZER(device_2d1.cmdwin_lock),
 };
 
 static struct z180_device device_2d1 = {
 	.dev = {
+		KGSL_DEVICE_COMMON_INIT(device_2d1.dev),
 		.name = DEVICE_2D1_NAME,
 		.id = KGSL_DEVICE_2D1,
-		.ver_major = DRIVER_VERSION_MAJOR,
-		.ver_minor = DRIVER_VERSION_MINOR,
 		.mh = {
 			.mharb = Z180_CFG_MHARB,
 			.mh_intf_cfg1 = 0x00032f07,
@@ -182,12 +178,10 @@
 		.pwrctrl = {
 			.irq_name = KGSL_2D1_IRQ,
 		},
-		.mutex = __MUTEX_INITIALIZER(device_2d1.dev.mutex),
-		.state = KGSL_STATE_INIT,
-		.active_cnt = 0,
 		.iomemname = KGSL_2D1_REG_MEMORY,
 		.ftbl = &z180_functable,
 	},
+	.cmdwin_lock = __SPIN_LOCK_INITIALIZER(device_2d1.cmdwin_lock),
 };
 
 static irqreturn_t z180_irq_handler(struct kgsl_device *device)
@@ -524,7 +518,6 @@
 	device->parentdev = &pdev->dev;
 
 	z180_dev = Z180_DEVICE(device);
-	spin_lock_init(&z180_dev->cmdwin_lock);
 
 	status = z180_ringbuffer_init(device);
 	if (status != 0)
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index 5508c3d..c07bdc4 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -24,6 +24,17 @@
 	   LIRC daemon handles protocol decoding for IR reception and
 	   encoding for IR transmitting (aka "blasting").
 
+config USER_RC_INPUT
+	tristate "User Space Input device wrapper for Remote Control"
+	depends on RC_CORE
+
+	---help---
+	   Say Y if you want to report remote control input events
+	   from userspace.
+
+	   To compile this driver as a module, choose M here: the module will
+	   be called user-rc-input.
+
 source "drivers/media/rc/keymaps/Kconfig"
 
 config IR_NEC_DECODER
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index 523fcd0..b9c1e21 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -11,6 +11,7 @@
 obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o
 obj-$(CONFIG_IR_RC5_SZ_DECODER) += ir-rc5-sz-decoder.o
 obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
+obj-$(CONFIG_USER_RC_INPUT) += user-rc-input.o
 
 # stand-alone IR receivers/transmitters
 obj-$(CONFIG_IR_IMON) += imon.o
diff --git a/drivers/media/rc/user-rc-input.c b/drivers/media/rc/user-rc-input.c
new file mode 100644
index 0000000..f1a9334
--- /dev/null
+++ b/drivers/media/rc/user-rc-input.c
@@ -0,0 +1,251 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/ioctl.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/cdev.h>
+#include <linux/slab.h>
+
+#include <media/rc-core.h>
+#include <media/user-rc-input.h>
+
+#define MAX_RC_DEVICES		1
+#define USER_RC_INPUT_DEV_NAME	"user-rc-input"
+#define USER_RC_INPUT_DRV_NAME	"rc-user-input"
+
+struct user_rc_input_dev {
+	struct cdev rc_input_cdev;
+	struct class *rc_input_class;
+	struct device *rc_input_dev;
+	struct rc_dev *rcdev;
+	dev_t rc_input_base_dev;
+	struct device *dev;
+	int in_use;
+};
+
+static int user_rc_input_open(struct inode *inode, struct file *file)
+{
+	struct cdev *input_cdev	= inode->i_cdev;
+	struct user_rc_input_dev *input_dev =
+	container_of(input_cdev, struct user_rc_input_dev, rc_input_cdev);
+
+	if (input_dev->in_use) {
+		dev_err(input_dev->dev,
+		"Device is already open..only one instance is allowed\n");
+		return -EBUSY;
+	}
+	input_dev->in_use++;
+	file->private_data = input_dev;
+
+	return 0;
+}
+
+static int user_rc_input_release(struct inode *inode, struct file *file)
+{
+	struct user_rc_input_dev *input_dev = file->private_data;
+
+	input_dev->in_use--;
+
+	return 0;
+}
+
+static ssize_t user_rc_input_write(struct file *file, const char __user *buffer,
+						size_t count, loff_t *ppos)
+{
+	int ret;
+	struct user_rc_input_dev *input_dev = file->private_data;
+	__u8 *buf;
+
+	buf = kmalloc(count * sizeof(__u8), GFP_KERNEL);
+	if (!buf) {
+		dev_err(input_dev->dev,
+			"kmalloc failed...Insufficient memory\n");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (copy_from_user(buf, buffer, count)) {
+		dev_err(input_dev->dev, "Copy from user failed\n");
+		ret = -EFAULT;
+		goto out_free;
+	}
+
+	switch (buf[0])	{
+	case USER_CONTROL_PRESSED:
+		dev_dbg(input_dev->dev, "user controlled"
+					" pressed 0x%x\n", buf[1]);
+		rc_keydown(input_dev->rcdev, buf[1], 0);
+		break;
+	case USER_CONTROL_REPEATED:
+		dev_dbg(input_dev->dev, "user controlled"
+					" repeated 0x%x\n", buf[1]);
+		rc_repeat(input_dev->rcdev);
+		break;
+	case USER_CONTROL_RELEASED:
+		dev_dbg(input_dev->dev, "user controlled"
+					" released 0x%x\n", buf[1]);
+		rc_keyup(input_dev->rcdev);
+		break;
+	}
+
+out_free:
+	kfree(buf);
+out:
+	return ret;
+}
+
+const struct file_operations fops = {
+	.owner  = THIS_MODULE,
+	.open   = user_rc_input_open,
+	.write  = user_rc_input_write,
+	.release = user_rc_input_release,
+};
+
+static int __devinit user_rc_input_probe(struct platform_device *pdev)
+{
+	struct user_rc_input_dev *user_rc_dev;
+	struct rc_dev *rcdev;
+	int retval;
+
+	user_rc_dev = kzalloc(sizeof(struct user_rc_input_dev), GFP_KERNEL);
+	if (!user_rc_dev)
+		return -ENOMEM;
+
+	user_rc_dev->rc_input_class = class_create(THIS_MODULE,
+						"user-rc-input-loopback");
+
+	if (IS_ERR(user_rc_dev->rc_input_class)) {
+		retval = PTR_ERR(user_rc_dev->rc_input_class);
+		goto err;
+	}
+
+	retval = alloc_chrdev_region(&user_rc_dev->rc_input_base_dev, 0,
+				MAX_RC_DEVICES,	USER_RC_INPUT_DEV_NAME);
+
+	if (retval) {
+		dev_err(&pdev->dev,
+			"alloc_chrdev_region failed\n");
+		goto alloc_chrdev_err;
+	}
+
+	dev_info(&pdev->dev, "User space report key event input "
+					"loopback driver registered, "
+		"major %d\n", MAJOR(user_rc_dev->rc_input_base_dev));
+
+	cdev_init(&user_rc_dev->rc_input_cdev, &fops);
+	retval = cdev_add(&user_rc_dev->rc_input_cdev,
+				user_rc_dev->rc_input_base_dev,
+							MAX_RC_DEVICES);
+	if (retval) {
+		dev_err(&pdev->dev, "cdev_add failed\n");
+		goto cdev_add_err;
+	}
+	user_rc_dev->rc_input_dev =
+				device_create(user_rc_dev->rc_input_class,
+									NULL,
+				MKDEV(MAJOR(user_rc_dev->rc_input_base_dev),
+				0), NULL, "user-rc-input-dev%d", 0);
+
+	if (IS_ERR(user_rc_dev->rc_input_dev)) {
+		retval = PTR_ERR(user_rc_dev->rc_input_dev);
+		dev_err(&pdev->dev, "device_create failed\n");
+		goto device_create_err;
+	}
+
+	rcdev = rc_allocate_device();
+	if (!rcdev) {
+		dev_err(&pdev->dev, "failed to allocate rc device");
+		retval = -ENOMEM;
+		goto err_allocate_device;
+	}
+
+	rcdev->driver_type = RC_DRIVER_SCANCODE;
+	rcdev->allowed_protos = RC_TYPE_OTHER;
+	rcdev->input_name = USER_RC_INPUT_DEV_NAME;
+	rcdev->input_id.bustype = BUS_HOST;
+	rcdev->driver_name = USER_RC_INPUT_DRV_NAME;
+	rcdev->map_name = RC_MAP_UE_RF4CE;
+
+	retval = rc_register_device(rcdev);
+	if (retval < 0) {
+		dev_err(&pdev->dev, "failed to register rc device\n");
+		goto rc_register_err;
+	}
+	user_rc_dev->rcdev = rcdev;
+	user_rc_dev->dev = &pdev->dev;
+	platform_set_drvdata(pdev, user_rc_dev);
+	user_rc_dev->in_use = 0;
+
+	return 0;
+
+rc_register_err:
+	rc_free_device(rcdev);
+err_allocate_device:
+	device_destroy(user_rc_dev->rc_input_class,
+			MKDEV(MAJOR(user_rc_dev->rc_input_base_dev), 0));
+cdev_add_err:
+	unregister_chrdev_region(user_rc_dev->rc_input_base_dev,
+							MAX_RC_DEVICES);
+device_create_err:
+	cdev_del(&user_rc_dev->rc_input_cdev);
+alloc_chrdev_err:
+	class_destroy(user_rc_dev->rc_input_class);
+err:
+	kfree(user_rc_dev);
+	return retval;
+}
+
+static int __devexit user_rc_input_remove(struct platform_device *pdev)
+{
+	struct user_rc_input_dev *user_rc_dev = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+	rc_free_device(user_rc_dev->rcdev);
+	device_destroy(user_rc_dev->rc_input_class,
+			MKDEV(MAJOR(user_rc_dev->rc_input_base_dev), 0));
+	unregister_chrdev_region(user_rc_dev->rc_input_base_dev,
+							MAX_RC_DEVICES);
+	cdev_del(&user_rc_dev->rc_input_cdev);
+	class_destroy(user_rc_dev->rc_input_class);
+	kfree(user_rc_dev);
+
+	return 0;
+}
+
+static struct platform_driver user_rc_input_driver = {
+	.probe  = user_rc_input_probe,
+	.remove = __devexit_p(user_rc_input_remove),
+	.driver = {
+		.name   = USER_RC_INPUT_DRV_NAME,
+		.owner  = THIS_MODULE,
+	},
+};
+
+static int __init user_rc_input_init(void)
+{
+	return platform_driver_register(&user_rc_input_driver);
+}
+module_init(user_rc_input_init);
+
+static void __exit user_rc_input_exit(void)
+{
+	platform_driver_unregister(&user_rc_input_driver);
+}
+module_exit(user_rc_input_exit);
+
+MODULE_DESCRIPTION("User RC Input driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/flash.c b/drivers/media/video/msm/flash.c
index a86e5c4..0d17e13 100644
--- a/drivers/media/video/msm/flash.c
+++ b/drivers/media/video/msm/flash.c
@@ -307,13 +307,13 @@
 #endif
 		rc = gpio_request(external->led_en, "sc628a");
 		if (!rc) {
-			gpio_direction_output(external->led_en, 1);
+			gpio_direction_output(external->led_en, 0);
 		} else {
 			goto err1;
 		}
 		rc = gpio_request(external->led_flash_en, "sc628a");
 		if (!rc) {
-			gpio_direction_output(external->led_flash_en, 1);
+			gpio_direction_output(external->led_flash_en, 0);
 			break;
 		}
 
diff --git a/drivers/media/video/msm/msm_vpe.c b/drivers/media/video/msm/msm_vpe.c
index b7376dc..71c10ad 100644
--- a/drivers/media/video/msm/msm_vpe.c
+++ b/drivers/media/video/msm/msm_vpe.c
@@ -50,10 +50,12 @@
 	/*  enable the frame irq, bit 0 = Display list 0 ROI done */
 	msm_camera_io_w_mb(1, vpe_ctrl->vpebase + VPE_INTR_ENABLE_OFFSET);
 	msm_camera_io_dump(vpe_ctrl->vpebase, 0x120);
+	msm_camera_io_dump(vpe_ctrl->vpebase + 0x00400, 0x18);
 	msm_camera_io_dump(vpe_ctrl->vpebase + 0x10000, 0x250);
 	msm_camera_io_dump(vpe_ctrl->vpebase + 0x30000, 0x20);
 	msm_camera_io_dump(vpe_ctrl->vpebase + 0x50000, 0x30);
 	msm_camera_io_dump(vpe_ctrl->vpebase + 0x50400, 0x10);
+
 	/* this triggers the operation. */
 	msm_camera_io_w(1, vpe_ctrl->vpebase + VPE_DL0_START_OFFSET);
 	wmb();
@@ -756,7 +758,7 @@
 	}
 
 	rc = request_irq(vpe_ctrl->vpeirq->start, vpe_parse_irq,
-		IRQF_TRIGGER_RISING, "vfe", 0);
+		IRQF_TRIGGER_RISING, "vpe", 0);
 	if (rc < 0) {
 		release_mem_region(vpe_ctrl->vpemem->start,
 			resource_size(vpe_ctrl->vpemem));
diff --git a/drivers/media/video/msm/msm_vpe.h b/drivers/media/video/msm/msm_vpe.h
index 553ee4f..0d14626 100644
--- a/drivers/media/video/msm/msm_vpe.h
+++ b/drivers/media/video/msm/msm_vpe.h
@@ -60,7 +60,8 @@
 #define VPE_SCALE_COEFF_LSP_0_OFFSET          0x50400
 #define VPE_SCALE_COEFF_MSP_0_OFFSET          0x50404
 
-#define VPE_AXI_ARB_2_OFFSET                  0x004C
+#define VPE_AXI_ARB_1_OFFSET                  0x00408
+#define VPE_AXI_ARB_2_OFFSET                  0x0040C
 
 #define VPE_SCALE_COEFF_LSBn(n)	(0x50400 + 8 * (n))
 #define VPE_SCALE_COEFF_MSBn(n)	(0x50404 + 8 * (n))
diff --git a/drivers/media/video/msm_vidc/msm_smem.c b/drivers/media/video/msm_vidc/msm_smem.c
new file mode 100644
index 0000000..25b5c5c
--- /dev/null
+++ b/drivers/media/video/msm_vidc/msm_smem.c
@@ -0,0 +1,244 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/slab.h>
+#include "msm_smem.h"
+
+struct smem_client {
+	int mem_type;
+	void *clnt;
+};
+
+static int ion_user_to_kernel(struct smem_client *client,
+			int fd, u32 offset, struct msm_smem *mem)
+{
+	struct ion_handle *hndl;
+	unsigned long ionflag;
+	size_t len;
+	int rc = 0;
+	hndl = ion_import_fd(client->clnt, fd);
+	if (IS_ERR_OR_NULL(hndl)) {
+		pr_err("Failed to get handle: %p, %d, %d, %p\n",
+				client, fd, offset, hndl);
+		rc = -ENOMEM;
+		goto fail_import_fd;
+	}
+	rc = ion_handle_get_flags(client->clnt, hndl, &ionflag);
+	if (rc) {
+		pr_err("Failed to get ion flags: %d", rc);
+		goto fail_map;
+	}
+	rc = ion_phys(client->clnt, hndl, &mem->paddr, &len);
+	if (rc) {
+		pr_err("Failed to get physical address\n");
+		goto fail_map;
+	}
+	mem->kvaddr = ion_map_kernel(client->clnt, hndl, ionflag);
+	if (!mem->kvaddr) {
+		pr_err("Failed to map shared mem in kernel\n");
+		rc = -EIO;
+		goto fail_map;
+	}
+
+	mem->kvaddr += offset;
+	mem->paddr += offset;
+	mem->mem_type = client->mem_type;
+	mem->smem_priv = hndl;
+	mem->device_addr = mem->paddr;
+	mem->size = len;
+	return rc;
+fail_map:
+	ion_free(client->clnt, hndl);
+fail_import_fd:
+	return rc;
+}
+
+static int alloc_ion_mem(struct smem_client *client, size_t size,
+		u32 align, u32 flags, struct msm_smem *mem)
+{
+	struct ion_handle *hndl;
+	size_t len;
+	int rc = 0;
+	flags = flags | ION_HEAP(ION_CP_MM_HEAP_ID);
+	hndl = ion_alloc(client->clnt, size, align, flags);
+	if (IS_ERR_OR_NULL(hndl)) {
+		pr_err("Failed to allocate shared memory = %p, %d, %d, 0x%x\n",
+				client, size, align, flags);
+		rc = -ENOMEM;
+		goto fail_shared_mem_alloc;
+	}
+	mem->mem_type = client->mem_type;
+	mem->smem_priv = hndl;
+	if (ion_phys(client->clnt, hndl, &mem->paddr, &len)) {
+		pr_err("Failed to get physical address\n");
+		rc = -EIO;
+		goto fail_map;
+	}
+	mem->device_addr = mem->paddr;
+	mem->size = size;
+	mem->kvaddr = ion_map_kernel(client->clnt, hndl, 0);
+	if (!mem->kvaddr) {
+		pr_err("Failed to map shared mem in kernel\n");
+		rc = -EIO;
+		goto fail_map;
+	}
+	return rc;
+fail_map:
+	ion_free(client->clnt, hndl);
+fail_shared_mem_alloc:
+	return rc;
+}
+
+static void free_ion_mem(struct smem_client *client, struct msm_smem *mem)
+{
+	ion_unmap_kernel(client->clnt, mem->smem_priv);
+	ion_free(client->clnt, mem->smem_priv);
+}
+
+static void *ion_new_client(void)
+{
+	struct ion_client *client = NULL;
+	client = msm_ion_client_create(-1, "video_client");
+	if (!client)
+		pr_err("Failed to create smem client\n");
+	return client;
+};
+
+static void ion_delete_client(struct smem_client *client)
+{
+	ion_client_destroy(client->clnt);
+}
+
+struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset)
+{
+	struct smem_client *client = clt;
+	int rc = 0;
+	struct msm_smem *mem;
+	if (fd < 0) {
+		pr_err("Invalid fd: %d\n", fd);
+		return NULL;
+	}
+	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+	if (!mem) {
+		pr_err("Failed to allocte shared mem\n");
+		return NULL;
+	}
+	switch (client->mem_type) {
+	case SMEM_ION:
+		rc = ion_user_to_kernel(clt, fd, offset, mem);
+		break;
+	default:
+		pr_err("Mem type not supported\n");
+		rc = -EINVAL;
+		break;
+	}
+	if (rc) {
+		pr_err("Failed to allocate shared memory\n");
+		kfree(mem);
+		mem = NULL;
+	}
+	return mem;
+}
+
+void *msm_smem_new_client(enum smem_type mtype)
+{
+	struct smem_client *client = NULL;
+	void *clnt = NULL;
+	switch (mtype) {
+	case SMEM_ION:
+		clnt = ion_new_client();
+		break;
+	default:
+		pr_err("Mem type not supported\n");
+		break;
+	}
+	if (clnt) {
+		client = kzalloc(sizeof(*client), GFP_KERNEL);
+		if (client) {
+			client->mem_type = mtype;
+			client->clnt = clnt;
+		}
+	} else {
+		pr_err("Failed to create new client: mtype = %d\n", mtype);
+	}
+	return client;
+};
+
+struct msm_smem *msm_smem_alloc(void *clt, size_t size, u32 align, u32 flags)
+{
+	struct smem_client *client;
+	int rc = 0;
+	struct msm_smem *mem;
+
+	client = clt;
+	if (!client) {
+		pr_err("Invalid  client passed\n");
+		return NULL;
+	}
+	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+	if (!mem) {
+		pr_err("Failed to allocate shared mem\n");
+		return NULL;
+	}
+	switch (client->mem_type) {
+	case SMEM_ION:
+		rc = alloc_ion_mem(client, size, align, flags, mem);
+		break;
+	default:
+		pr_err("Mem type not supported\n");
+		rc = -EINVAL;
+		break;
+	}
+	if (rc) {
+		pr_err("Failed to allocate shared memory\n");
+		kfree(mem);
+		mem = NULL;
+	}
+	return mem;
+}
+
+void msm_smem_free(void *clt, struct msm_smem *mem)
+{
+	struct smem_client *client = clt;
+	if (!client || !mem) {
+		pr_err("Invalid  client/handle passed\n");
+		return;
+	}
+	switch (client->mem_type) {
+	case SMEM_ION:
+		free_ion_mem(client, mem);
+		break;
+	default:
+		pr_err("Mem type not supported\n");
+		break;
+	}
+	kfree(mem);
+};
+
+void msm_smem_delete_client(void *clt)
+{
+	struct smem_client *client = clt;
+	if (!client) {
+		pr_err("Invalid  client passed\n");
+		return;
+	}
+	switch (client->mem_type) {
+	case SMEM_ION:
+		ion_delete_client(client);
+		break;
+	default:
+		pr_err("Mem type not supported\n");
+		break;
+	}
+	kfree(client);
+}
diff --git a/drivers/media/video/msm_vidc/msm_smem.h b/drivers/media/video/msm_vidc/msm_smem.h
new file mode 100644
index 0000000..84d12cc
--- /dev/null
+++ b/drivers/media/video/msm_vidc/msm_smem.h
@@ -0,0 +1,38 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef _MSM_SMEM_H_
+#define _MSM_SMEM_H_
+
+#include <linux/types.h>
+#include <linux/ion.h>
+
+enum smem_type {
+	SMEM_ION,
+};
+
+struct msm_smem {
+	int mem_type;
+	size_t size;
+	void *kvaddr;
+	unsigned long paddr;
+	unsigned long device_addr;
+	/*Device address and others to follow*/
+	void *smem_priv;
+};
+
+void *msm_smem_new_client(enum smem_type mtype);
+struct msm_smem *msm_smem_alloc(void *clt, size_t size, u32 align, u32 flags);
+void msm_smem_free(void *clt, struct msm_smem *mem);
+void msm_smem_delete_client(void *clt);
+struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset);
+#endif
diff --git a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
new file mode 100644
index 0000000..f125cdc
--- /dev/null
+++ b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
@@ -0,0 +1,505 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/ioctl.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/debugfs.h>
+#include <linux/version.h>
+#include <linux/slab.h>
+
+#include <media/msm_vidc.h>
+#include "msm_vidc_internal.h"
+#include "vidc_hal_api.h"
+#include "msm_smem.h"
+
+#define BASE_DEVICE_NUMBER 32
+
+struct msm_vidc_drv *vidc_driver;
+
+struct buffer_info {
+	struct list_head list;
+	int type;
+	int fd;
+	int buff_off;
+	int size;
+	u32 uvaddr;
+	struct msm_smem *handle;
+};
+
+struct msm_v4l2_vid_inst {
+	void *vidc_inst;
+	void *mem_client;
+	struct list_head registered_bufs;
+};
+
+struct buffer_info *get_registered_buf(struct list_head *list,
+				int fd, u32 buff_off, u32 size)
+{
+	struct buffer_info *temp;
+	struct buffer_info *ret = NULL;
+	if (!list || fd < 0) {
+		pr_err("%s Invalid input\n", __func__);
+		goto err_invalid_input;
+	}
+	if (!list_empty(list)) {
+		list_for_each_entry(temp, list, list) {
+			if (temp && temp->fd == fd &&
+			(CONTAINS(temp->buff_off, temp->size, buff_off)
+			|| CONTAINS(buff_off, size, temp->buff_off)
+			|| OVERLAPS(buff_off, size,
+				temp->buff_off, temp->size))) {
+				pr_err("This memory region is already mapped\n");
+				ret = temp;
+				break;
+			}
+		}
+	}
+err_invalid_input:
+	return ret;
+}
+
+static int msm_v4l2_open(struct file *filp)
+{
+	int rc = 0;
+	struct video_device *vdev = video_devdata(filp);
+	struct msm_video_device *vid_dev =
+		container_of(vdev, struct msm_video_device, vdev);
+	struct msm_vidc_core *core = video_drvdata(filp);
+	void *inst;
+	struct msm_v4l2_vid_inst *v4l2_inst = kzalloc(sizeof(*v4l2_inst),
+						GFP_KERNEL);
+	if (!v4l2_inst) {
+		pr_err("Failed to allocate memory for this instance\n");
+		rc = -ENOMEM;
+		goto fail_nomem;
+	}
+	v4l2_inst->mem_client = msm_smem_new_client(SMEM_ION);
+	if (!v4l2_inst->mem_client) {
+		pr_err("Failed to create memory client\n");
+		rc = -ENOMEM;
+		goto fail_mem_client;
+	}
+	inst = msm_vidc_open(core->id, vid_dev->type);
+	if (!inst) {
+		pr_err("Failed to create video instance, core: %d, type = %d\n",
+			core->id, vid_dev->type);
+		rc = -ENOMEM;
+		goto fail_open;
+	}
+	INIT_LIST_HEAD(&v4l2_inst->registered_bufs);
+	v4l2_inst->vidc_inst = inst;
+	filp->private_data = v4l2_inst;
+	return rc;
+fail_open:
+	msm_smem_delete_client(v4l2_inst->mem_client);
+fail_mem_client:
+	kfree(v4l2_inst);
+fail_nomem:
+	return rc;
+}
+
+static int msm_v4l2_close(struct file *filp)
+{
+	int rc;
+	struct list_head *ptr, *next;
+	struct buffer_info *binfo;
+	struct msm_v4l2_vid_inst *v4l2_inst = filp->private_data;
+	rc = msm_vidc_close(v4l2_inst->vidc_inst);
+	list_for_each_safe(ptr, next, &v4l2_inst->registered_bufs) {
+		binfo = list_entry(ptr, struct buffer_info, list);
+		list_del(&binfo->list);
+		msm_smem_free(v4l2_inst->mem_client, binfo->handle);
+		kfree(binfo);
+	}
+	msm_smem_delete_client(v4l2_inst->mem_client);
+	kfree(v4l2_inst);
+	return rc;
+}
+
+static int msm_v4l2_querycap(struct file *filp, void *fh,
+			struct v4l2_capability *cap)
+{
+	struct msm_v4l2_vid_inst *v4l2_inst = filp->private_data;
+	return msm_vidc_querycap(v4l2_inst->vidc_inst, cap);
+}
+
+int msm_v4l2_enum_fmt(struct file *file, void *fh,
+					struct v4l2_fmtdesc *f)
+{
+	struct msm_v4l2_vid_inst *v4l2_inst = file->private_data;
+	return msm_vidc_enum_fmt(v4l2_inst->vidc_inst, f);
+}
+
+int msm_v4l2_s_fmt(struct file *file, void *fh,
+					struct v4l2_format *f)
+{
+	struct msm_v4l2_vid_inst *v4l2_inst = file->private_data;
+	return msm_vidc_s_fmt(v4l2_inst->vidc_inst, f);
+}
+
+int msm_v4l2_g_fmt(struct file *file, void *fh,
+					struct v4l2_format *f)
+{
+	struct msm_v4l2_vid_inst *v4l2_inst = file->private_data;
+	return msm_vidc_g_fmt(v4l2_inst->vidc_inst, f);
+}
+
+int msm_v4l2_s_ctrl(struct file *file, void *fh,
+					struct v4l2_control *a)
+{
+	struct msm_v4l2_vid_inst *v4l2_inst = file->private_data;
+	return msm_vidc_s_ctrl(v4l2_inst->vidc_inst, a);
+}
+
+int msm_v4l2_g_ctrl(struct file *file, void *fh,
+					struct v4l2_control *a)
+{
+	struct msm_v4l2_vid_inst *v4l2_inst = file->private_data;
+	return msm_vidc_g_ctrl(v4l2_inst->vidc_inst, a);
+}
+
+int msm_v4l2_reqbufs(struct file *file, void *fh,
+				struct v4l2_requestbuffers *b)
+{
+	struct msm_v4l2_vid_inst *v4l2_inst = file->private_data;
+	return msm_vidc_reqbufs(v4l2_inst->vidc_inst, b);
+}
+
+int msm_v4l2_prepare_buf(struct file *file, void *fh,
+				struct v4l2_buffer *b)
+{
+	struct msm_v4l2_vid_inst *v4l2_inst = file->private_data;
+	struct msm_smem *handle;
+	struct buffer_info *binfo;
+	int rc = 0;
+	int i;
+	if (!v4l2_inst->mem_client) {
+		pr_err("Failed to get memory client\n");
+		rc = -ENOMEM;
+		goto exit;
+	}
+	for (i = 0; i < b->length; ++i) {
+		binfo = get_registered_buf(&v4l2_inst->registered_bufs,
+				b->m.planes[i].reserved[0],
+				b->m.planes[i].reserved[1],
+				b->m.planes[i].length);
+		if (binfo) {
+			pr_err("This memory region has already been prepared\n");
+			rc = -EINVAL;
+			goto exit;
+		}
+		binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
+		if (!binfo) {
+			pr_err("Out of memory\n");
+			rc = -ENOMEM;
+			goto exit;
+		}
+		handle = msm_smem_user_to_kernel(v4l2_inst->mem_client,
+				b->m.planes[i].reserved[0],
+				b->m.planes[i].reserved[1]);
+		if (!handle) {
+			pr_err("Failed to get device buffer address\n");
+			kfree(binfo);
+			goto exit;
+		}
+		binfo->type = b->type;
+		binfo->fd = b->m.planes[i].reserved[0];
+		binfo->buff_off = b->m.planes[i].reserved[1];
+		binfo->size = b->m.planes[i].length;
+		binfo->uvaddr = b->m.planes[i].m.userptr;
+		binfo->handle = handle;
+		pr_debug("Registering buffer: %d, %d, %d\n",
+				b->m.planes[i].reserved[0],
+				b->m.planes[i].reserved[1],
+				b->m.planes[i].length);
+		list_add_tail(&binfo->list, &v4l2_inst->registered_bufs);
+		b->m.planes[i].m.userptr = handle->device_addr;
+	}
+	rc = msm_vidc_prepare_buf(v4l2_inst->vidc_inst, b);
+exit:
+	return rc;
+}
+
+int msm_v4l2_qbuf(struct file *file, void *fh,
+				struct v4l2_buffer *b)
+{
+	struct msm_v4l2_vid_inst *v4l2_inst = file->private_data;
+	struct buffer_info *binfo;
+	int rc = 0;
+	int i;
+	for (i = 0; i < b->length; ++i) {
+		binfo = get_registered_buf(&v4l2_inst->registered_bufs,
+				b->m.planes[i].reserved[0],
+				b->m.planes[i].reserved[1],
+				b->m.planes[i].length);
+		if (!binfo) {
+			pr_err("This buffer is not registered: %d, %d, %d\n",
+				b->m.planes[i].reserved[0],
+				b->m.planes[i].reserved[1],
+				b->m.planes[i].length);
+			rc = -EINVAL;
+			goto err_invalid_buff;
+		}
+		b->m.planes[i].m.userptr = binfo->handle->device_addr;
+		pr_debug("Queueing device address = %ld\n",
+				binfo->handle->device_addr);
+	}
+	rc = msm_vidc_qbuf(v4l2_inst->vidc_inst, b);
+err_invalid_buff:
+	return rc;
+}
+
+int msm_v4l2_dqbuf(struct file *file, void *fh,
+				struct v4l2_buffer *b)
+{
+	struct msm_v4l2_vid_inst *v4l2_inst = file->private_data;
+	return msm_vidc_dqbuf(v4l2_inst->vidc_inst, b);
+}
+
+int msm_v4l2_streamon(struct file *file, void *fh,
+				enum v4l2_buf_type i)
+{
+	struct msm_v4l2_vid_inst *v4l2_inst = file->private_data;
+	return msm_vidc_streamon(v4l2_inst->vidc_inst, i);
+}
+
+int msm_v4l2_streamoff(struct file *file, void *fh,
+				enum v4l2_buf_type i)
+{
+	struct msm_v4l2_vid_inst *v4l2_inst = file->private_data;
+	return msm_vidc_streamoff(v4l2_inst->vidc_inst, i);
+}
+static const struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = {
+	.vidioc_querycap = msm_v4l2_querycap,
+	.vidioc_enum_fmt_vid_cap_mplane = msm_v4l2_enum_fmt,
+	.vidioc_enum_fmt_vid_out_mplane = msm_v4l2_enum_fmt,
+	.vidioc_s_fmt_vid_cap_mplane = msm_v4l2_s_fmt,
+	.vidioc_s_fmt_vid_out_mplane = msm_v4l2_s_fmt,
+	.vidioc_g_fmt_vid_cap_mplane = msm_v4l2_g_fmt,
+	.vidioc_g_fmt_vid_out_mplane = msm_v4l2_g_fmt,
+	.vidioc_reqbufs = msm_v4l2_reqbufs,
+	.vidioc_prepare_buf = msm_v4l2_prepare_buf,
+	.vidioc_qbuf = msm_v4l2_qbuf,
+	.vidioc_dqbuf = msm_v4l2_dqbuf,
+	.vidioc_streamon = msm_v4l2_streamon,
+	.vidioc_streamoff = msm_v4l2_streamoff,
+	.vidioc_s_ctrl = msm_v4l2_s_ctrl,
+	.vidioc_g_ctrl = msm_v4l2_g_ctrl,
+};
+
+static const struct v4l2_ioctl_ops msm_v4l2_enc_ioctl_ops = {
+};
+
+static unsigned int msm_v4l2_poll(struct file *filp,
+	struct poll_table_struct *pt)
+{
+	struct msm_v4l2_vid_inst *v4l2_inst = filp->private_data;
+	return msm_vidc_poll(v4l2_inst->vidc_inst, filp, pt);
+}
+
+static const struct v4l2_file_operations msm_v4l2_vidc_fops = {
+	.owner = THIS_MODULE,
+	.open = msm_v4l2_open,
+	.release = msm_v4l2_close,
+	.ioctl = video_ioctl2,
+	.poll = msm_v4l2_poll,
+};
+
+void msm_vidc_release_video_device(struct video_device *pvdev)
+{
+}
+
+static int msm_vidc_initialize_core(struct platform_device *pdev,
+				struct msm_vidc_core *core)
+{
+	struct resource *res;
+	int i = 0;
+	if (!core)
+		return -EINVAL;
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		pr_err("Failed to get IORESOURCE_MEM\n");
+		return -ENODEV;
+	}
+	core->register_base = res->start;
+	core->register_size = resource_size(res);
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!res) {
+		pr_err("Failed to get IORESOURCE_IRQ\n");
+		return -ENODEV;
+	}
+	core->irq = res->start;
+	INIT_LIST_HEAD(&core->instances);
+	mutex_init(&core->sync_lock);
+	spin_lock_init(&core->lock);
+	core->base_addr = 0x34f00000;
+	core->state = VIDC_CORE_UNINIT;
+	for (i = SYS_MSG_INDEX(SYS_MSG_START);
+		i <= SYS_MSG_INDEX(SYS_MSG_END); i++) {
+		init_completion(&core->completions[i]);
+	}
+	return 0;
+}
+
+static int __devinit msm_vidc_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct msm_vidc_core *core;
+	unsigned long flags;
+	char debugfs_name[MAX_DEBUGFS_NAME];
+
+	core = kzalloc(sizeof(*core), GFP_KERNEL);
+	if (!core || !vidc_driver) {
+		pr_err("Failed to allocate memory for device core\n");
+		rc = -ENOMEM;
+		goto err_no_mem;
+	}
+	rc = msm_vidc_initialize_core(pdev, core);
+	if (rc) {
+		pr_err("Failed to init core\n");
+		goto err_v4l2_register;
+	}
+	rc = v4l2_device_register(&pdev->dev, &core->v4l2_dev);
+	if (rc) {
+		pr_err("Failed to register v4l2 device\n");
+		goto err_v4l2_register;
+	}
+	core->vdev[MSM_VIDC_DECODER].vdev.release =
+		msm_vidc_release_video_device;
+	core->vdev[MSM_VIDC_DECODER].vdev.fops = &msm_v4l2_vidc_fops;
+	core->vdev[MSM_VIDC_DECODER].vdev.ioctl_ops = &msm_v4l2_ioctl_ops;
+	core->vdev[MSM_VIDC_DECODER].type = MSM_VIDC_DECODER;
+	rc = video_register_device(&core->vdev[MSM_VIDC_DECODER].vdev,
+					VFL_TYPE_GRABBER, BASE_DEVICE_NUMBER);
+	if (rc) {
+		pr_err("Failed to register video decoder device");
+		goto err_dec_register;
+	}
+	video_set_drvdata(&core->vdev[MSM_VIDC_DECODER].vdev, core);
+
+	core->vdev[MSM_VIDC_ENCODER].vdev.release =
+		msm_vidc_release_video_device;
+	core->vdev[MSM_VIDC_ENCODER].vdev.fops = &msm_v4l2_vidc_fops;
+	core->vdev[MSM_VIDC_ENCODER].vdev.ioctl_ops = &msm_v4l2_ioctl_ops;
+	core->vdev[MSM_VIDC_ENCODER].type = MSM_VIDC_ENCODER;
+	rc = video_register_device(&core->vdev[MSM_VIDC_ENCODER].vdev,
+				VFL_TYPE_GRABBER, BASE_DEVICE_NUMBER + 1);
+	if (rc) {
+		pr_err("Failed to register video encoder device");
+		goto err_enc_register;
+	}
+	video_set_drvdata(&core->vdev[MSM_VIDC_ENCODER].vdev, core);
+	core->device = vidc_hal_add_device(core->id, core->base_addr,
+			core->register_base, core->register_size, core->irq,
+			&handle_cmd_response);
+	if (!core->device) {
+		pr_err("Failed to create interrupt handler");
+		goto err_cores_exceeded;
+	}
+
+	spin_lock_irqsave(&vidc_driver->lock, flags);
+	if (vidc_driver->num_cores  + 1 > MSM_VIDC_CORES_MAX) {
+		spin_unlock_irqrestore(&vidc_driver->lock, flags);
+		pr_err("Maximum cores already exist, core_no = %d\n",
+				vidc_driver->num_cores);
+		goto err_cores_exceeded;
+	}
+
+	core->id = vidc_driver->num_cores++;
+	list_add_tail(&core->list, &vidc_driver->cores);
+	spin_unlock_irqrestore(&vidc_driver->lock, flags);
+	snprintf(debugfs_name, MAX_DEBUGFS_NAME, "core%d", core->id);
+	core->debugfs_root = debugfs_create_dir(debugfs_name,
+						vidc_driver->debugfs_root);
+	pdev->dev.platform_data = core;
+	return rc;
+
+err_cores_exceeded:
+	video_unregister_device(&core->vdev[MSM_VIDC_ENCODER].vdev);
+err_enc_register:
+	video_unregister_device(&core->vdev[MSM_VIDC_DECODER].vdev);
+err_dec_register:
+	v4l2_device_unregister(&core->v4l2_dev);
+err_v4l2_register:
+	kfree(core);
+err_no_mem:
+	return rc;
+}
+
+static int __devexit msm_vidc_remove(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct msm_vidc_core *core = pdev->dev.platform_data;
+	vidc_hal_delete_device(core->device);
+	video_unregister_device(&core->vdev[MSM_VIDC_ENCODER].vdev);
+	video_unregister_device(&core->vdev[MSM_VIDC_DECODER].vdev);
+	v4l2_device_unregister(&core->v4l2_dev);
+	kfree(core);
+	return rc;
+}
+static const struct of_device_id msm_vidc_dt_match[] = {
+	{.compatible = "qcom,msm-vidc"},
+};
+
+MODULE_DEVICE_TABLE(of, msm_vidc_dt_match);
+
+static struct platform_driver msm_vidc_driver = {
+	.probe = msm_vidc_probe,
+	.remove = msm_vidc_remove,
+	.driver = {
+		.name = "msm_vidc",
+		.owner = THIS_MODULE,
+		.of_match_table = msm_vidc_dt_match,
+	},
+};
+
+static int __init msm_vidc_init(void)
+{
+	int rc = 0;
+	vidc_driver = kzalloc(sizeof(*vidc_driver),
+						GFP_KERNEL);
+	if (!vidc_driver) {
+		pr_err("Failed to allocate memroy for msm_vidc_drv\n");
+		return -ENOMEM;
+	}
+
+	INIT_LIST_HEAD(&vidc_driver->cores);
+	spin_lock_init(&vidc_driver->lock);
+	vidc_driver->debugfs_root = debugfs_create_dir("msm_vidc", NULL);
+	if (!vidc_driver->debugfs_root)
+		pr_err("Failed to create debugfs for msm_vidc\n");
+
+	rc = platform_driver_register(&msm_vidc_driver);
+	if (rc) {
+		pr_err("Failed to register platform driver\n");
+		kfree(vidc_driver);
+		vidc_driver = NULL;
+	}
+
+	return rc;
+}
+
+static void __exit msm_vidc_exit(void)
+{
+	platform_driver_unregister(&msm_vidc_driver);
+	debugfs_remove_recursive(vidc_driver->debugfs_root);
+	kfree(vidc_driver);
+	vidc_driver = NULL;
+}
+
+module_init(msm_vidc_init);
+module_exit(msm_vidc_exit);
diff --git a/drivers/media/video/msm_vidc/msm_vdec.c b/drivers/media/video/msm_vidc/msm_vdec.c
new file mode 100644
index 0000000..879d324
--- /dev/null
+++ b/drivers/media/video/msm_vidc/msm_vdec.c
@@ -0,0 +1,872 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/slab.h>
+
+#include "msm_vidc_internal.h"
+#include "msm_vidc_common.h"
+#include "vidc_hal_api.h"
+#include "msm_smem.h"
+
+#define MSM_VDEC_DVC_NAME "msm_vdec_8974"
+#define MAX_PLANES 1
+#define DEFAULT_HEIGHT 720
+#define DEFAULT_WIDTH 1280
+#define MIN_NUM_OUTPUT_BUFFERS 2
+#define MAX_NUM_OUTPUT_BUFFERS 6
+
+static const char *const mpeg_video_vidc_divx_format[] = {
+	"DIVX Format 4",
+	"DIVX Format 5",
+	"DIVX Format 6",
+	NULL
+};
+static const char *mpeg_video_stream_format[] = {
+	"NAL Format Start Codes",
+	"NAL Format One NAL Per Buffer",
+	"NAL Format One Byte Length",
+	"NAL Format Two Byte Length",
+	"NAL Format Four Byte Length",
+	NULL
+};
+static const char *const mpeg_video_output_order[] = {
+	"Display Order",
+	"Decode Order",
+	NULL
+};
+static const struct msm_vidc_ctrl msm_vdec_ctrls[] = {
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT,
+		.name = "NAL Format",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES,
+		.maximum = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH,
+		.default_value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES,
+		.menu_skip_mask = ~(
+		(1 << V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_ONE_NAL_PER_BUFFER) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_ONE_BYTE_LENGTH) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH)
+		),
+		.qmenu = mpeg_video_stream_format,
+		.step = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER,
+		.name = "Output Order",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY,
+		.maximum = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE,
+		.default_value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY,
+		.menu_skip_mask = ~(
+			(1 << V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY) |
+			(1 << V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE)
+			),
+		.qmenu = mpeg_video_output_order,
+		.step = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_PICTURE_TYPE,
+		.name = "Picture Type Decoding",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = 1,
+		.maximum = 15,
+		.default_value = 15,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO,
+		.name = "Keep Aspect Ratio",
+		.type = V4L2_CTRL_TYPE_BOOLEAN,
+		.minimum = 0,
+		.maximum = 1,
+		.default_value = 0,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_POST_LOOP_DEBLOCKER_MODE,
+		.name = "Deblocker Mode",
+		.type = V4L2_CTRL_TYPE_BOOLEAN,
+		.minimum = 0,
+		.maximum = 1,
+		.default_value = 0,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT,
+		.name = "Divx Format",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4,
+		.maximum = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6,
+		.default_value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4,
+		.menu_skip_mask = ~(
+			(1 << V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4) |
+			(1 << V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5) |
+			(1 << V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6)
+			),
+		.qmenu = mpeg_video_vidc_divx_format,
+		.step = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_MB_ERROR_MAP_REPORTING,
+		.name = "MB Error Map Reporting",
+		.type = V4L2_CTRL_TYPE_BOOLEAN,
+		.minimum = 0,
+		.maximum = 1,
+		.default_value = 0,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER,
+		.name = "control",
+		.type = V4L2_CTRL_TYPE_BOOLEAN,
+		.minimum = 0,
+		.maximum = 1,
+		.default_value = 0,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+	},
+};
+
+#define NUM_CTRLS ARRAY_SIZE(msm_vdec_ctrls)
+
+static u32 get_frame_size_nv12(int plane,
+					u32 height, u32 width)
+{
+	int stride = (width + 31) & (~31);
+	return height * stride * 3/2;
+}
+static u32 get_frame_size_nv21(int plane,
+					u32 height, u32 width)
+{
+	return height * width * 2;
+}
+
+static u32 get_frame_size_compressed(int plane,
+					u32 height, u32 width)
+{
+	return 0x500000;
+}
+
+static const struct msm_vidc_format vdec_formats[] = {
+	{
+		.name = "YCbCr Semiplanar 4:2:0",
+		.description = "Y/CbCr 4:2:0",
+		.fourcc = V4L2_PIX_FMT_NV12,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_nv12,
+		.type = CAPTURE_PORT,
+	},
+	{
+		.name = "Mpeg4",
+		.description = "Mpeg4 compressed format",
+		.fourcc = V4L2_PIX_FMT_MPEG4,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_compressed,
+		.type = OUTPUT_PORT,
+	},
+	{
+		.name = "Mpeg2",
+		.description = "Mpeg2 compressed format",
+		.fourcc = V4L2_PIX_FMT_MPEG2,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_compressed,
+		.type = OUTPUT_PORT,
+	},
+	{
+		.name = "H263",
+		.description = "H263 compressed format",
+		.fourcc = V4L2_PIX_FMT_H263,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_compressed,
+		.type = OUTPUT_PORT,
+	},
+	{
+		.name = "H264",
+		.description = "H264 compressed format",
+		.fourcc = V4L2_PIX_FMT_H264,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_compressed,
+		.type = OUTPUT_PORT,
+	},
+	{
+		.name = "YCrCb Semiplanar 4:2:0",
+		.description = "Y/CrCb 4:2:0",
+		.fourcc = V4L2_PIX_FMT_NV21,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_nv21,
+		.type = CAPTURE_PORT,
+	},
+};
+
+int msm_vdec_streamon(struct msm_vidc_inst *inst, enum v4l2_buf_type i)
+{
+	int rc = 0;
+	struct vb2_queue *q;
+	q = msm_comm_get_vb2q(inst, i);
+	if (!q) {
+		pr_err("Failed to find buffer queue for type = %d\n", i);
+		return -EINVAL;
+	}
+	pr_debug("Calling streamon\n");
+	rc = vb2_streamon(q, i);
+	if (rc)
+		pr_err("streamon failed on port: %d\n", i);
+	return rc;
+}
+
+int msm_vdec_streamoff(struct msm_vidc_inst *inst, enum v4l2_buf_type i)
+{
+	int rc = 0;
+	struct vb2_queue *q;
+	unsigned long flags;
+	struct list_head *ptr, *next;
+	struct internal_buf *buf;
+	struct extradata_buf *ebuf;
+
+	q = msm_comm_get_vb2q(inst, i);
+	if (!q) {
+		pr_err("Failed to find buffer queue for type = %d\n", i);
+		return -EINVAL;
+	}
+	spin_lock_irqsave(&inst->lock, flags);
+	list_for_each_safe(ptr, next, &inst->internalbufs) {
+		buf = list_entry(ptr, struct internal_buf, list);
+		list_del(&buf->list);
+		msm_smem_free(inst->mem_client, buf->handle);
+		kfree(buf);
+		}
+	list_for_each_safe(ptr, next, &inst->extradatabufs) {
+		ebuf = list_entry(ptr, struct extradata_buf, list);
+		list_del(&ebuf->list);
+		msm_smem_free(inst->mem_client, ebuf->handle);
+		kfree(ebuf);
+		}
+	spin_unlock_irqrestore(&inst->lock, flags);
+
+	pr_debug("Calling streamoff\n");
+	rc = vb2_streamoff(q, i);
+	if (rc)
+		pr_err("streamoff failed on port: %d\n", i);
+	return rc;
+}
+
+int msm_vdec_prepare_buf(struct msm_vidc_inst *inst,
+					struct v4l2_buffer *b)
+{
+	int rc = 0;
+	int i;
+	struct vidc_buffer_addr_info buffer_info;
+	switch (b->type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: {
+		struct extradata_buf *binfo;
+		for (i = 0; i < b->length; i++) {
+			pr_err("device_addr = %ld, size = %d\n",
+				b->m.planes[i].m.userptr,
+				b->m.planes[i].length);
+			buffer_info.buffer_size = b->m.planes[i].length;
+			buffer_info.buffer_type = HAL_BUFFER_OUTPUT;
+			buffer_info.num_buffers = 1;
+			buffer_info.align_device_addr =
+				b->m.planes[i].m.userptr;
+			binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
+			if (!binfo) {
+				pr_err("Failed to allocate shared mem\n");
+				return -ENOMEM;
+			}
+			binfo->device_addr = b->m.planes[i].m.userptr;
+			rc = msm_comm_allocate_extradata_buffers(inst, binfo);
+			if (rc) {
+				pr_err("msm_comm_allocate_extradata_buffers failed");
+				break;
+			}
+			buffer_info.extradata_size = binfo->handle->size;
+			buffer_info.extradata_addr = binfo->handle->device_addr;
+			rc = vidc_hal_session_set_buffers((void *)inst->session,
+					&buffer_info);
+			if (rc) {
+				pr_err("vidc_hal_session_set_buffers failed");
+				break;
+			}
+		}
+		break;
+	}
+	default:
+		pr_err("Buffer type not recognized: %d\n", b->type);
+		break;
+	}
+	return rc;
+}
+
+int msm_vdec_qbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b)
+{
+	struct vb2_queue *q = NULL;
+	int rc = 0;
+	q = msm_comm_get_vb2q(inst, b->type);
+	if (!q) {
+		pr_err("Failed to find buffer queue for type = %d\n", b->type);
+		return -EINVAL;
+	}
+	rc = vb2_qbuf(q, b);
+	if (rc)
+		pr_err("Failed to qbuf, %d\n", rc);
+	return rc;
+}
+int msm_vdec_dqbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b)
+{
+	struct vb2_queue *q = NULL;
+	int rc = 0;
+	q = msm_comm_get_vb2q(inst, b->type);
+	if (!q) {
+		pr_err("Failed to find buffer queue for type = %d\n", b->type);
+		return -EINVAL;
+	}
+	rc = vb2_dqbuf(q, b, true);
+	if (rc)
+		pr_err("Failed to qbuf, %d\n", rc);
+	return rc;
+}
+
+int msm_vdec_reqbufs(struct msm_vidc_inst *inst, struct v4l2_requestbuffers *b)
+{
+	struct vb2_queue *q = NULL;
+	int rc = 0;
+	if (!inst || !b) {
+		pr_err("Invalid input, inst = %p, buffer = %p\n", inst, b);
+		return -EINVAL;
+	}
+	q = msm_comm_get_vb2q(inst, b->type);
+	if (!q) {
+		pr_err("Failed to find buffer queue for type = %d\n", b->type);
+		return -EINVAL;
+	}
+
+	rc = vb2_reqbufs(q, b);
+	if (rc)
+		pr_err("Failed to get reqbufs, %d\n", rc);
+	return rc;
+}
+
+int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
+{
+	const struct msm_vidc_format *fmt = NULL;
+	int rc = 0;
+	int i;
+	if (!inst || !f) {
+		pr_err("Invalid input, inst = %p, format = %p\n", inst, f);
+		return -EINVAL;
+	}
+	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+		fmt = inst->fmts[CAPTURE_PORT];
+	else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+		fmt = inst->fmts[OUTPUT_PORT];
+
+	if (fmt) {
+		f->fmt.pix_mp.pixelformat = fmt->fourcc;
+		f->fmt.pix_mp.height = inst->height;
+		f->fmt.pix_mp.width = inst->width;
+		for (i = 0; i < fmt->num_planes; ++i) {
+			f->fmt.pix_mp.plane_fmt[i].sizeimage =
+			fmt->get_frame_size(i, inst->height, inst->width);
+		}
+	} else {
+		pr_err("Buf type not recognized, type = %d\n",
+					f->type);
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
+{
+	const struct msm_vidc_format *fmt = NULL;
+	int rc = 0;
+	int i;
+	if (!inst || !f) {
+		pr_err("Invalid input, inst = %p, format = %p\n", inst, f);
+		return -EINVAL;
+	}
+	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		inst->width = f->fmt.pix_mp.width;
+		inst->height = f->fmt.pix_mp.height;
+		fmt = msm_comm_get_pixel_fmt_fourcc(vdec_formats,
+			ARRAY_SIZE(vdec_formats), f->fmt.pix_mp.pixelformat,
+			CAPTURE_PORT);
+		if (fmt && fmt->type != CAPTURE_PORT) {
+			pr_err("Format: %d not supported on CAPTURE port\n",
+					f->fmt.pix_mp.pixelformat);
+			rc = -EINVAL;
+			goto err_invalid_fmt;
+		}
+	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		fmt = msm_comm_get_pixel_fmt_fourcc(vdec_formats,
+			ARRAY_SIZE(vdec_formats), f->fmt.pix_mp.pixelformat,
+			OUTPUT_PORT);
+		if (fmt && fmt->type != OUTPUT_PORT) {
+			pr_err("Format: %d not supported on OUTPUT port\n",
+					f->fmt.pix_mp.pixelformat);
+			rc = -EINVAL;
+			goto err_invalid_fmt;
+		}
+	}
+
+	if (fmt) {
+		for (i = 0; i < fmt->num_planes; ++i) {
+			f->fmt.pix_mp.plane_fmt[i].sizeimage =
+				fmt->get_frame_size(i, f->fmt.pix_mp.height,
+						f->fmt.pix_mp.width);
+		}
+		inst->fmts[fmt->type] = fmt;
+		if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+			rc = msm_comm_try_state(inst, MSM_VIDC_OPEN);
+			if (rc) {
+				pr_err("Failed to open instance\n");
+				goto err_invalid_fmt;
+			}
+		}
+	} else {
+		pr_err("Buf type not recognized, type = %d\n",
+					f->type);
+		rc = -EINVAL;
+	}
+err_invalid_fmt:
+	return rc;
+}
+
+int msm_vdec_querycap(struct msm_vidc_inst *inst, struct v4l2_capability *cap)
+{
+	if (!inst || !cap) {
+		pr_err("Invalid input, inst = %p, cap = %p\n", inst, cap);
+		return -EINVAL;
+	}
+	strlcpy(cap->driver, MSM_VIDC_DRV_NAME, sizeof(cap->driver));
+	strlcpy(cap->card, MSM_VDEC_DVC_NAME, sizeof(cap->card));
+	cap->bus_info[0] = 0;
+	cap->version = MSM_VIDC_VERSION;
+	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
+						V4L2_CAP_VIDEO_OUTPUT_MPLANE |
+						V4L2_CAP_STREAMING;
+	memset(cap->reserved, 0, sizeof(cap->reserved));
+	return 0;
+}
+
+int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f)
+{
+	const struct msm_vidc_format *fmt = NULL;
+	int rc = 0;
+	if (!inst || !f) {
+		pr_err("Invalid input, inst = %p, f = %p\n", inst, f);
+		return -EINVAL;
+	}
+	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		fmt = msm_comm_get_pixel_fmt_index(vdec_formats,
+			ARRAY_SIZE(vdec_formats), f->index, CAPTURE_PORT);
+	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		fmt = msm_comm_get_pixel_fmt_index(vdec_formats,
+			ARRAY_SIZE(vdec_formats), f->index, OUTPUT_PORT);
+		f->flags = V4L2_FMT_FLAG_COMPRESSED;
+	}
+
+	memset(f->reserved, 0 , sizeof(f->reserved));
+	if (fmt) {
+		strlcpy(f->description, fmt->description,
+				sizeof(f->description));
+		f->pixelformat = fmt->fourcc;
+	} else {
+		pr_err("No more formats found\n");
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+static int msm_vdec_queue_setup(struct vb2_queue *q, unsigned int *num_buffers,
+			unsigned int *num_planes, unsigned long sizes[],
+			void *alloc_ctxs[])
+{
+	int i, rc = 0;
+	struct msm_vidc_inst *inst;
+	struct hal_frame_size frame_sz;
+	unsigned long flags;
+	if (!q || !q->drv_priv) {
+		pr_err("Invalid input, q = %p\n", q);
+		return -EINVAL;
+	}
+	inst = q->drv_priv;
+	switch (q->type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		*num_planes = 1;
+		if (*num_buffers < MIN_NUM_OUTPUT_BUFFERS ||
+				*num_buffers > MAX_NUM_OUTPUT_BUFFERS)
+			*num_buffers = MIN_NUM_OUTPUT_BUFFERS;
+		for (i = 0; i < *num_planes; i++) {
+			sizes[i] = inst->fmts[OUTPUT_PORT]->get_frame_size(
+					i, inst->height, inst->width);
+		}
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		pr_debug("Getting bufreqs on capture plane\n");
+		rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
+		if (rc) {
+			pr_err("Failed to open instance\n");
+			break;
+		}
+		frame_sz.buffer_type = HAL_BUFFER_OUTPUT;
+		frame_sz.width = inst->width;
+		frame_sz.height = inst->height;
+		pr_debug("width = %d, height = %d\n",
+				frame_sz.width, frame_sz.height);
+		rc = vidc_hal_session_set_property((void *)inst->session,
+				HAL_PARAM_FRAME_SIZE, &frame_sz);
+		if (rc) {
+			pr_err("Failed to set hal property for framesize\n");
+			break;
+		}
+		rc = msm_comm_try_get_bufreqs(inst);
+		if (rc) {
+			pr_err("Failed to get buffer requirements: %d\n", rc);
+			break;
+		}
+		*num_planes = 1;
+		spin_lock_irqsave(&inst->lock, flags);
+		*num_buffers = inst->buff_req.buffer[1].buffer_count_actual;
+		spin_unlock_irqrestore(&inst->lock, flags);
+		pr_debug("size = %d, alignment = %d\n",
+				inst->buff_req.buffer[1].buffer_size,
+				inst->buff_req.buffer[1].buffer_alignment);
+		for (i = 0; i < *num_planes; i++) {
+			sizes[i] = inst->fmts[CAPTURE_PORT]->get_frame_size(
+					i, inst->height, inst->width);
+		}
+
+		break;
+	default:
+		pr_err("Invalid q type = %d\n", q->type);
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static inline int start_streaming(struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	unsigned long flags;
+	struct vb2_buf_entry *temp;
+	struct list_head *ptr, *next;
+	struct v4l2_control control;
+	struct hal_nal_stream_format_supported stream_format;
+	struct hal_enable_picture enable_picture;
+	struct hal_enable hal_property;
+	struct hal_enable prop;
+	u32 control_idx = 0;
+	enum hal_property property_id = 0;
+	u32 property_val = 0;
+	void *pdata;
+	rc = msm_comm_set_scratch_buffers(inst);
+	if (rc) {
+		pr_err("Failed to set scratch buffers: %d\n", rc);
+		goto fail_start;
+	}
+	for (; control_idx < NUM_CTRLS; control_idx++) {
+		control.id = msm_vdec_ctrls[control_idx].id;
+		rc = v4l2_g_ctrl(&inst->ctrl_handler, &control);
+		if (rc) {
+			pr_err("Failed to get control value for ID=%d\n",
+				   msm_vdec_ctrls[control_idx].id);
+		} else {
+			property_id = 0;
+			switch (control.id) {
+			case V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT:
+				property_id =
+					HAL_PARAM_NAL_STREAM_FORMAT_SELECT;
+				stream_format.nal_stream_format_supported =
+					(0x00000001 << control.value);
+				pdata = &stream_format;
+				break;
+			case V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER:
+				property_id = HAL_PARAM_VDEC_OUTPUT_ORDER;
+				property_val = control.value;
+				pdata = &property_val;
+				break;
+			case V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_PICTURE_TYPE:
+				property_id =
+					HAL_PARAM_VDEC_PICTURE_TYPE_DECODE;
+				enable_picture.picture_type = control.value;
+				pdata = &enable_picture;
+				break;
+			case V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO:
+				property_id =
+				HAL_PARAM_VDEC_OUTPUT2_KEEP_ASPECT_RATIO;
+				hal_property.enable = control.value;
+				pdata = &hal_property;
+				break;
+			case V4L2_CID_MPEG_VIDC_VIDEO_POST_LOOP_DEBLOCKER_MODE:
+				property_id =
+					HAL_CONFIG_VDEC_POST_LOOP_DEBLOCKER;
+				hal_property.enable = control.value;
+				pdata = &hal_property;
+				break;
+			case V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT:
+				property_id = HAL_PARAM_DIVX_FORMAT;
+				property_val = control.value;
+				pdata = &property_val;
+				break;
+			case V4L2_CID_MPEG_VIDC_VIDEO_MB_ERROR_MAP_REPORTING:
+				property_id =
+					HAL_CONFIG_VDEC_MB_ERROR_MAP_REPORTING;
+				hal_property.enable = control.value;
+				pdata = &hal_property;
+				break;
+			case V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER:
+				property_id =
+					HAL_PARAM_VDEC_CONTINUE_DATA_TRANSFER;
+				hal_property.enable = control.value;
+				pdata = &hal_property;
+				break;
+			default:
+				break;
+			}
+			if (property_id) {
+				pr_err("Control: HAL property=%d,ctrl_id=%d,ctrl_value=%d\n",
+					   property_id,
+					   msm_vdec_ctrls[control_idx].id,
+					   control.value);
+				rc = vidc_hal_session_set_property((void *)
+						inst->session, property_id,
+						pdata);
+			}
+			if (rc)
+				pr_err("Failed to set hal property for framesize\n");
+		}
+	}
+
+	prop.enable = 1;
+	rc = vidc_hal_session_set_property((void *)inst->session,
+			HAL_PARAM_VDEC_CONTINUE_DATA_TRANSFER, &prop);
+	if (rc)
+		pr_err("Failed to set smooth streaming\n");
+
+	rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE);
+	if (rc) {
+		pr_err("Failed to move inst: %p to start done state\n",
+				inst);
+		goto fail_start;
+	}
+	spin_lock_irqsave(&inst->lock, flags);
+	if (!list_empty(&inst->pendingq)) {
+		list_for_each_safe(ptr, next, &inst->pendingq) {
+			temp = list_entry(ptr, struct vb2_buf_entry, list);
+			rc = msm_comm_qbuf(temp->vb);
+			if (rc) {
+				pr_err("Failed to qbuf to hardware\n");
+				break;
+			}
+			list_del(&temp->list);
+			kfree(temp);
+		}
+	}
+	spin_unlock_irqrestore(&inst->lock, flags);
+	return rc;
+fail_start:
+	return rc;
+}
+
+static int msm_vdec_start_streaming(struct vb2_queue *q)
+{
+	struct msm_vidc_inst *inst;
+	int rc = 0;
+	if (!q || !q->drv_priv) {
+		pr_err("Invalid input, q = %p\n", q);
+		return -EINVAL;
+	}
+	inst = q->drv_priv;
+	pr_debug("Streamon called on: %d capability\n", q->type);
+	switch (q->type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		if (inst->vb2_bufq[CAPTURE_PORT].streaming)
+			rc = start_streaming(inst);
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		if (inst->vb2_bufq[OUTPUT_PORT].streaming)
+			rc = start_streaming(inst);
+		break;
+	default:
+		pr_err("Q-type is not supported: %d\n", q->type);
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static int msm_vdec_stop_streaming(struct vb2_queue *q)
+{
+	struct msm_vidc_inst *inst;
+	int rc = 0;
+	if (!q || !q->drv_priv) {
+		pr_err("Invalid input, q = %p\n", q);
+		return -EINVAL;
+	}
+	inst = q->drv_priv;
+	pr_debug("Streamoff called on: %d capability\n", q->type);
+	switch (q->type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		rc = msm_comm_try_state(inst, MSM_VIDC_CLOSE_DONE);
+		break;
+	default:
+		pr_err("Q-type is not supported: %d\n", q->type);
+		rc = -EINVAL;
+		break;
+	}
+	if (rc)
+		pr_err("Failed to move inst: %p, cap = %d to state: %d\n",
+				inst, q->type, MSM_VIDC_CLOSE_DONE);
+	return rc;
+}
+
+static void msm_vdec_buf_queue(struct vb2_buffer *vb)
+{
+	int rc;
+	rc = msm_comm_qbuf(vb);
+	if (rc)
+		pr_err("Failed to queue buffer: %d\n", rc);
+}
+
+static const struct vb2_ops msm_vdec_vb2q_ops = {
+	.queue_setup = msm_vdec_queue_setup,
+	.start_streaming = msm_vdec_start_streaming,
+	.buf_queue = msm_vdec_buf_queue,
+	.stop_streaming = msm_vdec_stop_streaming,
+};
+
+const struct vb2_ops *msm_vdec_get_vb2q_ops(void)
+{
+	return &msm_vdec_vb2q_ops;
+}
+
+int msm_vdec_inst_init(struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	if (!inst) {
+		pr_err("Invalid input = %p\n", inst);
+		return -EINVAL;
+	}
+	inst->fmts[OUTPUT_PORT] = &vdec_formats[1];
+	inst->fmts[CAPTURE_PORT] = &vdec_formats[0];
+	inst->height = DEFAULT_HEIGHT;
+	inst->width = DEFAULT_WIDTH;
+	return rc;
+}
+
+static int msm_vdec_op_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	return 0;
+}
+static int msm_vdec_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops msm_vdec_ctrl_ops = {
+
+	.s_ctrl = msm_vdec_op_s_ctrl,
+	.g_volatile_ctrl = msm_vdec_op_g_volatile_ctrl,
+};
+
+const struct v4l2_ctrl_ops *msm_vdec_get_ctrl_ops(void)
+{
+	return &msm_vdec_ctrl_ops;
+}
+
+int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl)
+{
+	return v4l2_s_ctrl(&inst->ctrl_handler, ctrl);
+}
+int msm_vdec_g_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl)
+{
+	return v4l2_g_ctrl(&inst->ctrl_handler, ctrl);
+}
+int msm_vdec_ctrl_init(struct msm_vidc_inst *inst)
+{
+	int idx = 0;
+	struct v4l2_ctrl_config ctrl_cfg;
+	int ret_val = 0;
+
+	ret_val = v4l2_ctrl_handler_init(&inst->ctrl_handler, NUM_CTRLS);
+
+	if (ret_val) {
+		pr_err("CTRL ERR: Control handler init failed, %d\n",
+				inst->ctrl_handler.error);
+		return ret_val;
+	}
+
+	for (; idx < NUM_CTRLS; idx++) {
+		if (IS_PRIV_CTRL(msm_vdec_ctrls[idx].id)) {
+			/*add private control*/
+			ctrl_cfg.def = msm_vdec_ctrls[idx].default_value;
+			ctrl_cfg.flags = 0;
+			ctrl_cfg.id = msm_vdec_ctrls[idx].id;
+			/*ctrl_cfg.is_private =
+			 * msm_vdec_ctrls[idx].is_private;
+			 * ctrl_cfg.is_volatile =
+			 * msm_vdec_ctrls[idx].is_volatile;*/
+			ctrl_cfg.max = msm_vdec_ctrls[idx].maximum;
+			ctrl_cfg.min = msm_vdec_ctrls[idx].minimum;
+			ctrl_cfg.menu_skip_mask =
+				msm_vdec_ctrls[idx].menu_skip_mask;
+			ctrl_cfg.name = msm_vdec_ctrls[idx].name;
+			ctrl_cfg.ops = &msm_vdec_ctrl_ops;
+			ctrl_cfg.step = msm_vdec_ctrls[idx].step;
+			ctrl_cfg.type = msm_vdec_ctrls[idx].type;
+			ctrl_cfg.qmenu = msm_vdec_ctrls[idx].qmenu;
+
+			v4l2_ctrl_new_custom(&inst->ctrl_handler,
+					&ctrl_cfg, NULL);
+		} else {
+			if (msm_vdec_ctrls[idx].type == V4L2_CTRL_TYPE_MENU) {
+				v4l2_ctrl_new_std_menu(&inst->ctrl_handler,
+					&msm_vdec_ctrl_ops,
+					msm_vdec_ctrls[idx].id,
+					msm_vdec_ctrls[idx].maximum,
+					msm_vdec_ctrls[idx].menu_skip_mask,
+					msm_vdec_ctrls[idx].default_value);
+			} else {
+				v4l2_ctrl_new_std(&inst->ctrl_handler,
+					&msm_vdec_ctrl_ops,
+					msm_vdec_ctrls[idx].id,
+					msm_vdec_ctrls[idx].minimum,
+					msm_vdec_ctrls[idx].maximum,
+					msm_vdec_ctrls[idx].step,
+					msm_vdec_ctrls[idx].default_value);
+			}
+		}
+	}
+	ret_val = inst->ctrl_handler.error;
+	if (ret_val)
+		pr_err("CTRL ERR: Error adding ctrls to ctrl handle, %d\n",
+				inst->ctrl_handler.error);
+	return ret_val;
+}
diff --git a/drivers/media/video/msm_vidc/msm_vdec.h b/drivers/media/video/msm_vidc/msm_vdec.h
new file mode 100644
index 0000000..6529065
--- /dev/null
+++ b/drivers/media/video/msm_vidc/msm_vdec.h
@@ -0,0 +1,35 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef _MSM_VDEC_H_
+#define _MSM_VDEC_H_
+
+#include <media/msm_vidc.h>
+#include "msm_vidc_internal.h"
+
+int msm_vdec_inst_init(struct msm_vidc_inst *inst);
+int msm_vdec_ctrl_init(struct msm_vidc_inst *inst);
+int msm_vdec_querycap(void *instance, struct v4l2_capability *cap);
+int msm_vdec_enum_fmt(void *instance, struct v4l2_fmtdesc *f);
+int msm_vdec_s_fmt(void *instance, struct v4l2_format *f);
+int msm_vdec_g_fmt(void *instance, struct v4l2_format *f);
+int msm_vdec_s_ctrl(void *instance, struct v4l2_control *a);
+int msm_vdec_g_ctrl(void *instance, struct v4l2_control *a);
+int msm_vdec_reqbufs(void *instance, struct v4l2_requestbuffers *b);
+int msm_vdec_prepare_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
+int msm_vdec_qbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
+int msm_vdec_dqbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
+int msm_vdec_streamon(struct msm_vidc_inst *inst, enum v4l2_buf_type i);
+int msm_vdec_streamoff(struct msm_vidc_inst *inst, enum v4l2_buf_type i);
+struct vb2_ops *msm_vdec_get_vb2q_ops(void);
+
+#endif
diff --git a/drivers/media/video/msm_vidc/msm_venc.c b/drivers/media/video/msm_vidc/msm_venc.c
new file mode 100644
index 0000000..cae2d6f
--- /dev/null
+++ b/drivers/media/video/msm_vidc/msm_venc.c
@@ -0,0 +1,522 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/slab.h>
+
+#include "msm_vidc_internal.h"
+#include "msm_vidc_common.h"
+#include "vidc_hal_api.h"
+#include "msm_smem.h"
+
+#define MSM_VENC_DVC_NAME "msm_venc_8974"
+#define DEFAULT_HEIGHT 720
+#define DEFAULT_WIDTH 1280
+#define MIN_NUM_OUTPUT_BUFFERS 2
+#define MAX_NUM_OUTPUT_BUFFERS 8
+static u32 get_frame_size_nv12(int plane, u32 height, u32 width)
+{
+	int stride = (width + 31) & (~31);
+	return height * stride * 3/2;
+}
+static u32 get_frame_size_nv21(int plane, u32 height, u32 width)
+{
+	return height * width * 2;
+}
+
+static u32 get_frame_size_compressed(int plane, u32 height, u32 width)
+{
+	return width * height / 2;
+}
+
+static const struct msm_vidc_format venc_formats[] = {
+	{
+		.name = "YCbCr Semiplanar 4:2:0",
+		.description = "Y/CbCr 4:2:0",
+		.fourcc = V4L2_PIX_FMT_NV12,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_nv12,
+		.type = OUTPUT_PORT,
+	},
+	{
+		.name = "Mpeg4",
+		.description = "Mpeg4 compressed format",
+		.fourcc = V4L2_PIX_FMT_MPEG4,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_compressed,
+		.type = CAPTURE_PORT,
+	},
+	{
+		.name = "H263",
+		.description = "H263 compressed format",
+		.fourcc = V4L2_PIX_FMT_H263,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_compressed,
+		.type = CAPTURE_PORT,
+	},
+	{
+		.name = "H264",
+		.description = "H264 compressed format",
+		.fourcc = V4L2_PIX_FMT_H264,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_compressed,
+		.type = CAPTURE_PORT,
+	},
+	{
+		.name = "YCrCb Semiplanar 4:2:0",
+		.description = "Y/CrCb 4:2:0",
+		.fourcc = V4L2_PIX_FMT_NV21,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_nv21,
+		.type = OUTPUT_PORT,
+	},
+};
+
+static int msm_venc_queue_setup(struct vb2_queue *q, unsigned int *num_buffers,
+			unsigned int *num_planes, unsigned long sizes[],
+			void *alloc_ctxs[])
+{
+	int i, rc = 0;
+	struct msm_vidc_inst *inst;
+	struct hal_frame_size frame_sz;
+	unsigned long flags;
+	if (!q || !q->drv_priv) {
+		pr_err("Invalid input, q = %p\n", q);
+		return -EINVAL;
+	}
+	inst = q->drv_priv;
+	switch (q->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		*num_planes = 1;
+		if (*num_buffers < MIN_NUM_OUTPUT_BUFFERS ||
+				*num_buffers > MAX_NUM_OUTPUT_BUFFERS)
+			*num_buffers = MIN_NUM_OUTPUT_BUFFERS;
+		for (i = 0; i < *num_planes; i++) {
+			sizes[i] = inst->fmts[OUTPUT_PORT]->get_frame_size(
+					i, inst->height, inst->width);
+		}
+		break;
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
+		if (rc) {
+			pr_err("Failed to open instance\n");
+			break;
+		}
+		frame_sz.buffer_type = HAL_BUFFER_INPUT;
+		frame_sz.width = inst->width;
+		frame_sz.height = inst->height;
+		pr_debug("width = %d, height = %d\n",
+				frame_sz.width, frame_sz.height);
+		rc = vidc_hal_session_set_property((void *)inst->session,
+				HAL_PARAM_FRAME_SIZE, &frame_sz);
+		if (rc) {
+			pr_err("Failed to set hal property for framesize\n");
+			break;
+		}
+		rc = msm_comm_try_get_bufreqs(inst);
+		if (rc) {
+			pr_err("Failed to get buffer requirements: %d\n", rc);
+			break;
+		}
+		*num_planes = 1;
+		spin_lock_irqsave(&inst->lock, flags);
+		*num_buffers = inst->buff_req.buffer[0].buffer_count_actual;
+		spin_unlock_irqrestore(&inst->lock, flags);
+		pr_debug("size = %d, alignment = %d, count = %d\n",
+				inst->buff_req.buffer[0].buffer_size,
+				inst->buff_req.buffer[0].buffer_alignment,
+				inst->buff_req.buffer[0].buffer_count_actual);
+		for (i = 0; i < *num_planes; i++) {
+			sizes[i] = inst->fmts[CAPTURE_PORT]->get_frame_size(
+					i, inst->height, inst->width);
+		}
+
+		break;
+	default:
+		pr_err("Invalid q type = %d\n", q->type);
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static inline int start_streaming(struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	unsigned long flags;
+	struct vb2_buf_entry *temp;
+	struct list_head *ptr, *next;
+	rc = msm_comm_set_scratch_buffers(inst);
+	if (rc) {
+		pr_err("Failed to set scratch buffers: %d\n", rc);
+		goto fail_start;
+	}
+	rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE);
+	if (rc) {
+		pr_err("Failed to move inst: %p to start done state\n",
+				inst);
+		goto fail_start;
+	}
+	spin_lock_irqsave(&inst->lock, flags);
+	if (!list_empty(&inst->pendingq)) {
+		list_for_each_safe(ptr, next, &inst->pendingq) {
+			temp = list_entry(ptr, struct vb2_buf_entry, list);
+			rc = msm_comm_qbuf(temp->vb);
+			if (rc) {
+				pr_err("Failed to qbuf to hardware\n");
+				break;
+			}
+			list_del(&temp->list);
+			kfree(temp);
+		}
+	}
+	spin_unlock_irqrestore(&inst->lock, flags);
+	return rc;
+fail_start:
+	return rc;
+}
+
+static int msm_venc_start_streaming(struct vb2_queue *q)
+{
+	struct msm_vidc_inst *inst;
+	int rc = 0;
+	if (!q || !q->drv_priv) {
+		pr_err("Invalid input, q = %p\n", q);
+		return -EINVAL;
+	}
+	inst = q->drv_priv;
+	pr_debug("Streamon called on: %d capability\n", q->type);
+	switch (q->type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		if (inst->vb2_bufq[CAPTURE_PORT].streaming)
+			rc = start_streaming(inst);
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		if (inst->vb2_bufq[OUTPUT_PORT].streaming)
+			rc = start_streaming(inst);
+		break;
+	default:
+		pr_err("Q-type is not supported: %d\n", q->type);
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static int msm_venc_stop_streaming(struct vb2_queue *q)
+{
+	struct msm_vidc_inst *inst;
+	int rc = 0;
+	if (!q || !q->drv_priv) {
+		pr_err("Invalid input, q = %p\n", q);
+		return -EINVAL;
+	}
+	inst = q->drv_priv;
+	pr_debug("Streamoff called on: %d capability\n", q->type);
+	switch (q->type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		rc = msm_comm_try_state(inst, MSM_VIDC_CLOSE_DONE);
+		break;
+	default:
+		pr_err("Q-type is not supported: %d\n", q->type);
+		rc = -EINVAL;
+		break;
+	}
+	if (rc)
+		pr_err("Failed to move inst: %p, cap = %d to state: %d\n",
+				inst, q->type, MSM_VIDC_CLOSE_DONE);
+	return rc;
+}
+
+static void msm_venc_buf_queue(struct vb2_buffer *vb)
+{
+	int rc;
+	rc = msm_comm_qbuf(vb);
+	if (rc)
+		pr_err("Failed to queue buffer: %d\n", rc);
+}
+
+static const struct vb2_ops msm_venc_vb2q_ops = {
+	.queue_setup = msm_venc_queue_setup,
+	.start_streaming = msm_venc_start_streaming,
+	.buf_queue = msm_venc_buf_queue,
+	.stop_streaming = msm_venc_stop_streaming,
+};
+
+const struct vb2_ops *msm_venc_get_vb2q_ops(void)
+{
+	return &msm_venc_vb2q_ops;
+}
+
+int msm_venc_inst_init(struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	if (!inst) {
+		pr_err("Invalid input = %p\n", inst);
+		return -EINVAL;
+	}
+	inst->fmts[CAPTURE_PORT] = &venc_formats[1];
+	inst->fmts[OUTPUT_PORT] = &venc_formats[0];
+	inst->height = DEFAULT_HEIGHT;
+	inst->width = DEFAULT_WIDTH;
+	return rc;
+}
+
+int msm_venc_querycap(struct msm_vidc_inst *inst, struct v4l2_capability *cap)
+{
+	if (!inst || !cap) {
+		pr_err("Invalid input, inst = %p, cap = %p\n", inst, cap);
+		return -EINVAL;
+	}
+	strlcpy(cap->driver, MSM_VIDC_DRV_NAME, sizeof(cap->driver));
+	strlcpy(cap->card, MSM_VENC_DVC_NAME, sizeof(cap->card));
+	cap->bus_info[0] = 0;
+	cap->version = MSM_VIDC_VERSION;
+	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
+						V4L2_CAP_VIDEO_OUTPUT_MPLANE |
+						V4L2_CAP_STREAMING;
+	memset(cap->reserved, 0, sizeof(cap->reserved));
+	return 0;
+}
+
+int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f)
+{
+	const struct msm_vidc_format *fmt = NULL;
+	int rc = 0;
+	if (!inst || !f) {
+		pr_err("Invalid input, inst = %p, f = %p\n", inst, f);
+		return -EINVAL;
+	}
+	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		fmt = msm_comm_get_pixel_fmt_index(venc_formats,
+			ARRAY_SIZE(venc_formats), f->index, CAPTURE_PORT);
+	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		fmt = msm_comm_get_pixel_fmt_index(venc_formats,
+			ARRAY_SIZE(venc_formats), f->index, OUTPUT_PORT);
+		f->flags = V4L2_FMT_FLAG_COMPRESSED;
+	}
+
+	memset(f->reserved, 0 , sizeof(f->reserved));
+	if (fmt) {
+		strlcpy(f->description, fmt->description,
+				sizeof(f->description));
+		f->pixelformat = fmt->fourcc;
+	} else {
+		pr_err("No more formats found\n");
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
+{
+	const struct msm_vidc_format *fmt = NULL;
+	int rc = 0;
+	int i;
+	if (!inst || !f) {
+		pr_err("Invalid input, inst = %p, format = %p\n", inst, f);
+		return -EINVAL;
+	}
+	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		fmt = msm_comm_get_pixel_fmt_fourcc(venc_formats,
+			ARRAY_SIZE(venc_formats), f->fmt.pix_mp.pixelformat,
+			CAPTURE_PORT);
+		if (fmt && fmt->type != CAPTURE_PORT) {
+			pr_err("Format: %d not supported on CAPTURE port\n",
+					f->fmt.pix_mp.pixelformat);
+			rc = -EINVAL;
+			goto exit;
+		}
+	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		inst->width = f->fmt.pix_mp.width;
+		inst->height = f->fmt.pix_mp.height;
+		fmt = msm_comm_get_pixel_fmt_fourcc(venc_formats,
+			ARRAY_SIZE(venc_formats), f->fmt.pix_mp.pixelformat,
+			OUTPUT_PORT);
+		if (fmt && fmt->type != OUTPUT_PORT) {
+			pr_err("Format: %d not supported on OUTPUT port\n",
+					f->fmt.pix_mp.pixelformat);
+			rc = -EINVAL;
+			goto exit;
+		}
+	}
+
+	if (fmt) {
+		for (i = 0; i < fmt->num_planes; ++i) {
+			f->fmt.pix_mp.plane_fmt[i].sizeimage =
+				fmt->get_frame_size(i, f->fmt.pix_mp.height,
+						f->fmt.pix_mp.width);
+		}
+		inst->fmts[fmt->type] = fmt;
+		if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+			rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
+			if (rc) {
+				pr_err("Failed to open instance\n");
+				goto exit;
+			}
+		}
+	} else {
+		pr_err("Buf type not recognized, type = %d\n",
+					f->type);
+		rc = -EINVAL;
+	}
+exit:
+	return rc;
+}
+
+int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
+{
+	const struct msm_vidc_format *fmt = NULL;
+	int rc = 0;
+	int i;
+	if (!inst || !f) {
+		pr_err("Invalid input, inst = %p, format = %p\n", inst, f);
+		return -EINVAL;
+	}
+	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+		fmt = inst->fmts[CAPTURE_PORT];
+	else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+		fmt = inst->fmts[OUTPUT_PORT];
+
+	if (fmt) {
+		f->fmt.pix_mp.pixelformat = fmt->fourcc;
+		f->fmt.pix_mp.height = inst->height;
+		f->fmt.pix_mp.width = inst->width;
+		for (i = 0; i < fmt->num_planes; ++i) {
+			f->fmt.pix_mp.plane_fmt[i].sizeimage =
+			fmt->get_frame_size(i, inst->height, inst->width);
+		}
+	} else {
+		pr_err("Buf type not recognized, type = %d\n",
+					f->type);
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+int msm_venc_reqbufs(struct msm_vidc_inst *inst, struct v4l2_requestbuffers *b)
+{
+	struct vb2_queue *q = NULL;
+	int rc = 0;
+	if (!inst || !b) {
+		pr_err("Invalid input, inst = %p, buffer = %p\n", inst, b);
+		return -EINVAL;
+	}
+	q = msm_comm_get_vb2q(inst, b->type);
+	if (!q) {
+		pr_err("Failed to find buffer queue for type = %d\n", b->type);
+		return -EINVAL;
+	}
+
+	rc = vb2_reqbufs(q, b);
+	if (rc)
+		pr_err("Failed to get reqbufs, %d\n", rc);
+	return rc;
+}
+
+int msm_venc_prepare_buf(struct msm_vidc_inst *inst,
+					struct v4l2_buffer *b)
+{
+	int rc = 0;
+	int i;
+	struct vidc_buffer_addr_info buffer_info;
+
+	switch (b->type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		for (i = 0; i < b->length; i++) {
+			pr_err("device_addr = %ld, size = %d\n",
+				b->m.planes[i].m.userptr,
+				b->m.planes[i].length);
+			buffer_info.buffer_size = b->m.planes[i].length;
+			buffer_info.buffer_type = HAL_BUFFER_OUTPUT;
+			buffer_info.num_buffers = 1;
+			buffer_info.align_device_addr =
+				b->m.planes[i].m.userptr;
+			buffer_info.extradata_size = 0;
+			buffer_info.extradata_addr = 0;
+			rc = vidc_hal_session_set_buffers((void *)inst->session,
+					&buffer_info);
+			if (rc)
+				pr_err("vidc_hal_session_set_buffers failed");
+		}
+		break;
+	default:
+		pr_err("Buffer type not recognized: %d\n", b->type);
+		break;
+	}
+	return rc;
+}
+
+int msm_venc_qbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b)
+{
+	struct vb2_queue *q = NULL;
+	int rc = 0;
+	q = msm_comm_get_vb2q(inst, b->type);
+	if (!q) {
+		pr_err("Failed to find buffer queue for type = %d\n", b->type);
+		return -EINVAL;
+	}
+	rc = vb2_qbuf(q, b);
+	if (rc)
+		pr_err("Failed to qbuf, %d\n", rc);
+	return rc;
+}
+
+int msm_venc_dqbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b)
+{
+	struct vb2_queue *q = NULL;
+	int rc = 0;
+	q = msm_comm_get_vb2q(inst, b->type);
+	if (!q) {
+		pr_err("Failed to find buffer queue for type = %d\n", b->type);
+		return -EINVAL;
+	}
+	rc = vb2_dqbuf(q, b, true);
+	if (rc)
+		pr_err("Failed to qbuf, %d\n", rc);
+	return rc;
+}
+
+int msm_venc_streamon(struct msm_vidc_inst *inst, enum v4l2_buf_type i)
+{
+	int rc = 0;
+	struct vb2_queue *q;
+	q = msm_comm_get_vb2q(inst, i);
+	if (!q) {
+		pr_err("Failed to find buffer queue for type = %d\n", i);
+		return -EINVAL;
+	}
+	pr_debug("Calling streamon\n");
+	rc = vb2_streamon(q, i);
+	if (rc)
+		pr_err("streamon failed on port: %d\n", i);
+	return rc;
+}
+
+int msm_venc_streamoff(struct msm_vidc_inst *inst, enum v4l2_buf_type i)
+{
+	int rc = 0;
+	struct vb2_queue *q;
+	q = msm_comm_get_vb2q(inst, i);
+	if (!q) {
+		pr_err("Failed to find buffer queue for type = %d\n", i);
+		return -EINVAL;
+	}
+	pr_debug("Calling streamoff\n");
+	rc = vb2_streamoff(q, i);
+	if (rc)
+		pr_err("streamoff failed on port: %d\n", i);
+	return rc;
+}
diff --git a/drivers/media/video/msm_vidc/msm_venc.h b/drivers/media/video/msm_vidc/msm_venc.h
new file mode 100644
index 0000000..4a156dd
--- /dev/null
+++ b/drivers/media/video/msm_vidc/msm_venc.h
@@ -0,0 +1,35 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef _MSM_VENC_H_
+#define _MSM_VENC_H_
+
+#include <media/msm_vidc.h>
+#include "msm_vidc_internal.h"
+
+int msm_venc_inst_init(struct msm_vidc_inst *inst);
+int msm_venc_ctrl_init(struct msm_vidc_inst *inst);
+int msm_venc_querycap(void *instance, struct v4l2_capability *cap);
+int msm_venc_enum_fmt(void *instance, struct v4l2_fmtdesc *f);
+int msm_venc_s_fmt(void *instance, struct v4l2_format *f);
+int msm_venc_g_fmt(void *instance, struct v4l2_format *f);
+int msm_venc_s_ctrl(void *instance, struct v4l2_control *a);
+int msm_venc_g_ctrl(void *instance, struct v4l2_control *a);
+int msm_venc_reqbufs(void *instance, struct v4l2_requestbuffers *b);
+int msm_venc_prepare_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
+int msm_venc_qbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
+int msm_venc_dqbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
+int msm_venc_streamon(struct msm_vidc_inst *inst, enum v4l2_buf_type i);
+int msm_venc_streamoff(struct msm_vidc_inst *inst, enum v4l2_buf_type i);
+struct vb2_ops *msm_venc_get_vb2q_ops(void);
+
+#endif
diff --git a/drivers/media/video/msm_vidc/msm_vidc.c b/drivers/media/video/msm_vidc/msm_vidc.c
new file mode 100644
index 0000000..4725f5f
--- /dev/null
+++ b/drivers/media/video/msm_vidc/msm_vidc.c
@@ -0,0 +1,339 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/slab.h>
+#include <media/msm_vidc.h>
+#include "msm_vidc_internal.h"
+#include "msm_vdec.h"
+#include "msm_venc.h"
+#include "msm_vidc_common.h"
+#include "msm_smem.h"
+
+int msm_vidc_poll(void *instance, struct file *filp,
+		struct poll_table_struct *wait)
+{
+	int rc = 0;
+	struct msm_vidc_inst *inst = instance;
+	struct vb2_queue *outq = &inst->vb2_bufq[OUTPUT_PORT];
+	struct vb2_queue *capq = &inst->vb2_bufq[CAPTURE_PORT];
+	struct vb2_buffer *out_vb = NULL;
+	struct vb2_buffer *cap_vb = NULL;
+	unsigned long flags;
+	if (!outq->streaming && !capq->streaming) {
+		pr_err("Returning POLLERR from here: %d, %d\n",
+			outq->streaming, capq->streaming);
+		return POLLERR;
+	}
+	poll_wait(filp, &capq->done_wq, wait);
+	poll_wait(filp, &outq->done_wq, wait);
+	spin_lock_irqsave(&capq->done_lock, flags);
+	if (!list_empty(&capq->done_list))
+		cap_vb = list_first_entry(&capq->done_list, struct vb2_buffer,
+								done_entry);
+	if (cap_vb && (cap_vb->state == VB2_BUF_STATE_DONE
+				|| cap_vb->state == VB2_BUF_STATE_ERROR))
+		rc |= POLLIN | POLLRDNORM;
+	spin_unlock_irqrestore(&capq->done_lock, flags);
+	spin_lock_irqsave(&outq->done_lock, flags);
+	if (!list_empty(&outq->done_list))
+		out_vb = list_first_entry(&outq->done_list, struct vb2_buffer,
+								done_entry);
+	if (out_vb && (out_vb->state == VB2_BUF_STATE_DONE
+				|| out_vb->state == VB2_BUF_STATE_ERROR))
+		rc |= POLLOUT | POLLWRNORM;
+	spin_unlock_irqrestore(&outq->done_lock, flags);
+	return rc;
+}
+
+int msm_vidc_querycap(void *instance, struct v4l2_capability *cap)
+{
+	struct msm_vidc_inst *inst = instance;
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_querycap(instance, cap);
+	else if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_querycap(instance, cap);
+	return -EINVAL;
+}
+int msm_vidc_enum_fmt(void *instance, struct v4l2_fmtdesc *f)
+{
+	struct msm_vidc_inst *inst = instance;
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_enum_fmt(instance, f);
+	else if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_enum_fmt(instance, f);
+	return -EINVAL;
+}
+int msm_vidc_s_fmt(void *instance, struct v4l2_format *f)
+{
+	struct msm_vidc_inst *inst = instance;
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_s_fmt(instance, f);
+	if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_s_fmt(instance, f);
+	return -EINVAL;
+}
+int msm_vidc_g_fmt(void *instance, struct v4l2_format *f)
+{
+	struct msm_vidc_inst *inst = instance;
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_g_fmt(instance, f);
+	else if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_g_fmt(instance, f);
+	return -EINVAL;
+}
+int msm_vidc_s_ctrl(void *instance, struct v4l2_control *control)
+{
+	struct msm_vidc_inst *inst = instance;
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_s_ctrl(instance, control);
+	return -EINVAL;
+}
+int msm_vidc_g_ctrl(void *instance, struct v4l2_control *control)
+{
+	struct msm_vidc_inst *inst = instance;
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_g_ctrl(instance, control);
+	return -EINVAL;
+}
+int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b)
+{
+	struct msm_vidc_inst *inst = instance;
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_reqbufs(instance, b);
+	if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_reqbufs(instance, b);
+	return -EINVAL;
+}
+
+int msm_vidc_prepare_buf(void *instance, struct v4l2_buffer *b)
+{
+	struct msm_vidc_inst *inst = instance;
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_prepare_buf(instance, b);
+	if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_prepare_buf(instance, b);
+	return -EINVAL;
+}
+
+int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
+{
+	struct msm_vidc_inst *inst = instance;
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_qbuf(instance, b);
+	if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_qbuf(instance, b);
+	return -EINVAL;
+}
+
+int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b)
+{
+	struct msm_vidc_inst *inst = instance;
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_dqbuf(instance, b);
+	if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_dqbuf(instance, b);
+	return -EINVAL;
+}
+
+int msm_vidc_streamon(void *instance, enum v4l2_buf_type i)
+{
+	struct msm_vidc_inst *inst = instance;
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_streamon(instance, i);
+	if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_streamon(instance, i);
+	return -EINVAL;
+}
+
+int msm_vidc_streamoff(void *instance, enum v4l2_buf_type i)
+{
+	struct msm_vidc_inst *inst = instance;
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_streamoff(instance, i);
+	if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_streamoff(instance, i);
+	return -EINVAL;
+}
+
+void *vidc_get_userptr(void *alloc_ctx, unsigned long vaddr,
+				unsigned long size, int write)
+{
+	return NULL;
+}
+
+void vidc_put_userptr(void *buf_priv)
+{
+}
+
+static const struct vb2_mem_ops msm_vidc_vb2_mem_ops = {
+	.get_userptr = vidc_get_userptr,
+	.put_userptr = vidc_put_userptr,
+};
+
+static inline int vb2_bufq_init(struct msm_vidc_inst *inst,
+		enum v4l2_buf_type type, enum session_type sess)
+{
+	struct vb2_queue *q = NULL;
+	if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		q = &inst->vb2_bufq[CAPTURE_PORT];
+	} else if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		q = &inst->vb2_bufq[OUTPUT_PORT];
+	} else {
+		pr_err("buf_type = %d not recognised\n", type);
+		return -EINVAL;
+	}
+	q->type = type;
+	q->io_modes = VB2_MMAP | VB2_USERPTR;
+	q->io_flags = 0;
+	if (sess == MSM_VIDC_DECODER)
+		q->ops = msm_vdec_get_vb2q_ops();
+	else if (sess == MSM_VIDC_ENCODER)
+		q->ops = msm_venc_get_vb2q_ops();
+	q->mem_ops = &msm_vidc_vb2_mem_ops;
+	q->drv_priv = inst;
+	return vb2_queue_init(q);
+}
+
+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;
+	int i = 0;
+	if (core_id >= MSM_VIDC_CORES_MAX ||
+			session_type >= MSM_VIDC_MAX_DEVICES) {
+		pr_err("Invalid input, core_id = %d, session = %d\n",
+			core_id, session_type);
+		goto err_invalid_core;
+	}
+	core = get_vidc_core(core_id);
+	if (!core) {
+		pr_err("Failed to find core for core_id = %d\n", core_id);
+		goto err_invalid_core;
+	}
+
+	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+	if (!inst) {
+		pr_err("Unable to allocate video instance\n");
+		goto err_no_mem;
+	}
+	mutex_init(&inst->sync_lock);
+	spin_lock_init(&inst->lock);
+	inst->session_type = session_type;
+	INIT_LIST_HEAD(&inst->pendingq);
+	INIT_LIST_HEAD(&inst->internalbufs);
+	INIT_LIST_HEAD(&inst->extradatabufs);
+	inst->state = MSM_VIDC_CORE_UNINIT_DONE;
+	inst->core = core;
+	for (i = SESSION_MSG_INDEX(SESSION_MSG_START);
+		i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) {
+		init_completion(&inst->completions[i]);
+	}
+	inst->mem_client = msm_smem_new_client(SMEM_ION);
+	if (!inst->mem_client) {
+		pr_err("Failed to create memory client\n");
+		goto fail_mem_client;
+	}
+	if (session_type == MSM_VIDC_DECODER) {
+		msm_vdec_inst_init(inst);
+		msm_vdec_ctrl_init(inst);
+	} else if (session_type == MSM_VIDC_ENCODER) {
+		msm_venc_inst_init(inst);
+	}
+	rc = vb2_bufq_init(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+			session_type);
+	if (rc) {
+		pr_err("Failed to initialize vb2 queue on capture port\n");
+		goto fail_init;
+	}
+	rc = vb2_bufq_init(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+			session_type);
+	if (rc) {
+		pr_err("Failed to initialize vb2 queue on capture port\n");
+		goto fail_init;
+	}
+	rc = msm_comm_try_state(inst, MSM_VIDC_CORE_INIT);
+	if (rc) {
+		pr_err("Failed to move video instance to init state\n");
+		goto fail_init;
+	}
+	spin_lock_irqsave(&core->lock, flags);
+	list_add_tail(&inst->list, &core->instances);
+	spin_unlock_irqrestore(&core->lock, flags);
+	return inst;
+fail_init:
+	msm_smem_delete_client(inst->mem_client);
+fail_mem_client:
+	kfree(inst);
+	inst = NULL;
+err_no_mem:
+err_invalid_core:
+	return inst;
+}
+
+static void cleanup_instance(struct msm_vidc_inst *inst)
+{
+	unsigned long flags;
+	struct list_head *ptr, *next;
+	struct vb2_buf_entry *entry;
+	struct internal_buf *buf;
+	struct extradata_buf *ebuf;
+	if (inst) {
+		spin_lock_irqsave(&inst->lock, flags);
+		list_for_each_safe(ptr, next, &inst->pendingq) {
+			entry = list_entry(ptr, struct vb2_buf_entry, list);
+			list_del(&entry->list);
+			kfree(entry);
+		}
+		list_for_each_safe(ptr, next, &inst->internalbufs) {
+			buf = list_entry(ptr, struct internal_buf, list);
+			list_del(&buf->list);
+			msm_smem_free(inst->mem_client, buf->handle);
+			kfree(buf);
+		}
+		list_for_each_safe(ptr, next, &inst->extradatabufs) {
+			ebuf = list_entry(ptr, struct extradata_buf, list);
+			list_del(&ebuf->list);
+			msm_smem_free(inst->mem_client, ebuf->handle);
+			kfree(ebuf);
+		}
+		spin_unlock_irqrestore(&inst->lock, flags);
+		msm_smem_delete_client(inst->mem_client);
+	}
+}
+
+int msm_vidc_close(void *instance)
+{
+	struct msm_vidc_inst *inst = instance;
+	struct msm_vidc_inst *temp;
+	struct msm_vidc_core *core;
+	struct list_head *ptr, *next;
+	int rc = 0;
+	core = inst->core;
+	mutex_lock(&core->sync_lock);
+	list_for_each_safe(ptr, next, &core->instances) {
+		temp = list_entry(ptr, struct msm_vidc_inst, list);
+		if (temp == inst) {
+			list_del(&inst->list);
+			kfree(inst);
+		}
+	}
+	mutex_unlock(&core->sync_lock);
+	rc = msm_comm_try_state(inst, MSM_VIDC_CORE_UNINIT);
+	if (rc)
+		pr_err("Failed to move video instance to init state\n");
+	cleanup_instance(inst);
+	pr_debug("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
new file mode 100644
index 0000000..e889b1c
--- /dev/null
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -0,0 +1,929 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+#include "msm_vidc_common.h"
+#include "vidc_hal_api.h"
+#include "msm_smem.h"
+
+#define HW_RESPONSE_TIMEOUT 5000
+
+#define IS_ALREADY_IN_STATE(__p, __d) ({\
+	int __rc = (__p >= __d);\
+	__rc; \
+})
+
+struct msm_vidc_core *get_vidc_core(int core_id)
+{
+	struct msm_vidc_core *core;
+	int found = 0;
+	unsigned long flags;
+	if (core_id > MSM_VIDC_CORES_MAX) {
+		pr_err("Core id = %d is greater than max = %d\n",
+			core_id, MSM_VIDC_CORES_MAX);
+		return NULL;
+	}
+	spin_lock_irqsave(&vidc_driver->lock, flags);
+	list_for_each_entry(core, &vidc_driver->cores, list) {
+		if (core && core->id == core_id)
+			found = 1;
+			break;
+	}
+	spin_unlock_irqrestore(&vidc_driver->lock, flags);
+	if (found)
+		return core;
+	return NULL;
+}
+
+const struct msm_vidc_format *msm_comm_get_pixel_fmt_index(
+	const struct msm_vidc_format fmt[], int size, int index, int fmt_type)
+{
+	int i, k = 0;
+	if (!fmt || index < 0) {
+		pr_err("Invalid inputs, fmt = %p, index = %d\n",
+						fmt, index);
+		return NULL;
+	}
+	for (i = 0; i < size; i++) {
+		if (fmt[i].type != fmt_type)
+			continue;
+		if (k == index)
+			break;
+		k++;
+	}
+	if (i == size) {
+		pr_err("Format not found\n");
+		return NULL;
+	}
+	return &fmt[i];
+}
+const struct msm_vidc_format *msm_comm_get_pixel_fmt_fourcc(
+	const struct msm_vidc_format fmt[], int size, int fourcc, int fmt_type)
+{
+	int i;
+	if (!fmt) {
+		pr_err("Invalid inputs, fmt = %p\n", fmt);
+		return NULL;
+	}
+	for (i = 0; i < size; i++) {
+		if (fmt[i].fourcc == fourcc)
+				break;
+	}
+	if (i == size) {
+		pr_err("Format not found\n");
+		return NULL;
+	}
+	return &fmt[i];
+}
+
+struct vb2_queue *msm_comm_get_vb2q(
+		struct msm_vidc_inst *inst,	enum v4l2_buf_type type)
+{
+	if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+		return &inst->vb2_bufq[CAPTURE_PORT];
+	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+		return &inst->vb2_bufq[OUTPUT_PORT];
+	return NULL;
+}
+
+static void handle_sys_init_done(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_core *core;
+	struct vidc_hal_sys_init_done *sys_init_msg;
+	int index = SYS_MSG_INDEX(cmd);
+	if (!response) {
+		pr_err("Failed to get valid response for sys init\n");
+		return;
+	}
+	core = get_vidc_core(response->device_id);
+	if (!core) {
+		pr_err("Wrong device_id received\n");
+		return;
+	}
+	pr_debug("index = %d\n", index);
+	pr_debug("ptr = %p\n", &(core->completions[index]));
+	complete(&(core->completions[index]));
+	sys_init_msg = response->data;
+	if (!sys_init_msg) {
+		pr_err("sys_init_done message not proper\n");
+		return;
+	}
+}
+
+static inline void change_inst_state(struct msm_vidc_inst *inst,
+	enum instance_state state)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&inst->lock, flags);
+	pr_debug("Moved inst: %p from state: %d to state: %d\n",
+		   inst, inst->state, state);
+	inst->state = state;
+	spin_unlock_irqrestore(&inst->lock, flags);
+}
+
+static int signal_session_msg_receipt(enum command_response cmd,
+		struct msm_vidc_inst *inst)
+{
+	if (!inst) {
+		pr_err("Invalid(%p) instance id\n", inst);
+		return -EINVAL;
+	}
+	complete(&inst->completions[SESSION_MSG_INDEX(cmd)]);
+	return 0;
+}
+
+static int wait_for_sess_signal_receipt(struct msm_vidc_inst *inst,
+	enum command_response cmd)
+{
+	int rc = 0;
+	rc = wait_for_completion_timeout(
+		&inst->completions[SESSION_MSG_INDEX(cmd)],
+		msecs_to_jiffies(HW_RESPONSE_TIMEOUT));
+	if (!rc) {
+		pr_err("Wait interrupted or timeout: %d\n", rc);
+		rc = -EIO;
+	} else {
+		rc = 0;
+	}
+	return rc;
+}
+
+static int wait_for_state(struct msm_vidc_inst *inst,
+	enum instance_state flipped_state,
+	enum instance_state desired_state,
+	enum command_response hal_cmd)
+{
+	int rc = 0;
+	if (IS_ALREADY_IN_STATE(flipped_state, desired_state)) {
+		pr_err("inst: %p is already in state: %d\n", inst, inst->state);
+		goto err_same_state;
+	}
+	pr_debug("Waiting for hal_cmd: %d\n", hal_cmd);
+	rc = wait_for_sess_signal_receipt(inst, hal_cmd);
+	if (!rc)
+		change_inst_state(inst, desired_state);
+err_same_state:
+	return rc;
+}
+
+static void handle_session_init_done(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_inst *inst;
+	if (response) {
+		inst = (struct msm_vidc_inst *)response->session_id;
+		signal_session_msg_receipt(cmd, inst);
+		return;
+	} else {
+		pr_err("Failed to get valid response for session init\n");
+	}
+}
+
+static void handle_session_prop_info(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_inst *inst;
+	unsigned long flags;
+	if (!response || !response->data) {
+		pr_err("Failed to get valid response for prop info\n");
+		return;
+	}
+	inst = (struct msm_vidc_inst *)response->session_id;
+	spin_lock_irqsave(&inst->lock, flags);
+	memcpy(&inst->buff_req, response->data,
+			sizeof(struct buffer_requirements));
+	spin_unlock_irqrestore(&inst->lock, flags);
+	signal_session_msg_receipt(cmd, inst);
+}
+
+static void handle_load_resource_done(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_inst *inst;
+	if (response)
+		inst = (struct msm_vidc_inst *)response->session_id;
+	else
+		pr_err("Failed to get valid response for load resource\n");
+}
+
+static void handle_start_done(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_inst *inst;
+	if (response) {
+		inst = (struct msm_vidc_inst *)response->session_id;
+		signal_session_msg_receipt(cmd, inst);
+	} else {
+		pr_err("Failed to get valid response for start done\n");
+	}
+}
+
+static void handle_stop_done(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_inst *inst;
+	if (response) {
+		inst = (struct msm_vidc_inst *)response->session_id;
+		signal_session_msg_receipt(cmd, inst);
+	} else {
+		pr_err("Failed to get valid response for stop done\n");
+	}
+}
+
+static void handle_release_res_done(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_inst *inst;
+	if (response) {
+		inst = (struct msm_vidc_inst *)response->session_id;
+		signal_session_msg_receipt(cmd, inst);
+	} else {
+		pr_err("Failed to get valid response for release"
+			   " resource done\n");
+	}
+}
+
+static void handle_session_close(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_inst *inst;
+	if (response) {
+		inst = (struct msm_vidc_inst *)response->session_id;
+		signal_session_msg_receipt(cmd, inst);
+	} else {
+		pr_err("Failed to get valid response for session close\n");
+	}
+}
+
+static struct vb2_buffer *get_vb_from_device_addr(struct vb2_queue *q,
+		u32 dev_addr)
+{
+	struct vb2_buffer *vb = NULL;
+	int found = 0;
+	if (!q) {
+		pr_err("Invalid parameter\n");
+		return NULL;
+	}
+	list_for_each_entry(vb, &q->queued_list, queued_entry) {
+		if (vb->v4l2_planes[0].m.userptr == dev_addr) {
+			found = 1;
+			break;
+		}
+	}
+	if (!found) {
+		pr_err("Failed to find the buffer in queued list: %d, %d\n",
+			dev_addr, q->type);
+		vb = NULL;
+	}
+	return vb;
+}
+
+static void handle_ebd(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_data_done *response = data;
+	struct vb2_buffer *vb;
+	if (!response) {
+		pr_err("Invalid response from vidc_hal\n");
+		return;
+	}
+	vb = response->clnt_data;
+	if (vb)
+		vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+}
+
+static void handle_fbd(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_data_done *response = data;
+	struct msm_vidc_inst *inst;
+	struct vb2_buffer *vb;
+	struct vidc_hal_fbd *fill_buf_done;
+	if (!response) {
+		pr_err("Invalid response from vidc_hal\n");
+		return;
+	}
+	inst = (struct msm_vidc_inst *)response->session_id;
+	fill_buf_done = (struct vidc_hal_fbd *)&response->output_done;
+	vb = get_vb_from_device_addr(&inst->vb2_bufq[CAPTURE_PORT],
+		(u32)fill_buf_done->packet_buffer1);
+	if (vb) {
+		vb->v4l2_planes[0].bytesused = fill_buf_done->filled_len1;
+		pr_err("Filled length = %d\n", vb->v4l2_planes[0].bytesused);
+		if (fill_buf_done->flags1 & HAL_BUFFERFLAG_EOS)
+			vb->v4l2_buf.flags |= V4L2_BUF_FLAG_EOS;
+		vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+	}
+}
+
+void handle_cmd_response(enum command_response cmd, void *data)
+{
+	pr_debug("Command response = %d\n", cmd);
+	switch (cmd) {
+	case SYS_INIT_DONE:
+		handle_sys_init_done(cmd, data);
+		break;
+	case SESSION_INIT_DONE:
+		handle_session_init_done(cmd, data);
+		break;
+	case SESSION_PROPERTY_INFO:
+		handle_session_prop_info(cmd, data);
+		break;
+	case SESSION_LOAD_RESOURCE_DONE:
+		handle_load_resource_done(cmd, data);
+		break;
+	case SESSION_START_DONE:
+		handle_start_done(cmd, data);
+		break;
+	case SESSION_ETB_DONE:
+		handle_ebd(cmd, data);
+		break;
+	case SESSION_FTB_DONE:
+		handle_fbd(cmd, data);
+		break;
+	case SESSION_STOP_DONE:
+		handle_stop_done(cmd, data);
+		break;
+	case SESSION_RELEASE_RESOURCE_DONE:
+		handle_release_res_done(cmd, data);
+		break;
+	case SESSION_END_DONE:
+		handle_session_close(cmd, data);
+		break;
+	default:
+		pr_err("response unhandled\n");
+		break;
+	}
+}
+
+static int msm_comm_init_core_done(struct msm_vidc_inst *inst)
+{
+	struct msm_vidc_core *core = inst->core;
+	unsigned long flags;
+	int rc = 0;
+	mutex_lock(&core->sync_lock);
+	if (core->state >= VIDC_CORE_INIT_DONE) {
+		pr_err("Video core: %d is already in state: %d\n",
+				core->id, core->state);
+		goto core_already_inited;
+	}
+	pr_debug("Waiting for SYS_INIT_DONE\n");
+	rc = wait_for_completion_timeout(
+		&core->completions[SYS_MSG_INDEX(SYS_INIT_DONE)],
+		msecs_to_jiffies(HW_RESPONSE_TIMEOUT));
+	if (!rc) {
+		pr_err("Wait interrupted or timeout: %d\n", rc);
+		rc = -EIO;
+		goto exit;
+	} else {
+		spin_lock_irqsave(&core->lock, flags);
+		core->state = VIDC_CORE_INIT_DONE;
+		spin_unlock_irqrestore(&core->lock, flags);
+	}
+	pr_debug("SYS_INIT_DONE!!!\n");
+core_already_inited:
+	change_inst_state(inst, MSM_VIDC_CORE_INIT_DONE);
+	rc = 0;
+exit:
+	mutex_unlock(&core->sync_lock);
+	return rc;
+}
+
+static int msm_comm_init_core(struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	struct msm_vidc_core *core = inst->core;
+	unsigned long flags;
+	mutex_lock(&core->sync_lock);
+	if (core->state >= VIDC_CORE_INIT) {
+		pr_err("Video core: %d is already in state: %d\n",
+				core->id, core->state);
+		goto core_already_inited;
+	}
+	init_completion(&core->completions[SYS_MSG_INDEX(SYS_INIT_DONE)]);
+	rc = vidc_hal_core_init(core->device);
+	if (rc) {
+		pr_err("Failed to init core, id = %d\n", core->id);
+		goto exit;
+	}
+	spin_lock_irqsave(&core->lock, flags);
+	core->state = VIDC_CORE_INIT;
+	spin_unlock_irqrestore(&core->lock, flags);
+core_already_inited:
+	change_inst_state(inst, MSM_VIDC_CORE_INIT);
+exit:
+	mutex_unlock(&core->sync_lock);
+	return rc;
+}
+
+static int msm_vidc_deinit_core(struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	struct msm_vidc_core *core = inst->core;
+	unsigned long flags;
+	mutex_lock(&core->sync_lock);
+	if (core->state == VIDC_CORE_UNINIT) {
+		pr_err("Video core: %d is already in state: %d\n",
+				core->id, core->state);
+		goto core_already_uninited;
+	}
+	if (list_empty(&core->instances)) {
+		pr_debug("Calling vidc_hal_core_release\n");
+		rc = vidc_hal_core_release(core->device);
+		if (rc) {
+			pr_err("Failed to release core, id = %d\n", core->id);
+			goto exit;
+		}
+		spin_lock_irqsave(&core->lock, flags);
+		core->state = VIDC_CORE_UNINIT;
+		spin_unlock_irqrestore(&core->lock, flags);
+	}
+core_already_uninited:
+	change_inst_state(inst, MSM_VIDC_CORE_UNINIT);
+exit:
+	mutex_unlock(&core->sync_lock);
+	return rc;
+}
+
+static enum hal_domain get_hal_domain(int session_type)
+{
+	enum hal_domain domain;
+	switch (session_type) {
+	case MSM_VIDC_ENCODER:
+		domain = HAL_VIDEO_DOMAIN_ENCODER;
+		break;
+	case MSM_VIDC_DECODER:
+		domain = HAL_VIDEO_DOMAIN_DECODER;
+		break;
+	default:
+		pr_err("Wrong domain\n");
+		domain = HAL_UNUSED_DOMAIN;
+		break;
+	}
+	return domain;
+}
+
+static enum hal_video_codec get_hal_codec_type(int fourcc)
+{
+	enum hal_video_codec codec;
+	pr_debug("codec in %s is 0x%x", __func__, fourcc);
+	switch (fourcc) {
+	case V4L2_PIX_FMT_H264:
+	case V4L2_PIX_FMT_H264_NO_SC:
+		codec = HAL_VIDEO_CODEC_H264;
+		break;
+	case V4L2_PIX_FMT_H263:
+		codec = HAL_VIDEO_CODEC_H263;
+		break;
+	case V4L2_PIX_FMT_MPEG1:
+		codec = HAL_VIDEO_CODEC_MPEG1;
+		break;
+	case V4L2_PIX_FMT_MPEG2:
+		codec = HAL_VIDEO_CODEC_MPEG2;
+		break;
+	case V4L2_PIX_FMT_MPEG4:
+		codec = HAL_VIDEO_CODEC_MPEG4;
+		break;
+	case V4L2_PIX_FMT_VC1_ANNEX_G:
+	case V4L2_PIX_FMT_VC1_ANNEX_L:
+		codec = HAL_VIDEO_CODEC_VC1;
+		break;
+		/*HAL_VIDEO_CODEC_MVC
+		  HAL_VIDEO_CODEC_DIVX_311
+		  HAL_VIDEO_CODEC_DIVX
+		  HAL_VIDEO_CODEC_SPARK
+		  HAL_VIDEO_CODEC_VP6
+		  HAL_VIDEO_CODEC_VP7
+		  HAL_VIDEO_CODEC_VP8*/
+	default:
+		pr_err("Wrong codec: %d\n", fourcc);
+		codec = HAL_UNUSED_CODEC;
+	}
+	return codec;
+}
+
+static int msm_comm_session_init(int flipped_state,
+	struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	int fourcc = 0;
+	if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_OPEN)) {
+		pr_err("inst: %p is already in state: %d\n", inst, inst->state);
+		goto exit;
+	}
+	if (inst->session_type == MSM_VIDC_DECODER) {
+		fourcc = inst->fmts[OUTPUT_PORT]->fourcc;
+	} else if (inst->session_type == MSM_VIDC_ENCODER) {
+		fourcc = inst->fmts[CAPTURE_PORT]->fourcc;
+	} else {
+		pr_err("Invalid session\n");
+		return -EINVAL;
+	}
+	init_completion(
+		&inst->completions[SESSION_MSG_INDEX(SESSION_INIT_DONE)]);
+	inst->session = vidc_hal_session_init(inst->core->device, (u32) inst,
+					get_hal_domain(inst->session_type),
+					get_hal_codec_type(fourcc));
+	if (!inst->session) {
+		pr_err("Failed to call session init for: %d, %d, %d, %d\n",
+				(int)inst->core->device, (int)inst,
+				inst->session_type, fourcc);
+		goto exit;
+	}
+	change_inst_state(inst, MSM_VIDC_OPEN);
+exit:
+	return rc;
+}
+
+static int msm_vidc_load_resources(int flipped_state,
+	struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_LOAD_RESOURCES)) {
+		pr_err("inst: %p is already in state: %d\n", inst, inst->state);
+		goto exit;
+	}
+	rc = vidc_hal_session_load_res((void *) inst->session);
+	if (rc) {
+		pr_err("Failed to send load resources\n");
+		goto exit;
+	}
+	change_inst_state(inst, MSM_VIDC_LOAD_RESOURCES);
+exit:
+	return rc;
+}
+
+static int msm_vidc_start(int flipped_state, struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_START)) {
+		pr_err("inst: %p is already in state: %d\n", inst, inst->state);
+		goto exit;
+	}
+	init_completion(
+		&inst->completions[SESSION_MSG_INDEX(SESSION_START_DONE)]);
+	rc = vidc_hal_session_start((void *) inst->session);
+	if (rc) {
+		pr_err("Failed to send load resources\n");
+		goto exit;
+	}
+	change_inst_state(inst, MSM_VIDC_START);
+exit:
+	return rc;
+}
+
+static int msm_vidc_stop(int flipped_state, struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_STOP)) {
+		pr_err("inst: %p is already in state: %d\n", inst, inst->state);
+		goto exit;
+	}
+	pr_debug("Send Stop to hal\n");
+	init_completion(
+		&inst->completions[SESSION_MSG_INDEX(SESSION_STOP_DONE)]);
+	rc = vidc_hal_session_stop((void *) inst->session);
+	if (rc) {
+		pr_err("Failed to send stop\n");
+		goto exit;
+	}
+	change_inst_state(inst, MSM_VIDC_STOP);
+exit:
+	return rc;
+}
+
+static int msm_vidc_release_res(int flipped_state, struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_RELEASE_RESOURCES)) {
+		pr_err("inst: %p is already in state: %d\n", inst, inst->state);
+		goto exit;
+	}
+	pr_debug("Send release res to hal\n");
+	init_completion(
+	&inst->completions[SESSION_MSG_INDEX(SESSION_RELEASE_RESOURCE_DONE)]);
+	rc = vidc_hal_session_release_res((void *) inst->session);
+	if (rc) {
+		pr_err("Failed to send load resources\n");
+		goto exit;
+	}
+	change_inst_state(inst, MSM_VIDC_RELEASE_RESOURCES);
+exit:
+	return rc;
+}
+
+static int msm_comm_session_close(int flipped_state, struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_CLOSE)) {
+		pr_err("inst: %p is already in state: %d\n", inst, inst->state);
+		goto exit;
+	}
+	pr_debug("Send session close to hal\n");
+	init_completion(
+		&inst->completions[SESSION_MSG_INDEX(SESSION_END_DONE)]);
+	rc = vidc_hal_session_end((void *) inst->session);
+	if (rc) {
+		pr_err("Failed to send load resources\n");
+		goto exit;
+	}
+	change_inst_state(inst, MSM_VIDC_OPEN);
+exit:
+	return rc;
+}
+
+int msm_comm_try_state(struct msm_vidc_inst *inst, int state)
+{
+	int rc = 0;
+	int flipped_state;
+	if (!inst) {
+		pr_err("Invalid instance pointer = %p\n", inst);
+		return -EINVAL;
+	}
+	pr_debug("Trying to move inst: %p from: 0x%x to 0x%x\n",
+				inst, inst->state, state);
+	mutex_lock(&inst->sync_lock);
+	flipped_state = inst->state;
+	if (flipped_state < MSM_VIDC_STOP
+		&& state > MSM_VIDC_STOP) {
+		flipped_state = MSM_VIDC_STOP + (MSM_VIDC_STOP - flipped_state);
+		flipped_state &= 0xFFFE;
+		flipped_state = flipped_state - 1;
+	} else if (flipped_state > MSM_VIDC_STOP
+		&& state < MSM_VIDC_STOP) {
+		flipped_state = MSM_VIDC_STOP -
+				(flipped_state - MSM_VIDC_STOP + 1);
+		flipped_state &= 0xFFFE;
+		flipped_state = flipped_state - 1;
+	}
+	pr_debug("flipped_state = 0x%x\n", flipped_state);
+	switch (flipped_state) {
+	case MSM_VIDC_CORE_UNINIT_DONE:
+	case MSM_VIDC_CORE_INIT:
+		rc = msm_comm_init_core(inst);
+		if (rc || state <= inst->state)
+			break;
+	case MSM_VIDC_CORE_INIT_DONE:
+		rc = msm_comm_init_core_done(inst);
+		if (rc || state <= inst->state)
+			break;
+	case MSM_VIDC_OPEN:
+		rc = msm_comm_session_init(flipped_state, inst);
+		if (rc || state <= inst->state)
+			break;
+	case MSM_VIDC_OPEN_DONE:
+		rc = wait_for_state(inst, flipped_state, MSM_VIDC_OPEN_DONE,
+			SESSION_INIT_DONE);
+		if (rc || state <= inst->state)
+			break;
+	case MSM_VIDC_LOAD_RESOURCES:
+		rc = msm_vidc_load_resources(flipped_state, inst);
+		if (rc || state <= inst->state)
+			break;
+	case MSM_VIDC_LOAD_RESOURCES_DONE:
+	case MSM_VIDC_START:
+		rc = msm_vidc_start(flipped_state, inst);
+		if (rc || state <= inst->state)
+			break;
+	case MSM_VIDC_START_DONE:
+		rc = wait_for_state(inst, flipped_state, MSM_VIDC_START_DONE,
+				SESSION_START_DONE);
+		if (rc || state <= inst->state)
+			break;
+	case MSM_VIDC_STOP:
+		rc = msm_vidc_stop(flipped_state, inst);
+		if (rc || state <= inst->state)
+			break;
+	case MSM_VIDC_STOP_DONE:
+		rc = wait_for_state(inst, flipped_state, MSM_VIDC_STOP_DONE,
+				SESSION_STOP_DONE);
+		if (rc || state <= inst->state)
+			break;
+		pr_debug("Moving to Stop Done state\n");
+	case MSM_VIDC_RELEASE_RESOURCES:
+		rc = msm_vidc_release_res(flipped_state, inst);
+		if (rc || state <= inst->state)
+			break;
+	case MSM_VIDC_RELEASE_RESOURCES_DONE:
+		rc = wait_for_state(inst, flipped_state,
+			MSM_VIDC_RELEASE_RESOURCES_DONE,
+			SESSION_RELEASE_RESOURCE_DONE);
+		if (rc || state <= inst->state)
+			break;
+		pr_debug("Moving to release resources done state\n");
+	case MSM_VIDC_CLOSE:
+		rc = msm_comm_session_close(flipped_state, inst);
+		if (rc || state <= inst->state)
+			break;
+	case MSM_VIDC_CLOSE_DONE:
+		rc = wait_for_state(inst, flipped_state, MSM_VIDC_CLOSE_DONE,
+			SESSION_END_DONE);
+		if (rc || state <= inst->state)
+			break;
+	case MSM_VIDC_CORE_UNINIT:
+		pr_debug("***************Sending core uninit\n");
+		rc = msm_vidc_deinit_core(inst);
+		if (rc || state == inst->state)
+			break;
+	default:
+		pr_err("State not recognized\n");
+		rc = -EINVAL;
+		break;
+	}
+	mutex_unlock(&inst->sync_lock);
+	if (rc)
+		pr_err("Failed to move from state: %d to %d\n",
+			inst->state, state);
+	return rc;
+}
+
+int msm_comm_qbuf(struct vb2_buffer *vb)
+{
+	int rc = 0;
+	struct vb2_queue *q;
+	struct msm_vidc_inst *inst;
+	unsigned long flags;
+	struct vb2_buf_entry *entry;
+	struct vidc_frame_data frame_data;
+	q = vb->vb2_queue;
+	inst = q->drv_priv;
+
+	if (!inst || !vb) {
+		pr_err("Invalid input: %p, %p\n", inst, vb);
+		return -EINVAL;
+	}
+	if (inst->state != MSM_VIDC_START_DONE) {
+			entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+			if (!entry) {
+				pr_err("Out of memory\n");
+				goto err_no_mem;
+			}
+			entry->vb = vb;
+			pr_debug("Queueing buffer in pendingq\n");
+			spin_lock_irqsave(&inst->lock, flags);
+			list_add_tail(&entry->list, &inst->pendingq);
+			spin_unlock_irqrestore(&inst->lock, flags);
+	} else {
+		memset(&frame_data, 0 , sizeof(struct vidc_frame_data));
+		frame_data.alloc_len = vb->v4l2_planes[0].length;
+		frame_data.filled_len = vb->v4l2_planes[0].bytesused;
+		frame_data.device_addr = vb->v4l2_planes[0].m.userptr;
+		frame_data.clnt_data = (u32)vb;
+		if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+			frame_data.buffer_type = HAL_BUFFER_INPUT;
+			if (vb->v4l2_buf.flags & V4L2_BUF_FLAG_EOS) {
+				frame_data.flags = HAL_BUFFERFLAG_EOS;
+				pr_debug("Received EOS on output capability\n");
+			}
+			pr_debug("Sending etb to hal: Alloc: %d :filled: %d\n",
+				frame_data.alloc_len, frame_data.filled_len);
+			rc = vidc_hal_session_etb((void *) inst->session,
+					&frame_data);
+			pr_debug("Sent etb to HAL\n");
+		} else if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+			struct extradata_buf *addr;
+			struct list_head *ptr, *next;
+			frame_data.filled_len = 0;
+			frame_data.buffer_type = HAL_BUFFER_OUTPUT;
+			frame_data.extradata_addr = 0;
+			list_for_each_safe(ptr, next, &inst->extradatabufs) {
+				addr = list_entry(ptr,
+						struct extradata_buf, list);
+				if (addr->device_addr ==
+						frame_data.device_addr) {
+					frame_data.extradata_addr =
+						addr->handle->device_addr;
+					break;
+				}
+			}
+			pr_debug("Sending ftb to hal...: Alloc: %d :filled: %d"
+				" extradata_addr: %d\n", frame_data.alloc_len,
+				   frame_data.filled_len,
+				   frame_data.extradata_addr);
+			rc = vidc_hal_session_ftb((void *) inst->session,
+					&frame_data);
+		} else {
+			pr_err("This capability is not supported: %d\n",
+				q->type);
+			rc = -EINVAL;
+		}
+	}
+	if (rc)
+		pr_err("Failed to queue buffer\n");
+err_no_mem:
+	return rc;
+}
+
+int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	mutex_lock(&inst->sync_lock);
+	init_completion(
+		&inst->completions[SESSION_MSG_INDEX(SESSION_PROPERTY_INFO)]);
+	rc = vidc_hal_session_get_buf_req((void *) inst->session);
+	if (rc) {
+		pr_err("Failed to get property\n");
+		goto exit;
+	}
+	rc = wait_for_completion_timeout(
+		&inst->completions[SESSION_MSG_INDEX(SESSION_PROPERTY_INFO)],
+		msecs_to_jiffies(HW_RESPONSE_TIMEOUT));
+	if (!rc) {
+		pr_err("Wait interrupted or timeout: %d\n", rc);
+		rc = -EIO;
+		goto exit;
+	}
+	rc = 0;
+exit:
+	mutex_unlock(&inst->sync_lock);
+	return rc;
+}
+
+int msm_comm_allocate_extradata_buffers(struct msm_vidc_inst *inst,
+	struct extradata_buf *binfo)
+{
+	int rc = 0;
+	unsigned long flags;
+	struct msm_smem *handle;
+	pr_debug("Extradata: num = %d, size = %d, align = %d\n",
+			inst->buff_req.buffer[4].buffer_count_actual,
+			inst->buff_req.buffer[4].buffer_size,
+			inst->buff_req.buffer[4].buffer_alignment);
+	if (!inst->buff_req.buffer[4].buffer_size) {
+		pr_err("invalid size: %d",
+			   inst->buff_req.buffer[4].buffer_size);
+		rc = -ENOMEM;
+		goto err_no_mem;
+	}
+	handle = msm_smem_alloc(inst->mem_client,
+			inst->buff_req.buffer[4].buffer_size,
+			inst->buff_req.buffer[4].buffer_alignment, 0);
+	if (!handle) {
+		pr_err("Failed to allocate Extradata memory\n");
+		rc = -ENOMEM;
+		goto err_no_mem;
+	}
+	binfo->handle = handle;
+	spin_lock_irqsave(&inst->lock, flags);
+	list_add_tail(&binfo->list, &inst->extradatabufs);
+	spin_unlock_irqrestore(&inst->lock, flags);
+err_no_mem:
+	return rc;
+}
+
+int msm_comm_set_scratch_buffers(struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	struct msm_smem *handle;
+	struct internal_buf *binfo;
+	struct vidc_buffer_addr_info buffer_info;
+	unsigned long flags;
+	int i;
+	pr_debug("scratch: num = %d, size = %d\n",
+			inst->buff_req.buffer[6].buffer_count_actual,
+			inst->buff_req.buffer[6].buffer_size);
+	for (i = 0; i < inst->buff_req.buffer[6].buffer_count_actual;
+				i++) {
+		handle = msm_smem_alloc(inst->mem_client,
+				inst->buff_req.buffer[6].buffer_size, 1, 0);
+		if (!handle) {
+			pr_err("Failed to allocate scratch memory\n");
+			rc = -ENOMEM;
+			goto err_no_mem;
+		}
+		binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
+		if (!binfo) {
+			pr_err("Out of memory\n");
+			rc = -ENOMEM;
+			goto err_no_mem;
+		}
+		binfo->handle = handle;
+		spin_lock_irqsave(&inst->lock, flags);
+		list_add_tail(&binfo->list, &inst->internalbufs);
+		spin_unlock_irqrestore(&inst->lock, flags);
+		buffer_info.buffer_size =
+				inst->buff_req.buffer[6].buffer_size;
+		buffer_info.buffer_type = HAL_BUFFER_INTERNAL_SCRATCH;
+		buffer_info.num_buffers = 1;
+		buffer_info.align_device_addr = handle->device_addr;
+		rc = vidc_hal_session_set_buffers((void *) inst->session,
+				&buffer_info);
+		if (rc) {
+			pr_err("vidc_hal_session_set_buffers failed");
+			break;
+		}
+	}
+err_no_mem:
+	return rc;
+}
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.h b/drivers/media/video/msm_vidc/msm_vidc_common.h
new file mode 100644
index 0000000..45bfa7b
--- /dev/null
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.h
@@ -0,0 +1,38 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _MSM_VIDC_COMMON_H_
+#define _MSM_VIDC_COMMON_H_
+#include "msm_vidc_internal.h"
+struct vb2_buf_entry {
+	struct list_head list;
+	struct vb2_buffer *vb;
+};
+struct msm_vidc_core *get_vidc_core(int core_id);
+const struct msm_vidc_format *msm_comm_get_pixel_fmt_index(
+	const struct msm_vidc_format fmt[], int size, int index, int fmt_type);
+const struct msm_vidc_format *msm_comm_get_pixel_fmt_fourcc(
+	const struct msm_vidc_format fmt[], int size, int fourcc, int fmt_type);
+struct vb2_queue *msm_comm_get_vb2q(
+		struct msm_vidc_inst *inst, enum v4l2_buf_type type);
+int msm_comm_try_state(struct msm_vidc_inst *inst, int state);
+int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst);
+int msm_comm_allocate_extradata_buffers(struct msm_vidc_inst *inst,
+	struct extradata_buf *binfo);
+int msm_comm_set_scratch_buffers(struct msm_vidc_inst *inst);
+int msm_comm_qbuf(struct vb2_buffer *vb);
+#define IS_PRIV_CTRL(idx) (\
+		(V4L2_CTRL_ID2CLASS(idx) == V4L2_CTRL_CLASS_MPEG) && \
+		V4L2_CTRL_DRIVER_PRIV(idx))
+
+#endif
diff --git a/drivers/media/video/msm_vidc/msm_vidc_internal.h b/drivers/media/video/msm_vidc/msm_vidc_internal.h
new file mode 100644
index 0000000..dce2dee
--- /dev/null
+++ b/drivers/media/video/msm_vidc/msm_vidc_internal.h
@@ -0,0 +1,166 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _MSM_VIDC_INTERNAL_H_
+#define _MSM_VIDC_INTERNAL_H_
+
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/completion.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include <media/videobuf2-core.h>
+#include <media/msm_vidc.h>
+
+#include "vidc_hal_api.h"
+
+#define MSM_VIDC_DRV_NAME "msm_vidc_driver"
+#define MSM_VIDC_VERSION KERNEL_VERSION(0, 0, 1);
+#define MAX_DEBUGFS_NAME 50
+#define DEFAULT_TIMEOUT 3
+
+#define SYS_MSG_START VIDC_EVENT_CHANGE
+#define SYS_MSG_END SYS_DEBUG
+#define SESSION_MSG_START SESSION_LOAD_RESOURCE_DONE
+#define SESSION_MSG_END SESSION_PROPERTY_INFO
+#define SYS_MSG_INDEX(__msg) (__msg - SYS_MSG_START)
+#define SESSION_MSG_INDEX(__msg) (__msg - SESSION_MSG_START)
+
+enum vidc_ports {
+	OUTPUT_PORT,
+	CAPTURE_PORT,
+	MAX_PORT_NUM
+};
+
+enum vidc_core_state {
+	VIDC_CORE_UNINIT = 0,
+	VIDC_CORE_INIT,
+	VIDC_CORE_INIT_DONE,
+};
+
+/*Donot change the enum values unless
+ * you know what you are doing*/
+enum instance_state {
+	MSM_VIDC_CORE_UNINIT_DONE = 0x0001,
+	MSM_VIDC_CORE_INIT,
+	MSM_VIDC_CORE_INIT_DONE,
+	MSM_VIDC_OPEN,
+	MSM_VIDC_OPEN_DONE,
+	MSM_VIDC_LOAD_RESOURCES,
+	MSM_VIDC_LOAD_RESOURCES_DONE,
+	MSM_VIDC_START,
+	MSM_VIDC_START_DONE,
+	MSM_VIDC_STOP,
+	MSM_VIDC_STOP_DONE,
+	MSM_VIDC_RELEASE_RESOURCES,
+	MSM_VIDC_RELEASE_RESOURCES_DONE,
+	MSM_VIDC_CLOSE,
+	MSM_VIDC_CLOSE_DONE,
+	MSM_VIDC_CORE_UNINIT,
+};
+
+struct buf_info {
+	struct list_head list;
+	struct vb2_buffer *buf;
+};
+
+struct internal_buf {
+	struct list_head list;
+	struct msm_smem *handle;
+};
+
+struct extradata_buf {
+	struct list_head list;
+	struct msm_smem *handle;
+	u32 device_addr;
+};
+
+struct msm_vidc_format {
+	char name[64];
+	u8 description[32];
+	u32 fourcc;
+	int num_planes;
+	int type;
+	u32 (*get_frame_size)(int plane, u32 height, u32 width);
+};
+
+struct msm_vidc_drv {
+	spinlock_t lock;
+	struct list_head cores;
+	int num_cores;
+	struct dentry *debugfs_root;
+};
+
+struct msm_video_device {
+	int type;
+	struct video_device vdev;
+};
+
+struct msm_vidc_core {
+	struct list_head list;
+	struct mutex sync_lock;
+	int id;
+	void *device;
+	struct msm_video_device vdev[MSM_VIDC_MAX_DEVICES];
+	struct v4l2_device v4l2_dev;
+	spinlock_t lock;
+	struct list_head instances;
+	struct dentry *debugfs_root;
+	u32 base_addr;
+	u32 register_base;
+	u32 register_size;
+	u32 irq;
+	enum vidc_core_state state;
+	struct completion completions[SYS_MSG_END - SYS_MSG_START + 1];
+};
+
+struct msm_vidc_inst {
+	struct list_head list;
+	struct mutex sync_lock;
+	struct msm_vidc_core *core;
+	int session_type;
+	void *session;
+	u32 width;
+	u32 height;
+	int state;
+	const struct msm_vidc_format *fmts[MAX_PORT_NUM];
+	struct vb2_queue vb2_bufq[MAX_PORT_NUM];
+	spinlock_t lock;
+	struct list_head pendingq;
+	struct list_head internalbufs;
+	struct list_head extradatabufs;
+	struct buffer_requirements buff_req;
+	void *mem_client;
+	struct v4l2_ctrl_handler ctrl_handler;
+	struct completion completions[SESSION_MSG_END - SESSION_MSG_START + 1];
+};
+
+extern struct msm_vidc_drv *vidc_driver;
+
+struct msm_vidc_ctrl {
+	u32 id;
+	char name[64];
+	enum v4l2_ctrl_type type;
+	s32 minimum;
+	s32 maximum;
+	s32 default_value;
+	u32 step;
+	u32 menu_skip_mask;
+	const char * const *qmenu;
+};
+
+void handle_cmd_response(enum command_response cmd, void *data);
+#endif
diff --git a/drivers/mmc/core/quirks.c b/drivers/mmc/core/quirks.c
index 92990b9..f9999c5 100644
--- a/drivers/mmc/core/quirks.c
+++ b/drivers/mmc/core/quirks.c
@@ -29,6 +29,18 @@
 #define SDIO_DEVICE_ID_MSM_WCN1314	0x2881
 #endif
 
+#ifndef SDIO_VENDOR_ID_MSM_QCA
+#define SDIO_VENDOR_ID_MSM_QCA		0x271
+#endif
+
+#ifndef SDIO_DEVICE_ID_MSM_QCA_AR6003_1
+#define SDIO_DEVICE_ID_MSM_QCA_AR6003_1	0x300
+#endif
+
+#ifndef SDIO_DEVICE_ID_MSM_QCA_AR6003_2
+#define SDIO_DEVICE_ID_MSM_QCA_AR6003_2	0x301
+#endif
+
 /*
  * This hook just adds a quirk for all sdio devices
  */
@@ -51,6 +63,12 @@
 	SDIO_FIXUP(SDIO_VENDOR_ID_MSM, SDIO_DEVICE_ID_MSM_WCN1314,
 		   remove_quirk, MMC_QUIRK_BROKEN_CLK_GATING),
 
+	SDIO_FIXUP(SDIO_VENDOR_ID_MSM_QCA, SDIO_DEVICE_ID_MSM_QCA_AR6003_1,
+		   remove_quirk, MMC_QUIRK_BROKEN_CLK_GATING),
+
+	SDIO_FIXUP(SDIO_VENDOR_ID_MSM_QCA, SDIO_DEVICE_ID_MSM_QCA_AR6003_2,
+		   remove_quirk, MMC_QUIRK_BROKEN_CLK_GATING),
+
 	SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271,
 		   add_quirk, MMC_QUIRK_NONSTD_FUNC_IF),
 
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 39e6ce3..13fe3e6 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -707,7 +707,7 @@
 	}
 
 	if (!err && host->sdio_irqs)
-		mmc_signal_sdio_irq(host);
+		wake_up_process(host->sdio_irq_thread);
 	mmc_release_host(host);
 
 	/*
diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c
index d489233..c442907 100644
--- a/drivers/mmc/core/sdio_irq.c
+++ b/drivers/mmc/core/sdio_irq.c
@@ -27,18 +27,20 @@
 
 #include "sdio_ops.h"
 
-static int process_sdio_pending_irqs(struct mmc_card *card)
+static int process_sdio_pending_irqs(struct mmc_host *host)
 {
+	struct mmc_card *card = host->card;
 	int i, ret, count;
 	unsigned char pending;
 	struct sdio_func *func;
 
 	/*
 	 * Optimization, if there is only 1 function interrupt registered
-	 * call irq handler directly
+	 * and we know an IRQ was signaled then call irq handler directly.
+	 * Otherwise do the full probe.
 	 */
 	func = card->sdio_single_irq;
-	if (func) {
+	if (func && host->sdio_irq_pending) {
 		func->irq_handler(func);
 		return 1;
 	}
@@ -115,7 +117,8 @@
 		ret = __mmc_claim_host(host, &host->sdio_irq_thread_abort);
 		if (ret)
 			break;
-		ret = process_sdio_pending_irqs(host->card);
+		ret = process_sdio_pending_irqs(host);
+		host->sdio_irq_pending = false;
 		mmc_release_host(host);
 
 		/*
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index de5e741..e7797b1 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -1863,6 +1863,8 @@
 	chip->ext_charging = false;
 	chip->ext_charge_done = false;
 	bms_notify_check(chip);
+	/* Update battery charging LEDs and user space battery info */
+	power_supply_changed(&chip->batt_psy);
 }
 
 static void handle_start_ext_chg(struct pm8921_chg_chip *chip)
@@ -1917,6 +1919,8 @@
 	/* Start BMS */
 	schedule_delayed_work(&chip->eoc_work, delay);
 	wake_lock(&chip->eoc_wake_lock);
+	/* Update battery charging LEDs and user space battery info */
+	power_supply_changed(&chip->batt_psy);
 }
 
 static void turn_off_usb_ovp_fet(struct pm8921_chg_chip *chip)
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index d754a88..b612a0b 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -3273,15 +3273,6 @@
 	udc->gadget.dev.parent   = dev;
 	udc->gadget.dev.release  = udc_release;
 
-	retval = hw_device_init(regs);
-	if (retval < 0)
-		goto free_udc;
-
-	for (i = 0; i < hw_ep_max; i++) {
-		struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i];
-		INIT_LIST_HEAD(&mEp->ep.ep_list);
-	}
-
 	udc->transceiver = otg_get_transceiver();
 
 	if (udc->udc_driver->flags & CI13XXX_REQUIRE_TRANSCEIVER) {
@@ -3291,6 +3282,15 @@
 		}
 	}
 
+	retval = hw_device_init(regs);
+	if (retval < 0)
+		goto put_transceiver;
+
+	for (i = 0; i < hw_ep_max; i++) {
+		struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i];
+		INIT_LIST_HEAD(&mEp->ep.ep_list);
+	}
+
 	if (!(udc->udc_driver->flags & CI13XXX_REGS_SHARED)) {
 		retval = hw_device_reset(udc);
 		if (retval)
diff --git a/drivers/usb/gadget/f_rmnet.c b/drivers/usb/gadget/f_rmnet.c
index fcbc75c..f7230fe 100644
--- a/drivers/usb/gadget/f_rmnet.c
+++ b/drivers/usb/gadget/f_rmnet.c
@@ -525,7 +525,7 @@
 	}
 	dev->notify->driver_data = dev;
 
-	if (!dev->port.in->driver_data) {
+	if (!dev->port.in->desc || !dev->port.out->desc) {
 		if (config_ep_by_speed(cdev->gadget, f, dev->port.in) ||
 			config_ep_by_speed(cdev->gadget, f, dev->port.out)) {
 				dev->port.in->desc = NULL;
diff --git a/drivers/usb/gadget/msm72k_udc.c b/drivers/usb/gadget/msm72k_udc.c
index 35ea497..863ddcd 100644
--- a/drivers/usb/gadget/msm72k_udc.c
+++ b/drivers/usb/gadget/msm72k_udc.c
@@ -2301,13 +2301,14 @@
 static int msm72k_pullup(struct usb_gadget *_gadget, int is_active)
 {
 	struct usb_info *ui = container_of(_gadget, struct usb_info, gadget);
+	struct msm_otg *otg = to_msm_otg(ui->xceiv);
 	unsigned long flags;
 
-
 	atomic_set(&ui->softconnect, is_active);
 
 	spin_lock_irqsave(&ui->lock, flags);
-	if (ui->usb_state == USB_STATE_NOTATTACHED || ui->driver == NULL) {
+	if (ui->usb_state == USB_STATE_NOTATTACHED || ui->driver == NULL ||
+		atomic_read(&otg->chg_type) == USB_CHG_TYPE__WALLCHARGER) {
 		spin_unlock_irqrestore(&ui->lock, flags);
 		return 0;
 	}
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 4dd6aff..deb4064 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -697,6 +697,9 @@
 			/* Remote wakeup or resume */
 			set_bit(A_BUS_REQ, &motg->inputs);
 			otg->state = OTG_STATE_A_HOST;
+
+			/* ensure hardware is not in low power mode */
+			pm_runtime_resume(otg->dev);
 			break;
 		default:
 			break;
@@ -2511,7 +2514,10 @@
 		pr_debug("OTG IRQ: in LPM\n");
 		disable_irq_nosync(irq);
 		motg->async_int = 1;
-		pm_request_resume(otg->dev);
+		if (atomic_read(&motg->pm_suspended))
+			motg->sm_work_pending = true;
+		else
+			pm_request_resume(otg->dev);
 		return IRQ_HANDLED;
 	}
 
@@ -2676,7 +2682,10 @@
 		return;
 	}
 
-	queue_work(system_nrt_wq, &motg->sm_work);
+	if (atomic_read(&motg->pm_suspended))
+		motg->sm_work_pending = true;
+	else
+		queue_work(system_nrt_wq, &motg->sm_work);
 }
 
 static irqreturn_t msm_pmic_id_irq(int irq, void *data)
@@ -2695,8 +2704,12 @@
 		set_bit(A_BUS_REQ, &motg->inputs);
 	}
 
-	if (motg->otg.state != OTG_STATE_UNDEFINED)
-		queue_work(system_nrt_wq, &motg->sm_work);
+	if (motg->otg.state != OTG_STATE_UNDEFINED) {
+		if (atomic_read(&motg->pm_suspended))
+			motg->sm_work_pending = true;
+		else
+			queue_work(system_nrt_wq, &motg->sm_work);
+	}
 
 	return IRQ_HANDLED;
 }
@@ -3533,28 +3546,42 @@
 #ifdef CONFIG_PM_SLEEP
 static int msm_otg_pm_suspend(struct device *dev)
 {
+	int ret = 0;
 	struct msm_otg *motg = dev_get_drvdata(dev);
 
 	dev_dbg(dev, "OTG PM suspend\n");
-	return msm_otg_suspend(motg);
+
+	atomic_set(&motg->pm_suspended, 1);
+	ret = msm_otg_suspend(motg);
+	if (ret)
+		atomic_set(&motg->pm_suspended, 0);
+
+	return ret;
 }
 
 static int msm_otg_pm_resume(struct device *dev)
 {
+	int ret = 0;
 	struct msm_otg *motg = dev_get_drvdata(dev);
-	int ret;
 
 	dev_dbg(dev, "OTG PM resume\n");
-	ret = msm_otg_resume(motg);
-	if (ret)
-		return ret;
 
-	/* Update runtime PM status */
-	pm_runtime_disable(dev);
-	pm_runtime_set_active(dev);
-	pm_runtime_enable(dev);
+	atomic_set(&motg->pm_suspended, 0);
+	if (motg->sm_work_pending) {
+		motg->sm_work_pending = false;
 
-	return 0;
+		pm_runtime_get_noresume(dev);
+		ret = msm_otg_resume(motg);
+
+		/* Update runtime PM status */
+		pm_runtime_disable(dev);
+		pm_runtime_set_active(dev);
+		pm_runtime_enable(dev);
+
+		queue_work(system_nrt_wq, &motg->sm_work);
+	}
+
+	return ret;
 }
 #endif
 
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c
index fe71dc1..5fa9b09 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c
@@ -290,6 +290,8 @@
 			decoder->client_output_buf_req.actual_count
 			&& decoder->progressive_only)
 			need_reconfig = false;
+		if (input_vcd_frm->flags & VCD_FRAME_FLAG_EOS)
+			need_reconfig = false;
 		if ((input_vcd_frm->data_len <= seq_hdr_info.dec_frm_size ||
 			 (input_vcd_frm->flags & VCD_FRAME_FLAG_CODECCONFIG)) &&
 			(!need_reconfig ||
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index a2ee306..c9a17de 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -317,6 +317,7 @@
 
 	unsigned int		sdio_irqs;
 	struct task_struct	*sdio_irq_thread;
+	bool			sdio_irq_pending;
 	atomic_t		sdio_irq_thread_abort;
 
 	mmc_pm_flag_t		pm_flags;	/* requested pm features */
@@ -411,6 +412,7 @@
 static inline void mmc_signal_sdio_irq(struct mmc_host *host)
 {
 	host->ops->enable_sdio_irq(host, 0);
+	host->sdio_irq_pending = true;
 	wake_up_process(host->sdio_irq_thread);
 }
 
diff --git a/include/linux/msm_audio_mvs.h b/include/linux/msm_audio_mvs.h
index 8ec9796..1807cb0 100644
--- a/include/linux/msm_audio_mvs.h
+++ b/include/linux/msm_audio_mvs.h
@@ -133,4 +133,12 @@
 
 };
 
+#define Q5V2_MVS_MAX_VOC_PKT_SIZE 320
+
+struct q5v2_msm_audio_mvs_frame {
+	uint32_t frame_type;
+	uint32_t len;
+	uint8_t voc_pkt[Q5V2_MVS_MAX_VOC_PKT_SIZE];
+
+};
 #endif /* __MSM_AUDIO_MVS_H */
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index b53d9dd..6e96f85 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -293,6 +293,8 @@
 #define B_BUS_REQ	16
 	unsigned long inputs;
 	struct work_struct sm_work;
+	bool sm_work_pending;
+	atomic_t pm_suspended;
 	atomic_t in_lpm;
 	int async_int;
 	unsigned cur_power;
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 147b068..a3b45c9 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -656,6 +656,7 @@
 /* Cache handling flags */
 #define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0800
 #define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x1000
+#define V4L2_BUF_FLAG_EOS		0x2000
 
 /*
  *	O V E R L A Y   P R E V I E W
diff --git a/include/media/msm_vidc.h b/include/media/msm_vidc.h
new file mode 100644
index 0000000..b883ffa
--- /dev/null
+++ b/include/media/msm_vidc.h
@@ -0,0 +1,47 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _MSM_VIDC_H_
+#define _MSM_VIDC_H_
+
+#include <linux/videodev2.h>
+#include <linux/poll.h>
+
+enum core_id {
+	MSM_VIDC_CORE_0 = 0,
+	MSM_VIDC_CORES_MAX,
+};
+
+enum session_type {
+	MSM_VIDC_ENCODER = 0,
+	MSM_VIDC_DECODER,
+	MSM_VIDC_MAX_DEVICES,
+};
+
+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);
+int msm_vidc_s_fmt(void *instance, struct v4l2_format *f);
+int msm_vidc_g_fmt(void *instance, struct v4l2_format *f);
+int msm_vidc_s_ctrl(void *instance, struct v4l2_control *a);
+int msm_vidc_g_ctrl(void *instance, struct v4l2_control *a);
+int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b);
+int msm_vidc_prepare_buf(void *instance, struct v4l2_buffer *b);
+int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b);
+int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b);
+int msm_vidc_streamon(void *instance, enum v4l2_buf_type i);
+int msm_vidc_streamoff(void *instance, enum v4l2_buf_type i);
+int msm_vidc_poll(void *instance, struct file *filp,
+		struct poll_table_struct *pt);
+#endif
diff --git a/include/media/user-rc-input.h b/include/media/user-rc-input.h
new file mode 100644
index 0000000..e58e40f
--- /dev/null
+++ b/include/media/user-rc-input.h
@@ -0,0 +1,21 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __USER_RC_INPUT_H__
+#define __USER_RC_INPUT_H__
+
+#define USER_CONTROL_PRESSED    0x01
+#define USER_CONTROL_REPEATED   0x02
+#define USER_CONTROL_RELEASED   0x03
+
+#endif /* __USER_RC_INPUT_H__ */
+
diff --git a/include/sound/q6asm.h b/include/sound/q6asm.h
index 968d46e..54a9187 100644
--- a/include/sound/q6asm.h
+++ b/include/sound/q6asm.h
@@ -13,7 +13,6 @@
 #define __Q6_ASM_H__
 
 #include <mach/qdsp6v2/apr.h>
-#include <mach/msm_subsystem_map.h>
 #include <sound/apr_audio.h>
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 #include <linux/ion.h>
@@ -110,7 +109,7 @@
 	struct ion_handle *handle;
 	struct ion_client *client;
 #else
-	struct msm_mapped_buffer *mem_buffer;
+	void *mem_buffer;
 #endif
 };
 
diff --git a/sound/soc/msm/msm8930.c b/sound/soc/msm/msm8930.c
index a2c6f5f..3f7e399 100644
--- a/sound/soc/msm/msm8930.c
+++ b/sound/soc/msm/msm8930.c
@@ -13,7 +13,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/gpio.h>
-#include <linux/mfd/pm8xxx/misc.h>
+#include <linux/mfd/pm8xxx/spk.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
@@ -36,6 +36,8 @@
 #define BTSCO_RATE_8KHZ 8000
 #define BTSCO_RATE_16KHZ 16000
 
+#define SPK_AMP_POS	0x1
+#define SPK_AMP_NEG	0x2
 #define SITAR_EXT_CLK_RATE 12288000
 
 #define SITAR_MBHC_DEF_BUTTONS 3
@@ -45,6 +47,7 @@
 static int msm8930_slim_0_rx_ch = 1;
 static int msm8930_slim_0_tx_ch = 1;
 
+static int msm8930_ext_spk_pamp;
 static int msm8930_btsco_rate = BTSCO_RATE_8KHZ;
 static int msm8930_btsco_ch = 1;
 
@@ -111,11 +114,81 @@
 	return 1;
 }
 
+static void msm8960_ext_spk_power_amp_on(u32 spk)
+{
+	if (spk & (SPK_AMP_POS | SPK_AMP_NEG)) {
+		if ((msm8930_ext_spk_pamp & SPK_AMP_POS) &&
+			(msm8930_ext_spk_pamp & SPK_AMP_NEG)) {
+
+			pr_debug("%s() External Bottom Speaker Ampl already "
+				"turned on. spk = 0x%08x\n", __func__, spk);
+			return;
+		}
+
+		msm8930_ext_spk_pamp |= spk;
+
+		if ((msm8930_ext_spk_pamp & SPK_AMP_POS) &&
+			(msm8930_ext_spk_pamp & SPK_AMP_NEG)) {
+
+			pm8xxx_spk_enable(MSM8930_SPK_ON);
+			pr_debug("%s: slepping 4 ms after turning on external "
+				" Left Speaker Ampl\n", __func__);
+			usleep_range(4000, 4000);
+		}
+
+	} else  {
+
+		pr_err("%s: ERROR : Invalid External Speaker Ampl. spk = 0x%08x\n",
+			__func__, spk);
+		return;
+	}
+}
+
+static void msm8960_ext_spk_power_amp_off(u32 spk)
+{
+	if (spk & (SPK_AMP_POS | SPK_AMP_NEG)) {
+		if (!msm8930_ext_spk_pamp)
+			return;
+
+		pm8xxx_spk_enable(MSM8930_SPK_OFF);
+		msm8930_ext_spk_pamp = 0;
+		pr_debug("%s: slepping 4 ms after turning on external "
+			" Left Speaker Ampl\n", __func__);
+		usleep_range(4000, 4000);
+
+	} else  {
+
+		pr_err("%s: ERROR : Invalid External Speaker Ampl. spk = 0x%08x\n",
+			__func__, spk);
+		return;
+	}
+}
+
 static int msm8930_spkramp_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *k, int event)
 {
 	pr_debug("%s() %x\n", __func__, SND_SOC_DAPM_EVENT_ON(event));
-	/* TODO: add external speaker power amps support */
+	if (SND_SOC_DAPM_EVENT_ON(event)) {
+		if (!strncmp(w->name, "Ext Spk Left Pos", 17))
+			msm8960_ext_spk_power_amp_on(SPK_AMP_POS);
+		else if (!strncmp(w->name, "Ext Spk Left Neg", 17))
+			msm8960_ext_spk_power_amp_on(SPK_AMP_NEG);
+		else {
+			pr_err("%s() Invalid Speaker Widget = %s\n",
+					__func__, w->name);
+			return -EINVAL;
+		}
+	} else {
+		if (!strncmp(w->name, "Ext Spk Left Pos", 17))
+			msm8960_ext_spk_power_amp_off(SPK_AMP_POS);
+		else if (!strncmp(w->name, "Ext Spk Left Neg", 17))
+			msm8960_ext_spk_power_amp_off(SPK_AMP_NEG);
+		else {
+			pr_err("%s() Invalid Speaker Widget = %s\n",
+					__func__, w->name);
+			return -EINVAL;
+		}
+	}
 	return 0;
 }
 
@@ -174,7 +247,7 @@
 	msm8930_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 
 	SND_SOC_DAPM_SPK("Ext Spk Left Pos", msm8930_spkramp_event),
-	SND_SOC_DAPM_SPK("Ext Spk Left Neg", NULL),
+	SND_SOC_DAPM_SPK("Ext Spk Left Neg", msm8930_spkramp_event),
 
 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
 	SND_SOC_DAPM_MIC("Digital Mic1", NULL),
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index ba5c79d..fc08febf 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -38,7 +38,6 @@
 #include <mach/peripheral-loader.h>
 #include <mach/qdsp6v2/audio_acdb.h>
 #include <mach/qdsp6v2/rtac.h>
-#include <mach/msm_subsystem_map.h>
 
 #include <sound/apr_audio.h>
 #include <sound/q6asm.h>
@@ -258,7 +257,7 @@
 						 "%ld\n", __func__,
 				PTR_ERR((void *)port->buf[cnt].mem_buffer));
 				else {
-					if (msm_subsystem_unmap_buffer(
+					if (iounmap(
 						port->buf[cnt].mem_buffer) < 0)
 						pr_err("%s: unmap buffer"
 							" failed\n", __func__);
@@ -328,7 +327,7 @@
 				"%ld\n", __func__,
 				PTR_ERR((void *)port->buf[0].mem_buffer));
 		else {
-			if (msm_subsystem_unmap_buffer(
+			if (iounmap(
 				port->buf[0].mem_buffer) < 0)
 				pr_err("%s: unmap buffer"
 					" failed\n", __func__);
@@ -574,11 +573,8 @@
 						mutex_unlock(&ac->cmd_lock);
 						goto fail;
 					}
-					flags = MSM_SUBSYSTEM_MAP_KADDR |
-						MSM_SUBSYSTEM_MAP_CACHED;
 					buf[cnt].mem_buffer =
-					msm_subsystem_map_buffer(buf[cnt].phys,
-						bufsz, flags, NULL, 0);
+					ioremap(buf[cnt].phys, bufsz);
 					if (IS_ERR(
 						(void *)buf[cnt].mem_buffer)) {
 						pr_err("%s:map_buffer failed,"
@@ -588,7 +584,7 @@
 						goto fail;
 					}
 					buf[cnt].data =
-						buf[cnt].mem_buffer->vaddr;
+						buf[cnt].mem_buffer;
 					if (!buf[cnt].data) {
 						pr_err("%s:invalid vaddr,"
 						" iomap failed\n", __func__);
@@ -700,9 +696,7 @@
 		goto fail;
 	}
 
-	flags = MSM_SUBSYSTEM_MAP_KADDR | MSM_SUBSYSTEM_MAP_CACHED;
-	buf[0].mem_buffer = msm_subsystem_map_buffer(buf[0].phys,
-				bufsz * bufcnt, flags, NULL, 0);
+	buf[0].mem_buffer = ioremap(buf[0].phys, bufsz * bufcnt);
 	if (IS_ERR((void *)buf[cnt].mem_buffer)) {
 		pr_err("%s:map_buffer failed,"
 			"error = %ld\n",
@@ -711,7 +705,7 @@
 		mutex_unlock(&ac->cmd_lock);
 		goto fail;
 	}
-	buf[0].data = buf[0].mem_buffer->vaddr;
+	buf[0].data = buf[0].mem_buffer;
 #endif
 	if (!buf[0].data) {
 		pr_err("%s:invalid vaddr,"