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