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 RW |
18 | #include <linux/property.h> |
19 | ||
20 | /** | |
21 | * device_add_property_set - Add a collection of properties to a device object. | |
22 | * @dev: Device to add properties to. | |
23 | * @pset: Collection of properties to add. | |
24 | * | |
25 | * Associate a collection of device properties represented by @pset with @dev | |
26 | * as its secondary firmware node. | |
27 | */ | |
28 | void device_add_property_set(struct device *dev, struct property_set *pset) | |
29 | { | |
30 | if (pset) | |
31 | pset->fwnode.type = FWNODE_PDATA; | |
32 | ||
33 | set_secondary_fwnode(dev, &pset->fwnode); | |
34 | } | |
35 | EXPORT_SYMBOL_GPL(device_add_property_set); | |
36 | ||
37 | static inline bool is_pset(struct fwnode_handle *fwnode) | |
38 | { | |
39 | return fwnode && fwnode->type == FWNODE_PDATA; | |
40 | } | |
41 | ||
42 | static inline struct property_set *to_pset(struct fwnode_handle *fwnode) | |
43 | { | |
44 | return is_pset(fwnode) ? | |
45 | container_of(fwnode, struct property_set, fwnode) : NULL; | |
46 | } | |
47 | ||
48 | static struct property_entry *pset_prop_get(struct property_set *pset, | |
49 | const char *name) | |
50 | { | |
51 | struct property_entry *prop; | |
52 | ||
53 | if (!pset || !pset->properties) | |
54 | return NULL; | |
55 | ||
56 | for (prop = pset->properties; prop->name; prop++) | |
57 | if (!strcmp(name, prop->name)) | |
58 | return prop; | |
59 | ||
60 | return NULL; | |
61 | } | |
62 | ||
63 | static int pset_prop_read_array(struct property_set *pset, const char *name, | |
64 | enum dev_prop_type type, void *val, size_t nval) | |
65 | { | |
66 | struct property_entry *prop; | |
67 | unsigned int item_size; | |
68 | ||
69 | prop = pset_prop_get(pset, name); | |
70 | if (!prop) | |
71 | return -ENODATA; | |
72 | ||
73 | if (prop->type != type) | |
74 | return -EPROTO; | |
75 | ||
76 | if (!val) | |
77 | return prop->nval; | |
78 | ||
79 | if (prop->nval < nval) | |
80 | return -EOVERFLOW; | |
81 | ||
82 | switch (type) { | |
83 | case DEV_PROP_U8: | |
84 | item_size = sizeof(u8); | |
85 | break; | |
86 | case DEV_PROP_U16: | |
87 | item_size = sizeof(u16); | |
88 | break; | |
89 | case DEV_PROP_U32: | |
90 | item_size = sizeof(u32); | |
91 | break; | |
92 | case DEV_PROP_U64: | |
93 | item_size = sizeof(u64); | |
94 | break; | |
95 | case DEV_PROP_STRING: | |
96 | item_size = sizeof(const char *); | |
97 | break; | |
98 | default: | |
99 | return -EINVAL; | |
100 | } | |
101 | memcpy(val, prop->value.raw_data, nval * item_size); | |
102 | return 0; | |
103 | } | |
b31384fa | 104 | |
9017f252 RW |
105 | static inline struct fwnode_handle *dev_fwnode(struct device *dev) |
106 | { | |
107 | return IS_ENABLED(CONFIG_OF) && dev->of_node ? | |
108 | &dev->of_node->fwnode : dev->fwnode; | |
109 | } | |
b31384fa RW |
110 | |
111 | /** | |
112 | * device_property_present - check if a property of a device is present | |
113 | * @dev: Device whose property is being checked | |
114 | * @propname: Name of the property | |
115 | * | |
116 | * Check if property @propname is present in the device firmware description. | |
117 | */ | |
118 | bool device_property_present(struct device *dev, const char *propname) | |
119 | { | |
9017f252 | 120 | return fwnode_property_present(dev_fwnode(dev), propname); |
b31384fa RW |
121 | } |
122 | EXPORT_SYMBOL_GPL(device_property_present); | |
123 | ||
8a0662d9 RW |
124 | /** |
125 | * fwnode_property_present - check if a property of a firmware node is present | |
126 | * @fwnode: Firmware node whose property to check | |
127 | * @propname: Name of the property | |
128 | */ | |
129 | bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname) | |
130 | { | |
131 | if (is_of_node(fwnode)) | |
c181fb3e | 132 | return of_property_read_bool(to_of_node(fwnode), propname); |
8a0662d9 | 133 | else if (is_acpi_node(fwnode)) |
c181fb3e | 134 | return !acpi_dev_prop_get(to_acpi_node(fwnode), propname, NULL); |
8a0662d9 | 135 | |
16ba08d5 | 136 | return !!pset_prop_get(to_pset(fwnode), propname); |
8a0662d9 RW |
137 | } |
138 | EXPORT_SYMBOL_GPL(fwnode_property_present); | |
139 | ||
b31384fa RW |
140 | /** |
141 | * device_property_read_u8_array - return a u8 array property of a device | |
142 | * @dev: Device to get the property of | |
143 | * @propname: Name of the property | |
5c0acf3b | 144 | * @val: The values are stored here or %NULL to return the number of values |
b31384fa RW |
145 | * @nval: Size of the @val array |
146 | * | |
147 | * Function reads an array of u8 properties with @propname from the device | |
148 | * firmware description and stores them to @val if found. | |
149 | * | |
5c0acf3b AH |
150 | * Return: number of values if @val was %NULL, |
151 | * %0 if the property was found (success), | |
b31384fa RW |
152 | * %-EINVAL if given arguments are not valid, |
153 | * %-ENODATA if the property does not have a value, | |
154 | * %-EPROTO if the property is not an array of numbers, | |
155 | * %-EOVERFLOW if the size of the property is not as expected. | |
156 | */ | |
157 | int device_property_read_u8_array(struct device *dev, const char *propname, | |
158 | u8 *val, size_t nval) | |
159 | { | |
9017f252 | 160 | return fwnode_property_read_u8_array(dev_fwnode(dev), propname, val, nval); |
b31384fa RW |
161 | } |
162 | EXPORT_SYMBOL_GPL(device_property_read_u8_array); | |
163 | ||
164 | /** | |
165 | * device_property_read_u16_array - return a u16 array property of a device | |
166 | * @dev: Device to get the property of | |
167 | * @propname: Name of the property | |
5c0acf3b | 168 | * @val: The values are stored here or %NULL to return the number of values |
b31384fa RW |
169 | * @nval: Size of the @val array |
170 | * | |
171 | * Function reads an array of u16 properties with @propname from the device | |
172 | * firmware description and stores them to @val if found. | |
173 | * | |
5c0acf3b AH |
174 | * Return: number of values if @val was %NULL, |
175 | * %0 if the property was found (success), | |
b31384fa RW |
176 | * %-EINVAL if given arguments are not valid, |
177 | * %-ENODATA if the property does not have a value, | |
178 | * %-EPROTO if the property is not an array of numbers, | |
179 | * %-EOVERFLOW if the size of the property is not as expected. | |
180 | */ | |
181 | int device_property_read_u16_array(struct device *dev, const char *propname, | |
182 | u16 *val, size_t nval) | |
183 | { | |
9017f252 | 184 | return fwnode_property_read_u16_array(dev_fwnode(dev), propname, val, nval); |
b31384fa RW |
185 | } |
186 | EXPORT_SYMBOL_GPL(device_property_read_u16_array); | |
187 | ||
188 | /** | |
189 | * device_property_read_u32_array - return a u32 array property of a device | |
190 | * @dev: Device to get the property of | |
191 | * @propname: Name of the property | |
5c0acf3b | 192 | * @val: The values are stored here or %NULL to return the number of values |
b31384fa RW |
193 | * @nval: Size of the @val array |
194 | * | |
195 | * Function reads an array of u32 properties with @propname from the device | |
196 | * firmware description and stores them to @val if found. | |
197 | * | |
5c0acf3b AH |
198 | * Return: number of values if @val was %NULL, |
199 | * %0 if the property was found (success), | |
b31384fa RW |
200 | * %-EINVAL if given arguments are not valid, |
201 | * %-ENODATA if the property does not have a value, | |
202 | * %-EPROTO if the property is not an array of numbers, | |
203 | * %-EOVERFLOW if the size of the property is not as expected. | |
204 | */ | |
205 | int device_property_read_u32_array(struct device *dev, const char *propname, | |
206 | u32 *val, size_t nval) | |
207 | { | |
9017f252 | 208 | return fwnode_property_read_u32_array(dev_fwnode(dev), propname, val, nval); |
b31384fa RW |
209 | } |
210 | EXPORT_SYMBOL_GPL(device_property_read_u32_array); | |
211 | ||
212 | /** | |
213 | * device_property_read_u64_array - return a u64 array property of a device | |
214 | * @dev: Device to get the property of | |
215 | * @propname: Name of the property | |
5c0acf3b | 216 | * @val: The values are stored here or %NULL to return the number of values |
b31384fa RW |
217 | * @nval: Size of the @val array |
218 | * | |
219 | * Function reads an array of u64 properties with @propname from the device | |
220 | * firmware description and stores them to @val if found. | |
221 | * | |
5c0acf3b AH |
222 | * Return: number of values if @val was %NULL, |
223 | * %0 if the property was found (success), | |
b31384fa RW |
224 | * %-EINVAL if given arguments are not valid, |
225 | * %-ENODATA if the property does not have a value, | |
226 | * %-EPROTO if the property is not an array of numbers, | |
227 | * %-EOVERFLOW if the size of the property is not as expected. | |
228 | */ | |
229 | int device_property_read_u64_array(struct device *dev, const char *propname, | |
230 | u64 *val, size_t nval) | |
231 | { | |
9017f252 | 232 | return fwnode_property_read_u64_array(dev_fwnode(dev), propname, val, nval); |
b31384fa RW |
233 | } |
234 | EXPORT_SYMBOL_GPL(device_property_read_u64_array); | |
235 | ||
236 | /** | |
237 | * device_property_read_string_array - return a string array property of device | |
238 | * @dev: Device to get the property of | |
239 | * @propname: Name of the property | |
5c0acf3b | 240 | * @val: The values are stored here or %NULL to return the number of values |
b31384fa RW |
241 | * @nval: Size of the @val array |
242 | * | |
243 | * Function reads an array of string properties with @propname from the device | |
244 | * firmware description and stores them to @val if found. | |
245 | * | |
5c0acf3b AH |
246 | * Return: number of values if @val was %NULL, |
247 | * %0 if the property was found (success), | |
b31384fa RW |
248 | * %-EINVAL if given arguments are not valid, |
249 | * %-ENODATA if the property does not have a value, | |
250 | * %-EPROTO or %-EILSEQ if the property is not an array of strings, | |
251 | * %-EOVERFLOW if the size of the property is not as expected. | |
252 | */ | |
253 | int device_property_read_string_array(struct device *dev, const char *propname, | |
254 | const char **val, size_t nval) | |
255 | { | |
9017f252 | 256 | return fwnode_property_read_string_array(dev_fwnode(dev), propname, val, nval); |
b31384fa RW |
257 | } |
258 | EXPORT_SYMBOL_GPL(device_property_read_string_array); | |
259 | ||
260 | /** | |
261 | * device_property_read_string - return a string property of a device | |
262 | * @dev: Device to get the property of | |
263 | * @propname: Name of the property | |
264 | * @val: The value is stored here | |
265 | * | |
266 | * Function reads property @propname from the device firmware description and | |
267 | * stores the value into @val if found. The value is checked to be a string. | |
268 | * | |
269 | * Return: %0 if the property was found (success), | |
270 | * %-EINVAL if given arguments are not valid, | |
271 | * %-ENODATA if the property does not have a value, | |
272 | * %-EPROTO or %-EILSEQ if the property type is not a string. | |
273 | */ | |
274 | int device_property_read_string(struct device *dev, const char *propname, | |
275 | const char **val) | |
276 | { | |
9017f252 | 277 | return fwnode_property_read_string(dev_fwnode(dev), propname, val); |
b31384fa RW |
278 | } |
279 | EXPORT_SYMBOL_GPL(device_property_read_string); | |
8a0662d9 | 280 | |
9017f252 RW |
281 | #define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \ |
282 | (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \ | |
283 | : of_property_count_elems_of_size((node), (propname), sizeof(type)) | |
284 | ||
8a0662d9 RW |
285 | #define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \ |
286 | ({ \ | |
287 | int _ret_; \ | |
288 | if (is_of_node(_fwnode_)) \ | |
c181fb3e | 289 | _ret_ = OF_DEV_PROP_READ_ARRAY(to_of_node(_fwnode_), _propname_, \ |
8a0662d9 RW |
290 | _type_, _val_, _nval_); \ |
291 | else if (is_acpi_node(_fwnode_)) \ | |
c181fb3e | 292 | _ret_ = acpi_dev_prop_read(to_acpi_node(_fwnode_), _propname_, \ |
8a0662d9 RW |
293 | _proptype_, _val_, _nval_); \ |
294 | else \ | |
16ba08d5 RW |
295 | _ret_ = pset_prop_read_array(to_pset(_fwnode_), _propname_, \ |
296 | _proptype_, _val_, _nval_); \ | |
8a0662d9 RW |
297 | _ret_; \ |
298 | }) | |
299 | ||
300 | /** | |
301 | * fwnode_property_read_u8_array - return a u8 array property of firmware node | |
302 | * @fwnode: Firmware node to get the property of | |
303 | * @propname: Name of the property | |
5c0acf3b | 304 | * @val: The values are stored here or %NULL to return the number of values |
8a0662d9 RW |
305 | * @nval: Size of the @val array |
306 | * | |
307 | * Read an array of u8 properties with @propname from @fwnode and stores them to | |
308 | * @val if found. | |
309 | * | |
5c0acf3b AH |
310 | * Return: number of values if @val was %NULL, |
311 | * %0 if the property was found (success), | |
8a0662d9 RW |
312 | * %-EINVAL if given arguments are not valid, |
313 | * %-ENODATA if the property does not have a value, | |
314 | * %-EPROTO if the property is not an array of numbers, | |
315 | * %-EOVERFLOW if the size of the property is not as expected, | |
316 | * %-ENXIO if no suitable firmware interface is present. | |
317 | */ | |
318 | int fwnode_property_read_u8_array(struct fwnode_handle *fwnode, | |
319 | const char *propname, u8 *val, size_t nval) | |
320 | { | |
321 | return FWNODE_PROP_READ_ARRAY(fwnode, propname, u8, DEV_PROP_U8, | |
322 | val, nval); | |
323 | } | |
324 | EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array); | |
325 | ||
326 | /** | |
327 | * fwnode_property_read_u16_array - return a u16 array property of firmware node | |
328 | * @fwnode: Firmware node to get the property of | |
329 | * @propname: Name of the property | |
5c0acf3b | 330 | * @val: The values are stored here or %NULL to return the number of values |
8a0662d9 RW |
331 | * @nval: Size of the @val array |
332 | * | |
333 | * Read an array of u16 properties with @propname from @fwnode and store them to | |
334 | * @val if found. | |
335 | * | |
5c0acf3b AH |
336 | * Return: number of values if @val was %NULL, |
337 | * %0 if the property was found (success), | |
8a0662d9 RW |
338 | * %-EINVAL if given arguments are not valid, |
339 | * %-ENODATA if the property does not have a value, | |
340 | * %-EPROTO if the property is not an array of numbers, | |
341 | * %-EOVERFLOW if the size of the property is not as expected, | |
342 | * %-ENXIO if no suitable firmware interface is present. | |
343 | */ | |
344 | int fwnode_property_read_u16_array(struct fwnode_handle *fwnode, | |
345 | const char *propname, u16 *val, size_t nval) | |
346 | { | |
347 | return FWNODE_PROP_READ_ARRAY(fwnode, propname, u16, DEV_PROP_U16, | |
348 | val, nval); | |
349 | } | |
350 | EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array); | |
351 | ||
352 | /** | |
353 | * fwnode_property_read_u32_array - return a u32 array property of firmware node | |
354 | * @fwnode: Firmware node to get the property of | |
355 | * @propname: Name of the property | |
5c0acf3b | 356 | * @val: The values are stored here or %NULL to return the number of values |
8a0662d9 RW |
357 | * @nval: Size of the @val array |
358 | * | |
359 | * Read an array of u32 properties with @propname from @fwnode store them to | |
360 | * @val if found. | |
361 | * | |
5c0acf3b AH |
362 | * Return: number of values if @val was %NULL, |
363 | * %0 if the property was found (success), | |
8a0662d9 RW |
364 | * %-EINVAL if given arguments are not valid, |
365 | * %-ENODATA if the property does not have a value, | |
366 | * %-EPROTO if the property is not an array of numbers, | |
367 | * %-EOVERFLOW if the size of the property is not as expected, | |
368 | * %-ENXIO if no suitable firmware interface is present. | |
369 | */ | |
370 | int fwnode_property_read_u32_array(struct fwnode_handle *fwnode, | |
371 | const char *propname, u32 *val, size_t nval) | |
372 | { | |
373 | return FWNODE_PROP_READ_ARRAY(fwnode, propname, u32, DEV_PROP_U32, | |
374 | val, nval); | |
375 | } | |
376 | EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array); | |
377 | ||
378 | /** | |
379 | * fwnode_property_read_u64_array - return a u64 array property firmware node | |
380 | * @fwnode: Firmware node to get the property of | |
381 | * @propname: Name of the property | |
5c0acf3b | 382 | * @val: The values are stored here or %NULL to return the number of values |
8a0662d9 RW |
383 | * @nval: Size of the @val array |
384 | * | |
385 | * Read an array of u64 properties with @propname from @fwnode and store them to | |
386 | * @val if found. | |
387 | * | |
5c0acf3b AH |
388 | * Return: number of values if @val was %NULL, |
389 | * %0 if the property was found (success), | |
8a0662d9 RW |
390 | * %-EINVAL if given arguments are not valid, |
391 | * %-ENODATA if the property does not have a value, | |
392 | * %-EPROTO if the property is not an array of numbers, | |
393 | * %-EOVERFLOW if the size of the property is not as expected, | |
394 | * %-ENXIO if no suitable firmware interface is present. | |
395 | */ | |
396 | int fwnode_property_read_u64_array(struct fwnode_handle *fwnode, | |
397 | const char *propname, u64 *val, size_t nval) | |
398 | { | |
399 | return FWNODE_PROP_READ_ARRAY(fwnode, propname, u64, DEV_PROP_U64, | |
400 | val, nval); | |
401 | } | |
402 | EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array); | |
403 | ||
404 | /** | |
405 | * fwnode_property_read_string_array - return string array property of a node | |
406 | * @fwnode: Firmware node to get the property of | |
407 | * @propname: Name of the property | |
5c0acf3b | 408 | * @val: The values are stored here or %NULL to return the number of values |
8a0662d9 RW |
409 | * @nval: Size of the @val array |
410 | * | |
411 | * Read an string list property @propname from the given firmware node and store | |
412 | * them to @val if found. | |
413 | * | |
5c0acf3b AH |
414 | * Return: number of values if @val was %NULL, |
415 | * %0 if the property was found (success), | |
8a0662d9 RW |
416 | * %-EINVAL if given arguments are not valid, |
417 | * %-ENODATA if the property does not have a value, | |
418 | * %-EPROTO if the property is not an array of strings, | |
419 | * %-EOVERFLOW if the size of the property is not as expected, | |
420 | * %-ENXIO if no suitable firmware interface is present. | |
421 | */ | |
422 | int fwnode_property_read_string_array(struct fwnode_handle *fwnode, | |
423 | const char *propname, const char **val, | |
424 | size_t nval) | |
425 | { | |
426 | if (is_of_node(fwnode)) | |
f42712a9 | 427 | return val ? |
c181fb3e AS |
428 | of_property_read_string_array(to_of_node(fwnode), |
429 | propname, val, nval) : | |
430 | of_property_count_strings(to_of_node(fwnode), propname); | |
8a0662d9 | 431 | else if (is_acpi_node(fwnode)) |
c181fb3e | 432 | return acpi_dev_prop_read(to_acpi_node(fwnode), propname, |
8a0662d9 RW |
433 | DEV_PROP_STRING, val, nval); |
434 | ||
16ba08d5 RW |
435 | return pset_prop_read_array(to_pset(fwnode), propname, |
436 | DEV_PROP_STRING, val, nval); | |
8a0662d9 RW |
437 | } |
438 | EXPORT_SYMBOL_GPL(fwnode_property_read_string_array); | |
439 | ||
440 | /** | |
441 | * fwnode_property_read_string - return a string property of a firmware node | |
442 | * @fwnode: Firmware node to get the property of | |
443 | * @propname: Name of the property | |
444 | * @val: The value is stored here | |
445 | * | |
446 | * Read property @propname from the given firmware node and store the value into | |
447 | * @val if found. The value is checked to be a string. | |
448 | * | |
449 | * Return: %0 if the property was found (success), | |
450 | * %-EINVAL if given arguments are not valid, | |
451 | * %-ENODATA if the property does not have a value, | |
452 | * %-EPROTO or %-EILSEQ if the property is not a string, | |
453 | * %-ENXIO if no suitable firmware interface is present. | |
454 | */ | |
455 | int fwnode_property_read_string(struct fwnode_handle *fwnode, | |
456 | const char *propname, const char **val) | |
457 | { | |
458 | if (is_of_node(fwnode)) | |
c181fb3e | 459 | return of_property_read_string(to_of_node(fwnode), propname, val); |
8a0662d9 | 460 | else if (is_acpi_node(fwnode)) |
c181fb3e | 461 | return acpi_dev_prop_read(to_acpi_node(fwnode), propname, |
8a0662d9 RW |
462 | DEV_PROP_STRING, val, 1); |
463 | ||
464 | return -ENXIO; | |
465 | } | |
466 | EXPORT_SYMBOL_GPL(fwnode_property_read_string); | |
467 | ||
468 | /** | |
469 | * device_get_next_child_node - Return the next child node handle for a device | |
470 | * @dev: Device to find the next child node for. | |
471 | * @child: Handle to one of the device's child nodes or a null handle. | |
472 | */ | |
473 | struct fwnode_handle *device_get_next_child_node(struct device *dev, | |
474 | struct fwnode_handle *child) | |
475 | { | |
476 | if (IS_ENABLED(CONFIG_OF) && dev->of_node) { | |
477 | struct device_node *node; | |
478 | ||
c181fb3e | 479 | node = of_get_next_available_child(dev->of_node, to_of_node(child)); |
8a0662d9 RW |
480 | if (node) |
481 | return &node->fwnode; | |
482 | } else if (IS_ENABLED(CONFIG_ACPI)) { | |
483 | struct acpi_device *node; | |
484 | ||
c181fb3e | 485 | node = acpi_get_next_child(dev, to_acpi_node(child)); |
8a0662d9 RW |
486 | if (node) |
487 | return acpi_fwnode_handle(node); | |
488 | } | |
489 | return NULL; | |
490 | } | |
491 | EXPORT_SYMBOL_GPL(device_get_next_child_node); | |
492 | ||
493 | /** | |
494 | * fwnode_handle_put - Drop reference to a device node | |
495 | * @fwnode: Pointer to the device node to drop the reference to. | |
496 | * | |
497 | * This has to be used when terminating device_for_each_child_node() iteration | |
498 | * with break or return to prevent stale device node references from being left | |
499 | * behind. | |
500 | */ | |
501 | void fwnode_handle_put(struct fwnode_handle *fwnode) | |
502 | { | |
503 | if (is_of_node(fwnode)) | |
c181fb3e | 504 | of_node_put(to_of_node(fwnode)); |
8a0662d9 RW |
505 | } |
506 | EXPORT_SYMBOL_GPL(fwnode_handle_put); | |
507 | ||
508 | /** | |
509 | * device_get_child_node_count - return the number of child nodes for device | |
510 | * @dev: Device to cound the child nodes for | |
511 | */ | |
512 | unsigned int device_get_child_node_count(struct device *dev) | |
513 | { | |
514 | struct fwnode_handle *child; | |
515 | unsigned int count = 0; | |
516 | ||
517 | device_for_each_child_node(dev, child) | |
518 | count++; | |
519 | ||
520 | return count; | |
521 | } | |
522 | EXPORT_SYMBOL_GPL(device_get_child_node_count); | |
05ca5560 SS |
523 | |
524 | bool device_dma_is_coherent(struct device *dev) | |
525 | { | |
526 | bool coherent = false; | |
527 | ||
528 | if (IS_ENABLED(CONFIG_OF) && dev->of_node) | |
529 | coherent = of_dma_is_coherent(dev->of_node); | |
530 | else | |
531 | acpi_check_dma(ACPI_COMPANION(dev), &coherent); | |
532 | ||
533 | return coherent; | |
534 | } | |
535 | EXPORT_SYMBOL_GPL(device_dma_is_coherent); |