1 /* 2 * Originally from Linux v4.9 3 * Paul Mackerras August 1996. 4 * Copyright (C) 1996-2005 Paul Mackerras. 5 * 6 * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. 7 * {engebret|bergner}@us.ibm.com 8 * 9 * Adapted for sparc and sparc64 by David S. Miller davem@davemloft.net 10 * 11 * Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell and 12 * Grant Likely. 13 * 14 * Modified for U-Boot 15 * Copyright (c) 2017 Google, Inc 16 * 17 * This file follows drivers/of/base.c with functions in the same order as the 18 * Linux version. 19 * 20 * SPDX-License-Identifier: GPL-2.0+ 21 */ 22 23 #include <common.h> 24 #include <linux/libfdt.h> 25 #include <dm/of_access.h> 26 #include <linux/ctype.h> 27 #include <linux/err.h> 28 #include <linux/ioport.h> 29 30 DECLARE_GLOBAL_DATA_PTR; 31 32 /* list of struct alias_prop aliases */ 33 LIST_HEAD(aliases_lookup); 34 35 /* "/aliaes" node */ 36 static struct device_node *of_aliases; 37 38 /* "/chosen" node */ 39 static struct device_node *of_chosen; 40 41 /* node pointed to by the stdout-path alias */ 42 static struct device_node *of_stdout; 43 44 /* pointer to options given after the alias (separated by :) or NULL if none */ 45 static const char *of_stdout_options; 46 47 /** 48 * struct alias_prop - Alias property in 'aliases' node 49 * 50 * The structure represents one alias property of 'aliases' node as 51 * an entry in aliases_lookup list. 52 * 53 * @link: List node to link the structure in aliases_lookup list 54 * @alias: Alias property name 55 * @np: Pointer to device_node that the alias stands for 56 * @id: Index value from end of alias name 57 * @stem: Alias string without the index 58 */ 59 struct alias_prop { 60 struct list_head link; 61 const char *alias; 62 struct device_node *np; 63 int id; 64 char stem[0]; 65 }; 66 67 int of_n_addr_cells(const struct device_node *np) 68 { 69 const __be32 *ip; 70 71 do { 72 if (np->parent) 73 np = np->parent; 74 ip = of_get_property(np, "#address-cells", NULL); 75 if (ip) 76 return be32_to_cpup(ip); 77 } while (np->parent); 78 79 /* No #address-cells property for the root node */ 80 return OF_ROOT_NODE_ADDR_CELLS_DEFAULT; 81 } 82 83 int of_n_size_cells(const struct device_node *np) 84 { 85 const __be32 *ip; 86 87 do { 88 if (np->parent) 89 np = np->parent; 90 ip = of_get_property(np, "#size-cells", NULL); 91 if (ip) 92 return be32_to_cpup(ip); 93 } while (np->parent); 94 95 /* No #size-cells property for the root node */ 96 return OF_ROOT_NODE_SIZE_CELLS_DEFAULT; 97 } 98 99 int of_simple_addr_cells(const struct device_node *np) 100 { 101 const __be32 *ip; 102 103 ip = of_get_property(np, "#address-cells", NULL); 104 if (ip) 105 return be32_to_cpup(ip); 106 107 /* Return a default of 2 to match fdt_address_cells()*/ 108 return 2; 109 } 110 111 int of_simple_size_cells(const struct device_node *np) 112 { 113 const __be32 *ip; 114 115 ip = of_get_property(np, "#size-cells", NULL); 116 if (ip) 117 return be32_to_cpup(ip); 118 119 /* Return a default of 2 to match fdt_size_cells()*/ 120 return 2; 121 } 122 123 struct property *of_find_property(const struct device_node *np, 124 const char *name, int *lenp) 125 { 126 struct property *pp; 127 128 if (!np) 129 return NULL; 130 131 for (pp = np->properties; pp; pp = pp->next) { 132 if (strcmp(pp->name, name) == 0) { 133 if (lenp) 134 *lenp = pp->length; 135 break; 136 } 137 } 138 if (!pp && lenp) 139 *lenp = -FDT_ERR_NOTFOUND; 140 141 return pp; 142 } 143 144 struct device_node *of_find_all_nodes(struct device_node *prev) 145 { 146 struct device_node *np; 147 148 if (!prev) { 149 np = gd->of_root; 150 } else if (prev->child) { 151 np = prev->child; 152 } else { 153 /* 154 * Walk back up looking for a sibling, or the end of the 155 * structure 156 */ 157 np = prev; 158 while (np->parent && !np->sibling) 159 np = np->parent; 160 np = np->sibling; /* Might be null at the end of the tree */ 161 } 162 163 return np; 164 } 165 166 const void *of_get_property(const struct device_node *np, const char *name, 167 int *lenp) 168 { 169 struct property *pp = of_find_property(np, name, lenp); 170 171 return pp ? pp->value : NULL; 172 } 173 174 const struct property *of_get_first_property(const struct device_node *np) 175 { 176 if (!np) 177 return NULL; 178 179 return np->properties; 180 } 181 182 const struct property *of_get_next_property(const struct device_node *np, 183 const struct property *property) 184 { 185 if (!np) 186 return NULL; 187 188 return property->next; 189 } 190 191 const void *of_get_property_by_prop(const struct device_node *np, 192 const struct property *property, 193 const char **name, 194 int *lenp) 195 { 196 if (!np || !property) 197 return NULL; 198 if (name) 199 *name = property->name; 200 if (lenp) 201 *lenp = property->length; 202 203 return property->value; 204 } 205 206 static const char *of_prop_next_string(struct property *prop, const char *cur) 207 { 208 const void *curv = cur; 209 210 if (!prop) 211 return NULL; 212 213 if (!cur) 214 return prop->value; 215 216 curv += strlen(cur) + 1; 217 if (curv >= prop->value + prop->length) 218 return NULL; 219 220 return curv; 221 } 222 223 int of_device_is_compatible(const struct device_node *device, 224 const char *compat, const char *type, 225 const char *name) 226 { 227 struct property *prop; 228 const char *cp; 229 int index = 0, score = 0; 230 231 /* Compatible match has highest priority */ 232 if (compat && compat[0]) { 233 prop = of_find_property(device, "compatible", NULL); 234 for (cp = of_prop_next_string(prop, NULL); cp; 235 cp = of_prop_next_string(prop, cp), index++) { 236 if (of_compat_cmp(cp, compat, strlen(compat)) == 0) { 237 score = INT_MAX/2 - (index << 2); 238 break; 239 } 240 } 241 if (!score) 242 return 0; 243 } 244 245 /* Matching type is better than matching name */ 246 if (type && type[0]) { 247 if (!device->type || of_node_cmp(type, device->type)) 248 return 0; 249 score += 2; 250 } 251 252 /* Matching name is a bit better than not */ 253 if (name && name[0]) { 254 if (!device->name || of_node_cmp(name, device->name)) 255 return 0; 256 score++; 257 } 258 259 return score; 260 } 261 262 bool of_device_is_available(const struct device_node *device) 263 { 264 const char *status; 265 int statlen; 266 267 if (!device) 268 return false; 269 270 status = of_get_property(device, "status", &statlen); 271 if (status == NULL) 272 return true; 273 274 if (statlen > 0) { 275 if (!strcmp(status, "okay")) 276 return true; 277 } 278 279 return false; 280 } 281 282 struct device_node *of_get_parent(const struct device_node *node) 283 { 284 const struct device_node *np; 285 286 if (!node) 287 return NULL; 288 289 np = of_node_get(node->parent); 290 291 return (struct device_node *)np; 292 } 293 294 static struct device_node *__of_get_next_child(const struct device_node *node, 295 struct device_node *prev) 296 { 297 struct device_node *next; 298 299 if (!node) 300 return NULL; 301 302 next = prev ? prev->sibling : node->child; 303 /* 304 * coverity[dead_error_line : FALSE] 305 * Dead code here since our current implementation of of_node_get() 306 * always returns NULL (Coverity CID 163245). But we leave it as is 307 * since we may want to implement get/put later. 308 */ 309 for (; next; next = next->sibling) 310 if (of_node_get(next)) 311 break; 312 of_node_put(prev); 313 return next; 314 } 315 316 #define __for_each_child_of_node(parent, child) \ 317 for (child = __of_get_next_child(parent, NULL); child != NULL; \ 318 child = __of_get_next_child(parent, child)) 319 320 static struct device_node *__of_find_node_by_path(struct device_node *parent, 321 const char *path) 322 { 323 struct device_node *child; 324 int len; 325 326 len = strcspn(path, "/:"); 327 if (!len) 328 return NULL; 329 330 __for_each_child_of_node(parent, child) { 331 const char *name = strrchr(child->full_name, '/'); 332 333 name++; 334 if (strncmp(path, name, len) == 0 && (strlen(name) == len)) 335 return child; 336 } 337 return NULL; 338 } 339 340 #define for_each_property_of_node(dn, pp) \ 341 for (pp = dn->properties; pp != NULL; pp = pp->next) 342 343 struct device_node *of_find_node_opts_by_path(const char *path, 344 const char **opts) 345 { 346 struct device_node *np = NULL; 347 struct property *pp; 348 const char *separator = strchr(path, ':'); 349 350 if (opts) 351 *opts = separator ? separator + 1 : NULL; 352 353 if (strcmp(path, "/") == 0) 354 return of_node_get(gd->of_root); 355 356 /* The path could begin with an alias */ 357 if (*path != '/') { 358 int len; 359 const char *p = separator; 360 361 if (!p) 362 p = strchrnul(path, '/'); 363 len = p - path; 364 365 /* of_aliases must not be NULL */ 366 if (!of_aliases) 367 return NULL; 368 369 for_each_property_of_node(of_aliases, pp) { 370 if (strlen(pp->name) == len && !strncmp(pp->name, path, 371 len)) { 372 np = of_find_node_by_path(pp->value); 373 break; 374 } 375 } 376 if (!np) 377 return NULL; 378 path = p; 379 } 380 381 /* Step down the tree matching path components */ 382 if (!np) 383 np = of_node_get(gd->of_root); 384 while (np && *path == '/') { 385 struct device_node *tmp = np; 386 387 path++; /* Increment past '/' delimiter */ 388 np = __of_find_node_by_path(np, path); 389 of_node_put(tmp); 390 path = strchrnul(path, '/'); 391 if (separator && separator < path) 392 break; 393 } 394 395 return np; 396 } 397 398 struct device_node *of_find_compatible_node(struct device_node *from, 399 const char *type, const char *compatible) 400 { 401 struct device_node *np; 402 403 for_each_of_allnodes_from(from, np) 404 if (of_device_is_compatible(np, compatible, type, NULL) && 405 of_node_get(np)) 406 break; 407 of_node_put(from); 408 409 return np; 410 } 411 412 struct device_node *of_find_node_by_phandle(phandle handle) 413 { 414 struct device_node *np; 415 416 if (!handle) 417 return NULL; 418 419 for_each_of_allnodes(np) 420 if (np->phandle == handle) 421 break; 422 423 #ifdef CONFIG_USING_KERNEL_DTB_V2 424 /* If not find in kernel fdt, traverse u-boot fdt */ 425 if (!np) { 426 for (np = gd->of_root_f; np; np = of_find_all_nodes(np)) { 427 if (np->phandle == handle) 428 break; 429 } 430 } 431 #endif 432 (void)of_node_get(np); 433 434 return np; 435 } 436 437 /** 438 * of_find_property_value_of_size() - find property of given size 439 * 440 * Search for a property in a device node and validate the requested size. 441 * 442 * @np: device node from which the property value is to be read. 443 * @propname: name of the property to be searched. 444 * @len: requested length of property value 445 * 446 * @return the property value on success, -EINVAL if the property does not 447 * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the 448 * property data isn't large enough. 449 */ 450 static void *of_find_property_value_of_size(const struct device_node *np, 451 const char *propname, u32 len) 452 { 453 struct property *prop = of_find_property(np, propname, NULL); 454 455 if (!prop) 456 return ERR_PTR(-EINVAL); 457 if (!prop->value) 458 return ERR_PTR(-ENODATA); 459 if (len > prop->length) 460 return ERR_PTR(-EOVERFLOW); 461 462 return prop->value; 463 } 464 465 int of_read_u32(const struct device_node *np, const char *propname, u32 *outp) 466 { 467 const __be32 *val; 468 469 debug("%s: %s: ", __func__, propname); 470 if (!np) 471 return -EINVAL; 472 val = of_find_property_value_of_size(np, propname, sizeof(*outp)); 473 if (IS_ERR(val)) { 474 debug("(not found)\n"); 475 return PTR_ERR(val); 476 } 477 478 *outp = be32_to_cpup(val); 479 debug("%#x (%d)\n", *outp, *outp); 480 481 return 0; 482 } 483 484 /** 485 * of_property_read_u64 - Find and read a 64 bit integer from a property 486 * @np: device node from which the property value is to be read. 487 * @propname: name of the property to be searched. 488 * @out_value: pointer to return value, modified only if return value is 0. 489 * 490 * Search for a property in a device node and read a 64-bit value from 491 * it. Returns 0 on success, -EINVAL if the property does not exist, 492 * -ENODATA if property does not have a value, and -EOVERFLOW if the 493 * property data isn't large enough. 494 * 495 * The out_value is modified only if a valid u64 value can be decoded. 496 */ 497 int of_property_read_u64(const struct device_node *np, const char *propname, 498 u64 *out_value) 499 { 500 const __be32 *val = of_find_property_value_of_size(np, propname, 501 sizeof(*out_value)); 502 503 if (IS_ERR(val)) 504 return PTR_ERR(val); 505 506 *out_value = of_read_number(val, 2); 507 508 return 0; 509 } 510 511 int of_read_u32_array(const struct device_node *np, const char *propname, 512 u32 *out_values, size_t sz) 513 { 514 const __be32 *val; 515 516 debug("%s: %s: ", __func__, propname); 517 val = of_find_property_value_of_size(np, propname, 518 sz * sizeof(*out_values)); 519 520 if (IS_ERR(val)) 521 return PTR_ERR(val); 522 523 debug("size %zd\n", sz); 524 while (sz--) 525 *out_values++ = be32_to_cpup(val++); 526 527 return 0; 528 } 529 530 int of_write_u32_array(const struct device_node *np, const char *propname, 531 u32 *values, size_t sz) 532 { 533 __be32 *val; 534 535 debug("%s: %s: ", __func__, propname); 536 val = of_find_property_value_of_size(np, propname, 537 sz * sizeof(*values)); 538 539 if (IS_ERR(val)) 540 return PTR_ERR(val); 541 542 debug("size %zd\n", sz); 543 while (sz--) 544 *val++ = cpu_to_be32p(values++); 545 546 return 0; 547 } 548 549 int of_property_match_string(const struct device_node *np, const char *propname, 550 const char *string) 551 { 552 const struct property *prop = of_find_property(np, propname, NULL); 553 size_t l; 554 int i; 555 const char *p, *end; 556 557 if (!prop) 558 return -EINVAL; 559 if (!prop->value) 560 return -ENODATA; 561 562 p = prop->value; 563 end = p + prop->length; 564 565 for (i = 0; p < end; i++, p += l) { 566 l = strnlen(p, end - p) + 1; 567 if (p + l > end) 568 return -EILSEQ; 569 debug("comparing %s with %s\n", string, p); 570 if (strcmp(string, p) == 0) 571 return i; /* Found it; return index */ 572 } 573 return -ENODATA; 574 } 575 576 /** 577 * of_property_read_string_helper() - Utility helper for parsing string properties 578 * @np: device node from which the property value is to be read. 579 * @propname: name of the property to be searched. 580 * @out_strs: output array of string pointers. 581 * @sz: number of array elements to read. 582 * @skip: Number of strings to skip over at beginning of list. 583 * 584 * Don't call this function directly. It is a utility helper for the 585 * of_property_read_string*() family of functions. 586 */ 587 int of_property_read_string_helper(const struct device_node *np, 588 const char *propname, const char **out_strs, 589 size_t sz, int skip) 590 { 591 const struct property *prop = of_find_property(np, propname, NULL); 592 int l = 0, i = 0; 593 const char *p, *end; 594 595 if (!prop) 596 return -EINVAL; 597 if (!prop->value) 598 return -ENODATA; 599 p = prop->value; 600 end = p + prop->length; 601 602 for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) { 603 l = strnlen(p, end - p) + 1; 604 if (p + l > end) 605 return -EILSEQ; 606 if (out_strs && i >= skip) 607 *out_strs++ = p; 608 } 609 i -= skip; 610 return i <= 0 ? -ENODATA : i; 611 } 612 613 static int __of_parse_phandle_with_args(const struct device_node *np, 614 const char *list_name, 615 const char *cells_name, 616 int cell_count, int index, 617 struct of_phandle_args *out_args) 618 { 619 const __be32 *list, *list_end; 620 int rc = 0, cur_index = 0; 621 uint32_t count = 0; 622 struct device_node *node = NULL; 623 phandle phandle; 624 int size; 625 626 /* Retrieve the phandle list property */ 627 list = of_get_property(np, list_name, &size); 628 if (!list) 629 return -ENOENT; 630 list_end = list + size / sizeof(*list); 631 632 /* Loop over the phandles until all the requested entry is found */ 633 while (list < list_end) { 634 rc = -EINVAL; 635 count = 0; 636 637 /* 638 * If phandle is 0, then it is an empty entry with no 639 * arguments. Skip forward to the next entry. 640 */ 641 phandle = be32_to_cpup(list++); 642 if (phandle) { 643 /* 644 * Find the provider node and parse the #*-cells 645 * property to determine the argument length. 646 * 647 * This is not needed if the cell count is hard-coded 648 * (i.e. cells_name not set, but cell_count is set), 649 * except when we're going to return the found node 650 * below. 651 */ 652 if (cells_name || cur_index == index) { 653 node = of_find_node_by_phandle(phandle); 654 if (!node) { 655 debug("%s: could not find phandle\n", 656 np->full_name); 657 goto err; 658 } 659 } 660 661 if (cells_name) { 662 if (of_read_u32(node, cells_name, &count)) { 663 debug("%s: could not get %s for %s\n", 664 np->full_name, cells_name, 665 node->full_name); 666 goto err; 667 } 668 } else { 669 count = cell_count; 670 } 671 672 /* 673 * Make sure that the arguments actually fit in the 674 * remaining property data length 675 */ 676 if (list + count > list_end) { 677 debug("%s: arguments longer than property\n", 678 np->full_name); 679 goto err; 680 } 681 } 682 683 /* 684 * All of the error cases above bail out of the loop, so at 685 * this point, the parsing is successful. If the requested 686 * index matches, then fill the out_args structure and return, 687 * or return -ENOENT for an empty entry. 688 */ 689 rc = -ENOENT; 690 if (cur_index == index) { 691 if (!phandle) 692 goto err; 693 694 if (out_args) { 695 int i; 696 if (WARN_ON(count > OF_MAX_PHANDLE_ARGS)) 697 count = OF_MAX_PHANDLE_ARGS; 698 out_args->np = node; 699 out_args->args_count = count; 700 for (i = 0; i < count; i++) 701 out_args->args[i] = 702 be32_to_cpup(list++); 703 } else { 704 of_node_put(node); 705 } 706 707 /* Found it! return success */ 708 return 0; 709 } 710 711 of_node_put(node); 712 node = NULL; 713 list += count; 714 cur_index++; 715 } 716 717 /* 718 * Unlock node before returning result; will be one of: 719 * -ENOENT : index is for empty phandle 720 * -EINVAL : parsing error on data 721 * [1..n] : Number of phandle (count mode; when index = -1) 722 */ 723 rc = index < 0 ? cur_index : -ENOENT; 724 err: 725 if (node) 726 of_node_put(node); 727 return rc; 728 } 729 730 struct device_node *of_parse_phandle(const struct device_node *np, 731 const char *phandle_name, int index) 732 { 733 struct of_phandle_args args; 734 735 if (index < 0) 736 return NULL; 737 738 if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0, index, 739 &args)) 740 return NULL; 741 742 return args.np; 743 } 744 745 int of_parse_phandle_with_args(const struct device_node *np, 746 const char *list_name, const char *cells_name, 747 int index, struct of_phandle_args *out_args) 748 { 749 if (index < 0) 750 return -EINVAL; 751 752 return __of_parse_phandle_with_args(np, list_name, cells_name, 0, 753 index, out_args); 754 } 755 756 int of_count_phandle_with_args(const struct device_node *np, 757 const char *list_name, const char *cells_name) 758 { 759 return __of_parse_phandle_with_args(np, list_name, cells_name, 0, 760 -1, NULL); 761 } 762 763 static void of_alias_add(struct alias_prop *ap, struct device_node *np, 764 int id, const char *stem, int stem_len) 765 { 766 struct alias_prop *oldap; 767 ap->np = np; 768 ap->id = id; 769 strncpy(ap->stem, stem, stem_len); 770 ap->stem[stem_len] = 0; 771 772 /* Delete U-Boot alias which is same with kernel */ 773 mutex_lock(&of_mutex); 774 list_for_each_entry(oldap, &aliases_lookup, link) { 775 if (stem && !strcmp(stem, oldap->alias) && (id == oldap->id)) { 776 /* Always use from U-Boot aliase */ 777 if (strcmp(stem, "mmc")) 778 continue; 779 780 list_del(&oldap->link); 781 break; 782 } 783 } 784 mutex_unlock(&of_mutex); 785 786 list_add_tail(&ap->link, &aliases_lookup); 787 debug("adding DT alias:%s: stem=%s id=%i node=%s\n", 788 ap->alias, ap->stem, ap->id, of_node_full_name(np)); 789 } 790 791 int of_alias_scan(void) 792 { 793 struct property *pp; 794 795 of_aliases = of_find_node_by_path("/aliases"); 796 of_chosen = of_find_node_by_path("/chosen"); 797 if (of_chosen == NULL) 798 of_chosen = of_find_node_by_path("/chosen@0"); 799 800 if (of_chosen) { 801 const char *name; 802 803 name = of_get_property(of_chosen, "stdout-path", NULL); 804 if (name) 805 of_stdout = of_find_node_opts_by_path(name, 806 &of_stdout_options); 807 } 808 809 if (!of_aliases) 810 return 0; 811 812 for_each_property_of_node(of_aliases, pp) { 813 const char *start = pp->name; 814 const char *end = start + strlen(start); 815 struct device_node *np; 816 struct alias_prop *ap; 817 ulong id; 818 int len; 819 820 /* Skip those we do not want to proceed */ 821 if (!strcmp(pp->name, "name") || 822 !strcmp(pp->name, "phandle") || 823 !strcmp(pp->name, "linux,phandle")) 824 continue; 825 826 np = of_find_node_by_path(pp->value); 827 if (!np) 828 continue; 829 830 /* 831 * walk the alias backwards to extract the id and work out 832 * the 'stem' string 833 */ 834 while (isdigit(*(end-1)) && end > start) 835 end--; 836 len = end - start; 837 838 if (strict_strtoul(end, 10, &id) < 0) 839 continue; 840 841 /* Allocate an alias_prop with enough space for the stem */ 842 ap = malloc(sizeof(*ap) + len + 1); 843 if (!ap) 844 return -ENOMEM; 845 memset(ap, 0, sizeof(*ap) + len + 1); 846 ap->alias = start; 847 of_alias_add(ap, np, id, start, len); 848 } 849 850 return 0; 851 } 852 853 int of_alias_get_id(const struct device_node *np, const char *stem) 854 { 855 struct alias_prop *app; 856 int id = -ENODEV; 857 858 mutex_lock(&of_mutex); 859 list_for_each_entry(app, &aliases_lookup, link) { 860 if (strcmp(app->stem, stem) != 0) 861 continue; 862 863 if (np == app->np) { 864 id = app->id; 865 break; 866 } 867 } 868 mutex_unlock(&of_mutex); 869 870 return id; 871 } 872 873 struct device_node *of_alias_get_dev(const char *stem, int id) 874 { 875 struct alias_prop *app; 876 struct device_node *np = NULL; 877 878 mutex_lock(&of_mutex); 879 list_for_each_entry(app, &aliases_lookup, link) { 880 if (strcmp(app->stem, stem) != 0) 881 continue; 882 883 if (id == app->id) { 884 np = app->np; 885 break; 886 } 887 } 888 mutex_unlock(&of_mutex); 889 890 return np; 891 } 892 893 struct device_node *of_alias_dump(void) 894 { 895 struct alias_prop *app; 896 struct device_node *np = NULL; 897 898 mutex_lock(&of_mutex); 899 list_for_each_entry(app, &aliases_lookup, link) { 900 printf("%10s%d: %20s, phandle=%d %4s\n", 901 app->stem, app->id, 902 app->np->full_name, app->np->phandle, 903 of_get_property(app->np, "u-boot,dm-pre-reloc", NULL) || 904 of_get_property(app->np, "u-boot,dm-spl", NULL) ? "*" : ""); 905 } 906 mutex_unlock(&of_mutex); 907 908 return np; 909 } 910 911 struct device_node *of_get_stdout(void) 912 { 913 return of_stdout; 914 } 915