summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/media/platform/msm/camera_v2/camera/camera.c87
-rw-r--r--drivers/media/platform/msm/camera_v2/fd/Makefile3
-rw-r--r--drivers/media/platform/msm/camera_v2/msm.c22
-rw-r--r--drivers/media/platform/msm/camera_v2/msm.h5
-rw-r--r--drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c319
-rw-r--r--drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h12
-rw-r--r--drivers/media/platform/msm/camera_v2/msm_sd.h5
-rw-r--r--drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c79
-rw-r--r--drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.h4
-rw-r--r--include/uapi/media/msmb_camera.h19
-rw-r--r--include/uapi/media/msmb_generic_buf_mgr.h7
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