All of lore.kernel.org
 help / color / mirror / Atom feed
From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
To: dri-devel@lists.freedesktop.org, linux-fbdev@vger.kernel.org,
	linux-media@vger.kernel.org
Subject: [PATCH/RFC v3 05/19] video: display: Graph helpers
Date: Sat, 10 Aug 2013 01:03:04 +0200	[thread overview]
Message-ID: <1376089398-13322-6-git-send-email-laurent.pinchart+renesas@ideasonboard.com> (raw)
In-Reply-To: <1376089398-13322-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>

Add two graph helper functions. display_entity_build_notifier() builds
an entity notifier from an entities graph represented as a flat array,
typically passed from platform data. display_entity_link_graph() can
then be used to create media controller links between all entities in
the graph.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/video/display/display-core.c     | 107 +++++++++++++++++++++++++++++++
 drivers/video/display/display-notifier.c |  51 +++++++++++++++
 include/video/display.h                  |  20 ++++++
 3 files changed, 178 insertions(+)

diff --git a/drivers/video/display/display-core.c b/drivers/video/display/display-core.c
index bb18723..c3b47d3 100644
--- a/drivers/video/display/display-core.c
+++ b/drivers/video/display/display-core.c
@@ -10,6 +10,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/device.h>
 #include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -313,6 +314,112 @@ void display_entity_unregister(struct display_entity *entity)
 }
 EXPORT_SYMBOL_GPL(display_entity_unregister);
 
+/* -----------------------------------------------------------------------------
+ * Graph Helpers
+ */
+
+static int display_entity_link_entity(struct device *dev,
+				      struct display_entity *entity,
+				      struct list_head *entities)
+{
+	const struct display_entity_graph_data *graph = entity->match->data;
+	u32 link_flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED;
+	struct media_entity *local = &entity->entity;
+	unsigned int i;
+	int ret = 0;
+
+	dev_dbg(dev, "creating links for entity %s\n", local->name);
+
+	for (i = 0; i < entity->entity.num_pads; ++i) {
+		const struct display_entity_source_data *source;
+		struct media_pad *local_pad = &local->pads[i];
+		struct media_entity *remote = NULL;
+		struct media_pad *remote_pad;
+		struct display_entity *ent;
+
+		dev_dbg(dev, "processing pad %u\n", i);
+
+		/* Skip source pads, they will be processed from the other end
+		 * of the link.
+		 */
+		if (local_pad->flags & MEDIA_PAD_FL_SOURCE) {
+			dev_dbg(dev, "skipping source pad %s:%u\n",
+				local->name, i);
+			continue;
+		}
+
+		/* Find the remote entity. If not found, just skip the link as
+		 * it goes out of scope of the entities handled by the notifier.
+		 */
+		source = &graph->sources[i];
+		list_for_each_entry(ent, entities, list) {
+			if (strcmp(source->name, dev_name(ent->dev)) == 0) {
+				remote = &ent->entity;
+				break;
+			}
+		}
+
+		if (remote == NULL) {
+			dev_dbg(dev, "no entity found for %s\n", source->name);
+			continue;
+		}
+
+		if (source->port >= remote->num_pads) {
+			dev_err(dev, "invalid port number %u on %s\n",
+				source->port, source->name);
+			ret = -EINVAL;
+			break;
+		}
+
+		remote_pad = &remote->pads[source->port];
+
+		/* Create the media link. */
+		dev_dbg(dev, "creating %s:%u -> %s:%u link\n",
+			remote->name, remote_pad->index,
+			local->name, local_pad->index);
+
+		ret = media_entity_create_link(remote, remote_pad->index,
+					       local, local_pad->index,
+					       link_flags);
+		if (ret < 0) {
+			dev_err(dev, "failed to create %s:%u -> %s:%u link\n",
+				remote->name, remote_pad->index,
+				local->name, local_pad->index);
+			break;
+		}
+	}
+
+	return ret;
+}
+
+/**
+ * display_entity_link_graph - Link all entities in a graph
+ * @dev: device used to print debugging and error messages
+ * @entities: list of display entities in the graph
+ *
+ * This function creates media controller links for all entities in a graph
+ * based on graph link data. It relies on the entities match data pointers
+ * having been initialized by the display_entity_build_notifier() function when
+ * building the notifier and thus can't be used when the notifier is built in a
+ * different way.
+ *
+ * Return 0 on success or a negative error code otherwise.
+ */
+int display_entity_link_graph(struct device *dev, struct list_head *entities)
+{
+	struct display_entity *entity;
+	int ret;
+
+	list_for_each_entry(entity, entities, list) {
+		ret = display_entity_link_entity(dev, entity, entities);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(display_entity_link_graph);
+
 MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
 MODULE_DESCRIPTION("Display Core");
 MODULE_LICENSE("GPL");
diff --git a/drivers/video/display/display-notifier.c b/drivers/video/display/display-notifier.c
index c9210ec..2d752b3 100644
--- a/drivers/video/display/display-notifier.c
+++ b/drivers/video/display/display-notifier.c
@@ -220,6 +220,57 @@ void display_entity_unregister_notifier(struct display_entity_notifier *notifier
 }
 EXPORT_SYMBOL_GPL(display_entity_unregister_notifier);
 
+/**
+ * display_entity_build_notifier - build a notifier from graph data
+ * @notifier: display entity notifier to be built
+ * @graph: graph data
+ *
+ * Before registering a notifier drivers must initialize the notifier's list of
+ * entities. This helper function simplifies building the list of entities for
+ * drivers that use an array of struct display_entity_graph_data to describe the
+ * entities graph.
+ *
+ * The function allocates an array of struct display_entity_match, initialize it
+ * from graph data, and sets the notifier entities and num_entities fields.
+ *
+ * The entities array is allocated using the managed memory allocation API on
+ * the notifier device, which must be initialized before calling this function.
+ *
+ * Return 0 on success or a negative error code on error.
+ */
+int display_entity_build_notifier(struct display_entity_notifier *notifier,
+				  const struct display_entity_graph_data *graph)
+{
+	struct display_entity_match *entities;
+	unsigned int num_entities;
+	unsigned int i;
+
+	for (num_entities = 0; graph[num_entities].name; ++num_entities) {
+	}
+
+	if (num_entities == 0)
+		return -EINVAL;
+
+	entities = devm_kzalloc(notifier->dev, sizeof(*notifier->entities) *
+				num_entities, GFP_KERNEL);
+	if (entities == NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < num_entities; ++i) {
+		struct display_entity_match *match = &entities[i];
+
+		match->type = DISPLAY_ENTITY_BUS_PLATFORM;
+		match->match.platform.name = graph[i].name;
+		match->data = &graph[i];
+	}
+
+	notifier->num_entities = num_entities;
+	notifier->entities = entities;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(display_entity_build_notifier);
+
 /* -----------------------------------------------------------------------------
  * Entity Registration
  */
diff --git a/include/video/display.h b/include/video/display.h
index 2063694..58ff0d1 100644
--- a/include/video/display.h
+++ b/include/video/display.h
@@ -159,6 +159,7 @@ enum display_entity_bus_type {
  * @match.platform.name: platform device name
  * @match.dt.node: DT node
  * @list: link match objects waiting to be matched
+ * @data: driver private data, not touched by the core
  */
 struct display_entity_match {
 	enum display_entity_bus_type type;
@@ -169,6 +170,7 @@ struct display_entity_match {
 	} match;
 
 	struct list_head list;
+	const void *data;
 };
 
 /**
@@ -206,4 +208,22 @@ void display_entity_unregister_notifier(struct display_entity_notifier *notifier
 int display_entity_add(struct display_entity *entity);
 void display_entity_remove(struct display_entity *entity);
 
+/* -----------------------------------------------------------------------------
+ * Graph Helpers
+ */
+
+struct display_entity_source_data {
+	const char *name;
+	unsigned int port;
+};
+
+struct display_entity_graph_data {
+	const char *name;
+	const struct display_entity_source_data *sources;
+};
+
+int display_entity_build_notifier(struct display_entity_notifier *notifier,
+				  const struct display_entity_graph_data *graph);
+int display_entity_link_graph(struct device *dev, struct list_head *entities);
+
 #endif /* __DISPLAY_H__ */
-- 
1.8.1.5


WARNING: multiple messages have this Message-ID (diff)
From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
To: dri-devel@lists.freedesktop.org, linux-fbdev@vger.kernel.org,
	linux-media@vger.kernel.org
Subject: [PATCH/RFC v3 05/19] video: display: Graph helpers
Date: Fri, 09 Aug 2013 23:03:04 +0000	[thread overview]
Message-ID: <1376089398-13322-6-git-send-email-laurent.pinchart+renesas@ideasonboard.com> (raw)
In-Reply-To: <1376089398-13322-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>

Add two graph helper functions. display_entity_build_notifier() builds
an entity notifier from an entities graph represented as a flat array,
typically passed from platform data. display_entity_link_graph() can
then be used to create media controller links between all entities in
the graph.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/video/display/display-core.c     | 107 +++++++++++++++++++++++++++++++
 drivers/video/display/display-notifier.c |  51 +++++++++++++++
 include/video/display.h                  |  20 ++++++
 3 files changed, 178 insertions(+)

diff --git a/drivers/video/display/display-core.c b/drivers/video/display/display-core.c
index bb18723..c3b47d3 100644
--- a/drivers/video/display/display-core.c
+++ b/drivers/video/display/display-core.c
@@ -10,6 +10,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/device.h>
 #include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -313,6 +314,112 @@ void display_entity_unregister(struct display_entity *entity)
 }
 EXPORT_SYMBOL_GPL(display_entity_unregister);
 
+/* -----------------------------------------------------------------------------
+ * Graph Helpers
+ */
+
+static int display_entity_link_entity(struct device *dev,
+				      struct display_entity *entity,
+				      struct list_head *entities)
+{
+	const struct display_entity_graph_data *graph = entity->match->data;
+	u32 link_flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED;
+	struct media_entity *local = &entity->entity;
+	unsigned int i;
+	int ret = 0;
+
+	dev_dbg(dev, "creating links for entity %s\n", local->name);
+
+	for (i = 0; i < entity->entity.num_pads; ++i) {
+		const struct display_entity_source_data *source;
+		struct media_pad *local_pad = &local->pads[i];
+		struct media_entity *remote = NULL;
+		struct media_pad *remote_pad;
+		struct display_entity *ent;
+
+		dev_dbg(dev, "processing pad %u\n", i);
+
+		/* Skip source pads, they will be processed from the other end
+		 * of the link.
+		 */
+		if (local_pad->flags & MEDIA_PAD_FL_SOURCE) {
+			dev_dbg(dev, "skipping source pad %s:%u\n",
+				local->name, i);
+			continue;
+		}
+
+		/* Find the remote entity. If not found, just skip the link as
+		 * it goes out of scope of the entities handled by the notifier.
+		 */
+		source = &graph->sources[i];
+		list_for_each_entry(ent, entities, list) {
+			if (strcmp(source->name, dev_name(ent->dev)) = 0) {
+				remote = &ent->entity;
+				break;
+			}
+		}
+
+		if (remote = NULL) {
+			dev_dbg(dev, "no entity found for %s\n", source->name);
+			continue;
+		}
+
+		if (source->port >= remote->num_pads) {
+			dev_err(dev, "invalid port number %u on %s\n",
+				source->port, source->name);
+			ret = -EINVAL;
+			break;
+		}
+
+		remote_pad = &remote->pads[source->port];
+
+		/* Create the media link. */
+		dev_dbg(dev, "creating %s:%u -> %s:%u link\n",
+			remote->name, remote_pad->index,
+			local->name, local_pad->index);
+
+		ret = media_entity_create_link(remote, remote_pad->index,
+					       local, local_pad->index,
+					       link_flags);
+		if (ret < 0) {
+			dev_err(dev, "failed to create %s:%u -> %s:%u link\n",
+				remote->name, remote_pad->index,
+				local->name, local_pad->index);
+			break;
+		}
+	}
+
+	return ret;
+}
+
+/**
+ * display_entity_link_graph - Link all entities in a graph
+ * @dev: device used to print debugging and error messages
+ * @entities: list of display entities in the graph
+ *
+ * This function creates media controller links for all entities in a graph
+ * based on graph link data. It relies on the entities match data pointers
+ * having been initialized by the display_entity_build_notifier() function when
+ * building the notifier and thus can't be used when the notifier is built in a
+ * different way.
+ *
+ * Return 0 on success or a negative error code otherwise.
+ */
+int display_entity_link_graph(struct device *dev, struct list_head *entities)
+{
+	struct display_entity *entity;
+	int ret;
+
+	list_for_each_entry(entity, entities, list) {
+		ret = display_entity_link_entity(dev, entity, entities);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(display_entity_link_graph);
+
 MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
 MODULE_DESCRIPTION("Display Core");
 MODULE_LICENSE("GPL");
diff --git a/drivers/video/display/display-notifier.c b/drivers/video/display/display-notifier.c
index c9210ec..2d752b3 100644
--- a/drivers/video/display/display-notifier.c
+++ b/drivers/video/display/display-notifier.c
@@ -220,6 +220,57 @@ void display_entity_unregister_notifier(struct display_entity_notifier *notifier
 }
 EXPORT_SYMBOL_GPL(display_entity_unregister_notifier);
 
+/**
+ * display_entity_build_notifier - build a notifier from graph data
+ * @notifier: display entity notifier to be built
+ * @graph: graph data
+ *
+ * Before registering a notifier drivers must initialize the notifier's list of
+ * entities. This helper function simplifies building the list of entities for
+ * drivers that use an array of struct display_entity_graph_data to describe the
+ * entities graph.
+ *
+ * The function allocates an array of struct display_entity_match, initialize it
+ * from graph data, and sets the notifier entities and num_entities fields.
+ *
+ * The entities array is allocated using the managed memory allocation API on
+ * the notifier device, which must be initialized before calling this function.
+ *
+ * Return 0 on success or a negative error code on error.
+ */
+int display_entity_build_notifier(struct display_entity_notifier *notifier,
+				  const struct display_entity_graph_data *graph)
+{
+	struct display_entity_match *entities;
+	unsigned int num_entities;
+	unsigned int i;
+
+	for (num_entities = 0; graph[num_entities].name; ++num_entities) {
+	}
+
+	if (num_entities = 0)
+		return -EINVAL;
+
+	entities = devm_kzalloc(notifier->dev, sizeof(*notifier->entities) *
+				num_entities, GFP_KERNEL);
+	if (entities = NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < num_entities; ++i) {
+		struct display_entity_match *match = &entities[i];
+
+		match->type = DISPLAY_ENTITY_BUS_PLATFORM;
+		match->match.platform.name = graph[i].name;
+		match->data = &graph[i];
+	}
+
+	notifier->num_entities = num_entities;
+	notifier->entities = entities;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(display_entity_build_notifier);
+
 /* -----------------------------------------------------------------------------
  * Entity Registration
  */
diff --git a/include/video/display.h b/include/video/display.h
index 2063694..58ff0d1 100644
--- a/include/video/display.h
+++ b/include/video/display.h
@@ -159,6 +159,7 @@ enum display_entity_bus_type {
  * @match.platform.name: platform device name
  * @match.dt.node: DT node
  * @list: link match objects waiting to be matched
+ * @data: driver private data, not touched by the core
  */
 struct display_entity_match {
 	enum display_entity_bus_type type;
@@ -169,6 +170,7 @@ struct display_entity_match {
 	} match;
 
 	struct list_head list;
+	const void *data;
 };
 
 /**
@@ -206,4 +208,22 @@ void display_entity_unregister_notifier(struct display_entity_notifier *notifier
 int display_entity_add(struct display_entity *entity);
 void display_entity_remove(struct display_entity *entity);
 
+/* -----------------------------------------------------------------------------
+ * Graph Helpers
+ */
+
+struct display_entity_source_data {
+	const char *name;
+	unsigned int port;
+};
+
+struct display_entity_graph_data {
+	const char *name;
+	const struct display_entity_source_data *sources;
+};
+
+int display_entity_build_notifier(struct display_entity_notifier *notifier,
+				  const struct display_entity_graph_data *graph);
+int display_entity_link_graph(struct device *dev, struct list_head *entities);
+
 #endif /* __DISPLAY_H__ */
-- 
1.8.1.5


  parent reply	other threads:[~2013-08-09 23:02 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-09 23:02 [PATCH/RFC v3 00/19] Common Display Framework Laurent Pinchart
2013-08-09 23:02 ` Laurent Pinchart
2013-08-09 23:03 ` [PATCH/RFC v3 01/19] OMAPDSS: panels: Rename Kconfig options to OMAP2_DISPLAY_* Laurent Pinchart
2013-08-09 23:03   ` Laurent Pinchart
2013-08-09 23:03 ` [PATCH/RFC v3 02/19] video: Add Common Display Framework core Laurent Pinchart
2013-08-09 23:03   ` Laurent Pinchart
2013-08-09 23:03 ` [PATCH/RFC v3 03/19] video: display: Add video and stream control operations Laurent Pinchart
2013-08-09 23:03   ` Laurent Pinchart
2013-08-09 23:03 ` [PATCH/RFC v3 04/19] video: display: Add display entity notifier Laurent Pinchart
2013-08-09 23:03   ` Laurent Pinchart
2013-08-09 23:03 ` Laurent Pinchart [this message]
2013-08-09 23:03   ` [PATCH/RFC v3 05/19] video: display: Graph helpers Laurent Pinchart
2013-08-09 23:03 ` [PATCH/RFC v3 06/19] video: display: OF support Laurent Pinchart
2013-08-09 23:03   ` Laurent Pinchart
2013-08-27  9:30   ` Philipp Zabel
2013-08-27  9:30     ` Philipp Zabel
2013-08-30  0:47     ` Laurent Pinchart
2013-08-30  0:47       ` Laurent Pinchart
2013-09-04 14:21   ` Philipp Zabel
2013-09-04 14:21     ` Philipp Zabel
2013-09-11 11:33     ` Laurent Pinchart
2013-09-11 11:33       ` Laurent Pinchart
2013-09-11 13:14       ` Philipp Zabel
2013-09-11 13:14         ` Philipp Zabel
2013-09-11 13:48       ` Hans Verkuil
2013-09-11 13:48         ` Hans Verkuil
2013-08-09 23:03 ` [PATCH/RFC v3 07/19] video: display: Add pixel coding definitions Laurent Pinchart
2013-08-09 23:03   ` Laurent Pinchart
2013-08-09 23:03 ` [PATCH/RFC v3 08/19] video: display: Add MIPI DBI bus support Laurent Pinchart
2013-08-09 23:03   ` Laurent Pinchart
2013-08-09 23:03 ` [PATCH/RFC v3 09/19] video: panel: Add DPI panel support Laurent Pinchart
2013-08-09 23:03   ` Laurent Pinchart
2013-08-09 23:03 ` [PATCH/RFC v3 10/19] video: panel: Add R61505 " Laurent Pinchart
2013-08-09 23:03   ` Laurent Pinchart
2013-08-09 23:03 ` [PATCH/RFC v3 11/19] video: panel: Add R61517 " Laurent Pinchart
2013-08-09 23:03   ` Laurent Pinchart
2013-08-09 23:03 ` [PATCH/RFC v3 12/19] video: display: Add VGA Digital to Analog Converter support Laurent Pinchart
2013-08-09 23:03   ` Laurent Pinchart
2013-08-09 23:03 ` [PATCH/RFC v3 13/19] video: display: Add VGA connector support Laurent Pinchart
2013-08-09 23:03   ` Laurent Pinchart
2013-08-09 23:03 ` [PATCH/RFC v3 14/19] ARM: shmobile: r8a7790: Add DU clocks for DT Laurent Pinchart
2013-08-09 23:03   ` Laurent Pinchart
2013-08-09 23:03 ` [PATCH/RFC v3 15/19] ARM: shmobile: r8a7790: Add DU device node to device tree Laurent Pinchart
2013-08-09 23:03   ` Laurent Pinchart
2013-08-09 23:03 ` [PATCH/RFC v3 16/19] ARM: shmobile: marzen: Port DU platform data to CDF Laurent Pinchart
2013-08-09 23:03   ` Laurent Pinchart
2013-08-09 23:03 ` [PATCH/RFC v3 17/19] ARM: shmobile: lager: " Laurent Pinchart
2013-08-09 23:03   ` Laurent Pinchart
2013-08-09 23:03 ` [PATCH/RFC v3 18/19] ARM: shmobile: lager-reference: Add display device nodes to device tree Laurent Pinchart
2013-08-09 23:03   ` Laurent Pinchart
2013-08-09 23:03 ` [PATCH/RFC v3 19/19] drm/rcar-du: Port to the Common Display Framework Laurent Pinchart
2013-08-09 23:03   ` Laurent Pinchart
  -- strict thread matches above, loose matches on Subject: below --
2013-08-09 17:14 [PATCH/RFC v3 00/19] " Laurent Pinchart
2013-08-09 17:14 ` [PATCH/RFC v3 05/19] video: display: Graph helpers Laurent Pinchart

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=1376089398-13322-6-git-send-email-laurent.pinchart+renesas@ideasonboard.com \
    --to=laurent.pinchart+renesas@ideasonboard.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-fbdev@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    /path/to/YOUR_REPLY

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

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