blob: e6497f6877ee8282d7519933b4801644359e8c86 [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{
Daniel Scallyc097af12021-11-28 23:24:55 +0000481 int ret;
482
483 ret = fwnode_call_int_op(fwnode, get_reference_args, prop, nargs_prop,
484 nargs, index, args);
485
486 if (ret < 0 && !IS_ERR_OR_NULL(fwnode) &&
487 !IS_ERR_OR_NULL(fwnode->secondary))
488 ret = fwnode_call_int_op(fwnode->secondary, get_reference_args,
489 prop, nargs_prop, nargs, index, args);
490
491 return ret;
Sakari Ailus3e3119d2017-07-21 15:11:49 +0300492}
493EXPORT_SYMBOL_GPL(fwnode_property_get_reference_args);
494
Dmitry Torokhov2d479e12017-02-02 17:41:27 -0800495/**
Heikki Krogerus83b34af2019-05-31 17:15:39 +0300496 * fwnode_find_reference - Find named reference to a fwnode_handle
497 * @fwnode: Firmware node where to look for the reference
498 * @name: The name of the reference
499 * @index: Index of the reference
500 *
501 * @index can be used when the named reference holds a table of references.
502 *
503 * Returns pointer to the reference fwnode, or ERR_PTR. Caller is responsible to
504 * call fwnode_handle_put() on the returned fwnode pointer.
505 */
506struct fwnode_handle *fwnode_find_reference(const struct fwnode_handle *fwnode,
507 const char *name,
508 unsigned int index)
509{
510 struct fwnode_reference_args args;
511 int ret;
512
513 ret = fwnode_property_get_reference_args(fwnode, name, NULL, 0, index,
514 &args);
515 return ret ? ERR_PTR(ret) : args.fwnode;
516}
517EXPORT_SYMBOL_GPL(fwnode_find_reference);
518
519/**
Sakari Ailusbc0500c2019-10-03 15:32:12 +0300520 * fwnode_get_name - Return the name of a node
521 * @fwnode: The firmware node
522 *
523 * Returns a pointer to the node name.
524 */
525const char *fwnode_get_name(const struct fwnode_handle *fwnode)
526{
527 return fwnode_call_ptr_op(fwnode, get_name);
528}
Heikki Krogerus6fafbbe2020-03-02 16:53:51 +0300529EXPORT_SYMBOL_GPL(fwnode_get_name);
Sakari Ailusbc0500c2019-10-03 15:32:12 +0300530
531/**
Sakari Ailuse7e242b2019-10-03 15:32:13 +0300532 * fwnode_get_name_prefix - Return the prefix of node for printing purposes
533 * @fwnode: The firmware node
534 *
535 * Returns the prefix of a node, intended to be printed right before the node.
536 * The prefix works also as a separator between the nodes.
537 */
538const char *fwnode_get_name_prefix(const struct fwnode_handle *fwnode)
539{
540 return fwnode_call_ptr_op(fwnode, get_name_prefix);
541}
542
543/**
Sakari Ailusa57b7fb2019-10-03 15:32:10 +0300544 * fwnode_get_parent - Return parent firwmare node
545 * @fwnode: Firmware whose parent is retrieved
546 *
547 * Return parent firmware node of the given node if possible or %NULL if no
548 * parent was available.
549 */
550struct fwnode_handle *fwnode_get_parent(const struct fwnode_handle *fwnode)
551{
552 return fwnode_call_ptr_op(fwnode, get_parent);
553}
554EXPORT_SYMBOL_GPL(fwnode_get_parent);
555
556/**
Sakari Ailus23387252017-03-28 10:52:26 +0300557 * fwnode_get_next_parent - Iterate to the node's parent
558 * @fwnode: Firmware whose parent is retrieved
559 *
560 * This is like fwnode_get_parent() except that it drops the refcount
561 * on the passed node, making it suitable for iterating through a
562 * node's parents.
563 *
564 * Returns a node pointer with refcount incremented, use
565 * fwnode_handle_node() on it when done.
566 */
567struct fwnode_handle *fwnode_get_next_parent(struct fwnode_handle *fwnode)
568{
569 struct fwnode_handle *parent = fwnode_get_parent(fwnode);
570
571 fwnode_handle_put(fwnode);
572
573 return parent;
574}
575EXPORT_SYMBOL_GPL(fwnode_get_next_parent);
576
577/**
Saravana Kannanb5d3e2f2020-11-20 18:02:25 -0800578 * fwnode_get_next_parent_dev - Find device of closest ancestor fwnode
579 * @fwnode: firmware node
580 *
581 * Given a firmware node (@fwnode), this function finds its closest ancestor
582 * firmware node that has a corresponding struct device and returns that struct
583 * device.
584 *
585 * The caller of this function is expected to call put_device() on the returned
586 * device when they are done.
587 */
588struct device *fwnode_get_next_parent_dev(struct fwnode_handle *fwnode)
589{
Andy Shevchenko7e7ba9b2021-05-18 09:48:43 +0300590 struct device *dev;
Saravana Kannanb5d3e2f2020-11-20 18:02:25 -0800591
592 fwnode_handle_get(fwnode);
593 do {
594 fwnode = fwnode_get_next_parent(fwnode);
Andy Shevchenko7e7ba9b2021-05-18 09:48:43 +0300595 if (!fwnode)
596 return NULL;
597 dev = get_dev_from_fwnode(fwnode);
598 } while (!dev);
Saravana Kannanb5d3e2f2020-11-20 18:02:25 -0800599 fwnode_handle_put(fwnode);
600 return dev;
601}
602
603/**
Sakari Ailus87e5e952019-10-03 15:32:11 +0300604 * fwnode_count_parents - Return the number of parents a node has
605 * @fwnode: The node the parents of which are to be counted
606 *
607 * Returns the number of parents a node has.
608 */
609unsigned int fwnode_count_parents(const struct fwnode_handle *fwnode)
610{
611 struct fwnode_handle *__fwnode;
612 unsigned int count;
613
614 __fwnode = fwnode_get_parent(fwnode);
615
616 for (count = 0; __fwnode; count++)
617 __fwnode = fwnode_get_next_parent(__fwnode);
618
619 return count;
620}
621EXPORT_SYMBOL_GPL(fwnode_count_parents);
622
623/**
624 * fwnode_get_nth_parent - Return an nth parent of a node
625 * @fwnode: The node the parent of which is requested
626 * @depth: Distance of the parent from the node
627 *
628 * Returns the nth parent of a node. If there is no parent at the requested
629 * @depth, %NULL is returned. If @depth is 0, the functionality is equivalent to
630 * fwnode_handle_get(). For @depth == 1, it is fwnode_get_parent() and so on.
631 *
632 * The caller is responsible for calling fwnode_handle_put() for the returned
633 * node.
634 */
635struct fwnode_handle *fwnode_get_nth_parent(struct fwnode_handle *fwnode,
636 unsigned int depth)
637{
638 unsigned int i;
639
640 fwnode_handle_get(fwnode);
641
642 for (i = 0; i < depth && fwnode; i++)
643 fwnode = fwnode_get_next_parent(fwnode);
644
645 return fwnode;
646}
647EXPORT_SYMBOL_GPL(fwnode_get_nth_parent);
648
649/**
Saravana Kannanb5d3e2f2020-11-20 18:02:25 -0800650 * fwnode_is_ancestor_of - Test if @test_ancestor is ancestor of @test_child
651 * @test_ancestor: Firmware which is tested for being an ancestor
652 * @test_child: Firmware which is tested for being the child
653 *
654 * A node is considered an ancestor of itself too.
655 *
656 * Returns true if @test_ancestor is an ancestor of @test_child.
657 * Otherwise, returns false.
658 */
659bool fwnode_is_ancestor_of(struct fwnode_handle *test_ancestor,
660 struct fwnode_handle *test_child)
661{
662 if (!test_ancestor)
663 return false;
664
665 fwnode_handle_get(test_child);
666 while (test_child) {
667 if (test_child == test_ancestor) {
668 fwnode_handle_put(test_child);
669 return true;
670 }
671 test_child = fwnode_get_next_parent(test_child);
672 }
673 return false;
674}
675
676/**
Mika Westerberg34055192017-03-28 10:52:18 +0300677 * fwnode_get_next_child_node - Return the next child node handle for a node
678 * @fwnode: Firmware node to find the next child node for.
679 * @child: Handle to one of the node's child nodes or a %NULL handle.
680 */
Sakari Ailus37ba9832017-07-21 14:39:36 +0300681struct fwnode_handle *
682fwnode_get_next_child_node(const struct fwnode_handle *fwnode,
683 struct fwnode_handle *child)
Mika Westerberg34055192017-03-28 10:52:18 +0300684{
Sakari Ailus37081842017-06-06 12:37:37 +0300685 return fwnode_call_ptr_op(fwnode, get_next_child_node, child);
Mika Westerberg34055192017-03-28 10:52:18 +0300686}
687EXPORT_SYMBOL_GPL(fwnode_get_next_child_node);
688
689/**
Marcin Wojtas3395de96a2018-01-18 13:31:41 +0100690 * fwnode_get_next_available_child_node - Return the next
691 * available child node handle for a node
692 * @fwnode: Firmware node to find the next child node for.
693 * @child: Handle to one of the node's child nodes or a %NULL handle.
694 */
695struct fwnode_handle *
696fwnode_get_next_available_child_node(const struct fwnode_handle *fwnode,
697 struct fwnode_handle *child)
698{
699 struct fwnode_handle *next_child = child;
700
701 if (!fwnode)
702 return NULL;
703
704 do {
705 next_child = fwnode_get_next_child_node(fwnode, next_child);
Andy Shevchenko7e7ba9b2021-05-18 09:48:43 +0300706 if (!next_child)
707 return NULL;
708 } while (!fwnode_device_is_available(next_child));
Marcin Wojtas3395de96a2018-01-18 13:31:41 +0100709
710 return next_child;
711}
712EXPORT_SYMBOL_GPL(fwnode_get_next_available_child_node);
713
714/**
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100715 * device_get_next_child_node - Return the next child node handle for a device
716 * @dev: Device to find the next child node for.
717 * @child: Handle to one of the device's child nodes or a null handle.
718 */
719struct fwnode_handle *device_get_next_child_node(struct device *dev,
720 struct fwnode_handle *child)
721{
Andy Shevchenkofb38f312021-06-04 19:50:47 +0300722 const struct fwnode_handle *fwnode = dev_fwnode(dev);
723 struct fwnode_handle *next;
Mika Westerberg34055192017-03-28 10:52:18 +0300724
Andy Shevchenko114dbb42020-05-20 13:29:59 +0300725 /* Try to find a child in primary fwnode */
726 next = fwnode_get_next_child_node(fwnode, child);
727 if (next)
728 return next;
729
730 /* When no more children in primary, continue with secondary */
Andy Shevchenko29c4a542020-07-16 21:27:47 +0300731 if (fwnode && !IS_ERR_OR_NULL(fwnode->secondary))
Andy Shevchenko114dbb42020-05-20 13:29:59 +0300732 next = fwnode_get_next_child_node(fwnode->secondary, child);
733
734 return next;
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100735}
736EXPORT_SYMBOL_GPL(device_get_next_child_node);
737
738/**
Mika Westerberg21ea73f2017-03-28 10:52:19 +0300739 * fwnode_get_named_child_node - Return first matching named child node handle
740 * @fwnode: Firmware node to find the named child node for.
Adam Thomson613e9722016-06-21 18:50:20 +0100741 * @childname: String to match child node name against.
742 */
Sakari Ailus37ba9832017-07-21 14:39:36 +0300743struct fwnode_handle *
744fwnode_get_named_child_node(const struct fwnode_handle *fwnode,
745 const char *childname)
Adam Thomson613e9722016-06-21 18:50:20 +0100746{
Sakari Ailus37081842017-06-06 12:37:37 +0300747 return fwnode_call_ptr_op(fwnode, get_named_child_node, childname);
Adam Thomson613e9722016-06-21 18:50:20 +0100748}
Mika Westerberg21ea73f2017-03-28 10:52:19 +0300749EXPORT_SYMBOL_GPL(fwnode_get_named_child_node);
750
751/**
752 * device_get_named_child_node - Return first matching named child node handle
753 * @dev: Device to find the named child node for.
754 * @childname: String to match child node name against.
755 */
756struct fwnode_handle *device_get_named_child_node(struct device *dev,
757 const char *childname)
758{
759 return fwnode_get_named_child_node(dev_fwnode(dev), childname);
760}
Adam Thomson613e9722016-06-21 18:50:20 +0100761EXPORT_SYMBOL_GPL(device_get_named_child_node);
762
763/**
Sakari Ailuse7887c22017-03-28 10:52:22 +0300764 * fwnode_handle_get - Obtain a reference to a device node
765 * @fwnode: Pointer to the device node to obtain the reference to.
Sakari Ailuscf89a312017-09-19 12:39:11 +0300766 *
767 * Returns the fwnode handle.
Sakari Ailuse7887c22017-03-28 10:52:22 +0300768 */
Sakari Ailuscf89a312017-09-19 12:39:11 +0300769struct fwnode_handle *fwnode_handle_get(struct fwnode_handle *fwnode)
Sakari Ailuse7887c22017-03-28 10:52:22 +0300770{
Sakari Ailuscf89a312017-09-19 12:39:11 +0300771 if (!fwnode_has_op(fwnode, get))
772 return fwnode;
773
774 return fwnode_call_ptr_op(fwnode, get);
Sakari Ailuse7887c22017-03-28 10:52:22 +0300775}
776EXPORT_SYMBOL_GPL(fwnode_handle_get);
777
778/**
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100779 * fwnode_handle_put - Drop reference to a device node
780 * @fwnode: Pointer to the device node to drop the reference to.
781 *
782 * This has to be used when terminating device_for_each_child_node() iteration
783 * with break or return to prevent stale device node references from being left
784 * behind.
785 */
786void fwnode_handle_put(struct fwnode_handle *fwnode)
787{
Sakari Ailus37081842017-06-06 12:37:37 +0300788 fwnode_call_void_op(fwnode, put);
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100789}
790EXPORT_SYMBOL_GPL(fwnode_handle_put);
791
792/**
Sakari Ailus2294b3a2017-06-06 12:37:39 +0300793 * fwnode_device_is_available - check if a device is available for use
794 * @fwnode: Pointer to the fwnode of the device.
Daniel Scally52733822021-01-07 14:28:26 +0100795 *
796 * For fwnode node types that don't implement the .device_is_available()
797 * operation, this function returns true.
Sakari Ailus2294b3a2017-06-06 12:37:39 +0300798 */
Sakari Ailus37ba9832017-07-21 14:39:36 +0300799bool fwnode_device_is_available(const struct fwnode_handle *fwnode)
Sakari Ailus2294b3a2017-06-06 12:37:39 +0300800{
Daniel Scally52733822021-01-07 14:28:26 +0100801 if (!fwnode_has_op(fwnode, device_is_available))
802 return true;
803
Sakari Ailuse8158b482017-07-11 18:20:20 +0300804 return fwnode_call_bool_op(fwnode, device_is_available);
Sakari Ailus2294b3a2017-06-06 12:37:39 +0300805}
806EXPORT_SYMBOL_GPL(fwnode_device_is_available);
807
808/**
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100809 * device_get_child_node_count - return the number of child nodes for device
810 * @dev: Device to cound the child nodes for
811 */
812unsigned int device_get_child_node_count(struct device *dev)
813{
814 struct fwnode_handle *child;
815 unsigned int count = 0;
816
817 device_for_each_child_node(dev, child)
818 count++;
819
820 return count;
821}
822EXPORT_SYMBOL_GPL(device_get_child_node_count);
Suthikulpanit, Suravee05ca5562015-06-10 11:08:54 -0500823
Suthikulpanit, Suraveee5e55862015-10-28 15:50:49 -0700824bool device_dma_supported(struct device *dev)
825{
Andy Shevchenkofb38f312021-06-04 19:50:47 +0300826 const struct fwnode_handle *fwnode = dev_fwnode(dev);
827
Suthikulpanit, Suraveee5e55862015-10-28 15:50:49 -0700828 /* For DT, this is always supported.
829 * For ACPI, this depends on CCA, which
830 * is determined by the acpi_dma_supported().
831 */
Andy Shevchenkofb38f312021-06-04 19:50:47 +0300832 if (is_of_node(fwnode))
Suthikulpanit, Suraveee5e55862015-10-28 15:50:49 -0700833 return true;
834
Andy Shevchenkofb38f312021-06-04 19:50:47 +0300835 return acpi_dma_supported(to_acpi_device_node(fwnode));
Suthikulpanit, Suraveee5e55862015-10-28 15:50:49 -0700836}
837EXPORT_SYMBOL_GPL(device_dma_supported);
838
839enum dev_dma_attr device_get_dma_attr(struct device *dev)
840{
Andy Shevchenkofb38f312021-06-04 19:50:47 +0300841 const struct fwnode_handle *fwnode = dev_fwnode(dev);
Suthikulpanit, Suraveee5e55862015-10-28 15:50:49 -0700842 enum dev_dma_attr attr = DEV_DMA_NOT_SUPPORTED;
843
Andy Shevchenkofb38f312021-06-04 19:50:47 +0300844 if (is_of_node(fwnode)) {
845 if (of_dma_is_coherent(to_of_node(fwnode)))
Suthikulpanit, Suraveee5e55862015-10-28 15:50:49 -0700846 attr = DEV_DMA_COHERENT;
847 else
848 attr = DEV_DMA_NON_COHERENT;
849 } else
Andy Shevchenkofb38f312021-06-04 19:50:47 +0300850 attr = acpi_get_dma_attr(to_acpi_device_node(fwnode));
Suthikulpanit, Suraveee5e55862015-10-28 15:50:49 -0700851
852 return attr;
853}
854EXPORT_SYMBOL_GPL(device_get_dma_attr);
855
Jeremy Linton4c96b7d2015-08-12 17:06:26 -0500856/**
Marcin Wojtasb28f2632018-01-18 13:31:39 +0100857 * fwnode_get_phy_mode - Get phy mode for given firmware node
858 * @fwnode: Pointer to the given node
Jeremy Linton4c96b7d2015-08-12 17:06:26 -0500859 *
860 * The function gets phy interface string from property 'phy-mode' or
861 * 'phy-connection-type', and return its index in phy_modes table, or errno in
862 * error case.
863 */
Marcin Wojtasb28f2632018-01-18 13:31:39 +0100864int fwnode_get_phy_mode(struct fwnode_handle *fwnode)
Jeremy Linton4c96b7d2015-08-12 17:06:26 -0500865{
866 const char *pm;
867 int err, i;
868
Marcin Wojtasb28f2632018-01-18 13:31:39 +0100869 err = fwnode_property_read_string(fwnode, "phy-mode", &pm);
Jeremy Linton4c96b7d2015-08-12 17:06:26 -0500870 if (err < 0)
Marcin Wojtasb28f2632018-01-18 13:31:39 +0100871 err = fwnode_property_read_string(fwnode,
Jeremy Linton4c96b7d2015-08-12 17:06:26 -0500872 "phy-connection-type", &pm);
873 if (err < 0)
874 return err;
875
876 for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++)
877 if (!strcasecmp(pm, phy_modes(i)))
878 return i;
879
880 return -ENODEV;
881}
Marcin Wojtasb28f2632018-01-18 13:31:39 +0100882EXPORT_SYMBOL_GPL(fwnode_get_phy_mode);
883
884/**
885 * device_get_phy_mode - Get phy mode for given device
886 * @dev: Pointer to the given device
887 *
888 * The function gets phy interface string from property 'phy-mode' or
889 * 'phy-connection-type', and return its index in phy_modes table, or errno in
890 * error case.
891 */
892int device_get_phy_mode(struct device *dev)
893{
894 return fwnode_get_phy_mode(dev_fwnode(dev));
895}
Jeremy Linton4c96b7d2015-08-12 17:06:26 -0500896EXPORT_SYMBOL_GPL(device_get_phy_mode);
897
Mika Westerberg07bb80d2017-03-28 10:52:21 +0300898/**
Marcin Wojtas7c6c57f2018-01-18 13:31:40 +0100899 * fwnode_irq_get - Get IRQ directly from a fwnode
900 * @fwnode: Pointer to the firmware node
901 * @index: Zero-based index of the IRQ
902 *
903 * Returns Linux IRQ number on success. Other values are determined
904 * accordingly to acpi_/of_ irq_get() operation.
905 */
Andy Shevchenkofb38f312021-06-04 19:50:47 +0300906int fwnode_irq_get(const struct fwnode_handle *fwnode, unsigned int index)
Marcin Wojtas7c6c57f2018-01-18 13:31:40 +0100907{
Marcin Wojtas7c6c57f2018-01-18 13:31:40 +0100908 struct resource res;
909 int ret;
910
Andy Shevchenkofb38f312021-06-04 19:50:47 +0300911 if (is_of_node(fwnode))
912 return of_irq_get(to_of_node(fwnode), index);
Marcin Wojtas7c6c57f2018-01-18 13:31:40 +0100913
914 ret = acpi_irq_get(ACPI_HANDLE_FWNODE(fwnode), index, &res);
915 if (ret)
916 return ret;
917
918 return res.start;
919}
920EXPORT_SYMBOL(fwnode_irq_get);
921
922/**
Anand Ashok Dumbreeca6e2d2021-12-03 21:23:54 +0000923 * fwnode_iomap - Maps the memory mapped IO for a given fwnode
924 * @fwnode: Pointer to the firmware node
925 * @index: Index of the IO range
926 *
927 * Returns a pointer to the mapped memory.
928 */
929void __iomem *fwnode_iomap(struct fwnode_handle *fwnode, int index)
930{
931 if (IS_ENABLED(CONFIG_OF_ADDRESS) && is_of_node(fwnode))
932 return of_iomap(to_of_node(fwnode), index);
933
934 return NULL;
935}
936EXPORT_SYMBOL(fwnode_iomap);
937
938/**
Marco Felschf569da8c2018-12-18 16:52:39 +0100939 * fwnode_graph_get_next_endpoint - Get next endpoint firmware node
Mika Westerberg07bb80d2017-03-28 10:52:21 +0300940 * @fwnode: Pointer to the parent firmware node
941 * @prev: Previous endpoint node or %NULL to get the first
942 *
943 * Returns an endpoint firmware node pointer or %NULL if no more endpoints
944 * are available.
945 */
946struct fwnode_handle *
Sakari Ailus37ba9832017-07-21 14:39:36 +0300947fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode,
Mika Westerberg07bb80d2017-03-28 10:52:21 +0300948 struct fwnode_handle *prev)
949{
Daniel Scallyb5b41ab2021-08-06 23:09:05 +0100950 const struct fwnode_handle *parent;
951 struct fwnode_handle *ep;
952
953 /*
954 * If this function is in a loop and the previous iteration returned
955 * an endpoint from fwnode->secondary, then we need to use the secondary
956 * as parent rather than @fwnode.
957 */
958 if (prev)
959 parent = fwnode_graph_get_port_parent(prev);
960 else
961 parent = fwnode;
962
963 ep = fwnode_call_ptr_op(parent, graph_get_next_endpoint, prev);
964
965 if (IS_ERR_OR_NULL(ep) &&
966 !IS_ERR_OR_NULL(parent) && !IS_ERR_OR_NULL(parent->secondary))
967 ep = fwnode_graph_get_next_endpoint(parent->secondary, NULL);
968
969 return ep;
Mika Westerberg07bb80d2017-03-28 10:52:21 +0300970}
971EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint);
972
973/**
Kieran Bingham6a71d8d2017-06-06 12:37:41 +0300974 * fwnode_graph_get_port_parent - Return the device fwnode of a port endpoint
975 * @endpoint: Endpoint firmware node of the port
976 *
977 * Return: the firmware node of the device the @endpoint belongs to.
978 */
979struct fwnode_handle *
Sakari Ailus37ba9832017-07-21 14:39:36 +0300980fwnode_graph_get_port_parent(const struct fwnode_handle *endpoint)
Kieran Bingham6a71d8d2017-06-06 12:37:41 +0300981{
982 struct fwnode_handle *port, *parent;
983
984 port = fwnode_get_parent(endpoint);
985 parent = fwnode_call_ptr_op(port, graph_get_port_parent);
986
987 fwnode_handle_put(port);
988
989 return parent;
990}
991EXPORT_SYMBOL_GPL(fwnode_graph_get_port_parent);
992
993/**
Mika Westerberg07bb80d2017-03-28 10:52:21 +0300994 * fwnode_graph_get_remote_port_parent - Return fwnode of a remote device
995 * @fwnode: Endpoint firmware node pointing to the remote endpoint
996 *
997 * Extracts firmware node of a remote device the @fwnode points to.
998 */
999struct fwnode_handle *
Sakari Ailus37ba9832017-07-21 14:39:36 +03001000fwnode_graph_get_remote_port_parent(const struct fwnode_handle *fwnode)
Mika Westerberg07bb80d2017-03-28 10:52:21 +03001001{
Kieran Bingham6a71d8d2017-06-06 12:37:41 +03001002 struct fwnode_handle *endpoint, *parent;
Mika Westerberg07bb80d2017-03-28 10:52:21 +03001003
Kieran Bingham6a71d8d2017-06-06 12:37:41 +03001004 endpoint = fwnode_graph_get_remote_endpoint(fwnode);
1005 parent = fwnode_graph_get_port_parent(endpoint);
Mika Westerberg07bb80d2017-03-28 10:52:21 +03001006
Kieran Bingham6a71d8d2017-06-06 12:37:41 +03001007 fwnode_handle_put(endpoint);
Mika Westerberg07bb80d2017-03-28 10:52:21 +03001008
1009 return parent;
1010}
1011EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port_parent);
1012
1013/**
1014 * fwnode_graph_get_remote_port - Return fwnode of a remote port
1015 * @fwnode: Endpoint firmware node pointing to the remote endpoint
1016 *
1017 * Extracts firmware node of a remote port the @fwnode points to.
1018 */
Sakari Ailus37ba9832017-07-21 14:39:36 +03001019struct fwnode_handle *
1020fwnode_graph_get_remote_port(const struct fwnode_handle *fwnode)
Mika Westerberg07bb80d2017-03-28 10:52:21 +03001021{
Sakari Ailus3b27d002017-06-06 12:37:38 +03001022 return fwnode_get_next_parent(fwnode_graph_get_remote_endpoint(fwnode));
Mika Westerberg07bb80d2017-03-28 10:52:21 +03001023}
1024EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port);
1025
1026/**
1027 * fwnode_graph_get_remote_endpoint - Return fwnode of a remote endpoint
1028 * @fwnode: Endpoint firmware node pointing to the remote endpoint
1029 *
1030 * Extracts firmware node of a remote endpoint the @fwnode points to.
1031 */
1032struct fwnode_handle *
Sakari Ailus37ba9832017-07-21 14:39:36 +03001033fwnode_graph_get_remote_endpoint(const struct fwnode_handle *fwnode)
Mika Westerberg07bb80d2017-03-28 10:52:21 +03001034{
Sakari Ailus3b27d002017-06-06 12:37:38 +03001035 return fwnode_call_ptr_op(fwnode, graph_get_remote_endpoint);
Mika Westerberg07bb80d2017-03-28 10:52:21 +03001036}
1037EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_endpoint);
Sakari Ailus2bd54522017-03-28 10:52:25 +03001038
Sakari Ailusc87b8fc2021-12-01 14:59:33 +02001039static bool fwnode_graph_remote_available(struct fwnode_handle *ep)
1040{
1041 struct fwnode_handle *dev_node;
1042 bool available;
1043
1044 dev_node = fwnode_graph_get_remote_port_parent(ep);
1045 available = fwnode_device_is_available(dev_node);
1046 fwnode_handle_put(dev_node);
1047
1048 return available;
1049}
1050
Sakari Ailus125ee6b2017-06-06 12:37:40 +03001051/**
Sakari Ailus0fcc2bd2019-04-02 13:30:37 +03001052 * fwnode_graph_get_endpoint_by_id - get endpoint by port and endpoint numbers
1053 * @fwnode: parent fwnode_handle containing the graph
1054 * @port: identifier of the port node
1055 * @endpoint: identifier of the endpoint node under the port node
1056 * @flags: fwnode lookup flags
1057 *
1058 * Return the fwnode handle of the local endpoint corresponding the port and
1059 * endpoint IDs or NULL if not found.
1060 *
1061 * If FWNODE_GRAPH_ENDPOINT_NEXT is passed in @flags and the specified endpoint
1062 * has not been found, look for the closest endpoint ID greater than the
1063 * specified one and return the endpoint that corresponds to it, if present.
1064 *
Sakari Ailus49f39cb2021-12-01 14:59:30 +02001065 * Does not return endpoints that belong to disabled devices or endpoints that
1066 * are unconnected, unless FWNODE_GRAPH_DEVICE_DISABLED is passed in @flags.
Sakari Ailus0fcc2bd2019-04-02 13:30:37 +03001067 *
1068 * The returned endpoint needs to be released by calling fwnode_handle_put() on
1069 * it when it is not needed any more.
1070 */
1071struct fwnode_handle *
1072fwnode_graph_get_endpoint_by_id(const struct fwnode_handle *fwnode,
1073 u32 port, u32 endpoint, unsigned long flags)
1074{
Sakari Ailus0d820172021-12-01 14:59:34 +02001075 struct fwnode_handle *ep, *best_ep = NULL;
Sakari Ailus0fcc2bd2019-04-02 13:30:37 +03001076 unsigned int best_ep_id = 0;
1077 bool endpoint_next = flags & FWNODE_GRAPH_ENDPOINT_NEXT;
1078 bool enabled_only = !(flags & FWNODE_GRAPH_DEVICE_DISABLED);
1079
Sakari Ailus0d820172021-12-01 14:59:34 +02001080 fwnode_graph_for_each_endpoint(fwnode, ep) {
Sakari Ailus0fcc2bd2019-04-02 13:30:37 +03001081 struct fwnode_endpoint fwnode_ep = { 0 };
1082 int ret;
1083
Sakari Ailusc87b8fc2021-12-01 14:59:33 +02001084 if (enabled_only && !fwnode_graph_remote_available(ep))
1085 continue;
Sakari Ailus0fcc2bd2019-04-02 13:30:37 +03001086
1087 ret = fwnode_graph_parse_endpoint(ep, &fwnode_ep);
1088 if (ret < 0)
1089 continue;
1090
1091 if (fwnode_ep.port != port)
1092 continue;
1093
1094 if (fwnode_ep.id == endpoint)
1095 return ep;
1096
1097 if (!endpoint_next)
1098 continue;
1099
1100 /*
1101 * If the endpoint that has just been found is not the first
1102 * matching one and the ID of the one found previously is closer
1103 * to the requested endpoint ID, skip it.
1104 */
1105 if (fwnode_ep.id < endpoint ||
1106 (best_ep && best_ep_id < fwnode_ep.id))
1107 continue;
1108
1109 fwnode_handle_put(best_ep);
1110 best_ep = fwnode_handle_get(ep);
1111 best_ep_id = fwnode_ep.id;
1112 }
1113
Daniel Scallya9088772021-08-06 23:09:06 +01001114 return best_ep;
Sakari Ailus0fcc2bd2019-04-02 13:30:37 +03001115}
1116EXPORT_SYMBOL_GPL(fwnode_graph_get_endpoint_by_id);
1117
1118/**
Sakari Ailusc87b8fc2021-12-01 14:59:33 +02001119 * fwnode_graph_get_endpoint_count - Count endpoints on a device node
1120 * @fwnode: The node related to a device
1121 * @flags: fwnode lookup flags
1122 * Count endpoints in a device node.
1123 *
1124 * If FWNODE_GRAPH_DEVICE_DISABLED flag is specified, also unconnected endpoints
1125 * and endpoints connected to disabled devices are counted.
1126 */
1127unsigned int fwnode_graph_get_endpoint_count(struct fwnode_handle *fwnode,
1128 unsigned long flags)
1129{
1130 struct fwnode_handle *ep;
1131 unsigned int count = 0;
1132
1133 fwnode_graph_for_each_endpoint(fwnode, ep) {
1134 if (flags & FWNODE_GRAPH_DEVICE_DISABLED ||
1135 fwnode_graph_remote_available(ep))
1136 count++;
1137 }
1138
1139 return count;
1140}
1141EXPORT_SYMBOL_GPL(fwnode_graph_get_endpoint_count);
1142
1143/**
Sakari Ailus2bd54522017-03-28 10:52:25 +03001144 * fwnode_graph_parse_endpoint - parse common endpoint node properties
1145 * @fwnode: pointer to endpoint fwnode_handle
1146 * @endpoint: pointer to the fwnode endpoint data structure
1147 *
1148 * Parse @fwnode representing a graph endpoint node and store the
1149 * information in @endpoint. The caller must hold a reference to
1150 * @fwnode.
1151 */
Sakari Ailus37ba9832017-07-21 14:39:36 +03001152int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
Sakari Ailus2bd54522017-03-28 10:52:25 +03001153 struct fwnode_endpoint *endpoint)
1154{
Sakari Ailus2bd54522017-03-28 10:52:25 +03001155 memset(endpoint, 0, sizeof(*endpoint));
1156
Sakari Ailus3b27d002017-06-06 12:37:38 +03001157 return fwnode_call_int_op(fwnode, graph_parse_endpoint, endpoint);
Sakari Ailus2bd54522017-03-28 10:52:25 +03001158}
1159EXPORT_SYMBOL(fwnode_graph_parse_endpoint);
Sinan Kayab283f152017-12-13 02:20:49 -05001160
Andy Shevchenko67dcc262018-02-09 17:38:36 +02001161const void *device_get_match_data(struct device *dev)
Sinan Kayab283f152017-12-13 02:20:49 -05001162{
Andy Shevchenko67dcc262018-02-09 17:38:36 +02001163 return fwnode_call_ptr_op(dev_fwnode(dev), device_get_match_data, dev);
Sinan Kayab283f152017-12-13 02:20:49 -05001164}
1165EXPORT_SYMBOL_GPL(device_get_match_data);
Heikki Krogerusd7cf5592020-09-07 15:05:31 +03001166
1167static void *
1168fwnode_graph_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 struct fwnode_handle *ep;
1173 void *ret;
1174
1175 fwnode_graph_for_each_endpoint(fwnode, ep) {
1176 node = fwnode_graph_get_remote_port_parent(ep);
Sakari Ailus4a7f4112021-12-01 14:59:29 +02001177 if (!fwnode_device_is_available(node)) {
1178 fwnode_handle_put(node);
Heikki Krogerusd7cf5592020-09-07 15:05:31 +03001179 continue;
Sakari Ailus4a7f4112021-12-01 14:59:29 +02001180 }
Heikki Krogerusd7cf5592020-09-07 15:05:31 +03001181
1182 ret = match(node, con_id, data);
1183 fwnode_handle_put(node);
1184 if (ret) {
1185 fwnode_handle_put(ep);
1186 return ret;
1187 }
1188 }
1189 return NULL;
1190}
1191
1192static void *
1193fwnode_devcon_match(struct fwnode_handle *fwnode, const char *con_id,
1194 void *data, devcon_match_fn_t match)
1195{
1196 struct fwnode_handle *node;
1197 void *ret;
1198 int i;
1199
1200 for (i = 0; ; i++) {
1201 node = fwnode_find_reference(fwnode, con_id, i);
1202 if (IS_ERR(node))
1203 break;
1204
1205 ret = match(node, NULL, data);
1206 fwnode_handle_put(node);
1207 if (ret)
1208 return ret;
1209 }
1210
1211 return NULL;
1212}
1213
1214/**
1215 * fwnode_connection_find_match - Find connection from a device node
1216 * @fwnode: Device node with the connection
1217 * @con_id: Identifier for the connection
1218 * @data: Data for the match function
1219 * @match: Function to check and convert the connection description
1220 *
1221 * Find a connection with unique identifier @con_id between @fwnode and another
1222 * device node. @match will be used to convert the connection description to
1223 * data the caller is expecting to be returned.
1224 */
1225void *fwnode_connection_find_match(struct fwnode_handle *fwnode,
1226 const char *con_id, void *data,
1227 devcon_match_fn_t match)
1228{
1229 void *ret;
1230
1231 if (!fwnode || !match)
1232 return NULL;
1233
1234 ret = fwnode_graph_devcon_match(fwnode, con_id, data, match);
1235 if (ret)
1236 return ret;
1237
1238 return fwnode_devcon_match(fwnode, con_id, data, match);
1239}
1240EXPORT_SYMBOL_GPL(fwnode_connection_find_match);