dm: core: Expand integer-reading tests
[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 and -EOVERFLOW if the property data isn't large enough.
475  */
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
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
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
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
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
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
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
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  */
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
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
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
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
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
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
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
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
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
922 struct device_node *of_get_stdout(void)
923 {
924         return of_stdout;
925 }
926
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
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 }