[PATCH] Add of_platform_device_scan().

Scott Wood scottwood at freescale.com
Wed Oct 4 08:56:59 EST 2006


This patch adds of_platform_device_scan(), which adds matching device
nodes to the of_platform bus.  The goal is to let drivers reuse the match
struct to do this, rather than have special code in fsl_soc.c (or
equivalent) that knows which nodes to add.

This will be used by the ucc_geth.c driver; in the current QE patchset,
it registers an of_platform driver for devices that never get registered.

Signed-off-by: Scott Wood <scottwood at freescale.com>
---
 arch/powerpc/kernel/of_device.c |   80 ++++++++++++++++++++++++++++++---------
 include/asm-powerpc/of_device.h |    1 
 2 files changed, 63 insertions(+), 18 deletions(-)

diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
index 397c83e..1bd8fe6 100644
--- a/arch/powerpc/kernel/of_device.c
+++ b/arch/powerpc/kernel/of_device.c
@@ -8,36 +8,50 @@ #include <linux/slab.h>
 #include <asm/errno.h>
 #include <asm/of_device.h>
 
+static const struct of_device_id *
+of_match_device_by_node(const struct of_device_id *matches,
+                        struct device_node *node)
+{
+	while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
+		int match = 1;
+
+		if (matches->name[0] && (!node->name ||
+		    strcmp(matches->name, node->name)))
+			match = 0;
+
+		if (matches->type[0] && (!node->type ||
+		    strcmp(matches->type, node->type)))
+			match = 0;
+
+		if (matches->compatible[0] &&
+		    !device_is_compatible(node, matches->compatible))
+			match = 0;
+
+		if (match)
+			return matches;
+
+		matches++;
+	}
+
+	return NULL;
+}
+
 /**
  * of_match_device - Tell if an of_device structure has a matching
  * of_match structure
- * @ids: array of of device match structures to search in
+ * @matches: array of of device match structures to search in
  * @dev: the of device structure to match against
  *
  * Used by a driver to check whether an of_device present in the
  * system is in its list of supported devices.
  */
 const struct of_device_id *of_match_device(const struct of_device_id *matches,
-					const struct of_device *dev)
+                                           const struct of_device *dev)
 {
 	if (!dev->node)
 		return NULL;
-	while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
-		int match = 1;
-		if (matches->name[0])
-			match &= dev->node->name
-				&& !strcmp(matches->name, dev->node->name);
-		if (matches->type[0])
-			match &= dev->node->type
-				&& !strcmp(matches->type, dev->node->type);
-		if (matches->compatible[0])
-			match &= device_is_compatible(dev->node,
-				matches->compatible);
-		if (match)
-			return matches;
-		matches++;
-	}
-	return NULL;
+
+	return of_match_device_by_node(matches, dev->node);
 }
 
 static int of_platform_bus_match(struct device *dev, struct device_driver *drv)
@@ -236,6 +250,35 @@ struct of_device* of_platform_device_cre
 	return dev;
 }
 
+/**
+ * of_platform_device_scan - Find matching device tree nodes and
+ * call of_platform_device_create.
+ * @match: array of of device match structures to search in
+ *
+ * Used by a driver to add device nodes it supports to the platform bus.
+ * @match should be specified so as to exclude any devices that
+ * do not belong on the OF platform bus (e.g. PCI devices,
+ * devices that use the regular platform bus, etc).
+ */
+void of_platform_device_scan(const struct of_device_id *match)
+{
+	char bus_id[BUS_ID_SIZE];
+	struct device_node *np = NULL;
+
+	while ((np = of_find_all_nodes(np))) {
+		struct resource res;
+
+		if (!of_match_device_by_node(match, np))
+			continue;
+
+		if (of_address_to_resource(np, 0, &res))
+			continue;
+
+		snprintf(bus_id, BUS_ID_SIZE, "%x", res.start);
+		of_platform_device_create(np, bus_id, NULL);
+	}
+}
+
 EXPORT_SYMBOL(of_match_device);
 EXPORT_SYMBOL(of_platform_bus_type);
 EXPORT_SYMBOL(of_register_driver);
@@ -246,3 +289,4 @@ EXPORT_SYMBOL(of_dev_get);
 EXPORT_SYMBOL(of_dev_put);
 EXPORT_SYMBOL(of_platform_device_create);
 EXPORT_SYMBOL(of_release_dev);
+EXPORT_SYMBOL(of_platform_device_scan);
diff --git a/include/asm-powerpc/of_device.h b/include/asm-powerpc/of_device.h
index c5c0b0b..9f84c41 100644
--- a/include/asm-powerpc/of_device.h
+++ b/include/asm-powerpc/of_device.h
@@ -61,6 +61,7 @@ extern struct of_device *of_platform_dev
 						   const char *bus_id,
 						   struct device *parent);
 extern void of_release_dev(struct device *dev);
+extern void of_platform_device_scan(const struct of_device_id *match);
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_OF_DEVICE_H */
-- 
1.4.2.1




More information about the Linuxppc-dev mailing list