]>
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); | |
75 | pointer = prop->value.raw_data; | |
76 | if (!pointer) | |
77 | return ERR_PTR(-ENODATA); | |
78 | if (length > prop->length) | |
79 | return ERR_PTR(-EOVERFLOW); | |
80 | return pointer; | |
81 | } | |
82 | ||
83 | static int pset_prop_read_u8_array(struct property_set *pset, | |
84 | const char *propname, | |
85 | u8 *values, size_t nval) | |
86 | { | |
87 | void *pointer; | |
88 | size_t length = nval * sizeof(*values); | |
89 | ||
90 | pointer = pset_prop_find(pset, propname, length); | |
91 | if (IS_ERR(pointer)) | |
92 | return PTR_ERR(pointer); | |
93 | ||
94 | memcpy(values, pointer, length); | |
95 | return 0; | |
96 | } | |
97 | ||
98 | static int pset_prop_read_u16_array(struct property_set *pset, | |
99 | const char *propname, | |
100 | u16 *values, size_t nval) | |
101 | { | |
102 | void *pointer; | |
103 | size_t length = nval * sizeof(*values); | |
104 | ||
105 | pointer = pset_prop_find(pset, propname, length); | |
106 | if (IS_ERR(pointer)) | |
107 | return PTR_ERR(pointer); | |
108 | ||
109 | memcpy(values, pointer, length); | |
110 | return 0; | |
111 | } | |
112 | ||
113 | static int pset_prop_read_u32_array(struct property_set *pset, | |
114 | const char *propname, | |
115 | u32 *values, size_t nval) | |
116 | { | |
117 | void *pointer; | |
118 | size_t length = nval * sizeof(*values); | |
119 | ||
120 | pointer = pset_prop_find(pset, propname, length); | |
121 | if (IS_ERR(pointer)) | |
122 | return PTR_ERR(pointer); | |
123 | ||
124 | memcpy(values, pointer, length); | |
125 | return 0; | |
126 | } | |
127 | ||
128 | static int pset_prop_read_u64_array(struct property_set *pset, | |
129 | const char *propname, | |
130 | u64 *values, size_t nval) | |
131 | { | |
132 | void *pointer; | |
133 | size_t length = nval * sizeof(*values); | |
134 | ||
135 | pointer = pset_prop_find(pset, propname, length); | |
136 | if (IS_ERR(pointer)) | |
137 | return PTR_ERR(pointer); | |
138 | ||
139 | memcpy(values, pointer, length); | |
140 | return 0; | |
141 | } | |
142 | ||
143 | static int pset_prop_count_elems_of_size(struct property_set *pset, | |
144 | const char *propname, size_t length) | |
145 | { | |
146 | struct property_entry *prop; | |
147 | ||
148 | prop = pset_prop_get(pset, propname); | |
16ba08d5 | 149 | if (!prop) |
16ba08d5 | 150 | return -EINVAL; |
318a1971 AS |
151 | |
152 | return prop->length / length; | |
153 | } | |
154 | ||
155 | static int pset_prop_read_string_array(struct property_set *pset, | |
156 | const char *propname, | |
157 | const char **strings, size_t nval) | |
158 | { | |
159 | void *pointer; | |
160 | size_t length = nval * sizeof(*strings); | |
161 | ||
162 | pointer = pset_prop_find(pset, propname, length); | |
163 | if (IS_ERR(pointer)) | |
164 | return PTR_ERR(pointer); | |
165 | ||
166 | memcpy(strings, pointer, length); | |
16ba08d5 RW |
167 | return 0; |
168 | } | |
b31384fa | 169 | |
9017f252 RW |
170 | static inline struct fwnode_handle *dev_fwnode(struct device *dev) |
171 | { | |
172 | return IS_ENABLED(CONFIG_OF) && dev->of_node ? | |
173 | &dev->of_node->fwnode : dev->fwnode; | |
174 | } | |
b31384fa RW |
175 | |
176 | /** | |
177 | * device_property_present - check if a property of a device is present | |
178 | * @dev: Device whose property is being checked | |
179 | * @propname: Name of the property | |
180 | * | |
181 | * Check if property @propname is present in the device firmware description. | |
182 | */ | |
183 | bool device_property_present(struct device *dev, const char *propname) | |
184 | { | |
9017f252 | 185 | return fwnode_property_present(dev_fwnode(dev), propname); |
b31384fa RW |
186 | } |
187 | EXPORT_SYMBOL_GPL(device_property_present); | |
188 | ||
8a0662d9 RW |
189 | /** |
190 | * fwnode_property_present - check if a property of a firmware node is present | |
191 | * @fwnode: Firmware node whose property to check | |
192 | * @propname: Name of the property | |
193 | */ | |
194 | bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname) | |
195 | { | |
196 | if (is_of_node(fwnode)) | |
c181fb3e | 197 | return of_property_read_bool(to_of_node(fwnode), propname); |
8a0662d9 | 198 | else if (is_acpi_node(fwnode)) |
3a7a2ab8 | 199 | return !acpi_node_prop_get(fwnode, propname, NULL); |
61f5e294 AS |
200 | else if (is_pset_node(fwnode)) |
201 | return !!pset_prop_get(to_pset_node(fwnode), propname); | |
e3f9e299 | 202 | return false; |
8a0662d9 RW |
203 | } |
204 | EXPORT_SYMBOL_GPL(fwnode_property_present); | |
205 | ||
b31384fa RW |
206 | /** |
207 | * device_property_read_u8_array - return a u8 array property of a device | |
208 | * @dev: Device to get the property of | |
209 | * @propname: Name of the property | |
5c0acf3b | 210 | * @val: The values are stored here or %NULL to return the number of values |
b31384fa RW |
211 | * @nval: Size of the @val array |
212 | * | |
213 | * Function reads an array of u8 properties with @propname from the device | |
214 | * firmware description and stores them to @val if found. | |
215 | * | |
5c0acf3b AH |
216 | * Return: number of values if @val was %NULL, |
217 | * %0 if the property was found (success), | |
b31384fa RW |
218 | * %-EINVAL if given arguments are not valid, |
219 | * %-ENODATA if the property does not have a value, | |
220 | * %-EPROTO if the property is not an array of numbers, | |
221 | * %-EOVERFLOW if the size of the property is not as expected. | |
4fa7508e | 222 | * %-ENXIO if no suitable firmware interface is present. |
b31384fa RW |
223 | */ |
224 | int device_property_read_u8_array(struct device *dev, const char *propname, | |
225 | u8 *val, size_t nval) | |
226 | { | |
9017f252 | 227 | return fwnode_property_read_u8_array(dev_fwnode(dev), propname, val, nval); |
b31384fa RW |
228 | } |
229 | EXPORT_SYMBOL_GPL(device_property_read_u8_array); | |
230 | ||
231 | /** | |
232 | * device_property_read_u16_array - return a u16 array property of a device | |
233 | * @dev: Device to get the property of | |
234 | * @propname: Name of the property | |
5c0acf3b | 235 | * @val: The values are stored here or %NULL to return the number of values |
b31384fa RW |
236 | * @nval: Size of the @val array |
237 | * | |
238 | * Function reads an array of u16 properties with @propname from the device | |
239 | * firmware description and stores them to @val if found. | |
240 | * | |
5c0acf3b AH |
241 | * Return: number of values if @val was %NULL, |
242 | * %0 if the property was found (success), | |
b31384fa RW |
243 | * %-EINVAL if given arguments are not valid, |
244 | * %-ENODATA if the property does not have a value, | |
245 | * %-EPROTO if the property is not an array of numbers, | |
246 | * %-EOVERFLOW if the size of the property is not as expected. | |
4fa7508e | 247 | * %-ENXIO if no suitable firmware interface is present. |
b31384fa RW |
248 | */ |
249 | int device_property_read_u16_array(struct device *dev, const char *propname, | |
250 | u16 *val, size_t nval) | |
251 | { | |
9017f252 | 252 | return fwnode_property_read_u16_array(dev_fwnode(dev), propname, val, nval); |
b31384fa RW |
253 | } |
254 | EXPORT_SYMBOL_GPL(device_property_read_u16_array); | |
255 | ||
256 | /** | |
257 | * device_property_read_u32_array - return a u32 array property of a device | |
258 | * @dev: Device to get the property of | |
259 | * @propname: Name of the property | |
5c0acf3b | 260 | * @val: The values are stored here or %NULL to return the number of values |
b31384fa RW |
261 | * @nval: Size of the @val array |
262 | * | |
263 | * Function reads an array of u32 properties with @propname from the device | |
264 | * firmware description and stores them to @val if found. | |
265 | * | |
5c0acf3b AH |
266 | * Return: number of values if @val was %NULL, |
267 | * %0 if the property was found (success), | |
b31384fa RW |
268 | * %-EINVAL if given arguments are not valid, |
269 | * %-ENODATA if the property does not have a value, | |
270 | * %-EPROTO if the property is not an array of numbers, | |
271 | * %-EOVERFLOW if the size of the property is not as expected. | |
4fa7508e | 272 | * %-ENXIO if no suitable firmware interface is present. |
b31384fa RW |
273 | */ |
274 | int device_property_read_u32_array(struct device *dev, const char *propname, | |
275 | u32 *val, size_t nval) | |
276 | { | |
9017f252 | 277 | return fwnode_property_read_u32_array(dev_fwnode(dev), propname, val, nval); |
b31384fa RW |
278 | } |
279 | EXPORT_SYMBOL_GPL(device_property_read_u32_array); | |
280 | ||
281 | /** | |
282 | * device_property_read_u64_array - return a u64 array property of a device | |
283 | * @dev: Device to get the property of | |
284 | * @propname: Name of the property | |
5c0acf3b | 285 | * @val: The values are stored here or %NULL to return the number of values |
b31384fa RW |
286 | * @nval: Size of the @val array |
287 | * | |
288 | * Function reads an array of u64 properties with @propname from the device | |
289 | * firmware description and stores them to @val if found. | |
290 | * | |
5c0acf3b AH |
291 | * Return: number of values if @val was %NULL, |
292 | * %0 if the property was found (success), | |
b31384fa RW |
293 | * %-EINVAL if given arguments are not valid, |
294 | * %-ENODATA if the property does not have a value, | |
295 | * %-EPROTO if the property is not an array of numbers, | |
296 | * %-EOVERFLOW if the size of the property is not as expected. | |
4fa7508e | 297 | * %-ENXIO if no suitable firmware interface is present. |
b31384fa RW |
298 | */ |
299 | int device_property_read_u64_array(struct device *dev, const char *propname, | |
300 | u64 *val, size_t nval) | |
301 | { | |
9017f252 | 302 | return fwnode_property_read_u64_array(dev_fwnode(dev), propname, val, nval); |
b31384fa RW |
303 | } |
304 | EXPORT_SYMBOL_GPL(device_property_read_u64_array); | |
305 | ||
306 | /** | |
307 | * device_property_read_string_array - return a string array property of device | |
308 | * @dev: Device to get the property of | |
309 | * @propname: Name of the property | |
5c0acf3b | 310 | * @val: The values are stored here or %NULL to return the number of values |
b31384fa RW |
311 | * @nval: Size of the @val array |
312 | * | |
313 | * Function reads an array of string properties with @propname from the device | |
314 | * firmware description and stores them to @val if found. | |
315 | * | |
5c0acf3b AH |
316 | * Return: number of values if @val was %NULL, |
317 | * %0 if the property was found (success), | |
b31384fa RW |
318 | * %-EINVAL if given arguments are not valid, |
319 | * %-ENODATA if the property does not have a value, | |
320 | * %-EPROTO or %-EILSEQ if the property is not an array of strings, | |
321 | * %-EOVERFLOW if the size of the property is not as expected. | |
4fa7508e | 322 | * %-ENXIO if no suitable firmware interface is present. |
b31384fa RW |
323 | */ |
324 | int device_property_read_string_array(struct device *dev, const char *propname, | |
325 | const char **val, size_t nval) | |
326 | { | |
9017f252 | 327 | return fwnode_property_read_string_array(dev_fwnode(dev), propname, val, nval); |
b31384fa RW |
328 | } |
329 | EXPORT_SYMBOL_GPL(device_property_read_string_array); | |
330 | ||
331 | /** | |
332 | * device_property_read_string - return a string property of a device | |
333 | * @dev: Device to get the property of | |
334 | * @propname: Name of the property | |
335 | * @val: The value is stored here | |
336 | * | |
337 | * Function reads property @propname from the device firmware description and | |
338 | * stores the value into @val if found. The value is checked to be a string. | |
339 | * | |
340 | * Return: %0 if the property was found (success), | |
341 | * %-EINVAL if given arguments are not valid, | |
342 | * %-ENODATA if the property does not have a value, | |
343 | * %-EPROTO or %-EILSEQ if the property type is not a string. | |
4fa7508e | 344 | * %-ENXIO if no suitable firmware interface is present. |
b31384fa RW |
345 | */ |
346 | int device_property_read_string(struct device *dev, const char *propname, | |
347 | const char **val) | |
348 | { | |
9017f252 | 349 | return fwnode_property_read_string(dev_fwnode(dev), propname, val); |
b31384fa RW |
350 | } |
351 | EXPORT_SYMBOL_GPL(device_property_read_string); | |
8a0662d9 | 352 | |
3f5c8d31 MW |
353 | /** |
354 | * device_property_match_string - find a string in an array and return index | |
355 | * @dev: Device to get the property of | |
356 | * @propname: Name of the property holding the array | |
357 | * @string: String to look for | |
358 | * | |
359 | * Find a given string in a string array and if it is found return the | |
360 | * index back. | |
361 | * | |
362 | * Return: %0 if the property was found (success), | |
363 | * %-EINVAL if given arguments are not valid, | |
364 | * %-ENODATA if the property does not have a value, | |
365 | * %-EPROTO if the property is not an array of strings, | |
366 | * %-ENXIO if no suitable firmware interface is present. | |
367 | */ | |
368 | int device_property_match_string(struct device *dev, const char *propname, | |
369 | const char *string) | |
370 | { | |
371 | return fwnode_property_match_string(dev_fwnode(dev), propname, string); | |
372 | } | |
373 | EXPORT_SYMBOL_GPL(device_property_match_string); | |
374 | ||
9017f252 RW |
375 | #define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \ |
376 | (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \ | |
377 | : of_property_count_elems_of_size((node), (propname), sizeof(type)) | |
378 | ||
318a1971 AS |
379 | #define PSET_PROP_READ_ARRAY(node, propname, type, val, nval) \ |
380 | (val) ? pset_prop_read_##type##_array((node), (propname), (val), (nval)) \ | |
381 | : pset_prop_count_elems_of_size((node), (propname), sizeof(type)) | |
382 | ||
8a0662d9 RW |
383 | #define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \ |
384 | ({ \ | |
385 | int _ret_; \ | |
386 | if (is_of_node(_fwnode_)) \ | |
c181fb3e | 387 | _ret_ = OF_DEV_PROP_READ_ARRAY(to_of_node(_fwnode_), _propname_, \ |
8a0662d9 RW |
388 | _type_, _val_, _nval_); \ |
389 | else if (is_acpi_node(_fwnode_)) \ | |
3a7a2ab8 RW |
390 | _ret_ = acpi_node_prop_read(_fwnode_, _propname_, _proptype_, \ |
391 | _val_, _nval_); \ | |
61f5e294 | 392 | else if (is_pset_node(_fwnode_)) \ |
318a1971 AS |
393 | _ret_ = PSET_PROP_READ_ARRAY(to_pset_node(_fwnode_), _propname_, \ |
394 | _type_, _val_, _nval_); \ | |
4fa7508e GR |
395 | else \ |
396 | _ret_ = -ENXIO; \ | |
8a0662d9 RW |
397 | _ret_; \ |
398 | }) | |
399 | ||
400 | /** | |
401 | * fwnode_property_read_u8_array - return a u8 array property of firmware node | |
402 | * @fwnode: Firmware node to get the property of | |
403 | * @propname: Name of the property | |
5c0acf3b | 404 | * @val: The values are stored here or %NULL to return the number of values |
8a0662d9 RW |
405 | * @nval: Size of the @val array |
406 | * | |
407 | * Read an array of u8 properties with @propname from @fwnode and stores them to | |
408 | * @val if found. | |
409 | * | |
5c0acf3b AH |
410 | * Return: number of values if @val was %NULL, |
411 | * %0 if the property was found (success), | |
8a0662d9 RW |
412 | * %-EINVAL if given arguments are not valid, |
413 | * %-ENODATA if the property does not have a value, | |
414 | * %-EPROTO if the property is not an array of numbers, | |
415 | * %-EOVERFLOW if the size of the property is not as expected, | |
416 | * %-ENXIO if no suitable firmware interface is present. | |
417 | */ | |
418 | int fwnode_property_read_u8_array(struct fwnode_handle *fwnode, | |
419 | const char *propname, u8 *val, size_t nval) | |
420 | { | |
421 | return FWNODE_PROP_READ_ARRAY(fwnode, propname, u8, DEV_PROP_U8, | |
422 | val, nval); | |
423 | } | |
424 | EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array); | |
425 | ||
426 | /** | |
427 | * fwnode_property_read_u16_array - return a u16 array property of firmware node | |
428 | * @fwnode: Firmware node to get the property of | |
429 | * @propname: Name of the property | |
5c0acf3b | 430 | * @val: The values are stored here or %NULL to return the number of values |
8a0662d9 RW |
431 | * @nval: Size of the @val array |
432 | * | |
433 | * Read an array of u16 properties with @propname from @fwnode and store them to | |
434 | * @val if found. | |
435 | * | |
5c0acf3b AH |
436 | * Return: number of values if @val was %NULL, |
437 | * %0 if the property was found (success), | |
8a0662d9 RW |
438 | * %-EINVAL if given arguments are not valid, |
439 | * %-ENODATA if the property does not have a value, | |
440 | * %-EPROTO if the property is not an array of numbers, | |
441 | * %-EOVERFLOW if the size of the property is not as expected, | |
442 | * %-ENXIO if no suitable firmware interface is present. | |
443 | */ | |
444 | int fwnode_property_read_u16_array(struct fwnode_handle *fwnode, | |
445 | const char *propname, u16 *val, size_t nval) | |
446 | { | |
447 | return FWNODE_PROP_READ_ARRAY(fwnode, propname, u16, DEV_PROP_U16, | |
448 | val, nval); | |
449 | } | |
450 | EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array); | |
451 | ||
452 | /** | |
453 | * fwnode_property_read_u32_array - return a u32 array property of firmware node | |
454 | * @fwnode: Firmware node to get the property of | |
455 | * @propname: Name of the property | |
5c0acf3b | 456 | * @val: The values are stored here or %NULL to return the number of values |
8a0662d9 RW |
457 | * @nval: Size of the @val array |
458 | * | |
459 | * Read an array of u32 properties with @propname from @fwnode store them to | |
460 | * @val if found. | |
461 | * | |
5c0acf3b AH |
462 | * Return: number of values if @val was %NULL, |
463 | * %0 if the property was found (success), | |
8a0662d9 RW |
464 | * %-EINVAL if given arguments are not valid, |
465 | * %-ENODATA if the property does not have a value, | |
466 | * %-EPROTO if the property is not an array of numbers, | |
467 | * %-EOVERFLOW if the size of the property is not as expected, | |
468 | * %-ENXIO if no suitable firmware interface is present. | |
469 | */ | |
470 | int fwnode_property_read_u32_array(struct fwnode_handle *fwnode, | |
471 | const char *propname, u32 *val, size_t nval) | |
472 | { | |
473 | return FWNODE_PROP_READ_ARRAY(fwnode, propname, u32, DEV_PROP_U32, | |
474 | val, nval); | |
475 | } | |
476 | EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array); | |
477 | ||
478 | /** | |
479 | * fwnode_property_read_u64_array - return a u64 array property firmware node | |
480 | * @fwnode: Firmware node to get the property of | |
481 | * @propname: Name of the property | |
5c0acf3b | 482 | * @val: The values are stored here or %NULL to return the number of values |
8a0662d9 RW |
483 | * @nval: Size of the @val array |
484 | * | |
485 | * Read an array of u64 properties with @propname from @fwnode and store them to | |
486 | * @val if found. | |
487 | * | |
5c0acf3b AH |
488 | * Return: number of values if @val was %NULL, |
489 | * %0 if the property was found (success), | |
8a0662d9 RW |
490 | * %-EINVAL if given arguments are not valid, |
491 | * %-ENODATA if the property does not have a value, | |
492 | * %-EPROTO if the property is not an array of numbers, | |
493 | * %-EOVERFLOW if the size of the property is not as expected, | |
494 | * %-ENXIO if no suitable firmware interface is present. | |
495 | */ | |
496 | int fwnode_property_read_u64_array(struct fwnode_handle *fwnode, | |
497 | const char *propname, u64 *val, size_t nval) | |
498 | { | |
499 | return FWNODE_PROP_READ_ARRAY(fwnode, propname, u64, DEV_PROP_U64, | |
500 | val, nval); | |
501 | } | |
502 | EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array); | |
503 | ||
504 | /** | |
505 | * fwnode_property_read_string_array - return string array property of a node | |
506 | * @fwnode: Firmware node to get the property of | |
507 | * @propname: Name of the property | |
5c0acf3b | 508 | * @val: The values are stored here or %NULL to return the number of values |
8a0662d9 RW |
509 | * @nval: Size of the @val array |
510 | * | |
511 | * Read an string list property @propname from the given firmware node and store | |
512 | * them to @val if found. | |
513 | * | |
5c0acf3b AH |
514 | * Return: number of values if @val was %NULL, |
515 | * %0 if the property was found (success), | |
8a0662d9 RW |
516 | * %-EINVAL if given arguments are not valid, |
517 | * %-ENODATA if the property does not have a value, | |
518 | * %-EPROTO if the property is not an array of strings, | |
519 | * %-EOVERFLOW if the size of the property is not as expected, | |
520 | * %-ENXIO if no suitable firmware interface is present. | |
521 | */ | |
522 | int fwnode_property_read_string_array(struct fwnode_handle *fwnode, | |
523 | const char *propname, const char **val, | |
524 | size_t nval) | |
525 | { | |
526 | if (is_of_node(fwnode)) | |
f42712a9 | 527 | return val ? |
c181fb3e AS |
528 | of_property_read_string_array(to_of_node(fwnode), |
529 | propname, val, nval) : | |
530 | of_property_count_strings(to_of_node(fwnode), propname); | |
8a0662d9 | 531 | else if (is_acpi_node(fwnode)) |
3a7a2ab8 RW |
532 | return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING, |
533 | val, nval); | |
61f5e294 | 534 | else if (is_pset_node(fwnode)) |
318a1971 AS |
535 | return val ? |
536 | pset_prop_read_string_array(to_pset_node(fwnode), | |
537 | propname, val, nval) : | |
538 | pset_prop_count_elems_of_size(to_pset_node(fwnode), | |
539 | propname, | |
540 | sizeof(const char *)); | |
4fa7508e | 541 | return -ENXIO; |
8a0662d9 RW |
542 | } |
543 | EXPORT_SYMBOL_GPL(fwnode_property_read_string_array); | |
544 | ||
545 | /** | |
546 | * fwnode_property_read_string - return a string property of a firmware node | |
547 | * @fwnode: Firmware node to get the property of | |
548 | * @propname: Name of the property | |
549 | * @val: The value is stored here | |
550 | * | |
551 | * Read property @propname from the given firmware node and store the value into | |
552 | * @val if found. The value is checked to be a string. | |
553 | * | |
554 | * Return: %0 if the property was found (success), | |
555 | * %-EINVAL if given arguments are not valid, | |
556 | * %-ENODATA if the property does not have a value, | |
557 | * %-EPROTO or %-EILSEQ if the property is not a string, | |
558 | * %-ENXIO if no suitable firmware interface is present. | |
559 | */ | |
560 | int fwnode_property_read_string(struct fwnode_handle *fwnode, | |
561 | const char *propname, const char **val) | |
562 | { | |
563 | if (is_of_node(fwnode)) | |
c181fb3e | 564 | return of_property_read_string(to_of_node(fwnode), propname, val); |
8a0662d9 | 565 | else if (is_acpi_node(fwnode)) |
3a7a2ab8 RW |
566 | return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING, |
567 | val, 1); | |
61f5e294 | 568 | else if (is_pset_node(fwnode)) |
318a1971 AS |
569 | return pset_prop_read_string_array(to_pset_node(fwnode), |
570 | propname, val, 1); | |
e3f9e299 | 571 | return -ENXIO; |
8a0662d9 RW |
572 | } |
573 | EXPORT_SYMBOL_GPL(fwnode_property_read_string); | |
574 | ||
3f5c8d31 MW |
575 | /** |
576 | * fwnode_property_match_string - find a string in an array and return index | |
577 | * @fwnode: Firmware node to get the property of | |
578 | * @propname: Name of the property holding the array | |
579 | * @string: String to look for | |
580 | * | |
581 | * Find a given string in a string array and if it is found return the | |
582 | * index back. | |
583 | * | |
584 | * Return: %0 if the property was found (success), | |
585 | * %-EINVAL if given arguments are not valid, | |
586 | * %-ENODATA if the property does not have a value, | |
587 | * %-EPROTO if the property is not an array of strings, | |
588 | * %-ENXIO if no suitable firmware interface is present. | |
589 | */ | |
590 | int fwnode_property_match_string(struct fwnode_handle *fwnode, | |
591 | const char *propname, const char *string) | |
592 | { | |
593 | const char **values; | |
594 | int nval, ret, i; | |
595 | ||
596 | nval = fwnode_property_read_string_array(fwnode, propname, NULL, 0); | |
597 | if (nval < 0) | |
598 | return nval; | |
599 | ||
600 | values = kcalloc(nval, sizeof(*values), GFP_KERNEL); | |
601 | if (!values) | |
602 | return -ENOMEM; | |
603 | ||
604 | ret = fwnode_property_read_string_array(fwnode, propname, values, nval); | |
605 | if (ret < 0) | |
606 | goto out; | |
607 | ||
608 | ret = -ENODATA; | |
609 | for (i = 0; i < nval; i++) { | |
610 | if (!strcmp(values[i], string)) { | |
611 | ret = i; | |
612 | break; | |
613 | } | |
614 | } | |
615 | out: | |
616 | kfree(values); | |
617 | return ret; | |
618 | } | |
619 | EXPORT_SYMBOL_GPL(fwnode_property_match_string); | |
620 | ||
8a0662d9 RW |
621 | /** |
622 | * device_get_next_child_node - Return the next child node handle for a device | |
623 | * @dev: Device to find the next child node for. | |
624 | * @child: Handle to one of the device's child nodes or a null handle. | |
625 | */ | |
626 | struct fwnode_handle *device_get_next_child_node(struct device *dev, | |
627 | struct fwnode_handle *child) | |
628 | { | |
629 | if (IS_ENABLED(CONFIG_OF) && dev->of_node) { | |
630 | struct device_node *node; | |
631 | ||
c181fb3e | 632 | node = of_get_next_available_child(dev->of_node, to_of_node(child)); |
8a0662d9 RW |
633 | if (node) |
634 | return &node->fwnode; | |
635 | } else if (IS_ENABLED(CONFIG_ACPI)) { | |
504a3374 | 636 | return acpi_get_next_subnode(dev, child); |
8a0662d9 RW |
637 | } |
638 | return NULL; | |
639 | } | |
640 | EXPORT_SYMBOL_GPL(device_get_next_child_node); | |
641 | ||
642 | /** | |
643 | * fwnode_handle_put - Drop reference to a device node | |
644 | * @fwnode: Pointer to the device node to drop the reference to. | |
645 | * | |
646 | * This has to be used when terminating device_for_each_child_node() iteration | |
647 | * with break or return to prevent stale device node references from being left | |
648 | * behind. | |
649 | */ | |
650 | void fwnode_handle_put(struct fwnode_handle *fwnode) | |
651 | { | |
652 | if (is_of_node(fwnode)) | |
c181fb3e | 653 | of_node_put(to_of_node(fwnode)); |
8a0662d9 RW |
654 | } |
655 | EXPORT_SYMBOL_GPL(fwnode_handle_put); | |
656 | ||
657 | /** | |
658 | * device_get_child_node_count - return the number of child nodes for device | |
659 | * @dev: Device to cound the child nodes for | |
660 | */ | |
661 | unsigned int device_get_child_node_count(struct device *dev) | |
662 | { | |
663 | struct fwnode_handle *child; | |
664 | unsigned int count = 0; | |
665 | ||
666 | device_for_each_child_node(dev, child) | |
667 | count++; | |
668 | ||
669 | return count; | |
670 | } | |
671 | EXPORT_SYMBOL_GPL(device_get_child_node_count); | |
05ca5560 | 672 | |
e5e55864 SS |
673 | bool device_dma_supported(struct device *dev) |
674 | { | |
675 | /* For DT, this is always supported. | |
676 | * For ACPI, this depends on CCA, which | |
677 | * is determined by the acpi_dma_supported(). | |
678 | */ | |
679 | if (IS_ENABLED(CONFIG_OF) && dev->of_node) | |
680 | return true; | |
681 | ||
682 | return acpi_dma_supported(ACPI_COMPANION(dev)); | |
683 | } | |
684 | EXPORT_SYMBOL_GPL(device_dma_supported); | |
685 | ||
686 | enum dev_dma_attr device_get_dma_attr(struct device *dev) | |
687 | { | |
688 | enum dev_dma_attr attr = DEV_DMA_NOT_SUPPORTED; | |
689 | ||
690 | if (IS_ENABLED(CONFIG_OF) && dev->of_node) { | |
691 | if (of_dma_is_coherent(dev->of_node)) | |
692 | attr = DEV_DMA_COHERENT; | |
693 | else | |
694 | attr = DEV_DMA_NON_COHERENT; | |
695 | } else | |
696 | attr = acpi_get_dma_attr(ACPI_COMPANION(dev)); | |
697 | ||
698 | return attr; | |
699 | } | |
700 | EXPORT_SYMBOL_GPL(device_get_dma_attr); | |
701 | ||
4c96b7dc | 702 | /** |
2f710a3a | 703 | * device_get_phy_mode - Get phy mode for given device |
4c96b7dc JL |
704 | * @dev: Pointer to the given device |
705 | * | |
706 | * The function gets phy interface string from property 'phy-mode' or | |
707 | * 'phy-connection-type', and return its index in phy_modes table, or errno in | |
708 | * error case. | |
709 | */ | |
710 | int device_get_phy_mode(struct device *dev) | |
711 | { | |
712 | const char *pm; | |
713 | int err, i; | |
714 | ||
715 | err = device_property_read_string(dev, "phy-mode", &pm); | |
716 | if (err < 0) | |
717 | err = device_property_read_string(dev, | |
718 | "phy-connection-type", &pm); | |
719 | if (err < 0) | |
720 | return err; | |
721 | ||
722 | for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++) | |
723 | if (!strcasecmp(pm, phy_modes(i))) | |
724 | return i; | |
725 | ||
726 | return -ENODEV; | |
727 | } | |
728 | EXPORT_SYMBOL_GPL(device_get_phy_mode); | |
729 | ||
730 | static void *device_get_mac_addr(struct device *dev, | |
731 | const char *name, char *addr, | |
732 | int alen) | |
733 | { | |
734 | int ret = device_property_read_u8_array(dev, name, addr, alen); | |
735 | ||
2f710a3a | 736 | if (ret == 0 && alen == ETH_ALEN && is_valid_ether_addr(addr)) |
4c96b7dc JL |
737 | return addr; |
738 | return NULL; | |
739 | } | |
740 | ||
741 | /** | |
2f710a3a JL |
742 | * device_get_mac_address - Get the MAC for a given device |
743 | * @dev: Pointer to the device | |
744 | * @addr: Address of buffer to store the MAC in | |
745 | * @alen: Length of the buffer pointed to by addr, should be ETH_ALEN | |
746 | * | |
747 | * Search the firmware node for the best MAC address to use. 'mac-address' is | |
4c96b7dc JL |
748 | * checked first, because that is supposed to contain to "most recent" MAC |
749 | * address. If that isn't set, then 'local-mac-address' is checked next, | |
750 | * because that is the default address. If that isn't set, then the obsolete | |
751 | * 'address' is checked, just in case we're using an old device tree. | |
752 | * | |
753 | * Note that the 'address' property is supposed to contain a virtual address of | |
754 | * the register set, but some DTS files have redefined that property to be the | |
755 | * MAC address. | |
756 | * | |
757 | * All-zero MAC addresses are rejected, because those could be properties that | |
2f710a3a JL |
758 | * exist in the firmware tables, but were not updated by the firmware. For |
759 | * example, the DTS could define 'mac-address' and 'local-mac-address', with | |
760 | * zero MAC addresses. Some older U-Boots only initialized 'local-mac-address'. | |
761 | * In this case, the real MAC is in 'local-mac-address', and 'mac-address' | |
762 | * exists but is all zeros. | |
4c96b7dc JL |
763 | */ |
764 | void *device_get_mac_address(struct device *dev, char *addr, int alen) | |
765 | { | |
5b902d6f | 766 | char *res; |
4c96b7dc | 767 | |
5b902d6f JG |
768 | res = device_get_mac_addr(dev, "mac-address", addr, alen); |
769 | if (res) | |
770 | return res; | |
771 | ||
772 | res = device_get_mac_addr(dev, "local-mac-address", addr, alen); | |
773 | if (res) | |
774 | return res; | |
4c96b7dc JL |
775 | |
776 | return device_get_mac_addr(dev, "address", addr, alen); | |
777 | } | |
778 | EXPORT_SYMBOL(device_get_mac_address); |