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