msm camera: separate daemon pmem mapping away from video node
Signed-off-by: Mingcheng Zhu <mingchen@codeaurora.org>
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 53d835f..b94bd1b 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -71,7 +71,7 @@
/* 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)
+ unsigned int notification, void *arg)
{
struct msm_cam_v4l2_device *pcam;
@@ -313,10 +313,10 @@
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.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.config_ident = g_server_dev.config_info.config_dev_id[0];
@@ -380,7 +380,7 @@
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);
- pr_err("%s: msm_server_control rc=%d\n", __func__, rc);
+ 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,
@@ -400,7 +400,7 @@
}
}
end:
- pr_err("%s: END, type = %d, vaddr = 0x%x, vlen = %d, status = %d, rc = %d\n",
+ 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);
@@ -495,16 +495,16 @@
{
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->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;
+ pix->colorspace = pcam->dev_inst[idx]->vid_fmt.fmt.pix.colorspace;
if (pix->bytesperline < 0)
return pix->bytesperline;
- pix->sizeimage = pix->height * pix->bytesperline;
+ pix->sizeimage = pix->height * pix->bytesperline;
return 0;
}
@@ -544,10 +544,10 @@
sensor_fmt.colorspace = pix->colorspace;
sensor_fmt.code = pcam->usr_fmts[i].pxlcode;
- pix->width = sensor_fmt.width;
- pix->height = sensor_fmt.height;
- pix->field = sensor_fmt.field;
- pix->colorspace = sensor_fmt.colorspace;
+ pix->width = sensor_fmt.width;
+ pix->height = sensor_fmt.height;
+ pix->field = sensor_fmt.field;
+ pix->colorspace = sensor_fmt.colorspace;
return rc;
}
@@ -641,7 +641,7 @@
mutex_lock(&pcam->vid_lock);
switch (ctrl->id) {
case MSM_V4L2_PID_MMAP_INST:
- pr_err("%s: mmap_inst=(0x%p, %d)\n",
+ D("%s: mmap_inst=(0x%p, %d)\n",
__func__, pcam_inst, pcam->remap_index);
pcam->remap_index = pcam_inst->my_index;
break;
@@ -651,7 +651,7 @@
sizeof(pcam->mmap_entry))) {
rc = -EFAULT;
} else
- pr_err("%s:mmap entry:phy=0x%x,image_mode=%d,op_mode=%d\n",
+ D("%s:mmap entry:phy=0x%x,image_mode=%d,op_mode=%d\n",
__func__, pcam->mmap_entry.phy_addr,
pcam->mmap_entry.image_mode,
pcam->mmap_entry.op_mode);
@@ -1676,30 +1676,29 @@
switch (cmd) {
/* memory management shall be handeld here*/
case MSM_CAM_IOCTL_REGISTER_PMEM:
- return msm_register_pmem(
+ return msm_register_pmem(
&config_cam->p_mctl->sync.pmem_stats,
(void __user *)arg);
- break;
+ break;
case MSM_CAM_IOCTL_UNREGISTER_PMEM:
- return msm_pmem_table_del(
+ return msm_pmem_table_del(
&config_cam->p_mctl->sync.pmem_stats,
(void __user *)arg);
- break;
+ break;
case VIDIOC_SUBSCRIBE_EVENT:
- if (copy_from_user(&temp_sub,
+ if (copy_from_user(&temp_sub,
(void __user *)arg,
sizeof(struct v4l2_event_subscription))) {
rc = -EINVAL;
return rc;
- }
- rc = msm_server_v4l2_subscribe_event
+ }
+ rc = msm_server_v4l2_subscribe_event
(&config_cam->config_stat_event_queue.eventHandle,
&temp_sub);
- if (rc < 0)
- return rc;
-
- break;
+ if (rc < 0)
+ return rc;
+ break;
case VIDIOC_UNSUBSCRIBE_EVENT:
if (copy_from_user(&temp_sub, (void __user *)arg,
@@ -1712,7 +1711,6 @@
&temp_sub);
if (rc < 0)
return rc;
-
break;
case VIDIOC_DQEVENT: {
@@ -1767,6 +1765,12 @@
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;
@@ -1783,6 +1787,40 @@
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;
@@ -1821,9 +1859,9 @@
};
/* Init a config node for ISP control,
- which will create a config device (/dev/config0/ and plug in
- ISP's operation "v4l2_ioctl_ops*"
-*/
+ * which will create a config device (/dev/config0/ and plug in
+ * ISP's operation "v4l2_ioctl_ops*"
+ */
static const struct file_operations msm_fops_server = {
.owner = THIS_MODULE,
.open = msm_open_server,
@@ -1836,10 +1874,11 @@
.open = msm_open_config,
.poll = msm_poll_config,
.unlocked_ioctl = msm_ioctl_config,
+ .mmap = msm_mmap_config,
};
static int msm_setup_v4l2_event_queue(struct v4l2_fh *eventHandle,
- struct video_device *pvdev)
+ struct video_device *pvdev)
{
int rc = 0;
/* v4l2_fh support */
@@ -1884,7 +1923,7 @@
devno = MKDEV(MAJOR(msm_devno), dev_num+1);
device_config = device_create(msm_class, NULL, devno, NULL,
- "%s%d", device_name, dev_num);
+ "%s%d", device_name, dev_num);
if (IS_ERR(device_config)) {
rc = PTR_ERR(device_config);
@@ -1893,7 +1932,7 @@
}
cdev_init(&config_cam->config_cdev,
- &msm_fops_config);
+ &msm_fops_config);
config_cam->config_cdev.owner = THIS_MODULE;
rc = cdev_add(&config_cam->config_cdev, devno, 1);
@@ -2012,8 +2051,8 @@
/* register v4l2 video device to kernel as /dev/videoXX */
D("video_register_device\n");
rc = video_register_device(pvdev,
- VFL_TYPE_GRABBER,
- msm_camera_v4l2_nr);
+ VFL_TYPE_GRABBER,
+ msm_camera_v4l2_nr);
if (rc) {
pr_err("%s: video_register_device failed\n", __func__);
goto reg_fail;
@@ -2025,10 +2064,12 @@
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! */
+ /* 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; */
@@ -2065,8 +2106,8 @@
}
/* register a msm sensor into the msm device, which will probe the
- sensor HW. if the HW exist then create a video device (/dev/videoX/)
- to represent this sensor */
+ * sensor HW. if the HW exist then create a video device (/dev/videoX/)
+ * to represent this sensor */
int msm_sensor_register(struct platform_device *pdev,
int (*sensor_probe)(const struct msm_camera_sensor_info *,
struct v4l2_subdev *, struct msm_sensor_ctrl *))
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index fb156e7..29a6519 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -310,6 +310,7 @@
int use_count;
/*struct msm_isp_ops* isp_subdev;*/
struct msm_cam_media_controller *p_mctl;
+ struct msm_mem_map_info mem_map;
};
/* abstract camera server device for all sensor successfully probed*/
@@ -333,7 +334,7 @@
uint8_t ctrl_data[max_control_command_size];
struct msm_ctrl_cmd ctrl;
int use_count;
- /* all the registered ISP subdevice*/
+ /* all the registered ISP subdevice*/
struct msm_isp_ops *isp_subdev[MSM_MAX_CAMERA_CONFIGS];
};
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 882d987..5a20d87 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -138,6 +138,9 @@
#define MSM_CAM_IOCTL_V4L2_EVT_NOTIFY \
_IOR(MSM_CAM_IOCTL_MAGIC, 41, struct v4l2_event *)
+#define MSM_CAM_IOCTL_SET_MEM_MAP_INFO \
+ _IOR(MSM_CAM_IOCTL_MAGIC, 42, struct msm_mem_map_info *)
+
#define MSM_CAMERA_LED_OFF 0
#define MSM_CAMERA_LED_LOW 1
#define MSM_CAMERA_LED_HIGH 2
@@ -418,6 +421,11 @@
uint32_t idx; /* v4l2 buffer index */
};
+struct msm_mem_map_info {
+ uint32_t cookie;
+ uint32_t length;
+};
+
#define MSM_MEM_MMAP 0
#define MSM_MEM_USERPTR 1
#define MSM_PLANE_MAX 8