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