[PATCH v2 13/41] dm: core: Add a way to obtain a string list
Simon Glass
sjg at chromium.org
Sun Oct 24 01:26:07 CEST 2021
At present we support reading a string list a string at a time. Apart
from being inefficient, this makes it impossible to separate reading of
the devicetree into the of_to_plat() method where it belongs, since any
code which needs access to the string must read it from the devicetree.
Add a function which returns the string property as an array of pointers
to the strings, which is easily used by clients.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
(no changes since v1)
drivers/core/ofnode.c | 26 ++++++++++++++++++++++++++
drivers/core/read.c | 6 ++++++
include/dm/ofnode.h | 20 ++++++++++++++++++++
include/dm/read.h | 28 ++++++++++++++++++++++++++++
test/dm/ofnode.c | 20 ++++++++++++++++++++
5 files changed, 100 insertions(+)
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index 08705ef8d99..709bea272a6 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -456,6 +456,32 @@ int ofnode_read_string_count(ofnode node, const char *property)
}
}
+int ofnode_read_string_list(ofnode node, const char *property,
+ const char ***listp)
+{
+ const char **prop;
+ int count;
+ int i;
+
+ *listp = NULL;
+ count = ofnode_read_string_count(node, property);
+ if (count < 0)
+ return count;
+ if (!count)
+ return 0;
+
+ prop = calloc(count + 1, sizeof(char *));
+ if (!prop)
+ return -ENOMEM;
+
+ for (i = 0; i < count; i++)
+ ofnode_read_string_index(node, property, i, &prop[i]);
+ prop[count] = NULL;
+ *listp = prop;
+
+ return count;
+}
+
static void ofnode_from_fdtdec_phandle_args(struct fdtdec_phandle_args *in,
struct ofnode_phandle_args *out)
{
diff --git a/drivers/core/read.c b/drivers/core/read.c
index 4307ca45799..31f9e78a062 100644
--- a/drivers/core/read.c
+++ b/drivers/core/read.c
@@ -205,6 +205,12 @@ int dev_read_string_count(const struct udevice *dev, const char *propname)
return ofnode_read_string_count(dev_ofnode(dev), propname);
}
+int dev_read_string_list(const struct udevice *dev, const char *propname,
+ const char ***listp)
+{
+ return ofnode_read_string_list(dev_ofnode(dev), propname, listp);
+}
+
int dev_read_phandle_with_args(const struct udevice *dev, const char *list_name,
const char *cells_name, int cell_count,
int index, struct ofnode_phandle_args *out_args)
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index 4faa9bfa563..f2b5b9c2d33 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -609,6 +609,26 @@ int ofnode_read_string_index(ofnode node, const char *propname, int index,
*/
int ofnode_read_string_count(ofnode node, const char *property);
+/**
+ * ofnode_read_string_list() - read a list of strings
+ *
+ * This produces a list of string pointers with each one pointing to a string
+ * in the string list. If the property does not exist, it returns {NULL}.
+ *
+ * The data is allocated and the caller is reponsible for freeing the return
+ * value (the list of string pointers). The strings themselves may not be
+ * changed as they point directly into the devicetree property.
+ *
+ * @node: node to check
+ * @listp: returns an allocated, NULL-terminated list of strings if the return
+ * value is > 0, else is set to NULL
+ * @return number of strings in list, 0 if none, -ENOMEM if out of memory,
+ * -EINVAL if no such property, -EENODATA if property is empty
+ * @return: NULL-terminated list of strings (NULL if no property or empty)
+ */
+int ofnode_read_string_list(ofnode node, const char *property,
+ const char ***listp);
+
/**
* ofnode_parse_phandle_with_args() - Find a node pointed by phandle in a list
*
diff --git a/include/dm/read.h b/include/dm/read.h
index 890bf3d8472..75c6ad6ee49 100644
--- a/include/dm/read.h
+++ b/include/dm/read.h
@@ -371,6 +371,27 @@ int dev_read_string_index(const struct udevice *dev, const char *propname,
* number of strings in the list, or -ve error value if not found
*/
int dev_read_string_count(const struct udevice *dev, const char *propname);
+
+/**
+ * dev_read_string_list() - read a list of strings
+ *
+ * This produces a list of string pointers with each one pointing to a string
+ * in the string list. If the property does not exist, it returns {NULL}.
+ *
+ * The data is allocated and the caller is reponsible for freeing the return
+ * value (the list of string pointers). The strings themselves may not be
+ * changed as they point directly into the devicetree property.
+ *
+ * @dev: device to examine
+ * @propname: name of the property containing the string list
+ * @listp: returns an allocated, NULL-terminated list of strings if the return
+ * value is > 0, else is set to NULL
+ * @return number of strings in list, 0 if none, -ENOMEM if out of memory,
+ * -ENOENT if no such property
+ */
+int dev_read_string_list(const struct udevice *dev, const char *propname,
+ const char ***listp);
+
/**
* dev_read_phandle_with_args() - Find a node pointed by phandle in a list
*
@@ -906,6 +927,13 @@ static inline int dev_read_string_count(const struct udevice *dev,
return ofnode_read_string_count(dev_ofnode(dev), propname);
}
+static inline int dev_read_string_list(const struct udevice *dev,
+ const char *propname,
+ const char ***listp)
+{
+ return ofnode_read_string_list(dev_ofnode(dev), propname, listp);
+}
+
static inline int dev_read_phandle_with_args(const struct udevice *dev,
const char *list_name, const char *cells_name, int cell_count,
int index, struct ofnode_phandle_args *out_args)
diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c
index 537028ca8fc..470cbce4c2e 100644
--- a/test/dm/ofnode.c
+++ b/test/dm/ofnode.c
@@ -336,6 +336,7 @@ DM_TEST(dm_test_ofnode_conf, 0);
static int dm_test_ofnode_string(struct unit_test_state *uts)
{
+ const char **val;
const char *out;
ofnode node;
@@ -348,6 +349,10 @@ static int dm_test_ofnode_string(struct unit_test_state *uts)
ut_asserteq_str("test string", out);
ut_asserteq(0, ofnode_stringlist_search(node, "str-value",
"test string"));
+ ut_asserteq(1, ofnode_read_string_list(node, "str-value", &val));
+ ut_asserteq_str("test string", val[0]);
+ ut_assertnull(val[1]);
+ free(val);
/* list of strings */
ut_asserteq(5, ofnode_read_string_count(node, "mux-control-names"));
@@ -356,6 +361,15 @@ static int dm_test_ofnode_string(struct unit_test_state *uts)
ut_asserteq_str("mux0", out);
ut_asserteq(0, ofnode_stringlist_search(node, "mux-control-names",
"mux0"));
+ ut_asserteq(5, ofnode_read_string_list(node, "mux-control-names",
+ &val));
+ ut_asserteq_str("mux0", val[0]);
+ ut_asserteq_str("mux1", val[1]);
+ ut_asserteq_str("mux2", val[2]);
+ ut_asserteq_str("mux3", val[3]);
+ ut_asserteq_str("mux4", val[4]);
+ ut_assertnull(val[5]);
+ free(val);
ut_assertok(ofnode_read_string_index(node, "mux-control-names", 4,
&out));
@@ -369,6 +383,7 @@ DM_TEST(dm_test_ofnode_string, 0);
static int dm_test_ofnode_string_err(struct unit_test_state *uts)
{
+ const char **val;
const char *out;
ofnode node;
@@ -383,16 +398,21 @@ static int dm_test_ofnode_string_err(struct unit_test_state *uts)
ut_asserteq(-EINVAL, ofnode_read_string_count(node, "missing"));
ut_asserteq(-EINVAL, ofnode_read_string_index(node, "missing", 0,
&out));
+ ut_asserteq(-EINVAL, ofnode_read_string_list(node, "missing", &val));
/* empty property */
ut_asserteq(-ENODATA, ofnode_read_string_count(node, "bool-value"));
ut_asserteq(-ENODATA, ofnode_read_string_index(node, "bool-value", 0,
&out));
+ ut_asserteq(-ENODATA, ofnode_read_string_list(node, "bool-value",
+ &val));
/* badly formatted string list */
ut_asserteq(-EILSEQ, ofnode_read_string_count(node, "int64-value"));
ut_asserteq(-EILSEQ, ofnode_read_string_index(node, "int64-value", 0,
&out));
+ ut_asserteq(-EILSEQ, ofnode_read_string_list(node, "int64-value",
+ &val));
/* out of range / not found */
ut_asserteq(-ENODATA, ofnode_read_string_index(node, "str-value", 1,
--
2.33.0.1079.g6e70778dc9-goog
More information about the U-Boot
mailing list