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