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