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