1 /* 2 * ACPI device specific properties support. 3 * 4 * Copyright (C) 2014, Intel Corporation 5 * All rights reserved. 6 * 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> 10 * 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. 14 */ 15 16 #include <linux/acpi.h> 17 #include <linux/device.h> 18 #include <linux/export.h> 19 20 #include "internal.h" 21 22 static int acpi_data_get_property_array(struct acpi_device_data *data, 23 const char *name, 24 acpi_object_type type, 25 const union acpi_object **obj); 26 27 /* ACPI _DSD device properties UUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */ 28 static const u8 prp_uuid[16] = { 29 0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d, 30 0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01 31 }; 32 /* ACPI _DSD data subnodes UUID: dbb8e3e6-5886-4ba6-8795-1319f52a966b */ 33 static const u8 ads_uuid[16] = { 34 0xe6, 0xe3, 0xb8, 0xdb, 0x86, 0x58, 0xa6, 0x4b, 35 0x87, 0x95, 0x13, 0x19, 0xf5, 0x2a, 0x96, 0x6b 36 }; 37 38 static bool acpi_enumerate_nondev_subnodes(acpi_handle scope, 39 const union acpi_object *desc, 40 struct acpi_device_data *data); 41 static bool acpi_extract_properties(const union acpi_object *desc, 42 struct acpi_device_data *data); 43 44 static bool acpi_nondev_subnode_extract(const union acpi_object *desc, 45 acpi_handle handle, 46 const union acpi_object *link, 47 struct list_head *list) 48 { 49 struct acpi_data_node *dn; 50 bool result; 51 52 dn = kzalloc(sizeof(*dn), GFP_KERNEL); 53 if (!dn) 54 return false; 55 56 dn->name = link->package.elements[0].string.pointer; 57 dn->fwnode.type = FWNODE_ACPI_DATA; 58 INIT_LIST_HEAD(&dn->data.subnodes); 59 60 result = acpi_extract_properties(desc, &dn->data); 61 62 if (handle) { 63 acpi_handle scope; 64 acpi_status status; 65 66 /* 67 * The scope for the subnode object lookup is the one of the 68 * namespace node (device) containing the object that has 69 * returned the package. That is, it's the scope of that 70 * object's parent. 71 */ 72 status = acpi_get_parent(handle, &scope); 73 if (ACPI_SUCCESS(status) 74 && acpi_enumerate_nondev_subnodes(scope, desc, &dn->data)) 75 result = true; 76 } else if (acpi_enumerate_nondev_subnodes(NULL, desc, &dn->data)) { 77 result = true; 78 } 79 80 if (result) { 81 dn->handle = handle; 82 dn->data.pointer = desc; 83 list_add_tail(&dn->sibling, list); 84 return true; 85 } 86 87 kfree(dn); 88 acpi_handle_debug(handle, "Invalid properties/subnodes data, skipping\n"); 89 return false; 90 } 91 92 static bool acpi_nondev_subnode_data_ok(acpi_handle handle, 93 const union acpi_object *link, 94 struct list_head *list) 95 { 96 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; 97 acpi_status status; 98 99 status = acpi_evaluate_object_typed(handle, NULL, NULL, &buf, 100 ACPI_TYPE_PACKAGE); 101 if (ACPI_FAILURE(status)) 102 return false; 103 104 if (acpi_nondev_subnode_extract(buf.pointer, handle, link, list)) 105 return true; 106 107 ACPI_FREE(buf.pointer); 108 return false; 109 } 110 111 static bool acpi_nondev_subnode_ok(acpi_handle scope, 112 const union acpi_object *link, 113 struct list_head *list) 114 { 115 acpi_handle handle; 116 acpi_status status; 117 118 if (!scope) 119 return false; 120 121 status = acpi_get_handle(scope, link->package.elements[1].string.pointer, 122 &handle); 123 if (ACPI_FAILURE(status)) 124 return false; 125 126 return acpi_nondev_subnode_data_ok(handle, link, list); 127 } 128 129 static int acpi_add_nondev_subnodes(acpi_handle scope, 130 const union acpi_object *links, 131 struct list_head *list) 132 { 133 bool ret = false; 134 int i; 135 136 for (i = 0; i < links->package.count; i++) { 137 const union acpi_object *link, *desc; 138 acpi_handle handle; 139 bool result; 140 141 link = &links->package.elements[i]; 142 /* Only two elements allowed. */ 143 if (link->package.count != 2) 144 continue; 145 146 /* The first one must be a string. */ 147 if (link->package.elements[0].type != ACPI_TYPE_STRING) 148 continue; 149 150 /* The second one may be a string, a reference or a package. */ 151 switch (link->package.elements[1].type) { 152 case ACPI_TYPE_STRING: 153 result = acpi_nondev_subnode_ok(scope, link, list); 154 break; 155 case ACPI_TYPE_LOCAL_REFERENCE: 156 handle = link->package.elements[1].reference.handle; 157 result = acpi_nondev_subnode_data_ok(handle, link, list); 158 break; 159 case ACPI_TYPE_PACKAGE: 160 desc = &link->package.elements[1]; 161 result = acpi_nondev_subnode_extract(desc, NULL, link, list); 162 break; 163 default: 164 result = false; 165 break; 166 } 167 ret = ret || result; 168 } 169 170 return ret; 171 } 172 173 static bool acpi_enumerate_nondev_subnodes(acpi_handle scope, 174 const union acpi_object *desc, 175 struct acpi_device_data *data) 176 { 177 int i; 178 179 /* Look for the ACPI data subnodes UUID. */ 180 for (i = 0; i < desc->package.count; i += 2) { 181 const union acpi_object *uuid, *links; 182 183 uuid = &desc->package.elements[i]; 184 links = &desc->package.elements[i + 1]; 185 186 /* 187 * The first element must be a UUID and the second one must be 188 * a package. 189 */ 190 if (uuid->type != ACPI_TYPE_BUFFER || uuid->buffer.length != 16 191 || links->type != ACPI_TYPE_PACKAGE) 192 break; 193 194 if (memcmp(uuid->buffer.pointer, ads_uuid, sizeof(ads_uuid))) 195 continue; 196 197 return acpi_add_nondev_subnodes(scope, links, &data->subnodes); 198 } 199 200 return false; 201 } 202 203 static bool acpi_property_value_ok(const union acpi_object *value) 204 { 205 int j; 206 207 /* 208 * The value must be an integer, a string, a reference, or a package 209 * whose every element must be an integer, a string, or a reference. 210 */ 211 switch (value->type) { 212 case ACPI_TYPE_INTEGER: 213 case ACPI_TYPE_STRING: 214 case ACPI_TYPE_LOCAL_REFERENCE: 215 return true; 216 217 case ACPI_TYPE_PACKAGE: 218 for (j = 0; j < value->package.count; j++) 219 switch (value->package.elements[j].type) { 220 case ACPI_TYPE_INTEGER: 221 case ACPI_TYPE_STRING: 222 case ACPI_TYPE_LOCAL_REFERENCE: 223 continue; 224 225 default: 226 return false; 227 } 228 229 return true; 230 } 231 return false; 232 } 233 234 static bool acpi_properties_format_valid(const union acpi_object *properties) 235 { 236 int i; 237 238 for (i = 0; i < properties->package.count; i++) { 239 const union acpi_object *property; 240 241 property = &properties->package.elements[i]; 242 /* 243 * Only two elements allowed, the first one must be a string and 244 * the second one has to satisfy certain conditions. 245 */ 246 if (property->package.count != 2 247 || property->package.elements[0].type != ACPI_TYPE_STRING 248 || !acpi_property_value_ok(&property->package.elements[1])) 249 return false; 250 } 251 return true; 252 } 253 254 static void acpi_init_of_compatible(struct acpi_device *adev) 255 { 256 const union acpi_object *of_compatible; 257 int ret; 258 259 ret = acpi_data_get_property_array(&adev->data, "compatible", 260 ACPI_TYPE_STRING, &of_compatible); 261 if (ret) { 262 ret = acpi_dev_get_property(adev, "compatible", 263 ACPI_TYPE_STRING, &of_compatible); 264 if (ret) { 265 if (adev->parent 266 && adev->parent->flags.of_compatible_ok) 267 goto out; 268 269 return; 270 } 271 } 272 adev->data.of_compatible = of_compatible; 273 274 out: 275 adev->flags.of_compatible_ok = 1; 276 } 277 278 static bool acpi_extract_properties(const union acpi_object *desc, 279 struct acpi_device_data *data) 280 { 281 int i; 282 283 if (desc->package.count % 2) 284 return false; 285 286 /* Look for the device properties UUID. */ 287 for (i = 0; i < desc->package.count; i += 2) { 288 const union acpi_object *uuid, *properties; 289 290 uuid = &desc->package.elements[i]; 291 properties = &desc->package.elements[i + 1]; 292 293 /* 294 * The first element must be a UUID and the second one must be 295 * a package. 296 */ 297 if (uuid->type != ACPI_TYPE_BUFFER || uuid->buffer.length != 16 298 || properties->type != ACPI_TYPE_PACKAGE) 299 break; 300 301 if (memcmp(uuid->buffer.pointer, prp_uuid, sizeof(prp_uuid))) 302 continue; 303 304 /* 305 * We found the matching UUID. Now validate the format of the 306 * package immediately following it. 307 */ 308 if (!acpi_properties_format_valid(properties)) 309 break; 310 311 data->properties = properties; 312 return true; 313 } 314 315 return false; 316 } 317 318 void acpi_init_properties(struct acpi_device *adev) 319 { 320 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; 321 struct acpi_hardware_id *hwid; 322 acpi_status status; 323 bool acpi_of = false; 324 325 INIT_LIST_HEAD(&adev->data.subnodes); 326 327 /* 328 * Check if ACPI_DT_NAMESPACE_HID is present and inthat case we fill in 329 * Device Tree compatible properties for this device. 330 */ 331 list_for_each_entry(hwid, &adev->pnp.ids, list) { 332 if (!strcmp(hwid->id, ACPI_DT_NAMESPACE_HID)) { 333 acpi_of = true; 334 break; 335 } 336 } 337 338 status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, &buf, 339 ACPI_TYPE_PACKAGE); 340 if (ACPI_FAILURE(status)) 341 goto out; 342 343 if (acpi_extract_properties(buf.pointer, &adev->data)) { 344 adev->data.pointer = buf.pointer; 345 if (acpi_of) 346 acpi_init_of_compatible(adev); 347 } 348 if (acpi_enumerate_nondev_subnodes(adev->handle, buf.pointer, &adev->data)) 349 adev->data.pointer = buf.pointer; 350 351 if (!adev->data.pointer) { 352 acpi_handle_debug(adev->handle, "Invalid _DSD data, skipping\n"); 353 ACPI_FREE(buf.pointer); 354 } 355 356 out: 357 if (acpi_of && !adev->flags.of_compatible_ok) 358 acpi_handle_info(adev->handle, 359 ACPI_DT_NAMESPACE_HID " requires 'compatible' property\n"); 360 } 361 362 static void acpi_destroy_nondev_subnodes(struct list_head *list) 363 { 364 struct acpi_data_node *dn, *next; 365 366 if (list_empty(list)) 367 return; 368 369 list_for_each_entry_safe_reverse(dn, next, list, sibling) { 370 acpi_destroy_nondev_subnodes(&dn->data.subnodes); 371 wait_for_completion(&dn->kobj_done); 372 list_del(&dn->sibling); 373 ACPI_FREE((void *)dn->data.pointer); 374 kfree(dn); 375 } 376 } 377 378 void acpi_free_properties(struct acpi_device *adev) 379 { 380 acpi_destroy_nondev_subnodes(&adev->data.subnodes); 381 ACPI_FREE((void *)adev->data.pointer); 382 adev->data.of_compatible = NULL; 383 adev->data.pointer = NULL; 384 adev->data.properties = NULL; 385 } 386 387 /** 388 * acpi_data_get_property - return an ACPI property with given name 389 * @data: ACPI device deta object to get the property from 390 * @name: Name of the property 391 * @type: Expected property type 392 * @obj: Location to store the property value (if not %NULL) 393 * 394 * Look up a property with @name and store a pointer to the resulting ACPI 395 * object at the location pointed to by @obj if found. 396 * 397 * Callers must not attempt to free the returned objects. These objects will be 398 * freed by the ACPI core automatically during the removal of @data. 399 * 400 * Return: %0 if property with @name has been found (success), 401 * %-EINVAL if the arguments are invalid, 402 * %-EINVAL if the property doesn't exist, 403 * %-EPROTO if the property value type doesn't match @type. 404 */ 405 static int acpi_data_get_property(struct acpi_device_data *data, 406 const char *name, acpi_object_type type, 407 const union acpi_object **obj) 408 { 409 const union acpi_object *properties; 410 int i; 411 412 if (!data || !name) 413 return -EINVAL; 414 415 if (!data->pointer || !data->properties) 416 return -EINVAL; 417 418 properties = data->properties; 419 for (i = 0; i < properties->package.count; i++) { 420 const union acpi_object *propname, *propvalue; 421 const union acpi_object *property; 422 423 property = &properties->package.elements[i]; 424 425 propname = &property->package.elements[0]; 426 propvalue = &property->package.elements[1]; 427 428 if (!strcmp(name, propname->string.pointer)) { 429 if (type != ACPI_TYPE_ANY && propvalue->type != type) 430 return -EPROTO; 431 if (obj) 432 *obj = propvalue; 433 434 return 0; 435 } 436 } 437 return -EINVAL; 438 } 439 440 /** 441 * acpi_dev_get_property - return an ACPI property with given name. 442 * @adev: ACPI device to get the property from. 443 * @name: Name of the property. 444 * @type: Expected property type. 445 * @obj: Location to store the property value (if not %NULL). 446 */ 447 int acpi_dev_get_property(struct acpi_device *adev, const char *name, 448 acpi_object_type type, const union acpi_object **obj) 449 { 450 return adev ? acpi_data_get_property(&adev->data, name, type, obj) : -EINVAL; 451 } 452 EXPORT_SYMBOL_GPL(acpi_dev_get_property); 453 454 static struct acpi_device_data *acpi_device_data_of_node(struct fwnode_handle *fwnode) 455 { 456 if (fwnode->type == FWNODE_ACPI) { 457 struct acpi_device *adev = to_acpi_device_node(fwnode); 458 return &adev->data; 459 } else if (fwnode->type == FWNODE_ACPI_DATA) { 460 struct acpi_data_node *dn = to_acpi_data_node(fwnode); 461 return &dn->data; 462 } 463 return NULL; 464 } 465 466 /** 467 * acpi_node_prop_get - return an ACPI property with given name. 468 * @fwnode: Firmware node to get the property from. 469 * @propname: Name of the property. 470 * @valptr: Location to store a pointer to the property value (if not %NULL). 471 */ 472 int acpi_node_prop_get(struct fwnode_handle *fwnode, const char *propname, 473 void **valptr) 474 { 475 return acpi_data_get_property(acpi_device_data_of_node(fwnode), 476 propname, ACPI_TYPE_ANY, 477 (const union acpi_object **)valptr); 478 } 479 480 /** 481 * acpi_data_get_property_array - return an ACPI array property with given name 482 * @adev: ACPI data object to get the property from 483 * @name: Name of the property 484 * @type: Expected type of array elements 485 * @obj: Location to store a pointer to the property value (if not NULL) 486 * 487 * Look up an array property with @name and store a pointer to the resulting 488 * ACPI object at the location pointed to by @obj if found. 489 * 490 * Callers must not attempt to free the returned objects. Those objects will be 491 * freed by the ACPI core automatically during the removal of @data. 492 * 493 * Return: %0 if array property (package) with @name has been found (success), 494 * %-EINVAL if the arguments are invalid, 495 * %-EINVAL if the property doesn't exist, 496 * %-EPROTO if the property is not a package or the type of its elements 497 * doesn't match @type. 498 */ 499 static int acpi_data_get_property_array(struct acpi_device_data *data, 500 const char *name, 501 acpi_object_type type, 502 const union acpi_object **obj) 503 { 504 const union acpi_object *prop; 505 int ret, i; 506 507 ret = acpi_data_get_property(data, name, ACPI_TYPE_PACKAGE, &prop); 508 if (ret) 509 return ret; 510 511 if (type != ACPI_TYPE_ANY) { 512 /* Check that all elements are of correct type. */ 513 for (i = 0; i < prop->package.count; i++) 514 if (prop->package.elements[i].type != type) 515 return -EPROTO; 516 } 517 if (obj) 518 *obj = prop; 519 520 return 0; 521 } 522 523 /** 524 * __acpi_node_get_property_reference - returns handle to the referenced object 525 * @fwnode: Firmware node to get the property from 526 * @propname: Name of the property 527 * @index: Index of the reference to return 528 * @num_args: Maximum number of arguments after each reference 529 * @args: Location to store the returned reference with optional arguments 530 * 531 * Find property with @name, verifify that it is a package containing at least 532 * one object reference and if so, store the ACPI device object pointer to the 533 * target object in @args->adev. If the reference includes arguments, store 534 * them in the @args->args[] array. 535 * 536 * If there's more than one reference in the property value package, @index is 537 * used to select the one to return. 538 * 539 * It is possible to leave holes in the property value set like in the 540 * example below: 541 * 542 * Package () { 543 * "cs-gpios", 544 * Package () { 545 * ^GPIO, 19, 0, 0, 546 * ^GPIO, 20, 0, 0, 547 * 0, 548 * ^GPIO, 21, 0, 0, 549 * } 550 * } 551 * 552 * Calling this function with index %2 return %-ENOENT and with index %3 553 * returns the last entry. If the property does not contain any more values 554 * %-ENODATA is returned. The NULL entry must be single integer and 555 * preferably contain value %0. 556 * 557 * Return: %0 on success, negative error code on failure. 558 */ 559 int __acpi_node_get_property_reference(struct fwnode_handle *fwnode, 560 const char *propname, size_t index, size_t num_args, 561 struct acpi_reference_args *args) 562 { 563 const union acpi_object *element, *end; 564 const union acpi_object *obj; 565 struct acpi_device_data *data; 566 struct acpi_device *device; 567 int ret, idx = 0; 568 569 data = acpi_device_data_of_node(fwnode); 570 if (!data) 571 return -EINVAL; 572 573 ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj); 574 if (ret) 575 return ret; 576 577 /* 578 * The simplest case is when the value is a single reference. Just 579 * return that reference then. 580 */ 581 if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) { 582 if (index) 583 return -EINVAL; 584 585 ret = acpi_bus_get_device(obj->reference.handle, &device); 586 if (ret) 587 return ret; 588 589 args->adev = device; 590 args->nargs = 0; 591 return 0; 592 } 593 594 /* 595 * If it is not a single reference, then it is a package of 596 * references followed by number of ints as follows: 597 * 598 * Package () { REF, INT, REF, INT, INT } 599 * 600 * The index argument is then used to determine which reference 601 * the caller wants (along with the arguments). 602 */ 603 if (obj->type != ACPI_TYPE_PACKAGE || index >= obj->package.count) 604 return -EPROTO; 605 606 element = obj->package.elements; 607 end = element + obj->package.count; 608 609 while (element < end) { 610 u32 nargs, i; 611 612 if (element->type == ACPI_TYPE_LOCAL_REFERENCE) { 613 ret = acpi_bus_get_device(element->reference.handle, 614 &device); 615 if (ret) 616 return -ENODEV; 617 618 nargs = 0; 619 element++; 620 621 /* assume following integer elements are all args */ 622 for (i = 0; element + i < end && i < num_args; i++) { 623 int type = element[i].type; 624 625 if (type == ACPI_TYPE_INTEGER) 626 nargs++; 627 else if (type == ACPI_TYPE_LOCAL_REFERENCE) 628 break; 629 else 630 return -EPROTO; 631 } 632 633 if (nargs > MAX_ACPI_REFERENCE_ARGS) 634 return -EPROTO; 635 636 if (idx == index) { 637 args->adev = device; 638 args->nargs = nargs; 639 for (i = 0; i < nargs; i++) 640 args->args[i] = element[i].integer.value; 641 642 return 0; 643 } 644 645 element += nargs; 646 } else if (element->type == ACPI_TYPE_INTEGER) { 647 if (idx == index) 648 return -ENOENT; 649 element++; 650 } else { 651 return -EPROTO; 652 } 653 654 idx++; 655 } 656 657 return -ENODATA; 658 } 659 EXPORT_SYMBOL_GPL(__acpi_node_get_property_reference); 660 661 static int acpi_data_prop_read_single(struct acpi_device_data *data, 662 const char *propname, 663 enum dev_prop_type proptype, void *val) 664 { 665 const union acpi_object *obj; 666 int ret; 667 668 if (!val) 669 return -EINVAL; 670 671 if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) { 672 ret = acpi_data_get_property(data, propname, ACPI_TYPE_INTEGER, &obj); 673 if (ret) 674 return ret; 675 676 switch (proptype) { 677 case DEV_PROP_U8: 678 if (obj->integer.value > U8_MAX) 679 return -EOVERFLOW; 680 *(u8 *)val = obj->integer.value; 681 break; 682 case DEV_PROP_U16: 683 if (obj->integer.value > U16_MAX) 684 return -EOVERFLOW; 685 *(u16 *)val = obj->integer.value; 686 break; 687 case DEV_PROP_U32: 688 if (obj->integer.value > U32_MAX) 689 return -EOVERFLOW; 690 *(u32 *)val = obj->integer.value; 691 break; 692 default: 693 *(u64 *)val = obj->integer.value; 694 break; 695 } 696 } else if (proptype == DEV_PROP_STRING) { 697 ret = acpi_data_get_property(data, propname, ACPI_TYPE_STRING, &obj); 698 if (ret) 699 return ret; 700 701 *(char **)val = obj->string.pointer; 702 } else { 703 ret = -EINVAL; 704 } 705 return ret; 706 } 707 708 int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname, 709 enum dev_prop_type proptype, void *val) 710 { 711 return adev ? acpi_data_prop_read_single(&adev->data, propname, proptype, val) : -EINVAL; 712 } 713 714 static int acpi_copy_property_array_u8(const union acpi_object *items, u8 *val, 715 size_t nval) 716 { 717 int i; 718 719 for (i = 0; i < nval; i++) { 720 if (items[i].type != ACPI_TYPE_INTEGER) 721 return -EPROTO; 722 if (items[i].integer.value > U8_MAX) 723 return -EOVERFLOW; 724 725 val[i] = items[i].integer.value; 726 } 727 return 0; 728 } 729 730 static int acpi_copy_property_array_u16(const union acpi_object *items, 731 u16 *val, size_t nval) 732 { 733 int i; 734 735 for (i = 0; i < nval; i++) { 736 if (items[i].type != ACPI_TYPE_INTEGER) 737 return -EPROTO; 738 if (items[i].integer.value > U16_MAX) 739 return -EOVERFLOW; 740 741 val[i] = items[i].integer.value; 742 } 743 return 0; 744 } 745 746 static int acpi_copy_property_array_u32(const union acpi_object *items, 747 u32 *val, size_t nval) 748 { 749 int i; 750 751 for (i = 0; i < nval; i++) { 752 if (items[i].type != ACPI_TYPE_INTEGER) 753 return -EPROTO; 754 if (items[i].integer.value > U32_MAX) 755 return -EOVERFLOW; 756 757 val[i] = items[i].integer.value; 758 } 759 return 0; 760 } 761 762 static int acpi_copy_property_array_u64(const union acpi_object *items, 763 u64 *val, size_t nval) 764 { 765 int i; 766 767 for (i = 0; i < nval; i++) { 768 if (items[i].type != ACPI_TYPE_INTEGER) 769 return -EPROTO; 770 771 val[i] = items[i].integer.value; 772 } 773 return 0; 774 } 775 776 static int acpi_copy_property_array_string(const union acpi_object *items, 777 char **val, size_t nval) 778 { 779 int i; 780 781 for (i = 0; i < nval; i++) { 782 if (items[i].type != ACPI_TYPE_STRING) 783 return -EPROTO; 784 785 val[i] = items[i].string.pointer; 786 } 787 return 0; 788 } 789 790 static int acpi_data_prop_read(struct acpi_device_data *data, 791 const char *propname, 792 enum dev_prop_type proptype, 793 void *val, size_t nval) 794 { 795 const union acpi_object *obj; 796 const union acpi_object *items; 797 int ret; 798 799 if (val && nval == 1) { 800 ret = acpi_data_prop_read_single(data, propname, proptype, val); 801 if (!ret) 802 return ret; 803 } 804 805 ret = acpi_data_get_property_array(data, propname, ACPI_TYPE_ANY, &obj); 806 if (ret) 807 return ret; 808 809 if (!val) 810 return obj->package.count; 811 812 if (nval > obj->package.count) 813 return -EOVERFLOW; 814 else if (nval <= 0) 815 return -EINVAL; 816 817 items = obj->package.elements; 818 819 switch (proptype) { 820 case DEV_PROP_U8: 821 ret = acpi_copy_property_array_u8(items, (u8 *)val, nval); 822 break; 823 case DEV_PROP_U16: 824 ret = acpi_copy_property_array_u16(items, (u16 *)val, nval); 825 break; 826 case DEV_PROP_U32: 827 ret = acpi_copy_property_array_u32(items, (u32 *)val, nval); 828 break; 829 case DEV_PROP_U64: 830 ret = acpi_copy_property_array_u64(items, (u64 *)val, nval); 831 break; 832 case DEV_PROP_STRING: 833 ret = acpi_copy_property_array_string(items, (char **)val, nval); 834 break; 835 default: 836 ret = -EINVAL; 837 break; 838 } 839 return ret; 840 } 841 842 int acpi_dev_prop_read(struct acpi_device *adev, const char *propname, 843 enum dev_prop_type proptype, void *val, size_t nval) 844 { 845 return adev ? acpi_data_prop_read(&adev->data, propname, proptype, val, nval) : -EINVAL; 846 } 847 848 /** 849 * acpi_node_prop_read - retrieve the value of an ACPI property with given name. 850 * @fwnode: Firmware node to get the property from. 851 * @propname: Name of the property. 852 * @proptype: Expected property type. 853 * @val: Location to store the property value (if not %NULL). 854 * @nval: Size of the array pointed to by @val. 855 * 856 * If @val is %NULL, return the number of array elements comprising the value 857 * of the property. Otherwise, read at most @nval values to the array at the 858 * location pointed to by @val. 859 */ 860 int acpi_node_prop_read(struct fwnode_handle *fwnode, const char *propname, 861 enum dev_prop_type proptype, void *val, size_t nval) 862 { 863 return acpi_data_prop_read(acpi_device_data_of_node(fwnode), 864 propname, proptype, val, nval); 865 } 866 867 /** 868 * acpi_get_next_subnode - Return the next child node handle for a device. 869 * @dev: Device to find the next child node for. 870 * @child: Handle to one of the device's child nodes or a null handle. 871 */ 872 struct fwnode_handle *acpi_get_next_subnode(struct device *dev, 873 struct fwnode_handle *child) 874 { 875 struct acpi_device *adev = ACPI_COMPANION(dev); 876 struct list_head *head, *next; 877 878 if (!adev) 879 return NULL; 880 881 if (!child || child->type == FWNODE_ACPI) { 882 head = &adev->children; 883 if (list_empty(head)) 884 goto nondev; 885 886 if (child) { 887 adev = to_acpi_device_node(child); 888 next = adev->node.next; 889 if (next == head) { 890 child = NULL; 891 adev = ACPI_COMPANION(dev); 892 goto nondev; 893 } 894 adev = list_entry(next, struct acpi_device, node); 895 } else { 896 adev = list_first_entry(head, struct acpi_device, node); 897 } 898 return acpi_fwnode_handle(adev); 899 } 900 901 nondev: 902 if (!child || child->type == FWNODE_ACPI_DATA) { 903 struct acpi_data_node *dn; 904 905 head = &adev->data.subnodes; 906 if (list_empty(head)) 907 return NULL; 908 909 if (child) { 910 dn = to_acpi_data_node(child); 911 next = dn->sibling.next; 912 if (next == head) 913 return NULL; 914 915 dn = list_entry(next, struct acpi_data_node, sibling); 916 } else { 917 dn = list_first_entry(head, struct acpi_data_node, sibling); 918 } 919 return &dn->fwnode; 920 } 921 return NULL; 922 } 923