xref: /rk3399_rockchip-uboot/drivers/core/of_access.c (revision 4a2b8db466479ddec6ee85f9fe9d7f934016be9a)
1 /*
2  * Originally from Linux v4.9
3  * Paul Mackerras	August 1996.
4  * Copyright (C) 1996-2005 Paul Mackerras.
5  *
6  * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
7  *   {engebret|bergner}@us.ibm.com
8  *
9  * Adapted for sparc and sparc64 by David S. Miller davem@davemloft.net
10  *
11  * Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell and
12  * Grant Likely.
13  *
14  * Modified for U-Boot
15  * Copyright (c) 2017 Google, Inc
16  *
17  * This file follows drivers/of/base.c with functions in the same order as the
18  * Linux version.
19  *
20  * SPDX-License-Identifier:	GPL-2.0+
21  */
22 
23 #include <common.h>
24 #include <linux/libfdt.h>
25 #include <dm/of_access.h>
26 #include <linux/ctype.h>
27 #include <linux/err.h>
28 #include <linux/ioport.h>
29 
30 DECLARE_GLOBAL_DATA_PTR;
31 
32 #define PROP_HIDE_MAGIC		1
33 
34 /* list of struct alias_prop aliases */
35 LIST_HEAD(aliases_lookup);
36 
37 /* "/aliaes" node */
38 static struct device_node *of_aliases;
39 
40 /* "/chosen" node */
41 static struct device_node *of_chosen;
42 
43 /* node pointed to by the stdout-path alias */
44 static struct device_node *of_stdout;
45 
46 /* pointer to options given after the alias (separated by :) or NULL if none */
47 static const char *of_stdout_options;
48 
49 /**
50  * struct alias_prop - Alias property in 'aliases' node
51  *
52  * The structure represents one alias property of 'aliases' node as
53  * an entry in aliases_lookup list.
54  *
55  * @link:	List node to link the structure in aliases_lookup list
56  * @alias:	Alias property name
57  * @np:		Pointer to device_node that the alias stands for
58  * @id:		Index value from end of alias name
59  * @stem:	Alias string without the index
60  */
61 struct alias_prop {
62 	struct list_head link;
63 	const char *alias;
64 	struct device_node *np;
65 	int id;
66 	char stem[0];
67 };
68 
69 int of_n_addr_cells(const struct device_node *np)
70 {
71 	const __be32 *ip;
72 
73 	do {
74 		if (np->parent)
75 			np = np->parent;
76 		ip = of_get_property(np, "#address-cells", NULL);
77 		if (ip)
78 			return be32_to_cpup(ip);
79 	} while (np->parent);
80 
81 	/* No #address-cells property for the root node */
82 	return OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
83 }
84 
85 int of_n_size_cells(const struct device_node *np)
86 {
87 	const __be32 *ip;
88 
89 	do {
90 		if (np->parent)
91 			np = np->parent;
92 		ip = of_get_property(np, "#size-cells", NULL);
93 		if (ip)
94 			return be32_to_cpup(ip);
95 	} while (np->parent);
96 
97 	/* No #size-cells property for the root node */
98 	return OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
99 }
100 
101 int of_simple_addr_cells(const struct device_node *np)
102 {
103 	const __be32 *ip;
104 
105 	ip = of_get_property(np, "#address-cells", NULL);
106 	if (ip)
107 		return be32_to_cpup(ip);
108 
109 	/* Return a default of 2 to match fdt_address_cells()*/
110 	return 2;
111 }
112 
113 int of_simple_size_cells(const struct device_node *np)
114 {
115 	const __be32 *ip;
116 
117 	ip = of_get_property(np, "#size-cells", NULL);
118 	if (ip)
119 		return be32_to_cpup(ip);
120 
121 	/* Return a default of 2 to match fdt_size_cells()*/
122 	return 2;
123 }
124 
125 struct property *of_find_property(const struct device_node *np,
126 				  const char *name, int *lenp)
127 {
128 	struct property *pp;
129 
130 	if (!np)
131 		return NULL;
132 
133 	for (pp = np->properties; pp; pp = pp->next) {
134 		if (strcmp(pp->name, name) == 0) {
135 			if (lenp)
136 				*lenp = pp->length;
137 			break;
138 		}
139 	}
140 	if (!pp && lenp)
141 		*lenp = -FDT_ERR_NOTFOUND;
142 
143 	return pp;
144 }
145 
146 struct device_node *of_find_all_nodes(struct device_node *prev)
147 {
148 	struct device_node *np;
149 
150 	if (!prev) {
151 		np = gd->of_root;
152 	} else if (prev->child) {
153 		np = prev->child;
154 	} else {
155 		/*
156 		 * Walk back up looking for a sibling, or the end of the
157 		 * structure
158 		 */
159 		np = prev;
160 		while (np->parent && !np->sibling)
161 			np = np->parent;
162 		np = np->sibling; /* Might be null at the end of the tree */
163 	}
164 
165 	return np;
166 }
167 
168 const void *of_get_property(const struct device_node *np, const char *name,
169 			    int *lenp)
170 {
171 	struct property *pp = of_find_property(np, name, lenp);
172 
173 	return pp ? pp->value : NULL;
174 }
175 
176 const char *of_hide_property(struct device_node *np, const char *name)
177 {
178 	struct property *pp;
179 
180 	if (!np)
181 		return NULL;
182 
183 	for (pp = np->properties; pp; pp = pp->next) {
184 		if (strcmp(pp->name, name) == 0) {
185 			pp->name[0] += PROP_HIDE_MAGIC;
186 			return (const char *)pp->name;
187 		}
188 	}
189 
190 	return NULL;
191 }
192 
193 int of_present_property(struct device_node *np, const char *name)
194 {
195 	struct property *pp;
196 
197 	if (!np)
198 		return -FDT_ERR_NOTFOUND;
199 
200 	for (pp = np->properties; pp; pp = pp->next) {
201 		if (strcmp(pp->name, name) == 0) {
202 			pp->name[0] -= PROP_HIDE_MAGIC;
203 			break;
204 		}
205 	}
206 
207 	return 0;
208 }
209 
210 static const char *of_prop_next_string(struct property *prop, const char *cur)
211 {
212 	const void *curv = cur;
213 
214 	if (!prop)
215 		return NULL;
216 
217 	if (!cur)
218 		return prop->value;
219 
220 	curv += strlen(cur) + 1;
221 	if (curv >= prop->value + prop->length)
222 		return NULL;
223 
224 	return curv;
225 }
226 
227 int of_device_is_compatible(const struct device_node *device,
228 			    const char *compat, const char *type,
229 			    const char *name)
230 {
231 	struct property *prop;
232 	const char *cp;
233 	int index = 0, score = 0;
234 
235 	/* Compatible match has highest priority */
236 	if (compat && compat[0]) {
237 		prop = of_find_property(device, "compatible", NULL);
238 		for (cp = of_prop_next_string(prop, NULL); cp;
239 		     cp = of_prop_next_string(prop, cp), index++) {
240 			if (of_compat_cmp(cp, compat, strlen(compat)) == 0) {
241 				score = INT_MAX/2 - (index << 2);
242 				break;
243 			}
244 		}
245 		if (!score)
246 			return 0;
247 	}
248 
249 	/* Matching type is better than matching name */
250 	if (type && type[0]) {
251 		if (!device->type || of_node_cmp(type, device->type))
252 			return 0;
253 		score += 2;
254 	}
255 
256 	/* Matching name is a bit better than not */
257 	if (name && name[0]) {
258 		if (!device->name || of_node_cmp(name, device->name))
259 			return 0;
260 		score++;
261 	}
262 
263 	return score;
264 }
265 
266 bool of_device_is_available(const struct device_node *device)
267 {
268 	const char *status;
269 	int statlen;
270 
271 	if (!device)
272 		return false;
273 
274 	status = of_get_property(device, "status", &statlen);
275 	if (status == NULL)
276 		return true;
277 
278 	if (statlen > 0) {
279 		if (!strcmp(status, "okay"))
280 			return true;
281 	}
282 
283 	return false;
284 }
285 
286 struct device_node *of_get_parent(const struct device_node *node)
287 {
288 	const struct device_node *np;
289 
290 	if (!node)
291 		return NULL;
292 
293 	np = of_node_get(node->parent);
294 
295 	return (struct device_node *)np;
296 }
297 
298 static struct device_node *__of_get_next_child(const struct device_node *node,
299 					       struct device_node *prev)
300 {
301 	struct device_node *next;
302 
303 	if (!node)
304 		return NULL;
305 
306 	next = prev ? prev->sibling : node->child;
307 	/*
308 	 * coverity[dead_error_line : FALSE]
309 	 * Dead code here since our current implementation of of_node_get()
310 	 * always returns NULL (Coverity CID 163245). But we leave it as is
311 	 * since we may want to implement get/put later.
312 	 */
313 	for (; next; next = next->sibling)
314 		if (of_node_get(next))
315 			break;
316 	of_node_put(prev);
317 	return next;
318 }
319 
320 #define __for_each_child_of_node(parent, child) \
321 	for (child = __of_get_next_child(parent, NULL); child != NULL; \
322 	     child = __of_get_next_child(parent, child))
323 
324 static struct device_node *__of_find_node_by_path(struct device_node *parent,
325 						  const char *path)
326 {
327 	struct device_node *child;
328 	int len;
329 
330 	len = strcspn(path, "/:");
331 	if (!len)
332 		return NULL;
333 
334 	__for_each_child_of_node(parent, child) {
335 		const char *name = strrchr(child->full_name, '/');
336 
337 		name++;
338 		if (strncmp(path, name, len) == 0 && (strlen(name) == len))
339 			return child;
340 	}
341 	return NULL;
342 }
343 
344 #define for_each_property_of_node(dn, pp) \
345 	for (pp = dn->properties; pp != NULL; pp = pp->next)
346 
347 struct device_node *of_find_node_opts_by_path(const char *path,
348 					      const char **opts)
349 {
350 	struct device_node *np = NULL;
351 	struct property *pp;
352 	const char *separator = strchr(path, ':');
353 
354 	if (opts)
355 		*opts = separator ? separator + 1 : NULL;
356 
357 	if (strcmp(path, "/") == 0)
358 		return of_node_get(gd->of_root);
359 
360 	/* The path could begin with an alias */
361 	if (*path != '/') {
362 		int len;
363 		const char *p = separator;
364 
365 		if (!p)
366 			p = strchrnul(path, '/');
367 		len = p - path;
368 
369 		/* of_aliases must not be NULL */
370 		if (!of_aliases)
371 			return NULL;
372 
373 		for_each_property_of_node(of_aliases, pp) {
374 			if (strlen(pp->name) == len && !strncmp(pp->name, path,
375 								len)) {
376 				np = of_find_node_by_path(pp->value);
377 				break;
378 			}
379 		}
380 		if (!np)
381 			return NULL;
382 		path = p;
383 	}
384 
385 	/* Step down the tree matching path components */
386 	if (!np)
387 		np = of_node_get(gd->of_root);
388 	while (np && *path == '/') {
389 		struct device_node *tmp = np;
390 
391 		path++; /* Increment past '/' delimiter */
392 		np = __of_find_node_by_path(np, path);
393 		of_node_put(tmp);
394 		path = strchrnul(path, '/');
395 		if (separator && separator < path)
396 			break;
397 	}
398 
399 	return np;
400 }
401 
402 struct device_node *of_find_compatible_node(struct device_node *from,
403 		const char *type, const char *compatible)
404 {
405 	struct device_node *np;
406 
407 	for_each_of_allnodes_from(from, np)
408 		if (of_device_is_compatible(np, compatible, type, NULL) &&
409 		    of_node_get(np))
410 			break;
411 	of_node_put(from);
412 
413 	return np;
414 }
415 
416 struct device_node *of_find_node_by_phandle(phandle handle)
417 {
418 	struct device_node *np;
419 
420 	if (!handle)
421 		return NULL;
422 
423 	for_each_of_allnodes(np)
424 		if (np->phandle == handle)
425 			break;
426 	(void)of_node_get(np);
427 
428 	return np;
429 }
430 
431 /**
432  * of_find_property_value_of_size() - find property of given size
433  *
434  * Search for a property in a device node and validate the requested size.
435  *
436  * @np:		device node from which the property value is to be read.
437  * @propname:	name of the property to be searched.
438  * @len:	requested length of property value
439  *
440  * @return the property value on success, -EINVAL if the property does not
441  * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the
442  * property data isn't large enough.
443  */
444 static void *of_find_property_value_of_size(const struct device_node *np,
445 					    const char *propname, u32 len)
446 {
447 	struct property *prop = of_find_property(np, propname, NULL);
448 
449 	if (!prop)
450 		return ERR_PTR(-EINVAL);
451 	if (!prop->value)
452 		return ERR_PTR(-ENODATA);
453 	if (len > prop->length)
454 		return ERR_PTR(-EOVERFLOW);
455 
456 	return prop->value;
457 }
458 
459 int of_read_u32(const struct device_node *np, const char *propname, u32 *outp)
460 {
461 	const __be32 *val;
462 
463 	debug("%s: %s: ", __func__, propname);
464 	if (!np)
465 		return -EINVAL;
466 	val = of_find_property_value_of_size(np, propname, sizeof(*outp));
467 	if (IS_ERR(val)) {
468 		debug("(not found)\n");
469 		return PTR_ERR(val);
470 	}
471 
472 	*outp = be32_to_cpup(val);
473 	debug("%#x (%d)\n", *outp, *outp);
474 
475 	return 0;
476 }
477 
478 /**
479  * of_property_read_u64 - Find and read a 64 bit integer from a property
480  * @np:         device node from which the property value is to be read.
481  * @propname:   name of the property to be searched.
482  * @out_value:  pointer to return value, modified only if return value is 0.
483  *
484  * Search for a property in a device node and read a 64-bit value from
485  * it. Returns 0 on success, -EINVAL if the property does not exist,
486  * -ENODATA if property does not have a value, and -EOVERFLOW if the
487  * property data isn't large enough.
488  *
489  * The out_value is modified only if a valid u64 value can be decoded.
490  */
491 int of_property_read_u64(const struct device_node *np, const char *propname,
492                          u64 *out_value)
493 {
494 	const __be32 *val = of_find_property_value_of_size(np, propname,
495 							   sizeof(*out_value));
496 
497 	if (IS_ERR(val))
498 		return PTR_ERR(val);
499 
500 	*out_value = of_read_number(val, 2);
501 
502 	return 0;
503 }
504 
505 int of_read_u32_array(const struct device_node *np, const char *propname,
506 		      u32 *out_values, size_t sz)
507 {
508 	const __be32 *val;
509 
510 	debug("%s: %s: ", __func__, propname);
511 	val = of_find_property_value_of_size(np, propname,
512 					     sz * sizeof(*out_values));
513 
514 	if (IS_ERR(val))
515 		return PTR_ERR(val);
516 
517 	debug("size %zd\n", sz);
518 	while (sz--)
519 		*out_values++ = be32_to_cpup(val++);
520 
521 	return 0;
522 }
523 
524 int of_write_u32_array(const struct device_node *np, const char *propname,
525 		       u32 *values, size_t sz)
526 {
527 	__be32 *val;
528 
529 	debug("%s: %s: ", __func__, propname);
530 	val = of_find_property_value_of_size(np, propname,
531 					     sz * sizeof(*values));
532 
533 	if (IS_ERR(val))
534 		return PTR_ERR(val);
535 
536 	debug("size %zd\n", sz);
537 	while (sz--)
538 		*val++ = cpu_to_be32p(values++);
539 
540 	return 0;
541 }
542 
543 int of_property_match_string(const struct device_node *np, const char *propname,
544 			     const char *string)
545 {
546 	const struct property *prop = of_find_property(np, propname, NULL);
547 	size_t l;
548 	int i;
549 	const char *p, *end;
550 
551 	if (!prop)
552 		return -EINVAL;
553 	if (!prop->value)
554 		return -ENODATA;
555 
556 	p = prop->value;
557 	end = p + prop->length;
558 
559 	for (i = 0; p < end; i++, p += l) {
560 		l = strnlen(p, end - p) + 1;
561 		if (p + l > end)
562 			return -EILSEQ;
563 		debug("comparing %s with %s\n", string, p);
564 		if (strcmp(string, p) == 0)
565 			return i; /* Found it; return index */
566 	}
567 	return -ENODATA;
568 }
569 
570 /**
571  * of_property_read_string_helper() - Utility helper for parsing string properties
572  * @np:		device node from which the property value is to be read.
573  * @propname:	name of the property to be searched.
574  * @out_strs:	output array of string pointers.
575  * @sz:		number of array elements to read.
576  * @skip:	Number of strings to skip over at beginning of list.
577  *
578  * Don't call this function directly. It is a utility helper for the
579  * of_property_read_string*() family of functions.
580  */
581 int of_property_read_string_helper(const struct device_node *np,
582 				   const char *propname, const char **out_strs,
583 				   size_t sz, int skip)
584 {
585 	const struct property *prop = of_find_property(np, propname, NULL);
586 	int l = 0, i = 0;
587 	const char *p, *end;
588 
589 	if (!prop)
590 		return -EINVAL;
591 	if (!prop->value)
592 		return -ENODATA;
593 	p = prop->value;
594 	end = p + prop->length;
595 
596 	for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) {
597 		l = strnlen(p, end - p) + 1;
598 		if (p + l > end)
599 			return -EILSEQ;
600 		if (out_strs && i >= skip)
601 			*out_strs++ = p;
602 	}
603 	i -= skip;
604 	return i <= 0 ? -ENODATA : i;
605 }
606 
607 static int __of_parse_phandle_with_args(const struct device_node *np,
608 					const char *list_name,
609 					const char *cells_name,
610 					int cell_count, int index,
611 					struct of_phandle_args *out_args)
612 {
613 	const __be32 *list, *list_end;
614 	int rc = 0, cur_index = 0;
615 	uint32_t count = 0;
616 	struct device_node *node = NULL;
617 	phandle phandle;
618 	int size;
619 
620 	/* Retrieve the phandle list property */
621 	list = of_get_property(np, list_name, &size);
622 	if (!list)
623 		return -ENOENT;
624 	list_end = list + size / sizeof(*list);
625 
626 	/* Loop over the phandles until all the requested entry is found */
627 	while (list < list_end) {
628 		rc = -EINVAL;
629 		count = 0;
630 
631 		/*
632 		 * If phandle is 0, then it is an empty entry with no
633 		 * arguments.  Skip forward to the next entry.
634 		 */
635 		phandle = be32_to_cpup(list++);
636 		if (phandle) {
637 			/*
638 			 * Find the provider node and parse the #*-cells
639 			 * property to determine the argument length.
640 			 *
641 			 * This is not needed if the cell count is hard-coded
642 			 * (i.e. cells_name not set, but cell_count is set),
643 			 * except when we're going to return the found node
644 			 * below.
645 			 */
646 			if (cells_name || cur_index == index) {
647 				node = of_find_node_by_phandle(phandle);
648 				if (!node) {
649 					debug("%s: could not find phandle\n",
650 					      np->full_name);
651 					goto err;
652 				}
653 			}
654 
655 			if (cells_name) {
656 				if (of_read_u32(node, cells_name, &count)) {
657 					debug("%s: could not get %s for %s\n",
658 					      np->full_name, cells_name,
659 					      node->full_name);
660 					goto err;
661 				}
662 			} else {
663 				count = cell_count;
664 			}
665 
666 			/*
667 			 * Make sure that the arguments actually fit in the
668 			 * remaining property data length
669 			 */
670 			if (list + count > list_end) {
671 				debug("%s: arguments longer than property\n",
672 				      np->full_name);
673 				goto err;
674 			}
675 		}
676 
677 		/*
678 		 * All of the error cases above bail out of the loop, so at
679 		 * this point, the parsing is successful. If the requested
680 		 * index matches, then fill the out_args structure and return,
681 		 * or return -ENOENT for an empty entry.
682 		 */
683 		rc = -ENOENT;
684 		if (cur_index == index) {
685 			if (!phandle)
686 				goto err;
687 
688 			if (out_args) {
689 				int i;
690 				if (WARN_ON(count > OF_MAX_PHANDLE_ARGS))
691 					count = OF_MAX_PHANDLE_ARGS;
692 				out_args->np = node;
693 				out_args->args_count = count;
694 				for (i = 0; i < count; i++)
695 					out_args->args[i] =
696 							be32_to_cpup(list++);
697 			} else {
698 				of_node_put(node);
699 			}
700 
701 			/* Found it! return success */
702 			return 0;
703 		}
704 
705 		of_node_put(node);
706 		node = NULL;
707 		list += count;
708 		cur_index++;
709 	}
710 
711 	/*
712 	 * Unlock node before returning result; will be one of:
713 	 * -ENOENT : index is for empty phandle
714 	 * -EINVAL : parsing error on data
715 	 * [1..n]  : Number of phandle (count mode; when index = -1)
716 	 */
717 	rc = index < 0 ? cur_index : -ENOENT;
718  err:
719 	if (node)
720 		of_node_put(node);
721 	return rc;
722 }
723 
724 struct device_node *of_parse_phandle(const struct device_node *np,
725 				     const char *phandle_name, int index)
726 {
727 	struct of_phandle_args args;
728 
729 	if (index < 0)
730 		return NULL;
731 
732 	if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0, index,
733 					 &args))
734 		return NULL;
735 
736 	return args.np;
737 }
738 
739 int of_parse_phandle_with_args(const struct device_node *np,
740 			       const char *list_name, const char *cells_name,
741 			       int index, struct of_phandle_args *out_args)
742 {
743 	if (index < 0)
744 		return -EINVAL;
745 
746 	return __of_parse_phandle_with_args(np, list_name, cells_name, 0,
747 					    index, out_args);
748 }
749 
750 int of_count_phandle_with_args(const struct device_node *np,
751 			       const char *list_name, const char *cells_name)
752 {
753 	return __of_parse_phandle_with_args(np, list_name, cells_name, 0,
754 					    -1, NULL);
755 }
756 
757 static void of_alias_add(struct alias_prop *ap, struct device_node *np,
758 			 int id, const char *stem, int stem_len)
759 {
760 	struct alias_prop *oldap;
761 	ap->np = np;
762 	ap->id = id;
763 	strncpy(ap->stem, stem, stem_len);
764 	ap->stem[stem_len] = 0;
765 
766 	/* Delete U-Boot alias which is same with kernel */
767 	mutex_lock(&of_mutex);
768 	list_for_each_entry(oldap, &aliases_lookup, link) {
769 		if (stem && !strcmp(stem, oldap->alias) && (id == oldap->id)) {
770 			list_del(&oldap->link);
771 			break;
772 		}
773 	}
774 	mutex_unlock(&of_mutex);
775 
776 	list_add_tail(&ap->link, &aliases_lookup);
777 	debug("adding DT alias:%s: stem=%s id=%i node=%s\n",
778 	      ap->alias, ap->stem, ap->id, of_node_full_name(np));
779 }
780 
781 int of_alias_scan(void)
782 {
783 	struct property *pp;
784 
785 	of_aliases = of_find_node_by_path("/aliases");
786 	of_chosen = of_find_node_by_path("/chosen");
787 	if (of_chosen == NULL)
788 		of_chosen = of_find_node_by_path("/chosen@0");
789 
790 	if (of_chosen) {
791 		const char *name;
792 
793 		name = of_get_property(of_chosen, "stdout-path", NULL);
794 		if (name)
795 			of_stdout = of_find_node_opts_by_path(name,
796 							&of_stdout_options);
797 	}
798 
799 	if (!of_aliases)
800 		return 0;
801 
802 	for_each_property_of_node(of_aliases, pp) {
803 		const char *start = pp->name;
804 		const char *end = start + strlen(start);
805 		struct device_node *np;
806 		struct alias_prop *ap;
807 		ulong id;
808 		int len;
809 
810 		/* Skip those we do not want to proceed */
811 		if (!strcmp(pp->name, "name") ||
812 		    !strcmp(pp->name, "phandle") ||
813 		    !strcmp(pp->name, "linux,phandle"))
814 			continue;
815 
816 		np = of_find_node_by_path(pp->value);
817 		if (!np)
818 			continue;
819 
820 		/*
821 		 * walk the alias backwards to extract the id and work out
822 		 * the 'stem' string
823 		 */
824 		while (isdigit(*(end-1)) && end > start)
825 			end--;
826 		len = end - start;
827 
828 		if (strict_strtoul(end, 10, &id) < 0)
829 			continue;
830 
831 		/* Allocate an alias_prop with enough space for the stem */
832 		ap = malloc(sizeof(*ap) + len + 1);
833 		if (!ap)
834 			return -ENOMEM;
835 		memset(ap, 0, sizeof(*ap) + len + 1);
836 		ap->alias = start;
837 		of_alias_add(ap, np, id, start, len);
838 	}
839 
840 	return 0;
841 }
842 
843 int of_alias_get_id(const struct device_node *np, const char *stem)
844 {
845 	struct alias_prop *app;
846 	int id = -ENODEV;
847 
848 	mutex_lock(&of_mutex);
849 	list_for_each_entry(app, &aliases_lookup, link) {
850 		if (strcmp(app->stem, stem) != 0)
851 			continue;
852 
853 		if (np == app->np) {
854 			id = app->id;
855 			break;
856 		}
857 	}
858 	mutex_unlock(&of_mutex);
859 
860 	return id;
861 }
862 
863 struct device_node *of_alias_get_dev(const char *stem, int id)
864 {
865 	struct alias_prop *app;
866 	struct device_node *np = NULL;
867 
868 	mutex_lock(&of_mutex);
869 	list_for_each_entry(app, &aliases_lookup, link) {
870 		if (strcmp(app->stem, stem) != 0)
871 			continue;
872 
873 		if (id == app->id) {
874 			np = app->np;
875 			break;
876 		}
877 	}
878 	mutex_unlock(&of_mutex);
879 
880 	return np;
881 }
882 
883 struct device_node *of_alias_dump(void)
884 {
885 	struct alias_prop *app;
886 	struct device_node *np = NULL;
887 
888 	mutex_lock(&of_mutex);
889 	list_for_each_entry(app, &aliases_lookup, link) {
890 		printf("%10s%d: %20s, phandle=%d %4s\n",
891 		       app->stem, app->id,
892 		       app->np->full_name, app->np->phandle,
893 		       of_get_property(app->np, "u-boot,dm-pre-reloc", NULL) ||
894 		       of_get_property(app->np, "u-boot,dm-spl", NULL) ? "*" : "");
895 	}
896 	mutex_unlock(&of_mutex);
897 
898 	return np;
899 }
900 
901 struct device_node *of_get_stdout(void)
902 {
903 	struct device_node *np;
904 
905 	if (gd && gd->serial.using_pre_serial) {
906 		np = of_alias_get_dev("serial", gd->serial.id);
907 		if (!np)
908 			printf("Can't find alias serial%d\n", gd->serial.id);
909 		else
910 			debug("Find alias serial: %s\n", np->full_name);
911 
912 		of_stdout = np;
913 	}
914 
915 	return of_stdout;
916 }
917