Commit c67822704b73dcfb86debf4c25151e43309af844

Authored by Simon Glass
Committed by Albert ARIBAUD
1 parent f4589a7d6f

fdt: Add function to allow aliases to refer to multiple nodes

Some devices can deal with multiple compatible properties. The devices
need to know which nodes to bind to which features. For example an
I2C driver which supports two different controller types will want to
know which type it is dealing with in each case.

The new fdtdec_add_aliases_for_id() function deals with this by allowing
the driver to search for additional compatible nodes for a different ID.
It can then detect the new ones and perform appropriate processing.

Another option considered was to return a tuple (node offset, compat id)
and have the function be passed a list of compatible IDs. This is more
overhead for the common case though. We may add such a function later if
more drivers in U-Boot require it.

Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Tom Warren <twarren@nvidia.com>

Showing 2 changed files with 41 additions and 4 deletions Side-by-side Diff

... ... @@ -213,6 +213,29 @@
213 213 enum fdt_compat_id id, int *node_list, int maxcount);
214 214  
215 215 /*
  216 + * This function is similar to fdtdec_find_aliases_for_id() except that it
  217 + * adds to the node_list that is passed in. Any 0 elements are considered
  218 + * available for allocation - others are considered already used and are
  219 + * skipped.
  220 + *
  221 + * You can use this by calling fdtdec_find_aliases_for_id() with an
  222 + * uninitialised array, then setting the elements that are returned to -1,
  223 + * say, then calling this function, perhaps with a different compat id.
  224 + * Any elements you get back that are >0 are new nodes added by the call
  225 + * to this function.
  226 + *
  227 + * Note that if you have some nodes with aliases and some without, you are
  228 + * sailing close to the wind. The call to fdtdec_find_aliases_for_id() with
  229 + * one compat_id may fill in positions for which you have aliases defined
  230 + * for another compat_id. When you later call *this* function with the second
  231 + * compat_id, the alias positions may already be used. A debug warning may
  232 + * be generated in this case, but it is safest to define aliases for all
  233 + * nodes when you care about the ordering.
  234 + */
  235 +int fdtdec_add_aliases_for_id(const void *blob, const char *name,
  236 + enum fdt_compat_id id, int *node_list, int maxcount);
  237 +
  238 +/*
216 239 * Get the name for a compatible ID
217 240 *
218 241 * @param id Compatible ID to look for
... ... @@ -153,10 +153,18 @@
153 153 return node;
154 154 }
155 155  
156   -/* TODO: Can we tighten this code up a little? */
157 156 int fdtdec_find_aliases_for_id(const void *blob, const char *name,
158 157 enum fdt_compat_id id, int *node_list, int maxcount)
159 158 {
  159 + memset(node_list, '\0', sizeof(*node_list) * maxcount);
  160 +
  161 + return fdtdec_add_aliases_for_id(blob, name, id, node_list, maxcount);
  162 +}
  163 +
  164 +/* TODO: Can we tighten this code up a little? */
  165 +int fdtdec_add_aliases_for_id(const void *blob, const char *name,
  166 + enum fdt_compat_id id, int *node_list, int maxcount)
  167 +{
160 168 int name_len = strlen(name);
161 169 int nodes[maxcount];
162 170 int num_found = 0;
... ... @@ -185,8 +193,6 @@
185 193 __func__, name);
186 194  
187 195 /* Now find all the aliases */
188   - memset(node_list, '\0', sizeof(*node_list) * maxcount);
189   -
190 196 for (offset = fdt_first_property_offset(blob, alias_node);
191 197 offset > 0;
192 198 offset = fdt_next_property_offset(blob, offset)) {
193 199  
... ... @@ -233,11 +239,19 @@
233 239 * it as done.
234 240 */
235 241 if (fdtdec_get_is_enabled(blob, node)) {
  242 + if (node_list[number]) {
  243 + debug("%s: warning: alias '%s' requires that "
  244 + "a node be placed in the list in a "
  245 + "position which is already filled by "
  246 + "node '%s'\n", __func__, path,
  247 + fdt_get_name(blob, node, NULL));
  248 + continue;
  249 + }
236 250 node_list[number] = node;
237 251 if (number >= num_found)
238 252 num_found = number + 1;
239 253 }
240   - nodes[j] = 0;
  254 + nodes[found] = 0;
241 255 }
242 256  
243 257 /* Add any nodes not mentioned by an alias */