From 66d0d0c188db9e816c5b18e8823a8d8bf5e9cd63 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:18 -0600 Subject: [PATCH] dm: core: Expand integer-reading tests 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 --- 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 8631e1c286..85f7da5a49 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 4dd2aee11c..e4b4b352e4 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 dd70b44344..c556a18f7d 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 a674d7d8fd..8b0a108706 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 5ddfd0298a..eac0c50364 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);