msm-camera: add SMMU code for use with videobuf2 framework

Signed-off-by: Ankit Premrajka <ankitp@codeaurora.org>
Signed-off-by: Mingcheng Zhu <mingchen@codeaurora.org>
diff --git a/drivers/media/video/videobuf2-msm-mem.c b/drivers/media/video/videobuf2-msm-mem.c
index 13fbd1f..3b460ef 100644
--- a/drivers/media/video/videobuf2-msm-mem.c
+++ b/drivers/media/video/videobuf2-msm-mem.c
@@ -29,7 +29,7 @@
 #include <media/videobuf2-msm-mem.h>
 #include <media/msm_camera.h>
 #include <mach/memory.h>
-
+#include <mach/msm_subsystem_map.h>
 #include <media/videobuf2-core.h>
 
 #define MAGIC_PMEM 0x0733ac64
@@ -82,6 +82,8 @@
 static void *msm_vb2_mem_ops_alloc(void *alloc_ctx, unsigned long size)
 {
 	struct videobuf2_contig_pmem *mem;
+	unsigned int flags = 0;
+	long rc;
 	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
 	if (!mem)
 		return ERR_PTR(-ENOMEM);
@@ -96,13 +98,28 @@
 		kfree(mem);
 		return ERR_PTR(-ENOMEM);
 	}
+	flags = MSM_SUBSYSTEM_MAP_IOVA;
+	mem->subsys_id = MSM_SUBSYSTEM_CAMERA;
+	mem->msm_buffer = msm_subsystem_map_buffer(mem->phyaddr, mem->size,
+					flags, &(mem->subsys_id), 1);
+	if (IS_ERR((void *)mem->msm_buffer)) {
+		pr_err("%s: msm_subsystem_map_buffer failed\n", __func__);
+		rc = PTR_ERR((void *)mem->msm_buffer);
+		msm_mem_free(mem->phyaddr);
+		kfree(mem);
+		return ERR_PTR(-ENOMEM);
+	}
 	return mem;
 }
 static void msm_vb2_mem_ops_put(void *buf_priv)
 {
 	struct videobuf2_contig_pmem *mem = buf_priv;
-	if (!mem->is_userptr)
+	if (!mem->is_userptr) {
+		D("%s Freeing memory ", __func__);
+		if (msm_subsystem_unmap_buffer(mem->msm_buffer) < 0)
+			D("%s unmapped memory\n", __func__);
 		msm_mem_free(mem->phyaddr);
+	}
 	kfree(mem);
 }
 int videobuf2_pmem_contig_mmap_get(struct videobuf2_contig_pmem *mem,
@@ -133,6 +150,7 @@
 	unsigned long kvstart;
 	unsigned long len;
 	int rc;
+	unsigned int flags = 0;
 
 	if (mem->phyaddr != 0)
 		return 0;
@@ -148,12 +166,23 @@
 	mem->y_off = yoffset;
 	mem->cbcr_off = cbcroffset;
 	mem->buffer_type = path;
+	flags = MSM_SUBSYSTEM_MAP_IOVA;
+	mem->subsys_id = MSM_SUBSYSTEM_CAMERA;
+	mem->msm_buffer = msm_subsystem_map_buffer(mem->phyaddr, mem->size,
+					flags, &(mem->subsys_id), 1);
+	if (IS_ERR((void *)mem->msm_buffer)) {
+		pr_err("%s: msm_subsystem_map_buffer failed\n", __func__);
+		put_pmem_file(mem->file);
+		return PTR_ERR((void *)mem->msm_buffer);
+	}
 	return rc;
 }
 EXPORT_SYMBOL_GPL(videobuf2_pmem_contig_user_get);
 
 void videobuf2_pmem_contig_user_put(struct videobuf2_contig_pmem *mem)
 {
+	if (msm_subsystem_unmap_buffer(mem->msm_buffer) < 0)
+		D("%s unmapped memory\n", __func__);
 	if (mem->is_userptr)
 		put_pmem_file(mem->file);
 	mem->is_userptr = 0;
@@ -206,7 +235,6 @@
 	D("mem = 0x%x\n", (u32)mem);
 	BUG_ON(!mem);
 	MAGIC_CHECK(mem->magic, MAGIC_PMEM);
-
 	/* Try to remap memory */
 	size = vma->vm_end - vma->vm_start;
 	size = (size < mem->size) ? size : mem->size;
@@ -261,13 +289,14 @@
 }
 EXPORT_SYMBOL_GPL(videobuf2_queue_pmem_contig_init);
 
-int videobuf2_to_pmem_contig(struct vb2_buffer *vb, unsigned int plane_no)
+unsigned long videobuf2_to_pmem_contig(struct vb2_buffer *vb,
+				unsigned int plane_no)
 {
 	struct videobuf2_contig_pmem *mem;
 	mem = vb2_plane_cookie(vb, plane_no);
 	BUG_ON(!mem);
 	MAGIC_CHECK(mem->magic, MAGIC_PMEM);
-	return mem->phyaddr;
+	return mem->msm_buffer->iova[0];
 }
 EXPORT_SYMBOL_GPL(videobuf2_to_pmem_contig);