diff options
Diffstat (limited to 'drivers/core')
-rw-r--r-- | drivers/core/fdtaddr.c | 2 | ||||
-rw-r--r-- | drivers/core/of_access.c | 27 | ||||
-rw-r--r-- | drivers/core/ofnode.c | 14 | ||||
-rw-r--r-- | drivers/core/root.c | 35 |
4 files changed, 64 insertions, 14 deletions
diff --git a/drivers/core/fdtaddr.c b/drivers/core/fdtaddr.c index f8cdbd6688d..bfd9580050c 100644 --- a/drivers/core/fdtaddr.c +++ b/drivers/core/fdtaddr.c @@ -138,7 +138,7 @@ void *devfdt_get_addr_ptr(struct udevice *dev) void *devfdt_remap_addr_index(struct udevice *dev, int index) { - fdt_addr_t addr = devfdt_get_addr(dev); + fdt_addr_t addr = devfdt_get_addr_index(dev, index); if (addr == FDT_ADDR_T_NONE) return NULL; diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c index 0729dfcdb3b..14c020a687b 100644 --- a/drivers/core/of_access.c +++ b/drivers/core/of_access.c @@ -376,6 +376,33 @@ struct device_node *of_find_compatible_node(struct device_node *from, return np; } +static int of_device_has_prop_value(const struct device_node *device, + const char *propname, const void *propval, + int proplen) +{ + struct property *prop = of_find_property(device, propname, NULL); + + if (!prop || !prop->value || prop->length != proplen) + return 0; + return !memcmp(prop->value, propval, proplen); +} + +struct device_node *of_find_node_by_prop_value(struct device_node *from, + const char *propname, + const void *propval, int proplen) +{ + struct device_node *np; + + for_each_of_allnodes_from(from, np) { + if (of_device_has_prop_value(np, propname, propval, proplen) && + of_node_get(np)) + break; + } + of_node_put(from); + + return np; +} + struct device_node *of_find_node_by_phandle(phandle handle) { struct device_node *np; diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 0cfb0fbabb0..a7e19277232 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -777,3 +777,17 @@ ofnode ofnode_by_compatible(ofnode from, const char *compat) gd->fdt_blob, ofnode_to_offset(from), compat)); } } + +ofnode ofnode_by_prop_value(ofnode from, const char *propname, + const void *propval, int proplen) +{ + if (of_live_active()) { + return np_to_ofnode(of_find_node_by_prop_value( + (struct device_node *)ofnode_to_np(from), propname, + propval, proplen)); + } else { + return offset_to_ofnode(fdt_node_offset_by_prop_value( + gd->fdt_blob, ofnode_to_offset(from), + propname, propval, proplen)); + } +} diff --git a/drivers/core/root.c b/drivers/core/root.c index 72bcc7d7f2a..47d10b888fa 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -330,10 +330,25 @@ static int dm_scan_fdt_node(struct udevice *parent, const void *blob, } #endif +static int dm_scan_fdt_ofnode_path(const char *path, bool pre_reloc_only) +{ + ofnode node; + + node = ofnode_path(path); + if (!ofnode_valid(node)) + return 0; + +#if CONFIG_IS_ENABLED(OF_LIVE) + if (of_live_active()) + return dm_scan_fdt_live(gd->dm_root, node.np, pre_reloc_only); +#endif + return dm_scan_fdt_node(gd->dm_root, gd->fdt_blob, node.of_offset, + pre_reloc_only); +} + int dm_extended_scan_fdt(const void *blob, bool pre_reloc_only) { int ret; - ofnode node; ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only); if (ret) { @@ -341,21 +356,15 @@ int dm_extended_scan_fdt(const void *blob, bool pre_reloc_only) return ret; } - /* bind fixed-clock */ - node = ofnode_path("/clocks"); - /* if no DT "clocks" node, no need to go further */ - if (!ofnode_valid(node)) + ret = dm_scan_fdt_ofnode_path("/clocks", pre_reloc_only); + if (ret) { + debug("scan for /clocks failed: %d\n", ret); return ret; + } -#if CONFIG_IS_ENABLED(OF_LIVE) - if (of_live_active()) - ret = dm_scan_fdt_live(gd->dm_root, node.np, pre_reloc_only); - else -#endif - ret = dm_scan_fdt_node(gd->dm_root, gd->fdt_blob, node.of_offset, - pre_reloc_only); + ret = dm_scan_fdt_ofnode_path("/firmware", pre_reloc_only); if (ret) - debug("dm_scan_fdt_node() failed: %d\n", ret); + debug("scan for /firmware failed: %d\n", ret); return ret; } |