]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/base/property.c
device property: Make it possible to use secondary firmware nodes
[mirror_ubuntu-jammy-kernel.git] / drivers / base / property.c
CommitLineData
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
18static 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 */
31bool device_property_present(struct device *dev, const char *propname)
32{
9017f252 33 return fwnode_property_present(dev_fwnode(dev), propname);
b31384fa
RW
34}
35EXPORT_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 */
42bool 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}
51EXPORT_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 */
70int 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}
75EXPORT_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 */
94int 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}
99EXPORT_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 */
118int 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}
123EXPORT_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 */
142int 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}
147EXPORT_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 */
166int 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}
171EXPORT_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 */
187int 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}
192EXPORT_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 */
230int 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}
236EXPORT_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 */
256int 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}
262EXPORT_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 */
282int 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}
288EXPORT_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 */
308int 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}
314EXPORT_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 */
334int 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}
349EXPORT_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 */
366int 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}
377EXPORT_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 */
384struct 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}
402EXPORT_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 */
412void fwnode_handle_put(struct fwnode_handle *fwnode)
413{
414 if (is_of_node(fwnode))
415 of_node_put(of_node(fwnode));
416}
417EXPORT_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 */
423unsigned 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}
433EXPORT_SYMBOL_GPL(device_get_child_node_count);