* overlay_apply_node - Merges a node into the base device tree * @fdt: Base Device Tree blob * @target: Node offset in the base device tree to apply the fragment to * @fdto: Device tree overlay blob * @node: Node offset in the overlay holding the changes to merge * * overlay_apply_node() merges a node into a target base device tree * node pointed. * * This is part of the final step in the
| 599 | * Negative error code on failure |
| 600 | */ |
| 601 | static int overlay_apply_node(void *fdt, int target, |
| 602 | void *fdto, int node) |
| 603 | { |
| 604 | int property; |
| 605 | int subnode; |
| 606 | |
| 607 | fdt_for_each_property_offset(property, fdto, node) { |
| 608 | const char *name; |
| 609 | const void *prop; |
| 610 | int prop_len; |
| 611 | int ret; |
| 612 | |
| 613 | prop = fdt_getprop_by_offset(fdto, property, &name, |
| 614 | &prop_len); |
| 615 | if (prop_len == -FDT_ERR_NOTFOUND) |
| 616 | return -FDT_ERR_INTERNAL; |
| 617 | if (prop_len < 0) |
| 618 | return prop_len; |
| 619 | |
| 620 | ret = fdt_setprop(fdt, target, name, prop, prop_len); |
| 621 | if (ret) |
| 622 | return ret; |
| 623 | } |
| 624 | |
| 625 | fdt_for_each_subnode(subnode, fdto, node) { |
| 626 | const char *name = fdt_get_name(fdto, subnode, NULL); |
| 627 | int nnode; |
| 628 | int ret; |
| 629 | |
| 630 | nnode = fdt_add_subnode(fdt, target, name); |
| 631 | if (nnode == -FDT_ERR_EXISTS) { |
| 632 | nnode = fdt_subnode_offset(fdt, target, name); |
| 633 | if (nnode == -FDT_ERR_NOTFOUND) |
| 634 | return -FDT_ERR_INTERNAL; |
| 635 | } |
| 636 | |
| 637 | if (nnode < 0) |
| 638 | return nnode; |
| 639 | |
| 640 | ret = overlay_apply_node(fdt, nnode, fdto, subnode); |
| 641 | if (ret) |
| 642 | return ret; |
| 643 | } |
| 644 | |
| 645 | return 0; |
| 646 | } |
| 647 | |
| 648 | /** |
| 649 | * overlay_merge - Merge an overlay into its base device tree |
no test coverage detected