commit: http://blackfin.uclinux.org/git/?p=linux-kernel;a=commitdiff;h=ea6acc9b77c8b0fc564e42a22e39ae457845b324
branch: http://blackfin.uclinux.org/git/?p=linux-kernel;a=shortlog;h=refs/heads/trunk

Signed-off-by: Scott Jiang <[email protected]>
---
 drivers/media/platform/blackfin/bfin_display.c |  271 ++++--------------------
 1 files changed, 44 insertions(+), 227 deletions(-)

diff --git a/drivers/media/platform/blackfin/bfin_display.c b/drivers/media/platform/blackfin/bfin_display.c
index b727511..8a6d900 100644
--- a/drivers/media/platform/blackfin/bfin_display.c
+++ b/drivers/media/platform/blackfin/bfin_display.c
@@ -99,14 +99,10 @@ struct bfin_disp_device {
 	struct list_head dma_queue;
 	/* used in videobuf2 callback */
 	spinlock_t lock;
-	/* used to access display device */
+	/* used to serialize all ioctls */
 	struct mutex mutex;
-};
-
-struct bfin_disp_fh {
-	struct v4l2_fh fh;
-	/* indicates whether this file handle is doing IO */
-	bool io_allowed;
+	/* used to serialize all queuing ioctls */
+	struct mutex qlock;
 };
 
 static const struct bfin_disp_format bfin_disp_formats[] = {
@@ -196,95 +192,6 @@ static void bfin_disp_free_encoder_formats(struct bfin_disp_device *disp)
 	disp->enc_formats = NULL;
 }
 
-static int bfin_disp_open(struct file *file)
-{
-	struct bfin_disp_device *disp = video_drvdata(file);
-	struct video_device *vfd = &disp->video_dev;
-	struct bfin_disp_fh *bfin_disp_fh;
-
-	if (!disp->sd) {
-		v4l2_err(&disp->v4l2_dev, "No sub device registered\n");
-		return -ENODEV;
-	}
-
-	bfin_disp_fh = kzalloc(sizeof(*bfin_disp_fh), GFP_KERNEL);
-	if (!bfin_disp_fh) {
-		v4l2_err(&disp->v4l2_dev,
-			 "unable to allocate memory for file handle object\n");
-		return -ENOMEM;
-	}
-
-	v4l2_fh_init(&bfin_disp_fh->fh, vfd);
-
-	/* store pointer to v4l2_fh in private_data member of file */
-	file->private_data = &bfin_disp_fh->fh;
-	v4l2_fh_add(&bfin_disp_fh->fh);
-	bfin_disp_fh->io_allowed = false;
-	return 0;
-}
-
-static int bfin_disp_release(struct file *file)
-{
-	struct bfin_disp_device *disp = video_drvdata(file);
-	struct v4l2_fh *fh = file->private_data;
-	struct bfin_disp_fh *bfin_disp_fh = container_of(fh, struct bfin_disp_fh, fh);
-
-	/* if this instance is doing IO */
-	if (bfin_disp_fh->io_allowed)
-		vb2_queue_release(&disp->buffer_queue);
-
-	file->private_data = NULL;
-	v4l2_fh_del(&bfin_disp_fh->fh);
-	v4l2_fh_exit(&bfin_disp_fh->fh);
-	kfree(bfin_disp_fh);
-	return 0;
-}
-
-static int bfin_disp_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	struct bfin_disp_device *disp = video_drvdata(file);
-	int ret;
-
-	if (mutex_lock_interruptible(&disp->mutex))
-		return -ERESTARTSYS;
-	ret = vb2_mmap(&disp->buffer_queue, vma);
-	mutex_unlock(&disp->mutex);
-	return ret;
-}
-
-#ifndef CONFIG_MMU
-static unsigned long bfin_disp_get_unmapped_area(struct file *file,
-					    unsigned long addr,
-					    unsigned long len,
-					    unsigned long pgoff,
-					    unsigned long flags)
-{
-	struct bfin_disp_device *disp = video_drvdata(file);
-	int ret;
-
-	if (mutex_lock_interruptible(&disp->mutex))
-		return -ERESTARTSYS;
-	ret = vb2_get_unmapped_area(&disp->buffer_queue,
-				    addr,
-				    len,
-				    pgoff,
-				    flags);
-	mutex_unlock(&disp->mutex);
-	return ret;
-}
-#endif
-
-static unsigned int bfin_disp_poll(struct file *file, poll_table *wait)
-{
-	struct bfin_disp_device *disp = video_drvdata(file);
-	int ret;
-
-	mutex_lock(&disp->mutex);
-	ret = vb2_poll(&disp->buffer_queue, file, wait);
-	mutex_unlock(&disp->mutex);
-	return ret;
-}
-
 static int bfin_disp_queue_setup(struct vb2_queue *vq,
 				const struct v4l2_format *fmt,
 				unsigned int *nbuffers, unsigned int *nplanes,
@@ -349,18 +256,6 @@ static void bfin_disp_buffer_cleanup(struct vb2_buffer *vb)
 	spin_unlock_irqrestore(&disp->lock, flags);
 }
 
-static void bfin_disp_lock(struct vb2_queue *vq)
-{
-	struct bfin_disp_device *disp = vb2_get_drv_priv(vq);
-	mutex_lock(&disp->mutex);
-}
-
-static void bfin_disp_unlock(struct vb2_queue *vq)
-{
-	struct bfin_disp_device *disp = vb2_get_drv_priv(vq);
-	mutex_unlock(&disp->mutex);
-}
-
 static irqreturn_t bfin_disp_isr(int irq, void *dev_id)
 {
 	struct ppi_if *ppi = dev_id;
@@ -396,6 +291,8 @@ static int bfin_disp_start_streaming(struct vb2_queue *vq, unsigned int count)
 	struct bfin_disp_device *disp = vb2_get_drv_priv(vq);
 	struct ppi_if *ppi = disp->ppi;
 	struct ppi_params params;
+	dma_addr_t addr;
+	unsigned long flags;
 	int ret;
 
 	/* enable streamon on the sub device */
@@ -447,7 +344,7 @@ static int bfin_disp_start_streaming(struct vb2_queue *vq, unsigned int count)
 	ret = ppi->ops->set_params(ppi, &params);
 	if (ret < 0) {
 		v4l2_err(&disp->v4l2_dev,
-				"Error in setting ppi params\n");
+				"set ppi params failed\n");
 		return ret;
 	}
 
@@ -455,10 +352,31 @@ static int bfin_disp_start_streaming(struct vb2_queue *vq, unsigned int count)
 	ret = ppi->ops->attach_irq(ppi, bfin_disp_isr);
 	if (ret < 0) {
 		v4l2_err(&disp->v4l2_dev,
-				"Error in attaching interrupt handler\n");
+				"attach interrupt handler failed\n");
 		return ret;
 	}
 
+	spin_lock_irqsave(&disp->lock, flags);
+	/* if dma queue is empty, return error */
+	if (list_empty(&disp->dma_queue)) {
+		spin_unlock_irqrestore(&disp->lock, flags);
+		v4l2_err(&disp->v4l2_dev, "dma queue is empty\n");
+		return -EINVAL;
+	}
+
+	/* get the next frame from the dma queue */
+	disp->cur_frm = list_entry(disp->dma_queue.next,
+					struct bfin_disp_buffer, list);
+	/* remove buffer from the dma queue */
+	list_del(&disp->cur_frm->list);
+	spin_unlock_irqrestore(&disp->lock, flags);
+
+	addr = vb2_dma_contig_plane_dma_addr(&disp->cur_frm->vb, 0);
+	/* update DMA address */
+	ppi->ops->update_addr(ppi, (unsigned long)addr);
+	/* enable ppi */
+	ppi->ops->start(ppi);
+
 	return 0;
 }
 
@@ -497,116 +415,12 @@ static struct vb2_ops bfin_disp_video_qops = {
 	.buf_prepare            = bfin_disp_buffer_prepare,
 	.buf_cleanup            = bfin_disp_buffer_cleanup,
 	.buf_queue              = bfin_disp_buffer_queue,
-	.wait_prepare           = bfin_disp_unlock,
-	.wait_finish            = bfin_disp_lock,
+	.wait_prepare           = vb2_ops_wait_prepare,
+	.wait_finish            = vb2_ops_wait_finish,
 	.start_streaming        = bfin_disp_start_streaming,
 	.stop_streaming         = bfin_disp_stop_streaming,
 };
 
-static int bfin_disp_reqbufs(struct file *file, void *priv,
-			struct v4l2_requestbuffers *req_buf)
-{
-	struct bfin_disp_device *disp = video_drvdata(file);
-	struct vb2_queue *vq = &disp->buffer_queue;
-	struct v4l2_fh *fh = file->private_data;
-	struct bfin_disp_fh *bfin_disp_fh = container_of(fh, struct bfin_disp_fh, fh);
-
-	if (vb2_is_busy(vq))
-		return -EBUSY;
-
-	bfin_disp_fh->io_allowed = true;
-
-	return vb2_reqbufs(vq, req_buf);
-}
-
-static int bfin_disp_querybuf(struct file *file, void *priv,
-				struct v4l2_buffer *buf)
-{
-	struct bfin_disp_device *disp = video_drvdata(file);
-
-	return vb2_querybuf(&disp->buffer_queue, buf);
-}
-
-static int bfin_disp_qbuf(struct file *file, void *priv,
-			struct v4l2_buffer *buf)
-{
-	struct bfin_disp_device *disp = video_drvdata(file);
-	struct v4l2_fh *fh = file->private_data;
-	struct bfin_disp_fh *bfin_disp_fh = container_of(fh, struct bfin_disp_fh, fh);
-
-	if (!bfin_disp_fh->io_allowed)
-		return -EBUSY;
-
-	return vb2_qbuf(&disp->buffer_queue, buf);
-}
-
-static int bfin_disp_dqbuf(struct file *file, void *priv,
-			struct v4l2_buffer *buf)
-{
-	struct bfin_disp_device *disp = video_drvdata(file);
-	struct v4l2_fh *fh = file->private_data;
-	struct bfin_disp_fh *bfin_disp_fh = container_of(fh, struct bfin_disp_fh, fh);
-
-	if (!bfin_disp_fh->io_allowed)
-		return -EBUSY;
-
-	return vb2_dqbuf(&disp->buffer_queue,
-				buf, file->f_flags & O_NONBLOCK);
-}
-
-static int bfin_disp_streamon(struct file *file, void *priv,
-				enum v4l2_buf_type buf_type)
-{
-	struct bfin_disp_device *disp = video_drvdata(file);
-	struct bfin_disp_fh *fh = file->private_data;
-	struct ppi_if *ppi = disp->ppi;
-	dma_addr_t addr;
-	int ret;
-
-	if (!fh->io_allowed)
-		return -EBUSY;
-
-	/* call streamon to start streaming in videobuf */
-	ret = vb2_streamon(&disp->buffer_queue, buf_type);
-	if (ret)
-		return ret;
-
-	/* if dma queue is empty, return error */
-	if (list_empty(&disp->dma_queue)) {
-		v4l2_err(&disp->v4l2_dev, "dma queue is empty\n");
-		ret = -EINVAL;
-		goto err;
-	}
-
-	/* get the next frame from the dma queue */
-	disp->cur_frm = list_entry(disp->dma_queue.next,
-					struct bfin_disp_buffer, list);
-	/* remove buffer from the dma queue */
-	list_del(&disp->cur_frm->list);
-	addr = vb2_dma_contig_plane_dma_addr(&disp->cur_frm->vb, 0);
-	/* update DMA address */
-	ppi->ops->update_addr(ppi, (unsigned long)addr);
-	/* enable ppi */
-	ppi->ops->start(ppi);
-
-	return 0;
-err:
-	vb2_streamoff(&disp->buffer_queue, buf_type);
-	return ret;
-}
-
-static int bfin_disp_streamoff(struct file *file, void *priv,
-				enum v4l2_buf_type buf_type)
-{
-	struct bfin_disp_device *disp = video_drvdata(file);
-	struct bfin_disp_fh *fh = file->private_data;
-
-	if (!fh->io_allowed)
-		return -EBUSY;
-
-	return vb2_streamoff(&disp->buffer_queue, buf_type);
-}
-
 static int bfin_disp_g_std(struct file *file, void *priv, v4l2_std_id *std)
 {
 	struct bfin_disp_device *disp = video_drvdata(file);
@@ -894,12 +708,12 @@ static const struct v4l2_ioctl_ops bfin_disp_ioctl_ops = {
 	.vidioc_g_std            = bfin_disp_g_std,
 	.vidioc_s_dv_timings     = bfin_disp_s_dv_timings,
 	.vidioc_g_dv_timings     = bfin_disp_g_dv_timings,
-	.vidioc_reqbufs          = bfin_disp_reqbufs,
-	.vidioc_querybuf         = bfin_disp_querybuf,
-	.vidioc_qbuf             = bfin_disp_qbuf,
-	.vidioc_dqbuf            = bfin_disp_dqbuf,
-	.vidioc_streamon         = bfin_disp_streamon,
-	.vidioc_streamoff        = bfin_disp_streamoff,
+	.vidioc_reqbufs          = vb2_ioctl_reqbufs,
+	.vidioc_querybuf         = vb2_ioctl_querybuf,
+	.vidioc_qbuf             = vb2_ioctl_qbuf,
+	.vidioc_dqbuf            = vb2_ioctl_dqbuf,
+	.vidioc_streamon         = vb2_ioctl_streamon,
+	.vidioc_streamoff        = vb2_ioctl_streamoff,
 	.vidioc_g_parm           = bfin_disp_g_parm,
 	.vidioc_s_parm           = bfin_disp_s_parm,
 	.vidioc_g_chip_ident     = bfin_disp_g_chip_ident,
@@ -912,14 +726,14 @@ static const struct v4l2_ioctl_ops bfin_disp_ioctl_ops = {
 
 static struct v4l2_file_operations bfin_disp_fops = {
 	.owner = THIS_MODULE,
-	.open = bfin_disp_open,
-	.release = bfin_disp_release,
+	.open = v4l2_fh_open,
+	.release = vb2_fop_release,
 	.unlocked_ioctl = video_ioctl2,
-	.mmap = bfin_disp_mmap,
+	.mmap = vb2_fop_mmap,
 #ifndef CONFIG_MMU
-	.get_unmapped_area = bfin_disp_get_unmapped_area,
+	.get_unmapped_area = vb2_fop_get_unmapped_area,
 #endif
-	.poll = bfin_disp_poll
+	.poll = vb2_fop_poll,
 };
 
 static int bfin_disp_probe(struct platform_device *pdev)
@@ -974,6 +788,7 @@ static int bfin_disp_probe(struct platform_device *pdev)
 
 	spin_lock_init(&disp->lock);
 	mutex_init(&disp->mutex);
+	mutex_init(&disp->qlock);
 	/* init video dma queues */
 	INIT_LIST_HEAD(&disp->dma_queue);
 
@@ -985,6 +800,8 @@ static int bfin_disp_probe(struct platform_device *pdev)
 	q->buf_struct_size = sizeof(struct bfin_disp_buffer);
 	q->ops = &bfin_disp_video_qops;
 	q->mem_ops = &vb2_dma_contig_memops;
+	/* provide a mutex to vb2 queue */
+	q->lock = &disp->qlock;
 
 	ret = vb2_queue_init(q);
 	if (ret) {
_______________________________________________
Linux-kernel-commits mailing list
[email protected]
https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits

Reply via email to