"Das U-Boot" Source Tree
at master 1134 lines 25 kB view raw
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 <log.h> 23#include <malloc.h> 24#include <asm/global_data.h> 25#include <linux/bug.h> 26#include <linux/libfdt.h> 27#include <dm/of_access.h> 28#include <dm/util.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 log_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 log_debug("(not found)\n"); 499 return PTR_ERR(val); 500 } 501 502 *outp = *val; 503 log_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 log_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 log_debug("(not found)\n"); 518 return PTR_ERR(val); 519 } 520 521 *outp = be16_to_cpup(val); 522 log_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 log_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 log_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 log_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 log_debug("(not found)\n"); 564 return PTR_ERR(val); 565 } 566 567 *outp = be32_to_cpup(val + index); 568 log_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 log_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 log_debug("(not found)\n"); 586 return PTR_ERR(val); 587 } 588 589 *outp = be64_to_cpup(val + index); 590 log_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 log_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_root_parse_phandle_with_args(struct device_node *root, 670 const struct device_node *np, 671 const char *list_name, 672 const char *cells_name, 673 int cell_count, int index, 674 struct of_phandle_args *out_args) 675{ 676 const __be32 *list, *list_end; 677 int rc = 0, cur_index = 0; 678 uint32_t count; 679 struct device_node *node = NULL; 680 phandle phandle; 681 int size; 682 683 /* Retrieve the phandle list property */ 684 list = of_get_property(np, list_name, &size); 685 if (!list) 686 return -ENOENT; 687 list_end = list + size / sizeof(*list); 688 689 /* Loop over the phandles until all the requested entry is found */ 690 while (list < list_end) { 691 rc = -EINVAL; 692 count = 0; 693 694 /* 695 * If phandle is 0, then it is an empty entry with no 696 * arguments. Skip forward to the next entry. 697 */ 698 phandle = be32_to_cpup(list++); 699 if (phandle) { 700 /* 701 * Find the provider node and parse the #*-cells 702 * property to determine the argument length. 703 * 704 * This is not needed if the cell count is hard-coded 705 * (i.e. cells_name not set, but cell_count is set), 706 * except when we're going to return the found node 707 * below. 708 */ 709 if (cells_name || cur_index == index) { 710 node = of_find_node_by_phandle(root, phandle); 711 if (!node) { 712 dm_warn("%s: could not find phandle\n", 713 np->full_name); 714 goto err; 715 } 716 } 717 718 if (cells_name) { 719 if (of_read_u32(node, cells_name, &count)) { 720 dm_warn("%s: could not get %s for %s\n", 721 np->full_name, cells_name, 722 node->full_name); 723 goto err; 724 } 725 } else { 726 count = cell_count; 727 } 728 729 /* 730 * Make sure that the arguments actually fit in the 731 * remaining property data length 732 */ 733 if (list + count > list_end) { 734 dm_warn("%s: arguments longer than property\n", 735 np->full_name); 736 goto err; 737 } 738 } 739 740 /* 741 * All of the error cases above bail out of the loop, so at 742 * this point, the parsing is successful. If the requested 743 * index matches, then fill the out_args structure and return, 744 * or return -ENOENT for an empty entry. 745 */ 746 rc = -ENOENT; 747 if (cur_index == index) { 748 if (!phandle) 749 goto err; 750 751 if (out_args) { 752 int i; 753 if (WARN_ON(count > OF_MAX_PHANDLE_ARGS)) 754 count = OF_MAX_PHANDLE_ARGS; 755 out_args->np = node; 756 out_args->args_count = count; 757 for (i = 0; i < count; i++) 758 out_args->args[i] = 759 be32_to_cpup(list++); 760 } else { 761 of_node_put(node); 762 } 763 764 /* Found it! return success */ 765 return 0; 766 } 767 768 of_node_put(node); 769 node = NULL; 770 list += count; 771 cur_index++; 772 } 773 774 /* 775 * Unlock node before returning result; will be one of: 776 * -ENOENT : index is for empty phandle 777 * -EINVAL : parsing error on data 778 * [1..n] : Number of phandle (count mode; when index = -1) 779 */ 780 rc = index < 0 ? cur_index : -ENOENT; 781 err: 782 if (node) 783 of_node_put(node); 784 return rc; 785} 786 787struct device_node *of_root_parse_phandle(struct device_node *root, 788 const struct device_node *np, 789 const char *phandle_name, int index) 790{ 791 struct of_phandle_args args; 792 793 if (index < 0) 794 return NULL; 795 796 if (__of_root_parse_phandle_with_args(root, np, phandle_name, NULL, 0, 797 index, &args)) 798 return NULL; 799 800 return args.np; 801} 802 803int of_root_parse_phandle_with_args(struct device_node *root, 804 const struct device_node *np, 805 const char *list_name, const char *cells_name, 806 int cell_count, int index, 807 struct of_phandle_args *out_args) 808{ 809 if (index < 0) 810 return -EINVAL; 811 812 return __of_root_parse_phandle_with_args(root, np, list_name, cells_name, 813 cell_count, index, out_args); 814} 815 816int of_root_count_phandle_with_args(struct device_node *root, 817 const struct device_node *np, 818 const char *list_name, const char *cells_name, 819 int cell_count) 820{ 821 return __of_root_parse_phandle_with_args(root, np, list_name, cells_name, 822 cell_count, -1, NULL); 823} 824 825struct device_node *of_parse_phandle(const struct device_node *np, 826 const char *phandle_name, int index) 827{ 828 return of_root_parse_phandle(NULL, np, phandle_name, index); 829} 830 831int of_parse_phandle_with_args(const struct device_node *np, 832 const char *list_name, const char *cells_name, 833 int cell_count, int index, 834 struct of_phandle_args *out_args) 835{ 836 return of_root_parse_phandle_with_args(NULL, np, list_name, cells_name, 837 cell_count, index, out_args); 838} 839 840int of_count_phandle_with_args(const struct device_node *np, 841 const char *list_name, const char *cells_name, 842 int cell_count) 843{ 844 return of_root_count_phandle_with_args(NULL, np, list_name, cells_name, 845 cell_count); 846} 847 848static void of_alias_add(struct alias_prop *ap, struct device_node *np, 849 int id, const char *stem, int stem_len) 850{ 851 ap->np = np; 852 ap->id = id; 853 strncpy(ap->stem, stem, stem_len); 854 ap->stem[stem_len] = 0; 855 list_add_tail(&ap->link, &aliases_lookup); 856 log_debug("adding DT alias:%s: stem=%s id=%i node=%s\n", 857 ap->alias, ap->stem, ap->id, of_node_full_name(np)); 858} 859 860int of_alias_scan(void) 861{ 862 struct property *pp; 863 864 of_aliases = of_find_node_by_path("/aliases"); 865 of_chosen = of_find_node_by_path("/chosen"); 866 if (of_chosen == NULL) 867 of_chosen = of_find_node_by_path("/chosen@0"); 868 869 if (of_chosen) { 870 const char *name; 871 872 name = of_get_property(of_chosen, "stdout-path", NULL); 873 if (name) 874 of_stdout = of_find_node_opts_by_path(NULL, name, 875 &of_stdout_options); 876 } 877 878 if (!of_aliases) 879 return 0; 880 881 for_each_property_of_node(of_aliases, pp) { 882 const char *start = pp->name; 883 const char *end = start + strlen(start); 884 struct device_node *np; 885 struct alias_prop *ap; 886 ulong id; 887 int len; 888 889 /* Skip those we do not want to proceed */ 890 if (!strcmp(pp->name, "name") || 891 !strcmp(pp->name, "phandle") || 892 !strcmp(pp->name, "linux,phandle")) 893 continue; 894 895 np = of_find_node_by_path(pp->value); 896 if (!np) 897 continue; 898 899 /* 900 * walk the alias backwards to extract the id and work out 901 * the 'stem' string 902 */ 903 while (isdigit(*(end-1)) && end > start) 904 end--; 905 len = end - start; 906 907 if (strict_strtoul(end, 10, &id) < 0) 908 continue; 909 910 /* Allocate an alias_prop with enough space for the stem */ 911 ap = malloc(sizeof(*ap) + len + 1); 912 if (!ap) 913 return -ENOMEM; 914 memset(ap, 0, sizeof(*ap) + len + 1); 915 ap->alias = start; 916 of_alias_add(ap, np, id, start, len); 917 } 918 919 return 0; 920} 921 922int of_alias_get_id(const struct device_node *np, const char *stem) 923{ 924 struct alias_prop *app; 925 int id = -ENODEV; 926 927 mutex_lock(&of_mutex); 928 list_for_each_entry(app, &aliases_lookup, link) { 929 if (strcmp(app->stem, stem) != 0) 930 continue; 931 932 if (np == app->np) { 933 id = app->id; 934 break; 935 } 936 } 937 mutex_unlock(&of_mutex); 938 939 return id; 940} 941 942int of_alias_get_highest_id(const char *stem) 943{ 944 struct alias_prop *app; 945 int id = -1; 946 947 mutex_lock(&of_mutex); 948 list_for_each_entry(app, &aliases_lookup, link) { 949 if (strcmp(app->stem, stem) != 0) 950 continue; 951 952 if (app->id > id) 953 id = app->id; 954 } 955 mutex_unlock(&of_mutex); 956 957 return id; 958} 959 960struct device_node *of_get_stdout(void) 961{ 962 return of_stdout; 963} 964 965int of_write_prop(struct device_node *np, const char *propname, int len, 966 const void *value) 967{ 968 struct property *pp; 969 struct property *pp_last = NULL; 970 struct property *new; 971 972 if (!np) 973 return -EINVAL; 974 975 for (pp = np->properties; pp; pp = pp->next) { 976 if (strcmp(pp->name, propname) == 0) { 977 /* Property exists -> change value */ 978 pp->value = (void *)value; 979 pp->length = len; 980 return 0; 981 } 982 pp_last = pp; 983 } 984 985 /* Property does not exist -> append new property */ 986 new = malloc(sizeof(struct property)); 987 if (!new) 988 return -ENOMEM; 989 990 new->name = strdup(propname); 991 if (!new->name) { 992 free(new); 993 return -ENOMEM; 994 } 995 996 new->value = (void *)value; 997 new->length = len; 998 new->next = NULL; 999 1000 if (pp_last) 1001 pp_last->next = new; 1002 else 1003 np->properties = new; 1004 1005 return 0; 1006} 1007 1008int of_add_subnode(struct device_node *parent, const char *name, int len, 1009 struct device_node **childp) 1010{ 1011 struct device_node *child, *new, *last_sibling = NULL; 1012 char *new_name, *full_name; 1013 int parent_fnl; 1014 1015 if (len == -1) 1016 len = strlen(name); 1017 __for_each_child_of_node(parent, child) { 1018 /* 1019 * make sure we don't use a child called "trevor" when we are 1020 * searching for "trev". 1021 */ 1022 if (!strncmp(child->name, name, len) && strlen(name) == len) { 1023 *childp = child; 1024 return -EEXIST; 1025 } 1026 last_sibling = child; 1027 } 1028 1029 /* Subnode does not exist -> append new subnode */ 1030 new = calloc(1, sizeof(struct device_node)); 1031 if (!new) 1032 return -ENOMEM; 1033 1034 new_name = memdup(name, len + 1); 1035 if (!new_name) { 1036 free(new); 1037 return -ENOMEM; 1038 } 1039 new_name[len] = '\0'; 1040 1041 /* 1042 * if the parent is the root node (named "") we don't need to prepend 1043 * its full path 1044 */ 1045 parent_fnl = *parent->name ? strlen(parent->full_name) : 0; 1046 full_name = calloc(1, parent_fnl + 1 + len + 1); 1047 if (!full_name) { 1048 free(new_name); 1049 free(new); 1050 return -ENOMEM; 1051 } 1052 new->name = new_name; /* assign to constant pointer */ 1053 1054 strcpy(full_name, parent->full_name); /* "" for root node */ 1055 full_name[parent_fnl] = '/'; 1056 strlcpy(&full_name[parent_fnl + 1], name, len + 1); 1057 new->full_name = full_name; 1058 1059 /* Add as last sibling of the parent */ 1060 if (last_sibling) 1061 last_sibling->sibling = new; 1062 if (!parent->child) 1063 parent->child = new; 1064 new->parent = parent; 1065 1066 *childp = new; 1067 1068 return 0; 1069} 1070 1071int __of_remove_property(struct device_node *np, struct property *prop) 1072{ 1073 struct property **next; 1074 1075 for (next = &np->properties; *next; next = &(*next)->next) { 1076 if (*next == prop) 1077 break; 1078 } 1079 if (!*next) 1080 return -ENODEV; 1081 1082 /* found the node */ 1083 *next = prop->next; 1084 1085 return 0; 1086} 1087 1088int of_remove_property(struct device_node *np, struct property *prop) 1089{ 1090 int rc; 1091 1092 mutex_lock(&of_mutex); 1093 1094 rc = __of_remove_property(np, prop); 1095 1096 mutex_unlock(&of_mutex); 1097 1098 return rc; 1099} 1100 1101int of_remove_node(struct device_node *to_remove) 1102{ 1103 struct device_node *parent = to_remove->parent; 1104 struct device_node *np, *prev; 1105 1106 if (!parent) 1107 return -EPERM; 1108 prev = NULL; 1109 __for_each_child_of_node(parent, np) { 1110 if (np == to_remove) 1111 break; 1112 prev = np; 1113 } 1114 if (!np) 1115 return -EFAULT; 1116 1117 /* if there is a previous node, link it to this one's sibling */ 1118 if (prev) 1119 prev->sibling = np->sibling; 1120 else 1121 parent->child = np->sibling; 1122 1123 /* 1124 * don't free it, since if this is an unflattened tree, all the memory 1125 * was alloced in one block; this pointer will be somewhere in the 1126 * middle of that 1127 * 1128 * TODO(sjg@chromium.org): Consider marking nodes as 'allocated'? 1129 * 1130 * free(np); 1131 */ 1132 1133 return 0; 1134}