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