From 6c6591c823e5a01b42ef52526656119e19fb756d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 10 Jan 2025 17:00:09 -0700 Subject: ofnode: Use 4K for a default tree-size At some point it would be nice to have the ofnode API automatically expand the tree as required, to accommodate new nodes. For now, expand the default size so that UPL can be supported. Signed-off-by: Simon Glass --- drivers/core/ofnode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/core/ofnode.c') diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index c8161827d1c..98483c0f523 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -118,7 +118,7 @@ int oftree_new(oftree *treep) return log_msg_ret("liv", ret); tree = oftree_from_np(root); } else { - const int size = 1024; + const int size = 4096; void *fdt; ret = check_tree_count(); -- cgit v1.2.3 From 8b2561bf9f548f78ddf4dca05126a3bd5d1a3f94 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 10 Jan 2025 17:00:10 -0700 Subject: ofnode: Indicate when out of space in a few places Update ofnode_add_subnode() and ofnode_add_prop() to return a suitable error when space is exhausted in the FDT. This makes it easier to see what is going wrong. Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- drivers/core/ofnode.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers/core/ofnode.c') diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 98483c0f523..83c60069cb3 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -1710,9 +1710,10 @@ ofnode ofnode_by_prop_value(ofnode from, const char *propname, int ofnode_write_prop(ofnode node, const char *propname, const void *value, int len, bool copy) { + int ret; + if (of_live_active()) { void *newval; - int ret; if (copy) { newval = malloc(len); @@ -1726,8 +1727,12 @@ int ofnode_write_prop(ofnode node, const char *propname, const void *value, free(newval); return ret; } else { - return fdt_setprop(ofnode_to_fdt(node), ofnode_to_offset(node), - propname, value, len); + ret = fdt_setprop(ofnode_to_fdt(node), ofnode_to_offset(node), + propname, value, len); + if (ret) + return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EINVAL; + + return 0; } } @@ -2015,7 +2020,7 @@ int ofnode_add_subnode(ofnode node, const char *name, ofnode *subnodep) ret = -EEXIST; } if (offset < 0) - return -EINVAL; + return offset == -FDT_ERR_NOSPACE ? -ENOSPC : -EINVAL; subnode = noffset_to_ofnode(node, offset); } -- cgit v1.2.3 From aacc05b07d28e01bbbaf9037b3e8e1275e48701f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 10 Jan 2025 17:00:28 -0700 Subject: dm: core: Provide ofnode_name_eq_unit() to accept a unit address When a unit-address is provided, use it to match against the node name. Since this increases code size, put it into a separate function. Signed-off-by: Simon Glass --- drivers/core/ofnode.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'drivers/core/ofnode.c') diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 83c60069cb3..373c7840eef 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -309,6 +309,29 @@ bool ofnode_name_eq(ofnode node, const char *name) return (strlen(name) == len) && !strncmp(node_name, name, len); } +bool ofnode_name_eq_unit(ofnode node, const char *name) +{ + const char *node_name, *p; + int len; + + assert(ofnode_valid(node)); + + node_name = ofnode_get_name(node); + + /* check the whole name */ + if (!strcmp(node_name, name)) + return true; + + /* if @name has no unit address, try the node name without it */ + len = strlen(name); + p = strchr(node_name, '@'); + if (p && !strchr(name, '@') && len == p - node_name && + !strncmp(node_name, name, len)) + return true; + + return false; +} + int ofnode_read_u8(ofnode node, const char *propname, u8 *outp) { const u8 *cell; -- cgit v1.2.3 From 8985ff56b16dc6c04da2c96d48e7f6f54d04e3ff Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 10 Jan 2025 17:00:29 -0700 Subject: dm: core: Provide ofnode_find_subnode_unit() The ofnode_find_subnode() function currently processes things two different ways, so the treatment of unit addresses differs depending on whether OF_LIVE is enabled or not. Add a new version which uses the ofnode API and add a test to check that unit addresses can be matched correctly. Leave the old function in place for the !OF_LIVE case, to avoid a code-size increase, e.g. on firefly-rk3288 Signed-off-by: Simon Glass --- drivers/core/ofnode.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'drivers/core/ofnode.c') diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 373c7840eef..26e014d5c53 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -599,14 +599,9 @@ ofnode ofnode_find_subnode(ofnode node, const char *subnode_name) log_debug("%s: %s: ", __func__, subnode_name); if (ofnode_is_np(node)) { - struct device_node *np = ofnode_to_np(node); - - for (np = np->child; np; np = np->sibling) { - if (!strcmp(subnode_name, np->name)) - break; - } - subnode = np_to_ofnode(np); + subnode = ofnode_find_subnode_unit(node, subnode_name); } else { + /* special case to avoid code-size increase */ int ooffset = fdt_subnode_offset(ofnode_to_fdt(node), ofnode_to_offset(node), subnode_name); subnode = noffset_to_ofnode(node, ooffset); @@ -617,6 +612,26 @@ ofnode ofnode_find_subnode(ofnode node, const char *subnode_name) return subnode; } +ofnode ofnode_find_subnode_unit(ofnode node, const char *subnode_name) +{ + ofnode subnode, found = ofnode_null(); + + assert(ofnode_valid(node)); + log_debug("%s: ", subnode_name); + + ofnode_for_each_subnode(subnode, node) { + if (ofnode_name_eq_unit(subnode, subnode_name)) { + found = subnode; + break; + } + } + + log_debug("%s\n", ofnode_valid(found) ? + ofnode_get_name(found) : ""); + + return found; +} + int ofnode_read_u32_array(ofnode node, const char *propname, u32 *out_values, size_t sz) { -- cgit v1.2.3