brintos

brintos / linux-shallow public Read only

0
0
Text · 43.7 KiB · 11b922f Raw
1509 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * drivers/of/property.c - Procedures for accessing and interpreting4 *			   Devicetree properties and graphs.5 *6 * Initially created by copying procedures from drivers/of/base.c. This7 * file contains the OF property as well as the OF graph interface8 * functions.9 *10 * Paul Mackerras	August 1996.11 * Copyright (C) 1996-2005 Paul Mackerras.12 *13 *  Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.14 *    {engebret|bergner}@us.ibm.com15 *16 *  Adapted for sparc and sparc64 by David S. Miller davem@davemloft.net17 *18 *  Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell and19 *  Grant Likely.20 */21 22#define pr_fmt(fmt)	"OF: " fmt23 24#include <linux/of.h>25#include <linux/of_address.h>26#include <linux/of_device.h>27#include <linux/of_graph.h>28#include <linux/of_irq.h>29#include <linux/string.h>30#include <linux/moduleparam.h>31 32#include "of_private.h"33 34/**35 * of_graph_is_present() - check graph's presence36 * @node: pointer to device_node containing graph port37 *38 * Return: True if @node has a port or ports (with a port) sub-node,39 * false otherwise.40 */41bool of_graph_is_present(const struct device_node *node)42{43	struct device_node *ports __free(device_node) = of_get_child_by_name(node, "ports");44 45	if (ports)46		node = ports;47 48	struct device_node *port __free(device_node) = of_get_child_by_name(node, "port");49 50	return !!port;51}52EXPORT_SYMBOL(of_graph_is_present);53 54/**55 * of_property_count_elems_of_size - Count the number of elements in a property56 *57 * @np:		device node from which the property value is to be read.58 * @propname:	name of the property to be searched.59 * @elem_size:	size of the individual element60 *61 * Search for a property in a device node and count the number of elements of62 * size elem_size in it.63 *64 * Return: The number of elements on sucess, -EINVAL if the property does not65 * exist or its length does not match a multiple of elem_size and -ENODATA if66 * the property does not have a value.67 */68int of_property_count_elems_of_size(const struct device_node *np,69				const char *propname, int elem_size)70{71	struct property *prop = of_find_property(np, propname, NULL);72 73	if (!prop)74		return -EINVAL;75	if (!prop->value)76		return -ENODATA;77 78	if (prop->length % elem_size != 0) {79		pr_err("size of %s in node %pOF is not a multiple of %d\n",80		       propname, np, elem_size);81		return -EINVAL;82	}83 84	return prop->length / elem_size;85}86EXPORT_SYMBOL_GPL(of_property_count_elems_of_size);87 88/**89 * of_find_property_value_of_size90 *91 * @np:		device node from which the property value is to be read.92 * @propname:	name of the property to be searched.93 * @min:	minimum allowed length of property value94 * @max:	maximum allowed length of property value (0 means unlimited)95 * @len:	if !=NULL, actual length is written to here96 *97 * Search for a property in a device node and valid the requested size.98 *99 * Return: The property value on success, -EINVAL if the property does not100 * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the101 * property data is too small or too large.102 *103 */104static void *of_find_property_value_of_size(const struct device_node *np,105			const char *propname, u32 min, u32 max, size_t *len)106{107	struct property *prop = of_find_property(np, propname, NULL);108 109	if (!prop)110		return ERR_PTR(-EINVAL);111	if (!prop->value)112		return ERR_PTR(-ENODATA);113	if (prop->length < min)114		return ERR_PTR(-EOVERFLOW);115	if (max && prop->length > max)116		return ERR_PTR(-EOVERFLOW);117 118	if (len)119		*len = prop->length;120 121	return prop->value;122}123 124/**125 * of_property_read_u32_index - Find and read a u32 from a multi-value property.126 *127 * @np:		device node from which the property value is to be read.128 * @propname:	name of the property to be searched.129 * @index:	index of the u32 in the list of values130 * @out_value:	pointer to return value, modified only if no error.131 *132 * Search for a property in a device node and read nth 32-bit value from133 * it.134 *135 * Return: 0 on success, -EINVAL if the property does not exist,136 * -ENODATA if property does not have a value, and -EOVERFLOW if the137 * property data isn't large enough.138 *139 * The out_value is modified only if a valid u32 value can be decoded.140 */141int of_property_read_u32_index(const struct device_node *np,142				       const char *propname,143				       u32 index, u32 *out_value)144{145	const u32 *val = of_find_property_value_of_size(np, propname,146					((index + 1) * sizeof(*out_value)),147					0,148					NULL);149 150	if (IS_ERR(val))151		return PTR_ERR(val);152 153	*out_value = be32_to_cpup(((__be32 *)val) + index);154	return 0;155}156EXPORT_SYMBOL_GPL(of_property_read_u32_index);157 158/**159 * of_property_read_u64_index - Find and read a u64 from a multi-value property.160 *161 * @np:		device node from which the property value is to be read.162 * @propname:	name of the property to be searched.163 * @index:	index of the u64 in the list of values164 * @out_value:	pointer to return value, modified only if no error.165 *166 * Search for a property in a device node and read nth 64-bit value from167 * it.168 *169 * Return: 0 on success, -EINVAL if the property does not exist,170 * -ENODATA if property does not have a value, and -EOVERFLOW if the171 * property data isn't large enough.172 *173 * The out_value is modified only if a valid u64 value can be decoded.174 */175int of_property_read_u64_index(const struct device_node *np,176				       const char *propname,177				       u32 index, u64 *out_value)178{179	const u64 *val = of_find_property_value_of_size(np, propname,180					((index + 1) * sizeof(*out_value)),181					0, NULL);182 183	if (IS_ERR(val))184		return PTR_ERR(val);185 186	*out_value = be64_to_cpup(((__be64 *)val) + index);187	return 0;188}189EXPORT_SYMBOL_GPL(of_property_read_u64_index);190 191/**192 * of_property_read_variable_u8_array - Find and read an array of u8 from a193 * property, with bounds on the minimum and maximum array size.194 *195 * @np:		device node from which the property value is to be read.196 * @propname:	name of the property to be searched.197 * @out_values:	pointer to found values.198 * @sz_min:	minimum number of array elements to read199 * @sz_max:	maximum number of array elements to read, if zero there is no200 *		upper limit on the number of elements in the dts entry but only201 *		sz_min will be read.202 *203 * Search for a property in a device node and read 8-bit value(s) from204 * it.205 *206 * dts entry of array should be like:207 *  ``property = /bits/ 8 <0x50 0x60 0x70>;``208 *209 * Return: The number of elements read on success, -EINVAL if the property210 * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW211 * if the property data is smaller than sz_min or longer than sz_max.212 *213 * The out_values is modified only if a valid u8 value can be decoded.214 */215int of_property_read_variable_u8_array(const struct device_node *np,216					const char *propname, u8 *out_values,217					size_t sz_min, size_t sz_max)218{219	size_t sz, count;220	const u8 *val = of_find_property_value_of_size(np, propname,221						(sz_min * sizeof(*out_values)),222						(sz_max * sizeof(*out_values)),223						&sz);224 225	if (IS_ERR(val))226		return PTR_ERR(val);227 228	if (!sz_max)229		sz = sz_min;230	else231		sz /= sizeof(*out_values);232 233	count = sz;234	while (count--)235		*out_values++ = *val++;236 237	return sz;238}239EXPORT_SYMBOL_GPL(of_property_read_variable_u8_array);240 241/**242 * of_property_read_variable_u16_array - Find and read an array of u16 from a243 * property, with bounds on the minimum and maximum array size.244 *245 * @np:		device node from which the property value is to be read.246 * @propname:	name of the property to be searched.247 * @out_values:	pointer to found values.248 * @sz_min:	minimum number of array elements to read249 * @sz_max:	maximum number of array elements to read, if zero there is no250 *		upper limit on the number of elements in the dts entry but only251 *		sz_min will be read.252 *253 * Search for a property in a device node and read 16-bit value(s) from254 * it.255 *256 * dts entry of array should be like:257 *  ``property = /bits/ 16 <0x5000 0x6000 0x7000>;``258 *259 * Return: The number of elements read on success, -EINVAL if the property260 * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW261 * if the property data is smaller than sz_min or longer than sz_max.262 *263 * The out_values is modified only if a valid u16 value can be decoded.264 */265int of_property_read_variable_u16_array(const struct device_node *np,266					const char *propname, u16 *out_values,267					size_t sz_min, size_t sz_max)268{269	size_t sz, count;270	const __be16 *val = of_find_property_value_of_size(np, propname,271						(sz_min * sizeof(*out_values)),272						(sz_max * sizeof(*out_values)),273						&sz);274 275	if (IS_ERR(val))276		return PTR_ERR(val);277 278	if (!sz_max)279		sz = sz_min;280	else281		sz /= sizeof(*out_values);282 283	count = sz;284	while (count--)285		*out_values++ = be16_to_cpup(val++);286 287	return sz;288}289EXPORT_SYMBOL_GPL(of_property_read_variable_u16_array);290 291/**292 * of_property_read_variable_u32_array - Find and read an array of 32 bit293 * integers from a property, with bounds on the minimum and maximum array size.294 *295 * @np:		device node from which the property value is to be read.296 * @propname:	name of the property to be searched.297 * @out_values:	pointer to return found values.298 * @sz_min:	minimum number of array elements to read299 * @sz_max:	maximum number of array elements to read, if zero there is no300 *		upper limit on the number of elements in the dts entry but only301 *		sz_min will be read.302 *303 * Search for a property in a device node and read 32-bit value(s) from304 * it.305 *306 * Return: The number of elements read on success, -EINVAL if the property307 * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW308 * if the property data is smaller than sz_min or longer than sz_max.309 *310 * The out_values is modified only if a valid u32 value can be decoded.311 */312int of_property_read_variable_u32_array(const struct device_node *np,313			       const char *propname, u32 *out_values,314			       size_t sz_min, size_t sz_max)315{316	size_t sz, count;317	const __be32 *val = of_find_property_value_of_size(np, propname,318						(sz_min * sizeof(*out_values)),319						(sz_max * sizeof(*out_values)),320						&sz);321 322	if (IS_ERR(val))323		return PTR_ERR(val);324 325	if (!sz_max)326		sz = sz_min;327	else328		sz /= sizeof(*out_values);329 330	count = sz;331	while (count--)332		*out_values++ = be32_to_cpup(val++);333 334	return sz;335}336EXPORT_SYMBOL_GPL(of_property_read_variable_u32_array);337 338/**339 * of_property_read_u64 - Find and read a 64 bit integer from a property340 * @np:		device node from which the property value is to be read.341 * @propname:	name of the property to be searched.342 * @out_value:	pointer to return value, modified only if return value is 0.343 *344 * Search for a property in a device node and read a 64-bit value from345 * it.346 *347 * Return: 0 on success, -EINVAL if the property does not exist,348 * -ENODATA if property does not have a value, and -EOVERFLOW if the349 * property data isn't large enough.350 *351 * The out_value is modified only if a valid u64 value can be decoded.352 */353int of_property_read_u64(const struct device_node *np, const char *propname,354			 u64 *out_value)355{356	const __be32 *val = of_find_property_value_of_size(np, propname,357						sizeof(*out_value),358						0,359						NULL);360 361	if (IS_ERR(val))362		return PTR_ERR(val);363 364	*out_value = of_read_number(val, 2);365	return 0;366}367EXPORT_SYMBOL_GPL(of_property_read_u64);368 369/**370 * of_property_read_variable_u64_array - Find and read an array of 64 bit371 * integers from a property, with bounds on the minimum and maximum array size.372 *373 * @np:		device node from which the property value is to be read.374 * @propname:	name of the property to be searched.375 * @out_values:	pointer to found values.376 * @sz_min:	minimum number of array elements to read377 * @sz_max:	maximum number of array elements to read, if zero there is no378 *		upper limit on the number of elements in the dts entry but only379 *		sz_min will be read.380 *381 * Search for a property in a device node and read 64-bit value(s) from382 * it.383 *384 * Return: The number of elements read on success, -EINVAL if the property385 * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW386 * if the property data is smaller than sz_min or longer than sz_max.387 *388 * The out_values is modified only if a valid u64 value can be decoded.389 */390int of_property_read_variable_u64_array(const struct device_node *np,391			       const char *propname, u64 *out_values,392			       size_t sz_min, size_t sz_max)393{394	size_t sz, count;395	const __be32 *val = of_find_property_value_of_size(np, propname,396						(sz_min * sizeof(*out_values)),397						(sz_max * sizeof(*out_values)),398						&sz);399 400	if (IS_ERR(val))401		return PTR_ERR(val);402 403	if (!sz_max)404		sz = sz_min;405	else406		sz /= sizeof(*out_values);407 408	count = sz;409	while (count--) {410		*out_values++ = of_read_number(val, 2);411		val += 2;412	}413 414	return sz;415}416EXPORT_SYMBOL_GPL(of_property_read_variable_u64_array);417 418/**419 * of_property_read_string - Find and read a string from a property420 * @np:		device node from which the property value is to be read.421 * @propname:	name of the property to be searched.422 * @out_string:	pointer to null terminated return string, modified only if423 *		return value is 0.424 *425 * Search for a property in a device tree node and retrieve a null426 * terminated string value (pointer to data, not a copy).427 *428 * Return: 0 on success, -EINVAL if the property does not exist, -ENODATA if429 * property does not have a value, and -EILSEQ if the string is not430 * null-terminated within the length of the property data.431 *432 * Note that the empty string "" has length of 1, thus -ENODATA cannot433 * be interpreted as an empty string.434 *435 * The out_string pointer is modified only if a valid string can be decoded.436 */437int of_property_read_string(const struct device_node *np, const char *propname,438				const char **out_string)439{440	const struct property *prop = of_find_property(np, propname, NULL);441 442	if (!prop)443		return -EINVAL;444	if (!prop->length)445		return -ENODATA;446	if (strnlen(prop->value, prop->length) >= prop->length)447		return -EILSEQ;448	*out_string = prop->value;449	return 0;450}451EXPORT_SYMBOL_GPL(of_property_read_string);452 453/**454 * of_property_match_string() - Find string in a list and return index455 * @np: pointer to the node containing the string list property456 * @propname: string list property name457 * @string: pointer to the string to search for in the string list458 *459 * Search for an exact match of string in a device node property which is a460 * string of lists.461 *462 * Return: the index of the first occurrence of the string on success, -EINVAL463 * if the property does not exist, -ENODATA if the property does not have a464 * value, and -EILSEQ if the string is not null-terminated within the length of465 * the property data.466 */467int of_property_match_string(const struct device_node *np, const char *propname,468			     const char *string)469{470	const struct property *prop = of_find_property(np, propname, NULL);471	size_t l;472	int i;473	const char *p, *end;474 475	if (!prop)476		return -EINVAL;477	if (!prop->value)478		return -ENODATA;479 480	p = prop->value;481	end = p + prop->length;482 483	for (i = 0; p < end; i++, p += l) {484		l = strnlen(p, end - p) + 1;485		if (p + l > end)486			return -EILSEQ;487		pr_debug("comparing %s with %s\n", string, p);488		if (strcmp(string, p) == 0)489			return i; /* Found it; return index */490	}491	return -ENODATA;492}493EXPORT_SYMBOL_GPL(of_property_match_string);494 495/**496 * of_property_read_string_helper() - Utility helper for parsing string properties497 * @np:		device node from which the property value is to be read.498 * @propname:	name of the property to be searched.499 * @out_strs:	output array of string pointers.500 * @sz:		number of array elements to read.501 * @skip:	Number of strings to skip over at beginning of list.502 *503 * Don't call this function directly. It is a utility helper for the504 * of_property_read_string*() family of functions.505 */506int of_property_read_string_helper(const struct device_node *np,507				   const char *propname, const char **out_strs,508				   size_t sz, int skip)509{510	const struct property *prop = of_find_property(np, propname, NULL);511	int l = 0, i = 0;512	const char *p, *end;513 514	if (!prop)515		return -EINVAL;516	if (!prop->value)517		return -ENODATA;518	p = prop->value;519	end = p + prop->length;520 521	for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) {522		l = strnlen(p, end - p) + 1;523		if (p + l > end)524			return -EILSEQ;525		if (out_strs && i >= skip)526			*out_strs++ = p;527	}528	i -= skip;529	return i <= 0 ? -ENODATA : i;530}531EXPORT_SYMBOL_GPL(of_property_read_string_helper);532 533const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur,534			       u32 *pu)535{536	const void *curv = cur;537 538	if (!prop)539		return NULL;540 541	if (!cur) {542		curv = prop->value;543		goto out_val;544	}545 546	curv += sizeof(*cur);547	if (curv >= prop->value + prop->length)548		return NULL;549 550out_val:551	*pu = be32_to_cpup(curv);552	return curv;553}554EXPORT_SYMBOL_GPL(of_prop_next_u32);555 556const char *of_prop_next_string(struct property *prop, const char *cur)557{558	const void *curv = cur;559 560	if (!prop)561		return NULL;562 563	if (!cur)564		return prop->value;565 566	curv += strlen(cur) + 1;567	if (curv >= prop->value + prop->length)568		return NULL;569 570	return curv;571}572EXPORT_SYMBOL_GPL(of_prop_next_string);573 574/**575 * of_graph_parse_endpoint() - parse common endpoint node properties576 * @node: pointer to endpoint device_node577 * @endpoint: pointer to the OF endpoint data structure578 *579 * The caller should hold a reference to @node.580 */581int of_graph_parse_endpoint(const struct device_node *node,582			    struct of_endpoint *endpoint)583{584	struct device_node *port_node __free(device_node) =585			    of_get_parent(node);586 587	WARN_ONCE(!port_node, "%s(): endpoint %pOF has no parent node\n",588		  __func__, node);589 590	memset(endpoint, 0, sizeof(*endpoint));591 592	endpoint->local_node = node;593	/*594	 * It doesn't matter whether the two calls below succeed.595	 * If they don't then the default value 0 is used.596	 */597	of_property_read_u32(port_node, "reg", &endpoint->port);598	of_property_read_u32(node, "reg", &endpoint->id);599 600	return 0;601}602EXPORT_SYMBOL(of_graph_parse_endpoint);603 604/**605 * of_graph_get_port_by_id() - get the port matching a given id606 * @parent: pointer to the parent device node607 * @id: id of the port608 *609 * Return: A 'port' node pointer with refcount incremented. The caller610 * has to use of_node_put() on it when done.611 */612struct device_node *of_graph_get_port_by_id(struct device_node *parent, u32 id)613{614	struct device_node *node __free(device_node) = of_get_child_by_name(parent, "ports");615 616	if (node)617		parent = node;618 619	for_each_child_of_node_scoped(parent, port) {620		u32 port_id = 0;621 622		if (!of_node_name_eq(port, "port"))623			continue;624		of_property_read_u32(port, "reg", &port_id);625		if (id == port_id)626			return_ptr(port);627	}628 629	return NULL;630}631EXPORT_SYMBOL(of_graph_get_port_by_id);632 633/**634 * of_graph_get_next_endpoint() - get next endpoint node635 * @parent: pointer to the parent device node636 * @prev: previous endpoint node, or NULL to get first637 *638 * Return: An 'endpoint' node pointer with refcount incremented. Refcount639 * of the passed @prev node is decremented.640 */641struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,642					struct device_node *prev)643{644	struct device_node *endpoint;645	struct device_node *port;646 647	if (!parent)648		return NULL;649 650	/*651	 * Start by locating the port node. If no previous endpoint is specified652	 * search for the first port node, otherwise get the previous endpoint653	 * parent port node.654	 */655	if (!prev) {656		struct device_node *node __free(device_node) =657			of_get_child_by_name(parent, "ports");658 659		if (node)660			parent = node;661 662		port = of_get_child_by_name(parent, "port");663		if (!port) {664			pr_debug("graph: no port node found in %pOF\n", parent);665			return NULL;666		}667	} else {668		port = of_get_parent(prev);669		if (WARN_ONCE(!port, "%s(): endpoint %pOF has no parent node\n",670			      __func__, prev))671			return NULL;672	}673 674	while (1) {675		/*676		 * Now that we have a port node, get the next endpoint by677		 * getting the next child. If the previous endpoint is NULL this678		 * will return the first child.679		 */680		endpoint = of_get_next_child(port, prev);681		if (endpoint) {682			of_node_put(port);683			return endpoint;684		}685 686		/* No more endpoints under this port, try the next one. */687		prev = NULL;688 689		do {690			port = of_get_next_child(parent, port);691			if (!port)692				return NULL;693		} while (!of_node_name_eq(port, "port"));694	}695}696EXPORT_SYMBOL(of_graph_get_next_endpoint);697 698/**699 * of_graph_get_endpoint_by_regs() - get endpoint node of specific identifiers700 * @parent: pointer to the parent device node701 * @port_reg: identifier (value of reg property) of the parent port node702 * @reg: identifier (value of reg property) of the endpoint node703 *704 * Return: An 'endpoint' node pointer which is identified by reg and at the same705 * is the child of a port node identified by port_reg. reg and port_reg are706 * ignored when they are -1. Use of_node_put() on the pointer when done.707 */708struct device_node *of_graph_get_endpoint_by_regs(709	const struct device_node *parent, int port_reg, int reg)710{711	struct of_endpoint endpoint;712	struct device_node *node = NULL;713 714	for_each_endpoint_of_node(parent, node) {715		of_graph_parse_endpoint(node, &endpoint);716		if (((port_reg == -1) || (endpoint.port == port_reg)) &&717			((reg == -1) || (endpoint.id == reg)))718			return node;719	}720 721	return NULL;722}723EXPORT_SYMBOL(of_graph_get_endpoint_by_regs);724 725/**726 * of_graph_get_remote_endpoint() - get remote endpoint node727 * @node: pointer to a local endpoint device_node728 *729 * Return: Remote endpoint node associated with remote endpoint node linked730 *	   to @node. Use of_node_put() on it when done.731 */732struct device_node *of_graph_get_remote_endpoint(const struct device_node *node)733{734	/* Get remote endpoint node. */735	return of_parse_phandle(node, "remote-endpoint", 0);736}737EXPORT_SYMBOL(of_graph_get_remote_endpoint);738 739/**740 * of_graph_get_port_parent() - get port's parent node741 * @node: pointer to a local endpoint device_node742 *743 * Return: device node associated with endpoint node linked744 *	   to @node. Use of_node_put() on it when done.745 */746struct device_node *of_graph_get_port_parent(struct device_node *node)747{748	unsigned int depth;749 750	if (!node)751		return NULL;752 753	/*754	 * Preserve usecount for passed in node as of_get_next_parent()755	 * will do of_node_put() on it.756	 */757	of_node_get(node);758 759	/* Walk 3 levels up only if there is 'ports' node. */760	for (depth = 3; depth && node; depth--) {761		node = of_get_next_parent(node);762		if (depth == 2 && !of_node_name_eq(node, "ports") &&763		    !of_node_name_eq(node, "in-ports") &&764		    !of_node_name_eq(node, "out-ports"))765			break;766	}767	return node;768}769EXPORT_SYMBOL(of_graph_get_port_parent);770 771/**772 * of_graph_get_remote_port_parent() - get remote port's parent node773 * @node: pointer to a local endpoint device_node774 *775 * Return: Remote device node associated with remote endpoint node linked776 *	   to @node. Use of_node_put() on it when done.777 */778struct device_node *of_graph_get_remote_port_parent(779			       const struct device_node *node)780{781	/* Get remote endpoint node. */782	struct device_node *np __free(device_node) =783		of_graph_get_remote_endpoint(node);784 785	return of_graph_get_port_parent(np);786}787EXPORT_SYMBOL(of_graph_get_remote_port_parent);788 789/**790 * of_graph_get_remote_port() - get remote port node791 * @node: pointer to a local endpoint device_node792 *793 * Return: Remote port node associated with remote endpoint node linked794 * to @node. Use of_node_put() on it when done.795 */796struct device_node *of_graph_get_remote_port(const struct device_node *node)797{798	struct device_node *np;799 800	/* Get remote endpoint node. */801	np = of_graph_get_remote_endpoint(node);802	if (!np)803		return NULL;804	return of_get_next_parent(np);805}806EXPORT_SYMBOL(of_graph_get_remote_port);807 808/**809 * of_graph_get_endpoint_count() - get the number of endpoints in a device node810 * @np: parent device node containing ports and endpoints811 *812 * Return: count of endpoint of this device node813 */814unsigned int of_graph_get_endpoint_count(const struct device_node *np)815{816	struct device_node *endpoint;817	unsigned int num = 0;818 819	for_each_endpoint_of_node(np, endpoint)820		num++;821 822	return num;823}824EXPORT_SYMBOL(of_graph_get_endpoint_count);825 826/**827 * of_graph_get_remote_node() - get remote parent device_node for given port/endpoint828 * @node: pointer to parent device_node containing graph port/endpoint829 * @port: identifier (value of reg property) of the parent port node830 * @endpoint: identifier (value of reg property) of the endpoint node831 *832 * Return: Remote device node associated with remote endpoint node linked833 * to @node. Use of_node_put() on it when done.834 */835struct device_node *of_graph_get_remote_node(const struct device_node *node,836					     u32 port, u32 endpoint)837{838	struct device_node *endpoint_node, *remote;839 840	endpoint_node = of_graph_get_endpoint_by_regs(node, port, endpoint);841	if (!endpoint_node) {842		pr_debug("no valid endpoint (%d, %d) for node %pOF\n",843			 port, endpoint, node);844		return NULL;845	}846 847	remote = of_graph_get_remote_port_parent(endpoint_node);848	of_node_put(endpoint_node);849	if (!remote) {850		pr_debug("no valid remote node\n");851		return NULL;852	}853 854	if (!of_device_is_available(remote)) {855		pr_debug("not available for remote node\n");856		of_node_put(remote);857		return NULL;858	}859 860	return remote;861}862EXPORT_SYMBOL(of_graph_get_remote_node);863 864static struct fwnode_handle *of_fwnode_get(struct fwnode_handle *fwnode)865{866	return of_fwnode_handle(of_node_get(to_of_node(fwnode)));867}868 869static void of_fwnode_put(struct fwnode_handle *fwnode)870{871	of_node_put(to_of_node(fwnode));872}873 874static bool of_fwnode_device_is_available(const struct fwnode_handle *fwnode)875{876	return of_device_is_available(to_of_node(fwnode));877}878 879static bool of_fwnode_device_dma_supported(const struct fwnode_handle *fwnode)880{881	return true;882}883 884static enum dev_dma_attr885of_fwnode_device_get_dma_attr(const struct fwnode_handle *fwnode)886{887	if (of_dma_is_coherent(to_of_node(fwnode)))888		return DEV_DMA_COHERENT;889	else890		return DEV_DMA_NON_COHERENT;891}892 893static bool of_fwnode_property_present(const struct fwnode_handle *fwnode,894				       const char *propname)895{896	return of_property_read_bool(to_of_node(fwnode), propname);897}898 899static int of_fwnode_property_read_int_array(const struct fwnode_handle *fwnode,900					     const char *propname,901					     unsigned int elem_size, void *val,902					     size_t nval)903{904	const struct device_node *node = to_of_node(fwnode);905 906	if (!val)907		return of_property_count_elems_of_size(node, propname,908						       elem_size);909 910	switch (elem_size) {911	case sizeof(u8):912		return of_property_read_u8_array(node, propname, val, nval);913	case sizeof(u16):914		return of_property_read_u16_array(node, propname, val, nval);915	case sizeof(u32):916		return of_property_read_u32_array(node, propname, val, nval);917	case sizeof(u64):918		return of_property_read_u64_array(node, propname, val, nval);919	}920 921	return -ENXIO;922}923 924static int925of_fwnode_property_read_string_array(const struct fwnode_handle *fwnode,926				     const char *propname, const char **val,927				     size_t nval)928{929	const struct device_node *node = to_of_node(fwnode);930 931	return val ?932		of_property_read_string_array(node, propname, val, nval) :933		of_property_count_strings(node, propname);934}935 936static const char *of_fwnode_get_name(const struct fwnode_handle *fwnode)937{938	return kbasename(to_of_node(fwnode)->full_name);939}940 941static const char *of_fwnode_get_name_prefix(const struct fwnode_handle *fwnode)942{943	/* Root needs no prefix here (its name is "/"). */944	if (!to_of_node(fwnode)->parent)945		return "";946 947	return "/";948}949 950static struct fwnode_handle *951of_fwnode_get_parent(const struct fwnode_handle *fwnode)952{953	return of_fwnode_handle(of_get_parent(to_of_node(fwnode)));954}955 956static struct fwnode_handle *957of_fwnode_get_next_child_node(const struct fwnode_handle *fwnode,958			      struct fwnode_handle *child)959{960	return of_fwnode_handle(of_get_next_available_child(to_of_node(fwnode),961							    to_of_node(child)));962}963 964static struct fwnode_handle *965of_fwnode_get_named_child_node(const struct fwnode_handle *fwnode,966			       const char *childname)967{968	const struct device_node *node = to_of_node(fwnode);969	struct device_node *child;970 971	for_each_available_child_of_node(node, child)972		if (of_node_name_eq(child, childname))973			return of_fwnode_handle(child);974 975	return NULL;976}977 978static int979of_fwnode_get_reference_args(const struct fwnode_handle *fwnode,980			     const char *prop, const char *nargs_prop,981			     unsigned int nargs, unsigned int index,982			     struct fwnode_reference_args *args)983{984	struct of_phandle_args of_args;985	unsigned int i;986	int ret;987 988	if (nargs_prop)989		ret = of_parse_phandle_with_args(to_of_node(fwnode), prop,990						 nargs_prop, index, &of_args);991	else992		ret = of_parse_phandle_with_fixed_args(to_of_node(fwnode), prop,993						       nargs, index, &of_args);994	if (ret < 0)995		return ret;996	if (!args) {997		of_node_put(of_args.np);998		return 0;999	}1000 1001	args->nargs = of_args.args_count;1002	args->fwnode = of_fwnode_handle(of_args.np);1003 1004	for (i = 0; i < NR_FWNODE_REFERENCE_ARGS; i++)1005		args->args[i] = i < of_args.args_count ? of_args.args[i] : 0;1006 1007	return 0;1008}1009 1010static struct fwnode_handle *1011of_fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode,1012				  struct fwnode_handle *prev)1013{1014	return of_fwnode_handle(of_graph_get_next_endpoint(to_of_node(fwnode),1015							   to_of_node(prev)));1016}1017 1018static struct fwnode_handle *1019of_fwnode_graph_get_remote_endpoint(const struct fwnode_handle *fwnode)1020{1021	return of_fwnode_handle(1022		of_graph_get_remote_endpoint(to_of_node(fwnode)));1023}1024 1025static struct fwnode_handle *1026of_fwnode_graph_get_port_parent(struct fwnode_handle *fwnode)1027{1028	struct device_node *np;1029 1030	/* Get the parent of the port */1031	np = of_get_parent(to_of_node(fwnode));1032	if (!np)1033		return NULL;1034 1035	/* Is this the "ports" node? If not, it's the port parent. */1036	if (!of_node_name_eq(np, "ports"))1037		return of_fwnode_handle(np);1038 1039	return of_fwnode_handle(of_get_next_parent(np));1040}1041 1042static int of_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,1043					  struct fwnode_endpoint *endpoint)1044{1045	const struct device_node *node = to_of_node(fwnode);1046	struct device_node *port_node __free(device_node) = of_get_parent(node);1047 1048	endpoint->local_fwnode = fwnode;1049 1050	of_property_read_u32(port_node, "reg", &endpoint->port);1051	of_property_read_u32(node, "reg", &endpoint->id);1052 1053	return 0;1054}1055 1056static const void *1057of_fwnode_device_get_match_data(const struct fwnode_handle *fwnode,1058				const struct device *dev)1059{1060	return of_device_get_match_data(dev);1061}1062 1063static void of_link_to_phandle(struct device_node *con_np,1064			      struct device_node *sup_np,1065			      u8 flags)1066{1067	struct device_node *tmp_np __free(device_node) = of_node_get(sup_np);1068 1069	/* Check that sup_np and its ancestors are available. */1070	while (tmp_np) {1071		if (of_fwnode_handle(tmp_np)->dev)1072			break;1073 1074		if (!of_device_is_available(tmp_np))1075			return;1076 1077		tmp_np = of_get_next_parent(tmp_np);1078	}1079 1080	fwnode_link_add(of_fwnode_handle(con_np), of_fwnode_handle(sup_np), flags);1081}1082 1083/**1084 * parse_prop_cells - Property parsing function for suppliers1085 *1086 * @np:		Pointer to device tree node containing a list1087 * @prop_name:	Name of property to be parsed. Expected to hold phandle values1088 * @index:	For properties holding a list of phandles, this is the index1089 *		into the list.1090 * @list_name:	Property name that is known to contain list of phandle(s) to1091 *		supplier(s)1092 * @cells_name:	property name that specifies phandles' arguments count1093 *1094 * This is a helper function to parse properties that have a known fixed name1095 * and are a list of phandles and phandle arguments.1096 *1097 * Returns:1098 * - phandle node pointer with refcount incremented. Caller must of_node_put()1099 *   on it when done.1100 * - NULL if no phandle found at index1101 */1102static struct device_node *parse_prop_cells(struct device_node *np,1103					    const char *prop_name, int index,1104					    const char *list_name,1105					    const char *cells_name)1106{1107	struct of_phandle_args sup_args;1108 1109	if (strcmp(prop_name, list_name))1110		return NULL;1111 1112	if (__of_parse_phandle_with_args(np, list_name, cells_name, 0, index,1113					 &sup_args))1114		return NULL;1115 1116	return sup_args.np;1117}1118 1119#define DEFINE_SIMPLE_PROP(fname, name, cells)				  \1120static struct device_node *parse_##fname(struct device_node *np,	  \1121					const char *prop_name, int index) \1122{									  \1123	return parse_prop_cells(np, prop_name, index, name, cells);	  \1124}1125 1126static int strcmp_suffix(const char *str, const char *suffix)1127{1128	unsigned int len, suffix_len;1129 1130	len = strlen(str);1131	suffix_len = strlen(suffix);1132	if (len <= suffix_len)1133		return -1;1134	return strcmp(str + len - suffix_len, suffix);1135}1136 1137/**1138 * parse_suffix_prop_cells - Suffix property parsing function for suppliers1139 *1140 * @np:		Pointer to device tree node containing a list1141 * @prop_name:	Name of property to be parsed. Expected to hold phandle values1142 * @index:	For properties holding a list of phandles, this is the index1143 *		into the list.1144 * @suffix:	Property suffix that is known to contain list of phandle(s) to1145 *		supplier(s)1146 * @cells_name:	property name that specifies phandles' arguments count1147 *1148 * This is a helper function to parse properties that have a known fixed suffix1149 * and are a list of phandles and phandle arguments.1150 *1151 * Returns:1152 * - phandle node pointer with refcount incremented. Caller must of_node_put()1153 *   on it when done.1154 * - NULL if no phandle found at index1155 */1156static struct device_node *parse_suffix_prop_cells(struct device_node *np,1157					    const char *prop_name, int index,1158					    const char *suffix,1159					    const char *cells_name)1160{1161	struct of_phandle_args sup_args;1162 1163	if (strcmp_suffix(prop_name, suffix))1164		return NULL;1165 1166	if (of_parse_phandle_with_args(np, prop_name, cells_name, index,1167				       &sup_args))1168		return NULL;1169 1170	return sup_args.np;1171}1172 1173#define DEFINE_SUFFIX_PROP(fname, suffix, cells)			     \1174static struct device_node *parse_##fname(struct device_node *np,	     \1175					const char *prop_name, int index)    \1176{									     \1177	return parse_suffix_prop_cells(np, prop_name, index, suffix, cells); \1178}1179 1180/**1181 * struct supplier_bindings - Property parsing functions for suppliers1182 *1183 * @parse_prop: function name1184 *	parse_prop() finds the node corresponding to a supplier phandle1185 *  parse_prop.np: Pointer to device node holding supplier phandle property1186 *  parse_prop.prop_name: Name of property holding a phandle value1187 *  parse_prop.index: For properties holding a list of phandles, this is the1188 *		      index into the list1189 * @get_con_dev: If the consumer node containing the property is never converted1190 *		 to a struct device, implement this ops so fw_devlink can use it1191 *		 to find the true consumer.1192 * @optional: Describes whether a supplier is mandatory or not1193 * @fwlink_flags: Optional fwnode link flags to use when creating a fwnode link1194 *		  for this property.1195 *1196 * Returns:1197 * parse_prop() return values are1198 * - phandle node pointer with refcount incremented. Caller must of_node_put()1199 *   on it when done.1200 * - NULL if no phandle found at index1201 */1202struct supplier_bindings {1203	struct device_node *(*parse_prop)(struct device_node *np,1204					  const char *prop_name, int index);1205	struct device_node *(*get_con_dev)(struct device_node *np);1206	bool optional;1207	u8 fwlink_flags;1208};1209 1210DEFINE_SIMPLE_PROP(clocks, "clocks", "#clock-cells")1211DEFINE_SIMPLE_PROP(interconnects, "interconnects", "#interconnect-cells")1212DEFINE_SIMPLE_PROP(iommus, "iommus", "#iommu-cells")1213DEFINE_SIMPLE_PROP(mboxes, "mboxes", "#mbox-cells")1214DEFINE_SIMPLE_PROP(io_channels, "io-channels", "#io-channel-cells")1215DEFINE_SIMPLE_PROP(io_backends, "io-backends", "#io-backend-cells")1216DEFINE_SIMPLE_PROP(interrupt_parent, "interrupt-parent", NULL)1217DEFINE_SIMPLE_PROP(dmas, "dmas", "#dma-cells")1218DEFINE_SIMPLE_PROP(power_domains, "power-domains", "#power-domain-cells")1219DEFINE_SIMPLE_PROP(hwlocks, "hwlocks", "#hwlock-cells")1220DEFINE_SIMPLE_PROP(extcon, "extcon", NULL)1221DEFINE_SIMPLE_PROP(nvmem_cells, "nvmem-cells", "#nvmem-cell-cells")1222DEFINE_SIMPLE_PROP(phys, "phys", "#phy-cells")1223DEFINE_SIMPLE_PROP(wakeup_parent, "wakeup-parent", NULL)1224DEFINE_SIMPLE_PROP(pinctrl0, "pinctrl-0", NULL)1225DEFINE_SIMPLE_PROP(pinctrl1, "pinctrl-1", NULL)1226DEFINE_SIMPLE_PROP(pinctrl2, "pinctrl-2", NULL)1227DEFINE_SIMPLE_PROP(pinctrl3, "pinctrl-3", NULL)1228DEFINE_SIMPLE_PROP(pinctrl4, "pinctrl-4", NULL)1229DEFINE_SIMPLE_PROP(pinctrl5, "pinctrl-5", NULL)1230DEFINE_SIMPLE_PROP(pinctrl6, "pinctrl-6", NULL)1231DEFINE_SIMPLE_PROP(pinctrl7, "pinctrl-7", NULL)1232DEFINE_SIMPLE_PROP(pinctrl8, "pinctrl-8", NULL)1233DEFINE_SIMPLE_PROP(pwms, "pwms", "#pwm-cells")1234DEFINE_SIMPLE_PROP(resets, "resets", "#reset-cells")1235DEFINE_SIMPLE_PROP(leds, "leds", NULL)1236DEFINE_SIMPLE_PROP(backlight, "backlight", NULL)1237DEFINE_SIMPLE_PROP(panel, "panel", NULL)1238DEFINE_SIMPLE_PROP(msi_parent, "msi-parent", "#msi-cells")1239DEFINE_SIMPLE_PROP(post_init_providers, "post-init-providers", NULL)1240DEFINE_SIMPLE_PROP(access_controllers, "access-controllers", "#access-controller-cells")1241DEFINE_SIMPLE_PROP(pses, "pses", "#pse-cells")1242DEFINE_SIMPLE_PROP(power_supplies, "power-supplies", NULL)1243DEFINE_SUFFIX_PROP(regulators, "-supply", NULL)1244DEFINE_SUFFIX_PROP(gpio, "-gpio", "#gpio-cells")1245 1246static struct device_node *parse_gpios(struct device_node *np,1247				       const char *prop_name, int index)1248{1249	if (!strcmp_suffix(prop_name, ",nr-gpios"))1250		return NULL;1251 1252	return parse_suffix_prop_cells(np, prop_name, index, "-gpios",1253				       "#gpio-cells");1254}1255 1256static struct device_node *parse_iommu_maps(struct device_node *np,1257					    const char *prop_name, int index)1258{1259	if (strcmp(prop_name, "iommu-map"))1260		return NULL;1261 1262	return of_parse_phandle(np, prop_name, (index * 4) + 1);1263}1264 1265static struct device_node *parse_gpio_compat(struct device_node *np,1266					     const char *prop_name, int index)1267{1268	struct of_phandle_args sup_args;1269 1270	if (strcmp(prop_name, "gpio") && strcmp(prop_name, "gpios"))1271		return NULL;1272 1273	/*1274	 * Ignore node with gpio-hog property since its gpios are all provided1275	 * by its parent.1276	 */1277	if (of_property_read_bool(np, "gpio-hog"))1278		return NULL;1279 1280	if (of_parse_phandle_with_args(np, prop_name, "#gpio-cells", index,1281				       &sup_args))1282		return NULL;1283 1284	return sup_args.np;1285}1286 1287static struct device_node *parse_interrupts(struct device_node *np,1288					    const char *prop_name, int index)1289{1290	struct of_phandle_args sup_args;1291 1292	if (!IS_ENABLED(CONFIG_OF_IRQ) || IS_ENABLED(CONFIG_PPC))1293		return NULL;1294 1295	if (strcmp(prop_name, "interrupts") &&1296	    strcmp(prop_name, "interrupts-extended"))1297		return NULL;1298 1299	return of_irq_parse_one(np, index, &sup_args) ? NULL : sup_args.np;1300}1301 1302static struct device_node *parse_interrupt_map(struct device_node *np,1303					       const char *prop_name, int index)1304{1305	const __be32 *imap, *imap_end;1306	struct of_phandle_args sup_args;1307	u32 addrcells, intcells;1308	int imaplen;1309 1310	if (!IS_ENABLED(CONFIG_OF_IRQ))1311		return NULL;1312 1313	if (strcmp(prop_name, "interrupt-map"))1314		return NULL;1315 1316	if (of_property_read_u32(np, "#interrupt-cells", &intcells))1317		return NULL;1318	addrcells = of_bus_n_addr_cells(np);1319 1320	imap = of_get_property(np, "interrupt-map", &imaplen);1321	imaplen /= sizeof(*imap);1322	if (!imap)1323		return NULL;1324 1325	imap_end = imap + imaplen;1326 1327	for (int i = 0; imap + addrcells + intcells + 1 < imap_end; i++) {1328		imap += addrcells + intcells;1329 1330		imap = of_irq_parse_imap_parent(imap, imap_end - imap, &sup_args);1331		if (!imap)1332			return NULL;1333 1334		if (i == index)1335			return sup_args.np;1336 1337		of_node_put(sup_args.np);1338	}1339 1340	return NULL;1341}1342 1343static struct device_node *parse_remote_endpoint(struct device_node *np,1344						 const char *prop_name,1345						 int index)1346{1347	/* Return NULL for index > 0 to signify end of remote-endpoints. */1348	if (index > 0 || strcmp(prop_name, "remote-endpoint"))1349		return NULL;1350 1351	return of_graph_get_remote_port_parent(np);1352}1353 1354static const struct supplier_bindings of_supplier_bindings[] = {1355	{ .parse_prop = parse_clocks, },1356	{ .parse_prop = parse_interconnects, },1357	{ .parse_prop = parse_iommus, .optional = true, },1358	{ .parse_prop = parse_iommu_maps, .optional = true, },1359	{ .parse_prop = parse_mboxes, },1360	{ .parse_prop = parse_io_channels, },1361	{ .parse_prop = parse_io_backends, },1362	{ .parse_prop = parse_interrupt_parent, },1363	{ .parse_prop = parse_dmas, .optional = true, },1364	{ .parse_prop = parse_power_domains, },1365	{ .parse_prop = parse_hwlocks, },1366	{ .parse_prop = parse_extcon, },1367	{ .parse_prop = parse_nvmem_cells, },1368	{ .parse_prop = parse_phys, },1369	{ .parse_prop = parse_wakeup_parent, },1370	{ .parse_prop = parse_pinctrl0, },1371	{ .parse_prop = parse_pinctrl1, },1372	{ .parse_prop = parse_pinctrl2, },1373	{ .parse_prop = parse_pinctrl3, },1374	{ .parse_prop = parse_pinctrl4, },1375	{ .parse_prop = parse_pinctrl5, },1376	{ .parse_prop = parse_pinctrl6, },1377	{ .parse_prop = parse_pinctrl7, },1378	{ .parse_prop = parse_pinctrl8, },1379	{1380		.parse_prop = parse_remote_endpoint,1381		.get_con_dev = of_graph_get_port_parent,1382	},1383	{ .parse_prop = parse_pwms, },1384	{ .parse_prop = parse_resets, },1385	{ .parse_prop = parse_leds, },1386	{ .parse_prop = parse_backlight, },1387	{ .parse_prop = parse_panel, },1388	{ .parse_prop = parse_msi_parent, },1389	{ .parse_prop = parse_pses, },1390	{ .parse_prop = parse_power_supplies, },1391	{ .parse_prop = parse_gpio_compat, },1392	{ .parse_prop = parse_interrupts, },1393	{ .parse_prop = parse_interrupt_map, },1394	{ .parse_prop = parse_access_controllers, },1395	{ .parse_prop = parse_regulators, },1396	{ .parse_prop = parse_gpio, },1397	{ .parse_prop = parse_gpios, },1398	{1399		.parse_prop = parse_post_init_providers,1400		.fwlink_flags = FWLINK_FLAG_IGNORE,1401	},1402	{}1403};1404 1405/**1406 * of_link_property - Create device links to suppliers listed in a property1407 * @con_np: The consumer device tree node which contains the property1408 * @prop_name: Name of property to be parsed1409 *1410 * This function checks if the property @prop_name that is present in the1411 * @con_np device tree node is one of the known common device tree bindings1412 * that list phandles to suppliers. If @prop_name isn't one, this function1413 * doesn't do anything.1414 *1415 * If @prop_name is one, this function attempts to create fwnode links from the1416 * consumer device tree node @con_np to all the suppliers device tree nodes1417 * listed in @prop_name.1418 *1419 * Any failed attempt to create a fwnode link will NOT result in an immediate1420 * return.  of_link_property() must create links to all the available supplier1421 * device tree nodes even when attempts to create a link to one or more1422 * suppliers fail.1423 */1424static int of_link_property(struct device_node *con_np, const char *prop_name)1425{1426	struct device_node *phandle;1427	const struct supplier_bindings *s = of_supplier_bindings;1428	unsigned int i = 0;1429	bool matched = false;1430 1431	/* Do not stop at first failed link, link all available suppliers. */1432	while (!matched && s->parse_prop) {1433		if (s->optional && !fw_devlink_is_strict()) {1434			s++;1435			continue;1436		}1437 1438		while ((phandle = s->parse_prop(con_np, prop_name, i))) {1439			struct device_node *con_dev_np __free(device_node) =1440				s->get_con_dev ? s->get_con_dev(con_np) : of_node_get(con_np);1441 1442			matched = true;1443			i++;1444			of_link_to_phandle(con_dev_np, phandle, s->fwlink_flags);1445			of_node_put(phandle);1446		}1447		s++;1448	}1449	return 0;1450}1451 1452static void __iomem *of_fwnode_iomap(struct fwnode_handle *fwnode, int index)1453{1454#ifdef CONFIG_OF_ADDRESS1455	return of_iomap(to_of_node(fwnode), index);1456#else1457	return NULL;1458#endif1459}1460 1461static int of_fwnode_irq_get(const struct fwnode_handle *fwnode,1462			     unsigned int index)1463{1464	return of_irq_get(to_of_node(fwnode), index);1465}1466 1467static int of_fwnode_add_links(struct fwnode_handle *fwnode)1468{1469	struct property *p;1470	struct device_node *con_np = to_of_node(fwnode);1471 1472	if (IS_ENABLED(CONFIG_X86))1473		return 0;1474 1475	if (!con_np)1476		return -EINVAL;1477 1478	for_each_property_of_node(con_np, p)1479		of_link_property(con_np, p->name);1480 1481	return 0;1482}1483 1484const struct fwnode_operations of_fwnode_ops = {1485	.get = of_fwnode_get,1486	.put = of_fwnode_put,1487	.device_is_available = of_fwnode_device_is_available,1488	.device_get_match_data = of_fwnode_device_get_match_data,1489	.device_dma_supported = of_fwnode_device_dma_supported,1490	.device_get_dma_attr = of_fwnode_device_get_dma_attr,1491	.property_present = of_fwnode_property_present,1492	.property_read_int_array = of_fwnode_property_read_int_array,1493	.property_read_string_array = of_fwnode_property_read_string_array,1494	.get_name = of_fwnode_get_name,1495	.get_name_prefix = of_fwnode_get_name_prefix,1496	.get_parent = of_fwnode_get_parent,1497	.get_next_child_node = of_fwnode_get_next_child_node,1498	.get_named_child_node = of_fwnode_get_named_child_node,1499	.get_reference_args = of_fwnode_get_reference_args,1500	.graph_get_next_endpoint = of_fwnode_graph_get_next_endpoint,1501	.graph_get_remote_endpoint = of_fwnode_graph_get_remote_endpoint,1502	.graph_get_port_parent = of_fwnode_graph_get_port_parent,1503	.graph_parse_endpoint = of_fwnode_graph_parse_endpoint,1504	.iomap = of_fwnode_iomap,1505	.irq_get = of_fwnode_irq_get,1506	.add_links = of_fwnode_add_links,1507};1508EXPORT_SYMBOL_GPL(of_fwnode_ops);1509