svn commit: r282770 - head/sys/dev/ofw

Andrew Turner andrew at FreeBSD.org
Mon May 11 14:10:55 UTC 2015


Author: andrew
Date: Mon May 11 14:10:54 2015
New Revision: 282770
URL: https://svnweb.freebsd.org/changeset/base/282770

Log:
  Add ofw_bus_find_compatible to find a compatible ofw node. This will be
  used on ARM to help find the correct node to use to start secondary CPUs
  as this happens before device enumeration.

Modified:
  head/sys/dev/ofw/ofw_bus_subr.c

Modified: head/sys/dev/ofw/ofw_bus_subr.c
==============================================================================
--- head/sys/dev/ofw/ofw_bus_subr.c	Mon May 11 14:07:48 2015	(r282769)
+++ head/sys/dev/ofw/ofw_bus_subr.c	Mon May 11 14:10:54 2015	(r282770)
@@ -176,12 +176,37 @@ ofw_bus_status_okay(device_t dev)
 	return (0);
 }
 
+static int
+ofw_bus_node_is_compatible(const char *compat, int len, const char *onecompat)
+{
+	int onelen, l, ret;
+
+	onelen = strlen(onecompat);
+
+	ret = 0;
+	while (len > 0) {
+		if (strlen(compat) == onelen &&
+		    strncasecmp(compat, onecompat, onelen) == 0) {
+			/* Found it. */
+			ret = 1;
+			break;
+		}
+
+		/* Slide to the next sub-string. */
+		l = strlen(compat) + 1;
+		compat += l;
+		len -= l;
+	}
+
+	return (ret);
+}
+
 int
 ofw_bus_is_compatible(device_t dev, const char *onecompat)
 {
 	phandle_t node;
 	const char *compat;
-	int len, onelen, l;
+	int len;
 
 	if ((compat = ofw_bus_get_compat(dev)) == NULL)
 		return (0);
@@ -193,20 +218,7 @@ ofw_bus_is_compatible(device_t dev, cons
 	if ((len = OF_getproplen(node, "compatible")) <= 0)
 		return (0);
 
-	onelen = strlen(onecompat);
-
-	while (len > 0) {
-		if (strlen(compat) == onelen &&
-		    strncasecmp(compat, onecompat, onelen) == 0)
-			/* Found it. */
-			return (1);
-
-		/* Slide to the next sub-string. */
-		l = strlen(compat) + 1;
-		compat += l;
-		len -= l;
-	}
-	return (0);
+	return (ofw_bus_node_is_compatible(compat, len, onecompat));
 }
 
 int
@@ -487,3 +499,30 @@ ofw_bus_intr_to_rl(device_t dev, phandle
 	return (err);
 }
 
+phandle_t
+ofw_bus_find_compatible(phandle_t node, const char *onecompat)
+{
+	phandle_t child, ret;
+	void *compat;
+	int len;
+
+	/*
+	 * Traverse all children of 'start' node, and find first with
+	 * matching 'compatible' property.
+	 */
+	for (child = OF_child(node); child != 0; child = OF_peer(child)) {
+		len = OF_getprop_alloc(node, "compatible", 1, &compat);
+		if (len >= 0) {
+			ret = ofw_bus_node_is_compatible(compat, len,
+			    onecompat);
+			free(compat, M_OFWPROP);
+			if (ret != 0)
+				return (child);
+		}
+
+		ret = ofw_bus_find_compatible(child, onecompat);
+		if (ret != 0)
+			return (ret);
+	}
+	return (0);
+}


More information about the svn-src-all mailing list