]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/base/property.c
device property: Make dev_fwnode() public
[mirror_ubuntu-bionic-kernel.git] / drivers / base / property.c
CommitLineData
b31384fa
RW
1/*
2 * property.c - Unified device property interface.
3 *
4 * Copyright (C) 2014, Intel Corporation
5 * Authors: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
6 * Mika Westerberg <mika.westerberg@linux.intel.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
b31384fa 13#include <linux/acpi.h>
16ba08d5
RW
14#include <linux/export.h>
15#include <linux/kernel.h>
b31384fa 16#include <linux/of.h>
05ca5560 17#include <linux/of_address.h>
07bb80d4 18#include <linux/of_graph.h>
16ba08d5 19#include <linux/property.h>
4c96b7dc
JL
20#include <linux/etherdevice.h>
21#include <linux/phy.h>
16ba08d5 22
f4d05266
HK
23struct property_set {
24 struct fwnode_handle fwnode;
bec84da8 25 const struct property_entry *properties;
f4d05266
HK
26};
27
61f5e294 28static inline bool is_pset_node(struct fwnode_handle *fwnode)
16ba08d5 29{
0224a4a3 30 return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_PDATA;
16ba08d5
RW
31}
32
61f5e294 33static inline struct property_set *to_pset_node(struct fwnode_handle *fwnode)
16ba08d5 34{
61f5e294 35 return is_pset_node(fwnode) ?
16ba08d5
RW
36 container_of(fwnode, struct property_set, fwnode) : NULL;
37}
38
bec84da8
DT
39static const struct property_entry *pset_prop_get(struct property_set *pset,
40 const char *name)
16ba08d5 41{
bec84da8 42 const struct property_entry *prop;
16ba08d5
RW
43
44 if (!pset || !pset->properties)
45 return NULL;
46
47 for (prop = pset->properties; prop->name; prop++)
48 if (!strcmp(name, prop->name))
49 return prop;
50
51 return NULL;
52}
53
bec84da8
DT
54static const void *pset_prop_find(struct property_set *pset,
55 const char *propname, size_t length)
16ba08d5 56{
bec84da8
DT
57 const struct property_entry *prop;
58 const void *pointer;
16ba08d5 59
318a1971
AS
60 prop = pset_prop_get(pset, propname);
61 if (!prop)
62 return ERR_PTR(-EINVAL);
66586bab
AS
63 if (prop->is_array)
64 pointer = prop->pointer.raw_data;
65 else
66 pointer = &prop->value.raw_data;
318a1971
AS
67 if (!pointer)
68 return ERR_PTR(-ENODATA);
69 if (length > prop->length)
70 return ERR_PTR(-EOVERFLOW);
71 return pointer;
72}
73
74static int pset_prop_read_u8_array(struct property_set *pset,
75 const char *propname,
76 u8 *values, size_t nval)
77{
bec84da8 78 const void *pointer;
318a1971
AS
79 size_t length = nval * sizeof(*values);
80
81 pointer = pset_prop_find(pset, propname, length);
82 if (IS_ERR(pointer))
83 return PTR_ERR(pointer);
84
85 memcpy(values, pointer, length);
86 return 0;
87}
88
89static int pset_prop_read_u16_array(struct property_set *pset,
90 const char *propname,
91 u16 *values, size_t nval)
92{
bec84da8 93 const void *pointer;
318a1971
AS
94 size_t length = nval * sizeof(*values);
95
96 pointer = pset_prop_find(pset, propname, length);
97 if (IS_ERR(pointer))
98 return PTR_ERR(pointer);
99
100 memcpy(values, pointer, length);
101 return 0;
102}
103
104static int pset_prop_read_u32_array(struct property_set *pset,
105 const char *propname,
106 u32 *values, size_t nval)
107{
bec84da8 108 const void *pointer;
318a1971
AS
109 size_t length = nval * sizeof(*values);
110
111 pointer = pset_prop_find(pset, propname, length);
112 if (IS_ERR(pointer))
113 return PTR_ERR(pointer);
114
115 memcpy(values, pointer, length);
116 return 0;
117}
118
119static int pset_prop_read_u64_array(struct property_set *pset,
120 const char *propname,
121 u64 *values, size_t nval)
122{
bec84da8 123 const void *pointer;
318a1971
AS
124 size_t length = nval * sizeof(*values);
125
126 pointer = pset_prop_find(pset, propname, length);
127 if (IS_ERR(pointer))
128 return PTR_ERR(pointer);
129
130 memcpy(values, pointer, length);
131 return 0;
132}
133
134static int pset_prop_count_elems_of_size(struct property_set *pset,
135 const char *propname, size_t length)
136{
bec84da8 137 const struct property_entry *prop;
318a1971
AS
138
139 prop = pset_prop_get(pset, propname);
16ba08d5 140 if (!prop)
16ba08d5 141 return -EINVAL;
318a1971
AS
142
143 return prop->length / length;
144}
145
146static int pset_prop_read_string_array(struct property_set *pset,
147 const char *propname,
148 const char **strings, size_t nval)
149{
bec84da8 150 const void *pointer;
318a1971
AS
151 size_t length = nval * sizeof(*strings);
152
153 pointer = pset_prop_find(pset, propname, length);
154 if (IS_ERR(pointer))
155 return PTR_ERR(pointer);
156
157 memcpy(strings, pointer, length);
16ba08d5
RW
158 return 0;
159}
b31384fa 160
66586bab
AS
161static int pset_prop_read_string(struct property_set *pset,
162 const char *propname, const char **strings)
163{
bec84da8
DT
164 const struct property_entry *prop;
165 const char * const *pointer;
66586bab
AS
166
167 prop = pset_prop_get(pset, propname);
168 if (!prop)
169 return -EINVAL;
170 if (!prop->is_string)
171 return -EILSEQ;
172 if (prop->is_array) {
173 pointer = prop->pointer.str;
174 if (!pointer)
175 return -ENODATA;
176 } else {
177 pointer = &prop->value.str;
178 if (*pointer && strnlen(*pointer, prop->length) >= prop->length)
179 return -EILSEQ;
180 }
181
182 *strings = *pointer;
183 return 0;
184}
185
e44bb0cb 186struct fwnode_handle *dev_fwnode(struct device *dev)
9017f252
RW
187{
188 return IS_ENABLED(CONFIG_OF) && dev->of_node ?
189 &dev->of_node->fwnode : dev->fwnode;
190}
e44bb0cb 191EXPORT_SYMBOL_GPL(dev_fwnode);
b31384fa
RW
192
193/**
194 * device_property_present - check if a property of a device is present
195 * @dev: Device whose property is being checked
196 * @propname: Name of the property
197 *
198 * Check if property @propname is present in the device firmware description.
199 */
200bool device_property_present(struct device *dev, const char *propname)
201{
9017f252 202 return fwnode_property_present(dev_fwnode(dev), propname);
b31384fa
RW
203}
204EXPORT_SYMBOL_GPL(device_property_present);
205
362c0b30
AS
206static bool __fwnode_property_present(struct fwnode_handle *fwnode,
207 const char *propname)
8a0662d9
RW
208{
209 if (is_of_node(fwnode))
c181fb3e 210 return of_property_read_bool(to_of_node(fwnode), propname);
8a0662d9 211 else if (is_acpi_node(fwnode))
3a7a2ab8 212 return !acpi_node_prop_get(fwnode, propname, NULL);
61f5e294
AS
213 else if (is_pset_node(fwnode))
214 return !!pset_prop_get(to_pset_node(fwnode), propname);
e3f9e299 215 return false;
8a0662d9 216}
362c0b30
AS
217
218/**
219 * fwnode_property_present - check if a property of a firmware node is present
220 * @fwnode: Firmware node whose property to check
221 * @propname: Name of the property
222 */
223bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
224{
225 bool ret;
226
227 ret = __fwnode_property_present(fwnode, propname);
0d67e0fa
HK
228 if (ret == false && !IS_ERR_OR_NULL(fwnode) &&
229 !IS_ERR_OR_NULL(fwnode->secondary))
362c0b30
AS
230 ret = __fwnode_property_present(fwnode->secondary, propname);
231 return ret;
232}
8a0662d9
RW
233EXPORT_SYMBOL_GPL(fwnode_property_present);
234
b31384fa
RW
235/**
236 * device_property_read_u8_array - return a u8 array property of a device
237 * @dev: Device to get the property of
238 * @propname: Name of the property
5c0acf3b 239 * @val: The values are stored here or %NULL to return the number of values
b31384fa
RW
240 * @nval: Size of the @val array
241 *
242 * Function reads an array of u8 properties with @propname from the device
243 * firmware description and stores them to @val if found.
244 *
5c0acf3b
AH
245 * Return: number of values if @val was %NULL,
246 * %0 if the property was found (success),
b31384fa
RW
247 * %-EINVAL if given arguments are not valid,
248 * %-ENODATA if the property does not have a value,
249 * %-EPROTO if the property is not an array of numbers,
250 * %-EOVERFLOW if the size of the property is not as expected.
4fa7508e 251 * %-ENXIO if no suitable firmware interface is present.
b31384fa
RW
252 */
253int device_property_read_u8_array(struct device *dev, const char *propname,
254 u8 *val, size_t nval)
255{
9017f252 256 return fwnode_property_read_u8_array(dev_fwnode(dev), propname, val, nval);
b31384fa
RW
257}
258EXPORT_SYMBOL_GPL(device_property_read_u8_array);
259
260/**
261 * device_property_read_u16_array - return a u16 array property of a device
262 * @dev: Device to get the property of
263 * @propname: Name of the property
5c0acf3b 264 * @val: The values are stored here or %NULL to return the number of values
b31384fa
RW
265 * @nval: Size of the @val array
266 *
267 * Function reads an array of u16 properties with @propname from the device
268 * firmware description and stores them to @val if found.
269 *
5c0acf3b
AH
270 * Return: number of values if @val was %NULL,
271 * %0 if the property was found (success),
b31384fa
RW
272 * %-EINVAL if given arguments are not valid,
273 * %-ENODATA if the property does not have a value,
274 * %-EPROTO if the property is not an array of numbers,
275 * %-EOVERFLOW if the size of the property is not as expected.
4fa7508e 276 * %-ENXIO if no suitable firmware interface is present.
b31384fa
RW
277 */
278int device_property_read_u16_array(struct device *dev, const char *propname,
279 u16 *val, size_t nval)
280{
9017f252 281 return fwnode_property_read_u16_array(dev_fwnode(dev), propname, val, nval);
b31384fa
RW
282}
283EXPORT_SYMBOL_GPL(device_property_read_u16_array);
284
285/**
286 * device_property_read_u32_array - return a u32 array property of a device
287 * @dev: Device to get the property of
288 * @propname: Name of the property
5c0acf3b 289 * @val: The values are stored here or %NULL to return the number of values
b31384fa
RW
290 * @nval: Size of the @val array
291 *
292 * Function reads an array of u32 properties with @propname from the device
293 * firmware description and stores them to @val if found.
294 *
5c0acf3b
AH
295 * Return: number of values if @val was %NULL,
296 * %0 if the property was found (success),
b31384fa
RW
297 * %-EINVAL if given arguments are not valid,
298 * %-ENODATA if the property does not have a value,
299 * %-EPROTO if the property is not an array of numbers,
300 * %-EOVERFLOW if the size of the property is not as expected.
4fa7508e 301 * %-ENXIO if no suitable firmware interface is present.
b31384fa
RW
302 */
303int device_property_read_u32_array(struct device *dev, const char *propname,
304 u32 *val, size_t nval)
305{
9017f252 306 return fwnode_property_read_u32_array(dev_fwnode(dev), propname, val, nval);
b31384fa
RW
307}
308EXPORT_SYMBOL_GPL(device_property_read_u32_array);
309
310/**
311 * device_property_read_u64_array - return a u64 array property of a device
312 * @dev: Device to get the property of
313 * @propname: Name of the property
5c0acf3b 314 * @val: The values are stored here or %NULL to return the number of values
b31384fa
RW
315 * @nval: Size of the @val array
316 *
317 * Function reads an array of u64 properties with @propname from the device
318 * firmware description and stores them to @val if found.
319 *
5c0acf3b
AH
320 * Return: number of values if @val was %NULL,
321 * %0 if the property was found (success),
b31384fa
RW
322 * %-EINVAL if given arguments are not valid,
323 * %-ENODATA if the property does not have a value,
324 * %-EPROTO if the property is not an array of numbers,
325 * %-EOVERFLOW if the size of the property is not as expected.
4fa7508e 326 * %-ENXIO if no suitable firmware interface is present.
b31384fa
RW
327 */
328int device_property_read_u64_array(struct device *dev, const char *propname,
329 u64 *val, size_t nval)
330{
9017f252 331 return fwnode_property_read_u64_array(dev_fwnode(dev), propname, val, nval);
b31384fa
RW
332}
333EXPORT_SYMBOL_GPL(device_property_read_u64_array);
334
335/**
336 * device_property_read_string_array - return a string array property of device
337 * @dev: Device to get the property of
338 * @propname: Name of the property
5c0acf3b 339 * @val: The values are stored here or %NULL to return the number of values
b31384fa
RW
340 * @nval: Size of the @val array
341 *
342 * Function reads an array of string properties with @propname from the device
343 * firmware description and stores them to @val if found.
344 *
5c0acf3b
AH
345 * Return: number of values if @val was %NULL,
346 * %0 if the property was found (success),
b31384fa
RW
347 * %-EINVAL if given arguments are not valid,
348 * %-ENODATA if the property does not have a value,
349 * %-EPROTO or %-EILSEQ if the property is not an array of strings,
350 * %-EOVERFLOW if the size of the property is not as expected.
4fa7508e 351 * %-ENXIO if no suitable firmware interface is present.
b31384fa
RW
352 */
353int device_property_read_string_array(struct device *dev, const char *propname,
354 const char **val, size_t nval)
355{
9017f252 356 return fwnode_property_read_string_array(dev_fwnode(dev), propname, val, nval);
b31384fa
RW
357}
358EXPORT_SYMBOL_GPL(device_property_read_string_array);
359
360/**
361 * device_property_read_string - return a string property of a device
362 * @dev: Device to get the property of
363 * @propname: Name of the property
364 * @val: The value is stored here
365 *
366 * Function reads property @propname from the device firmware description and
367 * stores the value into @val if found. The value is checked to be a string.
368 *
369 * Return: %0 if the property was found (success),
370 * %-EINVAL if given arguments are not valid,
371 * %-ENODATA if the property does not have a value,
372 * %-EPROTO or %-EILSEQ if the property type is not a string.
4fa7508e 373 * %-ENXIO if no suitable firmware interface is present.
b31384fa
RW
374 */
375int device_property_read_string(struct device *dev, const char *propname,
376 const char **val)
377{
9017f252 378 return fwnode_property_read_string(dev_fwnode(dev), propname, val);
b31384fa
RW
379}
380EXPORT_SYMBOL_GPL(device_property_read_string);
8a0662d9 381
3f5c8d31
MW
382/**
383 * device_property_match_string - find a string in an array and return index
384 * @dev: Device to get the property of
385 * @propname: Name of the property holding the array
386 * @string: String to look for
387 *
388 * Find a given string in a string array and if it is found return the
389 * index back.
390 *
391 * Return: %0 if the property was found (success),
392 * %-EINVAL if given arguments are not valid,
393 * %-ENODATA if the property does not have a value,
394 * %-EPROTO if the property is not an array of strings,
395 * %-ENXIO if no suitable firmware interface is present.
396 */
397int device_property_match_string(struct device *dev, const char *propname,
398 const char *string)
399{
400 return fwnode_property_match_string(dev_fwnode(dev), propname, string);
401}
402EXPORT_SYMBOL_GPL(device_property_match_string);
403
1d656fb7
AS
404#define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \
405 (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \
9017f252
RW
406 : of_property_count_elems_of_size((node), (propname), sizeof(type))
407
318a1971
AS
408#define PSET_PROP_READ_ARRAY(node, propname, type, val, nval) \
409 (val) ? pset_prop_read_##type##_array((node), (propname), (val), (nval)) \
410 : pset_prop_count_elems_of_size((node), (propname), sizeof(type))
411
362c0b30 412#define FWNODE_PROP_READ(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
1d656fb7
AS
413({ \
414 int _ret_; \
415 if (is_of_node(_fwnode_)) \
416 _ret_ = OF_DEV_PROP_READ_ARRAY(to_of_node(_fwnode_), _propname_, \
417 _type_, _val_, _nval_); \
418 else if (is_acpi_node(_fwnode_)) \
419 _ret_ = acpi_node_prop_read(_fwnode_, _propname_, _proptype_, \
420 _val_, _nval_); \
61f5e294 421 else if (is_pset_node(_fwnode_)) \
318a1971
AS
422 _ret_ = PSET_PROP_READ_ARRAY(to_pset_node(_fwnode_), _propname_, \
423 _type_, _val_, _nval_); \
1d656fb7
AS
424 else \
425 _ret_ = -ENXIO; \
426 _ret_; \
8a0662d9
RW
427})
428
362c0b30
AS
429#define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
430({ \
431 int _ret_; \
432 _ret_ = FWNODE_PROP_READ(_fwnode_, _propname_, _type_, _proptype_, \
433 _val_, _nval_); \
0d67e0fa
HK
434 if (_ret_ == -EINVAL && !IS_ERR_OR_NULL(_fwnode_) && \
435 !IS_ERR_OR_NULL(_fwnode_->secondary)) \
362c0b30
AS
436 _ret_ = FWNODE_PROP_READ(_fwnode_->secondary, _propname_, _type_, \
437 _proptype_, _val_, _nval_); \
438 _ret_; \
439})
440
8a0662d9
RW
441/**
442 * fwnode_property_read_u8_array - return a u8 array property of firmware node
443 * @fwnode: Firmware node to get the property of
444 * @propname: Name of the property
5c0acf3b 445 * @val: The values are stored here or %NULL to return the number of values
8a0662d9
RW
446 * @nval: Size of the @val array
447 *
448 * Read an array of u8 properties with @propname from @fwnode and stores them to
449 * @val if found.
450 *
5c0acf3b
AH
451 * Return: number of values if @val was %NULL,
452 * %0 if the property was found (success),
8a0662d9
RW
453 * %-EINVAL if given arguments are not valid,
454 * %-ENODATA if the property does not have a value,
455 * %-EPROTO if the property is not an array of numbers,
456 * %-EOVERFLOW if the size of the property is not as expected,
457 * %-ENXIO if no suitable firmware interface is present.
458 */
459int fwnode_property_read_u8_array(struct fwnode_handle *fwnode,
460 const char *propname, u8 *val, size_t nval)
461{
462 return FWNODE_PROP_READ_ARRAY(fwnode, propname, u8, DEV_PROP_U8,
463 val, nval);
464}
465EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array);
466
467/**
468 * fwnode_property_read_u16_array - return a u16 array property of firmware node
469 * @fwnode: Firmware node to get the property of
470 * @propname: Name of the property
5c0acf3b 471 * @val: The values are stored here or %NULL to return the number of values
8a0662d9
RW
472 * @nval: Size of the @val array
473 *
474 * Read an array of u16 properties with @propname from @fwnode and store them to
475 * @val if found.
476 *
5c0acf3b
AH
477 * Return: number of values if @val was %NULL,
478 * %0 if the property was found (success),
8a0662d9
RW
479 * %-EINVAL if given arguments are not valid,
480 * %-ENODATA if the property does not have a value,
481 * %-EPROTO if the property is not an array of numbers,
482 * %-EOVERFLOW if the size of the property is not as expected,
483 * %-ENXIO if no suitable firmware interface is present.
484 */
485int fwnode_property_read_u16_array(struct fwnode_handle *fwnode,
486 const char *propname, u16 *val, size_t nval)
487{
488 return FWNODE_PROP_READ_ARRAY(fwnode, propname, u16, DEV_PROP_U16,
489 val, nval);
490}
491EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array);
492
493/**
494 * fwnode_property_read_u32_array - return a u32 array property of firmware node
495 * @fwnode: Firmware node to get the property of
496 * @propname: Name of the property
5c0acf3b 497 * @val: The values are stored here or %NULL to return the number of values
8a0662d9
RW
498 * @nval: Size of the @val array
499 *
500 * Read an array of u32 properties with @propname from @fwnode store them to
501 * @val if found.
502 *
5c0acf3b
AH
503 * Return: number of values if @val was %NULL,
504 * %0 if the property was found (success),
8a0662d9
RW
505 * %-EINVAL if given arguments are not valid,
506 * %-ENODATA if the property does not have a value,
507 * %-EPROTO if the property is not an array of numbers,
508 * %-EOVERFLOW if the size of the property is not as expected,
509 * %-ENXIO if no suitable firmware interface is present.
510 */
511int fwnode_property_read_u32_array(struct fwnode_handle *fwnode,
512 const char *propname, u32 *val, size_t nval)
513{
514 return FWNODE_PROP_READ_ARRAY(fwnode, propname, u32, DEV_PROP_U32,
515 val, nval);
516}
517EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array);
518
519/**
520 * fwnode_property_read_u64_array - return a u64 array property firmware node
521 * @fwnode: Firmware node to get the property of
522 * @propname: Name of the property
5c0acf3b 523 * @val: The values are stored here or %NULL to return the number of values
8a0662d9
RW
524 * @nval: Size of the @val array
525 *
526 * Read an array of u64 properties with @propname from @fwnode and store them to
527 * @val if found.
528 *
5c0acf3b
AH
529 * Return: number of values if @val was %NULL,
530 * %0 if the property was found (success),
8a0662d9
RW
531 * %-EINVAL if given arguments are not valid,
532 * %-ENODATA if the property does not have a value,
533 * %-EPROTO if the property is not an array of numbers,
534 * %-EOVERFLOW if the size of the property is not as expected,
535 * %-ENXIO if no suitable firmware interface is present.
536 */
537int fwnode_property_read_u64_array(struct fwnode_handle *fwnode,
538 const char *propname, u64 *val, size_t nval)
539{
540 return FWNODE_PROP_READ_ARRAY(fwnode, propname, u64, DEV_PROP_U64,
541 val, nval);
542}
543EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array);
544
362c0b30
AS
545static int __fwnode_property_read_string_array(struct fwnode_handle *fwnode,
546 const char *propname,
547 const char **val, size_t nval)
548{
549 if (is_of_node(fwnode))
550 return val ?
551 of_property_read_string_array(to_of_node(fwnode),
552 propname, val, nval) :
553 of_property_count_strings(to_of_node(fwnode), propname);
554 else if (is_acpi_node(fwnode))
555 return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
556 val, nval);
557 else if (is_pset_node(fwnode))
558 return val ?
559 pset_prop_read_string_array(to_pset_node(fwnode),
560 propname, val, nval) :
561 pset_prop_count_elems_of_size(to_pset_node(fwnode),
562 propname,
563 sizeof(const char *));
564 return -ENXIO;
565}
566
567static int __fwnode_property_read_string(struct fwnode_handle *fwnode,
568 const char *propname, const char **val)
569{
570 if (is_of_node(fwnode))
571 return of_property_read_string(to_of_node(fwnode), propname, val);
572 else if (is_acpi_node(fwnode))
573 return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
574 val, 1);
575 else if (is_pset_node(fwnode))
576 return pset_prop_read_string(to_pset_node(fwnode), propname, val);
577 return -ENXIO;
578}
579
8a0662d9
RW
580/**
581 * fwnode_property_read_string_array - return string array property of a node
582 * @fwnode: Firmware node to get the property of
583 * @propname: Name of the property
5c0acf3b 584 * @val: The values are stored here or %NULL to return the number of values
8a0662d9
RW
585 * @nval: Size of the @val array
586 *
587 * Read an string list property @propname from the given firmware node and store
588 * them to @val if found.
589 *
5c0acf3b
AH
590 * Return: number of values if @val was %NULL,
591 * %0 if the property was found (success),
8a0662d9
RW
592 * %-EINVAL if given arguments are not valid,
593 * %-ENODATA if the property does not have a value,
594 * %-EPROTO if the property is not an array of strings,
595 * %-EOVERFLOW if the size of the property is not as expected,
596 * %-ENXIO if no suitable firmware interface is present.
597 */
598int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
599 const char *propname, const char **val,
600 size_t nval)
601{
362c0b30
AS
602 int ret;
603
604 ret = __fwnode_property_read_string_array(fwnode, propname, val, nval);
0d67e0fa
HK
605 if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) &&
606 !IS_ERR_OR_NULL(fwnode->secondary))
362c0b30
AS
607 ret = __fwnode_property_read_string_array(fwnode->secondary,
608 propname, val, nval);
609 return ret;
8a0662d9
RW
610}
611EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
612
613/**
614 * fwnode_property_read_string - return a string property of a firmware node
615 * @fwnode: Firmware node to get the property of
616 * @propname: Name of the property
617 * @val: The value is stored here
618 *
619 * Read property @propname from the given firmware node and store the value into
620 * @val if found. The value is checked to be a string.
621 *
622 * Return: %0 if the property was found (success),
623 * %-EINVAL if given arguments are not valid,
624 * %-ENODATA if the property does not have a value,
625 * %-EPROTO or %-EILSEQ if the property is not a string,
626 * %-ENXIO if no suitable firmware interface is present.
627 */
628int fwnode_property_read_string(struct fwnode_handle *fwnode,
629 const char *propname, const char **val)
630{
362c0b30
AS
631 int ret;
632
633 ret = __fwnode_property_read_string(fwnode, propname, val);
0d67e0fa
HK
634 if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) &&
635 !IS_ERR_OR_NULL(fwnode->secondary))
362c0b30
AS
636 ret = __fwnode_property_read_string(fwnode->secondary,
637 propname, val);
638 return ret;
8a0662d9
RW
639}
640EXPORT_SYMBOL_GPL(fwnode_property_read_string);
641
3f5c8d31
MW
642/**
643 * fwnode_property_match_string - find a string in an array and return index
644 * @fwnode: Firmware node to get the property of
645 * @propname: Name of the property holding the array
646 * @string: String to look for
647 *
648 * Find a given string in a string array and if it is found return the
649 * index back.
650 *
651 * Return: %0 if the property was found (success),
652 * %-EINVAL if given arguments are not valid,
653 * %-ENODATA if the property does not have a value,
654 * %-EPROTO if the property is not an array of strings,
655 * %-ENXIO if no suitable firmware interface is present.
656 */
657int fwnode_property_match_string(struct fwnode_handle *fwnode,
658 const char *propname, const char *string)
659{
660 const char **values;
a7c1d0a9 661 int nval, ret;
3f5c8d31
MW
662
663 nval = fwnode_property_read_string_array(fwnode, propname, NULL, 0);
664 if (nval < 0)
665 return nval;
666
f6740c18
AS
667 if (nval == 0)
668 return -ENODATA;
669
3f5c8d31
MW
670 values = kcalloc(nval, sizeof(*values), GFP_KERNEL);
671 if (!values)
672 return -ENOMEM;
673
674 ret = fwnode_property_read_string_array(fwnode, propname, values, nval);
675 if (ret < 0)
676 goto out;
677
a7c1d0a9
AS
678 ret = match_string(values, nval, string);
679 if (ret < 0)
680 ret = -ENODATA;
3f5c8d31
MW
681out:
682 kfree(values);
683 return ret;
684}
685EXPORT_SYMBOL_GPL(fwnode_property_match_string);
686
2d479e1f
DT
687static int property_copy_string_array(struct property_entry *dst,
688 const struct property_entry *src)
13141e1c 689{
2d479e1f
DT
690 char **d;
691 size_t nval = src->length / sizeof(*d);
692 int i;
13141e1c 693
2d479e1f
DT
694 d = kcalloc(nval, sizeof(*d), GFP_KERNEL);
695 if (!d)
696 return -ENOMEM;
13141e1c 697
2d479e1f
DT
698 for (i = 0; i < nval; i++) {
699 d[i] = kstrdup(src->pointer.str[i], GFP_KERNEL);
700 if (!d[i] && src->pointer.str[i]) {
701 while (--i >= 0)
702 kfree(d[i]);
703 kfree(d);
704 return -ENOMEM;
13141e1c 705 }
13141e1c
MW
706 }
707
2d479e1f
DT
708 dst->pointer.raw_data = d;
709 return 0;
13141e1c
MW
710}
711
2d479e1f
DT
712static int property_entry_copy_data(struct property_entry *dst,
713 const struct property_entry *src)
13141e1c 714{
2d479e1f 715 int error;
13141e1c
MW
716
717 dst->name = kstrdup(src->name, GFP_KERNEL);
718 if (!dst->name)
719 return -ENOMEM;
720
721 if (src->is_array) {
2d479e1f
DT
722 if (!src->length) {
723 error = -ENODATA;
724 goto out_free_name;
725 }
f6740c18 726
13141e1c 727 if (src->is_string) {
2d479e1f
DT
728 error = property_copy_string_array(dst, src);
729 if (error)
730 goto out_free_name;
13141e1c
MW
731 } else {
732 dst->pointer.raw_data = kmemdup(src->pointer.raw_data,
733 src->length, GFP_KERNEL);
2d479e1f
DT
734 if (!dst->pointer.raw_data) {
735 error = -ENOMEM;
736 goto out_free_name;
737 }
13141e1c
MW
738 }
739 } else if (src->is_string) {
740 dst->value.str = kstrdup(src->value.str, GFP_KERNEL);
2d479e1f
DT
741 if (!dst->value.str && src->value.str) {
742 error = -ENOMEM;
743 goto out_free_name;
744 }
13141e1c
MW
745 } else {
746 dst->value.raw_data = src->value.raw_data;
747 }
748
749 dst->length = src->length;
750 dst->is_array = src->is_array;
751 dst->is_string = src->is_string;
752
753 return 0;
2d479e1f
DT
754
755out_free_name:
756 kfree(dst->name);
757 return error;
758}
759
760static void property_entry_free_data(const struct property_entry *p)
761{
762 size_t i, nval;
763
764 if (p->is_array) {
765 if (p->is_string && p->pointer.str) {
766 nval = p->length / sizeof(const char *);
767 for (i = 0; i < nval; i++)
768 kfree(p->pointer.str[i]);
769 }
770 kfree(p->pointer.raw_data);
771 } else if (p->is_string) {
772 kfree(p->value.str);
773 }
774 kfree(p->name);
775}
776
777/**
778 * property_entries_dup - duplicate array of properties
779 * @properties: array of properties to copy
780 *
781 * This function creates a deep copy of the given NULL-terminated array
782 * of property entries.
783 */
784struct property_entry *
785property_entries_dup(const struct property_entry *properties)
786{
787 struct property_entry *p;
788 int i, n = 0;
789
790 while (properties[n].name)
791 n++;
792
793 p = kcalloc(n + 1, sizeof(*p), GFP_KERNEL);
794 if (!p)
795 return ERR_PTR(-ENOMEM);
796
797 for (i = 0; i < n; i++) {
798 int ret = property_entry_copy_data(&p[i], &properties[i]);
799 if (ret) {
800 while (--i >= 0)
801 property_entry_free_data(&p[i]);
802 kfree(p);
803 return ERR_PTR(ret);
804 }
805 }
806
807 return p;
808}
809EXPORT_SYMBOL_GPL(property_entries_dup);
810
811/**
812 * property_entries_free - free previously allocated array of properties
813 * @properties: array of properties to destroy
814 *
815 * This function frees given NULL-terminated array of property entries,
816 * along with their data.
817 */
818void property_entries_free(const struct property_entry *properties)
819{
820 const struct property_entry *p;
821
822 for (p = properties; p->name; p++)
823 property_entry_free_data(p);
824
825 kfree(properties);
826}
827EXPORT_SYMBOL_GPL(property_entries_free);
828
829/**
830 * pset_free_set - releases memory allocated for copied property set
831 * @pset: Property set to release
832 *
833 * Function takes previously copied property set and releases all the
834 * memory allocated to it.
835 */
836static void pset_free_set(struct property_set *pset)
837{
838 if (!pset)
839 return;
840
841 property_entries_free(pset->properties);
842 kfree(pset);
13141e1c
MW
843}
844
845/**
846 * pset_copy_set - copies property set
847 * @pset: Property set to copy
848 *
849 * This function takes a deep copy of the given property set and returns
850 * pointer to the copy. Call device_free_property_set() to free resources
851 * allocated in this function.
852 *
853 * Return: Pointer to the new property set or error pointer.
854 */
855static struct property_set *pset_copy_set(const struct property_set *pset)
856{
2d479e1f 857 struct property_entry *properties;
13141e1c 858 struct property_set *p;
13141e1c
MW
859
860 p = kzalloc(sizeof(*p), GFP_KERNEL);
861 if (!p)
862 return ERR_PTR(-ENOMEM);
863
2d479e1f
DT
864 properties = property_entries_dup(pset->properties);
865 if (IS_ERR(properties)) {
13141e1c 866 kfree(p);
2d479e1f 867 return ERR_CAST(properties);
13141e1c
MW
868 }
869
2d479e1f 870 p->properties = properties;
13141e1c
MW
871 return p;
872}
873
874/**
f4d05266 875 * device_remove_properties - Remove properties from a device object.
13141e1c
MW
876 * @dev: Device whose properties to remove.
877 *
878 * The function removes properties previously associated to the device
f4d05266 879 * secondary firmware node with device_add_properties(). Memory allocated
13141e1c
MW
880 * to the properties will also be released.
881 */
f4d05266 882void device_remove_properties(struct device *dev)
13141e1c
MW
883{
884 struct fwnode_handle *fwnode;
885
886 fwnode = dev_fwnode(dev);
887 if (!fwnode)
888 return;
889 /*
890 * Pick either primary or secondary node depending which one holds
891 * the pset. If there is no real firmware node (ACPI/DT) primary
892 * will hold the pset.
893 */
0d67e0fa
HK
894 if (is_pset_node(fwnode)) {
895 set_primary_fwnode(dev, NULL);
13141e1c 896 pset_free_set(to_pset_node(fwnode));
0d67e0fa
HK
897 } else {
898 fwnode = fwnode->secondary;
899 if (!IS_ERR(fwnode) && is_pset_node(fwnode)) {
900 set_secondary_fwnode(dev, NULL);
901 pset_free_set(to_pset_node(fwnode));
902 }
903 }
13141e1c 904}
f4d05266 905EXPORT_SYMBOL_GPL(device_remove_properties);
13141e1c
MW
906
907/**
f4d05266 908 * device_add_properties - Add a collection of properties to a device object.
13141e1c 909 * @dev: Device to add properties to.
f4d05266 910 * @properties: Collection of properties to add.
13141e1c 911 *
f4d05266
HK
912 * Associate a collection of device properties represented by @properties with
913 * @dev as its secondary firmware node. The function takes a copy of
914 * @properties.
13141e1c 915 */
bec84da8
DT
916int device_add_properties(struct device *dev,
917 const struct property_entry *properties)
13141e1c 918{
f4d05266 919 struct property_set *p, pset;
13141e1c 920
f4d05266 921 if (!properties)
13141e1c
MW
922 return -EINVAL;
923
f4d05266
HK
924 pset.properties = properties;
925
926 p = pset_copy_set(&pset);
13141e1c
MW
927 if (IS_ERR(p))
928 return PTR_ERR(p);
929
930 p->fwnode.type = FWNODE_PDATA;
931 set_secondary_fwnode(dev, &p->fwnode);
932 return 0;
933}
f4d05266 934EXPORT_SYMBOL_GPL(device_add_properties);
13141e1c 935
afaf26fd
MW
936/**
937 * fwnode_get_parent - Return parent firwmare node
938 * @fwnode: Firmware whose parent is retrieved
939 *
940 * Return parent firmware node of the given node if possible or %NULL if no
941 * parent was available.
942 */
943struct fwnode_handle *fwnode_get_parent(struct fwnode_handle *fwnode)
944{
945 struct fwnode_handle *parent = NULL;
946
947 if (is_of_node(fwnode)) {
948 struct device_node *node;
949
950 node = of_get_parent(to_of_node(fwnode));
951 if (node)
952 parent = &node->fwnode;
953 } else if (is_acpi_node(fwnode)) {
954 parent = acpi_node_get_parent(fwnode);
955 }
956
957 return parent;
958}
959EXPORT_SYMBOL_GPL(fwnode_get_parent);
960
8a0662d9 961/**
34055190
MW
962 * fwnode_get_next_child_node - Return the next child node handle for a node
963 * @fwnode: Firmware node to find the next child node for.
964 * @child: Handle to one of the node's child nodes or a %NULL handle.
8a0662d9 965 */
34055190 966struct fwnode_handle *fwnode_get_next_child_node(struct fwnode_handle *fwnode,
8a0662d9
RW
967 struct fwnode_handle *child)
968{
34055190 969 if (is_of_node(fwnode)) {
8a0662d9
RW
970 struct device_node *node;
971
34055190
MW
972 node = of_get_next_available_child(to_of_node(fwnode),
973 to_of_node(child));
8a0662d9
RW
974 if (node)
975 return &node->fwnode;
34055190
MW
976 } else if (is_acpi_node(fwnode)) {
977 return acpi_get_next_subnode(fwnode, child);
8a0662d9 978 }
34055190 979
8a0662d9
RW
980 return NULL;
981}
34055190
MW
982EXPORT_SYMBOL_GPL(fwnode_get_next_child_node);
983
984/**
985 * device_get_next_child_node - Return the next child node handle for a device
986 * @dev: Device to find the next child node for.
987 * @child: Handle to one of the device's child nodes or a null handle.
988 */
989struct fwnode_handle *device_get_next_child_node(struct device *dev,
990 struct fwnode_handle *child)
991{
992 struct acpi_device *adev = ACPI_COMPANION(dev);
993 struct fwnode_handle *fwnode = NULL;
994
995 if (dev->of_node)
996 fwnode = &dev->of_node->fwnode;
997 else if (adev)
998 fwnode = acpi_fwnode_handle(adev);
999
1000 return fwnode_get_next_child_node(fwnode, child);
1001}
8a0662d9
RW
1002EXPORT_SYMBOL_GPL(device_get_next_child_node);
1003
613e9721 1004/**
21ea73f5
MW
1005 * fwnode_get_named_child_node - Return first matching named child node handle
1006 * @fwnode: Firmware node to find the named child node for.
613e9721
AT
1007 * @childname: String to match child node name against.
1008 */
21ea73f5 1009struct fwnode_handle *fwnode_get_named_child_node(struct fwnode_handle *fwnode,
613e9721
AT
1010 const char *childname)
1011{
1012 struct fwnode_handle *child;
1013
1014 /*
21ea73f5 1015 * Find first matching named child node of this fwnode.
613e9721
AT
1016 * For ACPI this will be a data only sub-node.
1017 */
21ea73f5 1018 fwnode_for_each_child_node(fwnode, child) {
613e9721
AT
1019 if (is_of_node(child)) {
1020 if (!of_node_cmp(to_of_node(child)->name, childname))
1021 return child;
1022 } else if (is_acpi_data_node(child)) {
1023 if (acpi_data_node_match(child, childname))
1024 return child;
1025 }
1026 }
1027
1028 return NULL;
1029}
21ea73f5
MW
1030EXPORT_SYMBOL_GPL(fwnode_get_named_child_node);
1031
1032/**
1033 * device_get_named_child_node - Return first matching named child node handle
1034 * @dev: Device to find the named child node for.
1035 * @childname: String to match child node name against.
1036 */
1037struct fwnode_handle *device_get_named_child_node(struct device *dev,
1038 const char *childname)
1039{
1040 return fwnode_get_named_child_node(dev_fwnode(dev), childname);
1041}
613e9721
AT
1042EXPORT_SYMBOL_GPL(device_get_named_child_node);
1043
e7887c28
SA
1044/**
1045 * fwnode_handle_get - Obtain a reference to a device node
1046 * @fwnode: Pointer to the device node to obtain the reference to.
1047 */
1048void fwnode_handle_get(struct fwnode_handle *fwnode)
1049{
1050 if (is_of_node(fwnode))
1051 of_node_get(to_of_node(fwnode));
1052}
1053EXPORT_SYMBOL_GPL(fwnode_handle_get);
1054
8a0662d9
RW
1055/**
1056 * fwnode_handle_put - Drop reference to a device node
1057 * @fwnode: Pointer to the device node to drop the reference to.
1058 *
1059 * This has to be used when terminating device_for_each_child_node() iteration
1060 * with break or return to prevent stale device node references from being left
1061 * behind.
1062 */
1063void fwnode_handle_put(struct fwnode_handle *fwnode)
1064{
1065 if (is_of_node(fwnode))
c181fb3e 1066 of_node_put(to_of_node(fwnode));
8a0662d9
RW
1067}
1068EXPORT_SYMBOL_GPL(fwnode_handle_put);
1069
1070/**
1071 * device_get_child_node_count - return the number of child nodes for device
1072 * @dev: Device to cound the child nodes for
1073 */
1074unsigned int device_get_child_node_count(struct device *dev)
1075{
1076 struct fwnode_handle *child;
1077 unsigned int count = 0;
1078
1079 device_for_each_child_node(dev, child)
1080 count++;
1081
1082 return count;
1083}
1084EXPORT_SYMBOL_GPL(device_get_child_node_count);
05ca5560 1085
e5e55864
SS
1086bool device_dma_supported(struct device *dev)
1087{
1088 /* For DT, this is always supported.
1089 * For ACPI, this depends on CCA, which
1090 * is determined by the acpi_dma_supported().
1091 */
1092 if (IS_ENABLED(CONFIG_OF) && dev->of_node)
1093 return true;
1094
1095 return acpi_dma_supported(ACPI_COMPANION(dev));
1096}
1097EXPORT_SYMBOL_GPL(device_dma_supported);
1098
1099enum dev_dma_attr device_get_dma_attr(struct device *dev)
1100{
1101 enum dev_dma_attr attr = DEV_DMA_NOT_SUPPORTED;
1102
1103 if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
1104 if (of_dma_is_coherent(dev->of_node))
1105 attr = DEV_DMA_COHERENT;
1106 else
1107 attr = DEV_DMA_NON_COHERENT;
1108 } else
1109 attr = acpi_get_dma_attr(ACPI_COMPANION(dev));
1110
1111 return attr;
1112}
1113EXPORT_SYMBOL_GPL(device_get_dma_attr);
1114
4c96b7dc 1115/**
2f710a3a 1116 * device_get_phy_mode - Get phy mode for given device
4c96b7dc
JL
1117 * @dev: Pointer to the given device
1118 *
1119 * The function gets phy interface string from property 'phy-mode' or
1120 * 'phy-connection-type', and return its index in phy_modes table, or errno in
1121 * error case.
1122 */
1123int device_get_phy_mode(struct device *dev)
1124{
1125 const char *pm;
1126 int err, i;
1127
1128 err = device_property_read_string(dev, "phy-mode", &pm);
1129 if (err < 0)
1130 err = device_property_read_string(dev,
1131 "phy-connection-type", &pm);
1132 if (err < 0)
1133 return err;
1134
1135 for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++)
1136 if (!strcasecmp(pm, phy_modes(i)))
1137 return i;
1138
1139 return -ENODEV;
1140}
1141EXPORT_SYMBOL_GPL(device_get_phy_mode);
1142
1143static void *device_get_mac_addr(struct device *dev,
1144 const char *name, char *addr,
1145 int alen)
1146{
1147 int ret = device_property_read_u8_array(dev, name, addr, alen);
1148
2f710a3a 1149 if (ret == 0 && alen == ETH_ALEN && is_valid_ether_addr(addr))
4c96b7dc
JL
1150 return addr;
1151 return NULL;
1152}
1153
1154/**
2f710a3a
JL
1155 * device_get_mac_address - Get the MAC for a given device
1156 * @dev: Pointer to the device
1157 * @addr: Address of buffer to store the MAC in
1158 * @alen: Length of the buffer pointed to by addr, should be ETH_ALEN
1159 *
1160 * Search the firmware node for the best MAC address to use. 'mac-address' is
4c96b7dc
JL
1161 * checked first, because that is supposed to contain to "most recent" MAC
1162 * address. If that isn't set, then 'local-mac-address' is checked next,
1163 * because that is the default address. If that isn't set, then the obsolete
1164 * 'address' is checked, just in case we're using an old device tree.
1165 *
1166 * Note that the 'address' property is supposed to contain a virtual address of
1167 * the register set, but some DTS files have redefined that property to be the
1168 * MAC address.
1169 *
1170 * All-zero MAC addresses are rejected, because those could be properties that
2f710a3a
JL
1171 * exist in the firmware tables, but were not updated by the firmware. For
1172 * example, the DTS could define 'mac-address' and 'local-mac-address', with
1173 * zero MAC addresses. Some older U-Boots only initialized 'local-mac-address'.
1174 * In this case, the real MAC is in 'local-mac-address', and 'mac-address'
1175 * exists but is all zeros.
4c96b7dc
JL
1176*/
1177void *device_get_mac_address(struct device *dev, char *addr, int alen)
1178{
5b902d6f 1179 char *res;
4c96b7dc 1180
5b902d6f
JG
1181 res = device_get_mac_addr(dev, "mac-address", addr, alen);
1182 if (res)
1183 return res;
1184
1185 res = device_get_mac_addr(dev, "local-mac-address", addr, alen);
1186 if (res)
1187 return res;
4c96b7dc
JL
1188
1189 return device_get_mac_addr(dev, "address", addr, alen);
1190}
1191EXPORT_SYMBOL(device_get_mac_address);
07bb80d4
MW
1192
1193/**
1194 * device_graph_get_next_endpoint - Get next endpoint firmware node
1195 * @fwnode: Pointer to the parent firmware node
1196 * @prev: Previous endpoint node or %NULL to get the first
1197 *
1198 * Returns an endpoint firmware node pointer or %NULL if no more endpoints
1199 * are available.
1200 */
1201struct fwnode_handle *
1202fwnode_graph_get_next_endpoint(struct fwnode_handle *fwnode,
1203 struct fwnode_handle *prev)
1204{
1205 struct fwnode_handle *endpoint = NULL;
1206
1207 if (is_of_node(fwnode)) {
1208 struct device_node *node;
1209
1210 node = of_graph_get_next_endpoint(to_of_node(fwnode),
1211 to_of_node(prev));
1212
1213 if (node)
1214 endpoint = &node->fwnode;
1215 } else if (is_acpi_node(fwnode)) {
1216 endpoint = acpi_graph_get_next_endpoint(fwnode, prev);
1217 if (IS_ERR(endpoint))
1218 endpoint = NULL;
1219 }
1220
1221 return endpoint;
1222
1223}
1224EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint);
1225
1226/**
1227 * fwnode_graph_get_remote_port_parent - Return fwnode of a remote device
1228 * @fwnode: Endpoint firmware node pointing to the remote endpoint
1229 *
1230 * Extracts firmware node of a remote device the @fwnode points to.
1231 */
1232struct fwnode_handle *
1233fwnode_graph_get_remote_port_parent(struct fwnode_handle *fwnode)
1234{
1235 struct fwnode_handle *parent = NULL;
1236
1237 if (is_of_node(fwnode)) {
1238 struct device_node *node;
1239
1240 node = of_graph_get_remote_port_parent(to_of_node(fwnode));
1241 if (node)
1242 parent = &node->fwnode;
1243 } else if (is_acpi_node(fwnode)) {
1244 int ret;
1245
1246 ret = acpi_graph_get_remote_endpoint(fwnode, &parent, NULL,
1247 NULL);
1248 if (ret)
1249 return NULL;
1250 }
1251
1252 return parent;
1253}
1254EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port_parent);
1255
1256/**
1257 * fwnode_graph_get_remote_port - Return fwnode of a remote port
1258 * @fwnode: Endpoint firmware node pointing to the remote endpoint
1259 *
1260 * Extracts firmware node of a remote port the @fwnode points to.
1261 */
1262struct fwnode_handle *fwnode_graph_get_remote_port(struct fwnode_handle *fwnode)
1263{
1264 struct fwnode_handle *port = NULL;
1265
1266 if (is_of_node(fwnode)) {
1267 struct device_node *node;
1268
1269 node = of_graph_get_remote_port(to_of_node(fwnode));
1270 if (node)
1271 port = &node->fwnode;
1272 } else if (is_acpi_node(fwnode)) {
1273 int ret;
1274
1275 ret = acpi_graph_get_remote_endpoint(fwnode, NULL, &port, NULL);
1276 if (ret)
1277 return NULL;
1278 }
1279
1280 return port;
1281}
1282EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port);
1283
1284/**
1285 * fwnode_graph_get_remote_endpoint - Return fwnode of a remote endpoint
1286 * @fwnode: Endpoint firmware node pointing to the remote endpoint
1287 *
1288 * Extracts firmware node of a remote endpoint the @fwnode points to.
1289 */
1290struct fwnode_handle *
1291fwnode_graph_get_remote_endpoint(struct fwnode_handle *fwnode)
1292{
1293 struct fwnode_handle *endpoint = NULL;
1294
1295 if (is_of_node(fwnode)) {
1296 struct device_node *node;
1297
1298 node = of_parse_phandle(to_of_node(fwnode), "remote-endpoint",
1299 0);
1300 if (node)
1301 endpoint = &node->fwnode;
1302 } else if (is_acpi_node(fwnode)) {
1303 int ret;
1304
1305 ret = acpi_graph_get_remote_endpoint(fwnode, NULL, NULL,
1306 &endpoint);
1307 if (ret)
1308 return NULL;
1309 }
1310
1311 return endpoint;
1312}
1313EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_endpoint);