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