8631e1c286b548bd7090d0a6a3dc6f356962f06d
[platform/kernel/u-boot.git] / drivers / core / of_access.c
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 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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, -ENODATA if property does not have a value, and -EOVERFLOW if the
475  * property data isn't large enough.
476  */
477 static void *of_find_property_value_of_size(const struct device_node *np,
478                                             const char *propname, u32 len)
479 {
480         struct property *prop = of_find_property(np, propname, NULL);
481
482         if (!prop)
483                 return ERR_PTR(-EINVAL);
484         if (!prop->value)
485                 return ERR_PTR(-ENODATA);
486         if (len > prop->length)
487                 return ERR_PTR(-EOVERFLOW);
488
489         return prop->value;
490 }
491
492 int of_read_u8(const struct device_node *np, const char *propname, u8 *outp)
493 {
494         const u8 *val;
495
496         debug("%s: %s: ", __func__, propname);
497         if (!np)
498                 return -EINVAL;
499         val = of_find_property_value_of_size(np, propname, sizeof(*outp));
500         if (IS_ERR(val)) {
501                 debug("(not found)\n");
502                 return PTR_ERR(val);
503         }
504
505         *outp = *val;
506         debug("%#x (%d)\n", *outp, *outp);
507
508         return 0;
509 }
510
511 int of_read_u16(const struct device_node *np, const char *propname, u16 *outp)
512 {
513         const __be16 *val;
514
515         debug("%s: %s: ", __func__, propname);
516         if (!np)
517                 return -EINVAL;
518         val = of_find_property_value_of_size(np, propname, sizeof(*outp));
519         if (IS_ERR(val)) {
520                 debug("(not found)\n");
521                 return PTR_ERR(val);
522         }
523
524         *outp = be16_to_cpup(val);
525         debug("%#x (%d)\n", *outp, *outp);
526
527         return 0;
528 }
529
530 int of_read_u32(const struct device_node *np, const char *propname, u32 *outp)
531 {
532         return of_read_u32_index(np, propname, 0, outp);
533 }
534
535 int of_read_u32_array(const struct device_node *np, const char *propname,
536                       u32 *out_values, size_t sz)
537 {
538         const __be32 *val;
539
540         debug("%s: %s: ", __func__, propname);
541         val = of_find_property_value_of_size(np, propname,
542                                              sz * sizeof(*out_values));
543
544         if (IS_ERR(val))
545                 return PTR_ERR(val);
546
547         debug("size %zd\n", sz);
548         while (sz--)
549                 *out_values++ = be32_to_cpup(val++);
550
551         return 0;
552 }
553
554 int of_read_u32_index(const struct device_node *np, const char *propname,
555                       int index, u32 *outp)
556 {
557         const __be32 *val;
558
559         debug("%s: %s: ", __func__, propname);
560         if (!np)
561                 return -EINVAL;
562
563         val = of_find_property_value_of_size(np, propname,
564                                              sizeof(*outp) * (index + 1));
565         if (IS_ERR(val)) {
566                 debug("(not found)\n");
567                 return PTR_ERR(val);
568         }
569
570         *outp = be32_to_cpup(val + index);
571         debug("%#x (%d)\n", *outp, *outp);
572
573         return 0;
574 }
575
576 int of_read_u64(const struct device_node *np, const char *propname, u64 *outp)
577 {
578         const __be64 *val;
579
580         debug("%s: %s: ", __func__, propname);
581         if (!np)
582                 return -EINVAL;
583         val = of_find_property_value_of_size(np, propname, sizeof(*outp));
584         if (IS_ERR(val)) {
585                 debug("(not found)\n");
586                 return PTR_ERR(val);
587         }
588
589         *outp = be64_to_cpup(val);
590         debug("%#llx (%lld)\n", (unsigned long long)*outp,
591               (unsigned long long)*outp);
592
593         return 0;
594 }
595
596 int of_property_match_string(const struct device_node *np, const char *propname,
597                              const char *string)
598 {
599         const struct property *prop = of_find_property(np, propname, NULL);
600         size_t l;
601         int i;
602         const char *p, *end;
603
604         if (!prop)
605                 return -EINVAL;
606         if (!prop->value)
607                 return -ENODATA;
608
609         p = prop->value;
610         end = p + prop->length;
611
612         for (i = 0; p < end; i++, p += l) {
613                 l = strnlen(p, end - p) + 1;
614                 if (p + l > end)
615                         return -EILSEQ;
616                 debug("comparing %s with %s\n", string, p);
617                 if (strcmp(string, p) == 0)
618                         return i; /* Found it; return index */
619         }
620         return -ENODATA;
621 }
622
623 /**
624  * of_property_read_string_helper() - Utility helper for parsing string properties
625  * @np:         device node from which the property value is to be read.
626  * @propname:   name of the property to be searched.
627  * @out_strs:   output array of string pointers.
628  * @sz:         number of array elements to read.
629  * @skip:       Number of strings to skip over at beginning of list (cannot be
630  *      negative)
631  *
632  * Don't call this function directly. It is a utility helper for the
633  * of_property_read_string*() family of functions.
634  */
635 int of_property_read_string_helper(const struct device_node *np,
636                                    const char *propname, const char **out_strs,
637                                    size_t sz, int skip)
638 {
639         const struct property *prop = of_find_property(np, propname, NULL);
640         int l = 0, i = 0;
641         const char *p, *end;
642
643         if (!prop)
644                 return -EINVAL;
645         if (!prop->value)
646                 return -ENODATA;
647         p = prop->value;
648         end = p + prop->length;
649
650         for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) {
651                 l = strnlen(p, end - p) + 1;
652                 if (p + l > end)
653                         return -EILSEQ;
654                 if (out_strs && i >= skip)
655                         *out_strs++ = p;
656         }
657         i -= skip;
658         return i <= 0 ? -ENODATA : i;
659 }
660
661 static int __of_parse_phandle_with_args(const struct device_node *np,
662                                         const char *list_name,
663                                         const char *cells_name,
664                                         int cell_count, int index,
665                                         struct of_phandle_args *out_args)
666 {
667         const __be32 *list, *list_end;
668         int rc = 0, cur_index = 0;
669         uint32_t count;
670         struct device_node *node = NULL;
671         phandle phandle;
672         int size;
673
674         /* Retrieve the phandle list property */
675         list = of_get_property(np, list_name, &size);
676         if (!list)
677                 return -ENOENT;
678         list_end = list + size / sizeof(*list);
679
680         /* Loop over the phandles until all the requested entry is found */
681         while (list < list_end) {
682                 rc = -EINVAL;
683                 count = 0;
684
685                 /*
686                  * If phandle is 0, then it is an empty entry with no
687                  * arguments.  Skip forward to the next entry.
688                  */
689                 phandle = be32_to_cpup(list++);
690                 if (phandle) {
691                         /*
692                          * Find the provider node and parse the #*-cells
693                          * property to determine the argument length.
694                          *
695                          * This is not needed if the cell count is hard-coded
696                          * (i.e. cells_name not set, but cell_count is set),
697                          * except when we're going to return the found node
698                          * below.
699                          */
700                         if (cells_name || cur_index == index) {
701                                 node = of_find_node_by_phandle(NULL, phandle);
702                                 if (!node) {
703                                         debug("%s: could not find phandle\n",
704                                               np->full_name);
705                                         goto err;
706                                 }
707                         }
708
709                         if (cells_name) {
710                                 if (of_read_u32(node, cells_name, &count)) {
711                                         debug("%s: could not get %s for %s\n",
712                                               np->full_name, cells_name,
713                                               node->full_name);
714                                         goto err;
715                                 }
716                         } else {
717                                 count = cell_count;
718                         }
719
720                         /*
721                          * Make sure that the arguments actually fit in the
722                          * remaining property data length
723                          */
724                         if (list + count > list_end) {
725                                 debug("%s: arguments longer than property\n",
726                                       np->full_name);
727                                 goto err;
728                         }
729                 }
730
731                 /*
732                  * All of the error cases above bail out of the loop, so at
733                  * this point, the parsing is successful. If the requested
734                  * index matches, then fill the out_args structure and return,
735                  * or return -ENOENT for an empty entry.
736                  */
737                 rc = -ENOENT;
738                 if (cur_index == index) {
739                         if (!phandle)
740                                 goto err;
741
742                         if (out_args) {
743                                 int i;
744                                 if (WARN_ON(count > OF_MAX_PHANDLE_ARGS))
745                                         count = OF_MAX_PHANDLE_ARGS;
746                                 out_args->np = node;
747                                 out_args->args_count = count;
748                                 for (i = 0; i < count; i++)
749                                         out_args->args[i] =
750                                                         be32_to_cpup(list++);
751                         } else {
752                                 of_node_put(node);
753                         }
754
755                         /* Found it! return success */
756                         return 0;
757                 }
758
759                 of_node_put(node);
760                 node = NULL;
761                 list += count;
762                 cur_index++;
763         }
764
765         /*
766          * Unlock node before returning result; will be one of:
767          * -ENOENT : index is for empty phandle
768          * -EINVAL : parsing error on data
769          * [1..n]  : Number of phandle (count mode; when index = -1)
770          */
771         rc = index < 0 ? cur_index : -ENOENT;
772  err:
773         if (node)
774                 of_node_put(node);
775         return rc;
776 }
777
778 struct device_node *of_parse_phandle(const struct device_node *np,
779                                      const char *phandle_name, int index)
780 {
781         struct of_phandle_args args;
782
783         if (index < 0)
784                 return NULL;
785
786         if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0, index,
787                                          &args))
788                 return NULL;
789
790         return args.np;
791 }
792
793 int of_parse_phandle_with_args(const struct device_node *np,
794                                const char *list_name, const char *cells_name,
795                                int cell_count, int index,
796                                struct of_phandle_args *out_args)
797 {
798         if (index < 0)
799                 return -EINVAL;
800
801         return __of_parse_phandle_with_args(np, list_name, cells_name,
802                                             cell_count, index, out_args);
803 }
804
805 int of_count_phandle_with_args(const struct device_node *np,
806                                const char *list_name, const char *cells_name,
807                                int cell_count)
808 {
809         return __of_parse_phandle_with_args(np, list_name, cells_name,
810                                             cell_count, -1, NULL);
811 }
812
813 static void of_alias_add(struct alias_prop *ap, struct device_node *np,
814                          int id, const char *stem, int stem_len)
815 {
816         ap->np = np;
817         ap->id = id;
818         strncpy(ap->stem, stem, stem_len);
819         ap->stem[stem_len] = 0;
820         list_add_tail(&ap->link, &aliases_lookup);
821         debug("adding DT alias:%s: stem=%s id=%i node=%s\n",
822               ap->alias, ap->stem, ap->id, of_node_full_name(np));
823 }
824
825 int of_alias_scan(void)
826 {
827         struct property *pp;
828
829         of_aliases = of_find_node_by_path("/aliases");
830         of_chosen = of_find_node_by_path("/chosen");
831         if (of_chosen == NULL)
832                 of_chosen = of_find_node_by_path("/chosen@0");
833
834         if (of_chosen) {
835                 const char *name;
836
837                 name = of_get_property(of_chosen, "stdout-path", NULL);
838                 if (name)
839                         of_stdout = of_find_node_opts_by_path(NULL, name,
840                                                         &of_stdout_options);
841         }
842
843         if (!of_aliases)
844                 return 0;
845
846         for_each_property_of_node(of_aliases, pp) {
847                 const char *start = pp->name;
848                 const char *end = start + strlen(start);
849                 struct device_node *np;
850                 struct alias_prop *ap;
851                 ulong id;
852                 int len;
853
854                 /* Skip those we do not want to proceed */
855                 if (!strcmp(pp->name, "name") ||
856                     !strcmp(pp->name, "phandle") ||
857                     !strcmp(pp->name, "linux,phandle"))
858                         continue;
859
860                 np = of_find_node_by_path(pp->value);
861                 if (!np)
862                         continue;
863
864                 /*
865                  * walk the alias backwards to extract the id and work out
866                  * the 'stem' string
867                  */
868                 while (isdigit(*(end-1)) && end > start)
869                         end--;
870                 len = end - start;
871
872                 if (strict_strtoul(end, 10, &id) < 0)
873                         continue;
874
875                 /* Allocate an alias_prop with enough space for the stem */
876                 ap = malloc(sizeof(*ap) + len + 1);
877                 if (!ap)
878                         return -ENOMEM;
879                 memset(ap, 0, sizeof(*ap) + len + 1);
880                 ap->alias = start;
881                 of_alias_add(ap, np, id, start, len);
882         }
883
884         return 0;
885 }
886
887 int of_alias_get_id(const struct device_node *np, const char *stem)
888 {
889         struct alias_prop *app;
890         int id = -ENODEV;
891
892         mutex_lock(&of_mutex);
893         list_for_each_entry(app, &aliases_lookup, link) {
894                 if (strcmp(app->stem, stem) != 0)
895                         continue;
896
897                 if (np == app->np) {
898                         id = app->id;
899                         break;
900                 }
901         }
902         mutex_unlock(&of_mutex);
903
904         return id;
905 }
906
907 int of_alias_get_highest_id(const char *stem)
908 {
909         struct alias_prop *app;
910         int id = -1;
911
912         mutex_lock(&of_mutex);
913         list_for_each_entry(app, &aliases_lookup, link) {
914                 if (strcmp(app->stem, stem) != 0)
915                         continue;
916
917                 if (app->id > id)
918                         id = app->id;
919         }
920         mutex_unlock(&of_mutex);
921
922         return id;
923 }
924
925 struct device_node *of_get_stdout(void)
926 {
927         return of_stdout;
928 }
929
930 int of_write_prop(struct device_node *np, const char *propname, int len,
931                   const void *value)
932 {
933         struct property *pp;
934         struct property *pp_last = NULL;
935         struct property *new;
936
937         if (!np)
938                 return -EINVAL;
939
940         for (pp = np->properties; pp; pp = pp->next) {
941                 if (strcmp(pp->name, propname) == 0) {
942                         /* Property exists -> change value */
943                         pp->value = (void *)value;
944                         pp->length = len;
945                         return 0;
946                 }
947                 pp_last = pp;
948         }
949
950         /* Property does not exist -> append new property */
951         new = malloc(sizeof(struct property));
952         if (!new)
953                 return -ENOMEM;
954
955         new->name = strdup(propname);
956         if (!new->name) {
957                 free(new);
958                 return -ENOMEM;
959         }
960
961         new->value = (void *)value;
962         new->length = len;
963         new->next = NULL;
964
965         if (pp_last)
966                 pp_last->next = new;
967         else
968                 np->properties = new;
969
970         return 0;
971 }
972
973 int of_add_subnode(struct device_node *parent, const char *name, int len,
974                    struct device_node **childp)
975 {
976         struct device_node *child, *new, *last_sibling = NULL;
977         char *new_name, *full_name;
978         int parent_fnl;
979
980         if (len == -1)
981                 len = strlen(name);
982         __for_each_child_of_node(parent, child) {
983                 /*
984                  * make sure we don't use a child called "trevor" when we are
985                  * searching for "trev".
986                  */
987                 if (!strncmp(child->name, name, len) && strlen(name) == len) {
988                         *childp = child;
989                         return -EEXIST;
990                 }
991                 last_sibling = child;
992         }
993
994         /* Subnode does not exist -> append new subnode */
995         new = calloc(1, sizeof(struct device_node));
996         if (!new)
997                 return -ENOMEM;
998
999         new_name = memdup(name, len + 1);
1000         if (!new_name) {
1001                 free(new);
1002                 return -ENOMEM;
1003         }
1004         new_name[len] = '\0';
1005
1006         /*
1007          * if the parent is the root node (named "") we don't need to prepend
1008          * its full path
1009          */
1010         parent_fnl = *parent->name ? strlen(parent->full_name) : 0;
1011         full_name = calloc(1, parent_fnl + 1 + len + 1);
1012         if (!full_name) {
1013                 free(new_name);
1014                 free(new);
1015                 return -ENOMEM;
1016         }
1017         new->name = new_name;   /* assign to constant pointer */
1018
1019         strcpy(full_name, parent->full_name); /* "" for root node */
1020         full_name[parent_fnl] = '/';
1021         strlcpy(&full_name[parent_fnl + 1], name, len + 1);
1022         new->full_name = full_name;
1023
1024         /* Add as last sibling of the parent */
1025         if (last_sibling)
1026                 last_sibling->sibling = new;
1027         if (!parent->child)
1028                 parent->child = new;
1029         new->parent = parent;
1030
1031         *childp = new;
1032
1033         return 0;
1034 }