2 * ACPI device specific properties support.
4 * Copyright (C) 2014, Intel Corporation
7 * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
8 * Darren Hart <dvhart@linux.intel.com>
9 * Rafael J. Wysocki <rafael.j.wysocki@intel.com>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
16 #include <linux/acpi.h>
17 #include <linux/device.h>
18 #include <linux/export.h>
22 static int acpi_data_get_property_array(const struct acpi_device_data
*data
,
24 acpi_object_type type
,
25 const union acpi_object
**obj
);
27 /* ACPI _DSD device properties GUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
28 static const guid_t prp_guid
=
29 GUID_INIT(0xdaffd814, 0x6eba, 0x4d8c,
30 0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01);
31 /* ACPI _DSD data subnodes GUID: dbb8e3e6-5886-4ba6-8795-1319f52a966b */
32 static const guid_t ads_guid
=
33 GUID_INIT(0xdbb8e3e6, 0x5886, 0x4ba6,
34 0x87, 0x95, 0x13, 0x19, 0xf5, 0x2a, 0x96, 0x6b);
36 static bool acpi_enumerate_nondev_subnodes(acpi_handle scope
,
37 const union acpi_object
*desc
,
38 struct acpi_device_data
*data
,
39 struct fwnode_handle
*parent
);
40 static bool acpi_extract_properties(const union acpi_object
*desc
,
41 struct acpi_device_data
*data
);
43 static bool acpi_nondev_subnode_extract(const union acpi_object
*desc
,
45 const union acpi_object
*link
,
46 struct list_head
*list
,
47 struct fwnode_handle
*parent
)
49 struct acpi_data_node
*dn
;
52 dn
= kzalloc(sizeof(*dn
), GFP_KERNEL
);
56 dn
->name
= link
->package
.elements
[0].string
.pointer
;
57 dn
->fwnode
.ops
= &acpi_data_fwnode_ops
;
59 INIT_LIST_HEAD(&dn
->data
.subnodes
);
61 result
= acpi_extract_properties(desc
, &dn
->data
);
68 * The scope for the subnode object lookup is the one of the
69 * namespace node (device) containing the object that has
70 * returned the package. That is, it's the scope of that
73 status
= acpi_get_parent(handle
, &scope
);
74 if (ACPI_SUCCESS(status
)
75 && acpi_enumerate_nondev_subnodes(scope
, desc
, &dn
->data
,
78 } else if (acpi_enumerate_nondev_subnodes(NULL
, desc
, &dn
->data
,
85 dn
->data
.pointer
= desc
;
86 list_add_tail(&dn
->sibling
, list
);
91 acpi_handle_debug(handle
, "Invalid properties/subnodes data, skipping\n");
95 static bool acpi_nondev_subnode_data_ok(acpi_handle handle
,
96 const union acpi_object
*link
,
97 struct list_head
*list
,
98 struct fwnode_handle
*parent
)
100 struct acpi_buffer buf
= { ACPI_ALLOCATE_BUFFER
};
103 status
= acpi_evaluate_object_typed(handle
, NULL
, NULL
, &buf
,
105 if (ACPI_FAILURE(status
))
108 if (acpi_nondev_subnode_extract(buf
.pointer
, handle
, link
, list
,
112 ACPI_FREE(buf
.pointer
);
116 static bool acpi_nondev_subnode_ok(acpi_handle scope
,
117 const union acpi_object
*link
,
118 struct list_head
*list
,
119 struct fwnode_handle
*parent
)
127 status
= acpi_get_handle(scope
, link
->package
.elements
[1].string
.pointer
,
129 if (ACPI_FAILURE(status
))
132 return acpi_nondev_subnode_data_ok(handle
, link
, list
, parent
);
135 static int acpi_add_nondev_subnodes(acpi_handle scope
,
136 const union acpi_object
*links
,
137 struct list_head
*list
,
138 struct fwnode_handle
*parent
)
143 for (i
= 0; i
< links
->package
.count
; i
++) {
144 const union acpi_object
*link
, *desc
;
148 link
= &links
->package
.elements
[i
];
149 /* Only two elements allowed. */
150 if (link
->package
.count
!= 2)
153 /* The first one must be a string. */
154 if (link
->package
.elements
[0].type
!= ACPI_TYPE_STRING
)
157 /* The second one may be a string, a reference or a package. */
158 switch (link
->package
.elements
[1].type
) {
159 case ACPI_TYPE_STRING
:
160 result
= acpi_nondev_subnode_ok(scope
, link
, list
,
163 case ACPI_TYPE_LOCAL_REFERENCE
:
164 handle
= link
->package
.elements
[1].reference
.handle
;
165 result
= acpi_nondev_subnode_data_ok(handle
, link
, list
,
168 case ACPI_TYPE_PACKAGE
:
169 desc
= &link
->package
.elements
[1];
170 result
= acpi_nondev_subnode_extract(desc
, NULL
, link
,
183 static bool acpi_enumerate_nondev_subnodes(acpi_handle scope
,
184 const union acpi_object
*desc
,
185 struct acpi_device_data
*data
,
186 struct fwnode_handle
*parent
)
190 /* Look for the ACPI data subnodes GUID. */
191 for (i
= 0; i
< desc
->package
.count
; i
+= 2) {
192 const union acpi_object
*guid
, *links
;
194 guid
= &desc
->package
.elements
[i
];
195 links
= &desc
->package
.elements
[i
+ 1];
198 * The first element must be a GUID and the second one must be
201 if (guid
->type
!= ACPI_TYPE_BUFFER
||
202 guid
->buffer
.length
!= 16 ||
203 links
->type
!= ACPI_TYPE_PACKAGE
)
206 if (!guid_equal((guid_t
*)guid
->buffer
.pointer
, &ads_guid
))
209 return acpi_add_nondev_subnodes(scope
, links
, &data
->subnodes
,
216 static bool acpi_property_value_ok(const union acpi_object
*value
)
221 * The value must be an integer, a string, a reference, or a package
222 * whose every element must be an integer, a string, or a reference.
224 switch (value
->type
) {
225 case ACPI_TYPE_INTEGER
:
226 case ACPI_TYPE_STRING
:
227 case ACPI_TYPE_LOCAL_REFERENCE
:
230 case ACPI_TYPE_PACKAGE
:
231 for (j
= 0; j
< value
->package
.count
; j
++)
232 switch (value
->package
.elements
[j
].type
) {
233 case ACPI_TYPE_INTEGER
:
234 case ACPI_TYPE_STRING
:
235 case ACPI_TYPE_LOCAL_REFERENCE
:
247 static bool acpi_properties_format_valid(const union acpi_object
*properties
)
251 for (i
= 0; i
< properties
->package
.count
; i
++) {
252 const union acpi_object
*property
;
254 property
= &properties
->package
.elements
[i
];
256 * Only two elements allowed, the first one must be a string and
257 * the second one has to satisfy certain conditions.
259 if (property
->package
.count
!= 2
260 || property
->package
.elements
[0].type
!= ACPI_TYPE_STRING
261 || !acpi_property_value_ok(&property
->package
.elements
[1]))
267 static void acpi_init_of_compatible(struct acpi_device
*adev
)
269 const union acpi_object
*of_compatible
;
272 ret
= acpi_data_get_property_array(&adev
->data
, "compatible",
273 ACPI_TYPE_STRING
, &of_compatible
);
275 ret
= acpi_dev_get_property(adev
, "compatible",
276 ACPI_TYPE_STRING
, &of_compatible
);
279 && adev
->parent
->flags
.of_compatible_ok
)
285 adev
->data
.of_compatible
= of_compatible
;
288 adev
->flags
.of_compatible_ok
= 1;
291 static bool acpi_extract_properties(const union acpi_object
*desc
,
292 struct acpi_device_data
*data
)
296 if (desc
->package
.count
% 2)
299 /* Look for the device properties GUID. */
300 for (i
= 0; i
< desc
->package
.count
; i
+= 2) {
301 const union acpi_object
*guid
, *properties
;
303 guid
= &desc
->package
.elements
[i
];
304 properties
= &desc
->package
.elements
[i
+ 1];
307 * The first element must be a GUID and the second one must be
310 if (guid
->type
!= ACPI_TYPE_BUFFER
||
311 guid
->buffer
.length
!= 16 ||
312 properties
->type
!= ACPI_TYPE_PACKAGE
)
315 if (!guid_equal((guid_t
*)guid
->buffer
.pointer
, &prp_guid
))
319 * We found the matching GUID. Now validate the format of the
320 * package immediately following it.
322 if (!acpi_properties_format_valid(properties
))
325 data
->properties
= properties
;
332 void acpi_init_properties(struct acpi_device
*adev
)
334 struct acpi_buffer buf
= { ACPI_ALLOCATE_BUFFER
};
335 struct acpi_hardware_id
*hwid
;
337 bool acpi_of
= false;
339 INIT_LIST_HEAD(&adev
->data
.subnodes
);
345 * Check if ACPI_DT_NAMESPACE_HID is present and inthat case we fill in
346 * Device Tree compatible properties for this device.
348 list_for_each_entry(hwid
, &adev
->pnp
.ids
, list
) {
349 if (!strcmp(hwid
->id
, ACPI_DT_NAMESPACE_HID
)) {
355 status
= acpi_evaluate_object_typed(adev
->handle
, "_DSD", NULL
, &buf
,
357 if (ACPI_FAILURE(status
))
360 if (acpi_extract_properties(buf
.pointer
, &adev
->data
)) {
361 adev
->data
.pointer
= buf
.pointer
;
363 acpi_init_of_compatible(adev
);
365 if (acpi_enumerate_nondev_subnodes(adev
->handle
, buf
.pointer
,
366 &adev
->data
, acpi_fwnode_handle(adev
)))
367 adev
->data
.pointer
= buf
.pointer
;
369 if (!adev
->data
.pointer
) {
370 acpi_handle_debug(adev
->handle
, "Invalid _DSD data, skipping\n");
371 ACPI_FREE(buf
.pointer
);
375 if (acpi_of
&& !adev
->flags
.of_compatible_ok
)
376 acpi_handle_info(adev
->handle
,
377 ACPI_DT_NAMESPACE_HID
" requires 'compatible' property\n");
379 if (!adev
->data
.pointer
)
380 acpi_extract_apple_properties(adev
);
383 static void acpi_destroy_nondev_subnodes(struct list_head
*list
)
385 struct acpi_data_node
*dn
, *next
;
387 if (list_empty(list
))
390 list_for_each_entry_safe_reverse(dn
, next
, list
, sibling
) {
391 acpi_destroy_nondev_subnodes(&dn
->data
.subnodes
);
392 wait_for_completion(&dn
->kobj_done
);
393 list_del(&dn
->sibling
);
394 ACPI_FREE((void *)dn
->data
.pointer
);
399 void acpi_free_properties(struct acpi_device
*adev
)
401 acpi_destroy_nondev_subnodes(&adev
->data
.subnodes
);
402 ACPI_FREE((void *)adev
->data
.pointer
);
403 adev
->data
.of_compatible
= NULL
;
404 adev
->data
.pointer
= NULL
;
405 adev
->data
.properties
= NULL
;
409 * acpi_data_get_property - return an ACPI property with given name
410 * @data: ACPI device deta object to get the property from
411 * @name: Name of the property
412 * @type: Expected property type
413 * @obj: Location to store the property value (if not %NULL)
415 * Look up a property with @name and store a pointer to the resulting ACPI
416 * object at the location pointed to by @obj if found.
418 * Callers must not attempt to free the returned objects. These objects will be
419 * freed by the ACPI core automatically during the removal of @data.
421 * Return: %0 if property with @name has been found (success),
422 * %-EINVAL if the arguments are invalid,
423 * %-EINVAL if the property doesn't exist,
424 * %-EPROTO if the property value type doesn't match @type.
426 static int acpi_data_get_property(const struct acpi_device_data
*data
,
427 const char *name
, acpi_object_type type
,
428 const union acpi_object
**obj
)
430 const union acpi_object
*properties
;
436 if (!data
->pointer
|| !data
->properties
)
439 properties
= data
->properties
;
440 for (i
= 0; i
< properties
->package
.count
; i
++) {
441 const union acpi_object
*propname
, *propvalue
;
442 const union acpi_object
*property
;
444 property
= &properties
->package
.elements
[i
];
446 propname
= &property
->package
.elements
[0];
447 propvalue
= &property
->package
.elements
[1];
449 if (!strcmp(name
, propname
->string
.pointer
)) {
450 if (type
!= ACPI_TYPE_ANY
&& propvalue
->type
!= type
)
462 * acpi_dev_get_property - return an ACPI property with given name.
463 * @adev: ACPI device to get the property from.
464 * @name: Name of the property.
465 * @type: Expected property type.
466 * @obj: Location to store the property value (if not %NULL).
468 int acpi_dev_get_property(const struct acpi_device
*adev
, const char *name
,
469 acpi_object_type type
, const union acpi_object
**obj
)
471 return adev
? acpi_data_get_property(&adev
->data
, name
, type
, obj
) : -EINVAL
;
473 EXPORT_SYMBOL_GPL(acpi_dev_get_property
);
475 static const struct acpi_device_data
*
476 acpi_device_data_of_node(const struct fwnode_handle
*fwnode
)
478 if (is_acpi_device_node(fwnode
)) {
479 const struct acpi_device
*adev
= to_acpi_device_node(fwnode
);
481 } else if (is_acpi_data_node(fwnode
)) {
482 const struct acpi_data_node
*dn
= to_acpi_data_node(fwnode
);
489 * acpi_node_prop_get - return an ACPI property with given name.
490 * @fwnode: Firmware node to get the property from.
491 * @propname: Name of the property.
492 * @valptr: Location to store a pointer to the property value (if not %NULL).
494 int acpi_node_prop_get(const struct fwnode_handle
*fwnode
,
495 const char *propname
, void **valptr
)
497 return acpi_data_get_property(acpi_device_data_of_node(fwnode
),
498 propname
, ACPI_TYPE_ANY
,
499 (const union acpi_object
**)valptr
);
503 * acpi_data_get_property_array - return an ACPI array property with given name
504 * @adev: ACPI data object to get the property from
505 * @name: Name of the property
506 * @type: Expected type of array elements
507 * @obj: Location to store a pointer to the property value (if not NULL)
509 * Look up an array property with @name and store a pointer to the resulting
510 * ACPI object at the location pointed to by @obj if found.
512 * Callers must not attempt to free the returned objects. Those objects will be
513 * freed by the ACPI core automatically during the removal of @data.
515 * Return: %0 if array property (package) with @name has been found (success),
516 * %-EINVAL if the arguments are invalid,
517 * %-EINVAL if the property doesn't exist,
518 * %-EPROTO if the property is not a package or the type of its elements
519 * doesn't match @type.
521 static int acpi_data_get_property_array(const struct acpi_device_data
*data
,
523 acpi_object_type type
,
524 const union acpi_object
**obj
)
526 const union acpi_object
*prop
;
529 ret
= acpi_data_get_property(data
, name
, ACPI_TYPE_PACKAGE
, &prop
);
533 if (type
!= ACPI_TYPE_ANY
) {
534 /* Check that all elements are of correct type. */
535 for (i
= 0; i
< prop
->package
.count
; i
++)
536 if (prop
->package
.elements
[i
].type
!= type
)
546 * __acpi_node_get_property_reference - returns handle to the referenced object
547 * @fwnode: Firmware node to get the property from
548 * @propname: Name of the property
549 * @index: Index of the reference to return
550 * @num_args: Maximum number of arguments after each reference
551 * @args: Location to store the returned reference with optional arguments
553 * Find property with @name, verifify that it is a package containing at least
554 * one object reference and if so, store the ACPI device object pointer to the
555 * target object in @args->adev. If the reference includes arguments, store
556 * them in the @args->args[] array.
558 * If there's more than one reference in the property value package, @index is
559 * used to select the one to return.
561 * It is possible to leave holes in the property value set like in the
574 * Calling this function with index %2 return %-ENOENT and with index %3
575 * returns the last entry. If the property does not contain any more values
576 * %-ENODATA is returned. The NULL entry must be single integer and
577 * preferably contain value %0.
579 * Return: %0 on success, negative error code on failure.
581 int __acpi_node_get_property_reference(const struct fwnode_handle
*fwnode
,
582 const char *propname
, size_t index
, size_t num_args
,
583 struct acpi_reference_args
*args
)
585 const union acpi_object
*element
, *end
;
586 const union acpi_object
*obj
;
587 const struct acpi_device_data
*data
;
588 struct acpi_device
*device
;
591 data
= acpi_device_data_of_node(fwnode
);
595 ret
= acpi_data_get_property(data
, propname
, ACPI_TYPE_ANY
, &obj
);
600 * The simplest case is when the value is a single reference. Just
601 * return that reference then.
603 if (obj
->type
== ACPI_TYPE_LOCAL_REFERENCE
) {
607 ret
= acpi_bus_get_device(obj
->reference
.handle
, &device
);
617 * If it is not a single reference, then it is a package of
618 * references followed by number of ints as follows:
620 * Package () { REF, INT, REF, INT, INT }
622 * The index argument is then used to determine which reference
623 * the caller wants (along with the arguments).
625 if (obj
->type
!= ACPI_TYPE_PACKAGE
|| index
>= obj
->package
.count
)
628 element
= obj
->package
.elements
;
629 end
= element
+ obj
->package
.count
;
631 while (element
< end
) {
634 if (element
->type
== ACPI_TYPE_LOCAL_REFERENCE
) {
635 ret
= acpi_bus_get_device(element
->reference
.handle
,
643 /* assume following integer elements are all args */
644 for (i
= 0; element
+ i
< end
&& i
< num_args
; i
++) {
645 int type
= element
[i
].type
;
647 if (type
== ACPI_TYPE_INTEGER
)
649 else if (type
== ACPI_TYPE_LOCAL_REFERENCE
)
655 if (nargs
> MAX_ACPI_REFERENCE_ARGS
)
661 for (i
= 0; i
< nargs
; i
++)
662 args
->args
[i
] = element
[i
].integer
.value
;
668 } else if (element
->type
== ACPI_TYPE_INTEGER
) {
681 EXPORT_SYMBOL_GPL(__acpi_node_get_property_reference
);
683 static int acpi_data_prop_read_single(const struct acpi_device_data
*data
,
684 const char *propname
,
685 enum dev_prop_type proptype
, void *val
)
687 const union acpi_object
*obj
;
693 if (proptype
>= DEV_PROP_U8
&& proptype
<= DEV_PROP_U64
) {
694 ret
= acpi_data_get_property(data
, propname
, ACPI_TYPE_INTEGER
, &obj
);
700 if (obj
->integer
.value
> U8_MAX
)
702 *(u8
*)val
= obj
->integer
.value
;
705 if (obj
->integer
.value
> U16_MAX
)
707 *(u16
*)val
= obj
->integer
.value
;
710 if (obj
->integer
.value
> U32_MAX
)
712 *(u32
*)val
= obj
->integer
.value
;
715 *(u64
*)val
= obj
->integer
.value
;
718 } else if (proptype
== DEV_PROP_STRING
) {
719 ret
= acpi_data_get_property(data
, propname
, ACPI_TYPE_STRING
, &obj
);
723 *(char **)val
= obj
->string
.pointer
;
732 int acpi_dev_prop_read_single(struct acpi_device
*adev
, const char *propname
,
733 enum dev_prop_type proptype
, void *val
)
740 ret
= acpi_data_prop_read_single(&adev
->data
, propname
, proptype
, val
);
741 if (ret
< 0 || proptype
!= ACPI_TYPE_STRING
)
746 static int acpi_copy_property_array_u8(const union acpi_object
*items
, u8
*val
,
751 for (i
= 0; i
< nval
; i
++) {
752 if (items
[i
].type
!= ACPI_TYPE_INTEGER
)
754 if (items
[i
].integer
.value
> U8_MAX
)
757 val
[i
] = items
[i
].integer
.value
;
762 static int acpi_copy_property_array_u16(const union acpi_object
*items
,
763 u16
*val
, size_t nval
)
767 for (i
= 0; i
< nval
; i
++) {
768 if (items
[i
].type
!= ACPI_TYPE_INTEGER
)
770 if (items
[i
].integer
.value
> U16_MAX
)
773 val
[i
] = items
[i
].integer
.value
;
778 static int acpi_copy_property_array_u32(const union acpi_object
*items
,
779 u32
*val
, size_t nval
)
783 for (i
= 0; i
< nval
; i
++) {
784 if (items
[i
].type
!= ACPI_TYPE_INTEGER
)
786 if (items
[i
].integer
.value
> U32_MAX
)
789 val
[i
] = items
[i
].integer
.value
;
794 static int acpi_copy_property_array_u64(const union acpi_object
*items
,
795 u64
*val
, size_t nval
)
799 for (i
= 0; i
< nval
; i
++) {
800 if (items
[i
].type
!= ACPI_TYPE_INTEGER
)
803 val
[i
] = items
[i
].integer
.value
;
808 static int acpi_copy_property_array_string(const union acpi_object
*items
,
809 char **val
, size_t nval
)
813 for (i
= 0; i
< nval
; i
++) {
814 if (items
[i
].type
!= ACPI_TYPE_STRING
)
817 val
[i
] = items
[i
].string
.pointer
;
822 static int acpi_data_prop_read(const struct acpi_device_data
*data
,
823 const char *propname
,
824 enum dev_prop_type proptype
,
825 void *val
, size_t nval
)
827 const union acpi_object
*obj
;
828 const union acpi_object
*items
;
831 if (val
&& nval
== 1) {
832 ret
= acpi_data_prop_read_single(data
, propname
, proptype
, val
);
837 ret
= acpi_data_get_property_array(data
, propname
, ACPI_TYPE_ANY
, &obj
);
842 return obj
->package
.count
;
844 if (proptype
!= DEV_PROP_STRING
&& nval
> obj
->package
.count
)
849 items
= obj
->package
.elements
;
853 ret
= acpi_copy_property_array_u8(items
, (u8
*)val
, nval
);
856 ret
= acpi_copy_property_array_u16(items
, (u16
*)val
, nval
);
859 ret
= acpi_copy_property_array_u32(items
, (u32
*)val
, nval
);
862 ret
= acpi_copy_property_array_u64(items
, (u64
*)val
, nval
);
864 case DEV_PROP_STRING
:
865 ret
= acpi_copy_property_array_string(
867 min_t(u32
, nval
, obj
->package
.count
));
876 int acpi_dev_prop_read(const struct acpi_device
*adev
, const char *propname
,
877 enum dev_prop_type proptype
, void *val
, size_t nval
)
879 return adev
? acpi_data_prop_read(&adev
->data
, propname
, proptype
, val
, nval
) : -EINVAL
;
883 * acpi_node_prop_read - retrieve the value of an ACPI property with given name.
884 * @fwnode: Firmware node to get the property from.
885 * @propname: Name of the property.
886 * @proptype: Expected property type.
887 * @val: Location to store the property value (if not %NULL).
888 * @nval: Size of the array pointed to by @val.
890 * If @val is %NULL, return the number of array elements comprising the value
891 * of the property. Otherwise, read at most @nval values to the array at the
892 * location pointed to by @val.
894 int acpi_node_prop_read(const struct fwnode_handle
*fwnode
,
895 const char *propname
, enum dev_prop_type proptype
,
896 void *val
, size_t nval
)
898 return acpi_data_prop_read(acpi_device_data_of_node(fwnode
),
899 propname
, proptype
, val
, nval
);
903 * acpi_get_next_subnode - Return the next child node handle for a fwnode
904 * @fwnode: Firmware node to find the next child node for.
905 * @child: Handle to one of the device's child nodes or a null handle.
907 struct fwnode_handle
*acpi_get_next_subnode(const struct fwnode_handle
*fwnode
,
908 struct fwnode_handle
*child
)
910 const struct acpi_device
*adev
= to_acpi_device_node(fwnode
);
911 struct acpi_device
*child_adev
= NULL
;
912 const struct list_head
*head
;
913 struct list_head
*next
;
915 if (!child
|| is_acpi_device_node(child
)) {
917 head
= &adev
->children
;
921 if (list_empty(head
))
925 child_adev
= to_acpi_device_node(child
);
926 next
= child_adev
->node
.next
;
931 child_adev
= list_entry(next
, struct acpi_device
, node
);
933 child_adev
= list_first_entry(head
, struct acpi_device
,
936 return acpi_fwnode_handle(child_adev
);
940 if (!child
|| is_acpi_data_node(child
)) {
941 const struct acpi_data_node
*data
= to_acpi_data_node(fwnode
);
942 struct acpi_data_node
*dn
;
945 head
= &child_adev
->data
.subnodes
;
947 head
= &data
->data
.subnodes
;
951 if (list_empty(head
))
955 dn
= to_acpi_data_node(child
);
956 next
= dn
->sibling
.next
;
960 dn
= list_entry(next
, struct acpi_data_node
, sibling
);
962 dn
= list_first_entry(head
, struct acpi_data_node
, sibling
);
970 * acpi_node_get_parent - Return parent fwnode of this fwnode
971 * @fwnode: Firmware node whose parent to get
973 * Returns parent node of an ACPI device or data firmware node or %NULL if
976 struct fwnode_handle
*acpi_node_get_parent(const struct fwnode_handle
*fwnode
)
978 if (is_acpi_data_node(fwnode
)) {
979 /* All data nodes have parent pointer so just return that */
980 return to_acpi_data_node(fwnode
)->parent
;
981 } else if (is_acpi_device_node(fwnode
)) {
982 acpi_handle handle
, parent_handle
;
984 handle
= to_acpi_device_node(fwnode
)->handle
;
985 if (ACPI_SUCCESS(acpi_get_parent(handle
, &parent_handle
))) {
986 struct acpi_device
*adev
;
988 if (!acpi_bus_get_device(parent_handle
, &adev
))
989 return acpi_fwnode_handle(adev
);
997 * acpi_graph_get_next_endpoint - Get next endpoint ACPI firmware node
998 * @fwnode: Pointer to the parent firmware node
999 * @prev: Previous endpoint node or %NULL to get the first
1001 * Looks up next endpoint ACPI firmware node below a given @fwnode. Returns
1002 * %NULL if there is no next endpoint, ERR_PTR() in case of error. In case
1003 * of success the next endpoint is returned.
1005 struct fwnode_handle
*acpi_graph_get_next_endpoint(
1006 const struct fwnode_handle
*fwnode
, struct fwnode_handle
*prev
)
1008 struct fwnode_handle
*port
= NULL
;
1009 struct fwnode_handle
*endpoint
;
1013 port
= fwnode_get_next_child_node(fwnode
, port
);
1014 /* Ports must have port property */
1015 if (fwnode_property_present(port
, "port"))
1019 port
= fwnode_get_parent(prev
);
1025 endpoint
= fwnode_get_next_child_node(port
, prev
);
1027 port
= fwnode_get_next_child_node(fwnode
, port
);
1030 if (fwnode_property_present(port
, "port"))
1031 endpoint
= fwnode_get_next_child_node(port
, NULL
);
1035 /* Endpoints must have "endpoint" property */
1036 if (!fwnode_property_present(endpoint
, "endpoint"))
1037 return ERR_PTR(-EPROTO
);
1044 * acpi_graph_get_child_prop_value - Return a child with a given property value
1045 * @fwnode: device fwnode
1046 * @prop_name: The name of the property to look for
1047 * @val: the desired property value
1049 * Return the port node corresponding to a given port number. Returns
1050 * the child node on success, NULL otherwise.
1052 static struct fwnode_handle
*acpi_graph_get_child_prop_value(
1053 const struct fwnode_handle
*fwnode
, const char *prop_name
,
1056 struct fwnode_handle
*child
;
1058 fwnode_for_each_child_node(fwnode
, child
) {
1061 if (fwnode_property_read_u32(child
, prop_name
, &nr
))
1073 * acpi_graph_get_remote_enpoint - Parses and returns remote end of an endpoint
1074 * @fwnode: Endpoint firmware node pointing to a remote device
1075 * @parent: Firmware node of remote port parent is filled here if not %NULL
1076 * @port: Firmware node of remote port is filled here if not %NULL
1077 * @endpoint: Firmware node of remote endpoint is filled here if not %NULL
1079 * Function parses remote end of ACPI firmware remote endpoint and fills in
1080 * fields requested by the caller. Returns %0 in case of success and
1081 * negative errno otherwise.
1083 int acpi_graph_get_remote_endpoint(const struct fwnode_handle
*__fwnode
,
1084 struct fwnode_handle
**parent
,
1085 struct fwnode_handle
**port
,
1086 struct fwnode_handle
**endpoint
)
1088 struct fwnode_handle
*fwnode
;
1089 unsigned int port_nr
, endpoint_nr
;
1090 struct acpi_reference_args args
;
1093 memset(&args
, 0, sizeof(args
));
1094 ret
= acpi_node_get_property_reference(__fwnode
, "remote-endpoint", 0,
1100 * Always require two arguments with the reference: port and
1103 if (args
.nargs
!= 2)
1106 fwnode
= acpi_fwnode_handle(args
.adev
);
1107 port_nr
= args
.args
[0];
1108 endpoint_nr
= args
.args
[1];
1113 if (!port
&& !endpoint
)
1116 fwnode
= acpi_graph_get_child_prop_value(fwnode
, "port", port_nr
);
1126 fwnode
= acpi_graph_get_child_prop_value(fwnode
, "endpoint",
1136 static bool acpi_fwnode_device_is_available(const struct fwnode_handle
*fwnode
)
1138 if (!is_acpi_device_node(fwnode
))
1141 return acpi_device_is_present(to_acpi_device_node(fwnode
));
1144 static bool acpi_fwnode_property_present(const struct fwnode_handle
*fwnode
,
1145 const char *propname
)
1147 return !acpi_node_prop_get(fwnode
, propname
, NULL
);
1151 acpi_fwnode_property_read_int_array(const struct fwnode_handle
*fwnode
,
1152 const char *propname
,
1153 unsigned int elem_size
, void *val
,
1156 enum dev_prop_type type
;
1158 switch (elem_size
) {
1163 type
= DEV_PROP_U16
;
1166 type
= DEV_PROP_U32
;
1169 type
= DEV_PROP_U64
;
1175 return acpi_node_prop_read(fwnode
, propname
, type
, val
, nval
);
1179 acpi_fwnode_property_read_string_array(const struct fwnode_handle
*fwnode
,
1180 const char *propname
, const char **val
,
1183 return acpi_node_prop_read(fwnode
, propname
, DEV_PROP_STRING
,
1187 static struct fwnode_handle
*
1188 acpi_fwnode_get_named_child_node(const struct fwnode_handle
*fwnode
,
1189 const char *childname
)
1191 struct fwnode_handle
*child
;
1194 * Find first matching named child node of this fwnode.
1195 * For ACPI this will be a data only sub-node.
1197 fwnode_for_each_child_node(fwnode
, child
)
1198 if (acpi_data_node_match(child
, childname
))
1205 acpi_fwnode_get_reference_args(const struct fwnode_handle
*fwnode
,
1206 const char *prop
, const char *nargs_prop
,
1207 unsigned int args_count
, unsigned int index
,
1208 struct fwnode_reference_args
*args
)
1210 struct acpi_reference_args acpi_args
;
1214 ret
= __acpi_node_get_property_reference(fwnode
, prop
, index
,
1215 args_count
, &acpi_args
);
1221 args
->nargs
= acpi_args
.nargs
;
1222 args
->fwnode
= acpi_fwnode_handle(acpi_args
.adev
);
1224 for (i
= 0; i
< NR_FWNODE_REFERENCE_ARGS
; i
++)
1225 args
->args
[i
] = i
< acpi_args
.nargs
? acpi_args
.args
[i
] : 0;
1230 static struct fwnode_handle
*
1231 acpi_fwnode_graph_get_next_endpoint(const struct fwnode_handle
*fwnode
,
1232 struct fwnode_handle
*prev
)
1234 struct fwnode_handle
*endpoint
;
1236 endpoint
= acpi_graph_get_next_endpoint(fwnode
, prev
);
1237 if (IS_ERR(endpoint
))
1243 static struct fwnode_handle
*
1244 acpi_fwnode_graph_get_remote_endpoint(const struct fwnode_handle
*fwnode
)
1246 struct fwnode_handle
*endpoint
= NULL
;
1248 acpi_graph_get_remote_endpoint(fwnode
, NULL
, NULL
, &endpoint
);
1253 static struct fwnode_handle
*
1254 acpi_fwnode_get_parent(struct fwnode_handle
*fwnode
)
1256 return acpi_node_get_parent(fwnode
);
1259 static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle
*fwnode
,
1260 struct fwnode_endpoint
*endpoint
)
1262 struct fwnode_handle
*port_fwnode
= fwnode_get_parent(fwnode
);
1264 endpoint
->local_fwnode
= fwnode
;
1266 fwnode_property_read_u32(port_fwnode
, "port", &endpoint
->port
);
1267 fwnode_property_read_u32(fwnode
, "endpoint", &endpoint
->id
);
1272 #define DECLARE_ACPI_FWNODE_OPS(ops) \
1273 const struct fwnode_operations ops = { \
1274 .device_is_available = acpi_fwnode_device_is_available, \
1275 .property_present = acpi_fwnode_property_present, \
1276 .property_read_int_array = \
1277 acpi_fwnode_property_read_int_array, \
1278 .property_read_string_array = \
1279 acpi_fwnode_property_read_string_array, \
1280 .get_parent = acpi_node_get_parent, \
1281 .get_next_child_node = acpi_get_next_subnode, \
1282 .get_named_child_node = acpi_fwnode_get_named_child_node, \
1283 .get_reference_args = acpi_fwnode_get_reference_args, \
1284 .graph_get_next_endpoint = \
1285 acpi_fwnode_graph_get_next_endpoint, \
1286 .graph_get_remote_endpoint = \
1287 acpi_fwnode_graph_get_remote_endpoint, \
1288 .graph_get_port_parent = acpi_fwnode_get_parent, \
1289 .graph_parse_endpoint = acpi_fwnode_graph_parse_endpoint, \
1291 EXPORT_SYMBOL_GPL(ops)
1293 DECLARE_ACPI_FWNODE_OPS(acpi_device_fwnode_ops
);
1294 DECLARE_ACPI_FWNODE_OPS(acpi_data_fwnode_ops
);
1295 const struct fwnode_operations acpi_static_fwnode_ops
;