All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Niklas Söderlund" <niklas.soderlund+renesas@ragnatech.se>
To: Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
	Sakari Ailus <sakari.ailus@linux.intel.com>,
	linux-media@vger.kernel.org
Cc: linux-renesas-soc@vger.kernel.org
Subject: [PATCH 05/30] media: entity: Move the pipeline from entity to pads
Date: Thu, 23 Aug 2018 15:25:19 +0200	[thread overview]
Message-ID: <20180823132544.521-6-niklas.soderlund+renesas@ragnatech.se> (raw)
In-Reply-To: <20180823132544.521-1-niklas.soderlund+renesas@ragnatech.se>

From: Sakari Ailus <sakari.ailus@linux.intel.com>

This moves the pipe and stream_count fields from struct media_entity to
struct media_pad. Effectively streams become pad-specific rather than
being stream specific, allowing several independent streams to traverse a
single entity.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/media-entity.c                  | 61 ++++++++++++-------
 drivers/media/platform/exynos4-is/fimc-isp.c  |  2 +-
 drivers/media/platform/exynos4-is/fimc-lite.c |  2 +-
 drivers/media/platform/omap3isp/isp.c         |  2 +-
 drivers/media/platform/omap3isp/ispvideo.c    |  2 +-
 drivers/media/platform/omap3isp/ispvideo.h    |  2 +-
 drivers/media/platform/rcar-vin/rcar-dma.c    |  2 +-
 drivers/media/platform/xilinx/xilinx-dma.c    |  2 +-
 drivers/media/platform/xilinx/xilinx-dma.h    |  2 +-
 drivers/staging/media/imx/imx-media-utils.c   |  2 +-
 drivers/staging/media/omap4iss/iss.c          |  2 +-
 drivers/staging/media/omap4iss/iss_video.c    |  2 +-
 drivers/staging/media/omap4iss/iss_video.h    |  2 +-
 include/media/media-entity.h                  | 17 ++++--
 14 files changed, 61 insertions(+), 41 deletions(-)

diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index ec7c61dff6ae879d..239036a7582cbc95 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -419,7 +419,7 @@ __must_check int __media_pipeline_start(struct media_entity *entity,
 	struct media_pad *pad = entity->pads;
 	struct media_pad *pad_err = pad;
 	struct media_link *link;
-	int ret;
+	int ret = 0;
 
 	if (!pipe->streaming_count++) {
 		ret = media_graph_walk_init(&pipe->graph, mdev);
@@ -431,21 +431,27 @@ __must_check int __media_pipeline_start(struct media_entity *entity,
 
 	while ((pad = media_graph_walk_next(graph))) {
 		struct media_entity *entity = pad->entity;
+		unsigned int i;
+		bool skip_validation = pad->pipe;
 
 		DECLARE_BITMAP(active, MEDIA_ENTITY_MAX_PADS);
 		DECLARE_BITMAP(has_no_links, MEDIA_ENTITY_MAX_PADS);
 
-		entity->stream_count++;
+		for (i = 0; i < entity->num_pads; i++) {
+			struct media_pad *iter = &entity->pads[i];
 
-		if (WARN_ON(entity->pipe && entity->pipe != pipe)) {
-			ret = -EBUSY;
-			goto error;
+			if (iter->pipe && WARN_ON(iter->pipe != pipe))
+				ret = -EBUSY;
+			else
+				iter->pipe = pipe;
+			iter->stream_count++;
 		}
 
-		entity->pipe = pipe;
+		if (ret)
+			goto error;
 
 		/* Already streaming --- no need to check. */
-		if (entity->stream_count > 1)
+		if (skip_validation)
 			continue;
 
 		if (!entity->ops || !entity->ops->link_validate)
@@ -514,19 +520,24 @@ __must_check int __media_pipeline_start(struct media_entity *entity,
 
 	while ((pad_err = media_graph_walk_next(graph))) {
 		struct media_entity *entity_err = pad_err->entity;
+		unsigned int i;
+
+		for (i = 0; i < entity_err->num_pads; i++) {
+			struct media_pad *iter = &entity_err->pads[i];
 
-		/* Sanity check for negative stream_count */
-		if (!WARN_ON_ONCE(entity_err->stream_count <= 0)) {
-			entity_err->stream_count--;
-			if (entity_err->stream_count == 0)
-				entity_err->pipe = NULL;
+			/* Sanity check for negative stream_count */
+			if (!WARN_ON_ONCE(iter->stream_count <= 0)) {
+				--iter->stream_count;
+				if (iter->stream_count == 0)
+					iter->pipe = NULL;
+			}
 		}
 
 		/*
 		 * We haven't increased stream_count further than this
 		 * so we quit here.
 		 */
-		if (pad_err == pad)
+		if (pad_err->entity == pad->entity)
 			break;
 	}
 
@@ -553,7 +564,7 @@ EXPORT_SYMBOL_GPL(media_pipeline_start);
 
 void __media_pipeline_stop(struct media_entity *entity)
 {
-	struct media_pipeline *pipe = entity->pipe;
+	struct media_pipeline *pipe = entity->pads->pipe;
 	struct media_graph *graph = &pipe->graph;
 	struct media_pad *pad;
 
@@ -567,13 +578,17 @@ void __media_pipeline_stop(struct media_entity *entity)
 	media_graph_walk_start(graph, entity->pads);
 
 	while ((pad = media_graph_walk_next(graph))) {
-		struct media_entity *entity = pad->entity;
+		unsigned int i;
 
-		/* Sanity check for negative stream_count */
-		if (!WARN_ON_ONCE(entity->stream_count <= 0)) {
-			entity->stream_count--;
-			if (entity->stream_count == 0)
-				entity->pipe = NULL;
+		for (i = 0; i < entity->num_pads; i++) {
+			struct media_pad *iter = &entity->pads[i];
+
+			/* Sanity check for negative stream_count */
+			if (!WARN_ON_ONCE(iter->stream_count <= 0)) {
+				iter->stream_count--;
+				if (iter->stream_count == 0)
+					iter->pipe = NULL;
+			}
 		}
 	}
 
@@ -839,7 +854,7 @@ int __media_entity_setup_link(struct media_link *link, u32 flags)
 {
 	const u32 mask = MEDIA_LNK_FL_ENABLED;
 	struct media_device *mdev;
-	struct media_entity *source, *sink;
+	struct media_pad *source, *sink;
 	int ret = -EBUSY;
 
 	if (link == NULL)
@@ -855,8 +870,8 @@ int __media_entity_setup_link(struct media_link *link, u32 flags)
 	if (link->flags == flags)
 		return 0;
 
-	source = link->source->entity;
-	sink = link->sink->entity;
+	source = link->source;
+	sink = link->sink;
 
 	if (!(link->flags & MEDIA_LNK_FL_DYNAMIC) &&
 	    (source->stream_count || sink->stream_count))
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c
index 9a48c0f69320ba35..79d128a57e87fd58 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp.c
@@ -229,7 +229,7 @@ static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd,
 			}
 		}
 	} else {
-		if (sd->entity.stream_count == 0) {
+		if (sd->entity.pads->stream_count == 0) {
 			if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
 				struct v4l2_subdev_format format = *fmt;
 
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index 70d5f5586a5d5ca6..f486eeed805b0bbc 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -1096,7 +1096,7 @@ static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd,
 	mutex_lock(&fimc->lock);
 
 	if ((atomic_read(&fimc->out_path) == FIMC_IO_ISP &&
-	    sd->entity.stream_count > 0) ||
+	    sd->entity.pads->stream_count > 0) ||
 	    (atomic_read(&fimc->out_path) == FIMC_IO_DMA &&
 	    vb2_is_busy(&fimc->vb_queue))) {
 		mutex_unlock(&fimc->lock);
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 842e2235047d9c63..c487efe8c153942b 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -927,7 +927,7 @@ static int isp_pipeline_is_last(struct media_entity *me)
 	struct isp_pipeline *pipe;
 	struct media_pad *pad;
 
-	if (!me->pipe)
+	if (!me->pads->pipe)
 		return 0;
 	pipe = to_isp_pipeline(me);
 	if (pipe->stream_state == ISP_PIPELINE_STREAM_STOPPED)
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index 1f52779249cfaf60..5ac7ac8c98d52ac8 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -1102,7 +1102,7 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	/* Start streaming on the pipeline. No link touching an entity in the
 	 * pipeline can be activated or deactivated once streaming is started.
 	 */
-	pipe = video->video.entity.pipe
+	pipe = video->video.entity.pads->pipe
 	     ? to_isp_pipeline(&video->video.entity) : &video->pipe;
 
 	ret = media_entity_enum_init(&pipe->ent_enum, &video->isp->media_dev);
diff --git a/drivers/media/platform/omap3isp/ispvideo.h b/drivers/media/platform/omap3isp/ispvideo.h
index f6a2082b4a0a7708..8f4146c25a1b1293 100644
--- a/drivers/media/platform/omap3isp/ispvideo.h
+++ b/drivers/media/platform/omap3isp/ispvideo.h
@@ -103,7 +103,7 @@ struct isp_pipeline {
 };
 
 #define to_isp_pipeline(__e) \
-	container_of((__e)->pipe, struct isp_pipeline, pipe)
+	container_of((__e)->pads->pipe, struct isp_pipeline, pipe)
 
 static inline int isp_pipeline_ready(struct isp_pipeline *pipe)
 {
diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c
index 92323310f7352147..e749096926f34d4a 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -1128,7 +1128,7 @@ static int rvin_set_stream(struct rvin_dev *vin, int on)
 	 */
 	mdev = vin->vdev.entity.graph_obj.mdev;
 	mutex_lock(&mdev->graph_mutex);
-	pipe = sd->entity.pipe ? sd->entity.pipe : &vin->vdev.pipe;
+	pipe = sd->entity.pads->pipe ? sd->entity.pads->pipe : &vin->vdev.pipe;
 	ret = __media_pipeline_start(&vin->vdev.entity, pipe);
 	mutex_unlock(&mdev->graph_mutex);
 	if (ret)
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
index 9f0a53238d510fce..9ea9a58eec632b7b 100644
--- a/drivers/media/platform/xilinx/xilinx-dma.c
+++ b/drivers/media/platform/xilinx/xilinx-dma.c
@@ -406,7 +406,7 @@ static int xvip_dma_start_streaming(struct vb2_queue *vq, unsigned int count)
 	 * Use the pipeline object embedded in the first DMA object that starts
 	 * streaming.
 	 */
-	pipe = dma->video.entity.pipe
+	pipe = dma->video.entity.pads->pipe
 	     ? to_xvip_pipeline(&dma->video.entity) : &dma->pipe;
 
 	ret = media_pipeline_start(&dma->video.entity, &pipe->pipe);
diff --git a/drivers/media/platform/xilinx/xilinx-dma.h b/drivers/media/platform/xilinx/xilinx-dma.h
index e95d136c153a8f5f..c12e053ff41eed1c 100644
--- a/drivers/media/platform/xilinx/xilinx-dma.h
+++ b/drivers/media/platform/xilinx/xilinx-dma.h
@@ -50,7 +50,7 @@ struct xvip_pipeline {
 
 static inline struct xvip_pipeline *to_xvip_pipeline(struct media_entity *e)
 {
-	return container_of(e->pipe, struct xvip_pipeline, pipe);
+	return container_of(e->pads->pipe, struct xvip_pipeline, pipe);
 }
 
 /**
diff --git a/drivers/staging/media/imx/imx-media-utils.c b/drivers/staging/media/imx/imx-media-utils.c
index 8aa13403b09d15f6..1cfa77a96e610f6c 100644
--- a/drivers/staging/media/imx/imx-media-utils.c
+++ b/drivers/staging/media/imx/imx-media-utils.c
@@ -917,7 +917,7 @@ int imx_media_pipeline_set_stream(struct imx_media_dev *imxmd,
 			__media_pipeline_stop(entity);
 	} else {
 		v4l2_subdev_call(sd, video, s_stream, 0);
-		if (entity->pipe)
+		if (entity->pads->pipe)
 			__media_pipeline_stop(entity);
 	}
 
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index b1036baebb0357e7..6785363c09e9ba43 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -547,7 +547,7 @@ static int iss_pipeline_is_last(struct media_entity *me)
 	struct iss_pipeline *pipe;
 	struct media_pad *pad;
 
-	if (!me->pipe)
+	if (!me->pads->pipe)
 		return 0;
 	pipe = to_iss_pipeline(me);
 	if (pipe->stream_state == ISS_PIPELINE_STREAM_STOPPED)
diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c
index 28efafa0621ef010..d1d91a79992a61bc 100644
--- a/drivers/staging/media/omap4iss/iss_video.c
+++ b/drivers/staging/media/omap4iss/iss_video.c
@@ -880,7 +880,7 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	 * Start streaming on the pipeline. No link touching an entity in the
 	 * pipeline can be activated or deactivated once streaming is started.
 	 */
-	pipe = pad->entity->pipe
+	pipe = pad->pipe
 	     ? to_iss_pipeline(pad->entity) : &video->pipe;
 	pipe->external = NULL;
 	pipe->external_rate = 0;
diff --git a/drivers/staging/media/omap4iss/iss_video.h b/drivers/staging/media/omap4iss/iss_video.h
index d7e05d04512c5176..8e57a92a622c4145 100644
--- a/drivers/staging/media/omap4iss/iss_video.h
+++ b/drivers/staging/media/omap4iss/iss_video.h
@@ -98,7 +98,7 @@ struct iss_pipeline {
 };
 
 #define to_iss_pipeline(__e) \
-	container_of((__e)->pipe, struct iss_pipeline, pipe)
+	container_of((__e)->pads->pipe, struct iss_pipeline, pipe)
 
 static inline int iss_pipeline_ready(struct iss_pipeline *pipe)
 {
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index fad1776cbaadbbab..4f68638153679a36 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -160,14 +160,24 @@ struct media_link {
  *
  * @graph_obj:	Embedded structure containing the media object common data
  * @entity:	Entity this pad belongs to
+ * @pipe:	Pipeline this entity belongs to.
+ * @stream_count: Stream count for the entity.
  * @index:	Pad index in the entity pads array, numbered from 0 to n
  * @flags:	Pad flags, as defined in
  *		:ref:`include/uapi/linux/media.h <media_header>`
  *		(seek for ``MEDIA_PAD_FL_*``)
+ * .. note::
+ *
+ *    @stream_count reference counts must never be negative, but are
+ *    signed integers on purpose: a simple ``WARN_ON(<0)`` check can
+ *    be used to detect reference count bugs that would make them
+ *    negative.
  */
 struct media_pad {
 	struct media_gobj graph_obj;	/* must be first field in struct */
 	struct media_entity *entity;
+	struct media_pipeline *pipe;
+	int stream_count;
 	u16 index;
 	unsigned long flags;
 };
@@ -244,9 +254,7 @@ enum media_entity_type {
  * @pads:	Pads array with the size defined by @num_pads.
  * @links:	List of data links.
  * @ops:	Entity operations.
- * @stream_count: Stream count for the entity.
  * @use_count:	Use count for the entity.
- * @pipe:	Pipeline this entity belongs to.
  * @info:	Union with devnode information.  Kept just for backward
  *		compatibility.
  * @info.dev:	Contains device major and minor info.
@@ -259,7 +267,7 @@ enum media_entity_type {
  *
  * .. note::
  *
- *    @stream_count and @use_count reference counts must never be
+ *    @use_count reference counts must never be
  *    negative, but are signed integers on purpose: a simple ``WARN_ON(<0)``
  *    check can be used to detect reference count bugs that would make them
  *    negative.
@@ -281,11 +289,8 @@ struct media_entity {
 
 	const struct media_entity_operations *ops;
 
-	int stream_count;
 	int use_count;
 
-	struct media_pipeline *pipe;
-
 	union {
 		struct {
 			u32 major;
-- 
2.18.0

  parent reply	other threads:[~2018-08-23 16:57 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-23 13:25 [PATCH 00/30] v4l: add support for multiplexed streams Niklas Söderlund
2018-08-23 13:25 ` [PATCH 01/30] media: entity: Use pad as a starting point for graph walk Niklas Söderlund
2018-08-23 13:25 ` [PATCH 02/30] media: entity: Use pads instead of entities in the media graph walk stack Niklas Söderlund
2018-08-23 13:25 ` [PATCH 03/30] media: entity: Walk the graph based on pads Niklas Söderlund
2018-08-23 13:25 ` [PATCH 04/30] v4l: mc: Start walk from a specific pad in use count calculation Niklas Söderlund
2018-08-23 13:25 ` Niklas Söderlund [this message]
2018-08-23 13:25 ` [PATCH 06/30] media: entity: Use pad as the starting point for a pipeline Niklas Söderlund
2018-08-23 13:25 ` [PATCH 07/30] media: entity: Add has_route entity operation Niklas Söderlund
2018-09-27 12:58   ` jacopo mondi
2018-08-23 13:25 ` [PATCH 08/30] media: entity: Add media_has_route() function Niklas Söderlund
2018-08-23 13:25 ` [PATCH 09/30] media: entity: Swap pads if route is checked from source to sink Niklas Söderlund
2018-08-23 13:25 ` [PATCH 10/30] media: entity: Use routing information during graph traversal Niklas Söderlund
2018-08-23 13:25 ` [PATCH 11/30] media: entity: Skip link validation for pads to which there is no route to Niklas Söderlund
2018-08-23 13:25 ` [PATCH 12/30] media: entity: Add an iterator helper for connected pads Niklas Söderlund
2018-08-23 13:25 ` [PATCH 13/30] media: entity: Add only connected pads to the pipeline Niklas Söderlund
2018-08-23 13:25 ` [PATCH 14/30] media: entity: Add debug information in graph walk route check Niklas Söderlund
2018-08-23 13:25 ` [PATCH 15/30] media: entity: Look for indirect routes Niklas Söderlund
2018-09-28 16:58   ` jacopo mondi
2018-08-23 13:25 ` [PATCH 16/30] v4l: subdev: Add [GS]_ROUTING subdev ioctls and operations Niklas Söderlund
2018-08-23 13:25 ` [PATCH 17/30] v4l: subdev: compat: Implement handling for VIDIOC_SUBDEV_[GS]_ROUTING Niklas Söderlund
2018-08-23 13:25 ` [PATCH 18/30] v4l: subdev: Take routing information into account in link validation Niklas Söderlund
2018-08-23 13:25 ` [PATCH 19/30] v4l: subdev: Improve link format validation debug messages Niklas Söderlund
2018-08-23 13:25 ` [PATCH 20/30] v4l: mc: Add an S_ROUTING helper function for power state changes Niklas Söderlund
2018-08-23 13:25 ` [PATCH 21/30] v4l: Add bus type to frame descriptors Niklas Söderlund
2018-11-02 12:27   ` Kieran Bingham
2018-11-02 13:15     ` Sakari Ailus
2018-11-02 13:15       ` Sakari Ailus
2018-11-02 13:35       ` Kieran Bingham
2018-11-02 14:18         ` Sakari Ailus
2018-11-02 14:18           ` Sakari Ailus
2018-11-02 14:40           ` Kieran Bingham
2018-08-23 13:25 ` [PATCH 22/30] v4l: Add CSI-2 bus configuration " Niklas Söderlund
2018-08-23 13:25 ` [PATCH 23/30] v4l: Add stream to frame descriptor Niklas Söderlund
2018-08-23 13:25 ` [PATCH 24/30] adv748x: csi2: add translation from pixelcode to CSI-2 datatype Niklas Söderlund
2018-08-23 13:25 ` [PATCH 25/30] adv748x: csi2: only allow formats on sink pads Niklas Söderlund
2018-08-23 13:25 ` [PATCH 26/30] adv748x: csi2: describe the multiplexed stream Niklas Söderlund
2018-08-23 13:25 ` [PATCH 27/30] adv748x: csi2: add internal routing configuration Niklas Söderlund
2018-08-23 13:25 ` [PATCH 28/30] adv748x: afe: add routing support Niklas Söderlund
2018-08-23 13:25 ` [PATCH 29/30] rcar-csi2: use frame description information to configure CSI-2 bus Niklas Söderlund
2018-09-24 14:39   ` Kieran Bingham
2018-09-26 14:23     ` Niklas Söderlund
2018-09-26 14:23       ` Niklas Söderlund
2018-08-23 13:25 ` [PATCH 30/30] rcar-csi2: expose the subdevice internal routing Niklas Söderlund
2018-08-27 11:50 ` [PATCH 00/30] v4l: add support for multiplexed streams Sakari Ailus
2018-08-27 11:50   ` Sakari Ailus
2018-08-27 13:11   ` Niklas Söderlund
2018-08-27 13:11     ` Niklas Söderlund

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180823132544.521-6-niklas.soderlund+renesas@ragnatech.se \
    --to=niklas.soderlund+renesas@ragnatech.se \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=linux-media@vger.kernel.org \
    --cc=linux-renesas-soc@vger.kernel.org \
    --cc=sakari.ailus@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.