msm: camera: Add v4l2 private ioctls

Add private ioctls s_ctrl, query_ctrl where
we need to get ctrl data from userspace.

Change-Id: I404236d072bafb3ef6ef3c0723a707f5805fe92b
Signed-off-by: Kevin Chan <ktchan@codeaurora.org>
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 09511b1..c3c09d4 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -108,6 +108,25 @@
 	return rc;
 }
 
+static int msm_camera_v4l2_private_s_ctrl(struct file *f, void *pctx,
+			struct msm_camera_v4l2_ioctl_t *ioctl_ptr)
+{
+	int rc = -EINVAL;
+	struct msm_cam_v4l2_device *pcam  = video_drvdata(f);
+	struct msm_cam_v4l2_dev_inst *pcam_inst;
+	pcam_inst = container_of(f->private_data,
+		struct msm_cam_v4l2_dev_inst, eventHandle);
+	WARN_ON(pctx != f->private_data);
+	mutex_lock(&pcam->vid_lock);
+	switch (ioctl_ptr->id) {
+	case MSM_V4L2_PID_CTRL_CMD:
+		rc = msm_server_proc_ctrl_cmd(pcam, ioctl_ptr, 1);
+		break;
+	}
+	mutex_unlock(&pcam->vid_lock);
+	return rc;
+}
+
 static int msm_camera_v4l2_s_ctrl(struct file *f, void *pctx,
 					struct v4l2_control *ctrl)
 {
@@ -127,17 +146,6 @@
 			 __func__, pcam_inst, pcam_inst->my_index);
 		pcam_inst->is_mem_map_inst = 1;
 		break;
-	case MSM_V4L2_PID_MMAP_ENTRY:
-		if (copy_from_user(&pcam_inst->mem_map,
-			(void *)ctrl->value,
-			sizeof(struct msm_mem_map_info))) {
-			rc = -EFAULT;
-		} else
-			D("%s:mmap entry:cookie=0x%x,mem_type=%d,len=%d\n",
-				__func__, pcam_inst->mem_map.cookie,
-				pcam_inst->mem_map.mem_type,
-				pcam_inst->mem_map.length);
-		break;
 	default:
 		if (ctrl->id == MSM_V4L2_PID_CAM_MODE)
 			pcam->op_mode = ctrl->value;
@@ -685,6 +693,22 @@
 	return rc;
 }
 
+static long msm_camera_v4l2_private_ioctl(struct file *file, void *fh,
+					  bool valid_prio, int cmd,
+					  void *arg)
+{
+	int rc = -EINVAL;
+	struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
+	D("%s: cmd %d\n", __func__, _IOC_NR(cmd));
+
+	switch (cmd) {
+	case MSM_CAM_V4L2_IOCTL_PRIVATE_S_CTRL:
+		rc = msm_camera_v4l2_private_s_ctrl(file, fh, ioctl_ptr);
+		break;
+	}
+	return rc;
+}
+
 /* v4l2_ioctl_ops */
 static const struct v4l2_ioctl_ops g_msm_ioctl_ops = {
 	.vidioc_querycap = msm_camera_v4l2_querycap,
@@ -724,6 +748,7 @@
 	/* event subscribe/unsubscribe */
 	.vidioc_subscribe_event = msm_camera_v4l2_subscribe_event,
 	.vidioc_unsubscribe_event = msm_camera_v4l2_unsubscribe_event,
+	.vidioc_default = msm_camera_v4l2_private_ioctl,
 };
 
 /* v4l2_file_operations */
diff --git a/drivers/media/video/msm/server/msm_cam_server.c b/drivers/media/video/msm/server/msm_cam_server.c
index 1f20c8a..cb59737 100644
--- a/drivers/media/video/msm/server/msm_cam_server.c
+++ b/drivers/media/video/msm/server/msm_cam_server.c
@@ -560,55 +560,52 @@
 }
 
 int msm_server_proc_ctrl_cmd(struct msm_cam_v4l2_device *pcam,
-				 struct v4l2_control *ctrl, int is_set_cmd)
+		struct msm_camera_v4l2_ioctl_t *ioctl_ptr, int is_set_cmd)
 {
 	int rc = 0;
-	struct msm_ctrl_cmd ctrlcmd, *tmp_cmd;
+	struct msm_ctrl_cmd ctrlcmd, tmp_cmd, *cmd_ptr;
 	uint8_t *ctrl_data = NULL;
-	void __user *uptr_cmd;
-	void __user *uptr_value;
 	uint32_t cmd_len = sizeof(struct msm_ctrl_cmd);
 	uint32_t value_len;
 
-	tmp_cmd = (struct msm_ctrl_cmd *)ctrl->value;
-	uptr_cmd = (void __user *)ctrl->value;
-	uptr_value = (void __user *)tmp_cmd->value;
-	value_len = tmp_cmd->length;
-
-	D("%s: cmd type = %d, up1=0x%x, ulen1=%d, up2=0x%x, ulen2=%d\n",
-		__func__, tmp_cmd->type, (uint32_t)uptr_cmd, cmd_len,
-		(uint32_t)uptr_value, tmp_cmd->length);
-
-	ctrl_data = kzalloc(value_len+cmd_len, GFP_KERNEL);
-	if (ctrl_data == 0) {
-		pr_err("%s could not allocate memory\n", __func__);
-		rc = -ENOMEM;
-		goto end;
-	}
-	tmp_cmd = (struct msm_ctrl_cmd *)ctrl_data;
-	if (copy_from_user((void *)ctrl_data, uptr_cmd,
-					cmd_len)) {
+	if (copy_from_user(&tmp_cmd,
+		(void __user *)ioctl_ptr->ioctl_ptr, cmd_len)) {
 		pr_err("%s: copy_from_user failed.\n", __func__);
 		rc = -EINVAL;
 		goto end;
 	}
-	tmp_cmd->value = (void *)(ctrl_data+cmd_len);
-	if (uptr_value && tmp_cmd->length > 0) {
-		if (copy_from_user((void *)tmp_cmd->value, uptr_value,
-						value_len)) {
-			pr_err("%s: copy_from_user failed, size=%d\n",
-				__func__, value_len);
+	value_len = tmp_cmd.length;
+	ctrl_data = kzalloc(value_len+cmd_len, GFP_KERNEL);
+	if (!ctrl_data) {
+		pr_err("%s could not allocate memory\n", __func__);
+		rc = -ENOMEM;
+		goto end;
+	}
+
+	cmd_ptr = (struct msm_ctrl_cmd *) ctrl_data;
+	*cmd_ptr = tmp_cmd;
+	if (tmp_cmd.value && tmp_cmd.length > 0) {
+		cmd_ptr->value = (void *)(ctrl_data+cmd_len);
+		if (copy_from_user((void *)cmd_ptr->value,
+				   (void __user *)tmp_cmd.value,
+				   value_len)) {
+			pr_err("%s: copy_from_user failed.\n", __func__);
 			rc = -EINVAL;
 			goto end;
 		}
-	} else
-	tmp_cmd->value = NULL;
+	} else {
+		cmd_ptr->value = NULL;
+	}
+
+	D("%s: cmd type = %d, up1=0x%x, ulen1=%d, up2=0x%x, ulen2=%d\n",
+		__func__, tmp_cmd.type, (uint32_t)ioctl_ptr->ioctl_ptr, cmd_len,
+		(uint32_t)tmp_cmd.value, tmp_cmd.length);
 
 	ctrlcmd.type = MSM_V4L2_SET_CTRL_CMD;
 	ctrlcmd.length = cmd_len + value_len;
 	ctrlcmd.value = (void *)ctrl_data;
-	if (tmp_cmd->timeout_ms > 0)
-		ctrlcmd.timeout_ms = tmp_cmd->timeout_ms;
+	if (tmp_cmd.timeout_ms > 0)
+		ctrlcmd.timeout_ms = tmp_cmd.timeout_ms;
 	else
 		ctrlcmd.timeout_ms = 1000;
 	ctrlcmd.vnode_id = pcam->vnode_id;
@@ -618,17 +615,17 @@
 	rc = msm_server_control(&g_server_dev, &ctrlcmd);
 	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,
-				(void *)(ctrl_data+cmd_len), tmp_cmd->length)) {
+		if (tmp_cmd.value && tmp_cmd.length > 0 &&
+			copy_to_user((void __user *)tmp_cmd.value,
+				(void *)(ctrl_data+cmd_len), tmp_cmd.length)) {
 			pr_err("%s: copy_to_user failed, size=%d\n",
-				__func__, tmp_cmd->length);
+				__func__, tmp_cmd.length);
 			rc = -EINVAL;
 			goto end;
 		}
-		tmp_cmd->value = uptr_value;
-		if (copy_to_user((void __user *)uptr_cmd,
-			(void *)tmp_cmd, cmd_len)) {
+
+		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
+			(void *)&tmp_cmd, cmd_len)) {
 			pr_err("%s: copy_to_user failed in cpy, size=%d\n",
 				__func__, cmd_len);
 			rc = -EINVAL;
@@ -637,8 +634,8 @@
 	}
 end:
 	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);
+		__func__, tmp_cmd.type, (uint32_t)tmp_cmd.value,
+		tmp_cmd.length, tmp_cmd.status, rc);
 	kfree(ctrl_data);
 	return rc;
 }
@@ -655,8 +652,6 @@
 		pr_err("%s Invalid control\n", __func__);
 		return -EINVAL;
 	}
-	if (ctrl->id == MSM_V4L2_PID_CTRL_CMD)
-		return msm_server_proc_ctrl_cmd(pcam, ctrl, 1);
 
 	memset(ctrl_data, 0, sizeof(ctrl_data));
 
@@ -687,8 +682,6 @@
 		pr_err("%s Invalid control\n", __func__);
 		return -EINVAL;
 	}
-	if (ctrl->id == MSM_V4L2_PID_CTRL_CMD)
-		return msm_server_proc_ctrl_cmd(pcam, ctrl, 0);
 
 	memset(ctrl_data, 0, sizeof(ctrl_data));
 
diff --git a/drivers/media/video/msm/server/msm_cam_server.h b/drivers/media/video/msm/server/msm_cam_server.h
index 2fe4c2b..677feaa 100644
--- a/drivers/media/video/msm/server/msm_cam_server.h
+++ b/drivers/media/video/msm/server/msm_cam_server.h
@@ -36,7 +36,7 @@
 int msm_server_get_usecount(void);
 int32_t msm_find_free_queue(void);
 int msm_server_proc_ctrl_cmd(struct msm_cam_v4l2_device *pcam,
-	struct v4l2_control *ctrl, int is_set_cmd);
+	struct msm_camera_v4l2_ioctl_t *ioctl_ptr, int is_set_cmd);
 int msm_server_s_ctrl(struct msm_cam_v4l2_device *pcam,
 	struct v4l2_control *ctrl);
 int msm_server_g_ctrl(struct msm_cam_v4l2_device *pcam,
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 7b5e841..271079e 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -1450,19 +1450,19 @@
 #define QCAMERA_VNODE_GROUP_ID 2
 
 #define MSM_CAM_V4L2_IOCTL_GET_CAMERA_INFO \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct msm_camera_v4l2_ioctl_t *)
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct msm_camera_v4l2_ioctl_t)
 
 #define MSM_CAM_V4L2_IOCTL_GET_CONFIG_INFO \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 2, struct msm_camera_v4l2_ioctl_t *)
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 2, struct msm_camera_v4l2_ioctl_t)
 
 #define MSM_CAM_V4L2_IOCTL_GET_MCTL_INFO \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 3, struct msm_camera_v4l2_ioctl_t *)
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 3, struct msm_camera_v4l2_ioctl_t)
 
 #define MSM_CAM_V4L2_IOCTL_CTRL_CMD_DONE \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 4, struct msm_camera_v4l2_ioctl_t *)
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 4, struct msm_camera_v4l2_ioctl_t)
 
 #define MSM_CAM_V4L2_IOCTL_GET_EVENT_PAYLOAD \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 5, struct msm_camera_v4l2_ioctl_t *)
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 5, struct msm_camera_v4l2_ioctl_t)
 
 #define MSM_CAM_IOCTL_SEND_EVENT \
 	_IOWR('V', BASE_VIDIOC_PRIVATE + 6, struct v4l2_event)
@@ -1470,8 +1470,13 @@
 #define MSM_CAM_V4L2_IOCTL_CFG_VPE \
 	_IOWR('V', BASE_VIDIOC_PRIVATE + 7, struct msm_vpe_cfg_cmd)
 
+#define MSM_CAM_V4L2_IOCTL_PRIVATE_S_CTRL \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 8, struct msm_camera_v4l2_ioctl_t)
+
 struct msm_camera_v4l2_ioctl_t {
+	uint32_t id;
 	void __user *ioctl_ptr;
+	uint32_t len;
 };
 
 #endif /* __LINUX_MSM_CAMERA_H */