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
)
545 static struct fwnode_handle
*
546 acpi_fwnode_get_named_child_node(const struct fwnode_handle
*fwnode
,
547 const char *childname
)
549 struct fwnode_handle
*child
;
552 * Find first matching named child node of this fwnode.
553 * For ACPI this will be a data only sub-node.
555 fwnode_for_each_child_node(fwnode
, child
)
556 if (acpi_data_node_match(child
, childname
))
563 * __acpi_node_get_property_reference - returns handle to the referenced object
564 * @fwnode: Firmware node to get the property from
565 * @propname: Name of the property
566 * @index: Index of the reference to return
567 * @num_args: Maximum number of arguments after each reference
568 * @args: Location to store the returned reference with optional arguments
570 * Find property with @name, verifify that it is a package containing at least
571 * one object reference and if so, store the ACPI device object pointer to the
572 * target object in @args->adev. If the reference includes arguments, store
573 * them in the @args->args[] array.
575 * If there's more than one reference in the property value package, @index is
576 * used to select the one to return.
578 * It is possible to leave holes in the property value set like in the
591 * Calling this function with index %2 or index %3 return %-ENOENT. If the
592 * property does not contain any more values %-ENOENT is returned. The NULL
593 * entry must be single integer and preferably contain value %0.
595 * Return: %0 on success, negative error code on failure.
597 int __acpi_node_get_property_reference(const struct fwnode_handle
*fwnode
,
598 const char *propname
, size_t index
, size_t num_args
,
599 struct fwnode_reference_args
*args
)
601 const union acpi_object
*element
, *end
;
602 const union acpi_object
*obj
;
603 const struct acpi_device_data
*data
;
604 struct acpi_device
*device
;
607 data
= acpi_device_data_of_node(fwnode
);
611 ret
= acpi_data_get_property(data
, propname
, ACPI_TYPE_ANY
, &obj
);
613 return ret
== -EINVAL
? -ENOENT
: -EINVAL
;
616 * The simplest case is when the value is a single reference. Just
617 * return that reference then.
619 if (obj
->type
== ACPI_TYPE_LOCAL_REFERENCE
) {
623 ret
= acpi_bus_get_device(obj
->reference
.handle
, &device
);
625 return ret
== -ENODEV
? -EINVAL
: ret
;
627 args
->fwnode
= acpi_fwnode_handle(device
);
633 * If it is not a single reference, then it is a package of
634 * references followed by number of ints as follows:
636 * Package () { REF, INT, REF, INT, INT }
638 * The index argument is then used to determine which reference
639 * the caller wants (along with the arguments).
641 if (obj
->type
!= ACPI_TYPE_PACKAGE
)
643 if (index
>= obj
->package
.count
)
646 element
= obj
->package
.elements
;
647 end
= element
+ obj
->package
.count
;
649 while (element
< end
) {
652 if (element
->type
== ACPI_TYPE_LOCAL_REFERENCE
) {
653 struct fwnode_handle
*ref_fwnode
;
655 ret
= acpi_bus_get_device(element
->reference
.handle
,
664 * Find the referred data extension node under the
665 * referred device node.
667 for (ref_fwnode
= acpi_fwnode_handle(device
);
668 element
< end
&& element
->type
== ACPI_TYPE_STRING
;
670 ref_fwnode
= acpi_fwnode_get_named_child_node(
671 ref_fwnode
, element
->string
.pointer
);
676 /* assume following integer elements are all args */
677 for (i
= 0; element
+ i
< end
&& i
< num_args
; i
++) {
678 int type
= element
[i
].type
;
680 if (type
== ACPI_TYPE_INTEGER
)
682 else if (type
== ACPI_TYPE_LOCAL_REFERENCE
)
688 if (nargs
> NR_FWNODE_REFERENCE_ARGS
)
692 args
->fwnode
= ref_fwnode
;
694 for (i
= 0; i
< nargs
; i
++)
695 args
->args
[i
] = element
[i
].integer
.value
;
701 } else if (element
->type
== ACPI_TYPE_INTEGER
) {
714 EXPORT_SYMBOL_GPL(__acpi_node_get_property_reference
);
716 static int acpi_data_prop_read_single(const struct acpi_device_data
*data
,
717 const char *propname
,
718 enum dev_prop_type proptype
, void *val
)
720 const union acpi_object
*obj
;
726 if (proptype
>= DEV_PROP_U8
&& proptype
<= DEV_PROP_U64
) {
727 ret
= acpi_data_get_property(data
, propname
, ACPI_TYPE_INTEGER
, &obj
);
733 if (obj
->integer
.value
> U8_MAX
)
735 *(u8
*)val
= obj
->integer
.value
;
738 if (obj
->integer
.value
> U16_MAX
)
740 *(u16
*)val
= obj
->integer
.value
;
743 if (obj
->integer
.value
> U32_MAX
)
745 *(u32
*)val
= obj
->integer
.value
;
748 *(u64
*)val
= obj
->integer
.value
;
751 } else if (proptype
== DEV_PROP_STRING
) {
752 ret
= acpi_data_get_property(data
, propname
, ACPI_TYPE_STRING
, &obj
);
756 *(char **)val
= obj
->string
.pointer
;
765 int acpi_dev_prop_read_single(struct acpi_device
*adev
, const char *propname
,
766 enum dev_prop_type proptype
, void *val
)
773 ret
= acpi_data_prop_read_single(&adev
->data
, propname
, proptype
, val
);
774 if (ret
< 0 || proptype
!= ACPI_TYPE_STRING
)
779 static int acpi_copy_property_array_u8(const union acpi_object
*items
, u8
*val
,
784 for (i
= 0; i
< nval
; i
++) {
785 if (items
[i
].type
!= ACPI_TYPE_INTEGER
)
787 if (items
[i
].integer
.value
> U8_MAX
)
790 val
[i
] = items
[i
].integer
.value
;
795 static int acpi_copy_property_array_u16(const union acpi_object
*items
,
796 u16
*val
, size_t nval
)
800 for (i
= 0; i
< nval
; i
++) {
801 if (items
[i
].type
!= ACPI_TYPE_INTEGER
)
803 if (items
[i
].integer
.value
> U16_MAX
)
806 val
[i
] = items
[i
].integer
.value
;
811 static int acpi_copy_property_array_u32(const union acpi_object
*items
,
812 u32
*val
, size_t nval
)
816 for (i
= 0; i
< nval
; i
++) {
817 if (items
[i
].type
!= ACPI_TYPE_INTEGER
)
819 if (items
[i
].integer
.value
> U32_MAX
)
822 val
[i
] = items
[i
].integer
.value
;
827 static int acpi_copy_property_array_u64(const union acpi_object
*items
,
828 u64
*val
, size_t nval
)
832 for (i
= 0; i
< nval
; i
++) {
833 if (items
[i
].type
!= ACPI_TYPE_INTEGER
)
836 val
[i
] = items
[i
].integer
.value
;
841 static int acpi_copy_property_array_string(const union acpi_object
*items
,
842 char **val
, size_t nval
)
846 for (i
= 0; i
< nval
; i
++) {
847 if (items
[i
].type
!= ACPI_TYPE_STRING
)
850 val
[i
] = items
[i
].string
.pointer
;
855 static int acpi_data_prop_read(const struct acpi_device_data
*data
,
856 const char *propname
,
857 enum dev_prop_type proptype
,
858 void *val
, size_t nval
)
860 const union acpi_object
*obj
;
861 const union acpi_object
*items
;
864 if (val
&& nval
== 1) {
865 ret
= acpi_data_prop_read_single(data
, propname
, proptype
, val
);
870 ret
= acpi_data_get_property_array(data
, propname
, ACPI_TYPE_ANY
, &obj
);
875 return obj
->package
.count
;
877 if (proptype
!= DEV_PROP_STRING
&& nval
> obj
->package
.count
)
882 items
= obj
->package
.elements
;
886 ret
= acpi_copy_property_array_u8(items
, (u8
*)val
, nval
);
889 ret
= acpi_copy_property_array_u16(items
, (u16
*)val
, nval
);
892 ret
= acpi_copy_property_array_u32(items
, (u32
*)val
, nval
);
895 ret
= acpi_copy_property_array_u64(items
, (u64
*)val
, nval
);
897 case DEV_PROP_STRING
:
898 ret
= acpi_copy_property_array_string(
900 min_t(u32
, nval
, obj
->package
.count
));
909 int acpi_dev_prop_read(const struct acpi_device
*adev
, const char *propname
,
910 enum dev_prop_type proptype
, void *val
, size_t nval
)
912 return adev
? acpi_data_prop_read(&adev
->data
, propname
, proptype
, val
, nval
) : -EINVAL
;
916 * acpi_node_prop_read - retrieve the value of an ACPI property with given name.
917 * @fwnode: Firmware node to get the property from.
918 * @propname: Name of the property.
919 * @proptype: Expected property type.
920 * @val: Location to store the property value (if not %NULL).
921 * @nval: Size of the array pointed to by @val.
923 * If @val is %NULL, return the number of array elements comprising the value
924 * of the property. Otherwise, read at most @nval values to the array at the
925 * location pointed to by @val.
927 int acpi_node_prop_read(const struct fwnode_handle
*fwnode
,
928 const char *propname
, enum dev_prop_type proptype
,
929 void *val
, size_t nval
)
931 return acpi_data_prop_read(acpi_device_data_of_node(fwnode
),
932 propname
, proptype
, val
, nval
);
936 * acpi_get_next_subnode - Return the next child node handle for a fwnode
937 * @fwnode: Firmware node to find the next child node for.
938 * @child: Handle to one of the device's child nodes or a null handle.
940 struct fwnode_handle
*acpi_get_next_subnode(const struct fwnode_handle
*fwnode
,
941 struct fwnode_handle
*child
)
943 const struct acpi_device
*adev
= to_acpi_device_node(fwnode
);
944 const struct list_head
*head
;
945 struct list_head
*next
;
947 if (!child
|| is_acpi_device_node(child
)) {
948 struct acpi_device
*child_adev
;
951 head
= &adev
->children
;
955 if (list_empty(head
))
959 adev
= to_acpi_device_node(child
);
960 next
= adev
->node
.next
;
965 child_adev
= list_entry(next
, struct acpi_device
, node
);
967 child_adev
= list_first_entry(head
, struct acpi_device
,
970 return acpi_fwnode_handle(child_adev
);
974 if (!child
|| is_acpi_data_node(child
)) {
975 const struct acpi_data_node
*data
= to_acpi_data_node(fwnode
);
976 struct acpi_data_node
*dn
;
979 * We can have a combination of device and data nodes, e.g. with
980 * hierarchical _DSD properties. Make sure the adev pointer is
981 * restored before going through data nodes, otherwise we will
982 * be looking for data_nodes below the last device found instead
983 * of the common fwnode shared by device_nodes and data_nodes.
985 adev
= to_acpi_device_node(fwnode
);
987 head
= &adev
->data
.subnodes
;
989 head
= &data
->data
.subnodes
;
993 if (list_empty(head
))
997 dn
= to_acpi_data_node(child
);
998 next
= dn
->sibling
.next
;
1002 dn
= list_entry(next
, struct acpi_data_node
, sibling
);
1004 dn
= list_first_entry(head
, struct acpi_data_node
, sibling
);
1012 * acpi_node_get_parent - Return parent fwnode of this fwnode
1013 * @fwnode: Firmware node whose parent to get
1015 * Returns parent node of an ACPI device or data firmware node or %NULL if
1018 struct fwnode_handle
*acpi_node_get_parent(const struct fwnode_handle
*fwnode
)
1020 if (is_acpi_data_node(fwnode
)) {
1021 /* All data nodes have parent pointer so just return that */
1022 return to_acpi_data_node(fwnode
)->parent
;
1023 } else if (is_acpi_device_node(fwnode
)) {
1024 acpi_handle handle
, parent_handle
;
1026 handle
= to_acpi_device_node(fwnode
)->handle
;
1027 if (ACPI_SUCCESS(acpi_get_parent(handle
, &parent_handle
))) {
1028 struct acpi_device
*adev
;
1030 if (!acpi_bus_get_device(parent_handle
, &adev
))
1031 return acpi_fwnode_handle(adev
);
1039 * Return true if the node is an ACPI graph node. Called on either ports
1042 static bool is_acpi_graph_node(struct fwnode_handle
*fwnode
,
1045 unsigned int len
= strlen(str
);
1048 if (!len
|| !is_acpi_data_node(fwnode
))
1051 name
= to_acpi_data_node(fwnode
)->name
;
1053 return (fwnode_property_present(fwnode
, "reg") &&
1054 !strncmp(name
, str
, len
) && name
[len
] == '@') ||
1055 fwnode_property_present(fwnode
, str
);
1059 * acpi_graph_get_next_endpoint - Get next endpoint ACPI firmware node
1060 * @fwnode: Pointer to the parent firmware node
1061 * @prev: Previous endpoint node or %NULL to get the first
1063 * Looks up next endpoint ACPI firmware node below a given @fwnode. Returns
1064 * %NULL if there is no next endpoint or in case of error. In case of success
1065 * the next endpoint is returned.
1067 static struct fwnode_handle
*acpi_graph_get_next_endpoint(
1068 const struct fwnode_handle
*fwnode
, struct fwnode_handle
*prev
)
1070 struct fwnode_handle
*port
= NULL
;
1071 struct fwnode_handle
*endpoint
;
1075 port
= fwnode_get_next_child_node(fwnode
, port
);
1077 * The names of the port nodes begin with "port@"
1078 * followed by the number of the port node and they also
1079 * have a "reg" property that also has the number of the
1080 * port node. For compatibility reasons a node is also
1081 * recognised as a port node from the "port" property.
1083 if (is_acpi_graph_node(port
, "port"))
1087 port
= fwnode_get_parent(prev
);
1093 endpoint
= fwnode_get_next_child_node(port
, prev
);
1095 port
= fwnode_get_next_child_node(fwnode
, port
);
1098 if (is_acpi_graph_node(port
, "port"))
1099 endpoint
= fwnode_get_next_child_node(port
, NULL
);
1103 * The names of the endpoint nodes begin with "endpoint@" followed by
1104 * the number of the endpoint node and they also have a "reg" property
1105 * that also has the number of the endpoint node. For compatibility
1106 * reasons a node is also recognised as an endpoint node from the
1107 * "endpoint" property.
1109 if (!is_acpi_graph_node(endpoint
, "endpoint"))
1116 * acpi_graph_get_child_prop_value - Return a child with a given property value
1117 * @fwnode: device fwnode
1118 * @prop_name: The name of the property to look for
1119 * @val: the desired property value
1121 * Return the port node corresponding to a given port number. Returns
1122 * the child node on success, NULL otherwise.
1124 static struct fwnode_handle
*acpi_graph_get_child_prop_value(
1125 const struct fwnode_handle
*fwnode
, const char *prop_name
,
1128 struct fwnode_handle
*child
;
1130 fwnode_for_each_child_node(fwnode
, child
) {
1133 if (fwnode_property_read_u32(child
, prop_name
, &nr
))
1145 * acpi_graph_get_remote_enpoint - Parses and returns remote end of an endpoint
1146 * @fwnode: Endpoint firmware node pointing to a remote device
1147 * @endpoint: Firmware node of remote endpoint is filled here if not %NULL
1149 * Returns the remote endpoint corresponding to @__fwnode. NULL on error.
1151 static struct fwnode_handle
*
1152 acpi_graph_get_remote_endpoint(const struct fwnode_handle
*__fwnode
)
1154 struct fwnode_handle
*fwnode
;
1155 unsigned int port_nr
, endpoint_nr
;
1156 struct fwnode_reference_args args
;
1159 memset(&args
, 0, sizeof(args
));
1160 ret
= acpi_node_get_property_reference(__fwnode
, "remote-endpoint", 0,
1165 /* Direct endpoint reference? */
1166 if (!is_acpi_device_node(args
.fwnode
))
1167 return args
.nargs
? NULL
: args
.fwnode
;
1170 * Always require two arguments with the reference: port and
1173 if (args
.nargs
!= 2)
1176 fwnode
= args
.fwnode
;
1177 port_nr
= args
.args
[0];
1178 endpoint_nr
= args
.args
[1];
1180 fwnode
= acpi_graph_get_child_prop_value(fwnode
, "port", port_nr
);
1182 return acpi_graph_get_child_prop_value(fwnode
, "endpoint", endpoint_nr
);
1185 static bool acpi_fwnode_device_is_available(const struct fwnode_handle
*fwnode
)
1187 if (!is_acpi_device_node(fwnode
))
1190 return acpi_device_is_present(to_acpi_device_node(fwnode
));
1193 static bool acpi_fwnode_property_present(const struct fwnode_handle
*fwnode
,
1194 const char *propname
)
1196 return !acpi_node_prop_get(fwnode
, propname
, NULL
);
1200 acpi_fwnode_property_read_int_array(const struct fwnode_handle
*fwnode
,
1201 const char *propname
,
1202 unsigned int elem_size
, void *val
,
1205 enum dev_prop_type type
;
1207 switch (elem_size
) {
1212 type
= DEV_PROP_U16
;
1215 type
= DEV_PROP_U32
;
1218 type
= DEV_PROP_U64
;
1224 return acpi_node_prop_read(fwnode
, propname
, type
, val
, nval
);
1228 acpi_fwnode_property_read_string_array(const struct fwnode_handle
*fwnode
,
1229 const char *propname
, const char **val
,
1232 return acpi_node_prop_read(fwnode
, propname
, DEV_PROP_STRING
,
1237 acpi_fwnode_get_reference_args(const struct fwnode_handle
*fwnode
,
1238 const char *prop
, const char *nargs_prop
,
1239 unsigned int args_count
, unsigned int index
,
1240 struct fwnode_reference_args
*args
)
1242 return __acpi_node_get_property_reference(fwnode
, prop
, index
,
1246 static struct fwnode_handle
*
1247 acpi_fwnode_get_parent(struct fwnode_handle
*fwnode
)
1249 return acpi_node_get_parent(fwnode
);
1252 static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle
*fwnode
,
1253 struct fwnode_endpoint
*endpoint
)
1255 struct fwnode_handle
*port_fwnode
= fwnode_get_parent(fwnode
);
1257 endpoint
->local_fwnode
= fwnode
;
1259 if (fwnode_property_read_u32(port_fwnode
, "reg", &endpoint
->port
))
1260 fwnode_property_read_u32(port_fwnode
, "port", &endpoint
->port
);
1261 if (fwnode_property_read_u32(fwnode
, "reg", &endpoint
->id
))
1262 fwnode_property_read_u32(fwnode
, "endpoint", &endpoint
->id
);
1268 acpi_fwnode_device_get_match_data(const struct fwnode_handle
*fwnode
,
1269 const struct device
*dev
)
1271 return acpi_device_get_match_data(dev
);
1274 #define DECLARE_ACPI_FWNODE_OPS(ops) \
1275 const struct fwnode_operations ops = { \
1276 .device_is_available = acpi_fwnode_device_is_available, \
1277 .device_get_match_data = acpi_fwnode_device_get_match_data, \
1278 .property_present = acpi_fwnode_property_present, \
1279 .property_read_int_array = \
1280 acpi_fwnode_property_read_int_array, \
1281 .property_read_string_array = \
1282 acpi_fwnode_property_read_string_array, \
1283 .get_parent = acpi_node_get_parent, \
1284 .get_next_child_node = acpi_get_next_subnode, \
1285 .get_named_child_node = acpi_fwnode_get_named_child_node, \
1286 .get_reference_args = acpi_fwnode_get_reference_args, \
1287 .graph_get_next_endpoint = \
1288 acpi_graph_get_next_endpoint, \
1289 .graph_get_remote_endpoint = \
1290 acpi_graph_get_remote_endpoint, \
1291 .graph_get_port_parent = acpi_fwnode_get_parent, \
1292 .graph_parse_endpoint = acpi_fwnode_graph_parse_endpoint, \
1294 EXPORT_SYMBOL_GPL(ops)
1296 DECLARE_ACPI_FWNODE_OPS(acpi_device_fwnode_ops
);
1297 DECLARE_ACPI_FWNODE_OPS(acpi_data_fwnode_ops
);
1298 const struct fwnode_operations acpi_static_fwnode_ops
;
1300 bool is_acpi_device_node(const struct fwnode_handle
*fwnode
)
1302 return !IS_ERR_OR_NULL(fwnode
) &&
1303 fwnode
->ops
== &acpi_device_fwnode_ops
;
1305 EXPORT_SYMBOL(is_acpi_device_node
);
1307 bool is_acpi_data_node(const struct fwnode_handle
*fwnode
)
1309 return !IS_ERR_OR_NULL(fwnode
) && fwnode
->ops
== &acpi_data_fwnode_ops
;
1311 EXPORT_SYMBOL(is_acpi_data_node
);