1218792Snp// SPDX-License-Identifier: GPL-2.0+ 2218792Snp/* 3218792Snp * drivers/of/property.c - Procedures for accessing and interpreting 4218792Snp * Devicetree properties and graphs. 5218792Snp * 6218792Snp * Initially created by copying procedures from drivers/of/base.c. This 7218792Snp * file contains the OF property as well as the OF graph interface 8218792Snp * functions. 9218792Snp * 10218792Snp * Paul Mackerras August 1996. 11218792Snp * Copyright (C) 1996-2005 Paul Mackerras. 12218792Snp * 13218792Snp * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. 14218792Snp * {engebret|bergner}@us.ibm.com 15218792Snp * 16218792Snp * Adapted for sparc and sparc64 by David S. Miller davem@davemloft.net 17218792Snp * 18218792Snp * Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell and 19218792Snp * Grant Likely. 20218792Snp */ 21218792Snp 22218792Snp#define pr_fmt(fmt) "OF: " fmt 23218792Snp 24218792Snp#include <linux/of.h> 25218792Snp#include <linux/of_address.h> 26218792Snp#include <linux/of_device.h> 27218792Snp#include <linux/of_graph.h> 28218792Snp#include <linux/of_irq.h> 29218792Snp#include <linux/string.h> 30218792Snp#include <linux/moduleparam.h> 31218792Snp 32218792Snp#include "of_private.h" 33218792Snp 34218792Snp/** 35218792Snp * of_graph_is_present() - check graph's presence 36218792Snp * @node: pointer to device_node containing graph port 37218792Snp * 38218792Snp * Return: True if @node has a port or ports (with a port) sub-node, 39219286Snp * false otherwise. 40219286Snp */ 41219286Snpbool of_graph_is_present(const struct device_node *node) 42218792Snp{ 43218792Snp struct device_node *ports, *port; 44218792Snp 45218792Snp ports = of_get_child_by_name(node, "ports"); 46218792Snp if (ports) 47219436Snp node = ports; 48218792Snp 49218792Snp port = of_get_child_by_name(node, "port"); 50218792Snp of_node_put(ports); 51218792Snp of_node_put(port); 52218792Snp 53218792Snp return !!port; 54218792Snp} 55218792SnpEXPORT_SYMBOL(of_graph_is_present); 56218792Snp 57218792Snp/** 58218792Snp * of_property_count_elems_of_size - Count the number of elements in a property 59218792Snp * 60218792Snp * @np: device node from which the property value is to be read. 61218792Snp * @propname: name of the property to be searched. 62218792Snp * @elem_size: size of the individual element 63218792Snp * 64218792Snp * Search for a property in a device node and count the number of elements of 65218792Snp * size elem_size in it. 66218792Snp * 67218792Snp * Return: The number of elements on sucess, -EINVAL if the property does not 68218792Snp * exist or its length does not match a multiple of elem_size and -ENODATA if 69218792Snp * the property does not have a value. 70218792Snp */ 71218792Snpint of_property_count_elems_of_size(const struct device_node *np, 72218792Snp const char *propname, int elem_size) 73218792Snp{ 74218792Snp struct property *prop = of_find_property(np, propname, NULL); 75218792Snp 76218792Snp if (!prop) 77218792Snp return -EINVAL; 78218792Snp if (!prop->value) 79218792Snp return -ENODATA; 80218792Snp 81218792Snp if (prop->length % elem_size != 0) { 82218792Snp pr_err("size of %s in node %pOF is not a multiple of %d\n", 83218792Snp propname, np, elem_size); 84218792Snp return -EINVAL; 85218792Snp } 86218792Snp 87218792Snp return prop->length / elem_size; 88218792Snp} 89218792SnpEXPORT_SYMBOL_GPL(of_property_count_elems_of_size); 90218792Snp 91218792Snp/** 92218792Snp * of_find_property_value_of_size 93218792Snp * 94218792Snp * @np: device node from which the property value is to be read. 95218792Snp * @propname: name of the property to be searched. 96218792Snp * @min: minimum allowed length of property value 97218792Snp * @max: maximum allowed length of property value (0 means unlimited) 98218792Snp * @len: if !=NULL, actual length is written to here 99218792Snp * 100218792Snp * Search for a property in a device node and valid the requested size. 101218792Snp * 102218792Snp * Return: The property value on success, -EINVAL if the property does not 103218792Snp * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the 104218792Snp * property data is too small or too large. 105218792Snp * 106218792Snp */ 107218792Snpstatic void *of_find_property_value_of_size(const struct device_node *np, 108218792Snp const char *propname, u32 min, u32 max, size_t *len) 109218792Snp{ 110218792Snp struct property *prop = of_find_property(np, propname, NULL); 111218792Snp 112218792Snp if (!prop) 113218792Snp return ERR_PTR(-EINVAL); 114218792Snp if (!prop->value) 115218792Snp return ERR_PTR(-ENODATA); 116218792Snp if (prop->length < min) 117218792Snp return ERR_PTR(-EOVERFLOW); 118218792Snp if (max && prop->length > max) 119218792Snp return ERR_PTR(-EOVERFLOW); 120218792Snp 121218792Snp if (len) 122218792Snp *len = prop->length; 123218792Snp 124218792Snp return prop->value; 125218792Snp} 126218792Snp 127218792Snp/** 128218792Snp * of_property_read_u32_index - Find and read a u32 from a multi-value property. 129218792Snp * 130218792Snp * @np: device node from which the property value is to be read. 131218792Snp * @propname: name of the property to be searched. 132218792Snp * @index: index of the u32 in the list of values 133218792Snp * @out_value: pointer to return value, modified only if no error. 134218792Snp * 135218792Snp * Search for a property in a device node and read nth 32-bit value from 136218792Snp * it. 137218792Snp * 138218792Snp * Return: 0 on success, -EINVAL if the property does not exist, 139218792Snp * -ENODATA if property does not have a value, and -EOVERFLOW if the 140218792Snp * property data isn't large enough. 141218792Snp * 142218792Snp * The out_value is modified only if a valid u32 value can be decoded. 143218792Snp */ 144218792Snpint of_property_read_u32_index(const struct device_node *np, 145218792Snp const char *propname, 146218792Snp u32 index, u32 *out_value) 147218792Snp{ 148218792Snp const u32 *val = of_find_property_value_of_size(np, propname, 149218792Snp ((index + 1) * sizeof(*out_value)), 150218792Snp 0, 151218792Snp NULL); 152218792Snp 153218792Snp if (IS_ERR(val)) 154218792Snp return PTR_ERR(val); 155218792Snp 156218792Snp *out_value = be32_to_cpup(((__be32 *)val) + index); 157218792Snp return 0; 158218792Snp} 159218792SnpEXPORT_SYMBOL_GPL(of_property_read_u32_index); 160218792Snp 161218792Snp/** 162218792Snp * of_property_read_u64_index - Find and read a u64 from a multi-value property. 163218792Snp * 164218792Snp * @np: device node from which the property value is to be read. 165218792Snp * @propname: name of the property to be searched. 166218792Snp * @index: index of the u64 in the list of values 167218792Snp * @out_value: pointer to return value, modified only if no error. 168218792Snp * 169218792Snp * Search for a property in a device node and read nth 64-bit value from 170218792Snp * it. 171218792Snp * 172218792Snp * Return: 0 on success, -EINVAL if the property does not exist, 173218792Snp * -ENODATA if property does not have a value, and -EOVERFLOW if the 174218792Snp * property data isn't large enough. 175218792Snp * 176218792Snp * The out_value is modified only if a valid u64 value can be decoded. 177218792Snp */ 178218792Snpint of_property_read_u64_index(const struct device_node *np, 179218792Snp const char *propname, 180218792Snp u32 index, u64 *out_value) 181218792Snp{ 182218792Snp const u64 *val = of_find_property_value_of_size(np, propname, 183218792Snp ((index + 1) * sizeof(*out_value)), 184218792Snp 0, NULL); 185218792Snp 186218792Snp if (IS_ERR(val)) 187218792Snp return PTR_ERR(val); 188218792Snp 189218792Snp *out_value = be64_to_cpup(((__be64 *)val) + index); 190218792Snp return 0; 191218792Snp} 192218792SnpEXPORT_SYMBOL_GPL(of_property_read_u64_index); 193218792Snp 194218792Snp/** 195218792Snp * of_property_read_variable_u8_array - Find and read an array of u8 from a 196218792Snp * property, with bounds on the minimum and maximum array size. 197218792Snp * 198218792Snp * @np: device node from which the property value is to be read. 199218792Snp * @propname: name of the property to be searched. 200218792Snp * @out_values: pointer to found values. 201218792Snp * @sz_min: minimum number of array elements to read 202218792Snp * @sz_max: maximum number of array elements to read, if zero there is no 203218792Snp * upper limit on the number of elements in the dts entry but only 204218792Snp * sz_min will be read. 205218792Snp * 206218792Snp * Search for a property in a device node and read 8-bit value(s) from 207218792Snp * it. 208219944Snp * 209218792Snp * dts entry of array should be like: 210218792Snp * ``property = /bits/ 8 <0x50 0x60 0x70>;`` 211218792Snp * 212218792Snp * Return: The number of elements read on success, -EINVAL if the property 213218792Snp * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW 214218792Snp * if the property data is smaller than sz_min or longer than sz_max. 215218792Snp * 216218792Snp * The out_values is modified only if a valid u8 value can be decoded. 217218792Snp */ 218218792Snpint of_property_read_variable_u8_array(const struct device_node *np, 219218792Snp const char *propname, u8 *out_values, 220218792Snp size_t sz_min, size_t sz_max) 221218792Snp{ 222219944Snp size_t sz, count; 223218792Snp const u8 *val = of_find_property_value_of_size(np, propname, 224218792Snp (sz_min * sizeof(*out_values)), 225218792Snp (sz_max * sizeof(*out_values)), 226218792Snp &sz); 227218792Snp 228218792Snp if (IS_ERR(val)) 229218792Snp return PTR_ERR(val); 230218792Snp 231218792Snp if (!sz_max) 232218792Snp sz = sz_min; 233218792Snp else 234218792Snp sz /= sizeof(*out_values); 235218792Snp 236218792Snp count = sz; 237218792Snp while (count--) 238218792Snp *out_values++ = *val++; 239218792Snp 240218792Snp return sz; 241218792Snp} 242218792SnpEXPORT_SYMBOL_GPL(of_property_read_variable_u8_array); 243218792Snp 244218792Snp/** 245218792Snp * of_property_read_variable_u16_array - Find and read an array of u16 from a 246218792Snp * property, with bounds on the minimum and maximum array size. 247218792Snp * 248218792Snp * @np: device node from which the property value is to be read. 249218792Snp * @propname: name of the property to be searched. 250218792Snp * @out_values: pointer to found values. 251218792Snp * @sz_min: minimum number of array elements to read 252218792Snp * @sz_max: maximum number of array elements to read, if zero there is no 253218792Snp * upper limit on the number of elements in the dts entry but only 254218792Snp * sz_min will be read. 255218792Snp * 256218792Snp * Search for a property in a device node and read 16-bit value(s) from 257218792Snp * it. 258218792Snp * 259218792Snp * dts entry of array should be like: 260218792Snp * ``property = /bits/ 16 <0x5000 0x6000 0x7000>;`` 261218792Snp * 262218792Snp * Return: The number of elements read on success, -EINVAL if the property 263218792Snp * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW 264218792Snp * if the property data is smaller than sz_min or longer than sz_max. 265218792Snp * 266218792Snp * The out_values is modified only if a valid u16 value can be decoded. 267218792Snp */ 268218792Snpint of_property_read_variable_u16_array(const struct device_node *np, 269218792Snp const char *propname, u16 *out_values, 270218792Snp size_t sz_min, size_t sz_max) 271218792Snp{ 272218792Snp size_t sz, count; 273218792Snp const __be16 *val = of_find_property_value_of_size(np, propname, 274218792Snp (sz_min * sizeof(*out_values)), 275218792Snp (sz_max * sizeof(*out_values)), 276219436Snp &sz); 277218792Snp 278218792Snp if (IS_ERR(val)) 279218792Snp return PTR_ERR(val); 280218792Snp 281218792Snp if (!sz_max) 282219286Snp sz = sz_min; 283219392Snp else 284218792Snp sz /= sizeof(*out_values); 285218792Snp 286218792Snp count = sz; 287218792Snp while (count--) 288218792Snp *out_values++ = be16_to_cpup(val++); 289218792Snp 290218792Snp return sz; 291218792Snp} 292218792SnpEXPORT_SYMBOL_GPL(of_property_read_variable_u16_array); 293218792Snp 294218792Snp/** 295218792Snp * of_property_read_variable_u32_array - Find and read an array of 32 bit 296218792Snp * integers from a property, with bounds on the minimum and maximum array size. 297218792Snp * 298218792Snp * @np: device node from which the property value is to be read. 299218792Snp * @propname: name of the property to be searched. 300218792Snp * @out_values: pointer to return found values. 301218792Snp * @sz_min: minimum number of array elements to read 302218792Snp * @sz_max: maximum number of array elements to read, if zero there is no 303218792Snp * upper limit on the number of elements in the dts entry but only 304218792Snp * sz_min will be read. 305218792Snp * 306218792Snp * Search for a property in a device node and read 32-bit value(s) from 307218792Snp * it. 308218792Snp * 309218792Snp * Return: The number of elements read on success, -EINVAL if the property 310218792Snp * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW 311218792Snp * if the property data is smaller than sz_min or longer than sz_max. 312218792Snp * 313218792Snp * The out_values is modified only if a valid u32 value can be decoded. 314218792Snp */ 315218792Snpint of_property_read_variable_u32_array(const struct device_node *np, 316218792Snp const char *propname, u32 *out_values, 317218792Snp size_t sz_min, size_t sz_max) 318218792Snp{ 319218792Snp size_t sz, count; 320218792Snp const __be32 *val = of_find_property_value_of_size(np, propname, 321218792Snp (sz_min * sizeof(*out_values)), 322218792Snp (sz_max * sizeof(*out_values)), 323218792Snp &sz); 324218792Snp 325218792Snp if (IS_ERR(val)) 326218792Snp return PTR_ERR(val); 327218792Snp 328218792Snp if (!sz_max) 329218792Snp sz = sz_min; 330218792Snp else 331218792Snp sz /= sizeof(*out_values); 332218792Snp 333218792Snp count = sz; 334218792Snp while (count--) 335218792Snp *out_values++ = be32_to_cpup(val++); 336218792Snp 337218792Snp return sz; 338218792Snp} 339218792SnpEXPORT_SYMBOL_GPL(of_property_read_variable_u32_array); 340218792Snp 341218792Snp/** 342218792Snp * of_property_read_u64 - Find and read a 64 bit integer from a property 343218792Snp * @np: device node from which the property value is to be read. 344218792Snp * @propname: name of the property to be searched. 345218792Snp * @out_value: pointer to return value, modified only if return value is 0. 346218792Snp * 347218792Snp * Search for a property in a device node and read a 64-bit value from 348218792Snp * it. 349218792Snp * 350218792Snp * Return: 0 on success, -EINVAL if the property does not exist, 351218792Snp * -ENODATA if property does not have a value, and -EOVERFLOW if the 352218792Snp * property data isn't large enough. 353218792Snp * 354218792Snp * The out_value is modified only if a valid u64 value can be decoded. 355218792Snp */ 356218792Snpint of_property_read_u64(const struct device_node *np, const char *propname, 357218792Snp u64 *out_value) 358218792Snp{ 359218792Snp const __be32 *val = of_find_property_value_of_size(np, propname, 360218792Snp sizeof(*out_value), 361218792Snp 0, 362218792Snp NULL); 363218792Snp 364218792Snp if (IS_ERR(val)) 365218792Snp return PTR_ERR(val); 366218792Snp 367218792Snp *out_value = of_read_number(val, 2); 368218792Snp return 0; 369218792Snp} 370218792SnpEXPORT_SYMBOL_GPL(of_property_read_u64); 371218792Snp 372218792Snp/** 373218792Snp * of_property_read_variable_u64_array - Find and read an array of 64 bit 374218792Snp * integers from a property, with bounds on the minimum and maximum array size. 375218792Snp * 376218792Snp * @np: device node from which the property value is to be read. 377218792Snp * @propname: name of the property to be searched. 378218792Snp * @out_values: pointer to found values. 379218792Snp * @sz_min: minimum number of array elements to read 380218792Snp * @sz_max: maximum number of array elements to read, if zero there is no 381218792Snp * upper limit on the number of elements in the dts entry but only 382218792Snp * sz_min will be read. 383218792Snp * 384218792Snp * Search for a property in a device node and read 64-bit value(s) from 385218792Snp * it. 386218792Snp * 387218792Snp * Return: The number of elements read on success, -EINVAL if the property 388218792Snp * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW 389218792Snp * if the property data is smaller than sz_min or longer than sz_max. 390218792Snp * 391218792Snp * The out_values is modified only if a valid u64 value can be decoded. 392218792Snp */ 393218792Snpint of_property_read_variable_u64_array(const struct device_node *np, 394218792Snp const char *propname, u64 *out_values, 395218792Snp size_t sz_min, size_t sz_max) 396218792Snp{ 397218792Snp size_t sz, count; 398218792Snp const __be32 *val = of_find_property_value_of_size(np, propname, 399218792Snp (sz_min * sizeof(*out_values)), 400218792Snp (sz_max * sizeof(*out_values)), 401218792Snp &sz); 402218792Snp 403218792Snp if (IS_ERR(val)) 404218792Snp return PTR_ERR(val); 405218792Snp 406218792Snp if (!sz_max) 407218792Snp sz = sz_min; 408218792Snp else 409218792Snp sz /= sizeof(*out_values); 410218792Snp 411218792Snp count = sz; 412218792Snp while (count--) { 413218792Snp *out_values++ = of_read_number(val, 2); 414218792Snp val += 2; 415218792Snp } 416218792Snp 417218792Snp return sz; 418218792Snp} 419218792SnpEXPORT_SYMBOL_GPL(of_property_read_variable_u64_array); 420218792Snp 421218792Snp/** 422218792Snp * of_property_read_string - Find and read a string from a property 423218792Snp * @np: device node from which the property value is to be read. 424218792Snp * @propname: name of the property to be searched. 425218792Snp * @out_string: pointer to null terminated return string, modified only if 426218792Snp * return value is 0. 427218792Snp * 428218792Snp * Search for a property in a device tree node and retrieve a null 429218792Snp * terminated string value (pointer to data, not a copy). 430218792Snp * 431218792Snp * Return: 0 on success, -EINVAL if the property does not exist, -ENODATA if 432218792Snp * property does not have a value, and -EILSEQ if the string is not 433218792Snp * null-terminated within the length of the property data. 434218792Snp * 435218792Snp * Note that the empty string "" has length of 1, thus -ENODATA cannot 436218792Snp * be interpreted as an empty string. 437218792Snp * 438218792Snp * The out_string pointer is modified only if a valid string can be decoded. 439218792Snp */ 440218792Snpint of_property_read_string(const struct device_node *np, const char *propname, 441218792Snp const char **out_string) 442218792Snp{ 443218792Snp const struct property *prop = of_find_property(np, propname, NULL); 444218792Snp 445218792Snp if (!prop) 446218792Snp return -EINVAL; 447218792Snp if (!prop->length) 448218792Snp return -ENODATA; 449218792Snp if (strnlen(prop->value, prop->length) >= prop->length) 450218792Snp return -EILSEQ; 451218792Snp *out_string = prop->value; 452218792Snp return 0; 453218792Snp} 454218792SnpEXPORT_SYMBOL_GPL(of_property_read_string); 455218792Snp 456218792Snp/** 457218792Snp * of_property_match_string() - Find string in a list and return index 458218792Snp * @np: pointer to node containing string list property 459218792Snp * @propname: string list property name 460218792Snp * @string: pointer to string to search for in string list 461218792Snp * 462218792Snp * This function searches a string list property and returns the index 463218792Snp * of a specific string value. 464218792Snp */ 465218792Snpint of_property_match_string(const struct device_node *np, const char *propname, 466218792Snp const char *string) 467218792Snp{ 468218792Snp const struct property *prop = of_find_property(np, propname, NULL); 469218792Snp size_t l; 470218792Snp int i; 471218792Snp const char *p, *end; 472218792Snp 473218792Snp if (!prop) 474218792Snp return -EINVAL; 475218792Snp if (!prop->value) 476218792Snp return -ENODATA; 477218792Snp 478218792Snp p = prop->value; 479218792Snp end = p + prop->length; 480218792Snp 481218792Snp for (i = 0; p < end; i++, p += l) { 482218792Snp l = strnlen(p, end - p) + 1; 483218792Snp if (p + l > end) 484218792Snp return -EILSEQ; 485218792Snp pr_debug("comparing %s with %s\n", string, p); 486218792Snp if (strcmp(string, p) == 0) 487218792Snp return i; /* Found it; return index */ 488218792Snp } 489218792Snp return -ENODATA; 490218792Snp} 491218792SnpEXPORT_SYMBOL_GPL(of_property_match_string); 492218792Snp 493218792Snp/** 494218792Snp * of_property_read_string_helper() - Utility helper for parsing string properties 495218792Snp * @np: device node from which the property value is to be read. 496218792Snp * @propname: name of the property to be searched. 497218792Snp * @out_strs: output array of string pointers. 498218792Snp * @sz: number of array elements to read. 499218792Snp * @skip: Number of strings to skip over at beginning of list. 500218792Snp * 501218792Snp * Don't call this function directly. It is a utility helper for the 502218792Snp * of_property_read_string*() family of functions. 503218792Snp */ 504218792Snpint of_property_read_string_helper(const struct device_node *np, 505218792Snp const char *propname, const char **out_strs, 506218792Snp size_t sz, int skip) 507218792Snp{ 508218792Snp const struct property *prop = of_find_property(np, propname, NULL); 509218792Snp int l = 0, i = 0; 510218792Snp const char *p, *end; 511218792Snp 512218792Snp if (!prop) 513218792Snp return -EINVAL; 514218792Snp if (!prop->value) 515218792Snp return -ENODATA; 516218792Snp p = prop->value; 517218792Snp end = p + prop->length; 518218792Snp 519218792Snp for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) { 520218792Snp l = strnlen(p, end - p) + 1; 521218792Snp if (p + l > end) 522218792Snp return -EILSEQ; 523218792Snp if (out_strs && i >= skip) 524218792Snp *out_strs++ = p; 525218792Snp } 526218792Snp i -= skip; 527218792Snp return i <= 0 ? -ENODATA : i; 528218792Snp} 529218792SnpEXPORT_SYMBOL_GPL(of_property_read_string_helper); 530218792Snp 531218792Snpconst __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur, 532218792Snp u32 *pu) 533218792Snp{ 534218792Snp const void *curv = cur; 535218792Snp 536218792Snp if (!prop) 537218792Snp return NULL; 538218792Snp 539218792Snp if (!cur) { 540218792Snp curv = prop->value; 541218792Snp goto out_val; 542218792Snp } 543218792Snp 544218792Snp curv += sizeof(*cur); 545218792Snp if (curv >= prop->value + prop->length) 546220873Snp return NULL; 547220873Snp 548218792Snpout_val: 549218792Snp *pu = be32_to_cpup(curv); 550218792Snp return curv; 551218792Snp} 552218792SnpEXPORT_SYMBOL_GPL(of_prop_next_u32); 553218792Snp 554218792Snpconst char *of_prop_next_string(struct property *prop, const char *cur) 555220873Snp{ 556220873Snp const void *curv = cur; 557218792Snp 558218792Snp if (!prop) 559218792Snp return NULL; 560218792Snp 561218792Snp if (!cur) 562218792Snp return prop->value; 563218792Snp 564218792Snp curv += strlen(cur) + 1; 565218792Snp if (curv >= prop->value + prop->length) 566218792Snp return NULL; 567218792Snp 568218792Snp return curv; 569218792Snp} 570218792SnpEXPORT_SYMBOL_GPL(of_prop_next_string); 571218792Snp 572218792Snp/** 573218792Snp * of_graph_parse_endpoint() - parse common endpoint node properties 574218792Snp * @node: pointer to endpoint device_node 575218792Snp * @endpoint: pointer to the OF endpoint data structure 576218792Snp * 577218792Snp * The caller should hold a reference to @node. 578218792Snp */ 579218792Snpint of_graph_parse_endpoint(const struct device_node *node, 580218792Snp struct of_endpoint *endpoint) 581218792Snp{ 582218792Snp struct device_node *port_node = of_get_parent(node); 583218792Snp 584218792Snp WARN_ONCE(!port_node, "%s(): endpoint %pOF has no parent node\n", 585218792Snp __func__, node); 586218792Snp 587218792Snp memset(endpoint, 0, sizeof(*endpoint)); 588218792Snp 589218792Snp endpoint->local_node = node; 590218792Snp /* 591218792Snp * It doesn't matter whether the two calls below succeed. 592218792Snp * If they don't then the default value 0 is used. 593218792Snp */ 594218792Snp of_property_read_u32(port_node, "reg", &endpoint->port); 595218792Snp of_property_read_u32(node, "reg", &endpoint->id); 596218792Snp 597218792Snp of_node_put(port_node); 598218792Snp 599218792Snp return 0; 600218792Snp} 601218792SnpEXPORT_SYMBOL(of_graph_parse_endpoint); 602218792Snp 603218792Snp/** 604218792Snp * of_graph_get_port_by_id() - get the port matching a given id 605218792Snp * @parent: pointer to the parent device node 606218792Snp * @id: id of the port 607218792Snp * 608218792Snp * Return: A 'port' node pointer with refcount incremented. The caller 609218792Snp * has to use of_node_put() on it when done. 610218792Snp */ 611218792Snpstruct device_node *of_graph_get_port_by_id(struct device_node *parent, u32 id) 612218792Snp{ 613218792Snp struct device_node *node, *port; 614218792Snp 615218792Snp node = of_get_child_by_name(parent, "ports"); 616218792Snp if (node) 617218792Snp parent = node; 618218792Snp 619218792Snp for_each_child_of_node(parent, port) { 620218792Snp u32 port_id = 0; 621218792Snp 622218792Snp if (!of_node_name_eq(port, "port")) 623218792Snp continue; 624218792Snp of_property_read_u32(port, "reg", &port_id); 625218792Snp if (id == port_id) 626218792Snp break; 627218792Snp } 628218792Snp 629218792Snp of_node_put(node); 630218792Snp 631218792Snp return port; 632218792Snp} 633218792SnpEXPORT_SYMBOL(of_graph_get_port_by_id); 634218792Snp 635218792Snp/** 636218792Snp * of_graph_get_next_endpoint() - get next endpoint node 637218792Snp * @parent: pointer to the parent device node 638218792Snp * @prev: previous endpoint node, or NULL to get first 639218792Snp * 640218792Snp * Return: An 'endpoint' node pointer with refcount incremented. Refcount 641218792Snp * of the passed @prev node is decremented. 642218792Snp */ 643218792Snpstruct device_node *of_graph_get_next_endpoint(const struct device_node *parent, 644218792Snp struct device_node *prev) 645219944Snp{ 646218792Snp struct device_node *endpoint; 647218792Snp struct device_node *port; 648218792Snp 649218792Snp if (!parent) 650218792Snp return NULL; 651218792Snp 652218792Snp /* 653218792Snp * Start by locating the port node. If no previous endpoint is specified 654218792Snp * search for the first port node, otherwise get the previous endpoint 655218792Snp * parent port node. 656218792Snp */ 657218792Snp if (!prev) { 658218792Snp struct device_node *node; 659220873Snp 660218792Snp node = of_get_child_by_name(parent, "ports"); 661218792Snp if (node) 662218792Snp parent = node; 663218792Snp 664218792Snp port = of_get_child_by_name(parent, "port"); 665218792Snp of_node_put(node); 666218792Snp 667218792Snp if (!port) { 668218792Snp pr_debug("graph: no port node found in %pOF\n", parent); 669218792Snp return NULL; 670218792Snp } 671218792Snp } else { 672218792Snp port = of_get_parent(prev); 673218792Snp if (WARN_ONCE(!port, "%s(): endpoint %pOF has no parent node\n", 674218792Snp __func__, prev)) 675218792Snp return NULL; 676218792Snp } 677218792Snp 678218792Snp while (1) { 679218792Snp /* 680218792Snp * Now that we have a port node, get the next endpoint by 681218792Snp * getting the next child. If the previous endpoint is NULL this 682218792Snp * will return the first child. 683218792Snp */ 684218792Snp endpoint = of_get_next_child(port, prev); 685218792Snp if (endpoint) { 686218792Snp of_node_put(port); 687218792Snp return endpoint; 688218792Snp } 689218792Snp 690218792Snp /* No more endpoints under this port, try the next one. */ 691218792Snp prev = NULL; 692218792Snp 693218792Snp do { 694218792Snp port = of_get_next_child(parent, port); 695218792Snp if (!port) 696218792Snp return NULL; 697218792Snp } while (!of_node_name_eq(port, "port")); 698218792Snp } 699218792Snp} 700218792SnpEXPORT_SYMBOL(of_graph_get_next_endpoint); 701218792Snp 702218792Snp/** 703218792Snp * of_graph_get_endpoint_by_regs() - get endpoint node of specific identifiers 704218792Snp * @parent: pointer to the parent device node 705219286Snp * @port_reg: identifier (value of reg property) of the parent port node 706219286Snp * @reg: identifier (value of reg property) of the endpoint node 707219286Snp * 708219286Snp * Return: An 'endpoint' node pointer which is identified by reg and at the same 709219286Snp * is the child of a port node identified by port_reg. reg and port_reg are 710219286Snp * ignored when they are -1. Use of_node_put() on the pointer when done. 711219286Snp */ 712219286Snpstruct device_node *of_graph_get_endpoint_by_regs( 713219286Snp const struct device_node *parent, int port_reg, int reg) 714218792Snp{ 715218792Snp struct of_endpoint endpoint; 716218792Snp struct device_node *node = NULL; 717218792Snp 718218792Snp for_each_endpoint_of_node(parent, node) { 719218792Snp of_graph_parse_endpoint(node, &endpoint); 720218792Snp if (((port_reg == -1) || (endpoint.port == port_reg)) && 721218792Snp ((reg == -1) || (endpoint.id == reg))) 722218792Snp return node; 723218792Snp } 724218792Snp 725218792Snp return NULL; 726218792Snp} 727218792SnpEXPORT_SYMBOL(of_graph_get_endpoint_by_regs); 728218792Snp 729218792Snp/** 730218792Snp * of_graph_get_remote_endpoint() - get remote endpoint node 731218792Snp * @node: pointer to a local endpoint device_node 732218792Snp * 733218792Snp * Return: Remote endpoint node associated with remote endpoint node linked 734218792Snp * to @node. Use of_node_put() on it when done. 735218792Snp */ 736218792Snpstruct device_node *of_graph_get_remote_endpoint(const struct device_node *node) 737218792Snp{ 738218792Snp /* Get remote endpoint node. */ 739218792Snp return of_parse_phandle(node, "remote-endpoint", 0); 740218792Snp} 741218792SnpEXPORT_SYMBOL(of_graph_get_remote_endpoint); 742218792Snp 743218792Snp/** 744218792Snp * of_graph_get_port_parent() - get port's parent node 745218792Snp * @node: pointer to a local endpoint device_node 746218792Snp * 747218792Snp * Return: device node associated with endpoint node linked 748218792Snp * to @node. Use of_node_put() on it when done. 749218792Snp */ 750218792Snpstruct device_node *of_graph_get_port_parent(struct device_node *node) 751218792Snp{ 752218792Snp unsigned int depth; 753218792Snp 754218792Snp if (!node) 755218792Snp return NULL; 756218792Snp 757218792Snp /* 758218792Snp * Preserve usecount for passed in node as of_get_next_parent() 759218792Snp * will do of_node_put() on it. 760218792Snp */ 761218792Snp of_node_get(node); 762218792Snp 763218792Snp /* Walk 3 levels up only if there is 'ports' node. */ 764218792Snp for (depth = 3; depth && node; depth--) { 765218792Snp node = of_get_next_parent(node); 766218792Snp if (depth == 2 && !of_node_name_eq(node, "ports") && 767218792Snp !of_node_name_eq(node, "in-ports") && 768219286Snp !of_node_name_eq(node, "out-ports")) 769219286Snp break; 770218792Snp } 771218792Snp return node; 772218792Snp} 773218792SnpEXPORT_SYMBOL(of_graph_get_port_parent); 774218792Snp 775218792Snp/** 776218792Snp * of_graph_get_remote_port_parent() - get remote port's parent node 777218792Snp * @node: pointer to a local endpoint device_node 778218792Snp * 779218792Snp * Return: Remote device node associated with remote endpoint node linked 780218792Snp * to @node. Use of_node_put() on it when done. 781218792Snp */ 782218792Snpstruct device_node *of_graph_get_remote_port_parent( 783218792Snp const struct device_node *node) 784218792Snp{ 785218792Snp struct device_node *np, *pp; 786218792Snp 787218792Snp /* Get remote endpoint node. */ 788218792Snp np = of_graph_get_remote_endpoint(node); 789218792Snp 790218792Snp pp = of_graph_get_port_parent(np); 791218792Snp 792218792Snp of_node_put(np); 793218792Snp 794218792Snp return pp; 795218792Snp} 796218792SnpEXPORT_SYMBOL(of_graph_get_remote_port_parent); 797218792Snp 798218792Snp/** 799218792Snp * of_graph_get_remote_port() - get remote port node 800218792Snp * @node: pointer to a local endpoint device_node 801218792Snp * 802218792Snp * Return: Remote port node associated with remote endpoint node linked 803218792Snp * to @node. Use of_node_put() on it when done. 804218792Snp */ 805218792Snpstruct device_node *of_graph_get_remote_port(const struct device_node *node) 806218792Snp{ 807218792Snp struct device_node *np; 808218792Snp 809218792Snp /* Get remote endpoint node. */ 810218792Snp np = of_graph_get_remote_endpoint(node); 811218792Snp if (!np) 812218792Snp return NULL; 813218792Snp return of_get_next_parent(np); 814218792Snp} 815218792SnpEXPORT_SYMBOL(of_graph_get_remote_port); 816218792Snp 817218792Snp/** 818218792Snp * of_graph_get_endpoint_count() - get the number of endpoints in a device node 819218792Snp * @np: parent device node containing ports and endpoints 820218792Snp * 821218792Snp * Return: count of endpoint of this device node 822218792Snp */ 823218792Snpunsigned int of_graph_get_endpoint_count(const struct device_node *np) 824218792Snp{ 825218792Snp struct device_node *endpoint; 826218792Snp unsigned int num = 0; 827218792Snp 828218792Snp for_each_endpoint_of_node(np, endpoint) 829218792Snp num++; 830218792Snp 831218792Snp return num; 832218792Snp} 833218792SnpEXPORT_SYMBOL(of_graph_get_endpoint_count); 834218792Snp 835218792Snp/** 836218792Snp * of_graph_get_remote_node() - get remote parent device_node for given port/endpoint 837218792Snp * @node: pointer to parent device_node containing graph port/endpoint 838218792Snp * @port: identifier (value of reg property) of the parent port node 839218792Snp * @endpoint: identifier (value of reg property) of the endpoint node 840218792Snp * 841218792Snp * Return: Remote device node associated with remote endpoint node linked 842218792Snp * to @node. Use of_node_put() on it when done. 843218792Snp */ 844218792Snpstruct device_node *of_graph_get_remote_node(const struct device_node *node, 845218792Snp u32 port, u32 endpoint) 846218792Snp{ 847218792Snp struct device_node *endpoint_node, *remote; 848218792Snp 849218792Snp endpoint_node = of_graph_get_endpoint_by_regs(node, port, endpoint); 850218792Snp if (!endpoint_node) { 851218792Snp pr_debug("no valid endpoint (%d, %d) for node %pOF\n", 852218792Snp port, endpoint, node); 853218792Snp return NULL; 854218792Snp } 855218792Snp 856218792Snp remote = of_graph_get_remote_port_parent(endpoint_node); 857218792Snp of_node_put(endpoint_node); 858218792Snp if (!remote) { 859218792Snp pr_debug("no valid remote node\n"); 860218792Snp return NULL; 861218792Snp } 862218792Snp 863218792Snp if (!of_device_is_available(remote)) { 864218792Snp pr_debug("not available for remote node\n"); 865218792Snp of_node_put(remote); 866218792Snp return NULL; 867218792Snp } 868218792Snp 869218792Snp return remote; 870218792Snp} 871218792SnpEXPORT_SYMBOL(of_graph_get_remote_node); 872218792Snp 873218792Snpstatic struct fwnode_handle *of_fwnode_get(struct fwnode_handle *fwnode) 874218792Snp{ 875218792Snp return of_fwnode_handle(of_node_get(to_of_node(fwnode))); 876218792Snp} 877218792Snp 878218792Snpstatic void of_fwnode_put(struct fwnode_handle *fwnode) 879218792Snp{ 880218792Snp of_node_put(to_of_node(fwnode)); 881218792Snp} 882218792Snp 883218792Snpstatic bool of_fwnode_device_is_available(const struct fwnode_handle *fwnode) 884218792Snp{ 885218792Snp return of_device_is_available(to_of_node(fwnode)); 886218792Snp} 887218792Snp 888218792Snpstatic bool of_fwnode_device_dma_supported(const struct fwnode_handle *fwnode) 889218792Snp{ 890218792Snp return true; 891218792Snp} 892218792Snp 893218792Snpstatic enum dev_dma_attr 894218792Snpof_fwnode_device_get_dma_attr(const struct fwnode_handle *fwnode) 895218792Snp{ 896218792Snp if (of_dma_is_coherent(to_of_node(fwnode))) 897218792Snp return DEV_DMA_COHERENT; 898218792Snp else 899218792Snp return DEV_DMA_NON_COHERENT; 900218792Snp} 901218792Snp 902218792Snpstatic bool of_fwnode_property_present(const struct fwnode_handle *fwnode, 903218792Snp const char *propname) 904218792Snp{ 905218792Snp return of_property_read_bool(to_of_node(fwnode), propname); 906218792Snp} 907218792Snp 908218792Snpstatic int of_fwnode_property_read_int_array(const struct fwnode_handle *fwnode, 909218792Snp const char *propname, 910218792Snp unsigned int elem_size, void *val, 911218792Snp size_t nval) 912218792Snp{ 913218792Snp const struct device_node *node = to_of_node(fwnode); 914218792Snp 915218792Snp if (!val) 916218792Snp return of_property_count_elems_of_size(node, propname, 917218792Snp elem_size); 918218792Snp 919218792Snp switch (elem_size) { 920218792Snp case sizeof(u8): 921218792Snp return of_property_read_u8_array(node, propname, val, nval); 922218792Snp case sizeof(u16): 923218792Snp return of_property_read_u16_array(node, propname, val, nval); 924218792Snp case sizeof(u32): 925218792Snp return of_property_read_u32_array(node, propname, val, nval); 926218792Snp case sizeof(u64): 927218792Snp return of_property_read_u64_array(node, propname, val, nval); 928218792Snp } 929218792Snp 930218792Snp return -ENXIO; 931218792Snp} 932218792Snp 933218792Snpstatic int 934218792Snpof_fwnode_property_read_string_array(const struct fwnode_handle *fwnode, 935218792Snp const char *propname, const char **val, 936218792Snp size_t nval) 937218792Snp{ 938218792Snp const struct device_node *node = to_of_node(fwnode); 939218792Snp 940218792Snp return val ? 941218792Snp of_property_read_string_array(node, propname, val, nval) : 942218792Snp of_property_count_strings(node, propname); 943218792Snp} 944218792Snp 945218792Snpstatic const char *of_fwnode_get_name(const struct fwnode_handle *fwnode) 946218792Snp{ 947218792Snp return kbasename(to_of_node(fwnode)->full_name); 948218792Snp} 949218792Snp 950218792Snpstatic const char *of_fwnode_get_name_prefix(const struct fwnode_handle *fwnode) 951218792Snp{ 952218792Snp /* Root needs no prefix here (its name is "/"). */ 953218792Snp if (!to_of_node(fwnode)->parent) 954218792Snp return ""; 955218792Snp 956218792Snp return "/"; 957218792Snp} 958218792Snp 959218792Snpstatic struct fwnode_handle * 960218792Snpof_fwnode_get_parent(const struct fwnode_handle *fwnode) 961218792Snp{ 962218792Snp return of_fwnode_handle(of_get_parent(to_of_node(fwnode))); 963218792Snp} 964218792Snp 965218792Snpstatic struct fwnode_handle * 966218792Snpof_fwnode_get_next_child_node(const struct fwnode_handle *fwnode, 967218792Snp struct fwnode_handle *child) 968218792Snp{ 969218792Snp return of_fwnode_handle(of_get_next_available_child(to_of_node(fwnode), 970218792Snp to_of_node(child))); 971218792Snp} 972218792Snp 973218792Snpstatic struct fwnode_handle * 974218792Snpof_fwnode_get_named_child_node(const struct fwnode_handle *fwnode, 975219286Snp const char *childname) 976218792Snp{ 977218792Snp const struct device_node *node = to_of_node(fwnode); 978218792Snp struct device_node *child; 979218792Snp 980218792Snp for_each_available_child_of_node(node, child) 981218792Snp if (of_node_name_eq(child, childname)) 982218792Snp return of_fwnode_handle(child); 983218792Snp 984218792Snp return NULL; 985218792Snp} 986218792Snp 987218792Snpstatic int 988218792Snpof_fwnode_get_reference_args(const struct fwnode_handle *fwnode, 989218792Snp const char *prop, const char *nargs_prop, 990218792Snp unsigned int nargs, unsigned int index, 991218792Snp struct fwnode_reference_args *args) 992218792Snp{ 993218792Snp struct of_phandle_args of_args; 994218792Snp unsigned int i; 995218792Snp int ret; 996218792Snp 997218792Snp if (nargs_prop) 998218792Snp ret = of_parse_phandle_with_args(to_of_node(fwnode), prop, 999220873Snp nargs_prop, index, &of_args); 1000218792Snp else 1001218792Snp ret = of_parse_phandle_with_fixed_args(to_of_node(fwnode), prop, 1002218792Snp nargs, index, &of_args); 1003218792Snp if (ret < 0) 1004218792Snp return ret; 1005218792Snp if (!args) { 1006218792Snp of_node_put(of_args.np); 1007218792Snp return 0; 1008218792Snp } 1009218792Snp 1010218792Snp args->nargs = of_args.args_count; 1011218792Snp args->fwnode = of_fwnode_handle(of_args.np); 1012218792Snp 1013218792Snp for (i = 0; i < NR_FWNODE_REFERENCE_ARGS; i++) 1014218792Snp args->args[i] = i < of_args.args_count ? of_args.args[i] : 0; 1015218792Snp 1016218792Snp return 0; 1017218792Snp} 1018218792Snp 1019218792Snpstatic struct fwnode_handle * 1020218792Snpof_fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode, 1021218792Snp struct fwnode_handle *prev) 1022218792Snp{ 1023218792Snp return of_fwnode_handle(of_graph_get_next_endpoint(to_of_node(fwnode), 1024218792Snp to_of_node(prev))); 1025218792Snp} 1026218792Snp 1027218792Snpstatic struct fwnode_handle * 1028218792Snpof_fwnode_graph_get_remote_endpoint(const struct fwnode_handle *fwnode) 1029218792Snp{ 1030218792Snp return of_fwnode_handle( 1031218792Snp of_graph_get_remote_endpoint(to_of_node(fwnode))); 1032218792Snp} 1033218792Snp 1034218792Snpstatic struct fwnode_handle * 1035218792Snpof_fwnode_graph_get_port_parent(struct fwnode_handle *fwnode) 1036218792Snp{ 1037218792Snp struct device_node *np; 1038218792Snp 1039218792Snp /* Get the parent of the port */ 1040218792Snp np = of_get_parent(to_of_node(fwnode)); 1041218792Snp if (!np) 1042218792Snp return NULL; 1043218792Snp 1044218792Snp /* Is this the "ports" node? If not, it's the port parent. */ 1045220649Snp if (!of_node_name_eq(np, "ports")) 1046220649Snp return of_fwnode_handle(np); 1047220649Snp 1048218792Snp return of_fwnode_handle(of_get_next_parent(np)); 1049220649Snp} 1050220649Snp 1051220649Snpstatic int of_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, 1052220649Snp struct fwnode_endpoint *endpoint) 1053220649Snp{ 1054220873Snp const struct device_node *node = to_of_node(fwnode); 1055220649Snp struct device_node *port_node = of_get_parent(node); 1056220649Snp 1057220649Snp endpoint->local_fwnode = fwnode; 1058220649Snp 1059220649Snp of_property_read_u32(port_node, "reg", &endpoint->port); 1060218792Snp of_property_read_u32(node, "reg", &endpoint->id); 1061218792Snp 1062218792Snp of_node_put(port_node); 1063218792Snp 1064218792Snp return 0; 1065218792Snp} 1066218792Snp 1067218792Snpstatic const void * 1068218792Snpof_fwnode_device_get_match_data(const struct fwnode_handle *fwnode, 1069218792Snp const struct device *dev) 1070218792Snp{ 1071218792Snp return of_device_get_match_data(dev); 1072218792Snp} 1073218792Snp 1074218792Snpstatic void of_link_to_phandle(struct device_node *con_np, 1075218792Snp struct device_node *sup_np, 1076218792Snp u8 flags) 1077218792Snp{ 1078218792Snp struct device_node *tmp_np = of_node_get(sup_np); 1079218792Snp 1080218792Snp /* Check that sup_np and its ancestors are available. */ 1081218792Snp while (tmp_np) { 1082218792Snp if (of_fwnode_handle(tmp_np)->dev) { 1083218792Snp of_node_put(tmp_np); 1084218792Snp break; 1085218792Snp } 1086218792Snp 1087218792Snp if (!of_device_is_available(tmp_np)) { 1088218792Snp of_node_put(tmp_np); 1089218792Snp return; 1090218792Snp } 1091218792Snp 1092218792Snp tmp_np = of_get_next_parent(tmp_np); 1093218792Snp } 1094218792Snp 1095218792Snp fwnode_link_add(of_fwnode_handle(con_np), of_fwnode_handle(sup_np), flags); 1096218792Snp} 1097218792Snp 1098218792Snp/** 1099218792Snp * parse_prop_cells - Property parsing function for suppliers 1100218792Snp * 1101218792Snp * @np: Pointer to device tree node containing a list 1102218792Snp * @prop_name: Name of property to be parsed. Expected to hold phandle values 1103218792Snp * @index: For properties holding a list of phandles, this is the index 1104218792Snp * into the list. 1105218792Snp * @list_name: Property name that is known to contain list of phandle(s) to 1106218792Snp * supplier(s) 1107218792Snp * @cells_name: property name that specifies phandles' arguments count 1108218792Snp * 1109218792Snp * This is a helper function to parse properties that have a known fixed name 1110218792Snp * and are a list of phandles and phandle arguments. 1111218792Snp * 1112218792Snp * Returns: 1113218792Snp * - phandle node pointer with refcount incremented. Caller must of_node_put() 1114218792Snp * on it when done. 1115218792Snp * - NULL if no phandle found at index 1116218792Snp */ 1117218792Snpstatic struct device_node *parse_prop_cells(struct device_node *np, 1118218792Snp const char *prop_name, int index, 1119218792Snp const char *list_name, 1120218792Snp const char *cells_name) 1121218792Snp{ 1122218792Snp struct of_phandle_args sup_args; 1123218792Snp 1124218792Snp if (strcmp(prop_name, list_name)) 1125218792Snp return NULL; 1126218792Snp 1127218792Snp if (__of_parse_phandle_with_args(np, list_name, cells_name, 0, index, 1128218792Snp &sup_args)) 1129218792Snp return NULL; 1130218792Snp 1131218792Snp return sup_args.np; 1132218792Snp} 1133218792Snp 1134218792Snp#define DEFINE_SIMPLE_PROP(fname, name, cells) \ 1135218792Snpstatic struct device_node *parse_##fname(struct device_node *np, \ 1136218792Snp const char *prop_name, int index) \ 1137218792Snp{ \ 1138218792Snp return parse_prop_cells(np, prop_name, index, name, cells); \ 1139218792Snp} 1140218792Snp 1141218792Snpstatic int strcmp_suffix(const char *str, const char *suffix) 1142218792Snp{ 1143218792Snp unsigned int len, suffix_len; 1144218792Snp 1145218792Snp len = strlen(str); 1146218792Snp suffix_len = strlen(suffix); 1147218792Snp if (len <= suffix_len) 1148218792Snp return -1; 1149218792Snp return strcmp(str + len - suffix_len, suffix); 1150218792Snp} 1151218792Snp 1152218792Snp/** 1153218792Snp * parse_suffix_prop_cells - Suffix property parsing function for suppliers 1154218792Snp * 1155218792Snp * @np: Pointer to device tree node containing a list 1156218792Snp * @prop_name: Name of property to be parsed. Expected to hold phandle values 1157218792Snp * @index: For properties holding a list of phandles, this is the index 1158218792Snp * into the list. 1159218792Snp * @suffix: Property suffix that is known to contain list of phandle(s) to 1160218792Snp * supplier(s) 1161218792Snp * @cells_name: property name that specifies phandles' arguments count 1162218792Snp * 1163218792Snp * This is a helper function to parse properties that have a known fixed suffix 1164218792Snp * and are a list of phandles and phandle arguments. 1165218792Snp * 1166218792Snp * Returns: 1167218792Snp * - phandle node pointer with refcount incremented. Caller must of_node_put() 1168218792Snp * on it when done. 1169218792Snp * - NULL if no phandle found at index 1170218792Snp */ 1171218792Snpstatic struct device_node *parse_suffix_prop_cells(struct device_node *np, 1172219944Snp const char *prop_name, int index, 1173218792Snp const char *suffix, 1174218792Snp const char *cells_name) 1175218792Snp{ 1176218792Snp struct of_phandle_args sup_args; 1177219944Snp 1178218792Snp if (strcmp_suffix(prop_name, suffix)) 1179219944Snp return NULL; 1180218792Snp 1181218792Snp if (of_parse_phandle_with_args(np, prop_name, cells_name, index, 1182218792Snp &sup_args)) 1183218792Snp return NULL; 1184218792Snp 1185218792Snp return sup_args.np; 1186218792Snp} 1187218792Snp 1188218792Snp#define DEFINE_SUFFIX_PROP(fname, suffix, cells) \ 1189218792Snpstatic struct device_node *parse_##fname(struct device_node *np, \ 1190218792Snp const char *prop_name, int index) \ 1191218792Snp{ \ 1192218792Snp return parse_suffix_prop_cells(np, prop_name, index, suffix, cells); \ 1193218792Snp} 1194218792Snp 1195218792Snp/** 1196218792Snp * struct supplier_bindings - Property parsing functions for suppliers 1197218792Snp * 1198218792Snp * @parse_prop: function name 1199219944Snp * parse_prop() finds the node corresponding to a supplier phandle 1200219944Snp * parse_prop.np: Pointer to device node holding supplier phandle property 1201219944Snp * parse_prop.prop_name: Name of property holding a phandle value 1202218792Snp * parse_prop.index: For properties holding a list of phandles, this is the 1203218792Snp * index into the list 1204218792Snp * @get_con_dev: If the consumer node containing the property is never converted 1205218792Snp * to a struct device, implement this ops so fw_devlink can use it 1206218792Snp * to find the true consumer. 1207219944Snp * @optional: Describes whether a supplier is mandatory or not 1208218792Snp * @fwlink_flags: Optional fwnode link flags to use when creating a fwnode link 1209218792Snp * for this property. 1210218792Snp * 1211218792Snp * Returns: 1212219944Snp * parse_prop() return values are 1213219944Snp * - phandle node pointer with refcount incremented. Caller must of_node_put() 1214219944Snp * on it when done. 1215219944Snp * - NULL if no phandle found at index 1216219944Snp */ 1217219944Snpstruct supplier_bindings { 1218219944Snp struct device_node *(*parse_prop)(struct device_node *np, 1219219944Snp const char *prop_name, int index); 1220219944Snp struct device_node *(*get_con_dev)(struct device_node *np); 1221219944Snp bool optional; 1222219944Snp u8 fwlink_flags; 1223219944Snp}; 1224219944Snp 1225219944SnpDEFINE_SIMPLE_PROP(clocks, "clocks", "#clock-cells") 1226219944SnpDEFINE_SIMPLE_PROP(interconnects, "interconnects", "#interconnect-cells") 1227218792SnpDEFINE_SIMPLE_PROP(iommus, "iommus", "#iommu-cells") 1228218792SnpDEFINE_SIMPLE_PROP(mboxes, "mboxes", "#mbox-cells") 1229218792SnpDEFINE_SIMPLE_PROP(io_channels, "io-channels", "#io-channel-cells") 1230218792SnpDEFINE_SIMPLE_PROP(io_backends, "io-backends", "#io-backend-cells") 1231218792SnpDEFINE_SIMPLE_PROP(interrupt_parent, "interrupt-parent", NULL) 1232219944SnpDEFINE_SIMPLE_PROP(dmas, "dmas", "#dma-cells") 1233218792SnpDEFINE_SIMPLE_PROP(power_domains, "power-domains", "#power-domain-cells") 1234218792SnpDEFINE_SIMPLE_PROP(hwlocks, "hwlocks", "#hwlock-cells") 1235218792SnpDEFINE_SIMPLE_PROP(extcon, "extcon", NULL) 1236218792SnpDEFINE_SIMPLE_PROP(nvmem_cells, "nvmem-cells", "#nvmem-cell-cells") 1237218792SnpDEFINE_SIMPLE_PROP(phys, "phys", "#phy-cells") 1238218792SnpDEFINE_SIMPLE_PROP(wakeup_parent, "wakeup-parent", NULL) 1239218792SnpDEFINE_SIMPLE_PROP(pinctrl0, "pinctrl-0", NULL) 1240219944SnpDEFINE_SIMPLE_PROP(pinctrl1, "pinctrl-1", NULL) 1241218792SnpDEFINE_SIMPLE_PROP(pinctrl2, "pinctrl-2", NULL) 1242219944SnpDEFINE_SIMPLE_PROP(pinctrl3, "pinctrl-3", NULL) 1243218792SnpDEFINE_SIMPLE_PROP(pinctrl4, "pinctrl-4", NULL) 1244218792SnpDEFINE_SIMPLE_PROP(pinctrl5, "pinctrl-5", NULL) 1245218792SnpDEFINE_SIMPLE_PROP(pinctrl6, "pinctrl-6", NULL) 1246218792SnpDEFINE_SIMPLE_PROP(pinctrl7, "pinctrl-7", NULL) 1247218792SnpDEFINE_SIMPLE_PROP(pinctrl8, "pinctrl-8", NULL) 1248218792SnpDEFINE_SIMPLE_PROP(pwms, "pwms", "#pwm-cells") 1249218792SnpDEFINE_SIMPLE_PROP(resets, "resets", "#reset-cells") 1250218792SnpDEFINE_SIMPLE_PROP(leds, "leds", NULL) 1251218792SnpDEFINE_SIMPLE_PROP(backlight, "backlight", NULL) 1252218792SnpDEFINE_SIMPLE_PROP(panel, "panel", NULL) 1253218792SnpDEFINE_SIMPLE_PROP(msi_parent, "msi-parent", "#msi-cells") 1254218792SnpDEFINE_SIMPLE_PROP(post_init_providers, "post-init-providers", NULL) 1255218792SnpDEFINE_SUFFIX_PROP(regulators, "-supply", NULL) 1256218792SnpDEFINE_SUFFIX_PROP(gpio, "-gpio", "#gpio-cells") 1257218792Snp 1258218792Snpstatic struct device_node *parse_gpios(struct device_node *np, 1259218792Snp const char *prop_name, int index) 1260218792Snp{ 1261218792Snp if (!strcmp_suffix(prop_name, ",nr-gpios")) 1262218792Snp return NULL; 1263218792Snp 1264218792Snp return parse_suffix_prop_cells(np, prop_name, index, "-gpios", 1265218792Snp "#gpio-cells"); 1266218792Snp} 1267218792Snp 1268218792Snpstatic struct device_node *parse_iommu_maps(struct device_node *np, 1269218792Snp const char *prop_name, int index) 1270218792Snp{ 1271218792Snp if (strcmp(prop_name, "iommu-map")) 1272218792Snp return NULL; 1273218792Snp 1274218792Snp return of_parse_phandle(np, prop_name, (index * 4) + 1); 1275218792Snp} 1276218792Snp 1277218792Snpstatic struct device_node *parse_gpio_compat(struct device_node *np, 1278218792Snp const char *prop_name, int index) 1279218792Snp{ 1280218792Snp struct of_phandle_args sup_args; 1281218792Snp 1282218792Snp if (strcmp(prop_name, "gpio") && strcmp(prop_name, "gpios")) 1283218792Snp return NULL; 1284219287Snp 1285218792Snp /* 1286218792Snp * Ignore node with gpio-hog property since its gpios are all provided 1287219287Snp * by its parent. 1288219287Snp */ 1289219287Snp if (of_property_read_bool(np, "gpio-hog")) 1290219287Snp return NULL; 1291219287Snp 1292219287Snp if (of_parse_phandle_with_args(np, prop_name, "#gpio-cells", index, 1293219287Snp &sup_args)) 1294219287Snp return NULL; 1295219287Snp 1296219287Snp return sup_args.np; 1297219287Snp} 1298219287Snp 1299219287Snpstatic struct device_node *parse_interrupts(struct device_node *np, 1300219287Snp const char *prop_name, int index) 1301219287Snp{ 1302219287Snp struct of_phandle_args sup_args; 1303219287Snp 1304219287Snp if (!IS_ENABLED(CONFIG_OF_IRQ) || IS_ENABLED(CONFIG_PPC)) 1305219287Snp return NULL; 1306218792Snp 1307218792Snp if (strcmp(prop_name, "interrupts") && 1308219287Snp strcmp(prop_name, "interrupts-extended")) 1309219287Snp return NULL; 1310219287Snp 1311219287Snp return of_irq_parse_one(np, index, &sup_args) ? NULL : sup_args.np; 1312219287Snp} 1313219287Snp 1314219287Snpstatic struct device_node *parse_remote_endpoint(struct device_node *np, 1315219287Snp const char *prop_name, 1316219287Snp int index) 1317219287Snp{ 1318219287Snp /* Return NULL for index > 0 to signify end of remote-endpoints. */ 1319219287Snp if (index > 0 || strcmp(prop_name, "remote-endpoint")) 1320219287Snp return NULL; 1321219287Snp 1322219287Snp return of_graph_get_remote_port_parent(np); 1323219287Snp} 1324219287Snp 1325219287Snpstatic const struct supplier_bindings of_supplier_bindings[] = { 1326219287Snp { .parse_prop = parse_clocks, }, 1327219287Snp { .parse_prop = parse_interconnects, }, 1328218792Snp { .parse_prop = parse_iommus, .optional = true, }, 1329219287Snp { .parse_prop = parse_iommu_maps, .optional = true, }, 1330219287Snp { .parse_prop = parse_mboxes, }, 1331219287Snp { .parse_prop = parse_io_channels, }, 1332219287Snp { .parse_prop = parse_io_backends, }, 1333219287Snp { .parse_prop = parse_interrupt_parent, }, 1334219287Snp { .parse_prop = parse_dmas, .optional = true, }, 1335219287Snp { .parse_prop = parse_power_domains, }, 1336219287Snp { .parse_prop = parse_hwlocks, }, 1337219287Snp { .parse_prop = parse_extcon, }, 1338219287Snp { .parse_prop = parse_nvmem_cells, }, 1339219287Snp { .parse_prop = parse_phys, }, 1340219287Snp { .parse_prop = parse_wakeup_parent, }, 1341219287Snp { .parse_prop = parse_pinctrl0, }, 1342219287Snp { .parse_prop = parse_pinctrl1, }, 1343218792Snp { .parse_prop = parse_pinctrl2, }, 1344218792Snp { .parse_prop = parse_pinctrl3, }, 1345219287Snp { .parse_prop = parse_pinctrl4, }, 1346219287Snp { .parse_prop = parse_pinctrl5, }, 1347218792Snp { .parse_prop = parse_pinctrl6, }, 1348218792Snp { .parse_prop = parse_pinctrl7, }, 1349218792Snp { .parse_prop = parse_pinctrl8, }, 1350218792Snp { 1351218792Snp .parse_prop = parse_remote_endpoint, 1352218792Snp .get_con_dev = of_graph_get_port_parent, 1353218792Snp }, 1354218792Snp { .parse_prop = parse_pwms, }, 1355218792Snp { .parse_prop = parse_resets, }, 1356218792Snp { .parse_prop = parse_leds, }, 1357218792Snp { .parse_prop = parse_backlight, }, 1358218792Snp { .parse_prop = parse_panel, }, 1359218792Snp { .parse_prop = parse_msi_parent, }, 1360218792Snp { .parse_prop = parse_gpio_compat, }, 1361218792Snp { .parse_prop = parse_interrupts, }, 1362218792Snp { .parse_prop = parse_regulators, }, 1363218792Snp { .parse_prop = parse_gpio, }, 1364218792Snp { .parse_prop = parse_gpios, }, 1365218792Snp { 1366218792Snp .parse_prop = parse_post_init_providers, 1367218792Snp .fwlink_flags = FWLINK_FLAG_IGNORE, 1368218792Snp }, 1369218792Snp {} 1370218792Snp}; 1371218792Snp 1372218792Snp/** 1373218792Snp * of_link_property - Create device links to suppliers listed in a property 1374218792Snp * @con_np: The consumer device tree node which contains the property 1375218792Snp * @prop_name: Name of property to be parsed 1376218792Snp * 1377218792Snp * This function checks if the property @prop_name that is present in the 1378218792Snp * @con_np device tree node is one of the known common device tree bindings 1379218792Snp * that list phandles to suppliers. If @prop_name isn't one, this function 1380218792Snp * doesn't do anything. 1381218792Snp * 1382218792Snp * If @prop_name is one, this function attempts to create fwnode links from the 1383218792Snp * consumer device tree node @con_np to all the suppliers device tree nodes 1384218792Snp * listed in @prop_name. 1385218792Snp * 1386218792Snp * Any failed attempt to create a fwnode link will NOT result in an immediate 1387218792Snp * return. of_link_property() must create links to all the available supplier 1388218792Snp * device tree nodes even when attempts to create a link to one or more 1389218792Snp * suppliers fail. 1390218792Snp */ 1391218792Snpstatic int of_link_property(struct device_node *con_np, const char *prop_name) 1392218792Snp{ 1393218792Snp struct device_node *phandle; 1394218792Snp const struct supplier_bindings *s = of_supplier_bindings; 1395218792Snp unsigned int i = 0; 1396218792Snp bool matched = false; 1397218792Snp 1398218792Snp /* Do not stop at first failed link, link all available suppliers. */ 1399218792Snp while (!matched && s->parse_prop) { 1400218792Snp if (s->optional && !fw_devlink_is_strict()) { 1401218792Snp s++; 1402218792Snp continue; 1403218792Snp } 1404218792Snp 1405218792Snp while ((phandle = s->parse_prop(con_np, prop_name, i))) { 1406218792Snp struct device_node *con_dev_np; 1407218792Snp 1408218792Snp con_dev_np = s->get_con_dev 1409218792Snp ? s->get_con_dev(con_np) 1410218792Snp : of_node_get(con_np); 1411218792Snp matched = true; 1412218792Snp i++; 1413218792Snp of_link_to_phandle(con_dev_np, phandle, s->fwlink_flags); 1414218792Snp of_node_put(phandle); 1415218792Snp of_node_put(con_dev_np); 1416218792Snp } 1417218792Snp s++; 1418218792Snp } 1419218792Snp return 0; 1420218792Snp} 1421218792Snp 1422218792Snpstatic void __iomem *of_fwnode_iomap(struct fwnode_handle *fwnode, int index) 1423218792Snp{ 1424218792Snp#ifdef CONFIG_OF_ADDRESS 1425218792Snp return of_iomap(to_of_node(fwnode), index); 1426218792Snp#else 1427218792Snp return NULL; 1428218792Snp#endif 1429218792Snp} 1430218792Snp 1431218792Snpstatic int of_fwnode_irq_get(const struct fwnode_handle *fwnode, 1432218792Snp unsigned int index) 1433218792Snp{ 1434218792Snp return of_irq_get(to_of_node(fwnode), index); 1435218792Snp} 1436218792Snp 1437218792Snpstatic int of_fwnode_add_links(struct fwnode_handle *fwnode) 1438218792Snp{ 1439218792Snp struct property *p; 1440218792Snp struct device_node *con_np = to_of_node(fwnode); 1441218792Snp 1442218792Snp if (IS_ENABLED(CONFIG_X86)) 1443218792Snp return 0; 1444218792Snp 1445218792Snp if (!con_np) 1446218792Snp return -EINVAL; 1447218792Snp 1448218792Snp for_each_property_of_node(con_np, p) 1449218792Snp of_link_property(con_np, p->name); 1450218792Snp 1451218792Snp return 0; 1452218792Snp} 1453218792Snp 1454218792Snpconst struct fwnode_operations of_fwnode_ops = { 1455218792Snp .get = of_fwnode_get, 1456218792Snp .put = of_fwnode_put, 1457218792Snp .device_is_available = of_fwnode_device_is_available, 1458218792Snp .device_get_match_data = of_fwnode_device_get_match_data, 1459218792Snp .device_dma_supported = of_fwnode_device_dma_supported, 1460218792Snp .device_get_dma_attr = of_fwnode_device_get_dma_attr, 1461218792Snp .property_present = of_fwnode_property_present, 1462218792Snp .property_read_int_array = of_fwnode_property_read_int_array, 1463218792Snp .property_read_string_array = of_fwnode_property_read_string_array, 1464218792Snp .get_name = of_fwnode_get_name, 1465218792Snp .get_name_prefix = of_fwnode_get_name_prefix, 1466218792Snp .get_parent = of_fwnode_get_parent, 1467218792Snp .get_next_child_node = of_fwnode_get_next_child_node, 1468218792Snp .get_named_child_node = of_fwnode_get_named_child_node, 1469218792Snp .get_reference_args = of_fwnode_get_reference_args, 1470218792Snp .graph_get_next_endpoint = of_fwnode_graph_get_next_endpoint, 1471218792Snp .graph_get_remote_endpoint = of_fwnode_graph_get_remote_endpoint, 1472218792Snp .graph_get_port_parent = of_fwnode_graph_get_port_parent, 1473218792Snp .graph_parse_endpoint = of_fwnode_graph_parse_endpoint, 1474218792Snp .iomap = of_fwnode_iomap, 1475218792Snp .irq_get = of_fwnode_irq_get, 1476218792Snp .add_links = of_fwnode_add_links, 1477218792Snp}; 1478218792SnpEXPORT_SYMBOL_GPL(of_fwnode_ops); 1479218792Snp