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
);
28 * The GUIDs here are made equivalent to each other in order to avoid extra
29 * complexity in the properties handling code, with the caveat that the
30 * kernel will accept certain combinations of GUID and properties that are
31 * not defined without a warning. For instance if any of the properties
32 * from different GUID appear in a property list of another, it will be
33 * accepted by the kernel. Firmware validation tools should catch these.
35 static const guid_t prp_guids
[] = {
36 /* ACPI _DSD device properties GUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
37 GUID_INIT(0xdaffd814, 0x6eba, 0x4d8c,
38 0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01),
39 /* External facing port GUID: efcc06cc-73ac-4bc3-bff0-76143807c389 */
40 GUID_INIT(0xefcc06cc, 0x73ac, 0x4bc3,
41 0xbf, 0xf0, 0x76, 0x14, 0x38, 0x07, 0xc3, 0x89),
44 static const guid_t ads_guid
=
45 GUID_INIT(0xdbb8e3e6, 0x5886, 0x4ba6,
46 0x87, 0x95, 0x13, 0x19, 0xf5, 0x2a, 0x96, 0x6b);
48 static bool acpi_enumerate_nondev_subnodes(acpi_handle scope
,
49 const union acpi_object
*desc
,
50 struct acpi_device_data
*data
,
51 struct fwnode_handle
*parent
);
52 static bool acpi_extract_properties(const union acpi_object
*desc
,
53 struct acpi_device_data
*data
);
55 static bool acpi_nondev_subnode_extract(const union acpi_object
*desc
,
57 const union acpi_object
*link
,
58 struct list_head
*list
,
59 struct fwnode_handle
*parent
)
61 struct acpi_data_node
*dn
;
64 dn
= kzalloc(sizeof(*dn
), GFP_KERNEL
);
68 dn
->name
= link
->package
.elements
[0].string
.pointer
;
69 dn
->fwnode
.ops
= &acpi_data_fwnode_ops
;
71 INIT_LIST_HEAD(&dn
->data
.properties
);
72 INIT_LIST_HEAD(&dn
->data
.subnodes
);
74 result
= acpi_extract_properties(desc
, &dn
->data
);
81 * The scope for the subnode object lookup is the one of the
82 * namespace node (device) containing the object that has
83 * returned the package. That is, it's the scope of that
86 status
= acpi_get_parent(handle
, &scope
);
87 if (ACPI_SUCCESS(status
)
88 && acpi_enumerate_nondev_subnodes(scope
, desc
, &dn
->data
,
91 } else if (acpi_enumerate_nondev_subnodes(NULL
, desc
, &dn
->data
,
98 dn
->data
.pointer
= desc
;
99 list_add_tail(&dn
->sibling
, list
);
104 acpi_handle_debug(handle
, "Invalid properties/subnodes data, skipping\n");
108 static bool acpi_nondev_subnode_data_ok(acpi_handle handle
,
109 const union acpi_object
*link
,
110 struct list_head
*list
,
111 struct fwnode_handle
*parent
)
113 struct acpi_buffer buf
= { ACPI_ALLOCATE_BUFFER
};
116 status
= acpi_evaluate_object_typed(handle
, NULL
, NULL
, &buf
,
118 if (ACPI_FAILURE(status
))
121 if (acpi_nondev_subnode_extract(buf
.pointer
, handle
, link
, list
,
125 ACPI_FREE(buf
.pointer
);
129 static bool acpi_nondev_subnode_ok(acpi_handle scope
,
130 const union acpi_object
*link
,
131 struct list_head
*list
,
132 struct fwnode_handle
*parent
)
140 status
= acpi_get_handle(scope
, link
->package
.elements
[1].string
.pointer
,
142 if (ACPI_FAILURE(status
))
145 return acpi_nondev_subnode_data_ok(handle
, link
, list
, parent
);
148 static int acpi_add_nondev_subnodes(acpi_handle scope
,
149 const union acpi_object
*links
,
150 struct list_head
*list
,
151 struct fwnode_handle
*parent
)
156 for (i
= 0; i
< links
->package
.count
; i
++) {
157 const union acpi_object
*link
, *desc
;
161 link
= &links
->package
.elements
[i
];
162 /* Only two elements allowed. */
163 if (link
->package
.count
!= 2)
166 /* The first one must be a string. */
167 if (link
->package
.elements
[0].type
!= ACPI_TYPE_STRING
)
170 /* The second one may be a string, a reference or a package. */
171 switch (link
->package
.elements
[1].type
) {
172 case ACPI_TYPE_STRING
:
173 result
= acpi_nondev_subnode_ok(scope
, link
, list
,
176 case ACPI_TYPE_LOCAL_REFERENCE
:
177 handle
= link
->package
.elements
[1].reference
.handle
;
178 result
= acpi_nondev_subnode_data_ok(handle
, link
, list
,
181 case ACPI_TYPE_PACKAGE
:
182 desc
= &link
->package
.elements
[1];
183 result
= acpi_nondev_subnode_extract(desc
, NULL
, link
,
196 static bool acpi_enumerate_nondev_subnodes(acpi_handle scope
,
197 const union acpi_object
*desc
,
198 struct acpi_device_data
*data
,
199 struct fwnode_handle
*parent
)
203 /* Look for the ACPI data subnodes GUID. */
204 for (i
= 0; i
< desc
->package
.count
; i
+= 2) {
205 const union acpi_object
*guid
, *links
;
207 guid
= &desc
->package
.elements
[i
];
208 links
= &desc
->package
.elements
[i
+ 1];
211 * The first element must be a GUID and the second one must be
214 if (guid
->type
!= ACPI_TYPE_BUFFER
||
215 guid
->buffer
.length
!= 16 ||
216 links
->type
!= ACPI_TYPE_PACKAGE
)
219 if (!guid_equal((guid_t
*)guid
->buffer
.pointer
, &ads_guid
))
222 return acpi_add_nondev_subnodes(scope
, links
, &data
->subnodes
,
229 static bool acpi_property_value_ok(const union acpi_object
*value
)
234 * The value must be an integer, a string, a reference, or a package
235 * whose every element must be an integer, a string, or a reference.
237 switch (value
->type
) {
238 case ACPI_TYPE_INTEGER
:
239 case ACPI_TYPE_STRING
:
240 case ACPI_TYPE_LOCAL_REFERENCE
:
243 case ACPI_TYPE_PACKAGE
:
244 for (j
= 0; j
< value
->package
.count
; j
++)
245 switch (value
->package
.elements
[j
].type
) {
246 case ACPI_TYPE_INTEGER
:
247 case ACPI_TYPE_STRING
:
248 case ACPI_TYPE_LOCAL_REFERENCE
:
260 static bool acpi_properties_format_valid(const union acpi_object
*properties
)
264 for (i
= 0; i
< properties
->package
.count
; i
++) {
265 const union acpi_object
*property
;
267 property
= &properties
->package
.elements
[i
];
269 * Only two elements allowed, the first one must be a string and
270 * the second one has to satisfy certain conditions.
272 if (property
->package
.count
!= 2
273 || property
->package
.elements
[0].type
!= ACPI_TYPE_STRING
274 || !acpi_property_value_ok(&property
->package
.elements
[1]))
280 static void acpi_init_of_compatible(struct acpi_device
*adev
)
282 const union acpi_object
*of_compatible
;
285 ret
= acpi_data_get_property_array(&adev
->data
, "compatible",
286 ACPI_TYPE_STRING
, &of_compatible
);
288 ret
= acpi_dev_get_property(adev
, "compatible",
289 ACPI_TYPE_STRING
, &of_compatible
);
292 && adev
->parent
->flags
.of_compatible_ok
)
298 adev
->data
.of_compatible
= of_compatible
;
301 adev
->flags
.of_compatible_ok
= 1;
304 static bool acpi_is_property_guid(const guid_t
*guid
)
308 for (i
= 0; i
< ARRAY_SIZE(prp_guids
); i
++) {
309 if (guid_equal(guid
, &prp_guids
[i
]))
316 struct acpi_device_properties
*
317 acpi_data_add_props(struct acpi_device_data
*data
, const guid_t
*guid
,
318 const union acpi_object
*properties
)
320 struct acpi_device_properties
*props
;
322 props
= kzalloc(sizeof(*props
), GFP_KERNEL
);
324 INIT_LIST_HEAD(&props
->list
);
326 props
->properties
= properties
;
327 list_add_tail(&props
->list
, &data
->properties
);
333 static bool acpi_extract_properties(const union acpi_object
*desc
,
334 struct acpi_device_data
*data
)
338 if (desc
->package
.count
% 2)
341 /* Look for the device properties GUID. */
342 for (i
= 0; i
< desc
->package
.count
; i
+= 2) {
343 const union acpi_object
*guid
, *properties
;
345 guid
= &desc
->package
.elements
[i
];
346 properties
= &desc
->package
.elements
[i
+ 1];
349 * The first element must be a GUID and the second one must be
352 if (guid
->type
!= ACPI_TYPE_BUFFER
||
353 guid
->buffer
.length
!= 16 ||
354 properties
->type
!= ACPI_TYPE_PACKAGE
)
357 if (!acpi_is_property_guid((guid_t
*)guid
->buffer
.pointer
))
361 * We found the matching GUID. Now validate the format of the
362 * package immediately following it.
364 if (!acpi_properties_format_valid(properties
))
367 acpi_data_add_props(data
, (const guid_t
*)guid
->buffer
.pointer
,
371 return !list_empty(&data
->properties
);
374 void acpi_init_properties(struct acpi_device
*adev
)
376 struct acpi_buffer buf
= { ACPI_ALLOCATE_BUFFER
};
377 struct acpi_hardware_id
*hwid
;
379 bool acpi_of
= false;
381 INIT_LIST_HEAD(&adev
->data
.properties
);
382 INIT_LIST_HEAD(&adev
->data
.subnodes
);
388 * Check if ACPI_DT_NAMESPACE_HID is present and inthat case we fill in
389 * Device Tree compatible properties for this device.
391 list_for_each_entry(hwid
, &adev
->pnp
.ids
, list
) {
392 if (!strcmp(hwid
->id
, ACPI_DT_NAMESPACE_HID
)) {
398 status
= acpi_evaluate_object_typed(adev
->handle
, "_DSD", NULL
, &buf
,
400 if (ACPI_FAILURE(status
))
403 if (acpi_extract_properties(buf
.pointer
, &adev
->data
)) {
404 adev
->data
.pointer
= buf
.pointer
;
406 acpi_init_of_compatible(adev
);
408 if (acpi_enumerate_nondev_subnodes(adev
->handle
, buf
.pointer
,
409 &adev
->data
, acpi_fwnode_handle(adev
)))
410 adev
->data
.pointer
= buf
.pointer
;
412 if (!adev
->data
.pointer
) {
413 acpi_handle_debug(adev
->handle
, "Invalid _DSD data, skipping\n");
414 ACPI_FREE(buf
.pointer
);
418 if (acpi_of
&& !adev
->flags
.of_compatible_ok
)
419 acpi_handle_info(adev
->handle
,
420 ACPI_DT_NAMESPACE_HID
" requires 'compatible' property\n");
422 if (!adev
->data
.pointer
)
423 acpi_extract_apple_properties(adev
);
426 static void acpi_destroy_nondev_subnodes(struct list_head
*list
)
428 struct acpi_data_node
*dn
, *next
;
430 if (list_empty(list
))
433 list_for_each_entry_safe_reverse(dn
, next
, list
, sibling
) {
434 acpi_destroy_nondev_subnodes(&dn
->data
.subnodes
);
435 wait_for_completion(&dn
->kobj_done
);
436 list_del(&dn
->sibling
);
437 ACPI_FREE((void *)dn
->data
.pointer
);
442 void acpi_free_properties(struct acpi_device
*adev
)
444 struct acpi_device_properties
*props
, *tmp
;
446 acpi_destroy_nondev_subnodes(&adev
->data
.subnodes
);
447 ACPI_FREE((void *)adev
->data
.pointer
);
448 adev
->data
.of_compatible
= NULL
;
449 adev
->data
.pointer
= NULL
;
450 list_for_each_entry_safe(props
, tmp
, &adev
->data
.properties
, list
) {
451 list_del(&props
->list
);
457 * acpi_data_get_property - return an ACPI property with given name
458 * @data: ACPI device deta object to get the property from
459 * @name: Name of the property
460 * @type: Expected property type
461 * @obj: Location to store the property value (if not %NULL)
463 * Look up a property with @name and store a pointer to the resulting ACPI
464 * object at the location pointed to by @obj if found.
466 * Callers must not attempt to free the returned objects. These objects will be
467 * freed by the ACPI core automatically during the removal of @data.
469 * Return: %0 if property with @name has been found (success),
470 * %-EINVAL if the arguments are invalid,
471 * %-EINVAL if the property doesn't exist,
472 * %-EPROTO if the property value type doesn't match @type.
474 static int acpi_data_get_property(const struct acpi_device_data
*data
,
475 const char *name
, acpi_object_type type
,
476 const union acpi_object
**obj
)
478 const struct acpi_device_properties
*props
;
483 if (!data
->pointer
|| list_empty(&data
->properties
))
486 list_for_each_entry(props
, &data
->properties
, list
) {
487 const union acpi_object
*properties
;
490 properties
= props
->properties
;
491 for (i
= 0; i
< properties
->package
.count
; i
++) {
492 const union acpi_object
*propname
, *propvalue
;
493 const union acpi_object
*property
;
495 property
= &properties
->package
.elements
[i
];
497 propname
= &property
->package
.elements
[0];
498 propvalue
= &property
->package
.elements
[1];
500 if (!strcmp(name
, propname
->string
.pointer
)) {
501 if (type
!= ACPI_TYPE_ANY
&&
502 propvalue
->type
!= type
)
515 * acpi_dev_get_property - return an ACPI property with given name.
516 * @adev: ACPI device to get the property from.
517 * @name: Name of the property.
518 * @type: Expected property type.
519 * @obj: Location to store the property value (if not %NULL).
521 int acpi_dev_get_property(const struct acpi_device
*adev
, const char *name
,
522 acpi_object_type type
, const union acpi_object
**obj
)
524 return adev
? acpi_data_get_property(&adev
->data
, name
, type
, obj
) : -EINVAL
;
526 EXPORT_SYMBOL_GPL(acpi_dev_get_property
);
528 static const struct acpi_device_data
*
529 acpi_device_data_of_node(const struct fwnode_handle
*fwnode
)
531 if (is_acpi_device_node(fwnode
)) {
532 const struct acpi_device
*adev
= to_acpi_device_node(fwnode
);
534 } else if (is_acpi_data_node(fwnode
)) {
535 const struct acpi_data_node
*dn
= to_acpi_data_node(fwnode
);
542 * acpi_node_prop_get - return an ACPI property with given name.
543 * @fwnode: Firmware node to get the property from.
544 * @propname: Name of the property.
545 * @valptr: Location to store a pointer to the property value (if not %NULL).
547 int acpi_node_prop_get(const struct fwnode_handle
*fwnode
,
548 const char *propname
, void **valptr
)
550 return acpi_data_get_property(acpi_device_data_of_node(fwnode
),
551 propname
, ACPI_TYPE_ANY
,
552 (const union acpi_object
**)valptr
);
556 * acpi_data_get_property_array - return an ACPI array property with given name
557 * @adev: ACPI data object to get the property from
558 * @name: Name of the property
559 * @type: Expected type of array elements
560 * @obj: Location to store a pointer to the property value (if not NULL)
562 * Look up an array property with @name and store a pointer to the resulting
563 * ACPI object at the location pointed to by @obj if found.
565 * Callers must not attempt to free the returned objects. Those objects will be
566 * freed by the ACPI core automatically during the removal of @data.
568 * Return: %0 if array property (package) with @name has been found (success),
569 * %-EINVAL if the arguments are invalid,
570 * %-EINVAL if the property doesn't exist,
571 * %-EPROTO if the property is not a package or the type of its elements
572 * doesn't match @type.
574 static int acpi_data_get_property_array(const struct acpi_device_data
*data
,
576 acpi_object_type type
,
577 const union acpi_object
**obj
)
579 const union acpi_object
*prop
;
582 ret
= acpi_data_get_property(data
, name
, ACPI_TYPE_PACKAGE
, &prop
);
586 if (type
!= ACPI_TYPE_ANY
) {
587 /* Check that all elements are of correct type. */
588 for (i
= 0; i
< prop
->package
.count
; i
++)
589 if (prop
->package
.elements
[i
].type
!= type
)
599 * __acpi_node_get_property_reference - returns handle to the referenced object
600 * @fwnode: Firmware node to get the property from
601 * @propname: Name of the property
602 * @index: Index of the reference to return
603 * @num_args: Maximum number of arguments after each reference
604 * @args: Location to store the returned reference with optional arguments
606 * Find property with @name, verifify that it is a package containing at least
607 * one object reference and if so, store the ACPI device object pointer to the
608 * target object in @args->adev. If the reference includes arguments, store
609 * them in the @args->args[] array.
611 * If there's more than one reference in the property value package, @index is
612 * used to select the one to return.
614 * It is possible to leave holes in the property value set like in the
627 * Calling this function with index %2 or index %3 return %-ENOENT. If the
628 * property does not contain any more values %-ENOENT is returned. The NULL
629 * entry must be single integer and preferably contain value %0.
631 * Return: %0 on success, negative error code on failure.
633 int __acpi_node_get_property_reference(const struct fwnode_handle
*fwnode
,
634 const char *propname
, size_t index
, size_t num_args
,
635 struct acpi_reference_args
*args
)
637 const union acpi_object
*element
, *end
;
638 const union acpi_object
*obj
;
639 const struct acpi_device_data
*data
;
640 struct acpi_device
*device
;
643 data
= acpi_device_data_of_node(fwnode
);
647 ret
= acpi_data_get_property(data
, propname
, ACPI_TYPE_ANY
, &obj
);
649 return ret
== -EINVAL
? -ENOENT
: -EINVAL
;
652 * The simplest case is when the value is a single reference. Just
653 * return that reference then.
655 if (obj
->type
== ACPI_TYPE_LOCAL_REFERENCE
) {
659 ret
= acpi_bus_get_device(obj
->reference
.handle
, &device
);
661 return ret
== -ENODEV
? -EINVAL
: ret
;
669 * If it is not a single reference, then it is a package of
670 * references followed by number of ints as follows:
672 * Package () { REF, INT, REF, INT, INT }
674 * The index argument is then used to determine which reference
675 * the caller wants (along with the arguments).
677 if (obj
->type
!= ACPI_TYPE_PACKAGE
)
679 if (index
>= obj
->package
.count
)
682 element
= obj
->package
.elements
;
683 end
= element
+ obj
->package
.count
;
685 while (element
< end
) {
688 if (element
->type
== ACPI_TYPE_LOCAL_REFERENCE
) {
689 ret
= acpi_bus_get_device(element
->reference
.handle
,
697 /* assume following integer elements are all args */
698 for (i
= 0; element
+ i
< end
&& i
< num_args
; i
++) {
699 int type
= element
[i
].type
;
701 if (type
== ACPI_TYPE_INTEGER
)
703 else if (type
== ACPI_TYPE_LOCAL_REFERENCE
)
709 if (nargs
> MAX_ACPI_REFERENCE_ARGS
)
715 for (i
= 0; i
< nargs
; i
++)
716 args
->args
[i
] = element
[i
].integer
.value
;
722 } else if (element
->type
== ACPI_TYPE_INTEGER
) {
735 EXPORT_SYMBOL_GPL(__acpi_node_get_property_reference
);
737 static int acpi_data_prop_read_single(const struct acpi_device_data
*data
,
738 const char *propname
,
739 enum dev_prop_type proptype
, void *val
)
741 const union acpi_object
*obj
;
747 if (proptype
>= DEV_PROP_U8
&& proptype
<= DEV_PROP_U64
) {
748 ret
= acpi_data_get_property(data
, propname
, ACPI_TYPE_INTEGER
, &obj
);
754 if (obj
->integer
.value
> U8_MAX
)
756 *(u8
*)val
= obj
->integer
.value
;
759 if (obj
->integer
.value
> U16_MAX
)
761 *(u16
*)val
= obj
->integer
.value
;
764 if (obj
->integer
.value
> U32_MAX
)
766 *(u32
*)val
= obj
->integer
.value
;
769 *(u64
*)val
= obj
->integer
.value
;
772 } else if (proptype
== DEV_PROP_STRING
) {
773 ret
= acpi_data_get_property(data
, propname
, ACPI_TYPE_STRING
, &obj
);
777 *(char **)val
= obj
->string
.pointer
;
786 int acpi_dev_prop_read_single(struct acpi_device
*adev
, const char *propname
,
787 enum dev_prop_type proptype
, void *val
)
794 ret
= acpi_data_prop_read_single(&adev
->data
, propname
, proptype
, val
);
795 if (ret
< 0 || proptype
!= ACPI_TYPE_STRING
)
800 static int acpi_copy_property_array_u8(const union acpi_object
*items
, u8
*val
,
805 for (i
= 0; i
< nval
; i
++) {
806 if (items
[i
].type
!= ACPI_TYPE_INTEGER
)
808 if (items
[i
].integer
.value
> U8_MAX
)
811 val
[i
] = items
[i
].integer
.value
;
816 static int acpi_copy_property_array_u16(const union acpi_object
*items
,
817 u16
*val
, size_t nval
)
821 for (i
= 0; i
< nval
; i
++) {
822 if (items
[i
].type
!= ACPI_TYPE_INTEGER
)
824 if (items
[i
].integer
.value
> U16_MAX
)
827 val
[i
] = items
[i
].integer
.value
;
832 static int acpi_copy_property_array_u32(const union acpi_object
*items
,
833 u32
*val
, size_t nval
)
837 for (i
= 0; i
< nval
; i
++) {
838 if (items
[i
].type
!= ACPI_TYPE_INTEGER
)
840 if (items
[i
].integer
.value
> U32_MAX
)
843 val
[i
] = items
[i
].integer
.value
;
848 static int acpi_copy_property_array_u64(const union acpi_object
*items
,
849 u64
*val
, size_t nval
)
853 for (i
= 0; i
< nval
; i
++) {
854 if (items
[i
].type
!= ACPI_TYPE_INTEGER
)
857 val
[i
] = items
[i
].integer
.value
;
862 static int acpi_copy_property_array_string(const union acpi_object
*items
,
863 char **val
, size_t nval
)
867 for (i
= 0; i
< nval
; i
++) {
868 if (items
[i
].type
!= ACPI_TYPE_STRING
)
871 val
[i
] = items
[i
].string
.pointer
;
876 static int acpi_data_prop_read(const struct acpi_device_data
*data
,
877 const char *propname
,
878 enum dev_prop_type proptype
,
879 void *val
, size_t nval
)
881 const union acpi_object
*obj
;
882 const union acpi_object
*items
;
885 if (val
&& nval
== 1) {
886 ret
= acpi_data_prop_read_single(data
, propname
, proptype
, val
);
891 ret
= acpi_data_get_property_array(data
, propname
, ACPI_TYPE_ANY
, &obj
);
896 return obj
->package
.count
;
898 if (proptype
!= DEV_PROP_STRING
&& nval
> obj
->package
.count
)
903 items
= obj
->package
.elements
;
907 ret
= acpi_copy_property_array_u8(items
, (u8
*)val
, nval
);
910 ret
= acpi_copy_property_array_u16(items
, (u16
*)val
, nval
);
913 ret
= acpi_copy_property_array_u32(items
, (u32
*)val
, nval
);
916 ret
= acpi_copy_property_array_u64(items
, (u64
*)val
, nval
);
918 case DEV_PROP_STRING
:
919 ret
= acpi_copy_property_array_string(
921 min_t(u32
, nval
, obj
->package
.count
));
930 int acpi_dev_prop_read(const struct acpi_device
*adev
, const char *propname
,
931 enum dev_prop_type proptype
, void *val
, size_t nval
)
933 return adev
? acpi_data_prop_read(&adev
->data
, propname
, proptype
, val
, nval
) : -EINVAL
;
937 * acpi_node_prop_read - retrieve the value of an ACPI property with given name.
938 * @fwnode: Firmware node to get the property from.
939 * @propname: Name of the property.
940 * @proptype: Expected property type.
941 * @val: Location to store the property value (if not %NULL).
942 * @nval: Size of the array pointed to by @val.
944 * If @val is %NULL, return the number of array elements comprising the value
945 * of the property. Otherwise, read at most @nval values to the array at the
946 * location pointed to by @val.
948 int acpi_node_prop_read(const struct fwnode_handle
*fwnode
,
949 const char *propname
, enum dev_prop_type proptype
,
950 void *val
, size_t nval
)
952 return acpi_data_prop_read(acpi_device_data_of_node(fwnode
),
953 propname
, proptype
, val
, nval
);
957 * acpi_get_next_subnode - Return the next child node handle for a fwnode
958 * @fwnode: Firmware node to find the next child node for.
959 * @child: Handle to one of the device's child nodes or a null handle.
961 struct fwnode_handle
*acpi_get_next_subnode(const struct fwnode_handle
*fwnode
,
962 struct fwnode_handle
*child
)
964 const struct acpi_device
*adev
= to_acpi_device_node(fwnode
);
965 const struct list_head
*head
;
966 struct list_head
*next
;
968 if (!child
|| is_acpi_device_node(child
)) {
969 struct acpi_device
*child_adev
;
972 head
= &adev
->children
;
976 if (list_empty(head
))
980 adev
= to_acpi_device_node(child
);
981 next
= adev
->node
.next
;
986 child_adev
= list_entry(next
, struct acpi_device
, node
);
988 child_adev
= list_first_entry(head
, struct acpi_device
,
991 return acpi_fwnode_handle(child_adev
);
995 if (!child
|| is_acpi_data_node(child
)) {
996 const struct acpi_data_node
*data
= to_acpi_data_node(fwnode
);
997 struct acpi_data_node
*dn
;
1000 head
= &adev
->data
.subnodes
;
1002 head
= &data
->data
.subnodes
;
1006 if (list_empty(head
))
1010 dn
= to_acpi_data_node(child
);
1011 next
= dn
->sibling
.next
;
1015 dn
= list_entry(next
, struct acpi_data_node
, sibling
);
1017 dn
= list_first_entry(head
, struct acpi_data_node
, sibling
);
1025 * acpi_node_get_parent - Return parent fwnode of this fwnode
1026 * @fwnode: Firmware node whose parent to get
1028 * Returns parent node of an ACPI device or data firmware node or %NULL if
1031 struct fwnode_handle
*acpi_node_get_parent(const struct fwnode_handle
*fwnode
)
1033 if (is_acpi_data_node(fwnode
)) {
1034 /* All data nodes have parent pointer so just return that */
1035 return to_acpi_data_node(fwnode
)->parent
;
1036 } else if (is_acpi_device_node(fwnode
)) {
1037 acpi_handle handle
, parent_handle
;
1039 handle
= to_acpi_device_node(fwnode
)->handle
;
1040 if (ACPI_SUCCESS(acpi_get_parent(handle
, &parent_handle
))) {
1041 struct acpi_device
*adev
;
1043 if (!acpi_bus_get_device(parent_handle
, &adev
))
1044 return acpi_fwnode_handle(adev
);
1052 * acpi_graph_get_next_endpoint - Get next endpoint ACPI firmware node
1053 * @fwnode: Pointer to the parent firmware node
1054 * @prev: Previous endpoint node or %NULL to get the first
1056 * Looks up next endpoint ACPI firmware node below a given @fwnode. Returns
1057 * %NULL if there is no next endpoint, ERR_PTR() in case of error. In case
1058 * of success the next endpoint is returned.
1060 struct fwnode_handle
*acpi_graph_get_next_endpoint(
1061 const struct fwnode_handle
*fwnode
, struct fwnode_handle
*prev
)
1063 struct fwnode_handle
*port
= NULL
;
1064 struct fwnode_handle
*endpoint
;
1068 port
= fwnode_get_next_child_node(fwnode
, port
);
1069 /* Ports must have port property */
1070 if (fwnode_property_present(port
, "port"))
1074 port
= fwnode_get_parent(prev
);
1080 endpoint
= fwnode_get_next_child_node(port
, prev
);
1082 port
= fwnode_get_next_child_node(fwnode
, port
);
1085 if (fwnode_property_present(port
, "port"))
1086 endpoint
= fwnode_get_next_child_node(port
, NULL
);
1090 /* Endpoints must have "endpoint" property */
1091 if (!fwnode_property_present(endpoint
, "endpoint"))
1092 return ERR_PTR(-EPROTO
);
1099 * acpi_graph_get_child_prop_value - Return a child with a given property value
1100 * @fwnode: device fwnode
1101 * @prop_name: The name of the property to look for
1102 * @val: the desired property value
1104 * Return the port node corresponding to a given port number. Returns
1105 * the child node on success, NULL otherwise.
1107 static struct fwnode_handle
*acpi_graph_get_child_prop_value(
1108 const struct fwnode_handle
*fwnode
, const char *prop_name
,
1111 struct fwnode_handle
*child
;
1113 fwnode_for_each_child_node(fwnode
, child
) {
1116 if (fwnode_property_read_u32(child
, prop_name
, &nr
))
1128 * acpi_graph_get_remote_enpoint - Parses and returns remote end of an endpoint
1129 * @fwnode: Endpoint firmware node pointing to a remote device
1130 * @parent: Firmware node of remote port parent is filled here if not %NULL
1131 * @port: Firmware node of remote port is filled here if not %NULL
1132 * @endpoint: Firmware node of remote endpoint is filled here if not %NULL
1134 * Function parses remote end of ACPI firmware remote endpoint and fills in
1135 * fields requested by the caller. Returns %0 in case of success and
1136 * negative errno otherwise.
1138 int acpi_graph_get_remote_endpoint(const struct fwnode_handle
*__fwnode
,
1139 struct fwnode_handle
**parent
,
1140 struct fwnode_handle
**port
,
1141 struct fwnode_handle
**endpoint
)
1143 struct fwnode_handle
*fwnode
;
1144 unsigned int port_nr
, endpoint_nr
;
1145 struct acpi_reference_args args
;
1148 memset(&args
, 0, sizeof(args
));
1149 ret
= acpi_node_get_property_reference(__fwnode
, "remote-endpoint", 0,
1155 * Always require two arguments with the reference: port and
1158 if (args
.nargs
!= 2)
1161 fwnode
= acpi_fwnode_handle(args
.adev
);
1162 port_nr
= args
.args
[0];
1163 endpoint_nr
= args
.args
[1];
1168 if (!port
&& !endpoint
)
1171 fwnode
= acpi_graph_get_child_prop_value(fwnode
, "port", port_nr
);
1181 fwnode
= acpi_graph_get_child_prop_value(fwnode
, "endpoint",
1191 static bool acpi_fwnode_device_is_available(const struct fwnode_handle
*fwnode
)
1193 if (!is_acpi_device_node(fwnode
))
1196 return acpi_device_is_present(to_acpi_device_node(fwnode
));
1199 static bool acpi_fwnode_property_present(const struct fwnode_handle
*fwnode
,
1200 const char *propname
)
1202 return !acpi_node_prop_get(fwnode
, propname
, NULL
);
1206 acpi_fwnode_property_read_int_array(const struct fwnode_handle
*fwnode
,
1207 const char *propname
,
1208 unsigned int elem_size
, void *val
,
1211 enum dev_prop_type type
;
1213 switch (elem_size
) {
1218 type
= DEV_PROP_U16
;
1221 type
= DEV_PROP_U32
;
1224 type
= DEV_PROP_U64
;
1230 return acpi_node_prop_read(fwnode
, propname
, type
, val
, nval
);
1234 acpi_fwnode_property_read_string_array(const struct fwnode_handle
*fwnode
,
1235 const char *propname
, const char **val
,
1238 return acpi_node_prop_read(fwnode
, propname
, DEV_PROP_STRING
,
1242 static struct fwnode_handle
*
1243 acpi_fwnode_get_named_child_node(const struct fwnode_handle
*fwnode
,
1244 const char *childname
)
1246 struct fwnode_handle
*child
;
1249 * Find first matching named child node of this fwnode.
1250 * For ACPI this will be a data only sub-node.
1252 fwnode_for_each_child_node(fwnode
, child
)
1253 if (acpi_data_node_match(child
, childname
))
1260 acpi_fwnode_get_reference_args(const struct fwnode_handle
*fwnode
,
1261 const char *prop
, const char *nargs_prop
,
1262 unsigned int args_count
, unsigned int index
,
1263 struct fwnode_reference_args
*args
)
1265 struct acpi_reference_args acpi_args
;
1269 ret
= __acpi_node_get_property_reference(fwnode
, prop
, index
,
1270 args_count
, &acpi_args
);
1276 args
->nargs
= acpi_args
.nargs
;
1277 args
->fwnode
= acpi_fwnode_handle(acpi_args
.adev
);
1279 for (i
= 0; i
< NR_FWNODE_REFERENCE_ARGS
; i
++)
1280 args
->args
[i
] = i
< acpi_args
.nargs
? acpi_args
.args
[i
] : 0;
1285 static struct fwnode_handle
*
1286 acpi_fwnode_graph_get_next_endpoint(const struct fwnode_handle
*fwnode
,
1287 struct fwnode_handle
*prev
)
1289 struct fwnode_handle
*endpoint
;
1291 endpoint
= acpi_graph_get_next_endpoint(fwnode
, prev
);
1292 if (IS_ERR(endpoint
))
1298 static struct fwnode_handle
*
1299 acpi_fwnode_graph_get_remote_endpoint(const struct fwnode_handle
*fwnode
)
1301 struct fwnode_handle
*endpoint
= NULL
;
1303 acpi_graph_get_remote_endpoint(fwnode
, NULL
, NULL
, &endpoint
);
1308 static struct fwnode_handle
*
1309 acpi_fwnode_get_parent(struct fwnode_handle
*fwnode
)
1311 return acpi_node_get_parent(fwnode
);
1314 static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle
*fwnode
,
1315 struct fwnode_endpoint
*endpoint
)
1317 struct fwnode_handle
*port_fwnode
= fwnode_get_parent(fwnode
);
1319 endpoint
->local_fwnode
= fwnode
;
1321 fwnode_property_read_u32(port_fwnode
, "port", &endpoint
->port
);
1322 fwnode_property_read_u32(fwnode
, "endpoint", &endpoint
->id
);
1327 #define DECLARE_ACPI_FWNODE_OPS(ops) \
1328 const struct fwnode_operations ops = { \
1329 .device_is_available = acpi_fwnode_device_is_available, \
1330 .property_present = acpi_fwnode_property_present, \
1331 .property_read_int_array = \
1332 acpi_fwnode_property_read_int_array, \
1333 .property_read_string_array = \
1334 acpi_fwnode_property_read_string_array, \
1335 .get_parent = acpi_node_get_parent, \
1336 .get_next_child_node = acpi_get_next_subnode, \
1337 .get_named_child_node = acpi_fwnode_get_named_child_node, \
1338 .get_reference_args = acpi_fwnode_get_reference_args, \
1339 .graph_get_next_endpoint = \
1340 acpi_fwnode_graph_get_next_endpoint, \
1341 .graph_get_remote_endpoint = \
1342 acpi_fwnode_graph_get_remote_endpoint, \
1343 .graph_get_port_parent = acpi_fwnode_get_parent, \
1344 .graph_parse_endpoint = acpi_fwnode_graph_parse_endpoint, \
1346 EXPORT_SYMBOL_GPL(ops)
1348 DECLARE_ACPI_FWNODE_OPS(acpi_device_fwnode_ops
);
1349 DECLARE_ACPI_FWNODE_OPS(acpi_data_fwnode_ops
);
1350 const struct fwnode_operations acpi_static_fwnode_ops
;
1352 bool is_acpi_device_node(const struct fwnode_handle
*fwnode
)
1354 return !IS_ERR_OR_NULL(fwnode
) &&
1355 fwnode
->ops
== &acpi_device_fwnode_ops
;
1357 EXPORT_SYMBOL(is_acpi_device_node
);
1359 bool is_acpi_data_node(const struct fwnode_handle
*fwnode
)
1361 return !IS_ERR_OR_NULL(fwnode
) && fwnode
->ops
== &acpi_data_fwnode_ops
;
1363 EXPORT_SYMBOL(is_acpi_data_node
);