]>
Commit | Line | Data |
---|---|---|
b31384fa RW |
1 | /* |
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 | ||
b31384fa | 13 | #include <linux/acpi.h> |
16ba08d5 RW |
14 | #include <linux/export.h> |
15 | #include <linux/kernel.h> | |
b31384fa | 16 | #include <linux/of.h> |
05ca5560 | 17 | #include <linux/of_address.h> |
16ba08d5 | 18 | #include <linux/property.h> |
4c96b7dc JL |
19 | #include <linux/etherdevice.h> |
20 | #include <linux/phy.h> | |
16ba08d5 RW |
21 | |
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 | */ | |
30 | void device_add_property_set(struct device *dev, struct property_set *pset) | |
31 | { | |
ecc87eed AS |
32 | if (!pset) |
33 | return; | |
16ba08d5 | 34 | |
ecc87eed | 35 | pset->fwnode.type = FWNODE_PDATA; |
16ba08d5 RW |
36 | set_secondary_fwnode(dev, &pset->fwnode); |
37 | } | |
38 | EXPORT_SYMBOL_GPL(device_add_property_set); | |
39 | ||
61f5e294 | 40 | static inline bool is_pset_node(struct fwnode_handle *fwnode) |
16ba08d5 RW |
41 | { |
42 | return fwnode && fwnode->type == FWNODE_PDATA; | |
43 | } | |
44 | ||
61f5e294 | 45 | static inline struct property_set *to_pset_node(struct fwnode_handle *fwnode) |
16ba08d5 | 46 | { |
61f5e294 | 47 | return is_pset_node(fwnode) ? |
16ba08d5 RW |
48 | container_of(fwnode, struct property_set, fwnode) : NULL; |
49 | } | |
50 | ||
51 | static 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 | ||
318a1971 AS |
66 | static void *pset_prop_find(struct property_set *pset, const char *propname, |
67 | size_t length) | |
16ba08d5 RW |
68 | { |
69 | struct property_entry *prop; | |
318a1971 | 70 | void *pointer; |
16ba08d5 | 71 | |
318a1971 AS |
72 | prop = pset_prop_get(pset, propname); |
73 | if (!prop) | |
74 | return ERR_PTR(-EINVAL); | |
66586bab AS |
75 | if (prop->is_array) |
76 | pointer = prop->pointer.raw_data; | |
77 | else | |
78 | pointer = &prop->value.raw_data; | |
318a1971 AS |
79 | if (!pointer) |
80 | return ERR_PTR(-ENODATA); | |
81 | if (length > prop->length) | |
82 | return ERR_PTR(-EOVERFLOW); | |
83 | return pointer; | |
84 | } | |
85 | ||
86 | static 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); | |
92 | ||
93 | pointer = pset_prop_find(pset, propname, length); | |
94 | if (IS_ERR(pointer)) | |
95 | return PTR_ERR(pointer); | |
96 | ||
97 | memcpy(values, pointer, length); | |
98 | return 0; | |
99 | } | |
100 | ||
101 | static 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 | ||
116 | static 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 | ||
131 | static 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 | ||
146 | static 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); | |
16ba08d5 | 152 | if (!prop) |
16ba08d5 | 153 | return -EINVAL; |
318a1971 AS |
154 | |
155 | return prop->length / length; | |
156 | } | |
157 | ||
158 | static 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); | |
16ba08d5 RW |
170 | return 0; |
171 | } | |
b31384fa | 172 | |
66586bab AS |
173 | static 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 | ||
9017f252 RW |
198 | static 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 | } | |
b31384fa RW |
203 | |
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 | */ | |
211 | bool device_property_present(struct device *dev, const char *propname) | |
212 | { | |
9017f252 | 213 | return fwnode_property_present(dev_fwnode(dev), propname); |
b31384fa RW |
214 | } |
215 | EXPORT_SYMBOL_GPL(device_property_present); | |
216 | ||
362c0b30 AS |
217 | static bool __fwnode_property_present(struct fwnode_handle *fwnode, |
218 | const char *propname) | |
8a0662d9 RW |
219 | { |
220 | if (is_of_node(fwnode)) | |
c181fb3e | 221 | return of_property_read_bool(to_of_node(fwnode), propname); |
8a0662d9 | 222 | else if (is_acpi_node(fwnode)) |
3a7a2ab8 | 223 | return !acpi_node_prop_get(fwnode, propname, NULL); |
61f5e294 AS |
224 | else if (is_pset_node(fwnode)) |
225 | return !!pset_prop_get(to_pset_node(fwnode), propname); | |
e3f9e299 | 226 | return false; |
8a0662d9 | 227 | } |
362c0b30 AS |
228 | |
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 | */ | |
234 | bool 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 | } | |
8a0662d9 RW |
243 | EXPORT_SYMBOL_GPL(fwnode_property_present); |
244 | ||
b31384fa RW |
245 | /** |
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 | |
5c0acf3b | 249 | * @val: The values are stored here or %NULL to return the number of values |
b31384fa RW |
250 | * @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 | * | |
5c0acf3b AH |
255 | * Return: number of values if @val was %NULL, |
256 | * %0 if the property was found (success), | |
b31384fa RW |
257 | * %-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. | |
4fa7508e | 261 | * %-ENXIO if no suitable firmware interface is present. |
b31384fa RW |
262 | */ |
263 | int device_property_read_u8_array(struct device *dev, const char *propname, | |
264 | u8 *val, size_t nval) | |
265 | { | |
9017f252 | 266 | return fwnode_property_read_u8_array(dev_fwnode(dev), propname, val, nval); |
b31384fa RW |
267 | } |
268 | EXPORT_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 | |
5c0acf3b | 274 | * @val: The values are stored here or %NULL to return the number of values |
b31384fa RW |
275 | * @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 | * | |
5c0acf3b AH |
280 | * Return: number of values if @val was %NULL, |
281 | * %0 if the property was found (success), | |
b31384fa RW |
282 | * %-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. | |
4fa7508e | 286 | * %-ENXIO if no suitable firmware interface is present. |
b31384fa RW |
287 | */ |
288 | int device_property_read_u16_array(struct device *dev, const char *propname, | |
289 | u16 *val, size_t nval) | |
290 | { | |
9017f252 | 291 | return fwnode_property_read_u16_array(dev_fwnode(dev), propname, val, nval); |
b31384fa RW |
292 | } |
293 | EXPORT_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 | |
5c0acf3b | 299 | * @val: The values are stored here or %NULL to return the number of values |
b31384fa RW |
300 | * @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 | * | |
5c0acf3b AH |
305 | * Return: number of values if @val was %NULL, |
306 | * %0 if the property was found (success), | |
b31384fa RW |
307 | * %-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. | |
4fa7508e | 311 | * %-ENXIO if no suitable firmware interface is present. |
b31384fa RW |
312 | */ |
313 | int device_property_read_u32_array(struct device *dev, const char *propname, | |
314 | u32 *val, size_t nval) | |
315 | { | |
9017f252 | 316 | return fwnode_property_read_u32_array(dev_fwnode(dev), propname, val, nval); |
b31384fa RW |
317 | } |
318 | EXPORT_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 | |
5c0acf3b | 324 | * @val: The values are stored here or %NULL to return the number of values |
b31384fa RW |
325 | * @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 | * | |
5c0acf3b AH |
330 | * Return: number of values if @val was %NULL, |
331 | * %0 if the property was found (success), | |
b31384fa RW |
332 | * %-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. | |
4fa7508e | 336 | * %-ENXIO if no suitable firmware interface is present. |
b31384fa RW |
337 | */ |
338 | int device_property_read_u64_array(struct device *dev, const char *propname, | |
339 | u64 *val, size_t nval) | |
340 | { | |
9017f252 | 341 | return fwnode_property_read_u64_array(dev_fwnode(dev), propname, val, nval); |
b31384fa RW |
342 | } |
343 | EXPORT_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 | |
5c0acf3b | 349 | * @val: The values are stored here or %NULL to return the number of values |
b31384fa RW |
350 | * @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 | * | |
5c0acf3b AH |
355 | * Return: number of values if @val was %NULL, |
356 | * %0 if the property was found (success), | |
b31384fa RW |
357 | * %-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. | |
4fa7508e | 361 | * %-ENXIO if no suitable firmware interface is present. |
b31384fa RW |
362 | */ |
363 | int device_property_read_string_array(struct device *dev, const char *propname, | |
364 | const char **val, size_t nval) | |
365 | { | |
9017f252 | 366 | return fwnode_property_read_string_array(dev_fwnode(dev), propname, val, nval); |
b31384fa RW |
367 | } |
368 | EXPORT_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. | |
4fa7508e | 383 | * %-ENXIO if no suitable firmware interface is present. |
b31384fa RW |
384 | */ |
385 | int device_property_read_string(struct device *dev, const char *propname, | |
386 | const char **val) | |
387 | { | |
9017f252 | 388 | return fwnode_property_read_string(dev_fwnode(dev), propname, val); |
b31384fa RW |
389 | } |
390 | EXPORT_SYMBOL_GPL(device_property_read_string); | |
8a0662d9 | 391 | |
3f5c8d31 MW |
392 | /** |
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 | */ | |
407 | int 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 | } | |
412 | EXPORT_SYMBOL_GPL(device_property_match_string); | |
413 | ||
1d656fb7 AS |
414 | #define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \ |
415 | (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \ | |
9017f252 RW |
416 | : of_property_count_elems_of_size((node), (propname), sizeof(type)) |
417 | ||
318a1971 AS |
418 | #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 | ||
362c0b30 | 422 | #define FWNODE_PROP_READ(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \ |
1d656fb7 AS |
423 | ({ \ |
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_); \ | |
61f5e294 | 431 | else if (is_pset_node(_fwnode_)) \ |
318a1971 AS |
432 | _ret_ = PSET_PROP_READ_ARRAY(to_pset_node(_fwnode_), _propname_, \ |
433 | _type_, _val_, _nval_); \ | |
1d656fb7 AS |
434 | else \ |
435 | _ret_ = -ENXIO; \ | |
436 | _ret_; \ | |
8a0662d9 RW |
437 | }) |
438 | ||
362c0b30 AS |
439 | #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 | ||
8a0662d9 RW |
450 | /** |
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 | |
5c0acf3b | 454 | * @val: The values are stored here or %NULL to return the number of values |
8a0662d9 RW |
455 | * @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 | * | |
5c0acf3b AH |
460 | * Return: number of values if @val was %NULL, |
461 | * %0 if the property was found (success), | |
8a0662d9 RW |
462 | * %-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 | */ | |
468 | int 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 | } | |
474 | EXPORT_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 | |
5c0acf3b | 480 | * @val: The values are stored here or %NULL to return the number of values |
8a0662d9 RW |
481 | * @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 | * | |
5c0acf3b AH |
486 | * Return: number of values if @val was %NULL, |
487 | * %0 if the property was found (success), | |
8a0662d9 RW |
488 | * %-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 | */ | |
494 | int 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 | } | |
500 | EXPORT_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 | |
5c0acf3b | 506 | * @val: The values are stored here or %NULL to return the number of values |
8a0662d9 RW |
507 | * @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 | * | |
5c0acf3b AH |
512 | * Return: number of values if @val was %NULL, |
513 | * %0 if the property was found (success), | |
8a0662d9 RW |
514 | * %-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 | */ | |
520 | int 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 | } | |
526 | EXPORT_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 | |
5c0acf3b | 532 | * @val: The values are stored here or %NULL to return the number of values |
8a0662d9 RW |
533 | * @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 | * | |
5c0acf3b AH |
538 | * Return: number of values if @val was %NULL, |
539 | * %0 if the property was found (success), | |
8a0662d9 RW |
540 | * %-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 | */ | |
546 | int 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 | } | |
552 | EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array); | |
553 | ||
362c0b30 AS |
554 | static 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 | ||
576 | static 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 | ||
8a0662d9 RW |
589 | /** |
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 | |
5c0acf3b | 593 | * @val: The values are stored here or %NULL to return the number of values |
8a0662d9 RW |
594 | * @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 | * | |
5c0acf3b AH |
599 | * Return: number of values if @val was %NULL, |
600 | * %0 if the property was found (success), | |
8a0662d9 RW |
601 | * %-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 | */ | |
607 | int fwnode_property_read_string_array(struct fwnode_handle *fwnode, | |
608 | const char *propname, const char **val, | |
609 | size_t nval) | |
610 | { | |
362c0b30 AS |
611 | 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; | |
8a0662d9 RW |
618 | } |
619 | EXPORT_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 | */ | |
636 | int fwnode_property_read_string(struct fwnode_handle *fwnode, | |
637 | const char *propname, const char **val) | |
638 | { | |
362c0b30 AS |
639 | 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; | |
8a0662d9 RW |
646 | } |
647 | EXPORT_SYMBOL_GPL(fwnode_property_read_string); | |
648 | ||
3f5c8d31 MW |
649 | /** |
650 | * 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 | */ | |
664 | int 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 | } | |
689 | out: | |
690 | kfree(values); | |
691 | return ret; | |
692 | } | |
693 | EXPORT_SYMBOL_GPL(fwnode_property_match_string); | |
694 | ||
8a0662d9 RW |
695 | /** |
696 | * 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 | */ | |
700 | struct 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 | ||
c181fb3e | 706 | node = of_get_next_available_child(dev->of_node, to_of_node(child)); |
8a0662d9 RW |
707 | if (node) |
708 | return &node->fwnode; | |
709 | } else if (IS_ENABLED(CONFIG_ACPI)) { | |
504a3374 | 710 | return acpi_get_next_subnode(dev, child); |
8a0662d9 RW |
711 | } |
712 | return NULL; | |
713 | } | |
714 | EXPORT_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 | */ | |
724 | void fwnode_handle_put(struct fwnode_handle *fwnode) | |
725 | { | |
726 | if (is_of_node(fwnode)) | |
c181fb3e | 727 | of_node_put(to_of_node(fwnode)); |
8a0662d9 RW |
728 | } |
729 | EXPORT_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 | */ | |
735 | unsigned 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 | } | |
745 | EXPORT_SYMBOL_GPL(device_get_child_node_count); | |
05ca5560 | 746 | |
e5e55864 SS |
747 | bool 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 | } | |
758 | EXPORT_SYMBOL_GPL(device_dma_supported); | |
759 | ||
760 | enum 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 | } | |
774 | EXPORT_SYMBOL_GPL(device_get_dma_attr); | |
775 | ||
4c96b7dc | 776 | /** |
2f710a3a | 777 | * device_get_phy_mode - Get phy mode for given device |
4c96b7dc JL |
778 | * @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 | */ | |
784 | int 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 | } | |
802 | EXPORT_SYMBOL_GPL(device_get_phy_mode); | |
803 | ||
804 | static 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 | ||
2f710a3a | 810 | if (ret == 0 && alen == ETH_ALEN && is_valid_ether_addr(addr)) |
4c96b7dc JL |
811 | return addr; |
812 | return NULL; | |
813 | } | |
814 | ||
815 | /** | |
2f710a3a JL |
816 | * 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 | |
4c96b7dc JL |
822 | * 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 | |
2f710a3a JL |
832 | * 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. | |
4c96b7dc JL |
837 | */ |
838 | void *device_get_mac_address(struct device *dev, char *addr, int alen) | |
839 | { | |
5b902d6f | 840 | char *res; |
4c96b7dc | 841 | |
5b902d6f JG |
842 | 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; | |
4c96b7dc JL |
849 | |
850 | return device_get_mac_addr(dev, "address", addr, alen); | |
851 | } | |
852 | EXPORT_SYMBOL(device_get_mac_address); |