[PATCH v3 30/45] dm: core: Expand integer-reading tests

Simon Glass sjg at chromium.org
Fri Sep 30 02:00:48 CEST 2022


The current tests do not cover all the behaviour. Add some more.

Tidy up a few inconsistencies between livetree and flattree which come to
light with these tests. Also drop the -ENODATA error since it is never
actually returned.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

Changes in v3:
- Avoid code-size increase in SPL where error codes matter less

 drivers/core/of_access.c |   5 +-
 drivers/core/ofnode.c    |  17 +++++--
 include/dm/of_access.h   |  10 ++--
 include/dm/ofnode.h      |   8 +--
 test/dm/ofnode.c         | 102 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 125 insertions(+), 17 deletions(-)

diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c
index 8631e1c286b..85f7da5a499 100644
--- a/drivers/core/of_access.c
+++ b/drivers/core/of_access.c
@@ -471,8 +471,7 @@ struct device_node *of_find_node_by_phandle(struct device_node *root,
  * @len:	requested length of property value
  *
  * Return: the property value on success, -EINVAL if the property does not
- * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the
- * property data isn't large enough.
+ * exist and -EOVERFLOW if the property data isn't large enough.
  */
 static void *of_find_property_value_of_size(const struct device_node *np,
 					    const char *propname, u32 len)
@@ -481,8 +480,6 @@ static void *of_find_property_value_of_size(const struct device_node *np,
 
 	if (!prop)
 		return ERR_PTR(-EINVAL);
-	if (!prop->value)
-		return ERR_PTR(-ENODATA);
 	if (len > prop->length)
 		return ERR_PTR(-EOVERFLOW);
 
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index 4dd2aee11ce..e4b4b352e46 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -296,9 +296,20 @@ int ofnode_read_u32_array(ofnode node, const char *propname,
 		return of_read_u32_array(ofnode_to_np(node), propname,
 					 out_values, sz);
 	} else {
-		return fdtdec_get_int_array(gd->fdt_blob,
-					    ofnode_to_offset(node), propname,
-					    out_values, sz);
+		int ret;
+
+		ret = fdtdec_get_int_array(gd->fdt_blob,
+					   ofnode_to_offset(node), propname,
+					   out_values, sz);
+
+		/* get the error right, but space is more important in SPL */
+		if (!IS_ENABLED(CONFIG_SPL_BUILD)) {
+			if (ret == -FDT_ERR_NOTFOUND)
+				return -EINVAL;
+			else if (ret == -FDT_ERR_BADLAYOUT)
+				return -EOVERFLOW;
+		}
+		return ret;
 	}
 }
 
diff --git a/include/dm/of_access.h b/include/dm/of_access.h
index dd70b44344d..c556a18f7d9 100644
--- a/include/dm/of_access.h
+++ b/include/dm/of_access.h
@@ -327,8 +327,7 @@ int of_read_u32(const struct device_node *np, const char *propname, u32 *outp);
  * @outp:	pointer to return value, modified only if return value is 0.
  *
  * Return:
- *   0 on success, -EINVAL if the property does not exist,
- *   -ENODATA if property does not have a value, and -EOVERFLOW if the
+ *   0 on success, -EINVAL if the property does not exist, or -EOVERFLOW if the
  *   property data isn't large enough.
  */
 int of_read_u32_index(const struct device_node *np, const char *propname,
@@ -345,8 +344,7 @@ int of_read_u32_index(const struct device_node *np, const char *propname,
  * @outp:	pointer to return value, modified only if return value is 0.
  *
  * Return:
- *   0 on success, -EINVAL if the property does not exist,
- *   -ENODATA if property does not have a value, and -EOVERFLOW if the
+ *   0 on success, -EINVAL if the property does not exist, or -EOVERFLOW if the
  *   property data isn't large enough.
  */
 int of_read_u64(const struct device_node *np, const char *propname, u64 *outp);
@@ -362,8 +360,8 @@ int of_read_u64(const struct device_node *np, const char *propname, u64 *outp);
  * @out_values:	pointer to return value, modified only if return value is 0.
  * @sz:		number of array elements to read
  * Return:
- *   0 on success, -EINVAL if the property does not exist, -ENODATA
- *   if property does not have a value, and -EOVERFLOW is longer than sz.
+ *   0 on success, -EINVAL if the property does not exist, or -EOVERFLOW if
+ *   longer than sz.
  */
 int of_read_u32_array(const struct device_node *np, const char *propname,
 		      u32 *out_values, size_t sz);
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index a674d7d8fd6..8b0a1087062 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -373,12 +373,12 @@ const char *ofnode_read_string(ofnode node, const char *propname);
  * @propname:	name of the property to read
  * @out_values:	pointer to return value, modified only if return value is 0
  * @sz:		number of array elements to read
- * Return: 0 if OK, -ve on error
+ * Return: 0 on success, -EINVAL if the property does not exist,
+ * -ENODATA if property does not have a value, and -EOVERFLOW if the
+ * property data isn't large enough
  *
  * Search for a property in a device node and read 32-bit value(s) from
- * it. Returns 0 on success, -EINVAL if the property does not exist,
- * -ENODATA if property does not have a value, and -EOVERFLOW if the
- * property data isn't large enough.
+ * it.
  *
  * The out_values is modified only if a valid u32 value can be decoded.
  */
diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c
index 5ddfd0298a6..eac0c50364a 100644
--- a/test/dm/ofnode.c
+++ b/test/dm/ofnode.c
@@ -320,6 +320,9 @@ static int dm_test_ofnode_get_path(struct unit_test_state *uts)
 	res = ofnode_get_path(node, buf, 32);
 	ut_asserteq(-ENOSPC, res);
 
+	res = ofnode_get_path(ofnode_root(), buf, 32);
+	ut_asserteq_str("/", buf);
+
 	return 0;
 }
 DM_TEST(dm_test_ofnode_get_path, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
@@ -589,6 +592,7 @@ DM_TEST(dm_test_ofnode_livetree_writing,
 static int dm_test_ofnode_u32(struct unit_test_state *uts)
 {
 	ofnode node;
+	u32 val;
 
 	node = ofnode_path("/lcd");
 	ut_assert(ofnode_valid(node));
@@ -597,10 +601,62 @@ static int dm_test_ofnode_u32(struct unit_test_state *uts)
 	ut_asserteq(1367, ofnode_read_u32_default(node, "xres", 123));
 	ut_assertok(ofnode_write_u32(node, "xres", 1366));
 
+	node = ofnode_path("/backlight");
+	ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 0, &val));
+	ut_asserteq(0, val);
+	ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 1, &val));
+	ut_asserteq(16, val);
+	ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 8, &val));
+	ut_asserteq(255, val);
+	ut_asserteq(-EOVERFLOW,
+		    ofnode_read_u32_index(node, "brightness-levels", 9, &val));
+	ut_asserteq(-EINVAL, ofnode_read_u32_index(node, "missing", 0, &val));
+
 	return 0;
 }
 DM_TEST(dm_test_ofnode_u32, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
 
+static int dm_test_ofnode_u32_array(struct unit_test_state *uts)
+{
+	ofnode node;
+	u32 val[10];
+
+	node = ofnode_path("/a-test");
+	ut_assert(ofnode_valid(node));
+	ut_assertok(ofnode_read_u32_array(node, "int-value", val, 1));
+	ut_asserteq(-EINVAL, ofnode_read_u32_array(node, "missing", val, 1));
+	ut_asserteq(-EOVERFLOW, ofnode_read_u32_array(node, "bool-value", val,
+						      1));
+
+	memset(val, '\0', sizeof(val));
+	ut_assertok(ofnode_read_u32_array(node, "int-array", val + 1, 3));
+	ut_asserteq(0, val[0]);
+	ut_asserteq(5678, val[1]);
+	ut_asserteq(9123, val[2]);
+	ut_asserteq(4567, val[3]);
+	ut_asserteq(0, val[4]);
+	ut_asserteq(-EOVERFLOW, ofnode_read_u32_array(node, "int-array", val,
+						      4));
+
+	return 0;
+}
+DM_TEST(dm_test_ofnode_u32_array, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
+static int dm_test_ofnode_u64(struct unit_test_state *uts)
+{
+	ofnode node;
+	u64 val;
+
+	node = ofnode_path("/a-test");
+	ut_assert(ofnode_valid(node));
+	ut_assertok(ofnode_read_u64(node, "int64-value", &val));
+	ut_asserteq_64(0x1111222233334444, val);
+	ut_asserteq(-EINVAL, ofnode_read_u64(node, "missing", &val));
+
+	return 0;
+}
+DM_TEST(dm_test_ofnode_u64, UT_TESTF_SCAN_FDT);
+
 static int dm_test_ofnode_add_subnode(struct unit_test_state *uts)
 {
 	ofnode node, check, subnode;
@@ -693,3 +749,49 @@ static int dm_test_ofnode_for_each_prop(struct unit_test_state *uts)
 	return 0;
 }
 DM_TEST(dm_test_ofnode_for_each_prop, UT_TESTF_SCAN_FDT);
+
+static int dm_test_ofnode_by_compatible(struct unit_test_state *uts)
+{
+	const char *compat = "denx,u-boot-fdt-test";
+	ofnode node;
+	int count;
+
+	count = 0;
+	for (node = ofnode_null();
+	     node = ofnode_by_compatible(node, compat), ofnode_valid(node);)
+		count++;
+	ut_asserteq(11, count);
+
+	return 0;
+}
+DM_TEST(dm_test_ofnode_by_compatible, UT_TESTF_SCAN_FDT);
+
+static int dm_test_ofnode_find_subnode(struct unit_test_state *uts)
+{
+	ofnode node, subnode;
+
+	node = ofnode_path("/buttons");
+
+	subnode = ofnode_find_subnode(node, "btn1");
+	ut_assert(ofnode_valid(subnode));
+	ut_asserteq_str("btn1", ofnode_get_name(subnode));
+
+	subnode = ofnode_find_subnode(node, "btn");
+	ut_assert(!ofnode_valid(subnode));
+
+	return 0;
+}
+DM_TEST(dm_test_ofnode_find_subnode, UT_TESTF_SCAN_FDT);
+
+static int dm_test_ofnode_get_name(struct unit_test_state *uts)
+{
+	ofnode node;
+
+	node = ofnode_path("/buttons");
+	ut_assert(ofnode_valid(node));
+	ut_asserteq_str("buttons", ofnode_get_name(node));
+	ut_asserteq_str("", ofnode_get_name(ofnode_root()));
+
+	return 0;
+}
+DM_TEST(dm_test_ofnode_get_name, UT_TESTF_SCAN_FDT);
-- 
2.38.0.rc1.362.ged0d419d3c-goog



More information about the U-Boot mailing list