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