Commit c444914a authored by Sylwester Nawrocki's avatar Sylwester Nawrocki Committed by Mauro Carvalho Chehab

[media] s5p-fimc: Use vb2 ioctl/fop helpers in FIMC capture driver

mmap/poll file operation and several ioctl handlers are replaced
with the vb2 helper functions. Some helpers are used indirectly
to maintain the buffer queue ownership.
Signed-off-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 95c4a17f
...@@ -454,24 +454,12 @@ static void buffer_queue(struct vb2_buffer *vb) ...@@ -454,24 +454,12 @@ static void buffer_queue(struct vb2_buffer *vb)
spin_unlock_irqrestore(&fimc->slock, flags); spin_unlock_irqrestore(&fimc->slock, flags);
} }
static void fimc_lock(struct vb2_queue *vq)
{
struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
mutex_lock(&ctx->fimc_dev->lock);
}
static void fimc_unlock(struct vb2_queue *vq)
{
struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
mutex_unlock(&ctx->fimc_dev->lock);
}
static struct vb2_ops fimc_capture_qops = { static struct vb2_ops fimc_capture_qops = {
.queue_setup = queue_setup, .queue_setup = queue_setup,
.buf_prepare = buffer_prepare, .buf_prepare = buffer_prepare,
.buf_queue = buffer_queue, .buf_queue = buffer_queue,
.wait_prepare = fimc_unlock, .wait_prepare = vb2_ops_wait_prepare,
.wait_finish = fimc_lock, .wait_finish = vb2_ops_wait_finish,
.start_streaming = start_streaming, .start_streaming = start_streaming,
.stop_streaming = stop_streaming, .stop_streaming = stop_streaming,
}; };
...@@ -530,7 +518,7 @@ static int fimc_capture_open(struct file *file) ...@@ -530,7 +518,7 @@ static int fimc_capture_open(struct file *file)
goto unlock; goto unlock;
} }
if (++fimc->vid_cap.refcnt == 1) { if (v4l2_fh_is_singular_file(file)) {
ret = fimc_pipeline_call(fimc, open, &fimc->pipeline, ret = fimc_pipeline_call(fimc, open, &fimc->pipeline,
&fimc->vid_cap.vfd.entity, true); &fimc->vid_cap.vfd.entity, true);
...@@ -543,8 +531,9 @@ static int fimc_capture_open(struct file *file) ...@@ -543,8 +531,9 @@ static int fimc_capture_open(struct file *file)
if (ret < 0) { if (ret < 0) {
clear_bit(ST_CAPT_BUSY, &fimc->state); clear_bit(ST_CAPT_BUSY, &fimc->state);
pm_runtime_put_sync(&fimc->pdev->dev); pm_runtime_put_sync(&fimc->pdev->dev);
fimc->vid_cap.refcnt--;
v4l2_fh_release(file); v4l2_fh_release(file);
} else {
fimc->vid_cap.refcnt++;
} }
} }
unlock: unlock:
...@@ -553,7 +542,7 @@ static int fimc_capture_open(struct file *file) ...@@ -553,7 +542,7 @@ static int fimc_capture_open(struct file *file)
return ret; return ret;
} }
static int fimc_capture_close(struct file *file) static int fimc_capture_release(struct file *file)
{ {
struct fimc_dev *fimc = video_drvdata(file); struct fimc_dev *fimc = video_drvdata(file);
int ret; int ret;
...@@ -562,50 +551,20 @@ static int fimc_capture_close(struct file *file) ...@@ -562,50 +551,20 @@ static int fimc_capture_close(struct file *file)
mutex_lock(&fimc->lock); mutex_lock(&fimc->lock);
if (--fimc->vid_cap.refcnt == 0) { if (v4l2_fh_is_singular_file(file)) {
clear_bit(ST_CAPT_BUSY, &fimc->state); clear_bit(ST_CAPT_BUSY, &fimc->state);
fimc_stop_capture(fimc, false); fimc_stop_capture(fimc, false);
fimc_pipeline_call(fimc, close, &fimc->pipeline); fimc_pipeline_call(fimc, close, &fimc->pipeline);
clear_bit(ST_CAPT_SUSPENDED, &fimc->state); clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
fimc->vid_cap.refcnt--;
} }
pm_runtime_put(&fimc->pdev->dev); pm_runtime_put(&fimc->pdev->dev);
if (fimc->vid_cap.refcnt == 0) { if (v4l2_fh_is_singular_file(file))
vb2_queue_release(&fimc->vid_cap.vbq);
fimc_ctrls_delete(fimc->vid_cap.ctx); fimc_ctrls_delete(fimc->vid_cap.ctx);
}
ret = v4l2_fh_release(file);
mutex_unlock(&fimc->lock); ret = vb2_fop_release(file);
return ret;
}
static unsigned int fimc_capture_poll(struct file *file,
struct poll_table_struct *wait)
{
struct fimc_dev *fimc = video_drvdata(file);
int ret;
if (mutex_lock_interruptible(&fimc->lock))
return POLL_ERR;
ret = vb2_poll(&fimc->vid_cap.vbq, file, wait);
mutex_unlock(&fimc->lock);
return ret;
}
static int fimc_capture_mmap(struct file *file, struct vm_area_struct *vma)
{
struct fimc_dev *fimc = video_drvdata(file);
int ret;
if (mutex_lock_interruptible(&fimc->lock))
return -ERESTARTSYS;
ret = vb2_mmap(&fimc->vid_cap.vbq, vma);
mutex_unlock(&fimc->lock); mutex_unlock(&fimc->lock);
return ret; return ret;
...@@ -614,10 +573,10 @@ static int fimc_capture_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -614,10 +573,10 @@ static int fimc_capture_mmap(struct file *file, struct vm_area_struct *vma)
static const struct v4l2_file_operations fimc_capture_fops = { static const struct v4l2_file_operations fimc_capture_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = fimc_capture_open, .open = fimc_capture_open,
.release = fimc_capture_close, .release = fimc_capture_release,
.poll = fimc_capture_poll, .poll = vb2_fop_poll,
.unlocked_ioctl = video_ioctl2, .unlocked_ioctl = video_ioctl2,
.mmap = fimc_capture_mmap, .mmap = vb2_fop_mmap,
}; };
/* /*
...@@ -1247,7 +1206,7 @@ static int fimc_cap_streamon(struct file *file, void *priv, ...@@ -1247,7 +1206,7 @@ static int fimc_cap_streamon(struct file *file, void *priv,
goto err_p_stop; goto err_p_stop;
} }
ret = vb2_streamon(&vc->vbq, type); ret = vb2_ioctl_streamon(file, priv, type);
if (!ret) if (!ret)
return ret; return ret;
...@@ -1262,7 +1221,7 @@ static int fimc_cap_streamoff(struct file *file, void *priv, ...@@ -1262,7 +1221,7 @@ static int fimc_cap_streamoff(struct file *file, void *priv,
struct fimc_dev *fimc = video_drvdata(file); struct fimc_dev *fimc = video_drvdata(file);
int ret; int ret;
ret = vb2_streamoff(&fimc->vid_cap.vbq, type); ret = vb2_ioctl_streamoff(file, priv, type);
if (ret == 0) if (ret == 0)
media_entity_pipeline_stop(&fimc->vid_cap.vfd.entity); media_entity_pipeline_stop(&fimc->vid_cap.vfd.entity);
...@@ -1274,59 +1233,14 @@ static int fimc_cap_reqbufs(struct file *file, void *priv, ...@@ -1274,59 +1233,14 @@ static int fimc_cap_reqbufs(struct file *file, void *priv,
struct v4l2_requestbuffers *reqbufs) struct v4l2_requestbuffers *reqbufs)
{ {
struct fimc_dev *fimc = video_drvdata(file); struct fimc_dev *fimc = video_drvdata(file);
int ret = vb2_reqbufs(&fimc->vid_cap.vbq, reqbufs); int ret;
ret = vb2_ioctl_reqbufs(file, priv, reqbufs);
if (!ret) if (!ret)
fimc->vid_cap.reqbufs_count = reqbufs->count; fimc->vid_cap.reqbufs_count = reqbufs->count;
return ret;
}
static int fimc_cap_querybuf(struct file *file, void *priv,
struct v4l2_buffer *buf)
{
struct fimc_dev *fimc = video_drvdata(file);
return vb2_querybuf(&fimc->vid_cap.vbq, buf);
}
static int fimc_cap_qbuf(struct file *file, void *priv,
struct v4l2_buffer *buf)
{
struct fimc_dev *fimc = video_drvdata(file);
return vb2_qbuf(&fimc->vid_cap.vbq, buf);
}
static int fimc_cap_expbuf(struct file *file, void *priv, return ret;
struct v4l2_exportbuffer *eb)
{
struct fimc_dev *fimc = video_drvdata(file);
return vb2_expbuf(&fimc->vid_cap.vbq, eb);
}
static int fimc_cap_dqbuf(struct file *file, void *priv,
struct v4l2_buffer *buf)
{
struct fimc_dev *fimc = video_drvdata(file);
return vb2_dqbuf(&fimc->vid_cap.vbq, buf, file->f_flags & O_NONBLOCK);
}
static int fimc_cap_create_bufs(struct file *file, void *priv,
struct v4l2_create_buffers *create)
{
struct fimc_dev *fimc = video_drvdata(file);
return vb2_create_bufs(&fimc->vid_cap.vbq, create);
}
static int fimc_cap_prepare_buf(struct file *file, void *priv,
struct v4l2_buffer *b)
{
struct fimc_dev *fimc = video_drvdata(file);
return vb2_prepare_buf(&fimc->vid_cap.vbq, b);
} }
static int fimc_cap_g_selection(struct file *file, void *fh, static int fimc_cap_g_selection(struct file *file, void *fh,
...@@ -1425,14 +1339,12 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = { ...@@ -1425,14 +1339,12 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = {
.vidioc_g_fmt_vid_cap_mplane = fimc_cap_g_fmt_mplane, .vidioc_g_fmt_vid_cap_mplane = fimc_cap_g_fmt_mplane,
.vidioc_reqbufs = fimc_cap_reqbufs, .vidioc_reqbufs = fimc_cap_reqbufs,
.vidioc_querybuf = fimc_cap_querybuf, .vidioc_querybuf = vb2_ioctl_querybuf,
.vidioc_qbuf = vb2_ioctl_qbuf,
.vidioc_qbuf = fimc_cap_qbuf, .vidioc_dqbuf = vb2_ioctl_dqbuf,
.vidioc_dqbuf = fimc_cap_dqbuf, .vidioc_expbuf = vb2_ioctl_expbuf,
.vidioc_expbuf = fimc_cap_expbuf, .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
.vidioc_create_bufs = vb2_ioctl_create_bufs,
.vidioc_prepare_buf = fimc_cap_prepare_buf,
.vidioc_create_bufs = fimc_cap_create_bufs,
.vidioc_streamon = fimc_cap_streamon, .vidioc_streamon = fimc_cap_streamon,
.vidioc_streamoff = fimc_cap_streamoff, .vidioc_streamoff = fimc_cap_streamoff,
...@@ -1759,9 +1671,9 @@ static int fimc_register_capture_device(struct fimc_dev *fimc, ...@@ -1759,9 +1671,9 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
struct v4l2_device *v4l2_dev) struct v4l2_device *v4l2_dev)
{ {
struct video_device *vfd = &fimc->vid_cap.vfd; struct video_device *vfd = &fimc->vid_cap.vfd;
struct fimc_vid_cap *vid_cap; struct vb2_queue *q = &fimc->vid_cap.vbq;
struct fimc_ctx *ctx; struct fimc_ctx *ctx;
struct vb2_queue *q; struct fimc_vid_cap *vid_cap;
int ret = -ENOMEM; int ret = -ENOMEM;
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
...@@ -1783,28 +1695,27 @@ static int fimc_register_capture_device(struct fimc_dev *fimc, ...@@ -1783,28 +1695,27 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
vfd->v4l2_dev = v4l2_dev; vfd->v4l2_dev = v4l2_dev;
vfd->minor = -1; vfd->minor = -1;
vfd->release = video_device_release_empty; vfd->release = video_device_release_empty;
vfd->queue = q;
vfd->lock = &fimc->lock; vfd->lock = &fimc->lock;
video_set_drvdata(vfd, fimc); video_set_drvdata(vfd, fimc);
vid_cap = &fimc->vid_cap; vid_cap = &fimc->vid_cap;
vid_cap->active_buf_cnt = 0; vid_cap->active_buf_cnt = 0;
vid_cap->reqbufs_count = 0; vid_cap->reqbufs_count = 0;
vid_cap->refcnt = 0; vid_cap->ctx = ctx;
INIT_LIST_HEAD(&vid_cap->pending_buf_q); INIT_LIST_HEAD(&vid_cap->pending_buf_q);
INIT_LIST_HEAD(&vid_cap->active_buf_q); INIT_LIST_HEAD(&vid_cap->active_buf_q);
vid_cap->ctx = ctx;
q = &fimc->vid_cap.vbq;
memset(q, 0, sizeof(*q)); memset(q, 0, sizeof(*q));
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
q->drv_priv = fimc->vid_cap.ctx; q->drv_priv = ctx;
q->ops = &fimc_capture_qops; q->ops = &fimc_capture_qops;
q->mem_ops = &vb2_dma_contig_memops; q->mem_ops = &vb2_dma_contig_memops;
q->buf_struct_size = sizeof(struct fimc_vid_buffer); q->buf_struct_size = sizeof(struct fimc_vid_buffer);
q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
q->lock = &fimc->lock;
ret = vb2_queue_init(q); ret = vb2_queue_init(q);
if (ret) if (ret)
......
...@@ -667,16 +667,15 @@ static int fimc_m2m_open(struct file *file) ...@@ -667,16 +667,15 @@ static int fimc_m2m_open(struct file *file)
struct fimc_ctx *ctx; struct fimc_ctx *ctx;
int ret = -EBUSY; int ret = -EBUSY;
dbg("pid: %d, state: 0x%lx, refcnt: %d", pr_debug("pid: %d, state: %#lx\n", task_pid_nr(current), fimc->state);
task_pid_nr(current), fimc->state, fimc->vid_cap.refcnt);
if (mutex_lock_interruptible(&fimc->lock)) if (mutex_lock_interruptible(&fimc->lock))
return -ERESTARTSYS; return -ERESTARTSYS;
/* /*
* Return if the corresponding video capture node * Don't allow simultaneous open() of the mem-to-mem and the
* is already opened. * capture video node that belong to same FIMC IP instance.
*/ */
if (fimc->vid_cap.refcnt > 0) if (test_bit(ST_CAPT_BUSY, &fimc->state))
goto unlock; goto unlock;
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment