blob: 149de311a10e63fc9636401771365684985f18a3 [file] [log] [blame]
Rafael J. Wysockib31384f2014-11-04 01:28:56 +01001/*
2 * property.c - Unified device property interface.
3 *
4 * Copyright (C) 2014, Intel Corporation
5 * Authors: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
6 * Mika Westerberg <mika.westerberg@linux.intel.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
Rafael J. Wysockib31384f2014-11-04 01:28:56 +010013#include <linux/acpi.h>
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020014#include <linux/export.h>
15#include <linux/kernel.h>
Rafael J. Wysockib31384f2014-11-04 01:28:56 +010016#include <linux/of.h>
Suthikulpanit, Suravee05ca5562015-06-10 11:08:54 -050017#include <linux/of_address.h>
Mika Westerberg07bb80d2017-03-28 10:52:21 +030018#include <linux/of_graph.h>
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020019#include <linux/property.h>
Jeremy Linton4c96b7d2015-08-12 17:06:26 -050020#include <linux/etherdevice.h>
21#include <linux/phy.h>
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020022
Heikki Krogerusf4d05262016-03-29 14:52:23 +030023struct property_set {
24 struct fwnode_handle fwnode;
Dmitry Torokhovbec84da2017-02-02 17:41:25 -080025 const struct property_entry *properties;
Heikki Krogerusf4d05262016-03-29 14:52:23 +030026};
27
Andy Shevchenko61f5e292015-11-30 17:11:30 +020028static inline bool is_pset_node(struct fwnode_handle *fwnode)
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020029{
Heikki Krogerus0224a4a2016-04-27 14:04:20 +030030 return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_PDATA;
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020031}
32
Andy Shevchenko61f5e292015-11-30 17:11:30 +020033static inline struct property_set *to_pset_node(struct fwnode_handle *fwnode)
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020034{
Andy Shevchenko61f5e292015-11-30 17:11:30 +020035 return is_pset_node(fwnode) ?
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020036 container_of(fwnode, struct property_set, fwnode) : NULL;
37}
38
Dmitry Torokhovbec84da2017-02-02 17:41:25 -080039static const struct property_entry *pset_prop_get(struct property_set *pset,
40 const char *name)
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020041{
Dmitry Torokhovbec84da2017-02-02 17:41:25 -080042 const struct property_entry *prop;
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020043
44 if (!pset || !pset->properties)
45 return NULL;
46
47 for (prop = pset->properties; prop->name; prop++)
48 if (!strcmp(name, prop->name))
49 return prop;
50
51 return NULL;
52}
53
Dmitry Torokhovbec84da2017-02-02 17:41:25 -080054static const void *pset_prop_find(struct property_set *pset,
55 const char *propname, size_t length)
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020056{
Dmitry Torokhovbec84da2017-02-02 17:41:25 -080057 const struct property_entry *prop;
58 const void *pointer;
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020059
Andy Shevchenko318a19712015-11-30 17:11:31 +020060 prop = pset_prop_get(pset, propname);
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020061 if (!prop)
Andy Shevchenko318a19712015-11-30 17:11:31 +020062 return ERR_PTR(-EINVAL);
Andy Shevchenko66586ba2015-11-30 17:11:32 +020063 if (prop->is_array)
64 pointer = prop->pointer.raw_data;
65 else
66 pointer = &prop->value.raw_data;
Andy Shevchenko318a19712015-11-30 17:11:31 +020067 if (!pointer)
68 return ERR_PTR(-ENODATA);
69 if (length > prop->length)
70 return ERR_PTR(-EOVERFLOW);
71 return pointer;
72}
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020073
Andy Shevchenko318a19712015-11-30 17:11:31 +020074static int pset_prop_read_u8_array(struct property_set *pset,
75 const char *propname,
76 u8 *values, size_t nval)
77{
Dmitry Torokhovbec84da2017-02-02 17:41:25 -080078 const void *pointer;
Andy Shevchenko318a19712015-11-30 17:11:31 +020079 size_t length = nval * sizeof(*values);
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020080
Andy Shevchenko318a19712015-11-30 17:11:31 +020081 pointer = pset_prop_find(pset, propname, length);
82 if (IS_ERR(pointer))
83 return PTR_ERR(pointer);
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020084
Andy Shevchenko318a19712015-11-30 17:11:31 +020085 memcpy(values, pointer, length);
86 return 0;
87}
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020088
Andy Shevchenko318a19712015-11-30 17:11:31 +020089static int pset_prop_read_u16_array(struct property_set *pset,
90 const char *propname,
91 u16 *values, size_t nval)
92{
Dmitry Torokhovbec84da2017-02-02 17:41:25 -080093 const void *pointer;
Andy Shevchenko318a19712015-11-30 17:11:31 +020094 size_t length = nval * sizeof(*values);
95
96 pointer = pset_prop_find(pset, propname, length);
97 if (IS_ERR(pointer))
98 return PTR_ERR(pointer);
99
100 memcpy(values, pointer, length);
101 return 0;
102}
103
104static int pset_prop_read_u32_array(struct property_set *pset,
105 const char *propname,
106 u32 *values, size_t nval)
107{
Dmitry Torokhovbec84da2017-02-02 17:41:25 -0800108 const void *pointer;
Andy Shevchenko318a19712015-11-30 17:11:31 +0200109 size_t length = nval * sizeof(*values);
110
111 pointer = pset_prop_find(pset, propname, length);
112 if (IS_ERR(pointer))
113 return PTR_ERR(pointer);
114
115 memcpy(values, pointer, length);
116 return 0;
117}
118
119static int pset_prop_read_u64_array(struct property_set *pset,
120 const char *propname,
121 u64 *values, size_t nval)
122{
Dmitry Torokhovbec84da2017-02-02 17:41:25 -0800123 const void *pointer;
Andy Shevchenko318a19712015-11-30 17:11:31 +0200124 size_t length = nval * sizeof(*values);
125
126 pointer = pset_prop_find(pset, propname, length);
127 if (IS_ERR(pointer))
128 return PTR_ERR(pointer);
129
130 memcpy(values, pointer, length);
131 return 0;
132}
133
134static int pset_prop_count_elems_of_size(struct property_set *pset,
135 const char *propname, size_t length)
136{
Dmitry Torokhovbec84da2017-02-02 17:41:25 -0800137 const struct property_entry *prop;
Andy Shevchenko318a19712015-11-30 17:11:31 +0200138
139 prop = pset_prop_get(pset, propname);
140 if (!prop)
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +0200141 return -EINVAL;
Andy Shevchenko318a19712015-11-30 17:11:31 +0200142
143 return prop->length / length;
144}
145
146static int pset_prop_read_string_array(struct property_set *pset,
147 const char *propname,
148 const char **strings, size_t nval)
149{
Sakari Ailus0f194992017-03-28 15:22:18 +0300150 const struct property_entry *prop;
Dmitry Torokhovbec84da2017-02-02 17:41:25 -0800151 const void *pointer;
Sakari Ailus0f194992017-03-28 15:22:18 +0300152 size_t array_len, length;
153
154 /* Find out the array length. */
155 prop = pset_prop_get(pset, propname);
156 if (!prop)
157 return -EINVAL;
158
159 if (!prop->is_array)
160 /* The array length for a non-array string property is 1. */
161 array_len = 1;
162 else
163 /* Find the length of an array. */
164 array_len = pset_prop_count_elems_of_size(pset, propname,
165 sizeof(const char *));
166
167 /* Return how many there are if strings is NULL. */
168 if (!strings)
169 return array_len;
170
171 array_len = min(nval, array_len);
172 length = array_len * sizeof(*strings);
Andy Shevchenko318a19712015-11-30 17:11:31 +0200173
174 pointer = pset_prop_find(pset, propname, length);
175 if (IS_ERR(pointer))
176 return PTR_ERR(pointer);
177
178 memcpy(strings, pointer, length);
Sakari Ailus0f194992017-03-28 15:22:18 +0300179
Sakari Ailusb0b027c2017-03-28 15:22:19 +0300180 return array_len;
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +0200181}
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100182
Sakari Ailuse44bb0c2017-03-28 10:52:24 +0300183struct fwnode_handle *dev_fwnode(struct device *dev)
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100184{
185 return IS_ENABLED(CONFIG_OF) && dev->of_node ?
186 &dev->of_node->fwnode : dev->fwnode;
187}
Sakari Ailuse44bb0c2017-03-28 10:52:24 +0300188EXPORT_SYMBOL_GPL(dev_fwnode);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100189
190/**
191 * device_property_present - check if a property of a device is present
192 * @dev: Device whose property is being checked
193 * @propname: Name of the property
194 *
195 * Check if property @propname is present in the device firmware description.
196 */
197bool device_property_present(struct device *dev, const char *propname)
198{
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100199 return fwnode_property_present(dev_fwnode(dev), propname);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100200}
201EXPORT_SYMBOL_GPL(device_property_present);
202
Andy Shevchenko362c0b32015-11-30 17:11:36 +0200203static bool __fwnode_property_present(struct fwnode_handle *fwnode,
204 const char *propname)
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100205{
206 if (is_of_node(fwnode))
Alexander Sverdlinc181fb32015-06-22 22:38:53 +0200207 return of_property_read_bool(to_of_node(fwnode), propname);
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100208 else if (is_acpi_node(fwnode))
Rafael J. Wysocki3a7a2ab2015-08-27 04:40:05 +0200209 return !acpi_node_prop_get(fwnode, propname, NULL);
Andy Shevchenko61f5e292015-11-30 17:11:30 +0200210 else if (is_pset_node(fwnode))
211 return !!pset_prop_get(to_pset_node(fwnode), propname);
Andy Shevchenkoe3f9e292015-11-30 17:11:29 +0200212 return false;
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100213}
Andy Shevchenko362c0b32015-11-30 17:11:36 +0200214
215/**
216 * fwnode_property_present - check if a property of a firmware node is present
217 * @fwnode: Firmware node whose property to check
218 * @propname: Name of the property
219 */
220bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
221{
222 bool ret;
223
224 ret = __fwnode_property_present(fwnode, propname);
Heikki Krogerus0d67e0f2016-03-10 13:03:18 +0200225 if (ret == false && !IS_ERR_OR_NULL(fwnode) &&
226 !IS_ERR_OR_NULL(fwnode->secondary))
Andy Shevchenko362c0b32015-11-30 17:11:36 +0200227 ret = __fwnode_property_present(fwnode->secondary, propname);
228 return ret;
229}
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100230EXPORT_SYMBOL_GPL(fwnode_property_present);
231
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100232/**
233 * device_property_read_u8_array - return a u8 array property of a device
234 * @dev: Device to get the property of
235 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200236 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100237 * @nval: Size of the @val array
238 *
239 * Function reads an array of u8 properties with @propname from the device
240 * firmware description and stores them to @val if found.
241 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200242 * Return: number of values if @val was %NULL,
243 * %0 if the property was found (success),
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100244 * %-EINVAL if given arguments are not valid,
245 * %-ENODATA if the property does not have a value,
246 * %-EPROTO if the property is not an array of numbers,
247 * %-EOVERFLOW if the size of the property is not as expected.
Guenter Roeck4fa7508e2015-08-26 20:27:04 -0700248 * %-ENXIO if no suitable firmware interface is present.
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100249 */
250int device_property_read_u8_array(struct device *dev, const char *propname,
251 u8 *val, size_t nval)
252{
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100253 return fwnode_property_read_u8_array(dev_fwnode(dev), propname, val, nval);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100254}
255EXPORT_SYMBOL_GPL(device_property_read_u8_array);
256
257/**
258 * device_property_read_u16_array - return a u16 array property of a device
259 * @dev: Device to get the property of
260 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200261 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100262 * @nval: Size of the @val array
263 *
264 * Function reads an array of u16 properties with @propname from the device
265 * firmware description and stores them to @val if found.
266 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200267 * Return: number of values if @val was %NULL,
268 * %0 if the property was found (success),
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100269 * %-EINVAL if given arguments are not valid,
270 * %-ENODATA if the property does not have a value,
271 * %-EPROTO if the property is not an array of numbers,
272 * %-EOVERFLOW if the size of the property is not as expected.
Guenter Roeck4fa7508e2015-08-26 20:27:04 -0700273 * %-ENXIO if no suitable firmware interface is present.
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100274 */
275int device_property_read_u16_array(struct device *dev, const char *propname,
276 u16 *val, size_t nval)
277{
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100278 return fwnode_property_read_u16_array(dev_fwnode(dev), propname, val, nval);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100279}
280EXPORT_SYMBOL_GPL(device_property_read_u16_array);
281
282/**
283 * device_property_read_u32_array - return a u32 array property of a device
284 * @dev: Device to get the property of
285 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200286 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100287 * @nval: Size of the @val array
288 *
289 * Function reads an array of u32 properties with @propname from the device
290 * firmware description and stores them to @val if found.
291 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200292 * Return: number of values if @val was %NULL,
293 * %0 if the property was found (success),
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100294 * %-EINVAL if given arguments are not valid,
295 * %-ENODATA if the property does not have a value,
296 * %-EPROTO if the property is not an array of numbers,
297 * %-EOVERFLOW if the size of the property is not as expected.
Guenter Roeck4fa7508e2015-08-26 20:27:04 -0700298 * %-ENXIO if no suitable firmware interface is present.
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100299 */
300int device_property_read_u32_array(struct device *dev, const char *propname,
301 u32 *val, size_t nval)
302{
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100303 return fwnode_property_read_u32_array(dev_fwnode(dev), propname, val, nval);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100304}
305EXPORT_SYMBOL_GPL(device_property_read_u32_array);
306
307/**
308 * device_property_read_u64_array - return a u64 array property of a device
309 * @dev: Device to get the property of
310 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200311 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100312 * @nval: Size of the @val array
313 *
314 * Function reads an array of u64 properties with @propname from the device
315 * firmware description and stores them to @val if found.
316 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200317 * Return: number of values if @val was %NULL,
318 * %0 if the property was found (success),
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100319 * %-EINVAL if given arguments are not valid,
320 * %-ENODATA if the property does not have a value,
321 * %-EPROTO if the property is not an array of numbers,
322 * %-EOVERFLOW if the size of the property is not as expected.
Guenter Roeck4fa7508e2015-08-26 20:27:04 -0700323 * %-ENXIO if no suitable firmware interface is present.
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100324 */
325int device_property_read_u64_array(struct device *dev, const char *propname,
326 u64 *val, size_t nval)
327{
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100328 return fwnode_property_read_u64_array(dev_fwnode(dev), propname, val, nval);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100329}
330EXPORT_SYMBOL_GPL(device_property_read_u64_array);
331
332/**
333 * device_property_read_string_array - return a string array property of device
334 * @dev: Device to get the property of
335 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200336 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100337 * @nval: Size of the @val array
338 *
339 * Function reads an array of string properties with @propname from the device
340 * firmware description and stores them to @val if found.
341 *
Sakari Ailusb0b027c2017-03-28 15:22:19 +0300342 * Return: number of values read on success if @val is non-NULL,
343 * number of values available on success if @val is NULL,
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100344 * %-EINVAL if given arguments are not valid,
345 * %-ENODATA if the property does not have a value,
346 * %-EPROTO or %-EILSEQ if the property is not an array of strings,
347 * %-EOVERFLOW if the size of the property is not as expected.
Guenter Roeck4fa7508e2015-08-26 20:27:04 -0700348 * %-ENXIO if no suitable firmware interface is present.
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100349 */
350int device_property_read_string_array(struct device *dev, const char *propname,
351 const char **val, size_t nval)
352{
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100353 return fwnode_property_read_string_array(dev_fwnode(dev), propname, val, nval);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100354}
355EXPORT_SYMBOL_GPL(device_property_read_string_array);
356
357/**
358 * device_property_read_string - return a string property of a device
359 * @dev: Device to get the property of
360 * @propname: Name of the property
361 * @val: The value is stored here
362 *
363 * Function reads property @propname from the device firmware description and
364 * stores the value into @val if found. The value is checked to be a string.
365 *
366 * Return: %0 if the property was found (success),
367 * %-EINVAL if given arguments are not valid,
368 * %-ENODATA if the property does not have a value,
369 * %-EPROTO or %-EILSEQ if the property type is not a string.
Guenter Roeck4fa7508e2015-08-26 20:27:04 -0700370 * %-ENXIO if no suitable firmware interface is present.
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100371 */
372int device_property_read_string(struct device *dev, const char *propname,
373 const char **val)
374{
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100375 return fwnode_property_read_string(dev_fwnode(dev), propname, val);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100376}
377EXPORT_SYMBOL_GPL(device_property_read_string);
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100378
Mika Westerberg3f5c8d32015-09-14 17:37:35 +0300379/**
380 * device_property_match_string - find a string in an array and return index
381 * @dev: Device to get the property of
382 * @propname: Name of the property holding the array
383 * @string: String to look for
384 *
385 * Find a given string in a string array and if it is found return the
386 * index back.
387 *
388 * Return: %0 if the property was found (success),
389 * %-EINVAL if given arguments are not valid,
390 * %-ENODATA if the property does not have a value,
391 * %-EPROTO if the property is not an array of strings,
392 * %-ENXIO if no suitable firmware interface is present.
393 */
394int device_property_match_string(struct device *dev, const char *propname,
395 const char *string)
396{
397 return fwnode_property_match_string(dev_fwnode(dev), propname, string);
398}
399EXPORT_SYMBOL_GPL(device_property_match_string);
400
Andy Shevchenko1d656fb2015-11-30 17:11:34 +0200401#define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \
402 (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100403 : of_property_count_elems_of_size((node), (propname), sizeof(type))
404
Andy Shevchenko318a19712015-11-30 17:11:31 +0200405#define PSET_PROP_READ_ARRAY(node, propname, type, val, nval) \
406 (val) ? pset_prop_read_##type##_array((node), (propname), (val), (nval)) \
407 : pset_prop_count_elems_of_size((node), (propname), sizeof(type))
408
Andy Shevchenko362c0b32015-11-30 17:11:36 +0200409#define FWNODE_PROP_READ(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
Andy Shevchenko1d656fb2015-11-30 17:11:34 +0200410({ \
411 int _ret_; \
412 if (is_of_node(_fwnode_)) \
413 _ret_ = OF_DEV_PROP_READ_ARRAY(to_of_node(_fwnode_), _propname_, \
414 _type_, _val_, _nval_); \
415 else if (is_acpi_node(_fwnode_)) \
416 _ret_ = acpi_node_prop_read(_fwnode_, _propname_, _proptype_, \
417 _val_, _nval_); \
Andy Shevchenko61f5e292015-11-30 17:11:30 +0200418 else if (is_pset_node(_fwnode_)) \
Andy Shevchenko318a19712015-11-30 17:11:31 +0200419 _ret_ = PSET_PROP_READ_ARRAY(to_pset_node(_fwnode_), _propname_, \
420 _type_, _val_, _nval_); \
Andy Shevchenko1d656fb2015-11-30 17:11:34 +0200421 else \
422 _ret_ = -ENXIO; \
423 _ret_; \
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100424})
425
Andy Shevchenko362c0b32015-11-30 17:11:36 +0200426#define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
427({ \
428 int _ret_; \
429 _ret_ = FWNODE_PROP_READ(_fwnode_, _propname_, _type_, _proptype_, \
430 _val_, _nval_); \
Heikki Krogerus0d67e0f2016-03-10 13:03:18 +0200431 if (_ret_ == -EINVAL && !IS_ERR_OR_NULL(_fwnode_) && \
432 !IS_ERR_OR_NULL(_fwnode_->secondary)) \
Andy Shevchenko362c0b32015-11-30 17:11:36 +0200433 _ret_ = FWNODE_PROP_READ(_fwnode_->secondary, _propname_, _type_, \
434 _proptype_, _val_, _nval_); \
435 _ret_; \
436})
437
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100438/**
439 * fwnode_property_read_u8_array - return a u8 array property of firmware node
440 * @fwnode: Firmware node to get the property of
441 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200442 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100443 * @nval: Size of the @val array
444 *
445 * Read an array of u8 properties with @propname from @fwnode and stores them to
446 * @val if found.
447 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200448 * Return: number of values if @val was %NULL,
449 * %0 if the property was found (success),
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100450 * %-EINVAL if given arguments are not valid,
451 * %-ENODATA if the property does not have a value,
452 * %-EPROTO if the property is not an array of numbers,
453 * %-EOVERFLOW if the size of the property is not as expected,
454 * %-ENXIO if no suitable firmware interface is present.
455 */
456int fwnode_property_read_u8_array(struct fwnode_handle *fwnode,
457 const char *propname, u8 *val, size_t nval)
458{
459 return FWNODE_PROP_READ_ARRAY(fwnode, propname, u8, DEV_PROP_U8,
460 val, nval);
461}
462EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array);
463
464/**
465 * fwnode_property_read_u16_array - return a u16 array property of firmware node
466 * @fwnode: Firmware node to get the property of
467 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200468 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100469 * @nval: Size of the @val array
470 *
471 * Read an array of u16 properties with @propname from @fwnode and store them to
472 * @val if found.
473 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200474 * Return: number of values if @val was %NULL,
475 * %0 if the property was found (success),
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100476 * %-EINVAL if given arguments are not valid,
477 * %-ENODATA if the property does not have a value,
478 * %-EPROTO if the property is not an array of numbers,
479 * %-EOVERFLOW if the size of the property is not as expected,
480 * %-ENXIO if no suitable firmware interface is present.
481 */
482int fwnode_property_read_u16_array(struct fwnode_handle *fwnode,
483 const char *propname, u16 *val, size_t nval)
484{
485 return FWNODE_PROP_READ_ARRAY(fwnode, propname, u16, DEV_PROP_U16,
486 val, nval);
487}
488EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array);
489
490/**
491 * fwnode_property_read_u32_array - return a u32 array property of firmware node
492 * @fwnode: Firmware node to get the property of
493 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200494 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100495 * @nval: Size of the @val array
496 *
497 * Read an array of u32 properties with @propname from @fwnode store them to
498 * @val if found.
499 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200500 * Return: number of values if @val was %NULL,
501 * %0 if the property was found (success),
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100502 * %-EINVAL if given arguments are not valid,
503 * %-ENODATA if the property does not have a value,
504 * %-EPROTO if the property is not an array of numbers,
505 * %-EOVERFLOW if the size of the property is not as expected,
506 * %-ENXIO if no suitable firmware interface is present.
507 */
508int fwnode_property_read_u32_array(struct fwnode_handle *fwnode,
509 const char *propname, u32 *val, size_t nval)
510{
511 return FWNODE_PROP_READ_ARRAY(fwnode, propname, u32, DEV_PROP_U32,
512 val, nval);
513}
514EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array);
515
516/**
517 * fwnode_property_read_u64_array - return a u64 array property firmware node
518 * @fwnode: Firmware node to get the property of
519 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200520 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100521 * @nval: Size of the @val array
522 *
523 * Read an array of u64 properties with @propname from @fwnode and store them to
524 * @val if found.
525 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200526 * Return: number of values if @val was %NULL,
527 * %0 if the property was found (success),
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100528 * %-EINVAL if given arguments are not valid,
529 * %-ENODATA if the property does not have a value,
530 * %-EPROTO if the property is not an array of numbers,
531 * %-EOVERFLOW if the size of the property is not as expected,
532 * %-ENXIO if no suitable firmware interface is present.
533 */
534int fwnode_property_read_u64_array(struct fwnode_handle *fwnode,
535 const char *propname, u64 *val, size_t nval)
536{
537 return FWNODE_PROP_READ_ARRAY(fwnode, propname, u64, DEV_PROP_U64,
538 val, nval);
539}
540EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array);
541
Andy Shevchenko362c0b32015-11-30 17:11:36 +0200542static int __fwnode_property_read_string_array(struct fwnode_handle *fwnode,
543 const char *propname,
544 const char **val, size_t nval)
545{
546 if (is_of_node(fwnode))
547 return val ?
548 of_property_read_string_array(to_of_node(fwnode),
549 propname, val, nval) :
550 of_property_count_strings(to_of_node(fwnode), propname);
551 else if (is_acpi_node(fwnode))
552 return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
553 val, nval);
554 else if (is_pset_node(fwnode))
Sakari Ailus0f194992017-03-28 15:22:18 +0300555 return pset_prop_read_string_array(to_pset_node(fwnode),
556 propname, val, nval);
Andy Shevchenko362c0b32015-11-30 17:11:36 +0200557 return -ENXIO;
558}
559
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100560/**
561 * fwnode_property_read_string_array - return string array property of a node
562 * @fwnode: Firmware node to get the property of
563 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200564 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100565 * @nval: Size of the @val array
566 *
567 * Read an string list property @propname from the given firmware node and store
568 * them to @val if found.
569 *
Sakari Ailusb0b027c2017-03-28 15:22:19 +0300570 * Return: number of values read on success if @val is non-NULL,
571 * number of values available on success if @val is NULL,
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100572 * %-EINVAL if given arguments are not valid,
573 * %-ENODATA if the property does not have a value,
Sakari Ailus026b8212017-03-28 15:22:17 +0300574 * %-EPROTO or %-EILSEQ if the property is not an array of strings,
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100575 * %-EOVERFLOW if the size of the property is not as expected,
576 * %-ENXIO if no suitable firmware interface is present.
577 */
578int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
579 const char *propname, const char **val,
580 size_t nval)
581{
Andy Shevchenko362c0b32015-11-30 17:11:36 +0200582 int ret;
583
584 ret = __fwnode_property_read_string_array(fwnode, propname, val, nval);
Heikki Krogerus0d67e0f2016-03-10 13:03:18 +0200585 if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) &&
586 !IS_ERR_OR_NULL(fwnode->secondary))
Andy Shevchenko362c0b32015-11-30 17:11:36 +0200587 ret = __fwnode_property_read_string_array(fwnode->secondary,
588 propname, val, nval);
589 return ret;
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100590}
591EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
592
593/**
594 * fwnode_property_read_string - return a string property of a firmware node
595 * @fwnode: Firmware node to get the property of
596 * @propname: Name of the property
597 * @val: The value is stored here
598 *
599 * Read property @propname from the given firmware node and store the value into
600 * @val if found. The value is checked to be a string.
601 *
602 * Return: %0 if the property was found (success),
603 * %-EINVAL if given arguments are not valid,
604 * %-ENODATA if the property does not have a value,
605 * %-EPROTO or %-EILSEQ if the property is not a string,
606 * %-ENXIO if no suitable firmware interface is present.
607 */
608int fwnode_property_read_string(struct fwnode_handle *fwnode,
609 const char *propname, const char **val)
610{
Sakari Ailuse4817472017-03-28 15:26:22 +0300611 int ret = fwnode_property_read_string_array(fwnode, propname, val, 1);
Andy Shevchenko362c0b32015-11-30 17:11:36 +0200612
Sakari Ailusb0b027c2017-03-28 15:22:19 +0300613 return ret < 0 ? ret : 0;
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100614}
615EXPORT_SYMBOL_GPL(fwnode_property_read_string);
616
617/**
Mika Westerberg3f5c8d32015-09-14 17:37:35 +0300618 * fwnode_property_match_string - find a string in an array and return index
619 * @fwnode: Firmware node to get the property of
620 * @propname: Name of the property holding the array
621 * @string: String to look for
622 *
623 * Find a given string in a string array and if it is found return the
624 * index back.
625 *
626 * Return: %0 if the property was found (success),
627 * %-EINVAL if given arguments are not valid,
628 * %-ENODATA if the property does not have a value,
629 * %-EPROTO if the property is not an array of strings,
630 * %-ENXIO if no suitable firmware interface is present.
631 */
632int fwnode_property_match_string(struct fwnode_handle *fwnode,
633 const char *propname, const char *string)
634{
635 const char **values;
Andy Shevchenkoa7c1d0a2016-03-17 14:22:17 -0700636 int nval, ret;
Mika Westerberg3f5c8d32015-09-14 17:37:35 +0300637
638 nval = fwnode_property_read_string_array(fwnode, propname, NULL, 0);
639 if (nval < 0)
640 return nval;
641
Andy Shevchenkof6740c12015-12-29 13:07:50 +0200642 if (nval == 0)
643 return -ENODATA;
644
Mika Westerberg3f5c8d32015-09-14 17:37:35 +0300645 values = kcalloc(nval, sizeof(*values), GFP_KERNEL);
646 if (!values)
647 return -ENOMEM;
648
649 ret = fwnode_property_read_string_array(fwnode, propname, values, nval);
650 if (ret < 0)
651 goto out;
652
Andy Shevchenkoa7c1d0a2016-03-17 14:22:17 -0700653 ret = match_string(values, nval, string);
654 if (ret < 0)
655 ret = -ENODATA;
Mika Westerberg3f5c8d32015-09-14 17:37:35 +0300656out:
657 kfree(values);
658 return ret;
659}
660EXPORT_SYMBOL_GPL(fwnode_property_match_string);
661
Dmitry Torokhov2d479e12017-02-02 17:41:27 -0800662static int property_copy_string_array(struct property_entry *dst,
663 const struct property_entry *src)
Mika Westerberg13141e12015-11-30 17:11:37 +0200664{
Dmitry Torokhov2d479e12017-02-02 17:41:27 -0800665 char **d;
666 size_t nval = src->length / sizeof(*d);
667 int i;
Mika Westerberg13141e12015-11-30 17:11:37 +0200668
Dmitry Torokhov2d479e12017-02-02 17:41:27 -0800669 d = kcalloc(nval, sizeof(*d), GFP_KERNEL);
670 if (!d)
671 return -ENOMEM;
Mika Westerberg13141e12015-11-30 17:11:37 +0200672
Dmitry Torokhov2d479e12017-02-02 17:41:27 -0800673 for (i = 0; i < nval; i++) {
674 d[i] = kstrdup(src->pointer.str[i], GFP_KERNEL);
675 if (!d[i] && src->pointer.str[i]) {
676 while (--i >= 0)
677 kfree(d[i]);
678 kfree(d);
679 return -ENOMEM;
Mika Westerberg13141e12015-11-30 17:11:37 +0200680 }
Mika Westerberg13141e12015-11-30 17:11:37 +0200681 }
682
Dmitry Torokhov2d479e12017-02-02 17:41:27 -0800683 dst->pointer.raw_data = d;
684 return 0;
Mika Westerberg13141e12015-11-30 17:11:37 +0200685}
686
Dmitry Torokhov2d479e12017-02-02 17:41:27 -0800687static int property_entry_copy_data(struct property_entry *dst,
688 const struct property_entry *src)
Mika Westerberg13141e12015-11-30 17:11:37 +0200689{
Dmitry Torokhov2d479e12017-02-02 17:41:27 -0800690 int error;
Mika Westerberg13141e12015-11-30 17:11:37 +0200691
692 dst->name = kstrdup(src->name, GFP_KERNEL);
693 if (!dst->name)
694 return -ENOMEM;
695
696 if (src->is_array) {
Dmitry Torokhov2d479e12017-02-02 17:41:27 -0800697 if (!src->length) {
698 error = -ENODATA;
699 goto out_free_name;
700 }
Andy Shevchenkof6740c12015-12-29 13:07:50 +0200701
Mika Westerberg13141e12015-11-30 17:11:37 +0200702 if (src->is_string) {
Dmitry Torokhov2d479e12017-02-02 17:41:27 -0800703 error = property_copy_string_array(dst, src);
704 if (error)
705 goto out_free_name;
Mika Westerberg13141e12015-11-30 17:11:37 +0200706 } else {
707 dst->pointer.raw_data = kmemdup(src->pointer.raw_data,
708 src->length, GFP_KERNEL);
Dmitry Torokhov2d479e12017-02-02 17:41:27 -0800709 if (!dst->pointer.raw_data) {
710 error = -ENOMEM;
711 goto out_free_name;
712 }
Mika Westerberg13141e12015-11-30 17:11:37 +0200713 }
714 } else if (src->is_string) {
715 dst->value.str = kstrdup(src->value.str, GFP_KERNEL);
Dmitry Torokhov2d479e12017-02-02 17:41:27 -0800716 if (!dst->value.str && src->value.str) {
717 error = -ENOMEM;
718 goto out_free_name;
719 }
Mika Westerberg13141e12015-11-30 17:11:37 +0200720 } else {
721 dst->value.raw_data = src->value.raw_data;
722 }
723
724 dst->length = src->length;
725 dst->is_array = src->is_array;
726 dst->is_string = src->is_string;
727
728 return 0;
Dmitry Torokhov2d479e12017-02-02 17:41:27 -0800729
730out_free_name:
731 kfree(dst->name);
732 return error;
733}
734
735static void property_entry_free_data(const struct property_entry *p)
736{
737 size_t i, nval;
738
739 if (p->is_array) {
740 if (p->is_string && p->pointer.str) {
741 nval = p->length / sizeof(const char *);
742 for (i = 0; i < nval; i++)
743 kfree(p->pointer.str[i]);
744 }
745 kfree(p->pointer.raw_data);
746 } else if (p->is_string) {
747 kfree(p->value.str);
748 }
749 kfree(p->name);
750}
751
752/**
753 * property_entries_dup - duplicate array of properties
754 * @properties: array of properties to copy
755 *
756 * This function creates a deep copy of the given NULL-terminated array
757 * of property entries.
758 */
759struct property_entry *
760property_entries_dup(const struct property_entry *properties)
761{
762 struct property_entry *p;
763 int i, n = 0;
764
765 while (properties[n].name)
766 n++;
767
768 p = kcalloc(n + 1, sizeof(*p), GFP_KERNEL);
769 if (!p)
770 return ERR_PTR(-ENOMEM);
771
772 for (i = 0; i < n; i++) {
773 int ret = property_entry_copy_data(&p[i], &properties[i]);
774 if (ret) {
775 while (--i >= 0)
776 property_entry_free_data(&p[i]);
777 kfree(p);
778 return ERR_PTR(ret);
779 }
780 }
781
782 return p;
783}
784EXPORT_SYMBOL_GPL(property_entries_dup);
785
786/**
787 * property_entries_free - free previously allocated array of properties
788 * @properties: array of properties to destroy
789 *
790 * This function frees given NULL-terminated array of property entries,
791 * along with their data.
792 */
793void property_entries_free(const struct property_entry *properties)
794{
795 const struct property_entry *p;
796
797 for (p = properties; p->name; p++)
798 property_entry_free_data(p);
799
800 kfree(properties);
801}
802EXPORT_SYMBOL_GPL(property_entries_free);
803
804/**
805 * pset_free_set - releases memory allocated for copied property set
806 * @pset: Property set to release
807 *
808 * Function takes previously copied property set and releases all the
809 * memory allocated to it.
810 */
811static void pset_free_set(struct property_set *pset)
812{
813 if (!pset)
814 return;
815
816 property_entries_free(pset->properties);
817 kfree(pset);
Mika Westerberg13141e12015-11-30 17:11:37 +0200818}
819
820/**
821 * pset_copy_set - copies property set
822 * @pset: Property set to copy
823 *
824 * This function takes a deep copy of the given property set and returns
825 * pointer to the copy. Call device_free_property_set() to free resources
826 * allocated in this function.
827 *
828 * Return: Pointer to the new property set or error pointer.
829 */
830static struct property_set *pset_copy_set(const struct property_set *pset)
831{
Dmitry Torokhov2d479e12017-02-02 17:41:27 -0800832 struct property_entry *properties;
Mika Westerberg13141e12015-11-30 17:11:37 +0200833 struct property_set *p;
Mika Westerberg13141e12015-11-30 17:11:37 +0200834
835 p = kzalloc(sizeof(*p), GFP_KERNEL);
836 if (!p)
837 return ERR_PTR(-ENOMEM);
838
Dmitry Torokhov2d479e12017-02-02 17:41:27 -0800839 properties = property_entries_dup(pset->properties);
840 if (IS_ERR(properties)) {
Mika Westerberg13141e12015-11-30 17:11:37 +0200841 kfree(p);
Dmitry Torokhov2d479e12017-02-02 17:41:27 -0800842 return ERR_CAST(properties);
Mika Westerberg13141e12015-11-30 17:11:37 +0200843 }
844
Dmitry Torokhov2d479e12017-02-02 17:41:27 -0800845 p->properties = properties;
Mika Westerberg13141e12015-11-30 17:11:37 +0200846 return p;
847}
848
849/**
Heikki Krogerusf4d05262016-03-29 14:52:23 +0300850 * device_remove_properties - Remove properties from a device object.
Mika Westerberg13141e12015-11-30 17:11:37 +0200851 * @dev: Device whose properties to remove.
852 *
853 * The function removes properties previously associated to the device
Heikki Krogerusf4d05262016-03-29 14:52:23 +0300854 * secondary firmware node with device_add_properties(). Memory allocated
Mika Westerberg13141e12015-11-30 17:11:37 +0200855 * to the properties will also be released.
856 */
Heikki Krogerusf4d05262016-03-29 14:52:23 +0300857void device_remove_properties(struct device *dev)
Mika Westerberg13141e12015-11-30 17:11:37 +0200858{
859 struct fwnode_handle *fwnode;
860
861 fwnode = dev_fwnode(dev);
862 if (!fwnode)
863 return;
864 /*
865 * Pick either primary or secondary node depending which one holds
866 * the pset. If there is no real firmware node (ACPI/DT) primary
867 * will hold the pset.
868 */
Heikki Krogerus0d67e0f2016-03-10 13:03:18 +0200869 if (is_pset_node(fwnode)) {
870 set_primary_fwnode(dev, NULL);
Mika Westerberg13141e12015-11-30 17:11:37 +0200871 pset_free_set(to_pset_node(fwnode));
Heikki Krogerus0d67e0f2016-03-10 13:03:18 +0200872 } else {
873 fwnode = fwnode->secondary;
874 if (!IS_ERR(fwnode) && is_pset_node(fwnode)) {
875 set_secondary_fwnode(dev, NULL);
876 pset_free_set(to_pset_node(fwnode));
877 }
878 }
Mika Westerberg13141e12015-11-30 17:11:37 +0200879}
Heikki Krogerusf4d05262016-03-29 14:52:23 +0300880EXPORT_SYMBOL_GPL(device_remove_properties);
Mika Westerberg13141e12015-11-30 17:11:37 +0200881
882/**
Heikki Krogerusf4d05262016-03-29 14:52:23 +0300883 * device_add_properties - Add a collection of properties to a device object.
Mika Westerberg13141e12015-11-30 17:11:37 +0200884 * @dev: Device to add properties to.
Heikki Krogerusf4d05262016-03-29 14:52:23 +0300885 * @properties: Collection of properties to add.
Mika Westerberg13141e12015-11-30 17:11:37 +0200886 *
Heikki Krogerusf4d05262016-03-29 14:52:23 +0300887 * Associate a collection of device properties represented by @properties with
888 * @dev as its secondary firmware node. The function takes a copy of
889 * @properties.
Mika Westerberg13141e12015-11-30 17:11:37 +0200890 */
Dmitry Torokhovbec84da2017-02-02 17:41:25 -0800891int device_add_properties(struct device *dev,
892 const struct property_entry *properties)
Mika Westerberg13141e12015-11-30 17:11:37 +0200893{
Heikki Krogerusf4d05262016-03-29 14:52:23 +0300894 struct property_set *p, pset;
Mika Westerberg13141e12015-11-30 17:11:37 +0200895
Heikki Krogerusf4d05262016-03-29 14:52:23 +0300896 if (!properties)
Mika Westerberg13141e12015-11-30 17:11:37 +0200897 return -EINVAL;
898
Heikki Krogerusf4d05262016-03-29 14:52:23 +0300899 pset.properties = properties;
900
901 p = pset_copy_set(&pset);
Mika Westerberg13141e12015-11-30 17:11:37 +0200902 if (IS_ERR(p))
903 return PTR_ERR(p);
904
905 p->fwnode.type = FWNODE_PDATA;
906 set_secondary_fwnode(dev, &p->fwnode);
907 return 0;
908}
Heikki Krogerusf4d05262016-03-29 14:52:23 +0300909EXPORT_SYMBOL_GPL(device_add_properties);
Mika Westerberg13141e12015-11-30 17:11:37 +0200910
911/**
Sakari Ailus23387252017-03-28 10:52:26 +0300912 * fwnode_get_next_parent - Iterate to the node's parent
913 * @fwnode: Firmware whose parent is retrieved
914 *
915 * This is like fwnode_get_parent() except that it drops the refcount
916 * on the passed node, making it suitable for iterating through a
917 * node's parents.
918 *
919 * Returns a node pointer with refcount incremented, use
920 * fwnode_handle_node() on it when done.
921 */
922struct fwnode_handle *fwnode_get_next_parent(struct fwnode_handle *fwnode)
923{
924 struct fwnode_handle *parent = fwnode_get_parent(fwnode);
925
926 fwnode_handle_put(fwnode);
927
928 return parent;
929}
930EXPORT_SYMBOL_GPL(fwnode_get_next_parent);
931
932/**
Mika Westerbergafaf26f2017-03-28 10:52:17 +0300933 * fwnode_get_parent - Return parent firwmare node
934 * @fwnode: Firmware whose parent is retrieved
935 *
936 * Return parent firmware node of the given node if possible or %NULL if no
937 * parent was available.
938 */
939struct fwnode_handle *fwnode_get_parent(struct fwnode_handle *fwnode)
940{
941 struct fwnode_handle *parent = NULL;
942
943 if (is_of_node(fwnode)) {
944 struct device_node *node;
945
946 node = of_get_parent(to_of_node(fwnode));
947 if (node)
948 parent = &node->fwnode;
949 } else if (is_acpi_node(fwnode)) {
950 parent = acpi_node_get_parent(fwnode);
951 }
952
953 return parent;
954}
955EXPORT_SYMBOL_GPL(fwnode_get_parent);
956
957/**
Mika Westerberg34055192017-03-28 10:52:18 +0300958 * fwnode_get_next_child_node - Return the next child node handle for a node
959 * @fwnode: Firmware node to find the next child node for.
960 * @child: Handle to one of the node's child nodes or a %NULL handle.
961 */
962struct fwnode_handle *fwnode_get_next_child_node(struct fwnode_handle *fwnode,
963 struct fwnode_handle *child)
964{
965 if (is_of_node(fwnode)) {
966 struct device_node *node;
967
968 node = of_get_next_available_child(to_of_node(fwnode),
969 to_of_node(child));
970 if (node)
971 return &node->fwnode;
972 } else if (is_acpi_node(fwnode)) {
973 return acpi_get_next_subnode(fwnode, child);
974 }
975
976 return NULL;
977}
978EXPORT_SYMBOL_GPL(fwnode_get_next_child_node);
979
980/**
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100981 * device_get_next_child_node - Return the next child node handle for a device
982 * @dev: Device to find the next child node for.
983 * @child: Handle to one of the device's child nodes or a null handle.
984 */
985struct fwnode_handle *device_get_next_child_node(struct device *dev,
986 struct fwnode_handle *child)
987{
Mika Westerberg34055192017-03-28 10:52:18 +0300988 struct acpi_device *adev = ACPI_COMPANION(dev);
989 struct fwnode_handle *fwnode = NULL;
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100990
Mika Westerberg34055192017-03-28 10:52:18 +0300991 if (dev->of_node)
992 fwnode = &dev->of_node->fwnode;
993 else if (adev)
994 fwnode = acpi_fwnode_handle(adev);
995
996 return fwnode_get_next_child_node(fwnode, child);
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100997}
998EXPORT_SYMBOL_GPL(device_get_next_child_node);
999
1000/**
Mika Westerberg21ea73f2017-03-28 10:52:19 +03001001 * fwnode_get_named_child_node - Return first matching named child node handle
1002 * @fwnode: Firmware node to find the named child node for.
Adam Thomson613e9722016-06-21 18:50:20 +01001003 * @childname: String to match child node name against.
1004 */
Mika Westerberg21ea73f2017-03-28 10:52:19 +03001005struct fwnode_handle *fwnode_get_named_child_node(struct fwnode_handle *fwnode,
Adam Thomson613e9722016-06-21 18:50:20 +01001006 const char *childname)
1007{
1008 struct fwnode_handle *child;
1009
1010 /*
Mika Westerberg21ea73f2017-03-28 10:52:19 +03001011 * Find first matching named child node of this fwnode.
Adam Thomson613e9722016-06-21 18:50:20 +01001012 * For ACPI this will be a data only sub-node.
1013 */
Mika Westerberg21ea73f2017-03-28 10:52:19 +03001014 fwnode_for_each_child_node(fwnode, child) {
Adam Thomson613e9722016-06-21 18:50:20 +01001015 if (is_of_node(child)) {
1016 if (!of_node_cmp(to_of_node(child)->name, childname))
1017 return child;
1018 } else if (is_acpi_data_node(child)) {
1019 if (acpi_data_node_match(child, childname))
1020 return child;
1021 }
1022 }
1023
1024 return NULL;
1025}
Mika Westerberg21ea73f2017-03-28 10:52:19 +03001026EXPORT_SYMBOL_GPL(fwnode_get_named_child_node);
1027
1028/**
1029 * device_get_named_child_node - Return first matching named child node handle
1030 * @dev: Device to find the named child node for.
1031 * @childname: String to match child node name against.
1032 */
1033struct fwnode_handle *device_get_named_child_node(struct device *dev,
1034 const char *childname)
1035{
1036 return fwnode_get_named_child_node(dev_fwnode(dev), childname);
1037}
Adam Thomson613e9722016-06-21 18:50:20 +01001038EXPORT_SYMBOL_GPL(device_get_named_child_node);
1039
1040/**
Sakari Ailuse7887c22017-03-28 10:52:22 +03001041 * fwnode_handle_get - Obtain a reference to a device node
1042 * @fwnode: Pointer to the device node to obtain the reference to.
1043 */
1044void fwnode_handle_get(struct fwnode_handle *fwnode)
1045{
1046 if (is_of_node(fwnode))
1047 of_node_get(to_of_node(fwnode));
1048}
1049EXPORT_SYMBOL_GPL(fwnode_handle_get);
1050
1051/**
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +01001052 * fwnode_handle_put - Drop reference to a device node
1053 * @fwnode: Pointer to the device node to drop the reference to.
1054 *
1055 * This has to be used when terminating device_for_each_child_node() iteration
1056 * with break or return to prevent stale device node references from being left
1057 * behind.
1058 */
1059void fwnode_handle_put(struct fwnode_handle *fwnode)
1060{
1061 if (is_of_node(fwnode))
Alexander Sverdlinc181fb32015-06-22 22:38:53 +02001062 of_node_put(to_of_node(fwnode));
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +01001063}
1064EXPORT_SYMBOL_GPL(fwnode_handle_put);
1065
1066/**
1067 * device_get_child_node_count - return the number of child nodes for device
1068 * @dev: Device to cound the child nodes for
1069 */
1070unsigned int device_get_child_node_count(struct device *dev)
1071{
1072 struct fwnode_handle *child;
1073 unsigned int count = 0;
1074
1075 device_for_each_child_node(dev, child)
1076 count++;
1077
1078 return count;
1079}
1080EXPORT_SYMBOL_GPL(device_get_child_node_count);
Suthikulpanit, Suravee05ca5562015-06-10 11:08:54 -05001081
Suthikulpanit, Suraveee5e55862015-10-28 15:50:49 -07001082bool device_dma_supported(struct device *dev)
1083{
1084 /* For DT, this is always supported.
1085 * For ACPI, this depends on CCA, which
1086 * is determined by the acpi_dma_supported().
1087 */
1088 if (IS_ENABLED(CONFIG_OF) && dev->of_node)
1089 return true;
1090
1091 return acpi_dma_supported(ACPI_COMPANION(dev));
1092}
1093EXPORT_SYMBOL_GPL(device_dma_supported);
1094
1095enum dev_dma_attr device_get_dma_attr(struct device *dev)
1096{
1097 enum dev_dma_attr attr = DEV_DMA_NOT_SUPPORTED;
1098
1099 if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
1100 if (of_dma_is_coherent(dev->of_node))
1101 attr = DEV_DMA_COHERENT;
1102 else
1103 attr = DEV_DMA_NON_COHERENT;
1104 } else
1105 attr = acpi_get_dma_attr(ACPI_COMPANION(dev));
1106
1107 return attr;
1108}
1109EXPORT_SYMBOL_GPL(device_get_dma_attr);
1110
Jeremy Linton4c96b7d2015-08-12 17:06:26 -05001111/**
Jeremy Linton2f710a32015-08-19 11:46:42 -05001112 * device_get_phy_mode - Get phy mode for given device
Jeremy Linton4c96b7d2015-08-12 17:06:26 -05001113 * @dev: Pointer to the given device
1114 *
1115 * The function gets phy interface string from property 'phy-mode' or
1116 * 'phy-connection-type', and return its index in phy_modes table, or errno in
1117 * error case.
1118 */
1119int device_get_phy_mode(struct device *dev)
1120{
1121 const char *pm;
1122 int err, i;
1123
1124 err = device_property_read_string(dev, "phy-mode", &pm);
1125 if (err < 0)
1126 err = device_property_read_string(dev,
1127 "phy-connection-type", &pm);
1128 if (err < 0)
1129 return err;
1130
1131 for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++)
1132 if (!strcasecmp(pm, phy_modes(i)))
1133 return i;
1134
1135 return -ENODEV;
1136}
1137EXPORT_SYMBOL_GPL(device_get_phy_mode);
1138
1139static void *device_get_mac_addr(struct device *dev,
1140 const char *name, char *addr,
1141 int alen)
1142{
1143 int ret = device_property_read_u8_array(dev, name, addr, alen);
1144
Jeremy Linton2f710a32015-08-19 11:46:42 -05001145 if (ret == 0 && alen == ETH_ALEN && is_valid_ether_addr(addr))
Jeremy Linton4c96b7d2015-08-12 17:06:26 -05001146 return addr;
1147 return NULL;
1148}
1149
1150/**
Jeremy Linton2f710a32015-08-19 11:46:42 -05001151 * device_get_mac_address - Get the MAC for a given device
1152 * @dev: Pointer to the device
1153 * @addr: Address of buffer to store the MAC in
1154 * @alen: Length of the buffer pointed to by addr, should be ETH_ALEN
1155 *
1156 * Search the firmware node for the best MAC address to use. 'mac-address' is
Jeremy Linton4c96b7d2015-08-12 17:06:26 -05001157 * checked first, because that is supposed to contain to "most recent" MAC
1158 * address. If that isn't set, then 'local-mac-address' is checked next,
1159 * because that is the default address. If that isn't set, then the obsolete
1160 * 'address' is checked, just in case we're using an old device tree.
1161 *
1162 * Note that the 'address' property is supposed to contain a virtual address of
1163 * the register set, but some DTS files have redefined that property to be the
1164 * MAC address.
1165 *
1166 * All-zero MAC addresses are rejected, because those could be properties that
Jeremy Linton2f710a32015-08-19 11:46:42 -05001167 * exist in the firmware tables, but were not updated by the firmware. For
1168 * example, the DTS could define 'mac-address' and 'local-mac-address', with
1169 * zero MAC addresses. Some older U-Boots only initialized 'local-mac-address'.
1170 * In this case, the real MAC is in 'local-mac-address', and 'mac-address'
1171 * exists but is all zeros.
Jeremy Linton4c96b7d2015-08-12 17:06:26 -05001172*/
1173void *device_get_mac_address(struct device *dev, char *addr, int alen)
1174{
Julien Grall5b902d62015-09-03 23:59:50 +01001175 char *res;
Jeremy Linton4c96b7d2015-08-12 17:06:26 -05001176
Julien Grall5b902d62015-09-03 23:59:50 +01001177 res = device_get_mac_addr(dev, "mac-address", addr, alen);
1178 if (res)
1179 return res;
1180
1181 res = device_get_mac_addr(dev, "local-mac-address", addr, alen);
1182 if (res)
1183 return res;
Jeremy Linton4c96b7d2015-08-12 17:06:26 -05001184
1185 return device_get_mac_addr(dev, "address", addr, alen);
1186}
1187EXPORT_SYMBOL(device_get_mac_address);
Mika Westerberg07bb80d2017-03-28 10:52:21 +03001188
1189/**
1190 * device_graph_get_next_endpoint - Get next endpoint firmware node
1191 * @fwnode: Pointer to the parent firmware node
1192 * @prev: Previous endpoint node or %NULL to get the first
1193 *
1194 * Returns an endpoint firmware node pointer or %NULL if no more endpoints
1195 * are available.
1196 */
1197struct fwnode_handle *
1198fwnode_graph_get_next_endpoint(struct fwnode_handle *fwnode,
1199 struct fwnode_handle *prev)
1200{
1201 struct fwnode_handle *endpoint = NULL;
1202
1203 if (is_of_node(fwnode)) {
1204 struct device_node *node;
1205
1206 node = of_graph_get_next_endpoint(to_of_node(fwnode),
1207 to_of_node(prev));
1208
1209 if (node)
1210 endpoint = &node->fwnode;
1211 } else if (is_acpi_node(fwnode)) {
1212 endpoint = acpi_graph_get_next_endpoint(fwnode, prev);
1213 if (IS_ERR(endpoint))
1214 endpoint = NULL;
1215 }
1216
1217 return endpoint;
1218
1219}
1220EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint);
1221
1222/**
1223 * fwnode_graph_get_remote_port_parent - Return fwnode of a remote device
1224 * @fwnode: Endpoint firmware node pointing to the remote endpoint
1225 *
1226 * Extracts firmware node of a remote device the @fwnode points to.
1227 */
1228struct fwnode_handle *
1229fwnode_graph_get_remote_port_parent(struct fwnode_handle *fwnode)
1230{
1231 struct fwnode_handle *parent = NULL;
1232
1233 if (is_of_node(fwnode)) {
1234 struct device_node *node;
1235
1236 node = of_graph_get_remote_port_parent(to_of_node(fwnode));
1237 if (node)
1238 parent = &node->fwnode;
1239 } else if (is_acpi_node(fwnode)) {
1240 int ret;
1241
1242 ret = acpi_graph_get_remote_endpoint(fwnode, &parent, NULL,
1243 NULL);
1244 if (ret)
1245 return NULL;
1246 }
1247
1248 return parent;
1249}
1250EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port_parent);
1251
1252/**
1253 * fwnode_graph_get_remote_port - Return fwnode of a remote port
1254 * @fwnode: Endpoint firmware node pointing to the remote endpoint
1255 *
1256 * Extracts firmware node of a remote port the @fwnode points to.
1257 */
1258struct fwnode_handle *fwnode_graph_get_remote_port(struct fwnode_handle *fwnode)
1259{
1260 struct fwnode_handle *port = NULL;
1261
1262 if (is_of_node(fwnode)) {
1263 struct device_node *node;
1264
1265 node = of_graph_get_remote_port(to_of_node(fwnode));
1266 if (node)
1267 port = &node->fwnode;
1268 } else if (is_acpi_node(fwnode)) {
1269 int ret;
1270
1271 ret = acpi_graph_get_remote_endpoint(fwnode, NULL, &port, NULL);
1272 if (ret)
1273 return NULL;
1274 }
1275
1276 return port;
1277}
1278EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port);
1279
1280/**
1281 * fwnode_graph_get_remote_endpoint - Return fwnode of a remote endpoint
1282 * @fwnode: Endpoint firmware node pointing to the remote endpoint
1283 *
1284 * Extracts firmware node of a remote endpoint the @fwnode points to.
1285 */
1286struct fwnode_handle *
1287fwnode_graph_get_remote_endpoint(struct fwnode_handle *fwnode)
1288{
1289 struct fwnode_handle *endpoint = NULL;
1290
1291 if (is_of_node(fwnode)) {
1292 struct device_node *node;
1293
1294 node = of_parse_phandle(to_of_node(fwnode), "remote-endpoint",
1295 0);
1296 if (node)
1297 endpoint = &node->fwnode;
1298 } else if (is_acpi_node(fwnode)) {
1299 int ret;
1300
1301 ret = acpi_graph_get_remote_endpoint(fwnode, NULL, NULL,
1302 &endpoint);
1303 if (ret)
1304 return NULL;
1305 }
1306
1307 return endpoint;
1308}
1309EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_endpoint);
Sakari Ailus2bd54522017-03-28 10:52:25 +03001310
1311/**
1312 * fwnode_graph_parse_endpoint - parse common endpoint node properties
1313 * @fwnode: pointer to endpoint fwnode_handle
1314 * @endpoint: pointer to the fwnode endpoint data structure
1315 *
1316 * Parse @fwnode representing a graph endpoint node and store the
1317 * information in @endpoint. The caller must hold a reference to
1318 * @fwnode.
1319 */
1320int fwnode_graph_parse_endpoint(struct fwnode_handle *fwnode,
1321 struct fwnode_endpoint *endpoint)
1322{
1323 struct fwnode_handle *port_fwnode = fwnode_get_parent(fwnode);
1324
1325 memset(endpoint, 0, sizeof(*endpoint));
1326
1327 endpoint->local_fwnode = fwnode;
1328
1329 if (is_acpi_node(port_fwnode)) {
1330 fwnode_property_read_u32(port_fwnode, "port", &endpoint->port);
1331 fwnode_property_read_u32(fwnode, "endpoint", &endpoint->id);
1332 } else {
1333 fwnode_property_read_u32(port_fwnode, "reg", &endpoint->port);
1334 fwnode_property_read_u32(fwnode, "reg", &endpoint->id);
1335 }
1336
1337 fwnode_handle_put(port_fwnode);
1338
1339 return 0;
1340}
1341EXPORT_SYMBOL(fwnode_graph_parse_endpoint);