diff mbox series

[2/2,RFC] media: rcar-vin: make timeout of the irq timer configurable via v4l2 control

Message ID 1592588777-100596-2-git-send-email-mrodin@de.adit-jv.com
State New
Headers show
Series None | expand

Commit Message

Michael Rodin June 19, 2020, 5:46 p.m. UTC
Different framerates imply different periods between successive frames.
Therefore it is reasonable to make the timeout of the irq_timer
configurable at the run time so userspace can avoid unnecessary long
waiting times. Therefore this commit adds a new custom control to rcar-vin.
This allows to change the timeout before the start of streaming.

Signed-off-by: Michael Rodin <mrodin@de.adit-jv.com>
---
 drivers/media/platform/rcar-vin/rcar-core.c | 17 ++++++++++++++++-
 drivers/media/platform/rcar-vin/rcar-dma.c  | 14 +++++++++-----
 drivers/media/platform/rcar-vin/rcar-vin.h  |  5 +++++
 include/uapi/linux/rcar-vin.h               |  7 +++++++
 include/uapi/linux/v4l2-controls.h          |  6 ++++++
 5 files changed, 43 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index 7440c89..81faa87 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -884,6 +884,17 @@  static int rvin_mc_parse_of_graph(struct rvin_dev *vin)
 	return 0;
 }
 
+static const struct v4l2_ctrl_config rvin_ctrl_irq_timeout = {
+	.ops = &rvin_ctrl_ops,
+	.id = V4L2_CID_RCAR_VIN_IRQ_TIMEOUT,
+	.name = "frame completion timeout",
+	.type = V4L2_CTRL_TYPE_INTEGER,
+	.min = 0,
+	.max = S32_MAX,
+	.step = 1,
+	.def = IRQ_TIMEOUT_MS,
+};
+
 static int rvin_mc_init(struct rvin_dev *vin)
 {
 	int ret;
@@ -901,13 +912,17 @@  static int rvin_mc_init(struct rvin_dev *vin)
 	if (ret)
 		rvin_group_put(vin);
 
-	ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 1);
+	ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 2);
 	if (ret < 0)
 		return ret;
 
 	v4l2_ctrl_new_std(&vin->ctrl_handler, &rvin_ctrl_ops,
 			  V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255);
 
+	vin->ctrl_irq_timeout = v4l2_ctrl_new_custom(&vin->ctrl_handler,
+						     &rvin_ctrl_irq_timeout,
+						     NULL);
+
 	if (vin->ctrl_handler.error) {
 		ret = vin->ctrl_handler.error;
 		v4l2_ctrl_handler_free(&vin->ctrl_handler);
diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c
index bf8d733..062f338 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -947,7 +947,7 @@  static void rvin_irq_timer_function(struct timer_list *timer)
 					    irq_timer);
 
 	vin_err(vin, "%s: frame completion timeout after %i ms!\n",
-		__func__, IRQ_TIMEOUT_MS);
+		__func__, jiffies_to_msecs(vin->irq_timeout));
 	v4l2_event_queue(&vin->vdev, &rvin_irq_timeout);
 }
 
@@ -1022,7 +1022,7 @@  static irqreturn_t rvin_irq(int irq, void *data)
 		vin_dbg(vin, "Dropping frame %u\n", vin->sequence);
 	}
 
-	mod_timer(&vin->irq_timer, jiffies + msecs_to_jiffies(IRQ_TIMEOUT_MS));
+	mod_timer(&vin->irq_timer, jiffies + vin->irq_timeout);
 
 	vin->sequence++;
 
@@ -1233,6 +1233,7 @@  static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count)
 	struct rvin_dev *vin = vb2_get_drv_priv(vq);
 	unsigned long flags;
 	int ret;
+	s32 irq_timeout = v4l2_ctrl_g_ctrl(vin->ctrl_irq_timeout);
 
 	/* Allocate scratch buffer. */
 	vin->scratch = dma_alloc_coherent(vin->dev, vin->format.sizeimage,
@@ -1265,11 +1266,14 @@  static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count)
 
 	spin_unlock_irqrestore(&vin->qlock, flags);
 out:
-	if (ret)
+	if (ret) {
 		dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch,
 				  vin->scratch_phys);
-	else
-		mod_timer(&vin->irq_timer, jiffies + msecs_to_jiffies(IRQ_TIMEOUT_MS));
+	} else {
+		vin->irq_timeout = msecs_to_jiffies(irq_timeout);
+		mod_timer(&vin->irq_timer, jiffies + vin->irq_timeout);
+		vin_dbg(vin, "%s: set irq timer to %i ms\n", __func__, irq_timeout);
+	}
 
 	return ret;
 }
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h
index 7408f67..4e514e7 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -201,6 +201,9 @@  struct rvin_info {
  * @src_rect:		active size of the video source
  * @std:		active video standard of the video source
  * @irq_timer:		monitors regular capturing of frames in rvin_irq()
+ * @irq_timeout:	timeout value in jiffies, which is currently used by
+ *			@irq_timer and can be changed via @ctrl_irq_timeout
+ * @ctrl_irq_timeout:	controls value of @irq_timeout
  *
  * @alpha:		Alpha component to fill in for supported pixel formats
  */
@@ -246,6 +249,8 @@  struct rvin_dev {
 	v4l2_std_id std;
 
 	struct timer_list irq_timer;
+	unsigned long irq_timeout;
+	struct v4l2_ctrl *ctrl_irq_timeout;
 	unsigned int alpha;
 };
 
diff --git a/include/uapi/linux/rcar-vin.h b/include/uapi/linux/rcar-vin.h
index 4eb7f5e..6c72584 100644
--- a/include/uapi/linux/rcar-vin.h
+++ b/include/uapi/linux/rcar-vin.h
@@ -3,8 +3,15 @@ 
 #ifndef RCAR_VIN_USER_H
 #define RCAR_VIN_USER_H
 
+#include <linux/v4l2-controls.h>
+
 /* class for events sent by the rcar-vin driver */
 #define V4L2_EVENT_RCAR_VIN_CLASS	V4L2_EVENT_PRIVATE_START
 #define V4L2_EVENT_RCAR_VIN_IRQ_TIMEOUT	(V4L2_EVENT_RCAR_VIN_CLASS | 0x1)
 
+/* private controls for rcar-vin */
+enum rcar_vin_ctrl_id {
+	V4L2_CID_RCAR_VIN_IRQ_TIMEOUT = V4L2_CID_USER_RCAR_VIN_BASE
+};
+
 #endif /* RCAR_VIN_USER_H */
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index 6227141..cf4f085 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -198,6 +198,12 @@  enum v4l2_colorfx {
  */
 #define V4L2_CID_USER_ATMEL_ISC_BASE		(V4L2_CID_USER_BASE + 0x10c0)
 
+/*
+ * The base for the rcar-vin driver controls.
+ * We reserve 16 controls for this driver.
+ */
+#define V4L2_CID_USER_RCAR_VIN_BASE		(V4L2_CID_USER_BASE + 0x10d0)
+
 /* MPEG-class control IDs */
 /* The MPEG controls are applicable to all codec controls
  * and the 'MPEG' part of the define is historical */