blob: 5379eae478b1add7661dee3efedbc133c9001a9a [file] [log] [blame]
Greg Kroah-Hartman989d42e2017-11-07 17:30:07 +01001// SPDX-License-Identifier: GPL-2.0
Rafael J. Wysockib31384f2014-11-04 01:28:56 +01002/*
3 * property.c - Unified device property interface.
4 *
5 * Copyright (C) 2014, Intel Corporation
6 * Authors: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
7 * Mika Westerberg <mika.westerberg@linux.intel.com>
Rafael J. Wysockib31384f2014-11-04 01:28:56 +01008 */
9
Rafael J. Wysockib31384f2014-11-04 01:28:56 +010010#include <linux/acpi.h>
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020011#include <linux/export.h>
12#include <linux/kernel.h>
Rafael J. Wysockib31384f2014-11-04 01:28:56 +010013#include <linux/of.h>
Suthikulpanit, Suravee05ca5562015-06-10 11:08:54 -050014#include <linux/of_address.h>
Mika Westerberg07bb80d2017-03-28 10:52:21 +030015#include <linux/of_graph.h>
Marcin Wojtas7c6c57f2018-01-18 13:31:40 +010016#include <linux/of_irq.h>
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020017#include <linux/property.h>
Jeremy Linton4c96b7d2015-08-12 17:06:26 -050018#include <linux/phy.h>
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020019
Sakari Ailuse44bb0c2017-03-28 10:52:24 +030020struct fwnode_handle *dev_fwnode(struct device *dev)
Rafael J. Wysocki9017f252015-03-24 00:24:16 +010021{
22 return IS_ENABLED(CONFIG_OF) && dev->of_node ?
Andy Shevchenko3cd80152021-05-10 12:56:12 +030023 of_fwnode_handle(dev->of_node) : dev->fwnode;
Rafael J. Wysocki9017f252015-03-24 00:24:16 +010024}
Sakari Ailuse44bb0c2017-03-28 10:52:24 +030025EXPORT_SYMBOL_GPL(dev_fwnode);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +010026
27/**
28 * device_property_present - check if a property of a device is present
29 * @dev: Device whose property is being checked
30 * @propname: Name of the property
31 *
32 * Check if property @propname is present in the device firmware description.
33 */
34bool device_property_present(struct device *dev, const char *propname)
35{
Rafael J. Wysocki9017f252015-03-24 00:24:16 +010036 return fwnode_property_present(dev_fwnode(dev), propname);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +010037}
38EXPORT_SYMBOL_GPL(device_property_present);
39
Andy Shevchenko362c0b32015-11-30 17:11:36 +020040/**
41 * fwnode_property_present - check if a property of a firmware node is present
42 * @fwnode: Firmware node whose property to check
43 * @propname: Name of the property
44 */
Sakari Ailus37ba9832017-07-21 14:39:36 +030045bool fwnode_property_present(const struct fwnode_handle *fwnode,
46 const char *propname)
Andy Shevchenko362c0b32015-11-30 17:11:36 +020047{
48 bool ret;
49
Sakari Ailuse8158b482017-07-11 18:20:20 +030050 ret = fwnode_call_bool_op(fwnode, property_present, propname);
Heikki Krogerus0d67e0f2016-03-10 13:03:18 +020051 if (ret == false && !IS_ERR_OR_NULL(fwnode) &&
52 !IS_ERR_OR_NULL(fwnode->secondary))
Sakari Ailuse8158b482017-07-11 18:20:20 +030053 ret = fwnode_call_bool_op(fwnode->secondary, property_present,
Sakari Ailus37081842017-06-06 12:37:37 +030054 propname);
Andy Shevchenko362c0b32015-11-30 17:11:36 +020055 return ret;
56}
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +010057EXPORT_SYMBOL_GPL(fwnode_property_present);
58
Rafael J. Wysockib31384f2014-11-04 01:28:56 +010059/**
60 * device_property_read_u8_array - return a u8 array property of a device
61 * @dev: Device to get the property of
62 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +020063 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysockib31384f2014-11-04 01:28:56 +010064 * @nval: Size of the @val array
65 *
66 * Function reads an array of u8 properties with @propname from the device
67 * firmware description and stores them to @val if found.
68 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +020069 * Return: number of values if @val was %NULL,
70 * %0 if the property was found (success),
Rafael J. Wysockib31384f2014-11-04 01:28:56 +010071 * %-EINVAL if given arguments are not valid,
72 * %-ENODATA if the property does not have a value,
73 * %-EPROTO if the property is not an array of numbers,
74 * %-EOVERFLOW if the size of the property is not as expected.
Guenter Roeck4fa7508e2015-08-26 20:27:04 -070075 * %-ENXIO if no suitable firmware interface is present.
Rafael J. Wysockib31384f2014-11-04 01:28:56 +010076 */
77int device_property_read_u8_array(struct device *dev, const char *propname,
78 u8 *val, size_t nval)
79{
Rafael J. Wysocki9017f252015-03-24 00:24:16 +010080 return fwnode_property_read_u8_array(dev_fwnode(dev), propname, val, nval);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +010081}
82EXPORT_SYMBOL_GPL(device_property_read_u8_array);
83
84/**
85 * device_property_read_u16_array - return a u16 array property of a device
86 * @dev: Device to get the property of
87 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +020088 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysockib31384f2014-11-04 01:28:56 +010089 * @nval: Size of the @val array
90 *
91 * Function reads an array of u16 properties with @propname from the device
92 * firmware description and stores them to @val if found.
93 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +020094 * Return: number of values if @val was %NULL,
95 * %0 if the property was found (success),
Rafael J. Wysockib31384f2014-11-04 01:28:56 +010096 * %-EINVAL if given arguments are not valid,
97 * %-ENODATA if the property does not have a value,
98 * %-EPROTO if the property is not an array of numbers,
99 * %-EOVERFLOW if the size of the property is not as expected.
Guenter Roeck4fa7508e2015-08-26 20:27:04 -0700100 * %-ENXIO if no suitable firmware interface is present.
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100101 */
102int device_property_read_u16_array(struct device *dev, const char *propname,
103 u16 *val, size_t nval)
104{
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100105 return fwnode_property_read_u16_array(dev_fwnode(dev), propname, val, nval);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100106}
107EXPORT_SYMBOL_GPL(device_property_read_u16_array);
108
109/**
110 * device_property_read_u32_array - return a u32 array property of a device
111 * @dev: Device to get the property of
112 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200113 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100114 * @nval: Size of the @val array
115 *
116 * Function reads an array of u32 properties with @propname from the device
117 * firmware description and stores them to @val if found.
118 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200119 * Return: number of values if @val was %NULL,
120 * %0 if the property was found (success),
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100121 * %-EINVAL if given arguments are not valid,
122 * %-ENODATA if the property does not have a value,
123 * %-EPROTO if the property is not an array of numbers,
124 * %-EOVERFLOW if the size of the property is not as expected.
Guenter Roeck4fa7508e2015-08-26 20:27:04 -0700125 * %-ENXIO if no suitable firmware interface is present.
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100126 */
127int device_property_read_u32_array(struct device *dev, const char *propname,
128 u32 *val, size_t nval)
129{
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100130 return fwnode_property_read_u32_array(dev_fwnode(dev), propname, val, nval);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100131}
132EXPORT_SYMBOL_GPL(device_property_read_u32_array);
133
134/**
135 * device_property_read_u64_array - return a u64 array property of a device
136 * @dev: Device to get the property of
137 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200138 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100139 * @nval: Size of the @val array
140 *
141 * Function reads an array of u64 properties with @propname from the device
142 * firmware description and stores them to @val if found.
143 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200144 * Return: number of values if @val was %NULL,
145 * %0 if the property was found (success),
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100146 * %-EINVAL if given arguments are not valid,
147 * %-ENODATA if the property does not have a value,
148 * %-EPROTO if the property is not an array of numbers,
149 * %-EOVERFLOW if the size of the property is not as expected.
Guenter Roeck4fa7508e2015-08-26 20:27:04 -0700150 * %-ENXIO if no suitable firmware interface is present.
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100151 */
152int device_property_read_u64_array(struct device *dev, const char *propname,
153 u64 *val, size_t nval)
154{
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100155 return fwnode_property_read_u64_array(dev_fwnode(dev), propname, val, nval);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100156}
157EXPORT_SYMBOL_GPL(device_property_read_u64_array);
158
159/**
160 * device_property_read_string_array - return a string array property of device
161 * @dev: Device to get the property of
162 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200163 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100164 * @nval: Size of the @val array
165 *
166 * Function reads an array of string properties with @propname from the device
167 * firmware description and stores them to @val if found.
168 *
Sakari Ailusb0b027c2017-03-28 15:22:19 +0300169 * Return: number of values read on success if @val is non-NULL,
170 * number of values available on success if @val is NULL,
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100171 * %-EINVAL if given arguments are not valid,
172 * %-ENODATA if the property does not have a value,
173 * %-EPROTO or %-EILSEQ if the property is not an array of strings,
174 * %-EOVERFLOW if the size of the property is not as expected.
Guenter Roeck4fa7508e2015-08-26 20:27:04 -0700175 * %-ENXIO if no suitable firmware interface is present.
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100176 */
177int device_property_read_string_array(struct device *dev, const char *propname,
178 const char **val, size_t nval)
179{
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100180 return fwnode_property_read_string_array(dev_fwnode(dev), propname, val, nval);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100181}
182EXPORT_SYMBOL_GPL(device_property_read_string_array);
183
184/**
185 * device_property_read_string - return a string property of a device
186 * @dev: Device to get the property of
187 * @propname: Name of the property
188 * @val: The value is stored here
189 *
190 * Function reads property @propname from the device firmware description and
191 * stores the value into @val if found. The value is checked to be a string.
192 *
193 * Return: %0 if the property was found (success),
194 * %-EINVAL if given arguments are not valid,
195 * %-ENODATA if the property does not have a value,
196 * %-EPROTO or %-EILSEQ if the property type is not a string.
Guenter Roeck4fa7508e2015-08-26 20:27:04 -0700197 * %-ENXIO if no suitable firmware interface is present.
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100198 */
199int device_property_read_string(struct device *dev, const char *propname,
200 const char **val)
201{
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100202 return fwnode_property_read_string(dev_fwnode(dev), propname, val);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100203}
204EXPORT_SYMBOL_GPL(device_property_read_string);
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100205
Mika Westerberg3f5c8d32015-09-14 17:37:35 +0300206/**
207 * device_property_match_string - find a string in an array and return index
208 * @dev: Device to get the property of
209 * @propname: Name of the property holding the array
210 * @string: String to look for
211 *
212 * Find a given string in a string array and if it is found return the
213 * index back.
214 *
215 * Return: %0 if the property was found (success),
216 * %-EINVAL if given arguments are not valid,
217 * %-ENODATA if the property does not have a value,
218 * %-EPROTO if the property is not an array of strings,
219 * %-ENXIO if no suitable firmware interface is present.
220 */
221int device_property_match_string(struct device *dev, const char *propname,
222 const char *string)
223{
224 return fwnode_property_match_string(dev_fwnode(dev), propname, string);
225}
226EXPORT_SYMBOL_GPL(device_property_match_string);
227
Sakari Ailus37ba9832017-07-21 14:39:36 +0300228static int fwnode_property_read_int_array(const struct fwnode_handle *fwnode,
Sakari Ailus37081842017-06-06 12:37:37 +0300229 const char *propname,
230 unsigned int elem_size, void *val,
231 size_t nval)
232{
233 int ret;
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100234
Sakari Ailus37081842017-06-06 12:37:37 +0300235 ret = fwnode_call_int_op(fwnode, property_read_int_array, propname,
236 elem_size, val, nval);
237 if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) &&
238 !IS_ERR_OR_NULL(fwnode->secondary))
239 ret = fwnode_call_int_op(
240 fwnode->secondary, property_read_int_array, propname,
241 elem_size, val, nval);
Andy Shevchenko318a19712015-11-30 17:11:31 +0200242
Sakari Ailus37081842017-06-06 12:37:37 +0300243 return ret;
244}
Andy Shevchenko362c0b32015-11-30 17:11:36 +0200245
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100246/**
247 * fwnode_property_read_u8_array - return a u8 array property of firmware node
248 * @fwnode: Firmware node to get the property of
249 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200250 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100251 * @nval: Size of the @val array
252 *
253 * Read an array of u8 properties with @propname from @fwnode and stores them to
254 * @val if found.
255 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200256 * Return: number of values if @val was %NULL,
257 * %0 if the property was found (success),
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100258 * %-EINVAL if given arguments are not valid,
259 * %-ENODATA if the property does not have a value,
260 * %-EPROTO if the property is not an array of numbers,
261 * %-EOVERFLOW if the size of the property is not as expected,
262 * %-ENXIO if no suitable firmware interface is present.
263 */
Sakari Ailus37ba9832017-07-21 14:39:36 +0300264int fwnode_property_read_u8_array(const struct fwnode_handle *fwnode,
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100265 const char *propname, u8 *val, size_t nval)
266{
Sakari Ailus37081842017-06-06 12:37:37 +0300267 return fwnode_property_read_int_array(fwnode, propname, sizeof(u8),
268 val, nval);
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100269}
270EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array);
271
272/**
273 * fwnode_property_read_u16_array - return a u16 array property of firmware node
274 * @fwnode: Firmware node to get the property of
275 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200276 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100277 * @nval: Size of the @val array
278 *
279 * Read an array of u16 properties with @propname from @fwnode and store them to
280 * @val if found.
281 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200282 * Return: number of values if @val was %NULL,
283 * %0 if the property was found (success),
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100284 * %-EINVAL if given arguments are not valid,
285 * %-ENODATA if the property does not have a value,
286 * %-EPROTO if the property is not an array of numbers,
287 * %-EOVERFLOW if the size of the property is not as expected,
288 * %-ENXIO if no suitable firmware interface is present.
289 */
Sakari Ailus37ba9832017-07-21 14:39:36 +0300290int fwnode_property_read_u16_array(const struct fwnode_handle *fwnode,
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100291 const char *propname, u16 *val, size_t nval)
292{
Sakari Ailus37081842017-06-06 12:37:37 +0300293 return fwnode_property_read_int_array(fwnode, propname, sizeof(u16),
294 val, nval);
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100295}
296EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array);
297
298/**
299 * fwnode_property_read_u32_array - return a u32 array property of firmware node
300 * @fwnode: Firmware node to get the property of
301 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200302 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100303 * @nval: Size of the @val array
304 *
305 * Read an array of u32 properties with @propname from @fwnode store them to
306 * @val if found.
307 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200308 * Return: number of values if @val was %NULL,
309 * %0 if the property was found (success),
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100310 * %-EINVAL if given arguments are not valid,
311 * %-ENODATA if the property does not have a value,
312 * %-EPROTO if the property is not an array of numbers,
313 * %-EOVERFLOW if the size of the property is not as expected,
314 * %-ENXIO if no suitable firmware interface is present.
315 */
Sakari Ailus37ba9832017-07-21 14:39:36 +0300316int fwnode_property_read_u32_array(const struct fwnode_handle *fwnode,
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100317 const char *propname, u32 *val, size_t nval)
318{
Sakari Ailus37081842017-06-06 12:37:37 +0300319 return fwnode_property_read_int_array(fwnode, propname, sizeof(u32),
320 val, nval);
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100321}
322EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array);
323
324/**
325 * fwnode_property_read_u64_array - return a u64 array property firmware node
326 * @fwnode: Firmware node to get the property of
327 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200328 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100329 * @nval: Size of the @val array
330 *
331 * Read an array of u64 properties with @propname from @fwnode and store them to
332 * @val if found.
333 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200334 * Return: number of values if @val was %NULL,
335 * %0 if the property was found (success),
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100336 * %-EINVAL if given arguments are not valid,
337 * %-ENODATA if the property does not have a value,
338 * %-EPROTO if the property is not an array of numbers,
339 * %-EOVERFLOW if the size of the property is not as expected,
340 * %-ENXIO if no suitable firmware interface is present.
341 */
Sakari Ailus37ba9832017-07-21 14:39:36 +0300342int fwnode_property_read_u64_array(const struct fwnode_handle *fwnode,
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100343 const char *propname, u64 *val, size_t nval)
344{
Sakari Ailus37081842017-06-06 12:37:37 +0300345 return fwnode_property_read_int_array(fwnode, propname, sizeof(u64),
346 val, nval);
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100347}
348EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array);
349
350/**
351 * fwnode_property_read_string_array - return string array property of a node
352 * @fwnode: Firmware node to get the property of
353 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200354 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100355 * @nval: Size of the @val array
356 *
357 * Read an string list property @propname from the given firmware node and store
358 * them to @val if found.
359 *
Sakari Ailusb0b027c2017-03-28 15:22:19 +0300360 * Return: number of values read on success if @val is non-NULL,
361 * number of values available on success if @val is NULL,
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100362 * %-EINVAL if given arguments are not valid,
363 * %-ENODATA if the property does not have a value,
Sakari Ailus026b8212017-03-28 15:22:17 +0300364 * %-EPROTO or %-EILSEQ if the property is not an array of strings,
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100365 * %-EOVERFLOW if the size of the property is not as expected,
366 * %-ENXIO if no suitable firmware interface is present.
367 */
Sakari Ailus37ba9832017-07-21 14:39:36 +0300368int fwnode_property_read_string_array(const struct fwnode_handle *fwnode,
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100369 const char *propname, const char **val,
370 size_t nval)
371{
Andy Shevchenko362c0b32015-11-30 17:11:36 +0200372 int ret;
373
Sakari Ailus37081842017-06-06 12:37:37 +0300374 ret = fwnode_call_int_op(fwnode, property_read_string_array, propname,
375 val, nval);
Heikki Krogerus0d67e0f2016-03-10 13:03:18 +0200376 if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) &&
377 !IS_ERR_OR_NULL(fwnode->secondary))
Sakari Ailus37081842017-06-06 12:37:37 +0300378 ret = fwnode_call_int_op(fwnode->secondary,
379 property_read_string_array, propname,
380 val, nval);
Andy Shevchenko362c0b32015-11-30 17:11:36 +0200381 return ret;
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100382}
383EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
384
385/**
386 * fwnode_property_read_string - return a string property of a firmware node
387 * @fwnode: Firmware node to get the property of
388 * @propname: Name of the property
389 * @val: The value is stored here
390 *
391 * Read property @propname from the given firmware node and store the value into
392 * @val if found. The value is checked to be a string.
393 *
394 * Return: %0 if the property was found (success),
395 * %-EINVAL if given arguments are not valid,
396 * %-ENODATA if the property does not have a value,
397 * %-EPROTO or %-EILSEQ if the property is not a string,
398 * %-ENXIO if no suitable firmware interface is present.
399 */
Sakari Ailus37ba9832017-07-21 14:39:36 +0300400int fwnode_property_read_string(const struct fwnode_handle *fwnode,
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100401 const char *propname, const char **val)
402{
Sakari Ailuse4817472017-03-28 15:26:22 +0300403 int ret = fwnode_property_read_string_array(fwnode, propname, val, 1);
Andy Shevchenko362c0b32015-11-30 17:11:36 +0200404
Sakari Ailusb0b027c2017-03-28 15:22:19 +0300405 return ret < 0 ? ret : 0;
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100406}
407EXPORT_SYMBOL_GPL(fwnode_property_read_string);
408
409/**
Mika Westerberg3f5c8d32015-09-14 17:37:35 +0300410 * fwnode_property_match_string - find a string in an array and return index
411 * @fwnode: Firmware node to get the property of
412 * @propname: Name of the property holding the array
413 * @string: String to look for
414 *
415 * Find a given string in a string array and if it is found return the
416 * index back.
417 *
418 * Return: %0 if the property was found (success),
419 * %-EINVAL if given arguments are not valid,
420 * %-ENODATA if the property does not have a value,
421 * %-EPROTO if the property is not an array of strings,
422 * %-ENXIO if no suitable firmware interface is present.
423 */
Sakari Ailus37ba9832017-07-21 14:39:36 +0300424int fwnode_property_match_string(const struct fwnode_handle *fwnode,
Mika Westerberg3f5c8d32015-09-14 17:37:35 +0300425 const char *propname, const char *string)
426{
427 const char **values;
Andy Shevchenkoa7c1d0a2016-03-17 14:22:17 -0700428 int nval, ret;
Mika Westerberg3f5c8d32015-09-14 17:37:35 +0300429
430 nval = fwnode_property_read_string_array(fwnode, propname, NULL, 0);
431 if (nval < 0)
432 return nval;
433
Andy Shevchenkof6740c12015-12-29 13:07:50 +0200434 if (nval == 0)
435 return -ENODATA;
436
Mika Westerberg3f5c8d32015-09-14 17:37:35 +0300437 values = kcalloc(nval, sizeof(*values), GFP_KERNEL);
438 if (!values)
439 return -ENOMEM;
440
441 ret = fwnode_property_read_string_array(fwnode, propname, values, nval);
442 if (ret < 0)
443 goto out;
444
Andy Shevchenkoa7c1d0a2016-03-17 14:22:17 -0700445 ret = match_string(values, nval, string);
446 if (ret < 0)
447 ret = -ENODATA;
Mika Westerberg3f5c8d32015-09-14 17:37:35 +0300448out:
449 kfree(values);
450 return ret;
451}
452EXPORT_SYMBOL_GPL(fwnode_property_match_string);
453
Sakari Ailus3e3119d2017-07-21 15:11:49 +0300454/**
455 * fwnode_property_get_reference_args() - Find a reference with arguments
456 * @fwnode: Firmware node where to look for the reference
457 * @prop: The name of the property
458 * @nargs_prop: The name of the property telling the number of
459 * arguments in the referred node. NULL if @nargs is known,
460 * otherwise @nargs is ignored. Only relevant on OF.
461 * @nargs: Number of arguments. Ignored if @nargs_prop is non-NULL.
462 * @index: Index of the reference, from zero onwards.
463 * @args: Result structure with reference and integer arguments.
464 *
465 * Obtain a reference based on a named property in an fwnode, with
466 * integer arguments.
467 *
468 * Caller is responsible to call fwnode_handle_put() on the returned
469 * args->fwnode pointer.
470 *
Sakari Ailusc343bc22017-09-26 12:08:27 +0300471 * Returns: %0 on success
472 * %-ENOENT when the index is out of bounds, the index has an empty
473 * reference or the property was not found
474 * %-EINVAL on parse error
Sakari Ailus3e3119d2017-07-21 15:11:49 +0300475 */
476int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode,
477 const char *prop, const char *nargs_prop,
478 unsigned int nargs, unsigned int index,
479 struct fwnode_reference_args *args)
480{
481 return fwnode_call_int_op(fwnode, get_reference_args, prop, nargs_prop,
482 nargs, index, args);
483}
484EXPORT_SYMBOL_GPL(fwnode_property_get_reference_args);
485
Dmitry Torokhov2d479e12017-02-02 17:41:27 -0800486/**
Heikki Krogerus83b34af2019-05-31 17:15:39 +0300487 * fwnode_find_reference - Find named reference to a fwnode_handle
488 * @fwnode: Firmware node where to look for the reference
489 * @name: The name of the reference
490 * @index: Index of the reference
491 *
492 * @index can be used when the named reference holds a table of references.
493 *
494 * Returns pointer to the reference fwnode, or ERR_PTR. Caller is responsible to
495 * call fwnode_handle_put() on the returned fwnode pointer.
496 */
497struct fwnode_handle *fwnode_find_reference(const struct fwnode_handle *fwnode,
498 const char *name,
499 unsigned int index)
500{
501 struct fwnode_reference_args args;
502 int ret;
503
504 ret = fwnode_property_get_reference_args(fwnode, name, NULL, 0, index,
505 &args);
506 return ret ? ERR_PTR(ret) : args.fwnode;
507}
508EXPORT_SYMBOL_GPL(fwnode_find_reference);
509
510/**
Sakari Ailusbc0500c2019-10-03 15:32:12 +0300511 * fwnode_get_name - Return the name of a node
512 * @fwnode: The firmware node
513 *
514 * Returns a pointer to the node name.
515 */
516const char *fwnode_get_name(const struct fwnode_handle *fwnode)
517{
518 return fwnode_call_ptr_op(fwnode, get_name);
519}
Heikki Krogerus6fafbbe2020-03-02 16:53:51 +0300520EXPORT_SYMBOL_GPL(fwnode_get_name);
Sakari Ailusbc0500c2019-10-03 15:32:12 +0300521
522/**
Sakari Ailuse7e242b2019-10-03 15:32:13 +0300523 * fwnode_get_name_prefix - Return the prefix of node for printing purposes
524 * @fwnode: The firmware node
525 *
526 * Returns the prefix of a node, intended to be printed right before the node.
527 * The prefix works also as a separator between the nodes.
528 */
529const char *fwnode_get_name_prefix(const struct fwnode_handle *fwnode)
530{
531 return fwnode_call_ptr_op(fwnode, get_name_prefix);
532}
533
534/**
Sakari Ailusa57b7fb2019-10-03 15:32:10 +0300535 * fwnode_get_parent - Return parent firwmare node
536 * @fwnode: Firmware whose parent is retrieved
537 *
538 * Return parent firmware node of the given node if possible or %NULL if no
539 * parent was available.
540 */
541struct fwnode_handle *fwnode_get_parent(const struct fwnode_handle *fwnode)
542{
543 return fwnode_call_ptr_op(fwnode, get_parent);
544}
545EXPORT_SYMBOL_GPL(fwnode_get_parent);
546
547/**
Sakari Ailus23387252017-03-28 10:52:26 +0300548 * fwnode_get_next_parent - Iterate to the node's parent
549 * @fwnode: Firmware whose parent is retrieved
550 *
551 * This is like fwnode_get_parent() except that it drops the refcount
552 * on the passed node, making it suitable for iterating through a
553 * node's parents.
554 *
555 * Returns a node pointer with refcount incremented, use
556 * fwnode_handle_node() on it when done.
557 */
558struct fwnode_handle *fwnode_get_next_parent(struct fwnode_handle *fwnode)
559{
560 struct fwnode_handle *parent = fwnode_get_parent(fwnode);
561
562 fwnode_handle_put(fwnode);
563
564 return parent;
565}
566EXPORT_SYMBOL_GPL(fwnode_get_next_parent);
567
568/**
Saravana Kannanb5d3e2f2020-11-20 18:02:25 -0800569 * fwnode_get_next_parent_dev - Find device of closest ancestor fwnode
570 * @fwnode: firmware node
571 *
572 * Given a firmware node (@fwnode), this function finds its closest ancestor
573 * firmware node that has a corresponding struct device and returns that struct
574 * device.
575 *
576 * The caller of this function is expected to call put_device() on the returned
577 * device when they are done.
578 */
579struct device *fwnode_get_next_parent_dev(struct fwnode_handle *fwnode)
580{
Andy Shevchenko7e7ba9b2021-05-18 09:48:43 +0300581 struct device *dev;
Saravana Kannanb5d3e2f2020-11-20 18:02:25 -0800582
583 fwnode_handle_get(fwnode);
584 do {
585 fwnode = fwnode_get_next_parent(fwnode);
Andy Shevchenko7e7ba9b2021-05-18 09:48:43 +0300586 if (!fwnode)
587 return NULL;
588 dev = get_dev_from_fwnode(fwnode);
589 } while (!dev);
Saravana Kannanb5d3e2f2020-11-20 18:02:25 -0800590 fwnode_handle_put(fwnode);
591 return dev;
592}
593
594/**
Sakari Ailus87e5e952019-10-03 15:32:11 +0300595 * fwnode_count_parents - Return the number of parents a node has
596 * @fwnode: The node the parents of which are to be counted
597 *
598 * Returns the number of parents a node has.
599 */
600unsigned int fwnode_count_parents(const struct fwnode_handle *fwnode)
601{
602 struct fwnode_handle *__fwnode;
603 unsigned int count;
604
605 __fwnode = fwnode_get_parent(fwnode);
606
607 for (count = 0; __fwnode; count++)
608 __fwnode = fwnode_get_next_parent(__fwnode);
609
610 return count;
611}
612EXPORT_SYMBOL_GPL(fwnode_count_parents);
613
614/**
615 * fwnode_get_nth_parent - Return an nth parent of a node
616 * @fwnode: The node the parent of which is requested
617 * @depth: Distance of the parent from the node
618 *
619 * Returns the nth parent of a node. If there is no parent at the requested
620 * @depth, %NULL is returned. If @depth is 0, the functionality is equivalent to
621 * fwnode_handle_get(). For @depth == 1, it is fwnode_get_parent() and so on.
622 *
623 * The caller is responsible for calling fwnode_handle_put() for the returned
624 * node.
625 */
626struct fwnode_handle *fwnode_get_nth_parent(struct fwnode_handle *fwnode,
627 unsigned int depth)
628{
629 unsigned int i;
630
631 fwnode_handle_get(fwnode);
632
633 for (i = 0; i < depth && fwnode; i++)
634 fwnode = fwnode_get_next_parent(fwnode);
635
636 return fwnode;
637}
638EXPORT_SYMBOL_GPL(fwnode_get_nth_parent);
639
640/**
Saravana Kannanb5d3e2f2020-11-20 18:02:25 -0800641 * fwnode_is_ancestor_of - Test if @test_ancestor is ancestor of @test_child
642 * @test_ancestor: Firmware which is tested for being an ancestor
643 * @test_child: Firmware which is tested for being the child
644 *
645 * A node is considered an ancestor of itself too.
646 *
647 * Returns true if @test_ancestor is an ancestor of @test_child.
648 * Otherwise, returns false.
649 */
650bool fwnode_is_ancestor_of(struct fwnode_handle *test_ancestor,
651 struct fwnode_handle *test_child)
652{
653 if (!test_ancestor)
654 return false;
655
656 fwnode_handle_get(test_child);
657 while (test_child) {
658 if (test_child == test_ancestor) {
659 fwnode_handle_put(test_child);
660 return true;
661 }
662 test_child = fwnode_get_next_parent(test_child);
663 }
664 return false;
665}
666
667/**
Mika Westerberg34055192017-03-28 10:52:18 +0300668 * fwnode_get_next_child_node - Return the next child node handle for a node
669 * @fwnode: Firmware node to find the next child node for.
670 * @child: Handle to one of the node's child nodes or a %NULL handle.
671 */
Sakari Ailus37ba9832017-07-21 14:39:36 +0300672struct fwnode_handle *
673fwnode_get_next_child_node(const struct fwnode_handle *fwnode,
674 struct fwnode_handle *child)
Mika Westerberg34055192017-03-28 10:52:18 +0300675{
Sakari Ailus37081842017-06-06 12:37:37 +0300676 return fwnode_call_ptr_op(fwnode, get_next_child_node, child);
Mika Westerberg34055192017-03-28 10:52:18 +0300677}
678EXPORT_SYMBOL_GPL(fwnode_get_next_child_node);
679
680/**
Marcin Wojtas3395de96a2018-01-18 13:31:41 +0100681 * fwnode_get_next_available_child_node - Return the next
682 * available child node handle for a node
683 * @fwnode: Firmware node to find the next child node for.
684 * @child: Handle to one of the node's child nodes or a %NULL handle.
685 */
686struct fwnode_handle *
687fwnode_get_next_available_child_node(const struct fwnode_handle *fwnode,
688 struct fwnode_handle *child)
689{
690 struct fwnode_handle *next_child = child;
691
692 if (!fwnode)
693 return NULL;
694
695 do {
696 next_child = fwnode_get_next_child_node(fwnode, next_child);
Andy Shevchenko7e7ba9b2021-05-18 09:48:43 +0300697 if (!next_child)
698 return NULL;
699 } while (!fwnode_device_is_available(next_child));
Marcin Wojtas3395de96a2018-01-18 13:31:41 +0100700
701 return next_child;
702}
703EXPORT_SYMBOL_GPL(fwnode_get_next_available_child_node);
704
705/**
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100706 * device_get_next_child_node - Return the next child node handle for a device
707 * @dev: Device to find the next child node for.
708 * @child: Handle to one of the device's child nodes or a null handle.
709 */
710struct fwnode_handle *device_get_next_child_node(struct device *dev,
711 struct fwnode_handle *child)
712{
Andy Shevchenkofb38f312021-06-04 19:50:47 +0300713 const struct fwnode_handle *fwnode = dev_fwnode(dev);
714 struct fwnode_handle *next;
Mika Westerberg34055192017-03-28 10:52:18 +0300715
Andy Shevchenko114dbb42020-05-20 13:29:59 +0300716 /* Try to find a child in primary fwnode */
717 next = fwnode_get_next_child_node(fwnode, child);
718 if (next)
719 return next;
720
721 /* When no more children in primary, continue with secondary */
Andy Shevchenko29c4a542020-07-16 21:27:47 +0300722 if (fwnode && !IS_ERR_OR_NULL(fwnode->secondary))
Andy Shevchenko114dbb42020-05-20 13:29:59 +0300723 next = fwnode_get_next_child_node(fwnode->secondary, child);
724
725 return next;
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100726}
727EXPORT_SYMBOL_GPL(device_get_next_child_node);
728
729/**
Mika Westerberg21ea73f2017-03-28 10:52:19 +0300730 * fwnode_get_named_child_node - Return first matching named child node handle
731 * @fwnode: Firmware node to find the named child node for.
Adam Thomson613e9722016-06-21 18:50:20 +0100732 * @childname: String to match child node name against.
733 */
Sakari Ailus37ba9832017-07-21 14:39:36 +0300734struct fwnode_handle *
735fwnode_get_named_child_node(const struct fwnode_handle *fwnode,
736 const char *childname)
Adam Thomson613e9722016-06-21 18:50:20 +0100737{
Sakari Ailus37081842017-06-06 12:37:37 +0300738 return fwnode_call_ptr_op(fwnode, get_named_child_node, childname);
Adam Thomson613e9722016-06-21 18:50:20 +0100739}
Mika Westerberg21ea73f2017-03-28 10:52:19 +0300740EXPORT_SYMBOL_GPL(fwnode_get_named_child_node);
741
742/**
743 * device_get_named_child_node - Return first matching named child node handle
744 * @dev: Device to find the named child node for.
745 * @childname: String to match child node name against.
746 */
747struct fwnode_handle *device_get_named_child_node(struct device *dev,
748 const char *childname)
749{
750 return fwnode_get_named_child_node(dev_fwnode(dev), childname);
751}
Adam Thomson613e9722016-06-21 18:50:20 +0100752EXPORT_SYMBOL_GPL(device_get_named_child_node);
753
754/**
Sakari Ailuse7887c22017-03-28 10:52:22 +0300755 * fwnode_handle_get - Obtain a reference to a device node
756 * @fwnode: Pointer to the device node to obtain the reference to.
Sakari Ailuscf89a312017-09-19 12:39:11 +0300757 *
758 * Returns the fwnode handle.
Sakari Ailuse7887c22017-03-28 10:52:22 +0300759 */
Sakari Ailuscf89a312017-09-19 12:39:11 +0300760struct fwnode_handle *fwnode_handle_get(struct fwnode_handle *fwnode)
Sakari Ailuse7887c22017-03-28 10:52:22 +0300761{
Sakari Ailuscf89a312017-09-19 12:39:11 +0300762 if (!fwnode_has_op(fwnode, get))
763 return fwnode;
764
765 return fwnode_call_ptr_op(fwnode, get);
Sakari Ailuse7887c22017-03-28 10:52:22 +0300766}
767EXPORT_SYMBOL_GPL(fwnode_handle_get);
768
769/**
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100770 * fwnode_handle_put - Drop reference to a device node
771 * @fwnode: Pointer to the device node to drop the reference to.
772 *
773 * This has to be used when terminating device_for_each_child_node() iteration
774 * with break or return to prevent stale device node references from being left
775 * behind.
776 */
777void fwnode_handle_put(struct fwnode_handle *fwnode)
778{
Sakari Ailus37081842017-06-06 12:37:37 +0300779 fwnode_call_void_op(fwnode, put);
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100780}
781EXPORT_SYMBOL_GPL(fwnode_handle_put);
782
783/**
Sakari Ailus2294b3a2017-06-06 12:37:39 +0300784 * fwnode_device_is_available - check if a device is available for use
785 * @fwnode: Pointer to the fwnode of the device.
Daniel Scally52733822021-01-07 14:28:26 +0100786 *
787 * For fwnode node types that don't implement the .device_is_available()
788 * operation, this function returns true.
Sakari Ailus2294b3a2017-06-06 12:37:39 +0300789 */
Sakari Ailus37ba9832017-07-21 14:39:36 +0300790bool fwnode_device_is_available(const struct fwnode_handle *fwnode)
Sakari Ailus2294b3a2017-06-06 12:37:39 +0300791{
Daniel Scally52733822021-01-07 14:28:26 +0100792 if (!fwnode_has_op(fwnode, device_is_available))
793 return true;
794
Sakari Ailuse8158b482017-07-11 18:20:20 +0300795 return fwnode_call_bool_op(fwnode, device_is_available);
Sakari Ailus2294b3a2017-06-06 12:37:39 +0300796}
797EXPORT_SYMBOL_GPL(fwnode_device_is_available);
798
799/**
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100800 * device_get_child_node_count - return the number of child nodes for device
801 * @dev: Device to cound the child nodes for
802 */
803unsigned int device_get_child_node_count(struct device *dev)
804{
805 struct fwnode_handle *child;
806 unsigned int count = 0;
807
808 device_for_each_child_node(dev, child)
809 count++;
810
811 return count;
812}
813EXPORT_SYMBOL_GPL(device_get_child_node_count);
Suthikulpanit, Suravee05ca5562015-06-10 11:08:54 -0500814
Suthikulpanit, Suraveee5e55862015-10-28 15:50:49 -0700815bool device_dma_supported(struct device *dev)
816{
Andy Shevchenkofb38f312021-06-04 19:50:47 +0300817 const struct fwnode_handle *fwnode = dev_fwnode(dev);
818
Suthikulpanit, Suraveee5e55862015-10-28 15:50:49 -0700819 /* For DT, this is always supported.
820 * For ACPI, this depends on CCA, which
821 * is determined by the acpi_dma_supported().
822 */
Andy Shevchenkofb38f312021-06-04 19:50:47 +0300823 if (is_of_node(fwnode))
Suthikulpanit, Suraveee5e55862015-10-28 15:50:49 -0700824 return true;
825
Andy Shevchenkofb38f312021-06-04 19:50:47 +0300826 return acpi_dma_supported(to_acpi_device_node(fwnode));
Suthikulpanit, Suraveee5e55862015-10-28 15:50:49 -0700827}
828EXPORT_SYMBOL_GPL(device_dma_supported);
829
830enum dev_dma_attr device_get_dma_attr(struct device *dev)
831{
Andy Shevchenkofb38f312021-06-04 19:50:47 +0300832 const struct fwnode_handle *fwnode = dev_fwnode(dev);
Suthikulpanit, Suraveee5e55862015-10-28 15:50:49 -0700833 enum dev_dma_attr attr = DEV_DMA_NOT_SUPPORTED;
834
Andy Shevchenkofb38f312021-06-04 19:50:47 +0300835 if (is_of_node(fwnode)) {
836 if (of_dma_is_coherent(to_of_node(fwnode)))
Suthikulpanit, Suraveee5e55862015-10-28 15:50:49 -0700837 attr = DEV_DMA_COHERENT;
838 else
839 attr = DEV_DMA_NON_COHERENT;
840 } else
Andy Shevchenkofb38f312021-06-04 19:50:47 +0300841 attr = acpi_get_dma_attr(to_acpi_device_node(fwnode));
Suthikulpanit, Suraveee5e55862015-10-28 15:50:49 -0700842
843 return attr;
844}
845EXPORT_SYMBOL_GPL(device_get_dma_attr);
846
Jeremy Linton4c96b7d2015-08-12 17:06:26 -0500847/**
Marcin Wojtasb28f2632018-01-18 13:31:39 +0100848 * fwnode_get_phy_mode - Get phy mode for given firmware node
849 * @fwnode: Pointer to the given node
Jeremy Linton4c96b7d2015-08-12 17:06:26 -0500850 *
851 * The function gets phy interface string from property 'phy-mode' or
852 * 'phy-connection-type', and return its index in phy_modes table, or errno in
853 * error case.
854 */
Marcin Wojtasb28f2632018-01-18 13:31:39 +0100855int fwnode_get_phy_mode(struct fwnode_handle *fwnode)
Jeremy Linton4c96b7d2015-08-12 17:06:26 -0500856{
857 const char *pm;
858 int err, i;
859
Marcin Wojtasb28f2632018-01-18 13:31:39 +0100860 err = fwnode_property_read_string(fwnode, "phy-mode", &pm);
Jeremy Linton4c96b7d2015-08-12 17:06:26 -0500861 if (err < 0)
Marcin Wojtasb28f2632018-01-18 13:31:39 +0100862 err = fwnode_property_read_string(fwnode,
Jeremy Linton4c96b7d2015-08-12 17:06:26 -0500863 "phy-connection-type", &pm);
864 if (err < 0)
865 return err;
866
867 for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++)
868 if (!strcasecmp(pm, phy_modes(i)))
869 return i;
870
871 return -ENODEV;
872}
Marcin Wojtasb28f2632018-01-18 13:31:39 +0100873EXPORT_SYMBOL_GPL(fwnode_get_phy_mode);
874
875/**
876 * device_get_phy_mode - Get phy mode for given device
877 * @dev: Pointer to the given device
878 *
879 * The function gets phy interface string from property 'phy-mode' or
880 * 'phy-connection-type', and return its index in phy_modes table, or errno in
881 * error case.
882 */
883int device_get_phy_mode(struct device *dev)
884{
885 return fwnode_get_phy_mode(dev_fwnode(dev));
886}
Jeremy Linton4c96b7d2015-08-12 17:06:26 -0500887EXPORT_SYMBOL_GPL(device_get_phy_mode);
888
Mika Westerberg07bb80d2017-03-28 10:52:21 +0300889/**
Marcin Wojtas7c6c57f2018-01-18 13:31:40 +0100890 * fwnode_irq_get - Get IRQ directly from a fwnode
891 * @fwnode: Pointer to the firmware node
892 * @index: Zero-based index of the IRQ
893 *
894 * Returns Linux IRQ number on success. Other values are determined
895 * accordingly to acpi_/of_ irq_get() operation.
896 */
Andy Shevchenkofb38f312021-06-04 19:50:47 +0300897int fwnode_irq_get(const struct fwnode_handle *fwnode, unsigned int index)
Marcin Wojtas7c6c57f2018-01-18 13:31:40 +0100898{
Marcin Wojtas7c6c57f2018-01-18 13:31:40 +0100899 struct resource res;
900 int ret;
901
Andy Shevchenkofb38f312021-06-04 19:50:47 +0300902 if (is_of_node(fwnode))
903 return of_irq_get(to_of_node(fwnode), index);
Marcin Wojtas7c6c57f2018-01-18 13:31:40 +0100904
905 ret = acpi_irq_get(ACPI_HANDLE_FWNODE(fwnode), index, &res);
906 if (ret)
907 return ret;
908
909 return res.start;
910}
911EXPORT_SYMBOL(fwnode_irq_get);
912
913/**
Marco Felschf569da8c2018-12-18 16:52:39 +0100914 * fwnode_graph_get_next_endpoint - Get next endpoint firmware node
Mika Westerberg07bb80d2017-03-28 10:52:21 +0300915 * @fwnode: Pointer to the parent firmware node
916 * @prev: Previous endpoint node or %NULL to get the first
917 *
918 * Returns an endpoint firmware node pointer or %NULL if no more endpoints
919 * are available.
920 */
921struct fwnode_handle *
Sakari Ailus37ba9832017-07-21 14:39:36 +0300922fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode,
Mika Westerberg07bb80d2017-03-28 10:52:21 +0300923 struct fwnode_handle *prev)
924{
Daniel Scallyb5b41ab2021-08-06 23:09:05 +0100925 const struct fwnode_handle *parent;
926 struct fwnode_handle *ep;
927
928 /*
929 * If this function is in a loop and the previous iteration returned
930 * an endpoint from fwnode->secondary, then we need to use the secondary
931 * as parent rather than @fwnode.
932 */
933 if (prev)
934 parent = fwnode_graph_get_port_parent(prev);
935 else
936 parent = fwnode;
937
938 ep = fwnode_call_ptr_op(parent, graph_get_next_endpoint, prev);
939
940 if (IS_ERR_OR_NULL(ep) &&
941 !IS_ERR_OR_NULL(parent) && !IS_ERR_OR_NULL(parent->secondary))
942 ep = fwnode_graph_get_next_endpoint(parent->secondary, NULL);
943
944 return ep;
Mika Westerberg07bb80d2017-03-28 10:52:21 +0300945}
946EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint);
947
948/**
Kieran Bingham6a71d8d2017-06-06 12:37:41 +0300949 * fwnode_graph_get_port_parent - Return the device fwnode of a port endpoint
950 * @endpoint: Endpoint firmware node of the port
951 *
952 * Return: the firmware node of the device the @endpoint belongs to.
953 */
954struct fwnode_handle *
Sakari Ailus37ba9832017-07-21 14:39:36 +0300955fwnode_graph_get_port_parent(const struct fwnode_handle *endpoint)
Kieran Bingham6a71d8d2017-06-06 12:37:41 +0300956{
957 struct fwnode_handle *port, *parent;
958
959 port = fwnode_get_parent(endpoint);
960 parent = fwnode_call_ptr_op(port, graph_get_port_parent);
961
962 fwnode_handle_put(port);
963
964 return parent;
965}
966EXPORT_SYMBOL_GPL(fwnode_graph_get_port_parent);
967
968/**
Mika Westerberg07bb80d2017-03-28 10:52:21 +0300969 * fwnode_graph_get_remote_port_parent - Return fwnode of a remote device
970 * @fwnode: Endpoint firmware node pointing to the remote endpoint
971 *
972 * Extracts firmware node of a remote device the @fwnode points to.
973 */
974struct fwnode_handle *
Sakari Ailus37ba9832017-07-21 14:39:36 +0300975fwnode_graph_get_remote_port_parent(const struct fwnode_handle *fwnode)
Mika Westerberg07bb80d2017-03-28 10:52:21 +0300976{
Kieran Bingham6a71d8d2017-06-06 12:37:41 +0300977 struct fwnode_handle *endpoint, *parent;
Mika Westerberg07bb80d2017-03-28 10:52:21 +0300978
Kieran Bingham6a71d8d2017-06-06 12:37:41 +0300979 endpoint = fwnode_graph_get_remote_endpoint(fwnode);
980 parent = fwnode_graph_get_port_parent(endpoint);
Mika Westerberg07bb80d2017-03-28 10:52:21 +0300981
Kieran Bingham6a71d8d2017-06-06 12:37:41 +0300982 fwnode_handle_put(endpoint);
Mika Westerberg07bb80d2017-03-28 10:52:21 +0300983
984 return parent;
985}
986EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port_parent);
987
988/**
989 * fwnode_graph_get_remote_port - Return fwnode of a remote port
990 * @fwnode: Endpoint firmware node pointing to the remote endpoint
991 *
992 * Extracts firmware node of a remote port the @fwnode points to.
993 */
Sakari Ailus37ba9832017-07-21 14:39:36 +0300994struct fwnode_handle *
995fwnode_graph_get_remote_port(const struct fwnode_handle *fwnode)
Mika Westerberg07bb80d2017-03-28 10:52:21 +0300996{
Sakari Ailus3b27d002017-06-06 12:37:38 +0300997 return fwnode_get_next_parent(fwnode_graph_get_remote_endpoint(fwnode));
Mika Westerberg07bb80d2017-03-28 10:52:21 +0300998}
999EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port);
1000
1001/**
1002 * fwnode_graph_get_remote_endpoint - Return fwnode of a remote endpoint
1003 * @fwnode: Endpoint firmware node pointing to the remote endpoint
1004 *
1005 * Extracts firmware node of a remote endpoint the @fwnode points to.
1006 */
1007struct fwnode_handle *
Sakari Ailus37ba9832017-07-21 14:39:36 +03001008fwnode_graph_get_remote_endpoint(const struct fwnode_handle *fwnode)
Mika Westerberg07bb80d2017-03-28 10:52:21 +03001009{
Sakari Ailus3b27d002017-06-06 12:37:38 +03001010 return fwnode_call_ptr_op(fwnode, graph_get_remote_endpoint);
Mika Westerberg07bb80d2017-03-28 10:52:21 +03001011}
1012EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_endpoint);
Sakari Ailus2bd54522017-03-28 10:52:25 +03001013
Sakari Ailusc87b8fc2021-12-01 14:59:33 +02001014static bool fwnode_graph_remote_available(struct fwnode_handle *ep)
1015{
1016 struct fwnode_handle *dev_node;
1017 bool available;
1018
1019 dev_node = fwnode_graph_get_remote_port_parent(ep);
1020 available = fwnode_device_is_available(dev_node);
1021 fwnode_handle_put(dev_node);
1022
1023 return available;
1024}
1025
Sakari Ailus125ee6b2017-06-06 12:37:40 +03001026/**
Sakari Ailus0fcc2bd2019-04-02 13:30:37 +03001027 * fwnode_graph_get_endpoint_by_id - get endpoint by port and endpoint numbers
1028 * @fwnode: parent fwnode_handle containing the graph
1029 * @port: identifier of the port node
1030 * @endpoint: identifier of the endpoint node under the port node
1031 * @flags: fwnode lookup flags
1032 *
1033 * Return the fwnode handle of the local endpoint corresponding the port and
1034 * endpoint IDs or NULL if not found.
1035 *
1036 * If FWNODE_GRAPH_ENDPOINT_NEXT is passed in @flags and the specified endpoint
1037 * has not been found, look for the closest endpoint ID greater than the
1038 * specified one and return the endpoint that corresponds to it, if present.
1039 *
Sakari Ailus49f39cb2021-12-01 14:59:30 +02001040 * Does not return endpoints that belong to disabled devices or endpoints that
1041 * are unconnected, unless FWNODE_GRAPH_DEVICE_DISABLED is passed in @flags.
Sakari Ailus0fcc2bd2019-04-02 13:30:37 +03001042 *
1043 * The returned endpoint needs to be released by calling fwnode_handle_put() on
1044 * it when it is not needed any more.
1045 */
1046struct fwnode_handle *
1047fwnode_graph_get_endpoint_by_id(const struct fwnode_handle *fwnode,
1048 u32 port, u32 endpoint, unsigned long flags)
1049{
Sakari Ailus0d820172021-12-01 14:59:34 +02001050 struct fwnode_handle *ep, *best_ep = NULL;
Sakari Ailus0fcc2bd2019-04-02 13:30:37 +03001051 unsigned int best_ep_id = 0;
1052 bool endpoint_next = flags & FWNODE_GRAPH_ENDPOINT_NEXT;
1053 bool enabled_only = !(flags & FWNODE_GRAPH_DEVICE_DISABLED);
1054
Sakari Ailus0d820172021-12-01 14:59:34 +02001055 fwnode_graph_for_each_endpoint(fwnode, ep) {
Sakari Ailus0fcc2bd2019-04-02 13:30:37 +03001056 struct fwnode_endpoint fwnode_ep = { 0 };
1057 int ret;
1058
Sakari Ailusc87b8fc2021-12-01 14:59:33 +02001059 if (enabled_only && !fwnode_graph_remote_available(ep))
1060 continue;
Sakari Ailus0fcc2bd2019-04-02 13:30:37 +03001061
1062 ret = fwnode_graph_parse_endpoint(ep, &fwnode_ep);
1063 if (ret < 0)
1064 continue;
1065
1066 if (fwnode_ep.port != port)
1067 continue;
1068
1069 if (fwnode_ep.id == endpoint)
1070 return ep;
1071
1072 if (!endpoint_next)
1073 continue;
1074
1075 /*
1076 * If the endpoint that has just been found is not the first
1077 * matching one and the ID of the one found previously is closer
1078 * to the requested endpoint ID, skip it.
1079 */
1080 if (fwnode_ep.id < endpoint ||
1081 (best_ep && best_ep_id < fwnode_ep.id))
1082 continue;
1083
1084 fwnode_handle_put(best_ep);
1085 best_ep = fwnode_handle_get(ep);
1086 best_ep_id = fwnode_ep.id;
1087 }
1088
Daniel Scallya9088772021-08-06 23:09:06 +01001089 return best_ep;
Sakari Ailus0fcc2bd2019-04-02 13:30:37 +03001090}
1091EXPORT_SYMBOL_GPL(fwnode_graph_get_endpoint_by_id);
1092
1093/**
Sakari Ailusc87b8fc2021-12-01 14:59:33 +02001094 * fwnode_graph_get_endpoint_count - Count endpoints on a device node
1095 * @fwnode: The node related to a device
1096 * @flags: fwnode lookup flags
1097 * Count endpoints in a device node.
1098 *
1099 * If FWNODE_GRAPH_DEVICE_DISABLED flag is specified, also unconnected endpoints
1100 * and endpoints connected to disabled devices are counted.
1101 */
1102unsigned int fwnode_graph_get_endpoint_count(struct fwnode_handle *fwnode,
1103 unsigned long flags)
1104{
1105 struct fwnode_handle *ep;
1106 unsigned int count = 0;
1107
1108 fwnode_graph_for_each_endpoint(fwnode, ep) {
1109 if (flags & FWNODE_GRAPH_DEVICE_DISABLED ||
1110 fwnode_graph_remote_available(ep))
1111 count++;
1112 }
1113
1114 return count;
1115}
1116EXPORT_SYMBOL_GPL(fwnode_graph_get_endpoint_count);
1117
1118/**
Sakari Ailus2bd54522017-03-28 10:52:25 +03001119 * fwnode_graph_parse_endpoint - parse common endpoint node properties
1120 * @fwnode: pointer to endpoint fwnode_handle
1121 * @endpoint: pointer to the fwnode endpoint data structure
1122 *
1123 * Parse @fwnode representing a graph endpoint node and store the
1124 * information in @endpoint. The caller must hold a reference to
1125 * @fwnode.
1126 */
Sakari Ailus37ba9832017-07-21 14:39:36 +03001127int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
Sakari Ailus2bd54522017-03-28 10:52:25 +03001128 struct fwnode_endpoint *endpoint)
1129{
Sakari Ailus2bd54522017-03-28 10:52:25 +03001130 memset(endpoint, 0, sizeof(*endpoint));
1131
Sakari Ailus3b27d002017-06-06 12:37:38 +03001132 return fwnode_call_int_op(fwnode, graph_parse_endpoint, endpoint);
Sakari Ailus2bd54522017-03-28 10:52:25 +03001133}
1134EXPORT_SYMBOL(fwnode_graph_parse_endpoint);
Sinan Kayab283f152017-12-13 02:20:49 -05001135
Andy Shevchenko67dcc262018-02-09 17:38:36 +02001136const void *device_get_match_data(struct device *dev)
Sinan Kayab283f152017-12-13 02:20:49 -05001137{
Andy Shevchenko67dcc262018-02-09 17:38:36 +02001138 return fwnode_call_ptr_op(dev_fwnode(dev), device_get_match_data, dev);
Sinan Kayab283f152017-12-13 02:20:49 -05001139}
1140EXPORT_SYMBOL_GPL(device_get_match_data);
Heikki Krogerusd7cf5592020-09-07 15:05:31 +03001141
1142static void *
1143fwnode_graph_devcon_match(struct fwnode_handle *fwnode, const char *con_id,
1144 void *data, devcon_match_fn_t match)
1145{
1146 struct fwnode_handle *node;
1147 struct fwnode_handle *ep;
1148 void *ret;
1149
1150 fwnode_graph_for_each_endpoint(fwnode, ep) {
1151 node = fwnode_graph_get_remote_port_parent(ep);
Sakari Ailus4a7f4112021-12-01 14:59:29 +02001152 if (!fwnode_device_is_available(node)) {
1153 fwnode_handle_put(node);
Heikki Krogerusd7cf5592020-09-07 15:05:31 +03001154 continue;
Sakari Ailus4a7f4112021-12-01 14:59:29 +02001155 }
Heikki Krogerusd7cf5592020-09-07 15:05:31 +03001156
1157 ret = match(node, con_id, data);
1158 fwnode_handle_put(node);
1159 if (ret) {
1160 fwnode_handle_put(ep);
1161 return ret;
1162 }
1163 }
1164 return NULL;
1165}
1166
1167static void *
1168fwnode_devcon_match(struct fwnode_handle *fwnode, const char *con_id,
1169 void *data, devcon_match_fn_t match)
1170{
1171 struct fwnode_handle *node;
1172 void *ret;
1173 int i;
1174
1175 for (i = 0; ; i++) {
1176 node = fwnode_find_reference(fwnode, con_id, i);
1177 if (IS_ERR(node))
1178 break;
1179
1180 ret = match(node, NULL, data);
1181 fwnode_handle_put(node);
1182 if (ret)
1183 return ret;
1184 }
1185
1186 return NULL;
1187}
1188
1189/**
1190 * fwnode_connection_find_match - Find connection from a device node
1191 * @fwnode: Device node with the connection
1192 * @con_id: Identifier for the connection
1193 * @data: Data for the match function
1194 * @match: Function to check and convert the connection description
1195 *
1196 * Find a connection with unique identifier @con_id between @fwnode and another
1197 * device node. @match will be used to convert the connection description to
1198 * data the caller is expecting to be returned.
1199 */
1200void *fwnode_connection_find_match(struct fwnode_handle *fwnode,
1201 const char *con_id, void *data,
1202 devcon_match_fn_t match)
1203{
1204 void *ret;
1205
1206 if (!fwnode || !match)
1207 return NULL;
1208
1209 ret = fwnode_graph_devcon_match(fwnode, con_id, data, match);
1210 if (ret)
1211 return ret;
1212
1213 return fwnode_devcon_match(fwnode, con_id, data, match);
1214}
1215EXPORT_SYMBOL_GPL(fwnode_connection_find_match);