diff options
| -rw-r--r-- | include/fdtdec.h | 23 | ||||
| -rw-r--r-- | lib/fdtdec.c | 22 | 
2 files changed, 41 insertions, 4 deletions
| diff --git a/include/fdtdec.h b/include/fdtdec.h index 6249f22e8..1e198f8c6 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 5239e7947..2149bd706 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 */ |