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_data_get_property_reference - returns handle to the referenced object 472 * @data: ACPI device data object containing the property 473 * @propname: Name of the property 474 * @index: Index of the reference to return 475 * @args: Location to store the returned reference with optional arguments 476 * 477 * Find property with @name, verifify that it is a package containing at least 478 * one object reference and if so, store the ACPI device object pointer to the 479 * target object in @args->adev. If the reference includes arguments, store 480 * them in the @args->args[] array. 481 * 482 * If there's more than one reference in the property value package, @index is 483 * used to select the one to return. 484 * 485 * Return: %0 on success, negative error code on failure. 486 */ 487 static int acpi_data_get_property_reference(struct acpi_device_data *data, 488 const char *propname, size_t index, 489 struct acpi_reference_args *args) 490 { 491 const union acpi_object *element, *end; 492 const union acpi_object *obj; 493 struct acpi_device *device; 494 int ret, idx = 0; 495 496 ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj); 497 if (ret) 498 return ret; 499 500 /* 501 * The simplest case is when the value is a single reference. Just 502 * return that reference then. 503 */ 504 if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) { 505 if (index) 506 return -EINVAL; 507 508 ret = acpi_bus_get_device(obj->reference.handle, &device); 509 if (ret) 510 return ret; 511 512 args->adev = device; 513 args->nargs = 0; 514 return 0; 515 } 516 517 /* 518 * If it is not a single reference, then it is a package of 519 * references followed by number of ints as follows: 520 * 521 * Package () { REF, INT, REF, INT, INT } 522 * 523 * The index argument is then used to determine which reference 524 * the caller wants (along with the arguments). 525 */ 526 if (obj->type != ACPI_TYPE_PACKAGE || index >= obj->package.count) 527 return -EPROTO; 528 529 element = obj->package.elements; 530 end = element + obj->package.count; 531 532 while (element < end) { 533 u32 nargs, i; 534 535 if (element->type != ACPI_TYPE_LOCAL_REFERENCE) 536 return -EPROTO; 537 538 ret = acpi_bus_get_device(element->reference.handle, &device); 539 if (ret) 540 return -ENODEV; 541 542 element++; 543 nargs = 0; 544 545 /* assume following integer elements are all args */ 546 for (i = 0; element + i < end; i++) { 547 int type = element[i].type; 548 549 if (type == ACPI_TYPE_INTEGER) 550 nargs++; 551 else if (type == ACPI_TYPE_LOCAL_REFERENCE) 552 break; 553 else 554 return -EPROTO; 555 } 556 557 if (idx++ == index) { 558 args->adev = device; 559 args->nargs = nargs; 560 for (i = 0; i < nargs; i++) 561 args->args[i] = element[i].integer.value; 562 563 return 0; 564 } 565 566 element += nargs; 567 } 568 569 return -EPROTO; 570 } 571 572 /** 573 * acpi_node_get_property_reference - get a handle to the referenced object. 574 * @fwnode: Firmware node to get the property from. 575 * @propname: Name of the property. 576 * @index: Index of the reference to return. 577 * @args: Location to store the returned reference with optional arguments. 578 */ 579 int acpi_node_get_property_reference(struct fwnode_handle *fwnode, 580 const char *name, size_t index, 581 struct acpi_reference_args *args) 582 { 583 struct acpi_device_data *data = acpi_device_data_of_node(fwnode); 584 585 return data ? acpi_data_get_property_reference(data, name, index, args) : -EINVAL; 586 } 587 EXPORT_SYMBOL_GPL(acpi_node_get_property_reference); 588 589 static int acpi_data_prop_read_single(struct acpi_device_data *data, 590 const char *propname, 591 enum dev_prop_type proptype, void *val) 592 { 593 const union acpi_object *obj; 594 int ret; 595 596 if (!val) 597 return -EINVAL; 598 599 if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) { 600 ret = acpi_data_get_property(data, propname, ACPI_TYPE_INTEGER, &obj); 601 if (ret) 602 return ret; 603 604 switch (proptype) { 605 case DEV_PROP_U8: 606 if (obj->integer.value > U8_MAX) 607 return -EOVERFLOW; 608 *(u8 *)val = obj->integer.value; 609 break; 610 case DEV_PROP_U16: 611 if (obj->integer.value > U16_MAX) 612 return -EOVERFLOW; 613 *(u16 *)val = obj->integer.value; 614 break; 615 case DEV_PROP_U32: 616 if (obj->integer.value > U32_MAX) 617 return -EOVERFLOW; 618 *(u32 *)val = obj->integer.value; 619 break; 620 default: 621 *(u64 *)val = obj->integer.value; 622 break; 623 } 624 } else if (proptype == DEV_PROP_STRING) { 625 ret = acpi_data_get_property(data, propname, ACPI_TYPE_STRING, &obj); 626 if (ret) 627 return ret; 628 629 *(char **)val = obj->string.pointer; 630 } else { 631 ret = -EINVAL; 632 } 633 return ret; 634 } 635 636 int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname, 637 enum dev_prop_type proptype, void *val) 638 { 639 return adev ? acpi_data_prop_read_single(&adev->data, propname, proptype, val) : -EINVAL; 640 } 641 642 static int acpi_copy_property_array_u8(const union acpi_object *items, u8 *val, 643 size_t nval) 644 { 645 int i; 646 647 for (i = 0; i < nval; i++) { 648 if (items[i].type != ACPI_TYPE_INTEGER) 649 return -EPROTO; 650 if (items[i].integer.value > U8_MAX) 651 return -EOVERFLOW; 652 653 val[i] = items[i].integer.value; 654 } 655 return 0; 656 } 657 658 static int acpi_copy_property_array_u16(const union acpi_object *items, 659 u16 *val, size_t nval) 660 { 661 int i; 662 663 for (i = 0; i < nval; i++) { 664 if (items[i].type != ACPI_TYPE_INTEGER) 665 return -EPROTO; 666 if (items[i].integer.value > U16_MAX) 667 return -EOVERFLOW; 668 669 val[i] = items[i].integer.value; 670 } 671 return 0; 672 } 673 674 static int acpi_copy_property_array_u32(const union acpi_object *items, 675 u32 *val, size_t nval) 676 { 677 int i; 678 679 for (i = 0; i < nval; i++) { 680 if (items[i].type != ACPI_TYPE_INTEGER) 681 return -EPROTO; 682 if (items[i].integer.value > U32_MAX) 683 return -EOVERFLOW; 684 685 val[i] = items[i].integer.value; 686 } 687 return 0; 688 } 689 690 static int acpi_copy_property_array_u64(const union acpi_object *items, 691 u64 *val, size_t nval) 692 { 693 int i; 694 695 for (i = 0; i < nval; i++) { 696 if (items[i].type != ACPI_TYPE_INTEGER) 697 return -EPROTO; 698 699 val[i] = items[i].integer.value; 700 } 701 return 0; 702 } 703 704 static int acpi_copy_property_array_string(const union acpi_object *items, 705 char **val, size_t nval) 706 { 707 int i; 708 709 for (i = 0; i < nval; i++) { 710 if (items[i].type != ACPI_TYPE_STRING) 711 return -EPROTO; 712 713 val[i] = items[i].string.pointer; 714 } 715 return 0; 716 } 717 718 static int acpi_data_prop_read(struct acpi_device_data *data, 719 const char *propname, 720 enum dev_prop_type proptype, 721 void *val, size_t nval) 722 { 723 const union acpi_object *obj; 724 const union acpi_object *items; 725 int ret; 726 727 if (val && nval == 1) { 728 ret = acpi_data_prop_read_single(data, propname, proptype, val); 729 if (!ret) 730 return ret; 731 } 732 733 ret = acpi_data_get_property_array(data, propname, ACPI_TYPE_ANY, &obj); 734 if (ret) 735 return ret; 736 737 if (!val) 738 return obj->package.count; 739 740 if (nval > obj->package.count) 741 return -EOVERFLOW; 742 else if (nval <= 0) 743 return -EINVAL; 744 745 items = obj->package.elements; 746 747 switch (proptype) { 748 case DEV_PROP_U8: 749 ret = acpi_copy_property_array_u8(items, (u8 *)val, nval); 750 break; 751 case DEV_PROP_U16: 752 ret = acpi_copy_property_array_u16(items, (u16 *)val, nval); 753 break; 754 case DEV_PROP_U32: 755 ret = acpi_copy_property_array_u32(items, (u32 *)val, nval); 756 break; 757 case DEV_PROP_U64: 758 ret = acpi_copy_property_array_u64(items, (u64 *)val, nval); 759 break; 760 case DEV_PROP_STRING: 761 ret = acpi_copy_property_array_string(items, (char **)val, nval); 762 break; 763 default: 764 ret = -EINVAL; 765 break; 766 } 767 return ret; 768 } 769 770 int acpi_dev_prop_read(struct acpi_device *adev, const char *propname, 771 enum dev_prop_type proptype, void *val, size_t nval) 772 { 773 return adev ? acpi_data_prop_read(&adev->data, propname, proptype, val, nval) : -EINVAL; 774 } 775 776 /** 777 * acpi_node_prop_read - retrieve the value of an ACPI property with given name. 778 * @fwnode: Firmware node to get the property from. 779 * @propname: Name of the property. 780 * @proptype: Expected property type. 781 * @val: Location to store the property value (if not %NULL). 782 * @nval: Size of the array pointed to by @val. 783 * 784 * If @val is %NULL, return the number of array elements comprising the value 785 * of the property. Otherwise, read at most @nval values to the array at the 786 * location pointed to by @val. 787 */ 788 int acpi_node_prop_read(struct fwnode_handle *fwnode, const char *propname, 789 enum dev_prop_type proptype, void *val, size_t nval) 790 { 791 return acpi_data_prop_read(acpi_device_data_of_node(fwnode), 792 propname, proptype, val, nval); 793 } 794 795 /** 796 * acpi_get_next_subnode - Return the next child node handle for a device. 797 * @dev: Device to find the next child node for. 798 * @child: Handle to one of the device's child nodes or a null handle. 799 */ 800 struct fwnode_handle *acpi_get_next_subnode(struct device *dev, 801 struct fwnode_handle *child) 802 { 803 struct acpi_device *adev = ACPI_COMPANION(dev); 804 struct list_head *head, *next; 805 806 if (!adev) 807 return NULL; 808 809 if (!child || child->type == FWNODE_ACPI) { 810 head = &adev->children; 811 if (list_empty(head)) 812 goto nondev; 813 814 if (child) { 815 adev = to_acpi_device_node(child); 816 next = adev->node.next; 817 if (next == head) { 818 child = NULL; 819 adev = ACPI_COMPANION(dev); 820 goto nondev; 821 } 822 adev = list_entry(next, struct acpi_device, node); 823 } else { 824 adev = list_first_entry(head, struct acpi_device, node); 825 } 826 return acpi_fwnode_handle(adev); 827 } 828 829 nondev: 830 if (!child || child->type == FWNODE_ACPI_DATA) { 831 struct acpi_data_node *dn; 832 833 head = &adev->data.subnodes; 834 if (list_empty(head)) 835 return NULL; 836 837 if (child) { 838 dn = to_acpi_data_node(child); 839 next = dn->sibling.next; 840 if (next == head) 841 return NULL; 842 843 dn = list_entry(next, struct acpi_data_node, sibling); 844 } else { 845 dn = list_first_entry(head, struct acpi_data_node, sibling); 846 } 847 return &dn->fwnode; 848 } 849 return NULL; 850 } 851