linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/10] sh-vou: fixes, convert to vb2
@ 2015-06-05 10:59 Hans Verkuil
  2015-06-05 10:59 ` [PATCH 01/10] sh-vou: hook up the clock correctly Hans Verkuil
                   ` (9 more replies)
  0 siblings, 10 replies; 15+ messages in thread
From: Hans Verkuil @ 2015-06-05 10:59 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

From: Hans Verkuil <hans.verkuil@cisco.com>

This driver no longer works and uses old v4l2 frameworks. This patch series
updates the driver so it is once again working and is up to date.

It now passes the v4l2-compliance tests as well.

This has been tested with my Renesas development board.

Regards,

	Hans

Hans Verkuil (10):
  sh-vou: hook up the clock correctly
  sh-vou: fix querycap support
  sh-vou: use v4l2_fh
  sh-vou: support compulsory G/S/ENUM_OUTPUT ioctls
  sh-vou: fix incorrect initial pixelformat.
  sh-vou: replace g/s_crop/cropcap by g/s_selection
  sh-vou: add support for log_status
  sh-vou: let sh_vou_s_fmt_vid_out call sh_vou_try_fmt_vid_out
  sh-vou: fix bytesperline
  sh-vou: convert to vb2

 arch/sh/kernel/cpu/sh4a/clock-sh7724.c |   2 +-
 drivers/media/platform/sh_vou.c        | 825 +++++++++++++++------------------
 2 files changed, 381 insertions(+), 446 deletions(-)

-- 
2.1.4


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 01/10] sh-vou: hook up the clock correctly
  2015-06-05 10:59 [PATCH 00/10] sh-vou: fixes, convert to vb2 Hans Verkuil
@ 2015-06-05 10:59 ` Hans Verkuil
  2015-06-06 21:42   ` Geert Uytterhoeven
  2015-06-05 10:59 ` [PATCH 02/10] sh-vou: fix querycap support Hans Verkuil
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 15+ messages in thread
From: Hans Verkuil @ 2015-06-05 10:59 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh, Hans Verkuil, Magnus Damm

From: Hans Verkuil <hans.verkuil@cisco.com>

Bitrot has set in for this driver and the sh-vou.0 clock was never enabled,
so this driver didn't do anything. In addition, the clock was incorrectly
defined in clock-sh7724.c. Fix this.

While we're at it: use proper resource managed calls.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Cc: Magnus Damm <damm@opensource.se>
---
 arch/sh/kernel/cpu/sh4a/clock-sh7724.c |  2 +-
 drivers/media/platform/sh_vou.c        | 54 ++++++++++++----------------------
 2 files changed, 20 insertions(+), 36 deletions(-)

diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
index c187b95..f1df899 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
@@ -343,7 +343,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_CON_ID("2ddmac0", &mstp_clks[HWBLK_2DDMAC]),
 	CLKDEV_DEV_ID("sh_fsi.0", &mstp_clks[HWBLK_SPU]),
 	CLKDEV_CON_ID("jpu0", &mstp_clks[HWBLK_JPU]),
-	CLKDEV_DEV_ID("sh-vou.0", &mstp_clks[HWBLK_VOU]),
+	CLKDEV_CON_ID("sh-vou.0", &mstp_clks[HWBLK_VOU]),
 	CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU0]),
 	CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[HWBLK_CEU0]),
 	CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU0]),
diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
index 829e85c..9e98233 100644
--- a/drivers/media/platform/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -21,6 +21,7 @@
 #include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <linux/module.h>
+#include <linux/clk.h>
 
 #include <media/sh_vou.h>
 #include <media/v4l2-common.h>
@@ -65,6 +66,7 @@ struct sh_vou_device {
 	struct video_device vdev;
 	atomic_t use_count;
 	struct sh_vou_pdata *pdata;
+	struct clk *clk;
 	spinlock_t lock;
 	void __iomem *base;
 	/* State information */
@@ -1300,7 +1302,7 @@ static int sh_vou_probe(struct platform_device *pdev)
 	struct i2c_adapter *i2c_adap;
 	struct video_device *vdev;
 	struct sh_vou_device *vou_dev;
-	struct resource *reg_res, *region;
+	struct resource *reg_res;
 	struct v4l2_subdev *subdev;
 	int irq, ret;
 
@@ -1312,10 +1314,16 @@ static int sh_vou_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	vou_dev = kzalloc(sizeof(*vou_dev), GFP_KERNEL);
+	vou_dev = devm_kzalloc(&pdev->dev, sizeof(*vou_dev), GFP_KERNEL);
 	if (!vou_dev)
 		return -ENOMEM;
 
+	vou_dev->clk = devm_clk_get(&pdev->dev, "sh-vou.0");
+	if (IS_ERR(vou_dev->clk)) {
+		dev_err(&pdev->dev, "cannot get clock\n");
+		return PTR_ERR(vou_dev->clk);
+	}
+
 	INIT_LIST_HEAD(&vou_dev->queue);
 	spin_lock_init(&vou_dev->lock);
 	mutex_init(&vou_dev->fop_lock);
@@ -1340,28 +1348,18 @@ static int sh_vou_probe(struct platform_device *pdev)
 	pix->sizeimage		= VOU_MAX_IMAGE_WIDTH * 2 * 480;
 	pix->colorspace		= V4L2_COLORSPACE_SMPTE170M;
 
-	region = request_mem_region(reg_res->start, resource_size(reg_res),
-				    pdev->name);
-	if (!region) {
-		dev_err(&pdev->dev, "VOU region already claimed\n");
-		ret = -EBUSY;
-		goto ereqmemreg;
-	}
+	vou_dev->base = devm_ioremap_resource(&pdev->dev, reg_res);
+	if (IS_ERR(vou_dev->base))
+		return PTR_ERR(vou_dev->base);
 
-	vou_dev->base = ioremap(reg_res->start, resource_size(reg_res));
-	if (!vou_dev->base) {
-		ret = -ENOMEM;
-		goto emap;
-	}
-
-	ret = request_irq(irq, sh_vou_isr, 0, "vou", vou_dev);
+	ret = devm_request_irq(&pdev->dev, irq, sh_vou_isr, 0, "vou", vou_dev);
 	if (ret < 0)
-		goto ereqirq;
+		return ret;
 
 	ret = v4l2_device_register(&pdev->dev, &vou_dev->v4l2_dev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "Error registering v4l2 device\n");
-		goto ev4l2devreg;
+		return ret;
 	}
 
 	vdev = &vou_dev->vdev;
@@ -1383,6 +1381,7 @@ static int sh_vou_probe(struct platform_device *pdev)
 		goto ei2cgadap;
 	}
 
+	clk_prepare_enable(vou_dev->clk);
 	ret = sh_vou_hw_init(vou_dev);
 	if (ret < 0)
 		goto ereset;
@@ -1403,43 +1402,28 @@ static int sh_vou_probe(struct platform_device *pdev)
 evregdev:
 ei2cnd:
 ereset:
+	clk_disable_unprepare(vou_dev->clk);
 	i2c_put_adapter(i2c_adap);
 ei2cgadap:
 	pm_runtime_disable(&pdev->dev);
 	v4l2_device_unregister(&vou_dev->v4l2_dev);
-ev4l2devreg:
-	free_irq(irq, vou_dev);
-ereqirq:
-	iounmap(vou_dev->base);
-emap:
-	release_mem_region(reg_res->start, resource_size(reg_res));
-ereqmemreg:
-	kfree(vou_dev);
 	return ret;
 }
 
 static int sh_vou_remove(struct platform_device *pdev)
 {
-	int irq = platform_get_irq(pdev, 0);
 	struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
 	struct sh_vou_device *vou_dev = container_of(v4l2_dev,
 						struct sh_vou_device, v4l2_dev);
 	struct v4l2_subdev *sd = list_entry(v4l2_dev->subdevs.next,
 					    struct v4l2_subdev, list);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct resource *reg_res;
 
-	if (irq > 0)
-		free_irq(irq, vou_dev);
 	pm_runtime_disable(&pdev->dev);
 	video_unregister_device(&vou_dev->vdev);
+	clk_disable_unprepare(vou_dev->clk);
 	i2c_put_adapter(client->adapter);
 	v4l2_device_unregister(&vou_dev->v4l2_dev);
-	iounmap(vou_dev->base);
-	reg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (reg_res)
-		release_mem_region(reg_res->start, resource_size(reg_res));
-	kfree(vou_dev);
 	return 0;
 }
 
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 02/10] sh-vou: fix querycap support
  2015-06-05 10:59 [PATCH 00/10] sh-vou: fixes, convert to vb2 Hans Verkuil
  2015-06-05 10:59 ` [PATCH 01/10] sh-vou: hook up the clock correctly Hans Verkuil
@ 2015-06-05 10:59 ` Hans Verkuil
  2015-06-05 10:59 ` [PATCH 03/10] sh-vou: use v4l2_fh Hans Verkuil
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Hans Verkuil @ 2015-06-05 10:59 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Fix v4l2-compliance errors due to empty driver and bus_info fields.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/sh_vou.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
index 9e98233..ba1a16c 100644
--- a/drivers/media/platform/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -398,6 +398,8 @@ static int sh_vou_querycap(struct file *file, void  *priv,
 	dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
 
 	strlcpy(cap->card, "SuperH VOU", sizeof(cap->card));
+	strlcpy(cap->driver, "sh-vou", sizeof(cap->driver));
+	strlcpy(cap->bus_info, "platform:sh-vou", sizeof(cap->bus_info));
 	cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
 	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 	return 0;
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 03/10] sh-vou: use v4l2_fh
  2015-06-05 10:59 [PATCH 00/10] sh-vou: fixes, convert to vb2 Hans Verkuil
  2015-06-05 10:59 ` [PATCH 01/10] sh-vou: hook up the clock correctly Hans Verkuil
  2015-06-05 10:59 ` [PATCH 02/10] sh-vou: fix querycap support Hans Verkuil
@ 2015-06-05 10:59 ` Hans Verkuil
  2015-06-05 10:59 ` [PATCH 04/10] sh-vou: support compulsory G/S/ENUM_OUTPUT ioctls Hans Verkuil
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Hans Verkuil @ 2015-06-05 10:59 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

This allows us to drop the use_count and you get free G/S_PRIORITY support.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/sh_vou.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
index ba1a16c..a75e6fa 100644
--- a/drivers/media/platform/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -64,7 +64,6 @@ enum sh_vou_status {
 struct sh_vou_device {
 	struct v4l2_device v4l2_dev;
 	struct video_device vdev;
-	atomic_t use_count;
 	struct sh_vou_pdata *pdata;
 	struct clk *clk;
 	spinlock_t lock;
@@ -81,6 +80,7 @@ struct sh_vou_device {
 };
 
 struct sh_vou_file {
+	struct v4l2_fh fh;
 	struct videobuf_queue vbq;
 };
 
@@ -1175,20 +1175,24 @@ static int sh_vou_open(struct file *file)
 
 	dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
 
+	v4l2_fh_init(&vou_file->fh, &vou_dev->vdev);
 	if (mutex_lock_interruptible(&vou_dev->fop_lock)) {
 		kfree(vou_file);
 		return -ERESTARTSYS;
 	}
-	if (atomic_inc_return(&vou_dev->use_count) == 1) {
+	v4l2_fh_add(&vou_file->fh);
+	if (v4l2_fh_is_singular(&vou_file->fh)) {
 		int ret;
+
 		/* First open */
 		vou_dev->status = SH_VOU_INITIALISING;
 		pm_runtime_get_sync(vou_dev->v4l2_dev.dev);
 		ret = sh_vou_hw_init(vou_dev);
 		if (ret < 0) {
-			atomic_dec(&vou_dev->use_count);
 			pm_runtime_put(vou_dev->v4l2_dev.dev);
 			vou_dev->status = SH_VOU_IDLE;
+			v4l2_fh_del(&vou_file->fh);
+			v4l2_fh_exit(&vou_file->fh);
 			mutex_unlock(&vou_dev->fop_lock);
 			kfree(vou_file);
 			return ret;
@@ -1215,14 +1219,16 @@ static int sh_vou_release(struct file *file)
 
 	dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
 
-	if (!atomic_dec_return(&vou_dev->use_count)) {
-		mutex_lock(&vou_dev->fop_lock);
+	mutex_lock(&vou_dev->fop_lock);
+	if (v4l2_fh_is_singular(&vou_file->fh)) {
 		/* Last close */
 		vou_dev->status = SH_VOU_IDLE;
 		sh_vou_reg_a_set(vou_dev, VOUER, 0, 0x101);
 		pm_runtime_put(vou_dev->v4l2_dev.dev);
-		mutex_unlock(&vou_dev->fop_lock);
 	}
+	v4l2_fh_del(&vou_file->fh);
+	v4l2_fh_exit(&vou_file->fh);
+	mutex_unlock(&vou_dev->fop_lock);
 
 	file->private_data = NULL;
 	kfree(vou_file);
@@ -1329,7 +1335,6 @@ static int sh_vou_probe(struct platform_device *pdev)
 	INIT_LIST_HEAD(&vou_dev->queue);
 	spin_lock_init(&vou_dev->lock);
 	mutex_init(&vou_dev->fop_lock);
-	atomic_set(&vou_dev->use_count, 0);
 	vou_dev->pdata = vou_pdata;
 	vou_dev->status = SH_VOU_IDLE;
 
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 04/10] sh-vou: support compulsory G/S/ENUM_OUTPUT ioctls
  2015-06-05 10:59 [PATCH 00/10] sh-vou: fixes, convert to vb2 Hans Verkuil
                   ` (2 preceding siblings ...)
  2015-06-05 10:59 ` [PATCH 03/10] sh-vou: use v4l2_fh Hans Verkuil
@ 2015-06-05 10:59 ` Hans Verkuil
  2015-06-05 10:59 ` [PATCH 05/10] sh-vou: fix incorrect initial pixelformat Hans Verkuil
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Hans Verkuil @ 2015-06-05 10:59 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Video output drivers must support these ioctls. Otherwise applications
cannot deduce that these outputs exist and what capabilities they have.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/sh_vou.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
index a75e6fa..2adf16d 100644
--- a/drivers/media/platform/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -874,6 +874,30 @@ static int sh_vou_streamoff(struct file *file, void *priv,
 	return 0;
 }
 
+static int sh_vou_enum_output(struct file *file, void *fh,
+			      struct v4l2_output *a)
+{
+	struct sh_vou_device *vou_dev = video_drvdata(file);
+
+	if (a->index)
+		return -EINVAL;
+	strlcpy(a->name, "Video Out", sizeof(a->name));
+	a->type = V4L2_OUTPUT_TYPE_ANALOG;
+	a->std = vou_dev->vdev.tvnorms;
+	return 0;
+}
+
+int sh_vou_g_output(struct file *file, void *fh, unsigned int *i)
+{
+	*i = 0;
+	return 0;
+}
+
+int sh_vou_s_output(struct file *file, void *fh, unsigned int i)
+{
+	return i ? -EINVAL : 0;
+}
+
 static u32 sh_vou_ntsc_mode(enum sh_vou_bus_fmt bus_fmt)
 {
 	switch (bus_fmt) {
@@ -1278,6 +1302,9 @@ static const struct v4l2_ioctl_ops sh_vou_ioctl_ops = {
 	.vidioc_dqbuf			= sh_vou_dqbuf,
 	.vidioc_streamon		= sh_vou_streamon,
 	.vidioc_streamoff		= sh_vou_streamoff,
+	.vidioc_g_output		= sh_vou_g_output,
+	.vidioc_s_output		= sh_vou_s_output,
+	.vidioc_enum_output		= sh_vou_enum_output,
 	.vidioc_s_std			= sh_vou_s_std,
 	.vidioc_g_std			= sh_vou_g_std,
 	.vidioc_cropcap			= sh_vou_cropcap,
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 05/10] sh-vou: fix incorrect initial pixelformat.
  2015-06-05 10:59 [PATCH 00/10] sh-vou: fixes, convert to vb2 Hans Verkuil
                   ` (3 preceding siblings ...)
  2015-06-05 10:59 ` [PATCH 04/10] sh-vou: support compulsory G/S/ENUM_OUTPUT ioctls Hans Verkuil
@ 2015-06-05 10:59 ` Hans Verkuil
  2015-06-05 10:59 ` [PATCH 06/10] sh-vou: replace g/s_crop/cropcap by g/s_selection Hans Verkuil
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Hans Verkuil @ 2015-06-05 10:59 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

It was set to a format that wasn't supported.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/sh_vou.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
index 2adf16d..eaa432e 100644
--- a/drivers/media/platform/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -1376,7 +1376,7 @@ static int sh_vou_probe(struct platform_device *pdev)
 	rect->height		= 480;
 	pix->width		= VOU_MAX_IMAGE_WIDTH;
 	pix->height		= 480;
-	pix->pixelformat	= V4L2_PIX_FMT_YVYU;
+	pix->pixelformat	= V4L2_PIX_FMT_NV16;
 	pix->field		= V4L2_FIELD_NONE;
 	pix->bytesperline	= VOU_MAX_IMAGE_WIDTH * 2;
 	pix->sizeimage		= VOU_MAX_IMAGE_WIDTH * 2 * 480;
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 06/10] sh-vou: replace g/s_crop/cropcap by g/s_selection
  2015-06-05 10:59 [PATCH 00/10] sh-vou: fixes, convert to vb2 Hans Verkuil
                   ` (4 preceding siblings ...)
  2015-06-05 10:59 ` [PATCH 05/10] sh-vou: fix incorrect initial pixelformat Hans Verkuil
@ 2015-06-05 10:59 ` Hans Verkuil
  2015-06-05 10:59 ` [PATCH 07/10] sh-vou: add support for log_status Hans Verkuil
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Hans Verkuil @ 2015-06-05 10:59 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Implement g/s_selection. The v4l2 core will emulate g/s_crop and
cropcap on top of g/s_selection.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/sh_vou.c | 71 +++++++++++++++--------------------------
 1 file changed, 25 insertions(+), 46 deletions(-)

diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
index eaa432e..7ed5a8b 100644
--- a/drivers/media/platform/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -951,24 +951,36 @@ static int sh_vou_g_std(struct file *file, void *priv, v4l2_std_id *std)
 	return 0;
 }
 
-static int sh_vou_g_crop(struct file *file, void *fh, struct v4l2_crop *a)
+static int sh_vou_g_selection(struct file *file, void *fh,
+			      struct v4l2_selection *sel)
 {
 	struct sh_vou_device *vou_dev = video_drvdata(file);
 
-	dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
-
-	a->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-	a->c = vou_dev->rect;
-
+	if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+		return -EINVAL;
+	switch (sel->target) {
+	case V4L2_SEL_TGT_COMPOSE:
+		sel->r = vou_dev->rect;
+		break;
+	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+		sel->r.left = 0;
+		sel->r.top = 0;
+		sel->r.width = VOU_MAX_IMAGE_WIDTH;
+		sel->r.height = VOU_MAX_IMAGE_HEIGHT;
+		break;
+	default:
+		return -EINVAL;
+	}
 	return 0;
 }
 
 /* Assume a dull encoder, do all the work ourselves. */
-static int sh_vou_s_crop(struct file *file, void *fh, const struct v4l2_crop *a)
+static int sh_vou_s_selection(struct file *file, void *fh,
+			      struct v4l2_selection *sel)
 {
-	struct v4l2_crop a_writable = *a;
+	struct v4l2_rect *rect = &sel->r;
 	struct sh_vou_device *vou_dev = video_drvdata(file);
-	struct v4l2_rect *rect = &a_writable.c;
 	struct v4l2_crop sd_crop = {.type = V4L2_BUF_TYPE_VIDEO_OUTPUT};
 	struct v4l2_pix_format *pix = &vou_dev->pix;
 	struct sh_vou_geometry geo;
@@ -982,10 +994,8 @@ static int sh_vou_s_crop(struct file *file, void *fh, const struct v4l2_crop *a)
 	unsigned int img_height_max;
 	int ret;
 
-	dev_dbg(vou_dev->v4l2_dev.dev, "%s(): %ux%u@%u:%u\n", __func__,
-		rect->width, rect->height, rect->left, rect->top);
-
-	if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+	if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
+	    sel->target != V4L2_SEL_TGT_COMPOSE)
 		return -EINVAL;
 
 	if (vou_dev->std & V4L2_STD_525_60)
@@ -1049,36 +1059,6 @@ static int sh_vou_s_crop(struct file *file, void *fh, const struct v4l2_crop *a)
 	return 0;
 }
 
-/*
- * Total field: NTSC 858 x 2 * 262/263, PAL 864 x 2 * 312/313, default rectangle
- * is the initial register values, height takes the interlaced format into
- * account. The actual image can only go up to 720 x 2 * 240, So, VOUVPR can
- * actually only meaningfully contain values <= 720 and <= 240 respectively, and
- * not <= 864 and <= 312.
- */
-static int sh_vou_cropcap(struct file *file, void *priv,
-			  struct v4l2_cropcap *a)
-{
-	struct sh_vou_device *vou_dev = video_drvdata(file);
-
-	dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
-
-	a->type				= V4L2_BUF_TYPE_VIDEO_OUTPUT;
-	a->bounds.left			= 0;
-	a->bounds.top			= 0;
-	a->bounds.width			= VOU_MAX_IMAGE_WIDTH;
-	a->bounds.height		= VOU_MAX_IMAGE_HEIGHT;
-	/* Default = max, set VOUDPR = 0, which is not hardware default */
-	a->defrect.left			= 0;
-	a->defrect.top			= 0;
-	a->defrect.width		= VOU_MAX_IMAGE_WIDTH;
-	a->defrect.height		= VOU_MAX_IMAGE_HEIGHT;
-	a->pixelaspect.numerator	= 1;
-	a->pixelaspect.denominator	= 1;
-
-	return 0;
-}
-
 static irqreturn_t sh_vou_isr(int irq, void *dev_id)
 {
 	struct sh_vou_device *vou_dev = dev_id;
@@ -1307,9 +1287,8 @@ static const struct v4l2_ioctl_ops sh_vou_ioctl_ops = {
 	.vidioc_enum_output		= sh_vou_enum_output,
 	.vidioc_s_std			= sh_vou_s_std,
 	.vidioc_g_std			= sh_vou_g_std,
-	.vidioc_cropcap			= sh_vou_cropcap,
-	.vidioc_g_crop			= sh_vou_g_crop,
-	.vidioc_s_crop			= sh_vou_s_crop,
+	.vidioc_g_selection		= sh_vou_g_selection,
+	.vidioc_s_selection		= sh_vou_s_selection,
 };
 
 static const struct v4l2_file_operations sh_vou_fops = {
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 07/10] sh-vou: add support for log_status
  2015-06-05 10:59 [PATCH 00/10] sh-vou: fixes, convert to vb2 Hans Verkuil
                   ` (5 preceding siblings ...)
  2015-06-05 10:59 ` [PATCH 06/10] sh-vou: replace g/s_crop/cropcap by g/s_selection Hans Verkuil
@ 2015-06-05 10:59 ` Hans Verkuil
  2015-06-05 13:28   ` Sergei Shtylyov
  2015-06-05 10:59 ` [PATCH 08/10] sh-vou: let sh_vou_s_fmt_vid_out call sh_vou_try_fmt_vid_out Hans Verkuil
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 15+ messages in thread
From: Hans Verkuil @ 2015-06-05 10:59 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Dump the VOU registers in log_status.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/sh_vou.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
index 7ed5a8b..400efec 100644
--- a/drivers/media/platform/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -951,6 +951,34 @@ static int sh_vou_g_std(struct file *file, void *priv, v4l2_std_id *std)
 	return 0;
 }
 
+static int sh_vou_log_status(struct file *file, void *priv)
+{
+	struct sh_vou_device *vou_dev = video_drvdata(file);
+
+	pr_info("PSELA:   0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUER));
+	pr_info("VOUER:   0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUER));
+	pr_info("VOUCR:   0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUCR));
+	pr_info("VOUSTR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUSTR));
+	pr_info("VOUVCR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUVCR));
+	pr_info("VOUISR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUISR));
+	pr_info("VOUBCR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUBCR));
+	pr_info("VOUDPR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUDPR));
+	pr_info("VOUDSR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUDSR));
+	pr_info("VOUVPR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUVPR));
+	pr_info("VOUIR:   0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUIR));
+	pr_info("VOUSRR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUSRR));
+	pr_info("VOUMSR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUMSR));
+	pr_info("VOUHIR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUHIR));
+	pr_info("VOUDFR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUDFR));
+	pr_info("VOUAD1R: 0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUAD1R));
+	pr_info("VOUAD2R: 0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUAD2R));
+	pr_info("VOUAIR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUAIR));
+	pr_info("VOUSWR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUSWR));
+	pr_info("VOURCR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOURCR));
+	pr_info("VOURPR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOURPR));
+	return 0;
+}
+
 static int sh_vou_g_selection(struct file *file, void *fh,
 			      struct v4l2_selection *sel)
 {
@@ -1289,6 +1317,7 @@ static const struct v4l2_ioctl_ops sh_vou_ioctl_ops = {
 	.vidioc_g_std			= sh_vou_g_std,
 	.vidioc_g_selection		= sh_vou_g_selection,
 	.vidioc_s_selection		= sh_vou_s_selection,
+	.vidioc_log_status		= sh_vou_log_status,
 };
 
 static const struct v4l2_file_operations sh_vou_fops = {
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 08/10] sh-vou: let sh_vou_s_fmt_vid_out call sh_vou_try_fmt_vid_out
  2015-06-05 10:59 [PATCH 00/10] sh-vou: fixes, convert to vb2 Hans Verkuil
                   ` (6 preceding siblings ...)
  2015-06-05 10:59 ` [PATCH 07/10] sh-vou: add support for log_status Hans Verkuil
@ 2015-06-05 10:59 ` Hans Verkuil
  2015-06-05 10:59 ` [PATCH 09/10] sh-vou: fix bytesperline Hans Verkuil
  2015-06-05 10:59 ` [PATCH 10/10] sh-vou: convert to vb2 Hans Verkuil
  9 siblings, 0 replies; 15+ messages in thread
From: Hans Verkuil @ 2015-06-05 10:59 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

This ensures that both do the same checks, and simplifies s_fmt_vid_out
a bit.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/sh_vou.c | 86 +++++++++++++++++++----------------------
 1 file changed, 40 insertions(+), 46 deletions(-)

diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
index 400efec..489d045 100644
--- a/drivers/media/platform/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -675,34 +675,19 @@ static void vou_adjust_output(struct sh_vou_geometry *geo, v4l2_std_id std)
 		 vou_scale_v_num[idx], vou_scale_v_den[idx], best);
 }
 
-static int sh_vou_s_fmt_vid_out(struct file *file, void *priv,
-				struct v4l2_format *fmt)
+static int sh_vou_try_fmt_vid_out(struct file *file, void *priv,
+				  struct v4l2_format *fmt)
 {
 	struct sh_vou_device *vou_dev = video_drvdata(file);
 	struct v4l2_pix_format *pix = &fmt->fmt.pix;
 	unsigned int img_height_max;
 	int pix_idx;
-	struct sh_vou_geometry geo;
-	struct v4l2_subdev_format format = {
-		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
-		/* Revisit: is this the correct code? */
-		.format.code = MEDIA_BUS_FMT_YUYV8_2X8,
-		.format.field = V4L2_FIELD_INTERLACED,
-		.format.colorspace = V4L2_COLORSPACE_SMPTE170M,
-	};
-	struct v4l2_mbus_framefmt *mbfmt = &format.format;
-	int ret;
-
-	dev_dbg(vou_dev->v4l2_dev.dev, "%s(): %ux%u -> %ux%u\n", __func__,
-		vou_dev->rect.width, vou_dev->rect.height,
-		pix->width, pix->height);
 
-	if (pix->field == V4L2_FIELD_ANY)
-		pix->field = V4L2_FIELD_NONE;
+	dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
 
-	if (fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
-	    pix->field != V4L2_FIELD_NONE)
-		return -EINVAL;
+	pix->field = V4L2_FIELD_INTERLACED;
+	pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
+	pix->ycbcr_enc = pix->quantization = 0;
 
 	for (pix_idx = 0; pix_idx < ARRAY_SIZE(vou_fmt); pix_idx++)
 		if (vou_fmt[pix_idx].pfmt == pix->pixelformat)
@@ -716,9 +701,37 @@ static int sh_vou_s_fmt_vid_out(struct file *file, void *priv,
 	else
 		img_height_max = 576;
 
-	/* Image width must be a multiple of 4 */
 	v4l_bound_align_image(&pix->width, 0, VOU_MAX_IMAGE_WIDTH, 2,
 			      &pix->height, 0, img_height_max, 1, 0);
+	pix->bytesperline = pix->width * 2;
+
+	return 0;
+}
+
+static int sh_vou_s_fmt_vid_out(struct file *file, void *priv,
+				struct v4l2_format *fmt)
+{
+	struct sh_vou_device *vou_dev = video_drvdata(file);
+	struct v4l2_pix_format *pix = &fmt->fmt.pix;
+	unsigned int img_height_max;
+	struct sh_vou_geometry geo;
+	struct v4l2_subdev_format format = {
+		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+		/* Revisit: is this the correct code? */
+		.format.code = MEDIA_BUS_FMT_YUYV8_2X8,
+		.format.field = V4L2_FIELD_INTERLACED,
+		.format.colorspace = V4L2_COLORSPACE_SMPTE170M,
+	};
+	struct v4l2_mbus_framefmt *mbfmt = &format.format;
+	int ret = sh_vou_try_fmt_vid_out(file, priv, fmt);
+	int pix_idx;
+
+	if (ret)
+		return ret;
+
+	for (pix_idx = 0; pix_idx < ARRAY_SIZE(vou_fmt); pix_idx++)
+		if (vou_fmt[pix_idx].pfmt == pix->pixelformat)
+			break;
 
 	geo.in_width = pix->width;
 	geo.in_height = pix->height;
@@ -737,6 +750,11 @@ static int sh_vou_s_fmt_vid_out(struct file *file, void *priv,
 	dev_dbg(vou_dev->v4l2_dev.dev, "%s(): %ux%u -> %ux%u\n", __func__,
 		geo.output.width, geo.output.height, mbfmt->width, mbfmt->height);
 
+	if (vou_dev->std & V4L2_STD_525_60)
+		img_height_max = 480;
+	else
+		img_height_max = 576;
+
 	/* Sanity checks */
 	if ((unsigned)mbfmt->width > VOU_MAX_IMAGE_WIDTH ||
 	    (unsigned)mbfmt->height > img_height_max ||
@@ -769,30 +787,6 @@ static int sh_vou_s_fmt_vid_out(struct file *file, void *priv,
 	return 0;
 }
 
-static int sh_vou_try_fmt_vid_out(struct file *file, void *priv,
-				  struct v4l2_format *fmt)
-{
-	struct sh_vou_device *vou_dev = video_drvdata(file);
-	struct v4l2_pix_format *pix = &fmt->fmt.pix;
-	int i;
-
-	dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
-
-	fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-	pix->field = V4L2_FIELD_NONE;
-
-	v4l_bound_align_image(&pix->width, 0, VOU_MAX_IMAGE_WIDTH, 1,
-			      &pix->height, 0, VOU_MAX_IMAGE_HEIGHT, 1, 0);
-
-	for (i = 0; i < ARRAY_SIZE(vou_fmt); i++)
-		if (vou_fmt[i].pfmt == pix->pixelformat)
-			return 0;
-
-	pix->pixelformat = vou_fmt[0].pfmt;
-
-	return 0;
-}
-
 static int sh_vou_reqbufs(struct file *file, void *priv,
 			  struct v4l2_requestbuffers *req)
 {
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 09/10] sh-vou: fix bytesperline
  2015-06-05 10:59 [PATCH 00/10] sh-vou: fixes, convert to vb2 Hans Verkuil
                   ` (7 preceding siblings ...)
  2015-06-05 10:59 ` [PATCH 08/10] sh-vou: let sh_vou_s_fmt_vid_out call sh_vou_try_fmt_vid_out Hans Verkuil
@ 2015-06-05 10:59 ` Hans Verkuil
  2015-06-05 10:59 ` [PATCH 10/10] sh-vou: convert to vb2 Hans Verkuil
  9 siblings, 0 replies; 15+ messages in thread
From: Hans Verkuil @ 2015-06-05 10:59 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

The bytesperline values were wrong for planar formats where bytesperline is
the line length for the first plane.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/sh_vou.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
index 489d045..d431cb1 100644
--- a/drivers/media/platform/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -135,6 +135,7 @@ struct sh_vou_fmt {
 	u32		pfmt;
 	char		*desc;
 	unsigned char	bpp;
+	unsigned char	bpl;
 	unsigned char	rgb;
 	unsigned char	yf;
 	unsigned char	pkf;
@@ -145,6 +146,7 @@ static struct sh_vou_fmt vou_fmt[] = {
 	{
 		.pfmt	= V4L2_PIX_FMT_NV12,
 		.bpp	= 12,
+		.bpl	= 1,
 		.desc	= "YVU420 planar",
 		.yf	= 0,
 		.rgb	= 0,
@@ -152,6 +154,7 @@ static struct sh_vou_fmt vou_fmt[] = {
 	{
 		.pfmt	= V4L2_PIX_FMT_NV16,
 		.bpp	= 16,
+		.bpl	= 1,
 		.desc	= "YVYU planar",
 		.yf	= 1,
 		.rgb	= 0,
@@ -159,6 +162,7 @@ static struct sh_vou_fmt vou_fmt[] = {
 	{
 		.pfmt	= V4L2_PIX_FMT_RGB24,
 		.bpp	= 24,
+		.bpl	= 3,
 		.desc	= "RGB24",
 		.pkf	= 2,
 		.rgb	= 1,
@@ -166,6 +170,7 @@ static struct sh_vou_fmt vou_fmt[] = {
 	{
 		.pfmt	= V4L2_PIX_FMT_RGB565,
 		.bpp	= 16,
+		.bpl	= 2,
 		.desc	= "RGB565",
 		.pkf	= 3,
 		.rgb	= 1,
@@ -173,6 +178,7 @@ static struct sh_vou_fmt vou_fmt[] = {
 	{
 		.pfmt	= V4L2_PIX_FMT_RGB565X,
 		.bpp	= 16,
+		.bpl	= 2,
 		.desc	= "RGB565 byteswapped",
 		.pkf	= 3,
 		.rgb	= 1,
@@ -703,7 +709,8 @@ static int sh_vou_try_fmt_vid_out(struct file *file, void *priv,
 
 	v4l_bound_align_image(&pix->width, 0, VOU_MAX_IMAGE_WIDTH, 2,
 			      &pix->height, 0, img_height_max, 1, 0);
-	pix->bytesperline = pix->width * 2;
+	pix->bytesperline = pix->width * vou_fmt[pix_idx].bpl;
+	pix->sizeimage = pix->height * ((pix->width * vou_fmt[pix_idx].bpp) >> 3);
 
 	return 0;
 }
@@ -1380,7 +1387,7 @@ static int sh_vou_probe(struct platform_device *pdev)
 	pix->height		= 480;
 	pix->pixelformat	= V4L2_PIX_FMT_NV16;
 	pix->field		= V4L2_FIELD_NONE;
-	pix->bytesperline	= VOU_MAX_IMAGE_WIDTH * 2;
+	pix->bytesperline	= VOU_MAX_IMAGE_WIDTH;
 	pix->sizeimage		= VOU_MAX_IMAGE_WIDTH * 2 * 480;
 	pix->colorspace		= V4L2_COLORSPACE_SMPTE170M;
 
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 10/10] sh-vou: convert to vb2
  2015-06-05 10:59 [PATCH 00/10] sh-vou: fixes, convert to vb2 Hans Verkuil
                   ` (8 preceding siblings ...)
  2015-06-05 10:59 ` [PATCH 09/10] sh-vou: fix bytesperline Hans Verkuil
@ 2015-06-05 10:59 ` Hans Verkuil
  9 siblings, 0 replies; 15+ messages in thread
From: Hans Verkuil @ 2015-06-05 10:59 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

This converts this driver to videobuf2. As usual it is a big and hard to review
patch, but this is always a big-bang change.

It has been tested with my Renesas board.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Tested-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/sh_vou.c | 586 +++++++++++++++++-----------------------
 1 file changed, 247 insertions(+), 339 deletions(-)

diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
index d431cb1..1ebf4ad 100644
--- a/drivers/media/platform/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -28,7 +28,7 @@
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-mediabus.h>
-#include <media/videobuf-dma-contig.h>
+#include <media/videobuf2-dma-contig.h>
 
 /* Mirror addresses are not available for all registers */
 #define VOUER	0
@@ -58,8 +58,19 @@ enum sh_vou_status {
 	SH_VOU_RUNNING,
 };
 
+#define VOU_MIN_IMAGE_WIDTH	16
 #define VOU_MAX_IMAGE_WIDTH	720
-#define VOU_MAX_IMAGE_HEIGHT	576
+#define VOU_MIN_IMAGE_HEIGHT	16
+
+struct sh_vou_buffer {
+	struct vb2_buffer vb;
+	struct list_head list;
+};
+
+static inline struct sh_vou_buffer *to_sh_vou_buffer(struct vb2_buffer *vb2)
+{
+	return container_of(vb2, struct sh_vou_buffer, vb);
+}
 
 struct sh_vou_device {
 	struct v4l2_device v4l2_dev;
@@ -71,19 +82,17 @@ struct sh_vou_device {
 	/* State information */
 	struct v4l2_pix_format pix;
 	struct v4l2_rect rect;
-	struct list_head queue;
+	struct list_head buf_list;
 	v4l2_std_id std;
 	int pix_idx;
-	struct videobuf_buffer *active;
+	struct vb2_queue queue;
+	struct vb2_alloc_ctx *alloc_ctx;
+	struct sh_vou_buffer *active;
 	enum sh_vou_status status;
+	unsigned sequence;
 	struct mutex fop_lock;
 };
 
-struct sh_vou_file {
-	struct v4l2_fh fh;
-	struct videobuf_queue vbq;
-};
-
 /* Register access routines for sides A, B and mirror addresses */
 static void sh_vou_reg_a_write(struct sh_vou_device *vou_dev, unsigned int reg,
 			       u32 value)
@@ -186,11 +195,11 @@ static struct sh_vou_fmt vou_fmt[] = {
 };
 
 static void sh_vou_schedule_next(struct sh_vou_device *vou_dev,
-				 struct videobuf_buffer *vb)
+				 struct vb2_buffer *vb)
 {
 	dma_addr_t addr1, addr2;
 
-	addr1 = videobuf_to_dma_contig(vb);
+	addr1 = vb2_dma_contig_plane_dma_addr(vb, 0);
 	switch (vou_dev->pix.pixelformat) {
 	case V4L2_PIX_FMT_NV12:
 	case V4L2_PIX_FMT_NV16:
@@ -204,8 +213,7 @@ static void sh_vou_schedule_next(struct sh_vou_device *vou_dev,
 	sh_vou_reg_m_write(vou_dev, VOUAD2R, addr2);
 }
 
-static void sh_vou_stream_start(struct sh_vou_device *vou_dev,
-				struct videobuf_buffer *vb)
+static void sh_vou_stream_config(struct sh_vou_device *vou_dev)
 {
 	unsigned int row_coeff;
 #ifdef __LITTLE_ENDIAN
@@ -232,167 +240,136 @@ static void sh_vou_stream_start(struct sh_vou_device *vou_dev,
 
 	sh_vou_reg_a_write(vou_dev, VOUSWR, dataswap);
 	sh_vou_reg_ab_write(vou_dev, VOUAIR, vou_dev->pix.width * row_coeff);
-	sh_vou_schedule_next(vou_dev, vb);
-}
-
-static void free_buffer(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
-	BUG_ON(in_interrupt());
-
-	/* Wait until this buffer is no longer in STATE_QUEUED or STATE_ACTIVE */
-	videobuf_waiton(vq, vb, 0, 0);
-	videobuf_dma_contig_free(vq, vb);
-	vb->state = VIDEOBUF_NEEDS_INIT;
 }
 
 /* Locking: caller holds fop_lock mutex */
-static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count,
-			    unsigned int *size)
+static int sh_vou_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+		       unsigned int *nbuffers, unsigned int *nplanes,
+		       unsigned int sizes[], void *alloc_ctxs[])
 {
-	struct video_device *vdev = vq->priv_data;
-	struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
-
-	*size = vou_fmt[vou_dev->pix_idx].bpp * vou_dev->pix.width *
-		vou_dev->pix.height / 8;
-
-	if (*count < 2)
-		*count = 2;
-
-	/* Taking into account maximum frame size, *count will stay >= 2 */
-	if (PAGE_ALIGN(*size) * *count > 4 * 1024 * 1024)
-		*count = 4 * 1024 * 1024 / PAGE_ALIGN(*size);
+	struct sh_vou_device *vou_dev = vb2_get_drv_priv(vq);
+	struct v4l2_pix_format *pix = &vou_dev->pix;
+	int bytes_per_line = vou_fmt[vou_dev->pix_idx].bpp * pix->width / 8;
 
-	dev_dbg(vou_dev->v4l2_dev.dev, "%s(): count=%d, size=%d\n", __func__,
-		*count, *size);
+	dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
 
+	if (fmt && fmt->fmt.pix.sizeimage < pix->height * bytes_per_line)
+		return -EINVAL;
+	*nplanes = 1;
+	sizes[0] = fmt ? fmt->fmt.pix.sizeimage : pix->height * bytes_per_line;
+	alloc_ctxs[0] = vou_dev->alloc_ctx;
 	return 0;
 }
 
-/* Locking: caller holds fop_lock mutex */
-static int sh_vou_buf_prepare(struct videobuf_queue *vq,
-			      struct videobuf_buffer *vb,
-			      enum v4l2_field field)
+static int sh_vou_buf_prepare(struct vb2_buffer *vb)
 {
-	struct video_device *vdev = vq->priv_data;
-	struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
+	struct sh_vou_device *vou_dev = vb2_get_drv_priv(vb->vb2_queue);
 	struct v4l2_pix_format *pix = &vou_dev->pix;
-	int bytes_per_line = vou_fmt[vou_dev->pix_idx].bpp * pix->width / 8;
-	int ret;
+	unsigned bytes_per_line = vou_fmt[vou_dev->pix_idx].bpp * pix->width / 8;
+	unsigned size = pix->height * bytes_per_line;
 
 	dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
 
-	if (vb->width	!= pix->width ||
-	    vb->height	!= pix->height ||
-	    vb->field	!= pix->field) {
-		vb->width	= pix->width;
-		vb->height	= pix->height;
-		vb->field	= field;
-		if (vb->state != VIDEOBUF_NEEDS_INIT)
-			free_buffer(vq, vb);
-	}
-
-	vb->size = vb->height * bytes_per_line;
-	if (vb->baddr && vb->bsize < vb->size) {
+	if (vb2_plane_size(vb, 0) < size) {
 		/* User buffer too small */
-		dev_warn(vq->dev, "User buffer too small: [%zu] @ %lx\n",
-			 vb->bsize, vb->baddr);
+		dev_warn(vou_dev->v4l2_dev.dev, "buffer too small (%lu < %u)\n",
+			 vb2_plane_size(vb, 0), size);
 		return -EINVAL;
 	}
 
-	if (vb->state == VIDEOBUF_NEEDS_INIT) {
-		ret = videobuf_iolock(vq, vb, NULL);
-		if (ret < 0) {
-			dev_warn(vq->dev, "IOLOCK buf-type %d: %d\n",
-				 vb->memory, ret);
-			return ret;
-		}
-		vb->state = VIDEOBUF_PREPARED;
-	}
-
-	dev_dbg(vou_dev->v4l2_dev.dev,
-		"%s(): fmt #%d, %u bytes per line, phys %pad, type %d, state %d\n",
-		__func__, vou_dev->pix_idx, bytes_per_line,
-		({ dma_addr_t addr = videobuf_to_dma_contig(vb); &addr; }),
-		vb->memory, vb->state);
-
+	vb2_set_plane_payload(vb, 0, size);
 	return 0;
 }
 
 /* Locking: caller holds fop_lock mutex and vq->irqlock spinlock */
-static void sh_vou_buf_queue(struct videobuf_queue *vq,
-			     struct videobuf_buffer *vb)
+static void sh_vou_buf_queue(struct vb2_buffer *vb)
 {
-	struct video_device *vdev = vq->priv_data;
-	struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
+	struct sh_vou_device *vou_dev = vb2_get_drv_priv(vb->vb2_queue);
+	struct sh_vou_buffer *shbuf = to_sh_vou_buffer(vb);
+	unsigned long flags;
 
-	dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
+	spin_lock_irqsave(&vou_dev->lock, flags);
+	list_add_tail(&shbuf->list, &vou_dev->buf_list);
+	spin_unlock_irqrestore(&vou_dev->lock, flags);
+}
 
-	vb->state = VIDEOBUF_QUEUED;
-	list_add_tail(&vb->queue, &vou_dev->queue);
-
-	if (vou_dev->status == SH_VOU_RUNNING) {
-		return;
-	} else if (!vou_dev->active) {
-		vou_dev->active = vb;
-		/* Start from side A: we use mirror addresses, so, set B */
-		sh_vou_reg_a_write(vou_dev, VOURPR, 1);
-		dev_dbg(vou_dev->v4l2_dev.dev, "%s: first buffer status 0x%x\n",
-			__func__, sh_vou_reg_a_read(vou_dev, VOUSTR));
-		sh_vou_schedule_next(vou_dev, vb);
-		/* Only activate VOU after the second buffer */
-	} else if (vou_dev->active->queue.next == &vb->queue) {
-		/* Second buffer - initialise register side B */
-		sh_vou_reg_a_write(vou_dev, VOURPR, 0);
-		sh_vou_stream_start(vou_dev, vb);
-
-		/* Register side switching with frame VSYNC */
-		sh_vou_reg_a_write(vou_dev, VOURCR, 5);
-		dev_dbg(vou_dev->v4l2_dev.dev, "%s: second buffer status 0x%x\n",
-			__func__, sh_vou_reg_a_read(vou_dev, VOUSTR));
-
-		/* Enable End-of-Frame (VSYNC) interrupts */
-		sh_vou_reg_a_write(vou_dev, VOUIR, 0x10004);
-		/* Two buffers on the queue - activate the hardware */
-
-		vou_dev->status = SH_VOU_RUNNING;
-		sh_vou_reg_a_write(vou_dev, VOUER, 0x107);
+static int sh_vou_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct sh_vou_device *vou_dev = vb2_get_drv_priv(vq);
+	struct sh_vou_buffer *buf, *node;
+	int ret;
+
+	vou_dev->sequence = 0;
+	ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0,
+					 video, s_stream, 1);
+	if (ret < 0 && ret != -ENOIOCTLCMD) {
+		list_for_each_entry_safe(buf, node, &vou_dev->buf_list, list) {
+			vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+			list_del(&buf->list);
+		}
+		vou_dev->active = NULL;
+		return ret;
 	}
+
+	buf = list_entry(vou_dev->buf_list.next, struct sh_vou_buffer, list);
+
+	vou_dev->active = buf;
+
+	/* Start from side A: we use mirror addresses, so, set B */
+	sh_vou_reg_a_write(vou_dev, VOURPR, 1);
+	dev_dbg(vou_dev->v4l2_dev.dev, "%s: first buffer status 0x%x\n",
+		__func__, sh_vou_reg_a_read(vou_dev, VOUSTR));
+	sh_vou_schedule_next(vou_dev, &buf->vb);
+
+	buf = list_entry(buf->list.next, struct sh_vou_buffer, list);
+
+	/* Second buffer - initialise register side B */
+	sh_vou_reg_a_write(vou_dev, VOURPR, 0);
+	sh_vou_schedule_next(vou_dev, &buf->vb);
+
+	/* Register side switching with frame VSYNC */
+	sh_vou_reg_a_write(vou_dev, VOURCR, 5);
+
+	sh_vou_stream_config(vou_dev);
+	/* Enable End-of-Frame (VSYNC) interrupts */
+	sh_vou_reg_a_write(vou_dev, VOUIR, 0x10004);
+
+	/* Two buffers on the queue - activate the hardware */
+	vou_dev->status = SH_VOU_RUNNING;
+	sh_vou_reg_a_write(vou_dev, VOUER, 0x107);
+	return 0;
 }
 
-static void sh_vou_buf_release(struct videobuf_queue *vq,
-			       struct videobuf_buffer *vb)
+static void sh_vou_stop_streaming(struct vb2_queue *vq)
 {
-	struct video_device *vdev = vq->priv_data;
-	struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
+	struct sh_vou_device *vou_dev = vb2_get_drv_priv(vq);
+	struct sh_vou_buffer *buf, *node;
 	unsigned long flags;
 
-	dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
-
+	v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0,
+					 video, s_stream, 0);
+	/* disable output */
+	sh_vou_reg_a_set(vou_dev, VOUER, 0, 1);
+	/* ...but the current frame will complete */
+	sh_vou_reg_a_set(vou_dev, VOUIR, 0, 0x30000);
+	msleep(50);
 	spin_lock_irqsave(&vou_dev->lock, flags);
-
-	if (vou_dev->active == vb) {
-		/* disable output */
-		sh_vou_reg_a_set(vou_dev, VOUER, 0, 1);
-		/* ...but the current frame will complete */
-		sh_vou_reg_a_set(vou_dev, VOUIR, 0, 0x30000);
-		vou_dev->active = NULL;
+	list_for_each_entry_safe(buf, node, &vou_dev->buf_list, list) {
+		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+		list_del(&buf->list);
 	}
-
-	if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED)) {
-		vb->state = VIDEOBUF_ERROR;
-		list_del(&vb->queue);
-	}
-
+	vou_dev->active = NULL;
 	spin_unlock_irqrestore(&vou_dev->lock, flags);
-
-	free_buffer(vq, vb);
 }
 
-static struct videobuf_queue_ops sh_vou_video_qops = {
-	.buf_setup	= sh_vou_buf_setup,
-	.buf_prepare	= sh_vou_buf_prepare,
-	.buf_queue	= sh_vou_buf_queue,
-	.buf_release	= sh_vou_buf_release,
+static struct vb2_ops sh_vou_qops = {
+	.queue_setup		= sh_vou_queue_setup,
+	.buf_prepare		= sh_vou_buf_prepare,
+	.buf_queue		= sh_vou_buf_queue,
+	.start_streaming	= sh_vou_start_streaming,
+	.stop_streaming		= sh_vou_stop_streaming,
+	.wait_prepare		= vb2_ops_wait_prepare,
+	.wait_finish		= vb2_ops_wait_finish,
 };
 
 /* Video IOCTLs */
@@ -406,7 +383,8 @@ static int sh_vou_querycap(struct file *file, void  *priv,
 	strlcpy(cap->card, "SuperH VOU", sizeof(cap->card));
 	strlcpy(cap->driver, "sh-vou", sizeof(cap->driver));
 	strlcpy(cap->bus_info, "platform:sh-vou", sizeof(cap->bus_info));
-	cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
+	cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_READWRITE |
+			   V4L2_CAP_STREAMING;
 	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 	return 0;
 }
@@ -550,8 +528,10 @@ static void vou_adjust_input(struct sh_vou_geometry *geo, v4l2_std_id std)
 		img_height_max = 576;
 
 	/* Image width must be a multiple of 4 */
-	v4l_bound_align_image(&geo->in_width, 0, VOU_MAX_IMAGE_WIDTH, 2,
-			      &geo->in_height, 0, img_height_max, 1, 0);
+	v4l_bound_align_image(&geo->in_width,
+			      VOU_MIN_IMAGE_WIDTH, VOU_MAX_IMAGE_WIDTH, 2,
+			      &geo->in_height,
+			      VOU_MIN_IMAGE_HEIGHT, img_height_max, 1, 0);
 
 	/* Select scales to come as close as possible to the output image */
 	for (i = ARRAY_SIZE(vou_scale_h_num) - 1; i >= 0; i--) {
@@ -707,19 +687,19 @@ static int sh_vou_try_fmt_vid_out(struct file *file, void *priv,
 	else
 		img_height_max = 576;
 
-	v4l_bound_align_image(&pix->width, 0, VOU_MAX_IMAGE_WIDTH, 2,
-			      &pix->height, 0, img_height_max, 1, 0);
+	v4l_bound_align_image(&pix->width,
+			      VOU_MIN_IMAGE_WIDTH, VOU_MAX_IMAGE_WIDTH, 2,
+			      &pix->height,
+			      VOU_MIN_IMAGE_HEIGHT, img_height_max, 1, 0);
 	pix->bytesperline = pix->width * vou_fmt[pix_idx].bpl;
 	pix->sizeimage = pix->height * ((pix->width * vou_fmt[pix_idx].bpp) >> 3);
 
 	return 0;
 }
 
-static int sh_vou_s_fmt_vid_out(struct file *file, void *priv,
-				struct v4l2_format *fmt)
+static int sh_vou_set_fmt_vid_out(struct sh_vou_device *vou_dev,
+				struct v4l2_pix_format *pix)
 {
-	struct sh_vou_device *vou_dev = video_drvdata(file);
-	struct v4l2_pix_format *pix = &fmt->fmt.pix;
 	unsigned int img_height_max;
 	struct sh_vou_geometry geo;
 	struct v4l2_subdev_format format = {
@@ -730,11 +710,11 @@ static int sh_vou_s_fmt_vid_out(struct file *file, void *priv,
 		.format.colorspace = V4L2_COLORSPACE_SMPTE170M,
 	};
 	struct v4l2_mbus_framefmt *mbfmt = &format.format;
-	int ret = sh_vou_try_fmt_vid_out(file, priv, fmt);
 	int pix_idx;
+	int ret;
 
-	if (ret)
-		return ret;
+	if (vb2_is_busy(&vou_dev->queue))
+		return -EBUSY;
 
 	for (pix_idx = 0; pix_idx < ARRAY_SIZE(vou_fmt); pix_idx++)
 		if (vou_fmt[pix_idx].pfmt == pix->pixelformat)
@@ -794,85 +774,15 @@ static int sh_vou_s_fmt_vid_out(struct file *file, void *priv,
 	return 0;
 }
 
-static int sh_vou_reqbufs(struct file *file, void *priv,
-			  struct v4l2_requestbuffers *req)
-{
-	struct sh_vou_device *vou_dev = video_drvdata(file);
-	struct sh_vou_file *vou_file = priv;
-
-	dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
-
-	if (req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
-		return -EINVAL;
-
-	return videobuf_reqbufs(&vou_file->vbq, req);
-}
-
-static int sh_vou_querybuf(struct file *file, void *priv,
-			   struct v4l2_buffer *b)
-{
-	struct sh_vou_device *vou_dev = video_drvdata(file);
-	struct sh_vou_file *vou_file = priv;
-
-	dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
-
-	return videobuf_querybuf(&vou_file->vbq, b);
-}
-
-static int sh_vou_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
-	struct sh_vou_device *vou_dev = video_drvdata(file);
-	struct sh_vou_file *vou_file = priv;
-
-	dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
-
-	return videobuf_qbuf(&vou_file->vbq, b);
-}
-
-static int sh_vou_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
-	struct sh_vou_device *vou_dev = video_drvdata(file);
-	struct sh_vou_file *vou_file = priv;
-
-	dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
-
-	return videobuf_dqbuf(&vou_file->vbq, b, file->f_flags & O_NONBLOCK);
-}
-
-static int sh_vou_streamon(struct file *file, void *priv,
-			   enum v4l2_buf_type buftype)
+static int sh_vou_s_fmt_vid_out(struct file *file, void *priv,
+				struct v4l2_format *fmt)
 {
 	struct sh_vou_device *vou_dev = video_drvdata(file);
-	struct sh_vou_file *vou_file = priv;
-	int ret;
-
-	dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
+	int ret = sh_vou_try_fmt_vid_out(file, priv, fmt);
 
-	ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0,
-					 video, s_stream, 1);
-	if (ret < 0 && ret != -ENOIOCTLCMD)
+	if (ret)
 		return ret;
-
-	/* This calls our .buf_queue() (== sh_vou_buf_queue) */
-	return videobuf_streamon(&vou_file->vbq);
-}
-
-static int sh_vou_streamoff(struct file *file, void *priv,
-			    enum v4l2_buf_type buftype)
-{
-	struct sh_vou_device *vou_dev = video_drvdata(file);
-	struct sh_vou_file *vou_file = priv;
-
-	dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
-
-	/*
-	 * This calls buf_release from host driver's videobuf_queue_ops for all
-	 * remaining buffers. When the last buffer is freed, stop streaming
-	 */
-	videobuf_streamoff(&vou_file->vbq);
-	v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video, s_stream, 0);
-
-	return 0;
+	return sh_vou_set_fmt_vid_out(vou_dev, &fmt->fmt.pix);
 }
 
 static int sh_vou_enum_output(struct file *file, void *fh,
@@ -921,8 +831,11 @@ static int sh_vou_s_std(struct file *file, void *priv, v4l2_std_id std_id)
 
 	dev_dbg(vou_dev->v4l2_dev.dev, "%s(): 0x%llx\n", __func__, std_id);
 
-	if (std_id & ~vou_dev->vdev.tvnorms)
-		return -EINVAL;
+	if (std_id == vou_dev->std)
+		return 0;
+
+	if (vb2_is_busy(&vou_dev->queue))
+		return -EBUSY;
 
 	ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video,
 					 s_std_output, std_id);
@@ -930,13 +843,25 @@ static int sh_vou_s_std(struct file *file, void *priv, v4l2_std_id std_id)
 	if (ret < 0 && ret != -ENOIOCTLCMD)
 		return ret;
 
-	if (std_id & V4L2_STD_525_60)
+	vou_dev->rect.top = vou_dev->rect.left = 0;
+	vou_dev->rect.width = VOU_MAX_IMAGE_WIDTH;
+	if (std_id & V4L2_STD_525_60) {
 		sh_vou_reg_ab_set(vou_dev, VOUCR,
 			sh_vou_ntsc_mode(vou_dev->pdata->bus_fmt) << 29, 7 << 29);
-	else
+		vou_dev->rect.height = 480;
+	} else {
 		sh_vou_reg_ab_set(vou_dev, VOUCR, 5 << 29, 7 << 29);
+		vou_dev->rect.height = 576;
+	}
 
+	vou_dev->pix.width = vou_dev->rect.width;
+	vou_dev->pix.height = vou_dev->rect.height;
+	vou_dev->pix.bytesperline =
+		vou_dev->pix.width * vou_fmt[vou_dev->pix_idx].bpl;
+	vou_dev->pix.sizeimage = vou_dev->pix.height *
+		((vou_dev->pix.width * vou_fmt[vou_dev->pix_idx].bpp) >> 3);
 	vou_dev->std = std_id;
+	sh_vou_set_fmt_vid_out(vou_dev, &vou_dev->pix);
 
 	return 0;
 }
@@ -996,7 +921,10 @@ static int sh_vou_g_selection(struct file *file, void *fh,
 		sel->r.left = 0;
 		sel->r.top = 0;
 		sel->r.width = VOU_MAX_IMAGE_WIDTH;
-		sel->r.height = VOU_MAX_IMAGE_HEIGHT;
+		if (vou_dev->std & V4L2_STD_525_60)
+			sel->r.height = 480;
+		else
+			sel->r.height = 576;
 		break;
 	default:
 		return -EINVAL;
@@ -1027,13 +955,18 @@ static int sh_vou_s_selection(struct file *file, void *fh,
 	    sel->target != V4L2_SEL_TGT_COMPOSE)
 		return -EINVAL;
 
+	if (vb2_is_busy(&vou_dev->queue))
+		return -EBUSY;
+
 	if (vou_dev->std & V4L2_STD_525_60)
 		img_height_max = 480;
 	else
 		img_height_max = 576;
 
-	v4l_bound_align_image(&rect->width, 0, VOU_MAX_IMAGE_WIDTH, 1,
-			      &rect->height, 0, img_height_max, 1, 0);
+	v4l_bound_align_image(&rect->width,
+			      VOU_MIN_IMAGE_WIDTH, VOU_MAX_IMAGE_WIDTH, 1,
+			      &rect->height,
+			      VOU_MIN_IMAGE_HEIGHT, img_height_max, 1, 0);
 
 	if (rect->width + rect->left > VOU_MAX_IMAGE_WIDTH)
 		rect->left = VOU_MAX_IMAGE_WIDTH - rect->width;
@@ -1092,7 +1025,7 @@ static irqreturn_t sh_vou_isr(int irq, void *dev_id)
 {
 	struct sh_vou_device *vou_dev = dev_id;
 	static unsigned long j;
-	struct videobuf_buffer *vb;
+	struct sh_vou_buffer *vb;
 	static int cnt;
 	u32 irq_status = sh_vou_reg_a_read(vou_dev, VOUIR), masked;
 	u32 vou_status = sh_vou_reg_a_read(vou_dev, VOUSTR);
@@ -1105,7 +1038,7 @@ static irqreturn_t sh_vou_isr(int irq, void *dev_id)
 	}
 
 	spin_lock(&vou_dev->lock);
-	if (!vou_dev->active || list_empty(&vou_dev->queue)) {
+	if (!vou_dev->active || list_empty(&vou_dev->buf_list)) {
 		if (printk_timed_ratelimit(&j, 500))
 			dev_warn(vou_dev->v4l2_dev.dev,
 				 "IRQ without active buffer: %x!\n", irq_status);
@@ -1127,33 +1060,30 @@ static irqreturn_t sh_vou_isr(int irq, void *dev_id)
 	sh_vou_reg_a_write(vou_dev, VOUIR, masked);
 
 	vb = vou_dev->active;
-	list_del(&vb->queue);
-
-	vb->state = VIDEOBUF_DONE;
-	v4l2_get_timestamp(&vb->ts);
-	vb->field_count++;
-	wake_up(&vb->done);
-
-	if (list_empty(&vou_dev->queue)) {
-		/* Stop VOU */
-		dev_dbg(vou_dev->v4l2_dev.dev, "%s: queue empty after %d\n",
-			__func__, cnt);
-		sh_vou_reg_a_set(vou_dev, VOUER, 0, 1);
-		vou_dev->active = NULL;
-		vou_dev->status = SH_VOU_INITIALISING;
-		/* Disable End-of-Frame (VSYNC) interrupts */
-		sh_vou_reg_a_set(vou_dev, VOUIR, 0, 0x30000);
+	if (list_is_singular(&vb->list)) {
+		/* Keep cycling while no next buffer is available */
+		sh_vou_schedule_next(vou_dev, &vb->vb);
 		spin_unlock(&vou_dev->lock);
 		return IRQ_HANDLED;
 	}
 
-	vou_dev->active = list_entry(vou_dev->queue.next,
-				     struct videobuf_buffer, queue);
+	list_del(&vb->list);
+
+	v4l2_get_timestamp(&vb->vb.v4l2_buf.timestamp);
+	vb->vb.v4l2_buf.sequence = vou_dev->sequence++;
+	vb->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED;
+	vb2_buffer_done(&vb->vb, VB2_BUF_STATE_DONE);
 
-	if (vou_dev->active->queue.next != &vou_dev->queue) {
-		struct videobuf_buffer *new = list_entry(vou_dev->active->queue.next,
-						struct videobuf_buffer, queue);
-		sh_vou_schedule_next(vou_dev, new);
+	vou_dev->active = list_entry(vou_dev->buf_list.next,
+				     struct sh_vou_buffer, list);
+
+	if (list_is_singular(&vou_dev->buf_list)) {
+		/* Keep cycling while no next buffer is available */
+		sh_vou_schedule_next(vou_dev, &vou_dev->active->vb);
+	} else {
+		struct sh_vou_buffer *new = list_entry(vou_dev->active->list.next,
+						struct sh_vou_buffer, list);
+		sh_vou_schedule_next(vou_dev, &new->vb);
 	}
 
 	spin_unlock(&vou_dev->lock);
@@ -1193,6 +1123,8 @@ static int sh_vou_hw_init(struct sh_vou_device *vou_dev)
 	/* Default - fixed HSYNC length, can be made configurable is required */
 	sh_vou_reg_ab_write(vou_dev, VOUMSR, 0x800000);
 
+	sh_vou_set_fmt_vid_out(vou_dev, &vou_dev->pix);
+
 	return 0;
 }
 
@@ -1200,104 +1132,47 @@ static int sh_vou_hw_init(struct sh_vou_device *vou_dev)
 static int sh_vou_open(struct file *file)
 {
 	struct sh_vou_device *vou_dev = video_drvdata(file);
-	struct sh_vou_file *vou_file = kzalloc(sizeof(struct sh_vou_file),
-					       GFP_KERNEL);
+	int err;
 
-	if (!vou_file)
-		return -ENOMEM;
-
-	dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
-
-	v4l2_fh_init(&vou_file->fh, &vou_dev->vdev);
-	if (mutex_lock_interruptible(&vou_dev->fop_lock)) {
-		kfree(vou_file);
+	if (mutex_lock_interruptible(&vou_dev->fop_lock))
 		return -ERESTARTSYS;
-	}
-	v4l2_fh_add(&vou_file->fh);
-	if (v4l2_fh_is_singular(&vou_file->fh)) {
-		int ret;
 
+	err = v4l2_fh_open(file);
+	if (err)
+		goto done_open;
+	if (v4l2_fh_is_singular_file(file) &&
+	    vou_dev->status == SH_VOU_INITIALISING) {
 		/* First open */
-		vou_dev->status = SH_VOU_INITIALISING;
 		pm_runtime_get_sync(vou_dev->v4l2_dev.dev);
-		ret = sh_vou_hw_init(vou_dev);
-		if (ret < 0) {
+		err = sh_vou_hw_init(vou_dev);
+		if (err < 0) {
 			pm_runtime_put(vou_dev->v4l2_dev.dev);
+			v4l2_fh_release(file);
+		} else {
 			vou_dev->status = SH_VOU_IDLE;
-			v4l2_fh_del(&vou_file->fh);
-			v4l2_fh_exit(&vou_file->fh);
-			mutex_unlock(&vou_dev->fop_lock);
-			kfree(vou_file);
-			return ret;
 		}
 	}
-
-	videobuf_queue_dma_contig_init(&vou_file->vbq, &sh_vou_video_qops,
-				       vou_dev->v4l2_dev.dev, &vou_dev->lock,
-				       V4L2_BUF_TYPE_VIDEO_OUTPUT,
-				       V4L2_FIELD_NONE,
-				       sizeof(struct videobuf_buffer),
-				       &vou_dev->vdev, &vou_dev->fop_lock);
+done_open:
 	mutex_unlock(&vou_dev->fop_lock);
-
-	file->private_data = vou_file;
-
-	return 0;
+	return err;
 }
 
 static int sh_vou_release(struct file *file)
 {
 	struct sh_vou_device *vou_dev = video_drvdata(file);
-	struct sh_vou_file *vou_file = file->private_data;
-
-	dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
 
 	mutex_lock(&vou_dev->fop_lock);
-	if (v4l2_fh_is_singular(&vou_file->fh)) {
+	if (v4l2_fh_is_singular_file(file)) {
 		/* Last close */
 		vou_dev->status = SH_VOU_IDLE;
 		sh_vou_reg_a_set(vou_dev, VOUER, 0, 0x101);
 		pm_runtime_put(vou_dev->v4l2_dev.dev);
 	}
-	v4l2_fh_del(&vou_file->fh);
-	v4l2_fh_exit(&vou_file->fh);
+	_vb2_fop_release(file, NULL);
 	mutex_unlock(&vou_dev->fop_lock);
-
-	file->private_data = NULL;
-	kfree(vou_file);
-
 	return 0;
 }
 
-static int sh_vou_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	struct sh_vou_device *vou_dev = video_drvdata(file);
-	struct sh_vou_file *vou_file = file->private_data;
-	int ret;
-
-	dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
-
-	if (mutex_lock_interruptible(&vou_dev->fop_lock))
-		return -ERESTARTSYS;
-	ret = videobuf_mmap_mapper(&vou_file->vbq, vma);
-	mutex_unlock(&vou_dev->fop_lock);
-	return ret;
-}
-
-static unsigned int sh_vou_poll(struct file *file, poll_table *wait)
-{
-	struct sh_vou_device *vou_dev = video_drvdata(file);
-	struct sh_vou_file *vou_file = file->private_data;
-	unsigned int res;
-
-	dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
-
-	mutex_lock(&vou_dev->fop_lock);
-	res = videobuf_poll_stream(file, &vou_file->vbq, wait);
-	mutex_unlock(&vou_dev->fop_lock);
-	return res;
-}
-
 /* sh_vou display ioctl operations */
 static const struct v4l2_ioctl_ops sh_vou_ioctl_ops = {
 	.vidioc_querycap        	= sh_vou_querycap,
@@ -1305,12 +1180,15 @@ static const struct v4l2_ioctl_ops sh_vou_ioctl_ops = {
 	.vidioc_g_fmt_vid_out		= sh_vou_g_fmt_vid_out,
 	.vidioc_s_fmt_vid_out		= sh_vou_s_fmt_vid_out,
 	.vidioc_try_fmt_vid_out		= sh_vou_try_fmt_vid_out,
-	.vidioc_reqbufs			= sh_vou_reqbufs,
-	.vidioc_querybuf		= sh_vou_querybuf,
-	.vidioc_qbuf			= sh_vou_qbuf,
-	.vidioc_dqbuf			= sh_vou_dqbuf,
-	.vidioc_streamon		= sh_vou_streamon,
-	.vidioc_streamoff		= sh_vou_streamoff,
+	.vidioc_reqbufs			= vb2_ioctl_reqbufs,
+	.vidioc_create_bufs		= vb2_ioctl_create_bufs,
+	.vidioc_querybuf		= vb2_ioctl_querybuf,
+	.vidioc_qbuf			= vb2_ioctl_qbuf,
+	.vidioc_dqbuf			= vb2_ioctl_dqbuf,
+	.vidioc_prepare_buf		= vb2_ioctl_prepare_buf,
+	.vidioc_streamon		= vb2_ioctl_streamon,
+	.vidioc_streamoff		= vb2_ioctl_streamoff,
+	.vidioc_expbuf			= vb2_ioctl_expbuf,
 	.vidioc_g_output		= sh_vou_g_output,
 	.vidioc_s_output		= sh_vou_s_output,
 	.vidioc_enum_output		= sh_vou_enum_output,
@@ -1326,8 +1204,9 @@ static const struct v4l2_file_operations sh_vou_fops = {
 	.open		= sh_vou_open,
 	.release	= sh_vou_release,
 	.unlocked_ioctl	= video_ioctl2,
-	.mmap		= sh_vou_mmap,
-	.poll		= sh_vou_poll,
+	.mmap		= vb2_fop_mmap,
+	.poll		= vb2_fop_poll,
+	.write		= vb2_fop_write,
 };
 
 static const struct video_device sh_vou_video_template = {
@@ -1348,6 +1227,7 @@ static int sh_vou_probe(struct platform_device *pdev)
 	struct sh_vou_device *vou_dev;
 	struct resource *reg_res;
 	struct v4l2_subdev *subdev;
+	struct vb2_queue *q;
 	int irq, ret;
 
 	reg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1368,11 +1248,12 @@ static int sh_vou_probe(struct platform_device *pdev)
 		return PTR_ERR(vou_dev->clk);
 	}
 
-	INIT_LIST_HEAD(&vou_dev->queue);
+	INIT_LIST_HEAD(&vou_dev->buf_list);
 	spin_lock_init(&vou_dev->lock);
 	mutex_init(&vou_dev->fop_lock);
 	vou_dev->pdata = vou_pdata;
-	vou_dev->status = SH_VOU_IDLE;
+	vou_dev->status = SH_VOU_INITIALISING;
+	vou_dev->pix_idx = 1;
 
 	rect = &vou_dev->rect;
 	pix = &vou_dev->pix;
@@ -1386,7 +1267,7 @@ static int sh_vou_probe(struct platform_device *pdev)
 	pix->width		= VOU_MAX_IMAGE_WIDTH;
 	pix->height		= 480;
 	pix->pixelformat	= V4L2_PIX_FMT_NV16;
-	pix->field		= V4L2_FIELD_NONE;
+	pix->field		= V4L2_FIELD_INTERLACED;
 	pix->bytesperline	= VOU_MAX_IMAGE_WIDTH;
 	pix->sizeimage		= VOU_MAX_IMAGE_WIDTH * 2 * 480;
 	pix->colorspace		= V4L2_COLORSPACE_SMPTE170M;
@@ -1415,6 +1296,30 @@ static int sh_vou_probe(struct platform_device *pdev)
 
 	video_set_drvdata(vdev, vou_dev);
 
+	/* Initialize the vb2 queue */
+	q = &vou_dev->queue;
+	q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+	q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_WRITE;
+	q->drv_priv = vou_dev;
+	q->buf_struct_size = sizeof(struct sh_vou_buffer);
+	q->ops = &sh_vou_qops;
+	q->mem_ops = &vb2_dma_contig_memops;
+	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	q->min_buffers_needed = 2;
+	q->lock = &vou_dev->fop_lock;
+	ret = vb2_queue_init(q);
+	if (ret)
+		goto einitctx;
+
+	vou_dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
+	if (IS_ERR(vou_dev->alloc_ctx)) {
+		dev_err(&pdev->dev, "Can't allocate buffer context");
+		ret = PTR_ERR(vou_dev->alloc_ctx);
+		goto einitctx;
+	}
+	vdev->queue = q;
+	INIT_LIST_HEAD(&vou_dev->buf_list);
+
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_resume(&pdev->dev);
 
@@ -1448,6 +1353,8 @@ ereset:
 	clk_disable_unprepare(vou_dev->clk);
 	i2c_put_adapter(i2c_adap);
 ei2cgadap:
+	vb2_dma_contig_cleanup_ctx(vou_dev->alloc_ctx);
+einitctx:
 	pm_runtime_disable(&pdev->dev);
 	v4l2_device_unregister(&vou_dev->v4l2_dev);
 	return ret;
@@ -1466,6 +1373,7 @@ static int sh_vou_remove(struct platform_device *pdev)
 	video_unregister_device(&vou_dev->vdev);
 	clk_disable_unprepare(vou_dev->clk);
 	i2c_put_adapter(client->adapter);
+	vb2_dma_contig_cleanup_ctx(vou_dev->alloc_ctx);
 	v4l2_device_unregister(&vou_dev->v4l2_dev);
 	return 0;
 }
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH 07/10] sh-vou: add support for log_status
  2015-06-05 10:59 ` [PATCH 07/10] sh-vou: add support for log_status Hans Verkuil
@ 2015-06-05 13:28   ` Sergei Shtylyov
  2015-06-05 14:37     ` Hans Verkuil
  0 siblings, 1 reply; 15+ messages in thread
From: Sergei Shtylyov @ 2015-06-05 13:28 UTC (permalink / raw)
  To: Hans Verkuil, linux-media; +Cc: linux-sh, Hans Verkuil

Hello.

On 6/5/2015 1:59 PM, Hans Verkuil wrote:

> From: Hans Verkuil <hans.verkuil@cisco.com>

> Dump the VOU registers in log_status.

> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> ---
>   drivers/media/platform/sh_vou.c | 29 +++++++++++++++++++++++++++++
>   1 file changed, 29 insertions(+)

> diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
> index 7ed5a8b..400efec 100644
> --- a/drivers/media/platform/sh_vou.c
> +++ b/drivers/media/platform/sh_vou.c
> @@ -951,6 +951,34 @@ static int sh_vou_g_std(struct file *file, void *priv, v4l2_std_id *std)
>   	return 0;
>   }
>
> +static int sh_vou_log_status(struct file *file, void *priv)
> +{
> +	struct sh_vou_device *vou_dev = video_drvdata(file);
> +
> +	pr_info("PSELA:   0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUER));
> +	pr_info("VOUER:   0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUER));

    You're dumping the same register twice, under different names?

> +	pr_info("VOUCR:   0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUCR));
> +	pr_info("VOUSTR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUSTR));
> +	pr_info("VOUVCR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUVCR));
> +	pr_info("VOUISR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUISR));
> +	pr_info("VOUBCR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUBCR));
> +	pr_info("VOUDPR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUDPR));
> +	pr_info("VOUDSR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUDSR));
> +	pr_info("VOUVPR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUVPR));
> +	pr_info("VOUIR:   0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUIR));
> +	pr_info("VOUSRR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUSRR));
> +	pr_info("VOUMSR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUMSR));
> +	pr_info("VOUHIR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUHIR));
> +	pr_info("VOUDFR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUDFR));
> +	pr_info("VOUAD1R: 0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUAD1R));
> +	pr_info("VOUAD2R: 0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUAD2R));
> +	pr_info("VOUAIR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUAIR));
> +	pr_info("VOUSWR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUSWR));
> +	pr_info("VOURCR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOURCR));
> +	pr_info("VOURPR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOURPR));
> +	return 0;
> +}
> +
[...]

WBR, Sergei


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 07/10] sh-vou: add support for log_status
  2015-06-05 13:28   ` Sergei Shtylyov
@ 2015-06-05 14:37     ` Hans Verkuil
  0 siblings, 0 replies; 15+ messages in thread
From: Hans Verkuil @ 2015-06-05 14:37 UTC (permalink / raw)
  To: Sergei Shtylyov, linux-media; +Cc: linux-sh, Hans Verkuil

On 06/05/2015 03:28 PM, Sergei Shtylyov wrote:
> Hello.
> 
> On 6/5/2015 1:59 PM, Hans Verkuil wrote:
> 
>> From: Hans Verkuil <hans.verkuil@cisco.com>
> 
>> Dump the VOU registers in log_status.
> 
>> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
>> ---
>>   drivers/media/platform/sh_vou.c | 29 +++++++++++++++++++++++++++++
>>   1 file changed, 29 insertions(+)
> 
>> diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
>> index 7ed5a8b..400efec 100644
>> --- a/drivers/media/platform/sh_vou.c
>> +++ b/drivers/media/platform/sh_vou.c
>> @@ -951,6 +951,34 @@ static int sh_vou_g_std(struct file *file, void *priv, v4l2_std_id *std)
>>   	return 0;
>>   }
>>
>> +static int sh_vou_log_status(struct file *file, void *priv)
>> +{
>> +	struct sh_vou_device *vou_dev = video_drvdata(file);
>> +
>> +	pr_info("PSELA:   0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUER));
>> +	pr_info("VOUER:   0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUER));
> 
>     You're dumping the same register twice, under different names?

Oops, PSELA doesn't belong here. I'll remove that line. Thanks for spotting this.

Regards,

	Hans

> 
>> +	pr_info("VOUCR:   0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUCR));
>> +	pr_info("VOUSTR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUSTR));
>> +	pr_info("VOUVCR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUVCR));
>> +	pr_info("VOUISR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUISR));
>> +	pr_info("VOUBCR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUBCR));
>> +	pr_info("VOUDPR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUDPR));
>> +	pr_info("VOUDSR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUDSR));
>> +	pr_info("VOUVPR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUVPR));
>> +	pr_info("VOUIR:   0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUIR));
>> +	pr_info("VOUSRR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUSRR));
>> +	pr_info("VOUMSR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUMSR));
>> +	pr_info("VOUHIR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUHIR));
>> +	pr_info("VOUDFR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUDFR));
>> +	pr_info("VOUAD1R: 0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUAD1R));
>> +	pr_info("VOUAD2R: 0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUAD2R));
>> +	pr_info("VOUAIR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUAIR));
>> +	pr_info("VOUSWR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOUSWR));
>> +	pr_info("VOURCR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOURCR));
>> +	pr_info("VOURPR:  0x%08x\n", sh_vou_reg_a_read(vou_dev, VOURPR));
>> +	return 0;
>> +}
>> +
> [...]
> 
> WBR, Sergei
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 01/10] sh-vou: hook up the clock correctly
  2015-06-05 10:59 ` [PATCH 01/10] sh-vou: hook up the clock correctly Hans Verkuil
@ 2015-06-06 21:42   ` Geert Uytterhoeven
  2015-06-07  8:51     ` Hans Verkuil
  0 siblings, 1 reply; 15+ messages in thread
From: Geert Uytterhoeven @ 2015-06-06 21:42 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Linux Media Mailing List, Linux-sh list, Hans Verkuil, Magnus Damm

Hi Hans,

On Fri, Jun 5, 2015 at 12:59 PM, Hans Verkuil <hverkuil@xs4all.nl> wrote:
> From: Hans Verkuil <hans.verkuil@cisco.com>
>
> Bitrot has set in for this driver and the sh-vou.0 clock was never enabled,
> so this driver didn't do anything. In addition, the clock was incorrectly
> defined in clock-sh7724.c. Fix this.

I think the clock should be enabled automatically using Runtime PM.
drivers/sh/pm_runtime.c should configure the "NULL" (i.e. the first) clock
for power management, after which pm_runtime_get_sync() will enable it.

> While we're at it: use proper resource managed calls.

Shouldn't that be a separate patch? Especially if the real fix becomes a
one-liner (see below).

> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> Cc: Magnus Damm <damm@opensource.se>
> ---
>  arch/sh/kernel/cpu/sh4a/clock-sh7724.c |  2 +-
>  drivers/media/platform/sh_vou.c        | 54 ++++++++++++----------------------
>  2 files changed, 20 insertions(+), 36 deletions(-)
>
> diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
> index c187b95..f1df899 100644
> --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
> +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
> @@ -343,7 +343,7 @@ static struct clk_lookup lookups[] = {
>         CLKDEV_CON_ID("2ddmac0", &mstp_clks[HWBLK_2DDMAC]),
>         CLKDEV_DEV_ID("sh_fsi.0", &mstp_clks[HWBLK_SPU]),
>         CLKDEV_CON_ID("jpu0", &mstp_clks[HWBLK_JPU]),
> -       CLKDEV_DEV_ID("sh-vou.0", &mstp_clks[HWBLK_VOU]),
> +       CLKDEV_CON_ID("sh-vou.0", &mstp_clks[HWBLK_VOU]),

I don't know which SH board you have, but both
arch/sh/boards/mach-ecovec24/setup.c and
arch/sh/boards/mach-se/7724/setup.c create the platform device as:

        static struct platform_device vou_device = {
                .name           = "sh-vou",
                .id             = -1,
        };

so unless I'm mistaken, the platform device's name will be "sh-vou",
not "sh-vou.0".

Does it work if you just correct the name in the CLKDEV_DEV_ID() line?

Thanks!

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 01/10] sh-vou: hook up the clock correctly
  2015-06-06 21:42   ` Geert Uytterhoeven
@ 2015-06-07  8:51     ` Hans Verkuil
  0 siblings, 0 replies; 15+ messages in thread
From: Hans Verkuil @ 2015-06-07  8:51 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Linux Media Mailing List, Linux-sh list, Hans Verkuil, Magnus Damm

On 06/06/2015 11:42 PM, Geert Uytterhoeven wrote:
> Hi Hans,
> 
> On Fri, Jun 5, 2015 at 12:59 PM, Hans Verkuil <hverkuil@xs4all.nl> wrote:
>> From: Hans Verkuil <hans.verkuil@cisco.com>
>>
>> Bitrot has set in for this driver and the sh-vou.0 clock was never enabled,
>> so this driver didn't do anything. In addition, the clock was incorrectly
>> defined in clock-sh7724.c. Fix this.
> 
> I think the clock should be enabled automatically using Runtime PM.
> drivers/sh/pm_runtime.c should configure the "NULL" (i.e. the first) clock
> for power management, after which pm_runtime_get_sync() will enable it.

Ah, that works too after I fixed a small bug in sh_vou_release (status should
have been reset to SH_VOU_INITIALISING).

>> While we're at it: use proper resource managed calls.
> 
> Shouldn't that be a separate patch? Especially if the real fix becomes a
> one-liner (see below).

I'll split it up.

>> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
>> Cc: Magnus Damm <damm@opensource.se>
>> ---
>>  arch/sh/kernel/cpu/sh4a/clock-sh7724.c |  2 +-
>>  drivers/media/platform/sh_vou.c        | 54 ++++++++++++----------------------
>>  2 files changed, 20 insertions(+), 36 deletions(-)
>>
>> diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
>> index c187b95..f1df899 100644
>> --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
>> +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
>> @@ -343,7 +343,7 @@ static struct clk_lookup lookups[] = {
>>         CLKDEV_CON_ID("2ddmac0", &mstp_clks[HWBLK_2DDMAC]),
>>         CLKDEV_DEV_ID("sh_fsi.0", &mstp_clks[HWBLK_SPU]),
>>         CLKDEV_CON_ID("jpu0", &mstp_clks[HWBLK_JPU]),
>> -       CLKDEV_DEV_ID("sh-vou.0", &mstp_clks[HWBLK_VOU]),
>> +       CLKDEV_CON_ID("sh-vou.0", &mstp_clks[HWBLK_VOU]),
> 
> I don't know which SH board you have, but both
> arch/sh/boards/mach-ecovec24/setup.c and
> arch/sh/boards/mach-se/7724/setup.c create the platform device as:

I have a R0P7724LC0011/21RL (mach-ecovec24 based) board.

> 
>         static struct platform_device vou_device = {
>                 .name           = "sh-vou",
>                 .id             = -1,
>         };
> 
> so unless I'm mistaken, the platform device's name will be "sh-vou",
> not "sh-vou.0".
> 
> Does it work if you just correct the name in the CLKDEV_DEV_ID() line?

Yes, that works.

Thanks for the help, I'll report this patch series with these fixes.

Regards,

	Hans

> 
> Thanks!
> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2015-06-07  8:51 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-05 10:59 [PATCH 00/10] sh-vou: fixes, convert to vb2 Hans Verkuil
2015-06-05 10:59 ` [PATCH 01/10] sh-vou: hook up the clock correctly Hans Verkuil
2015-06-06 21:42   ` Geert Uytterhoeven
2015-06-07  8:51     ` Hans Verkuil
2015-06-05 10:59 ` [PATCH 02/10] sh-vou: fix querycap support Hans Verkuil
2015-06-05 10:59 ` [PATCH 03/10] sh-vou: use v4l2_fh Hans Verkuil
2015-06-05 10:59 ` [PATCH 04/10] sh-vou: support compulsory G/S/ENUM_OUTPUT ioctls Hans Verkuil
2015-06-05 10:59 ` [PATCH 05/10] sh-vou: fix incorrect initial pixelformat Hans Verkuil
2015-06-05 10:59 ` [PATCH 06/10] sh-vou: replace g/s_crop/cropcap by g/s_selection Hans Verkuil
2015-06-05 10:59 ` [PATCH 07/10] sh-vou: add support for log_status Hans Verkuil
2015-06-05 13:28   ` Sergei Shtylyov
2015-06-05 14:37     ` Hans Verkuil
2015-06-05 10:59 ` [PATCH 08/10] sh-vou: let sh_vou_s_fmt_vid_out call sh_vou_try_fmt_vid_out Hans Verkuil
2015-06-05 10:59 ` [PATCH 09/10] sh-vou: fix bytesperline Hans Verkuil
2015-06-05 10:59 ` [PATCH 10/10] sh-vou: convert to vb2 Hans Verkuil

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).