All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 00/22] media: imx: Create media links in bound notifiers
@ 2020-05-01 17:15 Steve Longerbeam
  2020-05-01 17:15 ` [PATCH v6 01/22] media: entity: Pass entity to get_fwnode_pad operation Steve Longerbeam
                   ` (21 more replies)
  0 siblings, 22 replies; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

Move media link creation into the notifier bound callbacks in the
set of subdevices required by imx (imx5/6/7 CSI, imx6/7 MIPI CSI-2
receivers, and video-mux).

Rui, Laurent:

AFAICT the i.MX7 CSI can only ever connect to a CSI mux, which really
makes the function imx7_csi_get_upstream_endpoint() unnecessary. See
patches 17/22 and 18/22, and let me know if that makes sense.


History:

v6:
- Renamed v4l2_subdev_get_fwnode_pad_default() to
  v4l2_subdev_get_fwnode_pad_1_to_1().
- Instead of verifying the endpoint itself is owned by the subdevice,
  it's sufficient and more efficient to verify the endpoint's port parent
  is the subdevice, in v4l2_subdev_get_fwnode_pad_1_to_1().
  Suggested by Sakari.
- Dropped patch "media: entity: Modify default behavior of
  media_entity_get_fwnode_pad" again. It's not strictly needed for
  this patchset and can be revisited later.

v5:
- Revived patch "media: entity: Modify default behavior of
  media_entity_get_fwnode_pad" from v2.
- Added a v4l2_subdev_get_fwnode_pad_default, which can be used as
  a subdev's .get_fwnode_pad() operation if the subdev maps fwnode
  port id's and pad indexes 1:1. Used by video-mux, imx6/7 MIPI
  CSI-2 receivers, and imx7 CSI.
- Exported imx_media_create_fwnode_pad_link(s) to v4l2-core as
  v4l2_create_fwnode_links_to_pad() and v4l2_create_fwnode_links().
  Used by the video-mux, imx5/6/7 CSI's, and imx6/7 MIPI CSI-2
  receivers in their bound notifiers.
- Introduced a new group id IMX_MEDIA_GRP_ID_CSI_MUX, the imx6/7 CSI's
  will set the bound subdev grp_id to this if the bound subdev is a
  video mux.
- Removed imx7_csi_get_upstream_endpoint(), replacing with simpler
  code, see above.

v4:
- Removed the endpoint parsing callback APIs from video-mux and imx drivers
  as suggested by Sakari, replacing with endpoint parsing local to the
  drivers and the use of v4l2_async_notifier_add_fwnode_remote_subdev().
  As a result convenience function v4l2_async_register_fwnode_subdev()
  is no longer used and is reverted.

v3:
- The changes to the default behaviour in media_entity_get_fwnode_pad(),
  and the fixes to current media drivers that call it inconsistently, have
  been put-off to another time. Instead this version implements the
  get_fwnode_pad operation where required in the imx and video-mux
  subdevices to make media link creation work correctly. The
  improvements to media_entity_get_fwnode_pad() can wait to another
  patch series.

v2:
- rename/move the notifier-to-state inlines in imx7-mipi-csis.c and
  imx7-media-csi.c, suggested by Rui Silva.
- rewrite imx_media_create_links() to only add the missing media links
  from the imx6 MIPI CSI-2 receiver.


Steve Longerbeam (22):
  media: entity: Pass entity to get_fwnode_pad operation
  media: v4l2-subdev: add v4l2_subdev_get_fwnode_pad_1_to_1
  media: v4l2-mc: add v4l2_create_fwnode_links helpers
  media: video-mux: Parse information from firmware without using
    callbacks
  media: imx: Parse information from firmware without using callbacks
  Revert "media: v4l2-fwnode: Add a convenience function for registering
    subdevs with notifiers"
  media: imx: csi: Implement get_fwnode_pad op
  media: video-mux: Implement get_fwnode_pad op
  media: imx: mipi csi-2: Implement get_fwnode_pad op
  media: imx: imx7-mipi-csis: Implement get_fwnode_pad op
  media: imx: imx7-media-csi: Implement get_fwnode_pad op
  media: video-mux: Create media links in bound notifier
  media: imx: mipi csi-2: Create media links in bound notifier
  media: imx7: mipi csis: Create media links in bound notifier
  media: imx7: csi: Create media links in bound notifier
  media: imx: csi: Create media links in bound notifier
  media: imx7: csi: Remove imx7_csi_get_upstream_endpoint()
  media: imx5/6/7: csi: Mark a bound video mux as a CSI mux
  media: imx: csi: Lookup upstream endpoint with
    imx_media_get_pad_fwnode
  media: imx: Create missing links from CSI-2 receiver
  media: imx: silence a couple debug messages
  media: imx: TODO: Remove media link creation todos

 drivers/media/mc/mc-entity.c                  |   2 +-
 drivers/media/platform/video-mux.c            |  87 +++++++--
 drivers/media/v4l2-core/v4l2-fwnode.c         |  62 ------
 drivers/media/v4l2-core/v4l2-mc.c             |  95 +++++++++
 drivers/media/v4l2-core/v4l2-subdev.c         |  22 +++
 drivers/staging/media/imx/TODO                |  29 ---
 drivers/staging/media/imx/imx-media-csi.c     | 181 +++++++++++-------
 .../staging/media/imx/imx-media-dev-common.c  |  50 ++---
 drivers/staging/media/imx/imx-media-dev.c     |   2 +-
 .../staging/media/imx/imx-media-internal-sd.c |   6 +-
 drivers/staging/media/imx/imx-media-of.c      | 114 -----------
 drivers/staging/media/imx/imx-media-utils.c   |  33 ++++
 drivers/staging/media/imx/imx-media.h         |   6 +-
 drivers/staging/media/imx/imx6-mipi-csi2.c    |  93 +++++++--
 drivers/staging/media/imx/imx7-media-csi.c    | 160 +++++++++-------
 drivers/staging/media/imx/imx7-mipi-csis.c    | 107 ++++++++---
 include/media/media-entity.h                  |   3 +-
 include/media/v4l2-fwnode.h                   |  38 ----
 include/media/v4l2-mc.h                       |  48 +++++
 include/media/v4l2-subdev.h                   |  17 ++
 20 files changed, 660 insertions(+), 495 deletions(-)

-- 
2.17.1


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

* [PATCH v6 01/22] media: entity: Pass entity to get_fwnode_pad operation
  2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
@ 2020-05-01 17:15 ` Steve Longerbeam
  2020-05-01 17:15 ` [PATCH v6 02/22] media: v4l2-subdev: add v4l2_subdev_get_fwnode_pad_1_to_1 Steve Longerbeam
                   ` (20 subsequent siblings)
  21 siblings, 0 replies; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

Add a missing pointer to the entity in the media_entity operation
get_fwnode_pad. There are no implementers of this op yet, but a future
entity that does so will almost certainly need a reference to itself
to carry out the work.

Fixes: ae45cd5efc120 ("[media] media: entity: Add get_fwnode_pad entity
operation")
Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/media/mc/mc-entity.c | 2 +-
 include/media/media-entity.h | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c
index 211279c5fd77..12b45e669bcc 100644
--- a/drivers/media/mc/mc-entity.c
+++ b/drivers/media/mc/mc-entity.c
@@ -386,7 +386,7 @@ int media_entity_get_fwnode_pad(struct media_entity *entity,
 	if (ret)
 		return ret;
 
-	ret = entity->ops->get_fwnode_pad(&endpoint);
+	ret = entity->ops->get_fwnode_pad(entity, &endpoint);
 	if (ret < 0)
 		return ret;
 
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 8cb2c504a05c..cde80ad029b7 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -212,7 +212,8 @@ struct media_pad {
  *    mutex held.
  */
 struct media_entity_operations {
-	int (*get_fwnode_pad)(struct fwnode_endpoint *endpoint);
+	int (*get_fwnode_pad)(struct media_entity *entity,
+			      struct fwnode_endpoint *endpoint);
 	int (*link_setup)(struct media_entity *entity,
 			  const struct media_pad *local,
 			  const struct media_pad *remote, u32 flags);
-- 
2.17.1


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

* [PATCH v6 02/22] media: v4l2-subdev: add v4l2_subdev_get_fwnode_pad_1_to_1
  2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
  2020-05-01 17:15 ` [PATCH v6 01/22] media: entity: Pass entity to get_fwnode_pad operation Steve Longerbeam
@ 2020-05-01 17:15 ` Steve Longerbeam
  2020-05-01 17:15 ` [PATCH v6 03/22] media: v4l2-mc: add v4l2_create_fwnode_links helpers Steve Longerbeam
                   ` (19 subsequent siblings)
  21 siblings, 0 replies; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

Add a convenience function that can be used as the .get_fwnode_pad
operation for subdevices that map port numbers and pad indexes 1:1.
The function verifies the endpoint is owned by the subdevice, and if
so returns the endpoint port number.

Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
 drivers/media/v4l2-core/v4l2-subdev.c | 22 ++++++++++++++++++++++
 include/media/v4l2-subdev.h           | 17 +++++++++++++++++
 2 files changed, 39 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index a376b351135f..3bdda686341f 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -696,6 +696,28 @@ const struct v4l2_file_operations v4l2_subdev_fops = {
 };
 
 #ifdef CONFIG_MEDIA_CONTROLLER
+
+int v4l2_subdev_get_fwnode_pad_1_to_1(struct media_entity *entity,
+				      struct fwnode_endpoint *endpoint)
+{
+	struct fwnode_handle *fwnode;
+	struct v4l2_subdev *sd;
+
+	if (!is_media_entity_v4l2_subdev(entity))
+		return -EINVAL;
+
+	sd = media_entity_to_v4l2_subdev(entity);
+
+	fwnode = fwnode_graph_get_port_parent(endpoint->local_fwnode);
+	fwnode_handle_put(fwnode);
+
+	if (dev_fwnode(sd->dev) == fwnode)
+		return endpoint->port;
+
+	return -ENXIO;
+}
+EXPORT_SYMBOL_GPL(v4l2_subdev_get_fwnode_pad_1_to_1);
+
 int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd,
 				      struct media_link *link,
 				      struct v4l2_subdev_format *source_fmt,
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index a4848de59852..f7fe78a6f65a 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -1027,6 +1027,23 @@ static inline void *v4l2_get_subdev_hostdata(const struct v4l2_subdev *sd)
 
 #ifdef CONFIG_MEDIA_CONTROLLER
 
+/**
+ * v4l2_subdev_get_fwnode_pad_1_to_1 - Get pad number from a subdev fwnode
+ *                                     endpoint, assuming 1:1 port:pad
+ *
+ * @entity - Pointer to the subdev entity
+ * @endpoint - Pointer to a parsed fwnode endpoint
+ *
+ * This function can be used as the .get_fwnode_pad operation for
+ * subdevices that map port numbers and pad indexes 1:1. If the endpoint
+ * is owned by the subdevice, the function returns the endpoint port
+ * number.
+ *
+ * Returns the endpoint port number on success or a negative error code.
+ */
+int v4l2_subdev_get_fwnode_pad_1_to_1(struct media_entity *entity,
+				      struct fwnode_endpoint *endpoint);
+
 /**
  * v4l2_subdev_link_validate_default - validates a media link
  *
-- 
2.17.1


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

* [PATCH v6 03/22] media: v4l2-mc: add v4l2_create_fwnode_links helpers
  2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
  2020-05-01 17:15 ` [PATCH v6 01/22] media: entity: Pass entity to get_fwnode_pad operation Steve Longerbeam
  2020-05-01 17:15 ` [PATCH v6 02/22] media: v4l2-subdev: add v4l2_subdev_get_fwnode_pad_1_to_1 Steve Longerbeam
@ 2020-05-01 17:15 ` Steve Longerbeam
  2020-05-01 17:15 ` [PATCH v6 04/22] media: video-mux: Parse information from firmware without using callbacks Steve Longerbeam
                   ` (18 subsequent siblings)
  21 siblings, 0 replies; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

Add functions to create media links between source and sink subdevices,
based on the fwnode endpoint connections between them:

v4l2_create_fwnode_links_to_pad() - create links from a source subdev to
                                    a single sink pad based on fwnode
                                    endpoint connections.

v4l2_create_fwnode_links() - create all links from a source to sink subdev
                             based on fwnode endpoint connections.

These functions can be used in a sink's v4l2-async notifier subdev
bound callback to make the links from the bound subdev.

Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
 drivers/media/v4l2-core/v4l2-mc.c | 95 +++++++++++++++++++++++++++++++
 include/media/v4l2-mc.h           | 48 ++++++++++++++++
 2 files changed, 143 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-mc.c b/drivers/media/v4l2-core/v4l2-mc.c
index 0fffdd3ce6a4..ba2f2b8dcc8c 100644
--- a/drivers/media/v4l2-core/v4l2-mc.c
+++ b/drivers/media/v4l2-core/v4l2-mc.c
@@ -309,6 +309,101 @@ int v4l_vb2q_enable_media_source(struct vb2_queue *q)
 }
 EXPORT_SYMBOL_GPL(v4l_vb2q_enable_media_source);
 
+int v4l2_create_fwnode_links_to_pad(struct v4l2_subdev *src_sd,
+				    struct media_pad *sink)
+{
+	struct fwnode_handle *endpoint;
+	struct v4l2_subdev *sink_sd;
+
+	if (!(sink->flags & MEDIA_PAD_FL_SINK) ||
+	    !is_media_entity_v4l2_subdev(sink->entity))
+		return -EINVAL;
+
+	sink_sd = media_entity_to_v4l2_subdev(sink->entity);
+
+	fwnode_graph_for_each_endpoint(dev_fwnode(src_sd->dev), endpoint) {
+		struct fwnode_handle *remote_ep;
+		int src_idx, sink_idx, ret;
+		struct media_pad *src;
+
+		src_idx = media_entity_get_fwnode_pad(&src_sd->entity,
+						      endpoint,
+						      MEDIA_PAD_FL_SOURCE);
+		if (src_idx < 0)
+			continue;
+
+		remote_ep = fwnode_graph_get_remote_endpoint(endpoint);
+		if (!remote_ep)
+			continue;
+
+		/*
+		 * ask the sink to verify it owns the remote endpoint,
+		 * and translate to a sink pad.
+		 */
+		sink_idx = media_entity_get_fwnode_pad(&sink_sd->entity,
+						       remote_ep,
+						       MEDIA_PAD_FL_SINK);
+		fwnode_handle_put(remote_ep);
+
+		if (sink_idx < 0 || sink_idx != sink->index)
+			continue;
+
+		/*
+		 * the source endpoint corresponds to one of its source pads,
+		 * the source endpoint connects to an endpoint at the sink
+		 * entity, and the sink endpoint corresponds to the sink
+		 * pad requested, so we have found an endpoint connection
+		 * that works, create the media link for it.
+		 */
+
+		src = &src_sd->entity.pads[src_idx];
+
+		/* skip if link already exists */
+		if (media_entity_find_link(src, sink))
+			continue;
+
+		dev_dbg(sink_sd->dev, "creating link %s:%d -> %s:%d\n",
+			src_sd->entity.name, src_idx,
+			sink_sd->entity.name, sink_idx);
+
+		ret = media_create_pad_link(&src_sd->entity, src_idx,
+					    &sink_sd->entity, sink_idx, 0);
+		if (ret) {
+			dev_err(sink_sd->dev,
+				"link %s:%d -> %s:%d failed with %d\n",
+				src_sd->entity.name, src_idx,
+				sink_sd->entity.name, sink_idx, ret);
+
+			fwnode_handle_put(endpoint);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_create_fwnode_links_to_pad);
+
+int v4l2_create_fwnode_links(struct v4l2_subdev *src_sd,
+			     struct v4l2_subdev *sink_sd)
+{
+	unsigned int i;
+
+	for (i = 0; i < sink_sd->entity.num_pads; i++) {
+		struct media_pad *pad = &sink_sd->entity.pads[i];
+		int ret;
+
+		if (!(pad->flags & MEDIA_PAD_FL_SINK))
+			continue;
+
+		ret = v4l2_create_fwnode_links_to_pad(src_sd, pad);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_create_fwnode_links);
+
 /* -----------------------------------------------------------------------------
  * Pipeline power management
  *
diff --git a/include/media/v4l2-mc.h b/include/media/v4l2-mc.h
index 5e73eb8e28f6..246eed398648 100644
--- a/include/media/v4l2-mc.h
+++ b/include/media/v4l2-mc.h
@@ -12,6 +12,7 @@
 
 #include <media/media-device.h>
 #include <media/v4l2-dev.h>
+#include <media/v4l2-subdev.h>
 #include <linux/types.h>
 
 /* We don't need to include pci.h or usb.h here */
@@ -84,6 +85,53 @@ void v4l_disable_media_source(struct video_device *vdev);
  */
 int v4l_vb2q_enable_media_source(struct vb2_queue *q);
 
+/**
+ * v4l2_create_fwnode_links_to_pad - Create fwnode-based links from a
+ *                                   source subdev to a sink subdev pad.
+ *
+ * @src_sd - pointer to a source subdev
+ * @sink - pointer to a subdev sink pad
+ *
+ * This function searches for fwnode endpoint connections from a source
+ * subdevice to a single sink pad, and if suitable connections are found,
+ * translates them into media links to that pad. The function can be
+ * called by the sink subdevice, in its v4l2-async notifier subdev bound
+ * callback, to create links from a bound source subdevice.
+ *
+ * .. note::
+ *
+ *    Any sink subdevice that calls this function must implement the
+ *    .get_fwnode_pad media operation in order to verify endpoints passed
+ *    to the sink are owned by the sink.
+ *
+ * Return 0 on success or a negative error code on failure.
+ */
+int v4l2_create_fwnode_links_to_pad(struct v4l2_subdev *src_sd,
+				    struct media_pad *sink);
+
+/**
+ * v4l2_create_fwnode_links - Create fwnode-based links from a source
+ *                            subdev to a sink subdev.
+ *
+ * @src_sd - pointer to a source subdevice
+ * @sink_sd - pointer to a sink subdevice
+ *
+ * This function searches for any and all fwnode endpoint connections
+ * between source and sink subdevices, and translates them into media
+ * links. The function can be called by the sink subdevice, in its
+ * v4l2-async notifier subdev bound callback, to create all links from
+ * a bound source subdevice.
+ *
+ * .. note::
+ *
+ *    Any sink subdevice that calls this function must implement the
+ *    .get_fwnode_pad media operation in order to verify endpoints passed
+ *    to the sink are owned by the sink.
+ *
+ * Return 0 on success or a negative error code on failure.
+ */
+int v4l2_create_fwnode_links(struct v4l2_subdev *src_sd,
+			     struct v4l2_subdev *sink_sd);
 
 /**
  * v4l2_pipeline_pm_get - Increase the use count of a pipeline
-- 
2.17.1


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

* [PATCH v6 04/22] media: video-mux: Parse information from firmware without using callbacks
  2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
                   ` (2 preceding siblings ...)
  2020-05-01 17:15 ` [PATCH v6 03/22] media: v4l2-mc: add v4l2_create_fwnode_links helpers Steve Longerbeam
@ 2020-05-01 17:15 ` Steve Longerbeam
  2020-05-01 17:15 ` [PATCH v6 05/22] media: imx: " Steve Longerbeam
                   ` (17 subsequent siblings)
  21 siblings, 0 replies; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

Instead of using the convenience function
v4l2_async_register_fwnode_subdev(), parse the video-mux input endpoints
and set up the async sub-devices without using callbacks. The video-mux
knows which ports it must parse (the input ports) and how to handle
unconnected remotes, so it makes the code simpler to transfer control
of endpoint parsing to the driver.

Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
 drivers/media/platform/video-mux.c | 70 ++++++++++++++++++++----------
 1 file changed, 46 insertions(+), 24 deletions(-)

diff --git a/drivers/media/platform/video-mux.c b/drivers/media/platform/video-mux.c
index ddd0e338f9e4..7b6c96a29aa5 100644
--- a/drivers/media/platform/video-mux.c
+++ b/drivers/media/platform/video-mux.c
@@ -21,6 +21,7 @@
 
 struct video_mux {
 	struct v4l2_subdev subdev;
+	struct v4l2_async_notifier notifier;
 	struct media_pad *pads;
 	struct v4l2_mbus_framefmt *format_mbus;
 	struct mux_control *mux;
@@ -330,36 +331,49 @@ static const struct v4l2_subdev_ops video_mux_subdev_ops = {
 	.video = &video_mux_subdev_video_ops,
 };
 
-static int video_mux_parse_endpoint(struct device *dev,
-				    struct v4l2_fwnode_endpoint *vep,
-				    struct v4l2_async_subdev *asd)
-{
-	/*
-	 * it's not an error if remote is missing on a video-mux
-	 * input port, return -ENOTCONN to skip this endpoint with
-	 * no error.
-	 */
-	return fwnode_device_is_available(asd->match.fwnode) ? 0 : -ENOTCONN;
-}
-
 static int video_mux_async_register(struct video_mux *vmux,
 				    unsigned int num_input_pads)
 {
-	unsigned int i, *ports;
+	unsigned int i;
 	int ret;
 
-	ports = kcalloc(num_input_pads, sizeof(*ports), GFP_KERNEL);
-	if (!ports)
-		return -ENOMEM;
-	for (i = 0; i < num_input_pads; i++)
-		ports[i] = i;
+	v4l2_async_notifier_init(&vmux->notifier);
 
-	ret = v4l2_async_register_fwnode_subdev(
-		&vmux->subdev, sizeof(struct v4l2_async_subdev),
-		ports, num_input_pads, video_mux_parse_endpoint);
+	for (i = 0; i < num_input_pads; i++) {
+		struct v4l2_async_subdev *asd;
+		struct fwnode_handle *ep;
 
-	kfree(ports);
-	return ret;
+		ep = fwnode_graph_get_endpoint_by_id(
+			dev_fwnode(vmux->subdev.dev), i, 0,
+			FWNODE_GRAPH_ENDPOINT_NEXT);
+		if (!ep)
+			continue;
+
+		asd = kzalloc(sizeof(*asd), GFP_KERNEL);
+		if (!asd) {
+			fwnode_handle_put(ep);
+			return -ENOMEM;
+		}
+
+		ret = v4l2_async_notifier_add_fwnode_remote_subdev(
+			&vmux->notifier, ep, asd);
+
+		fwnode_handle_put(ep);
+
+		if (ret) {
+			kfree(asd);
+			/* OK if asd already exists */
+			if (ret != -EEXIST)
+				return ret;
+		}
+	}
+
+	ret = v4l2_async_subdev_notifier_register(&vmux->subdev,
+						  &vmux->notifier);
+	if (ret)
+		return ret;
+
+	return v4l2_async_register_subdev(&vmux->subdev);
 }
 
 static int video_mux_probe(struct platform_device *pdev)
@@ -434,7 +448,13 @@ static int video_mux_probe(struct platform_device *pdev)
 
 	vmux->subdev.entity.ops = &video_mux_ops;
 
-	return video_mux_async_register(vmux, num_pads - 1);
+	ret = video_mux_async_register(vmux, num_pads - 1);
+	if (ret) {
+		v4l2_async_notifier_unregister(&vmux->notifier);
+		v4l2_async_notifier_cleanup(&vmux->notifier);
+	}
+
+	return ret;
 }
 
 static int video_mux_remove(struct platform_device *pdev)
@@ -442,6 +462,8 @@ static int video_mux_remove(struct platform_device *pdev)
 	struct video_mux *vmux = platform_get_drvdata(pdev);
 	struct v4l2_subdev *sd = &vmux->subdev;
 
+	v4l2_async_notifier_unregister(&vmux->notifier);
+	v4l2_async_notifier_cleanup(&vmux->notifier);
 	v4l2_async_unregister_subdev(sd);
 	media_entity_cleanup(&sd->entity);
 
-- 
2.17.1


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

* [PATCH v6 05/22] media: imx: Parse information from firmware without using callbacks
  2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
                   ` (3 preceding siblings ...)
  2020-05-01 17:15 ` [PATCH v6 04/22] media: video-mux: Parse information from firmware without using callbacks Steve Longerbeam
@ 2020-05-01 17:15 ` Steve Longerbeam
  2020-05-01 17:15 ` [PATCH v6 06/22] Revert "media: v4l2-fwnode: Add a convenience function for registering subdevs with notifiers" Steve Longerbeam
                   ` (16 subsequent siblings)
  21 siblings, 0 replies; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

Instead of using the convenience functions
v4l2_async_notifier_parse_fwnode_endpoints*() or
v4l2_async_register_fwnode_subdev(), parse the input endpoints
and set up the async sub-devices without using callbacks. The drivers
know which ports it must parse and how to handle unconnected remotes,
so it makes the code simpler to transfer control of endpoint parsing
to the driver.

Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
 drivers/staging/media/imx/imx-media-csi.c  | 78 +++++++++----------
 drivers/staging/media/imx/imx6-mipi-csi2.c | 70 ++++++++++++-----
 drivers/staging/media/imx/imx7-media-csi.c | 53 ++++++++++---
 drivers/staging/media/imx/imx7-mipi-csis.c | 91 +++++++++++++++-------
 4 files changed, 192 insertions(+), 100 deletions(-)

diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c
index 66468326bcbc..905b1ee27db6 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -58,6 +58,8 @@ struct csi_priv {
 	struct ipu_soc *ipu;
 	struct v4l2_subdev sd;
 	struct media_pad pad[CSI_NUM_PADS];
+	struct v4l2_async_notifier notifier;
+
 	/* the video device at IDMAC output pad */
 	struct imx_media_video_dev *vdev;
 	struct imx_media_fim *fim;
@@ -1869,59 +1871,49 @@ static const struct v4l2_subdev_internal_ops csi_internal_ops = {
 	.unregistered = csi_unregistered,
 };
 
-static int imx_csi_parse_endpoint(struct device *dev,
-				  struct v4l2_fwnode_endpoint *vep,
-				  struct v4l2_async_subdev *asd)
-{
-	return fwnode_device_is_available(asd->match.fwnode) ? 0 : -ENOTCONN;
-}
-
 static int imx_csi_async_register(struct csi_priv *priv)
 {
-	struct v4l2_async_notifier *notifier;
-	struct fwnode_handle *fwnode;
+	struct v4l2_async_subdev *asd = NULL;
+	struct fwnode_handle *ep;
 	unsigned int port;
 	int ret;
 
-	notifier = kzalloc(sizeof(*notifier), GFP_KERNEL);
-	if (!notifier)
-		return -ENOMEM;
-
-	v4l2_async_notifier_init(notifier);
-
-	fwnode = dev_fwnode(priv->dev);
+	v4l2_async_notifier_init(&priv->notifier);
 
 	/* get this CSI's port id */
-	ret = fwnode_property_read_u32(fwnode, "reg", &port);
-	if (ret < 0)
-		goto out_free;
-
-	ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(
-		priv->dev->parent, notifier, sizeof(struct v4l2_async_subdev),
-		port, imx_csi_parse_endpoint);
+	ret = fwnode_property_read_u32(dev_fwnode(priv->dev), "reg", &port);
 	if (ret < 0)
-		goto out_cleanup;
+		return ret;
 
-	ret = v4l2_async_subdev_notifier_register(&priv->sd, notifier);
-	if (ret < 0)
-		goto out_cleanup;
+	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(priv->dev->parent),
+					     port, 0,
+					     FWNODE_GRAPH_ENDPOINT_NEXT);
+	if (ep) {
+		asd = kzalloc(sizeof(*asd), GFP_KERNEL);
+		if (!asd) {
+			fwnode_handle_put(ep);
+			return -ENOMEM;
+		}
 
-	ret = v4l2_async_register_subdev(&priv->sd);
-	if (ret < 0)
-		goto out_unregister;
+		ret = v4l2_async_notifier_add_fwnode_remote_subdev(
+			&priv->notifier, ep, asd);
 
-	priv->sd.subdev_notifier = notifier;
+		fwnode_handle_put(ep);
 
-	return 0;
+		if (ret) {
+			kfree(asd);
+			/* OK if asd already exists */
+			if (ret != -EEXIST)
+				return ret;
+		}
+	}
 
-out_unregister:
-	v4l2_async_notifier_unregister(notifier);
-out_cleanup:
-	v4l2_async_notifier_cleanup(notifier);
-out_free:
-	kfree(notifier);
+	ret = v4l2_async_subdev_notifier_register(&priv->sd,
+						  &priv->notifier);
+	if (ret)
+		return ret;
 
-	return ret;
+	return v4l2_async_register_subdev(&priv->sd);
 }
 
 static int imx_csi_probe(struct platform_device *pdev)
@@ -2001,9 +1993,13 @@ static int imx_csi_probe(struct platform_device *pdev)
 
 	ret = imx_csi_async_register(priv);
 	if (ret)
-		goto free;
+		goto cleanup;
 
 	return 0;
+
+cleanup:
+	v4l2_async_notifier_unregister(&priv->notifier);
+	v4l2_async_notifier_cleanup(&priv->notifier);
 free:
 	v4l2_ctrl_handler_free(&priv->ctrl_hdlr);
 	mutex_destroy(&priv->lock);
@@ -2017,6 +2013,8 @@ static int imx_csi_remove(struct platform_device *pdev)
 
 	v4l2_ctrl_handler_free(&priv->ctrl_hdlr);
 	mutex_destroy(&priv->lock);
+	v4l2_async_notifier_unregister(&priv->notifier);
+	v4l2_async_notifier_cleanup(&priv->notifier);
 	v4l2_async_unregister_subdev(sd);
 	media_entity_cleanup(&sd->entity);
 
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 8ab823042c09..332d77aec8aa 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -35,6 +35,7 @@
 struct csi2_dev {
 	struct device          *dev;
 	struct v4l2_subdev      sd;
+	struct v4l2_async_notifier notifier;
 	struct media_pad       pad[CSI2_NUM_PADS];
 	struct clk             *dphy_clk;
 	struct clk             *pllref_clk;
@@ -530,34 +531,59 @@ static const struct v4l2_subdev_internal_ops csi2_internal_ops = {
 	.registered = csi2_registered,
 };
 
-static int csi2_parse_endpoint(struct device *dev,
-			       struct v4l2_fwnode_endpoint *vep,
-			       struct v4l2_async_subdev *asd)
+static int csi2_async_register(struct csi2_dev *csi2)
 {
-	struct v4l2_subdev *sd = dev_get_drvdata(dev);
-	struct csi2_dev *csi2 = sd_to_dev(sd);
+	struct v4l2_fwnode_endpoint vep = {
+		.bus_type = V4L2_MBUS_CSI2_DPHY,
+	};
+	struct v4l2_async_subdev *asd = NULL;
+	struct fwnode_handle *ep;
+	int ret;
 
-	if (!fwnode_device_is_available(asd->match.fwnode)) {
-		v4l2_err(&csi2->sd, "remote is not available\n");
-		return -EINVAL;
-	}
+	v4l2_async_notifier_init(&csi2->notifier);
 
-	if (vep->bus_type != V4L2_MBUS_CSI2_DPHY) {
-		v4l2_err(&csi2->sd, "invalid bus type, must be MIPI CSI2\n");
-		return -EINVAL;
-	}
+	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi2->dev), 0, 0,
+					     FWNODE_GRAPH_ENDPOINT_NEXT);
+	if (!ep)
+		return -ENOTCONN;
+
+	ret = v4l2_fwnode_endpoint_parse(ep, &vep);
+	if (ret)
+		goto err_parse;
 
-	csi2->bus = vep->bus.mipi_csi2;
+	csi2->bus = vep.bus.mipi_csi2;
 
 	dev_dbg(csi2->dev, "data lanes: %d\n", csi2->bus.num_data_lanes);
 	dev_dbg(csi2->dev, "flags: 0x%08x\n", csi2->bus.flags);
 
-	return 0;
+	asd = kzalloc(sizeof(*asd), GFP_KERNEL);
+	if (!asd) {
+		ret = -ENOMEM;
+		goto err_parse;
+	}
+
+	ret = v4l2_async_notifier_add_fwnode_remote_subdev(
+		&csi2->notifier, ep, asd);
+	if (ret)
+		goto err_parse;
+
+	fwnode_handle_put(ep);
+
+	ret = v4l2_async_subdev_notifier_register(&csi2->sd,
+						  &csi2->notifier);
+	if (ret)
+		return ret;
+
+	return v4l2_async_register_subdev(&csi2->sd);
+
+err_parse:
+	fwnode_handle_put(ep);
+	kfree(asd);
+	return ret;
 }
 
 static int csi2_probe(struct platform_device *pdev)
 {
-	unsigned int sink_port = 0;
 	struct csi2_dev *csi2;
 	struct resource *res;
 	int i, ret;
@@ -633,15 +659,15 @@ static int csi2_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, &csi2->sd);
 
-	ret = v4l2_async_register_fwnode_subdev(
-		&csi2->sd, sizeof(struct v4l2_async_subdev),
-		&sink_port, 1, csi2_parse_endpoint);
+	ret = csi2_async_register(csi2);
 	if (ret)
-		goto dphy_off;
+		goto clean_notifier;
 
 	return 0;
 
-dphy_off:
+clean_notifier:
+	v4l2_async_notifier_unregister(&csi2->notifier);
+	v4l2_async_notifier_cleanup(&csi2->notifier);
 	clk_disable_unprepare(csi2->dphy_clk);
 pllref_off:
 	clk_disable_unprepare(csi2->pllref_clk);
@@ -655,6 +681,8 @@ static int csi2_remove(struct platform_device *pdev)
 	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
 	struct csi2_dev *csi2 = sd_to_dev(sd);
 
+	v4l2_async_notifier_unregister(&csi2->notifier);
+	v4l2_async_notifier_cleanup(&csi2->notifier);
 	v4l2_async_unregister_subdev(sd);
 	clk_disable_unprepare(csi2->dphy_clk);
 	clk_disable_unprepare(csi2->pllref_clk);
diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c
index 1ac10f807ac0..abef59dc22b6 100644
--- a/drivers/staging/media/imx/imx7-media-csi.c
+++ b/drivers/staging/media/imx/imx7-media-csi.c
@@ -155,6 +155,7 @@
 struct imx7_csi {
 	struct device *dev;
 	struct v4l2_subdev sd;
+	struct v4l2_async_notifier notifier;
 	struct imx_media_video_dev *vdev;
 	struct imx_media_dev *imxmd;
 	struct media_pad pad[IMX7_CSI_PADS_NUM];
@@ -1202,11 +1203,41 @@ static const struct v4l2_subdev_internal_ops imx7_csi_internal_ops = {
 	.unregistered	= imx7_csi_unregistered,
 };
 
-static int imx7_csi_parse_endpoint(struct device *dev,
-				   struct v4l2_fwnode_endpoint *vep,
-				   struct v4l2_async_subdev *asd)
+static int imx7_csi_async_register(struct imx7_csi *csi)
 {
-	return fwnode_device_is_available(asd->match.fwnode) ? 0 : -EINVAL;
+	struct v4l2_async_subdev *asd = NULL;
+	struct fwnode_handle *ep;
+	int ret;
+
+	v4l2_async_notifier_init(&csi->notifier);
+
+	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi->dev), 0, 0,
+					     FWNODE_GRAPH_ENDPOINT_NEXT);
+	if (ep) {
+		asd = kzalloc(sizeof(*asd), GFP_KERNEL);
+		if (!asd) {
+			fwnode_handle_put(ep);
+			return -ENOMEM;
+		}
+
+		ret = v4l2_async_notifier_add_fwnode_remote_subdev(
+			&csi->notifier, ep, asd);
+
+		fwnode_handle_put(ep);
+
+		if (ret) {
+			kfree(asd);
+			/* OK if asd already exists */
+			if (ret != -EEXIST)
+				return ret;
+		}
+	}
+
+	ret = v4l2_async_subdev_notifier_register(&csi->sd, &csi->notifier);
+	if (ret)
+		return ret;
+
+	return v4l2_async_register_subdev(&csi->sd);
 }
 
 static int imx7_csi_probe(struct platform_device *pdev)
@@ -1289,19 +1320,21 @@ static int imx7_csi_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto free;
 
-	ret = v4l2_async_register_fwnode_subdev(&csi->sd,
-						sizeof(struct v4l2_async_subdev),
-						NULL, 0,
-						imx7_csi_parse_endpoint);
+	ret = imx7_csi_async_register(csi);
 	if (ret)
-		goto free;
+		goto subdev_notifier_cleanup;
 
 	return 0;
 
+subdev_notifier_cleanup:
+	v4l2_async_notifier_unregister(&csi->notifier);
+	v4l2_async_notifier_cleanup(&csi->notifier);
+
 free:
 	v4l2_ctrl_handler_free(&csi->ctrl_hdlr);
 
 cleanup:
+	v4l2_async_notifier_unregister(&imxmd->notifier);
 	v4l2_async_notifier_cleanup(&imxmd->notifier);
 	v4l2_device_unregister(&imxmd->v4l2_dev);
 	media_device_unregister(&imxmd->md);
@@ -1326,6 +1359,8 @@ static int imx7_csi_remove(struct platform_device *pdev)
 	v4l2_device_unregister(&imxmd->v4l2_dev);
 	media_device_cleanup(&imxmd->md);
 
+	v4l2_async_notifier_unregister(&csi->notifier);
+	v4l2_async_notifier_cleanup(&csi->notifier);
 	v4l2_async_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&csi->ctrl_hdlr);
 
diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c
index e2403b448b6d..b66299c1136d 100644
--- a/drivers/staging/media/imx/imx7-mipi-csis.c
+++ b/drivers/staging/media/imx/imx7-mipi-csis.c
@@ -221,6 +221,7 @@ struct csi_state {
 	struct device *dev;
 	struct media_pad pads[CSIS_PADS_NUM];
 	struct v4l2_subdev mipi_sd;
+	struct v4l2_async_notifier notifier;
 	struct v4l2_subdev *src_sd;
 
 	u8 index;
@@ -946,33 +947,11 @@ static int mipi_csis_parse_dt(struct platform_device *pdev,
 
 static int mipi_csis_pm_resume(struct device *dev, bool runtime);
 
-static int mipi_csis_parse_endpoint(struct device *dev,
-				    struct v4l2_fwnode_endpoint *ep,
-				    struct v4l2_async_subdev *asd)
-{
-	struct v4l2_subdev *mipi_sd = dev_get_drvdata(dev);
-	struct csi_state *state = mipi_sd_to_csis_state(mipi_sd);
-
-	if (ep->bus_type != V4L2_MBUS_CSI2_DPHY) {
-		dev_err(dev, "invalid bus type, must be MIPI CSI2\n");
-		return -EINVAL;
-	}
-
-	state->bus = ep->bus.mipi_csi2;
-
-	dev_dbg(state->dev, "data lanes: %d\n", state->bus.num_data_lanes);
-	dev_dbg(state->dev, "flags: 0x%08x\n", state->bus.flags);
-
-	return 0;
-}
-
 static int mipi_csis_subdev_init(struct v4l2_subdev *mipi_sd,
 				 struct platform_device *pdev,
 				 const struct v4l2_subdev_ops *ops)
 {
 	struct csi_state *state = mipi_sd_to_csis_state(mipi_sd);
-	unsigned int sink_port = 0;
-	int ret;
 
 	v4l2_subdev_init(mipi_sd, ops);
 	mipi_sd->owner = THIS_MODULE;
@@ -994,17 +973,58 @@ static int mipi_csis_subdev_init(struct v4l2_subdev *mipi_sd,
 
 	state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
 	state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
-	ret = media_entity_pads_init(&mipi_sd->entity, CSIS_PADS_NUM,
-				     state->pads);
+	return media_entity_pads_init(&mipi_sd->entity, CSIS_PADS_NUM,
+				      state->pads);
+}
+
+static int mipi_csis_async_register(struct csi_state *state)
+{
+	struct v4l2_fwnode_endpoint vep = {
+		.bus_type = V4L2_MBUS_CSI2_DPHY,
+	};
+	struct v4l2_async_subdev *asd = NULL;
+	struct fwnode_handle *ep;
+	int ret;
+
+	v4l2_async_notifier_init(&state->notifier);
+
+	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(state->dev), 0, 0,
+					     FWNODE_GRAPH_ENDPOINT_NEXT);
+	if (!ep)
+		return -ENOTCONN;
+
+	ret = v4l2_fwnode_endpoint_parse(ep, &vep);
+	if (ret)
+		goto err_parse;
+
+	state->bus = vep.bus.mipi_csi2;
+
+	dev_dbg(state->dev, "data lanes: %d\n", state->bus.num_data_lanes);
+	dev_dbg(state->dev, "flags: 0x%08x\n", state->bus.flags);
+
+	asd = kzalloc(sizeof(*asd), GFP_KERNEL);
+	if (!asd) {
+		ret = -ENOMEM;
+		goto err_parse;
+	}
+
+	ret = v4l2_async_notifier_add_fwnode_remote_subdev(
+		&state->notifier, ep, asd);
+	if (ret)
+		goto err_parse;
+
+	fwnode_handle_put(ep);
+
+	ret = v4l2_async_subdev_notifier_register(&state->mipi_sd,
+						  &state->notifier);
 	if (ret)
 		return ret;
 
-	ret = v4l2_async_register_fwnode_subdev(mipi_sd,
-						sizeof(struct v4l2_async_subdev),
-						&sink_port, 1,
-						mipi_csis_parse_endpoint);
-	if (ret < 0)
-		dev_err(&pdev->dev, "async fwnode register failed: %d\n", ret);
+	return v4l2_async_register_subdev(&state->mipi_sd);
+
+err_parse:
+	fwnode_handle_put(ep);
+	kfree(asd);
 
 	return ret;
 }
@@ -1111,6 +1131,12 @@ static int mipi_csis_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto disable_clock;
 
+	ret = mipi_csis_async_register(state);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "async register failed: %d\n", ret);
+		goto cleanup;
+	}
+
 	memcpy(state->events, mipi_csis_events, sizeof(state->events));
 
 	mipi_csis_debugfs_init(state);
@@ -1129,7 +1155,10 @@ static int mipi_csis_probe(struct platform_device *pdev)
 
 unregister_all:
 	mipi_csis_debugfs_exit(state);
+cleanup:
 	media_entity_cleanup(&state->mipi_sd.entity);
+	v4l2_async_notifier_unregister(&state->notifier);
+	v4l2_async_notifier_cleanup(&state->notifier);
 	v4l2_async_unregister_subdev(&state->mipi_sd);
 disable_clock:
 	mipi_csis_clk_disable(state);
@@ -1217,6 +1246,8 @@ static int mipi_csis_remove(struct platform_device *pdev)
 	struct csi_state *state = mipi_sd_to_csis_state(mipi_sd);
 
 	mipi_csis_debugfs_exit(state);
+	v4l2_async_notifier_unregister(&state->notifier);
+	v4l2_async_notifier_cleanup(&state->notifier);
 	v4l2_async_unregister_subdev(&state->mipi_sd);
 
 	pm_runtime_disable(&pdev->dev);
-- 
2.17.1


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

* [PATCH v6 06/22] Revert "media: v4l2-fwnode: Add a convenience function for registering subdevs with notifiers"
  2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
                   ` (4 preceding siblings ...)
  2020-05-01 17:15 ` [PATCH v6 05/22] media: imx: " Steve Longerbeam
@ 2020-05-01 17:15 ` Steve Longerbeam
  2020-05-01 17:15 ` [PATCH v6 07/22] media: imx: csi: Implement get_fwnode_pad op Steve Longerbeam
                   ` (15 subsequent siblings)
  21 siblings, 0 replies; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

The users of v4l2_async_register_fwnode_subdev() have switched to
parsing their endpoints and setting up async sub-device lists in their
notifiers locally, without using the endpoint parsing callbacks. There
are no more users of v4l2_async_register_fwnode_subdev() so this
convenience function can be removed.

This reverts commit 1634f0eded87d1f150e823fa56cd782ea0775eb2.

Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
 drivers/media/v4l2-core/v4l2-fwnode.c | 62 ---------------------------
 include/media/v4l2-fwnode.h           | 38 ----------------
 2 files changed, 100 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
index 97f0f8b23b5d..e1f273ae8522 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -1323,68 +1323,6 @@ int v4l2_async_register_subdev_sensor_common(struct v4l2_subdev *sd)
 }
 EXPORT_SYMBOL_GPL(v4l2_async_register_subdev_sensor_common);
 
-int v4l2_async_register_fwnode_subdev(struct v4l2_subdev *sd,
-				      size_t asd_struct_size,
-				      unsigned int *ports,
-				      unsigned int num_ports,
-				      parse_endpoint_func parse_endpoint)
-{
-	struct v4l2_async_notifier *notifier;
-	struct device *dev = sd->dev;
-	struct fwnode_handle *fwnode;
-	int ret;
-
-	if (WARN_ON(!dev))
-		return -ENODEV;
-
-	fwnode = dev_fwnode(dev);
-	if (!fwnode_device_is_available(fwnode))
-		return -ENODEV;
-
-	notifier = kzalloc(sizeof(*notifier), GFP_KERNEL);
-	if (!notifier)
-		return -ENOMEM;
-
-	v4l2_async_notifier_init(notifier);
-
-	if (!ports) {
-		ret = v4l2_async_notifier_parse_fwnode_endpoints(dev, notifier,
-								 asd_struct_size,
-								 parse_endpoint);
-		if (ret < 0)
-			goto out_cleanup;
-	} else {
-		unsigned int i;
-
-		for (i = 0; i < num_ports; i++) {
-			ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(dev, notifier, asd_struct_size, ports[i], parse_endpoint);
-			if (ret < 0)
-				goto out_cleanup;
-		}
-	}
-
-	ret = v4l2_async_subdev_notifier_register(sd, notifier);
-	if (ret < 0)
-		goto out_cleanup;
-
-	ret = v4l2_async_register_subdev(sd);
-	if (ret < 0)
-		goto out_unregister;
-
-	sd->subdev_notifier = notifier;
-
-	return 0;
-
-out_unregister:
-	v4l2_async_notifier_unregister(notifier);
-out_cleanup:
-	v4l2_async_notifier_cleanup(notifier);
-	kfree(notifier);
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(v4l2_async_register_fwnode_subdev);
-
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Sakari Ailus <sakari.ailus@linux.intel.com>");
 MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h
index dd82d6d9764e..fad7a6480bf9 100644
--- a/include/media/v4l2-fwnode.h
+++ b/include/media/v4l2-fwnode.h
@@ -20,7 +20,6 @@
 #include <linux/types.h>
 
 #include <media/v4l2-mediabus.h>
-#include <media/v4l2-subdev.h>
 
 struct fwnode_handle;
 struct v4l2_async_notifier;
@@ -490,43 +489,6 @@ v4l2_async_notifier_parse_fwnode_endpoints_by_port(struct device *dev,
 int v4l2_async_notifier_parse_fwnode_sensor_common(struct device *dev,
 						   struct v4l2_async_notifier *notifier);
 
-/**
- * v4l2_async_register_fwnode_subdev - registers a sub-device to the
- *					asynchronous sub-device framework
- *					and parses fwnode endpoints
- *
- * @sd: pointer to struct &v4l2_subdev
- * @asd_struct_size: size of the driver's async sub-device struct, including
- *		     sizeof(struct v4l2_async_subdev). The &struct
- *		     v4l2_async_subdev shall be the first member of
- *		     the driver's async sub-device struct, i.e. both
- *		     begin at the same memory address.
- * @ports: array of port id's to parse for fwnode endpoints. If NULL, will
- *	   parse all ports owned by the sub-device.
- * @num_ports: number of ports in @ports array. Ignored if @ports is NULL.
- * @parse_endpoint: Driver's callback function called on each V4L2 fwnode
- *		    endpoint. Optional.
- *
- * This function is just like v4l2_async_register_subdev() with the
- * exception that calling it will also allocate a notifier for the
- * sub-device, parse the sub-device's firmware node endpoints using
- * v4l2_async_notifier_parse_fwnode_endpoints() or
- * v4l2_async_notifier_parse_fwnode_endpoints_by_port(), and
- * registers the sub-device notifier. The sub-device is similarly
- * unregistered by calling v4l2_async_unregister_subdev().
- *
- * While registered, the subdev module is marked as in-use.
- *
- * An error is returned if the module is no longer loaded on any attempts
- * to register it.
- */
-int
-v4l2_async_register_fwnode_subdev(struct v4l2_subdev *sd,
-				  size_t asd_struct_size,
-				  unsigned int *ports,
-				  unsigned int num_ports,
-				  parse_endpoint_func parse_endpoint);
-
 /* Helper macros to access the connector links. */
 
 /** v4l2_connector_last_link - Helper macro to get the first
-- 
2.17.1


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

* [PATCH v6 07/22] media: imx: csi: Implement get_fwnode_pad op
  2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
                   ` (5 preceding siblings ...)
  2020-05-01 17:15 ` [PATCH v6 06/22] Revert "media: v4l2-fwnode: Add a convenience function for registering subdevs with notifiers" Steve Longerbeam
@ 2020-05-01 17:15 ` Steve Longerbeam
  2020-05-01 17:15 ` [PATCH v6 08/22] media: video-mux: " Steve Longerbeam
                   ` (14 subsequent siblings)
  21 siblings, 0 replies; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

The CSI does not have a 1:1 relationship between fwnode port numbers and
pad indexes. In fact the CSI fwnode device is itself a port which is the
sink, containing only a single fwnode endpoint. Implement media_entity
operation get_fwnode_pad to first verify the given endpoint is the CSI's
sink endpoint, and if so return the CSI sink pad index.

Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/staging/media/imx/imx-media-csi.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c
index 905b1ee27db6..08f698af4797 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -1832,9 +1832,32 @@ static void csi_unregistered(struct v4l2_subdev *sd)
 		ipu_csi_put(priv->csi);
 }
 
+/*
+ * The CSI has only one fwnode endpoint, at the sink pad. Verify the
+ * endpoint belongs to us, and return CSI_SINK_PAD.
+ */
+static int csi_get_fwnode_pad(struct media_entity *entity,
+			      struct fwnode_endpoint *endpoint)
+{
+	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
+	struct csi_priv *priv = v4l2_get_subdevdata(sd);
+	struct fwnode_handle *csi_port = dev_fwnode(priv->dev);
+	struct fwnode_handle *csi_ep;
+	int ret;
+
+	csi_ep = fwnode_get_next_child_node(csi_port, NULL);
+
+	ret = endpoint->local_fwnode == csi_ep ? CSI_SINK_PAD : -ENXIO;
+
+	fwnode_handle_put(csi_ep);
+
+	return ret;
+}
+
 static const struct media_entity_operations csi_entity_ops = {
 	.link_setup = csi_link_setup,
 	.link_validate = v4l2_subdev_link_validate,
+	.get_fwnode_pad = csi_get_fwnode_pad,
 };
 
 static const struct v4l2_subdev_core_ops csi_core_ops = {
-- 
2.17.1


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

* [PATCH v6 08/22] media: video-mux: Implement get_fwnode_pad op
  2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
                   ` (6 preceding siblings ...)
  2020-05-01 17:15 ` [PATCH v6 07/22] media: imx: csi: Implement get_fwnode_pad op Steve Longerbeam
@ 2020-05-01 17:15 ` Steve Longerbeam
  2020-05-01 17:15 ` [PATCH v6 09/22] media: imx: mipi csi-2: " Steve Longerbeam
                   ` (13 subsequent siblings)
  21 siblings, 0 replies; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

Use v4l2_subdev_get_fwnode_pad_1_to_1() as the get_fwnode_pad operation.
The video mux maps fwnode port numbers and pad indexes 1:1.

Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
 drivers/media/platform/video-mux.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/platform/video-mux.c b/drivers/media/platform/video-mux.c
index 7b6c96a29aa5..9f148f403603 100644
--- a/drivers/media/platform/video-mux.c
+++ b/drivers/media/platform/video-mux.c
@@ -97,6 +97,7 @@ static int video_mux_link_setup(struct media_entity *entity,
 static const struct media_entity_operations video_mux_ops = {
 	.link_setup = video_mux_link_setup,
 	.link_validate = v4l2_subdev_link_validate,
+	.get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1,
 };
 
 static int video_mux_s_stream(struct v4l2_subdev *sd, int enable)
-- 
2.17.1


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

* [PATCH v6 09/22] media: imx: mipi csi-2: Implement get_fwnode_pad op
  2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
                   ` (7 preceding siblings ...)
  2020-05-01 17:15 ` [PATCH v6 08/22] media: video-mux: " Steve Longerbeam
@ 2020-05-01 17:15 ` Steve Longerbeam
  2020-05-01 17:15 ` [PATCH v6 10/22] media: imx: imx7-mipi-csis: " Steve Longerbeam
                   ` (12 subsequent siblings)
  21 siblings, 0 replies; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

Use v4l2_subdev_get_fwnode_pad_1_to_1() as the get_fwnode_pad operation.
The MIPI CSI-2 receiver maps port numbers and pad indexes 1:1.

Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
 drivers/staging/media/imx/imx6-mipi-csi2.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 332d77aec8aa..23823c8c6c3d 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -510,6 +510,7 @@ static int csi2_registered(struct v4l2_subdev *sd)
 static const struct media_entity_operations csi2_entity_ops = {
 	.link_setup = csi2_link_setup,
 	.link_validate = v4l2_subdev_link_validate,
+	.get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1,
 };
 
 static const struct v4l2_subdev_video_ops csi2_video_ops = {
-- 
2.17.1


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

* [PATCH v6 10/22] media: imx: imx7-mipi-csis: Implement get_fwnode_pad op
  2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
                   ` (8 preceding siblings ...)
  2020-05-01 17:15 ` [PATCH v6 09/22] media: imx: mipi csi-2: " Steve Longerbeam
@ 2020-05-01 17:15 ` Steve Longerbeam
  2020-05-04  9:14   ` Rui Miguel Silva
  2020-05-01 17:15 ` [PATCH v6 11/22] media: imx: imx7-media-csi: " Steve Longerbeam
                   ` (11 subsequent siblings)
  21 siblings, 1 reply; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

Use v4l2_subdev_get_fwnode_pad_1_to_1() as the get_fwnode_pad operation.
The imx7-mipi-csis maps port numbers and pad indexes 1:1.

Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
 drivers/staging/media/imx/imx7-mipi-csis.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c
index b66299c1136d..7b5c3e662d0d 100644
--- a/drivers/staging/media/imx/imx7-mipi-csis.c
+++ b/drivers/staging/media/imx/imx7-mipi-csis.c
@@ -906,6 +906,7 @@ static const struct v4l2_subdev_core_ops mipi_csis_core_ops = {
 static const struct media_entity_operations mipi_csis_entity_ops = {
 	.link_setup	= mipi_csis_link_setup,
 	.link_validate	= v4l2_subdev_link_validate,
+	.get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1,
 };
 
 static const struct v4l2_subdev_video_ops mipi_csis_video_ops = {
-- 
2.17.1


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

* [PATCH v6 11/22] media: imx: imx7-media-csi: Implement get_fwnode_pad op
  2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
                   ` (9 preceding siblings ...)
  2020-05-01 17:15 ` [PATCH v6 10/22] media: imx: imx7-mipi-csis: " Steve Longerbeam
@ 2020-05-01 17:15 ` Steve Longerbeam
  2020-05-04  9:14   ` Rui Miguel Silva
  2020-05-01 17:15 ` [PATCH v6 12/22] media: video-mux: Create media links in bound notifier Steve Longerbeam
                   ` (10 subsequent siblings)
  21 siblings, 1 reply; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

Use v4l2_subdev_get_fwnode_pad_1_to_1() as the get_fwnode_pad operation.
The i.MX7 CSI maps port numbers and pad indexes 1:1.

Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
 drivers/staging/media/imx/imx7-media-csi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c
index abef59dc22b6..c74455f65b3e 100644
--- a/drivers/staging/media/imx/imx7-media-csi.c
+++ b/drivers/staging/media/imx/imx7-media-csi.c
@@ -1179,6 +1179,7 @@ static int imx7_csi_init_cfg(struct v4l2_subdev *sd,
 static const struct media_entity_operations imx7_csi_entity_ops = {
 	.link_setup	= imx7_csi_link_setup,
 	.link_validate	= v4l2_subdev_link_validate,
+	.get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1,
 };
 
 static const struct v4l2_subdev_video_ops imx7_csi_video_ops = {
-- 
2.17.1


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

* [PATCH v6 12/22] media: video-mux: Create media links in bound notifier
  2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
                   ` (10 preceding siblings ...)
  2020-05-01 17:15 ` [PATCH v6 11/22] media: imx: imx7-media-csi: " Steve Longerbeam
@ 2020-05-01 17:15 ` Steve Longerbeam
  2020-05-01 17:15 ` [PATCH v6 13/22] media: imx: mipi csi-2: " Steve Longerbeam
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

Implement a notifier bound op to register media links from the remote
sub-device's source pad(s) to the video-mux sink pad(s).

Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
Changes in v5:
- went back to something similar to v2. A call is made to helper
  v4l2_create_fwnode_links().
Changes in v4:
- none
Changes in v3:
- this version does the work inline. The previous version called
  a media_create_fwnode_links() which is removed in v3.
---
 drivers/media/platform/video-mux.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/media/platform/video-mux.c b/drivers/media/platform/video-mux.c
index 9f148f403603..53570250a25d 100644
--- a/drivers/media/platform/video-mux.c
+++ b/drivers/media/platform/video-mux.c
@@ -17,6 +17,7 @@
 #include <media/v4l2-async.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-fwnode.h>
+#include <media/v4l2-mc.h>
 #include <media/v4l2-subdev.h>
 
 struct video_mux {
@@ -36,6 +37,12 @@ static const struct v4l2_mbus_framefmt video_mux_format_mbus_default = {
 	.field = V4L2_FIELD_NONE,
 };
 
+static inline struct video_mux *
+notifier_to_video_mux(struct v4l2_async_notifier *n)
+{
+	return container_of(n, struct video_mux, notifier);
+}
+
 static inline struct video_mux *v4l2_subdev_to_video_mux(struct v4l2_subdev *sd)
 {
 	return container_of(sd, struct video_mux, subdev);
@@ -332,6 +339,19 @@ static const struct v4l2_subdev_ops video_mux_subdev_ops = {
 	.video = &video_mux_subdev_video_ops,
 };
 
+static int video_mux_notify_bound(struct v4l2_async_notifier *notifier,
+				  struct v4l2_subdev *sd,
+				  struct v4l2_async_subdev *asd)
+{
+	struct video_mux *vmux = notifier_to_video_mux(notifier);
+
+	return v4l2_create_fwnode_links(sd, &vmux->subdev);
+}
+
+static const struct v4l2_async_notifier_operations video_mux_notify_ops = {
+	.bound = video_mux_notify_bound,
+};
+
 static int video_mux_async_register(struct video_mux *vmux,
 				    unsigned int num_input_pads)
 {
@@ -369,6 +389,8 @@ static int video_mux_async_register(struct video_mux *vmux,
 		}
 	}
 
+	vmux->notifier.ops = &video_mux_notify_ops;
+
 	ret = v4l2_async_subdev_notifier_register(&vmux->subdev,
 						  &vmux->notifier);
 	if (ret)
-- 
2.17.1


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

* [PATCH v6 13/22] media: imx: mipi csi-2: Create media links in bound notifier
  2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
                   ` (11 preceding siblings ...)
  2020-05-01 17:15 ` [PATCH v6 12/22] media: video-mux: Create media links in bound notifier Steve Longerbeam
@ 2020-05-01 17:15 ` Steve Longerbeam
  2020-05-01 17:15 ` [PATCH v6 14/22] media: imx7: mipi csis: " Steve Longerbeam
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

Implement a notifier bound op to register media links from the remote
sub-device's source pad(s) to the mipi csi-2 receiver sink pad.

Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
Chnges in v5:
- imx_media_create_fwnode_pad_link() has been moved to core as
  v4l2_create_fwnode_links_to_pad().
Changes in v4:
- none
Changes in v3:
- call a local imx-media utility imx_media_create_fwnode_pad_link()
  that creates a single link.
---
 drivers/staging/media/imx/imx6-mipi-csi2.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 23823c8c6c3d..94d87d27d389 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-fwnode.h>
+#include <media/v4l2-mc.h>
 #include <media/v4l2-subdev.h>
 #include "imx-media.h"
 
@@ -91,6 +92,11 @@ static inline struct csi2_dev *sd_to_dev(struct v4l2_subdev *sdev)
 	return container_of(sdev, struct csi2_dev, sd);
 }
 
+static inline struct csi2_dev *notifier_to_dev(struct v4l2_async_notifier *n)
+{
+	return container_of(n, struct csi2_dev, notifier);
+}
+
 /*
  * The required sequence of MIPI CSI-2 startup as specified in the i.MX6
  * reference manual is as follows:
@@ -532,6 +538,20 @@ static const struct v4l2_subdev_internal_ops csi2_internal_ops = {
 	.registered = csi2_registered,
 };
 
+static int csi2_notify_bound(struct v4l2_async_notifier *notifier,
+			     struct v4l2_subdev *sd,
+			     struct v4l2_async_subdev *asd)
+{
+	struct csi2_dev *csi2 = notifier_to_dev(notifier);
+	struct media_pad *sink = &csi2->sd.entity.pads[CSI2_SINK_PAD];
+
+	return v4l2_create_fwnode_links_to_pad(sd, sink);
+}
+
+static const struct v4l2_async_notifier_operations csi2_notify_ops = {
+	.bound = csi2_notify_bound,
+};
+
 static int csi2_async_register(struct csi2_dev *csi2)
 {
 	struct v4l2_fwnode_endpoint vep = {
@@ -570,6 +590,8 @@ static int csi2_async_register(struct csi2_dev *csi2)
 
 	fwnode_handle_put(ep);
 
+	csi2->notifier.ops = &csi2_notify_ops;
+
 	ret = v4l2_async_subdev_notifier_register(&csi2->sd,
 						  &csi2->notifier);
 	if (ret)
-- 
2.17.1


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

* [PATCH v6 14/22] media: imx7: mipi csis: Create media links in bound notifier
  2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
                   ` (12 preceding siblings ...)
  2020-05-01 17:15 ` [PATCH v6 13/22] media: imx: mipi csi-2: " Steve Longerbeam
@ 2020-05-01 17:15 ` Steve Longerbeam
  2020-05-04  9:12   ` Rui Miguel Silva
  2020-05-01 17:15 ` [PATCH v6 15/22] media: imx7: csi: " Steve Longerbeam
                   ` (7 subsequent siblings)
  21 siblings, 1 reply; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

Implement a notifier bound op to register media links from the remote
sub-device's source pad(s) to the mipi csi-2 receiver sink pad.

Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
Changes in v5:
- imx_media_create_fwnode_pad_link() has been moved to core as
  v4l2_create_fwnode_links_to_pad().
Changes in v4:
- none
Changes in v3:
- call a local imx-media utility imx_media_create_fwnode_pad_link().
Changes in v2:
- Move notifier_to_csis_state() next to mipi_sd_to_csis_state(), remove
  unnecessary inline, and rename to mipi_notifier_to_csis_state().
  Suggested by Rui Silva.
---
 drivers/staging/media/imx/imx7-mipi-csis.c | 23 ++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c
index 7b5c3e662d0d..1025e42740f1 100644
--- a/drivers/staging/media/imx/imx7-mipi-csis.c
+++ b/drivers/staging/media/imx/imx7-mipi-csis.c
@@ -26,6 +26,7 @@
 
 #include <media/v4l2-device.h>
 #include <media/v4l2-fwnode.h>
+#include <media/v4l2-mc.h>
 #include <media/v4l2-subdev.h>
 
 #define CSIS_DRIVER_NAME			"imx7-mipi-csis"
@@ -385,6 +386,12 @@ static int mipi_csis_dump_regs(struct csi_state *state)
 	return 0;
 }
 
+static struct csi_state *
+mipi_notifier_to_csis_state(struct v4l2_async_notifier *n)
+{
+	return container_of(n, struct csi_state, notifier);
+}
+
 static struct csi_state *mipi_sd_to_csis_state(struct v4l2_subdev *sdev)
 {
 	return container_of(sdev, struct csi_state, mipi_sd);
@@ -948,6 +955,20 @@ static int mipi_csis_parse_dt(struct platform_device *pdev,
 
 static int mipi_csis_pm_resume(struct device *dev, bool runtime);
 
+static int mipi_csis_notify_bound(struct v4l2_async_notifier *notifier,
+				  struct v4l2_subdev *sd,
+				  struct v4l2_async_subdev *asd)
+{
+	struct csi_state *state = mipi_notifier_to_csis_state(notifier);
+	struct media_pad *sink = &state->mipi_sd.entity.pads[CSIS_PAD_SINK];
+
+	return v4l2_create_fwnode_links_to_pad(sd, sink);
+}
+
+static const struct v4l2_async_notifier_operations mipi_csis_notify_ops = {
+	.bound = mipi_csis_notify_bound,
+};
+
 static int mipi_csis_subdev_init(struct v4l2_subdev *mipi_sd,
 				 struct platform_device *pdev,
 				 const struct v4l2_subdev_ops *ops)
@@ -1016,6 +1037,8 @@ static int mipi_csis_async_register(struct csi_state *state)
 
 	fwnode_handle_put(ep);
 
+	state->notifier.ops = &mipi_csis_notify_ops;
+
 	ret = v4l2_async_subdev_notifier_register(&state->mipi_sd,
 						  &state->notifier);
 	if (ret)
-- 
2.17.1


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

* [PATCH v6 15/22] media: imx7: csi: Create media links in bound notifier
  2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
                   ` (13 preceding siblings ...)
  2020-05-01 17:15 ` [PATCH v6 14/22] media: imx7: mipi csis: " Steve Longerbeam
@ 2020-05-01 17:15 ` Steve Longerbeam
  2020-05-01 17:15 ` [PATCH v6 16/22] media: imx: " Steve Longerbeam
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

Implement a notifier bound op to register media links from the remote
sub-device's source pad(s) to the CSI sink pad.

Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
Reviewed-by: Rui Miguel Silva <rmfrfs@gmail.com>
---
Changes in v5:
- imx_media_create_fwnode_pad_link() has been moved to core as
  v4l2_create_fwnode_links_to_pad().
Changes in v4:
- none
Changes in v3:
- call a local imx-media utility imx_media_create_fwnode_pad_link().
Changes in v2:
- Rename notifier_to_dev() to imx7_csi_notifier_to_dev() and remove
  unnecessary inline. Suggested by Rui Silva.
---
 drivers/staging/media/imx/imx7-media-csi.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c
index c74455f65b3e..21a86fa3d89b 100644
--- a/drivers/staging/media/imx/imx7-media-csi.c
+++ b/drivers/staging/media/imx/imx7-media-csi.c
@@ -196,6 +196,12 @@ struct imx7_csi {
 	struct completion last_eof_completion;
 };
 
+static struct imx7_csi *
+imx7_csi_notifier_to_dev(struct v4l2_async_notifier *n)
+{
+	return container_of(n, struct imx7_csi, notifier);
+}
+
 static u32 imx7_csi_reg_read(struct imx7_csi *csi, unsigned int offset)
 {
 	return readl(csi->regbase + offset);
@@ -1204,6 +1210,20 @@ static const struct v4l2_subdev_internal_ops imx7_csi_internal_ops = {
 	.unregistered	= imx7_csi_unregistered,
 };
 
+static int imx7_csi_notify_bound(struct v4l2_async_notifier *notifier,
+				 struct v4l2_subdev *sd,
+				 struct v4l2_async_subdev *asd)
+{
+	struct imx7_csi *csi = imx7_csi_notifier_to_dev(notifier);
+	struct media_pad *sink = &csi->sd.entity.pads[IMX7_CSI_PAD_SINK];
+
+	return v4l2_create_fwnode_links_to_pad(sd, sink);
+}
+
+static const struct v4l2_async_notifier_operations imx7_csi_notify_ops = {
+	.bound = imx7_csi_notify_bound,
+};
+
 static int imx7_csi_async_register(struct imx7_csi *csi)
 {
 	struct v4l2_async_subdev *asd = NULL;
@@ -1234,6 +1254,8 @@ static int imx7_csi_async_register(struct imx7_csi *csi)
 		}
 	}
 
+	csi->notifier.ops = &imx7_csi_notify_ops;
+
 	ret = v4l2_async_subdev_notifier_register(&csi->sd, &csi->notifier);
 	if (ret)
 		return ret;
-- 
2.17.1


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

* [PATCH v6 16/22] media: imx: csi: Create media links in bound notifier
  2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
                   ` (14 preceding siblings ...)
  2020-05-01 17:15 ` [PATCH v6 15/22] media: imx7: csi: " Steve Longerbeam
@ 2020-05-01 17:15 ` Steve Longerbeam
  2020-05-01 17:15 ` [PATCH v6 17/22] media: imx7: csi: Remove imx7_csi_get_upstream_endpoint() Steve Longerbeam
                   ` (5 subsequent siblings)
  21 siblings, 0 replies; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

Implement a notifier bound op to register media links from the remote
sub-device's source pad(s) to the CSI sink pad.

Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
Changes in v5:
- imx_media_create_fwnode_pad_link() has been moved to core as
  v4l2_create_fwnode_links_to_pad().
Changes in v4:
- none
Changes in v3:
- call a local imx-media utility imx_media_create_fwnode_pad_link().
---
 drivers/staging/media/imx/imx-media-csi.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c
index 08f698af4797..a051a063a2db 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -120,6 +120,11 @@ static inline struct csi_priv *sd_to_dev(struct v4l2_subdev *sdev)
 	return container_of(sdev, struct csi_priv, sd);
 }
 
+static inline struct csi_priv *notifier_to_dev(struct v4l2_async_notifier *n)
+{
+	return container_of(n, struct csi_priv, notifier);
+}
+
 static inline bool is_parallel_bus(struct v4l2_fwnode_endpoint *ep)
 {
 	return ep->bus_type != V4L2_MBUS_CSI2_DPHY;
@@ -1894,6 +1899,20 @@ static const struct v4l2_subdev_internal_ops csi_internal_ops = {
 	.unregistered = csi_unregistered,
 };
 
+static int imx_csi_notify_bound(struct v4l2_async_notifier *notifier,
+				struct v4l2_subdev *sd,
+				struct v4l2_async_subdev *asd)
+{
+	struct csi_priv *priv = notifier_to_dev(notifier);
+	struct media_pad *sink = &priv->sd.entity.pads[CSI_SINK_PAD];
+
+	return v4l2_create_fwnode_links_to_pad(sd, sink);
+}
+
+static const struct v4l2_async_notifier_operations csi_notify_ops = {
+	.bound = imx_csi_notify_bound,
+};
+
 static int imx_csi_async_register(struct csi_priv *priv)
 {
 	struct v4l2_async_subdev *asd = NULL;
@@ -1931,6 +1950,8 @@ static int imx_csi_async_register(struct csi_priv *priv)
 		}
 	}
 
+	priv->notifier.ops = &csi_notify_ops;
+
 	ret = v4l2_async_subdev_notifier_register(&priv->sd,
 						  &priv->notifier);
 	if (ret)
-- 
2.17.1


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

* [PATCH v6 17/22] media: imx7: csi: Remove imx7_csi_get_upstream_endpoint()
  2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
                   ` (15 preceding siblings ...)
  2020-05-01 17:15 ` [PATCH v6 16/22] media: imx: " Steve Longerbeam
@ 2020-05-01 17:15 ` Steve Longerbeam
  2020-05-04  9:10   ` Rui Miguel Silva
  2020-05-01 17:15 ` [PATCH v6 18/22] media: imx5/6/7: csi: Mark a bound video mux as a CSI mux Steve Longerbeam
                   ` (4 subsequent siblings)
  21 siblings, 1 reply; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

The function imx7_csi_get_upstream_endpoint() is not necessary for
imx7. First, the imx7 CSI only receives from the CSI mux, so much of
the code in there is pointless. Second, it is only used to determine
whether the CSI mux has selected the CSI-2 input or the parallel input.
This can be accomplished much more simply by getting the function type
of selected input entity to the CSI mux.

Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
 drivers/staging/media/imx/imx7-media-csi.c | 77 ++++------------------
 1 file changed, 12 insertions(+), 65 deletions(-)

diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c
index 21a86fa3d89b..69f7abb32ae1 100644
--- a/drivers/staging/media/imx/imx7-media-csi.c
+++ b/drivers/staging/media/imx/imx7-media-csi.c
@@ -169,8 +169,6 @@ struct imx7_csi {
 
 	struct media_entity *sink;
 
-	struct v4l2_fwnode_endpoint upstream_ep;
-
 	struct v4l2_mbus_framefmt format_mbus[IMX7_CSI_PADS_NUM];
 	const struct imx_media_pixfmt *cc[IMX7_CSI_PADS_NUM];
 	struct v4l2_fract frame_interval[IMX7_CSI_PADS_NUM];
@@ -435,61 +433,6 @@ static void imx7_csi_deinit(struct imx7_csi *csi)
 	csi->is_init = false;
 }
 
-static int imx7_csi_get_upstream_endpoint(struct imx7_csi *csi,
-					  struct v4l2_fwnode_endpoint *ep,
-					  bool skip_mux)
-{
-	struct device_node *endpoint, *port;
-	struct media_entity *src;
-	struct v4l2_subdev *sd;
-	struct media_pad *pad;
-
-	if (!csi->src_sd)
-		return -EPIPE;
-
-	src = &csi->src_sd->entity;
-
-	/*
-	 * if the source is neither a mux or csi2 get the one directly upstream
-	 * from this csi
-	 */
-	if (src->function != MEDIA_ENT_F_VID_IF_BRIDGE &&
-	    src->function != MEDIA_ENT_F_VID_MUX)
-		src = &csi->sd.entity;
-
-skip_video_mux:
-	/* get source pad of entity directly upstream from src */
-	pad = imx_media_pipeline_pad(src, 0, 0, true);
-	if (!pad)
-		return -ENODEV;
-
-	sd = media_entity_to_v4l2_subdev(pad->entity);
-
-	/* To get bus type we may need to skip video mux */
-	if (skip_mux && src->function == MEDIA_ENT_F_VID_MUX) {
-		src = &sd->entity;
-		goto skip_video_mux;
-	}
-
-	/*
-	 * NOTE: this assumes an OF-graph port id is the same as a
-	 * media pad index.
-	 */
-	port = of_graph_get_port_by_id(sd->dev->of_node, pad->index);
-	if (!port)
-		return -ENODEV;
-
-	endpoint = of_get_next_child(port, NULL);
-	of_node_put(port);
-	if (!endpoint)
-		return -ENODEV;
-
-	v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), ep);
-	of_node_put(endpoint);
-
-	return 0;
-}
-
 static int imx7_csi_link_setup(struct media_entity *entity,
 			       const struct media_pad *local,
 			       const struct media_pad *remote, u32 flags)
@@ -556,23 +499,27 @@ static int imx7_csi_pad_link_validate(struct v4l2_subdev *sd,
 				      struct v4l2_subdev_format *sink_fmt)
 {
 	struct imx7_csi *csi = v4l2_get_subdevdata(sd);
-	struct v4l2_fwnode_endpoint upstream_ep = {};
+	struct media_pad *pad;
 	int ret;
 
 	ret = v4l2_subdev_link_validate_default(sd, link, source_fmt, sink_fmt);
 	if (ret)
 		return ret;
 
-	ret = imx7_csi_get_upstream_endpoint(csi, &upstream_ep, true);
-	if (ret) {
-		v4l2_err(&csi->sd, "failed to find upstream endpoint\n");
-		return ret;
-	}
+	if (!csi->src_sd)
+		return -EPIPE;
+
+	/*
+	 * find the entity that is selected by the CSI mux. This is needed
+	 * to distinguish between a parallel or CSI-2 pipeline.
+	 */
+	pad = imx_media_pipeline_pad(&csi->src_sd->entity, 0, 0, true);
+	if (!pad)
+		return -ENODEV;
 
 	mutex_lock(&csi->lock);
 
-	csi->upstream_ep = upstream_ep;
-	csi->is_csi2 = (upstream_ep.bus_type == V4L2_MBUS_CSI2_DPHY);
+	csi->is_csi2 = (pad->entity->function == MEDIA_ENT_F_VID_IF_BRIDGE);
 
 	mutex_unlock(&csi->lock);
 
-- 
2.17.1


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

* [PATCH v6 18/22] media: imx5/6/7: csi: Mark a bound video mux as a CSI mux
  2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
                   ` (16 preceding siblings ...)
  2020-05-01 17:15 ` [PATCH v6 17/22] media: imx7: csi: Remove imx7_csi_get_upstream_endpoint() Steve Longerbeam
@ 2020-05-01 17:15 ` Steve Longerbeam
  2020-05-04  9:12   ` Rui Miguel Silva
  2020-05-01 17:15 ` [PATCH v6 19/22] media: imx: csi: Lookup upstream endpoint with imx_media_get_pad_fwnode Steve Longerbeam
                   ` (3 subsequent siblings)
  21 siblings, 1 reply; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

For i.MX5/6, if the bound subdev is a video mux, it must be one of the
CSI muxes, and for i.MX7, the bound subdev must always be a CSI mux.

So if the bound subdev is a video mux, mark it as a CSI mux with a new
group id IMX_MEDIA_GRP_ID_CSI_MUX.

In the process use the new group id in csi_get_upstream_endpoint(), and
do some cleanup in that function for better readability.

Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
 drivers/staging/media/imx/imx-media-csi.c  | 45 +++++++++++++---------
 drivers/staging/media/imx/imx-media.h      |  1 +
 drivers/staging/media/imx/imx7-media-csi.c |  7 ++++
 3 files changed, 35 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c
index a051a063a2db..6cfbe67c43d1 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -165,7 +165,6 @@ static int csi_get_upstream_endpoint(struct csi_priv *priv,
 				     struct v4l2_fwnode_endpoint *ep)
 {
 	struct device_node *endpoint, *port;
-	struct media_entity *src;
 	struct v4l2_subdev *sd;
 	struct media_pad *pad;
 
@@ -176,30 +175,33 @@ static int csi_get_upstream_endpoint(struct csi_priv *priv,
 		return -EPIPE;
 
 	sd = priv->src_sd;
-	src = &sd->entity;
 
-	if (src->function == MEDIA_ENT_F_VID_MUX) {
+	switch (sd->grp_id) {
+	case IMX_MEDIA_GRP_ID_CSI_MUX:
 		/*
-		 * CSI is connected directly to video mux, skip up to
+		 * CSI is connected directly to CSI mux, skip up to
 		 * CSI-2 receiver if it is in the path, otherwise stay
-		 * with video mux.
+		 * with the CSI mux.
 		 */
-		sd = imx_media_pipeline_subdev(src, IMX_MEDIA_GRP_ID_CSI2,
+		sd = imx_media_pipeline_subdev(&sd->entity,
+					       IMX_MEDIA_GRP_ID_CSI2,
 					       true);
-		if (!IS_ERR(sd))
-			src = &sd->entity;
+		if (IS_ERR(sd))
+			sd = priv->src_sd;
+		break;
+	case IMX_MEDIA_GRP_ID_CSI2:
+		break;
+	default:
+		/*
+		 * the source is neither the CSI mux nor the CSI-2 receiver,
+		 * get the source pad directly upstream from CSI itself.
+		 */
+		sd = &priv->sd;
+		break;
 	}
 
-	/*
-	 * If the source is neither the video mux nor the CSI-2 receiver,
-	 * get the source pad directly upstream from CSI itself.
-	 */
-	if (src->function != MEDIA_ENT_F_VID_MUX &&
-	    sd->grp_id != IMX_MEDIA_GRP_ID_CSI2)
-		src = &priv->sd.entity;
-
-	/* get source pad of entity directly upstream from src */
-	pad = imx_media_pipeline_pad(src, 0, 0, true);
+	/* get source pad of entity directly upstream from sd */
+	pad = imx_media_pipeline_pad(&sd->entity, 0, 0, true);
 	if (!pad)
 		return -ENODEV;
 
@@ -1906,6 +1908,13 @@ static int imx_csi_notify_bound(struct v4l2_async_notifier *notifier,
 	struct csi_priv *priv = notifier_to_dev(notifier);
 	struct media_pad *sink = &priv->sd.entity.pads[CSI_SINK_PAD];
 
+	/*
+	 * If the subdev is a video mux, it must be one of the CSI
+	 * muxes. Mark it as such via its group id.
+	 */
+	if (sd->entity.function == MEDIA_ENT_F_VID_MUX)
+		sd->grp_id = IMX_MEDIA_GRP_ID_CSI_MUX;
+
 	return v4l2_create_fwnode_links_to_pad(sd, sink);
 }
 
diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h
index ca36beca16de..b5b7d3245727 100644
--- a/drivers/staging/media/imx/imx-media.h
+++ b/drivers/staging/media/imx/imx-media.h
@@ -311,5 +311,6 @@ void imx_media_csc_scaler_device_unregister(struct imx_media_video_dev *vdev);
 #define IMX_MEDIA_GRP_ID_IPU_IC_PRP    BIT(13)
 #define IMX_MEDIA_GRP_ID_IPU_IC_PRPENC BIT(14)
 #define IMX_MEDIA_GRP_ID_IPU_IC_PRPVF  BIT(15)
+#define IMX_MEDIA_GRP_ID_CSI_MUX       BIT(16)
 
 #endif
diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c
index 69f7abb32ae1..a3f3df901704 100644
--- a/drivers/staging/media/imx/imx7-media-csi.c
+++ b/drivers/staging/media/imx/imx7-media-csi.c
@@ -1164,6 +1164,13 @@ static int imx7_csi_notify_bound(struct v4l2_async_notifier *notifier,
 	struct imx7_csi *csi = imx7_csi_notifier_to_dev(notifier);
 	struct media_pad *sink = &csi->sd.entity.pads[IMX7_CSI_PAD_SINK];
 
+	/* The bound subdev must always be the CSI mux */
+	if (WARN_ON(sd->entity.function != MEDIA_ENT_F_VID_MUX))
+		return -ENXIO;
+
+	/* Mark it as such via its group id */
+	sd->grp_id = IMX_MEDIA_GRP_ID_CSI_MUX;
+
 	return v4l2_create_fwnode_links_to_pad(sd, sink);
 }
 
-- 
2.17.1


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

* [PATCH v6 19/22] media: imx: csi: Lookup upstream endpoint with imx_media_get_pad_fwnode
  2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
                   ` (17 preceding siblings ...)
  2020-05-01 17:15 ` [PATCH v6 18/22] media: imx5/6/7: csi: Mark a bound video mux as a CSI mux Steve Longerbeam
@ 2020-05-01 17:15 ` Steve Longerbeam
  2020-05-01 17:15 ` [PATCH v6 20/22] media: imx: Create missing links from CSI-2 receiver Steve Longerbeam
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

Fix the 1:1 port-id:pad-index assumption for the upstream subdevice, by
searching the upstream subdevice's endpoints for one that maps to the
pad's index. This is carried out by a new reverse mapping function
imx_media_get_pad_fwnode().

Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
 drivers/staging/media/imx/imx-media-csi.c   | 22 ++++----------
 drivers/staging/media/imx/imx-media-utils.c | 33 +++++++++++++++++++++
 drivers/staging/media/imx/imx-media.h       |  1 +
 3 files changed, 40 insertions(+), 16 deletions(-)

diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c
index 6cfbe67c43d1..d7e5b9ed27b8 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -164,7 +164,7 @@ static inline bool requires_passthrough(struct v4l2_fwnode_endpoint *ep,
 static int csi_get_upstream_endpoint(struct csi_priv *priv,
 				     struct v4l2_fwnode_endpoint *ep)
 {
-	struct device_node *endpoint, *port;
+	struct fwnode_handle *endpoint;
 	struct v4l2_subdev *sd;
 	struct media_pad *pad;
 
@@ -205,23 +205,13 @@ static int csi_get_upstream_endpoint(struct csi_priv *priv,
 	if (!pad)
 		return -ENODEV;
 
-	sd = media_entity_to_v4l2_subdev(pad->entity);
+	endpoint = imx_media_get_pad_fwnode(pad);
+	if (IS_ERR(endpoint))
+		return PTR_ERR(endpoint);
 
-	/*
-	 * NOTE: this assumes an OF-graph port id is the same as a
-	 * media pad index.
-	 */
-	port = of_graph_get_port_by_id(sd->dev->of_node, pad->index);
-	if (!port)
-		return -ENODEV;
-
-	endpoint = of_get_next_child(port, NULL);
-	of_node_put(port);
-	if (!endpoint)
-		return -ENODEV;
+	v4l2_fwnode_endpoint_parse(endpoint, ep);
 
-	v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), ep);
-	of_node_put(endpoint);
+	fwnode_handle_put(endpoint);
 
 	return 0;
 }
diff --git a/drivers/staging/media/imx/imx-media-utils.c b/drivers/staging/media/imx/imx-media-utils.c
index 42e64b618a61..7c058db41f7c 100644
--- a/drivers/staging/media/imx/imx-media-utils.c
+++ b/drivers/staging/media/imx/imx-media-utils.c
@@ -835,6 +835,39 @@ imx_media_pipeline_video_device(struct media_entity *start_entity,
 }
 EXPORT_SYMBOL_GPL(imx_media_pipeline_video_device);
 
+/*
+ * Find a fwnode endpoint that maps to the given subdevice's pad.
+ * If there are multiple endpoints that map to the pad, only the
+ * first endpoint encountered is returned.
+ *
+ * On success the refcount of the returned fwnode endpoint is
+ * incremented.
+ */
+struct fwnode_handle *imx_media_get_pad_fwnode(struct media_pad *pad)
+{
+	struct fwnode_handle *endpoint;
+	struct v4l2_subdev *sd;
+
+	if (!is_media_entity_v4l2_subdev(pad->entity))
+		return ERR_PTR(-ENODEV);
+
+	sd = media_entity_to_v4l2_subdev(pad->entity);
+
+	fwnode_graph_for_each_endpoint(dev_fwnode(sd->dev), endpoint) {
+		int pad_idx = media_entity_get_fwnode_pad(&sd->entity,
+							  endpoint,
+							  pad->flags);
+		if (pad_idx < 0)
+			continue;
+
+		if (pad_idx == pad->index)
+			return endpoint;
+	}
+
+	return ERR_PTR(-ENODEV);
+}
+EXPORT_SYMBOL_GPL(imx_media_get_pad_fwnode);
+
 /*
  * Turn current pipeline streaming on/off starting from entity.
  */
diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h
index b5b7d3245727..c5f2aa2f0e98 100644
--- a/drivers/staging/media/imx/imx-media.h
+++ b/drivers/staging/media/imx/imx-media.h
@@ -220,6 +220,7 @@ imx_media_pipeline_subdev(struct media_entity *start_entity, u32 grp_id,
 struct video_device *
 imx_media_pipeline_video_device(struct media_entity *start_entity,
 				enum v4l2_buf_type buftype, bool upstream);
+struct fwnode_handle *imx_media_get_pad_fwnode(struct media_pad *pad);
 
 struct imx_media_dma_buf {
 	void          *virt;
-- 
2.17.1


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

* [PATCH v6 20/22] media: imx: Create missing links from CSI-2 receiver
  2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
                   ` (18 preceding siblings ...)
  2020-05-01 17:15 ` [PATCH v6 19/22] media: imx: csi: Lookup upstream endpoint with imx_media_get_pad_fwnode Steve Longerbeam
@ 2020-05-01 17:15 ` Steve Longerbeam
  2020-05-01 17:15 ` [PATCH v6 21/22] media: imx: silence a couple debug messages Steve Longerbeam
  2020-05-01 17:15 ` [PATCH v6 22/22] media: imx: TODO: Remove media link creation todos Steve Longerbeam
  21 siblings, 0 replies; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

The entities external to the i.MX6 IPU and i.MX7 now create the links
to their fwnode-endpoint connected entities in their notifier bound
callbacks. Which means imx_media_create_of_links() and
imx_media_create_csi_of_links() are no longer needed and are removed.

However there is still one case in which imx-media needs to create
fwnode-endpoint based links at probe completion. The v4l2-async framework
does not allow multiple subdevice notifiers to contain a duplicate
subdevice in their asd_list. Only the first subdev notifier that discovers
and adds that one subdevice to its asd_list will receive a bound callback
for it. Other subdevices that also have firmware endpoint connections to
this duplicate subdevice will not have it in their asd_list, and thus will
never receive a bound callback for it. In the case of imx-media, the one
duplicate subdevice in question is the i.MX6 MIPI CSI-2 receiver.

Until there is a solution to that problem, rewrite imx_media_create_links()
to add the missing links from the CSI-2 receiver to the CSIs and CSI muxes.
The function is renamed imx_media_create_csi2_links().

Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
Changes in v5:
- imx_media_create_fwnode_pad_link() has been moved to core as
  v4l2_create_fwnode_link().
- use the new group id IMX_MEDIA_GRP_ID_CSI_MUX to look specifically
  for an imx CSI video mux. Suggested by Laurent.
Changes in v4:
- none
Changes in v3:
- call a local imx-media utility imx_media_create_fwnode_pad_links().
Changes in v2:
- this is a rewrite of v1 "media: imx: Use media_create_fwnode_links for
  external links", which only adds the missing CSI-2 receiver links.
---
 .../staging/media/imx/imx-media-dev-common.c  |  46 +++----
 drivers/staging/media/imx/imx-media-of.c      | 114 ------------------
 drivers/staging/media/imx/imx-media.h         |   4 -
 3 files changed, 17 insertions(+), 147 deletions(-)

diff --git a/drivers/staging/media/imx/imx-media-dev-common.c b/drivers/staging/media/imx/imx-media-dev-common.c
index 66b505f7e8df..f6ad9631fa0e 100644
--- a/drivers/staging/media/imx/imx-media-dev-common.c
+++ b/drivers/staging/media/imx/imx-media-dev-common.c
@@ -30,41 +30,31 @@ static int imx_media_subdev_bound(struct v4l2_async_notifier *notifier,
 }
 
 /*
- * Create the media links for all subdevs that registered.
+ * Create the missing media links from the CSI-2 receiver.
  * Called after all async subdevs have bound.
  */
-static int imx_media_create_links(struct v4l2_async_notifier *notifier)
+static void imx_media_create_csi2_links(struct imx_media_dev *imxmd)
 {
-	struct imx_media_dev *imxmd = notifier2dev(notifier);
-	struct v4l2_subdev *sd;
+	struct v4l2_subdev *sd, *csi2 = NULL;
 
 	list_for_each_entry(sd, &imxmd->v4l2_dev.subdevs, list) {
-		switch (sd->grp_id) {
-		case IMX_MEDIA_GRP_ID_IPU_VDIC:
-		case IMX_MEDIA_GRP_ID_IPU_IC_PRP:
-		case IMX_MEDIA_GRP_ID_IPU_IC_PRPENC:
-		case IMX_MEDIA_GRP_ID_IPU_IC_PRPVF:
-			/*
-			 * links have already been created for the
-			 * sync-registered subdevs.
-			 */
-			break;
-		case IMX_MEDIA_GRP_ID_IPU_CSI0:
-		case IMX_MEDIA_GRP_ID_IPU_CSI1:
-		case IMX_MEDIA_GRP_ID_CSI:
-			imx_media_create_csi_of_links(imxmd, sd);
-			break;
-		default:
-			/*
-			 * if this subdev has fwnode links, create media
-			 * links for them.
-			 */
-			imx_media_create_of_links(imxmd, sd);
+		if (sd->grp_id == IMX_MEDIA_GRP_ID_CSI2) {
+			csi2 = sd;
 			break;
 		}
 	}
+	if (!csi2)
+		return;
 
-	return 0;
+	list_for_each_entry(sd, &imxmd->v4l2_dev.subdevs, list) {
+		/* skip if not a CSI or a CSI mux */
+		if (!(sd->grp_id & IMX_MEDIA_GRP_ID_IPU_CSI) &&
+		    !(sd->grp_id & IMX_MEDIA_GRP_ID_CSI) &&
+		    !(sd->grp_id & IMX_MEDIA_GRP_ID_CSI_MUX))
+			continue;
+
+		v4l2_create_fwnode_links(csi2, sd);
+	}
 }
 
 /*
@@ -196,9 +186,7 @@ int imx_media_probe_complete(struct v4l2_async_notifier *notifier)
 
 	mutex_lock(&imxmd->mutex);
 
-	ret = imx_media_create_links(notifier);
-	if (ret)
-		goto unlock;
+	imx_media_create_csi2_links(imxmd);
 
 	ret = imx_media_create_pad_vdev_lists(imxmd);
 	if (ret)
diff --git a/drivers/staging/media/imx/imx-media-of.c b/drivers/staging/media/imx/imx-media-of.c
index 2d3efd2a6dde..82e13e972e23 100644
--- a/drivers/staging/media/imx/imx-media-of.c
+++ b/drivers/staging/media/imx/imx-media-of.c
@@ -74,117 +74,3 @@ int imx_media_add_of_subdevs(struct imx_media_dev *imxmd,
 	return ret;
 }
 EXPORT_SYMBOL_GPL(imx_media_add_of_subdevs);
-
-/*
- * Create a single media link to/from sd using a fwnode link.
- *
- * NOTE: this function assumes an OF port node is equivalent to
- * a media pad (port id equal to media pad index), and that an
- * OF endpoint node is equivalent to a media link.
- */
-static int create_of_link(struct imx_media_dev *imxmd,
-			  struct v4l2_subdev *sd,
-			  struct v4l2_fwnode_link *link)
-{
-	struct v4l2_subdev *remote, *src, *sink;
-	int src_pad, sink_pad;
-
-	if (link->local_port >= sd->entity.num_pads)
-		return -EINVAL;
-
-	remote = imx_media_find_subdev_by_fwnode(imxmd, link->remote_node);
-	if (!remote)
-		return 0;
-
-	if (sd->entity.pads[link->local_port].flags & MEDIA_PAD_FL_SINK) {
-		src = remote;
-		src_pad = link->remote_port;
-		sink = sd;
-		sink_pad = link->local_port;
-	} else {
-		src = sd;
-		src_pad = link->local_port;
-		sink = remote;
-		sink_pad = link->remote_port;
-	}
-
-	/* make sure link doesn't already exist before creating */
-	if (media_entity_find_link(&src->entity.pads[src_pad],
-				   &sink->entity.pads[sink_pad]))
-		return 0;
-
-	v4l2_info(sd->v4l2_dev, "%s:%d -> %s:%d\n",
-		  src->name, src_pad, sink->name, sink_pad);
-
-	return media_create_pad_link(&src->entity, src_pad,
-				     &sink->entity, sink_pad, 0);
-}
-
-/*
- * Create media links to/from sd using its device-tree endpoints.
- */
-int imx_media_create_of_links(struct imx_media_dev *imxmd,
-			      struct v4l2_subdev *sd)
-{
-	struct v4l2_fwnode_link link;
-	struct device_node *ep;
-	int ret;
-
-	for_each_endpoint_of_node(sd->dev->of_node, ep) {
-		ret = v4l2_fwnode_parse_link(of_fwnode_handle(ep), &link);
-		if (ret)
-			continue;
-
-		ret = create_of_link(imxmd, sd, &link);
-		v4l2_fwnode_put_link(&link);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(imx_media_create_of_links);
-
-/*
- * Create media links to the given CSI subdevice's sink pads,
- * using its device-tree endpoints.
- */
-int imx_media_create_csi_of_links(struct imx_media_dev *imxmd,
-				  struct v4l2_subdev *csi)
-{
-	struct device_node *csi_np = csi->dev->of_node;
-	struct device_node *ep;
-
-	for_each_child_of_node(csi_np, ep) {
-		struct fwnode_handle *fwnode, *csi_ep;
-		struct v4l2_fwnode_link link;
-		int ret;
-
-		memset(&link, 0, sizeof(link));
-
-		link.local_node = of_fwnode_handle(csi_np);
-		link.local_port = CSI_SINK_PAD;
-
-		csi_ep = of_fwnode_handle(ep);
-
-		fwnode = fwnode_graph_get_remote_endpoint(csi_ep);
-		if (!fwnode)
-			continue;
-
-		fwnode = fwnode_get_parent(fwnode);
-		fwnode_property_read_u32(fwnode, "reg", &link.remote_port);
-		fwnode = fwnode_get_next_parent(fwnode);
-		if (is_of_node(fwnode) &&
-		    of_node_name_eq(to_of_node(fwnode), "ports"))
-			fwnode = fwnode_get_next_parent(fwnode);
-		link.remote_node = fwnode;
-
-		ret = create_of_link(imxmd, csi, &link);
-		fwnode_handle_put(link.remote_node);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(imx_media_create_csi_of_links);
diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h
index c5f2aa2f0e98..f17135158029 100644
--- a/drivers/staging/media/imx/imx-media.h
+++ b/drivers/staging/media/imx/imx-media.h
@@ -263,10 +263,6 @@ void imx_media_unregister_ipu_internal_subdevs(struct imx_media_dev *imxmd);
 /* imx-media-of.c */
 int imx_media_add_of_subdevs(struct imx_media_dev *dev,
 			     struct device_node *np);
-int imx_media_create_of_links(struct imx_media_dev *imxmd,
-			      struct v4l2_subdev *sd);
-int imx_media_create_csi_of_links(struct imx_media_dev *imxmd,
-				  struct v4l2_subdev *csi);
 int imx_media_of_add_csi(struct imx_media_dev *imxmd,
 			 struct device_node *csi_np);
 
-- 
2.17.1


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

* [PATCH v6 21/22] media: imx: silence a couple debug messages
  2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
                   ` (19 preceding siblings ...)
  2020-05-01 17:15 ` [PATCH v6 20/22] media: imx: Create missing links from CSI-2 receiver Steve Longerbeam
@ 2020-05-01 17:15 ` Steve Longerbeam
  2020-05-01 17:15 ` [PATCH v6 22/22] media: imx: TODO: Remove media link creation todos Steve Longerbeam
  21 siblings, 0 replies; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

Convert to dev_dbg the "subdev bound" and IPU-internal media-link
creation messages.

Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/staging/media/imx/imx-media-dev-common.c  | 4 +++-
 drivers/staging/media/imx/imx-media-dev.c         | 2 +-
 drivers/staging/media/imx/imx-media-internal-sd.c | 6 +++---
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/media/imx/imx-media-dev-common.c b/drivers/staging/media/imx/imx-media-dev-common.c
index f6ad9631fa0e..5fe4b22ab847 100644
--- a/drivers/staging/media/imx/imx-media-dev-common.c
+++ b/drivers/staging/media/imx/imx-media-dev-common.c
@@ -24,7 +24,9 @@ static int imx_media_subdev_bound(struct v4l2_async_notifier *notifier,
 				  struct v4l2_subdev *sd,
 				  struct v4l2_async_subdev *asd)
 {
-	v4l2_info(sd->v4l2_dev, "subdev %s bound\n", sd->name);
+	struct imx_media_dev *imxmd = notifier2dev(notifier);
+
+	dev_dbg(imxmd->md.dev, "subdev %s bound\n", sd->name);
 
 	return 0;
 }
diff --git a/drivers/staging/media/imx/imx-media-dev.c b/drivers/staging/media/imx/imx-media-dev.c
index 2c3c2adca683..6d2205461e56 100644
--- a/drivers/staging/media/imx/imx-media-dev.c
+++ b/drivers/staging/media/imx/imx-media-dev.c
@@ -32,7 +32,7 @@ static int imx_media_subdev_bound(struct v4l2_async_notifier *notifier,
 			return ret;
 	}
 
-	v4l2_info(&imxmd->v4l2_dev, "subdev %s bound\n", sd->name);
+	dev_dbg(imxmd->md.dev, "subdev %s bound\n", sd->name);
 
 	return 0;
 }
diff --git a/drivers/staging/media/imx/imx-media-internal-sd.c b/drivers/staging/media/imx/imx-media-internal-sd.c
index d4237e1a4241..da4109b2fd13 100644
--- a/drivers/staging/media/imx/imx-media-internal-sd.c
+++ b/drivers/staging/media/imx/imx-media-internal-sd.c
@@ -142,9 +142,9 @@ static int create_internal_link(struct imx_media_dev *imxmd,
 				   &sink->entity.pads[link->remote_pad]))
 		return 0;
 
-	v4l2_info(&imxmd->v4l2_dev, "%s:%d -> %s:%d\n",
-		  src->name, link->local_pad,
-		  sink->name, link->remote_pad);
+	dev_dbg(imxmd->md.dev, "%s:%d -> %s:%d\n",
+		src->name, link->local_pad,
+		sink->name, link->remote_pad);
 
 	ret = media_create_pad_link(&src->entity, link->local_pad,
 				    &sink->entity, link->remote_pad, 0);
-- 
2.17.1


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

* [PATCH v6 22/22] media: imx: TODO: Remove media link creation todos
  2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
                   ` (20 preceding siblings ...)
  2020-05-01 17:15 ` [PATCH v6 21/22] media: imx: silence a couple debug messages Steve Longerbeam
@ 2020-05-01 17:15 ` Steve Longerbeam
  21 siblings, 0 replies; 28+ messages in thread
From: Steve Longerbeam @ 2020-05-01 17:15 UTC (permalink / raw)
  To: linux-media
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Rui Miguel Silva, Laurent Pinchart, Philipp Zabel,
	Steve Longerbeam

Remove the TODO items regarding media link creation, these issues are
resolved by moving media link creation to individual entity bound
callbacks and the implementation of the get_fwnode_pad operation.

Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
 drivers/staging/media/imx/TODO | 29 -----------------------------
 1 file changed, 29 deletions(-)

diff --git a/drivers/staging/media/imx/TODO b/drivers/staging/media/imx/TODO
index 6f29b5ca5324..a371cdedcdb0 100644
--- a/drivers/staging/media/imx/TODO
+++ b/drivers/staging/media/imx/TODO
@@ -17,35 +17,6 @@
   decided whether this feature is useful enough to make it generally
   available by exporting to v4l2-core.
 
-- After all async subdevices have been bound, v4l2_fwnode_parse_link()
-  is used to form the media links between the devices discovered in
-  the OF graph.
-
-  While this approach allows support for arbitrary OF graphs, there
-  are some assumptions for this to work:
-
-  1. If a port owned by a device in the graph has endpoint nodes, the
-     port is treated as a media pad.
-
-     This presents problems for devices that don't make this port = pad
-     assumption. Examples are SMIAPP compatible cameras which define only
-     a single output port node, but which define multiple pads owned
-     by multiple subdevices (pixel-array, binner, scaler). Or video
-     decoders (entity function MEDIA_ENT_F_ATV_DECODER), which also define
-     only a single output port node, but define multiple pads for video,
-     VBI, and audio out.
-
-     A workaround at present is to set the port reg properties to
-     correspond to the media pad index that the port represents. A
-     possible long-term solution is to implement a subdev API that
-     maps a port id to a media pad index.
-
-  2. Every endpoint of a port owned by a device in the graph is treated
-     as a media link.
-
-     Which means a port must not contain mixed-use endpoints, they
-     must all refer to media links between V4L2 subdevices.
-
 - i.MX7: all of the above, since it uses the imx media core
 
 - i.MX7: use Frame Interval Monitor
-- 
2.17.1


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

* Re: [PATCH v6 17/22] media: imx7: csi: Remove imx7_csi_get_upstream_endpoint()
  2020-05-01 17:15 ` [PATCH v6 17/22] media: imx7: csi: Remove imx7_csi_get_upstream_endpoint() Steve Longerbeam
@ 2020-05-04  9:10   ` Rui Miguel Silva
  0 siblings, 0 replies; 28+ messages in thread
From: Rui Miguel Silva @ 2020-05-04  9:10 UTC (permalink / raw)
  To: Steve Longerbeam
  Cc: linux-media, Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Laurent Pinchart, Philipp Zabel

Hi Steve,
thanks for the work here to make imx7 better :)

On Fri, May 01, 2020 at 10:15:51AM -0700, Steve Longerbeam wrote:
> The function imx7_csi_get_upstream_endpoint() is not necessary for
> imx7. First, the imx7 CSI only receives from the CSI mux, so much of
> the code in there is pointless. Second, it is only used to determine
> whether the CSI mux has selected the CSI-2 input or the parallel input.
> This can be accomplished much more simply by getting the function type
> of selected input entity to the CSI mux.
> 
> Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>

This all rework LGTM, and make even better makes sense.

Acked-by: Rui Miguel Silva <rmfrfs@gmail.com>

------
Cheers,
     Rui
> ---
>  drivers/staging/media/imx/imx7-media-csi.c | 77 ++++------------------
>  1 file changed, 12 insertions(+), 65 deletions(-)
> 
> diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c
> index 21a86fa3d89b..69f7abb32ae1 100644
> --- a/drivers/staging/media/imx/imx7-media-csi.c
> +++ b/drivers/staging/media/imx/imx7-media-csi.c
> @@ -169,8 +169,6 @@ struct imx7_csi {
>  
>  	struct media_entity *sink;
>  
> -	struct v4l2_fwnode_endpoint upstream_ep;
> -
>  	struct v4l2_mbus_framefmt format_mbus[IMX7_CSI_PADS_NUM];
>  	const struct imx_media_pixfmt *cc[IMX7_CSI_PADS_NUM];
>  	struct v4l2_fract frame_interval[IMX7_CSI_PADS_NUM];
> @@ -435,61 +433,6 @@ static void imx7_csi_deinit(struct imx7_csi *csi)
>  	csi->is_init = false;
>  }
>  
> -static int imx7_csi_get_upstream_endpoint(struct imx7_csi *csi,
> -					  struct v4l2_fwnode_endpoint *ep,
> -					  bool skip_mux)
> -{
> -	struct device_node *endpoint, *port;
> -	struct media_entity *src;
> -	struct v4l2_subdev *sd;
> -	struct media_pad *pad;
> -
> -	if (!csi->src_sd)
> -		return -EPIPE;
> -
> -	src = &csi->src_sd->entity;
> -
> -	/*
> -	 * if the source is neither a mux or csi2 get the one directly upstream
> -	 * from this csi
> -	 */
> -	if (src->function != MEDIA_ENT_F_VID_IF_BRIDGE &&
> -	    src->function != MEDIA_ENT_F_VID_MUX)
> -		src = &csi->sd.entity;
> -
> -skip_video_mux:
> -	/* get source pad of entity directly upstream from src */
> -	pad = imx_media_pipeline_pad(src, 0, 0, true);
> -	if (!pad)
> -		return -ENODEV;
> -
> -	sd = media_entity_to_v4l2_subdev(pad->entity);
> -
> -	/* To get bus type we may need to skip video mux */
> -	if (skip_mux && src->function == MEDIA_ENT_F_VID_MUX) {
> -		src = &sd->entity;
> -		goto skip_video_mux;
> -	}
> -
> -	/*
> -	 * NOTE: this assumes an OF-graph port id is the same as a
> -	 * media pad index.
> -	 */
> -	port = of_graph_get_port_by_id(sd->dev->of_node, pad->index);
> -	if (!port)
> -		return -ENODEV;
> -
> -	endpoint = of_get_next_child(port, NULL);
> -	of_node_put(port);
> -	if (!endpoint)
> -		return -ENODEV;
> -
> -	v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), ep);
> -	of_node_put(endpoint);
> -
> -	return 0;
> -}
> -
>  static int imx7_csi_link_setup(struct media_entity *entity,
>  			       const struct media_pad *local,
>  			       const struct media_pad *remote, u32 flags)
> @@ -556,23 +499,27 @@ static int imx7_csi_pad_link_validate(struct v4l2_subdev *sd,
>  				      struct v4l2_subdev_format *sink_fmt)
>  {
>  	struct imx7_csi *csi = v4l2_get_subdevdata(sd);
> -	struct v4l2_fwnode_endpoint upstream_ep = {};
> +	struct media_pad *pad;
>  	int ret;
>  
>  	ret = v4l2_subdev_link_validate_default(sd, link, source_fmt, sink_fmt);
>  	if (ret)
>  		return ret;
>  
> -	ret = imx7_csi_get_upstream_endpoint(csi, &upstream_ep, true);
> -	if (ret) {
> -		v4l2_err(&csi->sd, "failed to find upstream endpoint\n");
> -		return ret;
> -	}
> +	if (!csi->src_sd)
> +		return -EPIPE;
> +
> +	/*
> +	 * find the entity that is selected by the CSI mux. This is needed
> +	 * to distinguish between a parallel or CSI-2 pipeline.
> +	 */
> +	pad = imx_media_pipeline_pad(&csi->src_sd->entity, 0, 0, true);
> +	if (!pad)
> +		return -ENODEV;
>  
>  	mutex_lock(&csi->lock);
>  
> -	csi->upstream_ep = upstream_ep;
> -	csi->is_csi2 = (upstream_ep.bus_type == V4L2_MBUS_CSI2_DPHY);
> +	csi->is_csi2 = (pad->entity->function == MEDIA_ENT_F_VID_IF_BRIDGE);
>  
>  	mutex_unlock(&csi->lock);
>  
> -- 
> 2.17.1
>
> 

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

* Re: [PATCH v6 18/22] media: imx5/6/7: csi: Mark a bound video mux as a CSI mux
  2020-05-01 17:15 ` [PATCH v6 18/22] media: imx5/6/7: csi: Mark a bound video mux as a CSI mux Steve Longerbeam
@ 2020-05-04  9:12   ` Rui Miguel Silva
  0 siblings, 0 replies; 28+ messages in thread
From: Rui Miguel Silva @ 2020-05-04  9:12 UTC (permalink / raw)
  To: Steve Longerbeam
  Cc: linux-media, Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Laurent Pinchart, Philipp Zabel

Hi Steve,

On Fri, May 01, 2020 at 10:15:52AM -0700, Steve Longerbeam wrote:
> For i.MX5/6, if the bound subdev is a video mux, it must be one of the
> CSI muxes, and for i.MX7, the bound subdev must always be a CSI mux.
> 
> So if the bound subdev is a video mux, mark it as a CSI mux with a new
> group id IMX_MEDIA_GRP_ID_CSI_MUX.
> 
> In the process use the new group id in csi_get_upstream_endpoint(), and
> do some cleanup in that function for better readability.
> 
> Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>

for the imx7 check and change, LGTM.

Acked-by: Rui Miguel Silva <rmfrfs@gmail.com>

------
Cheers,
     Rui

> ---
>  drivers/staging/media/imx/imx-media-csi.c  | 45 +++++++++++++---------
>  drivers/staging/media/imx/imx-media.h      |  1 +
>  drivers/staging/media/imx/imx7-media-csi.c |  7 ++++
>  3 files changed, 35 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c
> index a051a063a2db..6cfbe67c43d1 100644
> --- a/drivers/staging/media/imx/imx-media-csi.c
> +++ b/drivers/staging/media/imx/imx-media-csi.c
> @@ -165,7 +165,6 @@ static int csi_get_upstream_endpoint(struct csi_priv *priv,
>  				     struct v4l2_fwnode_endpoint *ep)
>  {
>  	struct device_node *endpoint, *port;
> -	struct media_entity *src;
>  	struct v4l2_subdev *sd;
>  	struct media_pad *pad;
>  
> @@ -176,30 +175,33 @@ static int csi_get_upstream_endpoint(struct csi_priv *priv,
>  		return -EPIPE;
>  
>  	sd = priv->src_sd;
> -	src = &sd->entity;
>  
> -	if (src->function == MEDIA_ENT_F_VID_MUX) {
> +	switch (sd->grp_id) {
> +	case IMX_MEDIA_GRP_ID_CSI_MUX:
>  		/*
> -		 * CSI is connected directly to video mux, skip up to
> +		 * CSI is connected directly to CSI mux, skip up to
>  		 * CSI-2 receiver if it is in the path, otherwise stay
> -		 * with video mux.
> +		 * with the CSI mux.
>  		 */
> -		sd = imx_media_pipeline_subdev(src, IMX_MEDIA_GRP_ID_CSI2,
> +		sd = imx_media_pipeline_subdev(&sd->entity,
> +					       IMX_MEDIA_GRP_ID_CSI2,
>  					       true);
> -		if (!IS_ERR(sd))
> -			src = &sd->entity;
> +		if (IS_ERR(sd))
> +			sd = priv->src_sd;
> +		break;
> +	case IMX_MEDIA_GRP_ID_CSI2:
> +		break;
> +	default:
> +		/*
> +		 * the source is neither the CSI mux nor the CSI-2 receiver,
> +		 * get the source pad directly upstream from CSI itself.
> +		 */
> +		sd = &priv->sd;
> +		break;
>  	}
>  
> -	/*
> -	 * If the source is neither the video mux nor the CSI-2 receiver,
> -	 * get the source pad directly upstream from CSI itself.
> -	 */
> -	if (src->function != MEDIA_ENT_F_VID_MUX &&
> -	    sd->grp_id != IMX_MEDIA_GRP_ID_CSI2)
> -		src = &priv->sd.entity;
> -
> -	/* get source pad of entity directly upstream from src */
> -	pad = imx_media_pipeline_pad(src, 0, 0, true);
> +	/* get source pad of entity directly upstream from sd */
> +	pad = imx_media_pipeline_pad(&sd->entity, 0, 0, true);
>  	if (!pad)
>  		return -ENODEV;
>  
> @@ -1906,6 +1908,13 @@ static int imx_csi_notify_bound(struct v4l2_async_notifier *notifier,
>  	struct csi_priv *priv = notifier_to_dev(notifier);
>  	struct media_pad *sink = &priv->sd.entity.pads[CSI_SINK_PAD];
>  
> +	/*
> +	 * If the subdev is a video mux, it must be one of the CSI
> +	 * muxes. Mark it as such via its group id.
> +	 */
> +	if (sd->entity.function == MEDIA_ENT_F_VID_MUX)
> +		sd->grp_id = IMX_MEDIA_GRP_ID_CSI_MUX;
> +
>  	return v4l2_create_fwnode_links_to_pad(sd, sink);
>  }
>  
> diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h
> index ca36beca16de..b5b7d3245727 100644
> --- a/drivers/staging/media/imx/imx-media.h
> +++ b/drivers/staging/media/imx/imx-media.h
> @@ -311,5 +311,6 @@ void imx_media_csc_scaler_device_unregister(struct imx_media_video_dev *vdev);
>  #define IMX_MEDIA_GRP_ID_IPU_IC_PRP    BIT(13)
>  #define IMX_MEDIA_GRP_ID_IPU_IC_PRPENC BIT(14)
>  #define IMX_MEDIA_GRP_ID_IPU_IC_PRPVF  BIT(15)
> +#define IMX_MEDIA_GRP_ID_CSI_MUX       BIT(16)
>  
>  #endif
> diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c
> index 69f7abb32ae1..a3f3df901704 100644
> --- a/drivers/staging/media/imx/imx7-media-csi.c
> +++ b/drivers/staging/media/imx/imx7-media-csi.c
> @@ -1164,6 +1164,13 @@ static int imx7_csi_notify_bound(struct v4l2_async_notifier *notifier,
>  	struct imx7_csi *csi = imx7_csi_notifier_to_dev(notifier);
>  	struct media_pad *sink = &csi->sd.entity.pads[IMX7_CSI_PAD_SINK];
>  
> +	/* The bound subdev must always be the CSI mux */
> +	if (WARN_ON(sd->entity.function != MEDIA_ENT_F_VID_MUX))
> +		return -ENXIO;
> +
> +	/* Mark it as such via its group id */
> +	sd->grp_id = IMX_MEDIA_GRP_ID_CSI_MUX;
> +
>  	return v4l2_create_fwnode_links_to_pad(sd, sink);
>  }
>  
> -- 
> 2.17.1
> 

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

* Re: [PATCH v6 14/22] media: imx7: mipi csis: Create media links in bound notifier
  2020-05-01 17:15 ` [PATCH v6 14/22] media: imx7: mipi csis: " Steve Longerbeam
@ 2020-05-04  9:12   ` Rui Miguel Silva
  0 siblings, 0 replies; 28+ messages in thread
From: Rui Miguel Silva @ 2020-05-04  9:12 UTC (permalink / raw)
  To: Steve Longerbeam
  Cc: linux-media, Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Laurent Pinchart, Philipp Zabel

Hi Steve,
On Fri, May 01, 2020 at 10:15:48AM -0700, Steve Longerbeam wrote:
> Implement a notifier bound op to register media links from the remote
> sub-device's source pad(s) to the mipi csi-2 receiver sink pad.
> 
> Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>

Acked-by: Rui Miguel Silva <rmfrfs@gmail.com>

------
Cheers,
     Rui

> ---
> Changes in v5:
> - imx_media_create_fwnode_pad_link() has been moved to core as
>   v4l2_create_fwnode_links_to_pad().
> Changes in v4:
> - none
> Changes in v3:
> - call a local imx-media utility imx_media_create_fwnode_pad_link().
> Changes in v2:
> - Move notifier_to_csis_state() next to mipi_sd_to_csis_state(), remove
>   unnecessary inline, and rename to mipi_notifier_to_csis_state().
>   Suggested by Rui Silva.
> ---
>  drivers/staging/media/imx/imx7-mipi-csis.c | 23 ++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
> 
> diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c
> index 7b5c3e662d0d..1025e42740f1 100644
> --- a/drivers/staging/media/imx/imx7-mipi-csis.c
> +++ b/drivers/staging/media/imx/imx7-mipi-csis.c
> @@ -26,6 +26,7 @@
>  
>  #include <media/v4l2-device.h>
>  #include <media/v4l2-fwnode.h>
> +#include <media/v4l2-mc.h>
>  #include <media/v4l2-subdev.h>
>  
>  #define CSIS_DRIVER_NAME			"imx7-mipi-csis"
> @@ -385,6 +386,12 @@ static int mipi_csis_dump_regs(struct csi_state *state)
>  	return 0;
>  }
>  
> +static struct csi_state *
> +mipi_notifier_to_csis_state(struct v4l2_async_notifier *n)
> +{
> +	return container_of(n, struct csi_state, notifier);
> +}
> +
>  static struct csi_state *mipi_sd_to_csis_state(struct v4l2_subdev *sdev)
>  {
>  	return container_of(sdev, struct csi_state, mipi_sd);
> @@ -948,6 +955,20 @@ static int mipi_csis_parse_dt(struct platform_device *pdev,
>  
>  static int mipi_csis_pm_resume(struct device *dev, bool runtime);
>  
> +static int mipi_csis_notify_bound(struct v4l2_async_notifier *notifier,
> +				  struct v4l2_subdev *sd,
> +				  struct v4l2_async_subdev *asd)
> +{
> +	struct csi_state *state = mipi_notifier_to_csis_state(notifier);
> +	struct media_pad *sink = &state->mipi_sd.entity.pads[CSIS_PAD_SINK];
> +
> +	return v4l2_create_fwnode_links_to_pad(sd, sink);
> +}
> +
> +static const struct v4l2_async_notifier_operations mipi_csis_notify_ops = {
> +	.bound = mipi_csis_notify_bound,
> +};
> +
>  static int mipi_csis_subdev_init(struct v4l2_subdev *mipi_sd,
>  				 struct platform_device *pdev,
>  				 const struct v4l2_subdev_ops *ops)
> @@ -1016,6 +1037,8 @@ static int mipi_csis_async_register(struct csi_state *state)
>  
>  	fwnode_handle_put(ep);
>  
> +	state->notifier.ops = &mipi_csis_notify_ops;
> +
>  	ret = v4l2_async_subdev_notifier_register(&state->mipi_sd,
>  						  &state->notifier);
>  	if (ret)
> -- 
> 2.17.1
> 

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

* Re: [PATCH v6 10/22] media: imx: imx7-mipi-csis: Implement get_fwnode_pad op
  2020-05-01 17:15 ` [PATCH v6 10/22] media: imx: imx7-mipi-csis: " Steve Longerbeam
@ 2020-05-04  9:14   ` Rui Miguel Silva
  0 siblings, 0 replies; 28+ messages in thread
From: Rui Miguel Silva @ 2020-05-04  9:14 UTC (permalink / raw)
  To: Steve Longerbeam
  Cc: linux-media, Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Laurent Pinchart, Philipp Zabel

Hi Steve,
On Fri, May 01, 2020 at 10:15:44AM -0700, Steve Longerbeam wrote:
> Use v4l2_subdev_get_fwnode_pad_1_to_1() as the get_fwnode_pad operation.
> The imx7-mipi-csis maps port numbers and pad indexes 1:1.
> 
> Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>

Acked-by: Rui Miguel Silva <rmfrfs@gmail.com>

------
Cheers,
     Rui

> ---
>  drivers/staging/media/imx/imx7-mipi-csis.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c
> index b66299c1136d..7b5c3e662d0d 100644
> --- a/drivers/staging/media/imx/imx7-mipi-csis.c
> +++ b/drivers/staging/media/imx/imx7-mipi-csis.c
> @@ -906,6 +906,7 @@ static const struct v4l2_subdev_core_ops mipi_csis_core_ops = {
>  static const struct media_entity_operations mipi_csis_entity_ops = {
>  	.link_setup	= mipi_csis_link_setup,
>  	.link_validate	= v4l2_subdev_link_validate,
> +	.get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1,
>  };
>  
>  static const struct v4l2_subdev_video_ops mipi_csis_video_ops = {
> -- 
> 2.17.1
> 

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

* Re: [PATCH v6 11/22] media: imx: imx7-media-csi: Implement get_fwnode_pad op
  2020-05-01 17:15 ` [PATCH v6 11/22] media: imx: imx7-media-csi: " Steve Longerbeam
@ 2020-05-04  9:14   ` Rui Miguel Silva
  0 siblings, 0 replies; 28+ messages in thread
From: Rui Miguel Silva @ 2020-05-04  9:14 UTC (permalink / raw)
  To: Steve Longerbeam
  Cc: linux-media, Sakari Ailus, Mauro Carvalho Chehab, Hans Verkuil,
	Laurent Pinchart, Philipp Zabel

Hi,
On Fri, May 01, 2020 at 10:15:45AM -0700, Steve Longerbeam wrote:
> Use v4l2_subdev_get_fwnode_pad_1_to_1() as the get_fwnode_pad operation.
> The i.MX7 CSI maps port numbers and pad indexes 1:1.
> 
> Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>

Acked-by: Rui Miguel Silva <rmfrfs@gmail.com>

------
Cheers,
     Rui

> ---
>  drivers/staging/media/imx/imx7-media-csi.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c
> index abef59dc22b6..c74455f65b3e 100644
> --- a/drivers/staging/media/imx/imx7-media-csi.c
> +++ b/drivers/staging/media/imx/imx7-media-csi.c
> @@ -1179,6 +1179,7 @@ static int imx7_csi_init_cfg(struct v4l2_subdev *sd,
>  static const struct media_entity_operations imx7_csi_entity_ops = {
>  	.link_setup	= imx7_csi_link_setup,
>  	.link_validate	= v4l2_subdev_link_validate,
> +	.get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1,
>  };
>  
>  static const struct v4l2_subdev_video_ops imx7_csi_video_ops = {
> -- 
> 2.17.1
> 

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

end of thread, other threads:[~2020-05-04  9:14 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-01 17:15 [PATCH v6 00/22] media: imx: Create media links in bound notifiers Steve Longerbeam
2020-05-01 17:15 ` [PATCH v6 01/22] media: entity: Pass entity to get_fwnode_pad operation Steve Longerbeam
2020-05-01 17:15 ` [PATCH v6 02/22] media: v4l2-subdev: add v4l2_subdev_get_fwnode_pad_1_to_1 Steve Longerbeam
2020-05-01 17:15 ` [PATCH v6 03/22] media: v4l2-mc: add v4l2_create_fwnode_links helpers Steve Longerbeam
2020-05-01 17:15 ` [PATCH v6 04/22] media: video-mux: Parse information from firmware without using callbacks Steve Longerbeam
2020-05-01 17:15 ` [PATCH v6 05/22] media: imx: " Steve Longerbeam
2020-05-01 17:15 ` [PATCH v6 06/22] Revert "media: v4l2-fwnode: Add a convenience function for registering subdevs with notifiers" Steve Longerbeam
2020-05-01 17:15 ` [PATCH v6 07/22] media: imx: csi: Implement get_fwnode_pad op Steve Longerbeam
2020-05-01 17:15 ` [PATCH v6 08/22] media: video-mux: " Steve Longerbeam
2020-05-01 17:15 ` [PATCH v6 09/22] media: imx: mipi csi-2: " Steve Longerbeam
2020-05-01 17:15 ` [PATCH v6 10/22] media: imx: imx7-mipi-csis: " Steve Longerbeam
2020-05-04  9:14   ` Rui Miguel Silva
2020-05-01 17:15 ` [PATCH v6 11/22] media: imx: imx7-media-csi: " Steve Longerbeam
2020-05-04  9:14   ` Rui Miguel Silva
2020-05-01 17:15 ` [PATCH v6 12/22] media: video-mux: Create media links in bound notifier Steve Longerbeam
2020-05-01 17:15 ` [PATCH v6 13/22] media: imx: mipi csi-2: " Steve Longerbeam
2020-05-01 17:15 ` [PATCH v6 14/22] media: imx7: mipi csis: " Steve Longerbeam
2020-05-04  9:12   ` Rui Miguel Silva
2020-05-01 17:15 ` [PATCH v6 15/22] media: imx7: csi: " Steve Longerbeam
2020-05-01 17:15 ` [PATCH v6 16/22] media: imx: " Steve Longerbeam
2020-05-01 17:15 ` [PATCH v6 17/22] media: imx7: csi: Remove imx7_csi_get_upstream_endpoint() Steve Longerbeam
2020-05-04  9:10   ` Rui Miguel Silva
2020-05-01 17:15 ` [PATCH v6 18/22] media: imx5/6/7: csi: Mark a bound video mux as a CSI mux Steve Longerbeam
2020-05-04  9:12   ` Rui Miguel Silva
2020-05-01 17:15 ` [PATCH v6 19/22] media: imx: csi: Lookup upstream endpoint with imx_media_get_pad_fwnode Steve Longerbeam
2020-05-01 17:15 ` [PATCH v6 20/22] media: imx: Create missing links from CSI-2 receiver Steve Longerbeam
2020-05-01 17:15 ` [PATCH v6 21/22] media: imx: silence a couple debug messages Steve Longerbeam
2020-05-01 17:15 ` [PATCH v6 22/22] media: imx: TODO: Remove media link creation todos Steve Longerbeam

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.