blob: ebcbe342a77b1d51a3f8cd4c8036bd9d5ac45d51 [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>
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020018#include <linux/property.h>
Jeremy Linton4c96b7d2015-08-12 17:06:26 -050019#include <linux/etherdevice.h>
20#include <linux/phy.h>
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020021
22/**
23 * device_add_property_set - Add a collection of properties to a device object.
24 * @dev: Device to add properties to.
25 * @pset: Collection of properties to add.
26 *
27 * Associate a collection of device properties represented by @pset with @dev
28 * as its secondary firmware node.
29 */
30void device_add_property_set(struct device *dev, struct property_set *pset)
31{
Andy Shevchenkoecc87ee2015-08-05 16:51:11 +030032 if (!pset)
33 return;
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020034
Andy Shevchenkoecc87ee2015-08-05 16:51:11 +030035 pset->fwnode.type = FWNODE_PDATA;
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020036 set_secondary_fwnode(dev, &pset->fwnode);
37}
38EXPORT_SYMBOL_GPL(device_add_property_set);
39
Andy Shevchenko61f5e292015-11-30 17:11:30 +020040static inline bool is_pset_node(struct fwnode_handle *fwnode)
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020041{
42 return fwnode && fwnode->type == FWNODE_PDATA;
43}
44
Andy Shevchenko61f5e292015-11-30 17:11:30 +020045static inline struct property_set *to_pset_node(struct fwnode_handle *fwnode)
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020046{
Andy Shevchenko61f5e292015-11-30 17:11:30 +020047 return is_pset_node(fwnode) ?
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020048 container_of(fwnode, struct property_set, fwnode) : NULL;
49}
50
51static struct property_entry *pset_prop_get(struct property_set *pset,
52 const char *name)
53{
54 struct property_entry *prop;
55
56 if (!pset || !pset->properties)
57 return NULL;
58
59 for (prop = pset->properties; prop->name; prop++)
60 if (!strcmp(name, prop->name))
61 return prop;
62
63 return NULL;
64}
65
Andy Shevchenko318a19712015-11-30 17:11:31 +020066static void *pset_prop_find(struct property_set *pset, const char *propname,
67 size_t length)
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020068{
69 struct property_entry *prop;
Andy Shevchenko318a19712015-11-30 17:11:31 +020070 void *pointer;
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020071
Andy Shevchenko318a19712015-11-30 17:11:31 +020072 prop = pset_prop_get(pset, propname);
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020073 if (!prop)
Andy Shevchenko318a19712015-11-30 17:11:31 +020074 return ERR_PTR(-EINVAL);
Andy Shevchenko66586ba2015-11-30 17:11:32 +020075 if (prop->is_array)
76 pointer = prop->pointer.raw_data;
77 else
78 pointer = &prop->value.raw_data;
Andy Shevchenko318a19712015-11-30 17:11:31 +020079 if (!pointer)
80 return ERR_PTR(-ENODATA);
81 if (length > prop->length)
82 return ERR_PTR(-EOVERFLOW);
83 return pointer;
84}
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020085
Andy Shevchenko318a19712015-11-30 17:11:31 +020086static int pset_prop_read_u8_array(struct property_set *pset,
87 const char *propname,
88 u8 *values, size_t nval)
89{
90 void *pointer;
91 size_t length = nval * sizeof(*values);
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020092
Andy Shevchenko318a19712015-11-30 17:11:31 +020093 pointer = pset_prop_find(pset, propname, length);
94 if (IS_ERR(pointer))
95 return PTR_ERR(pointer);
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +020096
Andy Shevchenko318a19712015-11-30 17:11:31 +020097 memcpy(values, pointer, length);
98 return 0;
99}
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +0200100
Andy Shevchenko318a19712015-11-30 17:11:31 +0200101static int pset_prop_read_u16_array(struct property_set *pset,
102 const char *propname,
103 u16 *values, size_t nval)
104{
105 void *pointer;
106 size_t length = nval * sizeof(*values);
107
108 pointer = pset_prop_find(pset, propname, length);
109 if (IS_ERR(pointer))
110 return PTR_ERR(pointer);
111
112 memcpy(values, pointer, length);
113 return 0;
114}
115
116static int pset_prop_read_u32_array(struct property_set *pset,
117 const char *propname,
118 u32 *values, size_t nval)
119{
120 void *pointer;
121 size_t length = nval * sizeof(*values);
122
123 pointer = pset_prop_find(pset, propname, length);
124 if (IS_ERR(pointer))
125 return PTR_ERR(pointer);
126
127 memcpy(values, pointer, length);
128 return 0;
129}
130
131static int pset_prop_read_u64_array(struct property_set *pset,
132 const char *propname,
133 u64 *values, size_t nval)
134{
135 void *pointer;
136 size_t length = nval * sizeof(*values);
137
138 pointer = pset_prop_find(pset, propname, length);
139 if (IS_ERR(pointer))
140 return PTR_ERR(pointer);
141
142 memcpy(values, pointer, length);
143 return 0;
144}
145
146static int pset_prop_count_elems_of_size(struct property_set *pset,
147 const char *propname, size_t length)
148{
149 struct property_entry *prop;
150
151 prop = pset_prop_get(pset, propname);
152 if (!prop)
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +0200153 return -EINVAL;
Andy Shevchenko318a19712015-11-30 17:11:31 +0200154
155 return prop->length / length;
156}
157
158static int pset_prop_read_string_array(struct property_set *pset,
159 const char *propname,
160 const char **strings, size_t nval)
161{
162 void *pointer;
163 size_t length = nval * sizeof(*strings);
164
165 pointer = pset_prop_find(pset, propname, length);
166 if (IS_ERR(pointer))
167 return PTR_ERR(pointer);
168
169 memcpy(strings, pointer, length);
Rafael J. Wysocki16ba08d2015-04-03 16:05:11 +0200170 return 0;
171}
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100172
Andy Shevchenko66586ba2015-11-30 17:11:32 +0200173static int pset_prop_read_string(struct property_set *pset,
174 const char *propname, const char **strings)
175{
176 struct property_entry *prop;
177 const char **pointer;
178
179 prop = pset_prop_get(pset, propname);
180 if (!prop)
181 return -EINVAL;
182 if (!prop->is_string)
183 return -EILSEQ;
184 if (prop->is_array) {
185 pointer = prop->pointer.str;
186 if (!pointer)
187 return -ENODATA;
188 } else {
189 pointer = &prop->value.str;
190 if (*pointer && strnlen(*pointer, prop->length) >= prop->length)
191 return -EILSEQ;
192 }
193
194 *strings = *pointer;
195 return 0;
196}
197
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100198static inline struct fwnode_handle *dev_fwnode(struct device *dev)
199{
200 return IS_ENABLED(CONFIG_OF) && dev->of_node ?
201 &dev->of_node->fwnode : dev->fwnode;
202}
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100203
204/**
205 * device_property_present - check if a property of a device is present
206 * @dev: Device whose property is being checked
207 * @propname: Name of the property
208 *
209 * Check if property @propname is present in the device firmware description.
210 */
211bool device_property_present(struct device *dev, const char *propname)
212{
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100213 return fwnode_property_present(dev_fwnode(dev), propname);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100214}
215EXPORT_SYMBOL_GPL(device_property_present);
216
Andy Shevchenko362c0b32015-11-30 17:11:36 +0200217static bool __fwnode_property_present(struct fwnode_handle *fwnode,
218 const char *propname)
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100219{
220 if (is_of_node(fwnode))
Alexander Sverdlinc181fb32015-06-22 22:38:53 +0200221 return of_property_read_bool(to_of_node(fwnode), propname);
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100222 else if (is_acpi_node(fwnode))
Rafael J. Wysocki3a7a2ab2015-08-27 04:40:05 +0200223 return !acpi_node_prop_get(fwnode, propname, NULL);
Andy Shevchenko61f5e292015-11-30 17:11:30 +0200224 else if (is_pset_node(fwnode))
225 return !!pset_prop_get(to_pset_node(fwnode), propname);
Andy Shevchenkoe3f9e292015-11-30 17:11:29 +0200226 return false;
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100227}
Andy Shevchenko362c0b32015-11-30 17:11:36 +0200228
229/**
230 * fwnode_property_present - check if a property of a firmware node is present
231 * @fwnode: Firmware node whose property to check
232 * @propname: Name of the property
233 */
234bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
235{
236 bool ret;
237
238 ret = __fwnode_property_present(fwnode, propname);
239 if (ret == false && fwnode->secondary)
240 ret = __fwnode_property_present(fwnode->secondary, propname);
241 return ret;
242}
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100243EXPORT_SYMBOL_GPL(fwnode_property_present);
244
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100245/**
246 * device_property_read_u8_array - return a u8 array property of a device
247 * @dev: Device to get the property of
248 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200249 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100250 * @nval: Size of the @val array
251 *
252 * Function reads an array of u8 properties with @propname from the device
253 * firmware description and stores them to @val if found.
254 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200255 * Return: number of values if @val was %NULL,
256 * %0 if the property was found (success),
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100257 * %-EINVAL if given arguments are not valid,
258 * %-ENODATA if the property does not have a value,
259 * %-EPROTO if the property is not an array of numbers,
260 * %-EOVERFLOW if the size of the property is not as expected.
Guenter Roeck4fa7508e2015-08-26 20:27:04 -0700261 * %-ENXIO if no suitable firmware interface is present.
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100262 */
263int device_property_read_u8_array(struct device *dev, const char *propname,
264 u8 *val, size_t nval)
265{
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100266 return fwnode_property_read_u8_array(dev_fwnode(dev), propname, val, nval);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100267}
268EXPORT_SYMBOL_GPL(device_property_read_u8_array);
269
270/**
271 * device_property_read_u16_array - return a u16 array property of a device
272 * @dev: Device to get the property of
273 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200274 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100275 * @nval: Size of the @val array
276 *
277 * Function reads an array of u16 properties with @propname from the device
278 * firmware description and stores them to @val if found.
279 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200280 * Return: number of values if @val was %NULL,
281 * %0 if the property was found (success),
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100282 * %-EINVAL if given arguments are not valid,
283 * %-ENODATA if the property does not have a value,
284 * %-EPROTO if the property is not an array of numbers,
285 * %-EOVERFLOW if the size of the property is not as expected.
Guenter Roeck4fa7508e2015-08-26 20:27:04 -0700286 * %-ENXIO if no suitable firmware interface is present.
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100287 */
288int device_property_read_u16_array(struct device *dev, const char *propname,
289 u16 *val, size_t nval)
290{
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100291 return fwnode_property_read_u16_array(dev_fwnode(dev), propname, val, nval);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100292}
293EXPORT_SYMBOL_GPL(device_property_read_u16_array);
294
295/**
296 * device_property_read_u32_array - return a u32 array property of a device
297 * @dev: Device to get the property of
298 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200299 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100300 * @nval: Size of the @val array
301 *
302 * Function reads an array of u32 properties with @propname from the device
303 * firmware description and stores them to @val if found.
304 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200305 * Return: number of values if @val was %NULL,
306 * %0 if the property was found (success),
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100307 * %-EINVAL if given arguments are not valid,
308 * %-ENODATA if the property does not have a value,
309 * %-EPROTO if the property is not an array of numbers,
310 * %-EOVERFLOW if the size of the property is not as expected.
Guenter Roeck4fa7508e2015-08-26 20:27:04 -0700311 * %-ENXIO if no suitable firmware interface is present.
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100312 */
313int device_property_read_u32_array(struct device *dev, const char *propname,
314 u32 *val, size_t nval)
315{
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100316 return fwnode_property_read_u32_array(dev_fwnode(dev), propname, val, nval);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100317}
318EXPORT_SYMBOL_GPL(device_property_read_u32_array);
319
320/**
321 * device_property_read_u64_array - return a u64 array property of a device
322 * @dev: Device to get the property of
323 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200324 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100325 * @nval: Size of the @val array
326 *
327 * Function reads an array of u64 properties with @propname from the device
328 * firmware description and stores them to @val if found.
329 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200330 * Return: number of values if @val was %NULL,
331 * %0 if the property was found (success),
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100332 * %-EINVAL if given arguments are not valid,
333 * %-ENODATA if the property does not have a value,
334 * %-EPROTO if the property is not an array of numbers,
335 * %-EOVERFLOW if the size of the property is not as expected.
Guenter Roeck4fa7508e2015-08-26 20:27:04 -0700336 * %-ENXIO if no suitable firmware interface is present.
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100337 */
338int device_property_read_u64_array(struct device *dev, const char *propname,
339 u64 *val, size_t nval)
340{
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100341 return fwnode_property_read_u64_array(dev_fwnode(dev), propname, val, nval);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100342}
343EXPORT_SYMBOL_GPL(device_property_read_u64_array);
344
345/**
346 * device_property_read_string_array - return a string array property of device
347 * @dev: Device to get the property of
348 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200349 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100350 * @nval: Size of the @val array
351 *
352 * Function reads an array of string properties with @propname from the device
353 * firmware description and stores them to @val if found.
354 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200355 * Return: number of values if @val was %NULL,
356 * %0 if the property was found (success),
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100357 * %-EINVAL if given arguments are not valid,
358 * %-ENODATA if the property does not have a value,
359 * %-EPROTO or %-EILSEQ if the property is not an array of strings,
360 * %-EOVERFLOW if the size of the property is not as expected.
Guenter Roeck4fa7508e2015-08-26 20:27:04 -0700361 * %-ENXIO if no suitable firmware interface is present.
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100362 */
363int device_property_read_string_array(struct device *dev, const char *propname,
364 const char **val, size_t nval)
365{
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100366 return fwnode_property_read_string_array(dev_fwnode(dev), propname, val, nval);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100367}
368EXPORT_SYMBOL_GPL(device_property_read_string_array);
369
370/**
371 * device_property_read_string - return a string property of a device
372 * @dev: Device to get the property of
373 * @propname: Name of the property
374 * @val: The value is stored here
375 *
376 * Function reads property @propname from the device firmware description and
377 * stores the value into @val if found. The value is checked to be a string.
378 *
379 * Return: %0 if the property was found (success),
380 * %-EINVAL if given arguments are not valid,
381 * %-ENODATA if the property does not have a value,
382 * %-EPROTO or %-EILSEQ if the property type is not a string.
Guenter Roeck4fa7508e2015-08-26 20:27:04 -0700383 * %-ENXIO if no suitable firmware interface is present.
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100384 */
385int device_property_read_string(struct device *dev, const char *propname,
386 const char **val)
387{
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100388 return fwnode_property_read_string(dev_fwnode(dev), propname, val);
Rafael J. Wysockib31384f2014-11-04 01:28:56 +0100389}
390EXPORT_SYMBOL_GPL(device_property_read_string);
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100391
Mika Westerberg3f5c8d32015-09-14 17:37:35 +0300392/**
393 * device_property_match_string - find a string in an array and return index
394 * @dev: Device to get the property of
395 * @propname: Name of the property holding the array
396 * @string: String to look for
397 *
398 * Find a given string in a string array and if it is found return the
399 * index back.
400 *
401 * Return: %0 if the property was found (success),
402 * %-EINVAL if given arguments are not valid,
403 * %-ENODATA if the property does not have a value,
404 * %-EPROTO if the property is not an array of strings,
405 * %-ENXIO if no suitable firmware interface is present.
406 */
407int device_property_match_string(struct device *dev, const char *propname,
408 const char *string)
409{
410 return fwnode_property_match_string(dev_fwnode(dev), propname, string);
411}
412EXPORT_SYMBOL_GPL(device_property_match_string);
413
Andy Shevchenko1d656fb2015-11-30 17:11:34 +0200414#define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \
415 (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \
Rafael J. Wysocki9017f252015-03-24 00:24:16 +0100416 : of_property_count_elems_of_size((node), (propname), sizeof(type))
417
Andy Shevchenko318a19712015-11-30 17:11:31 +0200418#define PSET_PROP_READ_ARRAY(node, propname, type, val, nval) \
419 (val) ? pset_prop_read_##type##_array((node), (propname), (val), (nval)) \
420 : pset_prop_count_elems_of_size((node), (propname), sizeof(type))
421
Andy Shevchenko362c0b32015-11-30 17:11:36 +0200422#define FWNODE_PROP_READ(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
Andy Shevchenko1d656fb2015-11-30 17:11:34 +0200423({ \
424 int _ret_; \
425 if (is_of_node(_fwnode_)) \
426 _ret_ = OF_DEV_PROP_READ_ARRAY(to_of_node(_fwnode_), _propname_, \
427 _type_, _val_, _nval_); \
428 else if (is_acpi_node(_fwnode_)) \
429 _ret_ = acpi_node_prop_read(_fwnode_, _propname_, _proptype_, \
430 _val_, _nval_); \
Andy Shevchenko61f5e292015-11-30 17:11:30 +0200431 else if (is_pset_node(_fwnode_)) \
Andy Shevchenko318a19712015-11-30 17:11:31 +0200432 _ret_ = PSET_PROP_READ_ARRAY(to_pset_node(_fwnode_), _propname_, \
433 _type_, _val_, _nval_); \
Andy Shevchenko1d656fb2015-11-30 17:11:34 +0200434 else \
435 _ret_ = -ENXIO; \
436 _ret_; \
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100437})
438
Andy Shevchenko362c0b32015-11-30 17:11:36 +0200439#define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
440({ \
441 int _ret_; \
442 _ret_ = FWNODE_PROP_READ(_fwnode_, _propname_, _type_, _proptype_, \
443 _val_, _nval_); \
444 if (_ret_ == -EINVAL && _fwnode_->secondary) \
445 _ret_ = FWNODE_PROP_READ(_fwnode_->secondary, _propname_, _type_, \
446 _proptype_, _val_, _nval_); \
447 _ret_; \
448})
449
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100450/**
451 * fwnode_property_read_u8_array - return a u8 array property of firmware node
452 * @fwnode: Firmware node to get the property of
453 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200454 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100455 * @nval: Size of the @val array
456 *
457 * Read an array of u8 properties with @propname from @fwnode and stores them to
458 * @val if found.
459 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200460 * Return: number of values if @val was %NULL,
461 * %0 if the property was found (success),
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100462 * %-EINVAL if given arguments are not valid,
463 * %-ENODATA if the property does not have a value,
464 * %-EPROTO if the property is not an array of numbers,
465 * %-EOVERFLOW if the size of the property is not as expected,
466 * %-ENXIO if no suitable firmware interface is present.
467 */
468int fwnode_property_read_u8_array(struct fwnode_handle *fwnode,
469 const char *propname, u8 *val, size_t nval)
470{
471 return FWNODE_PROP_READ_ARRAY(fwnode, propname, u8, DEV_PROP_U8,
472 val, nval);
473}
474EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array);
475
476/**
477 * fwnode_property_read_u16_array - return a u16 array property of firmware node
478 * @fwnode: Firmware node to get the property of
479 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200480 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100481 * @nval: Size of the @val array
482 *
483 * Read an array of u16 properties with @propname from @fwnode and store them to
484 * @val if found.
485 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200486 * Return: number of values if @val was %NULL,
487 * %0 if the property was found (success),
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100488 * %-EINVAL if given arguments are not valid,
489 * %-ENODATA if the property does not have a value,
490 * %-EPROTO if the property is not an array of numbers,
491 * %-EOVERFLOW if the size of the property is not as expected,
492 * %-ENXIO if no suitable firmware interface is present.
493 */
494int fwnode_property_read_u16_array(struct fwnode_handle *fwnode,
495 const char *propname, u16 *val, size_t nval)
496{
497 return FWNODE_PROP_READ_ARRAY(fwnode, propname, u16, DEV_PROP_U16,
498 val, nval);
499}
500EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array);
501
502/**
503 * fwnode_property_read_u32_array - return a u32 array property of firmware node
504 * @fwnode: Firmware node to get the property of
505 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200506 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100507 * @nval: Size of the @val array
508 *
509 * Read an array of u32 properties with @propname from @fwnode store them to
510 * @val if found.
511 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200512 * Return: number of values if @val was %NULL,
513 * %0 if the property was found (success),
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100514 * %-EINVAL if given arguments are not valid,
515 * %-ENODATA if the property does not have a value,
516 * %-EPROTO if the property is not an array of numbers,
517 * %-EOVERFLOW if the size of the property is not as expected,
518 * %-ENXIO if no suitable firmware interface is present.
519 */
520int fwnode_property_read_u32_array(struct fwnode_handle *fwnode,
521 const char *propname, u32 *val, size_t nval)
522{
523 return FWNODE_PROP_READ_ARRAY(fwnode, propname, u32, DEV_PROP_U32,
524 val, nval);
525}
526EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array);
527
528/**
529 * fwnode_property_read_u64_array - return a u64 array property firmware node
530 * @fwnode: Firmware node to get the property of
531 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200532 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100533 * @nval: Size of the @val array
534 *
535 * Read an array of u64 properties with @propname from @fwnode and store them to
536 * @val if found.
537 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200538 * Return: number of values if @val was %NULL,
539 * %0 if the property was found (success),
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100540 * %-EINVAL if given arguments are not valid,
541 * %-ENODATA if the property does not have a value,
542 * %-EPROTO if the property is not an array of numbers,
543 * %-EOVERFLOW if the size of the property is not as expected,
544 * %-ENXIO if no suitable firmware interface is present.
545 */
546int fwnode_property_read_u64_array(struct fwnode_handle *fwnode,
547 const char *propname, u64 *val, size_t nval)
548{
549 return FWNODE_PROP_READ_ARRAY(fwnode, propname, u64, DEV_PROP_U64,
550 val, nval);
551}
552EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array);
553
Andy Shevchenko362c0b32015-11-30 17:11:36 +0200554static int __fwnode_property_read_string_array(struct fwnode_handle *fwnode,
555 const char *propname,
556 const char **val, size_t nval)
557{
558 if (is_of_node(fwnode))
559 return val ?
560 of_property_read_string_array(to_of_node(fwnode),
561 propname, val, nval) :
562 of_property_count_strings(to_of_node(fwnode), propname);
563 else if (is_acpi_node(fwnode))
564 return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
565 val, nval);
566 else if (is_pset_node(fwnode))
567 return val ?
568 pset_prop_read_string_array(to_pset_node(fwnode),
569 propname, val, nval) :
570 pset_prop_count_elems_of_size(to_pset_node(fwnode),
571 propname,
572 sizeof(const char *));
573 return -ENXIO;
574}
575
576static int __fwnode_property_read_string(struct fwnode_handle *fwnode,
577 const char *propname, const char **val)
578{
579 if (is_of_node(fwnode))
580 return of_property_read_string(to_of_node(fwnode), propname, val);
581 else if (is_acpi_node(fwnode))
582 return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
583 val, 1);
584 else if (is_pset_node(fwnode))
585 return pset_prop_read_string(to_pset_node(fwnode), propname, val);
586 return -ENXIO;
587}
588
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100589/**
590 * fwnode_property_read_string_array - return string array property of a node
591 * @fwnode: Firmware node to get the property of
592 * @propname: Name of the property
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200593 * @val: The values are stored here or %NULL to return the number of values
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100594 * @nval: Size of the @val array
595 *
596 * Read an string list property @propname from the given firmware node and store
597 * them to @val if found.
598 *
Adrian Hunter5c0acf32015-03-17 09:58:58 +0200599 * Return: number of values if @val was %NULL,
600 * %0 if the property was found (success),
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100601 * %-EINVAL if given arguments are not valid,
602 * %-ENODATA if the property does not have a value,
603 * %-EPROTO if the property is not an array of strings,
604 * %-EOVERFLOW if the size of the property is not as expected,
605 * %-ENXIO if no suitable firmware interface is present.
606 */
607int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
608 const char *propname, const char **val,
609 size_t nval)
610{
Andy Shevchenko362c0b32015-11-30 17:11:36 +0200611 int ret;
612
613 ret = __fwnode_property_read_string_array(fwnode, propname, val, nval);
614 if (ret == -EINVAL && fwnode->secondary)
615 ret = __fwnode_property_read_string_array(fwnode->secondary,
616 propname, val, nval);
617 return ret;
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100618}
619EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
620
621/**
622 * fwnode_property_read_string - return a string property of a firmware node
623 * @fwnode: Firmware node to get the property of
624 * @propname: Name of the property
625 * @val: The value is stored here
626 *
627 * Read property @propname from the given firmware node and store the value into
628 * @val if found. The value is checked to be a string.
629 *
630 * Return: %0 if the property was found (success),
631 * %-EINVAL if given arguments are not valid,
632 * %-ENODATA if the property does not have a value,
633 * %-EPROTO or %-EILSEQ if the property is not a string,
634 * %-ENXIO if no suitable firmware interface is present.
635 */
636int fwnode_property_read_string(struct fwnode_handle *fwnode,
637 const char *propname, const char **val)
638{
Andy Shevchenko362c0b32015-11-30 17:11:36 +0200639 int ret;
640
641 ret = __fwnode_property_read_string(fwnode, propname, val);
642 if (ret == -EINVAL && fwnode->secondary)
643 ret = __fwnode_property_read_string(fwnode->secondary,
644 propname, val);
645 return ret;
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100646}
647EXPORT_SYMBOL_GPL(fwnode_property_read_string);
648
649/**
Mika Westerberg3f5c8d32015-09-14 17:37:35 +0300650 * fwnode_property_match_string - find a string in an array and return index
651 * @fwnode: Firmware node to get the property of
652 * @propname: Name of the property holding the array
653 * @string: String to look for
654 *
655 * Find a given string in a string array and if it is found return the
656 * index back.
657 *
658 * Return: %0 if the property was found (success),
659 * %-EINVAL if given arguments are not valid,
660 * %-ENODATA if the property does not have a value,
661 * %-EPROTO if the property is not an array of strings,
662 * %-ENXIO if no suitable firmware interface is present.
663 */
664int fwnode_property_match_string(struct fwnode_handle *fwnode,
665 const char *propname, const char *string)
666{
667 const char **values;
668 int nval, ret, i;
669
670 nval = fwnode_property_read_string_array(fwnode, propname, NULL, 0);
671 if (nval < 0)
672 return nval;
673
674 values = kcalloc(nval, sizeof(*values), GFP_KERNEL);
675 if (!values)
676 return -ENOMEM;
677
678 ret = fwnode_property_read_string_array(fwnode, propname, values, nval);
679 if (ret < 0)
680 goto out;
681
682 ret = -ENODATA;
683 for (i = 0; i < nval; i++) {
684 if (!strcmp(values[i], string)) {
685 ret = i;
686 break;
687 }
688 }
689out:
690 kfree(values);
691 return ret;
692}
693EXPORT_SYMBOL_GPL(fwnode_property_match_string);
694
695/**
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100696 * device_get_next_child_node - Return the next child node handle for a device
697 * @dev: Device to find the next child node for.
698 * @child: Handle to one of the device's child nodes or a null handle.
699 */
700struct fwnode_handle *device_get_next_child_node(struct device *dev,
701 struct fwnode_handle *child)
702{
703 if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
704 struct device_node *node;
705
Alexander Sverdlinc181fb32015-06-22 22:38:53 +0200706 node = of_get_next_available_child(dev->of_node, to_of_node(child));
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100707 if (node)
708 return &node->fwnode;
709 } else if (IS_ENABLED(CONFIG_ACPI)) {
Rafael J. Wysocki504a3372015-08-27 04:42:33 +0200710 return acpi_get_next_subnode(dev, child);
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100711 }
712 return NULL;
713}
714EXPORT_SYMBOL_GPL(device_get_next_child_node);
715
716/**
717 * fwnode_handle_put - Drop reference to a device node
718 * @fwnode: Pointer to the device node to drop the reference to.
719 *
720 * This has to be used when terminating device_for_each_child_node() iteration
721 * with break or return to prevent stale device node references from being left
722 * behind.
723 */
724void fwnode_handle_put(struct fwnode_handle *fwnode)
725{
726 if (is_of_node(fwnode))
Alexander Sverdlinc181fb32015-06-22 22:38:53 +0200727 of_node_put(to_of_node(fwnode));
Rafael J. Wysocki8a0662d2014-11-04 14:03:59 +0100728}
729EXPORT_SYMBOL_GPL(fwnode_handle_put);
730
731/**
732 * device_get_child_node_count - return the number of child nodes for device
733 * @dev: Device to cound the child nodes for
734 */
735unsigned int device_get_child_node_count(struct device *dev)
736{
737 struct fwnode_handle *child;
738 unsigned int count = 0;
739
740 device_for_each_child_node(dev, child)
741 count++;
742
743 return count;
744}
745EXPORT_SYMBOL_GPL(device_get_child_node_count);
Suthikulpanit, Suravee05ca5562015-06-10 11:08:54 -0500746
Suthikulpanit, Suraveee5e55862015-10-28 15:50:49 -0700747bool device_dma_supported(struct device *dev)
748{
749 /* For DT, this is always supported.
750 * For ACPI, this depends on CCA, which
751 * is determined by the acpi_dma_supported().
752 */
753 if (IS_ENABLED(CONFIG_OF) && dev->of_node)
754 return true;
755
756 return acpi_dma_supported(ACPI_COMPANION(dev));
757}
758EXPORT_SYMBOL_GPL(device_dma_supported);
759
760enum dev_dma_attr device_get_dma_attr(struct device *dev)
761{
762 enum dev_dma_attr attr = DEV_DMA_NOT_SUPPORTED;
763
764 if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
765 if (of_dma_is_coherent(dev->of_node))
766 attr = DEV_DMA_COHERENT;
767 else
768 attr = DEV_DMA_NON_COHERENT;
769 } else
770 attr = acpi_get_dma_attr(ACPI_COMPANION(dev));
771
772 return attr;
773}
774EXPORT_SYMBOL_GPL(device_get_dma_attr);
775
Jeremy Linton4c96b7d2015-08-12 17:06:26 -0500776/**
Jeremy Linton2f710a32015-08-19 11:46:42 -0500777 * device_get_phy_mode - Get phy mode for given device
Jeremy Linton4c96b7d2015-08-12 17:06:26 -0500778 * @dev: Pointer to the given device
779 *
780 * The function gets phy interface string from property 'phy-mode' or
781 * 'phy-connection-type', and return its index in phy_modes table, or errno in
782 * error case.
783 */
784int device_get_phy_mode(struct device *dev)
785{
786 const char *pm;
787 int err, i;
788
789 err = device_property_read_string(dev, "phy-mode", &pm);
790 if (err < 0)
791 err = device_property_read_string(dev,
792 "phy-connection-type", &pm);
793 if (err < 0)
794 return err;
795
796 for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++)
797 if (!strcasecmp(pm, phy_modes(i)))
798 return i;
799
800 return -ENODEV;
801}
802EXPORT_SYMBOL_GPL(device_get_phy_mode);
803
804static void *device_get_mac_addr(struct device *dev,
805 const char *name, char *addr,
806 int alen)
807{
808 int ret = device_property_read_u8_array(dev, name, addr, alen);
809
Jeremy Linton2f710a32015-08-19 11:46:42 -0500810 if (ret == 0 && alen == ETH_ALEN && is_valid_ether_addr(addr))
Jeremy Linton4c96b7d2015-08-12 17:06:26 -0500811 return addr;
812 return NULL;
813}
814
815/**
Jeremy Linton2f710a32015-08-19 11:46:42 -0500816 * device_get_mac_address - Get the MAC for a given device
817 * @dev: Pointer to the device
818 * @addr: Address of buffer to store the MAC in
819 * @alen: Length of the buffer pointed to by addr, should be ETH_ALEN
820 *
821 * Search the firmware node for the best MAC address to use. 'mac-address' is
Jeremy Linton4c96b7d2015-08-12 17:06:26 -0500822 * checked first, because that is supposed to contain to "most recent" MAC
823 * address. If that isn't set, then 'local-mac-address' is checked next,
824 * because that is the default address. If that isn't set, then the obsolete
825 * 'address' is checked, just in case we're using an old device tree.
826 *
827 * Note that the 'address' property is supposed to contain a virtual address of
828 * the register set, but some DTS files have redefined that property to be the
829 * MAC address.
830 *
831 * All-zero MAC addresses are rejected, because those could be properties that
Jeremy Linton2f710a32015-08-19 11:46:42 -0500832 * exist in the firmware tables, but were not updated by the firmware. For
833 * example, the DTS could define 'mac-address' and 'local-mac-address', with
834 * zero MAC addresses. Some older U-Boots only initialized 'local-mac-address'.
835 * In this case, the real MAC is in 'local-mac-address', and 'mac-address'
836 * exists but is all zeros.
Jeremy Linton4c96b7d2015-08-12 17:06:26 -0500837*/
838void *device_get_mac_address(struct device *dev, char *addr, int alen)
839{
Julien Grall5b902d62015-09-03 23:59:50 +0100840 char *res;
Jeremy Linton4c96b7d2015-08-12 17:06:26 -0500841
Julien Grall5b902d62015-09-03 23:59:50 +0100842 res = device_get_mac_addr(dev, "mac-address", addr, alen);
843 if (res)
844 return res;
845
846 res = device_get_mac_addr(dev, "local-mac-address", addr, alen);
847 if (res)
848 return res;
Jeremy Linton4c96b7d2015-08-12 17:06:26 -0500849
850 return device_get_mac_addr(dev, "address", addr, alen);
851}
852EXPORT_SYMBOL(device_get_mac_address);