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