summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/fdtdec.h23
-rw-r--r--lib/fdtdec.c22
2 files changed, 41 insertions, 4 deletions
diff --git a/include/fdtdec.h b/include/fdtdec.h
index 6249f22e81..1e198f8c63 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -213,6 +213,29 @@ int fdtdec_find_aliases_for_id(const void *blob, const char *name,
enum fdt_compat_id id, int *node_list, int maxcount);
/*
+ * This function is similar to fdtdec_find_aliases_for_id() except that it
+ * adds to the node_list that is passed in. Any 0 elements are considered
+ * available for allocation - others are considered already used and are
+ * skipped.
+ *
+ * You can use this by calling fdtdec_find_aliases_for_id() with an
+ * uninitialised array, then setting the elements that are returned to -1,
+ * say, then calling this function, perhaps with a different compat id.
+ * Any elements you get back that are >0 are new nodes added by the call
+ * to this function.
+ *
+ * Note that if you have some nodes with aliases and some without, you are
+ * sailing close to the wind. The call to fdtdec_find_aliases_for_id() with
+ * one compat_id may fill in positions for which you have aliases defined
+ * for another compat_id. When you later call *this* function with the second
+ * compat_id, the alias positions may already be used. A debug warning may
+ * be generated in this case, but it is safest to define aliases for all
+ * nodes when you care about the ordering.
+ */
+int fdtdec_add_aliases_for_id(const void *blob, const char *name,
+ enum fdt_compat_id id, int *node_list, int maxcount);
+
+/*
* Get the name for a compatible ID
*
* @param id Compatible ID to look for
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 5239e79479..2149bd7068 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -153,10 +153,18 @@ int fdtdec_next_alias(const void *blob, const char *name,
return node;
}
-/* TODO: Can we tighten this code up a little? */
int fdtdec_find_aliases_for_id(const void *blob, const char *name,
enum fdt_compat_id id, int *node_list, int maxcount)
{
+ memset(node_list, '\0', sizeof(*node_list) * maxcount);
+
+ return fdtdec_add_aliases_for_id(blob, name, id, node_list, maxcount);
+}
+
+/* TODO: Can we tighten this code up a little? */
+int fdtdec_add_aliases_for_id(const void *blob, const char *name,
+ enum fdt_compat_id id, int *node_list, int maxcount)
+{
int name_len = strlen(name);
int nodes[maxcount];
int num_found = 0;
@@ -185,8 +193,6 @@ int fdtdec_find_aliases_for_id(const void *blob, const char *name,
__func__, name);
/* Now find all the aliases */
- memset(node_list, '\0', sizeof(*node_list) * maxcount);
-
for (offset = fdt_first_property_offset(blob, alias_node);
offset > 0;
offset = fdt_next_property_offset(blob, offset)) {
@@ -233,11 +239,19 @@ int fdtdec_find_aliases_for_id(const void *blob, const char *name,
* it as done.
*/
if (fdtdec_get_is_enabled(blob, node)) {
+ if (node_list[number]) {
+ debug("%s: warning: alias '%s' requires that "
+ "a node be placed in the list in a "
+ "position which is already filled by "
+ "node '%s'\n", __func__, path,
+ fdt_get_name(blob, node, NULL));
+ continue;
+ }
node_list[number] = node;
if (number >= num_found)
num_found = number + 1;
}
- nodes[j] = 0;
+ nodes[found] = 0;
}
/* Add any nodes not mentioned by an alias */
OpenPOWER on IntegriCloud