aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/staging/media/ipu3/ipu3-v4l2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/media/ipu3/ipu3-v4l2.c')
-rw-r--r--drivers/staging/media/ipu3/ipu3-v4l2.c92
1 files changed, 24 insertions, 68 deletions
diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c
index 09c8ede1457c..4dc8d9165f63 100644
--- a/drivers/staging/media/ipu3/ipu3-v4l2.c
+++ b/drivers/staging/media/ipu3/ipu3-v4l2.c
@@ -152,7 +152,6 @@ static int imgu_subdev_set_fmt(struct v4l2_subdev *sd,
struct imgu_v4l2_subdev *imgu_sd = container_of(sd,
struct imgu_v4l2_subdev,
subdev);
-
struct v4l2_mbus_framefmt *mf;
u32 pad = fmt->pad;
unsigned int pipe = imgu_sd->pipe;
@@ -367,8 +366,10 @@ static void imgu_vb2_buf_queue(struct vb2_buffer *vb)
vb2_set_plane_payload(vb, 0, need_bytes);
+ mutex_lock(&imgu->streaming_lock);
if (imgu->streaming)
imgu_queue_buffers(imgu, false, node->pipe);
+ mutex_unlock(&imgu->streaming_lock);
dev_dbg(&imgu->pci_dev->dev, "%s for pipe %u node %u", __func__,
node->pipe, node->id);
@@ -468,10 +469,13 @@ static int imgu_vb2_start_streaming(struct vb2_queue *vq, unsigned int count)
dev_dbg(dev, "%s node name %s pipe %u id %u", __func__,
node->name, node->pipe, node->id);
+ mutex_lock(&imgu->streaming_lock);
if (imgu->streaming) {
r = -EBUSY;
+ mutex_unlock(&imgu->streaming_lock);
goto fail_return_bufs;
}
+ mutex_unlock(&imgu->streaming_lock);
if (!node->enabled) {
dev_err(dev, "IMGU node is not enabled");
@@ -485,7 +489,6 @@ static int imgu_vb2_start_streaming(struct vb2_queue *vq, unsigned int count)
if (r < 0)
goto fail_return_bufs;
-
if (!imgu_all_nodes_streaming(imgu, node))
return 0;
@@ -498,9 +501,11 @@ static int imgu_vb2_start_streaming(struct vb2_queue *vq, unsigned int count)
/* Start streaming of the whole pipeline now */
dev_dbg(dev, "IMGU streaming is ready to start");
+ mutex_lock(&imgu->streaming_lock);
r = imgu_s_stream(imgu, true);
if (!r)
imgu->streaming = true;
+ mutex_unlock(&imgu->streaming_lock);
return 0;
@@ -532,6 +537,7 @@ static void imgu_vb2_stop_streaming(struct vb2_queue *vq)
dev_err(&imgu->pci_dev->dev,
"failed to stop subdev streaming\n");
+ mutex_lock(&imgu->streaming_lock);
/* Was this the first node with streaming disabled? */
if (imgu->streaming && imgu_all_nodes_streaming(imgu, node)) {
/* Yes, really stop streaming now */
@@ -542,6 +548,8 @@ static void imgu_vb2_stop_streaming(struct vb2_queue *vq)
}
imgu_return_all_buffers(imgu, node, VB2_BUF_STATE_ERROR);
+ mutex_unlock(&imgu->streaming_lock);
+
media_pipeline_stop(&node->vdev.entity);
}
@@ -597,6 +605,9 @@ static int enum_fmts(struct v4l2_fmtdesc *f, u32 type)
{
unsigned int i, j;
+ if (f->mbus_code != 0 && f->mbus_code != MEDIA_BUS_FMT_FIXED)
+ return -EINVAL;
+
for (i = j = 0; i < ARRAY_SIZE(formats); ++i) {
if (formats[i].type == type) {
if (j == f->index)
@@ -826,6 +837,9 @@ static int imgu_meta_enum_format(struct file *file, void *fh,
if (fmt->index > 0 || fmt->type != node->vbq.type)
return -EINVAL;
+ if (fmt->mbus_code != 0 && fmt->mbus_code != MEDIA_BUS_FMT_FIXED)
+ return -EINVAL;
+
strscpy(fmt->description, meta_fmts[i].name, sizeof(fmt->description));
fmt->pixelformat = meta_fmts[i].fourcc;
@@ -845,54 +859,6 @@ static int imgu_vidioc_g_meta_fmt(struct file *file, void *fh,
return 0;
}
-static int imgu_vidioc_enum_input(struct file *file, void *fh,
- struct v4l2_input *input)
-{
- if (input->index > 0)
- return -EINVAL;
- strscpy(input->name, "camera", sizeof(input->name));
- input->type = V4L2_INPUT_TYPE_CAMERA;
-
- return 0;
-}
-
-static int imgu_vidioc_g_input(struct file *file, void *fh, unsigned int *input)
-{
- *input = 0;
-
- return 0;
-}
-
-static int imgu_vidioc_s_input(struct file *file, void *fh, unsigned int input)
-{
- return input == 0 ? 0 : -EINVAL;
-}
-
-static int imgu_vidioc_enum_output(struct file *file, void *fh,
- struct v4l2_output *output)
-{
- if (output->index > 0)
- return -EINVAL;
- strscpy(output->name, "camera", sizeof(output->name));
- output->type = V4L2_INPUT_TYPE_CAMERA;
-
- return 0;
-}
-
-static int imgu_vidioc_g_output(struct file *file, void *fh,
- unsigned int *output)
-{
- *output = 0;
-
- return 0;
-}
-
-static int imgu_vidioc_s_output(struct file *file, void *fh,
- unsigned int output)
-{
- return output == 0 ? 0 : -EINVAL;
-}
-
/******************** function pointers ********************/
static struct v4l2_subdev_internal_ops imgu_subdev_internal_ops = {
@@ -965,14 +931,6 @@ static const struct v4l2_ioctl_ops imgu_v4l2_ioctl_ops = {
.vidioc_s_fmt_vid_out_mplane = imgu_vidioc_s_fmt,
.vidioc_try_fmt_vid_out_mplane = imgu_vidioc_try_fmt,
- .vidioc_enum_output = imgu_vidioc_enum_output,
- .vidioc_g_output = imgu_vidioc_g_output,
- .vidioc_s_output = imgu_vidioc_s_output,
-
- .vidioc_enum_input = imgu_vidioc_enum_input,
- .vidioc_g_input = imgu_vidioc_g_input,
- .vidioc_s_input = imgu_vidioc_s_input,
-
/* buffer queue management */
.vidioc_reqbufs = vb2_ioctl_reqbufs,
.vidioc_create_bufs = vb2_ioctl_create_bufs,
@@ -1086,7 +1044,7 @@ static void imgu_node_to_v4l2(u32 node, struct video_device *vdev,
vdev->ioctl_ops = &imgu_v4l2_ioctl_ops;
}
- vdev->device_caps = V4L2_CAP_STREAMING | cap;
+ vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_IO_MC | cap;
}
static int imgu_v4l2_subdev_register(struct imgu_device *imgu,
@@ -1292,19 +1250,17 @@ static void imgu_v4l2_nodes_cleanup_pipe(struct imgu_device *imgu,
static int imgu_v4l2_nodes_setup_pipe(struct imgu_device *imgu, int pipe)
{
- int i, r;
+ int i;
for (i = 0; i < IMGU_NODE_NUM; i++) {
- r = imgu_v4l2_node_setup(imgu, pipe, i);
- if (r)
- goto cleanup;
- }
+ int r = imgu_v4l2_node_setup(imgu, pipe, i);
+ if (r) {
+ imgu_v4l2_nodes_cleanup_pipe(imgu, pipe, i);
+ return r;
+ }
+ }
return 0;
-
-cleanup:
- imgu_v4l2_nodes_cleanup_pipe(imgu, pipe, i);
- return r;
}
static void imgu_v4l2_subdev_cleanup(struct imgu_device *imgu, unsigned int i)