OSDN Git Service

msm: camera: isp: Allocate kernel page and map to userspace
authorLokesh Kumar Aakulu <lkumar@codeaurora.org>
Tue, 14 Nov 2017 12:19:55 +0000 (17:49 +0530)
committerLokesh Kumar Aakulu <lkumar@codeaurora.org>
Tue, 14 Nov 2017 16:40:03 +0000 (22:10 +0530)
Share memory with kernel and user and update latest
kernel sof frame id.

Change-Id: Ie35132ffb9bd0298483b451b3333b3b2e3bb32ac
Signed-off-by: Lokesh Kumar Aakulu <lkumar@codeaurora.org>
drivers/media/platform/msm/camera_v2/isp/msm_isp.c
drivers/media/platform/msm/camera_v2/isp/msm_isp.h
drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c

index 22eb86f..23e27e1 100644 (file)
@@ -453,11 +453,69 @@ static long msm_isp_v4l2_fops_ioctl(struct file *file, unsigned int cmd,
        return video_usercopy(file, cmd, arg, msm_isp_subdev_do_ioctl);
 }
 
+static void isp_vma_open(struct vm_area_struct *vma)
+{
+       pr_debug("%s: open called\n", __func__);
+}
+
+static void isp_vma_close(struct vm_area_struct *vma)
+{
+       pr_debug("%s: close called\n", __func__);
+}
+
+static int isp_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+       struct page *page;
+       struct vfe_device *vfe_dev = vma->vm_private_data;
+       struct isp_proc *isp_page = NULL;
+
+       isp_page = vfe_dev->isp_page;
+
+       pr_debug("%s: vfeid:%d u_virt_addr:0x%lx k_virt_addr:%pK\n",
+               __func__, vfe_dev->pdev->id, vma->vm_start,
+               (void *)isp_page);
+       if (isp_page != NULL) {
+               page = virt_to_page(isp_page);
+               get_page(page);
+               vmf->page = page;
+               isp_page->kernel_sofid =
+                       vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
+               isp_page->vfeid = vfe_dev->pdev->id;
+       }
+       return 0;
+}
+
+static const struct vm_operations_struct isp_vm_ops = {
+       .open = isp_vma_open,
+       .close = isp_vma_close,
+       .fault = isp_vma_fault,
+};
+
+static int msm_isp_v4l2_fops_mmap(struct file *filep,
+       struct vm_area_struct *vma)
+{
+       int ret =  -EINVAL;
+       struct video_device *vdev = video_devdata(filep);
+       struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
+       struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd);
+
+       vma->vm_ops = &isp_vm_ops;
+       vma->vm_flags |=
+               (unsigned long)(VM_DONTEXPAND | VM_DONTDUMP);
+       vma->vm_private_data = vfe_dev;
+       isp_vma_open(vma);
+       ret = 0;
+       pr_debug("%s: isp mmap is called vm_start: 0x%lx\n",
+               __func__, vma->vm_start);
+       return ret;
+}
+
 static struct v4l2_file_operations msm_isp_v4l2_fops = {
 #ifdef CONFIG_COMPAT
        .compat_ioctl32 = msm_isp_v4l2_fops_ioctl,
 #endif
-       .unlocked_ioctl = msm_isp_v4l2_fops_ioctl
+       .unlocked_ioctl = msm_isp_v4l2_fops_ioctl,
+       .mmap = msm_isp_v4l2_fops_mmap
 };
 
 static int vfe_set_common_data(struct platform_device *pdev)
@@ -671,6 +729,8 @@ int vfe_hw_probe(struct platform_device *pdev)
        msm_isp_v4l2_fops.compat_ioctl32 =
                msm_isp_v4l2_fops_ioctl;
 #endif
+       msm_isp_v4l2_fops.mmap = msm_isp_v4l2_fops_mmap;
+
        vfe_dev->subdev.sd.devnode->fops = &msm_isp_v4l2_fops;
 
        vfe_dev->buf_mgr = &vfe_buf_mgr;
@@ -687,6 +747,14 @@ int vfe_hw_probe(struct platform_device *pdev)
        msm_isp_enable_debugfs(vfe_dev, msm_isp_bw_request_history);
        vfe_dev->buf_mgr->init_done = 1;
        vfe_dev->vfe_open_cnt = 0;
+       /*Allocate a page in kernel and map it to camera user process*/
+       vfe_dev->isp_page = (struct isp_proc *)get_zeroed_page(GFP_KERNEL);
+       if (vfe_dev->isp_page == NULL) {
+               pr_err("%s: no enough memory\n", __func__);
+               rc = -ENOMEM;
+               goto probe_fail3;
+       }
+       vfe_dev->isp_page->vfeid = vfe_dev->pdev->id;
        return rc;
 
 probe_fail3:
index b2d152b..d336e1e 100644 (file)
@@ -759,6 +759,11 @@ struct msm_vfe_common_subdev {
        struct msm_vfe_common_dev_data *common_data;
 };
 
+struct isp_proc {
+       uint32_t  kernel_sofid;
+       uint32_t  vfeid;
+};
+
 struct vfe_device {
        /* Driver private data */
        struct platform_device *pdev;
@@ -842,6 +847,7 @@ struct vfe_device {
        uint32_t recovery_irq1_mask;
        /* total bandwidth per vfe */
        uint64_t total_bandwidth;
+       struct isp_proc *isp_page;
 };
 
 struct vfe_parent_device {
index 5bcb303..7bb36d9 100644 (file)
@@ -933,6 +933,8 @@ void msm_isp_increment_frame_id(struct vfe_device *vfe_dev,
        }
 
        if (frame_src == VFE_PIX_0) {
+               vfe_dev->isp_page->kernel_sofid =
+                       vfe_dev->axi_data.src_info[frame_src].frame_id;
                if (!src_info->frame_id &&
                        !src_info->reg_update_frame_id &&
                        ((src_info->frame_id -