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