// SPDX-License-Identifier: GPL-2.0+ /* * drivers/of/property.c - Procedures for accessing and interpreting * Devicetree properties and graphs. * * Initially created by copying procedures from drivers/of/base.c. This * file contains the OF property as well as the OF graph interface * functions. * * Paul Mackerras August 1996. * Copyright (C) 1996-2005 Paul Mackerras. * * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. * {engebret|bergner}@us.ibm.com * * Adapted for sparc and sparc64 by David S. Miller davem@davemloft.net * * Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell and * Grant Likely.
*/
/** * of_property_read_bool - Find a property * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * * Search for a boolean property in a device node. Usage on non-boolean * property types is deprecated. * * Return: true if the property exists false otherwise.
*/ bool of_property_read_bool(conststruct device_node *np, constchar *propname)
{ struct property *prop = of_find_property(np, propname, NULL);
/* * Boolean properties should not have a value. Testing for property * presence should either use of_property_present() or just read the * property value and check the returned error code.
*/ if (prop && prop->length)
pr_warn("%pOF: Read of boolean property '%s' with a value.\n", np, propname);
/** * 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(conststruct device_node *np, constchar *propname, int elem_size)
{ conststruct 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;
}
/** * of_find_property_value_of_size * * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @min: minimum allowed length of property value * @max: maximum allowed length of property value (0 means unlimited) * @len: if !=NULL, actual length is written to here * * Search for a property in a device node and valid the requested size. * * 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 is too small or too large. *
*/ staticvoid *of_find_property_value_of_size(conststruct device_node *np, constchar *propname, u32 min, u32 max, size_t *len)
{ conststruct property *prop = of_find_property(np, propname, NULL);
if (!prop) return ERR_PTR(-EINVAL); if (!prop->value) return ERR_PTR(-ENODATA); if (prop->length < min) return ERR_PTR(-EOVERFLOW); if (max && prop->length > max) return ERR_PTR(-EOVERFLOW);
if (len)
*len = prop->length;
return prop->value;
}
/** * of_property_read_u16_index - Find and read a u16 from a multi-value property. * * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @index: index of the u16 in the list of values * @out_value: pointer to return value, modified only if no error. * * Search for a property in a device node and read nth 16-bit value from * it. * * 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. * * The out_value is modified only if a valid u16 value can be decoded.
*/ int of_property_read_u16_index(conststruct device_node *np, constchar *propname,
u32 index, u16 *out_value)
{ const u16 *val = of_find_property_value_of_size(np, propname,
((index + 1) * sizeof(*out_value)),
0, NULL);
/** * of_property_read_u32_index - Find and read a u32 from a multi-value property. * * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @index: index of the u32 in the list of values * @out_value: pointer to return value, modified only if no error. * * Search for a property in a device node and read nth 32-bit value from * it. * * 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. * * The out_value is modified only if a valid u32 value can be decoded.
*/ int of_property_read_u32_index(conststruct device_node *np, constchar *propname,
u32 index, u32 *out_value)
{ const u32 *val = of_find_property_value_of_size(np, propname,
((index + 1) * sizeof(*out_value)),
0,
NULL);
/** * of_property_read_u64_index - Find and read a u64 from a multi-value property. * * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @index: index of the u64 in the list of values * @out_value: pointer to return value, modified only if no error. * * Search for a property in a device node and read nth 64-bit value from * it. * * 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. * * The out_value is modified only if a valid u64 value can be decoded.
*/ int of_property_read_u64_index(conststruct device_node *np, constchar *propname,
u32 index, u64 *out_value)
{ const u64 *val = of_find_property_value_of_size(np, propname,
((index + 1) * sizeof(*out_value)),
0, NULL);
/** * of_property_read_variable_u8_array - Find and read an array of u8 from a * property, with bounds on the minimum and maximum array size. * * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @out_values: pointer to found values. * @sz_min: minimum number of array elements to read * @sz_max: maximum number of array elements to read, if zero there is no * upper limit on the number of elements in the dts entry but only * sz_min will be read. * * Search for a property in a device node and read 8-bit value(s) from * it. * * dts entry of array should be like: * ``property = /bits/ 8 <0x50 0x60 0x70>;`` * * Return: The number of elements read on success, -EINVAL if the property * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW * if the property data is smaller than sz_min or longer than sz_max. * * The out_values is modified only if a valid u8 value can be decoded.
*/ int of_property_read_variable_u8_array(conststruct device_node *np, constchar *propname, u8 *out_values,
size_t sz_min, size_t sz_max)
{
size_t sz, count; const u8 *val = of_find_property_value_of_size(np, propname,
(sz_min * sizeof(*out_values)),
(sz_max * sizeof(*out_values)),
&sz);
if (IS_ERR(val)) return PTR_ERR(val);
if (!sz_max)
sz = sz_min; else
sz /= sizeof(*out_values);
count = sz; while (count--)
*out_values++ = *val++;
/** * of_property_read_variable_u16_array - Find and read an array of u16 from a * property, with bounds on the minimum and maximum array size. * * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @out_values: pointer to found values. * @sz_min: minimum number of array elements to read * @sz_max: maximum number of array elements to read, if zero there is no * upper limit on the number of elements in the dts entry but only * sz_min will be read. * * Search for a property in a device node and read 16-bit value(s) from * it. * * dts entry of array should be like: * ``property = /bits/ 16 <0x5000 0x6000 0x7000>;`` * * Return: The number of elements read on success, -EINVAL if the property * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW * if the property data is smaller than sz_min or longer than sz_max. * * The out_values is modified only if a valid u16 value can be decoded.
*/ int of_property_read_variable_u16_array(conststruct device_node *np, constchar *propname, u16 *out_values,
size_t sz_min, size_t sz_max)
{
size_t sz, count; const __be16 *val = of_find_property_value_of_size(np, propname,
(sz_min * sizeof(*out_values)),
(sz_max * sizeof(*out_values)),
&sz);
if (IS_ERR(val)) return PTR_ERR(val);
if (!sz_max)
sz = sz_min; else
sz /= sizeof(*out_values);
count = sz; while (count--)
*out_values++ = be16_to_cpup(val++);
/** * of_property_read_variable_u32_array - Find and read an array of 32 bit * integers from a property, with bounds on the minimum and maximum array size. * * @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 found values. * @sz_min: minimum number of array elements to read * @sz_max: maximum number of array elements to read, if zero there is no * upper limit on the number of elements in the dts entry but only * sz_min will be read. * * Search for a property in a device node and read 32-bit value(s) from * it. * * Return: The number of elements read on success, -EINVAL if the property * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW * if the property data is smaller than sz_min or longer than sz_max. * * The out_values is modified only if a valid u32 value can be decoded.
*/ int of_property_read_variable_u32_array(conststruct device_node *np, constchar *propname, u32 *out_values,
size_t sz_min, size_t sz_max)
{
size_t sz, count; const __be32 *val = of_find_property_value_of_size(np, propname,
(sz_min * sizeof(*out_values)),
(sz_max * sizeof(*out_values)),
&sz);
if (IS_ERR(val)) return PTR_ERR(val);
if (!sz_max)
sz = sz_min; else
sz /= sizeof(*out_values);
count = sz; while (count--)
*out_values++ = be32_to_cpup(val++);
/** * of_property_read_u64 - Find and read a 64 bit integer from a property * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @out_value: pointer to return value, modified only if return value is 0. * * Search for a property in a device node and read a 64-bit value from * it. * * 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. * * The out_value is modified only if a valid u64 value can be decoded.
*/ int of_property_read_u64(conststruct device_node *np, constchar *propname,
u64 *out_value)
{ const __be32 *val = of_find_property_value_of_size(np, propname, sizeof(*out_value),
0,
NULL);
/** * of_property_read_variable_u64_array - Find and read an array of 64 bit * integers from a property, with bounds on the minimum and maximum array size. * * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @out_values: pointer to found values. * @sz_min: minimum number of array elements to read * @sz_max: maximum number of array elements to read, if zero there is no * upper limit on the number of elements in the dts entry but only * sz_min will be read. * * Search for a property in a device node and read 64-bit value(s) from * it. * * Return: The number of elements read on success, -EINVAL if the property * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW * if the property data is smaller than sz_min or longer than sz_max. * * The out_values is modified only if a valid u64 value can be decoded.
*/ int of_property_read_variable_u64_array(conststruct device_node *np, constchar *propname, u64 *out_values,
size_t sz_min, size_t sz_max)
{
size_t sz, count; const __be32 *val = of_find_property_value_of_size(np, propname,
(sz_min * sizeof(*out_values)),
(sz_max * sizeof(*out_values)),
&sz);
if (IS_ERR(val)) return PTR_ERR(val);
if (!sz_max)
sz = sz_min; else
sz /= sizeof(*out_values);
count = sz; while (count--) {
*out_values++ = of_read_number(val, 2);
val += 2;
}
/** * of_property_read_string - Find and read a string from a property * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @out_string: pointer to null terminated return string, modified only if * return value is 0. * * Search for a property in a device tree node and retrieve a null * terminated string value (pointer to data, not a copy). * * Return: 0 on success, -EINVAL if the property does not exist, -ENODATA if * property does not have a value, and -EILSEQ if the string is not * null-terminated within the length of the property data. * * Note that the empty string "" has length of 1, thus -ENODATA cannot * be interpreted as an empty string. * * The out_string pointer is modified only if a valid string can be decoded.
*/ int of_property_read_string(conststruct device_node *np, constchar *propname, constchar **out_string)
{ conststruct property *prop = of_find_property(np, propname, NULL);
if (!prop) return -EINVAL; if (!prop->length) return -ENODATA; if (strnlen(prop->value, prop->length) >= prop->length) return -EILSEQ;
*out_string = prop->value; return 0;
}
EXPORT_SYMBOL_GPL(of_property_read_string);
/** * of_property_match_string() - Find string in a list and return index * @np: pointer to the node containing the string list property * @propname: string list property name * @string: pointer to the string to search for in the string list * * Search for an exact match of string in a device node property which is a * string of lists. * * Return: the index of the first occurrence of the string on success, -EINVAL * if the property does not exist, -ENODATA if the property does not have a * value, and -EILSEQ if the string is not null-terminated within the length of * the property data.
*/ int of_property_match_string(conststruct device_node *np, constchar *propname, constchar *string)
{ conststruct property *prop = of_find_property(np, propname, NULL);
size_t l; int i; constchar *p, *end;
if (!prop) return -EINVAL; if (!prop->value) return -ENODATA;
p = prop->value;
end = p + prop->length;
for (i = 0; p < end; i++, p += l) {
l = strnlen(p, end - p) + 1; if (p + l > end) return -EILSEQ;
pr_debug("comparing %s with %s\n", string, p); if (strcmp(string, p) == 0) return i; /* Found it; return index */
} return -ENODATA;
}
EXPORT_SYMBOL_GPL(of_property_match_string);
/** * of_property_read_string_helper() - Utility helper for parsing string properties * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @out_strs: output array of string pointers. * @sz: number of array elements to read. * @skip: Number of strings to skip over at beginning of list. * * Don't call this function directly. It is a utility helper for the * of_property_read_string*() family of functions.
*/ int of_property_read_string_helper(conststruct device_node *np, constchar *propname, constchar **out_strs,
size_t sz, int skip)
{ conststruct property *prop = of_find_property(np, propname, NULL); int l = 0, i = 0; constchar *p, *end;
if (!prop) return -EINVAL; if (!prop->value) return -ENODATA;
p = prop->value;
end = p + prop->length;
for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) {
l = strnlen(p, end - p) + 1; if (p + l > end) return -EILSEQ; if (out_strs && i >= skip)
*out_strs++ = p;
}
i -= skip; return i <= 0 ? -ENODATA : i;
}
EXPORT_SYMBOL_GPL(of_property_read_string_helper);
/** * of_graph_parse_endpoint() - parse common endpoint node properties * @node: pointer to endpoint device_node * @endpoint: pointer to the OF endpoint data structure * * The caller should hold a reference to @node.
*/ int of_graph_parse_endpoint(conststruct device_node *node, struct of_endpoint *endpoint)
{ struct device_node *port_node __free(device_node) =
of_get_parent(node);
WARN_ONCE(!port_node, "%s(): endpoint %pOF has no parent node\n",
__func__, node);
memset(endpoint, 0, sizeof(*endpoint));
endpoint->local_node = node; /* * It doesn't matter whether the two calls below succeed. * If they don't then the default value 0 is used.
*/
of_property_read_u32(port_node, "reg", &endpoint->port);
of_property_read_u32(node, "reg", &endpoint->id);
/** * of_graph_get_port_by_id() - get the port matching a given id * @parent: pointer to the parent device node * @id: id of the port * * Return: A 'port' node pointer with refcount incremented. The caller * has to use of_node_put() on it when done.
*/ struct device_node *of_graph_get_port_by_id(struct device_node *parent, u32 id)
{ struct device_node *node __free(device_node) = of_get_child_by_name(parent, "ports");
/** * of_graph_get_next_port() - get next port node. * @parent: pointer to the parent device node, or parent ports node * @prev: previous port node, or NULL to get first * * Parent device node can be used as @parent whether device node has ports node * or not. It will work same as ports@0 node. * * Return: A 'port' node pointer with refcount incremented. Refcount * of the passed @prev node is decremented.
*/ struct device_node *of_graph_get_next_port(conststruct device_node *parent, struct device_node *prev)
{ if (!parent) return NULL;
if (!prev) { struct device_node *node __free(device_node) =
of_get_child_by_name(parent, "ports");
if (node)
parent = node;
return of_get_child_by_name(parent, "port");
}
do {
prev = of_get_next_child(parent, prev); if (!prev) break;
} while (!of_node_name_eq(prev, "port"));
/** * of_graph_get_next_port_endpoint() - get next endpoint node in port. * If it reached to end of the port, it will return NULL. * @port: pointer to the target port node * @prev: previous endpoint node, or NULL to get first * * Return: An 'endpoint' node pointer with refcount incremented. Refcount * of the passed @prev node is decremented.
*/ struct device_node *of_graph_get_next_port_endpoint(conststruct device_node *port, struct device_node *prev)
{ while (1) {
prev = of_get_next_child(port, prev); if (!prev) break; if (WARN(!of_node_name_eq(prev, "endpoint"), "non endpoint node is used (%pOF)", prev)) continue;
/** * of_graph_get_next_endpoint() - get next endpoint node * @parent: pointer to the parent device node * @prev: previous endpoint node, or NULL to get first * * Return: An 'endpoint' node pointer with refcount incremented. Refcount * of the passed @prev node is decremented.
*/ struct device_node *of_graph_get_next_endpoint(conststruct device_node *parent, struct device_node *prev)
{ struct device_node *endpoint; struct device_node *port;
if (!parent) return NULL;
/* * Start by locating the port node. If no previous endpoint is specified * search for the first port node, otherwise get the previous endpoint * parent port node.
*/ if (!prev) {
port = of_graph_get_next_port(parent, NULL); if (!port) {
pr_debug("graph: no port node found in %pOF\n", parent); return NULL;
}
} else {
port = of_get_parent(prev); if (WARN_ONCE(!port, "%s(): endpoint %pOF has no parent node\n",
__func__, prev)) return NULL;
}
while (1) { /* * Now that we have a port node, get the next endpoint by * getting the next child. If the previous endpoint is NULL this * will return the first child.
*/
endpoint = of_graph_get_next_port_endpoint(port, prev); if (endpoint) {
of_node_put(port); return endpoint;
}
/* No more endpoints under this port, try the next one. */
prev = NULL;
port = of_graph_get_next_port(parent, port); if (!port) return NULL;
}
}
EXPORT_SYMBOL(of_graph_get_next_endpoint);
/** * of_graph_get_endpoint_by_regs() - get endpoint node of specific identifiers * @parent: pointer to the parent device node * @port_reg: identifier (value of reg property) of the parent port node * @reg: identifier (value of reg property) of the endpoint node * * Return: An 'endpoint' node pointer which is identified by reg and at the same * is the child of a port node identified by port_reg. reg and port_reg are * ignored when they are -1. Use of_node_put() on the pointer when done.
*/ struct device_node *of_graph_get_endpoint_by_regs( conststruct device_node *parent, int port_reg, int reg)
{ struct of_endpoint endpoint; struct device_node *node = NULL;
/** * of_graph_get_remote_endpoint() - get remote endpoint node * @node: pointer to a local endpoint device_node * * Return: Remote endpoint node associated with remote endpoint node linked * to @node. Use of_node_put() on it when done.
*/ struct device_node *of_graph_get_remote_endpoint(conststruct device_node *node)
{ /* Get remote endpoint node. */ return of_parse_phandle(node, "remote-endpoint", 0);
}
EXPORT_SYMBOL(of_graph_get_remote_endpoint);
/** * of_graph_get_port_parent() - get port's parent node * @node: pointer to a local endpoint device_node * * Return: device node associated with endpoint node linked * to @node. Use of_node_put() on it when done.
*/ struct device_node *of_graph_get_port_parent(struct device_node *node)
{ unsignedint depth;
if (!node) return NULL;
/* * Preserve usecount for passed in node as of_get_next_parent() * will do of_node_put() on it.
*/
of_node_get(node);
/* Walk 3 levels up only if there is 'ports' node. */ for (depth = 3; depth && node; depth--) {
node = of_get_next_parent(node); if (depth == 2 && !of_node_name_eq(node, "ports") &&
!of_node_name_eq(node, "in-ports") &&
!of_node_name_eq(node, "out-ports")) break;
} return node;
}
EXPORT_SYMBOL(of_graph_get_port_parent);
/** * of_graph_get_remote_port_parent() - get remote port's parent node * @node: pointer to a local endpoint device_node * * Return: Remote device node associated with remote endpoint node linked * to @node. Use of_node_put() on it when done.
*/ struct device_node *of_graph_get_remote_port_parent( conststruct device_node *node)
{ /* Get remote endpoint node. */ struct device_node *np __free(device_node) =
of_graph_get_remote_endpoint(node);
/** * of_graph_get_remote_port() - get remote port node * @node: pointer to a local endpoint device_node * * Return: Remote port node associated with remote endpoint node linked * to @node. Use of_node_put() on it when done.
*/ struct device_node *of_graph_get_remote_port(conststruct device_node *node)
{ struct device_node *np;
/* Get remote endpoint node. */
np = of_graph_get_remote_endpoint(node); if (!np) return NULL; return of_get_next_parent(np);
}
EXPORT_SYMBOL(of_graph_get_remote_port);
/** * of_graph_get_endpoint_count() - get the number of endpoints in a device node * @np: parent device node containing ports and endpoints * * Return: count of endpoint of this device node
*/ unsignedint of_graph_get_endpoint_count(conststruct device_node *np)
{ struct device_node *endpoint; unsignedint num = 0;
/** * of_graph_get_port_count() - get the number of port in a device or ports node * @np: pointer to the device or ports node * * Return: count of port of this device or ports node
*/ unsignedint of_graph_get_port_count(struct device_node *np)
{ unsignedint num = 0;
/** * of_graph_get_remote_node() - get remote parent device_node for given port/endpoint * @node: pointer to parent device_node containing graph port/endpoint * @port: identifier (value of reg property) of the parent port node * @endpoint: identifier (value of reg property) of the endpoint node * * Return: Remote device node associated with remote endpoint node linked * to @node. Use of_node_put() on it when done.
*/ struct device_node *of_graph_get_remote_node(conststruct device_node *node,
u32 port, u32 endpoint)
{ struct device_node *endpoint_node, *remote;
staticconstchar *of_fwnode_get_name_prefix(conststruct fwnode_handle *fwnode)
{ /* Root needs no prefix here (its name is "/"). */ if (!to_of_node(fwnode)->parent) return"";
/** * parse_prop_cells - Property parsing function for suppliers * * @np: Pointer to device tree node containing a list * @prop_name: Name of property to be parsed. Expected to hold phandle values * @index: For properties holding a list of phandles, this is the index * into the list. * @list_name: Property name that is known to contain list of phandle(s) to * supplier(s) * @cells_name: property name that specifies phandles' arguments count * * This is a helper function to parse properties that have a known fixed name * and are a list of phandles and phandle arguments. * * Returns: * - phandle node pointer with refcount incremented. Caller must of_node_put() * on it when done. * - NULL if no phandle found at index
*/ staticstruct device_node *parse_prop_cells(struct device_node *np, constchar *prop_name, int index, constchar *list_name, constchar *cells_name)
{ struct of_phandle_args sup_args;
if (strcmp(prop_name, list_name)) return NULL;
if (__of_parse_phandle_with_args(np, list_name, cells_name, 0, index,
&sup_args)) return NULL;
len = strlen(str);
suffix_len = strlen(suffix); if (len <= suffix_len) return -1; return strcmp(str + len - suffix_len, suffix);
}
/** * parse_suffix_prop_cells - Suffix property parsing function for suppliers * * @np: Pointer to device tree node containing a list * @prop_name: Name of property to be parsed. Expected to hold phandle values * @index: For properties holding a list of phandles, this is the index * into the list. * @suffix: Property suffix that is known to contain list of phandle(s) to * supplier(s) * @cells_name: property name that specifies phandles' arguments count * * This is a helper function to parse properties that have a known fixed suffix * and are a list of phandles and phandle arguments. * * Returns: * - phandle node pointer with refcount incremented. Caller must of_node_put() * on it when done. * - NULL if no phandle found at index
*/ staticstruct device_node *parse_suffix_prop_cells(struct device_node *np, constchar *prop_name, int index, constchar *suffix, constchar *cells_name)
{ struct of_phandle_args sup_args;
if (strcmp_suffix(prop_name, suffix)) return NULL;
if (of_parse_phandle_with_args(np, prop_name, cells_name, index,
&sup_args)) return NULL;
/** * struct supplier_bindings - Property parsing functions for suppliers * * @parse_prop: function name * parse_prop() finds the node corresponding to a supplier phandle * parse_prop.np: Pointer to device node holding supplier phandle property * parse_prop.prop_name: Name of property holding a phandle value * parse_prop.index: For properties holding a list of phandles, this is the * index into the list * @get_con_dev: If the consumer node containing the property is never converted * to a struct device, implement this ops so fw_devlink can use it * to find the true consumer. * @optional: Describes whether a supplier is mandatory or not * @fwlink_flags: Optional fwnode link flags to use when creating a fwnode link * for this property. * * Returns: * parse_prop() return values are * - phandle node pointer with refcount incremented. Caller must of_node_put() * on it when done. * - NULL if no phandle found at index
*/ struct supplier_bindings { struct device_node *(*parse_prop)(struct device_node *np, constchar *prop_name, int index); struct device_node *(*get_con_dev)(struct device_node *np); bool optional;
u8 fwlink_flags;
};
staticstruct device_node *parse_remote_endpoint(struct device_node *np, constchar *prop_name, int index)
{ /* Return NULL for index > 0 to signify end of remote-endpoints. */ if (index > 0 || strcmp(prop_name, "remote-endpoint")) return NULL;
/** * of_link_property - Create device links to suppliers listed in a property * @con_np: The consumer device tree node which contains the property * @prop_name: Name of property to be parsed * * This function checks if the property @prop_name that is present in the * @con_np device tree node is one of the known common device tree bindings * that list phandles to suppliers. If @prop_name isn't one, this function * doesn't do anything. * * If @prop_name is one, this function attempts to create fwnode links from the * consumer device tree node @con_np to all the suppliers device tree nodes * listed in @prop_name. * * Any failed attempt to create a fwnode link will NOT result in an immediate * return. of_link_property() must create links to all the available supplier * device tree nodes even when attempts to create a link to one or more * suppliers fail.
*/ staticint of_link_property(struct device_node *con_np, constchar *prop_name)
{ struct device_node *phandle; conststruct supplier_bindings *s = of_supplier_bindings; unsignedint i = 0; bool matched = false;
/* Do not stop at first failed link, link all available suppliers. */ while (!matched && s->parse_prop) { if (s->optional && !fw_devlink_is_strict()) {
s++; continue;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.