^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) * property.c - Unified device property interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2014, Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Authors: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Mika Westerberg <mika.westerberg@linux.intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/of_graph.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/property.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct fwnode_handle *dev_fwnode(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) return IS_ENABLED(CONFIG_OF) && dev->of_node ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) &dev->of_node->fwnode : dev->fwnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) EXPORT_SYMBOL_GPL(dev_fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * device_property_present - check if a property of a device is present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * @dev: Device whose property is being checked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * @propname: Name of the property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * Check if property @propname is present in the device firmware description.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) bool device_property_present(struct device *dev, const char *propname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) return fwnode_property_present(dev_fwnode(dev), propname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) EXPORT_SYMBOL_GPL(device_property_present);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * fwnode_property_present - check if a property of a firmware node is present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * @fwnode: Firmware node whose property to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * @propname: Name of the property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) bool fwnode_property_present(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) const char *propname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) bool ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) ret = fwnode_call_bool_op(fwnode, property_present, propname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (ret == false && !IS_ERR_OR_NULL(fwnode) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) !IS_ERR_OR_NULL(fwnode->secondary))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) ret = fwnode_call_bool_op(fwnode->secondary, property_present,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) propname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) EXPORT_SYMBOL_GPL(fwnode_property_present);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * device_property_read_u8_array - return a u8 array property of a device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * @dev: Device to get the property of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * @propname: Name of the property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * @val: The values are stored here or %NULL to return the number of values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * @nval: Size of the @val array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * Function reads an array of u8 properties with @propname from the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * firmware description and stores them to @val if found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * Return: number of values if @val was %NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * %0 if the property was found (success),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * %-EINVAL if given arguments are not valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * %-ENODATA if the property does not have a value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * %-EPROTO if the property is not an array of numbers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * %-EOVERFLOW if the size of the property is not as expected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * %-ENXIO if no suitable firmware interface is present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int device_property_read_u8_array(struct device *dev, const char *propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) u8 *val, size_t nval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return fwnode_property_read_u8_array(dev_fwnode(dev), propname, val, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) EXPORT_SYMBOL_GPL(device_property_read_u8_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * device_property_read_u16_array - return a u16 array property of a device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * @dev: Device to get the property of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * @propname: Name of the property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * @val: The values are stored here or %NULL to return the number of values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * @nval: Size of the @val array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * Function reads an array of u16 properties with @propname from the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * firmware description and stores them to @val if found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * Return: number of values if @val was %NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * %0 if the property was found (success),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * %-EINVAL if given arguments are not valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * %-ENODATA if the property does not have a value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * %-EPROTO if the property is not an array of numbers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * %-EOVERFLOW if the size of the property is not as expected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * %-ENXIO if no suitable firmware interface is present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int device_property_read_u16_array(struct device *dev, const char *propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) u16 *val, size_t nval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return fwnode_property_read_u16_array(dev_fwnode(dev), propname, val, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) EXPORT_SYMBOL_GPL(device_property_read_u16_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * device_property_read_u32_array - return a u32 array property of a device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * @dev: Device to get the property of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * @propname: Name of the property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * @val: The values are stored here or %NULL to return the number of values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * @nval: Size of the @val array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * Function reads an array of u32 properties with @propname from the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * firmware description and stores them to @val if found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * Return: number of values if @val was %NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * %0 if the property was found (success),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * %-EINVAL if given arguments are not valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * %-ENODATA if the property does not have a value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * %-EPROTO if the property is not an array of numbers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * %-EOVERFLOW if the size of the property is not as expected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * %-ENXIO if no suitable firmware interface is present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) int device_property_read_u32_array(struct device *dev, const char *propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) u32 *val, size_t nval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return fwnode_property_read_u32_array(dev_fwnode(dev), propname, val, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) EXPORT_SYMBOL_GPL(device_property_read_u32_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * device_property_read_u64_array - return a u64 array property of a device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * @dev: Device to get the property of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * @propname: Name of the property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * @val: The values are stored here or %NULL to return the number of values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * @nval: Size of the @val array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * Function reads an array of u64 properties with @propname from the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * firmware description and stores them to @val if found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * Return: number of values if @val was %NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * %0 if the property was found (success),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * %-EINVAL if given arguments are not valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * %-ENODATA if the property does not have a value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * %-EPROTO if the property is not an array of numbers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * %-EOVERFLOW if the size of the property is not as expected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * %-ENXIO if no suitable firmware interface is present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) int device_property_read_u64_array(struct device *dev, const char *propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) u64 *val, size_t nval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return fwnode_property_read_u64_array(dev_fwnode(dev), propname, val, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) EXPORT_SYMBOL_GPL(device_property_read_u64_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * device_property_read_string_array - return a string array property of device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * @dev: Device to get the property of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * @propname: Name of the property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * @val: The values are stored here or %NULL to return the number of values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * @nval: Size of the @val array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * Function reads an array of string properties with @propname from the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * firmware description and stores them to @val if found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * Return: number of values read on success if @val is non-NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * number of values available on success if @val is NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * %-EINVAL if given arguments are not valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * %-ENODATA if the property does not have a value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * %-EPROTO or %-EILSEQ if the property is not an array of strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * %-EOVERFLOW if the size of the property is not as expected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * %-ENXIO if no suitable firmware interface is present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) int device_property_read_string_array(struct device *dev, const char *propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) const char **val, size_t nval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return fwnode_property_read_string_array(dev_fwnode(dev), propname, val, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) EXPORT_SYMBOL_GPL(device_property_read_string_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * device_property_read_string - return a string property of a device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * @dev: Device to get the property of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * @propname: Name of the property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * @val: The value is stored here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * Function reads property @propname from the device firmware description and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * stores the value into @val if found. The value is checked to be a string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * Return: %0 if the property was found (success),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * %-EINVAL if given arguments are not valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * %-ENODATA if the property does not have a value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * %-EPROTO or %-EILSEQ if the property type is not a string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * %-ENXIO if no suitable firmware interface is present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) int device_property_read_string(struct device *dev, const char *propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) const char **val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return fwnode_property_read_string(dev_fwnode(dev), propname, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) EXPORT_SYMBOL_GPL(device_property_read_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * device_property_match_string - find a string in an array and return index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * @dev: Device to get the property of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * @propname: Name of the property holding the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * @string: String to look for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * Find a given string in a string array and if it is found return the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * index back.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * Return: %0 if the property was found (success),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * %-EINVAL if given arguments are not valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * %-ENODATA if the property does not have a value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * %-EPROTO if the property is not an array of strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * %-ENXIO if no suitable firmware interface is present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) int device_property_match_string(struct device *dev, const char *propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) const char *string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return fwnode_property_match_string(dev_fwnode(dev), propname, string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) EXPORT_SYMBOL_GPL(device_property_match_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static int fwnode_property_read_int_array(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) const char *propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) unsigned int elem_size, void *val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) size_t nval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) ret = fwnode_call_int_op(fwnode, property_read_int_array, propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) elem_size, val, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) !IS_ERR_OR_NULL(fwnode->secondary))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) ret = fwnode_call_int_op(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) fwnode->secondary, property_read_int_array, propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) elem_size, val, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * fwnode_property_read_u8_array - return a u8 array property of firmware node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * @fwnode: Firmware node to get the property of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * @propname: Name of the property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * @val: The values are stored here or %NULL to return the number of values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * @nval: Size of the @val array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * Read an array of u8 properties with @propname from @fwnode and stores them to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * @val if found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * Return: number of values if @val was %NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * %0 if the property was found (success),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * %-EINVAL if given arguments are not valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * %-ENODATA if the property does not have a value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * %-EPROTO if the property is not an array of numbers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * %-EOVERFLOW if the size of the property is not as expected,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * %-ENXIO if no suitable firmware interface is present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) int fwnode_property_read_u8_array(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) const char *propname, u8 *val, size_t nval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return fwnode_property_read_int_array(fwnode, propname, sizeof(u8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) val, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * fwnode_property_read_u16_array - return a u16 array property of firmware node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * @fwnode: Firmware node to get the property of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * @propname: Name of the property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * @val: The values are stored here or %NULL to return the number of values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * @nval: Size of the @val array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * Read an array of u16 properties with @propname from @fwnode and store them to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * @val if found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * Return: number of values if @val was %NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * %0 if the property was found (success),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * %-EINVAL if given arguments are not valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * %-ENODATA if the property does not have a value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * %-EPROTO if the property is not an array of numbers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * %-EOVERFLOW if the size of the property is not as expected,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * %-ENXIO if no suitable firmware interface is present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) int fwnode_property_read_u16_array(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) const char *propname, u16 *val, size_t nval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return fwnode_property_read_int_array(fwnode, propname, sizeof(u16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) val, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * fwnode_property_read_u32_array - return a u32 array property of firmware node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * @fwnode: Firmware node to get the property of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * @propname: Name of the property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * @val: The values are stored here or %NULL to return the number of values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * @nval: Size of the @val array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * Read an array of u32 properties with @propname from @fwnode store them to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * @val if found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * Return: number of values if @val was %NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * %0 if the property was found (success),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * %-EINVAL if given arguments are not valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * %-ENODATA if the property does not have a value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * %-EPROTO if the property is not an array of numbers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * %-EOVERFLOW if the size of the property is not as expected,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * %-ENXIO if no suitable firmware interface is present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) int fwnode_property_read_u32_array(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) const char *propname, u32 *val, size_t nval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return fwnode_property_read_int_array(fwnode, propname, sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) val, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * fwnode_property_read_u64_array - return a u64 array property firmware node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * @fwnode: Firmware node to get the property of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * @propname: Name of the property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * @val: The values are stored here or %NULL to return the number of values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * @nval: Size of the @val array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) * Read an array of u64 properties with @propname from @fwnode and store them to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * @val if found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * Return: number of values if @val was %NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * %0 if the property was found (success),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * %-EINVAL if given arguments are not valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * %-ENODATA if the property does not have a value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * %-EPROTO if the property is not an array of numbers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) * %-EOVERFLOW if the size of the property is not as expected,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * %-ENXIO if no suitable firmware interface is present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) int fwnode_property_read_u64_array(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) const char *propname, u64 *val, size_t nval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return fwnode_property_read_int_array(fwnode, propname, sizeof(u64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) val, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * fwnode_property_read_string_array - return string array property of a node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * @fwnode: Firmware node to get the property of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * @propname: Name of the property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * @val: The values are stored here or %NULL to return the number of values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * @nval: Size of the @val array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * Read an string list property @propname from the given firmware node and store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * them to @val if found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * Return: number of values read on success if @val is non-NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * number of values available on success if @val is NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * %-EINVAL if given arguments are not valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * %-ENODATA if the property does not have a value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * %-EPROTO or %-EILSEQ if the property is not an array of strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * %-EOVERFLOW if the size of the property is not as expected,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * %-ENXIO if no suitable firmware interface is present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) int fwnode_property_read_string_array(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) const char *propname, const char **val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) size_t nval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) ret = fwnode_call_int_op(fwnode, property_read_string_array, propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) val, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) !IS_ERR_OR_NULL(fwnode->secondary))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) ret = fwnode_call_int_op(fwnode->secondary,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) property_read_string_array, propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) val, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * fwnode_property_read_string - return a string property of a firmware node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * @fwnode: Firmware node to get the property of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * @propname: Name of the property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * @val: The value is stored here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * Read property @propname from the given firmware node and store the value into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * @val if found. The value is checked to be a string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * Return: %0 if the property was found (success),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * %-EINVAL if given arguments are not valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * %-ENODATA if the property does not have a value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * %-EPROTO or %-EILSEQ if the property is not a string,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * %-ENXIO if no suitable firmware interface is present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) int fwnode_property_read_string(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) const char *propname, const char **val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) int ret = fwnode_property_read_string_array(fwnode, propname, val, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return ret < 0 ? ret : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) EXPORT_SYMBOL_GPL(fwnode_property_read_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * fwnode_property_match_string - find a string in an array and return index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * @fwnode: Firmware node to get the property of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * @propname: Name of the property holding the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * @string: String to look for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * Find a given string in a string array and if it is found return the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * index back.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * Return: %0 if the property was found (success),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * %-EINVAL if given arguments are not valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * %-ENODATA if the property does not have a value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * %-EPROTO if the property is not an array of strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * %-ENXIO if no suitable firmware interface is present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) int fwnode_property_match_string(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) const char *propname, const char *string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) const char **values;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) int nval, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) nval = fwnode_property_read_string_array(fwnode, propname, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (nval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return nval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (nval == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) values = kcalloc(nval, sizeof(*values), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (!values)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) ret = fwnode_property_read_string_array(fwnode, propname, values, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) ret = match_string(values, nval, string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) ret = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) kfree(values);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) EXPORT_SYMBOL_GPL(fwnode_property_match_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * fwnode_property_get_reference_args() - Find a reference with arguments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * @fwnode: Firmware node where to look for the reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * @prop: The name of the property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * @nargs_prop: The name of the property telling the number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * arguments in the referred node. NULL if @nargs is known,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) * otherwise @nargs is ignored. Only relevant on OF.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * @nargs: Number of arguments. Ignored if @nargs_prop is non-NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * @index: Index of the reference, from zero onwards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * @args: Result structure with reference and integer arguments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) * Obtain a reference based on a named property in an fwnode, with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * integer arguments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * Caller is responsible to call fwnode_handle_put() on the returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * args->fwnode pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * Returns: %0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * %-ENOENT when the index is out of bounds, the index has an empty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) * reference or the property was not found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * %-EINVAL on parse error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) const char *prop, const char *nargs_prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) unsigned int nargs, unsigned int index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct fwnode_reference_args *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return fwnode_call_int_op(fwnode, get_reference_args, prop, nargs_prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) nargs, index, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) EXPORT_SYMBOL_GPL(fwnode_property_get_reference_args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * fwnode_find_reference - Find named reference to a fwnode_handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * @fwnode: Firmware node where to look for the reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) * @name: The name of the reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * @index: Index of the reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) * @index can be used when the named reference holds a table of references.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) * Returns pointer to the reference fwnode, or ERR_PTR. Caller is responsible to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) * call fwnode_handle_put() on the returned fwnode pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) struct fwnode_handle *fwnode_find_reference(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) unsigned int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) struct fwnode_reference_args args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) ret = fwnode_property_get_reference_args(fwnode, name, NULL, 0, index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) &args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return ret ? ERR_PTR(ret) : args.fwnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) EXPORT_SYMBOL_GPL(fwnode_find_reference);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * device_remove_properties - Remove properties from a device object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) * @dev: Device whose properties to remove.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * The function removes properties previously associated to the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * firmware node with device_add_properties(). Memory allocated to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) * properties will also be released.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) void device_remove_properties(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) struct fwnode_handle *fwnode = dev_fwnode(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (!fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (is_software_node(fwnode->secondary)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) fwnode_remove_software_node(fwnode->secondary);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) set_secondary_fwnode(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) EXPORT_SYMBOL_GPL(device_remove_properties);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) * device_add_properties - Add a collection of properties to a device object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * @dev: Device to add properties to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * @properties: Collection of properties to add.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * Associate a collection of device properties represented by @properties with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * @dev. The function takes a copy of @properties.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * WARNING: The callers should not use this function if it is known that there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * is no real firmware node associated with @dev! In that case the callers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * should create a software node and assign it to @dev directly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) int device_add_properties(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) const struct property_entry *properties)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) struct fwnode_handle *fwnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) fwnode = fwnode_create_software_node(properties, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (IS_ERR(fwnode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return PTR_ERR(fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) set_secondary_fwnode(dev, fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) EXPORT_SYMBOL_GPL(device_add_properties);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * fwnode_get_name - Return the name of a node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * @fwnode: The firmware node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) * Returns a pointer to the node name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) const char *fwnode_get_name(const struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) return fwnode_call_ptr_op(fwnode, get_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) EXPORT_SYMBOL_GPL(fwnode_get_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) * fwnode_get_name_prefix - Return the prefix of node for printing purposes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) * @fwnode: The firmware node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) * Returns the prefix of a node, intended to be printed right before the node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * The prefix works also as a separator between the nodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) const char *fwnode_get_name_prefix(const struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) return fwnode_call_ptr_op(fwnode, get_name_prefix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) * fwnode_get_parent - Return parent firwmare node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) * @fwnode: Firmware whose parent is retrieved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) * Return parent firmware node of the given node if possible or %NULL if no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) * parent was available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) struct fwnode_handle *fwnode_get_parent(const struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) return fwnode_call_ptr_op(fwnode, get_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) EXPORT_SYMBOL_GPL(fwnode_get_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) * fwnode_get_next_parent - Iterate to the node's parent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) * @fwnode: Firmware whose parent is retrieved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * This is like fwnode_get_parent() except that it drops the refcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * on the passed node, making it suitable for iterating through a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * node's parents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) * Returns a node pointer with refcount incremented, use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) * fwnode_handle_node() on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) struct fwnode_handle *fwnode_get_next_parent(struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) struct fwnode_handle *parent = fwnode_get_parent(fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) fwnode_handle_put(fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) EXPORT_SYMBOL_GPL(fwnode_get_next_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * fwnode_get_next_parent_dev - Find device of closest ancestor fwnode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * @fwnode: firmware node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * Given a firmware node (@fwnode), this function finds its closest ancestor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * firmware node that has a corresponding struct device and returns that struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) * The caller of this function is expected to call put_device() on the returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) * device when they are done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) struct device *fwnode_get_next_parent_dev(struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) struct device *dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) fwnode_handle_get(fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) fwnode = fwnode_get_next_parent(fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) dev = get_dev_from_fwnode(fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) } while (fwnode && !dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) fwnode_handle_put(fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) * fwnode_count_parents - Return the number of parents a node has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * @fwnode: The node the parents of which are to be counted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * Returns the number of parents a node has.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) unsigned int fwnode_count_parents(const struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) struct fwnode_handle *__fwnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) unsigned int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) __fwnode = fwnode_get_parent(fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) for (count = 0; __fwnode; count++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) __fwnode = fwnode_get_next_parent(__fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) EXPORT_SYMBOL_GPL(fwnode_count_parents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) * fwnode_get_nth_parent - Return an nth parent of a node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) * @fwnode: The node the parent of which is requested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) * @depth: Distance of the parent from the node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * Returns the nth parent of a node. If there is no parent at the requested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) * @depth, %NULL is returned. If @depth is 0, the functionality is equivalent to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) * fwnode_handle_get(). For @depth == 1, it is fwnode_get_parent() and so on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) * The caller is responsible for calling fwnode_handle_put() for the returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) * node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) struct fwnode_handle *fwnode_get_nth_parent(struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) unsigned int depth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) fwnode_handle_get(fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) for (i = 0; i < depth && fwnode; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) fwnode = fwnode_get_next_parent(fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return fwnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) EXPORT_SYMBOL_GPL(fwnode_get_nth_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) * fwnode_is_ancestor_of - Test if @test_ancestor is ancestor of @test_child
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) * @test_ancestor: Firmware which is tested for being an ancestor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) * @test_child: Firmware which is tested for being the child
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * A node is considered an ancestor of itself too.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * Returns true if @test_ancestor is an ancestor of @test_child.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * Otherwise, returns false.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) bool fwnode_is_ancestor_of(struct fwnode_handle *test_ancestor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) struct fwnode_handle *test_child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (!test_ancestor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) fwnode_handle_get(test_child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) while (test_child) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) if (test_child == test_ancestor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) fwnode_handle_put(test_child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) test_child = fwnode_get_next_parent(test_child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) * fwnode_get_next_child_node - Return the next child node handle for a node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) * @fwnode: Firmware node to find the next child node for.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) * @child: Handle to one of the node's child nodes or a %NULL handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) struct fwnode_handle *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) fwnode_get_next_child_node(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) struct fwnode_handle *child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) return fwnode_call_ptr_op(fwnode, get_next_child_node, child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) EXPORT_SYMBOL_GPL(fwnode_get_next_child_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) * fwnode_get_next_available_child_node - Return the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) * available child node handle for a node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) * @fwnode: Firmware node to find the next child node for.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) * @child: Handle to one of the node's child nodes or a %NULL handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) struct fwnode_handle *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) fwnode_get_next_available_child_node(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) struct fwnode_handle *child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) struct fwnode_handle *next_child = child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (!fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) next_child = fwnode_get_next_child_node(fwnode, next_child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (!next_child || fwnode_device_is_available(next_child))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) } while (next_child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) return next_child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) EXPORT_SYMBOL_GPL(fwnode_get_next_available_child_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) * device_get_next_child_node - Return the next child node handle for a device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) * @dev: Device to find the next child node for.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) * @child: Handle to one of the device's child nodes or a null handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) struct fwnode_handle *device_get_next_child_node(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) struct fwnode_handle *child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) struct acpi_device *adev = ACPI_COMPANION(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) struct fwnode_handle *fwnode = NULL, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (dev->of_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) fwnode = &dev->of_node->fwnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) else if (adev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) fwnode = acpi_fwnode_handle(adev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) /* Try to find a child in primary fwnode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) next = fwnode_get_next_child_node(fwnode, child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) return next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) /* When no more children in primary, continue with secondary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (fwnode && !IS_ERR_OR_NULL(fwnode->secondary))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) next = fwnode_get_next_child_node(fwnode->secondary, child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) return next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) EXPORT_SYMBOL_GPL(device_get_next_child_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) * fwnode_get_named_child_node - Return first matching named child node handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) * @fwnode: Firmware node to find the named child node for.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) * @childname: String to match child node name against.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) struct fwnode_handle *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) fwnode_get_named_child_node(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) const char *childname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) return fwnode_call_ptr_op(fwnode, get_named_child_node, childname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) EXPORT_SYMBOL_GPL(fwnode_get_named_child_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) * device_get_named_child_node - Return first matching named child node handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) * @dev: Device to find the named child node for.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) * @childname: String to match child node name against.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) struct fwnode_handle *device_get_named_child_node(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) const char *childname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) return fwnode_get_named_child_node(dev_fwnode(dev), childname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) EXPORT_SYMBOL_GPL(device_get_named_child_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) * fwnode_handle_get - Obtain a reference to a device node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) * @fwnode: Pointer to the device node to obtain the reference to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) * Returns the fwnode handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) struct fwnode_handle *fwnode_handle_get(struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (!fwnode_has_op(fwnode, get))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) return fwnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) return fwnode_call_ptr_op(fwnode, get);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) EXPORT_SYMBOL_GPL(fwnode_handle_get);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) * fwnode_handle_put - Drop reference to a device node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) * @fwnode: Pointer to the device node to drop the reference to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) * This has to be used when terminating device_for_each_child_node() iteration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) * with break or return to prevent stale device node references from being left
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) * behind.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) void fwnode_handle_put(struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) fwnode_call_void_op(fwnode, put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) EXPORT_SYMBOL_GPL(fwnode_handle_put);
^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) * fwnode_device_is_available - check if a device is available for use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) * @fwnode: Pointer to the fwnode of the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) bool fwnode_device_is_available(const struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return fwnode_call_bool_op(fwnode, device_is_available);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) EXPORT_SYMBOL_GPL(fwnode_device_is_available);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) * device_get_child_node_count - return the number of child nodes for device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) * @dev: Device to cound the child nodes for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) unsigned int device_get_child_node_count(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) struct fwnode_handle *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) unsigned int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) device_for_each_child_node(dev, child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) EXPORT_SYMBOL_GPL(device_get_child_node_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) bool device_dma_supported(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) /* For DT, this is always supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) * For ACPI, this depends on CCA, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) * is determined by the acpi_dma_supported().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (IS_ENABLED(CONFIG_OF) && dev->of_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return acpi_dma_supported(ACPI_COMPANION(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) EXPORT_SYMBOL_GPL(device_dma_supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) enum dev_dma_attr device_get_dma_attr(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) enum dev_dma_attr attr = DEV_DMA_NOT_SUPPORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) if (of_dma_is_coherent(dev->of_node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) attr = DEV_DMA_COHERENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) attr = DEV_DMA_NON_COHERENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) attr = acpi_get_dma_attr(ACPI_COMPANION(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) return attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) EXPORT_SYMBOL_GPL(device_get_dma_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) * fwnode_get_phy_mode - Get phy mode for given firmware node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) * @fwnode: Pointer to the given node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) * The function gets phy interface string from property 'phy-mode' or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) * 'phy-connection-type', and return its index in phy_modes table, or errno in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) * error case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) int fwnode_get_phy_mode(struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) const char *pm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) err = fwnode_property_read_string(fwnode, "phy-mode", &pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) err = fwnode_property_read_string(fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) "phy-connection-type", &pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (!strcasecmp(pm, phy_modes(i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) EXPORT_SYMBOL_GPL(fwnode_get_phy_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) * device_get_phy_mode - Get phy mode for given device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) * @dev: Pointer to the given device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) * The function gets phy interface string from property 'phy-mode' or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * 'phy-connection-type', and return its index in phy_modes table, or errno in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) * error case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) int device_get_phy_mode(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return fwnode_get_phy_mode(dev_fwnode(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) EXPORT_SYMBOL_GPL(device_get_phy_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) static void *fwnode_get_mac_addr(struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) const char *name, char *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) int alen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) int ret = fwnode_property_read_u8_array(fwnode, name, addr, alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (ret == 0 && alen == ETH_ALEN && is_valid_ether_addr(addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) return addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) * fwnode_get_mac_address - Get the MAC from the firmware node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) * @fwnode: Pointer to the firmware node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) * @addr: Address of buffer to store the MAC in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) * @alen: Length of the buffer pointed to by addr, should be ETH_ALEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) * Search the firmware node for the best MAC address to use. 'mac-address' is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) * checked first, because that is supposed to contain to "most recent" MAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) * address. If that isn't set, then 'local-mac-address' is checked next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) * because that is the default address. If that isn't set, then the obsolete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) * 'address' is checked, just in case we're using an old device tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) * Note that the 'address' property is supposed to contain a virtual address of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) * the register set, but some DTS files have redefined that property to be the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) * MAC address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) * All-zero MAC addresses are rejected, because those could be properties that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) * exist in the firmware tables, but were not updated by the firmware. For
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) * example, the DTS could define 'mac-address' and 'local-mac-address', with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) * zero MAC addresses. Some older U-Boots only initialized 'local-mac-address'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) * In this case, the real MAC is in 'local-mac-address', and 'mac-address'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) * exists but is all zeros.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) void *fwnode_get_mac_address(struct fwnode_handle *fwnode, char *addr, int alen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) char *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) res = fwnode_get_mac_addr(fwnode, "mac-address", addr, alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) res = fwnode_get_mac_addr(fwnode, "local-mac-address", addr, alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) return fwnode_get_mac_addr(fwnode, "address", addr, alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) EXPORT_SYMBOL(fwnode_get_mac_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) * device_get_mac_address - Get the MAC for a given device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) * @dev: Pointer to the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) * @addr: Address of buffer to store the MAC in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) * @alen: Length of the buffer pointed to by addr, should be ETH_ALEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) void *device_get_mac_address(struct device *dev, char *addr, int alen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) return fwnode_get_mac_address(dev_fwnode(dev), addr, alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) EXPORT_SYMBOL(device_get_mac_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) * fwnode_irq_get - Get IRQ directly from a fwnode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) * @fwnode: Pointer to the firmware node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) * @index: Zero-based index of the IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) * Returns Linux IRQ number on success. Other values are determined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) * accordingly to acpi_/of_ irq_get() operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) int fwnode_irq_get(struct fwnode_handle *fwnode, unsigned int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) struct device_node *of_node = to_of_node(fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) struct resource res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (IS_ENABLED(CONFIG_OF) && of_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return of_irq_get(of_node, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) ret = acpi_irq_get(ACPI_HANDLE_FWNODE(fwnode), index, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) return res.start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) EXPORT_SYMBOL(fwnode_irq_get);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) * fwnode_graph_get_next_endpoint - Get next endpoint firmware node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) * @fwnode: Pointer to the parent firmware node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) * @prev: Previous endpoint node or %NULL to get the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) * Returns an endpoint firmware node pointer or %NULL if no more endpoints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) * are available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) struct fwnode_handle *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) struct fwnode_handle *prev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) return fwnode_call_ptr_op(fwnode, graph_get_next_endpoint, prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) * fwnode_graph_get_port_parent - Return the device fwnode of a port endpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) * @endpoint: Endpoint firmware node of the port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) * Return: the firmware node of the device the @endpoint belongs to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) struct fwnode_handle *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) fwnode_graph_get_port_parent(const struct fwnode_handle *endpoint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) struct fwnode_handle *port, *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) port = fwnode_get_parent(endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) parent = fwnode_call_ptr_op(port, graph_get_port_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) fwnode_handle_put(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) return parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) EXPORT_SYMBOL_GPL(fwnode_graph_get_port_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) * fwnode_graph_get_remote_port_parent - Return fwnode of a remote device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) * @fwnode: Endpoint firmware node pointing to the remote endpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) * Extracts firmware node of a remote device the @fwnode points to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) struct fwnode_handle *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) fwnode_graph_get_remote_port_parent(const struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) struct fwnode_handle *endpoint, *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) endpoint = fwnode_graph_get_remote_endpoint(fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) parent = fwnode_graph_get_port_parent(endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) fwnode_handle_put(endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) return parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) * fwnode_graph_get_remote_port - Return fwnode of a remote port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) * @fwnode: Endpoint firmware node pointing to the remote endpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) * Extracts firmware node of a remote port the @fwnode points to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) struct fwnode_handle *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) fwnode_graph_get_remote_port(const struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) return fwnode_get_next_parent(fwnode_graph_get_remote_endpoint(fwnode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) * fwnode_graph_get_remote_endpoint - Return fwnode of a remote endpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) * @fwnode: Endpoint firmware node pointing to the remote endpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) * Extracts firmware node of a remote endpoint the @fwnode points to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) struct fwnode_handle *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) fwnode_graph_get_remote_endpoint(const struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) return fwnode_call_ptr_op(fwnode, graph_get_remote_endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) * fwnode_graph_get_remote_node - get remote parent node for given port/endpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) * @fwnode: pointer to parent fwnode_handle containing graph port/endpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) * @port_id: identifier of the parent port node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) * @endpoint_id: identifier of the endpoint node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) * Return: Remote fwnode handle associated with remote endpoint node linked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) * to @node. Use fwnode_node_put() on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) struct fwnode_handle *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) fwnode_graph_get_remote_node(const struct fwnode_handle *fwnode, u32 port_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) u32 endpoint_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) struct fwnode_handle *endpoint = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) while ((endpoint = fwnode_graph_get_next_endpoint(fwnode, endpoint))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) struct fwnode_endpoint fwnode_ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) struct fwnode_handle *remote;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) ret = fwnode_graph_parse_endpoint(endpoint, &fwnode_ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) if (fwnode_ep.port != port_id || fwnode_ep.id != endpoint_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) remote = fwnode_graph_get_remote_port_parent(endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) if (!remote)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) return fwnode_device_is_available(remote) ? remote : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) * fwnode_graph_get_endpoint_by_id - get endpoint by port and endpoint numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) * @fwnode: parent fwnode_handle containing the graph
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) * @port: identifier of the port node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) * @endpoint: identifier of the endpoint node under the port node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) * @flags: fwnode lookup flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) * Return the fwnode handle of the local endpoint corresponding the port and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) * endpoint IDs or NULL if not found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) * If FWNODE_GRAPH_ENDPOINT_NEXT is passed in @flags and the specified endpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) * has not been found, look for the closest endpoint ID greater than the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) * specified one and return the endpoint that corresponds to it, if present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) * Do not return endpoints that belong to disabled devices, unless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) * FWNODE_GRAPH_DEVICE_DISABLED is passed in @flags.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) * The returned endpoint needs to be released by calling fwnode_handle_put() on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) * it when it is not needed any more.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) struct fwnode_handle *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) fwnode_graph_get_endpoint_by_id(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) u32 port, u32 endpoint, unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) struct fwnode_handle *ep = NULL, *best_ep = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) unsigned int best_ep_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) bool endpoint_next = flags & FWNODE_GRAPH_ENDPOINT_NEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) bool enabled_only = !(flags & FWNODE_GRAPH_DEVICE_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) while ((ep = fwnode_graph_get_next_endpoint(fwnode, ep))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) struct fwnode_endpoint fwnode_ep = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) if (enabled_only) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) struct fwnode_handle *dev_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) bool available;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) dev_node = fwnode_graph_get_remote_port_parent(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) available = fwnode_device_is_available(dev_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) fwnode_handle_put(dev_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if (!available)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) ret = fwnode_graph_parse_endpoint(ep, &fwnode_ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if (fwnode_ep.port != port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (fwnode_ep.id == endpoint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) return ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) if (!endpoint_next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) * If the endpoint that has just been found is not the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) * matching one and the ID of the one found previously is closer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) * to the requested endpoint ID, skip it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) if (fwnode_ep.id < endpoint ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) (best_ep && best_ep_id < fwnode_ep.id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) fwnode_handle_put(best_ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) best_ep = fwnode_handle_get(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) best_ep_id = fwnode_ep.id;
^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) return best_ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) EXPORT_SYMBOL_GPL(fwnode_graph_get_endpoint_by_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) * fwnode_graph_parse_endpoint - parse common endpoint node properties
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) * @fwnode: pointer to endpoint fwnode_handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) * @endpoint: pointer to the fwnode endpoint data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) * Parse @fwnode representing a graph endpoint node and store the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) * information in @endpoint. The caller must hold a reference to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) * @fwnode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) struct fwnode_endpoint *endpoint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) memset(endpoint, 0, sizeof(*endpoint));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) return fwnode_call_int_op(fwnode, graph_parse_endpoint, endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) EXPORT_SYMBOL(fwnode_graph_parse_endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) const void *device_get_match_data(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) return fwnode_call_ptr_op(dev_fwnode(dev), device_get_match_data, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) EXPORT_SYMBOL_GPL(device_get_match_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) static void *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) fwnode_graph_devcon_match(struct fwnode_handle *fwnode, const char *con_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) void *data, devcon_match_fn_t match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) struct fwnode_handle *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) struct fwnode_handle *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) void *ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) fwnode_graph_for_each_endpoint(fwnode, ep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) node = fwnode_graph_get_remote_port_parent(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) if (!fwnode_device_is_available(node)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) fwnode_handle_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) ret = match(node, con_id, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) fwnode_handle_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) fwnode_handle_put(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) static void *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) fwnode_devcon_match(struct fwnode_handle *fwnode, const char *con_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) void *data, devcon_match_fn_t match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) struct fwnode_handle *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) void *ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) for (i = 0; ; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) node = fwnode_find_reference(fwnode, con_id, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) if (IS_ERR(node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) ret = match(node, NULL, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) fwnode_handle_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) * fwnode_connection_find_match - Find connection from a device node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) * @fwnode: Device node with the connection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) * @con_id: Identifier for the connection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) * @data: Data for the match function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) * @match: Function to check and convert the connection description
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) * Find a connection with unique identifier @con_id between @fwnode and another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) * device node. @match will be used to convert the connection description to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) * data the caller is expecting to be returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) void *fwnode_connection_find_match(struct fwnode_handle *fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) const char *con_id, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) devcon_match_fn_t match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) void *ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) if (!fwnode || !match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) ret = fwnode_graph_devcon_match(fwnode, con_id, data, match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) return fwnode_devcon_match(fwnode, con_id, data, match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) EXPORT_SYMBOL_GPL(fwnode_connection_find_match);