Merge "regulator: pm8xxx-regulator: Add slew_rate platform data parameter" into msm-3.0
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index 2698ea7..e62dfbd 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -315,9 +315,9 @@
 				};
 			};
 
-			regulator@1d00 {
+			regulator@a000 {
 				regulator-name = "8941_boost";
-				reg = <0x1d00 0x100>;
+				reg = <0xa000 0x100>;
 				compatible = "qcom,qpnp-regulator";
 				status = "disabled";
 			};
diff --git a/arch/arm/boot/dts/msmcopper-regulator.dtsi b/arch/arm/boot/dts/msmcopper-regulator.dtsi
index bb26e00..0d0c587 100644
--- a/arch/arm/boot/dts/msmcopper-regulator.dtsi
+++ b/arch/arm/boot/dts/msmcopper-regulator.dtsi
@@ -41,7 +41,7 @@
 				status = "okay";
 			};
 
-			pm8941_boost: regulator@1d00 {
+			pm8941_boost: regulator@a000 {
 				regulator-min-microvolt = <5000000>;
 				regulator-max-microvolt = <5000000>;
 				qcom,enable-time = <500>;
diff --git a/arch/arm/mach-msm/board-8064-display.c b/arch/arm/mach-msm/board-8064-display.c
index 60bc26c..040e573 100644
--- a/arch/arm/mach-msm/board-8064-display.c
+++ b/arch/arm/mach-msm/board-8064-display.c
@@ -227,7 +227,7 @@
 };
 
 static int mdp_core_clk_rate_table[] = {
-	85330000,
+	59080000,
 	128000000,
 	160000000,
 	200000000,
@@ -235,7 +235,7 @@
 
 static struct msm_panel_common_pdata mdp_pdata = {
 	.gpio = MDP_VSYNC_GPIO,
-	.mdp_core_clk_rate = 85330000,
+	.mdp_core_clk_rate = 59080000,
 	.mdp_core_clk_table = mdp_core_clk_rate_table,
 	.num_mdp_clk = ARRAY_SIZE(mdp_core_clk_rate_table),
 	.mdp_bus_scale_table = &mdp_bus_scale_pdata,
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index b018a20..6ef1335a 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -1023,6 +1023,151 @@
 	},
 };
 
+#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
+static struct gpiomux_setting sdc2_clk_active_cfg = {
+	.func = GPIOMUX_FUNC_2,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting sdc2_cmd_data_0_3_active_cfg = {
+	.func = GPIOMUX_FUNC_2,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting sdc2_suspended_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting sdc2_data_1_suspended_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct msm_gpiomux_config apq8064_sdc2_configs[] __initdata = {
+	{
+		.gpio      = 59,
+		.settings = {
+			[GPIOMUX_ACTIVE] = &sdc2_clk_active_cfg,
+			[GPIOMUX_SUSPENDED] = &sdc2_suspended_cfg,
+		},
+	},
+	{
+		.gpio      = 57,
+		.settings = {
+			[GPIOMUX_ACTIVE] = &sdc2_cmd_data_0_3_active_cfg,
+			[GPIOMUX_SUSPENDED] = &sdc2_suspended_cfg,
+		},
+
+	},
+	{
+		.gpio      = 62,
+		.settings = {
+			[GPIOMUX_ACTIVE] = &sdc2_cmd_data_0_3_active_cfg,
+			[GPIOMUX_SUSPENDED] = &sdc2_suspended_cfg,
+		},
+	},
+	{
+		.gpio      = 61,
+		.settings = {
+			[GPIOMUX_ACTIVE] = &sdc2_cmd_data_0_3_active_cfg,
+			[GPIOMUX_SUSPENDED] = &sdc2_data_1_suspended_cfg,
+		},
+	},
+	{
+		.gpio      = 60,
+		.settings = {
+			[GPIOMUX_ACTIVE] = &sdc2_cmd_data_0_3_active_cfg,
+			[GPIOMUX_SUSPENDED] = &sdc2_suspended_cfg,
+		},
+	},
+	{
+		.gpio      = 58,
+		.settings = {
+			[GPIOMUX_ACTIVE] = &sdc2_cmd_data_0_3_active_cfg,
+			[GPIOMUX_SUSPENDED] = &sdc2_suspended_cfg,
+		},
+	},
+};
+#endif
+
+
+#ifdef CONFIG_MMC_MSM_SDC4_SUPPORT
+static struct gpiomux_setting sdc4_clk_active_cfg = {
+	.func = GPIOMUX_FUNC_2,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting sdc4_cmd_data_0_3_active_cfg = {
+	.func = GPIOMUX_FUNC_2,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting sdc4_suspended_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting sdc4_data_1_suspended_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct msm_gpiomux_config apq8064_sdc4_configs[] __initdata = {
+	{
+		.gpio      = 68,
+		.settings = {
+			[GPIOMUX_ACTIVE] = &sdc4_clk_active_cfg,
+			[GPIOMUX_SUSPENDED] = &sdc4_suspended_cfg,
+		},
+	},
+	{
+		.gpio      = 67,
+		.settings = {
+			[GPIOMUX_ACTIVE] = &sdc4_cmd_data_0_3_active_cfg,
+			[GPIOMUX_SUSPENDED] = &sdc4_suspended_cfg,
+		},
+
+	},
+	{
+		.gpio      = 66,
+		.settings = {
+			[GPIOMUX_ACTIVE] = &sdc4_cmd_data_0_3_active_cfg,
+			[GPIOMUX_SUSPENDED] = &sdc4_suspended_cfg,
+		},
+	},
+	{
+		.gpio      = 65,
+		.settings = {
+			[GPIOMUX_ACTIVE] = &sdc4_cmd_data_0_3_active_cfg,
+			[GPIOMUX_SUSPENDED] = &sdc4_data_1_suspended_cfg,
+		},
+	},
+	{
+		.gpio      = 64,
+		.settings = {
+			[GPIOMUX_ACTIVE] = &sdc4_cmd_data_0_3_active_cfg,
+			[GPIOMUX_SUSPENDED] = &sdc4_suspended_cfg,
+		},
+	},
+	{
+		.gpio      = 63,
+		.settings = {
+			[GPIOMUX_ACTIVE] = &sdc4_cmd_data_0_3_active_cfg,
+			[GPIOMUX_SUSPENDED] = &sdc4_suspended_cfg,
+		},
+	},
+};
+#endif
+
 void __init apq8064_init_gpiomux(void)
 {
 	int rc;
@@ -1104,4 +1249,14 @@
 	 if (machine_is_mpq8064_cdp())
 		msm_gpiomux_install(mpq8064_ir_configs,
 				ARRAY_SIZE(mpq8064_ir_configs));
+
+#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
+	 msm_gpiomux_install(apq8064_sdc2_configs,
+			     ARRAY_SIZE(apq8064_sdc2_configs));
+#endif
+
+#ifdef CONFIG_MMC_MSM_SDC4_SUPPORT
+	 msm_gpiomux_install(apq8064_sdc4_configs,
+			     ARRAY_SIZE(apq8064_sdc4_configs));
+#endif
 }
diff --git a/arch/arm/mach-msm/board-8064-storage.c b/arch/arm/mach-msm/board-8064-storage.c
index 72126c8..96e54b6 100644
--- a/arch/arm/mach-msm/board-8064-storage.c
+++ b/arch/arm/mach-msm/board-8064-storage.c
@@ -188,13 +188,50 @@
 	},
 };
 
+static struct msm_mmc_gpio sdc2_gpio[] = {
+	{59, "sdc2_clk"},
+	{57, "sdc2_cmd"},
+	{62, "sdc2_dat_0"},
+	{61, "sdc2_dat_1"},
+	{60, "sdc2_dat_2"},
+	{58, "sdc2_dat_3"},
+};
+
+static struct msm_mmc_gpio sdc4_gpio[] = {
+	{68, "sdc4_clk"},
+	{67, "sdc4_cmd"},
+	{66, "sdc4_dat_0"},
+	{65, "sdc4_dat_1"},
+	{64, "sdc4_dat_2"},
+	{63, "sdc4_dat_3"},
+};
+
+static struct msm_mmc_gpio_data mmc_gpio_data[MAX_SDCC_CONTROLLER] = {
+	[SDCC2] = {
+		.gpio = sdc2_gpio,
+		.size = ARRAY_SIZE(sdc2_gpio),
+	},
+	[SDCC4] = {
+		.gpio = sdc4_gpio,
+		.size = ARRAY_SIZE(sdc4_gpio),
+	}
+};
+
 static struct msm_mmc_pin_data mmc_slot_pin_data[MAX_SDCC_CONTROLLER] = {
 	[SDCC1] = {
 		.pad_data = &mmc_pad_data[SDCC1],
 	},
+	[SDCC2] = {
+		.is_gpio = 1,
+		.gpio_data = &mmc_gpio_data[SDCC2],
+	},
 	[SDCC3] = {
 		.pad_data = &mmc_pad_data[SDCC3],
 	},
+	[SDCC4] = {
+		.is_gpio = 1,
+		.gpio_data = &mmc_gpio_data[SDCC4],
+	},
 };
 
 #define MSM_MPM_PIN_SDC1_DAT1	17
@@ -227,6 +264,26 @@
 static struct mmc_platform_data *apq8064_sdc1_pdata;
 #endif
 
+#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
+static unsigned int sdc2_sup_clk_rates[] = {
+	400000, 24000000, 48000000
+};
+
+static struct mmc_platform_data sdc2_data = {
+	.ocr_mask       = MMC_VDD_27_28 | MMC_VDD_28_29,
+	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
+	.sup_clk_table	= sdc2_sup_clk_rates,
+	.sup_clk_cnt	= ARRAY_SIZE(sdc2_sup_clk_rates),
+	.pclk_src_dfab	= 1,
+	.pin_data	= &mmc_slot_pin_data[SDCC2],
+	.sdiowakeup_irq = MSM_GPIO_TO_INT(61),
+	.msm_bus_voting_data = &sps_to_ddr_bus_voting_data,
+};
+static struct mmc_platform_data *apq8064_sdc2_pdata = &sdc2_data;
+#else
+static struct mmc_platform_data *apq8064_sdc2_pdata;
+#endif
+
 #ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
 static unsigned int sdc3_sup_clk_rates[] = {
 	400000, 24000000, 48000000, 96000000, 192000000
@@ -258,6 +315,27 @@
 static struct mmc_platform_data *apq8064_sdc3_pdata;
 #endif
 
+
+#ifdef CONFIG_MMC_MSM_SDC4_SUPPORT
+static unsigned int sdc4_sup_clk_rates[] = {
+	400000, 24000000, 48000000
+};
+
+static struct mmc_platform_data sdc4_data = {
+	.ocr_mask       = MMC_VDD_27_28 | MMC_VDD_28_29,
+	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
+	.sup_clk_table	= sdc4_sup_clk_rates,
+	.sup_clk_cnt	= ARRAY_SIZE(sdc4_sup_clk_rates),
+	.pclk_src_dfab	= 1,
+	.pin_data	= &mmc_slot_pin_data[SDCC4],
+	.sdiowakeup_irq = MSM_GPIO_TO_INT(65),
+	.msm_bus_voting_data = &sps_to_ddr_bus_voting_data,
+};
+static struct mmc_platform_data *apq8064_sdc4_pdata = &sdc4_data;
+#else
+static struct mmc_platform_data *apq8064_sdc4_pdata;
+#endif
+
 void __init apq8064_init_mmc(void)
 {
 	if ((machine_is_apq8064_rumi3()) || machine_is_apq8064_sim()) {
@@ -278,6 +356,9 @@
 	if (apq8064_sdc1_pdata)
 		apq8064_add_sdcc(1, apq8064_sdc1_pdata);
 
+	if (apq8064_sdc2_pdata)
+		apq8064_add_sdcc(2, apq8064_sdc2_pdata);
+
 	if (apq8064_sdc3_pdata) {
 		if (!machine_is_apq8064_cdp()) {
 			apq8064_sdc3_pdata->wpswitch_gpio = 0;
@@ -292,4 +373,7 @@
 		}
 		apq8064_add_sdcc(3, apq8064_sdc3_pdata);
 	}
+
+	if (apq8064_sdc4_pdata)
+		apq8064_add_sdcc(4, apq8064_sdc4_pdata);
 }
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 0234de6..566befb 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -2191,6 +2191,7 @@
 	&apq8064_rpm_device,
 	&apq8064_rpm_log_device,
 	&apq8064_rpm_stat_device,
+	&apq_device_tz_log,
 	&msm_bus_8064_apps_fabric,
 	&msm_bus_8064_sys_fabric,
 	&msm_bus_8064_mm_fabric,
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index a1b9c1c..7b4ca29 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -6107,6 +6107,9 @@
 	if (cpu_is_msm8960() || cpu_is_apq8064())
 		rmwreg(0x2, DSI2_BYTE_NS_REG, 0x7);
 
+	/* Source the dsi1_esc_clk from the DSI1 PHY PLLs */
+	rmwreg(0x1, DSI1_ESC_NS_REG, 0x7);
+
 	/*
 	 * Source the sata_phy_ref_clk from PXO and set predivider of
 	 * sata_pmalive_clk to 1.
diff --git a/arch/arm/mach-msm/clock-local2.c b/arch/arm/mach-msm/clock-local2.c
index e8e88d7..355a6d3 100644
--- a/arch/arm/mach-msm/clock-local2.c
+++ b/arch/arm/mach-msm/clock-local2.c
@@ -503,7 +503,7 @@
  */
 static int local_vote_clk_reset(struct clk *c, enum clk_reset_action action)
 {
-	struct branch_clk *vclk = to_branch_clk(c);
+	struct local_vote_clk *vclk = to_local_vote_clk(c);
 	return __branch_clk_reset(BCR_REG(vclk), action);
 }
 
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index ef9b62a..1382632 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -850,6 +850,22 @@
 	},
 };
 
+#define SHARED_IMEM_TZ_BASE 0x2a03f720
+static struct resource tzlog_resources[] = {
+	{
+		.start = SHARED_IMEM_TZ_BASE,
+		.end = SHARED_IMEM_TZ_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+struct platform_device apq_device_tz_log = {
+	.name		= "tz_log",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(tzlog_resources),
+	.resource	= tzlog_resources,
+};
+
 /* MSM Video core device */
 #ifdef CONFIG_MSM_BUS_SCALING
 static struct msm_bus_vectors vidc_init_vectors[] = {
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index f8ab18a..f180aa5 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -401,3 +401,5 @@
 extern struct platform_device copper_device_tz_log;
 
 extern struct platform_device mdm_sglte_device;
+
+extern struct platform_device apq_device_tz_log;
diff --git a/drivers/bluetooth/hci_smd.c b/drivers/bluetooth/hci_smd.c
index 8f51e2d..18cef72 100644
--- a/drivers/bluetooth/hci_smd.c
+++ b/drivers/bluetooth/hci_smd.c
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/errno.h>
+#include <linux/semaphore.h>
 #include <linux/string.h>
 #include <linux/skbuff.h>
 #include <linux/wakelock.h>
@@ -43,7 +44,9 @@
 
 
 static int hcismd_set;
-static DEFINE_MUTEX(hci_smd_enable);
+static DEFINE_SEMAPHORE(hci_smd_enable);
+
+static int restart_in_progress;
 
 static int hcismd_set_enable(const char *val, struct kernel_param *kp);
 module_param_call(hcismd_set, hcismd_set_enable, NULL, &hcismd_set, 0644);
@@ -496,18 +499,24 @@
 
 static void hci_dev_restart(struct work_struct *worker)
 {
-	mutex_lock(&hci_smd_enable);
+	down(&hci_smd_enable);
+	restart_in_progress = 1;
 	hci_smd_deregister_dev(&hs);
 	hci_smd_register_smd(&hs);
-	mutex_unlock(&hci_smd_enable);
+	up(&hci_smd_enable);
 	kfree(worker);
 }
 
 static void hci_dev_smd_open(struct work_struct *worker)
 {
-	mutex_lock(&hci_smd_enable);
+	down(&hci_smd_enable);
+	if (restart_in_progress == 1) {
+		/* Allow wcnss to initialize */
+		restart_in_progress = 0;
+		msleep(10000);
+	}
 	hci_smd_hci_register_dev(&hs);
-	mutex_unlock(&hci_smd_enable);
+	up(&hci_smd_enable);
 	kfree(worker);
 }
 
@@ -515,7 +524,9 @@
 {
 	int ret = 0;
 
-	mutex_lock(&hci_smd_enable);
+	pr_err("hcismd_set_enable %d", hcismd_set);
+
+	down(&hci_smd_enable);
 
 	ret = param_set_int(val, kp);
 
@@ -525,7 +536,8 @@
 	switch (hcismd_set) {
 
 	case 1:
-		hci_smd_register_smd(&hs);
+		if (hs.hdev == NULL)
+			hci_smd_register_smd(&hs);
 	break;
 	case 0:
 		hci_smd_deregister_dev(&hs);
@@ -535,7 +547,7 @@
 	}
 
 done:
-	mutex_unlock(&hci_smd_enable);
+	up(&hci_smd_enable);
 	return ret;
 }
 static int  __init hci_smd_init(void)
@@ -544,6 +556,8 @@
 			 "msm_smd_Rx");
 	wake_lock_init(&hs.wake_lock_tx, WAKE_LOCK_SUSPEND,
 			 "msm_smd_Tx");
+	restart_in_progress = 0;
+	hs.hdev = NULL;
 	return 0;
 }
 module_init(hci_smd_init);
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index fff494c..2a191d5 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -352,7 +352,7 @@
 	}
 	kzfree(handle);
 	file->private_data = NULL;
-	if (podev->platform_support.bus_scale_table != NULL)
+	if (podev != NULL && podev->platform_support.bus_scale_table != NULL)
 		qcedev_ce_high_bw_req(podev, false);
 	return 0;
 }
diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c
index 21c3aff..63dfc2d 100644
--- a/drivers/crypto/msm/qcrypto.c
+++ b/drivers/crypto/msm/qcrypto.c
@@ -888,7 +888,7 @@
 						ctx->authsize, 1);
 
 			} else {
-				unsigned char tmp[SHA256_DIGESTSIZE];
+				unsigned char tmp[SHA256_DIGESTSIZE] = {0};
 
 				/* compare icv from src */
 				scatterwalk_map_and_copy(tmp,
diff --git a/drivers/media/video/msm/Makefile b/drivers/media/video/msm/Makefile
index b60f99f..e4d4081 100644
--- a/drivers/media/video/msm/Makefile
+++ b/drivers/media/video/msm/Makefile
@@ -11,8 +11,9 @@
   EXTRA_CFLAGS += -Idrivers/media/video/msm/eeprom
   EXTRA_CFLAGS += -Idrivers/media/video/msm/sensors
   EXTRA_CFLAGS += -Idrivers/media/video/msm/actuators
+  EXTRA_CFLAGS += -Idrivers/media/video/msm/server
   obj-$(CONFIG_MSM_CAMERA) += msm_isp.o msm.o msm_mem.o msm_mctl.o msm_mctl_buf.o msm_mctl_pp.o
-  obj-$(CONFIG_MSM_CAMERA) += io/ eeprom/ sensors/ actuators/ csi/
+  obj-$(CONFIG_MSM_CAMERA) += server/ eeprom/ sensors/ actuators/ csi/
   obj-$(CONFIG_MSM_CAMERA) += msm_gesture.o
 else
   obj-$(CONFIG_MSM_CAMERA) += msm_camera.o
diff --git a/drivers/media/video/msm/csi/msm_csid.c b/drivers/media/video/msm/csi/msm_csid.c
index c04ece2..111d878 100644
--- a/drivers/media/video/msm/csi/msm_csid.c
+++ b/drivers/media/video/msm/csi/msm_csid.c
@@ -107,6 +107,8 @@
 	void __iomem *csidbase;
 	csid_dev = v4l2_get_subdevdata(cfg_params->subdev);
 	csidbase = csid_dev->base;
+	if (csidbase == NULL)
+		return -ENOMEM;
 	csid_params = cfg_params->parms;
 
 	val = csid_params->lane_cnt - 1;
diff --git a/drivers/media/video/msm/csi/msm_csiphy.c b/drivers/media/video/msm/csi/msm_csiphy.c
index 7c59ae8..df01c6b 100644
--- a/drivers/media/video/msm/csi/msm_csiphy.c
+++ b/drivers/media/video/msm/csi/msm_csiphy.c
@@ -68,6 +68,9 @@
 	void __iomem *csiphybase;
 	csiphy_dev = v4l2_get_subdevdata(cfg_params->subdev);
 	csiphybase = csiphy_dev->base;
+	if (csiphybase == NULL)
+		return -ENOMEM;
+
 	csiphy_params = cfg_params->parms;
 	lane_mask = csiphy_params->lane_mask;
 	lane_cnt = csiphy_params->lane_cnt;
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 347321c..0696b96 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -19,13 +19,9 @@
 #include <linux/spinlock.h>
 #include <linux/proc_fs.h>
 #include "msm.h"
-#include "msm_csid.h"
-#include "msm_csic.h"
-#include "msm_csiphy.h"
-#include "msm_ispif.h"
+#include "msm_cam_server.h"
 #include "msm_sensor.h"
 #include "msm_actuator.h"
-#include "msm_vfe32.h"
 #include "msm_camera_eeprom.h"
 
 #define MSM_MAX_CAMERA_SENSORS 5
@@ -37,111 +33,11 @@
 #endif
 
 static unsigned msm_camera_v4l2_nr = -1;
-static struct msm_cam_server_dev g_server_dev;
-static struct class *msm_class;
-static dev_t msm_devno;
 static int vnode_count;
 
 module_param(msm_camera_v4l2_nr, uint, 0644);
 MODULE_PARM_DESC(msm_camera_v4l2_nr, "videoX start number, -1 is autodetect");
 
-static long msm_server_send_v4l2_evt(void *evt);
-static void msm_cam_server_subdev_notify(struct v4l2_subdev *sd,
-	unsigned int notification, void *arg);
-
-static void msm_queue_init(struct msm_device_queue *queue, const char *name)
-{
-	D("%s\n", __func__);
-	spin_lock_init(&queue->lock);
-	queue->len = 0;
-	queue->max = 0;
-	queue->name = name;
-	INIT_LIST_HEAD(&queue->list);
-	init_waitqueue_head(&queue->wait);
-}
-
-static void msm_enqueue(struct msm_device_queue *queue,
-			struct list_head *entry)
-{
-	unsigned long flags;
-	spin_lock_irqsave(&queue->lock, flags);
-	queue->len++;
-	if (queue->len > queue->max) {
-		queue->max = queue->len;
-		pr_info("%s: queue %s new max is %d\n", __func__,
-			queue->name, queue->max);
-	}
-	list_add_tail(entry, &queue->list);
-	wake_up(&queue->wait);
-	D("%s: woke up %s\n", __func__, queue->name);
-	spin_unlock_irqrestore(&queue->lock, flags);
-}
-
-static void msm_drain_eventq(struct msm_device_queue *queue)
-{
-	unsigned long flags;
-	struct msm_queue_cmd *qcmd;
-	spin_lock_irqsave(&queue->lock, flags);
-	while (!list_empty(&queue->list)) {
-		qcmd = list_first_entry(&queue->list,
-			struct msm_queue_cmd, list_eventdata);
-		list_del_init(&qcmd->list_eventdata);
-		kfree(qcmd->command);
-		free_qcmd(qcmd);
-	}
-	spin_unlock_irqrestore(&queue->lock, flags);
-}
-
-static int32_t msm_find_free_queue(void)
-{
-	int i;
-	for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
-		struct msm_cam_server_queue *queue;
-		queue = &g_server_dev.server_queue[i];
-		if (!queue->queue_active)
-			return i;
-	}
-	return -EINVAL;
-}
-
-uint32_t msm_camera_get_mctl_handle(void)
-{
-	uint32_t i;
-	if ((g_server_dev.mctl_handle_cnt << 8) == 0)
-		g_server_dev.mctl_handle_cnt++;
-	for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
-		if (g_server_dev.mctl[i].handle == 0) {
-			g_server_dev.mctl[i].handle =
-				(++g_server_dev.mctl_handle_cnt) << 8 | i;
-			memset(&g_server_dev.mctl[i].mctl,
-				   0, sizeof(g_server_dev.mctl[i].mctl));
-			return g_server_dev.mctl[i].handle;
-		}
-	}
-	return 0;
-}
-
-struct msm_cam_media_controller *msm_camera_get_mctl(uint32_t handle)
-{
-	uint32_t mctl_index;
-	mctl_index = handle & 0xff;
-	if ((mctl_index < MAX_NUM_ACTIVE_CAMERA) &&
-		(g_server_dev.mctl[mctl_index].handle == handle))
-		return &g_server_dev.mctl[mctl_index].mctl;
-	return NULL;
-}
-
-void msm_camera_free_mctl(uint32_t handle)
-{
-	uint32_t mctl_index;
-	mctl_index = handle & 0xff;
-	if ((mctl_index < MAX_NUM_ACTIVE_CAMERA) &&
-		(g_server_dev.mctl[mctl_index].handle == handle))
-		g_server_dev.mctl[mctl_index].handle = 0;
-	else
-		pr_err("%s: invalid free handle\n", __func__);
-}
-
 /* callback function from all subdevices of a msm_cam_v4l2_device */
 static void msm_cam_v4l2_subdev_notify(struct v4l2_subdev *sd,
 				unsigned int notification, void *arg)
@@ -157,663 +53,11 @@
 	if (pcam == NULL)
 		return;
 
-	pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
 	if (pmctl == NULL)
 		return;
 }
 
-static int msm_ctrl_cmd_done(void *arg)
-{
-	void __user *uptr;
-	struct msm_queue_cmd *qcmd;
-	struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
-	struct msm_ctrl_cmd *command =
-		kzalloc(sizeof(struct msm_ctrl_cmd), GFP_KERNEL);
-	if (!command) {
-		pr_err("%s Insufficient memory. return", __func__);
-		return -ENOMEM;
-	}
-
-	D("%s\n", __func__);
-	if (copy_from_user(command, (void __user *)ioctl_ptr->ioctl_ptr,
-					   sizeof(struct msm_ctrl_cmd))) {
-		pr_err("%s: copy_from_user failed, size=%d\n",
-			   __func__, sizeof(struct msm_ctrl_cmd));
-		return -EINVAL;
-	}
-
-	D("%s qid %d evtid %d %d\n", __func__, command->queue_idx,
-		command->evt_id,
-		g_server_dev.server_queue[command->queue_idx].evt_id);
-	g_server_dev.server_queue[command->queue_idx].ctrl = command;
-	if (command->evt_id !=
-		g_server_dev.server_queue[command->queue_idx].evt_id) {
-		pr_err("%s Invalid event id from userspace cmd id %d %d qid %d\n",
-			__func__, command->evt_id,
-			g_server_dev.server_queue[command->queue_idx].evt_id,
-			command->queue_idx);
-		return -EINVAL;
-	}
-
-	mutex_lock(&g_server_dev.server_queue_lock);
-	qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
-	atomic_set(&qcmd->on_heap, 1);
-	uptr = command->value;
-	qcmd->command = command;
-
-	if (command->length > 0) {
-		command->value =
-			g_server_dev.server_queue[command->queue_idx].ctrl_data;
-		if (command->length > max_control_command_size) {
-			pr_err("%s: user data %d is too big (max %d)\n",
-				__func__, command->length,
-				max_control_command_size);
-			free_qcmd(qcmd);
-			return -EINVAL;
-		}
-		if (copy_from_user(command->value, uptr, command->length)) {
-			free_qcmd(qcmd);
-			return -EINVAL;
-		}
-	}
-	msm_enqueue(&g_server_dev.server_queue
-		[command->queue_idx].ctrl_q, &qcmd->list_control);
-	mutex_unlock(&g_server_dev.server_queue_lock);
-	return 0;
-}
-
-/* send control command to config and wait for results*/
-static int msm_server_control(struct msm_cam_server_dev *server_dev,
-				struct msm_ctrl_cmd *out)
-{
-	int rc = 0;
-	void *value;
-	struct msm_queue_cmd *rcmd;
-	struct msm_queue_cmd *event_qcmd;
-	struct msm_ctrl_cmd *ctrlcmd;
-	struct msm_device_queue *queue =
-		&server_dev->server_queue[out->queue_idx].ctrl_q;
-
-	struct v4l2_event v4l2_evt;
-	struct msm_isp_event_ctrl *isp_event;
-	isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl), GFP_KERNEL);
-	if (!isp_event) {
-		pr_err("%s Insufficient memory. return", __func__);
-		return -ENOMEM;
-	}
-	event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
-	if (!event_qcmd) {
-		pr_err("%s Insufficient memory. return", __func__);
-		return -ENOMEM;
-	}
-
-	D("%s\n", __func__);
-	mutex_lock(&server_dev->server_queue_lock);
-	if (++server_dev->server_evt_id == 0)
-		server_dev->server_evt_id++;
-	D("%s qid %d evtid %d\n", __func__, out->queue_idx,
-		server_dev->server_evt_id);
-
-	server_dev->server_queue[out->queue_idx].evt_id =
-		server_dev->server_evt_id;
-	v4l2_evt.type = V4L2_EVENT_PRIVATE_START + MSM_CAM_RESP_V4L2;
-	v4l2_evt.u.data[0] = out->queue_idx;
-	/* setup event object to transfer the command; */
-	isp_event->resptype = MSM_CAM_RESP_V4L2;
-	isp_event->isp_data.ctrl = *out;
-	isp_event->isp_data.ctrl.evt_id = server_dev->server_evt_id;
-
-	atomic_set(&event_qcmd->on_heap, 1);
-	event_qcmd->command = isp_event;
-
-	msm_enqueue(&server_dev->server_queue[out->queue_idx].eventData_q,
-				&event_qcmd->list_eventdata);
-
-	/* now send command to config thread in userspace,
-	 * and wait for results */
-	v4l2_event_queue(server_dev->server_command_queue.pvdev,
-					  &v4l2_evt);
-	D("%s v4l2_event_queue: type = 0x%x\n", __func__, v4l2_evt.type);
-	mutex_unlock(&server_dev->server_queue_lock);
-
-	/* wait for config return status */
-	D("Waiting for config status\n");
-	rc = wait_event_interruptible_timeout(queue->wait,
-		!list_empty_careful(&queue->list),
-		msecs_to_jiffies(out->timeout_ms));
-	D("Waiting is over for config status\n");
-	if (list_empty_careful(&queue->list)) {
-		if (!rc)
-			rc = -ETIMEDOUT;
-		if (rc < 0) {
-			kfree(isp_event);
-			pr_err("%s: wait_event error %d\n", __func__, rc);
-			return rc;
-		}
-	}
-
-	rcmd = msm_dequeue(queue, list_control);
-	BUG_ON(!rcmd);
-	D("%s Finished servicing ioctl\n", __func__);
-
-	ctrlcmd = (struct msm_ctrl_cmd *)(rcmd->command);
-	value = out->value;
-	if (ctrlcmd->length > 0 && value != NULL &&
-	    ctrlcmd->length <= out->length)
-		memcpy(value, ctrlcmd->value, ctrlcmd->length);
-
-	memcpy(out, ctrlcmd, sizeof(struct msm_ctrl_cmd));
-	out->value = value;
-
-	kfree(ctrlcmd);
-	server_dev->server_queue[out->queue_idx].ctrl = NULL;
-
-	free_qcmd(rcmd);
-	kfree(isp_event);
-	D("%s: rc %d\n", __func__, rc);
-	/* rc is the time elapsed. */
-	if (rc >= 0) {
-		/* TODO: Refactor msm_ctrl_cmd::status field */
-		if (out->status == 0)
-			rc = -1;
-		else if (out->status == 1 || out->status == 4)
-			rc = 0;
-		else
-			rc = -EINVAL;
-	}
-	return rc;
-}
-
-/*send open command to server*/
-static int msm_send_open_server(struct msm_cam_v4l2_device *pcam)
-{
-	int rc = 0;
-	struct msm_ctrl_cmd ctrlcmd;
-	D("%s qid %d\n", __func__, pcam->server_queue_idx);
-	ctrlcmd.type	   = MSM_V4L2_OPEN;
-	ctrlcmd.timeout_ms = 10000;
-	ctrlcmd.length	 = strnlen(g_server_dev.config_info.config_dev_name[0],
-				MAX_DEV_NAME_LEN)+1;
-	ctrlcmd.value    = (char *)g_server_dev.config_info.config_dev_name[0];
-	ctrlcmd.vnode_id = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
-	/* send command to config thread in usersspace, and get return value */
-	rc = msm_server_control(&g_server_dev, &ctrlcmd);
-
-	return rc;
-}
-
-static int msm_send_close_server(struct msm_cam_v4l2_device *pcam)
-{
-	int rc = 0;
-	struct msm_ctrl_cmd ctrlcmd;
-	D("%s qid %d\n", __func__, pcam->server_queue_idx);
-	ctrlcmd.type	   = MSM_V4L2_CLOSE;
-	ctrlcmd.timeout_ms = 10000;
-	ctrlcmd.length	 = strnlen(g_server_dev.config_info.config_dev_name[0],
-				MAX_DEV_NAME_LEN)+1;
-	ctrlcmd.value    = (char *)g_server_dev.config_info.config_dev_name[0];
-	ctrlcmd.vnode_id = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
-	/* send command to config thread in usersspace, and get return value */
-	rc = msm_server_control(&g_server_dev, &ctrlcmd);
-
-	return rc;
-}
-
-static int msm_server_set_fmt(struct msm_cam_v4l2_device *pcam, int idx,
-				 struct v4l2_format *pfmt)
-{
-	int rc = 0;
-	int i = 0;
-	struct v4l2_pix_format *pix = &pfmt->fmt.pix;
-	struct msm_ctrl_cmd ctrlcmd;
-	struct img_plane_info plane_info;
-
-	plane_info.width = pix->width;
-	plane_info.height = pix->height;
-	plane_info.pixelformat = pix->pixelformat;
-	plane_info.buffer_type = pfmt->type;
-	plane_info.ext_mode = pcam->dev_inst[idx]->image_mode;
-	plane_info.num_planes = 1;
-	D("%s: %d, %d, 0x%x\n", __func__,
-		pfmt->fmt.pix.width, pfmt->fmt.pix.height,
-		pfmt->fmt.pix.pixelformat);
-
-	if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		D("%s, Attention! Wrong buf-type %d\n", __func__, pfmt->type);
-
-	for (i = 0; i < pcam->num_fmts; i++)
-		if (pcam->usr_fmts[i].fourcc == pix->pixelformat)
-			break;
-	if (i == pcam->num_fmts) {
-		pr_err("%s: User requested pixelformat %x not supported\n",
-						__func__, pix->pixelformat);
-		return -EINVAL;
-	}
-
-	ctrlcmd.type       = MSM_V4L2_VID_CAP_TYPE;
-	ctrlcmd.length     = sizeof(struct img_plane_info);
-	ctrlcmd.value      = (void *)&plane_info;
-	ctrlcmd.timeout_ms = 10000;
-	ctrlcmd.vnode_id   = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
-	/* send command to config thread in usersspace, and get return value */
-	rc = msm_server_control(&g_server_dev, &ctrlcmd);
-
-	if (rc >= 0) {
-		pcam->dev_inst[idx]->vid_fmt = *pfmt;
-		pcam->dev_inst[idx]->sensor_pxlcode
-					= pcam->usr_fmts[i].pxlcode;
-		D("%s:inst=0x%x,idx=%d,width=%d,heigth=%d\n",
-			 __func__, (u32)pcam->dev_inst[idx], idx,
-			 pcam->dev_inst[idx]->vid_fmt.fmt.pix.width,
-			 pcam->dev_inst[idx]->vid_fmt.fmt.pix.height);
-		pcam->dev_inst[idx]->plane_info = plane_info;
-	}
-
-	return rc;
-}
-
-static int msm_server_set_fmt_mplane(struct msm_cam_v4l2_device *pcam, int idx,
-				 struct v4l2_format *pfmt)
-{
-	int rc = 0;
-	int i = 0;
-	struct v4l2_pix_format_mplane *pix_mp = &pfmt->fmt.pix_mp;
-	struct msm_ctrl_cmd ctrlcmd;
-	struct img_plane_info plane_info;
-
-	plane_info.width = pix_mp->width;
-	plane_info.height = pix_mp->height;
-	plane_info.pixelformat = pix_mp->pixelformat;
-	plane_info.buffer_type = pfmt->type;
-	plane_info.ext_mode = pcam->dev_inst[idx]->image_mode;
-	plane_info.num_planes = pix_mp->num_planes;
-	if (plane_info.num_planes <= 0 ||
-		plane_info.num_planes > VIDEO_MAX_PLANES) {
-		pr_err("%s Invalid number of planes set %d", __func__,
-				plane_info.num_planes);
-		return -EINVAL;
-	}
-	D("%s: %d, %d, 0x%x\n", __func__,
-		pfmt->fmt.pix_mp.width, pfmt->fmt.pix_mp.height,
-		pfmt->fmt.pix_mp.pixelformat);
-
-	if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-		pr_err("%s, Attention! Wrong buf-type %d\n",
-			__func__, pfmt->type);
-		return -EINVAL;
-	}
-
-	for (i = 0; i < pcam->num_fmts; i++)
-		if (pcam->usr_fmts[i].fourcc == pix_mp->pixelformat)
-			break;
-	if (i == pcam->num_fmts) {
-		pr_err("%s: User requested pixelformat %x not supported\n",
-						__func__, pix_mp->pixelformat);
-		return -EINVAL;
-	}
-
-	ctrlcmd.type       = MSM_V4L2_VID_CAP_TYPE;
-	ctrlcmd.length     = sizeof(struct img_plane_info);
-	ctrlcmd.value      = (void *)&plane_info;
-	ctrlcmd.timeout_ms = 10000;
-	ctrlcmd.vnode_id   = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-
-	/* send command to config thread in usersspace, and get return value */
-	rc = msm_server_control(&g_server_dev, &ctrlcmd);
-	if (rc >= 0) {
-		pcam->dev_inst[idx]->vid_fmt = *pfmt;
-		pcam->dev_inst[idx]->sensor_pxlcode
-					= pcam->usr_fmts[i].pxlcode;
-		D("%s:inst=0x%x,idx=%d,width=%d,heigth=%d\n",
-			 __func__, (u32)pcam->dev_inst[idx], idx,
-			 pcam->dev_inst[idx]->vid_fmt.fmt.pix_mp.width,
-			 pcam->dev_inst[idx]->vid_fmt.fmt.pix_mp.height);
-		pcam->dev_inst[idx]->plane_info = plane_info;
-	}
-
-	return rc;
-}
-
-static int msm_server_streamon(struct msm_cam_v4l2_device *pcam, int idx)
-{
-	int rc = 0;
-	struct msm_ctrl_cmd ctrlcmd;
-	D("%s\n", __func__);
-	ctrlcmd.type	   = MSM_V4L2_STREAM_ON;
-	ctrlcmd.timeout_ms = 10000;
-	ctrlcmd.length	 = 0;
-	ctrlcmd.value    = NULL;
-	ctrlcmd.stream_type = pcam->dev_inst[idx]->image_mode;
-	ctrlcmd.vnode_id = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
-
-	/* send command to config thread in usersspace, and get return value */
-	rc = msm_server_control(&g_server_dev, &ctrlcmd);
-
-	return rc;
-}
-
-static int msm_server_streamoff(struct msm_cam_v4l2_device *pcam, int idx)
-{
-	int rc = 0;
-	struct msm_ctrl_cmd ctrlcmd;
-
-	D("%s, pcam = 0x%x\n", __func__, (u32)pcam);
-	ctrlcmd.type        = MSM_V4L2_STREAM_OFF;
-	ctrlcmd.timeout_ms  = 10000;
-	ctrlcmd.length      = 0;
-	ctrlcmd.value       = NULL;
-	ctrlcmd.stream_type = pcam->dev_inst[idx]->image_mode;
-	ctrlcmd.vnode_id = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
-	/* send command to config thread in usersspace, and get return value */
-	rc = msm_server_control(&g_server_dev, &ctrlcmd);
-
-	return rc;
-}
-
-static int msm_server_proc_ctrl_cmd(struct msm_cam_v4l2_device *pcam,
-				 struct v4l2_control *ctrl, int is_set_cmd)
-{
-	int rc = 0;
-	struct msm_ctrl_cmd ctrlcmd, *tmp_cmd;
-	uint8_t *ctrl_data = NULL;
-	void __user *uptr_cmd;
-	void __user *uptr_value;
-	uint32_t cmd_len = sizeof(struct msm_ctrl_cmd);
-	uint32_t value_len;
-
-	tmp_cmd = (struct msm_ctrl_cmd *)ctrl->value;
-	uptr_cmd = (void __user *)ctrl->value;
-	uptr_value = (void __user *)tmp_cmd->value;
-	value_len = tmp_cmd->length;
-
-	D("%s: cmd type = %d, up1=0x%x, ulen1=%d, up2=0x%x, ulen2=%d\n",
-		__func__, tmp_cmd->type, (uint32_t)uptr_cmd, cmd_len,
-		(uint32_t)uptr_value, tmp_cmd->length);
-
-	ctrl_data = kzalloc(value_len+cmd_len, GFP_KERNEL);
-	if (ctrl_data == 0) {
-		pr_err("%s could not allocate memory\n", __func__);
-		rc = -ENOMEM;
-		goto end;
-	}
-	tmp_cmd = (struct msm_ctrl_cmd *)ctrl_data;
-	if (copy_from_user((void *)ctrl_data, uptr_cmd,
-					cmd_len)) {
-		pr_err("%s: copy_from_user failed.\n", __func__);
-		rc = -EINVAL;
-		goto end;
-	}
-	tmp_cmd->value = (void *)(ctrl_data+cmd_len);
-	if (uptr_value && tmp_cmd->length > 0) {
-		if (copy_from_user((void *)tmp_cmd->value, uptr_value,
-						value_len)) {
-			pr_err("%s: copy_from_user failed, size=%d\n",
-				__func__, value_len);
-			rc = -EINVAL;
-			goto end;
-		}
-	} else
-	tmp_cmd->value = NULL;
-
-	ctrlcmd.type = MSM_V4L2_SET_CTRL_CMD;
-	ctrlcmd.length = cmd_len + value_len;
-	ctrlcmd.value = (void *)ctrl_data;
-	if (tmp_cmd->timeout_ms > 0)
-		ctrlcmd.timeout_ms = tmp_cmd->timeout_ms;
-	else
-		ctrlcmd.timeout_ms = 1000;
-	ctrlcmd.vnode_id = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-	/* send command to config thread in usersspace, and get return value */
-	rc = msm_server_control(&g_server_dev, &ctrlcmd);
-	D("%s: msm_server_control rc=%d\n", __func__, rc);
-	if (rc == 0) {
-		if (uptr_value && tmp_cmd->length > 0 &&
-			copy_to_user((void __user *)uptr_value,
-				(void *)(ctrl_data+cmd_len), tmp_cmd->length)) {
-			pr_err("%s: copy_to_user failed, size=%d\n",
-				__func__, tmp_cmd->length);
-			rc = -EINVAL;
-			goto end;
-		}
-		tmp_cmd->value = uptr_value;
-		if (copy_to_user((void __user *)uptr_cmd,
-			(void *)tmp_cmd, cmd_len)) {
-			pr_err("%s: copy_to_user failed in cpy, size=%d\n",
-				__func__, cmd_len);
-			rc = -EINVAL;
-			goto end;
-		}
-	}
-end:
-	D("%s: END, type = %d, vaddr = 0x%x, vlen = %d, status = %d, rc = %d\n",
-		__func__, tmp_cmd->type, (uint32_t)tmp_cmd->value,
-		tmp_cmd->length, tmp_cmd->status, rc);
-	kfree(ctrl_data);
-	return rc;
-}
-
-static int msm_server_s_ctrl(struct msm_cam_v4l2_device *pcam,
-				 struct v4l2_control *ctrl)
-{
-	int rc = 0;
-	struct msm_ctrl_cmd ctrlcmd;
-	uint8_t ctrl_data[max_control_command_size];
-
-	WARN_ON(ctrl == NULL);
-	if (ctrl == NULL) {
-		pr_err("%s Invalid control\n", __func__);
-		return -EINVAL;
-	}
-	if (ctrl->id == MSM_V4L2_PID_CTRL_CMD)
-		return msm_server_proc_ctrl_cmd(pcam, ctrl, 1);
-
-	memset(ctrl_data, 0, sizeof(ctrl_data));
-
-	ctrlcmd.type = MSM_V4L2_SET_CTRL;
-	ctrlcmd.length = sizeof(struct v4l2_control);
-	ctrlcmd.value = (void *)ctrl_data;
-	memcpy(ctrlcmd.value, ctrl, ctrlcmd.length);
-	ctrlcmd.timeout_ms = 1000;
-	ctrlcmd.vnode_id = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
-	/* send command to config thread in usersspace, and get return value */
-	rc = msm_server_control(&g_server_dev, &ctrlcmd);
-
-	return rc;
-}
-
-static int msm_server_g_ctrl(struct msm_cam_v4l2_device *pcam,
-				 struct v4l2_control *ctrl)
-{
-	int rc = 0;
-	struct msm_ctrl_cmd ctrlcmd;
-	uint8_t ctrl_data[max_control_command_size];
-
-	WARN_ON(ctrl == NULL);
-	if (ctrl == NULL) {
-		pr_err("%s Invalid control\n", __func__);
-		return -EINVAL;
-	}
-	if (ctrl->id == MSM_V4L2_PID_CTRL_CMD)
-		return msm_server_proc_ctrl_cmd(pcam, ctrl, 0);
-
-	memset(ctrl_data, 0, sizeof(ctrl_data));
-
-	ctrlcmd.type = MSM_V4L2_GET_CTRL;
-	ctrlcmd.length = sizeof(struct v4l2_control);
-	ctrlcmd.value = (void *)ctrl_data;
-	memcpy(ctrlcmd.value, ctrl, ctrlcmd.length);
-	ctrlcmd.timeout_ms = 1000;
-	ctrlcmd.vnode_id = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
-	/* send command to config thread in usersspace, and get return value */
-	rc = msm_server_control(&g_server_dev, &ctrlcmd);
-
-	ctrl->value = ((struct v4l2_control *)ctrlcmd.value)->value;
-
-	return rc;
-}
-
-static int msm_server_q_ctrl(struct msm_cam_v4l2_device *pcam,
-			struct v4l2_queryctrl *queryctrl)
-{
-	int rc = 0;
-	struct msm_ctrl_cmd ctrlcmd;
-	uint8_t ctrl_data[max_control_command_size];
-
-	WARN_ON(queryctrl == NULL);
-	memset(ctrl_data, 0, sizeof(ctrl_data));
-
-	ctrlcmd.type = MSM_V4L2_QUERY_CTRL;
-	ctrlcmd.length = sizeof(struct v4l2_queryctrl);
-	ctrlcmd.value = (void *)ctrl_data;
-	memcpy(ctrlcmd.value, queryctrl, ctrlcmd.length);
-	ctrlcmd.timeout_ms = 1000;
-	ctrlcmd.vnode_id = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
-	/* send command to config thread in userspace, and get return value */
-	rc = msm_server_control(&g_server_dev, &ctrlcmd);
-	D("%s: rc = %d\n", __func__, rc);
-
-	if (rc >= 0)
-		memcpy(queryctrl, ctrlcmd.value, sizeof(struct v4l2_queryctrl));
-
-	return rc;
-}
-
-static int msm_server_get_fmt(struct msm_cam_v4l2_device *pcam,
-		 int idx, struct v4l2_format *pfmt)
-{
-	struct v4l2_pix_format *pix = &pfmt->fmt.pix;
-
-	pix->width        = pcam->dev_inst[idx]->vid_fmt.fmt.pix.width;
-	pix->height       = pcam->dev_inst[idx]->vid_fmt.fmt.pix.height;
-	pix->field        = pcam->dev_inst[idx]->vid_fmt.fmt.pix.field;
-	pix->pixelformat  = pcam->dev_inst[idx]->vid_fmt.fmt.pix.pixelformat;
-	pix->bytesperline = pcam->dev_inst[idx]->vid_fmt.fmt.pix.bytesperline;
-	pix->colorspace   = pcam->dev_inst[idx]->vid_fmt.fmt.pix.colorspace;
-	if (pix->bytesperline < 0)
-		return pix->bytesperline;
-
-	pix->sizeimage    = pix->height * pix->bytesperline;
-
-	return 0;
-}
-
-static int msm_server_get_fmt_mplane(struct msm_cam_v4l2_device *pcam,
-		 int idx, struct v4l2_format *pfmt)
-{
-	*pfmt = pcam->dev_inst[idx]->vid_fmt;
-	return 0;
-}
-
-static int msm_server_try_fmt(struct msm_cam_v4l2_device *pcam,
-				 struct v4l2_format *pfmt)
-{
-	int rc = 0;
-	int i = 0;
-	struct v4l2_pix_format *pix = &pfmt->fmt.pix;
-
-	D("%s: 0x%x\n", __func__, pix->pixelformat);
-	if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-		pr_err("%s: pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE!\n",
-							__func__);
-		return -EINVAL;
-	}
-
-	/* check if the format is supported by this host-sensor combo */
-	for (i = 0; i < pcam->num_fmts; i++) {
-		D("%s: usr_fmts.fourcc: 0x%x\n", __func__,
-			pcam->usr_fmts[i].fourcc);
-		if (pcam->usr_fmts[i].fourcc == pix->pixelformat)
-			break;
-	}
-
-	if (i == pcam->num_fmts) {
-		pr_err("%s: Format %x not found\n", __func__, pix->pixelformat);
-		return -EINVAL;
-	}
-	return rc;
-}
-
-static int msm_server_try_fmt_mplane(struct msm_cam_v4l2_device *pcam,
-				 struct v4l2_format *pfmt)
-{
-	int rc = 0;
-	int i = 0;
-	struct v4l2_pix_format_mplane *pix_mp = &pfmt->fmt.pix_mp;
-
-	D("%s: 0x%x\n", __func__, pix_mp->pixelformat);
-	if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-		pr_err("%s: Incorrect format type %d ",
-			__func__, pfmt->type);
-		return -EINVAL;
-	}
-
-	/* check if the format is supported by this host-sensor combo */
-	for (i = 0; i < pcam->num_fmts; i++) {
-		D("%s: usr_fmts.fourcc: 0x%x\n", __func__,
-			pcam->usr_fmts[i].fourcc);
-		if (pcam->usr_fmts[i].fourcc == pix_mp->pixelformat)
-			break;
-	}
-
-	if (i == pcam->num_fmts) {
-		pr_err("%s: Format %x not found\n",
-			__func__, pix_mp->pixelformat);
-		return -EINVAL;
-	}
-	return rc;
-}
-
-static int msm_camera_get_crop(struct msm_cam_v4l2_device *pcam,
-				int idx, struct v4l2_crop *crop)
-{
-	int rc = 0;
-	struct msm_ctrl_cmd ctrlcmd;
-
-	BUG_ON(crop == NULL);
-
-	ctrlcmd.type = MSM_V4L2_GET_CROP;
-	ctrlcmd.length = sizeof(struct v4l2_crop);
-	ctrlcmd.value = (void *)crop;
-	ctrlcmd.timeout_ms = 1000;
-	ctrlcmd.vnode_id = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-	ctrlcmd.stream_type = pcam->dev_inst[idx]->image_mode;
-	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
-	/* send command to config thread in userspace, and get return value */
-	rc = msm_server_control(&g_server_dev, &ctrlcmd);
-	D("%s: rc = %d\n", __func__, rc);
-
-	return rc;
-}
-
 /*
  *
  * implementation of v4l2_ioctl_ops
@@ -1115,7 +359,7 @@
 		not in use when we free the buffers */
 	mutex_lock(&pcam->vid_lock);
 	pcam_inst->streamon = 0;
-	if (g_server_dev.use_count > 0)
+	if (msm_server_get_usecount() > 0)
 		rc = msm_server_streamoff(pcam, pcam_inst->my_index);
 	mutex_unlock(&pcam->vid_lock);
 	if (rc < 0)
@@ -1259,7 +503,7 @@
 		(void *)pfmt->fmt.pix.priv);
 	WARN_ON(pctx != f->private_data);
 
-	pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
 	if (pmctl == NULL)
 		return -EINVAL;
 
@@ -1294,7 +538,7 @@
 	D("%s Inst %p\n", __func__, pcam_inst);
 	WARN_ON(pctx != f->private_data);
 
-	pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
 	if (pmctl == NULL)
 		return -EINVAL;
 
@@ -1347,7 +591,7 @@
 	WARN_ON(pctx != f->private_data);
 
 	mutex_lock(&pcam->vid_lock);
-	rc = msm_camera_get_crop(pcam, pcam_inst->my_index, crop);
+	rc = msm_server_get_crop(pcam, pcam_inst->my_index, crop);
 	mutex_unlock(&pcam->vid_lock);
 	return rc;
 }
@@ -1440,55 +684,6 @@
 	return rc;
 }
 
-static int msm_server_v4l2_subscribe_event(struct v4l2_fh *fh,
-			struct v4l2_event_subscription *sub)
-{
-	int rc = 0;
-
-	D("%s: fh = 0x%x, type = 0x%x", __func__, (u32)fh, sub->type);
-	if (sub->type == V4L2_EVENT_ALL) {
-		/*sub->type = MSM_ISP_EVENT_START;*/
-		sub->type = V4L2_EVENT_PRIVATE_START + MSM_CAM_RESP_CTRL;
-		D("sub->type start = 0x%x\n", sub->type);
-		do {
-			rc = v4l2_event_subscribe(fh, sub);
-			if (rc < 0) {
-				D("%s: failed for evtType = 0x%x, rc = %d\n",
-						__func__, sub->type, rc);
-			/* unsubscribe all events here and return */
-			sub->type = V4L2_EVENT_ALL;
-			v4l2_event_unsubscribe(fh, sub);
-			return rc;
-			} else
-				D("%s: subscribed evtType = 0x%x, rc = %d\n",
-						__func__, sub->type, rc);
-			sub->type++;
-			D("sub->type while = 0x%x\n", sub->type);
-		} while (sub->type !=
-			V4L2_EVENT_PRIVATE_START + MSM_SVR_RESP_MAX);
-	} else {
-		D("sub->type not V4L2_EVENT_ALL = 0x%x\n", sub->type);
-		rc = v4l2_event_subscribe(fh, sub);
-		if (rc < 0)
-			D("%s: failed for evtType = 0x%x, rc = %d\n",
-						__func__, sub->type, rc);
-	}
-
-	D("%s: rc = %d\n", __func__, rc);
-	return rc;
-}
-
-static int msm_server_v4l2_unsubscribe_event(struct v4l2_fh *fh,
-			struct v4l2_event_subscription *sub)
-{
-	int rc = 0;
-
-	D("%s: fh = 0x%x\n", __func__, (u32)fh);
-	rc = v4l2_event_unsubscribe(fh, sub);
-	D("%s: rc = %d\n", __func__, rc);
-	return rc;
-}
-
 /* v4l2_ioctl_ops */
 static const struct v4l2_ioctl_ops g_msm_ioctl_ops = {
 	.vidioc_querycap = msm_camera_v4l2_querycap,
@@ -1530,213 +725,10 @@
 	.vidioc_unsubscribe_event = msm_camera_v4l2_unsubscribe_event,
 };
 
-/* open an active camera session to manage the streaming logic */
-static int msm_cam_server_open_session(struct msm_cam_server_dev *ps,
-	struct msm_cam_v4l2_device *pcam)
-{
-	int rc = 0;
-	struct msm_cam_media_controller *pmctl;
-
-	D("%s\n", __func__);
-
-	if (!ps || !pcam) {
-		pr_err("%s NULL pointer passed in!\n", __func__);
-		return rc;
-	}
-
-	/* The number of camera instance should be controlled by the
-		resource manager. Currently supporting one active instance
-		until multiple instances are supported */
-	if (atomic_read(&ps->number_pcam_active) > 0) {
-		pr_err("%s Cannot have more than one active camera %d\n",
-			__func__, atomic_read(&ps->number_pcam_active));
-		return -EINVAL;
-	}
-	/* book keeping this camera session*/
-	ps->pcam_active = pcam;
-	atomic_inc(&ps->number_pcam_active);
-
-	D("config pcam = 0x%p\n", ps->pcam_active);
-
-	/* 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_camera_get_mctl(pcam->mctl_handle);
-	pmctl->axi_sdev = ps->axi_device[0];
-	pmctl->isp_sdev = ps->isp_subdev[0];
-	return rc;
-}
-
-/* close an active camera session to server */
-static int msm_cam_server_close_session(struct msm_cam_server_dev *ps,
-	struct msm_cam_v4l2_device *pcam)
-{
-	int rc = 0;
-	D("%s\n", __func__);
-
-	if (!ps || !pcam) {
-		D("%s NULL pointer passed in!\n", __func__);
-		return rc;
-	}
-
-
-	atomic_dec(&ps->number_pcam_active);
-	ps->pcam_active = NULL;
-
-	msm_mctl_free(pcam);
-	return rc;
-}
-
-int msm_server_open_client(int *p_qidx)
-{
-	int rc = 0;
-	int server_q_idx = 0;
-	struct msm_cam_server_queue *queue = NULL;
-
-	mutex_lock(&g_server_dev.server_lock);
-	server_q_idx = msm_find_free_queue();
-	if (server_q_idx < 0) {
-		mutex_unlock(&g_server_dev.server_lock);
-		return server_q_idx;
-	}
-
-	*p_qidx = server_q_idx;
-	queue = &g_server_dev.server_queue[server_q_idx];
-	queue->ctrl = NULL;
-	queue->ctrl_data = kzalloc(sizeof(uint8_t) *
-		max_control_command_size, GFP_KERNEL);
-	msm_queue_init(&queue->ctrl_q, "control");
-	msm_queue_init(&queue->eventData_q, "eventdata");
-	queue->queue_active = 1;
-	mutex_unlock(&g_server_dev.server_lock);
-	return rc;
-}
-
-int msm_server_send_ctrl(struct msm_ctrl_cmd *out,
-	int ctrl_id)
-{
-	int rc = 0;
-	void *value;
-	struct msm_queue_cmd *rcmd;
-	struct msm_queue_cmd *event_qcmd;
-	struct msm_ctrl_cmd *ctrlcmd;
-	struct msm_cam_server_dev *server_dev = &g_server_dev;
-	struct msm_device_queue *queue =
-		&server_dev->server_queue[out->queue_idx].ctrl_q;
-
-	struct v4l2_event v4l2_evt;
-	struct msm_isp_event_ctrl *isp_event;
-	isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl), GFP_KERNEL);
-	if (!isp_event) {
-		pr_err("%s Insufficient memory. return", __func__);
-		return -ENOMEM;
-	}
-	event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
-	if (!event_qcmd) {
-		pr_err("%s Insufficient memory. return", __func__);
-		kfree(isp_event);
-		return -ENOMEM;
-	}
-
-	D("%s\n", __func__);
-	mutex_lock(&server_dev->server_queue_lock);
-	if (++server_dev->server_evt_id == 0)
-		server_dev->server_evt_id++;
-
-	D("%s qid %d evtid %d\n", __func__, out->queue_idx,
-		server_dev->server_evt_id);
-	server_dev->server_queue[out->queue_idx].evt_id =
-		server_dev->server_evt_id;
-	v4l2_evt.type = V4L2_EVENT_PRIVATE_START + ctrl_id;
-	v4l2_evt.u.data[0] = out->queue_idx;
-	/* setup event object to transfer the command; */
-	isp_event->resptype = MSM_CAM_RESP_V4L2;
-	isp_event->isp_data.ctrl = *out;
-	isp_event->isp_data.ctrl.evt_id = server_dev->server_evt_id;
-
-	atomic_set(&event_qcmd->on_heap, 1);
-	event_qcmd->command = isp_event;
-
-	msm_enqueue(&server_dev->server_queue[out->queue_idx].eventData_q,
-				&event_qcmd->list_eventdata);
-
-	/* now send command to config thread in userspace,
-	 * and wait for results */
-	v4l2_event_queue(server_dev->server_command_queue.pvdev,
-					  &v4l2_evt);
-	D("%s v4l2_event_queue: type = 0x%x\n", __func__, v4l2_evt.type);
-	mutex_unlock(&server_dev->server_queue_lock);
-
-	/* wait for config return status */
-	D("Waiting for config status\n");
-	rc = wait_event_interruptible_timeout(queue->wait,
-		!list_empty_careful(&queue->list),
-		msecs_to_jiffies(out->timeout_ms));
-	D("Waiting is over for config status\n");
-	if (list_empty_careful(&queue->list)) {
-		if (!rc)
-			rc = -ETIMEDOUT;
-		if (rc < 0) {
-			kfree(isp_event);
-			pr_err("%s: wait_event error %d\n", __func__, rc);
-			return rc;
-		}
-	}
-
-	rcmd = msm_dequeue(queue, list_control);
-	BUG_ON(!rcmd);
-	D("%s Finished servicing ioctl\n", __func__);
-
-	ctrlcmd = (struct msm_ctrl_cmd *)(rcmd->command);
-	value = out->value;
-	if (ctrlcmd->length > 0)
-		memcpy(value, ctrlcmd->value, ctrlcmd->length);
-
-	memcpy(out, ctrlcmd, sizeof(struct msm_ctrl_cmd));
-	out->value = value;
-
-	kfree(ctrlcmd);
-	server_dev->server_queue[out->queue_idx].ctrl = NULL;
-
-	free_qcmd(rcmd);
-	kfree(isp_event);
-	D("%s: rc %d\n", __func__, rc);
-	/* rc is the time elapsed. */
-	if (rc >= 0) {
-		/* TODO: Refactor msm_ctrl_cmd::status field */
-		if (out->status == 0)
-			rc = -1;
-		else if (out->status == 1 || out->status == 4)
-			rc = 0;
-		else
-			rc = -EINVAL;
-	}
-	return rc;
-}
-
-int msm_server_close_client(int idx)
-{
-	int rc = 0;
-	struct msm_cam_server_queue *queue = NULL;
-	mutex_lock(&g_server_dev.server_lock);
-	queue = &g_server_dev.server_queue[idx];
-	queue->queue_active = 0;
-	kfree(queue->ctrl);
-	queue->ctrl = NULL;
-	kfree(queue->ctrl_data);
-	queue->ctrl_data = NULL;
-	msm_queue_drain(&queue->ctrl_q, list_control);
-	msm_drain_eventq(&queue->eventData_q);
-	mutex_unlock(&g_server_dev.server_lock);
-	return rc;
-}
 /* v4l2_file_operations */
 static int msm_open(struct file *f)
 {
-	int i;
-	int rc = -EINVAL;
+	int i, rc = -EINVAL;
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 	int ion_client_created = 0;
 #endif
@@ -1746,7 +738,6 @@
 	struct msm_cam_v4l2_device *pcam  = video_drvdata(f);
 	struct msm_cam_v4l2_dev_inst *pcam_inst;
 	struct msm_cam_media_controller *pmctl = NULL;
-	struct msm_cam_server_queue *queue = NULL;
 
 	D("%s\n", __func__);
 
@@ -1754,7 +745,7 @@
 		pr_err("%s NULL pointer passed in!\n", __func__);
 		return rc;
 	}
-	if (!g_server_dev.use_count) {
+	if (!msm_server_get_usecount()) {
 		pr_err("%s: error, daemon not yet started.", __func__);
 		return -EINVAL;
 	}
@@ -1789,28 +780,12 @@
 	pcam->use_count++;
 	D("%s use_count %d\n", __func__, pcam->use_count);
 	if (pcam->use_count == 1) {
-		int ges_evt = MSM_V4L2_GES_CAM_OPEN;
-		pcam->server_queue_idx = server_q_idx;
-		queue = &g_server_dev.server_queue[server_q_idx];
-		queue->ctrl = NULL;
-		queue->ctrl_data = kzalloc(sizeof(uint8_t) *
-			max_control_command_size, GFP_KERNEL);
-		msm_queue_init(&queue->ctrl_q, "control");
-		msm_queue_init(&queue->eventData_q, "eventdata");
-		queue->queue_active = 1;
-
-		pr_err("%s send gesture evt\n", __func__);
-		msm_cam_server_subdev_notify(g_server_dev.gesture_device,
-			NOTIFY_GESTURE_CAM_EVT, &ges_evt);
-
-		rc = msm_cam_server_open_session(&g_server_dev, pcam);
+		rc = msm_server_begin_session(pcam, server_q_idx);
 		if (rc < 0) {
-			pr_err("%s: cam_server_open_session failed %d\n",
-			__func__, rc);
-			goto msm_cam_server_open_session_failed;
+			pr_err("%s error starting server session ", __func__);
+			goto msm_cam_server_begin_session_failed;
 		}
-
-		pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+		pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
 
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 		pmctl->client = msm_ion_client_create(-1, "camera");
@@ -1852,14 +827,14 @@
 
 	if (pcam->use_count == 1) {
 		rc = msm_send_open_server(pcam);
-		if (rc < 0) {
+		if (rc < 0 && rc != -ERESTARTSYS) {
 			pr_err("%s: msm_send_open_server failed %d\n",
 				__func__, rc);
 			goto msm_send_open_server_failed;
 		}
 	}
 	mutex_unlock(&pcam->vid_lock);
-	D("%s: end", __func__);
+	D("%s: end\n", __func__);
 	return rc;
 
 msm_send_open_server_failed:
@@ -1873,25 +848,16 @@
 	if (pcam->use_count == 1) {
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 		if (ion_client_created) {
-			pr_err("%s: destroy ion client", __func__);
+			D("%s: destroy ion client", __func__);
 			kref_put(&pmctl->refcount, msm_release_ion_client);
 		}
 #endif
-		if (msm_cam_server_close_session(&g_server_dev, pcam) < 0)
-			pr_err("%s: msm_cam_server_close_session failed\n",
+		if (msm_server_end_session(pcam) < 0)
+			pr_err("%s: msm_server_end_session failed\n",
 				__func__);
 	}
-msm_cam_server_open_session_failed:
+msm_cam_server_begin_session_failed:
 	if (pcam->use_count == 1) {
-		if (queue != NULL) {
-			queue->queue_active = 0;
-			msm_drain_eventq(&queue->eventData_q);
-			kfree(queue->ctrl_data);
-			queue->ctrl_data = NULL;
-			msm_queue_drain(&queue->ctrl_q, list_control);
-			msm_drain_eventq(&queue->eventData_q);
-			queue = NULL;
-		}
 		pcam->dev_inst[i] = NULL;
 		pcam->use_count = 0;
 	}
@@ -1901,73 +867,6 @@
 	return rc;
 }
 
-int msm_cam_server_close_mctl_session(struct msm_cam_v4l2_device *pcam)
-{
-	int rc = 0;
-	struct msm_cam_media_controller *pmctl = NULL;
-
-	pmctl = msm_camera_get_mctl(pcam->mctl_handle);
-	if (!pmctl) {
-		D("%s: invalid handle\n", __func__);
-		return -ENODEV;
-	}
-
-	if (pmctl->mctl_release) {
-		rc = pmctl->mctl_release(pmctl);
-		if (rc < 0)
-			pr_err("mctl_release fails %d\n", rc);
-	}
-
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	kref_put(&pmctl->refcount, msm_release_ion_client);
-#endif
-
-	rc = msm_cam_server_close_session(&g_server_dev, pcam);
-	if (rc < 0)
-		pr_err("msm_cam_server_close_session fails %d\n", rc);
-
-	return rc;
-}
-
-int msm_cam_server_open_mctl_session(struct msm_cam_v4l2_device *pcam,
-	int *p_active)
-{
-	int rc = 0;
-	struct msm_cam_media_controller *pmctl = NULL;
-	D("%s: %p", __func__, g_server_dev.pcam_active);
-	*p_active = 0;
-	if (g_server_dev.pcam_active) {
-		D("%s: Active camera present return", __func__);
-		return 0;
-	}
-	rc = msm_cam_server_open_session(&g_server_dev, pcam);
-	if (rc < 0) {
-		pr_err("%s: cam_server_open_session failed %d\n",
-		__func__, rc);
-		return rc;
-	}
-
-	pmctl = msm_camera_get_mctl(pcam->mctl_handle);
-	/* Should be set to sensor ops if any but right now its OK!! */
-	if (!pmctl->mctl_open) {
-		D("%s: media contoller is not inited\n",
-			 __func__);
-		rc = -ENODEV;
-		return rc;
-	}
-
-	D("%s: call mctl_open\n", __func__);
-	rc = pmctl->mctl_open(pmctl, MSM_APPS_ID_V4L2);
-
-	if (rc < 0) {
-		pr_err("%s: HW open failed rc = 0x%x\n",  __func__, rc);
-		return rc;
-	}
-	pmctl->pcam_ptr = pcam;
-	*p_active = 1;
-	return rc;
-}
-
 static int msm_addr_remap(struct msm_cam_v4l2_dev_inst *pcam_inst,
 				struct vm_area_struct *vma)
 {
@@ -1977,7 +876,7 @@
 	int rc = 0;
 	struct msm_cam_media_controller *mctl;
 
-	mctl = msm_camera_get_mctl(pcam_inst->pcam->mctl_handle);
+	mctl = msm_cam_server_get_mctl(pcam_inst->pcam->mctl_handle);
 	if (!mctl) {
 		pr_err("%s: invalid mctl pointer", __func__);
 		return -EFAULT;
@@ -2035,8 +934,8 @@
 void msm_release_ion_client(struct kref *ref)
 {
 	struct msm_cam_media_controller *mctl = container_of(ref,
-			struct msm_cam_media_controller, refcount);
-	pr_err("%s Calling ion_client_destroy ", __func__);
+		struct msm_cam_media_controller, refcount);
+	pr_err("%s Calling ion_client_destroy\n", __func__);
 	ion_client_destroy(mctl->client);
 }
 
@@ -2045,7 +944,6 @@
 	int rc = 0;
 	struct msm_cam_v4l2_device *pcam;
 	struct msm_cam_v4l2_dev_inst *pcam_inst;
-	struct msm_cam_server_queue *queue;
 	struct msm_cam_media_controller *pmctl;
 	pcam_inst = container_of(f->private_data,
 		struct msm_cam_v4l2_dev_inst, eventHandle);
@@ -2055,7 +953,7 @@
 		return -EINVAL;
 	}
 
-	pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
 	if (!pmctl) {
 		pr_err("%s NULL mctl pointer\n", __func__);
 		return -EINVAL;
@@ -2091,37 +989,24 @@
 	f->private_data = NULL;
 
 	if (pcam->use_count == 0) {
-		int ges_evt = MSM_V4L2_GES_CAM_CLOSE;
-		if (g_server_dev.use_count > 0) {
+		if (msm_server_get_usecount() > 0) {
 			rc = msm_send_close_server(pcam);
 			if (rc < 0)
 				pr_err("msm_send_close_server failed %d\n", rc);
 		}
+
 		if (pmctl->mctl_release) {
 			rc = pmctl->mctl_release(pmctl);
 			if (rc < 0)
 				pr_err("mctl_release fails %d\n", rc);
 		}
+
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 		kref_put(&pmctl->refcount, msm_release_ion_client);
 #endif
-		queue = &g_server_dev.server_queue[pcam->server_queue_idx];
-		queue->queue_active = 0;
-		kfree(queue->ctrl);
-		queue->ctrl = NULL;
-		kfree(queue->ctrl_data);
-		queue->ctrl_data = NULL;
-		msm_queue_drain(&queue->ctrl_q, list_control);
-		msm_drain_eventq(&queue->eventData_q);
-		rc = msm_cam_server_close_session(&g_server_dev, pcam);
+		rc = msm_server_end_session(pcam);
 		if (rc < 0)
-			pr_err("msm_cam_server_close_session fails %d\n", rc);
-
-		if (g_server_dev.use_count == 0)
-			mutex_unlock(&g_server_dev.server_lock);
-
-		msm_cam_server_subdev_notify(g_server_dev.gesture_device,
-			NOTIFY_GESTURE_CAM_EVT, &ges_evt);
+			pr_err("msm_server_end_session fails %d\n", rc);
 	}
 	mutex_unlock(&pcam->vid_lock);
 	return rc;
@@ -2156,280 +1041,8 @@
 	return rc;
 }
 
-static unsigned int msm_poll_server(struct file *fp,
-					struct poll_table_struct *wait)
-{
-	int rc = 0;
-
-	D("%s\n", __func__);
-	poll_wait(fp,
-		 &g_server_dev.server_command_queue.eventHandle.events->wait,
-		 wait);
-	if (v4l2_event_pending(&g_server_dev.server_command_queue.eventHandle))
-		rc |= POLLPRI;
-
-	return rc;
-}
-static long msm_ioctl_server(struct file *file, void *fh,
-		bool valid_prio, int cmd, void *arg)
-{
-	int rc = -EINVAL;
-	struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
-	struct msm_camera_info temp_cam_info;
-	struct msm_cam_config_dev_info temp_config_info;
-	struct msm_mctl_node_info temp_mctl_info;
-	int i;
-
-	D("%s: cmd %d\n", __func__, _IOC_NR(cmd));
-
-	switch (cmd) {
-	case MSM_CAM_V4L2_IOCTL_GET_CAMERA_INFO:
-		if (copy_from_user(&temp_cam_info,
-			(void __user *)ioctl_ptr->ioctl_ptr,
-			sizeof(struct msm_camera_info))) {
-			rc = -EINVAL;
-			return rc;
-		}
-		for (i = 0; i < g_server_dev.camera_info.num_cameras; i++) {
-			if (copy_to_user((void __user *)
-				temp_cam_info.video_dev_name[i],
-				g_server_dev.camera_info.video_dev_name[i],
-				strnlen(
-				g_server_dev.camera_info.video_dev_name[i],
-				MAX_DEV_NAME_LEN))) {
-				rc = -EINVAL;
-				return rc;
-			}
-			temp_cam_info.has_3d_support[i] =
-				g_server_dev.camera_info.has_3d_support[i];
-			temp_cam_info.is_internal_cam[i] =
-				g_server_dev.camera_info.is_internal_cam[i];
-			temp_cam_info.s_mount_angle[i] =
-				g_server_dev.camera_info.s_mount_angle[i];
-			temp_cam_info.sensor_type[i] =
-				g_server_dev.camera_info.sensor_type[i];
-
-		}
-		temp_cam_info.num_cameras =
-			g_server_dev.camera_info.num_cameras;
-		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
-				&temp_cam_info,
-				sizeof(struct msm_camera_info))) {
-					rc = -EINVAL;
-					return rc;
-		}
-		rc = 0;
-		break;
-
-	case MSM_CAM_V4L2_IOCTL_GET_CONFIG_INFO:
-		if (copy_from_user(&temp_config_info,
-				(void __user *)ioctl_ptr->ioctl_ptr,
-				sizeof(struct msm_cam_config_dev_info))) {
-
-			rc = -EINVAL;
-			return rc;
-		}
-		for (i = 0;
-		 i < g_server_dev.config_info.num_config_nodes; i++) {
-			if (copy_to_user(
-			(void __user *)temp_config_info.config_dev_name[i],
-			g_server_dev.config_info.config_dev_name[i],
-			strlen(g_server_dev.config_info.config_dev_name[i]))) {
-				rc = -EINVAL;
-				return rc;
-			}
-		}
-		temp_config_info.num_config_nodes =
-			g_server_dev.config_info.num_config_nodes;
-		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
-							  &temp_config_info,
-				sizeof(struct msm_cam_config_dev_info))) {
-			rc = -EINVAL;
-			return rc;
-		}
-		rc = 0;
-		break;
-	case MSM_CAM_V4L2_IOCTL_GET_MCTL_INFO:
-		if (copy_from_user(&temp_mctl_info,
-				(void __user *)ioctl_ptr->ioctl_ptr,
-				sizeof(struct msm_mctl_node_info))) {
-			rc = -EINVAL;
-			return rc;
-		}
-		for (i = 0; i < g_server_dev.mctl_node_info.num_mctl_nodes;
-				i++) {
-			if (copy_to_user((void __user *)
-			temp_mctl_info.mctl_node_name[i],
-			g_server_dev.mctl_node_info.mctl_node_name[i], strnlen(
-			g_server_dev.mctl_node_info.mctl_node_name[i],
-			MAX_DEV_NAME_LEN))) {
-				rc = -EINVAL;
-				return rc;
-			}
-		}
-		temp_mctl_info.num_mctl_nodes =
-			g_server_dev.mctl_node_info.num_mctl_nodes;
-		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
-							  &temp_mctl_info,
-				sizeof(struct msm_mctl_node_info))) {
-			rc = -EINVAL;
-			return rc;
-		}
-		rc = 0;
-	break;
-
-	case MSM_CAM_V4L2_IOCTL_CTRL_CMD_DONE:
-		D("%s: MSM_CAM_IOCTL_CTRL_CMD_DONE\n", __func__);
-		rc = msm_ctrl_cmd_done(arg);
-		break;
-
-	case MSM_CAM_V4L2_IOCTL_GET_EVENT_PAYLOAD: {
-		struct msm_queue_cmd *event_cmd;
-		struct msm_isp_event_ctrl u_isp_event;
-		struct msm_isp_event_ctrl *k_isp_event;
-		struct msm_device_queue *queue;
-		void __user *u_ctrl_value = NULL;
-		if (copy_from_user(&u_isp_event,
-			(void __user *)ioctl_ptr->ioctl_ptr,
-			sizeof(struct msm_isp_event_ctrl))) {
-			rc = -EINVAL;
-			return rc;
-		}
-		queue = &g_server_dev.server_queue
-			[u_isp_event.isp_data.ctrl.queue_idx].eventData_q;
-		event_cmd = msm_dequeue(queue, list_eventdata);
-		if (!event_cmd) {
-			pr_err("%s: No event payload\n", __func__);
-			rc = -EINVAL;
-			return rc;
-		}
-		k_isp_event = (struct msm_isp_event_ctrl *)
-				event_cmd->command;
-		free_qcmd(event_cmd);
-
-		/* Save the pointer of the user allocated command buffer*/
-		u_ctrl_value = u_isp_event.isp_data.ctrl.value;
-
-		/* Copy the event structure into user struct*/
-		u_isp_event = *k_isp_event;
-
-		/* Restore the saved pointer of the user
-		 * allocated command buffer. */
-		u_isp_event.isp_data.ctrl.value = u_ctrl_value;
-
-		/* Copy the ctrl cmd, if present*/
-		if (k_isp_event->isp_data.ctrl.length > 0) {
-			void *k_ctrl_value =
-				k_isp_event->isp_data.ctrl.value;
-			if (copy_to_user(u_ctrl_value, k_ctrl_value,
-				 k_isp_event->isp_data.ctrl.length)) {
-				rc = -EINVAL;
-				break;
-			}
-		}
-		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
-							  &u_isp_event,
-				sizeof(struct msm_isp_event_ctrl))) {
-			rc = -EINVAL;
-			return rc;
-		}
-		rc = 0;
-		break;
-	}
-
-	case MSM_CAM_IOCTL_SEND_EVENT:
-		rc = msm_server_send_v4l2_evt(arg);
-		break;
-
-	default:
-		pr_err("%s: Invalid IOCTL = %d", __func__, cmd);
-		break;
-	}
-	return rc;
-}
-
-static int msm_open_server(struct file *fp)
-{
-	int rc = 0;
-	D("%s: open %s\n", __func__, fp->f_path.dentry->d_name.name);
-	mutex_lock(&g_server_dev.server_lock);
-	g_server_dev.use_count++;
-	if (g_server_dev.use_count == 1)
-		fp->private_data =
-			&g_server_dev.server_command_queue.eventHandle;
-	mutex_unlock(&g_server_dev.server_lock);
-	return rc;
-}
-
-static unsigned int msm_poll_config(struct file *fp,
-					struct poll_table_struct *wait)
-{
-	int rc = 0;
-	struct msm_cam_config_dev *config = fp->private_data;
-	if (config == NULL)
-		return -EINVAL;
-
-	D("%s\n", __func__);
-
-	poll_wait(fp,
-	&config->config_stat_event_queue.eventHandle.events->wait, wait);
-	if (v4l2_event_pending(&config->config_stat_event_queue.eventHandle))
-		rc |= POLLPRI;
-	return rc;
-}
-
-static int msm_close_server(struct file *fp)
-{
-	struct v4l2_event_subscription sub;
-	D("%s\n", __func__);
-	mutex_lock(&g_server_dev.server_lock);
-	if (g_server_dev.use_count > 0)
-		g_server_dev.use_count--;
-	mutex_unlock(&g_server_dev.server_lock);
-	if (g_server_dev.use_count == 0) {
-		if (g_server_dev.pcam_active) {
-			struct v4l2_event v4l2_ev;
-			mutex_lock(&g_server_dev.server_lock);
-
-			v4l2_ev.type = V4L2_EVENT_PRIVATE_START
-				+ MSM_CAM_APP_NOTIFY_ERROR_EVENT;
-			ktime_get_ts(&v4l2_ev.timestamp);
-			v4l2_event_queue(
-				g_server_dev.pcam_active->pvdev, &v4l2_ev);
-		}
-	sub.type = V4L2_EVENT_ALL;
-	msm_server_v4l2_unsubscribe_event(
-		&g_server_dev.server_command_queue.eventHandle, &sub);
-	}
-	return 0;
-}
-
-static long msm_server_send_v4l2_evt(void *evt)
-{
-	struct v4l2_event *v4l2_ev = (struct v4l2_event *)evt;
-	int rc = 0;
-
-	if (NULL == evt) {
-		pr_err("%s: evt is NULL\n", __func__);
-		return -EINVAL;
-	}
-
-	D("%s: evt type 0x%x\n", __func__, v4l2_ev->type);
-	if ((v4l2_ev->type >= MSM_GES_APP_EVT_MIN) &&
-		(v4l2_ev->type < MSM_GES_APP_EVT_MAX)) {
-		msm_cam_server_subdev_notify(g_server_dev.gesture_device,
-			NOTIFY_GESTURE_EVT, v4l2_ev);
-	} else {
-		pr_err("%s: Invalid evt %d\n", __func__, v4l2_ev->type);
-		rc = -EINVAL;
-	}
-	D("%s: end\n", __func__);
-
-	return rc;
-}
-
-static long msm_v4l2_evt_notify(struct msm_cam_media_controller *mctl,
-		unsigned int cmd, unsigned long evt)
+long msm_v4l2_evt_notify(struct msm_cam_media_controller *mctl,
+	unsigned int cmd, unsigned long evt)
 {
 	struct v4l2_event v4l2_ev;
 	struct msm_cam_v4l2_device *pcam = NULL;
@@ -2451,280 +1064,6 @@
 	return 0;
 }
 
-static long msm_ioctl_config(struct file *fp, unsigned int cmd,
-	unsigned long arg)
-{
-
-	int rc = 0;
-	struct v4l2_event ev;
-	struct msm_cam_config_dev *config_cam = fp->private_data;
-	struct v4l2_event_subscription temp_sub;
-
-	D("%s: cmd %d\n", __func__, _IOC_NR(cmd));
-
-	switch (cmd) {
-	/* memory management shall be handeld here*/
-	case MSM_CAM_IOCTL_REGISTER_PMEM:
-		return msm_register_pmem(
-			&config_cam->p_mctl->stats_info.pmem_stats_list,
-			(void __user *)arg, config_cam->p_mctl->client);
-		break;
-
-	case MSM_CAM_IOCTL_UNREGISTER_PMEM:
-		return msm_pmem_table_del(
-			&config_cam->p_mctl->stats_info.pmem_stats_list,
-			(void __user *)arg, config_cam->p_mctl->client);
-		break;
-
-	case VIDIOC_SUBSCRIBE_EVENT:
-		if (copy_from_user(&temp_sub,
-			(void __user *)arg,
-			sizeof(struct v4l2_event_subscription))) {
-			rc = -EINVAL;
-			return rc;
-		}
-		rc = msm_server_v4l2_subscribe_event
-			(&config_cam->config_stat_event_queue.eventHandle,
-			&temp_sub);
-		if (rc < 0) {
-			pr_err("%s: cam_v4l2_subscribe_event failed rc=%d\n",
-				__func__, rc);
-			return rc;
-		}
-		break;
-
-	case VIDIOC_UNSUBSCRIBE_EVENT:
-		if (copy_from_user(&temp_sub, (void __user *)arg,
-			sizeof(struct v4l2_event_subscription))) {
-			rc = -EINVAL;
-			return rc;
-		}
-		rc = msm_server_v4l2_unsubscribe_event
-			(&config_cam->config_stat_event_queue.eventHandle,
-			&temp_sub);
-		if (rc < 0) {
-			pr_err("%s: server_unsubscribe_event failed rc=%d\n",
-				__func__, rc);
-			return rc;
-		}
-		break;
-
-	case VIDIOC_DQEVENT: {
-		void __user *u_msg_value = NULL, *user_ptr = NULL;
-		struct msm_isp_event_ctrl u_isp_event;
-		struct msm_isp_event_ctrl *k_isp_event;
-
-		/* First, copy the v4l2 event structure from userspace */
-		D("%s: VIDIOC_DQEVENT\n", __func__);
-		if (copy_from_user(&ev, (void __user *)arg,
-				sizeof(struct v4l2_event)))
-			break;
-		/* Next, get the pointer to event_ctrl structure
-		 * embedded inside the v4l2_event.u.data array. */
-		user_ptr = (void __user *)(*((uint32_t *)ev.u.data));
-
-		/* Next, copy the userspace event ctrl structure */
-		if (copy_from_user((void *)&u_isp_event, user_ptr,
-				   sizeof(struct msm_isp_event_ctrl))) {
-			break;
-		}
-		/* Save the pointer of the user allocated command buffer*/
-		u_msg_value = u_isp_event.isp_data.isp_msg.data;
-
-		/* Dequeue the event queued into the v4l2 queue*/
-		rc = v4l2_event_dequeue(
-			&config_cam->config_stat_event_queue.eventHandle,
-			&ev, fp->f_flags & O_NONBLOCK);
-		if (rc < 0) {
-			pr_err("no pending events?");
-			break;
-		}
-		/* Use k_isp_event to point to the event_ctrl structure
-		 * embedded inside v4l2_event.u.data */
-		k_isp_event = (struct msm_isp_event_ctrl *)
-				(*((uint32_t *)ev.u.data));
-		/* Copy the event structure into user struct. */
-		u_isp_event = *k_isp_event;
-		if (ev.type != (V4L2_EVENT_PRIVATE_START +
-				MSM_CAM_RESP_DIV_FRAME_EVT_MSG) &&
-				ev.type != (V4L2_EVENT_PRIVATE_START +
-				MSM_CAM_RESP_MCTL_PP_EVENT)) {
-
-			/* Restore the saved pointer of the
-			 * user allocated command buffer. */
-			u_isp_event.isp_data.isp_msg.data = u_msg_value;
-
-			if (ev.type == (V4L2_EVENT_PRIVATE_START +
-					MSM_CAM_RESP_STAT_EVT_MSG)) {
-				if (k_isp_event->isp_data.isp_msg.len > 0) {
-					void *k_msg_value =
-					k_isp_event->isp_data.isp_msg.data;
-					if (copy_to_user(u_msg_value,
-							k_msg_value,
-					 k_isp_event->isp_data.isp_msg.len)) {
-						rc = -EINVAL;
-						break;
-					}
-					kfree(k_msg_value);
-				}
-			}
-		}
-		/* Copy the event ctrl structure back
-		 * into user's structure. */
-		if (copy_to_user(user_ptr,
-				(void *)&u_isp_event, sizeof(
-				struct msm_isp_event_ctrl))) {
-			rc = -EINVAL;
-			break;
-		}
-		kfree(k_isp_event);
-
-		/* Copy the v4l2_event structure back to the user*/
-		if (copy_to_user((void __user *)arg, &ev,
-				sizeof(struct v4l2_event))) {
-			rc = -EINVAL;
-			break;
-		}
-		}
-
-		break;
-
-	case MSM_CAM_IOCTL_V4L2_EVT_NOTIFY:
-		rc = msm_v4l2_evt_notify(config_cam->p_mctl, cmd, arg);
-		break;
-
-	case MSM_CAM_IOCTL_SET_MEM_MAP_INFO:
-		if (copy_from_user(&config_cam->mem_map, (void __user *)arg,
-				sizeof(struct msm_mem_map_info)))
-			rc = -EINVAL;
-		break;
-
-	default:{
-		/* For the rest of config command, forward to media controller*/
-		struct msm_cam_media_controller *p_mctl = config_cam->p_mctl;
-		if (p_mctl && p_mctl->mctl_cmd) {
-			rc = config_cam->p_mctl->mctl_cmd(p_mctl, cmd, arg);
-		} else {
-			rc = -EINVAL;
-			pr_err("%s: media controller is null\n", __func__);
-		}
-
-		break;
-	} /* end of default*/
-	} /* end of switch*/
-	return rc;
-}
-
-static int msm_mmap_config(struct file *fp, struct vm_area_struct *vma)
-{
-	struct msm_cam_config_dev *config_cam = fp->private_data;
-	int rc = 0;
-	int phyaddr;
-	int retval;
-	unsigned long size;
-
-	D("%s: phy_addr=0x%x", __func__, config_cam->mem_map.cookie);
-	phyaddr = (int)config_cam->mem_map.cookie;
-	if (!phyaddr) {
-		pr_err("%s: no physical memory to map", __func__);
-		return -EFAULT;
-	}
-	memset(&config_cam->mem_map, 0,
-		sizeof(struct msm_mem_map_info));
-	size = vma->vm_end - vma->vm_start;
-	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-	retval = remap_pfn_range(vma, vma->vm_start,
-					phyaddr >> PAGE_SHIFT,
-					size, vma->vm_page_prot);
-	if (retval) {
-		pr_err("%s: remap failed, rc = %d",
-					__func__, retval);
-		rc = -ENOMEM;
-		goto end;
-	}
-	D("%s: phy_addr=0x%x: %08lx-%08lx, pgoff %08lx\n",
-			__func__, (uint32_t)phyaddr,
-			vma->vm_start, vma->vm_end, vma->vm_pgoff);
-end:
-	return rc;
-}
-
-static int msm_open_config(struct inode *inode, struct file *fp)
-{
-	int rc;
-	struct msm_cam_config_dev *config_cam = container_of(inode->i_cdev,
-		struct msm_cam_config_dev, config_cdev);
-
-	D("%s: open %s\n", __func__, fp->f_path.dentry->d_name.name);
-
-	rc = nonseekable_open(inode, fp);
-	if (rc < 0) {
-		pr_err("%s: nonseekable_open error %d\n", __func__, rc);
-		return rc;
-	}
-	config_cam->use_count++;
-
-	/*config_cam->isp_subdev = g_server_dev.pcam_active->mctl.isp_sdev;*/
-	/* assume there is only one active camera possible*/
-	config_cam->p_mctl =
-		msm_camera_get_mctl(g_server_dev.pcam_active->mctl_handle);
-
-	INIT_HLIST_HEAD(&config_cam->p_mctl->stats_info.pmem_stats_list);
-	spin_lock_init(&config_cam->p_mctl->stats_info.pmem_stats_spinlock);
-
-	config_cam->p_mctl->config_device = config_cam;
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	kref_get(&config_cam->p_mctl->refcount);
-#endif
-	fp->private_data = config_cam;
-	return rc;
-}
-
-static int msm_close_config(struct inode *node, struct file *f)
-{
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	struct msm_cam_config_dev *config_cam = f->private_data;
-	D("%s Decrementing ref count of config node ", __func__);
-	kref_put(&config_cam->p_mctl->refcount, msm_release_ion_client);
-#endif
-	return 0;
-}
-
-static struct v4l2_file_operations g_msm_fops = {
-	.owner   = THIS_MODULE,
-	.open	= msm_open,
-	.poll	= msm_poll,
-	.mmap	= msm_mmap,
-	.release = msm_close,
-	.ioctl   = video_ioctl2,
-};
-
-/* Init a config node for ISP control,
- * which will create a config device (/dev/config0/ and plug in
- * ISP's operation "v4l2_ioctl_ops*"
- */
-static const struct v4l2_file_operations msm_fops_server = {
-	.owner = THIS_MODULE,
-	.open  = msm_open_server,
-	.poll  = msm_poll_server,
-	.unlocked_ioctl = video_ioctl2,
-	.release = msm_close_server,
-};
-
-static const struct v4l2_ioctl_ops msm_ioctl_ops_server = {
-	.vidioc_subscribe_event = msm_server_v4l2_subscribe_event,
-	.vidioc_default = msm_ioctl_server,
-};
-
-static const struct file_operations msm_fops_config = {
-	.owner = THIS_MODULE,
-	.open  = msm_open_config,
-	.poll  = msm_poll_config,
-	.unlocked_ioctl = msm_ioctl_config,
-	.mmap	= msm_mmap_config,
-	.release = msm_close_config,
-};
-
 int msm_setup_v4l2_event_queue(struct v4l2_fh *eventHandle,
 	struct video_device *pvdev)
 {
@@ -2752,319 +1091,14 @@
 	return rc;
 }
 
-static int msm_setup_config_dev(int node, char *device_name)
-{
-	int rc = -ENODEV;
-	struct device *device_config;
-	int dev_num = node;
-	dev_t devno;
-	struct msm_cam_config_dev *config_cam;
-
-	config_cam = kzalloc(sizeof(*config_cam), GFP_KERNEL);
-	if (!config_cam) {
-		pr_err("%s: could not allocate memory for msm_cam_config_device\n",
-			__func__);
-		return -ENOMEM;
-	}
-
-	D("%s\n", __func__);
-
-	devno = MKDEV(MAJOR(msm_devno), dev_num+1);
-	device_config = device_create(msm_class, NULL, devno, NULL, "%s%d",
-		device_name, dev_num);
-
-	if (IS_ERR(device_config)) {
-		rc = PTR_ERR(device_config);
-		pr_err("%s: error creating device: %d\n", __func__, rc);
-		goto config_setup_fail;
-	}
-
-	cdev_init(&config_cam->config_cdev, &msm_fops_config);
-	config_cam->config_cdev.owner = THIS_MODULE;
-
-	rc = cdev_add(&config_cam->config_cdev, devno, 1);
-	if (rc < 0) {
-		pr_err("%s: error adding cdev: %d\n", __func__, rc);
-		device_destroy(msm_class, devno);
-		goto config_setup_fail;
-	}
-
-	g_server_dev.config_info.config_dev_name[dev_num] =
-		dev_name(device_config);
-	D("%s Connected config device %s\n", __func__,
-		g_server_dev.config_info.config_dev_name[dev_num]);
-	g_server_dev.config_info.config_dev_id[dev_num] = dev_num;
-
-	config_cam->config_stat_event_queue.pvdev = video_device_alloc();
-	if (config_cam->config_stat_event_queue.pvdev == NULL) {
-		pr_err("%s: video_device_alloc failed\n", __func__);
-		goto config_setup_fail;
-	}
-
-	rc = 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;
-
-config_setup_fail:
-	kfree(config_cam);
-	return rc;
-}
-
-static void msm_cam_server_subdev_notify(struct v4l2_subdev *sd,
-				unsigned int notification, void *arg)
-{
-	int rc = -EINVAL;
-	struct msm_sensor_ctrl_t *s_ctrl;
-	struct msm_camera_sensor_info *sinfo;
-	struct msm_camera_device_platform_data *camdev;
-	uint8_t csid_core = 0;
-
-	if (notification == NOTIFY_CID_CHANGE ||
-		notification == NOTIFY_ISPIF_STREAM ||
-		notification == NOTIFY_PCLK_CHANGE ||
-		notification == NOTIFY_CSIPHY_CFG ||
-		notification == NOTIFY_CSID_CFG ||
-		notification == NOTIFY_CSIC_CFG) {
-		s_ctrl = get_sctrl(sd);
-		sinfo = (struct msm_camera_sensor_info *) s_ctrl->sensordata;
-		camdev = sinfo->pdata;
-		csid_core = camdev->csid_core;
-	}
-
-	switch (notification) {
-	case NOTIFY_CID_CHANGE:
-		/* reconfig the ISPIF*/
-		if (g_server_dev.ispif_device) {
-			struct msm_ispif_params_list ispif_params;
-			ispif_params.len = 1;
-			ispif_params.params[0].intftype = PIX0;
-			ispif_params.params[0].cid_mask = 0x0001;
-			ispif_params.params[0].csid = csid_core;
-
-			rc = v4l2_subdev_call(
-				g_server_dev.ispif_device, core, ioctl,
-				VIDIOC_MSM_ISPIF_CFG, &ispif_params);
-			if (rc < 0)
-				return;
-		}
-		break;
-	case NOTIFY_ISPIF_STREAM:
-		/* call ISPIF stream on/off */
-		rc = v4l2_subdev_call(g_server_dev.ispif_device, video,
-				s_stream, (int)arg);
-		if (rc < 0)
-			return;
-
-		break;
-	case NOTIFY_ISP_MSG_EVT:
-	case NOTIFY_VFE_MSG_OUT:
-	case NOTIFY_VFE_MSG_STATS:
-	case NOTIFY_VFE_MSG_COMP_STATS:
-	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) {
-			rc = g_server_dev.isp_subdev[0]->isp_notify(
-				g_server_dev.vfe_device[0], notification, arg);
-		}
-		break;
-	case NOTIFY_VPE_MSG_EVT: {
-		struct msm_cam_media_controller *pmctl =
-		(struct msm_cam_media_controller *)
-		v4l2_get_subdev_hostdata(sd);
-		struct msm_vpe_resp *vdata = (struct msm_vpe_resp *)arg;
-		msm_mctl_pp_notify(pmctl,
-		(struct msm_mctl_pp_frame_info *)
-		vdata->extdata);
-		break;
-	}
-	case NOTIFY_VFE_IRQ:{
-		struct msm_vfe_cfg_cmd cfg_cmd;
-		struct msm_camvfe_params vfe_params;
-		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],
-			core, ioctl, 0, &vfe_params);
-	}
-		break;
-	case NOTIFY_AXI_IRQ:
-		rc = v4l2_subdev_call(g_server_dev.axi_device[0],
-			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,
-				s_crystal_freq, *(uint32_t *)arg, 0);
-		else
-			rc = v4l2_subdev_call(g_server_dev.vfe_device[0], video,
-				s_crystal_freq, *(uint32_t *)arg, 0);
-		break;
-	case NOTIFY_CSIPHY_CFG:
-		rc = v4l2_subdev_call(g_server_dev.csiphy_device[csid_core],
-			core, ioctl, VIDIOC_MSM_CSIPHY_CFG, arg);
-		break;
-	case NOTIFY_CSID_CFG:
-		rc = v4l2_subdev_call(g_server_dev.csid_device[csid_core],
-			core, ioctl, VIDIOC_MSM_CSID_CFG, arg);
-		break;
-	case NOTIFY_CSIC_CFG:
-		rc = v4l2_subdev_call(g_server_dev.csic_device[csid_core],
-			core, ioctl, VIDIOC_MSM_CSIC_CFG, arg);
-		break;
-	case NOTIFY_GESTURE_EVT:
-		rc = v4l2_subdev_call(g_server_dev.gesture_device,
-			core, ioctl, VIDIOC_MSM_GESTURE_EVT, arg);
-		break;
-	case NOTIFY_GESTURE_CAM_EVT:
-		rc = v4l2_subdev_call(g_server_dev.gesture_device,
-			core, ioctl, VIDIOC_MSM_GESTURE_CAM_EVT, arg);
-		break;
-	default:
-		break;
-	}
-
-	return;
-}
-
-int msm_cam_register_subdev_node(struct v4l2_subdev *sd,
-	enum msm_cam_subdev_type sdev_type, uint8_t index)
-{
-	struct video_device *vdev;
-	int err = 0;
-
-	if (sdev_type == CSIPHY_DEV) {
-		if (index >= MAX_NUM_CSIPHY_DEV)
-			return -EINVAL;
-		g_server_dev.csiphy_device[index] = sd;
-	} else if (sdev_type == CSID_DEV) {
-		if (index >= MAX_NUM_CSID_DEV)
-			return -EINVAL;
-		g_server_dev.csid_device[index] = sd;
-	} else if (sdev_type == CSIC_DEV) {
-		if (index >= MAX_NUM_CSIC_DEV)
-			return -EINVAL;
-		g_server_dev.csic_device[index] = sd;
-	} else if (sdev_type == ISPIF_DEV) {
-		g_server_dev.ispif_device = sd;
-	} else if (sdev_type == VFE_DEV) {
-		if (index >= MAX_NUM_VFE_DEV)
-			return -EINVAL;
-		g_server_dev.vfe_device[index] = sd;
-	} else if (sdev_type == VPE_DEV) {
-		if (index >= MAX_NUM_VPE_DEV)
-			return -EINVAL;
-		g_server_dev.vpe_device[index] = sd;
-	} else if (sdev_type == AXI_DEV) {
-		if (index >= MAX_NUM_AXI_DEV)
-			return -EINVAL;
-		g_server_dev.axi_device[index] = sd;
-	} else if (sdev_type == GESTURE_DEV) {
-		g_server_dev.gesture_device = sd;
-	}
-
-	err = v4l2_device_register_subdev(&g_server_dev.v4l2_dev, sd);
-	if (err < 0)
-		return err;
-
-	/* Register a device node for every subdev marked with the
-	 * V4L2_SUBDEV_FL_HAS_DEVNODE flag.
-	 */
-	if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
-		return err;
-
-	vdev = &sd->devnode;
-	strlcpy(vdev->name, sd->name, sizeof(vdev->name));
-	vdev->v4l2_dev = &g_server_dev.v4l2_dev;
-	vdev->fops = &v4l2_subdev_fops;
-	vdev->release = video_device_release_empty;
-	err = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1,
-						  sd->owner);
-	if (err < 0)
-		return err;
-#if defined(CONFIG_MEDIA_CONTROLLER)
-	sd->entity.v4l.major = VIDEO_MAJOR;
-	sd->entity.v4l.minor = vdev->minor;
-#endif
-	return 0;
-}
-
-static int msm_setup_server_dev(struct platform_device *pdev)
-{
-	int rc = -ENODEV, i;
-
-	D("%s\n", __func__);
-	g_server_dev.server_pdev = pdev;
-	g_server_dev.v4l2_dev.dev = &pdev->dev;
-	g_server_dev.v4l2_dev.notify = msm_cam_server_subdev_notify;
-	rc = v4l2_device_register(g_server_dev.v4l2_dev.dev,
-			&g_server_dev.v4l2_dev);
-	if (rc < 0)
-		return -EINVAL;
-
-	g_server_dev.video_dev = video_device_alloc();
-	if (g_server_dev.video_dev == NULL) {
-		pr_err("%s: video_device_alloc failed\n", __func__);
-		return rc;
-	}
-
-	strlcpy(g_server_dev.video_dev->name, pdev->name,
-			sizeof(g_server_dev.video_dev->name));
-
-	g_server_dev.video_dev->v4l2_dev = &g_server_dev.v4l2_dev;
-	g_server_dev.video_dev->fops = &msm_fops_server;
-	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;
-
-	video_set_drvdata(g_server_dev.video_dev, &g_server_dev);
-
-	strlcpy(g_server_dev.media_dev.model, "qcamera",
-		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;
-
-	rc = video_register_device(g_server_dev.video_dev,
-		VFL_TYPE_GRABBER, 100);
-
-	mutex_init(&g_server_dev.server_lock);
-	mutex_init(&g_server_dev.server_queue_lock);
-	g_server_dev.pcam_active = NULL;
-	g_server_dev.camera_info.num_cameras = 0;
-	atomic_set(&g_server_dev.number_pcam_active, 0);
-	g_server_dev.server_evt_id = 0;
-
-	/*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(
-		&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];
-		queue->queue_active = 0;
-		msm_queue_init(&queue->ctrl_q, "control");
-		msm_queue_init(&queue->eventData_q, "eventdata");
-	}
-	return rc;
-}
+static struct v4l2_file_operations g_msm_fops = {
+	.owner   = THIS_MODULE,
+	.open	= msm_open,
+	.poll	= msm_poll,
+	.mmap	= msm_mmap,
+	.release = msm_close,
+	.ioctl   = video_ioctl2,
+};
 
 static int msm_cam_dev_init(struct msm_cam_v4l2_device *pcam)
 {
@@ -3105,7 +1139,7 @@
 	strlcpy(pvdev->name, pcam->sensor_sdev->name, sizeof(pvdev->name));
 
 	pvdev->release   = video_device_release;
-	pvdev->fops	  = &g_msm_fops;
+	pvdev->fops	     = &g_msm_fops;
 	pvdev->ioctl_ops = &g_msm_ioctl_ops;
 	pvdev->minor	 = -1;
 	pvdev->vfl_type  = 1;
@@ -3131,16 +1165,7 @@
 	pcam->pvdev	= pvdev;
 	video_set_drvdata(pcam->pvdev, pcam);
 
-	/* If isp HW registeration is successful,
-	 * then create event queue to
-	 * receievent event froms HW
-	*/
-	/* yyan: no global - each sensor will
-	 * create a new vidoe node! */
-	/* g_pmsm_camera_v4l2_dev = pmsm_camera_v4l2_dev; */
-	/* g_pmsm_camera_v4l2_dev->pvdev = pvdev; */
-
-	return rc ;
+	return rc;
 
 reg_fail:
 	video_device_release(pvdev);
@@ -3281,46 +1306,7 @@
 			 __func__, rc);
 		goto failure;
 	}
-
-	g_server_dev.camera_info.video_dev_name
-	[g_server_dev.camera_info.num_cameras]
-	= video_device_node_name(pcam->pvdev);
-	D("%s Connected video device %s\n", __func__,
-		g_server_dev.camera_info.video_dev_name
-		[g_server_dev.camera_info.num_cameras]);
-
-	g_server_dev.camera_info.s_mount_angle
-	[g_server_dev.camera_info.num_cameras]
-	= sdata->sensor_platform_info->mount_angle;
-
-	g_server_dev.camera_info.is_internal_cam
-	[g_server_dev.camera_info.num_cameras]
-	= sdata->camera_type;
-
-	g_server_dev.mctl_node_info.mctl_node_name
-	[g_server_dev.mctl_node_info.num_mctl_nodes]
-	= video_device_node_name(pcam->mctl_node.pvdev);
-
-	pr_info("%s mctl_node_name[%d] = %s\n", __func__,
-		g_server_dev.mctl_node_info.num_mctl_nodes,
-		g_server_dev.mctl_node_info.mctl_node_name
-		[g_server_dev.mctl_node_info.num_mctl_nodes]);
-
-	/*Temporary solution to store info in media device structure
-	  until we can expand media device structure to support more
-	  device info*/
-	snprintf(pcam->media_dev.serial,
-			sizeof(pcam->media_dev.serial),
-			"%s-%d-%d", QCAMERA_NAME,
-			sdata->sensor_platform_info->mount_angle,
-			sdata->camera_type);
-
-	g_server_dev.camera_info.num_cameras++;
-	g_server_dev.mctl_node_info.num_mctl_nodes++;
-
-	D("%s done, rc = %d\n", __func__, rc);
-	D("%s number of sensors connected is %d\n", __func__,
-		g_server_dev.camera_info.num_cameras);
+	msm_server_update_sensor_info(pcam, sdata);
 
 	/* register the subdevice, must be done for callbacks */
 	rc = msm_cam_register_subdev_node(sensor_sd, SENSOR_DEV, vnode_count);
@@ -3358,83 +1344,3 @@
 }
 EXPORT_SYMBOL(msm_sensor_register);
 
-static int __devinit msm_camera_probe(struct platform_device *pdev)
-{
-	int rc = 0, i;
-	/*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;
-
-	rc = msm_isp_init_module(g_server_dev.config_info.num_config_nodes);
-	if (rc < 0) {
-		pr_err("Failed to initialize isp\n");
-		return rc;
-	}
-
-	if (!msm_class) {
-		rc = alloc_chrdev_region(&msm_devno, 0,
-		g_server_dev.config_info.num_config_nodes+1, "msm_camera");
-		if (rc < 0) {
-			pr_err("%s: failed to allocate chrdev: %d\n", __func__,
-			rc);
-			return rc;
-		}
-
-		msm_class = class_create(THIS_MODULE, "msm_camera");
-		if (IS_ERR(msm_class)) {
-			rc = PTR_ERR(msm_class);
-			pr_err("%s: create device class failed: %d\n",
-			__func__, rc);
-			return rc;
-		}
-	}
-
-	D("creating server and config nodes\n");
-	rc = msm_setup_server_dev(pdev);
-	if (rc < 0) {
-		pr_err("%s: failed to create server dev: %d\n", __func__,
-		rc);
-		return rc;
-	}
-
-	for (i = 0; i < g_server_dev.config_info.num_config_nodes; i++) {
-		rc = msm_setup_config_dev(i, "config");
-		if (rc < 0) {
-			pr_err("%s:failed to create config dev: %d\n",
-			 __func__, rc);
-			return rc;
-		}
-	}
-
-	msm_isp_register(&g_server_dev);
-	return rc;
-}
-
-static int __exit msm_camera_exit(struct platform_device *pdev)
-{
-	msm_isp_unregister(&g_server_dev);
-	return 0;
-}
-
-
-static struct platform_driver msm_cam_server_driver = {
-	.probe = msm_camera_probe,
-	.remove = msm_camera_exit,
-	.driver = {
-		.name = "msm_cam_server",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init msm_camera_init(void)
-{
-	return platform_driver_register(&msm_cam_server_driver);
-}
-
-static void __exit msm_cam_server_exit(void)
-{
-	platform_driver_unregister(&msm_cam_server_driver);
-}
-
-module_init(msm_camera_init);
-module_exit(msm_cam_server_exit);
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index 6798cbb..dfb7ca2 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -397,7 +397,6 @@
 	uint32_t queue_active;
 	struct msm_device_queue ctrl_q;
 	struct msm_device_queue eventData_q;
-	struct msm_ctrl_cmd *ctrl;
 	uint8_t *ctrl_data;
 	uint32_t evt_id;
 };
@@ -456,7 +455,6 @@
 
 /* camera server related functions */
 
-
 /* ISP related functions */
 void msm_isp_vfe_dev_init(struct v4l2_subdev *vd);
 /*
@@ -571,15 +569,14 @@
 void msm_release_ion_client(struct kref *ref);
 int msm_cam_register_subdev_node(struct v4l2_subdev *sd,
 			enum msm_cam_subdev_type sdev_type, uint8_t index);
-uint32_t msm_camera_get_mctl_handle(void);
-struct msm_cam_media_controller *msm_camera_get_mctl(uint32_t handle);
-void msm_camera_free_mctl(uint32_t handle);
 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);
 int msm_cam_server_open_mctl_session(struct msm_cam_v4l2_device *pcam,
 	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);
 #endif /* __KERNEL__ */
 
 #endif /* _MSM_H */
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index e9eb68f..19f9411 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -28,6 +28,7 @@
 #include <linux/android_pmem.h>
 
 #include "msm.h"
+#include "msm_cam_server.h"
 #include "msm_csid.h"
 #include "msm_csic.h"
 #include "msm_csiphy.h"
@@ -858,13 +859,13 @@
 		pr_err("%s: param is NULL", __func__);
 		return -EINVAL;
 	}
-	pcam->mctl_handle = msm_camera_get_mctl_handle();
+	pcam->mctl_handle = msm_cam_server_get_mctl_handle();
 	if (pcam->mctl_handle == 0) {
 		pr_err("%s: cannot get mctl handle", __func__);
 		return -EINVAL;
 	}
 
-	pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
 	if (!pmctl) {
 		pr_err("%s: invalid mctl controller", __func__);
 		return -EINVAL;
@@ -903,7 +904,7 @@
 	struct msm_cam_media_controller *pmctl = NULL;
 	D("%s\n", __func__);
 
-	pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
 	if (!pmctl) {
 		pr_err("%s: invalid mctl controller", __func__);
 		return -EINVAL;
@@ -911,7 +912,7 @@
 
 	mutex_destroy(&pmctl->lock);
 	wake_lock_destroy(&pmctl->wake_lock);
-	msm_camera_free_mctl(pcam->mctl_handle);
+	msm_cam_server_free_mctl(pcam->mctl_handle);
 	return rc;
 }
 
@@ -967,7 +968,7 @@
 		return rc;
 	}
 
-	pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
 	if (!pmctl) {
 		pr_err("%s mctl NULL!\n", __func__);
 		return rc;
@@ -1043,7 +1044,7 @@
 		return -EINVAL;
 	}
 
-	pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
 	mutex_lock(&pcam->mctl_node.dev_lock);
 	D("%s : active %d ", __func__, pcam->mctl_node.active);
 	if (pcam->mctl_node.active == 1) {
@@ -1478,7 +1479,7 @@
 		(void *)pfmt->fmt.pix.priv);
 	WARN_ON(pctx != f->private_data);
 
-	pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
 	if (!pcam_inst->vbqueue_initialized) {
 		pmctl->mctl_vbqueue_init(pcam_inst, &pcam_inst->vid_bufq,
 					V4L2_BUF_TYPE_VIDEO_CAPTURE);
@@ -1502,7 +1503,7 @@
 		pcam_inst, pcam_inst->vbqueue_initialized);
 	WARN_ON(pctx != f->private_data);
 
-	pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
 	if (!pcam_inst->vbqueue_initialized) {
 		pmctl->mctl_vbqueue_init(pcam_inst, &pcam_inst->vid_bufq,
 					V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
diff --git a/drivers/media/video/msm/msm_mctl_buf.c b/drivers/media/video/msm/msm_mctl_buf.c
index 416e542..522ea7d 100644
--- a/drivers/media/video/msm/msm_mctl_buf.c
+++ b/drivers/media/video/msm/msm_mctl_buf.c
@@ -26,6 +26,7 @@
 #include <linux/android_pmem.h>
 
 #include "msm.h"
+#include "msm_cam_server.h"
 #include "msm_ispif.h"
 
 #ifdef CONFIG_MSM_CAMERA_DEBUG
@@ -113,7 +114,7 @@
 			pcam_inst->plane_info.plane[0].offset;
 	}
 	buf_idx = vb->v4l2_buf.index;
-	pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
 	for (i = 0; i < vb->num_planes; i++) {
 		mem = vb2_plane_cookie(vb, i);
 		if (buf_type == VIDEOBUF2_MULTIPLE_PLANES)
@@ -251,7 +252,7 @@
 		}
 		spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
 	}
-	pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
 	for (i = 0; i < vb->num_planes; i++) {
 		mem = vb2_plane_cookie(vb, i);
 		videobuf2_pmem_contig_user_put(mem, pmctl->client);
@@ -472,7 +473,7 @@
 int msm_mctl_buf_init(struct msm_cam_v4l2_device *pcam)
 {
 	struct msm_cam_media_controller *pmctl;
-	pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
 	pmctl->mctl_vbqueue_init = msm_vbqueue_init;
 	return 0;
 }
diff --git a/drivers/media/video/msm/msm_vfe31_v4l2.c b/drivers/media/video/msm/msm_vfe31_v4l2.c
index 89615ec..d5f37dc 100644
--- a/drivers/media/video/msm/msm_vfe31_v4l2.c
+++ b/drivers/media/video/msm/msm_vfe31_v4l2.c
@@ -367,7 +367,6 @@
 static void vfe31_stop(void)
 {
 
-	uint8_t  axiBusyFlag = true;
 	unsigned long flags;
 
 	atomic_set(&vfe31_ctrl->vstate, 0);
@@ -397,7 +396,52 @@
 	 * at any time. stop camif immediately. */
 	msm_camera_io_w_mb(CAMIF_COMMAND_STOP_IMMEDIATELY,
 		vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
+}
 
+void axi_start(void)
+{
+	switch (vfe31_ctrl->operation_mode) {
+	case VFE_OUTPUTS_PREVIEW:
+	case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_PRIMARY) {
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+		} else if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
+		}
+		break;
+	default:
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_SECONDARY) {
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
+		} else if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch2]);
+		}
+		break;
+	}
+}
+
+void axi_stop(void)
+{
+	uint8_t  axiBusyFlag = true;
 	/* axi halt command. */
 	msm_camera_io_w(AXI_HALT,
 		vfe31_ctrl->vfebase + VFE_AXI_CMD);
@@ -954,43 +998,6 @@
 	}
 	msm_camera_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
 
-	switch (vfe31_ctrl->operation_mode) {
-	case VFE_OUTPUTS_PREVIEW:
-	case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
-		if (vfe31_ctrl->outpath.output_mode &
-			VFE31_OUTPUT_MODE_PRIMARY) {
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
-		} else if (vfe31_ctrl->outpath.output_mode &
-			VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
-		}
-		break;
-	default:
-		if (vfe31_ctrl->outpath.output_mode &
-			VFE31_OUTPUT_MODE_SECONDARY) {
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
-		} else if (vfe31_ctrl->outpath.output_mode &
-			VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch2]);
-		}
-		break;
-	}
 	msm_camio_bus_scale_cfg(
 		pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
 	vfe31_start_common();
@@ -3325,12 +3332,14 @@
 		cmd->cmd_type != CMD_STATS_RS_BUF_RELEASE &&
 		cmd->cmd_type != CMD_STATS_CS_BUF_RELEASE &&
 		cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE) {
-		if (copy_from_user(&vfecmd,
-			(void __user *)(cmd->value),
-			sizeof(vfecmd))) {
-			pr_err("%s %d: copy_from_user failed\n", __func__,
-				__LINE__);
-			return -EFAULT;
+		if (NULL != cmd->value) {
+			if (copy_from_user(&vfecmd,
+				(void __user *)(cmd->value),
+				sizeof(vfecmd))) {
+				pr_err("%s %d: copy_from_user failed\n",
+					__func__, __LINE__);
+				return -EFAULT;
+			}
 		}
 	} else {
 	/* here eith stats release or frame release. */
@@ -3571,6 +3580,14 @@
 		}
 		break;
 
+	case CMD_AXI_START:
+		axi_start();
+		break;
+
+	case CMD_AXI_STOP:
+		axi_stop();
+		break;
+
 	default:
 		pr_err("%s Unsupported AXI configuration %x ", __func__,
 			cmd->cmd_type);
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index d50b778..220752a 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -358,7 +358,6 @@
 
 static void vfe32_stop(void)
 {
-	uint8_t  axiBusyFlag = true;
 	unsigned long flags;
 
 	atomic_set(&vfe32_ctrl->vstate, 0);
@@ -389,31 +388,6 @@
 	msm_camera_io_w(CAMIF_COMMAND_STOP_IMMEDIATELY,
 		vfe32_ctrl->vfebase + VFE_CAMIF_COMMAND);
 
-	/* axi halt command. */
-	msm_camera_io_w(AXI_HALT,
-		vfe32_ctrl->vfebase + VFE_AXI_CMD);
-	wmb();
-	while (axiBusyFlag) {
-		if (msm_camera_io_r(vfe32_ctrl->vfebase + VFE_AXI_STATUS) & 0x1)
-			axiBusyFlag = false;
-	}
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(AXI_HALT_CLEAR,
-		vfe32_ctrl->vfebase + VFE_AXI_CMD);
-
-	/* after axi halt, then ok to apply global reset. */
-	/* enable reset_ack and async timer interrupt only while
-	stopping the pipeline.*/
-	msm_camera_io_w(0xf0000000,
-		vfe32_ctrl->vfebase + VFE_IRQ_MASK_0);
-	msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
-		vfe32_ctrl->vfebase + VFE_IRQ_MASK_1);
-
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(VFE_RESET_UPON_STOP_CMD,
-		vfe32_ctrl->vfebase + VFE_GLOBAL_RESET);
 }
 
 static void vfe32_subdev_notify(int id, int path)
@@ -910,7 +884,6 @@
 static int vfe32_start(struct msm_cam_media_controller *pmctl)
 {
 	uint32_t irq_comp_mask = 0;
-
 	irq_comp_mask	=
 		msm_camera_io_r(vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
 
@@ -934,44 +907,6 @@
 	}
 	msm_camera_io_w(irq_comp_mask, vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
 
-	switch (vfe32_ctrl->operation_mode) {
-	case VFE_OUTPUTS_PREVIEW:
-	case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
-		if (vfe32_ctrl->outpath.output_mode &
-			VFE32_OUTPUT_MODE_PRIMARY) {
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
-		} else if (vfe32_ctrl->outpath.output_mode &
-				VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch2]);
-		}
-		break;
-	default:
-		if (vfe32_ctrl->outpath.output_mode &
-			VFE32_OUTPUT_MODE_SECONDARY) {
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
-		} else if (vfe32_ctrl->outpath.output_mode &
-			VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
-			msm_camera_io_w(1, vfe32_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch2]);
-		}
-		break;
-	}
-
 	msm_camio_bus_scale_cfg(
 		pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
 	vfe32_start_common();
@@ -3998,23 +3933,97 @@
 	vfe32_ctrl->vfebase = 0;
 }
 
+void axi_start(void)
+{
+	switch (vfe32_ctrl->operation_mode) {
+	case VFE_OUTPUTS_PREVIEW:
+	case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
+		if (vfe32_ctrl->outpath.output_mode &
+			VFE32_OUTPUT_MODE_PRIMARY) {
+			msm_camera_io_w(1, vfe32_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(1, vfe32_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
+		} else if (vfe32_ctrl->outpath.output_mode &
+				VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+			msm_camera_io_w(1, vfe32_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(1, vfe32_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
+			msm_camera_io_w(1, vfe32_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch2]);
+		}
+		break;
+	default:
+		if (vfe32_ctrl->outpath.output_mode &
+			VFE32_OUTPUT_MODE_SECONDARY) {
+			msm_camera_io_w(1, vfe32_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(1, vfe32_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
+		} else if (vfe32_ctrl->outpath.output_mode &
+			VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+			msm_camera_io_w(1, vfe32_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(1, vfe32_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
+			msm_camera_io_w(1, vfe32_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch2]);
+		}
+		break;
+	}
+}
+
+void axi_stop(void)
+{
+	uint8_t  axiBusyFlag = true;
+		/* axi halt command. */
+	msm_camera_io_w(AXI_HALT,
+		vfe32_ctrl->vfebase + VFE_AXI_CMD);
+	wmb();
+	while (axiBusyFlag) {
+		if (msm_camera_io_r(vfe32_ctrl->vfebase + VFE_AXI_STATUS) & 0x1)
+			axiBusyFlag = false;
+	}
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(AXI_HALT_CLEAR,
+		vfe32_ctrl->vfebase + VFE_AXI_CMD);
+
+	/* after axi halt, then ok to apply global reset. */
+	/* enable reset_ack and async timer interrupt only while
+	stopping the pipeline.*/
+	msm_camera_io_w(0xf0000000,
+		vfe32_ctrl->vfebase + VFE_IRQ_MASK_0);
+	msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
+		vfe32_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(VFE_RESET_UPON_STOP_CMD,
+		vfe32_ctrl->vfebase + VFE_GLOBAL_RESET);
+}
+
 static int msm_axi_config(struct v4l2_subdev *sd, void __user *arg)
 {
 	struct msm_vfe_cfg_cmd cfgcmd;
 	struct msm_isp_cmd vfecmd;
 	int rc = 0;
 
-	if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
+	if (NULL != arg) {
+		if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
+			ERR_COPY_FROM_USER();
+			return -EFAULT;
+		}
 	}
-
-	if (copy_from_user(&vfecmd,
-			(void __user *)(cfgcmd.value),
-			sizeof(vfecmd))) {
-		pr_err("%s %d: copy_from_user failed\n", __func__,
-			__LINE__);
-		return -EFAULT;
+	if (NULL != cfgcmd.value) {
+		if (copy_from_user(&vfecmd,
+				(void __user *)(cfgcmd.value),
+				sizeof(vfecmd))) {
+			pr_err("%s %d: copy_from_user failed\n", __func__,
+				__LINE__);
+			return -EFAULT;
+		}
 	}
 
 	switch (cfgcmd.cmd_type) {
@@ -4117,6 +4126,12 @@
 		pr_err("%s Invalid/Unsupported AXI configuration %x",
 			__func__, cfgcmd.cmd_type);
 		break;
+	case CMD_AXI_START:
+		axi_start();
+		break;
+	case CMD_AXI_STOP:
+		axi_stop();
+		break;
 	default:
 		pr_err("%s Unsupported AXI configuration %x ", __func__,
 			cfgcmd.cmd_type);
diff --git a/drivers/media/video/msm/server/Makefile b/drivers/media/video/msm/server/Makefile
new file mode 100644
index 0000000..55abeed
--- /dev/null
+++ b/drivers/media/video/msm/server/Makefile
@@ -0,0 +1,11 @@
+GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
+
+ifeq ($(CONFIG_MSM_CAMERA_V4L2),y)
+  EXTRA_CFLAGS += -Idrivers/media/video/msm
+  EXTRA_CFLAGS += -Idrivers/media/video/msm/io
+  EXTRA_CFLAGS += -Idrivers/media/video/msm/csi
+  EXTRA_CFLAGS += -Idrivers/media/video/msm/eeprom
+  EXTRA_CFLAGS += -Idrivers/media/video/msm/sensors
+  EXTRA_CFLAGS += -Idrivers/media/video/msm/actuators
+  obj-$(CONFIG_MSM_CAMERA)   += msm_cam_server.o
+endif
diff --git a/drivers/media/video/msm/server/msm_cam_server.c b/drivers/media/video/msm/server/msm_cam_server.c
new file mode 100644
index 0000000..7154797f
--- /dev/null
+++ b/drivers/media/video/msm/server/msm_cam_server.c
@@ -0,0 +1,2318 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_cam_server.h"
+#include "msm_csid.h"
+#include "msm_csic.h"
+#include "msm_csiphy.h"
+#include "msm_ispif.h"
+#include "msm_sensor.h"
+#include "msm_actuator.h"
+#include "msm_vfe32.h"
+
+#ifdef CONFIG_MSM_CAMERA_DEBUG
+#define D(fmt, args...) pr_debug("msm: " fmt, ##args)
+#else
+#define D(fmt, args...) do {} while (0)
+#endif
+
+static struct msm_cam_server_dev g_server_dev;
+static struct class *msm_class;
+static dev_t msm_devno;
+
+static long msm_server_send_v4l2_evt(void *evt);
+static void msm_cam_server_subdev_notify(struct v4l2_subdev *sd,
+	unsigned int notification, void *arg);
+
+static void msm_queue_init(struct msm_device_queue *queue, const char *name)
+{
+	D("%s\n", __func__);
+	spin_lock_init(&queue->lock);
+	queue->len = 0;
+	queue->max = 0;
+	queue->name = name;
+	INIT_LIST_HEAD(&queue->list);
+	init_waitqueue_head(&queue->wait);
+}
+
+static void msm_enqueue(struct msm_device_queue *queue,
+			struct list_head *entry)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&queue->lock, flags);
+	queue->len++;
+	if (queue->len > queue->max) {
+		queue->max = queue->len;
+		pr_info("%s: queue %s new max is %d\n", __func__,
+			queue->name, queue->max);
+	}
+	list_add_tail(entry, &queue->list);
+	wake_up(&queue->wait);
+	D("%s: woke up %s\n", __func__, queue->name);
+	spin_unlock_irqrestore(&queue->lock, flags);
+}
+
+static void msm_drain_eventq(struct msm_device_queue *queue)
+{
+	unsigned long flags;
+	struct msm_queue_cmd *qcmd;
+	struct msm_isp_event_ctrl *isp_event;
+	spin_lock_irqsave(&queue->lock, flags);
+	while (!list_empty(&queue->list)) {
+		qcmd = list_first_entry(&queue->list,
+			struct msm_queue_cmd, list_eventdata);
+		list_del_init(&qcmd->list_eventdata);
+		isp_event =
+			(struct msm_isp_event_ctrl *)
+			qcmd->command;
+		if (isp_event->isp_data.ctrl.value != NULL)
+			kfree(isp_event->isp_data.ctrl.value);
+		kfree(qcmd->command);
+		free_qcmd(qcmd);
+	}
+	spin_unlock_irqrestore(&queue->lock, flags);
+}
+
+int32_t msm_find_free_queue(void)
+{
+	int i;
+	for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
+		struct msm_cam_server_queue *queue;
+		queue = &g_server_dev.server_queue[i];
+		if (!queue->queue_active)
+			return i;
+	}
+	return -EINVAL;
+}
+
+uint32_t msm_cam_server_get_mctl_handle(void)
+{
+	uint32_t i;
+	if ((g_server_dev.mctl_handle_cnt << 8) == 0)
+		g_server_dev.mctl_handle_cnt++;
+	for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
+		if (g_server_dev.mctl[i].handle == 0) {
+			g_server_dev.mctl[i].handle =
+				(++g_server_dev.mctl_handle_cnt) << 8 | i;
+			memset(&g_server_dev.mctl[i].mctl,
+				   0, sizeof(g_server_dev.mctl[i].mctl));
+			return g_server_dev.mctl[i].handle;
+		}
+	}
+	return 0;
+}
+
+void msm_cam_server_free_mctl(uint32_t handle)
+{
+	uint32_t mctl_index;
+	mctl_index = handle & 0xff;
+	if ((mctl_index < MAX_NUM_ACTIVE_CAMERA) &&
+		(g_server_dev.mctl[mctl_index].handle == handle))
+		g_server_dev.mctl[mctl_index].handle = 0;
+	else
+		pr_err("%s: invalid free handle\n", __func__);
+}
+
+struct msm_cam_media_controller *msm_cam_server_get_mctl(uint32_t handle)
+{
+	uint32_t mctl_index;
+	mctl_index = handle & 0xff;
+	if ((mctl_index < MAX_NUM_ACTIVE_CAMERA) &&
+		(g_server_dev.mctl[mctl_index].handle == handle))
+		return &g_server_dev.mctl[mctl_index].mctl;
+	return NULL;
+}
+
+static int msm_ctrl_cmd_done(void *arg)
+{
+	void __user *uptr;
+	struct msm_queue_cmd *qcmd;
+	struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
+	struct msm_ctrl_cmd *command;
+	D("%s\n", __func__);
+
+	command = kzalloc(sizeof(struct msm_ctrl_cmd), GFP_KERNEL);
+	if (!command) {
+		pr_err("%s Insufficient memory. return", __func__);
+		goto command_alloc_fail;
+	}
+
+	qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
+	if (!qcmd) {
+		pr_err("%s Insufficient memory. return", __func__);
+		goto qcmd_alloc_fail;
+	}
+
+	mutex_lock(&g_server_dev.server_queue_lock);
+
+	if (copy_from_user(command, (void __user *)ioctl_ptr->ioctl_ptr,
+					   sizeof(struct msm_ctrl_cmd))) {
+		pr_err("%s: copy_from_user failed, size=%d\n",
+			   __func__, sizeof(struct msm_ctrl_cmd));
+		goto ctrl_cmd_done_error;
+	}
+
+	if (!g_server_dev.server_queue[command->queue_idx].queue_active) {
+		pr_err("%s: Invalid queue\n", __func__);
+		goto ctrl_cmd_done_error;
+	}
+
+	D("%s qid %d evtid %d %d\n", __func__, command->queue_idx,
+		command->evt_id,
+		g_server_dev.server_queue[command->queue_idx].evt_id);
+
+	if (command->evt_id !=
+		g_server_dev.server_queue[command->queue_idx].evt_id) {
+		pr_err("Invalid event id from userspace\n");
+		goto ctrl_cmd_done_error;
+	}
+
+	atomic_set(&qcmd->on_heap, 1);
+	uptr = command->value;
+	qcmd->command = command;
+
+	if (command->length > 0) {
+		command->value =
+			g_server_dev.server_queue[command->queue_idx].ctrl_data;
+		if (command->length > max_control_command_size) {
+			pr_err("%s: user data %d is too big (max %d)\n",
+				__func__, command->length,
+				max_control_command_size);
+			goto ctrl_cmd_done_error;
+		}
+		if (copy_from_user(command->value, uptr, command->length)) {
+			pr_err("%s: copy_from_user failed, size=%d\n",
+				__func__, sizeof(struct msm_ctrl_cmd));
+			goto ctrl_cmd_done_error;
+		}
+	}
+	msm_enqueue(&g_server_dev.server_queue
+		[command->queue_idx].ctrl_q, &qcmd->list_control);
+	mutex_unlock(&g_server_dev.server_queue_lock);
+	return 0;
+
+ctrl_cmd_done_error:
+	mutex_unlock(&g_server_dev.server_queue_lock);
+	free_qcmd(qcmd);
+qcmd_alloc_fail:
+	kfree(command);
+command_alloc_fail:
+	return -EINVAL;
+}
+
+/* send control command to config and wait for results*/
+static int msm_server_control(struct msm_cam_server_dev *server_dev,
+				struct msm_ctrl_cmd *out)
+{
+	int rc = 0;
+	void *value;
+	struct msm_queue_cmd *rcmd;
+	struct msm_queue_cmd *event_qcmd;
+	struct msm_ctrl_cmd *ctrlcmd;
+	struct msm_device_queue *queue =
+		&server_dev->server_queue[out->queue_idx].ctrl_q;
+
+	struct v4l2_event v4l2_evt;
+	struct msm_isp_event_ctrl *isp_event;
+	void *ctrlcmd_data;
+
+	event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
+	if (!event_qcmd) {
+		pr_err("%s Insufficient memory. return", __func__);
+		rc = -ENOMEM;
+		goto event_qcmd_alloc_fail;
+	}
+
+	isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl), GFP_KERNEL);
+	if (!isp_event) {
+		pr_err("%s Insufficient memory. return", __func__);
+		rc = -ENOMEM;
+		goto isp_event_alloc_fail;
+	}
+
+	D("%s\n", __func__);
+	mutex_lock(&server_dev->server_queue_lock);
+	if (++server_dev->server_evt_id == 0)
+		server_dev->server_evt_id++;
+
+	D("%s qid %d evtid %d\n", __func__, out->queue_idx,
+		server_dev->server_evt_id);
+	server_dev->server_queue[out->queue_idx].evt_id =
+		server_dev->server_evt_id;
+	v4l2_evt.type = V4L2_EVENT_PRIVATE_START + MSM_CAM_RESP_V4L2;
+	v4l2_evt.u.data[0] = out->queue_idx;
+	/* setup event object to transfer the command; */
+	isp_event->resptype = MSM_CAM_RESP_V4L2;
+	isp_event->isp_data.ctrl = *out;
+	isp_event->isp_data.ctrl.evt_id = server_dev->server_evt_id;
+
+	if (out->value != NULL && out->length != 0) {
+		ctrlcmd_data = kzalloc(out->length, GFP_KERNEL);
+		if (!ctrlcmd_data) {
+			rc = -ENOMEM;
+			goto ctrlcmd_alloc_fail;
+		}
+		memcpy(ctrlcmd_data, out->value, out->length);
+		isp_event->isp_data.ctrl.value = ctrlcmd_data;
+	}
+
+	atomic_set(&event_qcmd->on_heap, 1);
+	event_qcmd->command = isp_event;
+
+	msm_enqueue(&server_dev->server_queue[out->queue_idx].eventData_q,
+				&event_qcmd->list_eventdata);
+
+	/* now send command to config thread in userspace,
+	 * and wait for results */
+	v4l2_event_queue(server_dev->server_command_queue.pvdev,
+					  &v4l2_evt);
+	D("%s v4l2_event_queue: type = 0x%x\n", __func__, v4l2_evt.type);
+	mutex_unlock(&server_dev->server_queue_lock);
+
+	/* wait for config return status */
+	D("Waiting for config status\n");
+	rc = wait_event_interruptible_timeout(queue->wait,
+		!list_empty_careful(&queue->list),
+		msecs_to_jiffies(out->timeout_ms));
+	D("Waiting is over for config status\n");
+	if (list_empty_careful(&queue->list)) {
+		if (!rc)
+			rc = -ETIMEDOUT;
+		if (rc < 0) {
+			if (++server_dev->server_evt_id == 0)
+				server_dev->server_evt_id++;
+			pr_err("%s: wait_event error %d\n", __func__, rc);
+			return rc;
+		}
+	}
+
+	rcmd = msm_dequeue(queue, list_control);
+	BUG_ON(!rcmd);
+	D("%s Finished servicing ioctl\n", __func__);
+
+	ctrlcmd = (struct msm_ctrl_cmd *)(rcmd->command);
+	value = out->value;
+	if (ctrlcmd->length > 0 && value != NULL &&
+		ctrlcmd->length <= out->length)
+		memcpy(value, ctrlcmd->value, ctrlcmd->length);
+
+	memcpy(out, ctrlcmd, sizeof(struct msm_ctrl_cmd));
+	out->value = value;
+
+	kfree(ctrlcmd);
+	free_qcmd(rcmd);
+	D("%s: rc %d\n", __func__, rc);
+	/* rc is the time elapsed. */
+	if (rc >= 0) {
+		/* TODO: Refactor msm_ctrl_cmd::status field */
+		if (out->status == 0)
+			rc = -1;
+		else if (out->status == 1 || out->status == 4)
+			rc = 0;
+		else
+			rc = -EINVAL;
+	}
+	return rc;
+
+ctrlcmd_alloc_fail:
+	kfree(isp_event);
+isp_event_alloc_fail:
+	kfree(event_qcmd);
+event_qcmd_alloc_fail:
+	return rc;
+}
+
+int msm_server_get_crop(struct msm_cam_v4l2_device *pcam,
+				int idx, struct v4l2_crop *crop)
+{
+	int rc = 0;
+	struct msm_ctrl_cmd ctrlcmd;
+
+	BUG_ON(crop == NULL);
+
+	ctrlcmd.type = MSM_V4L2_GET_CROP;
+	ctrlcmd.length = sizeof(struct v4l2_crop);
+	ctrlcmd.value = (void *)crop;
+	ctrlcmd.timeout_ms = 1000;
+	ctrlcmd.vnode_id = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+	ctrlcmd.stream_type = pcam->dev_inst[idx]->image_mode;
+	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+	/* send command to config thread in userspace, and get return value */
+	rc = msm_server_control(&g_server_dev, &ctrlcmd);
+	D("%s: rc = %d\n", __func__, rc);
+
+	return rc;
+}
+
+/*send open command to server*/
+int msm_send_open_server(struct msm_cam_v4l2_device *pcam)
+{
+	int rc = 0;
+	struct msm_ctrl_cmd ctrlcmd;
+	D("%s qid %d\n", __func__, pcam->server_queue_idx);
+	ctrlcmd.type	   = MSM_V4L2_OPEN;
+	ctrlcmd.timeout_ms = 10000;
+	ctrlcmd.length	 = strnlen(g_server_dev.config_info.config_dev_name[0],
+				MAX_DEV_NAME_LEN)+1;
+	ctrlcmd.value    = (char *)g_server_dev.config_info.config_dev_name[0];
+	ctrlcmd.vnode_id = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+	/* send command to config thread in usersspace, and get return value */
+	rc = msm_server_control(&g_server_dev, &ctrlcmd);
+
+	return rc;
+}
+
+int msm_send_close_server(struct msm_cam_v4l2_device *pcam)
+{
+	int rc = 0;
+	struct msm_ctrl_cmd ctrlcmd;
+	D("%s qid %d\n", __func__, pcam->server_queue_idx);
+	ctrlcmd.type	   = MSM_V4L2_CLOSE;
+	ctrlcmd.timeout_ms = 10000;
+	ctrlcmd.length	 = strnlen(g_server_dev.config_info.config_dev_name[0],
+				MAX_DEV_NAME_LEN)+1;
+	ctrlcmd.value    = (char *)g_server_dev.config_info.config_dev_name[0];
+	ctrlcmd.vnode_id = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+	/* send command to config thread in usersspace, and get return value */
+	rc = msm_server_control(&g_server_dev, &ctrlcmd);
+
+	return rc;
+}
+
+int msm_server_set_fmt(struct msm_cam_v4l2_device *pcam, int idx,
+				 struct v4l2_format *pfmt)
+{
+	int rc = 0;
+	int i = 0;
+	struct v4l2_pix_format *pix = &pfmt->fmt.pix;
+	struct msm_ctrl_cmd ctrlcmd;
+	struct img_plane_info plane_info;
+
+	plane_info.width = pix->width;
+	plane_info.height = pix->height;
+	plane_info.pixelformat = pix->pixelformat;
+	plane_info.buffer_type = pfmt->type;
+	plane_info.ext_mode = pcam->dev_inst[idx]->image_mode;
+	plane_info.num_planes = 1;
+	D("%s: %d, %d, 0x%x\n", __func__,
+		pfmt->fmt.pix.width, pfmt->fmt.pix.height,
+		pfmt->fmt.pix.pixelformat);
+
+	if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		D("%s, Attention! Wrong buf-type %d\n", __func__, pfmt->type);
+
+	for (i = 0; i < pcam->num_fmts; i++)
+		if (pcam->usr_fmts[i].fourcc == pix->pixelformat)
+			break;
+	if (i == pcam->num_fmts) {
+		pr_err("%s: User requested pixelformat %x not supported\n",
+						__func__, pix->pixelformat);
+		return -EINVAL;
+	}
+
+	ctrlcmd.type       = MSM_V4L2_VID_CAP_TYPE;
+	ctrlcmd.length     = sizeof(struct img_plane_info);
+	ctrlcmd.value      = (void *)&plane_info;
+	ctrlcmd.timeout_ms = 10000;
+	ctrlcmd.vnode_id   = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+	/* send command to config thread in usersspace, and get return value */
+	rc = msm_server_control(&g_server_dev, &ctrlcmd);
+
+	if (rc >= 0) {
+		pcam->dev_inst[idx]->vid_fmt = *pfmt;
+		pcam->dev_inst[idx]->sensor_pxlcode
+					= pcam->usr_fmts[i].pxlcode;
+		D("%s:inst=0x%x,idx=%d,width=%d,heigth=%d\n",
+			 __func__, (u32)pcam->dev_inst[idx], idx,
+			 pcam->dev_inst[idx]->vid_fmt.fmt.pix.width,
+			 pcam->dev_inst[idx]->vid_fmt.fmt.pix.height);
+		pcam->dev_inst[idx]->plane_info = plane_info;
+	}
+
+	return rc;
+}
+
+int msm_server_set_fmt_mplane(struct msm_cam_v4l2_device *pcam, int idx,
+				 struct v4l2_format *pfmt)
+{
+	int rc = 0;
+	int i = 0;
+	struct v4l2_pix_format_mplane *pix_mp = &pfmt->fmt.pix_mp;
+	struct msm_ctrl_cmd ctrlcmd;
+	struct img_plane_info plane_info;
+
+	plane_info.width = pix_mp->width;
+	plane_info.height = pix_mp->height;
+	plane_info.pixelformat = pix_mp->pixelformat;
+	plane_info.buffer_type = pfmt->type;
+	plane_info.ext_mode = pcam->dev_inst[idx]->image_mode;
+	plane_info.num_planes = pix_mp->num_planes;
+	if (plane_info.num_planes <= 0 ||
+		plane_info.num_planes > VIDEO_MAX_PLANES) {
+		pr_err("%s Invalid number of planes set %d", __func__,
+				plane_info.num_planes);
+		return -EINVAL;
+	}
+	D("%s: %d, %d, 0x%x\n", __func__,
+		pfmt->fmt.pix_mp.width, pfmt->fmt.pix_mp.height,
+		pfmt->fmt.pix_mp.pixelformat);
+
+	if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		pr_err("%s, Attention! Wrong buf-type %d\n",
+			__func__, pfmt->type);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < pcam->num_fmts; i++)
+		if (pcam->usr_fmts[i].fourcc == pix_mp->pixelformat)
+			break;
+	if (i == pcam->num_fmts) {
+		pr_err("%s: User requested pixelformat %x not supported\n",
+						__func__, pix_mp->pixelformat);
+		return -EINVAL;
+	}
+
+	ctrlcmd.type       = MSM_V4L2_VID_CAP_TYPE;
+	ctrlcmd.length     = sizeof(struct img_plane_info);
+	ctrlcmd.value      = (void *)&plane_info;
+	ctrlcmd.timeout_ms = 10000;
+	ctrlcmd.vnode_id   = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+
+	/* send command to config thread in usersspace, and get return value */
+	rc = msm_server_control(&g_server_dev, &ctrlcmd);
+	if (rc >= 0) {
+		pcam->dev_inst[idx]->vid_fmt = *pfmt;
+		pcam->dev_inst[idx]->sensor_pxlcode
+					= pcam->usr_fmts[i].pxlcode;
+		D("%s:inst=0x%x,idx=%d,width=%d,heigth=%d\n",
+			 __func__, (u32)pcam->dev_inst[idx], idx,
+			 pcam->dev_inst[idx]->vid_fmt.fmt.pix_mp.width,
+			 pcam->dev_inst[idx]->vid_fmt.fmt.pix_mp.height);
+		pcam->dev_inst[idx]->plane_info = plane_info;
+	}
+
+	return rc;
+}
+
+int msm_server_streamon(struct msm_cam_v4l2_device *pcam, int idx)
+{
+	int rc = 0;
+	struct msm_ctrl_cmd ctrlcmd;
+	D("%s\n", __func__);
+	ctrlcmd.type	   = MSM_V4L2_STREAM_ON;
+	ctrlcmd.timeout_ms = 10000;
+	ctrlcmd.length	 = 0;
+	ctrlcmd.value    = NULL;
+	ctrlcmd.stream_type = pcam->dev_inst[idx]->image_mode;
+	ctrlcmd.vnode_id = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+
+	/* send command to config thread in usersspace, and get return value */
+	rc = msm_server_control(&g_server_dev, &ctrlcmd);
+
+	return rc;
+}
+
+int msm_server_streamoff(struct msm_cam_v4l2_device *pcam, int idx)
+{
+	int rc = 0;
+	struct msm_ctrl_cmd ctrlcmd;
+
+	D("%s, pcam = 0x%x\n", __func__, (u32)pcam);
+	ctrlcmd.type        = MSM_V4L2_STREAM_OFF;
+	ctrlcmd.timeout_ms  = 10000;
+	ctrlcmd.length      = 0;
+	ctrlcmd.value       = NULL;
+	ctrlcmd.stream_type = pcam->dev_inst[idx]->image_mode;
+	ctrlcmd.vnode_id = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+	/* send command to config thread in usersspace, and get return value */
+	rc = msm_server_control(&g_server_dev, &ctrlcmd);
+
+	return rc;
+}
+
+int msm_server_proc_ctrl_cmd(struct msm_cam_v4l2_device *pcam,
+				 struct v4l2_control *ctrl, int is_set_cmd)
+{
+	int rc = 0;
+	struct msm_ctrl_cmd ctrlcmd, *tmp_cmd;
+	uint8_t *ctrl_data = NULL;
+	void __user *uptr_cmd;
+	void __user *uptr_value;
+	uint32_t cmd_len = sizeof(struct msm_ctrl_cmd);
+	uint32_t value_len;
+
+	tmp_cmd = (struct msm_ctrl_cmd *)ctrl->value;
+	uptr_cmd = (void __user *)ctrl->value;
+	uptr_value = (void __user *)tmp_cmd->value;
+	value_len = tmp_cmd->length;
+
+	D("%s: cmd type = %d, up1=0x%x, ulen1=%d, up2=0x%x, ulen2=%d\n",
+		__func__, tmp_cmd->type, (uint32_t)uptr_cmd, cmd_len,
+		(uint32_t)uptr_value, tmp_cmd->length);
+
+	ctrl_data = kzalloc(value_len+cmd_len, GFP_KERNEL);
+	if (ctrl_data == 0) {
+		pr_err("%s could not allocate memory\n", __func__);
+		rc = -ENOMEM;
+		goto end;
+	}
+	tmp_cmd = (struct msm_ctrl_cmd *)ctrl_data;
+	if (copy_from_user((void *)ctrl_data, uptr_cmd,
+					cmd_len)) {
+		pr_err("%s: copy_from_user failed.\n", __func__);
+		rc = -EINVAL;
+		goto end;
+	}
+	tmp_cmd->value = (void *)(ctrl_data+cmd_len);
+	if (uptr_value && tmp_cmd->length > 0) {
+		if (copy_from_user((void *)tmp_cmd->value, uptr_value,
+						value_len)) {
+			pr_err("%s: copy_from_user failed, size=%d\n",
+				__func__, value_len);
+			rc = -EINVAL;
+			goto end;
+		}
+	} else
+	tmp_cmd->value = NULL;
+
+	ctrlcmd.type = MSM_V4L2_SET_CTRL_CMD;
+	ctrlcmd.length = cmd_len + value_len;
+	ctrlcmd.value = (void *)ctrl_data;
+	if (tmp_cmd->timeout_ms > 0)
+		ctrlcmd.timeout_ms = tmp_cmd->timeout_ms;
+	else
+		ctrlcmd.timeout_ms = 1000;
+	ctrlcmd.vnode_id = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+	/* send command to config thread in usersspace, and get return value */
+	rc = msm_server_control(&g_server_dev, &ctrlcmd);
+	D("%s: msm_server_control rc=%d\n", __func__, rc);
+	if (rc == 0) {
+		if (uptr_value && tmp_cmd->length > 0 &&
+			copy_to_user((void __user *)uptr_value,
+				(void *)(ctrl_data+cmd_len), tmp_cmd->length)) {
+			pr_err("%s: copy_to_user failed, size=%d\n",
+				__func__, tmp_cmd->length);
+			rc = -EINVAL;
+			goto end;
+		}
+		tmp_cmd->value = uptr_value;
+		if (copy_to_user((void __user *)uptr_cmd,
+			(void *)tmp_cmd, cmd_len)) {
+			pr_err("%s: copy_to_user failed in cpy, size=%d\n",
+				__func__, cmd_len);
+			rc = -EINVAL;
+			goto end;
+		}
+	}
+end:
+	D("%s: END, type = %d, vaddr = 0x%x, vlen = %d, status = %d, rc = %d\n",
+		__func__, tmp_cmd->type, (uint32_t)tmp_cmd->value,
+		tmp_cmd->length, tmp_cmd->status, rc);
+	kfree(ctrl_data);
+	return rc;
+}
+
+int msm_server_s_ctrl(struct msm_cam_v4l2_device *pcam,
+				 struct v4l2_control *ctrl)
+{
+	int rc = 0;
+	struct msm_ctrl_cmd ctrlcmd;
+	uint8_t ctrl_data[max_control_command_size];
+
+	WARN_ON(ctrl == NULL);
+	if (ctrl == NULL) {
+		pr_err("%s Invalid control\n", __func__);
+		return -EINVAL;
+	}
+	if (ctrl->id == MSM_V4L2_PID_CTRL_CMD)
+		return msm_server_proc_ctrl_cmd(pcam, ctrl, 1);
+
+	memset(ctrl_data, 0, sizeof(ctrl_data));
+
+	ctrlcmd.type = MSM_V4L2_SET_CTRL;
+	ctrlcmd.length = sizeof(struct v4l2_control);
+	ctrlcmd.value = (void *)ctrl_data;
+	memcpy(ctrlcmd.value, ctrl, ctrlcmd.length);
+	ctrlcmd.timeout_ms = 1000;
+	ctrlcmd.vnode_id = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+	/* send command to config thread in usersspace, and get return value */
+	rc = msm_server_control(&g_server_dev, &ctrlcmd);
+
+	return rc;
+}
+
+int msm_server_g_ctrl(struct msm_cam_v4l2_device *pcam,
+				 struct v4l2_control *ctrl)
+{
+	int rc = 0;
+	struct msm_ctrl_cmd ctrlcmd;
+	uint8_t ctrl_data[max_control_command_size];
+
+	WARN_ON(ctrl == NULL);
+	if (ctrl == NULL) {
+		pr_err("%s Invalid control\n", __func__);
+		return -EINVAL;
+	}
+	if (ctrl->id == MSM_V4L2_PID_CTRL_CMD)
+		return msm_server_proc_ctrl_cmd(pcam, ctrl, 0);
+
+	memset(ctrl_data, 0, sizeof(ctrl_data));
+
+	ctrlcmd.type = MSM_V4L2_GET_CTRL;
+	ctrlcmd.length = sizeof(struct v4l2_control);
+	ctrlcmd.value = (void *)ctrl_data;
+	memcpy(ctrlcmd.value, ctrl, ctrlcmd.length);
+	ctrlcmd.timeout_ms = 1000;
+	ctrlcmd.vnode_id = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+	/* send command to config thread in usersspace, and get return value */
+	rc = msm_server_control(&g_server_dev, &ctrlcmd);
+
+	ctrl->value = ((struct v4l2_control *)ctrlcmd.value)->value;
+
+	return rc;
+}
+
+int msm_server_q_ctrl(struct msm_cam_v4l2_device *pcam,
+			struct v4l2_queryctrl *queryctrl)
+{
+	int rc = 0;
+	struct msm_ctrl_cmd ctrlcmd;
+	uint8_t ctrl_data[max_control_command_size];
+
+	WARN_ON(queryctrl == NULL);
+	memset(ctrl_data, 0, sizeof(ctrl_data));
+
+	ctrlcmd.type = MSM_V4L2_QUERY_CTRL;
+	ctrlcmd.length = sizeof(struct v4l2_queryctrl);
+	ctrlcmd.value = (void *)ctrl_data;
+	memcpy(ctrlcmd.value, queryctrl, ctrlcmd.length);
+	ctrlcmd.timeout_ms = 1000;
+	ctrlcmd.vnode_id = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+	/* send command to config thread in userspace, and get return value */
+	rc = msm_server_control(&g_server_dev, &ctrlcmd);
+	D("%s: rc = %d\n", __func__, rc);
+
+	if (rc >= 0)
+		memcpy(queryctrl, ctrlcmd.value, sizeof(struct v4l2_queryctrl));
+
+	return rc;
+}
+
+int msm_server_get_fmt(struct msm_cam_v4l2_device *pcam,
+		 int idx, struct v4l2_format *pfmt)
+{
+	struct v4l2_pix_format *pix = &pfmt->fmt.pix;
+
+	pix->width        = pcam->dev_inst[idx]->vid_fmt.fmt.pix.width;
+	pix->height       = pcam->dev_inst[idx]->vid_fmt.fmt.pix.height;
+	pix->field        = pcam->dev_inst[idx]->vid_fmt.fmt.pix.field;
+	pix->pixelformat  = pcam->dev_inst[idx]->vid_fmt.fmt.pix.pixelformat;
+	pix->bytesperline = pcam->dev_inst[idx]->vid_fmt.fmt.pix.bytesperline;
+	pix->colorspace   = pcam->dev_inst[idx]->vid_fmt.fmt.pix.colorspace;
+	if (pix->bytesperline < 0)
+		return pix->bytesperline;
+
+	pix->sizeimage    = pix->height * pix->bytesperline;
+
+	return 0;
+}
+
+int msm_server_get_fmt_mplane(struct msm_cam_v4l2_device *pcam,
+		 int idx, struct v4l2_format *pfmt)
+{
+	*pfmt = pcam->dev_inst[idx]->vid_fmt;
+	return 0;
+}
+
+int msm_server_try_fmt(struct msm_cam_v4l2_device *pcam,
+				 struct v4l2_format *pfmt)
+{
+	int rc = 0;
+	int i = 0;
+	struct v4l2_pix_format *pix = &pfmt->fmt.pix;
+
+	D("%s: 0x%x\n", __func__, pix->pixelformat);
+	if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		pr_err("%s: pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE!\n",
+							__func__);
+		return -EINVAL;
+	}
+
+	/* check if the format is supported by this host-sensor combo */
+	for (i = 0; i < pcam->num_fmts; i++) {
+		D("%s: usr_fmts.fourcc: 0x%x\n", __func__,
+			pcam->usr_fmts[i].fourcc);
+		if (pcam->usr_fmts[i].fourcc == pix->pixelformat)
+			break;
+	}
+
+	if (i == pcam->num_fmts) {
+		pr_err("%s: Format %x not found\n", __func__, pix->pixelformat);
+		return -EINVAL;
+	}
+	return rc;
+}
+
+int msm_server_try_fmt_mplane(struct msm_cam_v4l2_device *pcam,
+				 struct v4l2_format *pfmt)
+{
+	int rc = 0;
+	int i = 0;
+	struct v4l2_pix_format_mplane *pix_mp = &pfmt->fmt.pix_mp;
+
+	D("%s: 0x%x\n", __func__, pix_mp->pixelformat);
+	if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		pr_err("%s: Incorrect format type %d ",
+			__func__, pfmt->type);
+		return -EINVAL;
+	}
+
+	/* check if the format is supported by this host-sensor combo */
+	for (i = 0; i < pcam->num_fmts; i++) {
+		D("%s: usr_fmts.fourcc: 0x%x\n", __func__,
+			pcam->usr_fmts[i].fourcc);
+		if (pcam->usr_fmts[i].fourcc == pix_mp->pixelformat)
+			break;
+	}
+
+	if (i == pcam->num_fmts) {
+		pr_err("%s: Format %x not found\n",
+			__func__, pix_mp->pixelformat);
+		return -EINVAL;
+	}
+	return rc;
+}
+
+int msm_server_v4l2_subscribe_event(struct v4l2_fh *fh,
+			struct v4l2_event_subscription *sub)
+{
+	int rc = 0;
+
+	D("%s: fh = 0x%x, type = 0x%x", __func__, (u32)fh, sub->type);
+	if (sub->type == V4L2_EVENT_ALL) {
+		/*sub->type = MSM_ISP_EVENT_START;*/
+		sub->type = V4L2_EVENT_PRIVATE_START + MSM_CAM_RESP_CTRL;
+		D("sub->type start = 0x%x\n", sub->type);
+		do {
+			rc = v4l2_event_subscribe(fh, sub);
+			if (rc < 0) {
+				D("%s: failed for evtType = 0x%x, rc = %d\n",
+						__func__, sub->type, rc);
+			/* unsubscribe all events here and return */
+			sub->type = V4L2_EVENT_ALL;
+			v4l2_event_unsubscribe(fh, sub);
+			return rc;
+			} else
+				D("%s: subscribed evtType = 0x%x, rc = %d\n",
+						__func__, sub->type, rc);
+			sub->type++;
+			D("sub->type while = 0x%x\n", sub->type);
+		} while (sub->type !=
+			V4L2_EVENT_PRIVATE_START + MSM_SVR_RESP_MAX);
+	} else {
+		D("sub->type not V4L2_EVENT_ALL = 0x%x\n", sub->type);
+		rc = v4l2_event_subscribe(fh, sub);
+		if (rc < 0)
+			D("%s: failed for evtType = 0x%x, rc = %d\n",
+						__func__, sub->type, rc);
+	}
+
+	D("%s: rc = %d\n", __func__, rc);
+	return rc;
+}
+
+int msm_server_v4l2_unsubscribe_event(struct v4l2_fh *fh,
+			struct v4l2_event_subscription *sub)
+{
+	int rc = 0;
+
+	D("%s: fh = 0x%x\n", __func__, (u32)fh);
+	rc = v4l2_event_unsubscribe(fh, sub);
+	D("%s: rc = %d\n", __func__, rc);
+	return rc;
+}
+
+/* open an active camera session to manage the streaming logic */
+static int msm_cam_server_open_session(struct msm_cam_server_dev *ps,
+	struct msm_cam_v4l2_device *pcam)
+{
+	int rc = 0;
+	struct msm_cam_media_controller *pmctl;
+
+	D("%s\n", __func__);
+
+	if (!ps || !pcam) {
+		pr_err("%s NULL pointer passed in!\n", __func__);
+		return rc;
+	}
+
+	/* The number of camera instance should be controlled by the
+		resource manager. Currently supporting one active instance
+		until multiple instances are supported */
+	if (atomic_read(&ps->number_pcam_active) > 0) {
+		pr_err("%s Cannot have more than one active camera %d\n",
+			__func__, atomic_read(&ps->number_pcam_active));
+		return -EINVAL;
+	}
+	/* book keeping this camera session*/
+	ps->pcam_active = pcam;
+	atomic_inc(&ps->number_pcam_active);
+
+	D("config pcam = 0x%p\n", ps->pcam_active);
+
+	/* 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);
+	pmctl->axi_sdev = ps->axi_device[0];
+	pmctl->isp_sdev = ps->isp_subdev[0];
+	return rc;
+}
+
+/* close an active camera session to server */
+static int msm_cam_server_close_session(struct msm_cam_server_dev *ps,
+	struct msm_cam_v4l2_device *pcam)
+{
+	int rc = 0;
+	D("%s\n", __func__);
+
+	if (!ps || !pcam) {
+		D("%s NULL pointer passed in!\n", __func__);
+		return rc;
+	}
+
+
+	atomic_dec(&ps->number_pcam_active);
+	ps->pcam_active = NULL;
+
+	msm_mctl_free(pcam);
+	return rc;
+}
+
+static long msm_ioctl_server(struct file *file, void *fh,
+		bool valid_prio, int cmd, void *arg)
+{
+	int rc = -EINVAL;
+	struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
+	struct msm_camera_info temp_cam_info;
+	struct msm_cam_config_dev_info temp_config_info;
+	struct msm_mctl_node_info temp_mctl_info;
+	int i;
+
+	D("%s: cmd %d\n", __func__, _IOC_NR(cmd));
+
+	switch (cmd) {
+	case MSM_CAM_V4L2_IOCTL_GET_CAMERA_INFO:
+		if (copy_from_user(&temp_cam_info,
+				(void __user *)ioctl_ptr->ioctl_ptr,
+				sizeof(struct msm_camera_info))) {
+			pr_err("%s Copy from user failed for cmd %d",
+				__func__, cmd);
+			rc = -EINVAL;
+			return rc;
+		}
+		for (i = 0; i < g_server_dev.camera_info.num_cameras; i++) {
+			if (copy_to_user((void __user *)
+			temp_cam_info.video_dev_name[i],
+			g_server_dev.camera_info.video_dev_name[i],
+			strnlen(g_server_dev.camera_info.video_dev_name[i],
+				MAX_DEV_NAME_LEN))) {
+				pr_err("%s Copy to user failed for cmd %d",
+					__func__, cmd);
+				rc = -EINVAL;
+				return rc;
+			}
+			temp_cam_info.has_3d_support[i] =
+				g_server_dev.camera_info.has_3d_support[i];
+			temp_cam_info.is_internal_cam[i] =
+				g_server_dev.camera_info.is_internal_cam[i];
+			temp_cam_info.s_mount_angle[i] =
+				g_server_dev.camera_info.s_mount_angle[i];
+			temp_cam_info.sensor_type[i] =
+				g_server_dev.camera_info.sensor_type[i];
+
+		}
+		temp_cam_info.num_cameras =
+			g_server_dev.camera_info.num_cameras;
+		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
+			&temp_cam_info,	sizeof(struct msm_camera_info))) {
+			pr_err("%s Copy to user failed for cmd %d",
+				__func__, cmd);
+			rc = -EINVAL;
+			return rc;
+		}
+		rc = 0;
+		break;
+
+	case MSM_CAM_V4L2_IOCTL_GET_CONFIG_INFO:
+		if (copy_from_user(&temp_config_info,
+			(void __user *)ioctl_ptr->ioctl_ptr,
+			sizeof(struct msm_cam_config_dev_info))) {
+			pr_err("%s Copy from user failed for cmd %d",
+				__func__, cmd);
+			rc = -EINVAL;
+			return rc;
+		}
+		for (i = 0;
+		 i < g_server_dev.config_info.num_config_nodes; i++) {
+			if (copy_to_user(
+			(void __user *)temp_config_info.config_dev_name[i],
+			g_server_dev.config_info.config_dev_name[i],
+			strnlen(g_server_dev.config_info.config_dev_name[i],
+				MAX_DEV_NAME_LEN))) {
+				pr_err("%s Copy to user failed for cmd %d",
+					__func__, cmd);
+				rc = -EINVAL;
+				return rc;
+			}
+		}
+		temp_config_info.num_config_nodes =
+			g_server_dev.config_info.num_config_nodes;
+		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
+			&temp_config_info,
+			sizeof(struct msm_cam_config_dev_info))) {
+			pr_err("%s Copy to user failed for cmd %d",
+				__func__, cmd);
+			rc = -EINVAL;
+			return rc;
+		}
+		rc = 0;
+		break;
+	case MSM_CAM_V4L2_IOCTL_GET_MCTL_INFO:
+		if (copy_from_user(&temp_mctl_info,
+				(void __user *)ioctl_ptr->ioctl_ptr,
+				sizeof(struct msm_mctl_node_info))) {
+			pr_err("%s Copy from user failed for cmd %d",
+				__func__, cmd);
+			rc = -EINVAL;
+			return rc;
+		}
+		for (i = 0; i < g_server_dev.mctl_node_info.num_mctl_nodes;
+				i++) {
+			if (copy_to_user((void __user *)
+			temp_mctl_info.mctl_node_name[i],
+			g_server_dev.mctl_node_info.mctl_node_name[i], strnlen(
+			g_server_dev.mctl_node_info.mctl_node_name[i],
+			MAX_DEV_NAME_LEN))) {
+				pr_err("%s Copy to user failed for cmd %d",
+					__func__, cmd);
+				rc = -EINVAL;
+				return rc;
+			}
+		}
+		temp_mctl_info.num_mctl_nodes =
+			g_server_dev.mctl_node_info.num_mctl_nodes;
+		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
+			&temp_mctl_info, sizeof(struct msm_mctl_node_info))) {
+			pr_err("%s Copy to user failed for cmd %d",
+				__func__, cmd);
+			rc = -EINVAL;
+			return rc;
+		}
+		rc = 0;
+	break;
+
+	case MSM_CAM_V4L2_IOCTL_CTRL_CMD_DONE:
+		D("%s: MSM_CAM_IOCTL_CTRL_CMD_DONE\n", __func__);
+		rc = msm_ctrl_cmd_done(arg);
+		break;
+
+	case MSM_CAM_V4L2_IOCTL_GET_EVENT_PAYLOAD: {
+		struct msm_queue_cmd *event_cmd;
+		struct msm_isp_event_ctrl u_isp_event;
+		struct msm_isp_event_ctrl *k_isp_event;
+		struct msm_device_queue *queue;
+		void __user *u_ctrl_value = NULL;
+		if (copy_from_user(&u_isp_event,
+			(void __user *)ioctl_ptr->ioctl_ptr,
+			sizeof(struct msm_isp_event_ctrl))) {
+			pr_err("%s Copy from user failed for cmd %d",
+				__func__, cmd);
+			rc = -EINVAL;
+			return rc;
+		}
+
+		mutex_lock(&g_server_dev.server_queue_lock);
+		if (!g_server_dev.server_queue
+			[u_isp_event.isp_data.ctrl.queue_idx].queue_active) {
+			pr_err("%s: Invalid queue\n", __func__);
+			mutex_unlock(&g_server_dev.server_queue_lock);
+			rc = -EINVAL;
+			return rc;
+		}
+		queue = &g_server_dev.server_queue
+			[u_isp_event.isp_data.ctrl.queue_idx].eventData_q;
+		event_cmd = msm_dequeue(queue, list_eventdata);
+		if (!event_cmd) {
+			pr_err("%s: No event payload\n", __func__);
+			rc = -EINVAL;
+			mutex_unlock(&g_server_dev.server_queue_lock);
+			return rc;
+		}
+		k_isp_event = (struct msm_isp_event_ctrl *)
+				event_cmd->command;
+		free_qcmd(event_cmd);
+
+		/* Save the pointer of the user allocated command buffer*/
+		u_ctrl_value = u_isp_event.isp_data.ctrl.value;
+
+		/* Copy the event structure into user struct*/
+		u_isp_event = *k_isp_event;
+
+		/* Restore the saved pointer of the user
+		 * allocated command buffer. */
+		u_isp_event.isp_data.ctrl.value = u_ctrl_value;
+
+		/* Copy the ctrl cmd, if present*/
+		if (k_isp_event->isp_data.ctrl.length > 0 &&
+			k_isp_event->isp_data.ctrl.value != NULL) {
+			void *k_ctrl_value =
+				k_isp_event->isp_data.ctrl.value;
+			if (copy_to_user(u_ctrl_value, k_ctrl_value,
+				 k_isp_event->isp_data.ctrl.length)) {
+				pr_err("%s Copy to user failed for cmd %d",
+					__func__, cmd);
+				kfree(k_isp_event->isp_data.ctrl.value);
+				kfree(k_isp_event);
+				rc = -EINVAL;
+				mutex_unlock(&g_server_dev.server_queue_lock);
+				break;
+			}
+			kfree(k_isp_event->isp_data.ctrl.value);
+		}
+		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
+			&u_isp_event, sizeof(struct msm_isp_event_ctrl))) {
+			pr_err("%s Copy to user failed for cmd %d",
+				__func__, cmd);
+			kfree(k_isp_event);
+			mutex_unlock(&g_server_dev.server_queue_lock);
+			rc = -EINVAL;
+			return rc;
+		}
+		kfree(k_isp_event);
+		mutex_unlock(&g_server_dev.server_queue_lock);
+		rc = 0;
+		break;
+	}
+
+	case MSM_CAM_IOCTL_SEND_EVENT:
+		rc = msm_server_send_v4l2_evt(arg);
+		break;
+
+	default:
+		pr_err("%s: Invalid IOCTL = %d", __func__, cmd);
+		break;
+	}
+	return rc;
+}
+
+static int msm_open_server(struct file *fp)
+{
+	int rc = 0;
+	D("%s: open %s\n", __func__, fp->f_path.dentry->d_name.name);
+	mutex_lock(&g_server_dev.server_lock);
+	g_server_dev.use_count++;
+	if (g_server_dev.use_count == 1)
+		fp->private_data =
+			&g_server_dev.server_command_queue.eventHandle;
+	mutex_unlock(&g_server_dev.server_lock);
+	return rc;
+}
+
+static int msm_close_server(struct file *fp)
+{
+	struct v4l2_event_subscription sub;
+	D("%s\n", __func__);
+	mutex_lock(&g_server_dev.server_lock);
+	if (g_server_dev.use_count > 0)
+		g_server_dev.use_count--;
+	mutex_unlock(&g_server_dev.server_lock);
+
+	if (g_server_dev.use_count == 0) {
+		mutex_lock(&g_server_dev.server_lock);
+		if (g_server_dev.pcam_active) {
+			struct v4l2_event v4l2_ev;
+			struct msm_cam_media_controller *pmctl = NULL;
+			int rc;
+
+			pmctl = msm_cam_server_get_mctl(
+				g_server_dev.pcam_active->mctl_handle);
+			if (pmctl && pmctl->mctl_release) {
+				rc = pmctl->mctl_release(pmctl);
+				if (rc < 0)
+					pr_err("mctl_release fails %d\n", rc);
+				/*so that it isn't closed again*/
+				pmctl->mctl_release = NULL;
+			}
+
+			v4l2_ev.type = V4L2_EVENT_PRIVATE_START
+				+ MSM_CAM_APP_NOTIFY_ERROR_EVENT;
+			ktime_get_ts(&v4l2_ev.timestamp);
+			v4l2_event_queue(
+				g_server_dev.pcam_active->pvdev, &v4l2_ev);
+		}
+		sub.type = V4L2_EVENT_ALL;
+		msm_server_v4l2_unsubscribe_event(
+			&g_server_dev.server_command_queue.eventHandle, &sub);
+		mutex_unlock(&g_server_dev.server_lock);
+	}
+	return 0;
+}
+
+static unsigned int msm_poll_server(struct file *fp,
+					struct poll_table_struct *wait)
+{
+	int rc = 0;
+
+	D("%s\n", __func__);
+	poll_wait(fp,
+		 &g_server_dev.server_command_queue.eventHandle.events->wait,
+		 wait);
+	if (v4l2_event_pending(&g_server_dev.server_command_queue.eventHandle))
+		rc |= POLLPRI;
+
+	return rc;
+}
+
+int msm_server_get_usecount(void)
+{
+	return g_server_dev.use_count;
+}
+
+int msm_server_update_sensor_info(struct msm_cam_v4l2_device *pcam,
+	struct msm_camera_sensor_info *sdata)
+{
+	int rc = 0;
+
+	if (!pcam || !sdata) {
+		pr_err("%s Input data is null ", __func__);
+		return -EINVAL;
+	}
+
+	g_server_dev.camera_info.video_dev_name
+	[g_server_dev.camera_info.num_cameras]
+	= video_device_node_name(pcam->pvdev);
+	D("%s Connected video device %s\n", __func__,
+		g_server_dev.camera_info.video_dev_name
+		[g_server_dev.camera_info.num_cameras]);
+
+	g_server_dev.camera_info.s_mount_angle
+	[g_server_dev.camera_info.num_cameras]
+	= sdata->sensor_platform_info->mount_angle;
+
+	g_server_dev.camera_info.is_internal_cam
+	[g_server_dev.camera_info.num_cameras]
+	= sdata->camera_type;
+
+	g_server_dev.mctl_node_info.mctl_node_name
+	[g_server_dev.mctl_node_info.num_mctl_nodes]
+	= video_device_node_name(pcam->mctl_node.pvdev);
+
+	pr_info("%s mctl_node_name[%d] = %s\n", __func__,
+		g_server_dev.mctl_node_info.num_mctl_nodes,
+		g_server_dev.mctl_node_info.mctl_node_name
+		[g_server_dev.mctl_node_info.num_mctl_nodes]);
+
+	/*Temporary solution to store info in media device structure
+	  until we can expand media device structure to support more
+	  device info*/
+	snprintf(pcam->media_dev.serial,
+			sizeof(pcam->media_dev.serial),
+			"%s-%d-%d", QCAMERA_NAME,
+			sdata->sensor_platform_info->mount_angle,
+			sdata->camera_type);
+
+	g_server_dev.camera_info.num_cameras++;
+	g_server_dev.mctl_node_info.num_mctl_nodes++;
+
+	D("%s done, rc = %d\n", __func__, rc);
+	D("%s number of sensors connected is %d\n", __func__,
+		g_server_dev.camera_info.num_cameras);
+
+	return rc;
+}
+
+int msm_server_begin_session(struct msm_cam_v4l2_device *pcam,
+	int server_q_idx)
+{
+	int rc = -EINVAL, ges_evt;
+	struct msm_cam_server_queue *queue;
+
+	if (!pcam) {
+		pr_err("%s pcam passed is null ", __func__);
+		return rc;
+	}
+
+	ges_evt = MSM_V4L2_GES_CAM_OPEN;
+	D("%s send gesture evt\n", __func__);
+	msm_cam_server_subdev_notify(g_server_dev.gesture_device,
+		NOTIFY_GESTURE_CAM_EVT, &ges_evt);
+
+	pcam->server_queue_idx = server_q_idx;
+	queue = &g_server_dev.server_queue[server_q_idx];
+	queue->ctrl_data = kzalloc(sizeof(uint8_t) *
+			max_control_command_size, GFP_KERNEL);
+	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",
+			__func__, rc);
+		goto error;
+	}
+
+	return rc;
+error:
+	ges_evt = MSM_V4L2_GES_CAM_CLOSE;
+	msm_cam_server_subdev_notify(g_server_dev.gesture_device,
+		NOTIFY_GESTURE_CAM_EVT, &ges_evt);
+
+	queue->queue_active = 0;
+	msm_drain_eventq(&queue->eventData_q);
+	msm_queue_drain(&queue->ctrl_q, list_control);
+	kfree(queue->ctrl_data);
+	queue->ctrl_data = NULL;
+	queue = NULL;
+	return rc;
+}
+
+int msm_server_end_session(struct msm_cam_v4l2_device *pcam)
+{
+	int rc = -EINVAL, ges_evt;
+	struct msm_cam_server_queue *queue;
+
+	mutex_lock(&g_server_dev.server_queue_lock);
+	queue = &g_server_dev.server_queue[pcam->server_queue_idx];
+	queue->queue_active = 0;
+	kfree(queue->ctrl_data);
+	queue->ctrl_data = NULL;
+	msm_queue_drain(&queue->ctrl_q, list_control);
+	msm_drain_eventq(&queue->eventData_q);
+	mutex_unlock(&g_server_dev.server_queue_lock);
+
+	rc = msm_cam_server_close_session(&g_server_dev, pcam);
+	if (rc < 0)
+		pr_err("msm_cam_server_close_session fails %d\n", rc);
+
+	ges_evt = MSM_V4L2_GES_CAM_CLOSE;
+	msm_cam_server_subdev_notify(g_server_dev.gesture_device,
+			NOTIFY_GESTURE_CAM_EVT, &ges_evt);
+
+	return rc;
+}
+
+/* Init a config node for ISP control,
+ * which will create a config device (/dev/config0/ and plug in
+ * ISP's operation "v4l2_ioctl_ops*"
+ */
+static const struct v4l2_file_operations msm_fops_server = {
+	.owner = THIS_MODULE,
+	.open  = msm_open_server,
+	.poll  = msm_poll_server,
+	.unlocked_ioctl = video_ioctl2,
+	.release = msm_close_server,
+};
+
+static const struct v4l2_ioctl_ops msm_ioctl_ops_server = {
+	.vidioc_subscribe_event = msm_server_v4l2_subscribe_event,
+	.vidioc_default = msm_ioctl_server,
+};
+
+static void msm_cam_server_subdev_notify(struct v4l2_subdev *sd,
+				unsigned int notification, void *arg)
+{
+	int rc = -EINVAL;
+	struct msm_sensor_ctrl_t *s_ctrl;
+	struct msm_camera_sensor_info *sinfo;
+	struct msm_camera_device_platform_data *camdev;
+	uint8_t csid_core = 0;
+
+	if (notification == NOTIFY_CID_CHANGE ||
+		notification == NOTIFY_ISPIF_STREAM ||
+		notification == NOTIFY_PCLK_CHANGE ||
+		notification == NOTIFY_CSIPHY_CFG ||
+		notification == NOTIFY_CSID_CFG ||
+		notification == NOTIFY_CSIC_CFG) {
+		s_ctrl = get_sctrl(sd);
+		sinfo = (struct msm_camera_sensor_info *) s_ctrl->sensordata;
+		camdev = sinfo->pdata;
+		csid_core = camdev->csid_core;
+	}
+
+	switch (notification) {
+	case NOTIFY_CID_CHANGE:
+		/* reconfig the ISPIF*/
+		if (g_server_dev.ispif_device) {
+			struct msm_ispif_params_list ispif_params;
+			ispif_params.len = 1;
+			ispif_params.params[0].intftype = PIX0;
+			ispif_params.params[0].cid_mask = 0x0001;
+			ispif_params.params[0].csid = csid_core;
+
+			rc = v4l2_subdev_call(
+				g_server_dev.ispif_device, core, ioctl,
+				VIDIOC_MSM_ISPIF_CFG, &ispif_params);
+			if (rc < 0)
+				return;
+		}
+		break;
+	case NOTIFY_ISPIF_STREAM:
+		/* call ISPIF stream on/off */
+		rc = v4l2_subdev_call(g_server_dev.ispif_device, video,
+				s_stream, (int)arg);
+		if (rc < 0)
+			return;
+
+		break;
+	case NOTIFY_ISP_MSG_EVT:
+	case NOTIFY_VFE_MSG_OUT:
+	case NOTIFY_VFE_MSG_STATS:
+	case NOTIFY_VFE_MSG_COMP_STATS:
+	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) {
+			rc = g_server_dev.isp_subdev[0]->isp_notify(
+				g_server_dev.vfe_device[0], notification, arg);
+		}
+		break;
+	case NOTIFY_VPE_MSG_EVT: {
+		struct msm_cam_media_controller *pmctl =
+		(struct msm_cam_media_controller *)
+		v4l2_get_subdev_hostdata(sd);
+		struct msm_vpe_resp *vdata = (struct msm_vpe_resp *)arg;
+		msm_mctl_pp_notify(pmctl,
+		(struct msm_mctl_pp_frame_info *)
+		vdata->extdata);
+		break;
+	}
+	case NOTIFY_VFE_IRQ:{
+		struct msm_vfe_cfg_cmd cfg_cmd;
+		struct msm_camvfe_params vfe_params;
+		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],
+			core, ioctl, 0, &vfe_params);
+	}
+		break;
+	case NOTIFY_AXI_IRQ:
+		rc = v4l2_subdev_call(g_server_dev.axi_device[0],
+			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,
+			s_crystal_freq, *(uint32_t *)arg, 0);
+		else
+			rc = v4l2_subdev_call(g_server_dev.vfe_device[0], video,
+			s_crystal_freq, *(uint32_t *)arg, 0);
+		break;
+	case NOTIFY_CSIPHY_CFG:
+		rc = v4l2_subdev_call(g_server_dev.csiphy_device[csid_core],
+			core, ioctl, VIDIOC_MSM_CSIPHY_CFG, arg);
+		break;
+	case NOTIFY_CSID_CFG:
+		rc = v4l2_subdev_call(g_server_dev.csid_device[csid_core],
+			core, ioctl, VIDIOC_MSM_CSID_CFG, arg);
+		break;
+	case NOTIFY_CSIC_CFG:
+		rc = v4l2_subdev_call(g_server_dev.csic_device[csid_core],
+			core, ioctl, VIDIOC_MSM_CSIC_CFG, arg);
+		break;
+	case NOTIFY_GESTURE_EVT:
+		rc = v4l2_subdev_call(g_server_dev.gesture_device,
+			core, ioctl, VIDIOC_MSM_GESTURE_EVT, arg);
+		break;
+	case NOTIFY_GESTURE_CAM_EVT:
+		rc = v4l2_subdev_call(g_server_dev.gesture_device,
+			core, ioctl, VIDIOC_MSM_GESTURE_CAM_EVT, arg);
+		break;
+	default:
+		break;
+	}
+
+	return;
+}
+
+int msm_cam_register_subdev_node(struct v4l2_subdev *sd,
+	enum msm_cam_subdev_type sdev_type, uint8_t index)
+{
+	struct video_device *vdev;
+	int err = 0;
+
+	switch (sdev_type) {
+	case CSIPHY_DEV:
+		if (index >= MAX_NUM_CSIPHY_DEV) {
+			pr_err("%s Invalid CSIPHY idx %d", __func__, index);
+			err = -EINVAL;
+			break;
+		}
+		g_server_dev.csiphy_device[index] = sd;
+		break;
+
+	case CSID_DEV:
+		if (index >= MAX_NUM_CSID_DEV) {
+			pr_err("%s Invalid CSID idx %d", __func__, index);
+			err = -EINVAL;
+			break;
+		}
+		g_server_dev.csid_device[index] = sd;
+		break;
+
+	case CSIC_DEV:
+		if (index >= MAX_NUM_CSIC_DEV) {
+			pr_err("%s Invalid CSIC idx %d", __func__, index);
+			err = -EINVAL;
+			break;
+		}
+		g_server_dev.csic_device[index] = sd;
+		break;
+
+	case ISPIF_DEV:
+		g_server_dev.ispif_device = sd;
+		break;
+
+	case VFE_DEV:
+		if (index >= MAX_NUM_VFE_DEV) {
+			pr_err("%s Invalid VFE idx %d", __func__, index);
+			err = -EINVAL;
+			break;
+		}
+		g_server_dev.vfe_device[index] = sd;
+		break;
+
+	case VPE_DEV:
+		if (index >= MAX_NUM_VPE_DEV) {
+			pr_err("%s Invalid VPE idx %d", __func__, index);
+			err = -EINVAL;
+			break;
+		}
+		g_server_dev.vpe_device[index] = sd;
+		break;
+
+	case AXI_DEV:
+		if (index >= MAX_NUM_VPE_DEV) {
+			pr_err("%s Invalid AXI idx %d", __func__, index);
+			err = -EINVAL;
+			break;
+		}
+		g_server_dev.axi_device[index] = sd;
+		break;
+
+	case GESTURE_DEV:
+		g_server_dev.gesture_device = sd;
+		break;
+	default:
+		break;
+	}
+
+	if (err < 0)
+		return err;
+
+	err = v4l2_device_register_subdev(&g_server_dev.v4l2_dev, sd);
+	if (err < 0) {
+		pr_err("%s v4l2 subdev register failed for %d ret = %d",
+			__func__, sdev_type, err);
+		return err;
+	}
+
+	/* Register a device node for every subdev marked with the
+	 * V4L2_SUBDEV_FL_HAS_DEVNODE flag.
+	 */
+	if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
+		return err;
+
+	vdev = &sd->devnode;
+	strlcpy(vdev->name, sd->name, sizeof(vdev->name));
+	vdev->v4l2_dev = &g_server_dev.v4l2_dev;
+	vdev->fops = &v4l2_subdev_fops;
+	vdev->release = video_device_release_empty;
+	err = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1,
+						  sd->owner);
+	if (err < 0)
+		return err;
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	sd->entity.v4l.major = VIDEO_MAJOR;
+	sd->entity.v4l.minor = vdev->minor;
+#endif
+	return 0;
+}
+
+static int msm_setup_server_dev(struct platform_device *pdev)
+{
+	int rc = -ENODEV, i;
+
+	D("%s\n", __func__);
+	g_server_dev.server_pdev = pdev;
+	g_server_dev.v4l2_dev.dev = &pdev->dev;
+	g_server_dev.v4l2_dev.notify = msm_cam_server_subdev_notify;
+	rc = v4l2_device_register(g_server_dev.v4l2_dev.dev,
+			&g_server_dev.v4l2_dev);
+	if (rc < 0)
+		return -EINVAL;
+
+	g_server_dev.video_dev = video_device_alloc();
+	if (g_server_dev.video_dev == NULL) {
+		pr_err("%s: video_device_alloc failed\n", __func__);
+		return rc;
+	}
+
+	strlcpy(g_server_dev.video_dev->name, pdev->name,
+			sizeof(g_server_dev.video_dev->name));
+
+	g_server_dev.video_dev->v4l2_dev = &g_server_dev.v4l2_dev;
+	g_server_dev.video_dev->fops = &msm_fops_server;
+	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;
+
+	video_set_drvdata(g_server_dev.video_dev, &g_server_dev);
+
+	strlcpy(g_server_dev.media_dev.model, "qcamera",
+		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;
+
+	rc = video_register_device(g_server_dev.video_dev,
+		VFL_TYPE_GRABBER, 100);
+
+	mutex_init(&g_server_dev.server_lock);
+	mutex_init(&g_server_dev.server_queue_lock);
+	g_server_dev.pcam_active = NULL;
+	g_server_dev.camera_info.num_cameras = 0;
+	atomic_set(&g_server_dev.number_pcam_active, 0);
+	g_server_dev.server_evt_id = 0;
+
+	/*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(
+		&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];
+		queue->queue_active = 0;
+		msm_queue_init(&queue->ctrl_q, "control");
+		msm_queue_init(&queue->eventData_q, "eventdata");
+	}
+	return rc;
+}
+
+static long msm_server_send_v4l2_evt(void *evt)
+{
+	struct v4l2_event *v4l2_ev = (struct v4l2_event *)evt;
+	int rc = 0;
+
+	if (NULL == evt) {
+		pr_err("%s: evt is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	D("%s: evt type 0x%x\n", __func__, v4l2_ev->type);
+	if ((v4l2_ev->type >= MSM_GES_APP_EVT_MIN) &&
+		(v4l2_ev->type < MSM_GES_APP_EVT_MAX)) {
+		msm_cam_server_subdev_notify(g_server_dev.gesture_device,
+			NOTIFY_GESTURE_EVT, v4l2_ev);
+	} else {
+		pr_err("%s: Invalid evt %d\n", __func__, v4l2_ev->type);
+		rc = -EINVAL;
+	}
+	D("%s: end\n", __func__);
+
+	return rc;
+}
+
+int msm_cam_server_open_mctl_session(struct msm_cam_v4l2_device *pcam,
+	int *p_active)
+{
+	int rc = 0;
+	struct msm_cam_media_controller *pmctl = NULL;
+	D("%s: %p", __func__, g_server_dev.pcam_active);
+	*p_active = 0;
+	if (g_server_dev.pcam_active) {
+		D("%s: Active camera present return", __func__);
+		return 0;
+	}
+	rc = msm_cam_server_open_session(&g_server_dev, pcam);
+	if (rc < 0) {
+		pr_err("%s: cam_server_open_session failed %d\n",
+		__func__, rc);
+		return rc;
+	}
+
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
+	if (!pmctl->mctl_open) {
+		D("%s: media contoller is not inited\n",
+			 __func__);
+		rc = -ENODEV;
+		return rc;
+	}
+
+	D("%s: call mctl_open\n", __func__);
+	rc = pmctl->mctl_open(pmctl, MSM_APPS_ID_V4L2);
+
+	if (rc < 0) {
+		pr_err("%s: HW open failed rc = 0x%x\n",  __func__, rc);
+		return rc;
+	}
+	pmctl->pcam_ptr = pcam;
+	*p_active = 1;
+	return rc;
+}
+
+int msm_cam_server_close_mctl_session(struct msm_cam_v4l2_device *pcam)
+{
+	int rc = 0;
+	struct msm_cam_media_controller *pmctl = NULL;
+
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
+	if (!pmctl) {
+		D("%s: invalid handle\n", __func__);
+		return -ENODEV;
+	}
+
+	if (pmctl->mctl_release) {
+		rc = pmctl->mctl_release(pmctl);
+		if (rc < 0)
+			pr_err("mctl_release fails %d\n", rc);
+	}
+
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	kref_put(&pmctl->refcount, msm_release_ion_client);
+#endif
+
+	rc = msm_cam_server_close_session(&g_server_dev, pcam);
+	if (rc < 0)
+		pr_err("msm_cam_server_close_session fails %d\n", rc);
+
+	return rc;
+}
+
+int msm_server_open_client(int *p_qidx)
+{
+	int rc = 0;
+	int server_q_idx = 0;
+	struct msm_cam_server_queue *queue = NULL;
+
+	mutex_lock(&g_server_dev.server_lock);
+	server_q_idx = msm_find_free_queue();
+	if (server_q_idx < 0) {
+		mutex_unlock(&g_server_dev.server_lock);
+		return server_q_idx;
+	}
+
+	*p_qidx = server_q_idx;
+	queue = &g_server_dev.server_queue[server_q_idx];
+	queue->ctrl_data = kzalloc(sizeof(uint8_t) *
+		max_control_command_size, GFP_KERNEL);
+	msm_queue_init(&queue->ctrl_q, "control");
+	msm_queue_init(&queue->eventData_q, "eventdata");
+	queue->queue_active = 1;
+	mutex_unlock(&g_server_dev.server_lock);
+	return rc;
+}
+
+int msm_server_send_ctrl(struct msm_ctrl_cmd *out,
+	int ctrl_id)
+{
+	int rc = 0;
+	void *value;
+	struct msm_queue_cmd *rcmd;
+	struct msm_queue_cmd *event_qcmd;
+	struct msm_ctrl_cmd *ctrlcmd;
+	struct msm_cam_server_dev *server_dev = &g_server_dev;
+	struct msm_device_queue *queue =
+		&server_dev->server_queue[out->queue_idx].ctrl_q;
+
+	struct v4l2_event v4l2_evt;
+	struct msm_isp_event_ctrl *isp_event;
+	isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl), GFP_KERNEL);
+	if (!isp_event) {
+		pr_err("%s Insufficient memory. return", __func__);
+		return -ENOMEM;
+	}
+	event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
+	if (!event_qcmd) {
+		pr_err("%s Insufficient memory. return", __func__);
+		kfree(isp_event);
+		return -ENOMEM;
+	}
+
+	D("%s\n", __func__);
+	mutex_lock(&server_dev->server_queue_lock);
+	if (++server_dev->server_evt_id == 0)
+		server_dev->server_evt_id++;
+
+	D("%s qid %d evtid %d\n", __func__, out->queue_idx,
+		server_dev->server_evt_id);
+	server_dev->server_queue[out->queue_idx].evt_id =
+		server_dev->server_evt_id;
+	v4l2_evt.type = V4L2_EVENT_PRIVATE_START + ctrl_id;
+	v4l2_evt.u.data[0] = out->queue_idx;
+	/* setup event object to transfer the command; */
+	isp_event->resptype = MSM_CAM_RESP_V4L2;
+	isp_event->isp_data.ctrl = *out;
+	isp_event->isp_data.ctrl.evt_id = server_dev->server_evt_id;
+
+	atomic_set(&event_qcmd->on_heap, 1);
+	event_qcmd->command = isp_event;
+
+	msm_enqueue(&server_dev->server_queue[out->queue_idx].eventData_q,
+				&event_qcmd->list_eventdata);
+
+	/* now send command to config thread in userspace,
+	 * and wait for results */
+	v4l2_event_queue(server_dev->server_command_queue.pvdev,
+					  &v4l2_evt);
+	D("%s v4l2_event_queue: type = 0x%x\n", __func__, v4l2_evt.type);
+	mutex_unlock(&server_dev->server_queue_lock);
+
+	/* wait for config return status */
+	D("Waiting for config status\n");
+	rc = wait_event_interruptible_timeout(queue->wait,
+		!list_empty_careful(&queue->list),
+		msecs_to_jiffies(out->timeout_ms));
+	D("Waiting is over for config status\n");
+	if (list_empty_careful(&queue->list)) {
+		if (!rc)
+			rc = -ETIMEDOUT;
+		if (rc < 0) {
+			kfree(isp_event);
+			pr_err("%s: wait_event error %d\n", __func__, rc);
+			return rc;
+		}
+	}
+
+	rcmd = msm_dequeue(queue, list_control);
+	BUG_ON(!rcmd);
+	D("%s Finished servicing ioctl\n", __func__);
+
+	ctrlcmd = (struct msm_ctrl_cmd *)(rcmd->command);
+	value = out->value;
+	if (ctrlcmd->length > 0 && value != NULL &&
+		ctrlcmd->length <= out->length)
+		memcpy(value, ctrlcmd->value, ctrlcmd->length);
+
+	memcpy(out, ctrlcmd, sizeof(struct msm_ctrl_cmd));
+	out->value = value;
+
+	kfree(ctrlcmd);
+	free_qcmd(rcmd);
+	kfree(isp_event);
+	D("%s: rc %d\n", __func__, rc);
+	/* rc is the time elapsed. */
+	if (rc >= 0) {
+		/* TODO: Refactor msm_ctrl_cmd::status field */
+		if (out->status == 0)
+			rc = -1;
+		else if (out->status == 1 || out->status == 4)
+			rc = 0;
+		else
+			rc = -EINVAL;
+	}
+	return rc;
+}
+
+int msm_server_close_client(int idx)
+{
+	int rc = 0;
+	struct msm_cam_server_queue *queue = NULL;
+	mutex_lock(&g_server_dev.server_lock);
+	queue = &g_server_dev.server_queue[idx];
+	queue->queue_active = 0;
+	kfree(queue->ctrl_data);
+	queue->ctrl_data = NULL;
+	msm_queue_drain(&queue->ctrl_q, list_control);
+	msm_drain_eventq(&queue->eventData_q);
+	mutex_unlock(&g_server_dev.server_lock);
+	return rc;
+}
+
+static unsigned int msm_poll_config(struct file *fp,
+					struct poll_table_struct *wait)
+{
+	int rc = 0;
+	struct msm_cam_config_dev *config = fp->private_data;
+	if (config == NULL)
+		return -EINVAL;
+
+	D("%s\n", __func__);
+
+	poll_wait(fp,
+	&config->config_stat_event_queue.eventHandle.events->wait, wait);
+	if (v4l2_event_pending(&config->config_stat_event_queue.eventHandle))
+		rc |= POLLPRI;
+	return rc;
+}
+
+static int msm_mmap_config(struct file *fp, struct vm_area_struct *vma)
+{
+	struct msm_cam_config_dev *config_cam = fp->private_data;
+	int rc = 0;
+	int phyaddr;
+	int retval;
+	unsigned long size;
+
+	D("%s: phy_addr=0x%x", __func__, config_cam->mem_map.cookie);
+	phyaddr = (int)config_cam->mem_map.cookie;
+	if (!phyaddr) {
+		pr_err("%s: no physical memory to map", __func__);
+		return -EFAULT;
+	}
+	memset(&config_cam->mem_map, 0,
+		sizeof(struct msm_mem_map_info));
+	size = vma->vm_end - vma->vm_start;
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+	retval = remap_pfn_range(vma, vma->vm_start,
+					phyaddr >> PAGE_SHIFT,
+					size, vma->vm_page_prot);
+	if (retval) {
+		pr_err("%s: remap failed, rc = %d",
+					__func__, retval);
+		rc = -ENOMEM;
+		goto end;
+	}
+	D("%s: phy_addr=0x%x: %08lx-%08lx, pgoff %08lx\n",
+			__func__, (uint32_t)phyaddr,
+			vma->vm_start, vma->vm_end, vma->vm_pgoff);
+end:
+	return rc;
+}
+
+static int msm_open_config(struct inode *inode, struct file *fp)
+{
+	int rc;
+	struct msm_cam_config_dev *config_cam = container_of(inode->i_cdev,
+		struct msm_cam_config_dev, config_cdev);
+
+	D("%s: open %s\n", __func__, fp->f_path.dentry->d_name.name);
+
+	rc = nonseekable_open(inode, fp);
+	if (rc < 0) {
+		pr_err("%s: nonseekable_open error %d\n", __func__, rc);
+		return rc;
+	}
+	config_cam->use_count++;
+
+	/* assume there is only one active camera possible*/
+	config_cam->p_mctl =
+		msm_cam_server_get_mctl(g_server_dev.pcam_active->mctl_handle);
+
+	INIT_HLIST_HEAD(&config_cam->p_mctl->stats_info.pmem_stats_list);
+	spin_lock_init(&config_cam->p_mctl->stats_info.pmem_stats_spinlock);
+
+	config_cam->p_mctl->config_device = config_cam;
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	kref_get(&config_cam->p_mctl->refcount);
+#endif
+	fp->private_data = config_cam;
+	return rc;
+}
+
+static long msm_ioctl_config(struct file *fp, unsigned int cmd,
+	unsigned long arg)
+{
+
+	int rc = 0;
+	struct v4l2_event ev;
+	struct msm_cam_config_dev *config_cam = fp->private_data;
+	struct v4l2_event_subscription temp_sub;
+
+	D("%s: cmd %d\n", __func__, _IOC_NR(cmd));
+
+	switch (cmd) {
+	/* memory management shall be handeld here*/
+	case MSM_CAM_IOCTL_REGISTER_PMEM:
+		return msm_register_pmem(
+			&config_cam->p_mctl->stats_info.pmem_stats_list,
+			(void __user *)arg, config_cam->p_mctl->client);
+		break;
+
+	case MSM_CAM_IOCTL_UNREGISTER_PMEM:
+		return msm_pmem_table_del(
+			&config_cam->p_mctl->stats_info.pmem_stats_list,
+			(void __user *)arg, config_cam->p_mctl->client);
+		break;
+
+	case VIDIOC_SUBSCRIBE_EVENT:
+		if (copy_from_user(&temp_sub,
+			(void __user *)arg,
+			sizeof(struct v4l2_event_subscription))) {
+				pr_err("%s copy_from_user failed for cmd %d ",
+					__func__, cmd);
+				rc = -EINVAL;
+				return rc;
+		}
+		rc = msm_server_v4l2_subscribe_event
+			(&config_cam->config_stat_event_queue.eventHandle,
+				 &temp_sub);
+		if (rc < 0) {
+			pr_err("%s: cam_v4l2_subscribe_event failed rc=%d\n",
+				__func__, rc);
+			return rc;
+		}
+		break;
+
+	case VIDIOC_UNSUBSCRIBE_EVENT:
+		if (copy_from_user(&temp_sub, (void __user *)arg,
+			  sizeof(struct v4l2_event_subscription))) {
+			rc = -EINVAL;
+			return rc;
+		}
+		rc = msm_server_v4l2_unsubscribe_event
+			(&config_cam->config_stat_event_queue.eventHandle,
+			 &temp_sub);
+		if (rc < 0) {
+			pr_err("%s: cam_v4l2_unsubscribe_event failed rc=%d\n",
+				__func__, rc);
+			return rc;
+		}
+		break;
+
+	case VIDIOC_DQEVENT: {
+		void __user *u_msg_value = NULL, *user_ptr = NULL;
+		struct msm_isp_event_ctrl u_isp_event;
+		struct msm_isp_event_ctrl *k_isp_event;
+
+		/* First, copy the v4l2 event structure from userspace */
+		D("%s: VIDIOC_DQEVENT\n", __func__);
+		if (copy_from_user(&ev, (void __user *)arg,
+				sizeof(struct v4l2_event)))
+			break;
+		/* Next, get the pointer to event_ctrl structure
+		 * embedded inside the v4l2_event.u.data array. */
+		user_ptr = (void __user *)(*((uint32_t *)ev.u.data));
+
+		/* Next, copy the userspace event ctrl structure */
+		if (copy_from_user((void *)&u_isp_event, user_ptr,
+				   sizeof(struct msm_isp_event_ctrl))) {
+			break;
+		}
+		/* Save the pointer of the user allocated command buffer*/
+		u_msg_value = u_isp_event.isp_data.isp_msg.data;
+
+		/* Dequeue the event queued into the v4l2 queue*/
+		rc = v4l2_event_dequeue(
+			&config_cam->config_stat_event_queue.eventHandle,
+			&ev, fp->f_flags & O_NONBLOCK);
+		if (rc < 0) {
+			pr_err("no pending events?");
+			break;
+		}
+		/* Use k_isp_event to point to the event_ctrl structure
+		 * embedded inside v4l2_event.u.data */
+		k_isp_event = (struct msm_isp_event_ctrl *)
+				(*((uint32_t *)ev.u.data));
+		/* Copy the event structure into user struct. */
+		u_isp_event = *k_isp_event;
+		if (ev.type != (V4L2_EVENT_PRIVATE_START +
+				MSM_CAM_RESP_DIV_FRAME_EVT_MSG) &&
+				ev.type != (V4L2_EVENT_PRIVATE_START +
+				MSM_CAM_RESP_MCTL_PP_EVENT)) {
+
+			/* Restore the saved pointer of the
+			 * user allocated command buffer. */
+			u_isp_event.isp_data.isp_msg.data = u_msg_value;
+
+			if (ev.type == (V4L2_EVENT_PRIVATE_START +
+					MSM_CAM_RESP_STAT_EVT_MSG)) {
+				if (k_isp_event->isp_data.isp_msg.len > 0) {
+					void *k_msg_value =
+					k_isp_event->isp_data.isp_msg.data;
+					if (copy_to_user(u_msg_value,
+							k_msg_value,
+					 k_isp_event->isp_data.isp_msg.len)) {
+						rc = -EINVAL;
+						break;
+					}
+					kfree(k_msg_value);
+				}
+			}
+		}
+		/* Copy the event ctrl structure back
+		 * into user's structure. */
+		if (copy_to_user(user_ptr,
+				(void *)&u_isp_event, sizeof(
+				struct msm_isp_event_ctrl))) {
+			rc = -EINVAL;
+			break;
+		}
+		kfree(k_isp_event);
+
+		/* Copy the v4l2_event structure back to the user*/
+		if (copy_to_user((void __user *)arg, &ev,
+				sizeof(struct v4l2_event))) {
+			rc = -EINVAL;
+			break;
+		}
+		}
+
+		break;
+
+	case MSM_CAM_IOCTL_V4L2_EVT_NOTIFY:
+		rc = msm_v4l2_evt_notify(config_cam->p_mctl, cmd, arg);
+		break;
+
+	case MSM_CAM_IOCTL_SET_MEM_MAP_INFO:
+		if (copy_from_user(&config_cam->mem_map, (void __user *)arg,
+				sizeof(struct msm_mem_map_info)))
+			rc = -EINVAL;
+		break;
+
+	default:{
+		/* For the rest of config command, forward to media controller*/
+		struct msm_cam_media_controller *p_mctl = config_cam->p_mctl;
+		if (p_mctl && p_mctl->mctl_cmd) {
+			rc = config_cam->p_mctl->mctl_cmd(p_mctl, cmd, arg);
+		} else {
+			rc = -EINVAL;
+			pr_err("%s: media controller is null\n", __func__);
+		}
+
+		break;
+	} /* end of default*/
+	} /* end of switch*/
+	return rc;
+}
+
+static int msm_close_config(struct inode *node, struct file *f)
+{
+	struct v4l2_event ev;
+	struct v4l2_event_subscription sub;
+	struct msm_isp_event_ctrl *isp_event;
+	struct msm_cam_config_dev *config_cam = f->private_data;
+
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	D("%s Decrementing ref count of config node ", __func__);
+	kref_put(&config_cam->p_mctl->refcount, msm_release_ion_client);
+#endif
+	sub.type = V4L2_EVENT_ALL;
+	msm_server_v4l2_unsubscribe_event(
+		&config_cam->config_stat_event_queue.eventHandle,
+		&sub);
+	while (v4l2_event_pending(
+		&config_cam->config_stat_event_queue.eventHandle)) {
+		v4l2_event_dequeue(
+			&config_cam->config_stat_event_queue.eventHandle,
+			&ev, O_NONBLOCK);
+		isp_event = (struct msm_isp_event_ctrl *)
+			(*((uint32_t *)ev.u.data));
+		if (isp_event) {
+			if (isp_event->isp_data.isp_msg.len != 0 &&
+				isp_event->isp_data.isp_msg.data != NULL)
+				kfree(isp_event->isp_data.isp_msg.data);
+			kfree(isp_event);
+		}
+	}
+	return 0;
+}
+
+static const struct file_operations msm_fops_config = {
+	.owner = THIS_MODULE,
+	.open  = msm_open_config,
+	.poll  = msm_poll_config,
+	.unlocked_ioctl = msm_ioctl_config,
+	.mmap	= msm_mmap_config,
+	.release = msm_close_config,
+};
+
+static int msm_setup_config_dev(int node, char *device_name)
+{
+	int rc = -ENODEV;
+	struct device *device_config;
+	int dev_num = node;
+	dev_t devno;
+	struct msm_cam_config_dev *config_cam;
+
+	config_cam = kzalloc(sizeof(*config_cam), GFP_KERNEL);
+	if (!config_cam) {
+		pr_err("%s: could not allocate memory for config_device\n",
+			__func__);
+		return -ENOMEM;
+	}
+
+	D("%s\n", __func__);
+
+	devno = MKDEV(MAJOR(msm_devno), dev_num+1);
+	device_config = device_create(msm_class, NULL, devno, NULL, "%s%d",
+		device_name, dev_num);
+
+	if (IS_ERR(device_config)) {
+		rc = PTR_ERR(device_config);
+		pr_err("%s: error creating device: %d\n", __func__, rc);
+		goto config_setup_fail;
+	}
+
+	cdev_init(&config_cam->config_cdev, &msm_fops_config);
+	config_cam->config_cdev.owner = THIS_MODULE;
+
+	rc = cdev_add(&config_cam->config_cdev, devno, 1);
+	if (rc < 0) {
+		pr_err("%s: error adding cdev: %d\n", __func__, rc);
+		device_destroy(msm_class, devno);
+		goto config_setup_fail;
+	}
+	g_server_dev.config_info.config_dev_name[dev_num] =
+		dev_name(device_config);
+	D("%s Connected config device %s\n", __func__,
+		g_server_dev.config_info.config_dev_name[dev_num]);
+	g_server_dev.config_info.config_dev_id[dev_num] =
+		dev_num;
+
+	config_cam->config_stat_event_queue.pvdev = video_device_alloc();
+	if (config_cam->config_stat_event_queue.pvdev == NULL) {
+		pr_err("%s: video_device_alloc failed\n", __func__);
+		goto config_setup_fail;
+	}
+
+	rc = 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;
+
+config_setup_fail:
+	kfree(config_cam);
+	return rc;
+}
+
+static int __devinit msm_camera_probe(struct platform_device *pdev)
+{
+	int rc = 0, i;
+	/*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;
+
+	rc = msm_isp_init_module(g_server_dev.config_info.num_config_nodes);
+	if (rc < 0) {
+		pr_err("Failed to initialize isp\n");
+		return rc;
+	}
+
+	if (!msm_class) {
+		rc = alloc_chrdev_region(&msm_devno, 0,
+		g_server_dev.config_info.num_config_nodes+1, "msm_camera");
+		if (rc < 0) {
+			pr_err("%s: failed to allocate chrdev: %d\n", __func__,
+			rc);
+			return rc;
+		}
+
+		msm_class = class_create(THIS_MODULE, "msm_camera");
+		if (IS_ERR(msm_class)) {
+			rc = PTR_ERR(msm_class);
+			pr_err("%s: create device class failed: %d\n",
+			__func__, rc);
+			return rc;
+		}
+	}
+
+	D("creating server and config nodes\n");
+	rc = msm_setup_server_dev(pdev);
+	if (rc < 0) {
+		pr_err("%s: failed to create server dev: %d\n", __func__,
+		rc);
+		return rc;
+	}
+
+	for (i = 0; i < g_server_dev.config_info.num_config_nodes; i++) {
+		rc = msm_setup_config_dev(i, "config");
+		if (rc < 0) {
+			pr_err("%s:failed to create config dev: %d\n",
+			 __func__, rc);
+			return rc;
+		}
+	}
+
+	msm_isp_register(&g_server_dev);
+	return rc;
+}
+
+static int __exit msm_camera_exit(struct platform_device *pdev)
+{
+	msm_isp_unregister(&g_server_dev);
+	return 0;
+}
+
+static struct platform_driver msm_cam_server_driver = {
+	.probe = msm_camera_probe,
+	.remove = msm_camera_exit,
+	.driver = {
+		.name = "msm_cam_server",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init msm_cam_server_init(void)
+{
+	return platform_driver_register(&msm_cam_server_driver);
+}
+
+static void __exit msm_cam_server_exit(void)
+{
+	platform_driver_unregister(&msm_cam_server_driver);
+}
+
+module_init(msm_cam_server_init);
+module_exit(msm_cam_server_exit);
+MODULE_DESCRIPTION("msm camera server");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/server/msm_cam_server.h b/drivers/media/video/msm/server/msm_cam_server.h
new file mode 100644
index 0000000..2fe4c2b
--- /dev/null
+++ b/drivers/media/video/msm/server/msm_cam_server.h
@@ -0,0 +1,65 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _MSM_CAM_SERVER_H
+#define _MSM_CAM_SERVER_H
+
+#include <linux/proc_fs.h>
+#include <linux/ioctl.h>
+#include <mach/camera.h>
+#include "msm.h"
+
+uint32_t msm_cam_server_get_mctl_handle(void);
+struct msm_cam_media_controller *msm_cam_server_get_mctl(uint32_t handle);
+void msm_cam_server_free_mctl(uint32_t handle);
+/* Server session control APIs */
+int msm_server_begin_session(struct msm_cam_v4l2_device *pcam,
+	int server_q_idx);
+int msm_server_end_session(struct msm_cam_v4l2_device *pcam);
+int msm_send_open_server(struct msm_cam_v4l2_device *pcam);
+int msm_send_close_server(struct msm_cam_v4l2_device *pcam);
+int msm_server_update_sensor_info(struct msm_cam_v4l2_device *pcam,
+	struct msm_camera_sensor_info *sdata);
+/* Server camera control APIs */
+int msm_server_streamon(struct msm_cam_v4l2_device *pcam, int idx);
+int msm_server_streamoff(struct msm_cam_v4l2_device *pcam, int idx);
+int msm_server_get_usecount(void);
+int32_t msm_find_free_queue(void);
+int msm_server_proc_ctrl_cmd(struct msm_cam_v4l2_device *pcam,
+	struct v4l2_control *ctrl, int is_set_cmd);
+int msm_server_s_ctrl(struct msm_cam_v4l2_device *pcam,
+	struct v4l2_control *ctrl);
+int msm_server_g_ctrl(struct msm_cam_v4l2_device *pcam,
+	struct v4l2_control *ctrl);
+int msm_server_q_ctrl(struct msm_cam_v4l2_device *pcam,
+	struct v4l2_queryctrl *queryctrl);
+int msm_server_set_fmt(struct msm_cam_v4l2_device *pcam, int idx,
+	struct v4l2_format *pfmt);
+int msm_server_set_fmt_mplane(struct msm_cam_v4l2_device *pcam, int idx,
+	struct v4l2_format *pfmt);
+int msm_server_get_fmt(struct msm_cam_v4l2_device *pcam,
+	int idx, struct v4l2_format *pfmt);
+int msm_server_get_fmt_mplane(struct msm_cam_v4l2_device *pcam,
+	int idx, struct v4l2_format *pfmt);
+int msm_server_try_fmt(struct msm_cam_v4l2_device *pcam,
+	struct v4l2_format *pfmt);
+int msm_server_try_fmt_mplane(struct msm_cam_v4l2_device *pcam,
+	struct v4l2_format *pfmt);
+int msm_server_v4l2_subscribe_event(struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub);
+int msm_server_v4l2_unsubscribe_event(struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub);
+int msm_server_get_crop(struct msm_cam_v4l2_device *pcam,
+	int idx, struct v4l2_crop *crop);
+
+#endif /* _MSM_CAM_SERVER_H */
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 1d26d45..37f0799 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1588,6 +1588,9 @@
 	usbmon_urb_complete(&hcd->self, urb, status);
 	usb_unanchor_urb(urb);
 
+	if (hcd->driver->log_urb_complete)
+		hcd->driver->log_urb_complete(urb, "C", status);
+
 	/* pass ownership to the completion handler */
 	urb->status = status;
 	urb->complete (urb);
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index 822abdcf..6bd0577 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -39,6 +39,7 @@
 #include <mach/msm_iomap.h>
 #include <mach/msm_xo.h>
 #include <linux/spinlock.h>
+#include <linux/cpu.h>
 
 #define MSM_USB_BASE (hcd->regs)
 
@@ -64,6 +65,183 @@
 };
 
 static bool debug_bus_voting_enabled = true;
+
+static unsigned int enable_dbg_log = 1;
+module_param(enable_dbg_log, uint, S_IRUGO | S_IWUSR);
+/*by default log ep0 and efs sync ep*/
+static unsigned int ep_addr_rxdbg_mask = 9;
+module_param(ep_addr_rxdbg_mask, uint, S_IRUGO | S_IWUSR);
+static unsigned int ep_addr_txdbg_mask = 9;
+module_param(ep_addr_txdbg_mask, uint, S_IRUGO | S_IWUSR);
+
+/* Maximum debug message length */
+#define DBG_MSG_LEN   100UL
+
+/* Maximum number of messages */
+#define DBG_MAX_MSG   256UL
+
+#define TIME_BUF_LEN  20
+
+enum event_type {
+	EVENT_UNDEF = -1,
+	URB_SUBMIT,
+	URB_COMPLETE,
+	EVENT_NONE,
+};
+
+#define EVENT_STR_LEN	5
+
+static char *event_to_str(enum event_type e)
+{
+	switch (e) {
+	case URB_SUBMIT:
+		return "S";
+	case URB_COMPLETE:
+		return "C";
+	case EVENT_NONE:
+		return "NONE";
+	default:
+		return "UNDEF";
+	}
+}
+
+static enum event_type str_to_event(const char *name)
+{
+	if (!strncasecmp("S", name, EVENT_STR_LEN))
+		return URB_SUBMIT;
+	if (!strncasecmp("C", name, EVENT_STR_LEN))
+		return URB_COMPLETE;
+	if (!strncasecmp("", name, EVENT_STR_LEN))
+		return EVENT_NONE;
+
+	return EVENT_UNDEF;
+}
+
+/*log ep0 activity*/
+static struct {
+	char     (buf[DBG_MAX_MSG])[DBG_MSG_LEN];   /* buffer */
+	unsigned idx;   /* index */
+	rwlock_t lck;   /* lock */
+} dbg_hsic_ctrl = {
+	.idx = 0,
+	.lck = __RW_LOCK_UNLOCKED(lck)
+};
+
+static struct {
+	char     (buf[DBG_MAX_MSG])[DBG_MSG_LEN];   /* buffer */
+	unsigned idx;   /* index */
+	rwlock_t lck;   /* lock */
+} dbg_hsic_data = {
+	.idx = 0,
+	.lck = __RW_LOCK_UNLOCKED(lck)
+};
+
+/**
+ * dbg_inc: increments debug event index
+ * @idx: buffer index
+ */
+static void dbg_inc(unsigned *idx)
+{
+	*idx = (*idx + 1) & (DBG_MAX_MSG-1);
+}
+
+/*get_timestamp - returns time of day in us */
+static char *get_timestamp(char *tbuf)
+{
+	unsigned long long t;
+	unsigned long nanosec_rem;
+
+	t = cpu_clock(smp_processor_id());
+	nanosec_rem = do_div(t, 1000000000)/1000;
+	scnprintf(tbuf, TIME_BUF_LEN, "[%5lu.%06lu] ", (unsigned long)t,
+		nanosec_rem);
+	return tbuf;
+}
+
+static int allow_dbg_log(int ep_addr)
+{
+	int dir, num;
+
+	dir = ep_addr & USB_DIR_IN ? USB_DIR_IN : USB_DIR_OUT;
+	num = ep_addr & ~USB_DIR_IN;
+	num = 1 << num;
+
+	if ((dir == USB_DIR_IN) && (num & ep_addr_rxdbg_mask))
+		return 1;
+	if ((dir == USB_DIR_OUT) && (num & ep_addr_txdbg_mask))
+		return 1;
+
+	return 0;
+}
+
+static void dbg_log_event(struct urb *urb, char * event, unsigned extra)
+{
+	unsigned long flags;
+	int ep_addr;
+	char tbuf[TIME_BUF_LEN];
+
+	if (!enable_dbg_log)
+		return;
+
+	if (!urb) {
+		write_lock_irqsave(&dbg_hsic_ctrl.lck, flags);
+		scnprintf(dbg_hsic_ctrl.buf[dbg_hsic_ctrl.idx], DBG_MSG_LEN,
+			"%s: %s : %u\n", get_timestamp(tbuf), event, extra);
+		dbg_inc(&dbg_hsic_ctrl.idx);
+		write_unlock_irqrestore(&dbg_hsic_ctrl.lck, flags);
+		return;
+	}
+
+	ep_addr = urb->ep->desc.bEndpointAddress;
+	if (!allow_dbg_log(ep_addr))
+		return;
+
+	if ((ep_addr & 0x0f) == 0x0) {
+		/*submit event*/
+		if (!str_to_event(event)) {
+			write_lock_irqsave(&dbg_hsic_ctrl.lck, flags);
+			scnprintf(dbg_hsic_ctrl.buf[dbg_hsic_ctrl.idx],
+				DBG_MSG_LEN, "%s: [%s : %p]:[%s] "
+				  "%02x %02x %04x %04x %04x  %u %d\n",
+				  get_timestamp(tbuf), event, urb,
+				  (ep_addr & USB_DIR_IN) ? "in" : "out",
+				  urb->setup_packet[0], urb->setup_packet[1],
+				  (urb->setup_packet[3] << 8) |
+				  urb->setup_packet[2],
+				  (urb->setup_packet[5] << 8) |
+				  urb->setup_packet[4],
+				  (urb->setup_packet[7] << 8) |
+				  urb->setup_packet[6],
+				  urb->transfer_buffer_length, urb->status);
+
+			dbg_inc(&dbg_hsic_ctrl.idx);
+			write_unlock_irqrestore(&dbg_hsic_ctrl.lck, flags);
+		} else {
+			write_lock_irqsave(&dbg_hsic_ctrl.lck, flags);
+			scnprintf(dbg_hsic_ctrl.buf[dbg_hsic_ctrl.idx],
+				DBG_MSG_LEN, "%s: [%s : %p]:[%s] %u %d\n",
+				  get_timestamp(tbuf), event, urb,
+				  (ep_addr & USB_DIR_IN) ? "in" : "out",
+				  urb->actual_length, extra);
+
+			dbg_inc(&dbg_hsic_ctrl.idx);
+			write_unlock_irqrestore(&dbg_hsic_ctrl.lck, flags);
+		}
+	} else {
+		write_lock_irqsave(&dbg_hsic_data.lck, flags);
+		scnprintf(dbg_hsic_data.buf[dbg_hsic_data.idx], DBG_MSG_LEN,
+			  "%s: [%s : %p]:ep%d[%s]  %u %d\n",
+			  get_timestamp(tbuf), event, urb, ep_addr & 0x0f,
+			  (ep_addr & USB_DIR_IN) ? "in" : "out",
+			  str_to_event(event) ? urb->actual_length :
+			  urb->transfer_buffer_length,
+			  str_to_event(event) ?  extra : urb->status);
+
+		dbg_inc(&dbg_hsic_data.idx);
+		write_unlock_irqrestore(&dbg_hsic_data.lck, flags);
+	}
+}
+
 static inline struct msm_hsic_hcd *hcd_to_hsic(struct usb_hcd *hcd)
 {
 	return (struct msm_hsic_hcd *) (hcd->hcd_priv);
@@ -589,6 +767,25 @@
 	return 0;
 }
 
+static int ehci_hsic_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
+		gfp_t mem_flags)
+{
+	dbg_log_event(urb, event_to_str(URB_SUBMIT), 0);
+	return ehci_urb_enqueue(hcd, urb, mem_flags);
+}
+
+static int ehci_hsic_bus_suspend(struct usb_hcd *hcd)
+{
+	dbg_log_event(NULL, "Suspend RH", 0);
+	return ehci_bus_suspend(hcd);
+}
+
+static int ehci_hsic_bus_resume(struct usb_hcd *hcd)
+{
+	dbg_log_event(NULL, "Resume RH", 0);
+	return ehci_bus_resume(hcd);
+}
+
 static struct hc_driver msm_hsic_driver = {
 	.description		= hcd_name,
 	.product_desc		= "Qualcomm EHCI Host Controller using HSIC",
@@ -609,7 +806,7 @@
 	/*
 	 * managing i/o requests and associated device resources
 	 */
-	.urb_enqueue		= ehci_urb_enqueue,
+	.urb_enqueue		= ehci_hsic_urb_enqueue,
 	.urb_dequeue		= ehci_urb_dequeue,
 	.endpoint_disable	= ehci_endpoint_disable,
 	.endpoint_reset		= ehci_endpoint_reset,
@@ -631,8 +828,10 @@
 	/*
 	 * PM support
 	 */
-	.bus_suspend		= ehci_bus_suspend,
-	.bus_resume		= ehci_bus_resume,
+	.bus_suspend		= ehci_hsic_bus_suspend,
+	.bus_resume		= ehci_hsic_bus_resume,
+
+	.log_urb_complete	= dbg_log_event,
 };
 
 static int msm_hsic_init_clocks(struct msm_hsic_hcd *mehci, u32 init)
@@ -729,6 +928,7 @@
 	struct msm_hsic_hcd *mehci = data;
 
 	mehci->wakeup_int_cnt++;
+	dbg_log_event(NULL, "Remote Wakeup IRQ", mehci->wakeup_int_cnt);
 	dev_dbg(mehci->dev, "%s: hsic remote wakeup interrupt cnt: %u\n",
 			__func__, mehci->wakeup_int_cnt);
 
@@ -822,6 +1022,68 @@
 	.release = single_release,
 };
 
+static int ehci_hsic_msm_data_events_show(struct seq_file *s, void *unused)
+{
+	unsigned long	flags;
+	unsigned	i;
+
+	read_lock_irqsave(&dbg_hsic_data.lck, flags);
+
+	i = dbg_hsic_data.idx;
+	for (dbg_inc(&i); i != dbg_hsic_data.idx; dbg_inc(&i)) {
+		if (!strnlen(dbg_hsic_data.buf[i], DBG_MSG_LEN))
+			continue;
+		seq_printf(s, "%s\n", dbg_hsic_data.buf[i]);
+	}
+
+	read_unlock_irqrestore(&dbg_hsic_data.lck, flags);
+
+	return 0;
+}
+
+static int ehci_hsic_msm_data_events_open(struct inode *inode, struct file *f)
+{
+	return single_open(f, ehci_hsic_msm_data_events_show, inode->i_private);
+}
+
+const struct file_operations ehci_hsic_msm_dbg_data_fops = {
+	.open = ehci_hsic_msm_data_events_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static int ehci_hsic_msm_ctrl_events_show(struct seq_file *s, void *unused)
+{
+	unsigned long	flags;
+	unsigned	i;
+
+	read_lock_irqsave(&dbg_hsic_ctrl.lck, flags);
+
+	i = dbg_hsic_ctrl.idx;
+	for (dbg_inc(&i); i != dbg_hsic_ctrl.idx; dbg_inc(&i)) {
+		if (!strnlen(dbg_hsic_ctrl.buf[i], DBG_MSG_LEN))
+			continue;
+		seq_printf(s, "%s\n", dbg_hsic_ctrl.buf[i]);
+	}
+
+	read_unlock_irqrestore(&dbg_hsic_ctrl.lck, flags);
+
+	return 0;
+}
+
+static int ehci_hsic_msm_ctrl_events_open(struct inode *inode, struct file *f)
+{
+	return single_open(f, ehci_hsic_msm_ctrl_events_show, inode->i_private);
+}
+
+const struct file_operations ehci_hsic_msm_dbg_ctrl_fops = {
+	.open = ehci_hsic_msm_ctrl_events_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
 static struct dentry *ehci_hsic_msm_dbg_root;
 static int ehci_hsic_msm_debugfs_init(struct msm_hsic_hcd *mehci)
 {
@@ -852,6 +1114,26 @@
 		return -ENODEV;
 	}
 
+	ehci_hsic_msm_dentry = debugfs_create_file("show_ctrl_events",
+		S_IRUGO,
+		ehci_hsic_msm_dbg_root, mehci,
+		&ehci_hsic_msm_dbg_ctrl_fops);
+
+	if (!ehci_hsic_msm_dentry) {
+		debugfs_remove_recursive(ehci_hsic_msm_dbg_root);
+		return -ENODEV;
+	}
+
+	ehci_hsic_msm_dentry = debugfs_create_file("show_data_events",
+		S_IRUGO,
+		ehci_hsic_msm_dbg_root, mehci,
+		&ehci_hsic_msm_dbg_data_fops);
+
+	if (!ehci_hsic_msm_dentry) {
+		debugfs_remove_recursive(ehci_hsic_msm_dbg_root);
+		return -ENODEV;
+	}
+
 	return 0;
 }
 
@@ -1077,6 +1359,8 @@
 
 	dev_dbg(dev, "ehci-msm-hsic PM suspend\n");
 
+	dbg_log_event(NULL, "PM Suspend", 0);
+
 	if (device_may_wakeup(dev))
 		enable_irq_wake(hcd->irq);
 
@@ -1094,6 +1378,8 @@
 	struct usb_hcd *hcd = dev_get_drvdata(dev);
 	struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
 
+	dbg_log_event(NULL, "PM Resume", 0);
+
 	if (device_may_wakeup(dev))
 		disable_irq_wake(hcd->irq);
 
@@ -1123,6 +1409,9 @@
 	struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
 
 	dev_dbg(dev, "EHCI runtime suspend\n");
+
+	dbg_log_event(NULL, "Run Time PM Suspend", 0);
+
 	return msm_hsic_suspend(mehci);
 }
 
@@ -1132,6 +1421,9 @@
 	struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
 
 	dev_dbg(dev, "EHCI runtime resume\n");
+
+	dbg_log_event(NULL, "Run Time PM Resume", 0);
+
 	return msm_hsic_resume(mehci);
 }
 #endif
diff --git a/fs/fat/misc.c b/fs/fat/misc.c
index 6d93360..a1d192d 100644
--- a/fs/fat/misc.c
+++ b/fs/fat/misc.c
@@ -56,7 +56,11 @@
 	va_start(args, fmt);
 	vaf.fmt = fmt;
 	vaf.va = &args;
-	printk("%sFAT-fs (%s): %pV\n", level, sb->s_id, &vaf);
+	if (!strncmp(level, KERN_ERR, sizeof(KERN_ERR)))
+		printk_ratelimited("%sFAT-fs (%s): %pV\n", level,
+				   sb->s_id, &vaf);
+	else
+		printk("%sFAT-fs (%s): %pV\n", level, sb->s_id, &vaf);
 	va_end(args);
 }
 
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 5762463..a255388 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -343,6 +343,10 @@
 		 * address is set
 		 */
 	int	(*update_device)(struct usb_hcd *, struct usb_device *);
+
+	/* to log completion events*/
+	void	(*log_urb_complete)(struct urb *urb, char * event,
+			unsigned extra);
 };
 
 extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index d4cf1d2..8222b67 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -448,6 +448,9 @@
 #define CMD_AXI_CFG_SEC			0xF4
 #define CMD_AXI_CFG_SEC_ALL_CHNLS	0xF8
 
+#define CMD_AXI_START  0xE1
+#define CMD_AXI_STOP   0xE2
+
 /* vfe config command: config command(from config thread)*/
 struct msm_vfe_cfg_cmd {
 	int cmd_type;
diff --git a/sound/soc/msm/msm8930.c b/sound/soc/msm/msm8930.c
index 72bb9b5..a15928f 100644
--- a/sound/soc/msm/msm8930.c
+++ b/sound/soc/msm/msm8930.c
@@ -45,6 +45,11 @@
 #define SITAR_MBHC_DEF_BUTTONS 8
 #define SITAR_MBHC_DEF_RLOADS 5
 
+#define GPIO_AUX_PCM_DOUT 63
+#define GPIO_AUX_PCM_DIN 64
+#define GPIO_AUX_PCM_SYNC 65
+#define GPIO_AUX_PCM_CLK 66
+
 static int msm8930_spk_control;
 static int msm8930_slim_0_rx_ch = 1;
 static int msm8930_slim_0_tx_ch = 1;
@@ -812,6 +817,80 @@
 	return 0;
 }
 
+static int msm8930_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd,
+				struct snd_pcm_hw_params *params)
+{
+	struct snd_interval *rate = hw_param_interval(params,
+					 SNDRV_PCM_HW_PARAM_RATE);
+
+	struct snd_interval *channels = hw_param_interval(params,
+					SNDRV_PCM_HW_PARAM_CHANNELS);
+
+	/* PCM only supports mono output with 8khz sample rate */
+	rate->min = rate->max = 8000;
+	channels->min = channels->max = 1;
+
+	return 0;
+}
+
+static int msm8930_aux_pcm_get_gpios(void)
+{
+	int ret = 0;
+
+	pr_debug("%s\n", __func__);
+
+	ret = gpio_request(GPIO_AUX_PCM_DOUT, "AUX PCM DOUT");
+	if (ret < 0) {
+		pr_err("%s: Failed to request gpio(%d): AUX PCM DOUT",
+				__func__, GPIO_AUX_PCM_DOUT);
+
+		goto fail_dout;
+	}
+
+	ret = gpio_request(GPIO_AUX_PCM_DIN, "AUX PCM DIN");
+	if (ret < 0) {
+		pr_err("%s: Failed to request gpio(%d): AUX PCM DIN",
+				 __func__, GPIO_AUX_PCM_DIN);
+		goto fail_din;
+	}
+
+	ret = gpio_request(GPIO_AUX_PCM_SYNC, "AUX PCM SYNC");
+	if (ret < 0) {
+		pr_err("%s: Failed to request gpio(%d): AUX PCM SYNC",
+				__func__, GPIO_AUX_PCM_SYNC);
+		goto fail_sync;
+	}
+
+	ret = gpio_request(GPIO_AUX_PCM_CLK, "AUX PCM CLK");
+	if (ret < 0) {
+		pr_err("%s: Failed to request gpio(%d): AUX PCM CLK",
+				 __func__, GPIO_AUX_PCM_CLK);
+		goto fail_clk;
+	}
+
+	return 0;
+
+fail_clk:
+	gpio_free(GPIO_AUX_PCM_SYNC);
+fail_sync:
+	gpio_free(GPIO_AUX_PCM_DIN);
+fail_din:
+	gpio_free(GPIO_AUX_PCM_DOUT);
+fail_dout:
+
+	return ret;
+}
+
+static int msm8930_aux_pcm_free_gpios(void)
+{
+	gpio_free(GPIO_AUX_PCM_DIN);
+	gpio_free(GPIO_AUX_PCM_DOUT);
+	gpio_free(GPIO_AUX_PCM_SYNC);
+	gpio_free(GPIO_AUX_PCM_CLK);
+
+	return 0;
+}
+
 static int msm8930_startup(struct snd_pcm_substream *substream)
 {
 	pr_debug("%s(): substream = %s  stream = %d\n", __func__,
@@ -819,6 +898,26 @@
 	return 0;
 }
 
+static int msm8930_auxpcm_startup(struct snd_pcm_substream *substream)
+{
+	int ret = 0;
+
+	pr_debug("%s(): substream = %s\n", __func__, substream->name);
+	ret = msm8930_aux_pcm_get_gpios();
+	if (ret < 0) {
+		pr_err("%s: Aux PCM GPIO request failed\n", __func__);
+		return -EINVAL;
+	}
+	return 0;
+
+}
+
+static void msm8930_auxpcm_shutdown(struct snd_pcm_substream *substream)
+{
+	pr_debug("%s(): substream = %s\n", __func__, substream->name);
+	msm8930_aux_pcm_free_gpios();
+}
+
 static void msm8930_shutdown(struct snd_pcm_substream *substream)
 {
 	pr_debug("%s(): substream = %s  stream = %d\n", __func__,
@@ -831,6 +930,11 @@
 	.shutdown = msm8930_shutdown,
 };
 
+static struct snd_soc_ops msm8930_auxpcm_be_ops = {
+	.startup = msm8930_auxpcm_startup,
+	.shutdown = msm8930_auxpcm_shutdown,
+};
+
 /* Digital audio interface glue - connects codec <---> CPU */
 static struct snd_soc_dai_link msm8930_dai[] = {
 	/* FrontEnd DAI Links */
@@ -1061,6 +1165,30 @@
 		.no_pcm = 1,
 		.be_id = MSM_BACKEND_DAI_AFE_PCM_TX,
 	},
+	/* AUX PCM Backend DAI Links */
+	{
+		.name = LPASS_BE_AUXPCM_RX,
+		.stream_name = "AUX PCM Playback",
+		.cpu_dai_name = "msm-dai-q6.2",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-rx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_AUXPCM_RX,
+		.be_hw_params_fixup = msm8930_auxpcm_be_params_fixup,
+		.ops = &msm8930_auxpcm_be_ops,
+	},
+	{
+		.name = LPASS_BE_AUXPCM_TX,
+		.stream_name = "AUX PCM Capture",
+		.cpu_dai_name = "msm-dai-q6.3",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-tx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_AUXPCM_TX,
+		.be_hw_params_fixup = msm8930_auxpcm_be_params_fixup,
+	},
 	/* Incall Music BACK END DAI Link */
 	{
 		.name = LPASS_BE_VOICE_PLAYBACK_TX,