Merge "msm_fb: display: Create hdmi_as_primary node for boot parameter case" into msm-3.0
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 3384b48..2bc922a 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -53,6 +53,7 @@
 CONFIG_MACH_APQ8064_CDP=y
 CONFIG_MACH_APQ8064_MTP=y
 CONFIG_MACH_APQ8064_LIQUID=y
+CONFIG_MACH_MPQ8064_CDP=y
 CONFIG_MACH_MPQ8064_HRD=y
 CONFIG_MACH_MPQ8064_DTV=y
 # CONFIG_MSM_STACKED_MEMORY is not set
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index c186be4..71ad4ba 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -52,6 +52,7 @@
 CONFIG_MACH_APQ8064_CDP=y
 CONFIG_MACH_APQ8064_MTP=y
 CONFIG_MACH_APQ8064_LIQUID=y
+CONFIG_MACH_MPQ8064_CDP=y
 CONFIG_MACH_MPQ8064_HRD=y
 CONFIG_MACH_MPQ8064_DTV=y
 # CONFIG_MSM_STACKED_MEMORY is not set
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index ad4f12a..e4e2653 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -781,6 +781,12 @@
 	help
 	  Support for the Qualcomm APQ8064 LIQUID device.
 
+config MACH_MPQ8064_CDP
+	depends on ARCH_APQ8064
+	bool "MPQ8064 CDP"
+	help
+	  Support for the Qualcomm MPQ8064 CDP device.
+
 config MACH_MPQ8064_HRD
 	depends on ARCH_APQ8064
 	bool "MPQ8064 HRD"
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 93cfc099..73f02f5 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -2370,6 +2370,17 @@
 	.init_very_early = apq8064_early_reserve,
 MACHINE_END
 
+MACHINE_START(MPQ8064_CDP, "QCT MPQ8064 CDP")
+	.map_io = apq8064_map_io,
+	.reserve = apq8064_reserve,
+	.init_irq = apq8064_init_irq,
+	.handle_irq = gic_handle_irq,
+	.timer = &msm_timer,
+	.init_machine = apq8064_cdp_init,
+	.init_early = apq8064_allocate_memory_regions,
+	.init_very_early = apq8064_early_reserve,
+MACHINE_END
+
 MACHINE_START(MPQ8064_HRD, "QCT MPQ8064 HRD")
 	.map_io = apq8064_map_io,
 	.reserve = apq8064_reserve,
diff --git a/arch/arm/mach-msm/devices-iommu.c b/arch/arm/mach-msm/devices-iommu.c
index 96ee564..29e8180 100644
--- a/arch/arm/mach-msm/devices-iommu.c
+++ b/arch/arm/mach-msm/devices-iommu.c
@@ -364,11 +364,13 @@
 static struct msm_iommu_dev gfx3d_iommu = {
 	.name = "gfx3d",
 	.ncb = 3,
+	.ttbr_split = 2,
 };
 
 static struct msm_iommu_dev gfx3d1_iommu = {
 	.name = "gfx3d1",
 	.ncb = 3,
+	.ttbr_split = 2,
 };
 
 static struct msm_iommu_dev gfx2d0_iommu = {
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h
index d5a2ed4..994150f 100644
--- a/arch/arm/mach-msm/include/mach/iommu.h
+++ b/arch/arm/mach-msm/include/mach/iommu.h
@@ -41,6 +41,7 @@
 struct msm_iommu_dev {
 	const char *name;
 	int ncb;
+	int ttbr_split;
 };
 
 /**
@@ -74,6 +75,7 @@
 	void __iomem *base;
 	int irq;
 	int ncb;
+	int ttbr_split;
 	struct clk *clk;
 	struct clk *pclk;
 	const char *name;
diff --git a/arch/arm/mach-msm/iommu.c b/arch/arm/mach-msm/iommu.c
index a310ba0..d495c1b 100644
--- a/arch/arm/mach-msm/iommu.c
+++ b/arch/arm/mach-msm/iommu.c
@@ -176,7 +176,8 @@
 }
 
 static void __program_context(void __iomem *base, int ctx, int ncb,
-			      phys_addr_t pgtable, int redirect)
+			      phys_addr_t pgtable, int redirect,
+			      int ttbr_split)
 {
 	unsigned int prrr, nmrr;
 	int i, j, found;
@@ -189,8 +190,10 @@
 	/* V2P configuration: HTW for access */
 	SET_V2PCFG(base, ctx, 0x3);
 
-	SET_TTBCR(base, ctx, 0);
+	SET_TTBCR(base, ctx, ttbr_split);
 	SET_TTBR0_PA(base, ctx, (pgtable >> TTBR0_PA_SHIFT));
+	if (ttbr_split)
+		SET_TTBR1_PA(base, ctx, (pgtable >> TTBR1_PA_SHIFT));
 
 	/* Enable context fault interrupt */
 	SET_CFEIE(base, ctx, 1);
@@ -365,7 +368,8 @@
 		goto fail;
 
 	__program_context(iommu_drvdata->base, ctx_dev->num, iommu_drvdata->ncb,
-			  __pa(priv->pgtable), priv->redirect);
+			  __pa(priv->pgtable), priv->redirect,
+			  iommu_drvdata->ttbr_split);
 
 	__disable_clocks(iommu_drvdata);
 	list_add(&(ctx_drvdata->attached_elm), &priv->list_attached);
diff --git a/arch/arm/mach-msm/iommu_dev.c b/arch/arm/mach-msm/iommu_dev.c
index 70e96b0..6633cae 100644
--- a/arch/arm/mach-msm/iommu_dev.c
+++ b/arch/arm/mach-msm/iommu_dev.c
@@ -239,6 +239,7 @@
 	drvdata->base = regs_base;
 	drvdata->irq = irq;
 	drvdata->ncb = iommu_dev->ncb;
+	drvdata->ttbr_split = iommu_dev->ttbr_split;
 	drvdata->name = iommu_dev->name;
 
 	pr_info("device %s mapped at %p, irq %d with %d ctx banks\n",
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index cde8031..0ff30c3 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -1136,6 +1136,7 @@
 apq8064_cdp		MACH_APQ8064_CDP	APQ8064_CDP		3948
 apq8064_mtp		MACH_APQ8064_MTP	APQ8064_MTP		3949
 apq8064_liquid		MACH_APQ8064_LIQUID	APQ8064_LIQUID		3951
+mpq8064_cdp		MACH_MPQ8064_CDP	MPQ8064_CDP		3993
 mpq8064_hrd		MACH_MPQ8064_HRD	MPQ8064_HRD		3994
 mpq8064_dtv		MACH_MPQ8064_DTV	MPQ8064_DTV		3995
 msm7627a_qrd3		MACH_MSM7627A_QRD3	MSM7627A_QRD3		4005
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 175a441..8d59590 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -1366,6 +1366,14 @@
 		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);
@@ -1411,6 +1419,9 @@
 {
 	int i;
 	int rc = -EINVAL;
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	int ion_client_created = 0;
+#endif
 	/*struct msm_isp_ops *p_isp = 0;*/
 	/* get the video device */
 	struct msm_cam_v4l2_device *pcam  = video_drvdata(f);
@@ -1442,7 +1453,9 @@
 	pcam_inst->pcam = pcam;
 	pcam->dev_inst[i] = pcam_inst;
 
-	D("%s for %s\n", __func__, pcam->pdev->name);
+	D("%s index %d nodeid %d count %d\n", __func__,
+			pcam_inst->my_index,
+			pcam->vnode_id, pcam->use_count);
 	pcam->use_count++;
 	if (pcam->use_count == 1) {
 
@@ -1450,19 +1463,19 @@
 		if (rc < 0) {
 			pr_err("%s: cam_server_open_session failed %d\n",
 			__func__, rc);
-			mutex_unlock(&pcam->vid_lock);
-			return rc;
+			goto err;
 		}
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 		pcam->mctl.client = msm_ion_client_create(-1, "camera");
 		kref_init(&pcam->mctl.refcount);
+		ion_client_created = 1;
 #endif
 		/* Should be set to sensor ops if any but right now its OK!! */
 		if (!pcam->mctl.mctl_open) {
 			D("%s: media contoller is not inited\n",
 				 __func__);
-			mutex_unlock(&pcam->vid_lock);
-			return -ENODEV;
+			rc = -ENODEV;
+			goto err;
 		}
 
 		/* Now we really have to activate the camera */
@@ -1470,9 +1483,8 @@
 		rc = pcam->mctl.mctl_open(&(pcam->mctl), MSM_APPS_ID_V4L2);
 
 		if (rc < 0) {
-			mutex_unlock(&pcam->vid_lock);
 			pr_err("%s: HW open failed rc = 0x%x\n",  __func__, rc);
-			return rc;
+			goto err;
 		}
 		pcam->mctl.sync.pcam_sync = pcam;
 
@@ -1480,24 +1492,21 @@
 		rc = v4l2_device_register_subdev(&pcam->v4l2_dev,
 					pcam->mctl.isp_sdev->sd);
 		if (rc < 0) {
-			mutex_unlock(&pcam->vid_lock);
 			pr_err("%s: v4l2_device_register_subdev failed rc = %d\n",
 				__func__, rc);
-			return rc;
+			goto err;
 		}
 		if (pcam->mctl.isp_sdev->sd_vpe) {
 			rc = v4l2_device_register_subdev(&pcam->v4l2_dev,
 						pcam->mctl.isp_sdev->sd_vpe);
 			if (rc < 0) {
-				mutex_unlock(&pcam->vid_lock);
-				return rc;
+				goto err;
 			}
 		}
 		rc = msm_setup_v4l2_event_queue(&pcam_inst->eventHandle,
 							pcam->pvdev);
 		if (rc < 0) {
-			mutex_unlock(&pcam->vid_lock);
-			return rc;
+			goto err;
 		}
 	}
 	pcam_inst->vbqueue_initialized = 0;
@@ -1522,6 +1531,21 @@
 	D("%s: end", __func__);
 	/* rc = msm_cam_server_open_session(g_server_dev, pcam);*/
 	return rc;
+
+err:
+	if (pcam->use_count == 1) {
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		if (ion_client_created) {
+			pr_err("%s: destroy ion client", __func__);
+			kref_put(&pcam->mctl.refcount, msm_release_ion_client);
+		}
+#endif
+		pcam->dev_inst[i] = NULL;
+		pcam->use_count = 0;
+	}
+	mutex_unlock(&pcam->vid_lock);
+	kfree(pcam_inst);
+	return rc;
 }
 
 static int msm_addr_remap(struct msm_cam_v4l2_dev_inst *pcam_inst,
@@ -1622,6 +1646,8 @@
 	if (pcam_inst->vbqueue_initialized)
 		vb2_queue_release(&pcam_inst->vid_bufq);
 	D("%s Closing down instance %p ", __func__, pcam_inst);
+	D("%s index %d nodeid %d count %d\n", __func__, pcam_inst->my_index,
+		pcam->vnode_id, pcam->use_count);
 	pcam->dev_inst[pcam_inst->my_index] = NULL;
 	if (pcam_inst->my_index == 0) {
 		v4l2_fh_del(&pcam_inst->eventHandle);
@@ -2638,7 +2664,7 @@
 
 	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);
+		g_server_dev.camera_info.num_cameras);
 
 	/* register the subdevice, must be done for callbacks */
 	rc = v4l2_device_register_subdev(&pcam->v4l2_dev, sensor_sd);
diff --git a/include/linux/mfd/pm8xxx/misc.h b/include/linux/mfd/pm8xxx/misc.h
index c90d8d1..77683ce 100644
--- a/include/linux/mfd/pm8xxx/misc.h
+++ b/include/linux/mfd/pm8xxx/misc.h
@@ -79,7 +79,7 @@
 };
 
 enum pm8xxx_aux_clk_div {
-	X0_DIV_NONE,
+	XO_DIV_NONE,
 	XO_DIV_1,
 	XO_DIV_2,
 	XO_DIV_4,