^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * drivers/of/property.c - Procedures for accessing and interpreting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Devicetree properties and graphs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Initially created by copying procedures from drivers/of/base.c. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * file contains the OF property as well as the OF graph interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Paul Mackerras August 1996.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Copyright (C) 1996-2005 Paul Mackerras.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * {engebret|bergner}@us.ibm.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Adapted for sparc and sparc64 by David S. Miller davem@davemloft.net
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Grant Likely.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define pr_fmt(fmt) "OF: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/of_graph.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "of_private.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * of_graph_is_present() - check graph's presence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * @node: pointer to device_node containing graph port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * Return: True if @node has a port or ports (with a port) sub-node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) bool of_graph_is_present(const struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct device_node *ports, *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) ports = of_get_child_by_name(node, "ports");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (ports)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) node = ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) port = of_get_child_by_name(node, "port");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) of_node_put(ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) of_node_put(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return !!port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) EXPORT_SYMBOL(of_graph_is_present);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * of_property_count_elems_of_size - Count the number of elements in a property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * @np: device node from which the property value is to be read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * @propname: name of the property to be searched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * @elem_size: size of the individual element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * Search for a property in a device node and count the number of elements of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * size elem_size in it. Returns number of elements on sucess, -EINVAL if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * property does not exist or its length does not match a multiple of elem_size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * and -ENODATA if the property does not have a value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) int of_property_count_elems_of_size(const struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) const char *propname, int elem_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct property *prop = of_find_property(np, propname, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (!prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (!prop->value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (prop->length % elem_size != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) pr_err("size of %s in node %pOF is not a multiple of %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) propname, np, elem_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) return prop->length / elem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) EXPORT_SYMBOL_GPL(of_property_count_elems_of_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * of_find_property_value_of_size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * @np: device node from which the property value is to be read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * @propname: name of the property to be searched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * @min: minimum allowed length of property value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * @max: maximum allowed length of property value (0 means unlimited)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * @len: if !=NULL, actual length is written to here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * Search for a property in a device node and valid the requested size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * Returns the property value on success, -EINVAL if the property does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * property data is too small or too large.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static void *of_find_property_value_of_size(const struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) const char *propname, u32 min, u32 max, size_t *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct property *prop = of_find_property(np, propname, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (!prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (!prop->value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return ERR_PTR(-ENODATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (prop->length < min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return ERR_PTR(-EOVERFLOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (max && prop->length > max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return ERR_PTR(-EOVERFLOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) *len = prop->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return prop->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * of_property_read_u32_index - Find and read a u32 from a multi-value property.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * @np: device node from which the property value is to be read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * @propname: name of the property to be searched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * @index: index of the u32 in the list of values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * @out_value: pointer to return value, modified only if no error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * Search for a property in a device node and read nth 32-bit value from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * it. Returns 0 on success, -EINVAL if the property does not exist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * -ENODATA if property does not have a value, and -EOVERFLOW if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * property data isn't large enough.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * The out_value is modified only if a valid u32 value can be decoded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) int of_property_read_u32_index(const struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) const char *propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) u32 index, u32 *out_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) const u32 *val = of_find_property_value_of_size(np, propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) ((index + 1) * sizeof(*out_value)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (IS_ERR(val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return PTR_ERR(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) *out_value = be32_to_cpup(((__be32 *)val) + index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) EXPORT_SYMBOL_GPL(of_property_read_u32_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * of_property_read_u64_index - Find and read a u64 from a multi-value property.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * @np: device node from which the property value is to be read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * @propname: name of the property to be searched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * @index: index of the u64 in the list of values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * @out_value: pointer to return value, modified only if no error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * Search for a property in a device node and read nth 64-bit value from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * it. Returns 0 on success, -EINVAL if the property does not exist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * -ENODATA if property does not have a value, and -EOVERFLOW if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * property data isn't large enough.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * The out_value is modified only if a valid u64 value can be decoded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) int of_property_read_u64_index(const struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) const char *propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) u32 index, u64 *out_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) const u64 *val = of_find_property_value_of_size(np, propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) ((index + 1) * sizeof(*out_value)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (IS_ERR(val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return PTR_ERR(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) *out_value = be64_to_cpup(((__be64 *)val) + index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) EXPORT_SYMBOL_GPL(of_property_read_u64_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * of_property_read_variable_u8_array - Find and read an array of u8 from a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * property, with bounds on the minimum and maximum array size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * @np: device node from which the property value is to be read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * @propname: name of the property to be searched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * @out_values: pointer to found values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * @sz_min: minimum number of array elements to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * @sz_max: maximum number of array elements to read, if zero there is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * upper limit on the number of elements in the dts entry but only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * sz_min will be read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * Search for a property in a device node and read 8-bit value(s) from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * it. Returns number of elements read on success, -EINVAL if the property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * if the property data is smaller than sz_min or longer than sz_max.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * dts entry of array should be like:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * property = /bits/ 8 <0x50 0x60 0x70>;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * The out_values is modified only if a valid u8 value can be decoded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int of_property_read_variable_u8_array(const struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) const char *propname, u8 *out_values,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) size_t sz_min, size_t sz_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) size_t sz, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) const u8 *val = of_find_property_value_of_size(np, propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) (sz_min * sizeof(*out_values)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) (sz_max * sizeof(*out_values)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) &sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (IS_ERR(val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return PTR_ERR(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (!sz_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) sz = sz_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) sz /= sizeof(*out_values);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) count = sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) while (count--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) *out_values++ = *val++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) EXPORT_SYMBOL_GPL(of_property_read_variable_u8_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * of_property_read_variable_u16_array - Find and read an array of u16 from a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * property, with bounds on the minimum and maximum array size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * @np: device node from which the property value is to be read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * @propname: name of the property to be searched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * @out_values: pointer to found values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * @sz_min: minimum number of array elements to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * @sz_max: maximum number of array elements to read, if zero there is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * upper limit on the number of elements in the dts entry but only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * sz_min will be read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * Search for a property in a device node and read 16-bit value(s) from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * it. Returns number of elements read on success, -EINVAL if the property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * if the property data is smaller than sz_min or longer than sz_max.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * dts entry of array should be like:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * property = /bits/ 16 <0x5000 0x6000 0x7000>;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * The out_values is modified only if a valid u16 value can be decoded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) int of_property_read_variable_u16_array(const struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) const char *propname, u16 *out_values,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) size_t sz_min, size_t sz_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) size_t sz, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) const __be16 *val = of_find_property_value_of_size(np, propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) (sz_min * sizeof(*out_values)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) (sz_max * sizeof(*out_values)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) &sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (IS_ERR(val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return PTR_ERR(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (!sz_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) sz = sz_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) sz /= sizeof(*out_values);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) count = sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) while (count--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) *out_values++ = be16_to_cpup(val++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) EXPORT_SYMBOL_GPL(of_property_read_variable_u16_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * of_property_read_variable_u32_array - Find and read an array of 32 bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * integers from a property, with bounds on the minimum and maximum array size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * @np: device node from which the property value is to be read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * @propname: name of the property to be searched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * @out_values: pointer to return found values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * @sz_min: minimum number of array elements to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * @sz_max: maximum number of array elements to read, if zero there is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * upper limit on the number of elements in the dts entry but only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * sz_min will be read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * Search for a property in a device node and read 32-bit value(s) from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * it. Returns number of elements read on success, -EINVAL if the property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * if the property data is smaller than sz_min or longer than sz_max.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) * The out_values is modified only if a valid u32 value can be decoded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) int of_property_read_variable_u32_array(const struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) const char *propname, u32 *out_values,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) size_t sz_min, size_t sz_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) size_t sz, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) const __be32 *val = of_find_property_value_of_size(np, propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) (sz_min * sizeof(*out_values)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) (sz_max * sizeof(*out_values)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) &sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (IS_ERR(val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return PTR_ERR(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (!sz_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) sz = sz_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) sz /= sizeof(*out_values);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) count = sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) while (count--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) *out_values++ = be32_to_cpup(val++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) EXPORT_SYMBOL_GPL(of_property_read_variable_u32_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * of_property_read_u64 - Find and read a 64 bit integer from a property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * @np: device node from which the property value is to be read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * @propname: name of the property to be searched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * @out_value: pointer to return value, modified only if return value is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * Search for a property in a device node and read a 64-bit value from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) * it. Returns 0 on success, -EINVAL if the property does not exist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * -ENODATA if property does not have a value, and -EOVERFLOW if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * property data isn't large enough.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * The out_value is modified only if a valid u64 value can be decoded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) int of_property_read_u64(const struct device_node *np, const char *propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) u64 *out_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) const __be32 *val = of_find_property_value_of_size(np, propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) sizeof(*out_value),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (IS_ERR(val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return PTR_ERR(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) *out_value = of_read_number(val, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) EXPORT_SYMBOL_GPL(of_property_read_u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * of_property_read_variable_u64_array - Find and read an array of 64 bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * integers from a property, with bounds on the minimum and maximum array size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * @np: device node from which the property value is to be read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * @propname: name of the property to be searched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * @out_values: pointer to found values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * @sz_min: minimum number of array elements to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * @sz_max: maximum number of array elements to read, if zero there is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * upper limit on the number of elements in the dts entry but only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * sz_min will be read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * Search for a property in a device node and read 64-bit value(s) from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * it. Returns number of elements read on success, -EINVAL if the property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * if the property data is smaller than sz_min or longer than sz_max.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) * The out_values is modified only if a valid u64 value can be decoded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) int of_property_read_variable_u64_array(const struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) const char *propname, u64 *out_values,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) size_t sz_min, size_t sz_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) size_t sz, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) const __be32 *val = of_find_property_value_of_size(np, propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) (sz_min * sizeof(*out_values)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) (sz_max * sizeof(*out_values)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) &sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (IS_ERR(val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return PTR_ERR(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (!sz_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) sz = sz_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) sz /= sizeof(*out_values);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) count = sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) while (count--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) *out_values++ = of_read_number(val, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) val += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) EXPORT_SYMBOL_GPL(of_property_read_variable_u64_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * of_property_read_string - Find and read a string from a property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * @np: device node from which the property value is to be read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * @propname: name of the property to be searched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * @out_string: pointer to null terminated return string, modified only if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * return value is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * Search for a property in a device tree node and retrieve a null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * terminated string value (pointer to data, not a copy). Returns 0 on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * success, -EINVAL if the property does not exist, -ENODATA if property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * does not have a value, and -EILSEQ if the string is not null-terminated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * within the length of the property data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * The out_string pointer is modified only if a valid string can be decoded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) int of_property_read_string(const struct device_node *np, const char *propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) const char **out_string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) const struct property *prop = of_find_property(np, propname, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (!prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (!prop->value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (strnlen(prop->value, prop->length) >= prop->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return -EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) *out_string = prop->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) EXPORT_SYMBOL_GPL(of_property_read_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * of_property_match_string() - Find string in a list and return index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * @np: pointer to node containing string list property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * @propname: string list property name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * @string: pointer to string to search for in string list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) * This function searches a string list property and returns the index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) * of a specific string value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) int of_property_match_string(const struct device_node *np, const char *propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) const char *string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) const struct property *prop = of_find_property(np, propname, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) size_t l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) const char *p, *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (!prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (!prop->value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) p = prop->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) end = p + prop->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) for (i = 0; p < end; i++, p += l) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) l = strnlen(p, end - p) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (p + l > end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return -EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) pr_debug("comparing %s with %s\n", string, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (strcmp(string, p) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return i; /* Found it; return index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) EXPORT_SYMBOL_GPL(of_property_match_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * of_property_read_string_helper() - Utility helper for parsing string properties
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * @np: device node from which the property value is to be read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * @propname: name of the property to be searched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) * @out_strs: output array of string pointers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * @sz: number of array elements to read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) * @skip: Number of strings to skip over at beginning of list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * Don't call this function directly. It is a utility helper for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * of_property_read_string*() family of functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) int of_property_read_string_helper(const struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) const char *propname, const char **out_strs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) size_t sz, int skip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) const struct property *prop = of_find_property(np, propname, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) int l = 0, i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) const char *p, *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (!prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (!prop->value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) p = prop->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) end = p + prop->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) l = strnlen(p, end - p) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (p + l > end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return -EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (out_strs && i >= skip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) *out_strs++ = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) i -= skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return i <= 0 ? -ENODATA : i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) EXPORT_SYMBOL_GPL(of_property_read_string_helper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) u32 *pu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) const void *curv = cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (!prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (!cur) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) curv = prop->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) goto out_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) curv += sizeof(*cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (curv >= prop->value + prop->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) out_val:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) *pu = be32_to_cpup(curv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return curv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) EXPORT_SYMBOL_GPL(of_prop_next_u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) const char *of_prop_next_string(struct property *prop, const char *cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) const void *curv = cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (!prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (!cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return prop->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) curv += strlen(cur) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) if (curv >= prop->value + prop->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return curv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) EXPORT_SYMBOL_GPL(of_prop_next_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * of_graph_parse_endpoint() - parse common endpoint node properties
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * @node: pointer to endpoint device_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * @endpoint: pointer to the OF endpoint data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) * The caller should hold a reference to @node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) int of_graph_parse_endpoint(const struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) struct of_endpoint *endpoint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) struct device_node *port_node = of_get_parent(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) WARN_ONCE(!port_node, "%s(): endpoint %pOF has no parent node\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) __func__, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) memset(endpoint, 0, sizeof(*endpoint));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) endpoint->local_node = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) * It doesn't matter whether the two calls below succeed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) * If they don't then the default value 0 is used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) of_property_read_u32(port_node, "reg", &endpoint->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) of_property_read_u32(node, "reg", &endpoint->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) of_node_put(port_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) EXPORT_SYMBOL(of_graph_parse_endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) * of_graph_get_port_by_id() - get the port matching a given id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) * @parent: pointer to the parent device node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) * @id: id of the port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) * Return: A 'port' node pointer with refcount incremented. The caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * has to use of_node_put() on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) struct device_node *of_graph_get_port_by_id(struct device_node *parent, u32 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) struct device_node *node, *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) node = of_get_child_by_name(parent, "ports");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) parent = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) for_each_child_of_node(parent, port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) u32 port_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (!of_node_name_eq(port, "port"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) of_property_read_u32(port, "reg", &port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (id == port_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) of_node_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) return port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) EXPORT_SYMBOL(of_graph_get_port_by_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * of_graph_get_next_endpoint() - get next endpoint node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * @parent: pointer to the parent device node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * @prev: previous endpoint node, or NULL to get first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * Return: An 'endpoint' node pointer with refcount incremented. Refcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * of the passed @prev node is decremented.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) struct device_node *prev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) struct device_node *endpoint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) struct device_node *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (!parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) * Start by locating the port node. If no previous endpoint is specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) * search for the first port node, otherwise get the previous endpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) * parent port node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (!prev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) struct device_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) node = of_get_child_by_name(parent, "ports");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if (node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) parent = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) port = of_get_child_by_name(parent, "port");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) of_node_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (!port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) pr_err("graph: no port node found in %pOF\n", parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) port = of_get_parent(prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (WARN_ONCE(!port, "%s(): endpoint %pOF has no parent node\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) __func__, prev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) * Now that we have a port node, get the next endpoint by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) * getting the next child. If the previous endpoint is NULL this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) * will return the first child.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) endpoint = of_get_next_child(port, prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (endpoint) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) of_node_put(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return endpoint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) /* No more endpoints under this port, try the next one. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) prev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) port = of_get_next_child(parent, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (!port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) } while (!of_node_name_eq(port, "port"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) EXPORT_SYMBOL(of_graph_get_next_endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) * of_graph_get_endpoint_by_regs() - get endpoint node of specific identifiers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * @parent: pointer to the parent device node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) * @port_reg: identifier (value of reg property) of the parent port node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) * @reg: identifier (value of reg property) of the endpoint node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) * Return: An 'endpoint' node pointer which is identified by reg and at the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) * is the child of a port node identified by port_reg. reg and port_reg are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * ignored when they are -1. Use of_node_put() on the pointer when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) struct device_node *of_graph_get_endpoint_by_regs(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) const struct device_node *parent, int port_reg, int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) struct of_endpoint endpoint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct device_node *node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) for_each_endpoint_of_node(parent, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) of_graph_parse_endpoint(node, &endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (((port_reg == -1) || (endpoint.port == port_reg)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) ((reg == -1) || (endpoint.id == reg)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) EXPORT_SYMBOL(of_graph_get_endpoint_by_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) * of_graph_get_remote_endpoint() - get remote endpoint node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) * @node: pointer to a local endpoint device_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) * Return: Remote endpoint node associated with remote endpoint node linked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) * to @node. Use of_node_put() on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) struct device_node *of_graph_get_remote_endpoint(const struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) /* Get remote endpoint node. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) return of_parse_phandle(node, "remote-endpoint", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) EXPORT_SYMBOL(of_graph_get_remote_endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) * of_graph_get_port_parent() - get port's parent node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * @node: pointer to a local endpoint device_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * Return: device node associated with endpoint node linked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) * to @node. Use of_node_put() on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) struct device_node *of_graph_get_port_parent(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) unsigned int depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (!node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) * Preserve usecount for passed in node as of_get_next_parent()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) * will do of_node_put() on it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) of_node_get(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) /* Walk 3 levels up only if there is 'ports' node. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) for (depth = 3; depth && node; depth--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) node = of_get_next_parent(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (depth == 2 && !of_node_name_eq(node, "ports"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) return node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) EXPORT_SYMBOL(of_graph_get_port_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) * of_graph_get_remote_port_parent() - get remote port's parent node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) * @node: pointer to a local endpoint device_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) * Return: Remote device node associated with remote endpoint node linked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) * to @node. Use of_node_put() on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) struct device_node *of_graph_get_remote_port_parent(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) const struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) struct device_node *np, *pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) /* Get remote endpoint node. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) np = of_graph_get_remote_endpoint(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) pp = of_graph_get_port_parent(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) return pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) EXPORT_SYMBOL(of_graph_get_remote_port_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) * of_graph_get_remote_port() - get remote port node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) * @node: pointer to a local endpoint device_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) * Return: Remote port node associated with remote endpoint node linked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) * to @node. Use of_node_put() on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) struct device_node *of_graph_get_remote_port(const struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) /* Get remote endpoint node. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) np = of_graph_get_remote_endpoint(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) return of_get_next_parent(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) EXPORT_SYMBOL(of_graph_get_remote_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) int of_graph_get_endpoint_count(const struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) struct device_node *endpoint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) int num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) for_each_endpoint_of_node(np, endpoint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) num++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) return num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) EXPORT_SYMBOL(of_graph_get_endpoint_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * of_graph_get_remote_node() - get remote parent device_node for given port/endpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) * @node: pointer to parent device_node containing graph port/endpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) * @port: identifier (value of reg property) of the parent port node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) * @endpoint: identifier (value of reg property) of the endpoint node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) * Return: Remote device node associated with remote endpoint node linked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) * to @node. Use of_node_put() on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) struct device_node *of_graph_get_remote_node(const struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) u32 port, u32 endpoint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) struct device_node *endpoint_node, *remote;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) endpoint_node = of_graph_get_endpoint_by_regs(node, port, endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (!endpoint_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) pr_debug("no valid endpoint (%d, %d) for node %pOF\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) port, endpoint, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) remote = of_graph_get_remote_port_parent(endpoint_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) of_node_put(endpoint_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (!remote) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) pr_debug("no valid remote node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) if (!of_device_is_available(remote)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) pr_debug("not available for remote node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) of_node_put(remote);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) return remote;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) EXPORT_SYMBOL(of_graph_get_remote_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) static struct fwnode_handle *of_fwnode_get(struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) return of_fwnode_handle(of_node_get(to_of_node(fwnode)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) static void of_fwnode_put(struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) of_node_put(to_of_node(fwnode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) static bool of_fwnode_device_is_available(const struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) return of_device_is_available(to_of_node(fwnode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) static bool of_fwnode_property_present(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) const char *propname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) return of_property_read_bool(to_of_node(fwnode), propname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) static int of_fwnode_property_read_int_array(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) const char *propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) unsigned int elem_size, void *val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) size_t nval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) const struct device_node *node = to_of_node(fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) return of_property_count_elems_of_size(node, propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) elem_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) switch (elem_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) case sizeof(u8):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) return of_property_read_u8_array(node, propname, val, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) case sizeof(u16):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) return of_property_read_u16_array(node, propname, val, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) case sizeof(u32):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) return of_property_read_u32_array(node, propname, val, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) case sizeof(u64):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) return of_property_read_u64_array(node, propname, val, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) of_fwnode_property_read_string_array(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) const char *propname, const char **val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) size_t nval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) const struct device_node *node = to_of_node(fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) return val ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) of_property_read_string_array(node, propname, val, nval) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) of_property_count_strings(node, propname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) static const char *of_fwnode_get_name(const struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) return kbasename(to_of_node(fwnode)->full_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) static const char *of_fwnode_get_name_prefix(const struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) /* Root needs no prefix here (its name is "/"). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (!to_of_node(fwnode)->parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) return "/";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) static struct fwnode_handle *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) of_fwnode_get_parent(const struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) return of_fwnode_handle(of_get_parent(to_of_node(fwnode)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) static struct fwnode_handle *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) of_fwnode_get_next_child_node(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) struct fwnode_handle *child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) return of_fwnode_handle(of_get_next_available_child(to_of_node(fwnode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) to_of_node(child)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) static struct fwnode_handle *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) of_fwnode_get_named_child_node(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) const char *childname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) const struct device_node *node = to_of_node(fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) struct device_node *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) for_each_available_child_of_node(node, child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (of_node_name_eq(child, childname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return of_fwnode_handle(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) of_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) const char *prop, const char *nargs_prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) unsigned int nargs, unsigned int index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) struct fwnode_reference_args *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) struct of_phandle_args of_args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (nargs_prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) ret = of_parse_phandle_with_args(to_of_node(fwnode), prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) nargs_prop, index, &of_args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) ret = of_parse_phandle_with_fixed_args(to_of_node(fwnode), prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) nargs, index, &of_args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (!args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) args->nargs = of_args.args_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) args->fwnode = of_fwnode_handle(of_args.np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) for (i = 0; i < NR_FWNODE_REFERENCE_ARGS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) args->args[i] = i < of_args.args_count ? of_args.args[i] : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) static struct fwnode_handle *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) of_fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) struct fwnode_handle *prev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) return of_fwnode_handle(of_graph_get_next_endpoint(to_of_node(fwnode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) to_of_node(prev)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) static struct fwnode_handle *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) of_fwnode_graph_get_remote_endpoint(const struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) return of_fwnode_handle(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) of_graph_get_remote_endpoint(to_of_node(fwnode)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) static struct fwnode_handle *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) of_fwnode_graph_get_port_parent(struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) /* Get the parent of the port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) np = of_get_parent(to_of_node(fwnode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) /* Is this the "ports" node? If not, it's the port parent. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) if (!of_node_name_eq(np, "ports"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) return of_fwnode_handle(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) return of_fwnode_handle(of_get_next_parent(np));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) static int of_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) struct fwnode_endpoint *endpoint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) const struct device_node *node = to_of_node(fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) struct device_node *port_node = of_get_parent(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) endpoint->local_fwnode = fwnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) of_property_read_u32(port_node, "reg", &endpoint->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) of_property_read_u32(node, "reg", &endpoint->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) of_node_put(port_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) static const void *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) of_fwnode_device_get_match_data(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) const struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) return of_device_get_match_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) static bool of_is_ancestor_of(struct device_node *test_ancestor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) struct device_node *child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) of_node_get(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) while (child) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) if (child == test_ancestor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) of_node_put(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) child = of_get_next_parent(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) * of_link_to_phandle - Add fwnode link to supplier from supplier phandle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) * @con_np: consumer device tree node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) * @sup_np: supplier device tree node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) * Given a phandle to a supplier device tree node (@sup_np), this function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) * finds the device that owns the supplier device tree node and creates a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) * device link from @dev consumer device to the supplier device. This function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) * doesn't create device links for invalid scenarios such as trying to create a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) * link with a parent device as the consumer of its child device. In such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) * cases, it returns an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) * - 0 if fwnode link successfully created to supplier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) * - -EINVAL if the supplier link is invalid and should not be created
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) * - -ENODEV if struct device will never be create for supplier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) static int of_link_to_phandle(struct device_node *con_np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) struct device_node *sup_np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) struct device *sup_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) struct device_node *tmp_np = sup_np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) of_node_get(sup_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) * Find the device node that contains the supplier phandle. It may be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) * @sup_np or it may be an ancestor of @sup_np.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) while (sup_np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) /* Don't allow linking to a disabled supplier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (!of_device_is_available(sup_np)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) of_node_put(sup_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) sup_np = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) if (of_find_property(sup_np, "compatible", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) sup_np = of_get_next_parent(sup_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) if (!sup_np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) pr_debug("Not linking %pOFP to %pOFP - No device\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) con_np, tmp_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) * Don't allow linking a device node as a consumer of one of its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) * descendant nodes. By definition, a child node can't be a functional
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) * dependency for the parent node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (of_is_ancestor_of(con_np, sup_np)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) pr_debug("Not linking %pOFP to %pOFP - is descendant\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) con_np, sup_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) of_node_put(sup_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) * Don't create links to "early devices" that won't have struct devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) * created for them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) sup_dev = get_dev_from_fwnode(&sup_np->fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (!sup_dev &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) (of_node_check_flag(sup_np, OF_POPULATED) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) sup_np->fwnode.flags & FWNODE_FLAG_NOT_DEVICE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) pr_debug("Not linking %pOFP to %pOFP - No struct device\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) con_np, sup_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) of_node_put(sup_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) put_device(sup_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) fwnode_link_add(of_fwnode_handle(con_np), of_fwnode_handle(sup_np));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) of_node_put(sup_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) * parse_prop_cells - Property parsing function for suppliers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) * @np: Pointer to device tree node containing a list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) * @prop_name: Name of property to be parsed. Expected to hold phandle values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) * @index: For properties holding a list of phandles, this is the index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) * into the list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) * @list_name: Property name that is known to contain list of phandle(s) to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) * supplier(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) * @cells_name: property name that specifies phandles' arguments count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) * This is a helper function to parse properties that have a known fixed name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) * and are a list of phandles and phandle arguments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) * - phandle node pointer with refcount incremented. Caller must of_node_put()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) * on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) * - NULL if no phandle found at index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) static struct device_node *parse_prop_cells(struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) const char *prop_name, int index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) const char *list_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) const char *cells_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) struct of_phandle_args sup_args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (strcmp(prop_name, list_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) if (of_parse_phandle_with_args(np, list_name, cells_name, index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) &sup_args))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) return sup_args.np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) #define DEFINE_SIMPLE_PROP(fname, name, cells) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) static struct device_node *parse_##fname(struct device_node *np, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) const char *prop_name, int index) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) return parse_prop_cells(np, prop_name, index, name, cells); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) static int strcmp_suffix(const char *str, const char *suffix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) unsigned int len, suffix_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) len = strlen(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) suffix_len = strlen(suffix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) if (len <= suffix_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) return strcmp(str + len - suffix_len, suffix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) * parse_suffix_prop_cells - Suffix property parsing function for suppliers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) * @np: Pointer to device tree node containing a list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) * @prop_name: Name of property to be parsed. Expected to hold phandle values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) * @index: For properties holding a list of phandles, this is the index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) * into the list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) * @suffix: Property suffix that is known to contain list of phandle(s) to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) * supplier(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) * @cells_name: property name that specifies phandles' arguments count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) * This is a helper function to parse properties that have a known fixed suffix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) * and are a list of phandles and phandle arguments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) * - phandle node pointer with refcount incremented. Caller must of_node_put()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) * on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) * - NULL if no phandle found at index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) static struct device_node *parse_suffix_prop_cells(struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) const char *prop_name, int index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) const char *suffix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) const char *cells_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) struct of_phandle_args sup_args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (strcmp_suffix(prop_name, suffix))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) if (of_parse_phandle_with_args(np, prop_name, cells_name, index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) &sup_args))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) return sup_args.np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) #define DEFINE_SUFFIX_PROP(fname, suffix, cells) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) static struct device_node *parse_##fname(struct device_node *np, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) const char *prop_name, int index) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) return parse_suffix_prop_cells(np, prop_name, index, suffix, cells); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) * struct supplier_bindings - Property parsing functions for suppliers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) * @parse_prop: function name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) * parse_prop() finds the node corresponding to a supplier phandle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) * @parse_prop.np: Pointer to device node holding supplier phandle property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) * @parse_prop.prop_name: Name of property holding a phandle value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) * @parse_prop.index: For properties holding a list of phandles, this is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) * index into the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) * parse_prop() return values are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) * - phandle node pointer with refcount incremented. Caller must of_node_put()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) * on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) * - NULL if no phandle found at index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) struct supplier_bindings {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) struct device_node *(*parse_prop)(struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) const char *prop_name, int index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) bool optional;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) DEFINE_SIMPLE_PROP(clocks, "clocks", "#clock-cells")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) DEFINE_SIMPLE_PROP(interconnects, "interconnects", "#interconnect-cells")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) DEFINE_SIMPLE_PROP(iommus, "iommus", "#iommu-cells")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) DEFINE_SIMPLE_PROP(mboxes, "mboxes", "#mbox-cells")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) DEFINE_SIMPLE_PROP(io_channels, "io-channel", "#io-channel-cells")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) DEFINE_SIMPLE_PROP(interrupt_parent, "interrupt-parent", NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) DEFINE_SIMPLE_PROP(dmas, "dmas", "#dma-cells")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) DEFINE_SIMPLE_PROP(power_domains, "power-domains", "#power-domain-cells")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) DEFINE_SIMPLE_PROP(hwlocks, "hwlocks", "#hwlock-cells")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) DEFINE_SIMPLE_PROP(extcon, "extcon", NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) DEFINE_SIMPLE_PROP(nvmem_cells, "nvmem-cells", NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) DEFINE_SIMPLE_PROP(phys, "phys", "#phy-cells")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) DEFINE_SIMPLE_PROP(wakeup_parent, "wakeup-parent", NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) DEFINE_SIMPLE_PROP(pinctrl0, "pinctrl-0", NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) DEFINE_SIMPLE_PROP(pinctrl1, "pinctrl-1", NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) DEFINE_SIMPLE_PROP(pinctrl2, "pinctrl-2", NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) DEFINE_SIMPLE_PROP(pinctrl3, "pinctrl-3", NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) DEFINE_SIMPLE_PROP(pinctrl4, "pinctrl-4", NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) DEFINE_SIMPLE_PROP(pinctrl5, "pinctrl-5", NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) DEFINE_SIMPLE_PROP(pinctrl6, "pinctrl-6", NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) DEFINE_SIMPLE_PROP(pinctrl7, "pinctrl-7", NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) DEFINE_SIMPLE_PROP(pinctrl8, "pinctrl-8", NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) DEFINE_SUFFIX_PROP(regulators, "-supply", NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) DEFINE_SUFFIX_PROP(gpio, "-gpio", "#gpio-cells")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) static struct device_node *parse_gpios(struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) const char *prop_name, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) if (!strcmp_suffix(prop_name, ",nr-gpios"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) return parse_suffix_prop_cells(np, prop_name, index, "-gpios",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) "#gpio-cells");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) static struct device_node *parse_iommu_maps(struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) const char *prop_name, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) if (strcmp(prop_name, "iommu-map"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) return of_parse_phandle(np, prop_name, (index * 4) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) static struct device_node *parse_gpio_compat(struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) const char *prop_name, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) struct of_phandle_args sup_args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) if (strcmp(prop_name, "gpio") && strcmp(prop_name, "gpios"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) * Ignore node with gpio-hog property since its gpios are all provided
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) * by its parent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) if (of_find_property(np, "gpio-hog", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) if (of_parse_phandle_with_args(np, prop_name, "#gpio-cells", index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) &sup_args))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) return sup_args.np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) static struct device_node *parse_interrupts(struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) const char *prop_name, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) struct of_phandle_args sup_args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) if (!IS_ENABLED(CONFIG_OF_IRQ) || IS_ENABLED(CONFIG_PPC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) if (strcmp(prop_name, "interrupts") &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) strcmp(prop_name, "interrupts-extended"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) return of_irq_parse_one(np, index, &sup_args) ? NULL : sup_args.np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) static const struct supplier_bindings of_supplier_bindings[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) { .parse_prop = parse_clocks, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) { .parse_prop = parse_interconnects, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) { .parse_prop = parse_iommus, .optional = true, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) { .parse_prop = parse_iommu_maps, .optional = true, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) { .parse_prop = parse_mboxes, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) { .parse_prop = parse_io_channels, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) { .parse_prop = parse_interrupt_parent, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) { .parse_prop = parse_dmas, .optional = true, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) { .parse_prop = parse_power_domains, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) { .parse_prop = parse_hwlocks, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) { .parse_prop = parse_extcon, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) { .parse_prop = parse_nvmem_cells, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) { .parse_prop = parse_phys, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) { .parse_prop = parse_wakeup_parent, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) { .parse_prop = parse_pinctrl0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) { .parse_prop = parse_pinctrl1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) { .parse_prop = parse_pinctrl2, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) { .parse_prop = parse_pinctrl3, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) { .parse_prop = parse_pinctrl4, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) { .parse_prop = parse_pinctrl5, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) { .parse_prop = parse_pinctrl6, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) { .parse_prop = parse_pinctrl7, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) { .parse_prop = parse_pinctrl8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) { .parse_prop = parse_gpio_compat, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) { .parse_prop = parse_interrupts, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) { .parse_prop = parse_regulators, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) { .parse_prop = parse_gpio, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) { .parse_prop = parse_gpios, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) * of_link_property - Create device links to suppliers listed in a property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) * @dev: Consumer device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) * @con_np: The consumer device tree node which contains the property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) * @prop_name: Name of property to be parsed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) * This function checks if the property @prop_name that is present in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) * @con_np device tree node is one of the known common device tree bindings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) * that list phandles to suppliers. If @prop_name isn't one, this function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) * doesn't do anything.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) * If @prop_name is one, this function attempts to create fwnode links from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) * consumer device tree node @con_np to all the suppliers device tree nodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) * listed in @prop_name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) * Any failed attempt to create a fwnode link will NOT result in an immediate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) * return. of_link_property() must create links to all the available supplier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) * device tree nodes even when attempts to create a link to one or more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) * suppliers fail.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) static int of_link_property(struct device_node *con_np, const char *prop_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) struct device_node *phandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) const struct supplier_bindings *s = of_supplier_bindings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) unsigned int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) bool matched = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) /* Do not stop at first failed link, link all available suppliers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) while (!matched && s->parse_prop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) if (s->optional && !fw_devlink_is_strict()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) while ((phandle = s->parse_prop(con_np, prop_name, i))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) matched = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) of_link_to_phandle(con_np, phandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) of_node_put(phandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) static int of_fwnode_add_links(struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) struct property *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) struct device_node *con_np = to_of_node(fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) if (!con_np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) for_each_property_of_node(con_np, p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) of_link_property(con_np, p->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) const struct fwnode_operations of_fwnode_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) .get = of_fwnode_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) .put = of_fwnode_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) .device_is_available = of_fwnode_device_is_available,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) .device_get_match_data = of_fwnode_device_get_match_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) .property_present = of_fwnode_property_present,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) .property_read_int_array = of_fwnode_property_read_int_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) .property_read_string_array = of_fwnode_property_read_string_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) .get_name = of_fwnode_get_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) .get_name_prefix = of_fwnode_get_name_prefix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) .get_parent = of_fwnode_get_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) .get_next_child_node = of_fwnode_get_next_child_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) .get_named_child_node = of_fwnode_get_named_child_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) .get_reference_args = of_fwnode_get_reference_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) .graph_get_next_endpoint = of_fwnode_graph_get_next_endpoint,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) .graph_get_remote_endpoint = of_fwnode_graph_get_remote_endpoint,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) .graph_get_port_parent = of_fwnode_graph_get_port_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) .graph_parse_endpoint = of_fwnode_graph_parse_endpoint,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) .add_links = of_fwnode_add_links,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) EXPORT_SYMBOL_GPL(of_fwnode_ops);