dm: core: Add ofnode_read_prop()

Add a new function to read a property that supports reading the length as
well.

Reimplement ofnode_read_string() using it and fix its comment.

Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index 011b43b..eebc5a7 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -101,30 +101,47 @@
 	return prop ? true : false;
 }
 
-const char *ofnode_read_string(ofnode node, const char *propname)
+const void *ofnode_read_prop(ofnode node, const char *propname, int *sizep)
 {
-	const char *str = NULL;
-	int len = -1;
+	const char *val = NULL;
+	int len;
 
 	assert(ofnode_valid(node));
 	debug("%s: %s: ", __func__, propname);
 
 	if (ofnode_is_np(node)) {
 		struct property *prop = of_find_property(
-				ofnode_to_np(node), propname, NULL);
+				ofnode_to_np(node), propname, &len);
 
 		if (prop) {
-			str = prop->value;
+			val = prop->value;
 			len = prop->length;
 		}
 	} else {
-		str = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node),
+		val = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node),
 				  propname, &len);
 	}
-	if (!str) {
+	if (!val) {
 		debug("<not found>\n");
+		if (sizep)
+			*sizep = -FDT_ERR_NOTFOUND;
 		return NULL;
 	}
+	if (sizep)
+		*sizep = len;
+
+	return val;
+}
+
+const char *ofnode_read_string(ofnode node, const char *propname)
+{
+	const char *str;
+	int len;
+
+	str = ofnode_read_prop(node, propname, &len);
+	if (!str)
+		return NULL;
+
 	if (strnlen(str, len) >= len) {
 		debug("<invalid>\n");
 		return NULL;
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index 9e76ae8..8007483 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -257,9 +257,20 @@
 u64 ofnode_read_u64_default(ofnode node, const char *propname, u64 def);
 
 /**
+ * ofnode_read_prop() - Read a property from a node
+ *
+ * @node:	valid node reference to read property from
+ * @propname:	name of the property to read
+ * @sizep:	if non-NULL, returns the size of the property, or an error code
+		if not found
+ * @return property value, or NULL if there is no such property
+ */
+const void *ofnode_read_prop(ofnode node, const char *propname, int *sizep);
+
+/**
  * ofnode_read_string() - Read a string from a property
  *
- * @ref:	valid node reference to read property from
+ * @node:	valid node reference to read property from
  * @propname:	name of the property to read
  * @return string from property value, or NULL if there is no such property
  */
diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c
index 633a3a9..f1e4ed7 100644
--- a/test/dm/ofnode.c
+++ b/test/dm/ofnode.c
@@ -59,6 +59,32 @@
 }
 DM_TEST(dm_test_ofnode_fmap, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
 
+static int dm_test_ofnode_read(struct unit_test_state *uts)
+{
+	const u32 *val;
+	ofnode node;
+	int size;
+
+	node = ofnode_path("/a-test");
+	ut_assert(ofnode_valid(node));
+
+	val = ofnode_read_prop(node, "int-value", &size);
+	ut_assertnonnull(val);
+	ut_asserteq(4, size);
+	ut_asserteq(1234, fdt32_to_cpu(val[0]));
+
+	val = ofnode_read_prop(node, "missing", &size);
+	ut_assertnull(val);
+	ut_asserteq(-FDT_ERR_NOTFOUND, size);
+
+	/* Check it works without a size parameter */
+	val = ofnode_read_prop(node, "missing", NULL);
+	ut_assertnull(val);
+
+	return 0;
+}
+DM_TEST(dm_test_ofnode_read, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
 static int dm_test_ofnode_read_chosen(struct unit_test_state *uts)
 {
 	const char *str;