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