LCOV - code coverage report
Current view: top level - drivers/base - property.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 5 260 1.9 %
Date: 2023-04-06 08:38:28 Functions: 2 59 3.4 %

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

Generated by: LCOV version 1.14