LCOV - code coverage report
Current view: top level - drivers/base - property.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 2 262 0.8 %
Date: 2023-08-24 13:40:31 Functions: 1 59 1.7 %

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

Generated by: LCOV version 1.14