Lines Matching +full:string +full:- +full:array +full:- +full:property
1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (C) 2014 - 2023, Intel Corporation
32 * from different GUID appear in a property list of another, it will be
36 /* ACPI _DSD device properties GUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
39 /* Hotplug in D3 GUID: 6211e2c0-58a3-4af3-90e1-927a4e0c55a4 */
42 /* External facing port GUID: efcc06cc-73ac-4bc3-bff0-76143807c389 */
45 /* Thunderbolt GUID for IMR_VALID: c44d002f-69f9-4e7d-a904-a7baabdf43f7 */
48 /* Thunderbolt GUID for WAKE_SUPPORTED: 6c501103-c189-4296-ba72-9bf5a26ebe5d */
51 /* Storage device needs D3 GUID: 5025030f-842f-4ab4-a561-99a5189762d0 */
56 /* ACPI _DSD data subnodes GUID: dbb8e3e6-5886-4ba6-8795-1319f52a966b */
61 /* ACPI _DSD data buffer GUID: edb12dd0-363d-4085-a3d2-49522ca160c4 */
87 dn->name = link->package.elements[0].string.pointer; in acpi_nondev_subnode_extract()
88 fwnode_init(&dn->fwnode, &acpi_data_fwnode_ops); in acpi_nondev_subnode_extract()
89 dn->parent = parent; in acpi_nondev_subnode_extract()
90 INIT_LIST_HEAD(&dn->data.properties); in acpi_nondev_subnode_extract()
91 INIT_LIST_HEAD(&dn->data.subnodes); in acpi_nondev_subnode_extract()
93 result = acpi_extract_properties(handle, desc, &dn->data); in acpi_nondev_subnode_extract()
107 && acpi_enumerate_nondev_subnodes(scope, desc, &dn->data, in acpi_nondev_subnode_extract()
108 &dn->fwnode)) in acpi_nondev_subnode_extract()
110 } else if (acpi_enumerate_nondev_subnodes(NULL, desc, &dn->data, in acpi_nondev_subnode_extract()
111 &dn->fwnode)) { in acpi_nondev_subnode_extract()
116 dn->handle = handle; in acpi_nondev_subnode_extract()
117 dn->data.pointer = desc; in acpi_nondev_subnode_extract()
118 list_add_tail(&dn->sibling, list); in acpi_nondev_subnode_extract()
159 status = acpi_get_handle(scope, link->package.elements[1].string.pointer, in acpi_nondev_subnode_ok()
175 for (i = 0; i < links->package.count; i++) { in acpi_add_nondev_subnodes()
180 link = &links->package.elements[i]; in acpi_add_nondev_subnodes()
182 if (link->package.count != 2) in acpi_add_nondev_subnodes()
185 /* The first one must be a string. */ in acpi_add_nondev_subnodes()
186 if (link->package.elements[0].type != ACPI_TYPE_STRING) in acpi_add_nondev_subnodes()
189 /* The second one may be a string, a reference or a package. */ in acpi_add_nondev_subnodes()
190 switch (link->package.elements[1].type) { in acpi_add_nondev_subnodes()
196 handle = link->package.elements[1].reference.handle; in acpi_add_nondev_subnodes()
201 desc = &link->package.elements[1]; in acpi_add_nondev_subnodes()
223 for (i = 0; i < desc->package.count; i += 2) { in acpi_enumerate_nondev_subnodes()
227 guid = &desc->package.elements[i]; in acpi_enumerate_nondev_subnodes()
228 links = &desc->package.elements[i + 1]; in acpi_enumerate_nondev_subnodes()
234 if (guid->type != ACPI_TYPE_BUFFER || in acpi_enumerate_nondev_subnodes()
235 guid->buffer.length != 16 || in acpi_enumerate_nondev_subnodes()
236 links->type != ACPI_TYPE_PACKAGE) in acpi_enumerate_nondev_subnodes()
239 if (!guid_equal((guid_t *)guid->buffer.pointer, &ads_guid)) in acpi_enumerate_nondev_subnodes()
242 return acpi_add_nondev_subnodes(scope, links, &data->subnodes, in acpi_enumerate_nondev_subnodes()
254 * The value must be an integer, a string, a reference, or a package in acpi_property_value_ok()
255 * whose every element must be an integer, a string, or a reference. in acpi_property_value_ok()
257 switch (value->type) { in acpi_property_value_ok()
264 for (j = 0; j < value->package.count; j++) in acpi_property_value_ok()
265 switch (value->package.elements[j].type) { in acpi_property_value_ok()
284 for (i = 0; i < properties->package.count; i++) { in acpi_properties_format_valid()
285 const union acpi_object *property; in acpi_properties_format_valid() local
287 property = &properties->package.elements[i]; in acpi_properties_format_valid()
289 * Only two elements allowed, the first one must be a string and in acpi_properties_format_valid()
292 if (property->package.count != 2 in acpi_properties_format_valid()
293 || property->package.elements[0].type != ACPI_TYPE_STRING in acpi_properties_format_valid()
294 || !acpi_property_value_ok(&property->package.elements[1])) in acpi_properties_format_valid()
305 ret = acpi_data_get_property_array(&adev->data, "compatible", in acpi_init_of_compatible()
314 if (parent && parent->flags.of_compatible_ok) in acpi_init_of_compatible()
320 adev->data.of_compatible = of_compatible; in acpi_init_of_compatible()
323 adev->flags.of_compatible_ok = 1; in acpi_init_of_compatible()
346 INIT_LIST_HEAD(&props->list); in acpi_data_add_props()
347 props->guid = guid; in acpi_data_add_props()
348 props->properties = properties; in acpi_data_add_props()
349 list_add_tail(&props->list, &data->properties); in acpi_data_add_props()
363 list_for_each_entry(dn, &data->subnodes, sibling) { in acpi_untie_nondev_subnodes()
364 acpi_detach_data(dn->handle, acpi_nondev_subnode_tag); in acpi_untie_nondev_subnodes()
366 acpi_untie_nondev_subnodes(&dn->data); in acpi_untie_nondev_subnodes()
374 list_for_each_entry(dn, &data->subnodes, sibling) { in acpi_tie_nondev_subnodes()
378 status = acpi_attach_data(dn->handle, acpi_nondev_subnode_tag, dn); in acpi_tie_nondev_subnodes()
380 acpi_handle_err(dn->handle, "Can't tag data node\n"); in acpi_tie_nondev_subnodes()
384 ret = acpi_tie_nondev_subnodes(&dn->data); in acpi_tie_nondev_subnodes()
402 if (check_mul_overflow((size_t)properties->package.count, in acpi_data_add_buffer_props()
409 properties->package.count); in acpi_data_add_buffer_props()
417 props->guid = &buffer_prop_guid; in acpi_data_add_buffer_props()
418 props->bufs = (void *)(props + 1); in acpi_data_add_buffer_props()
419 props->properties = (void *)(props->bufs + properties->package.count); in acpi_data_add_buffer_props()
422 package = props->properties; in acpi_data_add_buffer_props()
423 package->type = ACPI_TYPE_PACKAGE; in acpi_data_add_buffer_props()
424 package->package.elements = package + 1; in acpi_data_add_buffer_props()
425 count = &package->package.count; in acpi_data_add_buffer_props()
431 for (i = 0; i < properties->package.count; i++) { in acpi_data_add_buffer_props()
433 union acpi_object *property = &properties->package.elements[i]; in acpi_data_add_buffer_props() local
437 if (property->type != ACPI_TYPE_PACKAGE || in acpi_data_add_buffer_props()
438 property->package.count != 2) { in acpi_data_add_buffer_props()
440 "buffer property %u has %u entries\n", in acpi_data_add_buffer_props()
441 i, property->package.count); in acpi_data_add_buffer_props()
445 prop = &property->package.elements[0]; in acpi_data_add_buffer_props()
446 obj = &property->package.elements[1]; in acpi_data_add_buffer_props()
448 if (prop->type != ACPI_TYPE_STRING || in acpi_data_add_buffer_props()
449 obj->type != ACPI_TYPE_STRING) { in acpi_data_add_buffer_props()
452 prop->type, obj->type); in acpi_data_add_buffer_props()
456 status = acpi_evaluate_object_typed(handle, obj->string.pointer, in acpi_data_add_buffer_props()
462 obj->string.length, in acpi_data_add_buffer_props()
463 obj->string.pointer); in acpi_data_add_buffer_props()
467 package->type = ACPI_TYPE_PACKAGE; in acpi_data_add_buffer_props()
468 package->package.elements = prop; in acpi_data_add_buffer_props()
469 package->package.count = 2; in acpi_data_add_buffer_props()
473 /* Replace the string object with a buffer object */ in acpi_data_add_buffer_props()
474 obj->type = ACPI_TYPE_BUFFER; in acpi_data_add_buffer_props()
475 obj->buffer.length = buf_obj->buffer.length; in acpi_data_add_buffer_props()
476 obj->buffer.pointer = buf_obj->buffer.pointer; in acpi_data_add_buffer_props()
478 props->bufs[i] = buf.pointer; in acpi_data_add_buffer_props()
484 list_add(&props->list, &data->properties); in acpi_data_add_buffer_props()
494 if (desc->package.count % 2) in acpi_extract_properties()
498 for (i = 0; i < desc->package.count; i += 2) { in acpi_extract_properties()
502 guid = &desc->package.elements[i]; in acpi_extract_properties()
503 properties = &desc->package.elements[i + 1]; in acpi_extract_properties()
509 if (guid->type != ACPI_TYPE_BUFFER || in acpi_extract_properties()
510 guid->buffer.length != 16 || in acpi_extract_properties()
511 properties->type != ACPI_TYPE_PACKAGE) in acpi_extract_properties()
514 if (guid_equal((guid_t *)guid->buffer.pointer, in acpi_extract_properties()
520 if (!acpi_is_property_guid((guid_t *)guid->buffer.pointer)) in acpi_extract_properties()
530 acpi_data_add_props(data, (const guid_t *)guid->buffer.pointer, in acpi_extract_properties()
534 return !list_empty(&data->properties); in acpi_extract_properties()
544 INIT_LIST_HEAD(&adev->data.properties); in acpi_init_properties()
545 INIT_LIST_HEAD(&adev->data.subnodes); in acpi_init_properties()
547 if (!adev->handle) in acpi_init_properties()
554 list_for_each_entry(hwid, &adev->pnp.ids, list) { in acpi_init_properties()
555 if (!strcmp(hwid->id, ACPI_DT_NAMESPACE_HID)) { in acpi_init_properties()
561 status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, &buf, in acpi_init_properties()
566 if (acpi_extract_properties(adev->handle, buf.pointer, &adev->data)) { in acpi_init_properties()
567 adev->data.pointer = buf.pointer; in acpi_init_properties()
571 if (acpi_enumerate_nondev_subnodes(adev->handle, buf.pointer, in acpi_init_properties()
572 &adev->data, acpi_fwnode_handle(adev))) in acpi_init_properties()
573 adev->data.pointer = buf.pointer; in acpi_init_properties()
575 if (!adev->data.pointer) { in acpi_init_properties()
576 acpi_handle_debug(adev->handle, "Invalid _DSD data, skipping\n"); in acpi_init_properties()
579 if (!acpi_tie_nondev_subnodes(&adev->data)) in acpi_init_properties()
580 acpi_untie_nondev_subnodes(&adev->data); in acpi_init_properties()
584 if (acpi_of && !adev->flags.of_compatible_ok) in acpi_init_properties()
585 acpi_handle_info(adev->handle, in acpi_init_properties()
586 ACPI_DT_NAMESPACE_HID " requires 'compatible' property\n"); in acpi_init_properties()
588 if (!adev->data.pointer) in acpi_init_properties()
599 list_del(&props->list); in acpi_free_device_properties()
601 if (props->bufs) in acpi_free_device_properties()
602 for (i = 0; i < props->properties->package.count; i++) in acpi_free_device_properties()
603 ACPI_FREE(props->bufs[i]); in acpi_free_device_properties()
616 acpi_destroy_nondev_subnodes(&dn->data.subnodes); in acpi_destroy_nondev_subnodes()
617 wait_for_completion(&dn->kobj_done); in acpi_destroy_nondev_subnodes()
618 list_del(&dn->sibling); in acpi_destroy_nondev_subnodes()
619 ACPI_FREE((void *)dn->data.pointer); in acpi_destroy_nondev_subnodes()
620 acpi_free_device_properties(&dn->data.properties); in acpi_destroy_nondev_subnodes()
627 acpi_untie_nondev_subnodes(&adev->data); in acpi_free_properties()
628 acpi_destroy_nondev_subnodes(&adev->data.subnodes); in acpi_free_properties()
629 ACPI_FREE((void *)adev->data.pointer); in acpi_free_properties()
630 adev->data.of_compatible = NULL; in acpi_free_properties()
631 adev->data.pointer = NULL; in acpi_free_properties()
632 acpi_free_device_properties(&adev->data.properties); in acpi_free_properties()
636 * acpi_data_get_property - return an ACPI property with given name
637 * @data: ACPI device deta object to get the property from
638 * @name: Name of the property
639 * @type: Expected property type
640 * @obj: Location to store the property value (if not %NULL)
642 * Look up a property with @name and store a pointer to the resulting ACPI
648 * Return: %0 if property with @name has been found (success),
649 * %-EINVAL if the arguments are invalid,
650 * %-EINVAL if the property doesn't exist,
651 * %-EPROTO if the property value type doesn't match @type.
660 return -EINVAL; in acpi_data_get_property()
662 if (!data->pointer || list_empty(&data->properties)) in acpi_data_get_property()
663 return -EINVAL; in acpi_data_get_property()
665 list_for_each_entry(props, &data->properties, list) { in acpi_data_get_property()
669 properties = props->properties; in acpi_data_get_property()
670 for (i = 0; i < properties->package.count; i++) { in acpi_data_get_property()
672 const union acpi_object *property; in acpi_data_get_property() local
674 property = &properties->package.elements[i]; in acpi_data_get_property()
676 propname = &property->package.elements[0]; in acpi_data_get_property()
677 propvalue = &property->package.elements[1]; in acpi_data_get_property()
679 if (!strcmp(name, propname->string.pointer)) { in acpi_data_get_property()
681 propvalue->type != type) in acpi_data_get_property()
682 return -EPROTO; in acpi_data_get_property()
690 return -EINVAL; in acpi_data_get_property()
694 * acpi_dev_get_property - return an ACPI property with given name.
695 * @adev: ACPI device to get the property from.
696 * @name: Name of the property.
697 * @type: Expected property type.
698 * @obj: Location to store the property value (if not %NULL).
703 return adev ? acpi_data_get_property(&adev->data, name, type, obj) : -EINVAL; in acpi_dev_get_property()
712 return &adev->data; in acpi_device_data_of_node()
716 return &dn->data; in acpi_device_data_of_node()
722 * acpi_node_prop_get - return an ACPI property with given name.
723 * @fwnode: Firmware node to get the property from.
724 * @propname: Name of the property.
725 * @valptr: Location to store a pointer to the property value (if not %NULL).
736 * acpi_data_get_property_array - return an ACPI array property with given name
737 * @data: ACPI data object to get the property from
738 * @name: Name of the property
739 * @type: Expected type of array elements
740 * @obj: Location to store a pointer to the property value (if not NULL)
742 * Look up an array property with @name and store a pointer to the resulting
748 * Return: %0 if array property (package) with @name has been found (success),
749 * %-EINVAL if the arguments are invalid,
750 * %-EINVAL if the property doesn't exist,
751 * %-EPROTO if the property is not a package or the type of its elements
768 for (i = 0; i < prop->package.count; i++) in acpi_data_get_property_array()
769 if (prop->package.elements[i].type != type) in acpi_data_get_property_array()
770 return -EPROTO; in acpi_data_get_property_array()
808 * the first reference (possibly represented as a string) or end of the in acpi_get_ref_args()
821 return -EINVAL; in acpi_get_ref_args()
825 return -EINVAL; in acpi_get_ref_args()
828 args->fwnode = ref_fwnode; in acpi_get_ref_args()
829 args->nargs = nargs; in acpi_get_ref_args()
831 args->args[i] = (*element)[i].integer.value; in acpi_get_ref_args()
848 scope = to_acpi_device_node(fwnode)->handle; in acpi_parse_string_ref()
850 scope = to_acpi_data_node(fwnode)->handle; in acpi_parse_string_ref()
874 return &dn->fwnode; in acpi_parse_string_ref()
878 * __acpi_node_get_property_reference - returns handle to the referenced object
879 * @fwnode: Firmware node to get the property from
880 * @propname: Name of the property
886 * Find property with @name, verifify that it is a package containing at least
888 * target object in @args->adev. If the reference includes arguments, store
889 * them in the @args->args[] array.
891 * If there's more than one reference in the property value package, @index is
894 * It is possible to leave holes in the property value set like in the
898 * "cs-gpios",
907 * Calling this function with index %2 or index %3 return %-ENOENT. If the
908 * property does not contain any more values %-ENOENT is returned. The NULL
926 return -ENOENT; in __acpi_node_get_property_reference()
930 return ret == -EINVAL ? -ENOENT : -EINVAL; in __acpi_node_get_property_reference()
932 switch (obj->type) { in __acpi_node_get_property_reference()
936 return -ENOENT; in __acpi_node_get_property_reference()
938 device = acpi_fetch_acpi_dev(obj->reference.handle); in __acpi_node_get_property_reference()
940 return -EINVAL; in __acpi_node_get_property_reference()
945 args->fwnode = acpi_fwnode_handle(device); in __acpi_node_get_property_reference()
946 args->nargs = 0; in __acpi_node_get_property_reference()
951 return -ENOENT; in __acpi_node_get_property_reference()
953 ref_fwnode = acpi_parse_string_ref(fwnode, obj->string.pointer); in __acpi_node_get_property_reference()
955 return -EINVAL; in __acpi_node_get_property_reference()
957 args->fwnode = ref_fwnode; in __acpi_node_get_property_reference()
958 args->nargs = 0; in __acpi_node_get_property_reference()
968 * Here, REF may be either a local reference or a string. The in __acpi_node_get_property_reference()
974 return -EINVAL; in __acpi_node_get_property_reference()
977 if (index >= obj->package.count) in __acpi_node_get_property_reference()
978 return -ENOENT; in __acpi_node_get_property_reference()
980 element = obj->package.elements; in __acpi_node_get_property_reference()
981 end = element + obj->package.count; in __acpi_node_get_property_reference()
984 switch (element->type) { in __acpi_node_get_property_reference()
986 device = acpi_fetch_acpi_dev(element->reference.handle); in __acpi_node_get_property_reference()
988 return -EINVAL; in __acpi_node_get_property_reference()
1004 element->string.pointer); in __acpi_node_get_property_reference()
1006 return -EINVAL; in __acpi_node_get_property_reference()
1022 return -ENOENT; in __acpi_node_get_property_reference()
1026 return -EINVAL; in __acpi_node_get_property_reference()
1032 return -ENOENT; in __acpi_node_get_property_reference()
1052 if (obj->integer.value > U8_MAX) in acpi_data_prop_read_single()
1053 return -EOVERFLOW; in acpi_data_prop_read_single()
1055 *(u8 *)val = obj->integer.value; in acpi_data_prop_read_single()
1058 if (obj->integer.value > U16_MAX) in acpi_data_prop_read_single()
1059 return -EOVERFLOW; in acpi_data_prop_read_single()
1061 *(u16 *)val = obj->integer.value; in acpi_data_prop_read_single()
1064 if (obj->integer.value > U32_MAX) in acpi_data_prop_read_single()
1065 return -EOVERFLOW; in acpi_data_prop_read_single()
1067 *(u32 *)val = obj->integer.value; in acpi_data_prop_read_single()
1071 *(u64 *)val = obj->integer.value; in acpi_data_prop_read_single()
1075 *(char **)val = obj->string.pointer; in acpi_data_prop_read_single()
1078 return -EINVAL; in acpi_data_prop_read_single()
1094 if (__items->type == ACPI_TYPE_BUFFER) { \
1095 __val[i] = __items->buffer.pointer[i]; \
1099 ret = -EPROTO; \
1107 ret = -EOVERFLOW; \
1123 return -EPROTO; in acpi_copy_property_array_string()
1125 val[i] = items[i].string.pointer; in acpi_copy_property_array_string()
1142 * The overflow error means that the property is there and it is in acpi_data_prop_read()
1143 * single-value, but its type does not match, so return. in acpi_data_prop_read()
1145 if (ret >= 0 || ret == -EOVERFLOW) in acpi_data_prop_read()
1149 * Reading this property as a single-value one failed, but its in acpi_data_prop_read()
1150 * value may still be represented as one-element array, so in acpi_data_prop_read()
1163 if (obj->type == ACPI_TYPE_BUFFER) in acpi_data_prop_read()
1164 return obj->buffer.length; in acpi_data_prop_read()
1166 return obj->package.count; in acpi_data_prop_read()
1173 if (obj->type == ACPI_TYPE_BUFFER) { in acpi_data_prop_read()
1174 if (nval > obj->buffer.length) in acpi_data_prop_read()
1175 return -EOVERFLOW; in acpi_data_prop_read()
1177 if (nval > obj->package.count) in acpi_data_prop_read()
1178 return -EOVERFLOW; in acpi_data_prop_read()
1183 return -EINVAL; in acpi_data_prop_read()
1185 if (obj->type == ACPI_TYPE_BUFFER) { in acpi_data_prop_read()
1187 return -EPROTO; in acpi_data_prop_read()
1190 items = obj->package.elements; in acpi_data_prop_read()
1209 min_t(u32, nval, obj->package.count)); in acpi_data_prop_read()
1212 ret = -EINVAL; in acpi_data_prop_read()
1219 * acpi_node_prop_read - retrieve the value of an ACPI property with given name.
1220 * @fwnode: Firmware node to get the property from.
1221 * @propname: Name of the property.
1222 * @proptype: Expected property type.
1223 * @val: Location to store the property value (if not %NULL).
1224 * @nval: Size of the array pointed to by @val.
1226 * If @val is %NULL, return the number of array elements comprising the value
1227 * of the property. Otherwise, read at most @nval values to the array at the
1255 * acpi_get_next_subnode - Return the next child node handle for a fwnode
1289 head = &adev->data.subnodes; in acpi_get_next_subnode()
1291 head = &data->data.subnodes; in acpi_get_next_subnode()
1300 next = dn->sibling.next; in acpi_get_next_subnode()
1308 return &dn->fwnode; in acpi_get_next_subnode()
1314 * acpi_node_get_parent - Return parent fwnode of this fwnode
1325 return to_acpi_data_node(fwnode)->parent; in acpi_node_get_parent()
1351 name = to_acpi_data_node(fwnode)->name; in is_acpi_graph_node()
1359 * acpi_graph_get_next_endpoint - Get next endpoint ACPI firmware node
1379 * have a "reg" property that also has the number of the in acpi_graph_get_next_endpoint()
1381 * recognised as a port node from the "port" property. in acpi_graph_get_next_endpoint()
1404 * the number of the endpoint node and they also have a "reg" property in acpi_graph_get_next_endpoint()
1407 * "endpoint" property. in acpi_graph_get_next_endpoint()
1416 * acpi_graph_get_child_prop_value - Return a child with a given property value
1418 * @prop_name: The name of the property to look for
1419 * @val: the desired property value
1445 * acpi_graph_get_remote_endpoint - Parses and returns remote end of an endpoint
1459 ret = acpi_node_get_property_reference(__fwnode, "remote-endpoint", 0, in acpi_graph_get_remote_endpoint()
1538 return -ENXIO; in acpi_fwnode_property_read_int_array()
1578 return dn->name; in acpi_fwnode_get_name()
1620 endpoint->local_fwnode = fwnode; in acpi_fwnode_graph_parse_endpoint()
1622 if (fwnode_property_read_u32(port_fwnode, "reg", &endpoint->port)) in acpi_fwnode_graph_parse_endpoint()
1623 fwnode_property_read_u32(port_fwnode, "port", &endpoint->port); in acpi_fwnode_graph_parse_endpoint()
1624 if (fwnode_property_read_u32(fwnode, "reg", &endpoint->id)) in acpi_fwnode_graph_parse_endpoint()
1625 fwnode_property_read_u32(fwnode, "endpoint", &endpoint->id); in acpi_fwnode_graph_parse_endpoint()
1678 fwnode->ops == &acpi_device_fwnode_ops; in is_acpi_device_node()
1684 return !IS_ERR_OR_NULL(fwnode) && fwnode->ops == &acpi_data_fwnode_ops; in is_acpi_data_node()