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 33DECLARE_GLOBAL_DATA_PTR; 34 35/* list of struct alias_prop aliases */ 36static LIST_HEAD(aliases_lookup); 37 38/* "/aliaes" node */ 39static struct device_node *of_aliases; 40 41/* "/chosen" node */ 42static struct device_node *of_chosen; 43 44/* node pointed to by the stdout-path alias */ 45static struct device_node *of_stdout; 46 47/* pointer to options given after the alias (separated by :) or NULL if none */ 48static 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 */ 62struct 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 70int 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 86int 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 102int 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 114int 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 126struct 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 147struct 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 169const 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 177const 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 185const 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 194const 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 209static 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 226int 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 265bool 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 285struct 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 297static 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 323static 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 346struct 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 407struct 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 421static 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 432struct 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 448struct 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 */ 476static 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 489int 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 508int 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 527int 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 532int 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 551int 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 573int of_read_u64_index(const struct device_node *np, const char *propname, 574 int index, u64 *outp) 575{ 576 const __be64 *val; 577 578 debug("%s: %s: ", __func__, propname); 579 if (!np) 580 return -EINVAL; 581 582 val = of_find_property_value_of_size(np, propname, 583 sizeof(*outp) * (index + 1)); 584 if (IS_ERR(val)) { 585 debug("(not found)\n"); 586 return PTR_ERR(val); 587 } 588 589 *outp = be64_to_cpup(val + index); 590 debug("%#llx (%lld)\n", (unsigned long long)*outp, 591 (unsigned long long)*outp); 592 593 return 0; 594} 595 596int of_read_u64(const struct device_node *np, const char *propname, u64 *outp) 597{ 598 return of_read_u64_index(np, propname, 0, outp); 599} 600 601int of_property_match_string(const struct device_node *np, const char *propname, 602 const char *string) 603{ 604 int len = 0; 605 const struct property *prop = of_find_property(np, propname, &len); 606 size_t l; 607 int i; 608 const char *p, *end; 609 610 if (!prop && len == -FDT_ERR_NOTFOUND) 611 return -ENOENT; 612 if (!prop) 613 return -EINVAL; 614 if (!prop->value) 615 return -ENODATA; 616 617 p = prop->value; 618 end = p + prop->length; 619 620 for (i = 0; p < end; i++, p += l) { 621 l = strnlen(p, end - p) + 1; 622 if (p + l > end) 623 return -EILSEQ; 624 debug("comparing %s with %s\n", string, p); 625 if (strcmp(string, p) == 0) 626 return i; /* Found it; return index */ 627 } 628 return -ENODATA; 629} 630 631/** 632 * of_property_read_string_helper() - Utility helper for parsing string properties 633 * @np: device node from which the property value is to be read. 634 * @propname: name of the property to be searched. 635 * @out_strs: output array of string pointers. 636 * @sz: number of array elements to read. 637 * @skip: Number of strings to skip over at beginning of list (cannot be 638 * negative) 639 * 640 * Don't call this function directly. It is a utility helper for the 641 * of_property_read_string*() family of functions. 642 */ 643int of_property_read_string_helper(const struct device_node *np, 644 const char *propname, const char **out_strs, 645 size_t sz, int skip) 646{ 647 const struct property *prop = of_find_property(np, propname, NULL); 648 int l = 0, i = 0; 649 const char *p, *end; 650 651 if (!prop) 652 return -EINVAL; 653 if (!prop->value) 654 return -ENODATA; 655 p = prop->value; 656 end = p + prop->length; 657 658 for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) { 659 l = strnlen(p, end - p) + 1; 660 if (p + l > end) 661 return -EILSEQ; 662 if (out_strs && i >= skip) 663 *out_strs++ = p; 664 } 665 i -= skip; 666 return i <= 0 ? -ENODATA : i; 667} 668 669static int __of_parse_phandle_with_args(const struct device_node *np, 670 const char *list_name, 671 const char *cells_name, 672 int cell_count, int index, 673 struct of_phandle_args *out_args) 674{ 675 const __be32 *list, *list_end; 676 int rc = 0, cur_index = 0; 677 uint32_t count; 678 struct device_node *node = NULL; 679 phandle phandle; 680 int size; 681 682 /* Retrieve the phandle list property */ 683 list = of_get_property(np, list_name, &size); 684 if (!list) 685 return -ENOENT; 686 list_end = list + size / sizeof(*list); 687 688 /* Loop over the phandles until all the requested entry is found */ 689 while (list < list_end) { 690 rc = -EINVAL; 691 count = 0; 692 693 /* 694 * If phandle is 0, then it is an empty entry with no 695 * arguments. Skip forward to the next entry. 696 */ 697 phandle = be32_to_cpup(list++); 698 if (phandle) { 699 /* 700 * Find the provider node and parse the #*-cells 701 * property to determine the argument length. 702 * 703 * This is not needed if the cell count is hard-coded 704 * (i.e. cells_name not set, but cell_count is set), 705 * except when we're going to return the found node 706 * below. 707 */ 708 if (cells_name || cur_index == index) { 709 node = of_find_node_by_phandle(NULL, phandle); 710 if (!node) { 711 debug("%s: could not find phandle\n", 712 np->full_name); 713 goto err; 714 } 715 } 716 717 if (cells_name) { 718 if (of_read_u32(node, cells_name, &count)) { 719 debug("%s: could not get %s for %s\n", 720 np->full_name, cells_name, 721 node->full_name); 722 goto err; 723 } 724 } else { 725 count = cell_count; 726 } 727 728 /* 729 * Make sure that the arguments actually fit in the 730 * remaining property data length 731 */ 732 if (list + count > list_end) { 733 debug("%s: arguments longer than property\n", 734 np->full_name); 735 goto err; 736 } 737 } 738 739 /* 740 * All of the error cases above bail out of the loop, so at 741 * this point, the parsing is successful. If the requested 742 * index matches, then fill the out_args structure and return, 743 * or return -ENOENT for an empty entry. 744 */ 745 rc = -ENOENT; 746 if (cur_index == index) { 747 if (!phandle) 748 goto err; 749 750 if (out_args) { 751 int i; 752 if (WARN_ON(count > OF_MAX_PHANDLE_ARGS)) 753 count = OF_MAX_PHANDLE_ARGS; 754 out_args->np = node; 755 out_args->args_count = count; 756 for (i = 0; i < count; i++) 757 out_args->args[i] = 758 be32_to_cpup(list++); 759 } else { 760 of_node_put(node); 761 } 762 763 /* Found it! return success */ 764 return 0; 765 } 766 767 of_node_put(node); 768 node = NULL; 769 list += count; 770 cur_index++; 771 } 772 773 /* 774 * Unlock node before returning result; will be one of: 775 * -ENOENT : index is for empty phandle 776 * -EINVAL : parsing error on data 777 * [1..n] : Number of phandle (count mode; when index = -1) 778 */ 779 rc = index < 0 ? cur_index : -ENOENT; 780 err: 781 if (node) 782 of_node_put(node); 783 return rc; 784} 785 786struct device_node *of_parse_phandle(const struct device_node *np, 787 const char *phandle_name, int index) 788{ 789 struct of_phandle_args args; 790 791 if (index < 0) 792 return NULL; 793 794 if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0, index, 795 &args)) 796 return NULL; 797 798 return args.np; 799} 800 801int of_parse_phandle_with_args(const struct device_node *np, 802 const char *list_name, const char *cells_name, 803 int cell_count, int index, 804 struct of_phandle_args *out_args) 805{ 806 if (index < 0) 807 return -EINVAL; 808 809 return __of_parse_phandle_with_args(np, list_name, cells_name, 810 cell_count, index, out_args); 811} 812 813int of_count_phandle_with_args(const struct device_node *np, 814 const char *list_name, const char *cells_name, 815 int cell_count) 816{ 817 return __of_parse_phandle_with_args(np, list_name, cells_name, 818 cell_count, -1, NULL); 819} 820 821static void of_alias_add(struct alias_prop *ap, struct device_node *np, 822 int id, const char *stem, int stem_len) 823{ 824 ap->np = np; 825 ap->id = id; 826 strncpy(ap->stem, stem, stem_len); 827 ap->stem[stem_len] = 0; 828 list_add_tail(&ap->link, &aliases_lookup); 829 debug("adding DT alias:%s: stem=%s id=%i node=%s\n", 830 ap->alias, ap->stem, ap->id, of_node_full_name(np)); 831} 832 833int of_alias_scan(void) 834{ 835 struct property *pp; 836 837 of_aliases = of_find_node_by_path("/aliases"); 838 of_chosen = of_find_node_by_path("/chosen"); 839 if (of_chosen == NULL) 840 of_chosen = of_find_node_by_path("/chosen@0"); 841 842 if (of_chosen) { 843 const char *name; 844 845 name = of_get_property(of_chosen, "stdout-path", NULL); 846 if (name) 847 of_stdout = of_find_node_opts_by_path(NULL, name, 848 &of_stdout_options); 849 } 850 851 if (!of_aliases) 852 return 0; 853 854 for_each_property_of_node(of_aliases, pp) { 855 const char *start = pp->name; 856 const char *end = start + strlen(start); 857 struct device_node *np; 858 struct alias_prop *ap; 859 ulong id; 860 int len; 861 862 /* Skip those we do not want to proceed */ 863 if (!strcmp(pp->name, "name") || 864 !strcmp(pp->name, "phandle") || 865 !strcmp(pp->name, "linux,phandle")) 866 continue; 867 868 np = of_find_node_by_path(pp->value); 869 if (!np) 870 continue; 871 872 /* 873 * walk the alias backwards to extract the id and work out 874 * the 'stem' string 875 */ 876 while (isdigit(*(end-1)) && end > start) 877 end--; 878 len = end - start; 879 880 if (strict_strtoul(end, 10, &id) < 0) 881 continue; 882 883 /* Allocate an alias_prop with enough space for the stem */ 884 ap = malloc(sizeof(*ap) + len + 1); 885 if (!ap) 886 return -ENOMEM; 887 memset(ap, 0, sizeof(*ap) + len + 1); 888 ap->alias = start; 889 of_alias_add(ap, np, id, start, len); 890 } 891 892 return 0; 893} 894 895int of_alias_get_id(const struct device_node *np, const char *stem) 896{ 897 struct alias_prop *app; 898 int id = -ENODEV; 899 900 mutex_lock(&of_mutex); 901 list_for_each_entry(app, &aliases_lookup, link) { 902 if (strcmp(app->stem, stem) != 0) 903 continue; 904 905 if (np == app->np) { 906 id = app->id; 907 break; 908 } 909 } 910 mutex_unlock(&of_mutex); 911 912 return id; 913} 914 915int of_alias_get_highest_id(const char *stem) 916{ 917 struct alias_prop *app; 918 int id = -1; 919 920 mutex_lock(&of_mutex); 921 list_for_each_entry(app, &aliases_lookup, link) { 922 if (strcmp(app->stem, stem) != 0) 923 continue; 924 925 if (app->id > id) 926 id = app->id; 927 } 928 mutex_unlock(&of_mutex); 929 930 return id; 931} 932 933struct device_node *of_get_stdout(void) 934{ 935 return of_stdout; 936} 937 938int of_write_prop(struct device_node *np, const char *propname, int len, 939 const void *value) 940{ 941 struct property *pp; 942 struct property *pp_last = NULL; 943 struct property *new; 944 945 if (!np) 946 return -EINVAL; 947 948 for (pp = np->properties; pp; pp = pp->next) { 949 if (strcmp(pp->name, propname) == 0) { 950 /* Property exists -> change value */ 951 pp->value = (void *)value; 952 pp->length = len; 953 return 0; 954 } 955 pp_last = pp; 956 } 957 958 /* Property does not exist -> append new property */ 959 new = malloc(sizeof(struct property)); 960 if (!new) 961 return -ENOMEM; 962 963 new->name = strdup(propname); 964 if (!new->name) { 965 free(new); 966 return -ENOMEM; 967 } 968 969 new->value = (void *)value; 970 new->length = len; 971 new->next = NULL; 972 973 if (pp_last) 974 pp_last->next = new; 975 else 976 np->properties = new; 977 978 return 0; 979} 980 981int of_add_subnode(struct device_node *parent, const char *name, int len, 982 struct device_node **childp) 983{ 984 struct device_node *child, *new, *last_sibling = NULL; 985 char *new_name, *full_name; 986 int parent_fnl; 987 988 if (len == -1) 989 len = strlen(name); 990 __for_each_child_of_node(parent, child) { 991 /* 992 * make sure we don't use a child called "trevor" when we are 993 * searching for "trev". 994 */ 995 if (!strncmp(child->name, name, len) && strlen(name) == len) { 996 *childp = child; 997 return -EEXIST; 998 } 999 last_sibling = child; 1000 } 1001 1002 /* Subnode does not exist -> append new subnode */ 1003 new = calloc(1, sizeof(struct device_node)); 1004 if (!new) 1005 return -ENOMEM; 1006 1007 new_name = memdup(name, len + 1); 1008 if (!new_name) { 1009 free(new); 1010 return -ENOMEM; 1011 } 1012 new_name[len] = '\0'; 1013 1014 /* 1015 * if the parent is the root node (named "") we don't need to prepend 1016 * its full path 1017 */ 1018 parent_fnl = *parent->name ? strlen(parent->full_name) : 0; 1019 full_name = calloc(1, parent_fnl + 1 + len + 1); 1020 if (!full_name) { 1021 free(new_name); 1022 free(new); 1023 return -ENOMEM; 1024 } 1025 new->name = new_name; /* assign to constant pointer */ 1026 1027 strcpy(full_name, parent->full_name); /* "" for root node */ 1028 full_name[parent_fnl] = '/'; 1029 strlcpy(&full_name[parent_fnl + 1], name, len + 1); 1030 new->full_name = full_name; 1031 1032 /* Add as last sibling of the parent */ 1033 if (last_sibling) 1034 last_sibling->sibling = new; 1035 if (!parent->child) 1036 parent->child = new; 1037 new->parent = parent; 1038 1039 *childp = new; 1040 1041 return 0; 1042} 1043 1044int __of_remove_property(struct device_node *np, struct property *prop) 1045{ 1046 struct property **next; 1047 1048 for (next = &np->properties; *next; next = &(*next)->next) { 1049 if (*next == prop) 1050 break; 1051 } 1052 if (!*next) 1053 return -ENODEV; 1054 1055 /* found the node */ 1056 *next = prop->next; 1057 1058 return 0; 1059} 1060 1061int of_remove_property(struct device_node *np, struct property *prop) 1062{ 1063 int rc; 1064 1065 mutex_lock(&of_mutex); 1066 1067 rc = __of_remove_property(np, prop); 1068 1069 mutex_unlock(&of_mutex); 1070 1071 return rc; 1072} 1073 1074int of_remove_node(struct device_node *to_remove) 1075{ 1076 struct device_node *parent = to_remove->parent; 1077 struct device_node *np, *prev; 1078 1079 if (!parent) 1080 return -EPERM; 1081 prev = NULL; 1082 __for_each_child_of_node(parent, np) { 1083 if (np == to_remove) 1084 break; 1085 prev = np; 1086 } 1087 if (!np) 1088 return -EFAULT; 1089 1090 /* if there is a previous node, link it to this one's sibling */ 1091 if (prev) 1092 prev->sibling = np->sibling; 1093 else 1094 parent->child = np->sibling; 1095 1096 /* 1097 * don't free it, since if this is an unflattened tree, all the memory 1098 * was alloced in one block; this pointer will be somewhere in the 1099 * middle of that 1100 * 1101 * TODO(sjg@chromium.org): Consider marking nodes as 'allocated'? 1102 * 1103 * free(np); 1104 */ 1105 1106 return 0; 1107} 1108