Merge "ASoC: msm: Apply cached volume and mute at call start." into msm-3.4
diff --git a/Documentation/devicetree/bindings/media/video/msm-vidc.txt b/Documentation/devicetree/bindings/media/video/msm-vidc.txt
index 11af7a9..dbbe46d 100644
--- a/Documentation/devicetree/bindings/media/video/msm-vidc.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-vidc.txt
@@ -5,11 +5,20 @@
 	- "qcom,msm-vidc"
 - reg : offset and length of the register set for the device.
 - interrupts : should contain the vidc interrupt.
+- vidc-cp-map : start and size of device virtual address range for secure buffers.
+  Video hardware uses this address range to identify if the buffers are secure
+  or non-secure.
+- vidc-ns-map : start and size of device virtual address range for non-secure buffers.
+  Video hardware uses this address range to identify if the buffers are secure
+  or non-secure.
 
 Example:
 
+
 	qcom,vidc@fdc00000 {
 		compatible = "qcom,msm-vidc";
 		reg = <0xfdc00000 0xff000>;
 		interrupts = <0 44 0>;
+		vidc-cp-map = <0x1000000 0x40000000>;
+		vidc-ns-map = <0x40000000 0x40000000>;
 	};
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 8426b52..2eb8216 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -46,6 +46,8 @@
 		compatible = "qcom,msm-vidc";
 		reg = <0xfdc00000 0xff000>;
 		interrupts = <0 44 0>;
+		vidc-cp-map = <0x1000000 0x40000000>;
+		vidc-ns-map = <0x40000000 0x40000000>;
 	};
 
 	serial@f991f000 {
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 7ccdd0f..5cd93dc 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -295,6 +295,7 @@
 obj-$(CONFIG_ARCH_MSM8974) += clock-local2.o clock-pll.o clock-8974.o clock-rpm.o clock-voter.o
 obj-$(CONFIG_ARCH_MSM8974) += gdsc.o
 obj-$(CONFIG_ARCH_MSM9625) += board-9625.o board-9625-gpiomux.o
+obj-$(CONFIG_ARCH_MSM8930) += acpuclock-krait.o acpuclock-8930.o acpuclock-8627.o
 
 obj-$(CONFIG_MACH_SAPPHIRE) += board-sapphire.o board-sapphire-gpio.o
 obj-$(CONFIG_MACH_SAPPHIRE) += board-sapphire-keypad.o board-sapphire-panel.o
diff --git a/arch/arm/mach-msm/acpuclock-8627.c b/arch/arm/mach-msm/acpuclock-8627.c
new file mode 100644
index 0000000..45f2096
--- /dev/null
+++ b/arch/arm/mach-msm/acpuclock-8627.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <mach/rpm-regulator.h>
+#include <mach/msm_bus_board.h>
+#include <mach/msm_bus.h>
+
+#include "acpuclock.h"
+#include "acpuclock-krait.h"
+
+/* Corner type vreg VDD values */
+#define LVL_NONE	RPM_VREG_CORNER_NONE
+#define LVL_LOW		RPM_VREG_CORNER_LOW
+#define LVL_NOM		RPM_VREG_CORNER_NOMINAL
+#define LVL_HIGH	RPM_VREG_CORNER_HIGH
+
+static struct hfpll_data hfpll_data = {
+	.mode_offset = 0x00,
+	.l_offset = 0x08,
+	.m_offset = 0x0C,
+	.n_offset = 0x10,
+	.config_offset = 0x04,
+	.config_val = 0x7845C665,
+	.has_droop_ctl = true,
+	.droop_offset = 0x14,
+	.droop_val = 0x0108C000,
+	.low_vdd_l_max = 40,
+	.vdd[HFPLL_VDD_NONE] = LVL_NONE,
+	.vdd[HFPLL_VDD_LOW]  = LVL_LOW,
+	.vdd[HFPLL_VDD_NOM]  = LVL_NOM,
+};
+
+static struct scalable scalable[] = {
+	[CPU0] = {
+		.hfpll_phys_base = 0x00903200,
+		.hfpll_data = &hfpll_data,
+		.aux_clk_sel_phys = 0x02088014,
+		.aux_clk_sel = 3,
+		.l2cpmr_iaddr = 0x4501,
+		.vreg[VREG_CORE] = { "krait0", 1300000, 1740000 },
+		.vreg[VREG_MEM]  = { "krait0_mem", 1150000 },
+		.vreg[VREG_DIG]  = { "krait0_dig", 1150000 },
+		.vreg[VREG_HFPLL_A] = { "krait0_hfpll", 1800000 },
+	},
+	[CPU1] = {
+		.hfpll_phys_base = 0x00903300,
+		.hfpll_data = &hfpll_data,
+		.aux_clk_sel_phys = 0x02098014,
+		.aux_clk_sel = 3,
+		.l2cpmr_iaddr = 0x5501,
+		.vreg[VREG_CORE] = { "krait1", 1300000, 1740000 },
+		.vreg[VREG_MEM]  = { "krait1_mem", 1150000 },
+		.vreg[VREG_DIG]  = { "krait1_dig", 1150000 },
+		.vreg[VREG_HFPLL_A] = { "krait1_hfpll", 1800000 },
+	},
+	[L2] = {
+		.hfpll_phys_base = 0x00903400,
+		.hfpll_data = &hfpll_data,
+		.aux_clk_sel_phys = 0x02011028,
+		.aux_clk_sel = 3,
+		.l2cpmr_iaddr = 0x0500,
+		.vreg[VREG_HFPLL_A] = { "l2_hfpll", 1800000 },
+	},
+};
+
+static struct msm_bus_paths bw_level_tbl[] = {
+	[0] =  BW_MBPS(640), /* At least  80 MHz on bus. */
+	[1] = BW_MBPS(1064), /* At least 133 MHz on bus. */
+	[2] = BW_MBPS(1600), /* At least 200 MHz on bus. */
+	[3] = BW_MBPS(2128), /* At least 266 MHz on bus. */
+	[4] = BW_MBPS(3200), /* At least 400 MHz on bus. */
+};
+
+static struct msm_bus_scale_pdata bus_scale_data = {
+	.usecase = bw_level_tbl,
+	.num_usecases = ARRAY_SIZE(bw_level_tbl),
+	.active_only = 1,
+	.name = "acpuclk-8627",
+};
+
+/* TODO: Update vdd_dig, vdd_mem and bw when data is available. */
+#define L2(x) (&l2_freq_tbl[(x)])
+static struct l2_level l2_freq_tbl[] = {
+	[0]  = { {STBY_KHZ, QSB,   0, 0, 0x00 },  LVL_NOM, 1050000, 0 },
+	[1]  = { {  384000, PLL_8, 0, 2, 0x00 },  LVL_NOM, 1050000, 1 },
+	[2]  = { {  432000, HFPLL, 2, 0, 0x20 },  LVL_NOM, 1050000, 1 },
+	[3]  = { {  486000, HFPLL, 2, 0, 0x24 },  LVL_NOM, 1050000, 1 },
+	[4]  = { {  540000, HFPLL, 2, 0, 0x28 },  LVL_NOM, 1050000, 2 },
+	[5]  = { {  594000, HFPLL, 1, 0, 0x16 },  LVL_NOM, 1050000, 2 },
+	[6]  = { {  648000, HFPLL, 1, 0, 0x18 },  LVL_NOM, 1050000, 2 },
+	[7]  = { {  702000, HFPLL, 1, 0, 0x1A },  LVL_NOM, 1050000, 3 },
+	[8]  = { {  756000, HFPLL, 1, 0, 0x1C }, LVL_HIGH, 1150000, 3 },
+	[9]  = { {  810000, HFPLL, 1, 0, 0x1E }, LVL_HIGH, 1150000, 3 },
+	[10] = { {  864000, HFPLL, 1, 0, 0x20 }, LVL_HIGH, 1150000, 4 },
+	[11] = { {  918000, HFPLL, 1, 0, 0x22 }, LVL_HIGH, 1150000, 4 },
+	[12] = { {  972000, HFPLL, 1, 0, 0x24 }, LVL_HIGH, 1150000, 4 },
+};
+
+/* TODO: Update core voltages when data is available. */
+static struct acpu_level acpu_freq_tbl[] = {
+	{ 0, { STBY_KHZ, QSB,   0, 0, 0x00 }, L2(0),   900000 },
+	{ 1, {   384000, PLL_8, 0, 2, 0x00 }, L2(1),   900000 },
+	{ 1, {   432000, HFPLL, 2, 0, 0x20 }, L2(5),   925000 },
+	{ 1, {   486000, HFPLL, 2, 0, 0x24 }, L2(5),   925000 },
+	{ 1, {   540000, HFPLL, 2, 0, 0x28 }, L2(5),   937500 },
+	{ 1, {   594000, HFPLL, 1, 0, 0x16 }, L2(5),   962500 },
+	{ 1, {   648000, HFPLL, 1, 0, 0x18 }, L2(9),   987500 },
+	{ 1, {   702000, HFPLL, 1, 0, 0x1A }, L2(9),  1000000 },
+	{ 1, {   756000, HFPLL, 1, 0, 0x1C }, L2(9),  1025000 },
+	{ 1, {   810000, HFPLL, 1, 0, 0x1E }, L2(9),  1062500 },
+	{ 1, {   864000, HFPLL, 1, 0, 0x20 }, L2(12), 1062500 },
+	{ 1, {   918000, HFPLL, 1, 0, 0x22 }, L2(12), 1087500 },
+	{ 1, {   972000, HFPLL, 1, 0, 0x24 }, L2(12), 1100000 },
+	{ 0, { 0 } }
+};
+
+static struct acpuclk_krait_params acpuclk_8627_params = {
+	.scalable = scalable,
+	.pvs_acpu_freq_tbl[PVS_SLOW] = acpu_freq_tbl,
+	.pvs_acpu_freq_tbl[PVS_NOMINAL] = acpu_freq_tbl,
+	.pvs_acpu_freq_tbl[PVS_FAST] = acpu_freq_tbl,
+	.l2_freq_tbl = l2_freq_tbl,
+	.l2_freq_tbl_size = ARRAY_SIZE(l2_freq_tbl),
+	.bus_scale_data = &bus_scale_data,
+	.qfprom_phys_base = 0x00700000,
+};
+
+static int __init acpuclk_8627_probe(struct platform_device *pdev)
+{
+	return acpuclk_krait_init(&pdev->dev, &acpuclk_8627_params);
+}
+
+static struct platform_driver acpuclk_8627_driver = {
+	.driver = {
+		.name = "acpuclk-8627",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init acpuclk_8627_init(void)
+{
+	return platform_driver_probe(&acpuclk_8627_driver,
+				     acpuclk_8627_probe);
+}
+device_initcall(acpuclk_8627_init);
diff --git a/arch/arm/mach-msm/acpuclock-8930.c b/arch/arm/mach-msm/acpuclock-8930.c
new file mode 100644
index 0000000..d60b4eb
--- /dev/null
+++ b/arch/arm/mach-msm/acpuclock-8930.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <mach/rpm-regulator.h>
+#include <mach/msm_bus_board.h>
+#include <mach/msm_bus.h>
+
+#include "acpuclock.h"
+#include "acpuclock-krait.h"
+
+/* Corner type vreg VDD values */
+#define LVL_NONE	RPM_VREG_CORNER_NONE
+#define LVL_LOW		RPM_VREG_CORNER_LOW
+#define LVL_NOM		RPM_VREG_CORNER_NOMINAL
+#define LVL_HIGH	RPM_VREG_CORNER_HIGH
+
+static struct hfpll_data hfpll_data = {
+	.mode_offset = 0x00,
+	.l_offset = 0x08,
+	.m_offset = 0x0C,
+	.n_offset = 0x10,
+	.config_offset = 0x04,
+	.config_val = 0x7845C665,
+	.has_droop_ctl = true,
+	.droop_offset = 0x14,
+	.droop_val = 0x0108C000,
+	.low_vdd_l_max = 40,
+	.vdd[HFPLL_VDD_NONE] = LVL_NONE,
+	.vdd[HFPLL_VDD_LOW]  = LVL_LOW,
+	.vdd[HFPLL_VDD_NOM]  = LVL_NOM,
+};
+
+static struct scalable scalable[] = {
+	[CPU0] = {
+		.hfpll_phys_base = 0x00903200,
+		.hfpll_data = &hfpll_data,
+		.aux_clk_sel_phys = 0x02088014,
+		.aux_clk_sel = 3,
+		.l2cpmr_iaddr = 0x4501,
+		.vreg[VREG_CORE] = { "krait0", 1300000, 1740000 },
+		.vreg[VREG_MEM]  = { "krait0_mem", 1150000 },
+		.vreg[VREG_DIG]  = { "krait0_dig", 1150000 },
+		.vreg[VREG_HFPLL_A] = { "krait0_hfpll", 1800000 },
+	},
+	[CPU1] = {
+		.hfpll_phys_base = 0x00903300,
+		.hfpll_data = &hfpll_data,
+		.aux_clk_sel_phys = 0x02098014,
+		.aux_clk_sel = 3,
+		.l2cpmr_iaddr = 0x5501,
+		.vreg[VREG_CORE] = { "krait1", 1300000, 1740000 },
+		.vreg[VREG_MEM]  = { "krait1_mem", 1150000 },
+		.vreg[VREG_DIG]  = { "krait1_dig", 1150000 },
+		.vreg[VREG_HFPLL_A] = { "krait1_hfpll", 1800000 },
+	},
+	[L2] = {
+		.hfpll_phys_base = 0x00903400,
+		.hfpll_data = &hfpll_data,
+		.aux_clk_sel_phys = 0x02011028,
+		.aux_clk_sel = 3,
+		.l2cpmr_iaddr = 0x0500,
+		.vreg[VREG_HFPLL_A] = { "l2_hfpll", 1800000 },
+	},
+};
+
+static struct msm_bus_paths bw_level_tbl[] = {
+	[0] =  BW_MBPS(640), /* At least  80 MHz on bus. */
+	[1] = BW_MBPS(1064), /* At least 133 MHz on bus. */
+	[2] = BW_MBPS(1600), /* At least 200 MHz on bus. */
+	[3] = BW_MBPS(2128), /* At least 266 MHz on bus. */
+	[4] = BW_MBPS(3200), /* At least 400 MHz on bus. */
+	[5] = BW_MBPS(3600), /* At least 450 MHz on bus. */
+	[6] = BW_MBPS(3936), /* At least 492 MHz on bus. */
+	[7] = BW_MBPS(4264), /* At least 533 MHz on bus. */
+};
+
+static struct msm_bus_scale_pdata bus_scale_data = {
+	.usecase = bw_level_tbl,
+	.num_usecases = ARRAY_SIZE(bw_level_tbl),
+	.active_only = 1,
+	.name = "acpuclk-8930",
+};
+
+/* TODO: Update vdd_dig, vdd_mem and bw when data is available. */
+#define L2(x) (&l2_freq_tbl[(x)])
+static struct l2_level l2_freq_tbl[] = {
+	[0]  = { {STBY_KHZ, QSB,   0, 0, 0x00 },  LVL_NOM, 1050000, 0 },
+	[1]  = { {  384000, PLL_8, 0, 2, 0x00 },  LVL_NOM, 1050000, 1 },
+	[2]  = { {  432000, HFPLL, 2, 0, 0x20 },  LVL_NOM, 1050000, 2 },
+	[3]  = { {  486000, HFPLL, 2, 0, 0x24 },  LVL_NOM, 1050000, 2 },
+	[4]  = { {  540000, HFPLL, 2, 0, 0x28 },  LVL_NOM, 1050000, 2 },
+	[5]  = { {  594000, HFPLL, 1, 0, 0x16 },  LVL_NOM, 1050000, 2 },
+	[6]  = { {  648000, HFPLL, 1, 0, 0x18 },  LVL_NOM, 1050000, 4 },
+	[7]  = { {  702000, HFPLL, 1, 0, 0x1A },  LVL_NOM, 1050000, 4 },
+	[8]  = { {  756000, HFPLL, 1, 0, 0x1C }, LVL_HIGH, 1150000, 4 },
+	[9]  = { {  810000, HFPLL, 1, 0, 0x1E }, LVL_HIGH, 1150000, 4 },
+	[10] = { {  864000, HFPLL, 1, 0, 0x20 }, LVL_HIGH, 1150000, 4 },
+	[11] = { {  918000, HFPLL, 1, 0, 0x22 }, LVL_HIGH, 1150000, 7 },
+	[12] = { {  972000, HFPLL, 1, 0, 0x24 }, LVL_HIGH, 1150000, 7 },
+	[13] = { { 1026000, HFPLL, 1, 0, 0x26 }, LVL_HIGH, 1150000, 7 },
+	[14] = { { 1080000, HFPLL, 1, 0, 0x28 }, LVL_HIGH, 1150000, 7 },
+	[15] = { { 1134000, HFPLL, 1, 0, 0x2A }, LVL_HIGH, 1150000, 7 },
+	[16] = { { 1188000, HFPLL, 1, 0, 0x2C }, LVL_HIGH, 1150000, 7 },
+};
+
+static struct acpu_level acpu_freq_tbl_slow[] = {
+	{ 0, { STBY_KHZ, QSB,   0, 0, 0x00 }, L2(0),   950000 },
+	{ 1, {   384000, PLL_8, 0, 2, 0x00 }, L2(1),   950000 },
+	{ 1, {   432000, HFPLL, 2, 0, 0x20 }, L2(6),   975000 },
+	{ 1, {   486000, HFPLL, 2, 0, 0x24 }, L2(6),   975000 },
+	{ 1, {   540000, HFPLL, 2, 0, 0x28 }, L2(6),  1000000 },
+	{ 1, {   594000, HFPLL, 1, 0, 0x16 }, L2(6),  1000000 },
+	{ 1, {   648000, HFPLL, 1, 0, 0x18 }, L2(6),  1025000 },
+	{ 1, {   702000, HFPLL, 1, 0, 0x1A }, L2(6),  1025000 },
+	{ 1, {   756000, HFPLL, 1, 0, 0x1C }, L2(11), 1075000 },
+	{ 1, {   810000, HFPLL, 1, 0, 0x1E }, L2(11), 1075000 },
+	{ 1, {   864000, HFPLL, 1, 0, 0x20 }, L2(11), 1100000 },
+	{ 1, {   918000, HFPLL, 1, 0, 0x22 }, L2(11), 1100000 },
+	{ 1, {   972000, HFPLL, 1, 0, 0x24 }, L2(11), 1125000 },
+	{ 1, {  1026000, HFPLL, 1, 0, 0x26 }, L2(11), 1125000 },
+	{ 1, {  1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1175000 },
+	{ 1, {  1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1175000 },
+	{ 1, {  1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1200000 },
+	{ 0, { 0 } }
+};
+
+static struct acpu_level acpu_freq_tbl_nom[] = {
+	{ 0, { STBY_KHZ, QSB,   0, 0, 0x00 }, L2(0),   925000 },
+	{ 1, {   384000, PLL_8, 0, 2, 0x00 }, L2(1),   925000 },
+	{ 1, {   432000, HFPLL, 2, 0, 0x20 }, L2(6),   950000 },
+	{ 1, {   486000, HFPLL, 2, 0, 0x24 }, L2(6),   950000 },
+	{ 1, {   540000, HFPLL, 2, 0, 0x28 }, L2(6),   975000 },
+	{ 1, {   594000, HFPLL, 1, 0, 0x16 }, L2(6),   975000 },
+	{ 1, {   648000, HFPLL, 1, 0, 0x18 }, L2(6),  1000000 },
+	{ 1, {   702000, HFPLL, 1, 0, 0x1A }, L2(6),  1000000 },
+	{ 1, {   756000, HFPLL, 1, 0, 0x1C }, L2(11), 1050000 },
+	{ 1, {   810000, HFPLL, 1, 0, 0x1E }, L2(11), 1050000 },
+	{ 1, {   864000, HFPLL, 1, 0, 0x20 }, L2(11), 1075000 },
+	{ 1, {   918000, HFPLL, 1, 0, 0x22 }, L2(11), 1075000 },
+	{ 1, {   972000, HFPLL, 1, 0, 0x24 }, L2(11), 1100000 },
+	{ 1, {  1026000, HFPLL, 1, 0, 0x26 }, L2(11), 1100000 },
+	{ 1, {  1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1150000 },
+	{ 1, {  1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1150000 },
+	{ 1, {  1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1175000 },
+	{ 0, { 0 } }
+};
+
+static struct acpu_level acpu_freq_tbl_fast[] = {
+	{ 0, { STBY_KHZ, QSB,   0, 0, 0x00 }, L2(0),   900000 },
+	{ 1, {   384000, PLL_8, 0, 2, 0x00 }, L2(1),   900000 },
+	{ 1, {   432000, HFPLL, 2, 0, 0x20 }, L2(6),   900000 },
+	{ 1, {   486000, HFPLL, 2, 0, 0x24 }, L2(6),   900000 },
+	{ 1, {   540000, HFPLL, 2, 0, 0x28 }, L2(6),   925000 },
+	{ 1, {   594000, HFPLL, 1, 0, 0x16 }, L2(6),   925000 },
+	{ 1, {   648000, HFPLL, 1, 0, 0x18 }, L2(6),   950000 },
+	{ 1, {   702000, HFPLL, 1, 0, 0x1A }, L2(6),   950000 },
+	{ 1, {   756000, HFPLL, 1, 0, 0x1C }, L2(11), 1000000 },
+	{ 1, {   810000, HFPLL, 1, 0, 0x1E }, L2(11), 1000000 },
+	{ 1, {   864000, HFPLL, 1, 0, 0x20 }, L2(11), 1025000 },
+	{ 1, {   918000, HFPLL, 1, 0, 0x22 }, L2(11), 1025000 },
+	{ 1, {   972000, HFPLL, 1, 0, 0x24 }, L2(11), 1050000 },
+	{ 1, {  1026000, HFPLL, 1, 0, 0x26 }, L2(11), 1050000 },
+	{ 1, {  1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1100000 },
+	{ 1, {  1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1100000 },
+	{ 1, {  1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1125000 },
+	{ 0, { 0 } }
+};
+
+static struct acpuclk_krait_params acpuclk_8930_params = {
+	.scalable = scalable,
+	.pvs_acpu_freq_tbl[PVS_SLOW] = acpu_freq_tbl_slow,
+	.pvs_acpu_freq_tbl[PVS_NOMINAL] = acpu_freq_tbl_nom,
+	.pvs_acpu_freq_tbl[PVS_FAST] = acpu_freq_tbl_fast,
+	.l2_freq_tbl = l2_freq_tbl,
+	.l2_freq_tbl_size = ARRAY_SIZE(l2_freq_tbl),
+	.bus_scale_data = &bus_scale_data,
+	.qfprom_phys_base = 0x00700000,
+};
+
+static int __init acpuclk_8930_probe(struct platform_device *pdev)
+{
+	return acpuclk_krait_init(&pdev->dev, &acpuclk_8930_params);
+}
+
+static struct platform_driver acpuclk_8930_driver = {
+	.driver = {
+		.name = "acpuclk-8930",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init acpuclk_8930_init(void)
+{
+	return platform_driver_probe(&acpuclk_8930_driver,
+				     acpuclk_8930_probe);
+}
+device_initcall(acpuclk_8930_init);
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index 7f198d2..8947c9f 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -170,12 +170,6 @@
 	[HFPLL_VDD_NOM]  = 1050000
 };
 
-static unsigned int hfpll_vdd_dig_tbl_8930[] = {
-	[HFPLL_VDD_NONE] = LVL_NONE,
-	[HFPLL_VDD_LOW]  = LVL_LOW,
-	[HFPLL_VDD_NOM]  = LVL_NOM
-};
-
 static struct scalable scalable_8960[] = {
 	[CPU0] = {
 			.hfpll_base      = MSM_HFPLL_BASE + 0x200,
@@ -302,95 +296,6 @@
 		},
 };
 
-static struct scalable scalable_8930[] = {
-	[CPU0] = {
-			.hfpll_base      = MSM_HFPLL_BASE + 0x200,
-			.aux_clk_sel     = MSM_ACC0_BASE  + 0x014,
-			.l2cpmr_iaddr    = L2CPUCPMR_IADDR,
-			.vreg[VREG_CORE] = { "krait0",     1300000 },
-			.vreg[VREG_MEM]  = { "krait0_mem", 1150000,
-					     RPM_VREG_VOTER1,
-					     RPM_VREG_ID_PM8038_L24 },
-			.vreg[VREG_DIG]  = { "krait0_dig", LVL_HIGH,
-					     RPM_VREG_VOTER1,
-					     RPM_VREG_ID_PM8038_VDD_DIG_CORNER
-					   },
-			.vreg[VREG_HFPLL_B] = { "hfpll0", 1800000,
-					     RPM_VREG_VOTER1,
-					     RPM_VREG_ID_PM8038_L23 },
-		},
-	[CPU1] = {
-			.hfpll_base      = MSM_HFPLL_BASE + 0x300,
-			.aux_clk_sel     = MSM_ACC1_BASE  + 0x014,
-			.l2cpmr_iaddr    = L2CPUCPMR_IADDR,
-			.vreg[VREG_CORE] = { "krait1",     1300000 },
-			.vreg[VREG_MEM]  = { "krait1_mem", 1150000,
-					     RPM_VREG_VOTER2,
-					     RPM_VREG_ID_PM8038_L24 },
-			.vreg[VREG_DIG]  = { "krait1_dig", LVL_HIGH,
-					     RPM_VREG_VOTER2,
-					     RPM_VREG_ID_PM8038_VDD_DIG_CORNER
-					   },
-			.vreg[VREG_HFPLL_B] = { "hfpll1", 1800000,
-					     RPM_VREG_VOTER2,
-					     RPM_VREG_ID_PM8038_L23 },
-		},
-	[L2] = {
-			.hfpll_base   = MSM_HFPLL_BASE    + 0x400,
-			.hfpll_vdd_tbl = hfpll_vdd_dig_tbl_8930,
-			.aux_clk_sel  = MSM_APCS_GCC_BASE + 0x028,
-			.l2cpmr_iaddr = L2CPMR_IADDR,
-			.vreg[VREG_HFPLL_B] = { "hfpll_l2", 1800000,
-					     RPM_VREG_VOTER6,
-					     RPM_VREG_ID_PM8038_L23 },
-		},
-};
-
-/*TODO: Update the rpm vreg id when the rpm driver is ready */
-static struct scalable scalable_8627[] = {
-	[CPU0] = {
-			.hfpll_base      = MSM_HFPLL_BASE + 0x200,
-			.aux_clk_sel     = MSM_ACC0_BASE  + 0x014,
-			.l2cpmr_iaddr    = L2CPUCPMR_IADDR,
-			.vreg[VREG_CORE] = { "krait0",     1300000 },
-			.vreg[VREG_MEM]  = { "krait0_mem", 1150000,
-					     RPM_VREG_VOTER1,
-					     RPM_VREG_ID_PM8038_L24 },
-			.vreg[VREG_DIG]  = { "krait0_dig", LVL_HIGH,
-					     RPM_VREG_VOTER1,
-					     RPM_VREG_ID_PM8038_VDD_DIG_CORNER
-					   },
-			.vreg[VREG_HFPLL_B] = { "hfpll0", 1800000,
-					     RPM_VREG_VOTER1,
-					     RPM_VREG_ID_PM8038_L23 },
-		},
-	[CPU1] = {
-			.hfpll_base      = MSM_HFPLL_BASE + 0x300,
-			.aux_clk_sel     = MSM_ACC1_BASE  + 0x014,
-			.l2cpmr_iaddr    = L2CPUCPMR_IADDR,
-			.vreg[VREG_CORE] = { "krait1",     1300000 },
-			.vreg[VREG_MEM]  = { "krait1_mem", 1150000,
-					     RPM_VREG_VOTER2,
-					     RPM_VREG_ID_PM8038_L24 },
-			.vreg[VREG_DIG]  = { "krait1_dig", LVL_HIGH,
-					     RPM_VREG_VOTER2,
-					     RPM_VREG_ID_PM8038_VDD_DIG_CORNER
-					   },
-			.vreg[VREG_HFPLL_B] = { "hfpll1", 1800000,
-					     RPM_VREG_VOTER2,
-					     RPM_VREG_ID_PM8038_L23 },
-		},
-	[L2] = {
-			.hfpll_base   = MSM_HFPLL_BASE    + 0x400,
-			.hfpll_vdd_tbl = hfpll_vdd_dig_tbl_8930,
-			.aux_clk_sel  = MSM_APCS_GCC_BASE + 0x028,
-			.l2cpmr_iaddr = L2CPMR_IADDR,
-			.vreg[VREG_HFPLL_B] = { "hfpll_l2", 1800000,
-					     RPM_VREG_VOTER6,
-					     RPM_VREG_ID_PM8038_L23 },
-		},
-};
-
 static struct l2_level *l2_freq_tbl;
 static struct acpu_level *acpu_freq_tbl;
 static int l2_freq_tbl_size;
@@ -695,129 +600,6 @@
 	{ 0, { 0 } }
 };
 
-/* TODO: Update vdd_dig, vdd_mem and bw when data is available. */
-#undef L2
-#define L2(x) (&l2_freq_tbl_8930[(x)])
-static struct l2_level l2_freq_tbl_8930[] = {
-	[0]  = { {STBY_KHZ, QSB,   0, 0, 0x00 },  LVL_NOM, 1050000, 0 },
-	[1]  = { {  384000, PLL_8, 0, 2, 0x00 },  LVL_NOM, 1050000, 1 },
-	[2]  = { {  432000, HFPLL, 2, 0, 0x20 },  LVL_NOM, 1050000, 2 },
-	[3]  = { {  486000, HFPLL, 2, 0, 0x24 },  LVL_NOM, 1050000, 2 },
-	[4]  = { {  540000, HFPLL, 2, 0, 0x28 },  LVL_NOM, 1050000, 2 },
-	[5]  = { {  594000, HFPLL, 1, 0, 0x16 },  LVL_NOM, 1050000, 2 },
-	[6]  = { {  648000, HFPLL, 1, 0, 0x18 },  LVL_NOM, 1050000, 4 },
-	[7]  = { {  702000, HFPLL, 1, 0, 0x1A },  LVL_NOM, 1050000, 4 },
-	[8]  = { {  756000, HFPLL, 1, 0, 0x1C }, LVL_HIGH, 1150000, 4 },
-	[9]  = { {  810000, HFPLL, 1, 0, 0x1E }, LVL_HIGH, 1150000, 4 },
-	[10] = { {  864000, HFPLL, 1, 0, 0x20 }, LVL_HIGH, 1150000, 4 },
-	[11] = { {  918000, HFPLL, 1, 0, 0x22 }, LVL_HIGH, 1150000, 7 },
-	[12] = { {  972000, HFPLL, 1, 0, 0x24 }, LVL_HIGH, 1150000, 7 },
-	[13] = { { 1026000, HFPLL, 1, 0, 0x26 }, LVL_HIGH, 1150000, 7 },
-	[14] = { { 1080000, HFPLL, 1, 0, 0x28 }, LVL_HIGH, 1150000, 7 },
-	[15] = { { 1134000, HFPLL, 1, 0, 0x2A }, LVL_HIGH, 1150000, 7 },
-	[16] = { { 1188000, HFPLL, 1, 0, 0x2C }, LVL_HIGH, 1150000, 7 },
-};
-
-/* TODO: Update core voltages when data is available. */
-static struct acpu_level acpu_freq_tbl_8930_slow[] = {
-	{ 0, { STBY_KHZ, QSB,   0, 0, 0x00 }, L2(0),   950000 },
-	{ 1, {   384000, PLL_8, 0, 2, 0x00 }, L2(1),   950000 },
-	{ 1, {   432000, HFPLL, 2, 0, 0x20 }, L2(6),   975000 },
-	{ 1, {   486000, HFPLL, 2, 0, 0x24 }, L2(6),   975000 },
-	{ 1, {   540000, HFPLL, 2, 0, 0x28 }, L2(6),  1000000 },
-	{ 1, {   594000, HFPLL, 1, 0, 0x16 }, L2(6),  1000000 },
-	{ 1, {   648000, HFPLL, 1, 0, 0x18 }, L2(6),  1025000 },
-	{ 1, {   702000, HFPLL, 1, 0, 0x1A }, L2(6),  1025000 },
-	{ 1, {   756000, HFPLL, 1, 0, 0x1C }, L2(11), 1075000 },
-	{ 1, {   810000, HFPLL, 1, 0, 0x1E }, L2(11), 1075000 },
-	{ 1, {   864000, HFPLL, 1, 0, 0x20 }, L2(11), 1100000 },
-	{ 1, {   918000, HFPLL, 1, 0, 0x22 }, L2(11), 1100000 },
-	{ 1, {   972000, HFPLL, 1, 0, 0x24 }, L2(11), 1125000 },
-	{ 1, {  1026000, HFPLL, 1, 0, 0x26 }, L2(11), 1125000 },
-	{ 1, {  1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1175000 },
-	{ 1, {  1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1175000 },
-	{ 1, {  1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1200000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_8930_nom[] = {
-	{ 0, { STBY_KHZ, QSB,   0, 0, 0x00 }, L2(0),   925000 },
-	{ 1, {   384000, PLL_8, 0, 2, 0x00 }, L2(1),   925000 },
-	{ 1, {   432000, HFPLL, 2, 0, 0x20 }, L2(6),   950000 },
-	{ 1, {   486000, HFPLL, 2, 0, 0x24 }, L2(6),   950000 },
-	{ 1, {   540000, HFPLL, 2, 0, 0x28 }, L2(6),   975000 },
-	{ 1, {   594000, HFPLL, 1, 0, 0x16 }, L2(6),   975000 },
-	{ 1, {   648000, HFPLL, 1, 0, 0x18 }, L2(6),  1000000 },
-	{ 1, {   702000, HFPLL, 1, 0, 0x1A }, L2(6),  1000000 },
-	{ 1, {   756000, HFPLL, 1, 0, 0x1C }, L2(11), 1050000 },
-	{ 1, {   810000, HFPLL, 1, 0, 0x1E }, L2(11), 1050000 },
-	{ 1, {   864000, HFPLL, 1, 0, 0x20 }, L2(11), 1075000 },
-	{ 1, {   918000, HFPLL, 1, 0, 0x22 }, L2(11), 1075000 },
-	{ 1, {   972000, HFPLL, 1, 0, 0x24 }, L2(11), 1100000 },
-	{ 1, {  1026000, HFPLL, 1, 0, 0x26 }, L2(11), 1100000 },
-	{ 1, {  1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1150000 },
-	{ 1, {  1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1150000 },
-	{ 1, {  1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1175000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_8930_fast[] = {
-	{ 0, { STBY_KHZ, QSB,   0, 0, 0x00 }, L2(0),   900000 },
-	{ 1, {   384000, PLL_8, 0, 2, 0x00 }, L2(1),   900000 },
-	{ 1, {   432000, HFPLL, 2, 0, 0x20 }, L2(6),   900000 },
-	{ 1, {   486000, HFPLL, 2, 0, 0x24 }, L2(6),   900000 },
-	{ 1, {   540000, HFPLL, 2, 0, 0x28 }, L2(6),   925000 },
-	{ 1, {   594000, HFPLL, 1, 0, 0x16 }, L2(6),   925000 },
-	{ 1, {   648000, HFPLL, 1, 0, 0x18 }, L2(6),   950000 },
-	{ 1, {   702000, HFPLL, 1, 0, 0x1A }, L2(6),   950000 },
-	{ 1, {   756000, HFPLL, 1, 0, 0x1C }, L2(11), 1000000 },
-	{ 1, {   810000, HFPLL, 1, 0, 0x1E }, L2(11), 1000000 },
-	{ 1, {   864000, HFPLL, 1, 0, 0x20 }, L2(11), 1025000 },
-	{ 1, {   918000, HFPLL, 1, 0, 0x22 }, L2(11), 1025000 },
-	{ 1, {   972000, HFPLL, 1, 0, 0x24 }, L2(11), 1050000 },
-	{ 1, {  1026000, HFPLL, 1, 0, 0x26 }, L2(11), 1050000 },
-	{ 1, {  1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1100000 },
-	{ 1, {  1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1100000 },
-	{ 1, {  1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1125000 },
-	{ 0, { 0 } }
-};
-/* TODO: Update vdd_dig, vdd_mem and bw when data is available. */
-#undef L2
-#define L2(x) (&l2_freq_tbl_8627[(x)])
-static struct l2_level l2_freq_tbl_8627[] = {
-	[0]  = { {STBY_KHZ, QSB,   0, 0, 0x00 },  LVL_NOM, 1050000, 0 },
-	[1]  = { {  384000, PLL_8, 0, 2, 0x00 },  LVL_NOM, 1050000, 1 },
-	[2]  = { {  432000, HFPLL, 2, 0, 0x20 },  LVL_NOM, 1050000, 1 },
-	[3]  = { {  486000, HFPLL, 2, 0, 0x24 },  LVL_NOM, 1050000, 1 },
-	[4]  = { {  540000, HFPLL, 2, 0, 0x28 },  LVL_NOM, 1050000, 2 },
-	[5]  = { {  594000, HFPLL, 1, 0, 0x16 },  LVL_NOM, 1050000, 2 },
-	[6]  = { {  648000, HFPLL, 1, 0, 0x18 },  LVL_NOM, 1050000, 2 },
-	[7]  = { {  702000, HFPLL, 1, 0, 0x1A },  LVL_NOM, 1050000, 3 },
-	[8]  = { {  756000, HFPLL, 1, 0, 0x1C }, LVL_HIGH, 1150000, 3 },
-	[9]  = { {  810000, HFPLL, 1, 0, 0x1E }, LVL_HIGH, 1150000, 3 },
-	[10] = { {  864000, HFPLL, 1, 0, 0x20 }, LVL_HIGH, 1150000, 4 },
-	[11] = { {  918000, HFPLL, 1, 0, 0x22 }, LVL_HIGH, 1150000, 4 },
-	[12] = { {  972000, HFPLL, 1, 0, 0x24 }, LVL_HIGH, 1150000, 4 },
-};
-
-/* TODO: Update core voltages when data is available. */
-static struct acpu_level acpu_freq_tbl_8627[] = {
-	{ 0, { STBY_KHZ, QSB,   0, 0, 0x00 }, L2(0),   900000 },
-	{ 1, {   384000, PLL_8, 0, 2, 0x00 }, L2(1),   900000 },
-	{ 1, {   432000, HFPLL, 2, 0, 0x20 }, L2(5),   925000 },
-	{ 1, {   486000, HFPLL, 2, 0, 0x24 }, L2(5),   925000 },
-	{ 1, {   540000, HFPLL, 2, 0, 0x28 }, L2(5),   937500 },
-	{ 1, {   594000, HFPLL, 1, 0, 0x16 }, L2(5),   962500 },
-	{ 1, {   648000, HFPLL, 1, 0, 0x18 }, L2(9),   987500 },
-	{ 1, {   702000, HFPLL, 1, 0, 0x1A }, L2(9),  1000000 },
-	{ 1, {   756000, HFPLL, 1, 0, 0x1C }, L2(9),  1025000 },
-	{ 1, {   810000, HFPLL, 1, 0, 0x1E }, L2(9),  1062500 },
-	{ 1, {   864000, HFPLL, 1, 0, 0x20 }, L2(12), 1062500 },
-	{ 1, {   918000, HFPLL, 1, 0, 0x22 }, L2(12), 1087500 },
-	{ 1, {   972000, HFPLL, 1, 0, 0x24 }, L2(12), 1100000 },
-	{ 0, { 0 } }
-};
-
 static struct acpu_level *acpu_freq_tbl_8960_v1[NUM_PVS] __initdata = {
 	[PVS_SLOW] = acpu_freq_tbl_8960_kraitv1_slow,
 	[PVS_NOM] = acpu_freq_tbl_8960_kraitv1_nom_fast,
@@ -838,12 +620,6 @@
 	[PVS_FASTER] = acpu_freq_tbl_8064_fast,
 };
 
-static struct acpu_level *acpu_freq_tbl_8930_pvs[NUM_PVS] __initdata = {
-	[PVS_SLOW] = acpu_freq_tbl_8930_slow,
-	[PVS_NOM] = acpu_freq_tbl_8930_nom,
-	[PVS_FAST] = acpu_freq_tbl_8930_fast,
-};
-
 static struct acpu_level *max_acpu_level;
 
 static unsigned long acpuclk_8960_get_rate(int cpu)
@@ -1608,18 +1384,6 @@
 		acpu_freq_tbl = acpu_freq_tbl_8064[pvs_id];
 		l2_freq_tbl = l2_freq_tbl_8064;
 		l2_freq_tbl_size = ARRAY_SIZE(l2_freq_tbl_8064);
-	} else if (cpu_is_msm8627()) {
-		scalable = scalable_8627;
-		acpu_freq_tbl = acpu_freq_tbl_8627;
-		l2_freq_tbl = l2_freq_tbl_8627;
-		l2_freq_tbl_size = ARRAY_SIZE(l2_freq_tbl_8627);
-	} else if (cpu_is_msm8930() || cpu_is_msm8930aa()) {
-		enum pvs pvs_id = get_pvs();
-
-		scalable = scalable_8930;
-		acpu_freq_tbl = acpu_freq_tbl_8930_pvs[pvs_id];
-		l2_freq_tbl = l2_freq_tbl_8930;
-		l2_freq_tbl_size = ARRAY_SIZE(l2_freq_tbl_8930);
 	} else {
 		BUG();
 	}
diff --git a/arch/arm/mach-msm/board-8064-camera.c b/arch/arm/mach-msm/board-8064-camera.c
index c37491d..40995bb 100644
--- a/arch/arm/mach-msm/board-8064-camera.c
+++ b/arch/arm/mach-msm/board-8064-camera.c
@@ -243,7 +243,7 @@
 	{
 		.src = MSM_BUS_MASTER_VFE,
 		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 140451840,
+		.ab  = 274406400,
 		.ib  = 561807360,
 	},
 	{
@@ -302,6 +302,27 @@
 	},
 };
 
+static struct msm_bus_vectors cam_video_ls_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 348192000,
+		.ib  = 617103360,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 206807040,
+		.ib  = 488816640,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 540000000,
+		.ib  = 1350000000,
+	},
+};
+
 static struct msm_bus_paths cam_bus_client_config[] = {
 	{
 		ARRAY_SIZE(cam_init_vectors),
@@ -323,6 +344,10 @@
 		ARRAY_SIZE(cam_zsl_vectors),
 		cam_zsl_vectors,
 	},
+	{
+		ARRAY_SIZE(cam_video_ls_vectors),
+		cam_video_ls_vectors,
+	},
 };
 
 static struct msm_bus_scale_pdata cam_bus_client_pdata = {
diff --git a/arch/arm/mach-msm/board-8064-display.c b/arch/arm/mach-msm/board-8064-display.c
index 177e1fd..330d7a8 100644
--- a/arch/arm/mach-msm/board-8064-display.c
+++ b/arch/arm/mach-msm/board-8064-display.c
@@ -1045,7 +1045,8 @@
 	}
 }
 
-void __init apq8064_set_display_params(char *prim_panel, char *ext_panel)
+void __init apq8064_set_display_params(char *prim_panel, char *ext_panel,
+		unsigned char resolution)
 {
 	/*
 	 * For certain MPQ boards, HDMI should be set as primary display
@@ -1080,4 +1081,6 @@
 		pr_debug("msm_fb_pdata.ext_panel_name %s\n",
 			msm_fb_pdata.ext_panel_name);
 	}
+
+	msm_fb_pdata.ext_resolution = resolution;
 }
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 08c3408..1f59909 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -657,6 +657,9 @@
 
 static char prim_panel_name[PANEL_NAME_MAX_LEN];
 static char ext_panel_name[PANEL_NAME_MAX_LEN];
+
+static int ext_resolution;
+
 static int __init prim_display_setup(char *param)
 {
 	if (strnlen(param, PANEL_NAME_MAX_LEN))
@@ -673,9 +676,18 @@
 }
 early_param("ext_display", ext_display_setup);
 
+static int __init hdmi_resulution_setup(char *param)
+{
+	int ret;
+	ret = kstrtoint(param, 10, &ext_resolution);
+	return ret;
+}
+early_param("ext_resolution", hdmi_resulution_setup);
+
 static void __init apq8064_reserve(void)
 {
-	apq8064_set_display_params(prim_panel_name, ext_panel_name);
+	apq8064_set_display_params(prim_panel_name, ext_panel_name,
+		ext_resolution);
 	msm_reserve();
 	if (apq8064_fmem_pdata.size) {
 #if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
diff --git a/arch/arm/mach-msm/board-8064.h b/arch/arm/mach-msm/board-8064.h
index a241ab3..2258b8d 100644
--- a/arch/arm/mach-msm/board-8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -87,7 +87,8 @@
 void apq8064_init_fb(void);
 void apq8064_allocate_fb_region(void);
 void apq8064_mdp_writeback(struct memtype_reserve *reserve_table);
-void __init apq8064_set_display_params(char *prim_panel, char *ext_panel);
+void __init apq8064_set_display_params(char *prim_panel, char *ext_panel,
+		unsigned char resolution);
 
 void apq8064_init_gpu(void);
 void apq8064_pm8xxx_gpio_mpp_init(void);
diff --git a/arch/arm/mach-msm/board-8930-camera.c b/arch/arm/mach-msm/board-8930-camera.c
index 6ee315c..d3e37cd 100644
--- a/arch/arm/mach-msm/board-8930-camera.c
+++ b/arch/arm/mach-msm/board-8930-camera.c
@@ -251,7 +251,7 @@
 	{
 		.src = MSM_BUS_MASTER_VFE,
 		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 140451840,
+		.ab  = 274406400,
 		.ib  = 561807360,
 	},
 	{
@@ -310,6 +310,27 @@
 	},
 };
 
+static struct msm_bus_vectors cam_video_ls_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 348192000,
+		.ib  = 617103360,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 206807040,
+		.ib  = 488816640,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 540000000,
+		.ib  = 1350000000,
+	},
+};
+
 static struct msm_bus_paths cam_bus_client_config[] = {
 	{
 		ARRAY_SIZE(cam_init_vectors),
@@ -331,6 +352,10 @@
 		ARRAY_SIZE(cam_zsl_vectors),
 		cam_zsl_vectors,
 	},
+	{
+		ARRAY_SIZE(cam_video_ls_vectors),
+		cam_video_ls_vectors,
+	},
 };
 
 static struct msm_bus_scale_pdata cam_bus_client_pdata = {
diff --git a/arch/arm/mach-msm/board-8930-regulator.c b/arch/arm/mach-msm/board-8930-regulator.c
index f06a1b7..af91089 100644
--- a/arch/arm/mach-msm/board-8930-regulator.c
+++ b/arch/arm/mach-msm/board-8930-regulator.c
@@ -172,11 +172,13 @@
 };
 VREG_CONSUMERS(S5) = {
 	REGULATOR_SUPPLY("8038_s5",		NULL),
-	REGULATOR_SUPPLY("krait0",		NULL),
+	REGULATOR_SUPPLY("krait0",		"acpuclk-8627"),
+	REGULATOR_SUPPLY("krait0",		"acpuclk-8930"),
 };
 VREG_CONSUMERS(S6) = {
 	REGULATOR_SUPPLY("8038_s6",		NULL),
-	REGULATOR_SUPPLY("krait1",		NULL),
+	REGULATOR_SUPPLY("krait1",		"acpuclk-8627"),
+	REGULATOR_SUPPLY("krait1",		"acpuclk-8930"),
 };
 VREG_CONSUMERS(LVS1) = {
 	REGULATOR_SUPPLY("8038_lvs1",		NULL),
@@ -511,10 +513,39 @@
 int msm8930_pm8038_regulator_pdata_len __devinitdata =
 	ARRAY_SIZE(msm8930_pm8038_regulator_pdata);
 
+#define RPM_REG_MAP(_id, _sleep_also, _voter, _supply, _dev_name) \
+	{ \
+		.vreg_id = RPM_VREG_ID_PM8038_##_id, \
+		.sleep_also = _sleep_also, \
+		.voter = _voter, \
+		.supply = _supply, \
+		.dev_name = _dev_name, \
+	}
+static struct rpm_regulator_consumer_mapping
+	      msm_rpm_regulator_consumer_mapping[] __devinitdata = {
+	RPM_REG_MAP(L23,            0, 1, "krait0_hfpll", "acpuclk-8930"),
+	RPM_REG_MAP(L23,            0, 2, "krait1_hfpll", "acpuclk-8930"),
+	RPM_REG_MAP(L23,            0, 6, "l2_hfpll",     "acpuclk-8930"),
+	RPM_REG_MAP(L24,            0, 1, "krait0_mem",   "acpuclk-8930"),
+	RPM_REG_MAP(L24,            0, 2, "krait1_mem",   "acpuclk-8930"),
+	RPM_REG_MAP(VDD_DIG_CORNER, 0, 1, "krait0_dig",   "acpuclk-8930"),
+	RPM_REG_MAP(VDD_DIG_CORNER, 0, 2, "krait1_dig",   "acpuclk-8930"),
+
+	RPM_REG_MAP(L23,            0, 1, "krait0_hfpll", "acpuclk-8627"),
+	RPM_REG_MAP(L23,            0, 2, "krait1_hfpll", "acpuclk-8627"),
+	RPM_REG_MAP(L23,            0, 6, "l2_hfpll",     "acpuclk-8627"),
+	RPM_REG_MAP(L24,            0, 1, "krait0_mem",   "acpuclk-8627"),
+	RPM_REG_MAP(L24,            0, 2, "krait1_mem",   "acpuclk-8627"),
+	RPM_REG_MAP(VDD_DIG_CORNER, 0, 1, "krait0_dig",   "acpuclk-8627"),
+	RPM_REG_MAP(VDD_DIG_CORNER, 0, 2, "krait1_dig",   "acpuclk-8627"),
+};
+
 struct rpm_regulator_platform_data msm8930_rpm_regulator_pdata __devinitdata = {
 	.init_data		= msm8930_rpm_regulator_init_data,
 	.num_regulators		= ARRAY_SIZE(msm8930_rpm_regulator_init_data),
 	.version		= RPM_VREG_VERSION_8930,
 	.vreg_id_vdd_mem	= RPM_VREG_ID_PM8038_L24,
 	.vreg_id_vdd_dig	= RPM_VREG_ID_PM8038_VDD_DIG_CORNER,
+	.consumer_map		= msm_rpm_regulator_consumer_mapping,
+	.consumer_map_len = ARRAY_SIZE(msm_rpm_regulator_consumer_mapping),
 };
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 5a803e6..88c0924 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -2162,7 +2162,6 @@
 };
 
 static struct platform_device *common_devices[] __initdata = {
-	&msm8960_device_acpuclk,
 	&msm8960_device_dmov,
 	&msm_device_smd,
 	&msm8960_device_uart_gsbi5,
@@ -2576,6 +2575,10 @@
 	msm_spm_l2_init(msm_spm_l2_data);
 	msm8930_init_buses();
 	platform_add_devices(msm8930_footswitch, msm8930_num_footswitch);
+	if (cpu_is_msm8627())
+		platform_device_register(&msm8627_device_acpuclk);
+	else if (cpu_is_msm8930() || cpu_is_msm8930aa())
+		platform_device_register(&msm8930_device_acpuclk);
 	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
 	msm8930_add_vidc_device();
 	/*
diff --git a/arch/arm/mach-msm/board-8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
index b6c03a4..a21c4c3 100644
--- a/arch/arm/mach-msm/board-8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -272,7 +272,7 @@
 	{
 		.src = MSM_BUS_MASTER_VFE,
 		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 154275840,
+		.ab  = 274406400,
 		.ib  = 617103360,
 	},
 	{
@@ -367,6 +367,40 @@
 	},
 };
 
+static struct msm_bus_vectors cam_video_ls_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 348192000,
+		.ib  = 617103360,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 206807040,
+		.ib  = 488816640,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 540000000,
+		.ib  = 1350000000,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_MM_IMEM,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_MM_IMEM,
+		.ab  = 0,
+		.ib  = 0,
+	},
+};
+
+
 static struct msm_bus_paths cam_bus_client_config[] = {
 	{
 		ARRAY_SIZE(cam_init_vectors),
@@ -388,6 +422,10 @@
 		ARRAY_SIZE(cam_zsl_vectors),
 		cam_zsl_vectors,
 	},
+	{
+		ARRAY_SIZE(cam_video_ls_vectors),
+		cam_video_ls_vectors,
+	},
 };
 
 static struct msm_bus_scale_pdata cam_bus_client_pdata = {
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 7db4bda..ba4e098 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -48,7 +48,6 @@
 #include <mach/msm_battery.h>
 #include <linux/smsc911x.h>
 #include <linux/atmel_maxtouch.h>
-#include <linux/fmem.h>
 #include <linux/msm_adc.h>
 #include <linux/ion.h>
 #include "devices.h"
@@ -448,9 +447,6 @@
 	.allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
 	.cached = 1,
 	.memory_type = MEMTYPE_EBI1,
-	.request_region = request_fmem_c_region,
-	.release_region = release_fmem_c_region,
-	.reusable = 1,
 };
 
 static struct platform_device android_pmem_adsp_device = {
@@ -778,14 +774,6 @@
 static void msm7x27a_cfg_uart2dm_serial(void) { }
 #endif
 
-static struct fmem_platform_data fmem_pdata;
-
-static struct platform_device fmem_device = {
-	.name = "fmem",
-	.id = 1,
-	.dev = { .platform_data = &fmem_pdata },
-};
-
 static struct platform_device *rumi_sim_devices[] __initdata = {
 	&msm_device_dmov,
 	&msm_device_smd,
@@ -823,7 +811,6 @@
 	&android_pmem_device,
 	&android_pmem_adsp_device,
 	&android_pmem_audio_device,
-	&fmem_device,
 	&msm_device_nand,
 	&msm_device_snd,
 	&msm_device_adspdec,
@@ -966,32 +953,10 @@
 {
 #ifdef CONFIG_ANDROID_PMEM
 #ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
-	unsigned int i;
-	unsigned int reusable_count = 0;
-
 	android_pmem_adsp_pdata.size = pmem_adsp_size;
 	android_pmem_pdata.size = pmem_mdp_size;
 	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.
-	 */
-	for (i = 0; i < ARRAY_SIZE(pmem_pdata_array); ++i) {
-		struct android_pmem_platform_data *pdata = pmem_pdata_array[i];
-
-		if (!reusable_count && pdata->reusable)
-			fmem_pdata.size += pdata->size;
-
-		reusable_count += (pdata->reusable) ? 1 : 0;
-
-		if (pdata->reusable && reusable_count > 1) {
-			pr_err("%s: Too many PMEM devices specified as reusable. PMEM device %s was not configured as reusable.\n",
-				__func__, pdata->name);
-			pdata->reusable = 0;
-		}
-	}
 #endif
 #endif
 }
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index bd73b70..a694557 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -31,7 +31,6 @@
 #include <linux/memblock.h>
 #include <linux/input/ft5x06_ts.h>
 #include <linux/msm_adc.h>
-#include <linux/fmem.h>
 #include <linux/regulator/msm-gpio-regulator.h>
 #include <linux/ion.h>
 #include <asm/mach/mmc.h>
@@ -394,9 +393,6 @@
 	.allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
 	.cached = 1,
 	.memory_type = MEMTYPE_EBI1,
-	.request_region = request_fmem_c_region,
-	.release_region = release_fmem_c_region,
-	.reusable = 1,
 };
 
 static struct platform_device android_pmem_adsp_device = {
@@ -639,14 +635,6 @@
 	},
 };
 
-static struct fmem_platform_data fmem_pdata;
-
-static struct platform_device fmem_device = {
-	.name = "fmem",
-	.id = 1,
-	.dev = { .platform_data = &fmem_pdata },
-};
-
 #define GPIO_VREG_INIT(_id, _reg_name, _gpio_label, _gpio, _active_low) \
 	[GPIO_VREG_ID_##_id] = { \
 		.init_data = { \
@@ -717,7 +705,6 @@
 	&asoc_msm_dai0,
 	&asoc_msm_dai1,
 	&msm_adc_device,
-	&fmem_device,
 #ifdef CONFIG_ION_MSM
 	&ion_dev,
 #endif
@@ -858,32 +845,9 @@
 {
 #ifdef CONFIG_ANDROID_PMEM
 #ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
-	unsigned int i;
-	unsigned int reusable_count = 0;
-
 	android_pmem_adsp_pdata.size = pmem_adsp_size;
 	android_pmem_pdata.size = pmem_mdp_size;
 	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.
-	 */
-	for (i = 0; i < ARRAY_SIZE(pmem_pdata_array); ++i) {
-		struct android_pmem_platform_data *pdata = pmem_pdata_array[i];
-
-		if (!reusable_count && pdata->reusable)
-			fmem_pdata.size += pdata->size;
-
-		reusable_count += (pdata->reusable) ? 1 : 0;
-
-		if (pdata->reusable && reusable_count > 1) {
-			pr_err("%s: Too many PMEM devices specified as reusable. PMEM device %s was not configured as reusable.\n",
-				__func__, pdata->name);
-			pdata->reusable = 0;
-		}
-	}
 #endif
 #endif
 }
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index d31e629..e87dd14 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -194,6 +194,7 @@
 #define DSI2_ESC_CC_REG				REG_MM(0x013C)
 #define DSI_PIXEL_CC_REG			REG_MM(0x0130)
 #define DSI2_PIXEL_CC_REG			REG_MM(0x0094)
+#define DSI2_PIXEL_CC2_REG			REG_MM(0x0264)
 #define DBG_BUS_VEC_A_REG			REG_MM(0x01C8)
 #define DBG_BUS_VEC_B_REG			REG_MM(0x01CC)
 #define DBG_BUS_VEC_C_REG			REG_MM(0x01D0)
@@ -785,7 +786,7 @@
 };
 
 /* gfx3d_axi_clk is set as a dependency of gmem_axi_clk at runtime */
-static struct branch_clk gfx3d_axi_clk_8064 = {
+static struct branch_clk gfx3d_axi_clk = {
 	.b = {
 		.ctl_reg = MAXI_EN5_REG,
 		.en_mask = BIT(25),
@@ -799,7 +800,7 @@
 	.c = {
 		.dbg_name = "gfx3d_axi_clk",
 		.ops = &clk_ops_branch,
-		CLK_INIT(gfx3d_axi_clk_8064.c),
+		CLK_INIT(gfx3d_axi_clk.c),
 	},
 };
 
@@ -2688,6 +2689,7 @@
 		.ops = &clk_ops_rcg,
 		VDD_DIG_FMAX_MAP2(LOW, 86000000, NOMINAL, 178000000),
 		CLK_INIT(csi0_src_clk.c),
+		.warned = true,
 	},
 };
 
@@ -2705,6 +2707,7 @@
 		.dbg_name = "csi0_clk",
 		.ops = &clk_ops_branch,
 		CLK_INIT(csi0_clk.c),
+		.warned = true,
 	},
 };
 
@@ -2744,6 +2747,7 @@
 		.ops = &clk_ops_rcg,
 		VDD_DIG_FMAX_MAP2(LOW, 86000000, NOMINAL, 178000000),
 		CLK_INIT(csi1_src_clk.c),
+		.warned = true,
 	},
 };
 
@@ -2761,6 +2765,7 @@
 		.dbg_name = "csi1_clk",
 		.ops = &clk_ops_branch,
 		CLK_INIT(csi1_clk.c),
+		.warned = true,
 	},
 };
 
@@ -2800,6 +2805,7 @@
 		.ops = &clk_ops_rcg,
 		VDD_DIG_FMAX_MAP2(LOW, 86000000, NOMINAL, 178000000),
 		CLK_INIT(csi2_src_clk.c),
+		.warned = true,
 	},
 };
 
@@ -2817,6 +2823,7 @@
 		.dbg_name = "csi2_clk",
 		.ops = &clk_ops_branch,
 		CLK_INIT(csi2_clk.c),
+		.warned = true,
 	},
 };
 
@@ -3406,6 +3413,27 @@
 		.ctl_val = CC_BANKED(9, 6, n), \
 	}
 
+static struct clk_freq_tbl clk_tbl_gfx3d_8960ab[] = {
+	F_GFX3D(        0, gnd,  0,  0),
+	F_GFX3D( 27000000, pxo,  0,  0),
+	F_GFX3D( 48000000, pll8, 1,  8),
+	F_GFX3D( 54857000, pll8, 1,  7),
+	F_GFX3D( 64000000, pll8, 1,  6),
+	F_GFX3D( 76800000, pll8, 1,  5),
+	F_GFX3D( 96000000, pll8, 1,  4),
+	F_GFX3D(128000000, pll8, 1,  3),
+	F_GFX3D(145455000, pll2, 2, 11),
+	F_GFX3D(160000000, pll2, 1,  5),
+	F_GFX3D(177778000, pll2, 2,  9),
+	F_GFX3D(200000000, pll2, 1,  4),
+	F_GFX3D(228571000, pll2, 2,  7),
+	F_GFX3D(266667000, pll2, 1,  3),
+	F_GFX3D(320000000, pll2, 2,  5),
+	F_GFX3D(325000000, pll3, 1,  2),
+	F_GFX3D(400000000, pll2, 1,  2),
+	F_END
+};
+
 static struct clk_freq_tbl clk_tbl_gfx3d_8960[] = {
 	F_GFX3D(        0, gnd,  0,  0),
 	F_GFX3D( 27000000, pxo,  0,  0),
@@ -3713,6 +3741,27 @@
 		.ns_val = NS_MND_BANKED8(22, 14, n, m, 3, 0, s##_to_mm_mux), \
 		.ctl_val = CC_BANKED(9, 6, n), \
 	}
+static struct clk_freq_tbl clk_tbl_mdp_8960ab[] = {
+	F_MDP(        0, gnd,  0,  0),
+	F_MDP(  9600000, pll8, 1, 40),
+	F_MDP( 13710000, pll8, 1, 28),
+	F_MDP( 27000000, pxo,  0,  0),
+	F_MDP( 29540000, pll8, 1, 13),
+	F_MDP( 34910000, pll8, 1, 11),
+	F_MDP( 38400000, pll8, 1, 10),
+	F_MDP( 59080000, pll8, 2, 13),
+	F_MDP( 76800000, pll8, 1,  5),
+	F_MDP( 85330000, pll8, 2,  9),
+	F_MDP( 96000000, pll8, 1,  4),
+	F_MDP(128000000, pll8, 1,  3),
+	F_MDP(160000000, pll2, 1,  5),
+	F_MDP(177780000, pll2, 2,  9),
+	F_MDP(200000000, pll2, 1,  4),
+	F_MDP(228571000, pll2, 2,  7),
+	F_MDP(266667000, pll2, 1,  3),
+	F_END
+};
+
 static struct clk_freq_tbl clk_tbl_mdp[] = {
 	F_MDP(        0, gnd,  0,  0),
 	F_MDP(  9600000, pll8, 1, 40),
@@ -4336,7 +4385,23 @@
 		.md_val = MD8(8, m, 0, n), \
 		.ns_val = NS(31, 24, n, m, 5, 4, 3, d, 2, 0, s##_to_lpa_mux), \
 	}
-static struct clk_freq_tbl clk_tbl_aif_osr[] = {
+static struct clk_freq_tbl clk_tbl_aif_osr_492[] = {
+	F_AIF_OSR(       0, gnd,  1, 0,   0),
+	F_AIF_OSR(  512000, pll4, 4, 1, 240),
+	F_AIF_OSR(  768000, pll4, 4, 1, 160),
+	F_AIF_OSR( 1024000, pll4, 4, 1, 120),
+	F_AIF_OSR( 1536000, pll4, 4, 1,  80),
+	F_AIF_OSR( 2048000, pll4, 4, 1,  60),
+	F_AIF_OSR( 3072000, pll4, 4, 1,  40),
+	F_AIF_OSR( 4096000, pll4, 4, 1,  30),
+	F_AIF_OSR( 6144000, pll4, 4, 1,  20),
+	F_AIF_OSR( 8192000, pll4, 4, 1,  15),
+	F_AIF_OSR(12288000, pll4, 4, 1,  10),
+	F_AIF_OSR(24576000, pll4, 4, 1,   5),
+	F_END
+};
+
+static struct clk_freq_tbl clk_tbl_aif_osr_393[] = {
 	F_AIF_OSR(       0, gnd,  1, 0,   0),
 	F_AIF_OSR(  512000, pll4, 4, 1, 192),
 	F_AIF_OSR(  768000, pll4, 4, 1, 128),
@@ -4369,7 +4434,7 @@
 		.ns_mask = (BM(31, 24) | BM(6, 0)), \
 		.mnd_en_mask = BIT(8), \
 		.set_rate = set_rate_mnd, \
-		.freq_tbl = clk_tbl_aif_osr, \
+		.freq_tbl = clk_tbl_aif_osr_393, \
 		.current_freq = &rcg_dummy_freq, \
 		.c = { \
 			.dbg_name = #i "_clk", \
@@ -4395,7 +4460,7 @@
 		.ns_mask = (BM(31, 24) | BM(6, 0)), \
 		.mnd_en_mask = BIT(8), \
 		.set_rate = set_rate_mnd, \
-		.freq_tbl = clk_tbl_aif_osr, \
+		.freq_tbl = clk_tbl_aif_osr_393, \
 		.current_freq = &rcg_dummy_freq, \
 		.c = { \
 			.dbg_name = #i "_clk", \
@@ -4476,7 +4541,23 @@
 		.md_val = MD16(m, n), \
 		.ns_val = NS(31, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_lpa_mux), \
 	}
-static struct clk_freq_tbl clk_tbl_pcm[] = {
+static struct clk_freq_tbl clk_tbl_pcm_492[] = {
+	{ .ns_val = BIT(10) /* external input */ },
+	F_PCM(  512000, pll4, 4, 1, 240),
+	F_PCM(  768000, pll4, 4, 1, 160),
+	F_PCM( 1024000, pll4, 4, 1, 120),
+	F_PCM( 1536000, pll4, 4, 1,  80),
+	F_PCM( 2048000, pll4, 4, 1,  60),
+	F_PCM( 3072000, pll4, 4, 1,  40),
+	F_PCM( 4096000, pll4, 4, 1,  30),
+	F_PCM( 6144000, pll4, 4, 1,  20),
+	F_PCM( 8192000, pll4, 4, 1,  15),
+	F_PCM(12288000, pll4, 4, 1,  10),
+	F_PCM(24576000, pll4, 4, 1,   5),
+	F_END
+};
+
+static struct clk_freq_tbl clk_tbl_pcm_393[] = {
 	{ .ns_val = BIT(10) /* external input */ },
 	F_PCM(  512000, pll4, 4, 1, 192),
 	F_PCM(  768000, pll4, 4, 1, 128),
@@ -4508,7 +4589,7 @@
 	.ns_mask = BM(31, 16) | BIT(10) | BM(6, 0),
 	.mnd_en_mask = BIT(8),
 	.set_rate = set_rate_mnd,
-	.freq_tbl = clk_tbl_pcm,
+	.freq_tbl = clk_tbl_pcm_393,
 	.current_freq = &rcg_dummy_freq,
 	.c = {
 		.dbg_name = "pcm_clk",
@@ -4535,7 +4616,7 @@
 	.ns_mask = (BM(31, 24) | BM(6, 0)),
 	.mnd_en_mask = BIT(8),
 	.set_rate = set_rate_mnd,
-	.freq_tbl = clk_tbl_aif_osr,
+	.freq_tbl = clk_tbl_aif_osr_393,
 	.current_freq = &rcg_dummy_freq,
 	.c = {
 		.dbg_name = "audio_slimbus_clk",
@@ -4821,7 +4902,7 @@
 	{ TEST_MM_HS(0x35), &vcap_axi_clk.c },
 	{ TEST_MM_HS(0x36), &rgb_tv_clk.c },
 	{ TEST_MM_HS(0x37), &npl_tv_clk.c },
-	{ TEST_MM_HS(0x38), &gfx3d_axi_clk_8064.c },
+	{ TEST_MM_HS(0x38), &gfx3d_axi_clk.c },
 
 	{ TEST_LPA(0x0F), &mi2s_bit_clk.c },
 	{ TEST_LPA(0x10), &codec_i2s_mic_bit_clk.c },
@@ -5199,7 +5280,7 @@
 	CLK_LOOKUP("core_clk",		gfx3d_clk.c,	"kgsl-3d0.0"),
 	CLK_LOOKUP("core_clk",		gfx3d_clk.c,	"footswitch-8x60.2"),
 	CLK_LOOKUP("bus_clk",
-			    gfx3d_axi_clk_8064.c, "footswitch-8x60.2"),
+			    gfx3d_axi_clk.c, "footswitch-8x60.2"),
 	CLK_LOOKUP("iface_clk",         vcap_p_clk.c,           ""),
 	CLK_LOOKUP("iface_clk",         vcap_p_clk.c,           "msm_vcap.0"),
 	CLK_LOOKUP("iface_clk",         vcap_p_clk.c,	"footswitch-8x60.10"),
@@ -5305,7 +5386,7 @@
 	CLK_LOOKUP("core_clk",		vfe_axi_clk.c,		""),
 	CLK_LOOKUP("core_clk",		vcodec_axi_a_clk.c,	""),
 	CLK_LOOKUP("core_clk",		vcodec_axi_b_clk.c,	""),
-	CLK_LOOKUP("core_clk",		gfx3d_axi_clk_8064.c,	""),
+	CLK_LOOKUP("core_clk",		gfx3d_axi_clk.c,	""),
 
 	CLK_LOOKUP("dfab_dsps_clk",	dfab_dsps_clk.c, NULL),
 	CLK_LOOKUP("core_clk",		dfab_usb_hs_clk.c,	"msm_otg"),
@@ -5335,8 +5416,9 @@
 	CLK_LOOKUP("core_clk",		vfe_axi_clk.c,		"msm_iommu.6"),
 	CLK_LOOKUP("core_clk",		vcodec_axi_a_clk.c,	"msm_iommu.7"),
 	CLK_LOOKUP("core_clk",		vcodec_axi_b_clk.c,	"msm_iommu.8"),
-	CLK_LOOKUP("core_clk",		gfx3d_axi_clk_8064.c,	"msm_iommu.9"),
-	CLK_LOOKUP("core_clk",		gfx3d_axi_clk_8064.c,	"msm_iommu.10"),
+	CLK_LOOKUP("core_clk",		gfx3d_axi_clk.c,	"msm_iommu.9"),
+	CLK_LOOKUP("core_clk",		gfx3d_axi_clk.c,	"msm_iommu.10"),
+
 	CLK_LOOKUP("core_clk",		vcap_axi_clk.c,		"msm_iommu.11"),
 
 	CLK_LOOKUP("mdp_iommu_clk", mdp_axi_clk.c,	"msm_vidc.0"),
@@ -5358,7 +5440,7 @@
 	CLK_LOOKUP("krait3_mclk",	krait3_m_clk, ""),
 };
 
-static struct clk_lookup msm_clocks_8960[] = {
+static struct clk_lookup msm_clocks_8960_common[] __initdata = {
 	CLK_LOOKUP("xo",		cxo_a_clk.c,	""),
 	CLK_LOOKUP("xo",		pxo_a_clk.c,	""),
 	CLK_LOOKUP("cxo",		cxo_clk.c,	"wcnss_wlan.0"),
@@ -5537,10 +5619,6 @@
 	CLK_LOOKUP("byte_clk",	dsi2_byte_clk.c,	"mipi_dsi.2"),
 	CLK_LOOKUP("esc_clk",	dsi1_esc_clk.c,		"mipi_dsi.1"),
 	CLK_LOOKUP("esc_clk",	dsi2_esc_clk.c,		"mipi_dsi.2"),
-	CLK_LOOKUP("core_clk",		gfx2d0_clk.c,	"kgsl-2d0.0"),
-	CLK_LOOKUP("core_clk",		gfx2d0_clk.c,	"footswitch-8x60.0"),
-	CLK_LOOKUP("core_clk",		gfx2d1_clk.c,	"kgsl-2d1.1"),
-	CLK_LOOKUP("core_clk",		gfx2d1_clk.c,	"footswitch-8x60.1"),
 	CLK_LOOKUP("core_clk",		gfx3d_clk.c,	"kgsl-3d0.0"),
 	CLK_LOOKUP("core_clk",		gfx3d_clk.c,	"footswitch-8x60.2"),
 	CLK_LOOKUP("bus_clk",		ijpeg_axi_clk.c, "footswitch-8x60.3"),
@@ -5560,8 +5638,6 @@
 	CLK_LOOKUP("src_clk",	tv_src_clk.c,		"dtv.0"),
 	CLK_LOOKUP("src_clk",	tv_src_clk.c,		"tvenc.0"),
 	CLK_LOOKUP("tv_src_clk",	tv_src_clk.c,	"footswitch-8x60.4"),
-	CLK_LOOKUP("enc_clk",	tv_enc_clk.c,		"tvenc.0"),
-	CLK_LOOKUP("dac_clk",	tv_dac_clk.c,		"tvenc.0"),
 	CLK_LOOKUP("core_clk",		vcodec_clk.c,	"msm_vidc.0"),
 	CLK_LOOKUP("core_clk",		vcodec_clk.c,	"footswitch-8x60.7"),
 	CLK_LOOKUP("mdp_clk",	mdp_tv_clk.c,		"dtv.0"),
@@ -5590,10 +5666,6 @@
 	CLK_LOOKUP("slave_iface_clk",	dsi1_s_p_clk.c,		"mipi_dsi.1"),
 	CLK_LOOKUP("master_iface_clk",	dsi2_m_p_clk.c,		"mipi_dsi.2"),
 	CLK_LOOKUP("slave_iface_clk",	dsi2_s_p_clk.c,		"mipi_dsi.2"),
-	CLK_LOOKUP("iface_clk",		gfx2d0_p_clk.c,	"kgsl-2d0.0"),
-	CLK_LOOKUP("iface_clk",		gfx2d0_p_clk.c,	"footswitch-8x60.0"),
-	CLK_LOOKUP("iface_clk",		gfx2d1_p_clk.c,	"kgsl-2d1.1"),
-	CLK_LOOKUP("iface_clk",		gfx2d1_p_clk.c,	"footswitch-8x60.1"),
 	CLK_LOOKUP("iface_clk",		gfx3d_p_clk.c,	"kgsl-3d0.0"),
 	CLK_LOOKUP("iface_clk",		gfx3d_p_clk.c,	"footswitch-8x60.2"),
 	CLK_LOOKUP("master_iface_clk",	hdmi_m_p_clk.c,	"hdmi_msm.1"),
@@ -5607,7 +5679,6 @@
 	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu"),
 	CLK_LOOKUP("iface_clk",		rot_p_clk.c,	"msm_rotator.0"),
 	CLK_LOOKUP("iface_clk",		rot_p_clk.c,	"footswitch-8x60.6"),
-	CLK_LOOKUP("iface_clk",	tv_enc_p_clk.c,		"tvenc.0"),
 	CLK_LOOKUP("iface_clk",		vcodec_p_clk.c,	"msm_vidc.0"),
 	CLK_LOOKUP("iface_clk",		vcodec_p_clk.c,	"footswitch-8x60.7"),
 	CLK_LOOKUP("vfe_pclk",		vfe_p_clk.c,		"msm_vfe.0"),
@@ -5648,8 +5719,6 @@
 	CLK_LOOKUP("core_clk",		vcodec_axi_a_clk.c,	"msm_iommu.7"),
 	CLK_LOOKUP("core_clk",		vcodec_axi_b_clk.c,	"msm_iommu.8"),
 	CLK_LOOKUP("core_clk",		gfx3d_clk.c,		"msm_iommu.9"),
-	CLK_LOOKUP("core_clk",		gfx2d0_clk.c,		"msm_iommu.10"),
-	CLK_LOOKUP("core_clk",		gfx2d1_clk.c,		"msm_iommu.11"),
 
 	CLK_LOOKUP("mdp_iommu_clk", mdp_axi_clk.c,	"msm_vidc.0"),
 	CLK_LOOKUP("rot_iommu_clk",	rot_axi_clk.c,	"msm_vidc.0"),
@@ -5683,6 +5752,32 @@
 	CLK_LOOKUP("q6_func_clk",	q6_func_clk,  ""),
 };
 
+static struct clk_lookup msm_clocks_8960_only[] __initdata = {
+	CLK_LOOKUP("enc_clk",	tv_enc_clk.c,		"tvenc.0"),
+	CLK_LOOKUP("dac_clk",	tv_dac_clk.c,		"tvenc.0"),
+	CLK_LOOKUP("iface_clk",	tv_enc_p_clk.c,		"tvenc.0"),
+
+	CLK_LOOKUP("core_clk",		gfx2d0_clk.c,	"kgsl-2d0.0"),
+	CLK_LOOKUP("core_clk",		gfx2d0_clk.c,	"footswitch-8x60.0"),
+	CLK_LOOKUP("core_clk",		gfx2d1_clk.c,	"kgsl-2d1.1"),
+	CLK_LOOKUP("core_clk",		gfx2d1_clk.c,	"footswitch-8x60.1"),
+	CLK_LOOKUP("iface_clk",		gfx2d0_p_clk.c,	"kgsl-2d0.0"),
+	CLK_LOOKUP("iface_clk",		gfx2d0_p_clk.c,	"footswitch-8x60.0"),
+	CLK_LOOKUP("iface_clk",		gfx2d1_p_clk.c,	"kgsl-2d1.1"),
+	CLK_LOOKUP("iface_clk",		gfx2d1_p_clk.c,	"footswitch-8x60.1"),
+	CLK_LOOKUP("core_clk",		gfx2d0_clk.c,		"msm_iommu.10"),
+	CLK_LOOKUP("core_clk",		gfx2d1_clk.c,		"msm_iommu.11"),
+};
+
+static struct clk_lookup msm_clocks_8960ab_only[] __initdata = {
+	CLK_LOOKUP("bus_clk", gfx3d_axi_clk.c, "footswitch-8x60.2"),
+	CLK_LOOKUP("div_clk",	tv_src_div_clk.c,	""),
+};
+
+static struct clk_lookup msm_clocks_8960[ARRAY_SIZE(msm_clocks_8960_common)
+	+ ARRAY_SIZE(msm_clocks_8960_only)
+	+ ARRAY_SIZE(msm_clocks_8960ab_only)];
+
 static struct clk_lookup msm_clocks_8930[] = {
 	CLK_LOOKUP("xo",		cxo_clk.c,	"msm_xo"),
 	CLK_LOOKUP("cxo",		cxo_clk.c,	"wcnss_wlan.0"),
@@ -6002,7 +6097,7 @@
 	.mode_reg = LCC_PLL0_MODE_REG,
 };
 
-static struct pll_config pll4_config __initdata = {
+static struct pll_config pll4_config_393 __initdata = {
 	.l = 0xE,
 	.m = 0x27A,
 	.n = 0x465,
@@ -6080,12 +6175,12 @@
 	 */
 	/*
 	 * Initialize MM AHB registers: Enable the FPB clock and disable HW
-	 * gating on 8627 for all clocks. Also set VFE_AHB's
+	 * gating on 8627 and 8960 for all clocks. Also set VFE_AHB's
 	 * FORCE_CORE_ON bit to prevent its memory from being collapsed when
 	 * the clock is halted. The sleep and wake-up delays are set to safe
 	 * values.
 	 */
-	if (cpu_is_msm8627()) {
+	if (cpu_is_msm8627() || cpu_is_msm8960ab()) {
 		rmwreg(0x00000003, AHB_EN_REG,  0x6C000103);
 		writel_relaxed(0x000007F9, AHB_EN2_REG);
 	} else {
@@ -6103,7 +6198,7 @@
 	/* Initialize MM AXI registers: Enable HW gating for all clocks that
 	 * support it. Also set FORCE_CORE_ON bits, and any sleep and wake-up
 	 * delays to safe values. */
-	if ((cpu_is_msm8960() &&
+	if (cpu_is_msm8960ab() || (cpu_is_msm8960() &&
 			SOCINFO_VERSION_MAJOR(socinfo_get_version()) < 3) ||
 			cpu_is_msm8627()) {
 		rmwreg(0x000007F9, MAXI_EN_REG,  0x0803FFFF);
@@ -6120,8 +6215,13 @@
 		rmwreg(0x019FECFF, MAXI_EN5_REG, 0x01FFEFFF);
 	if (cpu_is_msm8930() || cpu_is_msm8930aa() || cpu_is_msm8627())
 		rmwreg(0x000004FF, MAXI_EN5_REG, 0x00000FFF);
+	if (cpu_is_msm8960ab())
+		rmwreg(0x009FE000, MAXI_EN5_REG, 0x01FFE000);
+
 	if (cpu_is_msm8627())
 		rmwreg(0x000003C7, SAXI_EN_REG,  0x00003FFF);
+	else if (cpu_is_msm8960ab())
+		rmwreg(0x000001C6, SAXI_EN_REG,  0x00001DF6);
 	else
 		rmwreg(0x00003C38, SAXI_EN_REG,  0x00003FFF);
 
@@ -6149,14 +6249,19 @@
 	rmwreg(0x80FF0000, VFE_CC_REG,        0xE0FF4010);
 	rmwreg(0x800000FF, VFE_CC2_REG,       0xE00000FF);
 	rmwreg(0x80FF0000, VPE_CC_REG,        0xE0FF0010);
-	if (cpu_is_msm8960() || cpu_is_apq8064()) {
+	if (cpu_is_msm8960ab() || cpu_is_msm8960() || cpu_is_apq8064()) {
 		rmwreg(0x80FF0000, DSI2_BYTE_CC_REG,  0xE0FF0010);
 		rmwreg(0x80FF0000, DSI2_PIXEL_CC_REG, 0xE0FF0010);
 		rmwreg(0x80FF0000, JPEGD_CC_REG,      0xE0FF0010);
 	}
+	if (cpu_is_msm8960ab())
+		rmwreg(0x00000001, DSI2_PIXEL_CC2_REG, 0x00000001);
+
 	if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm8930aa() ||
 	    cpu_is_msm8627())
-		rmwreg(0x80FF0000, TV_CC_REG,         0xE1FFC010);
+		rmwreg(0x80FF0000, TV_CC_REG,        0xE1FFC010);
+	if (cpu_is_msm8960ab())
+		rmwreg(0x00000000, TV_CC_REG,        0x00004010);
 
 	if (cpu_is_msm8960()) {
 		rmwreg(0x80FF0000, GFX2D0_CC_REG,     0xE0FF0010);
@@ -6190,12 +6295,12 @@
 	writel_relaxed(BIT(15), PDM_CLK_NS_REG);
 
 	/* Source SLIMBus xo src from slimbus reference clock */
-	if (cpu_is_msm8960())
+	if (cpu_is_msm8960ab() || cpu_is_msm8960())
 		writel_relaxed(0x3, SLIMBUS_XO_SRC_CLK_CTL_REG);
 
 	/* Source the dsi_byte_clks from the DSI PHY PLLs */
 	rmwreg(0x1, DSI1_BYTE_NS_REG, 0x7);
-	if (cpu_is_msm8960() || cpu_is_apq8064())
+	if (cpu_is_msm8960ab() || cpu_is_msm8960() || cpu_is_apq8064())
 		rmwreg(0x2, DSI2_BYTE_NS_REG, 0x7);
 
 	/* Source the dsi1_esc_clk from the DSI1 PHY PLLs */
@@ -6233,7 +6338,7 @@
 		is_pll_enabled = readl_relaxed(LCC_PLL0_STATUS_REG) & BIT(16);
 		if (!is_pll_enabled)
 			/* Ref clk = 27MHz and program pll4 to 393.2160MHz */
-			configure_pll(&pll4_config, &pll4_regs, 1);
+			configure_pll(&pll4_config_393, &pll4_regs, 1);
 
 		/* Enable PLL4 source on the LPASS Primary PLL Mux */
 		writel_relaxed(0x1, LCC_PRI_PLL_CLK_CTL_REG);
@@ -6257,8 +6362,12 @@
 	}
 }
 
+struct clock_init_data msm8960_clock_init_data __initdata;
 static void __init msm8960_clock_pre_init(void)
 {
+	/* Initialize clock registers. */
+	reg_init();
+
 	if (cpu_is_apq8064()) {
 		vdd_sr2_hdmi_pll.set_vdd = set_vdd_sr2_hdmi_pll_8064;
 	} else if (cpu_is_msm8930() || cpu_is_msm8930aa() || cpu_is_msm8627()) {
@@ -6266,6 +6375,41 @@
 		vdd_sr2_hdmi_pll.set_vdd = set_vdd_sr2_hdmi_pll_8930;
 	}
 
+	/* Detect PLL4 programmed for alternate 491.52MHz clock plan. */
+	if (readl_relaxed(LCC_PLL0_L_VAL_REG) == 0x12) {
+		pll4_clk.c.rate = 491520000;
+		audio_slimbus_clk.freq_tbl = clk_tbl_aif_osr_492;
+		mi2s_osr_clk.freq_tbl = clk_tbl_aif_osr_492;
+		codec_i2s_mic_osr_clk.freq_tbl = clk_tbl_aif_osr_492;
+		spare_i2s_mic_osr_clk.freq_tbl = clk_tbl_aif_osr_492;
+		codec_i2s_spkr_osr_clk.freq_tbl = clk_tbl_aif_osr_492;
+		spare_i2s_spkr_osr_clk.freq_tbl = clk_tbl_aif_osr_492;
+		pcm_clk.freq_tbl = clk_tbl_pcm_492;
+	}
+
+	if (cpu_is_msm8960() || cpu_is_msm8960ab())
+		memcpy(msm_clocks_8960, msm_clocks_8960_common,
+			sizeof(msm_clocks_8960_common));
+	if (cpu_is_msm8960ab()) {
+		pll3_clk.c.rate = 650000000;
+		gfx3d_clk.freq_tbl = clk_tbl_gfx3d_8960ab;
+		gfx3d_clk.c.fmax[VDD_DIG_LOW] = 192000000;
+		gfx3d_clk.c.fmax[VDD_DIG_NOMINAL] = 325000000;
+		gfx3d_clk.c.fmax[VDD_DIG_HIGH] = 400000000;
+		mdp_clk.freq_tbl = clk_tbl_mdp_8960ab;
+		mdp_clk.c.fmax[VDD_DIG_LOW] = 128000000;
+		mdp_clk.c.fmax[VDD_DIG_NOMINAL] = 266667000;
+
+		memcpy(msm_clocks_8960 + ARRAY_SIZE(msm_clocks_8960_common),
+			msm_clocks_8960ab_only, sizeof(msm_clocks_8960ab_only));
+		msm8960_clock_init_data.size -=
+			ARRAY_SIZE(msm_clocks_8960_only);
+	} else if (cpu_is_msm8960()) {
+		memcpy(msm_clocks_8960 + ARRAY_SIZE(msm_clocks_8960_common),
+			 msm_clocks_8960_only, sizeof(msm_clocks_8960_only));
+		msm8960_clock_init_data.size -=
+			ARRAY_SIZE(msm_clocks_8960ab_only);
+	}
 	/*
 	 * Change the freq tables for and voltage requirements for
 	 * clocks which differ between 8960 and 8064.
@@ -6284,7 +6428,7 @@
 		memcpy(vfe_clk.c.fmax, fmax_vfe_8064,
 		       sizeof(vfe_clk.c.fmax));
 
-		gmem_axi_clk.c.depends = &gfx3d_axi_clk_8064.c;
+		gmem_axi_clk.c.depends = &gfx3d_axi_clk.c;
 	}
 
 	/*
@@ -6306,9 +6450,6 @@
 	vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
 
 	clk_ops_local_pll.enable = sr_pll_clk_enable;
-
-	/* Initialize clock registers. */
-	reg_init();
 }
 
 static void __init msm8960_clock_post_init(void)
@@ -6336,8 +6477,8 @@
 		clk_set_rate(&usb_hs4_xcvr_clk.c, 60000000);
 	}
 	clk_set_rate(&usb_fs1_src_clk.c, 60000000);
-	if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm8930aa() ||
-	    cpu_is_msm8627())
+	if (cpu_is_msm8960ab() || cpu_is_msm8960() || cpu_is_msm8930() ||
+		cpu_is_msm8930aa() || cpu_is_msm8627())
 		clk_set_rate(&usb_fs2_src_clk.c, 60000000);
 	clk_set_rate(&usb_hsic_xcvr_fs_clk.c, 60000000);
 	clk_set_rate(&usb_hsic_hsic_src_clk.c, 480000000);
diff --git a/arch/arm/mach-msm/devices-8930.c b/arch/arm/mach-msm/devices-8930.c
index a36e7d7..1f954c8 100644
--- a/arch/arm/mach-msm/devices-8930.c
+++ b/arch/arm/mach-msm/devices-8930.c
@@ -355,6 +355,16 @@
 	.id    = MSM_BUS_FAB_CPSS_FPB,
 };
 
+struct platform_device msm8627_device_acpuclk = {
+	.name		= "acpuclk-8627",
+	.id		= -1,
+};
+
+struct platform_device msm8930_device_acpuclk = {
+	.name		= "acpuclk-8930",
+	.id		= -1,
+};
+
 static struct fs_driver_data gfx3d_fs_data = {
 	.clks = (struct fs_clk_data[]){
 		{ .name = "core_clk", .reset_rate = 27000000 },
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 045dfb9..2207e3c 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -420,7 +420,9 @@
 extern struct platform_device msm7x27aa_device_acpuclk;
 extern struct platform_device msm7x30_device_acpuclk;
 extern struct platform_device msm8625_device_acpuclk;
+extern struct platform_device msm8627_device_acpuclk;
 extern struct platform_device msm8x50_device_acpuclk;
 extern struct platform_device msm8x60_device_acpuclk;
+extern struct platform_device msm8930_device_acpuclk;
 extern struct platform_device msm8960_device_acpuclk;
 extern struct platform_device msm9615_device_acpuclk;
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 86720d8..f21d296 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -475,6 +475,7 @@
 struct msm_fb_platform_data {
 	int (*detect_client)(const char *name);
 	int mddi_prescan;
+	unsigned char ext_resolution;
 	int (*allow_set_offset)(void);
 	char prim_panel_name[PANEL_NAME_MAX_LEN];
 	char ext_panel_name[PANEL_NAME_MAX_LEN];
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 08e2d44..43d707e 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -567,6 +567,7 @@
 	S_STEREO_VIDEO,
 	S_STEREO_CAPTURE,
 	S_DEFAULT,
+	S_LIVESHOT,
 	S_EXIT
 };
 
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index 23d11c3..c0a35f9 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -103,6 +103,7 @@
 	struct hci_fm_ch_det_threshold ch_det_threshold;
 	struct hci_fm_data_rd_rsp default_data;
 	struct hci_fm_spur_data spur_data;
+	unsigned char is_station_valid;
 };
 
 static struct video_device *priv_videodev;
@@ -2645,6 +2646,9 @@
 
 		ctrl->value = radio->ch_det_threshold.sinr_samples;
 		break;
+	case V4L2_CID_PRIVATE_VALID_CHANNEL:
+		ctrl->value = radio->is_station_valid;
+		break;
 	default:
 		retval = -EINVAL;
 	}
@@ -2811,6 +2815,8 @@
 	struct hci_fm_tx_rt tx_rt = {0};
 	struct hci_fm_def_data_rd_req rd_txgain;
 	struct hci_fm_def_data_wr_req wr_txgain;
+	char sinr_th, sinr;
+	__u8 intf_det_low_th, intf_det_high_th, intf_det_out;
 
 	switch (ctrl->id) {
 	case V4L2_CID_PRIVATE_IRIS_TX_TONE:
@@ -3281,6 +3287,40 @@
 	case V4L2_CID_PRIVATE_UPDATE_SPUR_TABLE:
 		update_spur_table(radio);
 		break;
+	case V4L2_CID_PRIVATE_VALID_CHANNEL:
+		retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("%s: Failed to determine channel's validity\n",
+				__func__);
+			return retval;
+		} else {
+			sinr_th = radio->ch_det_threshold.sinr;
+			intf_det_low_th = radio->ch_det_threshold.low_th;
+			intf_det_high_th = radio->ch_det_threshold.high_th;
+		}
+
+		retval = hci_cmd(HCI_FM_GET_STATION_PARAM_CMD, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("%s: Failed to determine channel's validity\n",
+				__func__);
+			return retval;
+		} else
+			sinr = radio->fm_st_rsp.station_rsp.sinr;
+
+		retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("%s: Failed to determine channel's validity\n",
+				 __func__);
+			return retval;
+		} else
+			intf_det_out = radio->st_dbg_param.in_det_out;
+
+		if ((sinr >= sinr_th) && (intf_det_out >= intf_det_low_th) &&
+			(intf_det_out <= intf_det_high_th))
+			radio->is_station_valid = VALID_CHANNEL;
+		else
+			radio->is_station_valid = INVALID_CHANNEL;
+		break;
 	default:
 		retval = -EINVAL;
 	}
diff --git a/drivers/media/video/msm/csi/msm_csi2_register.c b/drivers/media/video/msm/csi/msm_csi2_register.c
index 7b85ded..aa539ff 100644
--- a/drivers/media/video/msm/csi/msm_csi2_register.c
+++ b/drivers/media/video/msm/csi/msm_csi2_register.c
@@ -16,48 +16,28 @@
 #include "msm_csi_register.h"
 
 int msm_csi_register_subdevs(struct msm_cam_media_controller *p_mctl,
-	int core_index,
-	int (*msm_mctl_subdev_match_core)(struct device *, void *))
+	int core_index, struct msm_cam_server_dev *server_dev)
 {
 	int rc = -ENODEV;
-	struct device_driver *driver;
-	struct device *dev;
 
 	/* register csiphy subdev */
-	driver = driver_find(MSM_CSIPHY_DRV_NAME, &platform_bus_type);
-	if (!driver)
+	p_mctl->csiphy_sdev = server_dev->csiphy_device[core_index];
+	if (!p_mctl->csiphy_sdev)
 		goto out;
-
-	dev = driver_find_device(driver, NULL, (void *)core_index,
-			msm_mctl_subdev_match_core);
-	if (!dev)
-		goto out;
-
-	p_mctl->csiphy_sdev = dev_get_drvdata(dev);
+	v4l2_set_subdev_hostdata(p_mctl->csiphy_sdev, p_mctl);
 
 	/* register csid subdev */
-	driver = driver_find(MSM_CSID_DRV_NAME, &platform_bus_type);
-	if (!driver)
+	p_mctl->csid_sdev = server_dev->csid_device[core_index];
+	if (!p_mctl->csid_sdev)
 		goto out;
-
-	dev = driver_find_device(driver, NULL, (void *)core_index,
-			msm_mctl_subdev_match_core);
-	if (!dev)
-		goto out;
-
-	p_mctl->csid_sdev = dev_get_drvdata(dev);
+	v4l2_set_subdev_hostdata(p_mctl->csid_sdev, p_mctl);
 
 	/* register ispif subdev */
-	driver = driver_find(MSM_ISPIF_DRV_NAME, &platform_bus_type);
-	if (!driver)
+	p_mctl->ispif_sdev = server_dev->ispif_device[0];
+	if (!p_mctl->ispif_sdev)
 		goto out;
+	v4l2_set_subdev_hostdata(p_mctl->ispif_sdev, p_mctl);
 
-	dev = driver_find_device(driver, NULL, 0,
-			msm_mctl_subdev_match_core);
-	if (!dev)
-		goto out;
-
-	p_mctl->ispif_sdev = dev_get_drvdata(dev);
 	rc = 0;
 	return rc;
 out:
diff --git a/drivers/media/video/msm/csi/msm_csi_register.h b/drivers/media/video/msm/csi/msm_csi_register.h
index 578b609..ebb001c 100644
--- a/drivers/media/video/msm/csi/msm_csi_register.h
+++ b/drivers/media/video/msm/csi/msm_csi_register.h
@@ -13,4 +13,4 @@
 
 int msm_csi_register_subdevs(struct msm_cam_media_controller *p_mctl,
 	int core_index,
-	int (*msm_mctl_subdev_match_core)(struct device *, void *));
+	struct msm_cam_server_dev *server_dev);
diff --git a/drivers/media/video/msm/csi/msm_csic.c b/drivers/media/video/msm/csi/msm_csic.c
index dbb4f32..bcb7bb3 100644
--- a/drivers/media/video/msm/csi/msm_csic.c
+++ b/drivers/media/video/msm/csi/msm_csic.c
@@ -463,6 +463,12 @@
 	msm_cam_register_subdev_node(
 		&new_csic_dev->subdev, &sd_info);
 
+	media_entity_init(&new_csic_dev->subdev.entity, 0, NULL, 0);
+	new_csic_dev->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	new_csic_dev->subdev.entity.group_id = CSIC_DEV;
+	new_csic_dev->subdev.entity.name = pdev->name;
+	new_csic_dev->subdev.entity.revision =
+		new_csic_dev->subdev.devnode->num;
 	return 0;
 
 csic_no_resource:
diff --git a/drivers/media/video/msm/csi/msm_csic_register.c b/drivers/media/video/msm/csi/msm_csic_register.c
index 7ccaff2..dc3641a 100644
--- a/drivers/media/video/msm/csi/msm_csic_register.c
+++ b/drivers/media/video/msm/csi/msm_csic_register.c
@@ -16,23 +16,14 @@
 #include "msm_csi_register.h"
 
 int msm_csi_register_subdevs(struct msm_cam_media_controller *p_mctl,
-	int core_index,
-	int (*msm_mctl_subdev_match_core)(struct device *, void *))
+	int core_index, struct msm_cam_server_dev *server_dev)
 {
 	int rc = -ENODEV;
-	struct device_driver *driver;
-	struct device *dev;
 
-	driver = driver_find(MSM_CSIC_DRV_NAME, &platform_bus_type);
-	if (!driver)
+	p_mctl->csic_sdev = server_dev->csic_device[core_index];
+	if (!p_mctl->csic_sdev)
 		goto out;
-
-	dev = driver_find_device(driver, NULL, (void *)core_index,
-			msm_mctl_subdev_match_core);
-	if (!dev)
-		goto out;
-
-	p_mctl->csic_sdev = dev_get_drvdata(dev);
+	v4l2_set_subdev_hostdata(p_mctl->csic_sdev, p_mctl);
 
 	rc = 0;
 	p_mctl->ispif_sdev = NULL;
diff --git a/drivers/media/video/msm/csi/msm_csid.c b/drivers/media/video/msm/csi/msm_csid.c
index 962c60e..6ee87b7 100644
--- a/drivers/media/video/msm/csi/msm_csid.c
+++ b/drivers/media/video/msm/csi/msm_csid.c
@@ -320,6 +320,13 @@
 	sd_info.sd_index = pdev->id;
 	sd_info.irq_num = new_csid_dev->irq->start;
 	msm_cam_register_subdev_node(&new_csid_dev->subdev, &sd_info);
+
+	media_entity_init(&new_csid_dev->subdev.entity, 0, NULL, 0);
+	new_csid_dev->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	new_csid_dev->subdev.entity.group_id = CSID_DEV;
+	new_csid_dev->subdev.entity.name = pdev->name;
+	new_csid_dev->subdev.entity.revision =
+		new_csid_dev->subdev.devnode->num;
 	return 0;
 
 csid_no_resource:
diff --git a/drivers/media/video/msm/csi/msm_csiphy.c b/drivers/media/video/msm/csi/msm_csiphy.c
index c524884..bec7ae3 100644
--- a/drivers/media/video/msm/csi/msm_csiphy.c
+++ b/drivers/media/video/msm/csi/msm_csiphy.c
@@ -341,6 +341,13 @@
 	sd_info.irq_num = new_csiphy_dev->irq->start;
 	msm_cam_register_subdev_node(
 		&new_csiphy_dev->subdev, &sd_info);
+
+	media_entity_init(&new_csiphy_dev->subdev.entity, 0, NULL, 0);
+	new_csiphy_dev->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	new_csiphy_dev->subdev.entity.group_id = CSIPHY_DEV;
+	new_csiphy_dev->subdev.entity.name = pdev->name;
+	new_csiphy_dev->subdev.entity.revision =
+		new_csiphy_dev->subdev.devnode->num;
 	return 0;
 
 csiphy_no_resource:
diff --git a/drivers/media/video/msm/csi/msm_ispif.c b/drivers/media/video/msm/csi/msm_ispif.c
index 0f16bbf..1494644 100644
--- a/drivers/media/video/msm/csi/msm_ispif.c
+++ b/drivers/media/video/msm/csi/msm_ispif.c
@@ -517,7 +517,6 @@
 		if (rc < 0)
 			return rc;
 	}
-
 	rc = msm_ispif_reset();
 	return rc;
 }
@@ -693,6 +692,12 @@
 	sd_info.sd_index = pdev->id;
 	sd_info.irq_num = ispif->irq->start;
 	msm_cam_register_subdev_node(&ispif->subdev, &sd_info);
+
+	media_entity_init(&ispif->subdev.entity, 0, NULL, 0);
+	ispif->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	ispif->subdev.entity.group_id = ISPIF_DEV;
+	ispif->subdev.entity.name = pdev->name;
+	ispif->subdev.entity.revision = ispif->subdev.devnode->num;
 	return 0;
 
 ispif_no_mem:
diff --git a/drivers/media/video/msm/io/msm_io_8960.c b/drivers/media/video/msm/io/msm_io_8960.c
index f9c454a..699425a 100644
--- a/drivers/media/video/msm/io/msm_io_8960.c
+++ b/drivers/media/video/msm/io/msm_io_8960.c
@@ -87,6 +87,14 @@
 		} else
 			CDBG("%s: Bus Client NOT Registered!!!\n", __func__);
 		break;
+	case S_LIVESHOT:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 5);
+			CDBG("%s: S_LIVESHOT rc = %d\n", __func__, rc);
+		} else
+			CDBG("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
 	case S_DEFAULT:
 		break;
 	default:
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index b67af4f..3222f905 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -92,6 +92,33 @@
 	return rc;
 }
 
+static int msm_camera_v4l2_private_g_ctrl(struct file *f, void *pctx,
+	struct msm_camera_v4l2_ioctl_t *ioctl_ptr)
+{
+	int rc = -EINVAL;
+	struct msm_cam_v4l2_device *pcam  = video_drvdata(f);
+	struct msm_cam_v4l2_dev_inst *pcam_inst;
+	pcam_inst = container_of(f->private_data,
+		struct msm_cam_v4l2_dev_inst, eventHandle);
+
+	WARN_ON(pctx != f->private_data);
+
+	mutex_lock(&pcam->vid_lock);
+	switch (ioctl_ptr->id) {
+	case MSM_V4L2_PID_INST_HANDLE:
+		COPY_TO_USER(rc, (void __user *)ioctl_ptr->ioctl_ptr,
+			(void *)&pcam_inst->inst_handle, sizeof(uint32_t));
+		if (rc)
+			ERR_COPY_TO_USER();
+		break;
+	default:
+		pr_err("%s Unsupported ioctl %d ", __func__, ioctl_ptr->id);
+		break;
+	}
+	mutex_unlock(&pcam->vid_lock);
+	return rc;
+}
+
 static int msm_camera_v4l2_g_ctrl(struct file *f, void *pctx,
 					struct v4l2_control *c)
 {
@@ -686,7 +713,9 @@
 	struct msm_cam_v4l2_dev_inst *pcam_inst;
 	pcam_inst = container_of(f->private_data,
 		struct msm_cam_v4l2_dev_inst, eventHandle);
-	pcam_inst->image_mode = a->parm.capture.extendedmode;
+	pcam_inst->image_mode = (a->parm.capture.extendedmode & 0x7F);
+	SET_IMG_MODE(pcam_inst->inst_handle, pcam_inst->image_mode);
+	SET_VIDEO_INST_IDX(pcam_inst->inst_handle, pcam_inst->my_index);
 	pcam_inst->pcam->dev_inst_map[pcam_inst->image_mode] = pcam_inst;
 	pcam_inst->path = msm_vidbuf_get_path(pcam_inst->image_mode);
 	D("%spath=%d,rc=%d\n", __func__,
@@ -745,6 +774,12 @@
 	case MSM_CAM_V4L2_IOCTL_PRIVATE_S_CTRL:
 		rc = msm_camera_v4l2_private_s_ctrl(file, fh, ioctl_ptr);
 		break;
+	case MSM_CAM_V4L2_IOCTL_PRIVATE_G_CTRL:
+		rc = msm_camera_v4l2_private_g_ctrl(file, fh, ioctl_ptr);
+		break;
+	default:
+		pr_err("%s Unsupported ioctl cmd %d ", __func__, cmd);
+		break;
 	}
 	return rc;
 }
@@ -876,13 +911,8 @@
 		}
 		pmctl->pcam_ptr = pcam;
 
-		rc = msm_setup_v4l2_event_queue(&pcam_inst->eventHandle,
+		msm_setup_v4l2_event_queue(&pcam_inst->eventHandle,
 			pcam->pvdev);
-		if (rc < 0) {
-			pr_err("%s: msm_setup_v4l2_event_queue failed %d",
-				__func__, rc);
-			goto mctl_event_q_setup_failed;
-		}
 	}
 	pcam_inst->vbqueue_initialized = 0;
 	rc = 0;
@@ -905,9 +935,8 @@
 	return rc;
 
 msm_send_open_server_failed:
-	v4l2_fh_del(&pcam_inst->eventHandle);
-	v4l2_fh_exit(&pcam_inst->eventHandle);
-mctl_event_q_setup_failed:
+	msm_destroy_v4l2_event_queue(&pcam_inst->eventHandle);
+
 	if (pmctl->mctl_release)
 		if (pmctl->mctl_release(pmctl) < 0)
 			pr_err("%s: mctl_release failed\n", __func__);
@@ -1051,10 +1080,11 @@
 	D("%s index %d nodeid %d count %d\n", __func__, pcam_inst->my_index,
 		pcam->vnode_id, pcam->use_count);
 	pcam->dev_inst[pcam_inst->my_index] = NULL;
-	if (pcam_inst->my_index == 0) {
-		v4l2_fh_del(&pcam_inst->eventHandle);
-		v4l2_fh_exit(&pcam_inst->eventHandle);
-	}
+	if (pcam_inst->my_index == 0)
+		msm_destroy_v4l2_event_queue(&pcam_inst->eventHandle);
+
+	CLR_VIDEO_INST_IDX(pcam_inst->inst_handle);
+	CLR_IMG_MODE(pcam_inst->inst_handle);
 	mutex_unlock(&pcam_inst->inst_lock);
 	mutex_destroy(&pcam_inst->inst_lock);
 	kfree(pcam_inst);
@@ -1137,18 +1167,6 @@
 	return 0;
 }
 
-int msm_setup_v4l2_event_queue(struct v4l2_fh *eventHandle,
-	struct video_device *pvdev)
-{
-	int rc = 0;
-	/* v4l2_fh support */
-	spin_lock_init(&pvdev->fh_lock);
-	INIT_LIST_HEAD(&pvdev->fh_list);
-
-	v4l2_fh_init(eventHandle, pvdev);
-	v4l2_fh_add(eventHandle);
-	return rc;
-}
 
 static struct v4l2_file_operations g_msm_fops = {
 	.owner   = THIS_MODULE,
@@ -1201,7 +1219,7 @@
 	pvdev->fops	     = &g_msm_fops;
 	pvdev->ioctl_ops = &g_msm_ioctl_ops;
 	pvdev->minor	 = -1;
-	pvdev->vfl_type  = 1;
+	pvdev->vfl_type  = VFL_TYPE_GRABBER;
 
 	media_entity_init(&pvdev->entity, 0, NULL, 0);
 	pvdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index 08278ff..d77defd 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -61,6 +61,7 @@
 #define MSM_IRQ_ROUTER_DRV_NAME "msm_cam_irq_router"
 #define MSM_CPP_DRV_NAME "msm_cpp"
 
+#define MAX_NUM_SENSOR_DEV 3
 #define MAX_NUM_CSIPHY_DEV 3
 #define MAX_NUM_CSID_DEV 4
 #define MAX_NUM_CSIC_DEV 3
@@ -71,22 +72,6 @@
 #define MAX_NUM_JPEG_DEV 3
 #define MAX_NUM_CPP_DEV 1
 
-enum msm_cam_subdev_type {
-	CSIPHY_DEV,
-	CSID_DEV,
-	CSIC_DEV,
-	ISPIF_DEV,
-	VFE_DEV,
-	AXI_DEV,
-	VPE_DEV,
-	SENSOR_DEV,
-	ACTUATOR_DEV,
-	EEPROM_DEV,
-	GESTURE_DEV,
-	IRQ_ROUTER_DEV,
-	CPP_DEV,
-};
-
 /* msm queue management APIs*/
 
 #define msm_dequeue(queue, member) ({	   \
@@ -137,7 +122,7 @@
 
 struct msm_free_buf {
 	uint8_t num_planes;
-	int32_t image_mode;
+	uint32_t inst_handle;
 	uint32_t ch_paddr[VIDEO_MAX_PLANES];
 	uint32_t vb;
 };
@@ -315,7 +300,6 @@
 
 	/* vfe subdevice */
 	struct v4l2_subdev *sd;
-	struct v4l2_subdev *sd_vpe;
 };
 
 struct msm_isp_buf_info {
@@ -339,7 +323,7 @@
 	enum v4l2_mbus_pixelcode sensor_pxlcode;
 	struct msm_cam_v4l2_device *pcam;
 	int my_index;
-	int image_mode;
+	uint32_t image_mode;
 	int path;
 	int buf_count;
 	/* buffer offsets, if any */
@@ -351,6 +335,7 @@
 	struct img_plane_info plane_info;
 	int vbqueue_initialized;
 	struct mutex inst_lock;
+	uint32_t inst_handle;
 };
 
 struct msm_cam_mctl_node {
@@ -540,10 +525,11 @@
 	struct mutex server_lock;
 	struct mutex server_queue_lock;
 	/*v4l2 subdevs*/
+	struct v4l2_subdev *sensor_device[MAX_NUM_SENSOR_DEV];
 	struct v4l2_subdev *csiphy_device[MAX_NUM_CSIPHY_DEV];
 	struct v4l2_subdev *csid_device[MAX_NUM_CSID_DEV];
 	struct v4l2_subdev *csic_device[MAX_NUM_CSIC_DEV];
-	struct v4l2_subdev *ispif_device;
+	struct v4l2_subdev *ispif_device[MAX_NUM_ISPIF_DEV];
 	struct v4l2_subdev *vfe_device[MAX_NUM_VFE_DEV];
 	struct v4l2_subdev *axi_device[MAX_NUM_AXI_DEV];
 	struct v4l2_subdev *vpe_device[MAX_NUM_VPE_DEV];
@@ -562,6 +548,18 @@
 	struct msm_cam_server_irqmap_entry hw_irqmap[CAMERA_SS_IRQ_MAX];
 };
 
+enum msm_cam_buf_lookup_type {
+	BUF_LOOKUP_INVALID,
+	BUF_LOOKUP_BY_IMG_MODE,
+	BUF_LOOKUP_BY_INST_HANDLE,
+};
+
+struct msm_cam_buf_handle {
+	uint16_t buf_lookup_type;
+	uint32_t image_mode;
+	uint32_t inst_handle;
+};
+
 /* ISP related functions */
 void msm_isp_vfe_dev_init(struct v4l2_subdev *vd);
 /*
@@ -577,78 +575,69 @@
 int msm_mctl_buf_init(struct msm_cam_v4l2_device *pcam);
 int msm_mctl_init_user_formats(struct msm_cam_v4l2_device *pcam);
 int msm_mctl_buf_done(struct msm_cam_media_controller *pmctl,
-			int msg_type, struct msm_free_buf *buf,
-			uint32_t frame_id);
+	struct msm_cam_buf_handle *buf_handle,
+	struct msm_free_buf *buf,
+	uint32_t frame_id);
 int msm_mctl_buf_done_pp(struct msm_cam_media_controller *pmctl,
-	int msg_type, struct msm_free_buf *frame, int dirty, int node_type);
+	struct msm_cam_buf_handle *buf_handle,
+	struct msm_free_buf *frame, int dirty, int node_type);
 int msm_mctl_reserve_free_buf(struct msm_cam_media_controller *pmctl,
-				struct msm_cam_v4l2_dev_inst *pcam_inst,
-				int path, struct msm_free_buf *free_buf);
+	struct msm_cam_v4l2_dev_inst *pcam_inst,
+	struct msm_cam_buf_handle *buf_handle,
+	struct msm_free_buf *free_buf);
 int msm_mctl_release_free_buf(struct msm_cam_media_controller *pmctl,
-				struct msm_cam_v4l2_dev_inst *pcam_inst,
-				int path, struct msm_free_buf *free_buf);
+	struct msm_cam_v4l2_dev_inst *pcam_inst,
+	struct msm_free_buf *free_buf);
 /*Memory(PMEM) functions*/
 int msm_register_pmem(struct hlist_head *ptype, void __user *arg,
-				struct ion_client *client);
+	struct ion_client *client);
 int msm_pmem_table_del(struct hlist_head *ptype, void __user *arg,
-				struct ion_client *client);
+	struct ion_client *client);
 int msm_pmem_region_get_phy_addr(struct hlist_head *ptype,
 	struct msm_mem_map_info *mem_map, int32_t *phyaddr);
 uint8_t msm_pmem_region_lookup(struct hlist_head *ptype,
 	int pmem_type, struct msm_pmem_region *reg, uint8_t maxcount);
 uint8_t msm_pmem_region_lookup_2(struct hlist_head *ptype,
-					int pmem_type,
-					struct msm_pmem_region *reg,
-					uint8_t maxcount);
+	int pmem_type, struct msm_pmem_region *reg,
+	uint8_t maxcount);
 unsigned long msm_pmem_stats_vtop_lookup(
-				struct msm_cam_media_controller *mctl,
-				unsigned long buffer,
-				int fd);
+	struct msm_cam_media_controller *mctl,
+	unsigned long buffer, int fd);
 unsigned long msm_pmem_stats_ptov_lookup(
 	struct msm_cam_media_controller *mctl,
 	unsigned long addr, int *fd);
 
-int msm_vfe_subdev_init(struct v4l2_subdev *sd,
-			struct msm_cam_media_controller *mctl);
+int msm_vfe_subdev_init(struct v4l2_subdev *sd);
 void msm_vfe_subdev_release(struct v4l2_subdev *sd);
 
 int msm_isp_subdev_ioctl(struct v4l2_subdev *sd,
 	struct msm_vfe_cfg_cmd *cfgcmd, void *data);
-int msm_vpe_subdev_init(struct v4l2_subdev *sd,
-			struct msm_cam_media_controller *mctl);
+int msm_vpe_subdev_init(struct v4l2_subdev *sd);
 int msm_gemini_subdev_init(struct v4l2_subdev *gemini_sd);
 void msm_vpe_subdev_release(void);
 void msm_gemini_subdev_release(struct v4l2_subdev *gemini_sd);
 int msm_mctl_is_pp_msg_type(struct msm_cam_media_controller *p_mctl,
 	int msg_type);
 int msm_mctl_do_pp(struct msm_cam_media_controller *p_mctl,
-			int msg_type, uint32_t y_phy, uint32_t frame_id);
+	int msg_type, uint32_t y_phy, uint32_t frame_id);
 int msm_mctl_pp_ioctl(struct msm_cam_media_controller *p_mctl,
-			unsigned int cmd, unsigned long arg);
+	unsigned int cmd, unsigned long arg);
 int msm_mctl_pp_notify(struct msm_cam_media_controller *pmctl,
-			struct msm_mctl_pp_frame_info *pp_frame_info);
+	struct msm_mctl_pp_frame_info *pp_frame_info);
 int msm_mctl_img_mode_to_inst_index(struct msm_cam_media_controller *pmctl,
-					int out_type, int node_type);
+	int out_type, int node_type);
 struct msm_frame_buffer *msm_mctl_buf_find(
 	struct msm_cam_media_controller *pmctl,
 	struct msm_cam_v4l2_dev_inst *pcam_inst, int del_buf,
-	int msg_type, struct msm_free_buf *fbuf);
+	struct msm_free_buf *fbuf);
 void msm_mctl_gettimeofday(struct timeval *tv);
-struct msm_frame_buffer *msm_mctl_get_free_buf(
-		struct msm_cam_media_controller *pmctl,
-		int msg_type);
-int msm_mctl_put_free_buf(
-		struct msm_cam_media_controller *pmctl,
-		int msg_type, struct msm_frame_buffer *buf);
 int msm_mctl_check_pp(struct msm_cam_media_controller *p_mctl,
-		int msg_type, int *pp_divert_type, int *pp_type);
+	int msg_type, int *pp_divert_type, int *pp_type);
 int msm_mctl_do_pp_divert(
 	struct msm_cam_media_controller *p_mctl,
-	int msg_type, struct msm_free_buf *fbuf,
+	struct msm_cam_buf_handle *buf_handle,
+	struct msm_free_buf *fbuf,
 	uint32_t frame_id, int pp_type);
-int msm_mctl_buf_del(struct msm_cam_media_controller *pmctl,
-	int msg_type,
-	struct msm_frame_buffer *my_buf);
 int msm_mctl_pp_release_free_frame(
 	struct msm_cam_media_controller *p_mctl,
 	void __user *arg);
@@ -656,26 +645,29 @@
 	struct msm_cam_media_controller *p_mctl,
 	void __user *arg);
 int msm_mctl_set_pp_key(struct msm_cam_media_controller *p_mctl,
-				void __user *arg);
+	void __user *arg);
 int msm_mctl_pp_done(
 	struct msm_cam_media_controller *p_mctl,
 	void __user *arg);
 int msm_mctl_pp_divert_done(
 	struct msm_cam_media_controller *p_mctl,
 	void __user *arg);
-int msm_setup_v4l2_event_queue(struct v4l2_fh *eventHandle,
-					struct video_device *pvdev);
+void msm_setup_v4l2_event_queue(struct v4l2_fh *eventHandle,
+	struct video_device *pvdev);
+void msm_destroy_v4l2_event_queue(struct v4l2_fh *eventHandle);
 int msm_setup_mctl_node(struct msm_cam_v4l2_device *pcam);
 struct msm_cam_v4l2_dev_inst *msm_mctl_get_pcam_inst(
-		struct msm_cam_media_controller *pmctl,
-		int image_mode);
+	struct msm_cam_media_controller *pmctl,
+	struct msm_cam_buf_handle *buf_handle);
 int msm_mctl_buf_return_buf(struct msm_cam_media_controller *pmctl,
-			int image_mode, struct msm_frame_buffer *buf);
+	int image_mode, struct msm_frame_buffer *buf);
 int msm_mctl_pp_mctl_divert_done(struct msm_cam_media_controller *p_mctl,
-					void __user *arg);
+	void __user *arg);
 void msm_release_ion_client(struct kref *ref);
 int msm_cam_register_subdev_node(struct v4l2_subdev *sd,
 	struct msm_cam_subdev_info *sd_info);
+int msm_mctl_find_sensor_subdevs(struct msm_cam_media_controller *p_mctl,
+	int core_index);
 int msm_server_open_client(int *p_qidx);
 int msm_server_send_ctrl(struct msm_ctrl_cmd *out, int ctrl_id);
 int msm_server_close_client(int idx);
@@ -683,7 +675,7 @@
 	int *p_active);
 int msm_cam_server_close_mctl_session(struct msm_cam_v4l2_device *pcam);
 long msm_v4l2_evt_notify(struct msm_cam_media_controller *mctl,
-		unsigned int cmd, unsigned long evt);
+	unsigned int cmd, unsigned long evt);
 int msm_mctl_pp_get_vpe_buf_info(struct msm_mctl_pp_frame_info *zoom);
 void msm_queue_init(struct msm_device_queue *queue, const char *name);
 void msm_enqueue(struct msm_device_queue *queue, struct list_head *entry);
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index 5fcb62b..67e7c02 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -168,7 +168,9 @@
 	struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
 	struct msm_frame_info *frame_info =
 		(struct msm_frame_info *)vdata->evt_msg.data;
-	uint32_t vfe_id, image_mode;
+	uint32_t vfe_id;
+	struct msm_cam_buf_handle buf_handle;
+
 	if (!pcam) {
 		pr_debug("%s pcam is null. return\n", __func__);
 		msm_isp_sync_free(vdata);
@@ -176,10 +178,13 @@
 	}
 	if (frame_info) {
 		vfe_id = frame_info->path;
-		image_mode = frame_info->image_mode;
+		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
+		buf_handle.inst_handle = frame_info->inst_handle;
 	} else {
 		vfe_id = vdata->evt_msg.msg_id;
-		image_mode = msm_isp_vfe_msg_to_img_mode(pmctl, vfe_id);
+		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_IMG_MODE;
+		buf_handle.image_mode =
+			msm_isp_vfe_msg_to_img_mode(pmctl, vfe_id);
 	}
 
 	switch (vdata->type) {
@@ -189,14 +194,14 @@
 		D("%s Got V32_START_*: Getting ping addr id = %d",
 						__func__, vfe_id);
 		msm_mctl_reserve_free_buf(pmctl, NULL,
-					image_mode, &free_buf);
+					&buf_handle, &free_buf);
 		cfgcmd.cmd_type = CMD_CONFIG_PING_ADDR;
 		cfgcmd.value = &vfe_id;
 		vfe_params.vfe_cfg = &cfgcmd;
 		vfe_params.data = (void *)&free_buf;
 		rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
 		msm_mctl_reserve_free_buf(pmctl, NULL,
-					image_mode, &free_buf);
+					&buf_handle, &free_buf);
 		cfgcmd.cmd_type = CMD_CONFIG_PONG_ADDR;
 		cfgcmd.value = &vfe_id;
 		vfe_params.vfe_cfg = &cfgcmd;
@@ -208,7 +213,7 @@
 		pr_debug("%s Got V32_CAPTURE: getting buffer for id = %d",
 						__func__, vfe_id);
 		msm_mctl_reserve_free_buf(pmctl, NULL,
-					image_mode, &free_buf);
+					&buf_handle, &free_buf);
 		cfgcmd.cmd_type = CMD_CONFIG_PING_ADDR;
 		cfgcmd.value = &vfe_id;
 		vfe_params.vfe_cfg = &cfgcmd;
@@ -216,7 +221,7 @@
 		rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
 		temp_free_buf = free_buf;
 		if (msm_mctl_reserve_free_buf(pmctl, NULL,
-					image_mode, &free_buf)) {
+					&buf_handle, &free_buf)) {
 			/* Write the same buffer into PONG */
 			free_buf = temp_free_buf;
 		}
@@ -254,7 +259,7 @@
 		D("%s Got OUTPUT_IRQ: Getting free buf id = %d",
 						__func__, vfe_id);
 		msm_mctl_reserve_free_buf(pmctl, NULL,
-					image_mode, &free_buf);
+					&buf_handle, &free_buf);
 		cfgcmd.cmd_type = CMD_CONFIG_FREE_BUF_ADDR;
 		cfgcmd.value = &vfe_id;
 		vfe_params.vfe_cfg = &cfgcmd;
@@ -320,10 +325,10 @@
 	}
 	case NOTIFY_VFE_MSG_OUT: {
 		uint8_t msgid;
-		int32_t image_mode = -1;
+		struct msm_cam_buf_handle buf_handle;
 		struct isp_msg_output *isp_output =
 				(struct isp_msg_output *)arg;
-		if (isp_output->buf.image_mode < 0) {
+		if (!isp_output->buf.inst_handle) {
 			switch (isp_output->output_id) {
 			case MSG_ID_OUTPUT_P:
 				msgid = VFE_MSG_OUTPUT_P;
@@ -356,19 +361,22 @@
 				rc = -EINVAL;
 				break;
 			}
-			if (!rc)
-				image_mode =
+			if (!rc) {
+				buf_handle.buf_lookup_type =
+					BUF_LOOKUP_BY_IMG_MODE;
+				buf_handle.image_mode =
 				msm_isp_vfe_msg_to_img_mode(pmctl, msgid);
+			}
 		} else {
-			image_mode = isp_output->buf.image_mode;
+			buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
+			buf_handle.inst_handle = isp_output->buf.inst_handle;
 		}
 		isp_event->isp_data.isp_msg.msg_id =
 			isp_output->output_id;
 		isp_event->isp_data.isp_msg.frame_id =
 			isp_output->frameCounter;
 		buf = isp_output->buf;
-		BUG_ON(image_mode < 0);
-		msm_mctl_buf_done(pmctl, image_mode,
+		msm_mctl_buf_done(pmctl, &buf_handle,
 			&buf, isp_output->frameCounter);
 		}
 		break;
@@ -498,32 +506,8 @@
 		return -EINVAL;
 	}
 
-	rc = msm_iommu_map_contig_buffer(
-		(unsigned long)IMEM_Y_PING_OFFSET, CAMERA_DOMAIN, GEN_POOL,
-		((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)),
-		SZ_4K, IOMMU_WRITE | IOMMU_READ,
-		(unsigned long *)&mctl->ping_imem_y);
-	mctl->ping_imem_cbcr = mctl->ping_imem_y + IMEM_Y_SIZE;
-	if (rc < 0) {
-		pr_err("%s: ping iommu mapping returned error %d\n",
-			__func__, rc);
-		mctl->ping_imem_y = 0;
-		mctl->ping_imem_cbcr = 0;
-	}
-	msm_iommu_map_contig_buffer(
-		(unsigned long)IMEM_Y_PONG_OFFSET, CAMERA_DOMAIN, GEN_POOL,
-		((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)),
-		SZ_4K, IOMMU_WRITE | IOMMU_READ,
-		(unsigned long *)&mctl->pong_imem_y);
-	mctl->pong_imem_cbcr = mctl->pong_imem_y + IMEM_Y_SIZE;
-	if (rc < 0) {
-		pr_err("%s: pong iommu mapping returned error %d\n",
-			 __func__, rc);
-		mctl->pong_imem_y = 0;
-		mctl->pong_imem_cbcr = 0;
-	}
-
-	rc = msm_vfe_subdev_init(sd, mctl);
+	rc = v4l2_subdev_call(sd, core, ioctl,
+				VIDIOC_MSM_VFE_INIT, NULL);
 	if (rc < 0) {
 		pr_err("%s: vfe_init failed at %d\n",
 			__func__, rc);
@@ -535,17 +519,8 @@
 	struct v4l2_subdev *sd)
 {
 	D("%s\n", __func__);
-	msm_vfe_subdev_release(sd);
-	msm_iommu_unmap_contig_buffer(mctl->ping_imem_y,
-		CAMERA_DOMAIN, GEN_POOL,
-		((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)));
-	msm_iommu_unmap_contig_buffer(mctl->pong_imem_y,
-		CAMERA_DOMAIN, GEN_POOL,
-		((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)));
-	mctl->ping_imem_y = 0;
-	mctl->ping_imem_cbcr = 0;
-	mctl->pong_imem_y = 0;
-	mctl->pong_imem_cbcr = 0;
+	v4l2_subdev_call(sd, core, ioctl,
+				VIDIOC_MSM_VFE_RELEASE, NULL);
 }
 
 static int msm_config_vfe(struct v4l2_subdev *sd,
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index be4cb41..4bbc47c 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -418,94 +418,6 @@
 	return rc;
 }
 
-static int msm_mctl_subdev_match_core(struct device *dev, void *data)
-{
-	int core_index = (int)data;
-	struct platform_device *pdev = to_platform_device(dev);
-
-	if (pdev->id == core_index)
-		return 1;
-	else
-		return 0;
-}
-
-static int msm_mctl_register_subdevs(struct msm_cam_media_controller *p_mctl,
-	int core_index)
-{
-	struct device_driver *driver;
-	struct device *dev;
-	int rc = -ENODEV;
-
-	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(p_mctl->sensor_sdev);
-	struct msm_camera_sensor_info *sinfo =
-		(struct msm_camera_sensor_info *) s_ctrl->sensordata;
-	struct msm_camera_device_platform_data *pdata = sinfo->pdata;
-
-	rc = msm_csi_register_subdevs(p_mctl, core_index,
-				msm_mctl_subdev_match_core);
-
-	if (rc < 0)
-			goto out;
-
-	/* register vfe subdev */
-	driver = driver_find(MSM_VFE_DRV_NAME, &platform_bus_type);
-	if (!driver)
-		goto out;
-
-	dev = driver_find_device(driver, NULL, 0,
-				msm_mctl_subdev_match_core);
-	if (!dev)
-		goto out;
-
-	p_mctl->isp_sdev->sd = dev_get_drvdata(dev);
-
-	if (pdata->is_vpe) {
-		/* register vfe subdev */
-		driver = driver_find(MSM_VPE_DRV_NAME, &platform_bus_type);
-		if (!driver)
-			goto out;
-
-		dev = driver_find_device(driver, NULL, 0,
-				msm_mctl_subdev_match_core);
-		if (!dev)
-			goto out;
-
-		p_mctl->vpe_sdev = dev_get_drvdata(dev);
-	}
-
-	rc = 0;
-
-
-	/* register gemini subdev */
-	driver = driver_find(MSM_GEMINI_DRV_NAME, &platform_bus_type);
-	if (!driver) {
-		pr_err("%s:%d:Gemini: Failure: goto out\n",
-			__func__, __LINE__);
-		goto out;
-	}
-	pr_debug("%s:%d:Gemini: driver_find_device Gemini driver 0x%x\n",
-		__func__, __LINE__, (uint32_t)driver);
-	dev = driver_find_device(driver, NULL, NULL,
-				msm_mctl_subdev_match_core);
-	if (!dev) {
-		pr_err("%s:%d:Gemini: Failure goto out\n",
-			__func__, __LINE__);
-		goto out;
-	}
-	p_mctl->gemini_sdev = dev_get_drvdata(dev);
-	pr_debug("%s:%d:Gemini: After dev_get_drvdata gemini_sdev=0x%x\n",
-		__func__, __LINE__, (uint32_t)p_mctl->gemini_sdev);
-
-	if (p_mctl->gemini_sdev == NULL) {
-		pr_err("%s:%d:Gemini: Failure gemini_sdev is null\n",
-			__func__, __LINE__);
-		goto out;
-	}
-	rc = 0;
-out:
-	return rc;
-}
-
 static int msm_mctl_open(struct msm_cam_media_controller *p_mctl,
 				 const char *const apps_id)
 {
@@ -529,9 +441,9 @@
 		wake_lock(&p_mctl->wake_lock);
 
 		csid_core = camdev->csid_core;
-		rc = msm_mctl_register_subdevs(p_mctl, csid_core);
+		rc = msm_mctl_find_sensor_subdevs(p_mctl, csid_core);
 		if (rc < 0) {
-			pr_err("%s: msm_mctl_register_subdevs failed:%d\n",
+			pr_err("%s: msm_mctl_find_sensor_subdevs failed:%d\n",
 				__func__, rc);
 			goto register_sdev_failed;
 		}
@@ -592,38 +504,6 @@
 			goto msm_csi_version;
 		}
 
-		/* ISP first*/
-		if (p_mctl->isp_sdev && p_mctl->isp_sdev->isp_open) {
-			rc = p_mctl->isp_sdev->isp_open(
-				p_mctl->isp_sdev->sd, p_mctl);
-			if (rc < 0) {
-				pr_err("%s: isp init failed: %d\n",
-					__func__, rc);
-				goto isp_open_failed;
-			}
-		}
-
-		if (p_mctl->axi_sdev) {
-			rc = v4l2_subdev_call(p_mctl->axi_sdev, core, ioctl,
-				VIDIOC_MSM_AXI_INIT, p_mctl);
-			if (rc < 0) {
-				pr_err("%s: axi initialization failed %d\n",
-					__func__, rc);
-				goto axi_init_failed;
-			}
-		}
-
-		if (camdev->is_vpe) {
-			rc = v4l2_subdev_call(p_mctl->vpe_sdev, core, ioctl,
-				VIDIOC_MSM_VPE_INIT, p_mctl);
-			if (rc < 0) {
-				pr_err("%s: vpe initialization failed %d\n",
-				__func__, rc);
-				goto vpe_init_failed;
-			}
-		}
-
-
 		pm_qos_add_request(&p_mctl->pm_qos_req_list,
 			PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE);
 		pm_qos_update_request(&p_mctl->pm_qos_req_list,
@@ -635,19 +515,9 @@
 		D("%s: camera is already open", __func__);
 	}
 	mutex_unlock(&p_mctl->lock);
-
 	return rc;
 
-vpe_init_failed:
-	if (p_mctl->axi_sdev)
-		if (v4l2_subdev_call(p_mctl->axi_sdev, core, ioctl,
-			VIDIOC_MSM_AXI_RELEASE, NULL) < 0)
-			pr_err("%s: axi release failed %d\n", __func__, rc);
-axi_init_failed:
-	if (p_mctl->isp_sdev && p_mctl->isp_sdev->isp_release)
-		p_mctl->isp_sdev->isp_release(p_mctl, p_mctl->isp_sdev->sd);
 msm_csi_version:
-isp_open_failed:
 	if (p_mctl->csic_sdev)
 		if (v4l2_subdev_call(p_mctl->csic_sdev, core, ioctl,
 			VIDIOC_MSM_CSIC_RELEASE, NULL) < 0)
@@ -684,7 +554,6 @@
 	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(p_mctl->sensor_sdev);
 	struct msm_camera_sensor_info *sinfo =
 		(struct msm_camera_sensor_info *) s_ctrl->sensordata;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
 
 	v4l2_subdev_call(p_mctl->sensor_sdev, core, ioctl,
 		VIDIOC_MSM_SENSOR_RELEASE, NULL);
@@ -694,7 +563,7 @@
 			VIDIOC_MSM_CSIC_RELEASE, NULL);
 	}
 
-	if (camdev->is_vpe) {
+	if (p_mctl->vpe_sdev) {
 		v4l2_subdev_call(p_mctl->vpe_sdev, core, ioctl,
 			VIDIOC_MSM_VPE_RELEASE, NULL);
 	}
@@ -704,7 +573,8 @@
 			VIDIOC_MSM_AXI_RELEASE, NULL);
 	}
 
-	if (p_mctl->isp_sdev && p_mctl->isp_sdev->isp_release)
+	if (p_mctl->isp_sdev && p_mctl->isp_sdev->isp_release
+		&& p_mctl->isp_sdev->sd)
 		p_mctl->isp_sdev->isp_release(p_mctl,
 			p_mctl->isp_sdev->sd);
 
@@ -832,6 +702,7 @@
 	pmctl->eeprom_sdev = pcam->eeprom_sdev;
 	pmctl->sensor_sdev = pcam->sensor_sdev;
 	pmctl->sdata = pcam->sdata;
+	v4l2_set_subdev_hostdata(pcam->sensor_sdev, pmctl);
 
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 	pmctl->client = msm_ion_client_create(-1, "camera");
@@ -855,6 +726,8 @@
 
 	mutex_destroy(&pmctl->lock);
 	wake_lock_destroy(&pmctl->wake_lock);
+	/*clear out mctl fields*/
+	memset(pmctl, 0, sizeof(struct msm_cam_media_controller));
 	msm_cam_server_free_mctl(pcam->mctl_handle);
 	return rc;
 }
@@ -919,12 +792,9 @@
 	}
 
 	D("%s active %d\n", __func__, pcam->mctl_node.active);
-	rc = msm_setup_v4l2_event_queue(&pcam_inst->eventHandle,
-					pcam->mctl_node.pvdev);
-	if (rc < 0) {
-		mutex_unlock(&pcam->mctl_node.dev_lock);
-		return rc;
-	}
+	msm_setup_v4l2_event_queue(&pcam_inst->eventHandle,
+			pcam->mctl_node.pvdev);
+
 	pcam_inst->vbqueue_initialized = 0;
 	kref_get(&pmctl->refcount);
 	f->private_data = &pcam_inst->eventHandle;
@@ -1007,8 +877,10 @@
 		vb2_queue_release(&pcam_inst->vid_bufq);
 	D("%s Closing down instance %p ", __func__, pcam_inst);
 	pcam->mctl_node.dev_inst[pcam_inst->my_index] = NULL;
-	v4l2_fh_del(&pcam_inst->eventHandle);
-	v4l2_fh_exit(&pcam_inst->eventHandle);
+	msm_destroy_v4l2_event_queue(&pcam_inst->eventHandle);
+	CLR_MCTLPP_INST_IDX(pcam_inst->inst_handle);
+	CLR_IMG_MODE(pcam_inst->inst_handle);
+
 	mutex_destroy(&pcam_inst->inst_lock);
 
 	kfree(pcam_inst);
@@ -1581,7 +1453,9 @@
 	struct msm_cam_v4l2_dev_inst *pcam_inst;
 	pcam_inst = container_of(f->private_data,
 		struct msm_cam_v4l2_dev_inst, eventHandle);
-	pcam_inst->image_mode = a->parm.capture.extendedmode;
+	pcam_inst->image_mode = (a->parm.capture.extendedmode & 0x7F);
+	SET_IMG_MODE(pcam_inst->inst_handle, pcam_inst->image_mode);
+	SET_MCTLPP_INST_IDX(pcam_inst->inst_handle, pcam_inst->my_index);
 	pcam_inst->pcam->mctl_node.dev_inst_map[pcam_inst->image_mode] =
 		pcam_inst;
 	pcam_inst->path = msm_mctl_vidbuf_get_path(pcam_inst->image_mode);
@@ -1626,6 +1500,51 @@
 	return rc;
 }
 
+static int msm_mctl_v4l2_private_g_ctrl(struct file *f, void *pctx,
+	struct msm_camera_v4l2_ioctl_t *ioctl_ptr)
+{
+	int rc = -EINVAL;
+	struct msm_cam_v4l2_device *pcam  = video_drvdata(f);
+	struct msm_cam_v4l2_dev_inst *pcam_inst;
+	pcam_inst = container_of(f->private_data,
+		struct msm_cam_v4l2_dev_inst, eventHandle);
+
+	WARN_ON(pctx != f->private_data);
+
+	mutex_lock(&pcam->mctl_node.dev_lock);
+	switch (ioctl_ptr->id) {
+	case MSM_V4L2_PID_INST_HANDLE:
+		COPY_TO_USER(rc, (void __user *)ioctl_ptr->ioctl_ptr,
+			(void *)&pcam_inst->inst_handle, sizeof(uint32_t));
+		if (rc)
+			ERR_COPY_TO_USER();
+		break;
+	default:
+		pr_err("%s Unsupported ioctl %d ", __func__, ioctl_ptr->id);
+		break;
+	}
+	mutex_unlock(&pcam->mctl_node.dev_lock);
+	return rc;
+}
+
+static long msm_mctl_v4l2_private_ioctl(struct file *file, void *fh,
+	  bool valid_prio, int cmd, void *arg)
+{
+	int rc = -EINVAL;
+	struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
+	D("%s: cmd %d\n", __func__, _IOC_NR(cmd));
+
+	switch (cmd) {
+	case MSM_CAM_V4L2_IOCTL_PRIVATE_G_CTRL:
+		rc = msm_mctl_v4l2_private_g_ctrl(file, fh, ioctl_ptr);
+		break;
+	default:
+		pr_err("%s Unsupported ioctl cmd %d ", __func__, cmd);
+		break;
+	}
+	return rc;
+}
+
 /* mctl node v4l2_ioctl_ops */
 static const struct v4l2_ioctl_ops g_msm_mctl_ioctl_ops = {
 	.vidioc_querycap = msm_mctl_v4l2_querycap,
@@ -1665,6 +1584,7 @@
 	/* event subscribe/unsubscribe */
 	.vidioc_subscribe_event = msm_mctl_v4l2_subscribe_event,
 	.vidioc_unsubscribe_event = msm_mctl_v4l2_unsubscribe_event,
+	.vidioc_default = msm_mctl_v4l2_private_ioctl,
 };
 
 int msm_setup_mctl_node(struct msm_cam_v4l2_device *pcam)
diff --git a/drivers/media/video/msm/msm_mctl_buf.c b/drivers/media/video/msm/msm_mctl_buf.c
index cd86a80..befd213 100644
--- a/drivers/media/video/msm/msm_mctl_buf.c
+++ b/drivers/media/video/msm/msm_mctl_buf.c
@@ -368,7 +368,7 @@
 struct msm_frame_buffer *msm_mctl_buf_find(
 	struct msm_cam_media_controller *pmctl,
 	struct msm_cam_v4l2_dev_inst *pcam_inst, int del_buf,
-	int image_mode, struct msm_free_buf *fbuf)
+	struct msm_free_buf *fbuf)
 {
 	struct msm_frame_buffer *buf = NULL, *tmp;
 	uint32_t buf_phyaddr = 0;
@@ -409,14 +409,13 @@
 int msm_mctl_buf_done_proc(
 		struct msm_cam_media_controller *pmctl,
 		struct msm_cam_v4l2_dev_inst *pcam_inst,
-		int image_mode, struct msm_free_buf *fbuf,
+		struct msm_free_buf *fbuf,
 		uint32_t *frame_id, int gen_timestamp)
 {
 	struct msm_frame_buffer *buf = NULL;
 	int del_buf = 1;
 
-	buf = msm_mctl_buf_find(pmctl, pcam_inst, del_buf,
-					image_mode, fbuf);
+	buf = msm_mctl_buf_find(pmctl, pcam_inst, del_buf, fbuf);
 	if (!buf) {
 		pr_err("%s: buf=0x%x not found\n",
 			__func__, fbuf->ch_paddr[0]);
@@ -434,48 +433,81 @@
 
 
 int msm_mctl_buf_done(struct msm_cam_media_controller *p_mctl,
-			int image_mode, struct msm_free_buf *fbuf,
-			uint32_t frame_id)
+	struct msm_cam_buf_handle *buf_handle,
+	struct msm_free_buf *fbuf,
+	uint32_t frame_id)
 {
 	struct msm_cam_v4l2_dev_inst *pcam_inst;
 	int idx, rc;
 	int pp_divert_type = 0, pp_type = 0;
+	uint32_t image_mode;
+
+	if (!p_mctl || !buf_handle || !fbuf) {
+		pr_err("%s Invalid argument. ", __func__);
+		return -EINVAL;
+	}
+	if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_IMG_MODE)
+		image_mode = buf_handle->image_mode;
+	else
+		image_mode = GET_IMG_MODE(buf_handle->inst_handle);
+
+	if (image_mode > MSM_V4L2_EXT_CAPTURE_MODE_MAX) {
+		pr_err("%s Invalid image mode %d ", __func__, image_mode);
+		return -EINVAL;
+	}
 
 	msm_mctl_check_pp(p_mctl, image_mode, &pp_divert_type, &pp_type);
 	D("%s: pp_type=%d, pp_divert_type = %d, frame_id = 0x%x image_mode %d",
 		__func__, pp_type, pp_divert_type, frame_id, image_mode);
-	if (pp_type || pp_divert_type)
-		rc = msm_mctl_do_pp_divert(p_mctl,
-		image_mode, fbuf, frame_id, pp_type);
-	else {
-		idx = msm_mctl_img_mode_to_inst_index(
-				p_mctl, image_mode, 0);
-		if (idx < 0) {
-			/* check mctl node */
-			if ((image_mode >= 0) &&
-				p_mctl->pcam_ptr->mctl_node.
-					dev_inst_map[image_mode]) {
-				int index = p_mctl->pcam_ptr->mctl_node.
-					   dev_inst_map[image_mode]->my_index;
-				pcam_inst = p_mctl->pcam_ptr->mctl_node.
-					dev_inst[index];
-				D("%s: Mctl node index %d inst %p",
-					__func__, index, pcam_inst);
-				rc = msm_mctl_buf_done_proc(p_mctl, pcam_inst,
-					image_mode, fbuf,
-					&frame_id, 1);
-				D("%s mctl node buf done %d\n", __func__, 0);
-				return rc;
+	if (pp_type || pp_divert_type) {
+		rc = msm_mctl_do_pp_divert(p_mctl, buf_handle,
+			fbuf, frame_id, pp_type);
+	} else {
+		/* Find the instance on which vb2_buffer_done() needs to be
+		 * called, so that the user can get the buffer.
+		 * If the lookup type is
+		 * - By instance handle:
+		 *    Either mctl_pp inst idx or video inst idx should be set.
+		 *    Try to get the MCTL_PP inst idx first, if its not set,
+		 *    fall back to video inst idx. Once we get the inst idx,
+		 *    get the pcam_inst from the corresponding dev_inst[] map.
+		 *    If neither are set, its a serious error, trigger a BUG_ON.
+		 * - By image mode:
+		 *    Legacy usecase. Use the image mode and get the pcam_inst
+		 *    from the video node.
+		 */
+		if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_INST_HANDLE) {
+			idx = GET_MCTLPP_INST_IDX(buf_handle->inst_handle);
+			if (idx > MSM_DEV_INST_MAX) {
+				idx = GET_VIDEO_INST_IDX(
+					buf_handle->inst_handle);
+				BUG_ON(idx > MSM_DEV_INST_MAX);
+				pcam_inst = p_mctl->pcam_ptr->dev_inst[idx];
 			} else {
-			  pr_err("%s Invalid instance, dropping buffer\n",
-				  __func__);
-			  return idx;
+				pcam_inst = p_mctl->pcam_ptr->mctl_node.
+					dev_inst[idx];
 			}
+		} else if (buf_handle->buf_lookup_type ==
+				BUF_LOOKUP_BY_IMG_MODE) {
+			idx = msm_mctl_img_mode_to_inst_index(p_mctl,
+				buf_handle->image_mode, 0);
+			if (idx < 0) {
+				pr_err("%s Invalid idx %d ", __func__, idx);
+				return -EINVAL;
+			}
+			pcam_inst = p_mctl->pcam_ptr->dev_inst[idx];
+		} else {
+			pr_err("%s Invalid buffer lookup type %d", __func__,
+				buf_handle->buf_lookup_type);
+			return -EINVAL;
 		}
-		pcam_inst = p_mctl->pcam_ptr->dev_inst[idx];
+		if (!pcam_inst) {
+			pr_err("%s Invalid instance, Dropping buffer. ",
+				__func__);
+			return -EINVAL;
+		}
 		rc = msm_mctl_buf_done_proc(p_mctl, pcam_inst,
-				image_mode, fbuf,
-				&frame_id, 1);
+			fbuf, &frame_id, 1);
 	}
 	return rc;
 }
@@ -508,58 +540,99 @@
 	return ret;
 }
 
-struct msm_cam_v4l2_dev_inst *msm_mctl_get_pcam_inst(
-				struct msm_cam_media_controller *pmctl,
-				int image_mode)
+struct msm_cam_v4l2_dev_inst *msm_mctl_get_inst_by_img_mode(
+	struct msm_cam_media_controller *pmctl, uint32_t img_mode)
 {
 	struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
 	struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
 	int idx;
 
-	if (image_mode >= 0) {
-		/* Valid image mode. Search the mctl node first.
-		 * If mctl node doesnt have the instance, then
-		 * search in the user's video node */
-		if (pmctl->vfe_output_mode == VFE_OUTPUTS_MAIN_AND_THUMB
+	/* Valid image mode. Search the mctl node first.
+	 * If mctl node doesnt have the instance, then
+	 * search in the user's video node */
+	if (pmctl->vfe_output_mode == VFE_OUTPUTS_MAIN_AND_THUMB
 		|| pmctl->vfe_output_mode == VFE_OUTPUTS_THUMB_AND_MAIN) {
-			if (pcam->mctl_node.dev_inst_map[image_mode]
-			&& is_buffer_queued(pcam, image_mode)) {
-				idx =
-				pcam->mctl_node.dev_inst_map[image_mode]
-				->my_index;
-				pcam_inst = pcam->mctl_node.dev_inst[idx];
-				D("%s Found instance %p in mctl node device\n",
-				  __func__, pcam_inst);
-			} else if (pcam->dev_inst_map[image_mode]) {
-				idx = pcam->dev_inst_map[image_mode]->my_index;
-				pcam_inst = pcam->dev_inst[idx];
-				D("%s Found instance %p in video device\n",
+		if (pcam->mctl_node.dev_inst_map[img_mode]
+		&& is_buffer_queued(pcam, img_mode)) {
+			idx = pcam->mctl_node.dev_inst_map[img_mode]->my_index;
+			pcam_inst = pcam->mctl_node.dev_inst[idx];
+			D("%s Found instance %p in mctl node device\n",
 				__func__, pcam_inst);
-			}
-		} else {
-			if (pcam->mctl_node.dev_inst_map[image_mode]) {
-				idx = pcam->mctl_node.dev_inst_map[image_mode]
-				->my_index;
-				pcam_inst = pcam->mctl_node.dev_inst[idx];
-				D("%s Found instance %p in mctl node device\n",
+		} else if (pcam->dev_inst_map[img_mode]) {
+			idx = pcam->dev_inst_map[img_mode]->my_index;
+			pcam_inst = pcam->dev_inst[idx];
+			D("%s Found instance %p in video device\n",
 				__func__, pcam_inst);
-			} else if (pcam->dev_inst_map[image_mode]) {
-				idx = pcam->dev_inst_map[image_mode]->my_index;
-				pcam_inst = pcam->dev_inst[idx];
-				D("%s Found instance %p in video device\n",
-				__func__, pcam_inst);
-			}
 		}
-	} else
-		pr_err("%s Invalid image mode %d. Return NULL\n",
-			__func__, image_mode);
+	} else {
+		if (pcam->mctl_node.dev_inst_map[img_mode]) {
+			idx = pcam->mctl_node.dev_inst_map[img_mode]->my_index;
+			pcam_inst = pcam->mctl_node.dev_inst[idx];
+			D("%s Found instance %p in mctl node device\n",
+				__func__, pcam_inst);
+		} else if (pcam->dev_inst_map[img_mode]) {
+			idx = pcam->dev_inst_map[img_mode]->my_index;
+			pcam_inst = pcam->dev_inst[idx];
+			D("%s Found instance %p in video device\n",
+				__func__, pcam_inst);
+		}
+	}
+	return pcam_inst;
+}
+
+struct msm_cam_v4l2_dev_inst *msm_mctl_get_pcam_inst(
+				struct msm_cam_media_controller *pmctl,
+				struct msm_cam_buf_handle *buf_handle)
+{
+	struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
+	struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
+	int idx;
+
+	/* Get the pcam instance on based on the following rules:
+	 * If the lookup type is
+	 * - By instance handle:
+	 *    Either mctl_pp inst idx or video inst idx should be set.
+	 *    Try to get the MCTL_PP inst idx first, if its not set,
+	 *    fall back to video inst idx. Once we get the inst idx,
+	 *    get the pcam_inst from the corresponding dev_inst[] map.
+	 *    If neither are set, its a serious error, trigger a BUG_ON.
+	 * - By image mode:(Legacy usecase)
+	 *    If vfe is in configured in snapshot mode, first check if
+	 *    mctl pp node has a instance created for this image mode
+	 *    and if there is a buffer queued for that instance.
+	 *    If so, return that instance, otherwise get the pcam instance
+	 *    for this image_mode from the video instance.
+	 *    If the vfe is configured in any other mode, then first check
+	 *    if mctl pp node has a instance created for this image mode,
+	 *    otherwise get the pcam instance for this image mode from the
+	 *    video instance.
+	 */
+	if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_INST_HANDLE) {
+		idx = GET_MCTLPP_INST_IDX(buf_handle->inst_handle);
+		if (idx > MSM_DEV_INST_MAX) {
+			idx = GET_VIDEO_INST_IDX(buf_handle->inst_handle);
+			BUG_ON(idx > MSM_DEV_INST_MAX);
+			pcam_inst = pcam->dev_inst[idx];
+		} else {
+			pcam_inst = pcam->mctl_node.dev_inst[idx];
+		}
+	} else if ((buf_handle->buf_lookup_type == BUF_LOOKUP_BY_IMG_MODE)
+		&& (buf_handle->image_mode >= 0 &&
+		buf_handle->image_mode < MSM_V4L2_EXT_CAPTURE_MODE_MAX)) {
+		pcam_inst = msm_mctl_get_inst_by_img_mode(pmctl,
+				buf_handle->image_mode);
+	} else {
+		pr_err("%s Invalid buffer lookup type %d", __func__,
+			buf_handle->buf_lookup_type);
+	}
 	return pcam_inst;
 }
 
 int msm_mctl_reserve_free_buf(
-		struct msm_cam_media_controller *pmctl,
-		struct msm_cam_v4l2_dev_inst *pref_pcam_inst,
-		int image_mode, struct msm_free_buf *free_buf)
+	struct msm_cam_media_controller *pmctl,
+	struct msm_cam_v4l2_dev_inst *pref_pcam_inst,
+	struct msm_cam_buf_handle *buf_handle,
+	struct msm_free_buf *free_buf)
 {
 	struct msm_cam_v4l2_dev_inst *pcam_inst = pref_pcam_inst;
 	unsigned long flags = 0;
@@ -568,8 +641,8 @@
 	int rc = -EINVAL, i;
 	uint32_t buf_idx, plane_offset = 0;
 
-	if (!free_buf || !pmctl) {
-		pr_err("%s: free_buf/pmctl is null\n", __func__);
+	if (!free_buf || !pmctl || !buf_handle) {
+		pr_err("%s: Invalid argument passed\n", __func__);
 		return rc;
 	}
 	memset(free_buf, 0, sizeof(struct msm_free_buf));
@@ -579,7 +652,7 @@
 	 * If the preferred camera instance is NULL, get the
 	 * camera instance using the image mode passed */
 	if (!pcam_inst)
-		pcam_inst = msm_mctl_get_pcam_inst(pmctl, image_mode);
+		pcam_inst = msm_mctl_get_pcam_inst(pmctl, buf_handle);
 
 	if (!pcam_inst || !pcam_inst->streamon) {
 		pr_err("%s: stream is turned off\n", __func__);
@@ -641,7 +714,7 @@
 
 int msm_mctl_release_free_buf(struct msm_cam_media_controller *pmctl,
 				struct msm_cam_v4l2_dev_inst *pcam_inst,
-				int image_mode, struct msm_free_buf *free_buf)
+				struct msm_free_buf *free_buf)
 {
 	unsigned long flags = 0;
 	struct msm_frame_buffer *buf = NULL;
@@ -677,20 +750,39 @@
 }
 
 int msm_mctl_buf_done_pp(struct msm_cam_media_controller *pmctl,
-	int image_mode, struct msm_free_buf *frame, int dirty, int node_type)
+	struct msm_cam_buf_handle *buf_handle,
+	struct msm_free_buf *frame, int dirty, int node_type)
 {
-	struct msm_cam_v4l2_dev_inst *pcam_inst;
+	struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
 	int rc = 0, idx;
 
-	idx = msm_mctl_img_mode_to_inst_index(pmctl, image_mode, node_type);
-	if (idx < 0) {
-		pr_err("%s Invalid instance, buffer not released\n", __func__);
-		return idx;
+	if (!pmctl || !buf_handle) {
+		pr_err("%s Invalid argument ", __func__);
+		return -EINVAL;
 	}
-	if (node_type)
-		pcam_inst = pmctl->pcam_ptr->mctl_node.dev_inst[idx];
-	else
-		pcam_inst = pmctl->pcam_ptr->dev_inst[idx];
+
+	if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_INST_HANDLE) {
+		idx = GET_MCTLPP_INST_IDX(buf_handle->inst_handle);
+		if (idx > MSM_DEV_INST_MAX) {
+			idx = GET_VIDEO_INST_IDX(buf_handle->inst_handle);
+			BUG_ON(idx > MSM_DEV_INST_MAX);
+			pcam_inst = pmctl->pcam_ptr->dev_inst[idx];
+		} else {
+			pcam_inst = pmctl->pcam_ptr->mctl_node.dev_inst[idx];
+		}
+	} else if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_IMG_MODE) {
+		idx = msm_mctl_img_mode_to_inst_index(pmctl,
+			buf_handle->image_mode, node_type);
+		if (idx < 0) {
+			pr_err("%s Invalid instance, buffer not released\n",
+				__func__);
+			return idx;
+		}
+		if (node_type)
+			pcam_inst = pmctl->pcam_ptr->mctl_node.dev_inst[idx];
+		else
+			pcam_inst = pmctl->pcam_ptr->dev_inst[idx];
+	}
 	if (!pcam_inst) {
 		pr_err("%s Invalid instance, cannot send buf to user",
 			__func__);
@@ -701,121 +793,12 @@
 		__func__, pcam_inst, frame->ch_paddr[0], dirty);
 	if (dirty)
 		/* the frame is dirty, not going to disptach to app */
-		rc = msm_mctl_release_free_buf(pmctl, pcam_inst,
-						image_mode, frame);
+		rc = msm_mctl_release_free_buf(pmctl, pcam_inst, frame);
 	else
-		rc = msm_mctl_buf_done_proc(pmctl, pcam_inst,
-			image_mode, frame, NULL, 0);
+		rc = msm_mctl_buf_done_proc(pmctl, pcam_inst, frame, NULL, 0);
 	return rc;
 }
 
-struct msm_frame_buffer *msm_mctl_get_free_buf(
-		struct msm_cam_media_controller *pmctl,
-		int image_mode)
-{
-	struct msm_cam_v4l2_dev_inst *pcam_inst;
-	unsigned long flags = 0;
-	struct msm_frame_buffer *buf = NULL;
-	int rc = -EINVAL, idx;
-
-	idx = msm_mctl_img_mode_to_inst_index(pmctl,
-		image_mode, 0);
-	if (idx < 0) {
-		pr_err("%s Invalid instance, cant get buffer\n", __func__);
-		return NULL;
-	}
-	pcam_inst = pmctl->pcam_ptr->dev_inst[idx];
-	if (!pcam_inst->streamon) {
-		D("%s: stream 0x%p is off\n", __func__, pcam_inst);
-		return NULL;
-	}
-	spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
-	if (!list_empty(&pcam_inst->free_vq)) {
-		list_for_each_entry(buf, &pcam_inst->free_vq, list) {
-			if (buf->state == MSM_BUFFER_STATE_QUEUED) {
-				buf->state = MSM_BUFFER_STATE_RESERVED;
-				rc = 0;
-				break;
-			}
-		}
-	}
-	if (rc != 0) {
-		D("%s:No free buffer available: inst = 0x%p ",
-				__func__, pcam_inst);
-		buf = NULL;
-	}
-	spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
-	return buf;
-}
-
-int msm_mctl_put_free_buf(
-		struct msm_cam_media_controller *pmctl,
-		int image_mode, struct msm_frame_buffer *my_buf)
-{
-	struct msm_cam_v4l2_dev_inst *pcam_inst;
-	unsigned long flags = 0;
-	int rc = 0, idx;
-	struct msm_frame_buffer *buf = NULL;
-
-	idx = msm_mctl_img_mode_to_inst_index(pmctl,
-		image_mode, 0);
-	if (idx < 0) {
-		pr_err("%s Invalid instance, cant put buffer\n", __func__);
-		return idx;
-	}
-	pcam_inst = pmctl->pcam_ptr->dev_inst[idx];
-	if (!pcam_inst->streamon) {
-		D("%s: stream 0x%p is off\n", __func__, pcam_inst);
-		return rc;
-	}
-	spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
-	if (!list_empty(&pcam_inst->free_vq)) {
-		list_for_each_entry(buf, &pcam_inst->free_vq, list) {
-			if (my_buf == buf) {
-				buf->state = MSM_BUFFER_STATE_QUEUED;
-				spin_unlock_irqrestore(&pcam_inst->vq_irqlock,
-					flags);
-				return 0;
-			}
-		}
-	}
-	spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
-	return rc;
-}
-
-int msm_mctl_buf_del(struct msm_cam_media_controller *pmctl,
-	int image_mode,
-	struct msm_frame_buffer *my_buf)
-{
-	struct msm_cam_v4l2_dev_inst *pcam_inst;
-	struct msm_frame_buffer *buf = NULL;
-	unsigned long flags = 0;
-	int idx;
-
-	idx = msm_mctl_img_mode_to_inst_index(pmctl,
-		image_mode, 0);
-	if (idx < 0) {
-		pr_err("%s Invalid instance, cant delete buffer\n", __func__);
-		return idx;
-	}
-	pcam_inst = pmctl->pcam_ptr->dev_inst[idx];
-	D("%s: idx = %d, pinst=0x%p", __func__, idx, pcam_inst);
-	spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
-	if (!list_empty(&pcam_inst->free_vq)) {
-		list_for_each_entry(buf, &pcam_inst->free_vq, list) {
-			if (my_buf == buf) {
-				list_del_init(&buf->list);
-				spin_unlock_irqrestore(&pcam_inst->vq_irqlock,
-					flags);
-				return 0;
-			}
-		}
-	}
-	spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
-	pr_err("%s: buf 0x%p not found", __func__, my_buf);
-	return -EINVAL;
-}
-
 int msm_mctl_buf_return_buf(struct msm_cam_media_controller *pmctl,
 			int image_mode, struct msm_frame_buffer *rbuf)
 {
diff --git a/drivers/media/video/msm/msm_mctl_pp.c b/drivers/media/video/msm/msm_mctl_pp.c
index abcee4b..dcb7c51 100644
--- a/drivers/media/video/msm/msm_mctl_pp.c
+++ b/drivers/media/video/msm/msm_mctl_pp.c
@@ -153,61 +153,96 @@
 	spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
 	return 0;
 }
+
 static struct msm_cam_v4l2_dev_inst *msm_mctl_get_pcam_inst_for_divert(
-		struct msm_cam_media_controller *pmctl,
-		int image_mode, struct msm_free_buf *fbuf, int *node_type)
+	struct msm_cam_media_controller *pmctl,
+	struct msm_cam_buf_handle *buf_handle,
+	struct msm_free_buf *fbuf, int *node_type)
 {
 	struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
 	struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
 	int idx;
+	uint32_t img_mode;
 
-	if (image_mode >= 0) {
-		/* Valid image mode. Search the mctl node first.
-		 * If mctl node doesnt have the instance, then
-		 * search in the user's video node */
-		if (pcam->mctl_node.dev_inst_map[image_mode]
-		&& is_buf_in_queue(pcam, fbuf, image_mode)) {
-			idx =
-			pcam->mctl_node.dev_inst_map[image_mode]->my_index;
-			pcam_inst = pcam->mctl_node.dev_inst[idx];
-			*node_type = MCTL_NODE;
-			D("%s Found instance %p in mctl node device\n",
-				__func__, pcam_inst);
-		} else if (pcam->dev_inst_map[image_mode]) {
-			idx = pcam->dev_inst_map[image_mode]->my_index;
+	if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_INST_HANDLE) {
+		idx = GET_MCTLPP_INST_IDX(buf_handle->inst_handle);
+		if (idx > MSM_DEV_INST_MAX) {
+			idx = GET_VIDEO_INST_IDX(buf_handle->inst_handle);
+			BUG_ON(idx > MSM_DEV_INST_MAX);
 			pcam_inst = pcam->dev_inst[idx];
 			*node_type = VIDEO_NODE;
-			D("%s Found instance %p in video device",
-				__func__, pcam_inst);
-		} else
+		} else {
+			pcam_inst = pcam->mctl_node.dev_inst[idx];
+			*node_type = MCTL_NODE;
+		}
+	} else if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_IMG_MODE) {
+		img_mode = buf_handle->image_mode;
+		if (img_mode >= 0 && img_mode < MSM_V4L2_EXT_CAPTURE_MODE_MAX) {
+			/* Valid image mode. Search the mctl node first.
+			 * If mctl node doesnt have the instance, then
+			 * search in the user's video node */
+			if (pcam->mctl_node.dev_inst_map[img_mode]
+				&& is_buf_in_queue(pcam, fbuf, img_mode)) {
+				idx = pcam->mctl_node.
+					dev_inst_map[img_mode]->my_index;
+				pcam_inst = pcam->mctl_node.dev_inst[idx];
+				*node_type = MCTL_NODE;
+				D("%s Found instance %p in mctl node device\n",
+					__func__, pcam_inst);
+			} else if (pcam->dev_inst_map[img_mode]) {
+				idx = pcam->dev_inst_map[img_mode]->my_index;
+				pcam_inst = pcam->dev_inst[idx];
+				*node_type = VIDEO_NODE;
+				D("%s Found instance %p in video device",
+					__func__, pcam_inst);
+			} else {
+				pr_err("%s Cannot find instance for %d.\n",
+					__func__, img_mode);
+			}
+		} else {
 			pr_err("%s Invalid image mode %d. Return NULL\n",
-				   __func__, image_mode);
+				__func__, buf_handle->image_mode);
+		}
+	} else {
+		pr_err("%s Invalid buffer lookup type ", __func__);
 	}
-		return pcam_inst;
+	return pcam_inst;
 }
 
 int msm_mctl_do_pp_divert(
 	struct msm_cam_media_controller *p_mctl,
-	int image_mode, struct msm_free_buf *fbuf,
+	struct msm_cam_buf_handle *buf_handle,
+	struct msm_free_buf *fbuf,
 	uint32_t frame_id, int pp_type)
 {
 	struct msm_cam_v4l2_dev_inst *pcam_inst;
-	int rc = 0, i, buf_idx;
+	int rc = 0, i, buf_idx, node;
 	int del_buf = 0; /* delete from free queue */
 	struct msm_cam_evt_divert_frame div;
 	struct msm_frame_buffer *vb = NULL;
 	struct videobuf2_contig_pmem *mem;
-	int node;
+	uint32_t image_mode;
 
-	pcam_inst = msm_mctl_get_pcam_inst_for_divert
-		(p_mctl, image_mode, fbuf, &node);
+	if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_IMG_MODE) {
+		image_mode = buf_handle->image_mode;
+		div.frame.inst_handle = 0;
+	} else if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_INST_HANDLE) {
+		image_mode = GET_IMG_MODE(buf_handle->inst_handle);
+		div.frame.inst_handle = buf_handle->inst_handle;
+	} else {
+		pr_err("%s Invalid buffer lookup type %d ", __func__,
+			buf_handle->buf_lookup_type);
+		return -EINVAL;
+	}
+
+	pcam_inst = msm_mctl_get_pcam_inst_for_divert(p_mctl,
+			buf_handle, fbuf, &node);
 	if (!pcam_inst) {
 		pr_err("%s Invalid instance. Cannot divert frame.\n",
 			__func__);
 		return -EINVAL;
 	}
-	vb = msm_mctl_buf_find(p_mctl, pcam_inst,
-		  del_buf, image_mode, fbuf);
+	vb = msm_mctl_buf_find(p_mctl, pcam_inst, del_buf, fbuf);
 	if (!vb)
 		return -EINVAL;
 
@@ -392,50 +427,16 @@
 			struct msm_mctl_pp_cmd *pp_cmd)
 {
 	int rc = 0;
-	struct msm_mctl_pp_frame_buffer pp_buffer;
-	struct msm_frame_buffer *buf = NULL;
-	void __user *argp = (void __user *)pp_cmd->value;
-	int img_mode;
 	unsigned long flags;
 
 	switch (pp_cmd->id) {
-	case MCTL_CMD_GET_FRAME_BUFFER: {
-		if (copy_from_user(&pp_buffer, pp_cmd->value,
-				sizeof(pp_buffer)))
-			return -EFAULT;
-		img_mode = msm_mctl_pp_path_to_img_mode(pp_buffer.path);
-		if (img_mode < 0) {
-			pr_err("%s Invalid image mode\n", __func__);
-			return img_mode;
-		}
-		buf = msm_mctl_get_free_buf(p_mctl, img_mode);
-		pp_buffer.buf_handle = (uint32_t)buf;
-		if (copy_to_user((void *)argp,
-			&pp_buffer,
-			sizeof(struct msm_mctl_pp_frame_buffer))) {
-			ERR_COPY_TO_USER();
-			rc = -EFAULT;
-		}
-		break;
-	}
-	case MCTL_CMD_PUT_FRAME_BUFFER: {
-		if (copy_from_user(&pp_buffer, pp_cmd->value,
-				sizeof(pp_buffer)))
-			return -EFAULT;
-		img_mode = msm_mctl_pp_path_to_img_mode(pp_buffer.path);
-		if (img_mode < 0) {
-			pr_err("%s Invalid image mode\n", __func__);
-			return img_mode;
-		}
-		buf = (struct msm_frame_buffer *)pp_buffer.buf_handle;
-		msm_mctl_put_free_buf(p_mctl, img_mode, buf);
-		break;
-	}
 	case MCTL_CMD_DIVERT_FRAME_PP_PATH: {
 		struct msm_mctl_pp_divert_pp divert_pp;
 		if (copy_from_user(&divert_pp, pp_cmd->value,
-				sizeof(divert_pp)))
+				sizeof(divert_pp))) {
+			ERR_COPY_FROM_USER();
 			return -EFAULT;
+		}
 		D("%s: PP_PATH, path=%d",
 			__func__, divert_pp.path);
 		spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
@@ -490,17 +491,20 @@
 	struct msm_cam_media_controller *p_mctl,
 	void __user *arg)
 {
-	struct msm_cam_evt_divert_frame frame;
+	struct msm_cam_evt_divert_frame div_frame;
 	int image_mode, rc = 0;
 	struct msm_free_buf free_buf;
 	struct msm_cam_v4l2_dev_inst *pcam_inst;
+	struct msm_cam_buf_handle buf_handle;
 
 	memset(&free_buf, 0, sizeof(struct msm_free_buf));
-	if (copy_from_user(&frame, arg,
-		sizeof(struct msm_cam_evt_divert_frame)))
+	if (copy_from_user(&div_frame, arg,
+		sizeof(struct msm_cam_evt_divert_frame))) {
+		ERR_COPY_FROM_USER();
 		return -EFAULT;
+	}
 
-	image_mode = frame.image_mode;
+	image_mode = div_frame.image_mode;
 	if (image_mode <= 0) {
 		pr_err("%s Invalid image mode %d", __func__, image_mode);
 		return -EINVAL;
@@ -511,17 +515,25 @@
 		pr_err("%s Instance already closed ", __func__);
 		return -EINVAL;
 	}
+	if (div_frame.frame.inst_handle) {
+		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
+		buf_handle.inst_handle = div_frame.frame.inst_handle;
+	} else {
+		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_IMG_MODE;
+		buf_handle.image_mode = image_mode;
+	}
 	rc = msm_mctl_reserve_free_buf(p_mctl, pcam_inst,
-					image_mode, &free_buf);
+					&buf_handle, &free_buf);
 	if (rc == 0) {
-		msm_mctl_pp_get_phy_addr(pcam_inst, free_buf.vb, &frame.frame);
-		if (copy_to_user((void *)arg, &frame, sizeof(frame))) {
+		msm_mctl_pp_get_phy_addr(pcam_inst,
+			free_buf.vb, &div_frame.frame);
+		if (copy_to_user((void *)arg, &div_frame, sizeof(div_frame))) {
 			ERR_COPY_TO_USER();
 			rc = -EFAULT;
 		}
 	}
 	D("%s: reserve free buf got buffer %d from %p rc = %d, phy = 0x%x",
-		__func__, frame.frame.buf_idx,
+		__func__, div_frame.frame.buf_idx,
 		pcam_inst, rc, free_buf.ch_paddr[0]);
 	return rc;
 }
@@ -535,10 +547,13 @@
 	struct msm_pp_frame *frame;
 	int image_mode, rc = 0;
 	struct msm_free_buf free_buf;
+	struct msm_cam_buf_handle buf_handle;
 
 	if (copy_from_user(&div_frame, arg,
-		sizeof(struct msm_cam_evt_divert_frame)))
+		sizeof(struct msm_cam_evt_divert_frame))) {
+		ERR_COPY_FROM_USER();
 		return -EFAULT;
+	}
 
 	image_mode = div_frame.image_mode;
 	if (image_mode < 0) {
@@ -551,15 +566,21 @@
 	else
 		free_buf.ch_paddr[0] = frame->sp.phy_addr;
 
-	pcam_inst = msm_mctl_get_pcam_inst(p_mctl, image_mode);
+	if (div_frame.frame.inst_handle) {
+		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
+		buf_handle.inst_handle = div_frame.frame.inst_handle;
+	} else {
+		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_IMG_MODE;
+		buf_handle.image_mode = image_mode;
+	}
+	pcam_inst = msm_mctl_get_pcam_inst(p_mctl, &buf_handle);
 	if (!pcam_inst) {
 		pr_err("%s Invalid instance. Cannot release frame.\n",
 			__func__);
 		return -EINVAL;
 	}
 
-	rc = msm_mctl_release_free_buf(p_mctl, pcam_inst,
-					image_mode, &free_buf);
+	rc = msm_mctl_release_free_buf(p_mctl, pcam_inst, &free_buf);
 	D("%s: release free buf, rc = %d, phy = 0x%x",
 		__func__, rc, free_buf.ch_paddr[0]);
 
@@ -573,11 +594,13 @@
 	unsigned long flags;
 	spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
 	if (copy_from_user(&p_mctl->pp_info.pp_key,
-			arg, sizeof(p_mctl->pp_info.pp_key)))
+			arg, sizeof(p_mctl->pp_info.pp_key))) {
+		ERR_COPY_FROM_USER();
 		rc = -EFAULT;
-	else
+	} else {
 		D("%s: mctl=0x%p, pp_key_setting=0x%x",
 			__func__, p_mctl, p_mctl->pp_info.pp_key);
+	}
 	spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
 	return rc;
 }
@@ -591,12 +614,24 @@
 	int dirty = 0;
 	struct msm_free_buf buf;
 	unsigned long flags;
+	struct msm_cam_buf_handle buf_handle;
 
-	if (copy_from_user(&frame, arg, sizeof(frame)))
+	if (copy_from_user(&frame, arg, sizeof(frame))) {
+		ERR_COPY_FROM_USER();
 		return -EFAULT;
+	}
 
 	spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
-	image_mode = msm_mctl_pp_path_to_img_mode(frame.path);
+	if (frame.inst_handle) {
+		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
+		buf_handle.inst_handle = frame.inst_handle;
+		image_mode = GET_IMG_MODE(frame.inst_handle);
+	} else {
+		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_IMG_MODE;
+		buf_handle.image_mode =
+			msm_mctl_pp_path_to_img_mode(frame.path);
+		image_mode = buf_handle.image_mode;
+	}
 	if (image_mode < 0) {
 		pr_err("%s Invalid image mode\n", __func__);
 		return image_mode;
@@ -622,8 +657,7 @@
 			buf.ch_paddr[0] = frame.sp.phy_addr + frame.sp.y_off;
 	}
 	spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
-	/* here buf.addr is phy_addr */
-	rc = msm_mctl_buf_done_pp(p_mctl, image_mode, &buf, dirty, 0);
+	rc = msm_mctl_buf_done_pp(p_mctl, &buf_handle, &buf, dirty, 0);
 	return rc;
 }
 
@@ -636,10 +670,14 @@
 	int dirty = 0;
 	struct msm_free_buf buf;
 	unsigned long flags;
+	struct msm_cam_buf_handle buf_handle;
+
 	D("%s enter\n", __func__);
 
-	if (copy_from_user(&frame, arg, sizeof(frame)))
+	if (copy_from_user(&frame, arg, sizeof(frame))) {
+		ERR_COPY_FROM_USER();
 		return -EFAULT;
+	}
 
 	spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
 	D("%s Frame path: %d\n", __func__, frame.path);
@@ -665,6 +703,14 @@
 		goto err;
 	}
 
+	if (frame.inst_handle) {
+		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
+		buf_handle.inst_handle = frame.inst_handle;
+	} else {
+		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_IMG_MODE;
+		buf_handle.image_mode = image_mode;
+	}
+
 	if (frame.num_planes > 1)
 		buf.ch_paddr[0] = frame.mp[0].phy_addr +
 					frame.mp[0].data_offset;
@@ -673,7 +719,7 @@
 
 	spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
 	D("%s Frame done id: %d\n", __func__, frame.frame_id);
-	rc = msm_mctl_buf_done_pp(p_mctl, image_mode,
+	rc = msm_mctl_buf_done_pp(p_mctl, &buf_handle,
 		&buf, dirty, frame.node_type);
 	return rc;
 err:
diff --git a/drivers/media/video/msm/msm_vfe31_v4l2.c b/drivers/media/video/msm/msm_vfe31_v4l2.c
index b520a92..18168ee 100644
--- a/drivers/media/video/msm/msm_vfe31_v4l2.c
+++ b/drivers/media/video/msm/msm_vfe31_v4l2.c
@@ -643,7 +643,7 @@
 		vfe31_ctrl->vfebase + VFE_GLOBAL_RESET);
 }
 
-static void vfe31_subdev_notify(int id, int path, int image_mode)
+static void vfe31_subdev_notify(int id, int path, uint32_t inst_handle)
 {
 	struct msm_vfe_resp rp;
 	struct msm_frame_info frame_info;
@@ -652,7 +652,7 @@
 	memset(&rp, 0, sizeof(struct msm_vfe_resp));
 	CDBG("vfe31_subdev_notify : msgId = %d\n", id);
 	rp.evt_msg.type   = MSM_CAMERA_MSG;
-	frame_info.image_mode = image_mode;
+	frame_info.inst_handle = inst_handle;
 	frame_info.path = path;
 	rp.evt_msg.data = &frame_info;
 	rp.type	   = id;
@@ -663,20 +663,21 @@
 static int vfe31_config_axi(int mode, uint32_t *ao)
 {
 	uint32_t *ch_info;
-	uint32_t *axi_cfg = ao+V31_AXI_RESERVED;
+	uint32_t *axi_cfg = ao + V31_AXI_RESERVED;
 	/* Update the corresponding write masters for each output*/
 	ch_info = axi_cfg + V31_AXI_CFG_LEN;
 	vfe31_ctrl->outpath.out0.ch0 = 0x0000FFFF & *ch_info;
 	vfe31_ctrl->outpath.out0.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
-	vfe31_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info;
-	vfe31_ctrl->outpath.out0.image_mode = 0x0000FFFF & (*ch_info++ >> 16);
+	vfe31_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info++;
+	vfe31_ctrl->outpath.out0.inst_handle = *ch_info++;
 	vfe31_ctrl->outpath.out1.ch0 = 0x0000FFFF & *ch_info;
 	vfe31_ctrl->outpath.out1.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
-	vfe31_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info;
-	vfe31_ctrl->outpath.out1.image_mode = 0x0000FFFF & (*ch_info++ >> 16);
+	vfe31_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info++;
+	vfe31_ctrl->outpath.out1.inst_handle = *ch_info++;
 	vfe31_ctrl->outpath.out2.ch0 = 0x0000FFFF & *ch_info;
 	vfe31_ctrl->outpath.out2.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
 	vfe31_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info++;
+	vfe31_ctrl->outpath.out2.inst_handle = *ch_info++;
 
 	switch (mode) {
 	case OUTPUT_PRIM:
@@ -713,7 +714,7 @@
 	msm_camera_io_memcpy(vfe31_ctrl->vfebase +
 		vfe31_cmd[VFE_CMD_AXI_OUT_CFG].offset, axi_cfg,
 		vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length - V31_AXI_CH_INF_LEN -
-			V31_AXI_RESERVED);
+			V31_AXI_RESERVED_LEN);
 	return 0;
 }
 
@@ -1301,14 +1302,14 @@
 {
 	struct vfe31_output_ch *outch = NULL;
 	struct msm_free_buf *b = NULL;
-	uint32_t image_mode = 0;
+	uint32_t inst_handle = 0;
 
 	if (path == VFE_MSG_OUTPUT_PRIMARY)
-		image_mode = vfe31_ctrl->outpath.out0.image_mode;
+		inst_handle = vfe31_ctrl->outpath.out0.inst_handle;
 	else
-		image_mode = vfe31_ctrl->outpath.out1.image_mode;
+		inst_handle = vfe31_ctrl->outpath.out1.inst_handle;
 
-	vfe31_subdev_notify(id, path, image_mode);
+	vfe31_subdev_notify(id, path, inst_handle);
 	outch = vfe31_get_ch(path);
 	if (outch->free_buf.ch_paddr[0])
 		b = &outch->free_buf;
@@ -1318,14 +1319,14 @@
 {
 	struct vfe31_output_ch *outch = NULL;
 	int rc = 0;
-	uint32_t image_mode = 0;
+	uint32_t inst_handle = 0;
 
 	if (path == VFE_MSG_OUTPUT_PRIMARY)
-		image_mode = vfe31_ctrl->outpath.out0.image_mode;
+		inst_handle = vfe31_ctrl->outpath.out0.inst_handle;
 	else
-		image_mode = vfe31_ctrl->outpath.out1.image_mode;
+		inst_handle = vfe31_ctrl->outpath.out1.inst_handle;
 
-	vfe31_subdev_notify(id, path, image_mode);
+	vfe31_subdev_notify(id, path, inst_handle);
 	outch = vfe31_get_ch(path);
 	if (outch->ping.ch_paddr[0] && outch->pong.ch_paddr[0]) {
 		/* Configure Preview Ping Pong */
@@ -1477,16 +1478,26 @@
 	case VFE_CMD_START_RECORDING:
 		pr_info("vfe31_proc_general: cmdID = %s\n",
 			vfe31_general_cmd[cmd->id]);
+		if (copy_from_user(&temp1, (void __user *)(cmd->value),
+				sizeof(uint32_t))) {
+			pr_err("%s Error copying inst_handle for recording\n",
+				__func__);
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
 		if (vfe31_ctrl->operation_mode ==
-			VFE_OUTPUTS_PREVIEW_AND_VIDEO)
+			VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
+			vfe31_ctrl->outpath.out1.inst_handle = temp1;
 			rc = vfe31_configure_pingpong_buffers(
 				VFE_MSG_V31_START_RECORDING,
 				VFE_MSG_OUTPUT_SECONDARY);
-		else if (vfe31_ctrl->operation_mode ==
-			VFE_OUTPUTS_VIDEO_AND_PREVIEW)
+		} else if (vfe31_ctrl->operation_mode ==
+			VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
+			vfe31_ctrl->outpath.out0.inst_handle = temp1;
 			rc = vfe31_configure_pingpong_buffers(
 				VFE_MSG_V31_START_RECORDING,
 				VFE_MSG_OUTPUT_PRIMARY);
+		}
 		if (rc < 0) {
 			pr_err("%s error configuring pingpong buffers"
 				" for video", __func__);
@@ -1916,6 +1927,14 @@
 		break;
 
 	case VFE_CMD_LIVESHOT:
+		if (copy_from_user(&temp1, (void __user *)(cmd->value),
+				sizeof(uint32_t))) {
+			pr_err("%s Error copying inst_handle for liveshot ",
+				__func__);
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		vfe31_ctrl->outpath.out0.inst_handle = temp1;
 		/* Configure primary channel */
 		rc = vfe31_configure_pingpong_buffers(VFE_MSG_V31_CAPTURE,
 			VFE_MSG_OUTPUT_PRIMARY);
@@ -2715,12 +2734,12 @@
 }
 static void vfe_send_outmsg(struct v4l2_subdev *sd, uint8_t msgid,
 	uint32_t ch0_paddr, uint32_t ch1_paddr,
-	uint32_t ch2_paddr, uint32_t image_mode)
+	uint32_t ch2_paddr, uint32_t inst_handle)
 {
 	struct isp_msg_output msg;
 
 	msg.output_id		= msgid;
-	msg.buf.image_mode	= image_mode;
+	msg.buf.inst_handle	= inst_handle;
 	msg.buf.ch_paddr[0]	= ch0_paddr;
 	msg.buf.ch_paddr[1]	= ch1_paddr;
 	msg.buf.ch_paddr[2]	= ch2_paddr;
@@ -2803,7 +2822,7 @@
 		vfe_send_outmsg(&vfe31_ctrl->subdev,
 			MSG_ID_OUTPUT_PRIMARY, ch0_paddr,
 			ch1_paddr, ch2_paddr,
-			vfe31_ctrl->outpath.out0.image_mode);
+			vfe31_ctrl->outpath.out0.inst_handle);
 
 		if (vfe31_ctrl->liveshot_state == VFE_STATE_STOPPED)
 			vfe31_ctrl->liveshot_state = VFE_STATE_IDLE;
@@ -2876,7 +2895,7 @@
 		vfe_send_outmsg(&vfe31_ctrl->subdev,
 			MSG_ID_OUTPUT_SECONDARY, ch0_paddr,
 			ch1_paddr, ch2_paddr,
-			vfe31_ctrl->outpath.out1.image_mode);
+			vfe31_ctrl->outpath.out1.inst_handle);
 	} else {
 		vfe31_ctrl->outpath.out1.frame_drop_cnt++;
 		CDBG("path_irq_1 - no free buffer!\n");
@@ -3541,15 +3560,25 @@
 	struct msm_cam_media_controller *pmctl =
 		(struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
 	struct msm_isp_cmd vfecmd;
-	struct msm_camvfe_params *vfe_params =
-		(struct msm_camvfe_params *)arg;
-	struct msm_vfe_cfg_cmd *cmd = vfe_params->vfe_cfg;
-	void *data = vfe_params->data;
+	struct msm_camvfe_params *vfe_params;
+	struct msm_vfe_cfg_cmd *cmd;
+	void *data;
 
 	long rc = 0;
 	struct vfe_cmd_stats_buf *scfg = NULL;
 	struct vfe_cmd_stats_ack *sack = NULL;
 
+	if (subdev_cmd == VIDIOC_MSM_VFE_INIT) {
+		CDBG("%s init\n", __func__);
+		return msm_vfe_subdev_init(sd);
+	} else if (subdev_cmd == VIDIOC_MSM_VFE_RELEASE) {
+		msm_vfe_subdev_release(sd);
+		return 0;
+	}
+	vfe_params = (struct msm_camvfe_params *)arg;
+	cmd = vfe_params->vfe_cfg;
+	data = vfe_params->data;
+
 	switch (cmd->cmd_type) {
 	case VFE_CMD_STATS_REQBUF:
 	case VFE_CMD_STATS_ENQUEUEBUF:
@@ -3575,186 +3604,190 @@
 					return -EFAULT;
 				}
 		} else {
-		/* here eith stats release or frame release. */
-		if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
-			cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
-			cmd->cmd_type != CMD_CONFIG_FREE_BUF_ADDR) {
-			/* then must be stats release. */
-			if (!data) {
-				pr_err("%s: data = NULL, cmd->cmd_type = %d",
-					__func__, cmd->cmd_type);
-				return -EFAULT;
-			}
-			sack = kmalloc(sizeof(struct vfe_cmd_stats_ack),
+			/* here eith stats release or frame release. */
+			if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
+				cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
+				cmd->cmd_type != CMD_CONFIG_FREE_BUF_ADDR) {
+				/* then must be stats release. */
+				if (!data) {
+					pr_err("%s: data = NULL," \
+						"cmd->cmd_type = %d\n",
+						__func__, cmd->cmd_type);
+					return -EFAULT;
+				}
+				sack = kmalloc(sizeof(struct vfe_cmd_stats_ack),
 							GFP_ATOMIC);
-			if (!sack) {
-				pr_err("%s: no mem for cmd->cmd_type = %d",
-					 __func__, cmd->cmd_type);
-				return -ENOMEM;
+				if (!sack) {
+					pr_err("%s: no mem for" \
+						"cmd->cmd_type = %d\n",
+						__func__, cmd->cmd_type);
+					return -ENOMEM;
+				}
+
+				sack->nextStatsBuf = *(uint32_t *)data;
+			}
+		}
+
+		CDBG("%s: cmdType = %d\n", __func__, cmd->cmd_type);
+
+		if ((cmd->cmd_type == CMD_STATS_AF_ENABLE)    ||
+			(cmd->cmd_type == CMD_STATS_AWB_ENABLE)   ||
+			(cmd->cmd_type == CMD_STATS_IHIST_ENABLE) ||
+			(cmd->cmd_type == CMD_STATS_RS_ENABLE)    ||
+			(cmd->cmd_type == CMD_STATS_CS_ENABLE)    ||
+			(cmd->cmd_type == CMD_STATS_AEC_ENABLE)) {
+			scfg = NULL;
+			goto vfe31_config_done;
+		}
+		switch (cmd->cmd_type) {
+		case CMD_GENERAL: {
+			rc = vfe31_proc_general(pmctl, &vfecmd);
+			}
+			break;
+		case CMD_CONFIG_PING_ADDR: {
+			int path = *((int *)cmd->value);
+			struct vfe31_output_ch *outch = vfe31_get_ch(path);
+			outch->ping = *((struct msm_free_buf *)data);
+			}
+			break;
+
+		case CMD_CONFIG_PONG_ADDR: {
+			int path = *((int *)cmd->value);
+			struct vfe31_output_ch *outch = vfe31_get_ch(path);
+			outch->pong = *((struct msm_free_buf *)data);
+			}
+			break;
+
+		case CMD_CONFIG_FREE_BUF_ADDR: {
+			int path = *((int *)cmd->value);
+			struct vfe31_output_ch *outch = vfe31_get_ch(path);
+			outch->free_buf = *((struct msm_free_buf *)data);
+			}
+			break;
+
+		case CMD_SNAP_BUF_RELEASE:
+			break;
+
+		case CMD_AXI_CFG_PRIM: {
+			uint32_t *axio = NULL;
+			axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+			if (!axio) {
+				rc = -ENOMEM;
+				break;
 			}
 
-			sack->nextStatsBuf = *(uint32_t *)data;
-		}
-	  }
-
-	CDBG("%s: cmdType = %d\n", __func__, cmd->cmd_type);
-
-	if ((cmd->cmd_type == CMD_STATS_AF_ENABLE)    ||
-		(cmd->cmd_type == CMD_STATS_AWB_ENABLE)   ||
-		(cmd->cmd_type == CMD_STATS_IHIST_ENABLE) ||
-		(cmd->cmd_type == CMD_STATS_RS_ENABLE)    ||
-		(cmd->cmd_type == CMD_STATS_CS_ENABLE)    ||
-		(cmd->cmd_type == CMD_STATS_AEC_ENABLE)) {
-		scfg = NULL;
-		goto vfe31_config_done;
-	}
-	switch (cmd->cmd_type) {
-	case CMD_GENERAL: {
-		rc = vfe31_proc_general(pmctl, &vfecmd);
-		}
-		break;
-	case CMD_CONFIG_PING_ADDR: {
-		int path = *((int *)cmd->value);
-		struct vfe31_output_ch *outch = vfe31_get_ch(path);
-		outch->ping = *((struct msm_free_buf *)data);
-		}
-		break;
-
-	case CMD_CONFIG_PONG_ADDR: {
-		int path = *((int *)cmd->value);
-		struct vfe31_output_ch *outch = vfe31_get_ch(path);
-		outch->pong = *((struct msm_free_buf *)data);
-		}
-		break;
-
-	case CMD_CONFIG_FREE_BUF_ADDR: {
-		int path = *((int *)cmd->value);
-		struct vfe31_output_ch *outch = vfe31_get_ch(path);
-		outch->free_buf = *((struct msm_free_buf *)data);
-		}
-		break;
-
-	case CMD_SNAP_BUF_RELEASE:
-		break;
-
-	case CMD_AXI_CFG_PRIM: {
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+			if (copy_from_user(axio, (void __user *)(vfecmd.value),
 				vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+				kfree(axio);
+				rc = -EFAULT;
+				break;
+			}
+			vfe31_config_axi(OUTPUT_PRIM, axio);
 			kfree(axio);
-			rc = -EFAULT;
+			}
 			break;
-		}
-		vfe31_config_axi(OUTPUT_PRIM, axio);
-		kfree(axio);
-		}
-		break;
 
-	case CMD_AXI_CFG_PRIM_ALL_CHNLS: {
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
+		case CMD_AXI_CFG_PRIM_ALL_CHNLS: {
+			uint32_t *axio = NULL;
+			axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
+					GFP_ATOMIC);
+			if (!axio) {
+				rc = -ENOMEM;
+				break;
+			}
 
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+			if (copy_from_user(axio, (void __user *)(vfecmd.value),
 				vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+				kfree(axio);
+				rc = -EFAULT;
+				break;
+			}
+			vfe31_config_axi(OUTPUT_PRIM_ALL_CHNLS, axio);
 			kfree(axio);
-			rc = -EFAULT;
+		}
 			break;
-		}
-		vfe31_config_axi(OUTPUT_PRIM_ALL_CHNLS, axio);
-		kfree(axio);
-		}
-		break;
 
-	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC: {
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
+		case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC: {
+			uint32_t *axio = NULL;
+			axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
+					GFP_ATOMIC);
+			if (!axio) {
+				rc = -ENOMEM;
+				break;
+			}
 
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+			if (copy_from_user(axio, (void __user *)(vfecmd.value),
 				vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+				kfree(axio);
+				rc = -EFAULT;
+				break;
+			}
+			vfe31_config_axi(OUTPUT_PRIM|OUTPUT_SEC, axio);
 			kfree(axio);
-			rc = -EFAULT;
+			}
 			break;
-		}
-		vfe31_config_axi(OUTPUT_PRIM|OUTPUT_SEC, axio);
-		kfree(axio);
-		}
-		break;
 
-	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC_ALL_CHNLS: {
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
+		case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC_ALL_CHNLS: {
+			uint32_t *axio = NULL;
+			axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
+					GFP_ATOMIC);
+			if (!axio) {
+				rc = -ENOMEM;
+				break;
+			}
 
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+			if (copy_from_user(axio, (void __user *)(vfecmd.value),
 				vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+				kfree(axio);
+				rc = -EFAULT;
+				break;
+			}
+			vfe31_config_axi
+				(OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS, axio);
 			kfree(axio);
-			rc = -EFAULT;
+			}
 			break;
-		}
-		vfe31_config_axi(OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS, axio);
-		kfree(axio);
-		}
-		break;
 
-	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC: {
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
+		case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC: {
+			uint32_t *axio = NULL;
+			axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
 				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
+			if (!axio) {
+				rc = -ENOMEM;
+				break;
+			}
 
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+			if (copy_from_user(axio, (void __user *)(vfecmd.value),
 				vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+				kfree(axio);
+				rc = -EFAULT;
+				break;
+			}
+			vfe31_config_axi
+				(OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC, axio);
 			kfree(axio);
-			rc = -EFAULT;
+			}
 			break;
-		}
-		vfe31_config_axi(OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC, axio);
-		kfree(axio);
-		}
-		break;
 
-	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC_ALL_CHNLS: {
-		pr_err("%s Invalid/Unsupported AXI configuration %x",
-			__func__, cmd->cmd_type);
-		}
-		break;
+		case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC_ALL_CHNLS: {
+			pr_err("%s Invalid/Unsupported AXI configuration %x",
+				__func__, cmd->cmd_type);
+			}
+			break;
 
-	case CMD_AXI_START:
-		/* No need to decouple AXI/VFE for VFE3.1*/
-		break;
+		case CMD_AXI_START:
+			/* No need to decouple AXI/VFE for VFE3.1*/
+			break;
 
-	case CMD_AXI_STOP:
-		/* No need to decouple AXI/VFE for VFE3.1*/
-		break;
+		case CMD_AXI_STOP:
+			/* No need to decouple AXI/VFE for VFE3.1*/
+			break;
 
-	default:
-		pr_err("%s Unsupported AXI configuration %x ", __func__,
-			cmd->cmd_type);
-		break;
+		default:
+			pr_err("%s Unsupported AXI configuration %x ", __func__,
+				cmd->cmd_type);
+			break;
 		}
 	}
 vfe31_config_done:
@@ -3855,11 +3888,15 @@
 	usleep_range(10000, 15000);
 }
 
-int msm_vfe_subdev_init(struct v4l2_subdev *sd,
-		struct msm_cam_media_controller *mctl)
+int msm_vfe_subdev_init(struct v4l2_subdev *sd)
 {
 	int rc = 0;
-	v4l2_set_subdev_hostdata(sd, mctl);
+	struct msm_cam_media_controller *mctl;
+	mctl = v4l2_get_subdev_hostdata(sd);
+	if (mctl == NULL) {
+		rc = -EINVAL;
+		goto mctl_failed;
+	}
 
 	spin_lock_init(&vfe31_ctrl->stop_flag_lock);
 	spin_lock_init(&vfe31_ctrl->state_lock);
@@ -3939,6 +3976,7 @@
 	iounmap(vfe31_ctrl->vfebase);
 vfe_remap_failed:
 	disable_irq(vfe31_ctrl->vfeirq->start);
+mctl_failed:
 	return rc;
 }
 
@@ -4064,6 +4102,12 @@
 	sd_info.sd_index = 0;
 	sd_info.irq_num = vfe31_ctrl->vfeirq->start;
 	msm_cam_register_subdev_node(&vfe31_ctrl->subdev, &sd_info);
+
+	media_entity_init(&vfe31_ctrl->subdev.entity, 0, NULL, 0);
+	vfe31_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	vfe31_ctrl->subdev.entity.group_id = VFE_DEV;
+	vfe31_ctrl->subdev.entity.name = pdev->name;
+	vfe31_ctrl->subdev.entity.revision = vfe31_ctrl->subdev.devnode->num;
 	return 0;
 
 vfe31_no_resource:
diff --git a/drivers/media/video/msm/msm_vfe31_v4l2.h b/drivers/media/video/msm/msm_vfe31_v4l2.h
index 2cba995..6396966 100644
--- a/drivers/media/video/msm/msm_vfe31_v4l2.h
+++ b/drivers/media/video/msm/msm_vfe31_v4l2.h
@@ -217,10 +217,11 @@
 #define V31_OPERATION_CFG_LEN     32
 
 #define V31_AXI_OUT_OFF           0x00000038
-#define V31_AXI_OUT_LEN           212
-#define V31_AXI_CH_INF_LEN        24
+#define V31_AXI_OUT_LEN           240
+#define V31_AXI_CH_INF_LEN        48
 #define V31_AXI_CFG_LEN           47
 #define V31_AXI_RESERVED            1
+#define V31_AXI_RESERVED_LEN        4
 
 #define V31_FRAME_SKIP_OFF        0x00000504
 #define V31_FRAME_SKIP_LEN        32
@@ -696,7 +697,7 @@
 struct vfe31_output_ch {
 	struct list_head free_buf_queue;
 	spinlock_t free_buf_lock;
-	uint16_t image_mode;
+	uint32_t inst_handle;
 	int8_t ch0;
 	int8_t ch1;
 	int8_t ch2;
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index 396729e..38179e6 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -393,7 +393,7 @@
 		vfe32_ctrl->share_ctrl->vfebase + VFE_CAMIF_COMMAND);
 }
 
-static void vfe32_subdev_notify(int id, int path, int image_mode,
+static void vfe32_subdev_notify(int id, int path, uint32_t inst_handle,
 	struct v4l2_subdev *sd, struct vfe_share_ctrl_t *share_ctrl)
 {
 	struct msm_vfe_resp rp;
@@ -403,7 +403,7 @@
 	CDBG("vfe32_subdev_notify : msgId = %d\n", id);
 	memset(&rp, 0, sizeof(struct msm_vfe_resp));
 	rp.evt_msg.type   = MSM_CAMERA_MSG;
-	frame_info.image_mode = image_mode;
+	frame_info.inst_handle = inst_handle;
 	frame_info.path = path;
 	rp.evt_msg.data = &frame_info;
 	rp.type	   = id;
@@ -423,27 +423,27 @@
 	axi_ctrl->share_ctrl->outpath.out0.ch0 = 0x0000FFFF & *ch_info;
 	axi_ctrl->share_ctrl->outpath.out0.ch1 =
 		0x0000FFFF & (*ch_info++ >> 16);
-	axi_ctrl->share_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info;
-	axi_ctrl->share_ctrl->outpath.out0.image_mode =
-		0x0000FFFF & (*ch_info++ >> 16);
+	axi_ctrl->share_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info++;
+	axi_ctrl->share_ctrl->outpath.out0.inst_handle = *ch_info++;
+
 	axi_ctrl->share_ctrl->outpath.out1.ch0 = 0x0000FFFF & *ch_info;
 	axi_ctrl->share_ctrl->outpath.out1.ch1 =
 		0x0000FFFF & (*ch_info++ >> 16);
-	axi_ctrl->share_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info;
-	axi_ctrl->share_ctrl->outpath.out1.image_mode =
-		0x0000FFFF & (*ch_info++ >> 16);
+	axi_ctrl->share_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info++;
+	axi_ctrl->share_ctrl->outpath.out1.inst_handle = *ch_info++;
+
 	axi_ctrl->share_ctrl->outpath.out2.ch0 = 0x0000FFFF & *ch_info;
 	axi_ctrl->share_ctrl->outpath.out2.ch1 =
 		0x0000FFFF & (*ch_info++ >> 16);
-	axi_ctrl->share_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info;
-	axi_ctrl->share_ctrl->outpath.out2.image_mode =
-		0x0000FFFF & (*ch_info++ >> 16);
+	axi_ctrl->share_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info++;
+	axi_ctrl->share_ctrl->outpath.out2.inst_handle = *ch_info++;
+
 	axi_ctrl->share_ctrl->outpath.out3.ch0 = 0x0000FFFF & *ch_info;
 	axi_ctrl->share_ctrl->outpath.out3.ch1 =
 		0x0000FFFF & (*ch_info++ >> 16);
-	axi_ctrl->share_ctrl->outpath.out3.ch2 = 0x0000FFFF & *ch_info;
-	axi_ctrl->share_ctrl->outpath.out3.image_mode =
-		0x0000FFFF & (*ch_info++ >> 16);
+	axi_ctrl->share_ctrl->outpath.out3.ch2 = 0x0000FFFF & *ch_info++;
+	axi_ctrl->share_ctrl->outpath.out3.inst_handle = *ch_info++;
+
 	axi_ctrl->share_ctrl->outpath.output_mode = 0;
 
 	if (mode & OUTPUT_TERT1)
@@ -956,6 +956,8 @@
 	vfe32_ctrl->share_ctrl->vfe_capture_count =
 		vfe32_ctrl->share_ctrl->outpath.out0.capture_cnt;
 
+	msm_camio_bus_scale_cfg(
+		pmctl->sdata->pdata->cam_bus_scale_table, S_LIVESHOT);
 	vfe32_ctrl->share_ctrl->liveshot_state = VFE_STATE_START_REQUESTED;
 	msm_camera_io_w_mb(1, vfe32_ctrl->
 		share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
@@ -968,6 +970,8 @@
 	vfe32_ctrl->share_ctrl->liveshot_state = VFE_STATE_STOP_REQUESTED;
 	msm_camera_io_w_mb(1,
 		vfe32_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	msm_camio_bus_scale_cfg(
+		pmctl->sdata->pdata->cam_bus_scale_table, S_VIDEO);
 }
 
 static int vfe32_zsl(
@@ -1464,18 +1468,18 @@
 {
 	struct vfe32_output_ch *outch = NULL;
 	struct msm_free_buf *b = NULL;
-	uint32_t image_mode = 0;
+	uint32_t inst_handle = 0;
 
 	if (path == VFE_MSG_OUTPUT_PRIMARY)
-		image_mode = axi_ctrl->share_ctrl->outpath.out0.image_mode;
+		inst_handle = axi_ctrl->share_ctrl->outpath.out0.inst_handle;
 	else if (path == VFE_MSG_OUTPUT_SECONDARY)
-		image_mode = axi_ctrl->share_ctrl->outpath.out1.image_mode;
+		inst_handle = axi_ctrl->share_ctrl->outpath.out1.inst_handle;
 	else if (path == VFE_MSG_OUTPUT_TERTIARY1)
-		image_mode = axi_ctrl->share_ctrl->outpath.out2.image_mode;
+		inst_handle = axi_ctrl->share_ctrl->outpath.out2.inst_handle;
 	else if (path == VFE_MSG_OUTPUT_TERTIARY2)
-		image_mode = axi_ctrl->share_ctrl->outpath.out3.image_mode;
+		inst_handle = axi_ctrl->share_ctrl->outpath.out3.inst_handle;
 
-	vfe32_subdev_notify(id, path, image_mode,
+	vfe32_subdev_notify(id, path, inst_handle,
 		&axi_ctrl->subdev, axi_ctrl->share_ctrl);
 	outch = vfe32_get_ch(path, axi_ctrl->share_ctrl);
 	if (outch->free_buf.ch_paddr[0])
@@ -1487,17 +1491,17 @@
 {
 	struct vfe32_output_ch *outch = NULL;
 	int rc = 0;
-	uint32_t image_mode = 0;
+	uint32_t inst_handle = 0;
 	if (path == VFE_MSG_OUTPUT_PRIMARY)
-		image_mode = vfe32_ctrl->share_ctrl->outpath.out0.image_mode;
+		inst_handle = vfe32_ctrl->share_ctrl->outpath.out0.inst_handle;
 	else if (path == VFE_MSG_OUTPUT_SECONDARY)
-		image_mode = vfe32_ctrl->share_ctrl->outpath.out1.image_mode;
+		inst_handle = vfe32_ctrl->share_ctrl->outpath.out1.inst_handle;
 	else if (path == VFE_MSG_OUTPUT_TERTIARY1)
-		image_mode = vfe32_ctrl->share_ctrl->outpath.out2.image_mode;
+		inst_handle = vfe32_ctrl->share_ctrl->outpath.out2.inst_handle;
 	else if (path == VFE_MSG_OUTPUT_TERTIARY2)
-		image_mode = vfe32_ctrl->share_ctrl->outpath.out3.image_mode;
+		inst_handle = vfe32_ctrl->share_ctrl->outpath.out3.inst_handle;
 
-	vfe32_subdev_notify(id, path, image_mode,
+	vfe32_subdev_notify(id, path, inst_handle,
 		&vfe32_ctrl->subdev, vfe32_ctrl->share_ctrl);
 	outch = vfe32_get_ch(path, vfe32_ctrl->share_ctrl);
 	if (outch->ping.ch_paddr[0] && outch->pong.ch_paddr[0]) {
@@ -1704,18 +1708,30 @@
 	case VFE_CMD_START_RECORDING:
 		pr_info("vfe32_proc_general: cmdID = %s\n",
 			vfe32_general_cmd[cmd->id]);
+		if (copy_from_user(&temp1, (void __user *)(cmd->value),
+				sizeof(uint32_t))) {
+			pr_err("%s Error copying inst_handle for recording\n",
+				__func__);
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
 		if (vfe32_ctrl->share_ctrl->operation_mode &
-			VFE_OUTPUTS_PREVIEW_AND_VIDEO)
+			VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
+			vfe32_ctrl->share_ctrl->outpath.out1.inst_handle =
+				temp1;
 			rc = vfe32_configure_pingpong_buffers(
 				VFE_MSG_V32_START_RECORDING,
 				VFE_MSG_OUTPUT_SECONDARY,
 				vfe32_ctrl);
-		else if (vfe32_ctrl->share_ctrl->operation_mode &
-			VFE_OUTPUTS_VIDEO_AND_PREVIEW)
+		} else if (vfe32_ctrl->share_ctrl->operation_mode &
+			VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
+			vfe32_ctrl->share_ctrl->outpath.out0.inst_handle =
+				temp1;
 			rc = vfe32_configure_pingpong_buffers(
 				VFE_MSG_V32_START_RECORDING,
 				VFE_MSG_OUTPUT_PRIMARY,
 				vfe32_ctrl);
+		}
 		if (rc < 0) {
 			pr_err("%s error configuring pingpong buffers"
 				" for video", __func__);
@@ -2187,6 +2203,14 @@
 		break;
 
 	case VFE_CMD_LIVESHOT:
+		if (copy_from_user(&temp1, (void __user *)(cmd->value),
+				sizeof(uint32_t))) {
+			pr_err("%s Error copying inst_handle for liveshot ",
+				__func__);
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		vfe32_ctrl->share_ctrl->outpath.out0.inst_handle = temp1;
 		/* Configure primary channel */
 		rc = vfe32_configure_pingpong_buffers(VFE_MSG_V32_CAPTURE,
 					VFE_MSG_OUTPUT_PRIMARY, vfe32_ctrl);
@@ -3452,12 +3476,12 @@
 static void vfe_send_outmsg(
 	struct axi_ctrl_t *axi_ctrl, uint8_t msgid,
 	uint32_t ch0_paddr, uint32_t ch1_paddr,
-	uint32_t ch2_paddr, uint32_t image_mode)
+	uint32_t ch2_paddr, uint32_t inst_handle)
 {
 	struct isp_msg_output msg;
 
 	msg.output_id = msgid;
-	msg.buf.image_mode = image_mode;
+	msg.buf.inst_handle = inst_handle;
 	msg.buf.ch_paddr[0]	= ch0_paddr;
 	msg.buf.ch_paddr[1]	= ch1_paddr;
 	msg.buf.ch_paddr[2]	= ch2_paddr;
@@ -3559,7 +3583,7 @@
 		vfe_send_outmsg(axi_ctrl,
 			MSG_ID_OUTPUT_PRIMARY, ch0_paddr,
 			ch1_paddr, ch2_paddr,
-			axi_ctrl->share_ctrl->outpath.out0.image_mode);
+			axi_ctrl->share_ctrl->outpath.out0.inst_handle);
 
 	} else {
 		axi_ctrl->share_ctrl->outpath.out0.frame_drop_cnt++;
@@ -3637,7 +3661,7 @@
 		vfe_send_outmsg(axi_ctrl,
 			MSG_ID_OUTPUT_SECONDARY, ch0_paddr,
 			ch1_paddr, ch2_paddr,
-			axi_ctrl->share_ctrl->outpath.out1.image_mode);
+			axi_ctrl->share_ctrl->outpath.out1.inst_handle);
 
 	} else {
 		axi_ctrl->share_ctrl->outpath.out1.frame_drop_cnt++;
@@ -3678,7 +3702,7 @@
 			vfe_send_outmsg(axi_ctrl,
 				MSG_ID_OUTPUT_TERTIARY1, ch0_paddr,
 				0, 0,
-				axi_ctrl->share_ctrl->outpath.out2.image_mode);
+				axi_ctrl->share_ctrl->outpath.out2.inst_handle);
 
 		} else {
 			axi_ctrl->share_ctrl->outpath.out2.frame_drop_cnt++;
@@ -3719,7 +3743,7 @@
 			vfe_send_outmsg(axi_ctrl,
 				MSG_ID_OUTPUT_TERTIARY2, ch0_paddr,
 				0, 0,
-				axi_ctrl->share_ctrl->outpath.out3.image_mode);
+				axi_ctrl->share_ctrl->outpath.out3.inst_handle);
 		} else {
 			axi_ctrl->share_ctrl->outpath.out3.frame_drop_cnt++;
 			pr_err("path_irq irq - no free buffer for rdi1!\n");
@@ -4515,10 +4539,9 @@
 	struct vfe32_ctrl_type *vfe32_ctrl =
 		(struct vfe32_ctrl_type *)v4l2_get_subdevdata(sd);
 	struct msm_isp_cmd vfecmd;
-	struct msm_camvfe_params *vfe_params =
-		(struct msm_camvfe_params *)arg;
-	struct msm_vfe_cfg_cmd *cmd = vfe_params->vfe_cfg;
-	void *data = vfe_params->data;
+	struct msm_camvfe_params *vfe_params;
+	struct msm_vfe_cfg_cmd *cmd;
+	void *data;
 
 	long rc = 0;
 	struct vfe_cmd_stats_buf *scfg = NULL;
@@ -4529,6 +4552,17 @@
 		return -EFAULT;
 	}
 
+	CDBG("%s\n", __func__);
+	if (subdev_cmd == VIDIOC_MSM_VFE_INIT) {
+		CDBG("%s init\n", __func__);
+		return msm_vfe_subdev_init(sd);
+	} else if (subdev_cmd == VIDIOC_MSM_VFE_RELEASE) {
+		msm_vfe_subdev_release(sd);
+		return 0;
+	}
+	vfe_params = (struct msm_camvfe_params *)arg;
+	cmd = vfe_params->vfe_cfg;
+	data = vfe_params->data;
 	switch (cmd->cmd_type) {
 	case CMD_VFE_PROCESS_IRQ:
 		vfe32_process_irq(vfe32_ctrl, (uint32_t) data);
@@ -4668,12 +4702,17 @@
 	.core = &msm_vfe_subdev_core_ops,
 };
 
-int msm_axi_subdev_init(struct v4l2_subdev *sd,
-			struct msm_cam_media_controller *mctl)
+int msm_axi_subdev_init(struct v4l2_subdev *sd)
 {
 	int rc = 0;
 	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-	v4l2_set_subdev_hostdata(sd, mctl);
+	struct msm_cam_media_controller *mctl;
+	mctl = v4l2_get_subdev_hostdata(sd);
+	if (mctl == NULL) {
+		pr_err("%s: mctl is NULL\n", __func__);
+		rc = -EINVAL;
+		goto mctl_failed;
+	}
 	spin_lock_init(&axi_ctrl->tasklet_lock);
 	INIT_LIST_HEAD(&axi_ctrl->tasklet_q);
 	spin_lock_init(&axi_ctrl->share_ctrl->sd_notify_lock);
@@ -4721,16 +4760,15 @@
 	axi_ctrl->share_ctrl->vfebase = NULL;
 remap_failed:
 	disable_irq(axi_ctrl->vfeirq->start);
+mctl_failed:
 	return rc;
 }
 
-int msm_vfe_subdev_init(struct v4l2_subdev *sd,
-			struct msm_cam_media_controller *mctl)
+int msm_vfe_subdev_init(struct v4l2_subdev *sd)
 {
 	int rc = 0;
 	struct vfe32_ctrl_type *vfe32_ctrl =
 		(struct vfe32_ctrl_type *)v4l2_get_subdevdata(sd);
-	v4l2_set_subdev_hostdata(sd, mctl);
 
 	spin_lock_init(&vfe32_ctrl->share_ctrl->stop_flag_lock);
 	spin_lock_init(&vfe32_ctrl->state_lock);
@@ -5198,8 +5236,7 @@
 	int rc = -ENOIOCTLCMD;
 	switch (cmd) {
 	case VIDIOC_MSM_AXI_INIT:
-		rc = msm_axi_subdev_init(sd,
-			(struct msm_cam_media_controller *)arg);
+		rc = msm_axi_subdev_init(sd);
 		break;
 	case VIDIOC_MSM_AXI_CFG:
 		rc = msm_axi_config(sd, arg);
@@ -5288,6 +5325,12 @@
 	sd_info.irq_num = 0;
 	msm_cam_register_subdev_node(&axi_ctrl->subdev, &sd_info);
 
+	media_entity_init(&axi_ctrl->subdev.entity, 0, NULL, 0);
+	axi_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	axi_ctrl->subdev.entity.group_id = AXI_DEV;
+	axi_ctrl->subdev.entity.name = pdev->name;
+	axi_ctrl->subdev.entity.revision = axi_ctrl->subdev.devnode->num;
+
 	v4l2_subdev_init(&vfe32_ctrl->subdev, &msm_vfe_subdev_ops);
 	vfe32_ctrl->subdev.internal_ops = &msm_vfe_internal_ops;
 	vfe32_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
@@ -5333,6 +5376,12 @@
 	sd_info.irq_num = axi_ctrl->vfeirq->start;
 	msm_cam_register_subdev_node(&vfe32_ctrl->subdev, &sd_info);
 
+	media_entity_init(&vfe32_ctrl->subdev.entity, 0, NULL, 0);
+	vfe32_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	vfe32_ctrl->subdev.entity.group_id = VFE_DEV;
+	vfe32_ctrl->subdev.entity.name = pdev->name;
+	vfe32_ctrl->subdev.entity.revision = vfe32_ctrl->subdev.devnode->num;
+
 	/* Request for this device irq from the camera server. If the
 	 * IRQ Router is present on this target, the interrupt will be
 	 * handled by the camera server and the interrupt service
diff --git a/drivers/media/video/msm/msm_vfe32.h b/drivers/media/video/msm/msm_vfe32.h
index 2c528da..9336cfb 100644
--- a/drivers/media/video/msm/msm_vfe32.h
+++ b/drivers/media/video/msm/msm_vfe32.h
@@ -241,8 +241,8 @@
 #define V32_OPERATION_CFG_LEN     44
 
 #define V32_AXI_OUT_OFF           0x00000038
-#define V32_AXI_OUT_LEN           224
-#define V32_AXI_CH_INF_LEN        32
+#define V32_AXI_OUT_LEN           240
+#define V32_AXI_CH_INF_LEN        48
 #define V32_AXI_CFG_LEN           47
 #define V32_AXI_BUS_FMT_OFF    1
 #define V32_AXI_BUS_FMT_LEN    4
@@ -756,7 +756,7 @@
 struct vfe32_output_ch {
 	struct list_head free_buf_queue;
 	spinlock_t free_buf_lock;
-	uint16_t image_mode;
+	uint32_t inst_handle;
 	int8_t ch0;
 	int8_t ch1;
 	int8_t ch2;
@@ -1028,19 +1028,4 @@
 	uint32_t statsBuf[VFE_STATS_BUFFER_COUNT];
 };
 
-#define VIDIOC_MSM_AXI_INIT \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 18, struct msm_cam_media_controller *)
-
-#define VIDIOC_MSM_AXI_RELEASE \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 19, struct msm_cam_media_controller *)
-
-#define VIDIOC_MSM_AXI_CFG \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 20, void *)
-
-#define VIDIOC_MSM_AXI_IRQ \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 21, void *)
-
-#define VIDIOC_MSM_AXI_BUF_CFG \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 22, void *)
-
 #endif /* __MSM_VFE32_H__ */
diff --git a/drivers/media/video/msm/msm_vfe7x27a_v4l2.c b/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
index 96047d5..64e0385 100644
--- a/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
+++ b/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
@@ -585,7 +585,7 @@
 	struct isp_msg_output msg;
 
 	msg.output_id = msgid;
-	msg.buf.image_mode = -1;
+	msg.buf.inst_handle = 0;
 	msg.buf.ch_paddr[0]     = ch0_paddr;
 	msg.buf.ch_paddr[1]     = ch1_paddr;
 	msg.frameCounter = vfe2x_ctrl->vfeFrameId;
@@ -1182,12 +1182,11 @@
 			unsigned int subdev_cmd, void *arg)
 {
 	struct msm_isp_cmd vfecmd;
-	struct msm_camvfe_params *vfe_params =
-		(struct msm_camvfe_params *)arg;
-	struct msm_vfe_cfg_cmd *cmd = vfe_params->vfe_cfg;
+	struct msm_camvfe_params *vfe_params;
+	struct msm_vfe_cfg_cmd *cmd;
 	struct table_cmd *table_pending;
 	long rc = 0;
-	void *data = vfe_params->data;
+	void *data;
 
 	struct msm_pmem_region *regptr;
 	unsigned char buf[256];
@@ -1208,6 +1207,18 @@
 	struct vfe_outputack fack;
 
 	CDBG("msm_vfe_subdev_ioctl is called\n");
+	if (subdev_cmd == VIDIOC_MSM_VFE_INIT) {
+		CDBG("%s init\n", __func__);
+		return msm_vfe_subdev_init(sd);
+	} else if (subdev_cmd == VIDIOC_MSM_VFE_RELEASE) {
+		msm_vfe_subdev_release(sd);
+		return 0;
+	}
+
+	vfe_params = (struct msm_camvfe_params *)arg;
+	cmd = vfe_params->vfe_cfg;
+	data = vfe_params->data;
+
 	if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
 		cmd->cmd_type != CMD_STATS_BUF_RELEASE &&
 		cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE &&
@@ -1954,11 +1965,16 @@
 	{"vfe_clk", 192000000},
 };
 
-int msm_vfe_subdev_init(struct v4l2_subdev *sd,
-		struct msm_cam_media_controller *mctl)
+int msm_vfe_subdev_init(struct v4l2_subdev *sd)
 {
 	int rc = 0;
-	v4l2_set_subdev_hostdata(sd, mctl);
+	struct msm_cam_media_controller *mctl;
+	mctl = v4l2_get_subdev_hostdata(sd);
+	if (mctl == NULL) {
+		pr_err("%s: mctl is NULL\n", __func__);
+		rc = -EINVAL;
+		goto mctl_failed;
+	}
 
 	spin_lock_init(&vfe2x_ctrl->sd_notify_lock);
 	spin_lock_init(&vfe2x_ctrl->table_lock);
@@ -2011,11 +2027,11 @@
 	kfree(extdata);
 init_fail:
 	extlen = 0;
+mctl_failed:
 	return rc;
 }
 
-int msm_vpe_subdev_init(struct v4l2_subdev *sd,
-			struct msm_cam_media_controller *mctl)
+int msm_vpe_subdev_init(struct v4l2_subdev *sd)
 {
 	return 0;
 }
@@ -2101,6 +2117,12 @@
 	sd_info.sd_index = 0;
 	sd_info.irq_num = 0;
 	msm_cam_register_subdev_node(&vfe2x_ctrl->subdev, &sd_info);
+
+	media_entity_init(&vfe2x_ctrl->subdev.entity, 0, NULL, 0);
+	vfe2x_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	vfe2x_ctrl->subdev.entity.group_id = VFE_DEV;
+	vfe2x_ctrl->subdev.entity.name = pdev->name;
+	vfe2x_ctrl->subdev.entity.revision = vfe2x_ctrl->subdev.devnode->num;
 	return 0;
 }
 
diff --git a/drivers/media/video/msm/msm_vpe.c b/drivers/media/video/msm/msm_vpe.c
index 2b58f44..58fc153 100644
--- a/drivers/media/video/msm/msm_vpe.c
+++ b/drivers/media/video/msm/msm_vpe.c
@@ -603,10 +603,11 @@
 
 static int msm_vpe_resource_init(void);
 
-int msm_vpe_subdev_init(struct v4l2_subdev *sd,
-		struct msm_cam_media_controller *mctl)
+int msm_vpe_subdev_init(struct v4l2_subdev *sd)
 {
 	int rc = 0;
+	struct msm_cam_media_controller *mctl;
+	mctl = v4l2_get_subdev_hostdata(sd);
 	D("%s:begin", __func__);
 	if (atomic_read(&vpe_init_done)) {
 		pr_err("%s: VPE has been initialized", __func__);
@@ -619,7 +620,6 @@
 		atomic_set(&vpe_init_done, 0);
 		return rc;
 	}
-	v4l2_set_subdev_hostdata(sd, mctl);
 	spin_lock_init(&vpe_ctrl->lock);
 	D("%s:end", __func__);
 	return rc;
@@ -843,9 +843,7 @@
 
 	switch (cmd) {
 	case VIDIOC_MSM_VPE_INIT: {
-		struct msm_cam_media_controller *mctl =
-			(struct msm_cam_media_controller *)arg;
-		msm_vpe_subdev_init(sd, mctl);
+		msm_vpe_subdev_init(sd);
 		break;
 		}
 
@@ -980,7 +978,7 @@
 	platform_set_drvdata(pdev, &vpe_ctrl->subdev);
 
 	media_entity_init(&vpe_ctrl->subdev.entity, 0, NULL, 0);
-	vpe_ctrl->subdev.entity.type = MEDIA_ENT_T_DEVNODE_V4L;
+	vpe_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
 	vpe_ctrl->subdev.entity.group_id = VPE_DEV;
 	vpe_ctrl->subdev.entity.name = vpe_ctrl->subdev.name;
 
diff --git a/drivers/media/video/msm/msm_vpe.h b/drivers/media/video/msm/msm_vpe.h
index 5cf0309..6516ea1 100644
--- a/drivers/media/video/msm/msm_vpe.h
+++ b/drivers/media/video/msm/msm_vpe.h
@@ -180,14 +180,5 @@
 	int32_t phase_step_y;
 };
 
-#define VIDIOC_MSM_VPE_INIT \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 15, struct msm_cam_media_controller *)
-
-#define VIDIOC_MSM_VPE_RELEASE \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 16, struct msm_cam_media_controller *)
-
-#define VIDIOC_MSM_VPE_CFG \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 17, struct msm_mctl_pp_params *)
-
 #endif /*_MSM_VPE_H_*/
 
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index be1efe0..72f3f3d 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -284,7 +284,6 @@
 			int update_type, int res)
 {
 	int32_t rc = 0;
-
 	s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
 	msleep(30);
 	if (update_type == MSM_SENSOR_REG_INIT) {
@@ -792,8 +791,15 @@
 		sizeof(s_ctrl->sensor_v4l2_subdev.name), "%s", id->name);
 	v4l2_i2c_subdev_init(&s_ctrl->sensor_v4l2_subdev, client,
 		s_ctrl->sensor_v4l2_subdev_ops);
-
+	s_ctrl->sensor_v4l2_subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	media_entity_init(&s_ctrl->sensor_v4l2_subdev.entity, 0, NULL, 0);
+	s_ctrl->sensor_v4l2_subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	s_ctrl->sensor_v4l2_subdev.entity.group_id = SENSOR_DEV;
+	s_ctrl->sensor_v4l2_subdev.entity.name =
+		s_ctrl->sensor_v4l2_subdev.name;
 	msm_sensor_register(&s_ctrl->sensor_v4l2_subdev);
+	s_ctrl->sensor_v4l2_subdev.entity.revision =
+		s_ctrl->sensor_v4l2_subdev.devnode->num;
 	goto power_down;
 probe_fail:
 	pr_err("%s %s_i2c_probe failed\n", __func__, client->name);
diff --git a/drivers/media/video/msm/server/msm_cam_server.c b/drivers/media/video/msm/server/msm_cam_server.c
index 2d3022f..715b4e7 100644
--- a/drivers/media/video/msm/server/msm_cam_server.c
+++ b/drivers/media/video/msm/server/msm_cam_server.c
@@ -19,6 +19,7 @@
 #include "msm_sensor.h"
 #include "msm_actuator.h"
 #include "msm_vfe32.h"
+#include "msm_csi_register.h"
 
 #ifdef CONFIG_MSM_CAMERA_DEBUG
 #define D(fmt, args...) pr_debug("msm: " fmt, ##args)
@@ -95,6 +96,19 @@
 	return -EINVAL;
 }
 
+void msm_setup_v4l2_event_queue(struct v4l2_fh *eventHandle,
+	struct video_device *pvdev)
+{
+	v4l2_fh_init(eventHandle, pvdev);
+	v4l2_fh_add(eventHandle);
+}
+
+void msm_destroy_v4l2_event_queue(struct v4l2_fh *eventHandle)
+{
+	v4l2_fh_del(eventHandle);
+	v4l2_fh_exit(eventHandle);
+}
+
 uint32_t msm_cam_server_get_mctl_handle(void)
 {
 	uint32_t i;
@@ -422,6 +436,7 @@
 	plane_info.buffer_type = pfmt->type;
 	plane_info.ext_mode = pcam->dev_inst[idx]->image_mode;
 	plane_info.num_planes = 1;
+	plane_info.inst_handle = pcam->dev_inst[idx]->inst_handle;
 	D("%s: %d, %d, 0x%x\n", __func__,
 		pfmt->fmt.pix.width, pfmt->fmt.pix.height,
 		pfmt->fmt.pix.pixelformat);
@@ -478,6 +493,8 @@
 	plane_info.buffer_type = pfmt->type;
 	plane_info.ext_mode = pcam->dev_inst[idx]->image_mode;
 	plane_info.num_planes = pix_mp->num_planes;
+	plane_info.inst_handle = pcam->dev_inst[idx]->inst_handle;
+
 	if (plane_info.num_planes <= 0 ||
 		plane_info.num_planes > VIDEO_MAX_PLANES) {
 		pr_err("%s Invalid number of planes set %d", __func__,
@@ -880,7 +897,6 @@
 	struct msm_cam_v4l2_device *pcam)
 {
 	int rc = 0;
-	struct msm_cam_media_controller *pmctl;
 
 	D("%s\n", __func__);
 
@@ -906,17 +922,6 @@
 	/* initialization the media controller module*/
 	msm_mctl_init(pcam);
 
-	/*for single VFE msms (8660, 8960v1), just populate the session
-	with our VFE devices that registered*/
-	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
-	if (pmctl == NULL) {
-		pr_err("%s: cannot find mctl\n", __func__);
-		msm_mctl_free(pcam);
-		atomic_dec(&ps->number_pcam_active);
-		return -ENODEV;
-	}
-	pmctl->axi_sdev = ps->axi_device[0];
-	pmctl->isp_sdev = ps->isp_subdev[0];
 	return rc;
 }
 
@@ -940,6 +945,50 @@
 	return rc;
 }
 
+static int map_imem_addresses(struct msm_cam_media_controller *mctl)
+{
+	int rc = 0;
+	rc = msm_iommu_map_contig_buffer(
+		(unsigned long)IMEM_Y_PING_OFFSET, CAMERA_DOMAIN, GEN_POOL,
+		((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)),
+		SZ_4K, IOMMU_WRITE | IOMMU_READ,
+		(unsigned long *)&mctl->ping_imem_y);
+	mctl->ping_imem_cbcr = mctl->ping_imem_y + IMEM_Y_SIZE;
+	if (rc < 0) {
+		pr_err("%s: ping iommu mapping returned error %d\n",
+			__func__, rc);
+		mctl->ping_imem_y = 0;
+		mctl->ping_imem_cbcr = 0;
+	}
+	msm_iommu_map_contig_buffer(
+		(unsigned long)IMEM_Y_PONG_OFFSET, CAMERA_DOMAIN, GEN_POOL,
+		((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)),
+		SZ_4K, IOMMU_WRITE | IOMMU_READ,
+		(unsigned long *)&mctl->pong_imem_y);
+	mctl->pong_imem_cbcr = mctl->pong_imem_y + IMEM_Y_SIZE;
+	if (rc < 0) {
+		pr_err("%s: pong iommu mapping returned error %d\n",
+			 __func__, rc);
+		mctl->pong_imem_y = 0;
+		mctl->pong_imem_cbcr = 0;
+	}
+	return rc;
+}
+
+static void unmap_imem_addresses(struct msm_cam_media_controller *mctl)
+{
+	msm_iommu_unmap_contig_buffer(mctl->ping_imem_y,
+		CAMERA_DOMAIN, GEN_POOL,
+		((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)));
+	msm_iommu_unmap_contig_buffer(mctl->pong_imem_y,
+		CAMERA_DOMAIN, GEN_POOL,
+		((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)));
+	mctl->ping_imem_y = 0;
+	mctl->ping_imem_cbcr = 0;
+	mctl->pong_imem_y = 0;
+	mctl->pong_imem_cbcr = 0;
+}
+
 static long msm_ioctl_server(struct file *file, void *fh,
 		bool valid_prio, int cmd, void *arg)
 {
@@ -1283,6 +1332,7 @@
 {
 	int rc = -EINVAL, ges_evt;
 	struct msm_cam_server_queue *queue;
+	struct msm_cam_media_controller *pmctl;
 
 	if (!pcam) {
 		pr_err("%s pcam passed is null ", __func__);
@@ -1301,7 +1351,6 @@
 	msm_queue_init(&queue->ctrl_q, "control");
 	msm_queue_init(&queue->eventData_q, "eventdata");
 	queue->queue_active = 1;
-
 	rc = msm_cam_server_open_session(&g_server_dev, pcam);
 	if (rc < 0) {
 		pr_err("%s: cam_server_open_session failed %d\n",
@@ -1309,6 +1358,17 @@
 		goto error;
 	}
 
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
+	if (!pmctl) {
+		pr_err("%s: invalid mctl controller", __func__);
+		goto error;
+	}
+	rc = map_imem_addresses(pmctl);
+	if (rc < 0) {
+		pr_err("%sFailed to map imem addresses %d\n", __func__, rc);
+		goto error;
+	}
+
 	return rc;
 error:
 	ges_evt = MSM_V4L2_GES_CAM_CLOSE;
@@ -1328,6 +1388,7 @@
 {
 	int rc = -EINVAL, ges_evt;
 	struct msm_cam_server_queue *queue;
+	struct msm_cam_media_controller *pmctl;
 
 	mutex_lock(&g_server_dev.server_queue_lock);
 	queue = &g_server_dev.server_queue[pcam->server_queue_idx];
@@ -1338,6 +1399,13 @@
 	msm_drain_eventq(&queue->eventData_q);
 	mutex_unlock(&g_server_dev.server_queue_lock);
 
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
+	if (!pmctl) {
+		pr_err("%s: invalid mctl controller", __func__);
+		return -EINVAL;
+	}
+	unmap_imem_addresses(pmctl);
+
 	rc = msm_cam_server_close_session(&g_server_dev, pcam);
 	if (rc < 0)
 		pr_err("msm_cam_server_close_session fails %d\n", rc);
@@ -1374,6 +1442,7 @@
 	struct msm_camera_sensor_info *sinfo;
 	struct msm_camera_device_platform_data *camdev;
 	uint8_t csid_core = 0;
+	struct msm_cam_media_controller *p_mctl;
 
 	if (notification == NOTIFY_PCLK_CHANGE ||
 		notification == NOTIFY_CSIPHY_CFG ||
@@ -1384,7 +1453,14 @@
 		camdev = sinfo->pdata;
 		csid_core = camdev->csid_core;
 	}
-
+	if (notification != NOTIFY_GESTURE_CAM_EVT) {
+		p_mctl = v4l2_get_subdev_hostdata(sd);
+		if (p_mctl == NULL) {
+			pr_err("%s: cannot find mctl, %d\n",
+				__func__, notification);
+			return;
+		}
+	}
 	switch (notification) {
 	case NOTIFY_ISP_MSG_EVT:
 	case NOTIFY_VFE_MSG_OUT:
@@ -1393,10 +1469,10 @@
 	case NOTIFY_VFE_BUF_EVT:
 	case NOTIFY_VFE_BUF_FREE_EVT:
 		if (g_server_dev.isp_subdev[0] &&
-			g_server_dev.isp_subdev[0]->isp_notify) {
+			g_server_dev.isp_subdev[0]->isp_notify
+			&& p_mctl->isp_sdev->sd)
 			rc = g_server_dev.isp_subdev[0]->isp_notify(
-				g_server_dev.vfe_device[0], notification, arg);
-		}
+				p_mctl->isp_sdev->sd, notification, arg);
 		break;
 	case NOTIFY_VFE_IRQ:{
 		struct msm_vfe_cfg_cmd cfg_cmd;
@@ -1404,32 +1480,32 @@
 		cfg_cmd.cmd_type = CMD_VFE_PROCESS_IRQ;
 		vfe_params.vfe_cfg = &cfg_cmd;
 		vfe_params.data = arg;
-		rc = v4l2_subdev_call(g_server_dev.vfe_device[0],
+		rc = v4l2_subdev_call(p_mctl->isp_sdev->sd,
 			core, ioctl, 0, &vfe_params);
 	}
 		break;
 	case NOTIFY_AXI_IRQ:
-		rc = v4l2_subdev_call(g_server_dev.axi_device[0],
+		rc = v4l2_subdev_call(p_mctl->axi_sdev,
 			core, ioctl, VIDIOC_MSM_AXI_IRQ, arg);
 		break;
 	case NOTIFY_PCLK_CHANGE:
-		if (g_server_dev.axi_device[0])
-			rc = v4l2_subdev_call(g_server_dev.axi_device[0], video,
+		if (p_mctl->axi_sdev)
+			rc = v4l2_subdev_call(p_mctl->axi_sdev, video,
 			s_crystal_freq, *(uint32_t *)arg, 0);
 		else
-			rc = v4l2_subdev_call(g_server_dev.vfe_device[0], video,
+			rc = v4l2_subdev_call(p_mctl->isp_sdev->sd, video,
 			s_crystal_freq, *(uint32_t *)arg, 0);
 		break;
 	case NOTIFY_CSIPHY_CFG:
-		rc = v4l2_subdev_call(g_server_dev.csiphy_device[csid_core],
+		rc = v4l2_subdev_call(p_mctl->csiphy_sdev,
 			core, ioctl, VIDIOC_MSM_CSIPHY_CFG, arg);
 		break;
 	case NOTIFY_CSID_CFG:
-		rc = v4l2_subdev_call(g_server_dev.csid_device[csid_core],
+		rc = v4l2_subdev_call(p_mctl->csid_sdev,
 			core, ioctl, VIDIOC_MSM_CSID_CFG, arg);
 		break;
 	case NOTIFY_CSIC_CFG:
-		rc = v4l2_subdev_call(g_server_dev.csic_device[csid_core],
+		rc = v4l2_subdev_call(p_mctl->csic_sdev,
 			core, ioctl, VIDIOC_MSM_CSIC_CFG, arg);
 		break;
 	case NOTIFY_GESTURE_EVT:
@@ -1471,6 +1547,33 @@
 	return -EINVAL;
 }
 
+static struct v4l2_subdev  *msm_cam_find_subdev_node(
+	struct v4l2_subdev **sd_list, u32 revision_num)
+{
+	int i = 0;
+	for (i = 0; sd_list[i] != NULL; i++) {
+		if (sd_list[i]->entity.revision == revision_num) {
+			return sd_list[i];
+			break;
+		}
+	}
+	return NULL;
+}
+
+int msm_mctl_find_sensor_subdevs(struct msm_cam_media_controller *p_mctl,
+	int core_index)
+{
+	int rc = -ENODEV;
+
+	v4l2_set_subdev_hostdata(p_mctl->sensor_sdev, p_mctl);
+
+	rc = msm_csi_register_subdevs(p_mctl, core_index, &g_server_dev);
+	if (rc < 0)
+		pr_err("%s: Could not find sensor subdevs\n", __func__);
+
+	return rc;
+}
+
 static irqreturn_t msm_camera_server_parse_irq(int irq_num, void *data)
 {
 	unsigned long flags;
@@ -1825,6 +1928,15 @@
 	index     = sd_info->sd_index;
 
 	switch (sdev_type) {
+	case SENSOR_DEV:
+		if (index >= MAX_NUM_SENSOR_DEV) {
+			pr_err("%s Invalid sensor idx %d", __func__, index);
+			err = -EINVAL;
+			break;
+		}
+		g_server_dev.sensor_device[index] = sd;
+		break;
+
 	case CSIPHY_DEV:
 		if (index >= MAX_NUM_CSIPHY_DEV) {
 			pr_err("%s Invalid CSIPHY idx %d", __func__, index);
@@ -1865,7 +1977,7 @@
 			break;
 		}
 		cam_hw_idx = MSM_CAM_HW_ISPIF + index;
-		g_server_dev.ispif_device = sd;
+		g_server_dev.ispif_device[index] = sd;
 		if (g_server_dev.irqr_device) {
 			g_server_dev.subdev_table[cam_hw_idx] = sd;
 			err = msm_cam_server_fill_sdev_irqnum(cam_hw_idx,
@@ -1881,6 +1993,7 @@
 		}
 		cam_hw_idx = MSM_CAM_HW_VFE0 + index;
 		g_server_dev.vfe_device[index] = sd;
+		g_server_dev.isp_subdev[index]->sd = sd;
 		if (g_server_dev.irqr_device) {
 			g_server_dev.subdev_table[cam_hw_idx] = sd;
 			err = msm_cam_server_fill_sdev_irqnum(cam_hw_idx,
@@ -1960,19 +2073,25 @@
 	g_server_dev.video_dev->ioctl_ops = &msm_ioctl_ops_server;
 	g_server_dev.video_dev->release   = video_device_release;
 	g_server_dev.video_dev->minor = 100;
-	g_server_dev.video_dev->vfl_type = 1;
+	g_server_dev.video_dev->vfl_type = VFL_TYPE_GRABBER;
 
 	video_set_drvdata(g_server_dev.video_dev, &g_server_dev);
 
-	strlcpy(g_server_dev.media_dev.model, "qcamera",
+	strlcpy(g_server_dev.media_dev.model, QCAMERA_SERVER_NAME,
 		sizeof(g_server_dev.media_dev.model));
 	g_server_dev.media_dev.dev = &pdev->dev;
 	rc = media_device_register(&g_server_dev.media_dev);
 	g_server_dev.v4l2_dev.mdev = &g_server_dev.media_dev;
+	media_entity_init(&g_server_dev.video_dev->entity, 0, NULL, 0);
+	g_server_dev.video_dev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
+	g_server_dev.video_dev->entity.group_id = QCAMERA_VNODE_GROUP_ID;
 
 	rc = video_register_device(g_server_dev.video_dev,
 		VFL_TYPE_GRABBER, 100);
 
+	g_server_dev.video_dev->entity.name =
+		video_device_node_name(g_server_dev.video_dev);
+
 	mutex_init(&g_server_dev.server_lock);
 	mutex_init(&g_server_dev.server_queue_lock);
 	spin_lock_init(&g_server_dev.intr_table_lock);
@@ -1986,16 +2105,10 @@
 	/*initialize fake video device and event queue*/
 
 	g_server_dev.server_command_queue.pvdev = g_server_dev.video_dev;
-	rc = msm_setup_v4l2_event_queue(
+	msm_setup_v4l2_event_queue(
 		&g_server_dev.server_command_queue.eventHandle,
 		g_server_dev.server_command_queue.pvdev);
 
-	if (rc < 0) {
-		pr_err("%s failed to initialize event queue\n", __func__);
-		video_device_release(g_server_dev.server_command_queue.pvdev);
-		return rc;
-	}
-
 	for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
 		struct msm_cam_server_queue *queue;
 		queue = &g_server_dev.server_queue[i];
@@ -2342,6 +2455,104 @@
 	return rc;
 }
 
+static struct msm_isp_ops *find_isp_op(struct v4l2_subdev *sdev)
+{
+	int i;
+	for (i = 0; i < g_server_dev.config_info.num_config_nodes; i++) {
+		if (g_server_dev.isp_subdev[i]->sd == sdev)
+			return g_server_dev.isp_subdev[i];
+	}
+	return NULL;
+}
+
+static int msm_set_mctl_subdev(struct msm_cam_media_controller *pmctl,
+	struct msm_mctl_set_sdev_data *set_data)
+{
+	int rc = 0;
+	struct v4l2_subdev *vfe_sdev = NULL;
+	struct v4l2_subdev *temp_sdev = NULL;
+	switch (set_data->sdev_type) {
+	case CSIPHY_DEV:
+		pmctl->csiphy_sdev = msm_cam_find_subdev_node
+			(&g_server_dev.csiphy_device[0], set_data->revision);
+		temp_sdev = pmctl->csiphy_sdev;
+		break;
+	case CSID_DEV:
+		pmctl->csid_sdev = msm_cam_find_subdev_node
+			(&g_server_dev.csid_device[0], set_data->revision);
+		temp_sdev = pmctl->csid_sdev;
+		break;
+	case CSIC_DEV:
+		pmctl->csic_sdev = msm_cam_find_subdev_node
+			(&g_server_dev.csic_device[0], set_data->revision);
+		temp_sdev = pmctl->csic_sdev;
+		break;
+	case ISPIF_DEV:
+		pmctl->ispif_sdev = msm_cam_find_subdev_node
+			(&g_server_dev.ispif_device[0], set_data->revision);
+		temp_sdev = pmctl->ispif_sdev;
+		break;
+	case VFE_DEV:
+		vfe_sdev = msm_cam_find_subdev_node
+			(&g_server_dev.vfe_device[0], set_data->revision);
+		temp_sdev = vfe_sdev;
+		pmctl->isp_sdev = find_isp_op(vfe_sdev);
+		pmctl->isp_sdev->sd = vfe_sdev;
+		break;
+	case AXI_DEV:
+		pmctl->axi_sdev = msm_cam_find_subdev_node
+			(&g_server_dev.axi_device[0], set_data->revision);
+		temp_sdev = pmctl->axi_sdev;
+		break;
+	case VPE_DEV:
+		pmctl->vpe_sdev = msm_cam_find_subdev_node
+			(&g_server_dev.vpe_device[0], set_data->revision);
+		temp_sdev = pmctl->vpe_sdev;
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	if (temp_sdev != NULL)
+		v4l2_set_subdev_hostdata(temp_sdev, pmctl);
+	else
+		pr_err("%s: Could not find subdev\n", __func__);
+	return rc;
+}
+
+static int msm_unset_mctl_subdev(struct msm_cam_media_controller *pmctl,
+	struct msm_mctl_set_sdev_data *set_data)
+{
+	int rc = 0;
+	switch (set_data->sdev_type) {
+	case CSIPHY_DEV:
+		pmctl->csiphy_sdev = NULL;
+		break;
+	case CSID_DEV:
+		pmctl->csid_sdev = NULL;
+		break;
+	case CSIC_DEV:
+		pmctl->csic_sdev = NULL;
+		break;
+	case ISPIF_DEV:
+		pmctl->ispif_sdev = NULL;
+		break;
+	case VFE_DEV:
+		pmctl->isp_sdev = NULL;
+		break;
+	case AXI_DEV:
+		pmctl->axi_sdev = NULL;
+		break;
+	case VPE_DEV:
+		pmctl->vpe_sdev = NULL;
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
 static long msm_ioctl_config(struct file *fp, unsigned int cmd,
 	unsigned long arg)
 {
@@ -2497,6 +2708,30 @@
 			rc = -EINVAL;
 		break;
 
+	case MSM_CAM_IOCTL_SET_MCTL_SDEV:{
+		struct msm_mctl_set_sdev_data set_data;
+		if (copy_from_user(&set_data, (void __user *)arg,
+			sizeof(struct msm_mctl_set_sdev_data))) {
+			ERR_COPY_FROM_USER();
+			rc = -EINVAL;
+			break;
+		}
+		rc = msm_set_mctl_subdev(config_cam->p_mctl, &set_data);
+		break;
+	}
+
+	case MSM_CAM_IOCTL_UNSET_MCTL_SDEV:{
+		struct msm_mctl_set_sdev_data set_data;
+		if (copy_from_user(&set_data, (void __user *)arg,
+			sizeof(struct msm_mctl_set_sdev_data))) {
+			ERR_COPY_FROM_USER();
+			rc = -EINVAL;
+			break;
+		}
+		rc = msm_unset_mctl_subdev(config_cam->p_mctl, &set_data);
+		break;
+	}
+
 	default:{
 		/* For the rest of config command, forward to media controller*/
 		struct msm_cam_media_controller *p_mctl = config_cam->p_mctl;
@@ -2603,14 +2838,12 @@
 		goto config_setup_fail;
 	}
 
-	rc = msm_setup_v4l2_event_queue(
+	/* v4l2_fh support */
+	spin_lock_init(&config_cam->config_stat_event_queue.pvdev->fh_lock);
+	INIT_LIST_HEAD(&config_cam->config_stat_event_queue.pvdev->fh_list);
+	msm_setup_v4l2_event_queue(
 		&config_cam->config_stat_event_queue.eventHandle,
 		config_cam->config_stat_event_queue.pvdev);
-	if (rc < 0) {
-		pr_err("%s failed to initialize event queue\n", __func__);
-		video_device_release(config_cam->config_stat_event_queue.pvdev);
-		goto config_setup_fail;
-	}
 
 	return rc;
 
@@ -2622,6 +2855,7 @@
 static int __devinit msm_camera_probe(struct platform_device *pdev)
 {
 	int rc = 0, i;
+	memset(&g_server_dev, 0, sizeof(struct msm_cam_server_dev));
 	/*for now just create a config 0 node
 	  put logic here later to know how many configs to create*/
 	g_server_dev.config_info.num_config_nodes = 1;
diff --git a/drivers/media/video/msm_vidc/msm_smem.c b/drivers/media/video/msm_vidc/msm_smem.c
index 2913d74..76e3592 100644
--- a/drivers/media/video/msm_vidc/msm_smem.c
+++ b/drivers/media/video/msm_vidc/msm_smem.c
@@ -12,6 +12,7 @@
  */
 
 #include <linux/slab.h>
+#include <mach/iommu_domains.h>
 #include "msm_smem.h"
 
 struct smem_client {
@@ -19,12 +20,44 @@
 	void *clnt;
 };
 
+static int get_device_address(struct ion_client *clnt,
+		struct ion_handle *hndl, int domain_num, int partition_num,
+		unsigned long align, unsigned long *iova,
+		unsigned long *buffer_size,	unsigned long flags)
+{
+	int rc;
+
+	if (!iova || !buffer_size || !hndl || !clnt) {
+		pr_err("Invalid params: %p, %p, %p, %p\n",
+				clnt, hndl, iova, buffer_size);
+		return -EINVAL;
+	}
+	if (align < 4096)
+		align = 4096;
+	flags |= UNCACHED;
+	rc = ion_map_iommu(clnt, hndl, domain_num, partition_num, align,
+			0, iova, buffer_size, flags, 0);
+	if (rc)
+		pr_err("ion_map_iommu failed(%d).domain: %d,partition: %d\n",
+				rc, domain_num, partition_num);
+
+	return rc;
+}
+
+static void put_device_address(struct ion_client *clnt,
+		struct ion_handle *hndl, int domain_num)
+{
+	ion_unmap_iommu(clnt, hndl, domain_num, 0);
+}
+
 static int ion_user_to_kernel(struct smem_client *client,
-			int fd, u32 offset, struct msm_smem *mem)
+			int fd, u32 offset, int domain, int partition,
+			struct msm_smem *mem)
 {
 	struct ion_handle *hndl;
 	unsigned long ionflag;
-	size_t len;
+	unsigned long iova = 0;
+	unsigned long buffer_size = 0;
 	int rc = 0;
 	hndl = ion_import_dma_buf(client->clnt, fd);
 	if (IS_ERR_OR_NULL(hndl)) {
@@ -38,25 +71,29 @@
 		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->domain = domain;
+	mem->partition_num = partition;
+	rc = get_device_address(client->clnt, hndl, mem->domain,
+		mem->partition_num, 4096, &iova, &buffer_size, UNCACHED);
+	if (rc) {
+		pr_err("Failed to get device address: %d\n", rc);
+		goto fail_device_address;
+	}
 
 	mem->kvaddr += offset;
-	mem->paddr += offset;
 	mem->mem_type = client->mem_type;
 	mem->smem_priv = hndl;
-	mem->device_addr = mem->paddr;
-	mem->size = len;
+	mem->device_addr = iova + offset;
+	mem->size = buffer_size;
 	return rc;
+fail_device_address:
+	ion_unmap_kernel(client->clnt, hndl);
 fail_map:
 	ion_free(client->clnt, hndl);
 fail_import_fd:
@@ -64,14 +101,19 @@
 }
 
 static int alloc_ion_mem(struct smem_client *client, size_t size,
-		u32 align, u32 flags, struct msm_smem *mem)
+		u32 align, u32 flags, int domain, int partition,
+		struct msm_smem *mem)
 {
 	struct ion_handle *hndl;
-	size_t len;
+	unsigned long iova = 0;
+	unsigned long buffer_size = 0;
 	int rc = 0;
 	if (size == 0)
 		goto skip_mem_alloc;
 	flags = flags | ION_HEAP(ION_CP_MM_HEAP_ID);
+	if (align < 4096)
+		align = 4096;
+	size = (size + 4095) & (~4095);
 	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",
@@ -81,20 +123,27 @@
 	}
 	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->domain = domain;
+	mem->partition_num = partition;
 	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;
 	}
+	rc = get_device_address(client->clnt, hndl, mem->domain,
+		mem->partition_num, align, &iova, &buffer_size, UNCACHED);
+	if (rc) {
+		pr_err("Failed to get device address: %d\n", rc);
+		goto fail_device_address;
+	}
+	mem->device_addr = iova;
+	pr_err("device_address = 0x%lx, kvaddr = 0x%p\n",
+		mem->device_addr, mem->kvaddr);
+	mem->size = size;
 	return rc;
+fail_device_address:
+	ion_unmap_kernel(client->clnt, hndl);
 fail_map:
 	ion_free(client->clnt, hndl);
 fail_shared_mem_alloc:
@@ -104,6 +153,8 @@
 
 static void free_ion_mem(struct smem_client *client, struct msm_smem *mem)
 {
+	put_device_address(client->clnt,
+		mem->smem_priv, mem->domain);
 	ion_unmap_kernel(client->clnt, mem->smem_priv);
 	ion_free(client->clnt, mem->smem_priv);
 }
@@ -122,7 +173,8 @@
 	ion_client_destroy(client->clnt);
 }
 
-struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset)
+struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset,
+	int domain, int partition)
 {
 	struct smem_client *client = clt;
 	int rc = 0;
@@ -138,7 +190,8 @@
 	}
 	switch (client->mem_type) {
 	case SMEM_ION:
-		rc = ion_user_to_kernel(clt, fd, offset, mem);
+		rc = ion_user_to_kernel(clt, fd, offset,
+			domain, partition, mem);
 		break;
 	default:
 		pr_err("Mem type not supported\n");
@@ -177,7 +230,8 @@
 	return client;
 };
 
-struct msm_smem *msm_smem_alloc(void *clt, size_t size, u32 align, u32 flags)
+struct msm_smem *msm_smem_alloc(void *clt, size_t size, u32 align, u32 flags,
+		int domain, int partition)
 {
 	struct smem_client *client;
 	int rc = 0;
@@ -195,7 +249,8 @@
 	}
 	switch (client->mem_type) {
 	case SMEM_ION:
-		rc = alloc_ion_mem(client, size, align, flags, mem);
+		rc = alloc_ion_mem(client, size, align, flags,
+			domain, partition, mem);
 		break;
 	default:
 		pr_err("Mem type not supported\n");
diff --git a/drivers/media/video/msm_vidc/msm_smem.h b/drivers/media/video/msm_vidc/msm_smem.h
index 84d12cc..b742c79 100644
--- a/drivers/media/video/msm_vidc/msm_smem.h
+++ b/drivers/media/video/msm_vidc/msm_smem.h
@@ -24,15 +24,17 @@
 	int mem_type;
 	size_t size;
 	void *kvaddr;
-	unsigned long paddr;
 	unsigned long device_addr;
-	/*Device address and others to follow*/
+	int domain;
+	int partition_num;
 	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);
+struct msm_smem *msm_smem_alloc(void *clt, size_t size, u32 align, u32 flags,
+		int domain, int partition);
 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);
+struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset, int
+		domain, int partition);
 #endif
diff --git a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
index 6cd9e6b..e1a71ce 100644
--- a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
+++ b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
@@ -21,7 +21,9 @@
 #include <linux/debugfs.h>
 #include <linux/version.h>
 #include <linux/slab.h>
-
+#include <linux/of.h>
+#include <mach/iommu.h>
+#include <mach/iommu_domains.h>
 #include <media/msm_vidc.h>
 #include "msm_vidc_internal.h"
 #include "vidc_hal_api.h"
@@ -277,8 +279,10 @@
 			goto exit;
 		}
 		handle = msm_smem_user_to_kernel(v4l2_inst->mem_client,
-				b->m.planes[i].reserved[0],
-				b->m.planes[i].reserved[1]);
+			b->m.planes[i].reserved[0],
+			b->m.planes[i].reserved[1],
+			vidc_inst->core->resources.io_map[NS_MAP].domain,
+			0);
 		if (!handle) {
 			pr_err("Failed to get device buffer address\n");
 			kfree(binfo);
@@ -420,11 +424,92 @@
 {
 }
 
+static size_t read_u32_array(struct platform_device *pdev,
+		char *name, u32 *arr, size_t size)
+{
+	int len;
+	size_t sz = 0;
+	struct device_node *np = pdev->dev.of_node;
+	if (!of_get_property(np, name, &len)) {
+		pr_err("Failed to read %s from device tree\n",
+			name);
+		goto fail_read;
+	}
+	sz = len / sizeof(u32);
+	if (sz <= 0) {
+		pr_err("%s not specified in device tree\n", name);
+		goto fail_read;
+	}
+	if (sz > size) {
+		pr_err("Not enough memory to store %s values\n", name);
+		goto fail_read;
+	}
+	if (of_property_read_u32_array(np, name, arr, sz)) {
+		pr_err("error while reading %s from device tree\n",
+			name);
+		goto fail_read;
+	}
+	return sz;
+fail_read:
+	sz = 0;
+	return sz;
+}
+
+static int register_iommu_domains(struct platform_device *pdev,
+	struct msm_vidc_core *core)
+{
+	size_t len;
+	struct msm_iova_partition partition;
+	struct msm_iova_layout layout;
+	int rc = 0;
+	int i;
+	struct iommu_info *io_map = core->resources.io_map;
+	strlcpy(io_map[CP_MAP].name, "vidc-cp-map",
+			sizeof(io_map[CP_MAP].name));
+	strlcpy(io_map[CP_MAP].ctx, "venus_cp",
+			sizeof(io_map[CP_MAP].ctx));
+	strlcpy(io_map[NS_MAP].name, "vidc-ns-map",
+			sizeof(io_map[NS_MAP].name));
+	strlcpy(io_map[NS_MAP].ctx, "venus_ns",
+			sizeof(io_map[NS_MAP].ctx));
+
+	for (i = 0; i < MAX_MAP; i++) {
+		len = read_u32_array(pdev, io_map[i].name,
+				io_map[i].addr_range,
+				(sizeof(io_map[i].addr_range)/sizeof(u32)));
+		if (!len) {
+			pr_err("Error in reading cp address range\n");
+			rc = -EINVAL;
+			break;
+		}
+		partition.start = io_map[i].addr_range[0];
+		partition.size = io_map[i].addr_range[1];
+		layout.partitions = &partition;
+		layout.npartitions = 1;
+		layout.client_name = io_map[i].name;
+		layout.domain_flags = 0;
+		pr_debug("Registering domain with: %lx, %lx, %s\n",
+			partition.start, partition.size, layout.client_name);
+		io_map[i].domain = msm_register_domain(&layout);
+		if (io_map[i].domain < 0) {
+			pr_err("Failed to register cp domain\n");
+			rc = -EINVAL;
+			break;
+		}
+	}
+	/* There is no api provided as msm_unregister_domain, so
+	 * we are not able to unregister the previously
+	 * registered domains if any domain registration fails.*/
+	BUG_ON(i < MAX_MAP);
+	return rc;
+}
+
 static int msm_vidc_initialize_core(struct platform_device *pdev,
 				struct msm_vidc_core *core)
 {
 	struct resource *res;
 	int i = 0;
+	int rc = 0;
 	if (!core)
 		return -EINVAL;
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -443,13 +528,19 @@
 	INIT_LIST_HEAD(&core->instances);
 	mutex_init(&core->sync_lock);
 	spin_lock_init(&core->lock);
-	core->base_addr = 0x14f00000;
+	core->base_addr = 0x0;
 	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;
+	rc = register_iommu_domains(pdev, core);
+	if (rc) {
+		pr_err("Failed to register iommu domains: %d\n", rc);
+		goto fail_domain_register;
+	}
+fail_domain_register:
+	return rc;
 }
 
 static int __devinit msm_vidc_probe(struct platform_device *pdev)
diff --git a/drivers/media/video/msm_vidc/msm_vdec.c b/drivers/media/video/msm_vidc/msm_vdec.c
index 6fe196e..a8c6428 100644
--- a/drivers/media/video/msm_vidc/msm_vdec.c
+++ b/drivers/media/video/msm_vidc/msm_vdec.c
@@ -22,6 +22,8 @@
 #define MAX_PLANES 1
 #define DEFAULT_HEIGHT 720
 #define DEFAULT_WIDTH 1280
+#define MAX_SUPPORTED_WIDTH 4096
+#define MAX_SUPPORTED_HEIGHT 2160
 #define MIN_NUM_OUTPUT_BUFFERS 2
 #define MAX_NUM_OUTPUT_BUFFERS 6
 
@@ -169,7 +171,7 @@
 static u32 get_frame_size_compressed(int plane,
 					u32 height, u32 width)
 {
-	return height * width * 3/2;
+	return (MAX_SUPPORTED_WIDTH * MAX_SUPPORTED_HEIGHT * 3/2)/2;
 }
 
 static const struct msm_vidc_format vdec_formats[] = {
@@ -307,8 +309,21 @@
 			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;
+			if (!inst->extradata_handle) {
+				inst->extradata_handle =
+				msm_smem_alloc(inst->mem_client,
+				4096 * 1024, 1, 0,
+				inst->core->resources.io_map[NS_MAP].domain,
+				0);
+				if (!inst->extradata_handle) {
+					pr_err("Failed to allocate extradta memory\n");
+					rc = -ENOMEM;
+					break;
+				}
+			}
+			buffer_info.extradata_addr =
+				inst->extradata_handle->device_addr;
+			buffer_info.extradata_size = 4096 * 1024;
 			rc = vidc_hal_session_set_buffers((void *)inst->session,
 					&buffer_info);
 			if (rc) {
@@ -344,7 +359,8 @@
 			buffer_info.num_buffers = 1;
 			buffer_info.align_device_addr =
 				 b->m.planes[i].m.userptr;
-			buffer_info.extradata_addr = 0;
+			buffer_info.extradata_addr =
+				inst->extradata_handle->device_addr;
 			rc = vidc_hal_session_release_buffers(
 				(void *)inst->session, &buffer_info);
 			if (rc)
diff --git a/drivers/media/video/msm_vidc/msm_venc.c b/drivers/media/video/msm_vidc/msm_venc.c
index 4950097..72c6685 100644
--- a/drivers/media/video/msm_vidc/msm_venc.c
+++ b/drivers/media/video/msm_vidc/msm_venc.c
@@ -23,11 +23,11 @@
 #define MIN_NUM_OUTPUT_BUFFERS 2
 #define MAX_NUM_OUTPUT_BUFFERS 8
 #define MIN_BIT_RATE 64
-#define MAX_BIT_RATE 20000
+#define MAX_BIT_RATE 160000
 #define DEFAULT_BIT_RATE 64
 #define BIT_RATE_STEP 1
 #define MIN_FRAME_RATE 1
-#define MAX_FRAME_RATE 120
+#define MAX_FRAME_RATE 240
 #define DEFAULT_FRAME_RATE 30
 #define DEFAULT_IR_MBS 30
 #define MAX_SLICE_BYTE_SIZE 1024
@@ -63,6 +63,30 @@
 	"Model 2",
 	NULL
 };
+
+static const char *const h263_level[] = {
+	"1.0",
+	"2.0",
+	"3.0",
+	"4.0",
+	"4.5",
+	"5.0",
+	"6.0",
+	"7.0",
+};
+
+static const char *const h263_profile[] = {
+	"Baseline",
+	"H320 Coding",
+	"Backward Compatible",
+	"ISWV2",
+	"ISWV3",
+	"High Compression",
+	"Internet",
+	"Interlace",
+	"High Latency",
+};
+
 static const struct msm_vidc_ctrl msm_venc_ctrls[] = {
 	{
 		.id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE,
@@ -212,10 +236,48 @@
 		.minimum = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
 		.maximum = V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
 		.default_value = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
-		.step = 1,
+		.step = 0,
 		.menu_skip_mask = 0,
 	},
 	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE,
+		.name = "H263 Profile",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE,
+		.maximum = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY,
+		.default_value = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE,
+		.menu_skip_mask = ~(
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY)
+		),
+		.qmenu = h263_profile,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL,
+		.name = "H263 Level",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0,
+		.maximum = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0,
+		.default_value = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0,
+		.menu_skip_mask = ~(
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0)
+		),
+		.qmenu = h263_level,
+	},
+	{
 		.id = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION,
 		.name = "Rotation",
 		.type = V4L2_CTRL_TYPE_MENU,
@@ -410,8 +472,11 @@
 	venc_h264_profile_level = {HAL_H264_PROFILE_BASELINE,
 		HAL_H264_LEVEL_1};
 static struct hal_profile_level
-	venc_mpeg4_profile_level = {HAL_H264_PROFILE_BASELINE,
-		HAL_H264_LEVEL_1};
+	venc_mpeg4_profile_level = {HAL_MPEG4_PROFILE_SIMPLE,
+		HAL_MPEG4_LEVEL_0};
+static struct hal_profile_level
+	venc_h263_profile_level = {HAL_H263_PROFILE_BASELINE,
+				HAL_H263_LEVEL_10};
 static struct hal_h264_entropy_control
 	venc_h264_entropy_control = {HAL_H264_ENTROPY_CAVLC,
 		HAL_H264_CABAC_MODEL_0};
@@ -456,6 +521,14 @@
 		.type = CAPTURE_PORT,
 	},
 	{
+		.name = "VP8",
+		.description = "VP8 compressed format",
+		.fourcc = V4L2_PIX_FMT_VP8,
+		.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,
@@ -896,6 +969,84 @@
 		pr_debug("\nLevel: %d\n",
 			   profile_level.level);
 		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE:
+		property_id =
+			HAL_PARAM_PROFILE_LEVEL_CURRENT;
+
+		switch (control.value) {
+		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE:
+			control.value = HAL_H263_PROFILE_BASELINE;
+			break;
+		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING:
+			control.value = HAL_H263_PROFILE_H320CODING;
+			break;
+		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE:
+			control.value = HAL_H263_PROFILE_BACKWARDCOMPATIBLE;
+			break;
+		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2:
+			control.value = HAL_H263_PROFILE_ISWV2;
+			break;
+		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3:
+			control.value = HAL_H263_PROFILE_ISWV3;
+			break;
+		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION:
+			control.value = HAL_H263_PROFILE_HIGHCOMPRESSION;
+			break;
+		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET:
+			control.value = HAL_H263_PROFILE_INTERNET;
+			break;
+		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE:
+			control.value = HAL_H263_PROFILE_INTERLACE;
+			break;
+		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY:
+			control.value = HAL_H263_PROFILE_HIGHLATENCY;
+			break;
+		default:
+			break;
+		}
+		profile_level.profile = control.value;
+		venc_h263_profile_level.profile = control.value;
+		profile_level.level = venc_h263_profile_level.level;
+		pdata = &profile_level;
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL:
+		property_id =
+			HAL_PARAM_PROFILE_LEVEL_CURRENT;
+
+		switch (control.value) {
+		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0:
+			control.value = HAL_H263_LEVEL_10;
+			break;
+		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0:
+			control.value = HAL_H263_LEVEL_20;
+			break;
+		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0:
+			control.value = HAL_H263_LEVEL_30;
+			break;
+		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0:
+			control.value = HAL_H263_LEVEL_40;
+			break;
+		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5:
+			control.value = HAL_H263_LEVEL_45;
+			break;
+		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0:
+			control.value = HAL_H263_LEVEL_50;
+			break;
+		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0:
+			control.value = HAL_H263_LEVEL_60;
+			break;
+		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0:
+			control.value = HAL_H263_LEVEL_70;
+			break;
+		default:
+			break;
+		}
+
+		profile_level.level = control.value;
+		venc_h263_profile_level.level = control.value;
+		profile_level.profile = venc_h263_profile_level.profile;
+		pdata = &profile_level;
+		break;
 	case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION:
 		property_id =
 			HAL_CONFIG_VPE_OPERATIONS;
diff --git a/drivers/media/video/msm_vidc/msm_vidc.c b/drivers/media/video/msm_vidc/msm_vidc.c
index 28fe2b8..4d4cec5 100644
--- a/drivers/media/video/msm_vidc/msm_vidc.c
+++ b/drivers/media/video/msm_vidc/msm_vidc.c
@@ -316,6 +316,8 @@
 				kfree(buf);
 			}
 		}
+		if (inst->extradata_handle)
+			msm_smem_free(inst->mem_client, inst->extradata_handle);
 		spin_unlock_irqrestore(&inst->lock, flags);
 		msm_smem_delete_client(inst->mem_client);
 	}
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
index 261879d..cd330316 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -13,6 +13,10 @@
 
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/iommu.h>
+#include <mach/iommu.h>
+#include <mach/iommu_domains.h>
+#include <mach/peripheral-loader.h>
 
 #include "msm_vidc_common.h"
 #include "vidc_hal_api.h"
@@ -52,6 +56,60 @@
 	return NULL;
 }
 
+static int msm_comm_iommu_attach(struct msm_vidc_core *core)
+{
+	int rc;
+	struct iommu_domain *domain;
+	int i;
+	struct iommu_info *io_map;
+	struct device *dev;
+	for (i = 0; i < MAX_MAP; i++) {
+		io_map = &core->resources.io_map[i];
+		dev = msm_iommu_get_ctx(io_map->ctx);
+		domain = msm_get_iommu_domain(io_map->domain);
+		if (IS_ERR_OR_NULL(domain)) {
+			pr_err("Failed to get domain: %s\n", io_map->name);
+			rc = PTR_ERR(domain);
+			break;
+		}
+		rc = iommu_attach_device(domain, dev);
+		if (rc) {
+			pr_err("IOMMU attach failed: %s\n", io_map->name);
+			break;
+		}
+	}
+	if (i < MAX_MAP) {
+		i--;
+		for (; i >= 0; i--) {
+			io_map = &core->resources.io_map[i];
+			dev = msm_iommu_get_ctx(io_map->ctx);
+			domain = msm_get_iommu_domain(io_map->domain);
+			if (dev && domain)
+				iommu_detach_device(domain, dev);
+		}
+	}
+	return rc;
+}
+
+static void msm_comm_iommu_detach(struct msm_vidc_core *core)
+{
+	struct device *dev;
+	struct iommu_domain *domain;
+	struct iommu_info *io_map;
+	int i;
+	if (!core) {
+		pr_err("Invalid paramter: %p\n", core);
+		return;
+	}
+	for (i = 0; i < MAX_MAP; i++) {
+		io_map = &core->resources.io_map[i];
+		dev = msm_iommu_get_ctx(io_map->ctx);
+		domain = msm_get_iommu_domain(io_map->domain);
+		if (dev && domain)
+			iommu_detach_device(domain, dev);
+	}
+}
+
 const struct msm_vidc_format *msm_comm_get_pixel_fmt_index(
 	const struct msm_vidc_format fmt[], int size, int index, int fmt_type)
 {
@@ -454,6 +512,47 @@
 		break;
 	}
 }
+static int msm_comm_load_fw(struct msm_vidc_core *core)
+{
+	int rc = 0;
+	if (!core) {
+		pr_err("Invalid paramter: %p\n", core);
+		return -EINVAL;
+	}
+
+	if (!core->resources.fw.cookie)
+		core->resources.fw.cookie = pil_get("venus");
+
+	if (IS_ERR_OR_NULL(core->resources.fw.cookie)) {
+		pr_err("Failed to download firmware\n");
+		rc = -ENOMEM;
+		goto fail_pil_get;
+	}
+	rc = msm_comm_iommu_attach(core);
+	if (rc) {
+		pr_err("Failed to attach iommu");
+		goto fail_iommu_attach;
+	}
+	return rc;
+fail_iommu_attach:
+	pil_put(core->resources.fw.cookie);
+	core->resources.fw.cookie = NULL;
+fail_pil_get:
+	return rc;
+}
+
+static void msm_comm_unload_fw(struct msm_vidc_core *core)
+{
+	if (!core) {
+		pr_err("Invalid paramter: %p\n", core);
+		return;
+	}
+	if (core->resources.fw.cookie) {
+		pil_put(core->resources.fw.cookie);
+		core->resources.fw.cookie = NULL;
+		msm_comm_iommu_detach(core);
+	}
+}
 
 static int msm_comm_init_core_done(struct msm_vidc_inst *inst)
 {
@@ -499,18 +598,28 @@
 				core->id, core->state);
 		goto core_already_inited;
 	}
+	rc = msm_comm_load_fw(core);
+	if (rc) {
+		pr_err("Failed to load video firmware\n");
+		goto fail_fw_download;
+	}
 	init_completion(&core->completions[SYS_MSG_INDEX(SYS_INIT_DONE)]);
-	rc = vidc_hal_core_init(core->device);
+	rc = vidc_hal_core_init(core->device,
+		core->resources.io_map[NS_MAP].domain);
 	if (rc) {
 		pr_err("Failed to init core, id = %d\n", core->id);
-		goto exit;
+		goto fail_core_init;
 	}
 	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;
+fail_core_init:
+	msm_comm_unload_fw(core);
+fail_fw_download:
 	mutex_unlock(&core->sync_lock);
 	return rc;
 }
@@ -536,6 +645,7 @@
 		spin_lock_irqsave(&core->lock, flags);
 		core->state = VIDC_CORE_UNINIT;
 		spin_unlock_irqrestore(&core->lock, flags);
+		msm_comm_unload_fw(core);
 	}
 core_already_uninited:
 	change_inst_state(inst, MSM_VIDC_CORE_UNINIT);
@@ -889,9 +999,16 @@
 		} else if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 			frame_data.filled_len = 0;
 			frame_data.buffer_type = HAL_BUFFER_OUTPUT;
-			frame_data.extradata_addr = 0;
-			pr_debug("Sending ftb to hal..: Alloc: %d :filled: %d\n",
+			if (inst->extradata_handle) {
+				frame_data.extradata_addr =
+					inst->extradata_handle->device_addr;
+			} else {
+				frame_data.extradata_addr = 0;
+			}
+			pr_debug("Sending ftb to hal..: Alloc: %d :filled: %d",
 				frame_data.alloc_len, frame_data.filled_len);
+			pr_debug(" extradata_addr: %d\n",
+				frame_data.extradata_addr);
 			rc = vidc_hal_session_ftb((void *) inst->session,
 					&frame_data);
 		} else {
@@ -1020,7 +1137,8 @@
 	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);
+				inst->buff_req.buffer[6].buffer_size, 1, 0,
+				inst->core->resources.io_map[NS_MAP].domain, 0);
 		if (!handle) {
 			pr_err("Failed to allocate scratch memory\n");
 			rc = -ENOMEM;
diff --git a/drivers/media/video/msm_vidc/msm_vidc_internal.h b/drivers/media/video/msm_vidc/msm_vidc_internal.h
index fb8fbc4..151fb21 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_internal.h
+++ b/drivers/media/video/msm_vidc/msm_vidc_internal.h
@@ -106,6 +106,29 @@
 	struct video_device vdev;
 };
 
+struct msm_vidc_fw {
+	void *cookie;
+};
+
+struct iommu_info {
+	u32 addr_range[2];
+	char name[64];
+	char ctx[64];
+	int domain;
+	int partition;
+};
+
+enum io_maps {
+	CP_MAP,
+	NS_MAP,
+	MAX_MAP
+};
+
+struct msm_vidc_resources {
+	struct msm_vidc_fw fw;
+	struct iommu_info io_map[MAX_MAP];
+};
+
 struct msm_vidc_core {
 	struct list_head list;
 	struct mutex sync_lock;
@@ -121,6 +144,7 @@
 	u32 register_size;
 	u32 irq;
 	enum vidc_core_state state;
+	struct msm_vidc_resources resources;
 	struct completion completions[SYS_MSG_END - SYS_MSG_START + 1];
 };
 
@@ -146,6 +170,7 @@
 	bool in_reconfig;
 	u32 reconfig_width;
 	u32 reconfig_height;
+	struct msm_smem *extradata_handle;
 };
 
 extern struct msm_vidc_drv *vidc_driver;
diff --git a/drivers/media/video/msm_vidc/vidc_hal.c b/drivers/media/video/msm_vidc/vidc_hal.c
index 11b1ed0..9052a63 100644
--- a/drivers/media/video/msm_vidc/vidc_hal.c
+++ b/drivers/media/video/msm_vidc/vidc_hal.c
@@ -23,7 +23,7 @@
 #define REG_ADDR_OFFSET_BITMASK	0x000FFFFF
 
 /*Workaround for virtio */
-#define HFI_VIRTIO_FW_BIAS		0x14f00000
+#define HFI_VIRTIO_FW_BIAS		0x0
 
 struct hal_device_data hal_ctxt;
 
@@ -300,7 +300,8 @@
 	return 0;
 }
 
-static int vidc_hal_alloc(void *mem, void *clnt, u32 size, u32 align, u32 flags)
+static int vidc_hal_alloc(void *mem, void *clnt, u32 size, u32 align, u32 flags,
+		int domain)
 {
 	struct vidc_mem_addr *vmem;
 	struct msm_smem *alloc;
@@ -312,7 +313,7 @@
 	vmem = (struct vidc_mem_addr *)mem;
 	HAL_MSG_HIGH("start to alloc: size:%d, Flags: %d", size, flags);
 
-	alloc  = msm_smem_alloc(clnt, size, align, flags);
+	alloc  = msm_smem_alloc(clnt, size, align, flags, domain, 0);
 	HAL_MSG_LOW("Alloc done");
 	if (!alloc) {
 		HAL_MSG_HIGH("Alloc fail in %s", __func__);
@@ -503,7 +504,7 @@
 	device->hal_client = NULL;
 }
 
-static int vidc_hal_interface_queues_init(struct hal_device *dev)
+static int vidc_hal_interface_queues_init(struct hal_device *dev, int domain)
 {
 	struct hfi_queue_table_header *q_tbl_hdr;
 	struct hfi_queue_header *q_hdr;
@@ -513,7 +514,7 @@
 
 	rc = vidc_hal_alloc((void *) &dev->iface_q_table,
 					dev->hal_client,
-			VIDC_IFACEQ_TABLE_SIZE, 1, 0);
+			VIDC_IFACEQ_TABLE_SIZE, 1, 0, domain);
 	if (rc) {
 		HAL_MSG_ERROR("%s:iface_q_table_alloc_fail", __func__);
 		return -ENOMEM;
@@ -533,7 +534,7 @@
 		iface_q = &dev->iface_queues[i];
 		rc = vidc_hal_alloc((void *) &iface_q->q_array,
 				dev->hal_client, VIDC_IFACEQ_QUEUE_SIZE,
-				1, 0);
+				1, 0, domain);
 		if (rc) {
 			HAL_MSG_ERROR("%s:iface_q_table_alloc[%d]_fail",
 						__func__, i);
@@ -592,7 +593,7 @@
 	return rc;
 }
 
-int vidc_hal_core_init(void *device)
+int vidc_hal_core_init(void *device, int domain)
 {
 	struct hfi_cmd_sys_init_packet pkt;
 	int rc = 0;
@@ -619,10 +620,10 @@
 
 		HAL_MSG_ERROR("Device_Virt_Address : 0x%x,"
 		"Register_Virt_Addr: 0x%x",
-		(u32) dev->hal_data->device_base_addr,
+		dev->hal_data->device_base_addr,
 		(u32) dev->hal_data->register_base_addr);
 
-		rc = vidc_hal_interface_queues_init(dev);
+		rc = vidc_hal_interface_queues_init(dev, domain);
 		if (rc) {
 			HAL_MSG_ERROR("failed to init queues");
 			rc = -ENOMEM;
@@ -1120,6 +1121,7 @@
 	case HAL_CONFIG_VENC_REQUEST_IFRAME:
 		pkt->rg_property_data[0] =
 			HFI_PROPERTY_CONFIG_VENC_REQUEST_SYNC_FRAME;
+		pkt->size += sizeof(u32);
 		break;
 	case HAL_PARAM_VENC_MPEG4_SHORT_HEADER:
 		break;
@@ -1988,11 +1990,11 @@
 		list_for_each_safe(curr, next, &core.dev_head) {
 			device = list_entry(curr, struct hal_device, list);
 			if (device && device->hal_data->irq == irq &&
-				(CONTAINS((u32)device->hal_data->
+				(CONTAINS(device->hal_data->
 						device_base_addr,
 						FIRMWARE_SIZE, fw_addr) ||
 				CONTAINS(fw_addr, FIRMWARE_SIZE,
-						(u32)device->hal_data->
+						device->hal_data->
 						device_base_addr) ||
 				CONTAINS((u32)device->hal_data->
 						register_base_addr,
@@ -2006,12 +2008,12 @@
 				OVERLAPS(reg_addr, reg_size,
 						(u32)device->hal_data->
 						register_base_addr, reg_size) ||
-				OVERLAPS((u32)device->hal_data->
+				OVERLAPS(device->hal_data->
 						device_base_addr,
 						FIRMWARE_SIZE, fw_addr,
 						FIRMWARE_SIZE) ||
 				OVERLAPS(fw_addr, FIRMWARE_SIZE,
-						(u32)device->hal_data->
+						device->hal_data->
 						device_base_addr,
 						FIRMWARE_SIZE))) {
 				return 0;
@@ -2061,7 +2063,7 @@
 	struct hal_data *hal = NULL;
 	int rc = 0;
 
-	if (device_id || !fw_base_addr || !reg_base || !reg_size ||
+	if (device_id || !reg_base || !reg_size ||
 			!irq || !callback) {
 		HAL_MSG_ERROR("Invalid Paramters");
 		return NULL;
@@ -2079,13 +2081,7 @@
 			return NULL;
 		}
 		hal->irq = irq;
-		hal->device_base_addr =
-			ioremap_nocache(fw_base_addr, FIRMWARE_SIZE);
-		if (!hal->device_base_addr) {
-			HAL_MSG_ERROR("could not map fw addr %d of size %d",
-						  fw_base_addr, FIRMWARE_SIZE);
-			goto err_map;
-		}
+		hal->device_base_addr = fw_base_addr;
 		hal->register_base_addr =
 			ioremap_nocache(reg_base, reg_size);
 		if (!hal->register_base_addr) {
diff --git a/drivers/media/video/msm_vidc/vidc_hal.h b/drivers/media/video/msm_vidc/vidc_hal.h
index 6c7e5df..8e7c3d3 100644
--- a/drivers/media/video/msm_vidc/vidc_hal.h
+++ b/drivers/media/video/msm_vidc/vidc_hal.h
@@ -834,7 +834,7 @@
 
 struct hal_data {
 	u32 irq;
-	u8 *device_base_addr;
+	u32 device_base_addr;
 	u8 *register_base_addr;
 };
 
diff --git a/drivers/media/video/msm_vidc/vidc_hal_api.h b/drivers/media/video/msm_vidc/vidc_hal_api.h
index 332bbac..c77ae12 100644
--- a/drivers/media/video/msm_vidc/vidc_hal_api.h
+++ b/drivers/media/video/msm_vidc/vidc_hal_api.h
@@ -943,7 +943,7 @@
 };
 
 /* VIDC_HAL CORE API's */
-int vidc_hal_core_init(void *device);
+int vidc_hal_core_init(void *device, int domain);
 int vidc_hal_core_release(void *device);
 int vidc_hal_core_pc_prep(void *device);
 int vidc_hal_core_set_resource(void *device,
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index 154d523..9339800 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -83,6 +83,8 @@
 #define VENDOR_ID		0x18D1
 #define PRODUCT_ID		0x0001
 
+#define ANDROID_DEVICE_NODE_NAME_LENGTH 11
+
 struct android_usb_function {
 	char *name;
 	void *config;
@@ -94,6 +96,8 @@
 	/* for android_dev.enabled_functions */
 	struct list_head enabled_list;
 
+	struct android_dev *android_dev;
+
 	/* Optional: initialization during gadget bind */
 	int (*init)(struct android_usb_function *, struct usb_composite_dev *);
 	/* Optional: cleanup during gadget unbind */
@@ -132,12 +136,18 @@
 	char pm_qos[5];
 	struct pm_qos_request pm_qos_req_dma;
 	struct work_struct work;
+
+	struct list_head list_item;
+
+	struct usb_configuration config;
 };
 
 static struct class *android_class;
-static struct android_dev *_android_dev;
+static struct list_head android_dev_list;
+static int android_dev_count;
 static int android_bind_config(struct usb_configuration *c);
 static void android_unbind_config(struct usb_configuration *c);
+static struct android_dev *cdev_to_android_dev(struct usb_composite_dev *cdev);
 
 /* string IDs are assigned dynamically */
 #define STRING_MANUFACTURER_IDX		0
@@ -189,12 +199,6 @@
 	NULL,
 };
 
-static struct usb_configuration android_config_driver = {
-	.label		= "android",
-	.unbind		= android_unbind_config,
-	.bConfigurationValue = 1,
-};
-
 enum android_device_state {
 	USB_DISCONNECTED,
 	USB_CONNECTED,
@@ -291,7 +295,7 @@
 		return;
 
 	if (--dev->disable_depth == 0) {
-		usb_add_config(cdev, &android_config_driver,
+		usb_add_config(cdev, &dev->config,
 					android_bind_config);
 		usb_gadget_connect(cdev->gadget);
 	}
@@ -305,7 +309,7 @@
 		usb_gadget_disconnect(cdev->gadget);
 		/* Cancel pending control requests */
 		usb_ep_dequeue(cdev->gadget->ep0, cdev->req);
-		usb_remove_config(cdev, &android_config_driver);
+		usb_remove_config(cdev, &dev->config);
 	}
 }
 
@@ -343,7 +347,7 @@
 
 static void adb_android_function_enable(struct android_usb_function *f)
 {
-	struct android_dev *dev = _android_dev;
+	struct android_dev *dev = f->android_dev;
 	struct adb_data *data = f->config;
 
 	data->enabled = true;
@@ -355,7 +359,7 @@
 
 static void adb_android_function_disable(struct android_usb_function *f)
 {
-	struct android_dev *dev = _android_dev;
+	struct android_dev *dev = f->android_dev;
 	struct adb_data *data = f->config;
 
 	data->enabled = false;
@@ -376,32 +380,30 @@
 
 static void adb_ready_callback(void)
 {
-	struct android_dev *dev = _android_dev;
+	struct android_dev *dev = adb_function.android_dev;
 	struct adb_data *data = adb_function.config;
 
-	mutex_lock(&dev->mutex);
-
 	data->opened = true;
 
-	if (data->enabled)
+	if (data->enabled && dev) {
+		mutex_lock(&dev->mutex);
 		android_enable(dev);
-
-	mutex_unlock(&dev->mutex);
+		mutex_unlock(&dev->mutex);
+	}
 }
 
 static void adb_closed_callback(void)
 {
-	struct android_dev *dev = _android_dev;
+	struct android_dev *dev = adb_function.android_dev;
 	struct adb_data *data = adb_function.config;
 
-	mutex_lock(&dev->mutex);
-
 	data->opened = false;
 
-	if (data->enabled)
+	if (data->enabled) {
+		mutex_lock(&dev->mutex);
 		android_disable(dev);
-
-	mutex_unlock(&dev->mutex);
+		mutex_unlock(&dev->mutex);
+	}
 }
 
 
@@ -609,6 +611,7 @@
 	char buf[32], *b;
 	int once = 0, err = -1;
 	int (*notify)(uint32_t, const char *);
+	struct android_dev *dev = cdev_to_android_dev(c->cdev);
 
 	strlcpy(buf, diag_clients, sizeof(buf));
 	b = strim(buf);
@@ -617,8 +620,8 @@
 		notify = NULL;
 		name = strsep(&b, ",");
 		/* Allow only first diag channel to update pid and serial no */
-		if (_android_dev->pdata && !once++)
-			notify = _android_dev->pdata->update_pid_and_serial_num;
+		if (dev->pdata && !once++)
+			notify = dev->pdata->update_pid_and_serial_num;
 
 		if (name) {
 			err = diag_function_add(c, name, notify);
@@ -1065,7 +1068,7 @@
 static int mass_storage_function_init(struct android_usb_function *f,
 					struct usb_composite_dev *cdev)
 {
-	struct android_dev *dev = _android_dev;
+	struct android_dev *dev = cdev_to_android_dev(cdev);
 	struct mass_storage_function_config *config;
 	struct fsg_common *common;
 	int err;
@@ -1247,7 +1250,7 @@
 static int android_init_functions(struct android_usb_function **functions,
 				  struct usb_composite_dev *cdev)
 {
-	struct android_dev *dev = _android_dev;
+	struct android_dev *dev = cdev_to_android_dev(cdev);
 	struct android_usb_function *f;
 	struct device_attribute **attrs;
 	struct device_attribute *attr;
@@ -1256,6 +1259,7 @@
 
 	for (; (f = *functions++); index++) {
 		f->dev_name = kasprintf(GFP_KERNEL, "f_%s", f->name);
+		f->android_dev = NULL;
 		if (!f->dev_name) {
 			err = -ENOMEM;
 			goto err_out;
@@ -1342,9 +1346,15 @@
 	struct android_usb_function *f;
 	while ((f = *functions++)) {
 		if (!strcmp(name, f->name)) {
-			list_add_tail(&f->enabled_list,
-						&dev->enabled_functions);
-			return 0;
+			if (f->android_dev)
+				pr_err("%s cannot be enabled on two devices\n",
+					f->name);
+			else {
+				list_add_tail(&f->enabled_list,
+					      &dev->enabled_functions);
+				f->android_dev = dev;
+				return 0;
+			}
 		}
 	}
 	return -EINVAL;
@@ -1356,14 +1366,17 @@
 static ssize_t remote_wakeup_show(struct device *pdev,
 		struct device_attribute *attr, char *buf)
 {
+	struct android_dev *dev = dev_get_drvdata(pdev);
+
 	return snprintf(buf, PAGE_SIZE, "%d\n",
-			!!(android_config_driver.bmAttributes &
+			!!(dev->config.bmAttributes &
 				USB_CONFIG_ATT_WAKEUP));
 }
 
 static ssize_t remote_wakeup_store(struct device *pdev,
 		struct device_attribute *attr, const char *buff, size_t size)
 {
+	struct android_dev *dev = dev_get_drvdata(pdev);
 	int enable = 0;
 
 	sscanf(buff, "%d", &enable);
@@ -1372,9 +1385,9 @@
 			enable ? "enabling" : "disabling");
 
 	if (enable)
-		android_config_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+		dev->config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
 	else
-		android_config_driver.bmAttributes &= ~USB_CONFIG_ATT_WAKEUP;
+		dev->config.bmAttributes &= ~USB_CONFIG_ATT_WAKEUP;
 
 	return size;
 }
@@ -1403,6 +1416,7 @@
 			       const char *buff, size_t size)
 {
 	struct android_dev *dev = dev_get_drvdata(pdev);
+	struct android_usb_function *f;
 	char *name;
 	char buf[256], *b;
 	int err;
@@ -1414,6 +1428,10 @@
 		return -EBUSY;
 	}
 
+	/* Clear previous enabled list */
+	list_for_each_entry(f, &dev->enabled_functions, enabled_list) {
+		f->android_dev = NULL;
+	}
 	INIT_LIST_HEAD(&dev->enabled_functions);
 
 	strlcpy(buf, buff, sizeof(buf));
@@ -1612,7 +1630,7 @@
 
 static int android_bind_config(struct usb_configuration *c)
 {
-	struct android_dev *dev = _android_dev;
+	struct android_dev *dev = cdev_to_android_dev(c->cdev);
 	int ret = 0;
 
 	ret = android_bind_enabled_functions(dev, c);
@@ -1624,26 +1642,34 @@
 
 static void android_unbind_config(struct usb_configuration *c)
 {
-	struct android_dev *dev = _android_dev;
+	struct android_dev *dev = cdev_to_android_dev(c->cdev);
 
 	android_unbind_enabled_functions(dev, c);
 }
 
 static int android_bind(struct usb_composite_dev *cdev)
 {
-	struct android_dev *dev = _android_dev;
+	struct android_dev *dev;
 	struct usb_gadget	*gadget = cdev->gadget;
 	int			gcnum, id, ret;
 
+	/* Bind to the last android_dev that was probed */
+	dev = list_entry(android_dev_list.prev, struct android_dev, list_item);
+
+	dev->cdev = cdev;
+
 	/*
 	 * Start disconnected. Userspace will connect the gadget once
 	 * it is done configuring the functions.
 	 */
 	usb_gadget_disconnect(gadget);
 
-	ret = android_init_functions(dev->functions, cdev);
-	if (ret)
-		return ret;
+	/* Init the supported functions only once, on the first android_dev */
+	if (android_dev_count == 1) {
+		ret = android_init_functions(dev->functions, cdev);
+		if (ret)
+			return ret;
+	}
 
 	/* Allocate string descriptor numbers ... note that string
 	 * contents can be overridden by the composite_dev glue.
@@ -1673,7 +1699,7 @@
 	device_desc.iSerialNumber = id;
 
 	if (gadget_is_otg(cdev->gadget))
-		android_config_driver.descriptors = otg_desc;
+		dev->config.descriptors = otg_desc;
 
 	gcnum = usb_gadget_controller_number(gadget);
 	if (gcnum >= 0)
@@ -1684,14 +1710,12 @@
 		device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
 	}
 
-	dev->cdev = cdev;
-
 	return 0;
 }
 
 static int android_usb_unbind(struct usb_composite_dev *cdev)
 {
-	struct android_dev *dev = _android_dev;
+	struct android_dev *dev = cdev_to_android_dev(cdev);
 
 	manufacturer_string[0] = '\0';
 	product_string[0] = '\0';
@@ -1712,8 +1736,8 @@
 static int
 android_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *c)
 {
-	struct android_dev		*dev = _android_dev;
 	struct usb_composite_dev	*cdev = get_gadget_data(gadget);
+	struct android_dev		*dev = cdev_to_android_dev(cdev);
 	struct usb_request		*req = cdev->req;
 	struct android_usb_function	*f;
 	int value = -EOPNOTSUPP;
@@ -1756,8 +1780,8 @@
 
 static void android_disconnect(struct usb_gadget *gadget)
 {
-	struct android_dev *dev = _android_dev;
 	struct usb_composite_dev *cdev = get_gadget_data(gadget);
+	struct android_dev *dev = cdev_to_android_dev(cdev);
 	unsigned long flags;
 
 	composite_disconnect(gadget);
@@ -1768,14 +1792,21 @@
 	spin_unlock_irqrestore(&cdev->lock, flags);
 }
 
-static int android_create_device(struct android_dev *dev)
+static int android_create_device(struct android_dev *dev, u8 usb_core_id)
 {
 	struct device_attribute **attrs = android_usb_attributes;
 	struct device_attribute *attr;
+	char device_node_name[ANDROID_DEVICE_NODE_NAME_LENGTH];
 	int err;
 
+	/*
+	 * The primary usb core should always have usb_core_id=0, since
+	 * Android user space is currently interested in android0 events.
+	 */
+	snprintf(device_node_name, ANDROID_DEVICE_NODE_NAME_LENGTH,
+		 "android%d", usb_core_id);
 	dev->dev = device_create(android_class, NULL,
-					MKDEV(0, 0), NULL, "android0");
+					MKDEV(0, 0), NULL, device_node_name);
 	if (IS_ERR(dev->dev))
 		return PTR_ERR(dev->dev);
 
@@ -1801,27 +1832,64 @@
 	device_destroy(android_class, dev->dev->devt);
 }
 
+static struct android_dev *cdev_to_android_dev(struct usb_composite_dev *cdev)
+{
+	struct android_dev *dev = NULL;
+
+	/* Find the android dev from the list */
+	list_for_each_entry(dev, &android_dev_list, list_item) {
+		if (dev->cdev == cdev)
+			break;
+	}
+
+	return dev;
+}
+
 static int __devinit android_probe(struct platform_device *pdev)
 {
 	struct android_usb_platform_data *pdata = pdev->dev.platform_data;
-	struct android_dev *dev = _android_dev;
+	struct android_dev *android_dev;
 	int ret = 0;
 
-	dev->pdata = pdata;
+	if (!android_class) {
+		android_class = class_create(THIS_MODULE, "android_usb");
+		if (IS_ERR(android_class))
+			return PTR_ERR(android_class);
+	}
 
-	android_class = class_create(THIS_MODULE, "android_usb");
-	if (IS_ERR(android_class))
-		return PTR_ERR(android_class);
+	android_dev = kzalloc(sizeof(*android_dev), GFP_KERNEL);
+	if (!android_dev) {
+		pr_err("%s(): Failed to alloc memory for android_dev\n",
+			__func__);
+		ret = -ENOMEM;
+		goto err_alloc;
+	}
 
-	ret = android_create_device(dev);
+	android_dev->config.label = pdev->name;
+	android_dev->config.unbind = android_unbind_config;
+	android_dev->config.bConfigurationValue = 1;
+	android_dev->disable_depth = 1;
+	android_dev->functions = supported_functions;
+	INIT_LIST_HEAD(&android_dev->enabled_functions);
+	INIT_WORK(&android_dev->work, android_work);
+	mutex_init(&android_dev->mutex);
+
+	android_dev->pdata = pdata;
+
+	list_add_tail(&android_dev->list_item, &android_dev_list);
+	android_dev_count++;
+
+	if (pdata)
+		composite_driver.usb_core_id = pdata->usb_core_id;
+	else
+		composite_driver.usb_core_id = 0; /*To backward compatibility*/
+
+	ret = android_create_device(android_dev, composite_driver.usb_core_id);
 	if (ret) {
 		pr_err("%s(): android_create_device failed\n", __func__);
 		goto err_dev;
 	}
 
-	if (pdata)
-		composite_driver.usb_core_id = pdata->usb_core_id;
-
 	ret = usb_composite_probe(&android_usb_driver, android_bind);
 	if (ret) {
 		pr_err("%s(): Failed to register android "
@@ -1831,67 +1899,91 @@
 
 	/* pm qos request to prevent apps idle power collapse */
 	if (pdata && pdata->swfi_latency)
-		pm_qos_add_request(&dev->pm_qos_req_dma,
+		pm_qos_add_request(&android_dev->pm_qos_req_dma,
 			PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE);
-	strlcpy(dev->pm_qos, "high", sizeof(dev->pm_qos));
+	strlcpy(android_dev->pm_qos, "high", sizeof(android_dev->pm_qos));
 
 	return ret;
 err_probe:
-	android_destroy_device(dev);
+	android_destroy_device(android_dev);
 err_dev:
-	class_destroy(android_class);
+	list_del(&android_dev->list_item);
+	android_dev_count--;
+	kfree(android_dev);
+err_alloc:
+	if (list_empty(&android_dev_list)) {
+		class_destroy(android_class);
+		android_class = NULL;
+	}
 	return ret;
 }
 
 static int android_remove(struct platform_device *pdev)
 {
-	struct android_dev *dev = _android_dev;
+	struct android_dev *dev = NULL;
 	struct android_usb_platform_data *pdata = pdev->dev.platform_data;
+	int usb_core_id = 0;
 
-	android_destroy_device(dev);
-	class_destroy(android_class);
-	usb_composite_unregister(&android_usb_driver);
-	if (pdata && pdata->swfi_latency)
-		pm_qos_remove_request(&dev->pm_qos_req_dma);
+	if (pdata)
+		usb_core_id = pdata->usb_core_id;
+
+	/* Find the android dev from the list */
+	list_for_each_entry(dev, &android_dev_list, list_item) {
+		if (!dev->pdata)
+			break; /*To backward compatibility*/
+		if (dev->pdata->usb_core_id == usb_core_id)
+			break;
+	}
+
+	if (dev) {
+		android_destroy_device(dev);
+		if (pdata && pdata->swfi_latency)
+			pm_qos_remove_request(&dev->pm_qos_req_dma);
+		list_del(&dev->list_item);
+		android_dev_count--;
+		kfree(dev);
+	}
+
+	if (list_empty(&android_dev_list)) {
+		class_destroy(android_class);
+		android_class = NULL;
+		usb_composite_unregister(&android_usb_driver);
+	}
 
 	return 0;
 }
 
+static const struct platform_device_id android_id_table[] __devinitconst = {
+	{
+		.name = "android_usb",
+	},
+	{
+		.name = "android_usb_hsic",
+	},
+};
+
 static struct platform_driver android_platform_driver = {
 	.driver = { .name = "android_usb"},
 	.probe = android_probe,
 	.remove = android_remove,
+	.id_table = android_id_table,
 };
 
 static int __init init(void)
 {
-	struct android_dev *dev;
 	int ret;
 
-	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-	if (!dev) {
-		pr_err("%s(): Failed to alloc memory for android_dev\n",
-				__func__);
-		return -ENOMEM;
-	}
-
-	dev->disable_depth = 1;
-	dev->functions = supported_functions;
-	INIT_LIST_HEAD(&dev->enabled_functions);
-	INIT_WORK(&dev->work, android_work);
-	mutex_init(&dev->mutex);
-
-	_android_dev = dev;
-
 	/* Override composite driver functions */
 	composite_driver.setup = android_setup;
 	composite_driver.disconnect = android_disconnect;
 
+	INIT_LIST_HEAD(&android_dev_list);
+	android_dev_count = 0;
+
 	ret = platform_driver_register(&android_platform_driver);
 	if (ret) {
 		pr_err("%s(): Failed to register android"
 				 "platform driver\n", __func__);
-		kfree(dev);
 	}
 
 	return ret;
@@ -1901,7 +1993,5 @@
 static void __exit cleanup(void)
 {
 	platform_driver_unregister(&android_platform_driver);
-	kfree(_android_dev);
-	_android_dev = NULL;
 }
 module_exit(cleanup);
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index d35d861..86c0e73 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1625,7 +1625,7 @@
 {
 	int retval;
 
-	if (!driver || !driver->dev || !bind || composite)
+	if (!driver || !driver->dev || !bind)
 		return -EINVAL;
 
 	if (!driver->name)
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 278e04e..1ea3982 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -2865,15 +2865,6 @@
 	common->ep0req = cdev->req;
 	common->cdev = cdev;
 
-	/* Maybe allocate device-global string IDs, and patch descriptors */
-	if (fsg_strings[FSG_STRING_INTERFACE].id == 0) {
-		rc = usb_string_id(cdev);
-		if (unlikely(rc < 0))
-			goto error_release;
-		fsg_strings[FSG_STRING_INTERFACE].id = rc;
-		fsg_intf_desc.iInterface = rc;
-	}
-
 	/*
 	 * Create the LUNs, open their backing files, and register the
 	 * LUN devices in sysfs.
@@ -3194,6 +3185,15 @@
 	struct fsg_dev *fsg;
 	int rc;
 
+	/* Maybe allocate device-global string IDs, and patch descriptors */
+	if (fsg_strings[FSG_STRING_INTERFACE].id == 0) {
+		rc = usb_string_id(cdev);
+		if (unlikely(rc < 0))
+			return rc;
+		fsg_strings[FSG_STRING_INTERFACE].id = rc;
+		fsg_intf_desc.iInterface = rc;
+	}
+
 	fsg = kzalloc(sizeof *fsg, GFP_KERNEL);
 	if (unlikely(!fsg))
 		return -ENOMEM;
diff --git a/drivers/video/msm/external_common.c b/drivers/video/msm/external_common.c
index b6bf47d..36c8749 100644
--- a/drivers/video/msm/external_common.c
+++ b/drivers/video/msm/external_common.c
@@ -1974,13 +1974,15 @@
 
 bool hdmi_common_get_video_format_from_drv_data(struct msm_fb_data_type *mfd)
 {
-	uint32 format;
+	uint32 format = HDMI_VFRMT_1920x1080p60_16_9;
 	struct fb_var_screeninfo *var = &mfd->fbi->var;
 	bool changed = TRUE;
 
 	if (var->reserved[2]) {
 		format = var->reserved[2]-1;
 		DEV_DBG("reserved format is %d\n", format);
+	} else if (hdmi_prim_resolution) {
+		format = hdmi_prim_resolution - 1;
 	} else {
 		DEV_DBG("detecting resolution from %dx%d use var->reserved[3]"
 			" to specify mode", mfd->var_xres, mfd->var_yres);
@@ -1995,15 +1997,33 @@
 				: HDMI_VFRMT_720x576p50_16_9;
 			break;
 		case 1280:
-			format = HDMI_VFRMT_1280x720p60_16_9;
+			if (mfd->var_frame_rate == 50000)
+				format = HDMI_VFRMT_1280x720p50_16_9;
+			else
+				format = HDMI_VFRMT_1280x720p60_16_9;
 			break;
 		case 1440:
-			format = (mfd->var_yres == 480)
+			format = (mfd->var_yres == 240) /* interlaced has half
+							   of y res.
+							*/
 				? HDMI_VFRMT_1440x480i60_16_9
 				: HDMI_VFRMT_1440x576i50_16_9;
 			break;
 		case 1920:
-			format = HDMI_VFRMT_1920x1080p60_16_9;
+			if (mfd->var_yres == 540) {/* interlaced */
+				format = HDMI_VFRMT_1920x1080i60_16_9;
+			} else if (mfd->var_yres == 1080) {
+				if (mfd->var_frame_rate == 50000)
+					format = HDMI_VFRMT_1920x1080p50_16_9;
+				else if (mfd->var_frame_rate == 24000)
+					format = HDMI_VFRMT_1920x1080p24_16_9;
+				else if (mfd->var_frame_rate == 25000)
+					format = HDMI_VFRMT_1920x1080p25_16_9;
+				else if (mfd->var_frame_rate == 30000)
+					format = HDMI_VFRMT_1920x1080p30_16_9;
+				else
+					format = HDMI_VFRMT_1920x1080p60_16_9;
+			}
 			break;
 		}
 	}
diff --git a/drivers/video/msm/external_common.h b/drivers/video/msm/external_common.h
index 57c0804..43a8794 100644
--- a/drivers/video/msm/external_common.h
+++ b/drivers/video/msm/external_common.h
@@ -112,6 +112,8 @@
 #define HDMI_VFRMT_MAX			59
 #define HDMI_VFRMT_FORCE_32BIT		0x7FFFFFFF
 
+extern int ext_resolution;
+
 struct hdmi_disp_mode_timing_type {
 	uint32	video_format;
 	uint32	active_h;
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index f919ad0..4a1427d 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -4742,7 +4742,14 @@
 	}
 
 	external_common_state = &hdmi_msm_state->common;
-	external_common_state->video_resolution = HDMI_VFRMT_1920x1080p30_16_9;
+
+	if (hdmi_prim_display && hdmi_prim_resolution)
+		external_common_state->video_resolution =
+			hdmi_prim_resolution - 1;
+	else
+		external_common_state->video_resolution =
+			HDMI_VFRMT_1920x1080p60_16_9;
+
 #ifdef CONFIG_FB_MSM_HDMI_3D
 	external_common_state->switch_3d = hdmi_msm_switch_3d;
 #endif
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 3204552..c9be60a 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -2398,6 +2398,8 @@
 #ifdef CONFIG_FB_MSM_MIPI_DSI
 	case MIPI_VIDEO_PANEL:
 #ifndef CONFIG_FB_MSM_MDP303
+		mipi = &mfd->panel_info.mipi;
+		configure_mdp_core_clk_table((mipi->dsi_pclk_rate) * 23 / 20);
 		pdata->on = mdp4_dsi_video_on;
 		pdata->off = mdp4_dsi_video_off;
 		mfd->hw_refresh = TRUE;
diff --git a/drivers/video/msm/mdp.h b/drivers/video/msm/mdp.h
index 3fd51ba..184c5ce 100644
--- a/drivers/video/msm/mdp.h
+++ b/drivers/video/msm/mdp.h
@@ -88,6 +88,7 @@
 extern struct mdp_ccs mdp_ccs_yuv2rgb ;
 extern struct mdp_ccs mdp_ccs_rgb2yuv ;
 extern unsigned char hdmi_prim_display;
+extern unsigned char hdmi_prim_resolution;
 
 /*
  * MDP Image Structure
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 5f58af7..36cbbbd 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -193,6 +193,7 @@
 
 static struct msm_fb_platform_data *msm_fb_pdata;
 unsigned char hdmi_prim_display;
+unsigned char hdmi_prim_resolution;
 
 int msm_fb_detect_client(const char *name)
 {
@@ -213,6 +214,8 @@
 			if (!strncmp((char *)msm_fb_pdata->prim_panel_name,
 				"hdmi_msm", len))
 				hdmi_prim_display = 1;
+				hdmi_prim_resolution =
+					msm_fb_pdata->ext_resolution;
 			return 0;
 		} else {
 			ret = -EPERM;
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 48058e6..ae81dcd 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -204,6 +204,15 @@
 #define MSM_CAM_IOCTL_STATS_FLUSH_BUFQ \
 	_IOR(MSM_CAM_IOCTL_MAGIC, 57, struct msm_stats_flush_bufq *)
 
+#define MSM_CAM_IOCTL_SET_MCTL_SDEV \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 58, struct msm_mctl_set_sdev_data *)
+
+#define MSM_CAM_IOCTL_UNSET_MCTL_SDEV \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 59, struct msm_mctl_set_sdev_data *)
+
+#define MSM_CAM_IOCTL_GET_INST_HANDLE \
+	_IOR(MSM_CAM_IOCTL_MAGIC, 60, uint32_t *)
+
 struct msm_stats_reqbuf {
 	int num_buf;		/* how many buffers requested */
 	int stats_type;	/* stats type */
@@ -334,6 +343,7 @@
 		struct msm_pp_frame_mp mp[MAX_PLANES];
 	};
 	int node_type;
+	uint32_t inst_handle;
 };
 
 struct msm_cam_evt_divert_frame {
@@ -767,7 +777,7 @@
 #define MSM_V4L2_PID_CTRL_CMD               (V4L2_CID_PRIVATE_BASE+13)
 #define MSM_V4L2_PID_EVT_SUB_INFO           (V4L2_CID_PRIVATE_BASE+14)
 #define MSM_V4L2_PID_STROBE_FLASH           (V4L2_CID_PRIVATE_BASE+15)
-#define MSM_V4L2_PID_MMAP_ENTRY             (V4L2_CID_PRIVATE_BASE+16)
+#define MSM_V4L2_PID_INST_HANDLE            (V4L2_CID_PRIVATE_BASE+16)
 #define MSM_V4L2_PID_MMAP_INST              (V4L2_CID_PRIVATE_BASE+17)
 #define MSM_V4L2_PID_PP_PLANE_INFO          (V4L2_CID_PRIVATE_BASE+18)
 #define MSM_V4L2_PID_MAX                    MSM_V4L2_PID_PP_PLANE_INFO
@@ -1623,13 +1633,35 @@
 	uint8_t num_planes;
 	struct plane_data plane[MAX_PLANES];
 	uint32_t sp_y_offset;
-	uint8_t vpe_can_use;
+	uint32_t inst_handle;
 };
 
 #define QCAMERA_NAME "qcamera"
+#define QCAMERA_SERVER_NAME "qcamera_server"
 #define QCAMERA_DEVICE_GROUP_ID 1
 #define QCAMERA_VNODE_GROUP_ID 2
 
+enum msm_cam_subdev_type {
+	CSIPHY_DEV,
+	CSID_DEV,
+	CSIC_DEV,
+	ISPIF_DEV,
+	VFE_DEV,
+	AXI_DEV,
+	VPE_DEV,
+	SENSOR_DEV,
+	ACTUATOR_DEV,
+	EEPROM_DEV,
+	GESTURE_DEV,
+	IRQ_ROUTER_DEV,
+	CPP_DEV,
+};
+
+struct msm_mctl_set_sdev_data {
+	uint32_t revision;
+	enum msm_cam_subdev_type sdev_type;
+};
+
 #define MSM_CAM_V4L2_IOCTL_GET_CAMERA_INFO \
 	_IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct msm_camera_v4l2_ioctl_t)
 
@@ -1654,6 +1686,39 @@
 #define MSM_CAM_V4L2_IOCTL_PRIVATE_S_CTRL \
 	_IOWR('V', BASE_VIDIOC_PRIVATE + 8, struct msm_camera_v4l2_ioctl_t)
 
+#define MSM_CAM_V4L2_IOCTL_PRIVATE_G_CTRL \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 9, struct msm_camera_v4l2_ioctl_t)
+
+#define VIDIOC_MSM_VPE_INIT \
+	_IO('V', BASE_VIDIOC_PRIVATE + 15)
+
+#define VIDIOC_MSM_VPE_RELEASE \
+	_IO('V', BASE_VIDIOC_PRIVATE + 16)
+
+#define VIDIOC_MSM_VPE_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 17, struct msm_mctl_pp_params *)
+
+#define VIDIOC_MSM_AXI_INIT \
+	_IO('V', BASE_VIDIOC_PRIVATE + 18)
+
+#define VIDIOC_MSM_AXI_RELEASE \
+	_IO('V', BASE_VIDIOC_PRIVATE + 19)
+
+#define VIDIOC_MSM_AXI_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 20, void *)
+
+#define VIDIOC_MSM_AXI_IRQ \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 21, void *)
+
+#define VIDIOC_MSM_AXI_BUF_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 22, void *)
+
+#define VIDIOC_MSM_VFE_INIT \
+	_IO('V', BASE_VIDIOC_PRIVATE + 22)
+
+#define VIDIOC_MSM_VFE_RELEASE \
+	_IO('V', BASE_VIDIOC_PRIVATE + 23)
+
 struct msm_camera_v4l2_ioctl_t {
 	uint32_t id;
 	void __user *ioctl_ptr;
@@ -1804,4 +1869,38 @@
 
 #define V4L2_EVENT_CPP_FRAME_DONE  (V4L2_EVENT_PRIVATE_START + 0)
 
+/* Instance Handle - inst_handle
+ * Data bundle containing the information about where
+ * to get a buffer for a particular camera instance.
+ * This is a bitmask containing the following data:
+ * Buffer Handle Bitmask:
+ *      ------------------------------------
+ *      Bits    :  Purpose
+ *      ------------------------------------
+ *      31 - 24 :  Reserved.
+ *      23      :  is Image mode valid?
+ *      22 - 16 :  Image mode.
+ *      15      :  is MCTL PP inst idx valid?
+ *      14 - 8  :  MCTL PP inst idx.
+ *      7       :  is Video inst idx valid?
+ *      6 - 0   :  Video inst idx.
+ */
+#define CLR_IMG_MODE(handle)	(handle &= 0xFF00FFFF)
+#define SET_IMG_MODE(handle, data)	\
+	(handle |= ((0x1 << 23) | ((data & 0x7F) << 16)))
+#define GET_IMG_MODE(handle)	\
+	((handle & 0x800000) ? ((handle & 0x7F0000) >> 16) : 0xFF)
+
+#define CLR_MCTLPP_INST_IDX(handle)	(handle &= 0xFFFF00FF)
+#define SET_MCTLPP_INST_IDX(handle, data)	\
+	(handle |= ((0x1 << 15) | ((data & 0x7F) << 8)))
+#define GET_MCTLPP_INST_IDX(handle)	\
+	((handle & 0x8000) ? ((handle & 0x7F00) >> 8) : 0xFF)
+
+#define CLR_VIDEO_INST_IDX(handle)	(handle &= 0xFFFFFF00)
+#define GET_VIDEO_INST_IDX(handle)	\
+	((handle & 0x80) ? (handle & 0x7F) : 0xFF)
+#define SET_VIDEO_INST_IDX(handle, data)	\
+	(handle |= (0x1 << 7) | (data & 0x7F))
+
 #endif /* __LINUX_MSM_CAMERA_H */
diff --git a/include/media/msm_isp.h b/include/media/msm_isp.h
index 1f3527b..3df6ded 100644
--- a/include/media/msm_isp.h
+++ b/include/media/msm_isp.h
@@ -336,7 +336,7 @@
 #define VFE_OUTPUTS_RDI1                BIT(12)
 
 struct msm_frame_info {
-	uint32_t image_mode;
+	uint32_t inst_handle;
 	uint32_t path;
 };
 
diff --git a/include/media/radio-iris.h b/include/media/radio-iris.h
index 25a1d84..988de6a 100644
--- a/include/media/radio-iris.h
+++ b/include/media/radio-iris.h
@@ -599,6 +599,7 @@
 	V4L2_CID_PRIVATE_SPUR_FREQ_RMSSI,
 	V4L2_CID_PRIVATE_SPUR_SELECTION,
 	V4L2_CID_PRIVATE_UPDATE_SPUR_TABLE,
+	V4L2_CID_PRIVATE_VALID_CHANNEL,
 
 	/*using private CIDs under userclass*/
 	V4L2_CID_PRIVATE_IRIS_READ_DEFAULT = 0x00980928,
@@ -786,6 +787,11 @@
 #define CALIB_DATA_OFSET  2
 #define CALIB_MODE_OFSET  1
 #define MAX_CALIB_SIZE 75
+
+/* Channel validity */
+#define INVALID_CHANNEL		(0)
+#define VALID_CHANNEL		(1)
+
 struct hci_fm_set_cal_req_proc {
 	__u8    mode;
 	/*Max process calibration data size*/
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index dd8e2aa..fc15fb1 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -253,7 +253,9 @@
 	sync_supers_tsk = kthread_run(bdi_sync_supers, NULL, "sync_supers");
 	BUG_ON(IS_ERR(sync_supers_tsk));
 
-	setup_timer(&sync_supers_timer, sync_supers_timer_fn, 0);
+	init_timer_deferrable(&sync_supers_timer);
+	sync_supers_timer.function = sync_supers_timer_fn;
+	sync_supers_timer.data = 0;
 	bdi_arm_supers_timer();
 
 	err = bdi_init(&default_backing_dev_info);