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