]>
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 | ||
40 | static inline bool is_pset(struct fwnode_handle *fwnode) | |
41 | { | |
42 | return fwnode && fwnode->type == FWNODE_PDATA; | |
43 | } | |
44 | ||
45 | static inline struct property_set *to_pset(struct fwnode_handle *fwnode) | |
46 | { | |
47 | return is_pset(fwnode) ? | |
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 | ||
66 | static int pset_prop_read_array(struct property_set *pset, const char *name, | |
67 | enum dev_prop_type type, void *val, size_t nval) | |
68 | { | |
69 | struct property_entry *prop; | |
70 | unsigned int item_size; | |
71 | ||
72 | prop = pset_prop_get(pset, name); | |
73 | if (!prop) | |
74 | return -ENODATA; | |
75 | ||
76 | if (prop->type != type) | |
77 | return -EPROTO; | |
78 | ||
79 | if (!val) | |
80 | return prop->nval; | |
81 | ||
82 | if (prop->nval < nval) | |
83 | return -EOVERFLOW; | |
84 | ||
85 | switch (type) { | |
86 | case DEV_PROP_U8: | |
87 | item_size = sizeof(u8); | |
88 | break; | |
89 | case DEV_PROP_U16: | |
90 | item_size = sizeof(u16); | |
91 | break; | |
92 | case DEV_PROP_U32: | |
93 | item_size = sizeof(u32); | |
94 | break; | |
95 | case DEV_PROP_U64: | |
96 | item_size = sizeof(u64); | |
97 | break; | |
98 | case DEV_PROP_STRING: | |
99 | item_size = sizeof(const char *); | |
100 | break; | |
101 | default: | |
102 | return -EINVAL; | |
103 | } | |
104 | memcpy(val, prop->value.raw_data, nval * item_size); | |
105 | return 0; | |
106 | } | |
b31384fa | 107 | |
9017f252 RW |
108 | static inline struct fwnode_handle *dev_fwnode(struct device *dev) |
109 | { | |
110 | return IS_ENABLED(CONFIG_OF) && dev->of_node ? | |
111 | &dev->of_node->fwnode : dev->fwnode; | |
112 | } | |
b31384fa RW |
113 | |
114 | /** | |
115 | * device_property_present - check if a property of a device is present | |
116 | * @dev: Device whose property is being checked | |
117 | * @propname: Name of the property | |
118 | * | |
119 | * Check if property @propname is present in the device firmware description. | |
120 | */ | |
121 | bool device_property_present(struct device *dev, const char *propname) | |
122 | { | |
9017f252 | 123 | return fwnode_property_present(dev_fwnode(dev), propname); |
b31384fa RW |
124 | } |
125 | EXPORT_SYMBOL_GPL(device_property_present); | |
126 | ||
8a0662d9 RW |
127 | /** |
128 | * fwnode_property_present - check if a property of a firmware node is present | |
129 | * @fwnode: Firmware node whose property to check | |
130 | * @propname: Name of the property | |
131 | */ | |
132 | bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname) | |
133 | { | |
134 | if (is_of_node(fwnode)) | |
c181fb3e | 135 | return of_property_read_bool(to_of_node(fwnode), propname); |
8a0662d9 | 136 | else if (is_acpi_node(fwnode)) |
3a7a2ab8 | 137 | return !acpi_node_prop_get(fwnode, propname, NULL); |
8a0662d9 | 138 | |
16ba08d5 | 139 | return !!pset_prop_get(to_pset(fwnode), propname); |
8a0662d9 RW |
140 | } |
141 | EXPORT_SYMBOL_GPL(fwnode_property_present); | |
142 | ||
b31384fa RW |
143 | /** |
144 | * device_property_read_u8_array - return a u8 array property of a device | |
145 | * @dev: Device to get the property of | |
146 | * @propname: Name of the property | |
5c0acf3b | 147 | * @val: The values are stored here or %NULL to return the number of values |
b31384fa RW |
148 | * @nval: Size of the @val array |
149 | * | |
150 | * Function reads an array of u8 properties with @propname from the device | |
151 | * firmware description and stores them to @val if found. | |
152 | * | |
5c0acf3b AH |
153 | * Return: number of values if @val was %NULL, |
154 | * %0 if the property was found (success), | |
b31384fa RW |
155 | * %-EINVAL if given arguments are not valid, |
156 | * %-ENODATA if the property does not have a value, | |
157 | * %-EPROTO if the property is not an array of numbers, | |
158 | * %-EOVERFLOW if the size of the property is not as expected. | |
4fa7508e | 159 | * %-ENXIO if no suitable firmware interface is present. |
b31384fa RW |
160 | */ |
161 | int device_property_read_u8_array(struct device *dev, const char *propname, | |
162 | u8 *val, size_t nval) | |
163 | { | |
9017f252 | 164 | return fwnode_property_read_u8_array(dev_fwnode(dev), propname, val, nval); |
b31384fa RW |
165 | } |
166 | EXPORT_SYMBOL_GPL(device_property_read_u8_array); | |
167 | ||
168 | /** | |
169 | * device_property_read_u16_array - return a u16 array property of a device | |
170 | * @dev: Device to get the property of | |
171 | * @propname: Name of the property | |
5c0acf3b | 172 | * @val: The values are stored here or %NULL to return the number of values |
b31384fa RW |
173 | * @nval: Size of the @val array |
174 | * | |
175 | * Function reads an array of u16 properties with @propname from the device | |
176 | * firmware description and stores them to @val if found. | |
177 | * | |
5c0acf3b AH |
178 | * Return: number of values if @val was %NULL, |
179 | * %0 if the property was found (success), | |
b31384fa RW |
180 | * %-EINVAL if given arguments are not valid, |
181 | * %-ENODATA if the property does not have a value, | |
182 | * %-EPROTO if the property is not an array of numbers, | |
183 | * %-EOVERFLOW if the size of the property is not as expected. | |
4fa7508e | 184 | * %-ENXIO if no suitable firmware interface is present. |
b31384fa RW |
185 | */ |
186 | int device_property_read_u16_array(struct device *dev, const char *propname, | |
187 | u16 *val, size_t nval) | |
188 | { | |
9017f252 | 189 | return fwnode_property_read_u16_array(dev_fwnode(dev), propname, val, nval); |
b31384fa RW |
190 | } |
191 | EXPORT_SYMBOL_GPL(device_property_read_u16_array); | |
192 | ||
193 | /** | |
194 | * device_property_read_u32_array - return a u32 array property of a device | |
195 | * @dev: Device to get the property of | |
196 | * @propname: Name of the property | |
5c0acf3b | 197 | * @val: The values are stored here or %NULL to return the number of values |
b31384fa RW |
198 | * @nval: Size of the @val array |
199 | * | |
200 | * Function reads an array of u32 properties with @propname from the device | |
201 | * firmware description and stores them to @val if found. | |
202 | * | |
5c0acf3b AH |
203 | * Return: number of values if @val was %NULL, |
204 | * %0 if the property was found (success), | |
b31384fa RW |
205 | * %-EINVAL if given arguments are not valid, |
206 | * %-ENODATA if the property does not have a value, | |
207 | * %-EPROTO if the property is not an array of numbers, | |
208 | * %-EOVERFLOW if the size of the property is not as expected. | |
4fa7508e | 209 | * %-ENXIO if no suitable firmware interface is present. |
b31384fa RW |
210 | */ |
211 | int device_property_read_u32_array(struct device *dev, const char *propname, | |
212 | u32 *val, size_t nval) | |
213 | { | |
9017f252 | 214 | return fwnode_property_read_u32_array(dev_fwnode(dev), propname, val, nval); |
b31384fa RW |
215 | } |
216 | EXPORT_SYMBOL_GPL(device_property_read_u32_array); | |
217 | ||
218 | /** | |
219 | * device_property_read_u64_array - return a u64 array property of a device | |
220 | * @dev: Device to get the property of | |
221 | * @propname: Name of the property | |
5c0acf3b | 222 | * @val: The values are stored here or %NULL to return the number of values |
b31384fa RW |
223 | * @nval: Size of the @val array |
224 | * | |
225 | * Function reads an array of u64 properties with @propname from the device | |
226 | * firmware description and stores them to @val if found. | |
227 | * | |
5c0acf3b AH |
228 | * Return: number of values if @val was %NULL, |
229 | * %0 if the property was found (success), | |
b31384fa RW |
230 | * %-EINVAL if given arguments are not valid, |
231 | * %-ENODATA if the property does not have a value, | |
232 | * %-EPROTO if the property is not an array of numbers, | |
233 | * %-EOVERFLOW if the size of the property is not as expected. | |
4fa7508e | 234 | * %-ENXIO if no suitable firmware interface is present. |
b31384fa RW |
235 | */ |
236 | int device_property_read_u64_array(struct device *dev, const char *propname, | |
237 | u64 *val, size_t nval) | |
238 | { | |
9017f252 | 239 | return fwnode_property_read_u64_array(dev_fwnode(dev), propname, val, nval); |
b31384fa RW |
240 | } |
241 | EXPORT_SYMBOL_GPL(device_property_read_u64_array); | |
242 | ||
243 | /** | |
244 | * device_property_read_string_array - return a string array property of device | |
245 | * @dev: Device to get the property of | |
246 | * @propname: Name of the property | |
5c0acf3b | 247 | * @val: The values are stored here or %NULL to return the number of values |
b31384fa RW |
248 | * @nval: Size of the @val array |
249 | * | |
250 | * Function reads an array of string properties with @propname from the device | |
251 | * firmware description and stores them to @val if found. | |
252 | * | |
5c0acf3b AH |
253 | * Return: number of values if @val was %NULL, |
254 | * %0 if the property was found (success), | |
b31384fa RW |
255 | * %-EINVAL if given arguments are not valid, |
256 | * %-ENODATA if the property does not have a value, | |
257 | * %-EPROTO or %-EILSEQ if the property is not an array of strings, | |
258 | * %-EOVERFLOW if the size of the property is not as expected. | |
4fa7508e | 259 | * %-ENXIO if no suitable firmware interface is present. |
b31384fa RW |
260 | */ |
261 | int device_property_read_string_array(struct device *dev, const char *propname, | |
262 | const char **val, size_t nval) | |
263 | { | |
9017f252 | 264 | return fwnode_property_read_string_array(dev_fwnode(dev), propname, val, nval); |
b31384fa RW |
265 | } |
266 | EXPORT_SYMBOL_GPL(device_property_read_string_array); | |
267 | ||
268 | /** | |
269 | * device_property_read_string - return a string property of a device | |
270 | * @dev: Device to get the property of | |
271 | * @propname: Name of the property | |
272 | * @val: The value is stored here | |
273 | * | |
274 | * Function reads property @propname from the device firmware description and | |
275 | * stores the value into @val if found. The value is checked to be a string. | |
276 | * | |
277 | * Return: %0 if the property was found (success), | |
278 | * %-EINVAL if given arguments are not valid, | |
279 | * %-ENODATA if the property does not have a value, | |
280 | * %-EPROTO or %-EILSEQ if the property type is not a string. | |
4fa7508e | 281 | * %-ENXIO if no suitable firmware interface is present. |
b31384fa RW |
282 | */ |
283 | int device_property_read_string(struct device *dev, const char *propname, | |
284 | const char **val) | |
285 | { | |
9017f252 | 286 | return fwnode_property_read_string(dev_fwnode(dev), propname, val); |
b31384fa RW |
287 | } |
288 | EXPORT_SYMBOL_GPL(device_property_read_string); | |
8a0662d9 | 289 | |
9017f252 RW |
290 | #define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \ |
291 | (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \ | |
292 | : of_property_count_elems_of_size((node), (propname), sizeof(type)) | |
293 | ||
8a0662d9 RW |
294 | #define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \ |
295 | ({ \ | |
296 | int _ret_; \ | |
297 | if (is_of_node(_fwnode_)) \ | |
c181fb3e | 298 | _ret_ = OF_DEV_PROP_READ_ARRAY(to_of_node(_fwnode_), _propname_, \ |
8a0662d9 RW |
299 | _type_, _val_, _nval_); \ |
300 | else if (is_acpi_node(_fwnode_)) \ | |
3a7a2ab8 RW |
301 | _ret_ = acpi_node_prop_read(_fwnode_, _propname_, _proptype_, \ |
302 | _val_, _nval_); \ | |
4fa7508e | 303 | else if (is_pset(_fwnode_)) \ |
16ba08d5 RW |
304 | _ret_ = pset_prop_read_array(to_pset(_fwnode_), _propname_, \ |
305 | _proptype_, _val_, _nval_); \ | |
4fa7508e GR |
306 | else \ |
307 | _ret_ = -ENXIO; \ | |
8a0662d9 RW |
308 | _ret_; \ |
309 | }) | |
310 | ||
311 | /** | |
312 | * fwnode_property_read_u8_array - return a u8 array property of firmware node | |
313 | * @fwnode: Firmware node to get the property of | |
314 | * @propname: Name of the property | |
5c0acf3b | 315 | * @val: The values are stored here or %NULL to return the number of values |
8a0662d9 RW |
316 | * @nval: Size of the @val array |
317 | * | |
318 | * Read an array of u8 properties with @propname from @fwnode and stores them to | |
319 | * @val if found. | |
320 | * | |
5c0acf3b AH |
321 | * Return: number of values if @val was %NULL, |
322 | * %0 if the property was found (success), | |
8a0662d9 RW |
323 | * %-EINVAL if given arguments are not valid, |
324 | * %-ENODATA if the property does not have a value, | |
325 | * %-EPROTO if the property is not an array of numbers, | |
326 | * %-EOVERFLOW if the size of the property is not as expected, | |
327 | * %-ENXIO if no suitable firmware interface is present. | |
328 | */ | |
329 | int fwnode_property_read_u8_array(struct fwnode_handle *fwnode, | |
330 | const char *propname, u8 *val, size_t nval) | |
331 | { | |
332 | return FWNODE_PROP_READ_ARRAY(fwnode, propname, u8, DEV_PROP_U8, | |
333 | val, nval); | |
334 | } | |
335 | EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array); | |
336 | ||
337 | /** | |
338 | * fwnode_property_read_u16_array - return a u16 array property of firmware node | |
339 | * @fwnode: Firmware node to get the property of | |
340 | * @propname: Name of the property | |
5c0acf3b | 341 | * @val: The values are stored here or %NULL to return the number of values |
8a0662d9 RW |
342 | * @nval: Size of the @val array |
343 | * | |
344 | * Read an array of u16 properties with @propname from @fwnode and store them to | |
345 | * @val if found. | |
346 | * | |
5c0acf3b AH |
347 | * Return: number of values if @val was %NULL, |
348 | * %0 if the property was found (success), | |
8a0662d9 RW |
349 | * %-EINVAL if given arguments are not valid, |
350 | * %-ENODATA if the property does not have a value, | |
351 | * %-EPROTO if the property is not an array of numbers, | |
352 | * %-EOVERFLOW if the size of the property is not as expected, | |
353 | * %-ENXIO if no suitable firmware interface is present. | |
354 | */ | |
355 | int fwnode_property_read_u16_array(struct fwnode_handle *fwnode, | |
356 | const char *propname, u16 *val, size_t nval) | |
357 | { | |
358 | return FWNODE_PROP_READ_ARRAY(fwnode, propname, u16, DEV_PROP_U16, | |
359 | val, nval); | |
360 | } | |
361 | EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array); | |
362 | ||
363 | /** | |
364 | * fwnode_property_read_u32_array - return a u32 array property of firmware node | |
365 | * @fwnode: Firmware node to get the property of | |
366 | * @propname: Name of the property | |
5c0acf3b | 367 | * @val: The values are stored here or %NULL to return the number of values |
8a0662d9 RW |
368 | * @nval: Size of the @val array |
369 | * | |
370 | * Read an array of u32 properties with @propname from @fwnode store them to | |
371 | * @val if found. | |
372 | * | |
5c0acf3b AH |
373 | * Return: number of values if @val was %NULL, |
374 | * %0 if the property was found (success), | |
8a0662d9 RW |
375 | * %-EINVAL if given arguments are not valid, |
376 | * %-ENODATA if the property does not have a value, | |
377 | * %-EPROTO if the property is not an array of numbers, | |
378 | * %-EOVERFLOW if the size of the property is not as expected, | |
379 | * %-ENXIO if no suitable firmware interface is present. | |
380 | */ | |
381 | int fwnode_property_read_u32_array(struct fwnode_handle *fwnode, | |
382 | const char *propname, u32 *val, size_t nval) | |
383 | { | |
384 | return FWNODE_PROP_READ_ARRAY(fwnode, propname, u32, DEV_PROP_U32, | |
385 | val, nval); | |
386 | } | |
387 | EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array); | |
388 | ||
389 | /** | |
390 | * fwnode_property_read_u64_array - return a u64 array property firmware node | |
391 | * @fwnode: Firmware node to get the property of | |
392 | * @propname: Name of the property | |
5c0acf3b | 393 | * @val: The values are stored here or %NULL to return the number of values |
8a0662d9 RW |
394 | * @nval: Size of the @val array |
395 | * | |
396 | * Read an array of u64 properties with @propname from @fwnode and store them to | |
397 | * @val if found. | |
398 | * | |
5c0acf3b AH |
399 | * Return: number of values if @val was %NULL, |
400 | * %0 if the property was found (success), | |
8a0662d9 RW |
401 | * %-EINVAL if given arguments are not valid, |
402 | * %-ENODATA if the property does not have a value, | |
403 | * %-EPROTO if the property is not an array of numbers, | |
404 | * %-EOVERFLOW if the size of the property is not as expected, | |
405 | * %-ENXIO if no suitable firmware interface is present. | |
406 | */ | |
407 | int fwnode_property_read_u64_array(struct fwnode_handle *fwnode, | |
408 | const char *propname, u64 *val, size_t nval) | |
409 | { | |
410 | return FWNODE_PROP_READ_ARRAY(fwnode, propname, u64, DEV_PROP_U64, | |
411 | val, nval); | |
412 | } | |
413 | EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array); | |
414 | ||
415 | /** | |
416 | * fwnode_property_read_string_array - return string array property of a node | |
417 | * @fwnode: Firmware node to get the property of | |
418 | * @propname: Name of the property | |
5c0acf3b | 419 | * @val: The values are stored here or %NULL to return the number of values |
8a0662d9 RW |
420 | * @nval: Size of the @val array |
421 | * | |
422 | * Read an string list property @propname from the given firmware node and store | |
423 | * them to @val if found. | |
424 | * | |
5c0acf3b AH |
425 | * Return: number of values if @val was %NULL, |
426 | * %0 if the property was found (success), | |
8a0662d9 RW |
427 | * %-EINVAL if given arguments are not valid, |
428 | * %-ENODATA if the property does not have a value, | |
429 | * %-EPROTO if the property is not an array of strings, | |
430 | * %-EOVERFLOW if the size of the property is not as expected, | |
431 | * %-ENXIO if no suitable firmware interface is present. | |
432 | */ | |
433 | int fwnode_property_read_string_array(struct fwnode_handle *fwnode, | |
434 | const char *propname, const char **val, | |
435 | size_t nval) | |
436 | { | |
437 | if (is_of_node(fwnode)) | |
f42712a9 | 438 | return val ? |
c181fb3e AS |
439 | of_property_read_string_array(to_of_node(fwnode), |
440 | propname, val, nval) : | |
441 | of_property_count_strings(to_of_node(fwnode), propname); | |
8a0662d9 | 442 | else if (is_acpi_node(fwnode)) |
3a7a2ab8 RW |
443 | return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING, |
444 | val, nval); | |
4fa7508e GR |
445 | else if (is_pset(fwnode)) |
446 | return pset_prop_read_array(to_pset(fwnode), propname, | |
447 | DEV_PROP_STRING, val, nval); | |
448 | return -ENXIO; | |
8a0662d9 RW |
449 | } |
450 | EXPORT_SYMBOL_GPL(fwnode_property_read_string_array); | |
451 | ||
452 | /** | |
453 | * fwnode_property_read_string - return a string property of a firmware node | |
454 | * @fwnode: Firmware node to get the property of | |
455 | * @propname: Name of the property | |
456 | * @val: The value is stored here | |
457 | * | |
458 | * Read property @propname from the given firmware node and store the value into | |
459 | * @val if found. The value is checked to be a string. | |
460 | * | |
461 | * Return: %0 if the property was found (success), | |
462 | * %-EINVAL if given arguments are not valid, | |
463 | * %-ENODATA if the property does not have a value, | |
464 | * %-EPROTO or %-EILSEQ if the property is not a string, | |
465 | * %-ENXIO if no suitable firmware interface is present. | |
466 | */ | |
467 | int fwnode_property_read_string(struct fwnode_handle *fwnode, | |
468 | const char *propname, const char **val) | |
469 | { | |
470 | if (is_of_node(fwnode)) | |
c181fb3e | 471 | return of_property_read_string(to_of_node(fwnode), propname, val); |
8a0662d9 | 472 | else if (is_acpi_node(fwnode)) |
3a7a2ab8 RW |
473 | return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING, |
474 | val, 1); | |
8a0662d9 | 475 | |
4f73b065 AS |
476 | return pset_prop_read_array(to_pset(fwnode), propname, |
477 | DEV_PROP_STRING, val, 1); | |
8a0662d9 RW |
478 | } |
479 | EXPORT_SYMBOL_GPL(fwnode_property_read_string); | |
480 | ||
481 | /** | |
482 | * device_get_next_child_node - Return the next child node handle for a device | |
483 | * @dev: Device to find the next child node for. | |
484 | * @child: Handle to one of the device's child nodes or a null handle. | |
485 | */ | |
486 | struct fwnode_handle *device_get_next_child_node(struct device *dev, | |
487 | struct fwnode_handle *child) | |
488 | { | |
489 | if (IS_ENABLED(CONFIG_OF) && dev->of_node) { | |
490 | struct device_node *node; | |
491 | ||
c181fb3e | 492 | node = of_get_next_available_child(dev->of_node, to_of_node(child)); |
8a0662d9 RW |
493 | if (node) |
494 | return &node->fwnode; | |
495 | } else if (IS_ENABLED(CONFIG_ACPI)) { | |
496 | struct acpi_device *node; | |
497 | ||
3a7a2ab8 | 498 | node = acpi_get_next_child(dev, to_acpi_device_node(child)); |
8a0662d9 RW |
499 | if (node) |
500 | return acpi_fwnode_handle(node); | |
501 | } | |
502 | return NULL; | |
503 | } | |
504 | EXPORT_SYMBOL_GPL(device_get_next_child_node); | |
505 | ||
506 | /** | |
507 | * fwnode_handle_put - Drop reference to a device node | |
508 | * @fwnode: Pointer to the device node to drop the reference to. | |
509 | * | |
510 | * This has to be used when terminating device_for_each_child_node() iteration | |
511 | * with break or return to prevent stale device node references from being left | |
512 | * behind. | |
513 | */ | |
514 | void fwnode_handle_put(struct fwnode_handle *fwnode) | |
515 | { | |
516 | if (is_of_node(fwnode)) | |
c181fb3e | 517 | of_node_put(to_of_node(fwnode)); |
8a0662d9 RW |
518 | } |
519 | EXPORT_SYMBOL_GPL(fwnode_handle_put); | |
520 | ||
521 | /** | |
522 | * device_get_child_node_count - return the number of child nodes for device | |
523 | * @dev: Device to cound the child nodes for | |
524 | */ | |
525 | unsigned int device_get_child_node_count(struct device *dev) | |
526 | { | |
527 | struct fwnode_handle *child; | |
528 | unsigned int count = 0; | |
529 | ||
530 | device_for_each_child_node(dev, child) | |
531 | count++; | |
532 | ||
533 | return count; | |
534 | } | |
535 | EXPORT_SYMBOL_GPL(device_get_child_node_count); | |
05ca5560 SS |
536 | |
537 | bool device_dma_is_coherent(struct device *dev) | |
538 | { | |
539 | bool coherent = false; | |
540 | ||
541 | if (IS_ENABLED(CONFIG_OF) && dev->of_node) | |
542 | coherent = of_dma_is_coherent(dev->of_node); | |
543 | else | |
544 | acpi_check_dma(ACPI_COMPANION(dev), &coherent); | |
545 | ||
546 | return coherent; | |
547 | } | |
548 | EXPORT_SYMBOL_GPL(device_dma_is_coherent); | |
4c96b7dc JL |
549 | |
550 | /** | |
2f710a3a | 551 | * device_get_phy_mode - Get phy mode for given device |
4c96b7dc JL |
552 | * @dev: Pointer to the given device |
553 | * | |
554 | * The function gets phy interface string from property 'phy-mode' or | |
555 | * 'phy-connection-type', and return its index in phy_modes table, or errno in | |
556 | * error case. | |
557 | */ | |
558 | int device_get_phy_mode(struct device *dev) | |
559 | { | |
560 | const char *pm; | |
561 | int err, i; | |
562 | ||
563 | err = device_property_read_string(dev, "phy-mode", &pm); | |
564 | if (err < 0) | |
565 | err = device_property_read_string(dev, | |
566 | "phy-connection-type", &pm); | |
567 | if (err < 0) | |
568 | return err; | |
569 | ||
570 | for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++) | |
571 | if (!strcasecmp(pm, phy_modes(i))) | |
572 | return i; | |
573 | ||
574 | return -ENODEV; | |
575 | } | |
576 | EXPORT_SYMBOL_GPL(device_get_phy_mode); | |
577 | ||
578 | static void *device_get_mac_addr(struct device *dev, | |
579 | const char *name, char *addr, | |
580 | int alen) | |
581 | { | |
582 | int ret = device_property_read_u8_array(dev, name, addr, alen); | |
583 | ||
2f710a3a | 584 | if (ret == 0 && alen == ETH_ALEN && is_valid_ether_addr(addr)) |
4c96b7dc JL |
585 | return addr; |
586 | return NULL; | |
587 | } | |
588 | ||
589 | /** | |
2f710a3a JL |
590 | * device_get_mac_address - Get the MAC for a given device |
591 | * @dev: Pointer to the device | |
592 | * @addr: Address of buffer to store the MAC in | |
593 | * @alen: Length of the buffer pointed to by addr, should be ETH_ALEN | |
594 | * | |
595 | * Search the firmware node for the best MAC address to use. 'mac-address' is | |
4c96b7dc JL |
596 | * checked first, because that is supposed to contain to "most recent" MAC |
597 | * address. If that isn't set, then 'local-mac-address' is checked next, | |
598 | * because that is the default address. If that isn't set, then the obsolete | |
599 | * 'address' is checked, just in case we're using an old device tree. | |
600 | * | |
601 | * Note that the 'address' property is supposed to contain a virtual address of | |
602 | * the register set, but some DTS files have redefined that property to be the | |
603 | * MAC address. | |
604 | * | |
605 | * All-zero MAC addresses are rejected, because those could be properties that | |
2f710a3a JL |
606 | * exist in the firmware tables, but were not updated by the firmware. For |
607 | * example, the DTS could define 'mac-address' and 'local-mac-address', with | |
608 | * zero MAC addresses. Some older U-Boots only initialized 'local-mac-address'. | |
609 | * In this case, the real MAC is in 'local-mac-address', and 'mac-address' | |
610 | * exists but is all zeros. | |
4c96b7dc JL |
611 | */ |
612 | void *device_get_mac_address(struct device *dev, char *addr, int alen) | |
613 | { | |
5b902d6f | 614 | char *res; |
4c96b7dc | 615 | |
5b902d6f JG |
616 | res = device_get_mac_addr(dev, "mac-address", addr, alen); |
617 | if (res) | |
618 | return res; | |
619 | ||
620 | res = device_get_mac_addr(dev, "local-mac-address", addr, alen); | |
621 | if (res) | |
622 | return res; | |
4c96b7dc JL |
623 | |
624 | return device_get_mac_addr(dev, "address", addr, alen); | |
625 | } | |
626 | EXPORT_SYMBOL(device_get_mac_address); |