1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * property.c - Unified device property interface. |
4 | * |
5 | * Copyright (C) 2014, Intel Corporation |
6 | * Authors: Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
7 | * Mika Westerberg <mika.westerberg@linux.intel.com> |
8 | */ |
9 | |
10 | #include <linux/device.h> |
11 | #include <linux/err.h> |
12 | #include <linux/export.h> |
13 | #include <linux/kconfig.h> |
14 | #include <linux/of.h> |
15 | #include <linux/property.h> |
16 | #include <linux/phy.h> |
17 | #include <linux/slab.h> |
18 | #include <linux/string.h> |
19 | #include <linux/types.h> |
20 | |
21 | struct fwnode_handle *__dev_fwnode(struct device *dev) |
22 | { |
23 | return IS_ENABLED(CONFIG_OF) && dev->of_node ? |
24 | of_fwnode_handle(dev->of_node) : dev->fwnode; |
25 | } |
26 | EXPORT_SYMBOL_GPL(__dev_fwnode); |
27 | |
28 | const struct fwnode_handle *__dev_fwnode_const(const struct device *dev) |
29 | { |
30 | return IS_ENABLED(CONFIG_OF) && dev->of_node ? |
31 | of_fwnode_handle(dev->of_node) : dev->fwnode; |
32 | } |
33 | EXPORT_SYMBOL_GPL(__dev_fwnode_const); |
34 | |
35 | /** |
36 | * device_property_present - check if a property of a device is present |
37 | * @dev: Device whose property is being checked |
38 | * @propname: Name of the property |
39 | * |
40 | * Check if property @propname is present in the device firmware description. |
41 | * |
42 | * Return: true if property @propname is present. Otherwise, returns false. |
43 | */ |
44 | bool device_property_present(const struct device *dev, const char *propname) |
45 | { |
46 | return fwnode_property_present(dev_fwnode(dev), propname); |
47 | } |
48 | EXPORT_SYMBOL_GPL(device_property_present); |
49 | |
50 | /** |
51 | * fwnode_property_present - check if a property of a firmware node is present |
52 | * @fwnode: Firmware node whose property to check |
53 | * @propname: Name of the property |
54 | * |
55 | * Return: true if property @propname is present. Otherwise, returns false. |
56 | */ |
57 | bool fwnode_property_present(const struct fwnode_handle *fwnode, |
58 | const char *propname) |
59 | { |
60 | bool ret; |
61 | |
62 | if (IS_ERR_OR_NULL(ptr: fwnode)) |
63 | return false; |
64 | |
65 | ret = fwnode_call_bool_op(fwnode, property_present, propname); |
66 | if (ret) |
67 | return ret; |
68 | |
69 | return fwnode_call_bool_op(fwnode->secondary, property_present, propname); |
70 | } |
71 | EXPORT_SYMBOL_GPL(fwnode_property_present); |
72 | |
73 | /** |
74 | * device_property_read_u8_array - return a u8 array property of a device |
75 | * @dev: Device to get the property of |
76 | * @propname: Name of the property |
77 | * @val: The values are stored here or %NULL to return the number of values |
78 | * @nval: Size of the @val array |
79 | * |
80 | * Function reads an array of u8 properties with @propname from the device |
81 | * firmware description and stores them to @val if found. |
82 | * |
83 | * It's recommended to call device_property_count_u8() instead of calling |
84 | * this function with @val equals %NULL and @nval equals 0. |
85 | * |
86 | * Return: number of values if @val was %NULL, |
87 | * %0 if the property was found (success), |
88 | * %-EINVAL if given arguments are not valid, |
89 | * %-ENODATA if the property does not have a value, |
90 | * %-EPROTO if the property is not an array of numbers, |
91 | * %-EOVERFLOW if the size of the property is not as expected. |
92 | * %-ENXIO if no suitable firmware interface is present. |
93 | */ |
94 | int device_property_read_u8_array(const struct device *dev, const char *propname, |
95 | u8 *val, size_t nval) |
96 | { |
97 | return fwnode_property_read_u8_array(dev_fwnode(dev), propname, val, nval); |
98 | } |
99 | EXPORT_SYMBOL_GPL(device_property_read_u8_array); |
100 | |
101 | /** |
102 | * device_property_read_u16_array - return a u16 array property of a device |
103 | * @dev: Device to get the property of |
104 | * @propname: Name of the property |
105 | * @val: The values are stored here or %NULL to return the number of values |
106 | * @nval: Size of the @val array |
107 | * |
108 | * Function reads an array of u16 properties with @propname from the device |
109 | * firmware description and stores them to @val if found. |
110 | * |
111 | * It's recommended to call device_property_count_u16() instead of calling |
112 | * this function with @val equals %NULL and @nval equals 0. |
113 | * |
114 | * Return: number of values if @val was %NULL, |
115 | * %0 if the property was found (success), |
116 | * %-EINVAL if given arguments are not valid, |
117 | * %-ENODATA if the property does not have a value, |
118 | * %-EPROTO if the property is not an array of numbers, |
119 | * %-EOVERFLOW if the size of the property is not as expected. |
120 | * %-ENXIO if no suitable firmware interface is present. |
121 | */ |
122 | int device_property_read_u16_array(const struct device *dev, const char *propname, |
123 | u16 *val, size_t nval) |
124 | { |
125 | return fwnode_property_read_u16_array(dev_fwnode(dev), propname, val, nval); |
126 | } |
127 | EXPORT_SYMBOL_GPL(device_property_read_u16_array); |
128 | |
129 | /** |
130 | * device_property_read_u32_array - return a u32 array property of a device |
131 | * @dev: Device to get the property of |
132 | * @propname: Name of the property |
133 | * @val: The values are stored here or %NULL to return the number of values |
134 | * @nval: Size of the @val array |
135 | * |
136 | * Function reads an array of u32 properties with @propname from the device |
137 | * firmware description and stores them to @val if found. |
138 | * |
139 | * It's recommended to call device_property_count_u32() instead of calling |
140 | * this function with @val equals %NULL and @nval equals 0. |
141 | * |
142 | * Return: number of values if @val was %NULL, |
143 | * %0 if the property was found (success), |
144 | * %-EINVAL if given arguments are not valid, |
145 | * %-ENODATA if the property does not have a value, |
146 | * %-EPROTO if the property is not an array of numbers, |
147 | * %-EOVERFLOW if the size of the property is not as expected. |
148 | * %-ENXIO if no suitable firmware interface is present. |
149 | */ |
150 | int device_property_read_u32_array(const struct device *dev, const char *propname, |
151 | u32 *val, size_t nval) |
152 | { |
153 | return fwnode_property_read_u32_array(dev_fwnode(dev), propname, val, nval); |
154 | } |
155 | EXPORT_SYMBOL_GPL(device_property_read_u32_array); |
156 | |
157 | /** |
158 | * device_property_read_u64_array - return a u64 array property of a device |
159 | * @dev: Device to get the property of |
160 | * @propname: Name of the property |
161 | * @val: The values are stored here or %NULL to return the number of values |
162 | * @nval: Size of the @val array |
163 | * |
164 | * Function reads an array of u64 properties with @propname from the device |
165 | * firmware description and stores them to @val if found. |
166 | * |
167 | * It's recommended to call device_property_count_u64() instead of calling |
168 | * this function with @val equals %NULL and @nval equals 0. |
169 | * |
170 | * Return: number of values if @val was %NULL, |
171 | * %0 if the property was found (success), |
172 | * %-EINVAL if given arguments are not valid, |
173 | * %-ENODATA if the property does not have a value, |
174 | * %-EPROTO if the property is not an array of numbers, |
175 | * %-EOVERFLOW if the size of the property is not as expected. |
176 | * %-ENXIO if no suitable firmware interface is present. |
177 | */ |
178 | int device_property_read_u64_array(const struct device *dev, const char *propname, |
179 | u64 *val, size_t nval) |
180 | { |
181 | return fwnode_property_read_u64_array(dev_fwnode(dev), propname, val, nval); |
182 | } |
183 | EXPORT_SYMBOL_GPL(device_property_read_u64_array); |
184 | |
185 | /** |
186 | * device_property_read_string_array - return a string array property of device |
187 | * @dev: Device to get the property of |
188 | * @propname: Name of the property |
189 | * @val: The values are stored here or %NULL to return the number of values |
190 | * @nval: Size of the @val array |
191 | * |
192 | * Function reads an array of string properties with @propname from the device |
193 | * firmware description and stores them to @val if found. |
194 | * |
195 | * It's recommended to call device_property_string_array_count() instead of calling |
196 | * this function with @val equals %NULL and @nval equals 0. |
197 | * |
198 | * Return: number of values read on success if @val is non-NULL, |
199 | * number of values available on success if @val is NULL, |
200 | * %-EINVAL if given arguments are not valid, |
201 | * %-ENODATA if the property does not have a value, |
202 | * %-EPROTO or %-EILSEQ if the property is not an array of strings, |
203 | * %-EOVERFLOW if the size of the property is not as expected. |
204 | * %-ENXIO if no suitable firmware interface is present. |
205 | */ |
206 | int device_property_read_string_array(const struct device *dev, const char *propname, |
207 | const char **val, size_t nval) |
208 | { |
209 | return fwnode_property_read_string_array(dev_fwnode(dev), propname, val, nval); |
210 | } |
211 | EXPORT_SYMBOL_GPL(device_property_read_string_array); |
212 | |
213 | /** |
214 | * device_property_read_string - return a string property of a device |
215 | * @dev: Device to get the property of |
216 | * @propname: Name of the property |
217 | * @val: The value is stored here |
218 | * |
219 | * Function reads property @propname from the device firmware description and |
220 | * stores the value into @val if found. The value is checked to be a string. |
221 | * |
222 | * Return: %0 if the property was found (success), |
223 | * %-EINVAL if given arguments are not valid, |
224 | * %-ENODATA if the property does not have a value, |
225 | * %-EPROTO or %-EILSEQ if the property type is not a string. |
226 | * %-ENXIO if no suitable firmware interface is present. |
227 | */ |
228 | int device_property_read_string(const struct device *dev, const char *propname, |
229 | const char **val) |
230 | { |
231 | return fwnode_property_read_string(dev_fwnode(dev), propname, val); |
232 | } |
233 | EXPORT_SYMBOL_GPL(device_property_read_string); |
234 | |
235 | /** |
236 | * device_property_match_string - find a string in an array and return index |
237 | * @dev: Device to get the property of |
238 | * @propname: Name of the property holding the array |
239 | * @string: String to look for |
240 | * |
241 | * Find a given string in a string array and if it is found return the |
242 | * index back. |
243 | * |
244 | * Return: index, starting from %0, if the property was found (success), |
245 | * %-EINVAL if given arguments are not valid, |
246 | * %-ENODATA if the property does not have a value, |
247 | * %-EPROTO if the property is not an array of strings, |
248 | * %-ENXIO if no suitable firmware interface is present. |
249 | */ |
250 | int device_property_match_string(const struct device *dev, const char *propname, |
251 | const char *string) |
252 | { |
253 | return fwnode_property_match_string(dev_fwnode(dev), propname, string); |
254 | } |
255 | EXPORT_SYMBOL_GPL(device_property_match_string); |
256 | |
257 | static int fwnode_property_read_int_array(const struct fwnode_handle *fwnode, |
258 | const char *propname, |
259 | unsigned int elem_size, void *val, |
260 | size_t nval) |
261 | { |
262 | int ret; |
263 | |
264 | if (IS_ERR_OR_NULL(ptr: fwnode)) |
265 | return -EINVAL; |
266 | |
267 | ret = fwnode_call_int_op(fwnode, property_read_int_array, propname, |
268 | elem_size, val, nval); |
269 | if (ret != -EINVAL) |
270 | return ret; |
271 | |
272 | return fwnode_call_int_op(fwnode->secondary, property_read_int_array, propname, |
273 | elem_size, val, nval); |
274 | } |
275 | |
276 | /** |
277 | * fwnode_property_read_u8_array - return a u8 array property of firmware node |
278 | * @fwnode: Firmware node to get the property of |
279 | * @propname: Name of the property |
280 | * @val: The values are stored here or %NULL to return the number of values |
281 | * @nval: Size of the @val array |
282 | * |
283 | * Read an array of u8 properties with @propname from @fwnode and stores them to |
284 | * @val if found. |
285 | * |
286 | * It's recommended to call fwnode_property_count_u8() instead of calling |
287 | * this function with @val equals %NULL and @nval equals 0. |
288 | * |
289 | * Return: number of values if @val was %NULL, |
290 | * %0 if the property was found (success), |
291 | * %-EINVAL if given arguments are not valid, |
292 | * %-ENODATA if the property does not have a value, |
293 | * %-EPROTO if the property is not an array of numbers, |
294 | * %-EOVERFLOW if the size of the property is not as expected, |
295 | * %-ENXIO if no suitable firmware interface is present. |
296 | */ |
297 | int fwnode_property_read_u8_array(const struct fwnode_handle *fwnode, |
298 | const char *propname, u8 *val, size_t nval) |
299 | { |
300 | return fwnode_property_read_int_array(fwnode, propname, elem_size: sizeof(u8), |
301 | val, nval); |
302 | } |
303 | EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array); |
304 | |
305 | /** |
306 | * fwnode_property_read_u16_array - return a u16 array property of firmware node |
307 | * @fwnode: Firmware node to get the property of |
308 | * @propname: Name of the property |
309 | * @val: The values are stored here or %NULL to return the number of values |
310 | * @nval: Size of the @val array |
311 | * |
312 | * Read an array of u16 properties with @propname from @fwnode and store them to |
313 | * @val if found. |
314 | * |
315 | * It's recommended to call fwnode_property_count_u16() instead of calling |
316 | * this function with @val equals %NULL and @nval equals 0. |
317 | * |
318 | * Return: number of values if @val was %NULL, |
319 | * %0 if the property was found (success), |
320 | * %-EINVAL if given arguments are not valid, |
321 | * %-ENODATA if the property does not have a value, |
322 | * %-EPROTO if the property is not an array of numbers, |
323 | * %-EOVERFLOW if the size of the property is not as expected, |
324 | * %-ENXIO if no suitable firmware interface is present. |
325 | */ |
326 | int fwnode_property_read_u16_array(const struct fwnode_handle *fwnode, |
327 | const char *propname, u16 *val, size_t nval) |
328 | { |
329 | return fwnode_property_read_int_array(fwnode, propname, elem_size: sizeof(u16), |
330 | val, nval); |
331 | } |
332 | EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array); |
333 | |
334 | /** |
335 | * fwnode_property_read_u32_array - return a u32 array property of firmware node |
336 | * @fwnode: Firmware node to get the property of |
337 | * @propname: Name of the property |
338 | * @val: The values are stored here or %NULL to return the number of values |
339 | * @nval: Size of the @val array |
340 | * |
341 | * Read an array of u32 properties with @propname from @fwnode store them to |
342 | * @val if found. |
343 | * |
344 | * It's recommended to call fwnode_property_count_u32() instead of calling |
345 | * this function with @val equals %NULL and @nval equals 0. |
346 | * |
347 | * Return: number of values if @val was %NULL, |
348 | * %0 if the property was found (success), |
349 | * %-EINVAL if given arguments are not valid, |
350 | * %-ENODATA if the property does not have a value, |
351 | * %-EPROTO if the property is not an array of numbers, |
352 | * %-EOVERFLOW if the size of the property is not as expected, |
353 | * %-ENXIO if no suitable firmware interface is present. |
354 | */ |
355 | int fwnode_property_read_u32_array(const struct fwnode_handle *fwnode, |
356 | const char *propname, u32 *val, size_t nval) |
357 | { |
358 | return fwnode_property_read_int_array(fwnode, propname, elem_size: sizeof(u32), |
359 | val, nval); |
360 | } |
361 | EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array); |
362 | |
363 | /** |
364 | * fwnode_property_read_u64_array - return a u64 array property firmware node |
365 | * @fwnode: Firmware node to get the property of |
366 | * @propname: Name of the property |
367 | * @val: The values are stored here or %NULL to return the number of values |
368 | * @nval: Size of the @val array |
369 | * |
370 | * Read an array of u64 properties with @propname from @fwnode and store them to |
371 | * @val if found. |
372 | * |
373 | * It's recommended to call fwnode_property_count_u64() instead of calling |
374 | * this function with @val equals %NULL and @nval equals 0. |
375 | * |
376 | * Return: number of values if @val was %NULL, |
377 | * %0 if the property was found (success), |
378 | * %-EINVAL if given arguments are not valid, |
379 | * %-ENODATA if the property does not have a value, |
380 | * %-EPROTO if the property is not an array of numbers, |
381 | * %-EOVERFLOW if the size of the property is not as expected, |
382 | * %-ENXIO if no suitable firmware interface is present. |
383 | */ |
384 | int fwnode_property_read_u64_array(const struct fwnode_handle *fwnode, |
385 | const char *propname, u64 *val, size_t nval) |
386 | { |
387 | return fwnode_property_read_int_array(fwnode, propname, elem_size: sizeof(u64), |
388 | val, nval); |
389 | } |
390 | EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array); |
391 | |
392 | /** |
393 | * fwnode_property_read_string_array - return string array property of a node |
394 | * @fwnode: Firmware node to get the property of |
395 | * @propname: Name of the property |
396 | * @val: The values are stored here or %NULL to return the number of values |
397 | * @nval: Size of the @val array |
398 | * |
399 | * Read an string list property @propname from the given firmware node and store |
400 | * them to @val if found. |
401 | * |
402 | * It's recommended to call fwnode_property_string_array_count() instead of calling |
403 | * this function with @val equals %NULL and @nval equals 0. |
404 | * |
405 | * Return: number of values read on success if @val is non-NULL, |
406 | * number of values available on success if @val is NULL, |
407 | * %-EINVAL if given arguments are not valid, |
408 | * %-ENODATA if the property does not have a value, |
409 | * %-EPROTO or %-EILSEQ if the property is not an array of strings, |
410 | * %-EOVERFLOW if the size of the property is not as expected, |
411 | * %-ENXIO if no suitable firmware interface is present. |
412 | */ |
413 | int fwnode_property_read_string_array(const struct fwnode_handle *fwnode, |
414 | const char *propname, const char **val, |
415 | size_t nval) |
416 | { |
417 | int ret; |
418 | |
419 | if (IS_ERR_OR_NULL(ptr: fwnode)) |
420 | return -EINVAL; |
421 | |
422 | ret = fwnode_call_int_op(fwnode, property_read_string_array, propname, |
423 | val, nval); |
424 | if (ret != -EINVAL) |
425 | return ret; |
426 | |
427 | return fwnode_call_int_op(fwnode->secondary, property_read_string_array, propname, |
428 | val, nval); |
429 | } |
430 | EXPORT_SYMBOL_GPL(fwnode_property_read_string_array); |
431 | |
432 | /** |
433 | * fwnode_property_read_string - return a string property of a firmware node |
434 | * @fwnode: Firmware node to get the property of |
435 | * @propname: Name of the property |
436 | * @val: The value is stored here |
437 | * |
438 | * Read property @propname from the given firmware node and store the value into |
439 | * @val if found. The value is checked to be a string. |
440 | * |
441 | * Return: %0 if the property was found (success), |
442 | * %-EINVAL if given arguments are not valid, |
443 | * %-ENODATA if the property does not have a value, |
444 | * %-EPROTO or %-EILSEQ if the property is not a string, |
445 | * %-ENXIO if no suitable firmware interface is present. |
446 | */ |
447 | int fwnode_property_read_string(const struct fwnode_handle *fwnode, |
448 | const char *propname, const char **val) |
449 | { |
450 | int ret = fwnode_property_read_string_array(fwnode, propname, val, 1); |
451 | |
452 | return ret < 0 ? ret : 0; |
453 | } |
454 | EXPORT_SYMBOL_GPL(fwnode_property_read_string); |
455 | |
456 | /** |
457 | * fwnode_property_match_string - find a string in an array and return index |
458 | * @fwnode: Firmware node to get the property of |
459 | * @propname: Name of the property holding the array |
460 | * @string: String to look for |
461 | * |
462 | * Find a given string in a string array and if it is found return the |
463 | * index back. |
464 | * |
465 | * Return: index, starting from %0, if the property was found (success), |
466 | * %-EINVAL if given arguments are not valid, |
467 | * %-ENODATA if the property does not have a value, |
468 | * %-EPROTO if the property is not an array of strings, |
469 | * %-ENXIO if no suitable firmware interface is present. |
470 | */ |
471 | int fwnode_property_match_string(const struct fwnode_handle *fwnode, |
472 | const char *propname, const char *string) |
473 | { |
474 | const char **values; |
475 | int nval, ret; |
476 | |
477 | nval = fwnode_property_string_array_count(fwnode, propname); |
478 | if (nval < 0) |
479 | return nval; |
480 | |
481 | if (nval == 0) |
482 | return -ENODATA; |
483 | |
484 | values = kcalloc(n: nval, size: sizeof(*values), GFP_KERNEL); |
485 | if (!values) |
486 | return -ENOMEM; |
487 | |
488 | ret = fwnode_property_read_string_array(fwnode, propname, values, nval); |
489 | if (ret < 0) |
490 | goto out_free; |
491 | |
492 | ret = match_string(array: values, n: nval, string); |
493 | if (ret < 0) |
494 | ret = -ENODATA; |
495 | |
496 | out_free: |
497 | kfree(objp: values); |
498 | return ret; |
499 | } |
500 | EXPORT_SYMBOL_GPL(fwnode_property_match_string); |
501 | |
502 | /** |
503 | * fwnode_property_match_property_string - find a property string value in an array and return index |
504 | * @fwnode: Firmware node to get the property of |
505 | * @propname: Name of the property holding the string value |
506 | * @array: String array to search in |
507 | * @n: Size of the @array |
508 | * |
509 | * Find a property string value in a given @array and if it is found return |
510 | * the index back. |
511 | * |
512 | * Return: index, starting from %0, if the string value was found in the @array (success), |
513 | * %-ENOENT when the string value was not found in the @array, |
514 | * %-EINVAL if given arguments are not valid, |
515 | * %-ENODATA if the property does not have a value, |
516 | * %-EPROTO or %-EILSEQ if the property is not a string, |
517 | * %-ENXIO if no suitable firmware interface is present. |
518 | */ |
519 | int fwnode_property_match_property_string(const struct fwnode_handle *fwnode, |
520 | const char *propname, const char * const *array, size_t n) |
521 | { |
522 | const char *string; |
523 | int ret; |
524 | |
525 | ret = fwnode_property_read_string(fwnode, propname, &string); |
526 | if (ret) |
527 | return ret; |
528 | |
529 | ret = match_string(array, n, string); |
530 | if (ret < 0) |
531 | ret = -ENOENT; |
532 | |
533 | return ret; |
534 | } |
535 | EXPORT_SYMBOL_GPL(fwnode_property_match_property_string); |
536 | |
537 | /** |
538 | * fwnode_property_get_reference_args() - Find a reference with arguments |
539 | * @fwnode: Firmware node where to look for the reference |
540 | * @prop: The name of the property |
541 | * @nargs_prop: The name of the property telling the number of |
542 | * arguments in the referred node. NULL if @nargs is known, |
543 | * otherwise @nargs is ignored. Only relevant on OF. |
544 | * @nargs: Number of arguments. Ignored if @nargs_prop is non-NULL. |
545 | * @index: Index of the reference, from zero onwards. |
546 | * @args: Result structure with reference and integer arguments. |
547 | * May be NULL. |
548 | * |
549 | * Obtain a reference based on a named property in an fwnode, with |
550 | * integer arguments. |
551 | * |
552 | * The caller is responsible for calling fwnode_handle_put() on the returned |
553 | * @args->fwnode pointer. |
554 | * |
555 | * Return: %0 on success |
556 | * %-ENOENT when the index is out of bounds, the index has an empty |
557 | * reference or the property was not found |
558 | * %-EINVAL on parse error |
559 | */ |
560 | int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode, |
561 | const char *prop, const char *nargs_prop, |
562 | unsigned int nargs, unsigned int index, |
563 | struct fwnode_reference_args *args) |
564 | { |
565 | int ret; |
566 | |
567 | if (IS_ERR_OR_NULL(ptr: fwnode)) |
568 | return -ENOENT; |
569 | |
570 | ret = fwnode_call_int_op(fwnode, get_reference_args, prop, nargs_prop, |
571 | nargs, index, args); |
572 | if (ret == 0) |
573 | return ret; |
574 | |
575 | if (IS_ERR_OR_NULL(ptr: fwnode->secondary)) |
576 | return ret; |
577 | |
578 | return fwnode_call_int_op(fwnode->secondary, get_reference_args, prop, nargs_prop, |
579 | nargs, index, args); |
580 | } |
581 | EXPORT_SYMBOL_GPL(fwnode_property_get_reference_args); |
582 | |
583 | /** |
584 | * fwnode_find_reference - Find named reference to a fwnode_handle |
585 | * @fwnode: Firmware node where to look for the reference |
586 | * @name: The name of the reference |
587 | * @index: Index of the reference |
588 | * |
589 | * @index can be used when the named reference holds a table of references. |
590 | * |
591 | * The caller is responsible for calling fwnode_handle_put() on the returned |
592 | * fwnode pointer. |
593 | * |
594 | * Return: a pointer to the reference fwnode, when found. Otherwise, |
595 | * returns an error pointer. |
596 | */ |
597 | struct fwnode_handle *fwnode_find_reference(const struct fwnode_handle *fwnode, |
598 | const char *name, |
599 | unsigned int index) |
600 | { |
601 | struct fwnode_reference_args args; |
602 | int ret; |
603 | |
604 | ret = fwnode_property_get_reference_args(fwnode, name, NULL, 0, index, |
605 | &args); |
606 | return ret ? ERR_PTR(error: ret) : args.fwnode; |
607 | } |
608 | EXPORT_SYMBOL_GPL(fwnode_find_reference); |
609 | |
610 | /** |
611 | * fwnode_get_name - Return the name of a node |
612 | * @fwnode: The firmware node |
613 | * |
614 | * Return: a pointer to the node name, or %NULL. |
615 | */ |
616 | const char *fwnode_get_name(const struct fwnode_handle *fwnode) |
617 | { |
618 | return fwnode_call_ptr_op(fwnode, get_name); |
619 | } |
620 | EXPORT_SYMBOL_GPL(fwnode_get_name); |
621 | |
622 | /** |
623 | * fwnode_get_name_prefix - Return the prefix of node for printing purposes |
624 | * @fwnode: The firmware node |
625 | * |
626 | * Return: the prefix of a node, intended to be printed right before the node. |
627 | * The prefix works also as a separator between the nodes. |
628 | */ |
629 | const char *fwnode_get_name_prefix(const struct fwnode_handle *fwnode) |
630 | { |
631 | return fwnode_call_ptr_op(fwnode, get_name_prefix); |
632 | } |
633 | |
634 | /** |
635 | * fwnode_name_eq - Return true if node name is equal |
636 | * @fwnode: The firmware node |
637 | * @name: The name to which to compare the node name |
638 | * |
639 | * Compare the name provided as an argument to the name of the node, stopping |
640 | * the comparison at either NUL or '@' character, whichever comes first. This |
641 | * function is generally used for comparing node names while ignoring the |
642 | * possible unit address of the node. |
643 | * |
644 | * Return: true if the node name matches with the name provided in the @name |
645 | * argument, false otherwise. |
646 | */ |
647 | bool fwnode_name_eq(const struct fwnode_handle *fwnode, const char *name) |
648 | { |
649 | const char *node_name; |
650 | ptrdiff_t len; |
651 | |
652 | node_name = fwnode_get_name(fwnode); |
653 | if (!node_name) |
654 | return false; |
655 | |
656 | len = strchrnul(node_name, '@') - node_name; |
657 | |
658 | return str_has_prefix(str: node_name, prefix: name) == len; |
659 | } |
660 | EXPORT_SYMBOL_GPL(fwnode_name_eq); |
661 | |
662 | /** |
663 | * fwnode_get_parent - Return parent firwmare node |
664 | * @fwnode: Firmware whose parent is retrieved |
665 | * |
666 | * The caller is responsible for calling fwnode_handle_put() on the returned |
667 | * fwnode pointer. |
668 | * |
669 | * Return: parent firmware node of the given node if possible or %NULL if no |
670 | * parent was available. |
671 | */ |
672 | struct fwnode_handle *fwnode_get_parent(const struct fwnode_handle *fwnode) |
673 | { |
674 | return fwnode_call_ptr_op(fwnode, get_parent); |
675 | } |
676 | EXPORT_SYMBOL_GPL(fwnode_get_parent); |
677 | |
678 | /** |
679 | * fwnode_get_next_parent - Iterate to the node's parent |
680 | * @fwnode: Firmware whose parent is retrieved |
681 | * |
682 | * This is like fwnode_get_parent() except that it drops the refcount |
683 | * on the passed node, making it suitable for iterating through a |
684 | * node's parents. |
685 | * |
686 | * The caller is responsible for calling fwnode_handle_put() on the returned |
687 | * fwnode pointer. Note that this function also puts a reference to @fwnode |
688 | * unconditionally. |
689 | * |
690 | * Return: parent firmware node of the given node if possible or %NULL if no |
691 | * parent was available. |
692 | */ |
693 | struct fwnode_handle *fwnode_get_next_parent(struct fwnode_handle *fwnode) |
694 | { |
695 | struct fwnode_handle *parent = fwnode_get_parent(fwnode); |
696 | |
697 | fwnode_handle_put(fwnode); |
698 | |
699 | return parent; |
700 | } |
701 | EXPORT_SYMBOL_GPL(fwnode_get_next_parent); |
702 | |
703 | /** |
704 | * fwnode_count_parents - Return the number of parents a node has |
705 | * @fwnode: The node the parents of which are to be counted |
706 | * |
707 | * Return: the number of parents a node has. |
708 | */ |
709 | unsigned int fwnode_count_parents(const struct fwnode_handle *fwnode) |
710 | { |
711 | struct fwnode_handle *parent; |
712 | unsigned int count = 0; |
713 | |
714 | fwnode_for_each_parent_node(fwnode, parent) |
715 | count++; |
716 | |
717 | return count; |
718 | } |
719 | EXPORT_SYMBOL_GPL(fwnode_count_parents); |
720 | |
721 | /** |
722 | * fwnode_get_nth_parent - Return an nth parent of a node |
723 | * @fwnode: The node the parent of which is requested |
724 | * @depth: Distance of the parent from the node |
725 | * |
726 | * The caller is responsible for calling fwnode_handle_put() on the returned |
727 | * fwnode pointer. |
728 | * |
729 | * Return: the nth parent of a node. If there is no parent at the requested |
730 | * @depth, %NULL is returned. If @depth is 0, the functionality is equivalent to |
731 | * fwnode_handle_get(). For @depth == 1, it is fwnode_get_parent() and so on. |
732 | */ |
733 | struct fwnode_handle *fwnode_get_nth_parent(struct fwnode_handle *fwnode, |
734 | unsigned int depth) |
735 | { |
736 | struct fwnode_handle *parent; |
737 | |
738 | if (depth == 0) |
739 | return fwnode_handle_get(fwnode); |
740 | |
741 | fwnode_for_each_parent_node(fwnode, parent) { |
742 | if (--depth == 0) |
743 | return parent; |
744 | } |
745 | return NULL; |
746 | } |
747 | EXPORT_SYMBOL_GPL(fwnode_get_nth_parent); |
748 | |
749 | /** |
750 | * fwnode_get_next_child_node - Return the next child node handle for a node |
751 | * @fwnode: Firmware node to find the next child node for. |
752 | * @child: Handle to one of the node's child nodes or a %NULL handle. |
753 | * |
754 | * The caller is responsible for calling fwnode_handle_put() on the returned |
755 | * fwnode pointer. Note that this function also puts a reference to @child |
756 | * unconditionally. |
757 | */ |
758 | struct fwnode_handle * |
759 | fwnode_get_next_child_node(const struct fwnode_handle *fwnode, |
760 | struct fwnode_handle *child) |
761 | { |
762 | return fwnode_call_ptr_op(fwnode, get_next_child_node, child); |
763 | } |
764 | EXPORT_SYMBOL_GPL(fwnode_get_next_child_node); |
765 | |
766 | /** |
767 | * fwnode_get_next_available_child_node - Return the next available child node handle for a node |
768 | * @fwnode: Firmware node to find the next child node for. |
769 | * @child: Handle to one of the node's child nodes or a %NULL handle. |
770 | * |
771 | * The caller is responsible for calling fwnode_handle_put() on the returned |
772 | * fwnode pointer. Note that this function also puts a reference to @child |
773 | * unconditionally. |
774 | */ |
775 | struct fwnode_handle * |
776 | fwnode_get_next_available_child_node(const struct fwnode_handle *fwnode, |
777 | struct fwnode_handle *child) |
778 | { |
779 | struct fwnode_handle *next_child = child; |
780 | |
781 | if (IS_ERR_OR_NULL(ptr: fwnode)) |
782 | return NULL; |
783 | |
784 | do { |
785 | next_child = fwnode_get_next_child_node(fwnode, next_child); |
786 | if (!next_child) |
787 | return NULL; |
788 | } while (!fwnode_device_is_available(fwnode: next_child)); |
789 | |
790 | return next_child; |
791 | } |
792 | EXPORT_SYMBOL_GPL(fwnode_get_next_available_child_node); |
793 | |
794 | /** |
795 | * device_get_next_child_node - Return the next child node handle for a device |
796 | * @dev: Device to find the next child node for. |
797 | * @child: Handle to one of the device's child nodes or a %NULL handle. |
798 | * |
799 | * The caller is responsible for calling fwnode_handle_put() on the returned |
800 | * fwnode pointer. Note that this function also puts a reference to @child |
801 | * unconditionally. |
802 | */ |
803 | struct fwnode_handle *device_get_next_child_node(const struct device *dev, |
804 | struct fwnode_handle *child) |
805 | { |
806 | const struct fwnode_handle *fwnode = dev_fwnode(dev); |
807 | struct fwnode_handle *next; |
808 | |
809 | if (IS_ERR_OR_NULL(ptr: fwnode)) |
810 | return NULL; |
811 | |
812 | /* Try to find a child in primary fwnode */ |
813 | next = fwnode_get_next_child_node(fwnode, child); |
814 | if (next) |
815 | return next; |
816 | |
817 | /* When no more children in primary, continue with secondary */ |
818 | return fwnode_get_next_child_node(fwnode->secondary, child); |
819 | } |
820 | EXPORT_SYMBOL_GPL(device_get_next_child_node); |
821 | |
822 | /** |
823 | * fwnode_get_named_child_node - Return first matching named child node handle |
824 | * @fwnode: Firmware node to find the named child node for. |
825 | * @childname: String to match child node name against. |
826 | * |
827 | * The caller is responsible for calling fwnode_handle_put() on the returned |
828 | * fwnode pointer. |
829 | */ |
830 | struct fwnode_handle * |
831 | fwnode_get_named_child_node(const struct fwnode_handle *fwnode, |
832 | const char *childname) |
833 | { |
834 | return fwnode_call_ptr_op(fwnode, get_named_child_node, childname); |
835 | } |
836 | EXPORT_SYMBOL_GPL(fwnode_get_named_child_node); |
837 | |
838 | /** |
839 | * device_get_named_child_node - Return first matching named child node handle |
840 | * @dev: Device to find the named child node for. |
841 | * @childname: String to match child node name against. |
842 | * |
843 | * The caller is responsible for calling fwnode_handle_put() on the returned |
844 | * fwnode pointer. |
845 | */ |
846 | struct fwnode_handle *device_get_named_child_node(const struct device *dev, |
847 | const char *childname) |
848 | { |
849 | return fwnode_get_named_child_node(dev_fwnode(dev), childname); |
850 | } |
851 | EXPORT_SYMBOL_GPL(device_get_named_child_node); |
852 | |
853 | /** |
854 | * fwnode_handle_get - Obtain a reference to a device node |
855 | * @fwnode: Pointer to the device node to obtain the reference to. |
856 | * |
857 | * The caller is responsible for calling fwnode_handle_put() on the returned |
858 | * fwnode pointer. |
859 | * |
860 | * Return: the fwnode handle. |
861 | */ |
862 | struct fwnode_handle *fwnode_handle_get(struct fwnode_handle *fwnode) |
863 | { |
864 | if (!fwnode_has_op(fwnode, get)) |
865 | return fwnode; |
866 | |
867 | return fwnode_call_ptr_op(fwnode, get); |
868 | } |
869 | EXPORT_SYMBOL_GPL(fwnode_handle_get); |
870 | |
871 | /** |
872 | * fwnode_handle_put - Drop reference to a device node |
873 | * @fwnode: Pointer to the device node to drop the reference to. |
874 | * |
875 | * This has to be used when terminating device_for_each_child_node() iteration |
876 | * with break or return to prevent stale device node references from being left |
877 | * behind. |
878 | */ |
879 | void fwnode_handle_put(struct fwnode_handle *fwnode) |
880 | { |
881 | fwnode_call_void_op(fwnode, put); |
882 | } |
883 | EXPORT_SYMBOL_GPL(fwnode_handle_put); |
884 | |
885 | /** |
886 | * fwnode_device_is_available - check if a device is available for use |
887 | * @fwnode: Pointer to the fwnode of the device. |
888 | * |
889 | * Return: true if device is available for use. Otherwise, returns false. |
890 | * |
891 | * For fwnode node types that don't implement the .device_is_available() |
892 | * operation, this function returns true. |
893 | */ |
894 | bool fwnode_device_is_available(const struct fwnode_handle *fwnode) |
895 | { |
896 | if (IS_ERR_OR_NULL(ptr: fwnode)) |
897 | return false; |
898 | |
899 | if (!fwnode_has_op(fwnode, device_is_available)) |
900 | return true; |
901 | |
902 | return fwnode_call_bool_op(fwnode, device_is_available); |
903 | } |
904 | EXPORT_SYMBOL_GPL(fwnode_device_is_available); |
905 | |
906 | /** |
907 | * device_get_child_node_count - return the number of child nodes for device |
908 | * @dev: Device to cound the child nodes for |
909 | * |
910 | * Return: the number of child nodes for a given device. |
911 | */ |
912 | unsigned int device_get_child_node_count(const struct device *dev) |
913 | { |
914 | struct fwnode_handle *child; |
915 | unsigned int count = 0; |
916 | |
917 | device_for_each_child_node(dev, child) |
918 | count++; |
919 | |
920 | return count; |
921 | } |
922 | EXPORT_SYMBOL_GPL(device_get_child_node_count); |
923 | |
924 | bool device_dma_supported(const struct device *dev) |
925 | { |
926 | return fwnode_call_bool_op(dev_fwnode(dev), device_dma_supported); |
927 | } |
928 | EXPORT_SYMBOL_GPL(device_dma_supported); |
929 | |
930 | enum dev_dma_attr device_get_dma_attr(const struct device *dev) |
931 | { |
932 | if (!fwnode_has_op(dev_fwnode(dev), device_get_dma_attr)) |
933 | return DEV_DMA_NOT_SUPPORTED; |
934 | |
935 | return fwnode_call_int_op(dev_fwnode(dev), device_get_dma_attr); |
936 | } |
937 | EXPORT_SYMBOL_GPL(device_get_dma_attr); |
938 | |
939 | /** |
940 | * fwnode_get_phy_mode - Get phy mode for given firmware node |
941 | * @fwnode: Pointer to the given node |
942 | * |
943 | * The function gets phy interface string from property 'phy-mode' or |
944 | * 'phy-connection-type', and return its index in phy_modes table, or errno in |
945 | * error case. |
946 | */ |
947 | int fwnode_get_phy_mode(const struct fwnode_handle *fwnode) |
948 | { |
949 | const char *pm; |
950 | int err, i; |
951 | |
952 | err = fwnode_property_read_string(fwnode, "phy-mode" , &pm); |
953 | if (err < 0) |
954 | err = fwnode_property_read_string(fwnode, |
955 | "phy-connection-type" , &pm); |
956 | if (err < 0) |
957 | return err; |
958 | |
959 | for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++) |
960 | if (!strcasecmp(s1: pm, s2: phy_modes(interface: i))) |
961 | return i; |
962 | |
963 | return -ENODEV; |
964 | } |
965 | EXPORT_SYMBOL_GPL(fwnode_get_phy_mode); |
966 | |
967 | /** |
968 | * device_get_phy_mode - Get phy mode for given device |
969 | * @dev: Pointer to the given device |
970 | * |
971 | * The function gets phy interface string from property 'phy-mode' or |
972 | * 'phy-connection-type', and return its index in phy_modes table, or errno in |
973 | * error case. |
974 | */ |
975 | int device_get_phy_mode(struct device *dev) |
976 | { |
977 | return fwnode_get_phy_mode(dev_fwnode(dev)); |
978 | } |
979 | EXPORT_SYMBOL_GPL(device_get_phy_mode); |
980 | |
981 | /** |
982 | * fwnode_iomap - Maps the memory mapped IO for a given fwnode |
983 | * @fwnode: Pointer to the firmware node |
984 | * @index: Index of the IO range |
985 | * |
986 | * Return: a pointer to the mapped memory. |
987 | */ |
988 | void __iomem *fwnode_iomap(struct fwnode_handle *fwnode, int index) |
989 | { |
990 | return fwnode_call_ptr_op(fwnode, iomap, index); |
991 | } |
992 | EXPORT_SYMBOL(fwnode_iomap); |
993 | |
994 | /** |
995 | * fwnode_irq_get - Get IRQ directly from a fwnode |
996 | * @fwnode: Pointer to the firmware node |
997 | * @index: Zero-based index of the IRQ |
998 | * |
999 | * Return: Linux IRQ number on success. Negative errno on failure. |
1000 | */ |
1001 | int fwnode_irq_get(const struct fwnode_handle *fwnode, unsigned int index) |
1002 | { |
1003 | int ret; |
1004 | |
1005 | ret = fwnode_call_int_op(fwnode, irq_get, index); |
1006 | /* We treat mapping errors as invalid case */ |
1007 | if (ret == 0) |
1008 | return -EINVAL; |
1009 | |
1010 | return ret; |
1011 | } |
1012 | EXPORT_SYMBOL(fwnode_irq_get); |
1013 | |
1014 | /** |
1015 | * fwnode_irq_get_byname - Get IRQ from a fwnode using its name |
1016 | * @fwnode: Pointer to the firmware node |
1017 | * @name: IRQ name |
1018 | * |
1019 | * Description: |
1020 | * Find a match to the string @name in the 'interrupt-names' string array |
1021 | * in _DSD for ACPI, or of_node for Device Tree. Then get the Linux IRQ |
1022 | * number of the IRQ resource corresponding to the index of the matched |
1023 | * string. |
1024 | * |
1025 | * Return: Linux IRQ number on success, or negative errno otherwise. |
1026 | */ |
1027 | int fwnode_irq_get_byname(const struct fwnode_handle *fwnode, const char *name) |
1028 | { |
1029 | int index; |
1030 | |
1031 | if (!name) |
1032 | return -EINVAL; |
1033 | |
1034 | index = fwnode_property_match_string(fwnode, "interrupt-names" , name); |
1035 | if (index < 0) |
1036 | return index; |
1037 | |
1038 | return fwnode_irq_get(fwnode, index); |
1039 | } |
1040 | EXPORT_SYMBOL(fwnode_irq_get_byname); |
1041 | |
1042 | /** |
1043 | * fwnode_graph_get_next_endpoint - Get next endpoint firmware node |
1044 | * @fwnode: Pointer to the parent firmware node |
1045 | * @prev: Previous endpoint node or %NULL to get the first |
1046 | * |
1047 | * The caller is responsible for calling fwnode_handle_put() on the returned |
1048 | * fwnode pointer. Note that this function also puts a reference to @prev |
1049 | * unconditionally. |
1050 | * |
1051 | * Return: an endpoint firmware node pointer or %NULL if no more endpoints |
1052 | * are available. |
1053 | */ |
1054 | struct fwnode_handle * |
1055 | fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode, |
1056 | struct fwnode_handle *prev) |
1057 | { |
1058 | struct fwnode_handle *ep, *port_parent = NULL; |
1059 | const struct fwnode_handle *parent; |
1060 | |
1061 | /* |
1062 | * If this function is in a loop and the previous iteration returned |
1063 | * an endpoint from fwnode->secondary, then we need to use the secondary |
1064 | * as parent rather than @fwnode. |
1065 | */ |
1066 | if (prev) { |
1067 | port_parent = fwnode_graph_get_port_parent(fwnode: prev); |
1068 | parent = port_parent; |
1069 | } else { |
1070 | parent = fwnode; |
1071 | } |
1072 | if (IS_ERR_OR_NULL(ptr: parent)) |
1073 | return NULL; |
1074 | |
1075 | ep = fwnode_call_ptr_op(parent, graph_get_next_endpoint, prev); |
1076 | if (ep) |
1077 | goto out_put_port_parent; |
1078 | |
1079 | ep = fwnode_graph_get_next_endpoint(fwnode: parent->secondary, NULL); |
1080 | |
1081 | out_put_port_parent: |
1082 | fwnode_handle_put(port_parent); |
1083 | return ep; |
1084 | } |
1085 | EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint); |
1086 | |
1087 | /** |
1088 | * fwnode_graph_get_port_parent - Return the device fwnode of a port endpoint |
1089 | * @endpoint: Endpoint firmware node of the port |
1090 | * |
1091 | * The caller is responsible for calling fwnode_handle_put() on the returned |
1092 | * fwnode pointer. |
1093 | * |
1094 | * Return: the firmware node of the device the @endpoint belongs to. |
1095 | */ |
1096 | struct fwnode_handle * |
1097 | fwnode_graph_get_port_parent(const struct fwnode_handle *endpoint) |
1098 | { |
1099 | struct fwnode_handle *port, *parent; |
1100 | |
1101 | port = fwnode_get_parent(endpoint); |
1102 | parent = fwnode_call_ptr_op(port, graph_get_port_parent); |
1103 | |
1104 | fwnode_handle_put(port); |
1105 | |
1106 | return parent; |
1107 | } |
1108 | EXPORT_SYMBOL_GPL(fwnode_graph_get_port_parent); |
1109 | |
1110 | /** |
1111 | * fwnode_graph_get_remote_port_parent - Return fwnode of a remote device |
1112 | * @fwnode: Endpoint firmware node pointing to the remote endpoint |
1113 | * |
1114 | * Extracts firmware node of a remote device the @fwnode points to. |
1115 | * |
1116 | * The caller is responsible for calling fwnode_handle_put() on the returned |
1117 | * fwnode pointer. |
1118 | */ |
1119 | struct fwnode_handle * |
1120 | fwnode_graph_get_remote_port_parent(const struct fwnode_handle *fwnode) |
1121 | { |
1122 | struct fwnode_handle *endpoint, *parent; |
1123 | |
1124 | endpoint = fwnode_graph_get_remote_endpoint(fwnode); |
1125 | parent = fwnode_graph_get_port_parent(endpoint); |
1126 | |
1127 | fwnode_handle_put(endpoint); |
1128 | |
1129 | return parent; |
1130 | } |
1131 | EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port_parent); |
1132 | |
1133 | /** |
1134 | * fwnode_graph_get_remote_port - Return fwnode of a remote port |
1135 | * @fwnode: Endpoint firmware node pointing to the remote endpoint |
1136 | * |
1137 | * Extracts firmware node of a remote port the @fwnode points to. |
1138 | * |
1139 | * The caller is responsible for calling fwnode_handle_put() on the returned |
1140 | * fwnode pointer. |
1141 | */ |
1142 | struct fwnode_handle * |
1143 | fwnode_graph_get_remote_port(const struct fwnode_handle *fwnode) |
1144 | { |
1145 | return fwnode_get_next_parent(fwnode_graph_get_remote_endpoint(fwnode)); |
1146 | } |
1147 | EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port); |
1148 | |
1149 | /** |
1150 | * fwnode_graph_get_remote_endpoint - Return fwnode of a remote endpoint |
1151 | * @fwnode: Endpoint firmware node pointing to the remote endpoint |
1152 | * |
1153 | * Extracts firmware node of a remote endpoint the @fwnode points to. |
1154 | * |
1155 | * The caller is responsible for calling fwnode_handle_put() on the returned |
1156 | * fwnode pointer. |
1157 | */ |
1158 | struct fwnode_handle * |
1159 | fwnode_graph_get_remote_endpoint(const struct fwnode_handle *fwnode) |
1160 | { |
1161 | return fwnode_call_ptr_op(fwnode, graph_get_remote_endpoint); |
1162 | } |
1163 | EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_endpoint); |
1164 | |
1165 | static bool fwnode_graph_remote_available(struct fwnode_handle *ep) |
1166 | { |
1167 | struct fwnode_handle *dev_node; |
1168 | bool available; |
1169 | |
1170 | dev_node = fwnode_graph_get_remote_port_parent(ep); |
1171 | available = fwnode_device_is_available(dev_node); |
1172 | fwnode_handle_put(dev_node); |
1173 | |
1174 | return available; |
1175 | } |
1176 | |
1177 | /** |
1178 | * fwnode_graph_get_endpoint_by_id - get endpoint by port and endpoint numbers |
1179 | * @fwnode: parent fwnode_handle containing the graph |
1180 | * @port: identifier of the port node |
1181 | * @endpoint: identifier of the endpoint node under the port node |
1182 | * @flags: fwnode lookup flags |
1183 | * |
1184 | * The caller is responsible for calling fwnode_handle_put() on the returned |
1185 | * fwnode pointer. |
1186 | * |
1187 | * Return: the fwnode handle of the local endpoint corresponding the port and |
1188 | * endpoint IDs or %NULL if not found. |
1189 | * |
1190 | * If FWNODE_GRAPH_ENDPOINT_NEXT is passed in @flags and the specified endpoint |
1191 | * has not been found, look for the closest endpoint ID greater than the |
1192 | * specified one and return the endpoint that corresponds to it, if present. |
1193 | * |
1194 | * Does not return endpoints that belong to disabled devices or endpoints that |
1195 | * are unconnected, unless FWNODE_GRAPH_DEVICE_DISABLED is passed in @flags. |
1196 | */ |
1197 | struct fwnode_handle * |
1198 | fwnode_graph_get_endpoint_by_id(const struct fwnode_handle *fwnode, |
1199 | u32 port, u32 endpoint, unsigned long flags) |
1200 | { |
1201 | struct fwnode_handle *ep, *best_ep = NULL; |
1202 | unsigned int best_ep_id = 0; |
1203 | bool endpoint_next = flags & FWNODE_GRAPH_ENDPOINT_NEXT; |
1204 | bool enabled_only = !(flags & FWNODE_GRAPH_DEVICE_DISABLED); |
1205 | |
1206 | fwnode_graph_for_each_endpoint(fwnode, ep) { |
1207 | struct fwnode_endpoint fwnode_ep = { 0 }; |
1208 | int ret; |
1209 | |
1210 | if (enabled_only && !fwnode_graph_remote_available(ep)) |
1211 | continue; |
1212 | |
1213 | ret = fwnode_graph_parse_endpoint(fwnode: ep, endpoint: &fwnode_ep); |
1214 | if (ret < 0) |
1215 | continue; |
1216 | |
1217 | if (fwnode_ep.port != port) |
1218 | continue; |
1219 | |
1220 | if (fwnode_ep.id == endpoint) |
1221 | return ep; |
1222 | |
1223 | if (!endpoint_next) |
1224 | continue; |
1225 | |
1226 | /* |
1227 | * If the endpoint that has just been found is not the first |
1228 | * matching one and the ID of the one found previously is closer |
1229 | * to the requested endpoint ID, skip it. |
1230 | */ |
1231 | if (fwnode_ep.id < endpoint || |
1232 | (best_ep && best_ep_id < fwnode_ep.id)) |
1233 | continue; |
1234 | |
1235 | fwnode_handle_put(best_ep); |
1236 | best_ep = fwnode_handle_get(ep); |
1237 | best_ep_id = fwnode_ep.id; |
1238 | } |
1239 | |
1240 | return best_ep; |
1241 | } |
1242 | EXPORT_SYMBOL_GPL(fwnode_graph_get_endpoint_by_id); |
1243 | |
1244 | /** |
1245 | * fwnode_graph_get_endpoint_count - Count endpoints on a device node |
1246 | * @fwnode: The node related to a device |
1247 | * @flags: fwnode lookup flags |
1248 | * Count endpoints in a device node. |
1249 | * |
1250 | * If FWNODE_GRAPH_DEVICE_DISABLED flag is specified, also unconnected endpoints |
1251 | * and endpoints connected to disabled devices are counted. |
1252 | */ |
1253 | unsigned int fwnode_graph_get_endpoint_count(const struct fwnode_handle *fwnode, |
1254 | unsigned long flags) |
1255 | { |
1256 | struct fwnode_handle *ep; |
1257 | unsigned int count = 0; |
1258 | |
1259 | fwnode_graph_for_each_endpoint(fwnode, ep) { |
1260 | if (flags & FWNODE_GRAPH_DEVICE_DISABLED || |
1261 | fwnode_graph_remote_available(ep)) |
1262 | count++; |
1263 | } |
1264 | |
1265 | return count; |
1266 | } |
1267 | EXPORT_SYMBOL_GPL(fwnode_graph_get_endpoint_count); |
1268 | |
1269 | /** |
1270 | * fwnode_graph_parse_endpoint - parse common endpoint node properties |
1271 | * @fwnode: pointer to endpoint fwnode_handle |
1272 | * @endpoint: pointer to the fwnode endpoint data structure |
1273 | * |
1274 | * Parse @fwnode representing a graph endpoint node and store the |
1275 | * information in @endpoint. The caller must hold a reference to |
1276 | * @fwnode. |
1277 | */ |
1278 | int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, |
1279 | struct fwnode_endpoint *endpoint) |
1280 | { |
1281 | memset(endpoint, 0, sizeof(*endpoint)); |
1282 | |
1283 | return fwnode_call_int_op(fwnode, graph_parse_endpoint, endpoint); |
1284 | } |
1285 | EXPORT_SYMBOL(fwnode_graph_parse_endpoint); |
1286 | |
1287 | const void *device_get_match_data(const struct device *dev) |
1288 | { |
1289 | return fwnode_call_ptr_op(dev_fwnode(dev), device_get_match_data, dev); |
1290 | } |
1291 | EXPORT_SYMBOL_GPL(device_get_match_data); |
1292 | |
1293 | static unsigned int fwnode_graph_devcon_matches(const struct fwnode_handle *fwnode, |
1294 | const char *con_id, void *data, |
1295 | devcon_match_fn_t match, |
1296 | void **matches, |
1297 | unsigned int matches_len) |
1298 | { |
1299 | struct fwnode_handle *node; |
1300 | struct fwnode_handle *ep; |
1301 | unsigned int count = 0; |
1302 | void *ret; |
1303 | |
1304 | fwnode_graph_for_each_endpoint(fwnode, ep) { |
1305 | if (matches && count >= matches_len) { |
1306 | fwnode_handle_put(ep); |
1307 | break; |
1308 | } |
1309 | |
1310 | node = fwnode_graph_get_remote_port_parent(ep); |
1311 | if (!fwnode_device_is_available(node)) { |
1312 | fwnode_handle_put(node); |
1313 | continue; |
1314 | } |
1315 | |
1316 | ret = match(node, con_id, data); |
1317 | fwnode_handle_put(node); |
1318 | if (ret) { |
1319 | if (matches) |
1320 | matches[count] = ret; |
1321 | count++; |
1322 | } |
1323 | } |
1324 | return count; |
1325 | } |
1326 | |
1327 | static unsigned int fwnode_devcon_matches(const struct fwnode_handle *fwnode, |
1328 | const char *con_id, void *data, |
1329 | devcon_match_fn_t match, |
1330 | void **matches, |
1331 | unsigned int matches_len) |
1332 | { |
1333 | struct fwnode_handle *node; |
1334 | unsigned int count = 0; |
1335 | unsigned int i; |
1336 | void *ret; |
1337 | |
1338 | for (i = 0; ; i++) { |
1339 | if (matches && count >= matches_len) |
1340 | break; |
1341 | |
1342 | node = fwnode_find_reference(fwnode, con_id, i); |
1343 | if (IS_ERR(ptr: node)) |
1344 | break; |
1345 | |
1346 | ret = match(node, NULL, data); |
1347 | fwnode_handle_put(node); |
1348 | if (ret) { |
1349 | if (matches) |
1350 | matches[count] = ret; |
1351 | count++; |
1352 | } |
1353 | } |
1354 | |
1355 | return count; |
1356 | } |
1357 | |
1358 | /** |
1359 | * fwnode_connection_find_match - Find connection from a device node |
1360 | * @fwnode: Device node with the connection |
1361 | * @con_id: Identifier for the connection |
1362 | * @data: Data for the match function |
1363 | * @match: Function to check and convert the connection description |
1364 | * |
1365 | * Find a connection with unique identifier @con_id between @fwnode and another |
1366 | * device node. @match will be used to convert the connection description to |
1367 | * data the caller is expecting to be returned. |
1368 | */ |
1369 | void *fwnode_connection_find_match(const struct fwnode_handle *fwnode, |
1370 | const char *con_id, void *data, |
1371 | devcon_match_fn_t match) |
1372 | { |
1373 | unsigned int count; |
1374 | void *ret; |
1375 | |
1376 | if (!fwnode || !match) |
1377 | return NULL; |
1378 | |
1379 | count = fwnode_graph_devcon_matches(fwnode, con_id, data, match, matches: &ret, matches_len: 1); |
1380 | if (count) |
1381 | return ret; |
1382 | |
1383 | count = fwnode_devcon_matches(fwnode, con_id, data, match, matches: &ret, matches_len: 1); |
1384 | return count ? ret : NULL; |
1385 | } |
1386 | EXPORT_SYMBOL_GPL(fwnode_connection_find_match); |
1387 | |
1388 | /** |
1389 | * fwnode_connection_find_matches - Find connections from a device node |
1390 | * @fwnode: Device node with the connection |
1391 | * @con_id: Identifier for the connection |
1392 | * @data: Data for the match function |
1393 | * @match: Function to check and convert the connection description |
1394 | * @matches: (Optional) array of pointers to fill with matches |
1395 | * @matches_len: Length of @matches |
1396 | * |
1397 | * Find up to @matches_len connections with unique identifier @con_id between |
1398 | * @fwnode and other device nodes. @match will be used to convert the |
1399 | * connection description to data the caller is expecting to be returned |
1400 | * through the @matches array. |
1401 | * |
1402 | * If @matches is %NULL @matches_len is ignored and the total number of resolved |
1403 | * matches is returned. |
1404 | * |
1405 | * Return: Number of matches resolved, or negative errno. |
1406 | */ |
1407 | int fwnode_connection_find_matches(const struct fwnode_handle *fwnode, |
1408 | const char *con_id, void *data, |
1409 | devcon_match_fn_t match, |
1410 | void **matches, unsigned int matches_len) |
1411 | { |
1412 | unsigned int count_graph; |
1413 | unsigned int count_ref; |
1414 | |
1415 | if (!fwnode || !match) |
1416 | return -EINVAL; |
1417 | |
1418 | count_graph = fwnode_graph_devcon_matches(fwnode, con_id, data, match, |
1419 | matches, matches_len); |
1420 | |
1421 | if (matches) { |
1422 | matches += count_graph; |
1423 | matches_len -= count_graph; |
1424 | } |
1425 | |
1426 | count_ref = fwnode_devcon_matches(fwnode, con_id, data, match, |
1427 | matches, matches_len); |
1428 | |
1429 | return count_graph + count_ref; |
1430 | } |
1431 | EXPORT_SYMBOL_GPL(fwnode_connection_find_matches); |
1432 | |