mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-13 15:03:58 +03:00
ofnode: add read_u64_array and count_elems_of_size
These are similar to their Linux counterparts, adding helpers for reading arrays of 64-bit values with of_access and fdtdec implementations. Signed-off-by: Casey Connolly <casey.connolly@linaro.org>
This commit is contained in:
@@ -598,6 +598,25 @@ int of_read_u64(const struct device_node *np, const char *propname, u64 *outp)
|
||||
return of_read_u64_index(np, propname, 0, outp);
|
||||
}
|
||||
|
||||
int of_read_u64_array(const struct device_node *np, const char *propname,
|
||||
u64 *out_values, size_t sz)
|
||||
{
|
||||
const __be64 *val;
|
||||
|
||||
log_debug("%s: %s: ", __func__, propname);
|
||||
val = of_find_property_value_of_size(np, propname,
|
||||
sz * sizeof(*out_values));
|
||||
|
||||
if (IS_ERR(val))
|
||||
return PTR_ERR(val);
|
||||
|
||||
log_debug("size %zd\n", sz);
|
||||
while (sz--)
|
||||
*out_values++ = be64_to_cpup(val++);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int of_property_match_string(const struct device_node *np, const char *propname,
|
||||
const char *string)
|
||||
{
|
||||
@@ -845,6 +864,39 @@ int of_count_phandle_with_args(const struct device_node *np,
|
||||
cell_count);
|
||||
}
|
||||
|
||||
/**
|
||||
* of_property_count_elems_of_size - Count the number of elements in a property
|
||||
*
|
||||
* @np: device node from which the property value is to be read.
|
||||
* @propname: name of the property to be searched.
|
||||
* @elem_size: size of the individual element
|
||||
*
|
||||
* Search for a property in a device node and count the number of elements of
|
||||
* size elem_size in it.
|
||||
*
|
||||
* Return: The number of elements on sucess, -EINVAL if the property does not
|
||||
* exist or its length does not match a multiple of elem_size and -ENODATA if
|
||||
* the property does not have a value.
|
||||
*/
|
||||
int of_property_count_elems_of_size(const struct device_node *np,
|
||||
const char *propname, int elem_size)
|
||||
{
|
||||
const struct property *prop = of_find_property(np, propname, NULL);
|
||||
|
||||
if (!prop)
|
||||
return -EINVAL;
|
||||
if (!prop->value)
|
||||
return -ENODATA;
|
||||
|
||||
if (prop->length % elem_size != 0) {
|
||||
pr_err("size of %s in node %pOF is not a multiple of %d\n",
|
||||
propname, np, elem_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return prop->length / elem_size;
|
||||
}
|
||||
|
||||
static void of_alias_add(struct alias_prop *ap, struct device_node *np,
|
||||
int id, const char *stem, int stem_len)
|
||||
{
|
||||
|
||||
@@ -664,6 +664,54 @@ int ofnode_read_u32_array(ofnode node, const char *propname,
|
||||
}
|
||||
}
|
||||
|
||||
int ofnode_read_u64_array(ofnode node, const char *propname,
|
||||
u64 *out_values, size_t sz)
|
||||
{
|
||||
assert(ofnode_valid(node));
|
||||
log_debug("%s: %s: ", __func__, propname);
|
||||
|
||||
if (ofnode_is_np(node)) {
|
||||
return of_read_u64_array(ofnode_to_np(node), propname,
|
||||
out_values, sz);
|
||||
} else {
|
||||
int ret;
|
||||
|
||||
ret = fdtdec_get_long_array(ofnode_to_fdt(node),
|
||||
ofnode_to_offset(node), propname,
|
||||
out_values, sz);
|
||||
|
||||
/* get the error right, but space is more important in SPL */
|
||||
if (!IS_ENABLED(CONFIG_XPL_BUILD)) {
|
||||
if (ret == -FDT_ERR_NOTFOUND)
|
||||
return -EINVAL;
|
||||
else if (ret == -FDT_ERR_BADLAYOUT)
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
int ofnode_count_elems_of_size(ofnode node, const char *propname, int elem_size)
|
||||
{
|
||||
const char *prop;
|
||||
int len;
|
||||
assert(ofnode_valid(node));
|
||||
|
||||
if (ofnode_is_np(node)) {
|
||||
return of_property_count_elems_of_size(node.np, propname, elem_size);
|
||||
} else {
|
||||
prop = fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node), propname, &len);
|
||||
if (!prop)
|
||||
return -ENOENT;
|
||||
if (len % elem_size != 0) {
|
||||
log_debug("size of %s in node %pOF is not a multiple of %d\n",
|
||||
propname, &node, elem_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
return len / elem_size;
|
||||
}
|
||||
}
|
||||
|
||||
#if !CONFIG_IS_ENABLED(DM_INLINE_OFNODE)
|
||||
bool ofnode_is_enabled(ofnode node)
|
||||
{
|
||||
|
||||
@@ -385,6 +385,23 @@ int of_read_u64(const struct device_node *np, const char *propname, u64 *outp);
|
||||
int of_read_u32_array(const struct device_node *np, const char *propname,
|
||||
u32 *out_values, size_t sz);
|
||||
|
||||
/**
|
||||
* of_read_u64_array() - Find and read an array of 64 bit integers
|
||||
*
|
||||
* Search for a property in a device node and read 64-bit value(s) from
|
||||
* it.
|
||||
*
|
||||
* @np: device node from which the property value is to be read.
|
||||
* @propname: name of the property to be searched.
|
||||
* @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, or -EOVERFLOW if
|
||||
* longer than sz.
|
||||
*/
|
||||
int of_read_u64_array(const struct device_node *np, const char *propname,
|
||||
u64 *out_values, size_t sz);
|
||||
|
||||
/**
|
||||
* of_property_match_string() - Find string in a list and return index
|
||||
*
|
||||
@@ -616,6 +633,9 @@ int of_count_phandle_with_args(const struct device_node *np,
|
||||
const char *list_name, const char *cells_name,
|
||||
int cells_count);
|
||||
|
||||
int of_property_count_elems_of_size(const struct device_node *np,
|
||||
const char *propname, int elem_size);
|
||||
|
||||
/**
|
||||
* of_alias_scan() - Scan all properties of the 'aliases' node
|
||||
*
|
||||
|
||||
@@ -375,6 +375,13 @@ static inline oftree oftree_from_np(struct device_node *root)
|
||||
return tree;
|
||||
}
|
||||
|
||||
/* Dummy put for Linux compat */
|
||||
static inline void ofnode_put(ofnode node)
|
||||
{
|
||||
if (ofnode_is_np(node))
|
||||
of_node_put(node.np);
|
||||
}
|
||||
|
||||
/**
|
||||
* oftree_dispose() - Dispose of an oftree
|
||||
*
|
||||
@@ -588,6 +595,25 @@ const char *ofnode_read_string(ofnode node, const char *propname);
|
||||
int ofnode_read_u32_array(ofnode node, const char *propname,
|
||||
u32 *out_values, size_t sz);
|
||||
|
||||
/**
|
||||
* ofnode_read_u64_array() - Find and read an array of 64 bit integers
|
||||
*
|
||||
* @node: valid node reference to read property from
|
||||
* @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 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 64-bit value(s) from
|
||||
* it.
|
||||
*
|
||||
* The out_values is modified only if a valid u64 value can be decoded.
|
||||
*/
|
||||
int ofnode_read_u64_array(ofnode node, const char *propname,
|
||||
u64 *out_values, size_t sz);
|
||||
|
||||
/**
|
||||
* ofnode_read_bool() - read a boolean value from a property
|
||||
*
|
||||
@@ -652,6 +678,30 @@ static inline ofnode ofnode_next_subnode(ofnode node)
|
||||
fdt_next_subnode(gd->fdt_blob, ofnode_to_offset(node)));
|
||||
}
|
||||
#else
|
||||
|
||||
/**
|
||||
* ofnode_count_elems_of_size() - count the number of elements of size @elem_size
|
||||
* in the property @propname.
|
||||
*
|
||||
* @node: ofnode to check
|
||||
* @propname: the name of the property to count
|
||||
* @elem_size: the size of each element
|
||||
*
|
||||
* Returns: the number of elements or -EINVAL if the property size is not a
|
||||
* multiple of elem_size.
|
||||
*/
|
||||
int ofnode_count_elems_of_size(ofnode node, const char *propname, int elem_size);
|
||||
|
||||
static inline int ofnode_count_u32_elems(ofnode node, const char *propname)
|
||||
{
|
||||
return ofnode_count_elems_of_size(node, propname, 4);
|
||||
}
|
||||
|
||||
static inline int ofnode_count_u64_elems(ofnode node, const char *propname)
|
||||
{
|
||||
return ofnode_count_elems_of_size(node, propname, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* ofnode_is_enabled() - Checks whether a node is enabled.
|
||||
* This looks for a 'status' property. If this exists, then returns true if
|
||||
|
||||
@@ -700,6 +700,22 @@ int fdtdec_lookup_phandle(const void *blob, int node, const char *prop_name);
|
||||
int fdtdec_get_int_array(const void *blob, int node, const char *prop_name,
|
||||
u32 *array, int count);
|
||||
|
||||
/**
|
||||
* Look up a property in a node and return its contents in a u64
|
||||
* array of given length. The property must have at least enough data for
|
||||
* the array (8*count bytes). It may have more, but this will be ignored.
|
||||
*
|
||||
* @param blob FDT blob
|
||||
* @param node node to examine
|
||||
* @param prop_name name of property to find
|
||||
* @param array array to fill with data
|
||||
* @param count number of array elements
|
||||
* Return: 0 if ok, or -FDT_ERR_NOTFOUND if the property is not found,
|
||||
* or -FDT_ERR_BADLAYOUT if not enough data
|
||||
*/
|
||||
int fdtdec_get_long_array(const void *blob, int node, const char *prop_name,
|
||||
u64 *array, int count);
|
||||
|
||||
/**
|
||||
* Look up a property in a node and return its contents in an integer
|
||||
* array of given length. The property must exist but may have less data that
|
||||
|
||||
18
lib/fdtdec.c
18
lib/fdtdec.c
@@ -714,6 +714,24 @@ int fdtdec_get_int_array(const void *blob, int node, const char *prop_name,
|
||||
return err;
|
||||
}
|
||||
|
||||
int fdtdec_get_long_array(const void *blob, int node, const char *prop_name,
|
||||
u64 *array, int count)
|
||||
{
|
||||
const u64 *cell;
|
||||
int err = 0;
|
||||
|
||||
debug("%s: %s\n", __func__, prop_name);
|
||||
cell = get_prop_check_min_len(blob, node, prop_name,
|
||||
sizeof(u64) * count, &err);
|
||||
if (!err) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
array[i] = fdt64_to_cpu(cell[i]);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int fdtdec_get_int_array_count(const void *blob, int node,
|
||||
const char *prop_name, u32 *array, int count)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user