LCOV - code coverage report
Current view: top level - drivers/base - property.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 2 238 0.8 %
Date: 2022-12-09 01:23:36 Functions: 1 57 1.8 %

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

Generated by: LCOV version 1.14