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
33DECLARE_GLOBAL_DATA_PTR;
34
35/* list of struct alias_prop aliases */
36static LIST_HEAD(aliases_lookup);
37
38/* "/aliaes" node */
39static struct device_node *of_aliases;
40
41/* "/chosen" node */
42static struct device_node *of_chosen;
43
44/* node pointed to by the stdout-path alias */
45static struct device_node *of_stdout;
46
47/* pointer to options given after the alias (separated by :) or NULL if none */
48static 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 */
62struct 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
70int 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
86int 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
102int 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
114int 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
126struct 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
147struct 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
169const 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
177const 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
185const 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
194const 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
209static 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
226int 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
265bool 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
285struct 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
297static 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
323static 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
346struct 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
407struct 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
421static 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
432struct 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
448struct 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 */
476static 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
489int 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
508int 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
527int 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
532int 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
551int 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
573int of_read_u64_index(const struct device_node *np, const char *propname,
574		      int index, u64 *outp)
575{
576	const __be64 *val;
577
578	debug("%s: %s: ", __func__, propname);
579	if (!np)
580		return -EINVAL;
581
582	val = of_find_property_value_of_size(np, propname,
583					     sizeof(*outp) * (index + 1));
584	if (IS_ERR(val)) {
585		debug("(not found)\n");
586		return PTR_ERR(val);
587	}
588
589	*outp = be64_to_cpup(val + index);
590	debug("%#llx (%lld)\n", (unsigned long long)*outp,
591	      (unsigned long long)*outp);
592
593	return 0;
594}
595
596int of_read_u64(const struct device_node *np, const char *propname, u64 *outp)
597{
598	return of_read_u64_index(np, propname, 0, outp);
599}
600
601int of_property_match_string(const struct device_node *np, const char *propname,
602			     const char *string)
603{
604	int len = 0;
605	const struct property *prop = of_find_property(np, propname, &len);
606	size_t l;
607	int i;
608	const char *p, *end;
609
610	if (!prop && len == -FDT_ERR_NOTFOUND)
611		return -ENOENT;
612	if (!prop)
613		return -EINVAL;
614	if (!prop->value)
615		return -ENODATA;
616
617	p = prop->value;
618	end = p + prop->length;
619
620	for (i = 0; p < end; i++, p += l) {
621		l = strnlen(p, end - p) + 1;
622		if (p + l > end)
623			return -EILSEQ;
624		debug("comparing %s with %s\n", string, p);
625		if (strcmp(string, p) == 0)
626			return i; /* Found it; return index */
627	}
628	return -ENODATA;
629}
630
631/**
632 * of_property_read_string_helper() - Utility helper for parsing string properties
633 * @np:		device node from which the property value is to be read.
634 * @propname:	name of the property to be searched.
635 * @out_strs:	output array of string pointers.
636 * @sz:		number of array elements to read.
637 * @skip:	Number of strings to skip over at beginning of list (cannot be
638 *	negative)
639 *
640 * Don't call this function directly. It is a utility helper for the
641 * of_property_read_string*() family of functions.
642 */
643int of_property_read_string_helper(const struct device_node *np,
644				   const char *propname, const char **out_strs,
645				   size_t sz, int skip)
646{
647	const struct property *prop = of_find_property(np, propname, NULL);
648	int l = 0, i = 0;
649	const char *p, *end;
650
651	if (!prop)
652		return -EINVAL;
653	if (!prop->value)
654		return -ENODATA;
655	p = prop->value;
656	end = p + prop->length;
657
658	for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) {
659		l = strnlen(p, end - p) + 1;
660		if (p + l > end)
661			return -EILSEQ;
662		if (out_strs && i >= skip)
663			*out_strs++ = p;
664	}
665	i -= skip;
666	return i <= 0 ? -ENODATA : i;
667}
668
669static int __of_parse_phandle_with_args(const struct device_node *np,
670					const char *list_name,
671					const char *cells_name,
672					int cell_count, int index,
673					struct of_phandle_args *out_args)
674{
675	const __be32 *list, *list_end;
676	int rc = 0, cur_index = 0;
677	uint32_t count;
678	struct device_node *node = NULL;
679	phandle phandle;
680	int size;
681
682	/* Retrieve the phandle list property */
683	list = of_get_property(np, list_name, &size);
684	if (!list)
685		return -ENOENT;
686	list_end = list + size / sizeof(*list);
687
688	/* Loop over the phandles until all the requested entry is found */
689	while (list < list_end) {
690		rc = -EINVAL;
691		count = 0;
692
693		/*
694		 * If phandle is 0, then it is an empty entry with no
695		 * arguments.  Skip forward to the next entry.
696		 */
697		phandle = be32_to_cpup(list++);
698		if (phandle) {
699			/*
700			 * Find the provider node and parse the #*-cells
701			 * property to determine the argument length.
702			 *
703			 * This is not needed if the cell count is hard-coded
704			 * (i.e. cells_name not set, but cell_count is set),
705			 * except when we're going to return the found node
706			 * below.
707			 */
708			if (cells_name || cur_index == index) {
709				node = of_find_node_by_phandle(NULL, phandle);
710				if (!node) {
711					debug("%s: could not find phandle\n",
712					      np->full_name);
713					goto err;
714				}
715			}
716
717			if (cells_name) {
718				if (of_read_u32(node, cells_name, &count)) {
719					debug("%s: could not get %s for %s\n",
720					      np->full_name, cells_name,
721					      node->full_name);
722					goto err;
723				}
724			} else {
725				count = cell_count;
726			}
727
728			/*
729			 * Make sure that the arguments actually fit in the
730			 * remaining property data length
731			 */
732			if (list + count > list_end) {
733				debug("%s: arguments longer than property\n",
734				      np->full_name);
735				goto err;
736			}
737		}
738
739		/*
740		 * All of the error cases above bail out of the loop, so at
741		 * this point, the parsing is successful. If the requested
742		 * index matches, then fill the out_args structure and return,
743		 * or return -ENOENT for an empty entry.
744		 */
745		rc = -ENOENT;
746		if (cur_index == index) {
747			if (!phandle)
748				goto err;
749
750			if (out_args) {
751				int i;
752				if (WARN_ON(count > OF_MAX_PHANDLE_ARGS))
753					count = OF_MAX_PHANDLE_ARGS;
754				out_args->np = node;
755				out_args->args_count = count;
756				for (i = 0; i < count; i++)
757					out_args->args[i] =
758							be32_to_cpup(list++);
759			} else {
760				of_node_put(node);
761			}
762
763			/* Found it! return success */
764			return 0;
765		}
766
767		of_node_put(node);
768		node = NULL;
769		list += count;
770		cur_index++;
771	}
772
773	/*
774	 * Unlock node before returning result; will be one of:
775	 * -ENOENT : index is for empty phandle
776	 * -EINVAL : parsing error on data
777	 * [1..n]  : Number of phandle (count mode; when index = -1)
778	 */
779	rc = index < 0 ? cur_index : -ENOENT;
780 err:
781	if (node)
782		of_node_put(node);
783	return rc;
784}
785
786struct device_node *of_parse_phandle(const struct device_node *np,
787				     const char *phandle_name, int index)
788{
789	struct of_phandle_args args;
790
791	if (index < 0)
792		return NULL;
793
794	if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0, index,
795					 &args))
796		return NULL;
797
798	return args.np;
799}
800
801int of_parse_phandle_with_args(const struct device_node *np,
802			       const char *list_name, const char *cells_name,
803			       int cell_count, int index,
804			       struct of_phandle_args *out_args)
805{
806	if (index < 0)
807		return -EINVAL;
808
809	return __of_parse_phandle_with_args(np, list_name, cells_name,
810					    cell_count, index, out_args);
811}
812
813int of_count_phandle_with_args(const struct device_node *np,
814			       const char *list_name, const char *cells_name,
815			       int cell_count)
816{
817	return __of_parse_phandle_with_args(np, list_name, cells_name,
818					    cell_count, -1, NULL);
819}
820
821static void of_alias_add(struct alias_prop *ap, struct device_node *np,
822			 int id, const char *stem, int stem_len)
823{
824	ap->np = np;
825	ap->id = id;
826	strncpy(ap->stem, stem, stem_len);
827	ap->stem[stem_len] = 0;
828	list_add_tail(&ap->link, &aliases_lookup);
829	debug("adding DT alias:%s: stem=%s id=%i node=%s\n",
830	      ap->alias, ap->stem, ap->id, of_node_full_name(np));
831}
832
833int of_alias_scan(void)
834{
835	struct property *pp;
836
837	of_aliases = of_find_node_by_path("/aliases");
838	of_chosen = of_find_node_by_path("/chosen");
839	if (of_chosen == NULL)
840		of_chosen = of_find_node_by_path("/chosen@0");
841
842	if (of_chosen) {
843		const char *name;
844
845		name = of_get_property(of_chosen, "stdout-path", NULL);
846		if (name)
847			of_stdout = of_find_node_opts_by_path(NULL, name,
848							&of_stdout_options);
849	}
850
851	if (!of_aliases)
852		return 0;
853
854	for_each_property_of_node(of_aliases, pp) {
855		const char *start = pp->name;
856		const char *end = start + strlen(start);
857		struct device_node *np;
858		struct alias_prop *ap;
859		ulong id;
860		int len;
861
862		/* Skip those we do not want to proceed */
863		if (!strcmp(pp->name, "name") ||
864		    !strcmp(pp->name, "phandle") ||
865		    !strcmp(pp->name, "linux,phandle"))
866			continue;
867
868		np = of_find_node_by_path(pp->value);
869		if (!np)
870			continue;
871
872		/*
873		 * walk the alias backwards to extract the id and work out
874		 * the 'stem' string
875		 */
876		while (isdigit(*(end-1)) && end > start)
877			end--;
878		len = end - start;
879
880		if (strict_strtoul(end, 10, &id) < 0)
881			continue;
882
883		/* Allocate an alias_prop with enough space for the stem */
884		ap = malloc(sizeof(*ap) + len + 1);
885		if (!ap)
886			return -ENOMEM;
887		memset(ap, 0, sizeof(*ap) + len + 1);
888		ap->alias = start;
889		of_alias_add(ap, np, id, start, len);
890	}
891
892	return 0;
893}
894
895int of_alias_get_id(const struct device_node *np, const char *stem)
896{
897	struct alias_prop *app;
898	int id = -ENODEV;
899
900	mutex_lock(&of_mutex);
901	list_for_each_entry(app, &aliases_lookup, link) {
902		if (strcmp(app->stem, stem) != 0)
903			continue;
904
905		if (np == app->np) {
906			id = app->id;
907			break;
908		}
909	}
910	mutex_unlock(&of_mutex);
911
912	return id;
913}
914
915int of_alias_get_highest_id(const char *stem)
916{
917	struct alias_prop *app;
918	int id = -1;
919
920	mutex_lock(&of_mutex);
921	list_for_each_entry(app, &aliases_lookup, link) {
922		if (strcmp(app->stem, stem) != 0)
923			continue;
924
925		if (app->id > id)
926			id = app->id;
927	}
928	mutex_unlock(&of_mutex);
929
930	return id;
931}
932
933struct device_node *of_get_stdout(void)
934{
935	return of_stdout;
936}
937
938int of_write_prop(struct device_node *np, const char *propname, int len,
939		  const void *value)
940{
941	struct property *pp;
942	struct property *pp_last = NULL;
943	struct property *new;
944
945	if (!np)
946		return -EINVAL;
947
948	for (pp = np->properties; pp; pp = pp->next) {
949		if (strcmp(pp->name, propname) == 0) {
950			/* Property exists -> change value */
951			pp->value = (void *)value;
952			pp->length = len;
953			return 0;
954		}
955		pp_last = pp;
956	}
957
958	/* Property does not exist -> append new property */
959	new = malloc(sizeof(struct property));
960	if (!new)
961		return -ENOMEM;
962
963	new->name = strdup(propname);
964	if (!new->name) {
965		free(new);
966		return -ENOMEM;
967	}
968
969	new->value = (void *)value;
970	new->length = len;
971	new->next = NULL;
972
973	if (pp_last)
974		pp_last->next = new;
975	else
976		np->properties = new;
977
978	return 0;
979}
980
981int of_add_subnode(struct device_node *parent, const char *name, int len,
982		   struct device_node **childp)
983{
984	struct device_node *child, *new, *last_sibling = NULL;
985	char *new_name, *full_name;
986	int parent_fnl;
987
988	if (len == -1)
989		len = strlen(name);
990	__for_each_child_of_node(parent, child) {
991		/*
992		 * make sure we don't use a child called "trevor" when we are
993		 * searching for "trev".
994		 */
995		if (!strncmp(child->name, name, len) && strlen(name) == len) {
996			*childp = child;
997			return -EEXIST;
998		}
999		last_sibling = child;
1000	}
1001
1002	/* Subnode does not exist -> append new subnode */
1003	new = calloc(1, sizeof(struct device_node));
1004	if (!new)
1005		return -ENOMEM;
1006
1007	new_name = memdup(name, len + 1);
1008	if (!new_name) {
1009		free(new);
1010		return -ENOMEM;
1011	}
1012	new_name[len] = '\0';
1013
1014	/*
1015	 * if the parent is the root node (named "") we don't need to prepend
1016	 * its full path
1017	 */
1018	parent_fnl = *parent->name ? strlen(parent->full_name) : 0;
1019	full_name = calloc(1, parent_fnl + 1 + len + 1);
1020	if (!full_name) {
1021		free(new_name);
1022		free(new);
1023		return -ENOMEM;
1024	}
1025	new->name = new_name;	/* assign to constant pointer */
1026
1027	strcpy(full_name, parent->full_name); /* "" for root node */
1028	full_name[parent_fnl] = '/';
1029	strlcpy(&full_name[parent_fnl + 1], name, len + 1);
1030	new->full_name = full_name;
1031
1032	/* Add as last sibling of the parent */
1033	if (last_sibling)
1034		last_sibling->sibling = new;
1035	if (!parent->child)
1036		parent->child = new;
1037	new->parent = parent;
1038
1039	*childp = new;
1040
1041	return 0;
1042}
1043
1044int __of_remove_property(struct device_node *np, struct property *prop)
1045{
1046	struct property **next;
1047
1048	for (next = &np->properties; *next; next = &(*next)->next) {
1049		if (*next == prop)
1050			break;
1051	}
1052	if (!*next)
1053		return -ENODEV;
1054
1055	/* found the node */
1056	*next = prop->next;
1057
1058	return 0;
1059}
1060
1061int of_remove_property(struct device_node *np, struct property *prop)
1062{
1063	int rc;
1064
1065	mutex_lock(&of_mutex);
1066
1067	rc = __of_remove_property(np, prop);
1068
1069	mutex_unlock(&of_mutex);
1070
1071	return rc;
1072}
1073
1074int of_remove_node(struct device_node *to_remove)
1075{
1076	struct device_node *parent = to_remove->parent;
1077	struct device_node *np, *prev;
1078
1079	if (!parent)
1080		return -EPERM;
1081	prev = NULL;
1082	__for_each_child_of_node(parent, np) {
1083		if (np == to_remove)
1084			break;
1085		prev = np;
1086	}
1087	if (!np)
1088		return -EFAULT;
1089
1090	/* if there is a previous node, link it to this one's sibling */
1091	if (prev)
1092		prev->sibling = np->sibling;
1093	else
1094		parent->child = np->sibling;
1095
1096	/*
1097	 * don't free it, since if this is an unflattened tree, all the memory
1098	 * was alloced in one block; this pointer will be somewhere in the
1099	 * middle of that
1100	 *
1101	 * TODO(sjg@chromium.org): Consider marking nodes as 'allocated'?
1102	 *
1103	 * free(np);
1104	 */
1105
1106	return 0;
1107}
1108