diff options
Diffstat (limited to 'drivers/staging/media/ipu3/ipu3-v4l2.c')
-rw-r--r-- | drivers/staging/media/ipu3/ipu3-v4l2.c | 126 |
1 files changed, 61 insertions, 65 deletions
diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c index 9c0352b193a7..a7bc22040ed8 100644 --- a/drivers/staging/media/ipu3/ipu3-v4l2.c +++ b/drivers/staging/media/ipu3/ipu3-v4l2.c @@ -66,7 +66,7 @@ static int imgu_subdev_s_stream(struct v4l2_subdev *sd, int enable) struct imgu_css_pipe *css_pipe = &imgu->css.pipes[pipe]; struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; - dev_dbg(dev, "%s %d for pipe %d", __func__, enable, pipe); + dev_dbg(dev, "%s %d for pipe %u", __func__, enable, pipe); /* grab ctrl after streamon and return after off */ v4l2_ctrl_grab(imgu_sd->ctrl, enable); @@ -101,7 +101,7 @@ static int imgu_subdev_s_stream(struct v4l2_subdev *sd, int enable) else css_pipe->pipe_id = IPU3_CSS_PIPE_ID_CAPTURE; - dev_dbg(dev, "IPU3 pipe %d pipe_id %d", pipe, css_pipe->pipe_id); + dev_dbg(dev, "IPU3 pipe %u pipe_id %u", pipe, css_pipe->pipe_id); rects[IPU3_CSS_RECT_EFFECTIVE] = &imgu_sd->rect.eff; rects[IPU3_CSS_RECT_BDS] = &imgu_sd->rect.bds; @@ -109,7 +109,7 @@ static int imgu_subdev_s_stream(struct v4l2_subdev *sd, int enable) r = imgu_css_fmt_set(&imgu->css, fmts, rects, pipe); if (r) { - dev_err(dev, "failed to set initial formats pipe %d with (%d)", + dev_err(dev, "failed to set initial formats pipe %u with (%d)", pipe, r); return r; } @@ -157,7 +157,7 @@ static int imgu_subdev_set_fmt(struct v4l2_subdev *sd, u32 pad = fmt->pad; unsigned int pipe = imgu_sd->pipe; - dev_dbg(&imgu->pci_dev->dev, "set subdev %d pad %d fmt to [%dx%d]", + dev_dbg(&imgu->pci_dev->dev, "set subdev %u pad %u fmt to [%ux%u]", pipe, pad, fmt->format.width, fmt->format.height); imgu_pipe = &imgu->imgu_pipe[pipe]; @@ -233,7 +233,7 @@ static int imgu_subdev_set_selection(struct v4l2_subdev *sd, struct v4l2_rect *rect, *try_sel; dev_dbg(&imgu->pci_dev->dev, - "set subdev %d sel which %d target 0x%4x rect [%dx%d]", + "set subdev %u sel which %u target 0x%4x rect [%ux%u]", imgu_sd->pipe, sel->which, sel->target, sel->r.width, sel->r.height); @@ -279,7 +279,7 @@ static int imgu_link_setup(struct media_entity *entity, WARN_ON(pad >= IMGU_NODE_NUM); - dev_dbg(&imgu->pci_dev->dev, "pipe %d pad %d is %s", pipe, pad, + dev_dbg(&imgu->pci_dev->dev, "pipe %u pad %u is %s", pipe, pad, flags & MEDIA_LNK_FL_ENABLED ? "enabled" : "disabled"); imgu_pipe = &imgu->imgu_pipe[pipe]; @@ -294,7 +294,7 @@ static int imgu_link_setup(struct media_entity *entity, else __clear_bit(pipe, imgu->css.enabled_pipes); - dev_dbg(&imgu->pci_dev->dev, "pipe %d is %s", pipe, + dev_dbg(&imgu->pci_dev->dev, "pipe %u is %s", pipe, flags & MEDIA_LNK_FL_ENABLED ? "enabled" : "disabled"); return 0; @@ -341,8 +341,10 @@ static void imgu_vb2_buf_queue(struct vb2_buffer *vb) struct imgu_video_device *node = container_of(vb->vb2_queue, struct imgu_video_device, vbq); unsigned int queue = imgu_node_to_queue(node->id); + struct imgu_buffer *buf = container_of(vb, struct imgu_buffer, + vid_buf.vbb.vb2_buf); unsigned long need_bytes; - unsigned int pipe = node->pipe; + unsigned long payload = vb2_get_plane_payload(vb, 0); if (vb->vb2_queue->type == V4L2_BUF_TYPE_META_CAPTURE || vb->vb2_queue->type == V4L2_BUF_TYPE_META_OUTPUT) @@ -350,42 +352,26 @@ static void imgu_vb2_buf_queue(struct vb2_buffer *vb) else need_bytes = node->vdev_fmt.fmt.pix_mp.plane_fmt[0].sizeimage; - if (queue == IPU3_CSS_QUEUE_PARAMS) { - unsigned long payload = vb2_get_plane_payload(vb, 0); - struct vb2_v4l2_buffer *buf = - container_of(vb, struct vb2_v4l2_buffer, vb2_buf); - int r = -EINVAL; - - if (payload == 0) { - payload = need_bytes; - vb2_set_plane_payload(vb, 0, payload); - } - if (payload >= need_bytes) - r = imgu_css_set_parameters(&imgu->css, pipe, - vb2_plane_vaddr(vb, 0)); - buf->flags = V4L2_BUF_FLAG_DONE; - vb2_buffer_done(vb, r == 0 ? VB2_BUF_STATE_DONE - : VB2_BUF_STATE_ERROR); - - } else { - struct imgu_buffer *buf = container_of(vb, struct imgu_buffer, - vid_buf.vbb.vb2_buf); + if (queue == IPU3_CSS_QUEUE_PARAMS && payload && payload < need_bytes) { + dev_err(&imgu->pci_dev->dev, "invalid data size for params."); + vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); + return; + } - mutex_lock(&imgu->lock); + mutex_lock(&imgu->lock); + if (queue != IPU3_CSS_QUEUE_PARAMS) imgu_css_buf_init(&buf->css_buf, queue, buf->map.daddr); - list_add_tail(&buf->vid_buf.list, - &node->buffers); - mutex_unlock(&imgu->lock); - vb2_set_plane_payload(&buf->vid_buf.vbb.vb2_buf, 0, need_bytes); + list_add_tail(&buf->vid_buf.list, &node->buffers); + mutex_unlock(&imgu->lock); - if (imgu->streaming) - imgu_queue_buffers(imgu, false, pipe); - } + vb2_set_plane_payload(vb, 0, need_bytes); - dev_dbg(&imgu->pci_dev->dev, "%s for pipe %d node %d", __func__, - node->pipe, node->id); + if (imgu->streaming) + imgu_queue_buffers(imgu, false, node->pipe); + dev_dbg(&imgu->pci_dev->dev, "%s for pipe %u node %u", __func__, + node->pipe, node->id); } static int imgu_vb2_queue_setup(struct vb2_queue *vq, @@ -435,7 +421,7 @@ static bool imgu_all_nodes_streaming(struct imgu_device *imgu, pipe = except->pipe; if (!test_bit(pipe, imgu->css.enabled_pipes)) { dev_warn(&imgu->pci_dev->dev, - "pipe %d link is not ready yet", pipe); + "pipe %u link is not ready yet", pipe); return false; } @@ -479,7 +465,7 @@ static int imgu_vb2_start_streaming(struct vb2_queue *vq, unsigned int count) int r; unsigned int pipe; - dev_dbg(dev, "%s node name %s pipe %d id %u", __func__, + dev_dbg(dev, "%s node name %s pipe %u id %u", __func__, node->name, node->pipe, node->id); if (imgu->streaming) { @@ -539,7 +525,7 @@ static void imgu_vb2_stop_streaming(struct vb2_queue *vq) WARN_ON(!node->enabled); pipe = node->pipe; - dev_dbg(dev, "Try to stream off node [%d][%d]", pipe, node->id); + dev_dbg(dev, "Try to stream off node [%u][%u]", pipe, node->id); imgu_pipe = &imgu->imgu_pipe[pipe]; r = v4l2_subdev_call(&imgu_pipe->imgu_sd.subdev, video, s_stream, 0); if (r) @@ -664,20 +650,19 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node, struct v4l2_format *f, bool try) { struct device *dev = &imgu->pci_dev->dev; - struct v4l2_pix_format_mplane try_fmts[IPU3_CSS_QUEUES]; struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES] = { NULL }; struct v4l2_rect *rects[IPU3_CSS_RECTS] = { NULL }; struct v4l2_mbus_framefmt pad_fmt; unsigned int i, css_q; - int r; + int ret; struct imgu_css_pipe *css_pipe = &imgu->css.pipes[pipe]; struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; struct imgu_v4l2_subdev *imgu_sd = &imgu_pipe->imgu_sd; - dev_dbg(dev, "set fmt node [%u][%u](try = %d)", pipe, node, try); + dev_dbg(dev, "set fmt node [%u][%u](try = %u)", pipe, node, try); for (i = 0; i < IMGU_NODE_NUM; i++) - dev_dbg(dev, "IMGU pipe %d node %d enabled = %d", + dev_dbg(dev, "IMGU pipe %u node %u enabled = %u", pipe, i, imgu_pipe->nodes[i].enabled); if (imgu_pipe->nodes[IMGU_NODE_VF].enabled) @@ -688,7 +673,7 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node, else css_pipe->pipe_id = IPU3_CSS_PIPE_ID_CAPTURE; - dev_dbg(dev, "IPU3 pipe %d pipe_id = %d", pipe, css_pipe->pipe_id); + dev_dbg(dev, "IPU3 pipe %u pipe_id = %u", pipe, css_pipe->pipe_id); for (i = 0; i < IPU3_CSS_QUEUES; i++) { unsigned int inode = imgu_map_node(imgu, i); @@ -698,9 +683,13 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node, continue; if (try) { - try_fmts[i] = - imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp; - fmts[i] = &try_fmts[i]; + fmts[i] = kmemdup(&imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp, + sizeof(struct v4l2_pix_format_mplane), + GFP_KERNEL); + if (!fmts[i]) { + ret = -ENOMEM; + goto out; + } } else { fmts[i] = &imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp; } @@ -730,26 +719,33 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node, * before we return success from this function, so set it here. */ css_q = imgu_node_to_queue(node); - if (fmts[css_q]) - *fmts[css_q] = f->fmt.pix_mp; - else - return -EINVAL; + if (!fmts[css_q]) { + ret = -EINVAL; + goto out; + } + *fmts[css_q] = f->fmt.pix_mp; if (try) - r = imgu_css_fmt_try(&imgu->css, fmts, rects, pipe); + ret = imgu_css_fmt_try(&imgu->css, fmts, rects, pipe); else - r = imgu_css_fmt_set(&imgu->css, fmts, rects, pipe); + ret = imgu_css_fmt_set(&imgu->css, fmts, rects, pipe); - /* r is the binary number in the firmware blob */ - if (r < 0) - return r; + /* ret is the binary number in the firmware blob */ + if (ret < 0) + goto out; if (try) f->fmt.pix_mp = *fmts[css_q]; else f->fmt = imgu_pipe->nodes[node].vdev_fmt.fmt; - return 0; +out: + if (try) { + for (i = 0; i < IPU3_CSS_QUEUES; i++) + kfree(fmts[i]); + } + + return ret; } static int imgu_try_fmt(struct file *file, void *fh, struct v4l2_format *f) @@ -781,7 +777,7 @@ static int imgu_vidioc_try_fmt(struct file *file, void *fh, struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; int r; - dev_dbg(dev, "%s [%ux%u] for node %d\n", __func__, + dev_dbg(dev, "%s [%ux%u] for node %u\n", __func__, pix_mp->width, pix_mp->height, node->id); r = imgu_try_fmt(file, fh, f); @@ -799,7 +795,7 @@ static int imgu_vidioc_s_fmt(struct file *file, void *fh, struct v4l2_format *f) struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; int r; - dev_dbg(dev, "%s [%ux%u] for node %d\n", __func__, + dev_dbg(dev, "%s [%ux%u] for node %u\n", __func__, pix_mp->width, pix_mp->height, node->id); r = imgu_try_fmt(file, fh, f); @@ -1022,7 +1018,7 @@ static int imgu_sd_s_ctrl(struct v4l2_ctrl *ctrl) struct imgu_device *imgu = v4l2_get_subdevdata(&imgu_sd->subdev); struct device *dev = &imgu->pci_dev->dev; - dev_dbg(dev, "set val %d to ctrl 0x%8x for subdev %d", + dev_dbg(dev, "set val %d to ctrl 0x%8x for subdev %u", ctrl->val, ctrl->id, imgu_sd->pipe); switch (ctrl->id) { @@ -1122,7 +1118,7 @@ static int imgu_v4l2_subdev_register(struct imgu_device *imgu, imgu_sd->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; snprintf(imgu_sd->subdev.name, sizeof(imgu_sd->subdev.name), - "%s %d", IMGU_NAME, pipe); + "%s %u", IMGU_NAME, pipe); v4l2_set_subdevdata(&imgu_sd->subdev, imgu); atomic_set(&imgu_sd->running_mode, IPU3_RUNNING_MODE_VIDEO); v4l2_ctrl_handler_init(hdl, 1); @@ -1240,7 +1236,7 @@ static int imgu_v4l2_node_setup(struct imgu_device *imgu, unsigned int pipe, } /* Initialize vdev */ - snprintf(vdev->name, sizeof(vdev->name), "%s %d %s", + snprintf(vdev->name, sizeof(vdev->name), "%s %u %s", IMGU_NAME, pipe, node->name); vdev->release = video_device_release_empty; vdev->fops = &imgu_v4l2_fops; @@ -1335,7 +1331,7 @@ static int imgu_v4l2_register_pipes(struct imgu_device *imgu) r = imgu_v4l2_subdev_register(imgu, &imgu_pipe->imgu_sd, i); if (r) { dev_err(&imgu->pci_dev->dev, - "failed to register subdev%d ret (%d)\n", i, r); + "failed to register subdev%u ret (%d)\n", i, r); goto pipes_cleanup; } r = imgu_v4l2_nodes_setup_pipe(imgu, i); |