Merge tag 'u-boot-amlogic-20211102' of https://source.denx.de/u-boot/custodians/u...
[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(const char *path,
347                                               const char **opts)
348 {
349         struct device_node *np = NULL;
350         struct property *pp;
351         const char *separator = strchr(path, ':');
352
353         if (opts)
354                 *opts = separator ? separator + 1 : NULL;
355
356         if (strcmp(path, "/") == 0)
357                 return of_node_get(gd->of_root);
358
359         /* The path could begin with an alias */
360         if (*path != '/') {
361                 int len;
362                 const char *p = separator;
363
364                 if (!p)
365                         p = strchrnul(path, '/');
366                 len = p - path;
367
368                 /* of_aliases must not be NULL */
369                 if (!of_aliases)
370                         return NULL;
371
372                 for_each_property_of_node(of_aliases, pp) {
373                         if (strlen(pp->name) == len && !strncmp(pp->name, path,
374                                                                 len)) {
375                                 np = of_find_node_by_path(pp->value);
376                                 break;
377                         }
378                 }
379                 if (!np)
380                         return NULL;
381                 path = p;
382         }
383
384         /* Step down the tree matching path components */
385         if (!np)
386                 np = of_node_get(gd->of_root);
387         while (np && *path == '/') {
388                 struct device_node *tmp = np;
389
390                 path++; /* Increment past '/' delimiter */
391                 np = __of_find_node_by_path(np, path);
392                 of_node_put(tmp);
393                 path = strchrnul(path, '/');
394                 if (separator && separator < path)
395                         break;
396         }
397
398         return np;
399 }
400
401 struct device_node *of_find_compatible_node(struct device_node *from,
402                 const char *type, const char *compatible)
403 {
404         struct device_node *np;
405
406         for_each_of_allnodes_from(from, np)
407                 if (of_device_is_compatible(np, compatible, type, NULL) &&
408                     of_node_get(np))
409                         break;
410         of_node_put(from);
411
412         return np;
413 }
414
415 static int of_device_has_prop_value(const struct device_node *device,
416                                     const char *propname, const void *propval,
417                                     int proplen)
418 {
419         struct property *prop = of_find_property(device, propname, NULL);
420
421         if (!prop || !prop->value || prop->length != proplen)
422                 return 0;
423         return !memcmp(prop->value, propval, proplen);
424 }
425
426 struct device_node *of_find_node_by_prop_value(struct device_node *from,
427                                                const char *propname,
428                                                const void *propval, int proplen)
429 {
430         struct device_node *np;
431
432         for_each_of_allnodes_from(from, np) {
433                 if (of_device_has_prop_value(np, propname, propval, proplen) &&
434                     of_node_get(np))
435                         break;
436         }
437         of_node_put(from);
438
439         return np;
440 }
441
442 struct device_node *of_find_node_by_phandle(phandle handle)
443 {
444         struct device_node *np;
445
446         if (!handle)
447                 return NULL;
448
449         for_each_of_allnodes(np)
450                 if (np->phandle == handle)
451                         break;
452         (void)of_node_get(np);
453
454         return np;
455 }
456
457 /**
458  * of_find_property_value_of_size() - find property of given size
459  *
460  * Search for a property in a device node and validate the requested size.
461  *
462  * @np:         device node from which the property value is to be read.
463  * @propname:   name of the property to be searched.
464  * @len:        requested length of property value
465  *
466  * @return the property value on success, -EINVAL if the property does not
467  * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the
468  * property data isn't large enough.
469  */
470 static void *of_find_property_value_of_size(const struct device_node *np,
471                                             const char *propname, u32 len)
472 {
473         struct property *prop = of_find_property(np, propname, NULL);
474
475         if (!prop)
476                 return ERR_PTR(-EINVAL);
477         if (!prop->value)
478                 return ERR_PTR(-ENODATA);
479         if (len > prop->length)
480                 return ERR_PTR(-EOVERFLOW);
481
482         return prop->value;
483 }
484
485 int of_read_u32(const struct device_node *np, const char *propname, u32 *outp)
486 {
487         return of_read_u32_index(np, propname, 0, outp);
488 }
489
490 int of_read_u32_array(const struct device_node *np, const char *propname,
491                       u32 *out_values, size_t sz)
492 {
493         const __be32 *val;
494
495         debug("%s: %s: ", __func__, propname);
496         val = of_find_property_value_of_size(np, propname,
497                                              sz * sizeof(*out_values));
498
499         if (IS_ERR(val))
500                 return PTR_ERR(val);
501
502         debug("size %zd\n", sz);
503         while (sz--)
504                 *out_values++ = be32_to_cpup(val++);
505
506         return 0;
507 }
508
509 int of_read_u32_index(const struct device_node *np, const char *propname,
510                       int index, u32 *outp)
511 {
512         const __be32 *val;
513
514         debug("%s: %s: ", __func__, propname);
515         if (!np)
516                 return -EINVAL;
517
518         val = of_find_property_value_of_size(np, propname,
519                                              sizeof(*outp) * (index + 1));
520         if (IS_ERR(val)) {
521                 debug("(not found)\n");
522                 return PTR_ERR(val);
523         }
524
525         *outp = be32_to_cpup(val + index);
526         debug("%#x (%d)\n", *outp, *outp);
527
528         return 0;
529 }
530
531 int of_read_u64(const struct device_node *np, const char *propname, u64 *outp)
532 {
533         const __be64 *val;
534
535         debug("%s: %s: ", __func__, propname);
536         if (!np)
537                 return -EINVAL;
538         val = of_find_property_value_of_size(np, propname, sizeof(*outp));
539         if (IS_ERR(val)) {
540                 debug("(not found)\n");
541                 return PTR_ERR(val);
542         }
543
544         *outp = be64_to_cpup(val);
545         debug("%#llx (%lld)\n", (unsigned long long)*outp,
546               (unsigned long long)*outp);
547
548         return 0;
549 }
550
551 int of_property_match_string(const struct device_node *np, const char *propname,
552                              const char *string)
553 {
554         const struct property *prop = of_find_property(np, propname, NULL);
555         size_t l;
556         int i;
557         const char *p, *end;
558
559         if (!prop)
560                 return -EINVAL;
561         if (!prop->value)
562                 return -ENODATA;
563
564         p = prop->value;
565         end = p + prop->length;
566
567         for (i = 0; p < end; i++, p += l) {
568                 l = strnlen(p, end - p) + 1;
569                 if (p + l > end)
570                         return -EILSEQ;
571                 debug("comparing %s with %s\n", string, p);
572                 if (strcmp(string, p) == 0)
573                         return i; /* Found it; return index */
574         }
575         return -ENODATA;
576 }
577
578 /**
579  * of_property_read_string_helper() - Utility helper for parsing string properties
580  * @np:         device node from which the property value is to be read.
581  * @propname:   name of the property to be searched.
582  * @out_strs:   output array of string pointers.
583  * @sz:         number of array elements to read.
584  * @skip:       Number of strings to skip over at beginning of list.
585  *
586  * Don't call this function directly. It is a utility helper for the
587  * of_property_read_string*() family of functions.
588  */
589 int of_property_read_string_helper(const struct device_node *np,
590                                    const char *propname, const char **out_strs,
591                                    size_t sz, int skip)
592 {
593         const struct property *prop = of_find_property(np, propname, NULL);
594         int l = 0, i = 0;
595         const char *p, *end;
596
597         if (!prop)
598                 return -EINVAL;
599         if (!prop->value)
600                 return -ENODATA;
601         p = prop->value;
602         end = p + prop->length;
603
604         for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) {
605                 l = strnlen(p, end - p) + 1;
606                 if (p + l > end)
607                         return -EILSEQ;
608                 if (out_strs && i >= skip)
609                         *out_strs++ = p;
610         }
611         i -= skip;
612         return i <= 0 ? -ENODATA : i;
613 }
614
615 static int __of_parse_phandle_with_args(const struct device_node *np,
616                                         const char *list_name,
617                                         const char *cells_name,
618                                         int cell_count, int index,
619                                         struct of_phandle_args *out_args)
620 {
621         const __be32 *list, *list_end;
622         int rc = 0, cur_index = 0;
623         uint32_t count;
624         struct device_node *node = NULL;
625         phandle phandle;
626         int size;
627
628         /* Retrieve the phandle list property */
629         list = of_get_property(np, list_name, &size);
630         if (!list)
631                 return -ENOENT;
632         list_end = list + size / sizeof(*list);
633
634         /* Loop over the phandles until all the requested entry is found */
635         while (list < list_end) {
636                 rc = -EINVAL;
637                 count = 0;
638
639                 /*
640                  * If phandle is 0, then it is an empty entry with no
641                  * arguments.  Skip forward to the next entry.
642                  */
643                 phandle = be32_to_cpup(list++);
644                 if (phandle) {
645                         /*
646                          * Find the provider node and parse the #*-cells
647                          * property to determine the argument length.
648                          *
649                          * This is not needed if the cell count is hard-coded
650                          * (i.e. cells_name not set, but cell_count is set),
651                          * except when we're going to return the found node
652                          * below.
653                          */
654                         if (cells_name || cur_index == index) {
655                                 node = of_find_node_by_phandle(phandle);
656                                 if (!node) {
657                                         debug("%s: could not find phandle\n",
658                                               np->full_name);
659                                         goto err;
660                                 }
661                         }
662
663                         if (cells_name) {
664                                 if (of_read_u32(node, cells_name, &count)) {
665                                         debug("%s: could not get %s for %s\n",
666                                               np->full_name, cells_name,
667                                               node->full_name);
668                                         goto err;
669                                 }
670                         } else {
671                                 count = cell_count;
672                         }
673
674                         /*
675                          * Make sure that the arguments actually fit in the
676                          * remaining property data length
677                          */
678                         if (list + count > list_end) {
679                                 debug("%s: arguments longer than property\n",
680                                       np->full_name);
681                                 goto err;
682                         }
683                 }
684
685                 /*
686                  * All of the error cases above bail out of the loop, so at
687                  * this point, the parsing is successful. If the requested
688                  * index matches, then fill the out_args structure and return,
689                  * or return -ENOENT for an empty entry.
690                  */
691                 rc = -ENOENT;
692                 if (cur_index == index) {
693                         if (!phandle)
694                                 goto err;
695
696                         if (out_args) {
697                                 int i;
698                                 if (WARN_ON(count > OF_MAX_PHANDLE_ARGS))
699                                         count = OF_MAX_PHANDLE_ARGS;
700                                 out_args->np = node;
701                                 out_args->args_count = count;
702                                 for (i = 0; i < count; i++)
703                                         out_args->args[i] =
704                                                         be32_to_cpup(list++);
705                         } else {
706                                 of_node_put(node);
707                         }
708
709                         /* Found it! return success */
710                         return 0;
711                 }
712
713                 of_node_put(node);
714                 node = NULL;
715                 list += count;
716                 cur_index++;
717         }
718
719         /*
720          * Unlock node before returning result; will be one of:
721          * -ENOENT : index is for empty phandle
722          * -EINVAL : parsing error on data
723          * [1..n]  : Number of phandle (count mode; when index = -1)
724          */
725         rc = index < 0 ? cur_index : -ENOENT;
726  err:
727         if (node)
728                 of_node_put(node);
729         return rc;
730 }
731
732 struct device_node *of_parse_phandle(const struct device_node *np,
733                                      const char *phandle_name, int index)
734 {
735         struct of_phandle_args args;
736
737         if (index < 0)
738                 return NULL;
739
740         if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0, index,
741                                          &args))
742                 return NULL;
743
744         return args.np;
745 }
746
747 int of_parse_phandle_with_args(const struct device_node *np,
748                                const char *list_name, const char *cells_name,
749                                int cell_count, int index,
750                                struct of_phandle_args *out_args)
751 {
752         if (index < 0)
753                 return -EINVAL;
754
755         return __of_parse_phandle_with_args(np, list_name, cells_name,
756                                             cell_count, index, out_args);
757 }
758
759 int of_count_phandle_with_args(const struct device_node *np,
760                                const char *list_name, const char *cells_name,
761                                int cell_count)
762 {
763         return __of_parse_phandle_with_args(np, list_name, cells_name,
764                                             cell_count, -1, NULL);
765 }
766
767 static void of_alias_add(struct alias_prop *ap, struct device_node *np,
768                          int id, const char *stem, int stem_len)
769 {
770         ap->np = np;
771         ap->id = id;
772         strncpy(ap->stem, stem, stem_len);
773         ap->stem[stem_len] = 0;
774         list_add_tail(&ap->link, &aliases_lookup);
775         debug("adding DT alias:%s: stem=%s id=%i node=%s\n",
776               ap->alias, ap->stem, ap->id, of_node_full_name(np));
777 }
778
779 int of_alias_scan(void)
780 {
781         struct property *pp;
782
783         of_aliases = of_find_node_by_path("/aliases");
784         of_chosen = of_find_node_by_path("/chosen");
785         if (of_chosen == NULL)
786                 of_chosen = of_find_node_by_path("/chosen@0");
787
788         if (of_chosen) {
789                 const char *name;
790
791                 name = of_get_property(of_chosen, "stdout-path", NULL);
792                 if (name)
793                         of_stdout = of_find_node_opts_by_path(name,
794                                                         &of_stdout_options);
795         }
796
797         if (!of_aliases)
798                 return 0;
799
800         for_each_property_of_node(of_aliases, pp) {
801                 const char *start = pp->name;
802                 const char *end = start + strlen(start);
803                 struct device_node *np;
804                 struct alias_prop *ap;
805                 ulong id;
806                 int len;
807
808                 /* Skip those we do not want to proceed */
809                 if (!strcmp(pp->name, "name") ||
810                     !strcmp(pp->name, "phandle") ||
811                     !strcmp(pp->name, "linux,phandle"))
812                         continue;
813
814                 np = of_find_node_by_path(pp->value);
815                 if (!np)
816                         continue;
817
818                 /*
819                  * walk the alias backwards to extract the id and work out
820                  * the 'stem' string
821                  */
822                 while (isdigit(*(end-1)) && end > start)
823                         end--;
824                 len = end - start;
825
826                 if (strict_strtoul(end, 10, &id) < 0)
827                         continue;
828
829                 /* Allocate an alias_prop with enough space for the stem */
830                 ap = malloc(sizeof(*ap) + len + 1);
831                 if (!ap)
832                         return -ENOMEM;
833                 memset(ap, 0, sizeof(*ap) + len + 1);
834                 ap->alias = start;
835                 of_alias_add(ap, np, id, start, len);
836         }
837
838         return 0;
839 }
840
841 int of_alias_get_id(const struct device_node *np, const char *stem)
842 {
843         struct alias_prop *app;
844         int id = -ENODEV;
845
846         mutex_lock(&of_mutex);
847         list_for_each_entry(app, &aliases_lookup, link) {
848                 if (strcmp(app->stem, stem) != 0)
849                         continue;
850
851                 if (np == app->np) {
852                         id = app->id;
853                         break;
854                 }
855         }
856         mutex_unlock(&of_mutex);
857
858         return id;
859 }
860
861 int of_alias_get_highest_id(const char *stem)
862 {
863         struct alias_prop *app;
864         int id = -1;
865
866         mutex_lock(&of_mutex);
867         list_for_each_entry(app, &aliases_lookup, link) {
868                 if (strcmp(app->stem, stem) != 0)
869                         continue;
870
871                 if (app->id > id)
872                         id = app->id;
873         }
874         mutex_unlock(&of_mutex);
875
876         return id;
877 }
878
879 struct device_node *of_get_stdout(void)
880 {
881         return of_stdout;
882 }