aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/samsung/fimc/fimc_dev_u1.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/samsung/fimc/fimc_dev_u1.c')
-rw-r--r--drivers/media/video/samsung/fimc/fimc_dev_u1.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/drivers/media/video/samsung/fimc/fimc_dev_u1.c b/drivers/media/video/samsung/fimc/fimc_dev_u1.c
index 811ac96..52246a1 100644
--- a/drivers/media/video/samsung/fimc/fimc_dev_u1.c
+++ b/drivers/media/video/samsung/fimc/fimc_dev_u1.c
@@ -745,6 +745,50 @@ static struct vm_operations_struct fimc_mmap_ops = {
};
static inline
+int fimc_mmap_own_mem(struct file *filp, struct vm_area_struct *vma)
+{
+ struct fimc_prv_data *prv_data =
+ (struct fimc_prv_data *)filp->private_data;
+ struct fimc_control *ctrl = prv_data->ctrl;
+ u32 start_phy_addr = 0;
+ u32 size = vma->vm_end - vma->vm_start;
+ u32 pfn, idx = vma->vm_pgoff;
+ u32 buf_length = 0;
+
+ buf_length = ctrl->mem.size;
+ if (size > PAGE_ALIGN(buf_length)) {
+ fimc_err("Requested mmap size is too big\n");
+ return -EINVAL;
+ }
+
+ start_phy_addr = ctrl->mem.base + (vma->vm_pgoff << PAGE_SHIFT);
+
+ if (!cma_is_registered_region(start_phy_addr, size)) {
+ pr_err("[%s] handling non-cma region (%#x@%#x)is prohibited\n",
+ __func__, buf_length, start_phy_addr);
+ return -EINVAL;
+ }
+
+ /* only supports non-cached mmap */
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_flags |= VM_RESERVED;
+
+ if ((vma->vm_flags & VM_WRITE) && !(vma->vm_flags & VM_SHARED)) {
+ fimc_err("writable mapping must be shared\n");
+ return -EINVAL;
+ }
+
+ pfn = __phys_to_pfn(start_phy_addr);
+
+ if (remap_pfn_range(vma, vma->vm_start, pfn, size, vma->vm_page_prot)) {
+ fimc_err("mmap fail\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static inline
int fimc_mmap_out_src(struct file *filp, struct vm_area_struct *vma)
{
struct fimc_prv_data *prv_data =
@@ -829,10 +873,14 @@ static inline int fimc_mmap_out(struct file *filp, struct vm_area_struct *vma)
int idx = ctrl->out->ctx[ctx_id].overlay.req_idx;
int ret = -1;
+#if 0
if (idx >= 0)
ret = fimc_mmap_out_dst(filp, vma, idx);
else if (idx == FIMC_MMAP_IDX)
ret = fimc_mmap_out_src(filp, vma);
+#else
+ ret = fimc_mmap_own_mem(filp, vma);
+#endif
return ret;
}
@@ -849,6 +897,12 @@ static inline int fimc_mmap_cap(struct file *filp, struct vm_area_struct *vma)
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
vma->vm_flags |= VM_RESERVED;
+ if (!cma_is_registered_region(ctrl->cap->bufs[idx].base[0], size)) {
+ pr_err("[%s] handling non-cma region (%#x@%#x)is prohibited\n",
+ __func__, size, ctrl->cap->bufs[idx].base[0]);
+ return -EINVAL;
+ }
+
/*
* page frame number of the address for a source frame
* to be stored at.