Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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);