diff options
| -rw-r--r-- | drivers/media/platform/msm/camera_v2/camera/camera.c | 87 | ||||
| -rw-r--r-- | drivers/media/platform/msm/camera_v2/fd/Makefile | 3 | ||||
| -rw-r--r-- | drivers/media/platform/msm/camera_v2/msm.c | 22 | ||||
| -rw-r--r-- | drivers/media/platform/msm/camera_v2/msm.h | 5 | ||||
| -rw-r--r-- | drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c | 319 | ||||
| -rw-r--r-- | drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h | 12 | ||||
| -rw-r--r-- | drivers/media/platform/msm/camera_v2/msm_sd.h | 5 | ||||
| -rw-r--r-- | drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c | 79 | ||||
| -rw-r--r-- | drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.h | 4 | ||||
| -rw-r--r-- | include/uapi/media/msmb_camera.h | 19 | ||||
| -rw-r--r-- | include/uapi/media/msmb_generic_buf_mgr.h | 7 |
11 files changed, 510 insertions, 52 deletions
diff --git a/drivers/media/platform/msm/camera_v2/camera/camera.c b/drivers/media/platform/msm/camera_v2/camera/camera.c index 60a834588767..c1aeb8c43e81 100644 --- a/drivers/media/platform/msm/camera_v2/camera/camera.c +++ b/drivers/media/platform/msm/camera_v2/camera/camera.c @@ -475,6 +475,38 @@ static int camera_v4l2_unsubscribe_event(struct v4l2_fh *fh, return rc; } +static long camera_v4l2_vidioc_private_ioctl(struct file *filep, void *fh, + bool valid_prio, unsigned int cmd, void *arg) +{ + struct camera_v4l2_private *sp = fh_to_private(fh); + struct msm_video_device *pvdev = video_drvdata(filep); + struct msm_camera_private_ioctl_arg *k_ioctl = arg; + long rc = -EINVAL; + + if (WARN_ON(!k_ioctl || !pvdev)) + return -EIO; + + switch (k_ioctl->id) { + case MSM_CAMERA_PRIV_IOCTL_ID_RETURN_BUF: { + struct msm_camera_return_buf ptr, *tmp = NULL; + + MSM_CAM_GET_IOCTL_ARG_PTR(&tmp, &k_ioctl->ioctl_ptr, + sizeof(tmp)); + if (copy_from_user(&ptr, tmp, + sizeof(struct msm_camera_return_buf))) { + return -EFAULT; + } + rc = msm_vb2_return_buf_by_idx(pvdev->vdev->num, sp->stream_id, + ptr.index); + } + break; + default: + pr_debug("unimplemented id %d", k_ioctl->id); + return -EINVAL; + } + return rc; +} + static const struct v4l2_ioctl_ops camera_v4l2_ioctl_ops = { .vidioc_querycap = camera_v4l2_querycap, .vidioc_s_crop = camera_v4l2_s_crop, @@ -499,6 +531,7 @@ static const struct v4l2_ioctl_ops camera_v4l2_ioctl_ops = { /* event subscribe/unsubscribe */ .vidioc_subscribe_event = camera_v4l2_subscribe_event, .vidioc_unsubscribe_event = camera_v4l2_unsubscribe_event, + .vidioc_default = camera_v4l2_vidioc_private_ioctl, }; static int camera_v4l2_fh_open(struct file *filep) @@ -747,10 +780,62 @@ static int camera_v4l2_close(struct file *filep) } #ifdef CONFIG_COMPAT +static long camera_handle_internal_compat_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + long rc = 0; + struct msm_camera_private_ioctl_arg k_ioctl; + void __user *tmp_compat_ioctl_ptr = NULL; + + rc = msm_copy_camera_private_ioctl_args(arg, + &k_ioctl, &tmp_compat_ioctl_ptr); + if (rc < 0) { + pr_err("Subdev cmd %d failed\n", cmd); + return rc; + } + switch (k_ioctl.id) { + case MSM_CAMERA_PRIV_IOCTL_ID_RETURN_BUF: { + if (k_ioctl.size != sizeof(struct msm_camera_return_buf)) { + pr_debug("Invalid size for id %d with size %d", + k_ioctl.id, k_ioctl.size); + return -EINVAL; + } + k_ioctl.ioctl_ptr = (__u64)tmp_compat_ioctl_ptr; + if (!k_ioctl.ioctl_ptr) { + pr_debug("Invalid ptr for id %d", k_ioctl.id); + return -EINVAL; + } + rc = camera_v4l2_vidioc_private_ioctl(file, file->private_data, + 0, cmd, (void *)&k_ioctl); + } + break; + default: + pr_debug("unimplemented id %d", k_ioctl.id); + return -EINVAL; + } + return rc; +} + long camera_v4l2_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - return -ENOIOCTLCMD; + long ret = 0; + + switch (cmd) { + case VIDIOC_MSM_CAMERA_PRIVATE_IOCTL_CMD: { + ret = camera_handle_internal_compat_ioctl(file, cmd, arg); + if (ret < 0) { + pr_debug("Subdev cmd %d fail\n", cmd); + return ret; + } + } + break; + default: + ret = -ENOIOCTLCMD; + break; + + } + return ret; } #endif static struct v4l2_file_operations camera_v4l2_fops = { diff --git a/drivers/media/platform/msm/camera_v2/fd/Makefile b/drivers/media/platform/msm/camera_v2/fd/Makefile index 82b37a73bfa3..8d01d3a8708d 100644 --- a/drivers/media/platform/msm/camera_v2/fd/Makefile +++ b/drivers/media/platform/msm/camera_v2/fd/Makefile @@ -1,5 +1,8 @@ GCC_VERSION := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc) ccflags-y += -Idrivers/media/video/msm ccflags-y += -Idrivers/media/platform/msm/camera_v2/common +ccflags-y += -Idrivers/media/platform/msm/camera_v2 +ccflags-y += -Idrivers/media/platform/msm/camera_v2/pproc/cpp +ccflags-y += -Idrivers/media/platform/msm/camera_v2/msm_buf_mgr/ obj-$(CONFIG_MSM_FD) += msm_fd_dev.o msm_fd_hw.o diff --git a/drivers/media/platform/msm/camera_v2/msm.c b/drivers/media/platform/msm/camera_v2/msm.c index a34dbb80b468..c6dc4b75e479 100644 --- a/drivers/media/platform/msm/camera_v2/msm.c +++ b/drivers/media/platform/msm/camera_v2/msm.c @@ -1099,6 +1099,28 @@ struct msm_stream *msm_get_stream_from_vb2q(struct vb2_queue *q) } EXPORT_SYMBOL(msm_get_stream_from_vb2q); +#ifdef CONFIG_COMPAT +long msm_copy_camera_private_ioctl_args(unsigned long arg, + struct msm_camera_private_ioctl_arg *k_ioctl, + void __user **tmp_compat_ioctl_ptr) +{ + struct msm_camera_private_ioctl_arg *up_ioctl_ptr = + (struct msm_camera_private_ioctl_arg *)arg; + + if (WARN_ON(!arg || !k_ioctl || !tmp_compat_ioctl_ptr)) + return -EIO; + + k_ioctl->id = up_ioctl_ptr->id; + k_ioctl->size = up_ioctl_ptr->size; + k_ioctl->result = up_ioctl_ptr->result; + k_ioctl->reserved = up_ioctl_ptr->reserved; + *tmp_compat_ioctl_ptr = compat_ptr(up_ioctl_ptr->ioctl_ptr); + + return 0; +} +EXPORT_SYMBOL(msm_copy_camera_private_ioctl_args); +#endif + static void msm_sd_notify(struct v4l2_subdev *sd, unsigned int notification, void *arg) { diff --git a/drivers/media/platform/msm/camera_v2/msm.h b/drivers/media/platform/msm/camera_v2/msm.h index cab07df2a5bb..2b3576b8edd2 100644 --- a/drivers/media/platform/msm/camera_v2/msm.h +++ b/drivers/media/platform/msm/camera_v2/msm.h @@ -133,4 +133,9 @@ struct vb2_queue *msm_get_stream_vb2q(unsigned int session_id, unsigned int stream_id); struct msm_stream *msm_get_stream_from_vb2q(struct vb2_queue *q); struct msm_session *msm_session_find(unsigned int session_id); +#ifdef CONFIG_COMPAT +long msm_copy_camera_private_ioctl_args(unsigned long arg, + struct msm_camera_private_ioctl_arg *k_ioctl, + void __user **tmp_compat_ioctl_ptr); +#endif #endif /*_MSM_H */ diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c index b6cbdcc32360..ac9a4b2048d1 100644 --- a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c +++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c @@ -48,6 +48,7 @@ static int32_t msm_buf_mngr_hdl_cont_get_buf(struct msm_buf_mngr_device *dev, } return 0; } + static int32_t msm_buf_mngr_get_buf(struct msm_buf_mngr_device *dev, void __user *argp) { @@ -91,6 +92,52 @@ static int32_t msm_buf_mngr_get_buf(struct msm_buf_mngr_device *dev, return rc; } +static int32_t msm_buf_mngr_get_buf_by_idx(struct msm_buf_mngr_device *dev, + void *argp) +{ + unsigned long flags; + int32_t rc = 0; + struct msm_buf_mngr_info *buf_info = + (struct msm_buf_mngr_info *)argp; + struct msm_get_bufs *new_entry = + kzalloc(sizeof(struct msm_get_bufs), GFP_KERNEL); + + if (!new_entry) + return -ENOMEM; + + if (!buf_info) { + kfree(new_entry); + return -EIO; + } + + INIT_LIST_HEAD(&new_entry->entry); + new_entry->vb2_v4l2_buf = dev->vb2_ops.get_buf_by_idx( + buf_info->session_id, buf_info->stream_id, buf_info->index); + if (!new_entry->vb2_v4l2_buf) { + pr_debug("%s:Get buf is null\n", __func__); + kfree(new_entry); + return -EINVAL; + } + new_entry->session_id = buf_info->session_id; + new_entry->stream_id = buf_info->stream_id; + new_entry->index = new_entry->vb2_v4l2_buf->vb2_buf.index; + spin_lock_irqsave(&dev->buf_q_spinlock, flags); + list_add_tail(&new_entry->entry, &dev->buf_qhead); + spin_unlock_irqrestore(&dev->buf_q_spinlock, flags); + if (buf_info->type == MSM_CAMERA_BUF_MNGR_BUF_USER) { + mutex_lock(&dev->cont_mutex); + if (!list_empty(&dev->cont_qhead)) { + rc = msm_buf_mngr_hdl_cont_get_buf(dev, buf_info); + } else { + pr_err("Nothing mapped in user buf for %d,%d\n", + buf_info->session_id, buf_info->stream_id); + rc = -EINVAL; + } + mutex_unlock(&dev->cont_mutex); + } + return rc; +} + static int32_t msm_buf_mngr_buf_done(struct msm_buf_mngr_device *buf_mngr_dev, struct msm_buf_mngr_info *buf_info) { @@ -413,6 +460,67 @@ static int msm_generic_buf_mngr_close(struct v4l2_subdev *sd, return rc; } +int msm_cam_buf_mgr_ops(unsigned int cmd, void *argp) +{ + int rc = 0; + + if (!msm_buf_mngr_dev) + return -ENODEV; + if (!argp) + return -EINVAL; + + switch (cmd) { + case VIDIOC_MSM_BUF_MNGR_GET_BUF: + rc = msm_buf_mngr_get_buf(msm_buf_mngr_dev, argp); + break; + case VIDIOC_MSM_BUF_MNGR_BUF_DONE: + rc = msm_buf_mngr_buf_done(msm_buf_mngr_dev, argp); + break; + case VIDIOC_MSM_BUF_MNGR_PUT_BUF: + rc = msm_buf_mngr_put_buf(msm_buf_mngr_dev, argp); + break; + case VIDIOC_MSM_BUF_MNGR_IOCTL_CMD: { + struct msm_camera_private_ioctl_arg *k_ioctl = argp; + + switch (k_ioctl->id) { + case MSM_CAMERA_BUF_MNGR_IOCTL_ID_GET_BUF_BY_IDX: { + struct msm_buf_mngr_info *tmp = NULL; + + if (!k_ioctl->ioctl_ptr) + return -EINVAL; + if (k_ioctl->size != sizeof(struct msm_buf_mngr_info)) + return -EINVAL; + + MSM_CAM_GET_IOCTL_ARG_PTR(&tmp, &k_ioctl->ioctl_ptr, + sizeof(tmp)); + rc = msm_buf_mngr_get_buf_by_idx(msm_buf_mngr_dev, + tmp); + } + break; + default: + pr_debug("unimplemented id %d", k_ioctl->id); + return -EINVAL; + } + break; + } + default: + return -ENOIOCTLCMD; + } + + return rc; +} + +int msm_cam_buf_mgr_register_ops(struct msm_cam_buf_mgr_req_ops *cb_struct) +{ + if (!msm_buf_mngr_dev) + return -ENODEV; + if (!cb_struct) + return -EINVAL; + + cb_struct->msm_cam_buf_mgr_ops = msm_cam_buf_mgr_ops; + return 0; +} + static long msm_buf_mngr_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { @@ -425,16 +533,45 @@ static long msm_buf_mngr_subdev_ioctl(struct v4l2_subdev *sd, rc = -ENOMEM; return rc; } - switch (cmd) { - case VIDIOC_MSM_BUF_MNGR_GET_BUF: - rc = msm_buf_mngr_get_buf(buf_mngr_dev, argp); + case VIDIOC_MSM_BUF_MNGR_IOCTL_CMD: { + struct msm_camera_private_ioctl_arg k_ioctl, *ptr; + + if (!arg) + return -EINVAL; + ptr = arg; + k_ioctl = *ptr; + switch (k_ioctl.id) { + case MSM_CAMERA_BUF_MNGR_IOCTL_ID_GET_BUF_BY_IDX: { + struct msm_buf_mngr_info buf_info, *tmp = NULL; + + if (k_ioctl.size != sizeof(struct msm_buf_mngr_info)) + return -EINVAL; + if (!k_ioctl.ioctl_ptr) + return -EINVAL; + + MSM_CAM_GET_IOCTL_ARG_PTR(&tmp, &k_ioctl.ioctl_ptr, + sizeof(tmp)); + if (copy_from_user(&buf_info, tmp, + sizeof(struct msm_buf_mngr_info))) { + return -EFAULT; + } + MSM_CAM_GET_IOCTL_ARG_PTR(&k_ioctl.ioctl_ptr, + &buf_info, sizeof(void *)); + argp = &k_ioctl; + rc = msm_cam_buf_mgr_ops(cmd, argp); + } + break; + default: + pr_debug("unimplemented id %d", k_ioctl.id); + return -EINVAL; + } break; + } + case VIDIOC_MSM_BUF_MNGR_GET_BUF: case VIDIOC_MSM_BUF_MNGR_BUF_DONE: - rc = msm_buf_mngr_buf_done(buf_mngr_dev, argp); - break; case VIDIOC_MSM_BUF_MNGR_PUT_BUF: - rc = msm_buf_mngr_put_buf(buf_mngr_dev, argp); + rc = msm_cam_buf_mgr_ops(cmd, argp); break; case VIDIOC_MSM_BUF_MNGR_INIT: rc = msm_generic_buf_mngr_open(sd, NULL); @@ -462,6 +599,107 @@ static long msm_buf_mngr_subdev_ioctl(struct v4l2_subdev *sd, } #ifdef CONFIG_COMPAT +static long msm_camera_buf_mgr_fetch_buf_info( + struct msm_buf_mngr_info32_t *buf_info32, + struct msm_buf_mngr_info *buf_info, unsigned long arg) +{ + if (!arg || !buf_info32 || !buf_info) + return -EINVAL; + + if (copy_from_user(buf_info32, (void __user *)arg, + sizeof(struct msm_buf_mngr_info32_t))) + return -EFAULT; + + buf_info->session_id = buf_info32->session_id; + buf_info->stream_id = buf_info32->stream_id; + buf_info->frame_id = buf_info32->frame_id; + buf_info->index = buf_info32->index; + buf_info->timestamp.tv_sec = (long) buf_info32->timestamp.tv_sec; + buf_info->timestamp.tv_usec = (long) buf_info32-> + timestamp.tv_usec; + buf_info->reserved = buf_info32->reserved; + buf_info->type = buf_info32->type; + return 0; +} + +static long msm_camera_buf_mgr_update_buf_info( + struct msm_buf_mngr_info32_t *buf_info32, + struct msm_buf_mngr_info *buf_info, unsigned long arg) +{ + if (!arg || !buf_info32 || !buf_info) + return -EINVAL; + + buf_info32->session_id = buf_info->session_id; + buf_info32->stream_id = buf_info->stream_id; + buf_info32->index = buf_info->index; + buf_info32->timestamp.tv_sec = (int32_t) buf_info-> + timestamp.tv_sec; + buf_info32->timestamp.tv_usec = (int32_t) buf_info->timestamp. + tv_usec; + buf_info32->reserved = buf_info->reserved; + buf_info32->type = buf_info->type; + buf_info32->user_buf.buf_cnt = buf_info->user_buf.buf_cnt; + memcpy(&buf_info32->user_buf.buf_idx, + &buf_info->user_buf.buf_idx, + sizeof(buf_info->user_buf.buf_idx)); + if (copy_to_user((void __user *)arg, buf_info32, + sizeof(struct msm_buf_mngr_info32_t))) + return -EFAULT; + return 0; +} +static long msm_camera_buf_mgr_internal_compat_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct video_device *vdev = video_devdata(file); + struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); + long rc = 0; + struct msm_camera_private_ioctl_arg k_ioctl; + void __user *tmp_compat_ioctl_ptr = NULL; + + rc = msm_copy_camera_private_ioctl_args(arg, + &k_ioctl, &tmp_compat_ioctl_ptr); + if (rc < 0) { + pr_err("Subdev cmd %d failed\n", cmd); + return rc; + } + + switch (k_ioctl.id) { + case MSM_CAMERA_BUF_MNGR_IOCTL_ID_GET_BUF_BY_IDX: { + struct msm_buf_mngr_info32_t buf_info32; + struct msm_buf_mngr_info buf_info; + + if (k_ioctl.size != sizeof(struct msm_buf_mngr_info32_t)) { + pr_err("Invalid size for id %d with size %d", + k_ioctl.id, k_ioctl.size); + return -EINVAL; + } + if (!tmp_compat_ioctl_ptr) { + pr_err("Invalid ptr for id %d", k_ioctl.id); + return -EINVAL; + } + k_ioctl.ioctl_ptr = (__u64)&buf_info; + rc = msm_camera_buf_mgr_fetch_buf_info(&buf_info32, &buf_info, + (unsigned long)tmp_compat_ioctl_ptr); + if (rc < 0) { + pr_err("Fetch buf info failed for cmd=%d", cmd); + return rc; + } + rc = v4l2_subdev_call(sd, core, ioctl, cmd, &k_ioctl); + if (rc < 0) { + pr_err("Subdev cmd %d failed for id %d", cmd, + k_ioctl.id); + return rc; + } + } + break; + default: + pr_debug("unimplemented id %d", k_ioctl.id); + return -EINVAL; + } + + return 0; +} + static long msm_bmgr_subdev_fops_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -469,8 +707,6 @@ static long msm_bmgr_subdev_fops_compat_ioctl(struct file *file, struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); int32_t rc = 0; - void __user *up = (void __user *)arg; - /* Convert 32 bit IOCTL ID's to 64 bit IOCTL ID's * except VIDIOC_MSM_CPP_CFG32, which needs special * processing @@ -486,13 +722,14 @@ static long msm_bmgr_subdev_fops_compat_ioctl(struct file *file, cmd = VIDIOC_MSM_BUF_MNGR_PUT_BUF; break; case VIDIOC_MSM_BUF_MNGR_CONT_CMD: - cmd = VIDIOC_MSM_BUF_MNGR_CONT_CMD; break; case VIDIOC_MSM_BUF_MNGR_FLUSH32: cmd = VIDIOC_MSM_BUF_MNGR_FLUSH; break; + case VIDIOC_MSM_BUF_MNGR_IOCTL_CMD: + break; default: - pr_debug("%s : unsupported compat type", __func__); + pr_debug("unsupported compat type\n"); return -ENOIOCTLCMD; } @@ -504,65 +741,51 @@ static long msm_bmgr_subdev_fops_compat_ioctl(struct file *file, struct msm_buf_mngr_info32_t buf_info32; struct msm_buf_mngr_info buf_info; - if (copy_from_user(&buf_info32, (void __user *)up, - sizeof(struct msm_buf_mngr_info32_t))) - return -EFAULT; - - buf_info.session_id = buf_info32.session_id; - buf_info.stream_id = buf_info32.stream_id; - buf_info.frame_id = buf_info32.frame_id; - buf_info.index = buf_info32.index; - buf_info.timestamp.tv_sec = (long) buf_info32.timestamp.tv_sec; - buf_info.timestamp.tv_usec = (long) buf_info32. - timestamp.tv_usec; - buf_info.reserved = buf_info32.reserved; - buf_info.type = buf_info32.type; - + rc = msm_camera_buf_mgr_fetch_buf_info(&buf_info32, &buf_info, + arg); + if (rc < 0) { + pr_err("Fetch buf info failed for cmd=%d\n", cmd); + return rc; + } rc = v4l2_subdev_call(sd, core, ioctl, cmd, &buf_info); if (rc < 0) { - pr_debug("%s : Subdev cmd %d fail", __func__, cmd); + pr_debug("Subdev cmd %d fail\n", cmd); + return rc; + } + rc = msm_camera_buf_mgr_update_buf_info(&buf_info32, &buf_info, + arg); + if (rc < 0) { + pr_err("Update buf info failed for cmd=%d\n", cmd); + return rc; + } + break; + } + case VIDIOC_MSM_BUF_MNGR_IOCTL_CMD: { + rc = msm_camera_buf_mgr_internal_compat_ioctl(file, cmd, arg); + if (rc < 0) { + pr_debug("Subdev cmd %d fail\n", cmd); return rc; } - - buf_info32.session_id = buf_info.session_id; - buf_info32.stream_id = buf_info.stream_id; - buf_info32.index = buf_info.index; - buf_info32.timestamp.tv_sec = (int32_t) buf_info. - timestamp.tv_sec; - buf_info32.timestamp.tv_usec = (int32_t) buf_info.timestamp. - tv_usec; - buf_info32.reserved = buf_info.reserved; - buf_info32.type = buf_info.type; - buf_info32.user_buf.buf_cnt = buf_info.user_buf.buf_cnt; - memcpy(&buf_info32.user_buf.buf_idx, - &buf_info.user_buf.buf_idx, - sizeof(buf_info.user_buf.buf_idx)); - if (copy_to_user((void __user *)up, &buf_info32, - sizeof(struct msm_buf_mngr_info32_t))) - return -EFAULT; } break; case VIDIOC_MSM_BUF_MNGR_CONT_CMD: { struct msm_buf_mngr_main_cont_info cont_cmd; - if (copy_from_user(&cont_cmd, (void __user *)up, + if (copy_from_user(&cont_cmd, (void __user *)arg, sizeof(struct msm_buf_mngr_main_cont_info))) return -EFAULT; rc = v4l2_subdev_call(sd, core, ioctl, cmd, &cont_cmd); if (rc < 0) { - pr_debug("%s : Subdev cmd %d fail", __func__, cmd); + pr_debug("Subdev cmd %d fail\n", cmd); return rc; } } break; default: - pr_debug("%s : unsupported compat type", __func__); + pr_debug("unsupported compat type\n"); return -ENOIOCTLCMD; break; } - - - return 0; } #endif diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h index dc7f745f6190..c2f1a1527800 100644 --- a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h +++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -52,4 +52,14 @@ struct msm_buf_mngr_user_buf_cont_info { uint32_t cnt; struct ion_handle *ion_handle; }; + +/* kernel space functions*/ +struct msm_cam_buf_mgr_req_ops { + int (*msm_cam_buf_mgr_ops)(unsigned int cmd, void *argp); +}; + +/* API to register callback from client. This assumes cb_struct is allocated by + * client. + */ +int msm_cam_buf_mgr_register_ops(struct msm_cam_buf_mgr_req_ops *cb_struct); #endif diff --git a/drivers/media/platform/msm/camera_v2/msm_sd.h b/drivers/media/platform/msm/camera_v2/msm_sd.h index 6bb95ad0de87..d893d9fc07e3 100644 --- a/drivers/media/platform/msm/camera_v2/msm_sd.h +++ b/drivers/media/platform/msm/camera_v2/msm_sd.h @@ -73,6 +73,8 @@ struct msm_sd_req_vb2_q { unsigned int stream_id); struct vb2_queue * (*get_vb2_queue)(int session_id, unsigned int stream_id); + struct vb2_v4l2_buffer * (*get_buf_by_idx)(int session_id, + unsigned int stream_id, uint32_t index); int (*put_buf)(struct vb2_v4l2_buffer *vb2_buf, int session_id, unsigned int stream_id); int (*buf_done)(struct vb2_v4l2_buffer *vb2_v4l2_buf, int session_id, @@ -85,6 +87,9 @@ struct msm_sd_req_vb2_q { #define MSM_SD_NOTIFY_PUT_SD 0x00000002 #define MSM_SD_NOTIFY_REQ_CB 0x00000003 +#define MSM_CAM_GET_IOCTL_ARG_PTR(ptr, \ + ioctl_ptr, len) memcpy(ptr, ioctl_ptr, len) + int msm_sd_register(struct msm_sd_subdev *msm_subdev); int msm_sd_unregister(struct msm_sd_subdev *sd); struct v4l2_subdev *msm_sd_get_subdev(struct v4l2_subdev *sd, diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c index 6e0dac4608a9..59135225cb15 100644 --- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c +++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c @@ -231,6 +231,41 @@ end: return vb2_v4l2_buf; } +static struct vb2_v4l2_buffer *msm_vb2_get_buf_by_idx(int session_id, + unsigned int stream_id, uint32_t index) +{ + struct msm_stream *stream; + struct vb2_v4l2_buffer *vb2_v4l2_buf = NULL; + struct msm_vb2_buffer *msm_vb2 = NULL; + unsigned long flags; + + stream = msm_get_stream(session_id, stream_id); + if (IS_ERR_OR_NULL(stream)) + return NULL; + + spin_lock_irqsave(&stream->stream_lock, flags); + + if (!stream->vb2_q) { + pr_err("%s: stream q not available\n", __func__); + goto end; + } + + list_for_each_entry(msm_vb2, &(stream->queued_list), list) { + vb2_v4l2_buf = &(msm_vb2->vb2_v4l2_buf); + if ((vb2_v4l2_buf->vb2_buf.index != index) || msm_vb2->in_freeq + || vb2_v4l2_buf->vb2_buf.state != VB2_BUF_STATE_ACTIVE) + continue; + + msm_vb2->in_freeq = 1; + goto end; + } + msm_vb2 = NULL; + vb2_v4l2_buf = NULL; +end: + spin_unlock_irqrestore(&stream->stream_lock, flags); + return vb2_v4l2_buf; +} + static int msm_vb2_put_buf(struct vb2_v4l2_buffer *vb, int session_id, unsigned int stream_id) { @@ -320,6 +355,48 @@ static int msm_vb2_buf_done(struct vb2_v4l2_buffer *vb, int session_id, return rc; } +long msm_vb2_return_buf_by_idx(int session_id, unsigned int stream_id, + uint32_t index) +{ + struct msm_stream *stream; + struct vb2_v4l2_buffer *vb2_v4l2_buf = NULL; + struct msm_vb2_buffer *msm_vb2 = NULL; + unsigned long flags; + long rc = -EINVAL; + + stream = msm_get_stream(session_id, stream_id); + if (IS_ERR_OR_NULL(stream)) + return rc; + + spin_lock_irqsave(&stream->stream_lock, flags); + + if (!stream->vb2_q) { + pr_err("%s: stream q not available\n", __func__); + goto end; + } + + list_for_each_entry(msm_vb2, &(stream->queued_list), list) { + vb2_v4l2_buf = &(msm_vb2->vb2_v4l2_buf); + if ((vb2_v4l2_buf->vb2_buf.index != index) + || vb2_v4l2_buf->vb2_buf.state != VB2_BUF_STATE_ACTIVE) + continue; + + if (!msm_vb2->in_freeq) { + vb2_buffer_done(&vb2_v4l2_buf->vb2_buf, + VB2_BUF_STATE_ERROR); + rc = 0; + } else { + rc = -EINVAL; + } + break; + } + +end: + spin_unlock_irqrestore(&stream->stream_lock, flags); + return rc; +} +EXPORT_SYMBOL(msm_vb2_return_buf_by_idx); + static int msm_vb2_flush_buf(int session_id, unsigned int stream_id) { unsigned long flags; @@ -350,11 +427,11 @@ int msm_vb2_request_cb(struct msm_sd_req_vb2_q *req) } req->get_buf = msm_vb2_get_buf; + req->get_buf_by_idx = msm_vb2_get_buf_by_idx; req->get_vb2_queue = msm_vb2_get_queue; req->put_buf = msm_vb2_put_buf; req->buf_done = msm_vb2_buf_done; req->flush_buf = msm_vb2_flush_buf; - return 0; } diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.h b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.h index 96fa1d4c64c9..53511d5416d7 100644 --- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.h +++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -65,5 +65,7 @@ struct msm_stream { struct vb2_ops *msm_vb2_get_q_ops(void); struct vb2_mem_ops *msm_vb2_get_q_mem_ops(void); int msm_vb2_request_cb(struct msm_sd_req_vb2_q *req_sd); +long msm_vb2_return_buf_by_idx(int session_id, unsigned int stream_id, + uint32_t index); #endif /*_MSM_VB_H */ diff --git a/include/uapi/media/msmb_camera.h b/include/uapi/media/msmb_camera.h index 092551d0cc16..fe70daa772df 100644 --- a/include/uapi/media/msmb_camera.h +++ b/include/uapi/media/msmb_camera.h @@ -202,5 +202,24 @@ struct msm_camera_user_buf_cont_t { unsigned int buf_idx[MSM_CAMERA_MAX_USER_BUFF_CNT]; }; +struct msm_camera_return_buf { + __u32 index; + __u32 reserved; +}; + +#define MSM_CAMERA_PRIV_IOCTL_ID_BASE 0 +#define MSM_CAMERA_PRIV_IOCTL_ID_RETURN_BUF 1 + +struct msm_camera_private_ioctl_arg { + __u32 id; + __u32 size; + __u32 result; + __u32 reserved; + __user __u64 ioctl_ptr; +}; + +#define VIDIOC_MSM_CAMERA_PRIVATE_IOCTL_CMD \ + _IOWR('V', BASE_VIDIOC_PRIVATE, struct msm_camera_private_ioctl_arg) + #endif diff --git a/include/uapi/media/msmb_generic_buf_mgr.h b/include/uapi/media/msmb_generic_buf_mgr.h index a68b174b97bb..2961cae1e7c1 100644 --- a/include/uapi/media/msmb_generic_buf_mgr.h +++ b/include/uapi/media/msmb_generic_buf_mgr.h @@ -34,6 +34,9 @@ struct msm_buf_mngr_main_cont_info { int32_t cont_fd; }; +#define MSM_CAMERA_BUF_MNGR_IOCTL_ID_BASE 0 +#define MSM_CAMERA_BUF_MNGR_IOCTL_ID_GET_BUF_BY_IDX 1 + #define VIDIOC_MSM_BUF_MNGR_GET_BUF \ _IOWR('V', BASE_VIDIOC_PRIVATE + 33, struct msm_buf_mngr_info) @@ -55,5 +58,9 @@ struct msm_buf_mngr_main_cont_info { #define VIDIOC_MSM_BUF_MNGR_FLUSH \ _IOWR('V', BASE_VIDIOC_PRIVATE + 39, struct msm_buf_mngr_info) +#define VIDIOC_MSM_BUF_MNGR_IOCTL_CMD \ + _IOWR('V', BASE_VIDIOC_PRIVATE + 40, \ + struct msm_camera_private_ioctl_arg) + #endif |
