[PATCH] dm: core: of_access: fix return value in of_property_match_string

Eugen Hristev eugen.hristev at collabora.com
Thu May 4 14:22:21 CEST 2023

of_property_match_string calls of_find_property to search for the
string property.
If the device node does not exist, of_find_property returns NULL, and
of_property_match_string returns -EINVAL, which is correct.
However, if the device node exists, but the property is not found,
of_find_property still returns NULL, but it will place -FDT_ERR_NOTFOUND
in the *lenp variable.
of_property_match_string does not use the lenp parameter, thus this error
case is being lost, and treated as if the node is NULL, and returns
-EINVAL, which is incorrect.

The callers of of_property_match_string treat the error differently if
the return value is -EINVAL or -ENOENT, e.g. in dwc3 driver:

	ret = generic_phy_get_by_name(dev, "usb3-phy", &phy);
	if (!ret) {
		ret = generic_phy_init(&phy);
		if (ret)
			return ret;
	} else if (ret != -ENOENT && ret != -ENODATA) {
		debug("could not get phy (err %d)\n", ret);
		return ret;
	} else {
		phy.dev = NULL;

So the caller drivers will just consider the property missing if -ENOENT
is returned, versus the case of -EINVAL, which means something else.

To fix this situation, changed the code to call the of_find_property
with the right third argument to catch this error code and treat it

Signed-off-by: Eugen Hristev <eugen.hristev at collabora.com>
 drivers/core/of_access.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c
index 81a307992c01..57f10445b122 100644
--- a/drivers/core/of_access.c
+++ b/drivers/core/of_access.c
@@ -593,11 +593,14 @@ int of_read_u64(const struct device_node *np, const char *propname, u64 *outp)
 int of_property_match_string(const struct device_node *np, const char *propname,
 			     const char *string)
-	const struct property *prop = of_find_property(np, propname, NULL);
+	int len = 0;
+	const struct property *prop = of_find_property(np, propname, &len);
 	size_t l;
 	int i;
 	const char *p, *end;
+	if (!prop && len == -FDT_ERR_NOTFOUND)
+		return -ENOENT;
 	if (!prop)
 		return -EINVAL;
 	if (!prop->value)

More information about the U-Boot mailing list