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