[PATCH 06/12] dt3155v4l: move vb2_queue to top-level

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Hans Verkuil <hans.verkuil@xxxxxxxxx>

Instead of initializing the vb2_queue in open (and freeing in release)
do this in probe/remove instead. And as a bonus use the vb2 helper
functions to greatly simplify the driver.

Signed-off-by: Hans Verkuil <hans.verkuil@xxxxxxxxx>
---
 drivers/staging/media/dt3155v4l/dt3155v4l.c | 233 +++++++---------------------
 drivers/staging/media/dt3155v4l/dt3155v4l.h |   8 +-
 2 files changed, 57 insertions(+), 184 deletions(-)

diff --git a/drivers/staging/media/dt3155v4l/dt3155v4l.c b/drivers/staging/media/dt3155v4l/dt3155v4l.c
index 28b649d..6d571f6 100644
--- a/drivers/staging/media/dt3155v4l/dt3155v4l.c
+++ b/drivers/staging/media/dt3155v4l/dt3155v4l.c
@@ -201,41 +201,24 @@ static int dt3155_start_acq(struct dt3155_priv *pd)
 }
 
 static int
-dt3155_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
-		unsigned int *num_buffers, unsigned int *num_planes,
+dt3155_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+		unsigned int *nbuffers, unsigned int *num_planes,
 		unsigned int sizes[], void *alloc_ctxs[])
 
 {
-	struct dt3155_priv *pd = vb2_get_drv_priv(q);
-	void *ret;
+	struct dt3155_priv *pd = vb2_get_drv_priv(vq);
+	unsigned size = img_width * img_height;
 
-	if (*num_buffers == 0)
-		*num_buffers = 1;
+	if (vq->num_buffers + *nbuffers < 2)
+		*nbuffers = 2 - vq->num_buffers;
+	if (fmt && fmt->fmt.pix.sizeimage < size)
+		return -EINVAL;
 	*num_planes = 1;
-	sizes[0] = img_width * img_height;
-	if (pd->q->alloc_ctx[0])
-		return 0;
-	ret = vb2_dma_contig_init_ctx(&pd->pdev->dev);
-	if (IS_ERR(ret))
-		return PTR_ERR(ret);
-	pd->q->alloc_ctx[0] = ret;
+	sizes[0] = fmt ? fmt->fmt.pix.sizeimage : size;
+	alloc_ctxs[0] = pd->alloc_ctx;
 	return 0;
 }
 
-static void dt3155_wait_prepare(struct vb2_queue *q)
-{
-	struct dt3155_priv *pd = vb2_get_drv_priv(q);
-
-	mutex_unlock(pd->vdev.lock);
-}
-
-static void dt3155_wait_finish(struct vb2_queue *q)
-{
-	struct dt3155_priv *pd = vb2_get_drv_priv(q);
-
-	mutex_lock(pd->vdev.lock);
-}
-
 static int dt3155_buf_prepare(struct vb2_buffer *vb)
 {
 	vb2_set_plane_payload(vb, 0, img_width * img_height);
@@ -255,6 +238,9 @@ static void dt3155_stop_streaming(struct vb2_queue *q)
 	}
 	spin_unlock_irq(&pd->lock);
 	msleep(45); /* irq hendler will stop the hardware */
+	/* disable all irqs, clear all irq flags */
+	iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD,
+					pd->regs + INT_CSR);
 }
 
 static void dt3155_buf_queue(struct vb2_buffer *vb)
@@ -274,8 +260,8 @@ static void dt3155_buf_queue(struct vb2_buffer *vb)
 
 static const struct vb2_ops q_ops = {
 	.queue_setup = dt3155_queue_setup,
-	.wait_prepare = dt3155_wait_prepare,
-	.wait_finish = dt3155_wait_finish,
+	.wait_prepare = vb2_ops_wait_prepare,
+	.wait_finish = vb2_ops_wait_finish,
 	.buf_prepare = dt3155_buf_prepare,
 	.stop_streaming = dt3155_stop_streaming,
 	.buf_queue = dt3155_buf_queue,
@@ -313,7 +299,7 @@ static irqreturn_t dt3155_irq_handler_even(int irq, void *dev_id)
 		vb2_buffer_done(ipd->curr_buf, VB2_BUF_STATE_DONE);
 	}
 
-	if (!ipd->q->streaming || list_empty(&ipd->dmaq))
+	if (!ipd->vidq.streaming || list_empty(&ipd->dmaq))
 		goto stop_dma;
 	ivb = list_first_entry(&ipd->dmaq, typeof(*ivb), done_entry);
 	list_del(&ivb->done_entry);
@@ -342,124 +328,16 @@ stop_dma:
 	return IRQ_HANDLED;
 }
 
-static int dt3155_open(struct file *filp)
-{
-	int ret = 0;
-	struct dt3155_priv *pd = video_drvdata(filp);
-
-	if (mutex_lock_interruptible(&pd->mux))
-		return -ERESTARTSYS;
-	if (!pd->users) {
-		pd->q = kzalloc(sizeof(*pd->q), GFP_KERNEL);
-		if (!pd->q) {
-			ret = -ENOMEM;
-			goto err_alloc_queue;
-		}
-		pd->q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		pd->q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
-		pd->q->io_modes = VB2_READ | VB2_MMAP;
-		pd->q->ops = &q_ops;
-		pd->q->mem_ops = &vb2_dma_contig_memops;
-		pd->q->drv_priv = pd;
-		pd->curr_buf = NULL;
-		pd->field_count = 0;
-		ret = vb2_queue_init(pd->q);
-		if (ret < 0)
-			goto err_request_irq;
-		INIT_LIST_HEAD(&pd->dmaq);
-		spin_lock_init(&pd->lock);
-		/* disable all irqs, clear all irq flags */
-		iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD,
-						pd->regs + INT_CSR);
-	}
-	pd->users++;
-	mutex_unlock(&pd->mux);
-	return 0; /* success */
-err_request_irq:
-	kfree(pd->q);
-	pd->q = NULL;
-err_alloc_queue:
-	mutex_unlock(&pd->mux);
-	return ret;
-}
-
-static int dt3155_release(struct file *filp)
-{
-	struct dt3155_priv *pd = video_drvdata(filp);
-
-	mutex_lock(&pd->mux);
-	pd->users--;
-	BUG_ON(pd->users < 0);
-	if (!pd->users) {
-		vb2_queue_release(pd->q);
-		if (pd->q->alloc_ctx[0])
-			vb2_dma_contig_cleanup_ctx(pd->q->alloc_ctx[0]);
-		kfree(pd->q);
-		pd->q = NULL;
-	}
-	mutex_unlock(&pd->mux);
-	return 0;
-}
-
-static ssize_t dt3155_read(struct file *filp, char __user *user, size_t size, loff_t *loff)
-{
-	struct dt3155_priv *pd = video_drvdata(filp);
-	ssize_t res;
-
-	if (mutex_lock_interruptible(&pd->mux))
-		return -ERESTARTSYS;
-	res = vb2_read(pd->q, user, size, loff, filp->f_flags & O_NONBLOCK);
-	mutex_unlock(&pd->mux);
-	return res;
-}
-
-static unsigned int dt3155_poll(struct file *filp, struct poll_table_struct *polltbl)
-{
-	struct dt3155_priv *pd = video_drvdata(filp);
-	unsigned int res;
-
-	mutex_lock(&pd->mux);
-	res = vb2_poll(pd->q, filp, polltbl);
-	mutex_unlock(&pd->mux);
-	return res;
-}
-
-static int dt3155_mmap(struct file *filp, struct vm_area_struct *vma)
-{
-	struct dt3155_priv *pd = video_drvdata(filp);
-	int res;
-
-	if (mutex_lock_interruptible(&pd->mux))
-		return -ERESTARTSYS;
-	res = vb2_mmap(pd->q, vma);
-	mutex_unlock(&pd->mux);
-	return res;
-}
-
 static const struct v4l2_file_operations dt3155_fops = {
 	.owner = THIS_MODULE,
-	.open = dt3155_open,
-	.release = dt3155_release,
-	.read = dt3155_read,
-	.poll = dt3155_poll,
-	.unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
-	.mmap = dt3155_mmap,
+	.open = v4l2_fh_open,
+	.release = vb2_fop_release,
+	.unlocked_ioctl = video_ioctl2,
+	.read = vb2_fop_read,
+	.mmap = vb2_fop_mmap,
+	.poll = vb2_fop_poll
 };
 
-static int dt3155_streamon(struct file *filp, void *p, enum v4l2_buf_type type)
-{
-	struct dt3155_priv *pd = video_drvdata(filp);
-
-	return vb2_streamon(pd->q, type);
-}
-
-static int dt3155_streamoff(struct file *filp, void *p, enum v4l2_buf_type type)
-{
-	struct dt3155_priv *pd = video_drvdata(filp);
-
-	return vb2_streamoff(pd->q, type);
-}
-
 static int dt3155_querycap(struct file *filp, void *p, struct v4l2_capability *cap)
 {
 	struct dt3155_priv *pd = video_drvdata(filp);
@@ -516,34 +394,6 @@ static int dt3155_s_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *
 	return dt3155_g_fmt_vid_cap(filp, p, f);
 }
 
-static int dt3155_reqbufs(struct file *filp, void *p, struct v4l2_requestbuffers *b)
-{
-	struct dt3155_priv *pd = video_drvdata(filp);
-
-	return vb2_reqbufs(pd->q, b);
-}
-
-static int dt3155_querybuf(struct file *filp, void *p, struct v4l2_buffer *b)
-{
-	struct dt3155_priv *pd = video_drvdata(filp);
-
-	return vb2_querybuf(pd->q, b);
-}
-
-static int dt3155_qbuf(struct file *filp, void *p, struct v4l2_buffer *b)
-{
-	struct dt3155_priv *pd = video_drvdata(filp);
-
-	return vb2_qbuf(pd->q, b);
-}
-
-static int dt3155_dqbuf(struct file *filp, void *p, struct v4l2_buffer *b)
-{
-	struct dt3155_priv *pd = video_drvdata(filp);
-
-	return vb2_dqbuf(pd->q, b, filp->f_flags & O_NONBLOCK);
-}
-
 static int dt3155_querystd(struct file *filp, void *p, v4l2_std_id *norm)
 {
 	*norm = DT3155_CURRENT_NORM;
@@ -619,17 +469,19 @@ static int dt3155_s_parm(struct file *filp, void *p, struct v4l2_streamparm *par
 }
 
 static const struct v4l2_ioctl_ops dt3155_ioctl_ops = {
-	.vidioc_streamon = dt3155_streamon,
-	.vidioc_streamoff = dt3155_streamoff,
 	.vidioc_querycap = dt3155_querycap,
 	.vidioc_enum_fmt_vid_cap = dt3155_enum_fmt_vid_cap,
 	.vidioc_try_fmt_vid_cap = dt3155_try_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap = dt3155_g_fmt_vid_cap,
 	.vidioc_s_fmt_vid_cap = dt3155_s_fmt_vid_cap,
-	.vidioc_reqbufs = dt3155_reqbufs,
-	.vidioc_querybuf = dt3155_querybuf,
-	.vidioc_qbuf = dt3155_qbuf,
-	.vidioc_dqbuf = dt3155_dqbuf,
+	.vidioc_reqbufs = vb2_ioctl_reqbufs,
+	.vidioc_create_bufs = vb2_ioctl_create_bufs,
+	.vidioc_querybuf = vb2_ioctl_querybuf,
+	.vidioc_expbuf = vb2_ioctl_expbuf,
+	.vidioc_qbuf = vb2_ioctl_qbuf,
+	.vidioc_dqbuf = vb2_ioctl_dqbuf,
+	.vidioc_streamon = vb2_ioctl_streamon,
+	.vidioc_streamoff = vb2_ioctl_streamoff,
 	.vidioc_querystd = dt3155_querystd,
 	.vidioc_g_std = dt3155_g_std,
 	.vidioc_s_std = dt3155_s_std,
@@ -740,17 +592,34 @@ static int dt3155_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	pd->vdev = dt3155_vdev;
 	pd->vdev.v4l2_dev = &pd->v4l2_dev;
 	video_set_drvdata(&pd->vdev, pd);  /* for use in video_fops */
-	pd->users = 0;
 	pd->pdev = pdev;
 	INIT_LIST_HEAD(&pd->dmaq);
 	mutex_init(&pd->mux);
 	pd->vdev.lock = &pd->mux; /* for locking v4l2_file_operations */
+	pd->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	pd->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	pd->vidq.io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
+	pd->vidq.ops = &q_ops;
+	pd->vidq.mem_ops = &vb2_dma_contig_memops;
+	pd->vidq.drv_priv = pd;
+	pd->vidq.min_buffers_needed = 2;
+	pd->vidq.lock = &pd->mux; /* for locking v4l2_file_operations */
+	pd->vdev.queue = &pd->vidq;
+	err = vb2_queue_init(&pd->vidq);
+	if (err < 0)
+		goto err_v4l2_dev_unreg;
+	pd->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
+	if (IS_ERR(pd->alloc_ctx)) {
+		dev_err(&pdev->dev, "Can't allocate buffer context");
+		err = PTR_ERR(pd->alloc_ctx);
+		goto err_v4l2_dev_unreg;
+	}
 	spin_lock_init(&pd->lock);
 	pd->csr2 = csr2_init;
 	pd->config = config_init;
 	err = pci_enable_device(pdev);
 	if (err)
-		goto err_v4l2_dev_unreg;
+		goto err_free_ctx;
 	err = pci_request_region(pdev, 0, pci_name(pdev));
 	if (err)
 		goto err_pci_disable;
@@ -780,6 +649,8 @@ err_free_reg:
 	pci_release_region(pdev, 0);
 err_pci_disable:
 	pci_disable_device(pdev);
+err_free_ctx:
+	vb2_dma_contig_cleanup_ctx(pd->alloc_ctx);
 err_v4l2_dev_unreg:
 	v4l2_device_unregister(&pd->v4l2_dev);
 	return err;
@@ -792,10 +663,12 @@ static void dt3155_remove(struct pci_dev *pdev)
 
 	video_unregister_device(&pd->vdev);
 	free_irq(pd->pdev->irq, pd);
+	vb2_queue_release(&pd->vidq);
 	v4l2_device_unregister(&pd->v4l2_dev);
 	pci_iounmap(pdev, pd->regs);
 	pci_release_region(pdev, 0);
 	pci_disable_device(pdev);
+	vb2_dma_contig_cleanup_ctx(pd->alloc_ctx);
 }
 
 static const struct pci_device_id pci_ids[] = {
diff --git a/drivers/staging/media/dt3155v4l/dt3155v4l.h b/drivers/staging/media/dt3155v4l/dt3155v4l.h
index 3c8073a..11a8146 100644
--- a/drivers/staging/media/dt3155v4l/dt3155v4l.h
+++ b/drivers/staging/media/dt3155v4l/dt3155v4l.h
@@ -165,14 +165,14 @@
  * @v4l2_dev:		v4l2_device structure
  * @vdev:		video_device structure
  * @pdev:		pointer to pci_dev structure
- * @q			pointer to vb2_queue structure
+ * @vidq:		vb2_queue structure
+ * @alloc_ctx:		dma_contig allocation context
  * @curr_buf:		pointer to curren buffer
  * @mux:		mutex to protect the instance
  * @dmaq		queue for dma buffers
  * @lock		spinlock for dma queue
  * @field_count		fields counter
  * @stats:		statistics structure
- * @users		open count
  * @regs:		local copy of mmio base register
  * @csr2:		local copy of csr2 register
  * @config:		local copy of config register
@@ -181,14 +181,14 @@ struct dt3155_priv {
 	struct v4l2_device v4l2_dev;
 	struct video_device vdev;
 	struct pci_dev *pdev;
-	struct vb2_queue *q;
+	struct vb2_queue vidq;
+	struct vb2_alloc_ctx *alloc_ctx;
 	struct vb2_buffer *curr_buf;
 	struct mutex mux;
 	struct list_head dmaq;
 	spinlock_t lock;
 	unsigned int field_count;
 	void __iomem *regs;
-	int users;
 	u8 csr2, config;
 };
 
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux