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(const 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 GUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */ 28 static const guid_t prp_guid = 29 GUID_INIT(0xdaffd814, 0x6eba, 0x4d8c, 30 0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01); 31 /* ACPI _DSD data subnodes GUID: dbb8e3e6-5886-4ba6-8795-1319f52a966b */ 32 static const guid_t ads_guid = 33 GUID_INIT(0xdbb8e3e6, 0x5886, 0x4ba6, 34 0x87, 0x95, 0x13, 0x19, 0xf5, 0x2a, 0x96, 0x6b); 35 36 static bool acpi_enumerate_nondev_subnodes(acpi_handle scope, 37 const union acpi_object *desc, 38 struct acpi_device_data *data, 39 struct fwnode_handle *parent); 40 static bool acpi_extract_properties(const union acpi_object *desc, 41 struct acpi_device_data *data); 42 43 static bool acpi_nondev_subnode_extract(const union acpi_object *desc, 44 acpi_handle handle, 45 const union acpi_object *link, 46 struct list_head *list, 47 struct fwnode_handle *parent) 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.ops = &acpi_data_fwnode_ops; 58 dn->parent = parent; 59 INIT_LIST_HEAD(&dn->data.subnodes); 60 61 result = acpi_extract_properties(desc, &dn->data); 62 63 if (handle) { 64 acpi_handle scope; 65 acpi_status status; 66 67 /* 68 * The scope for the subnode object lookup is the one of the 69 * namespace node (device) containing the object that has 70 * returned the package. That is, it's the scope of that 71 * object's parent. 72 */ 73 status = acpi_get_parent(handle, &scope); 74 if (ACPI_SUCCESS(status) 75 && acpi_enumerate_nondev_subnodes(scope, desc, &dn->data, 76 &dn->fwnode)) 77 result = true; 78 } else if (acpi_enumerate_nondev_subnodes(NULL, desc, &dn->data, 79 &dn->fwnode)) { 80 result = true; 81 } 82 83 if (result) { 84 dn->handle = handle; 85 dn->data.pointer = desc; 86 list_add_tail(&dn->sibling, list); 87 return true; 88 } 89 90 kfree(dn); 91 acpi_handle_debug(handle, "Invalid properties/subnodes data, skipping\n"); 92 return false; 93 } 94 95 static bool acpi_nondev_subnode_data_ok(acpi_handle handle, 96 const union acpi_object *link, 97 struct list_head *list, 98 struct fwnode_handle *parent) 99 { 100 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; 101 acpi_status status; 102 103 status = acpi_evaluate_object_typed(handle, NULL, NULL, &buf, 104 ACPI_TYPE_PACKAGE); 105 if (ACPI_FAILURE(status)) 106 return false; 107 108 if (acpi_nondev_subnode_extract(buf.pointer, handle, link, list, 109 parent)) 110 return true; 111 112 ACPI_FREE(buf.pointer); 113 return false; 114 } 115 116 static bool acpi_nondev_subnode_ok(acpi_handle scope, 117 const union acpi_object *link, 118 struct list_head *list, 119 struct fwnode_handle *parent) 120 { 121 acpi_handle handle; 122 acpi_status status; 123 124 if (!scope) 125 return false; 126 127 status = acpi_get_handle(scope, link->package.elements[1].string.pointer, 128 &handle); 129 if (ACPI_FAILURE(status)) 130 return false; 131 132 return acpi_nondev_subnode_data_ok(handle, link, list, parent); 133 } 134 135 static int acpi_add_nondev_subnodes(acpi_handle scope, 136 const union acpi_object *links, 137 struct list_head *list, 138 struct fwnode_handle *parent) 139 { 140 bool ret = false; 141 int i; 142 143 for (i = 0; i < links->package.count; i++) { 144 const union acpi_object *link, *desc; 145 acpi_handle handle; 146 bool result; 147 148 link = &links->package.elements[i]; 149 /* Only two elements allowed. */ 150 if (link->package.count != 2) 151 continue; 152 153 /* The first one must be a string. */ 154 if (link->package.elements[0].type != ACPI_TYPE_STRING) 155 continue; 156 157 /* The second one may be a string, a reference or a package. */ 158 switch (link->package.elements[1].type) { 159 case ACPI_TYPE_STRING: 160 result = acpi_nondev_subnode_ok(scope, link, list, 161 parent); 162 break; 163 case ACPI_TYPE_LOCAL_REFERENCE: 164 handle = link->package.elements[1].reference.handle; 165 result = acpi_nondev_subnode_data_ok(handle, link, list, 166 parent); 167 break; 168 case ACPI_TYPE_PACKAGE: 169 desc = &link->package.elements[1]; 170 result = acpi_nondev_subnode_extract(desc, NULL, link, 171 list, parent); 172 break; 173 default: 174 result = false; 175 break; 176 } 177 ret = ret || result; 178 } 179 180 return ret; 181 } 182 183 static bool acpi_enumerate_nondev_subnodes(acpi_handle scope, 184 const union acpi_object *desc, 185 struct acpi_device_data *data, 186 struct fwnode_handle *parent) 187 { 188 int i; 189 190 /* Look for the ACPI data subnodes GUID. */ 191 for (i = 0; i < desc->package.count; i += 2) { 192 const union acpi_object *guid, *links; 193 194 guid = &desc->package.elements[i]; 195 links = &desc->package.elements[i + 1]; 196 197 /* 198 * The first element must be a GUID and the second one must be 199 * a package. 200 */ 201 if (guid->type != ACPI_TYPE_BUFFER || 202 guid->buffer.length != 16 || 203 links->type != ACPI_TYPE_PACKAGE) 204 break; 205 206 if (!guid_equal((guid_t *)guid->buffer.pointer, &ads_guid)) 207 continue; 208 209 return acpi_add_nondev_subnodes(scope, links, &data->subnodes, 210 parent); 211 } 212 213 return false; 214 } 215 216 static bool acpi_property_value_ok(const union acpi_object *value) 217 { 218 int j; 219 220 /* 221 * The value must be an integer, a string, a reference, or a package 222 * whose every element must be an integer, a string, or a reference. 223 */ 224 switch (value->type) { 225 case ACPI_TYPE_INTEGER: 226 case ACPI_TYPE_STRING: 227 case ACPI_TYPE_LOCAL_REFERENCE: 228 return true; 229 230 case ACPI_TYPE_PACKAGE: 231 for (j = 0; j < value->package.count; j++) 232 switch (value->package.elements[j].type) { 233 case ACPI_TYPE_INTEGER: 234 case ACPI_TYPE_STRING: 235 case ACPI_TYPE_LOCAL_REFERENCE: 236 continue; 237 238 default: 239 return false; 240 } 241 242 return true; 243 } 244 return false; 245 } 246 247 static bool acpi_properties_format_valid(const union acpi_object *properties) 248 { 249 int i; 250 251 for (i = 0; i < properties->package.count; i++) { 252 const union acpi_object *property; 253 254 property = &properties->package.elements[i]; 255 /* 256 * Only two elements allowed, the first one must be a string and 257 * the second one has to satisfy certain conditions. 258 */ 259 if (property->package.count != 2 260 || property->package.elements[0].type != ACPI_TYPE_STRING 261 || !acpi_property_value_ok(&property->package.elements[1])) 262 return false; 263 } 264 return true; 265 } 266 267 static void acpi_init_of_compatible(struct acpi_device *adev) 268 { 269 const union acpi_object *of_compatible; 270 int ret; 271 272 ret = acpi_data_get_property_array(&adev->data, "compatible", 273 ACPI_TYPE_STRING, &of_compatible); 274 if (ret) { 275 ret = acpi_dev_get_property(adev, "compatible", 276 ACPI_TYPE_STRING, &of_compatible); 277 if (ret) { 278 if (adev->parent 279 && adev->parent->flags.of_compatible_ok) 280 goto out; 281 282 return; 283 } 284 } 285 adev->data.of_compatible = of_compatible; 286 287 out: 288 adev->flags.of_compatible_ok = 1; 289 } 290 291 static bool acpi_extract_properties(const union acpi_object *desc, 292 struct acpi_device_data *data) 293 { 294 int i; 295 296 if (desc->package.count % 2) 297 return false; 298 299 /* Look for the device properties GUID. */ 300 for (i = 0; i < desc->package.count; i += 2) { 301 const union acpi_object *guid, *properties; 302 303 guid = &desc->package.elements[i]; 304 properties = &desc->package.elements[i + 1]; 305 306 /* 307 * The first element must be a GUID and the second one must be 308 * a package. 309 */ 310 if (guid->type != ACPI_TYPE_BUFFER || 311 guid->buffer.length != 16 || 312 properties->type != ACPI_TYPE_PACKAGE) 313 break; 314 315 if (!guid_equal((guid_t *)guid->buffer.pointer, &prp_guid)) 316 continue; 317 318 /* 319 * We found the matching GUID. Now validate the format of the 320 * package immediately following it. 321 */ 322 if (!acpi_properties_format_valid(properties)) 323 break; 324 325 data->properties = properties; 326 return true; 327 } 328 329 return false; 330 } 331 332 void acpi_init_properties(struct acpi_device *adev) 333 { 334 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; 335 struct acpi_hardware_id *hwid; 336 acpi_status status; 337 bool acpi_of = false; 338 339 INIT_LIST_HEAD(&adev->data.subnodes); 340 341 if (!adev->handle) 342 return; 343 344 /* 345 * Check if ACPI_DT_NAMESPACE_HID is present and inthat case we fill in 346 * Device Tree compatible properties for this device. 347 */ 348 list_for_each_entry(hwid, &adev->pnp.ids, list) { 349 if (!strcmp(hwid->id, ACPI_DT_NAMESPACE_HID)) { 350 acpi_of = true; 351 break; 352 } 353 } 354 355 status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, &buf, 356 ACPI_TYPE_PACKAGE); 357 if (ACPI_FAILURE(status)) 358 goto out; 359 360 if (acpi_extract_properties(buf.pointer, &adev->data)) { 361 adev->data.pointer = buf.pointer; 362 if (acpi_of) 363 acpi_init_of_compatible(adev); 364 } 365 if (acpi_enumerate_nondev_subnodes(adev->handle, buf.pointer, 366 &adev->data, acpi_fwnode_handle(adev))) 367 adev->data.pointer = buf.pointer; 368 369 if (!adev->data.pointer) { 370 acpi_handle_debug(adev->handle, "Invalid _DSD data, skipping\n"); 371 ACPI_FREE(buf.pointer); 372 } 373 374 out: 375 if (acpi_of && !adev->flags.of_compatible_ok) 376 acpi_handle_info(adev->handle, 377 ACPI_DT_NAMESPACE_HID " requires 'compatible' property\n"); 378 379 if (!adev->data.pointer) 380 acpi_extract_apple_properties(adev); 381 } 382 383 static void acpi_destroy_nondev_subnodes(struct list_head *list) 384 { 385 struct acpi_data_node *dn, *next; 386 387 if (list_empty(list)) 388 return; 389 390 list_for_each_entry_safe_reverse(dn, next, list, sibling) { 391 acpi_destroy_nondev_subnodes(&dn->data.subnodes); 392 wait_for_completion(&dn->kobj_done); 393 list_del(&dn->sibling); 394 ACPI_FREE((void *)dn->data.pointer); 395 kfree(dn); 396 } 397 } 398 399 void acpi_free_properties(struct acpi_device *adev) 400 { 401 acpi_destroy_nondev_subnodes(&adev->data.subnodes); 402 ACPI_FREE((void *)adev->data.pointer); 403 adev->data.of_compatible = NULL; 404 adev->data.pointer = NULL; 405 adev->data.properties = NULL; 406 } 407 408 /** 409 * acpi_data_get_property - return an ACPI property with given name 410 * @data: ACPI device deta object to get the property from 411 * @name: Name of the property 412 * @type: Expected property type 413 * @obj: Location to store the property value (if not %NULL) 414 * 415 * Look up a property with @name and store a pointer to the resulting ACPI 416 * object at the location pointed to by @obj if found. 417 * 418 * Callers must not attempt to free the returned objects. These objects will be 419 * freed by the ACPI core automatically during the removal of @data. 420 * 421 * Return: %0 if property with @name has been found (success), 422 * %-EINVAL if the arguments are invalid, 423 * %-EINVAL if the property doesn't exist, 424 * %-EPROTO if the property value type doesn't match @type. 425 */ 426 static int acpi_data_get_property(const struct acpi_device_data *data, 427 const char *name, acpi_object_type type, 428 const union acpi_object **obj) 429 { 430 const union acpi_object *properties; 431 int i; 432 433 if (!data || !name) 434 return -EINVAL; 435 436 if (!data->pointer || !data->properties) 437 return -EINVAL; 438 439 properties = data->properties; 440 for (i = 0; i < properties->package.count; i++) { 441 const union acpi_object *propname, *propvalue; 442 const union acpi_object *property; 443 444 property = &properties->package.elements[i]; 445 446 propname = &property->package.elements[0]; 447 propvalue = &property->package.elements[1]; 448 449 if (!strcmp(name, propname->string.pointer)) { 450 if (type != ACPI_TYPE_ANY && propvalue->type != type) 451 return -EPROTO; 452 if (obj) 453 *obj = propvalue; 454 455 return 0; 456 } 457 } 458 return -EINVAL; 459 } 460 461 /** 462 * acpi_dev_get_property - return an ACPI property with given name. 463 * @adev: ACPI device to get the property from. 464 * @name: Name of the property. 465 * @type: Expected property type. 466 * @obj: Location to store the property value (if not %NULL). 467 */ 468 int acpi_dev_get_property(const struct acpi_device *adev, const char *name, 469 acpi_object_type type, const union acpi_object **obj) 470 { 471 return adev ? acpi_data_get_property(&adev->data, name, type, obj) : -EINVAL; 472 } 473 EXPORT_SYMBOL_GPL(acpi_dev_get_property); 474 475 static const struct acpi_device_data * 476 acpi_device_data_of_node(const struct fwnode_handle *fwnode) 477 { 478 if (is_acpi_device_node(fwnode)) { 479 const struct acpi_device *adev = to_acpi_device_node(fwnode); 480 return &adev->data; 481 } else if (is_acpi_data_node(fwnode)) { 482 const struct acpi_data_node *dn = to_acpi_data_node(fwnode); 483 return &dn->data; 484 } 485 return NULL; 486 } 487 488 /** 489 * acpi_node_prop_get - return an ACPI property with given name. 490 * @fwnode: Firmware node to get the property from. 491 * @propname: Name of the property. 492 * @valptr: Location to store a pointer to the property value (if not %NULL). 493 */ 494 int acpi_node_prop_get(const struct fwnode_handle *fwnode, 495 const char *propname, void **valptr) 496 { 497 return acpi_data_get_property(acpi_device_data_of_node(fwnode), 498 propname, ACPI_TYPE_ANY, 499 (const union acpi_object **)valptr); 500 } 501 502 /** 503 * acpi_data_get_property_array - return an ACPI array property with given name 504 * @adev: ACPI data object to get the property from 505 * @name: Name of the property 506 * @type: Expected type of array elements 507 * @obj: Location to store a pointer to the property value (if not NULL) 508 * 509 * Look up an array property with @name and store a pointer to the resulting 510 * ACPI object at the location pointed to by @obj if found. 511 * 512 * Callers must not attempt to free the returned objects. Those objects will be 513 * freed by the ACPI core automatically during the removal of @data. 514 * 515 * Return: %0 if array property (package) with @name has been found (success), 516 * %-EINVAL if the arguments are invalid, 517 * %-EINVAL if the property doesn't exist, 518 * %-EPROTO if the property is not a package or the type of its elements 519 * doesn't match @type. 520 */ 521 static int acpi_data_get_property_array(const struct acpi_device_data *data, 522 const char *name, 523 acpi_object_type type, 524 const union acpi_object **obj) 525 { 526 const union acpi_object *prop; 527 int ret, i; 528 529 ret = acpi_data_get_property(data, name, ACPI_TYPE_PACKAGE, &prop); 530 if (ret) 531 return ret; 532 533 if (type != ACPI_TYPE_ANY) { 534 /* Check that all elements are of correct type. */ 535 for (i = 0; i < prop->package.count; i++) 536 if (prop->package.elements[i].type != type) 537 return -EPROTO; 538 } 539 if (obj) 540 *obj = prop; 541 542 return 0; 543 } 544 545 /** 546 * __acpi_node_get_property_reference - returns handle to the referenced object 547 * @fwnode: Firmware node to get the property from 548 * @propname: Name of the property 549 * @index: Index of the reference to return 550 * @num_args: Maximum number of arguments after each reference 551 * @args: Location to store the returned reference with optional arguments 552 * 553 * Find property with @name, verifify that it is a package containing at least 554 * one object reference and if so, store the ACPI device object pointer to the 555 * target object in @args->adev. If the reference includes arguments, store 556 * them in the @args->args[] array. 557 * 558 * If there's more than one reference in the property value package, @index is 559 * used to select the one to return. 560 * 561 * It is possible to leave holes in the property value set like in the 562 * example below: 563 * 564 * Package () { 565 * "cs-gpios", 566 * Package () { 567 * ^GPIO, 19, 0, 0, 568 * ^GPIO, 20, 0, 0, 569 * 0, 570 * ^GPIO, 21, 0, 0, 571 * } 572 * } 573 * 574 * Calling this function with index %2 or index %3 return %-ENOENT. If the 575 * property does not contain any more values %-ENOENT is returned. The NULL 576 * entry must be single integer and preferably contain value %0. 577 * 578 * Return: %0 on success, negative error code on failure. 579 */ 580 int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, 581 const char *propname, size_t index, size_t num_args, 582 struct acpi_reference_args *args) 583 { 584 const union acpi_object *element, *end; 585 const union acpi_object *obj; 586 const struct acpi_device_data *data; 587 struct acpi_device *device; 588 int ret, idx = 0; 589 590 data = acpi_device_data_of_node(fwnode); 591 if (!data) 592 return -ENOENT; 593 594 ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj); 595 if (ret) 596 return ret == -EINVAL ? -ENOENT : -EINVAL; 597 598 /* 599 * The simplest case is when the value is a single reference. Just 600 * return that reference then. 601 */ 602 if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) { 603 if (index) 604 return -EINVAL; 605 606 ret = acpi_bus_get_device(obj->reference.handle, &device); 607 if (ret) 608 return ret == -ENODEV ? -EINVAL : ret; 609 610 args->adev = device; 611 args->nargs = 0; 612 return 0; 613 } 614 615 /* 616 * If it is not a single reference, then it is a package of 617 * references followed by number of ints as follows: 618 * 619 * Package () { REF, INT, REF, INT, INT } 620 * 621 * The index argument is then used to determine which reference 622 * the caller wants (along with the arguments). 623 */ 624 if (obj->type != ACPI_TYPE_PACKAGE) 625 return -EINVAL; 626 if (index >= obj->package.count) 627 return -ENOENT; 628 629 element = obj->package.elements; 630 end = element + obj->package.count; 631 632 while (element < end) { 633 u32 nargs, i; 634 635 if (element->type == ACPI_TYPE_LOCAL_REFERENCE) { 636 ret = acpi_bus_get_device(element->reference.handle, 637 &device); 638 if (ret) 639 return -EINVAL; 640 641 nargs = 0; 642 element++; 643 644 /* assume following integer elements are all args */ 645 for (i = 0; element + i < end && i < num_args; i++) { 646 int type = element[i].type; 647 648 if (type == ACPI_TYPE_INTEGER) 649 nargs++; 650 else if (type == ACPI_TYPE_LOCAL_REFERENCE) 651 break; 652 else 653 return -EINVAL; 654 } 655 656 if (nargs > MAX_ACPI_REFERENCE_ARGS) 657 return -EINVAL; 658 659 if (idx == index) { 660 args->adev = device; 661 args->nargs = nargs; 662 for (i = 0; i < nargs; i++) 663 args->args[i] = element[i].integer.value; 664 665 return 0; 666 } 667 668 element += nargs; 669 } else if (element->type == ACPI_TYPE_INTEGER) { 670 if (idx == index) 671 return -ENOENT; 672 element++; 673 } else { 674 return -EINVAL; 675 } 676 677 idx++; 678 } 679 680 return -ENOENT; 681 } 682 EXPORT_SYMBOL_GPL(__acpi_node_get_property_reference); 683 684 static int acpi_data_prop_read_single(const struct acpi_device_data *data, 685 const char *propname, 686 enum dev_prop_type proptype, void *val) 687 { 688 const union acpi_object *obj; 689 int ret; 690 691 if (!val) 692 return -EINVAL; 693 694 if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) { 695 ret = acpi_data_get_property(data, propname, ACPI_TYPE_INTEGER, &obj); 696 if (ret) 697 return ret; 698 699 switch (proptype) { 700 case DEV_PROP_U8: 701 if (obj->integer.value > U8_MAX) 702 return -EOVERFLOW; 703 *(u8 *)val = obj->integer.value; 704 break; 705 case DEV_PROP_U16: 706 if (obj->integer.value > U16_MAX) 707 return -EOVERFLOW; 708 *(u16 *)val = obj->integer.value; 709 break; 710 case DEV_PROP_U32: 711 if (obj->integer.value > U32_MAX) 712 return -EOVERFLOW; 713 *(u32 *)val = obj->integer.value; 714 break; 715 default: 716 *(u64 *)val = obj->integer.value; 717 break; 718 } 719 } else if (proptype == DEV_PROP_STRING) { 720 ret = acpi_data_get_property(data, propname, ACPI_TYPE_STRING, &obj); 721 if (ret) 722 return ret; 723 724 *(char **)val = obj->string.pointer; 725 726 return 1; 727 } else { 728 ret = -EINVAL; 729 } 730 return ret; 731 } 732 733 int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname, 734 enum dev_prop_type proptype, void *val) 735 { 736 int ret; 737 738 if (!adev) 739 return -EINVAL; 740 741 ret = acpi_data_prop_read_single(&adev->data, propname, proptype, val); 742 if (ret < 0 || proptype != ACPI_TYPE_STRING) 743 return ret; 744 return 0; 745 } 746 747 static int acpi_copy_property_array_u8(const union acpi_object *items, u8 *val, 748 size_t nval) 749 { 750 int i; 751 752 for (i = 0; i < nval; i++) { 753 if (items[i].type != ACPI_TYPE_INTEGER) 754 return -EPROTO; 755 if (items[i].integer.value > U8_MAX) 756 return -EOVERFLOW; 757 758 val[i] = items[i].integer.value; 759 } 760 return 0; 761 } 762 763 static int acpi_copy_property_array_u16(const union acpi_object *items, 764 u16 *val, size_t nval) 765 { 766 int i; 767 768 for (i = 0; i < nval; i++) { 769 if (items[i].type != ACPI_TYPE_INTEGER) 770 return -EPROTO; 771 if (items[i].integer.value > U16_MAX) 772 return -EOVERFLOW; 773 774 val[i] = items[i].integer.value; 775 } 776 return 0; 777 } 778 779 static int acpi_copy_property_array_u32(const union acpi_object *items, 780 u32 *val, size_t nval) 781 { 782 int i; 783 784 for (i = 0; i < nval; i++) { 785 if (items[i].type != ACPI_TYPE_INTEGER) 786 return -EPROTO; 787 if (items[i].integer.value > U32_MAX) 788 return -EOVERFLOW; 789 790 val[i] = items[i].integer.value; 791 } 792 return 0; 793 } 794 795 static int acpi_copy_property_array_u64(const union acpi_object *items, 796 u64 *val, size_t nval) 797 { 798 int i; 799 800 for (i = 0; i < nval; i++) { 801 if (items[i].type != ACPI_TYPE_INTEGER) 802 return -EPROTO; 803 804 val[i] = items[i].integer.value; 805 } 806 return 0; 807 } 808 809 static int acpi_copy_property_array_string(const union acpi_object *items, 810 char **val, size_t nval) 811 { 812 int i; 813 814 for (i = 0; i < nval; i++) { 815 if (items[i].type != ACPI_TYPE_STRING) 816 return -EPROTO; 817 818 val[i] = items[i].string.pointer; 819 } 820 return nval; 821 } 822 823 static int acpi_data_prop_read(const struct acpi_device_data *data, 824 const char *propname, 825 enum dev_prop_type proptype, 826 void *val, size_t nval) 827 { 828 const union acpi_object *obj; 829 const union acpi_object *items; 830 int ret; 831 832 if (val && nval == 1) { 833 ret = acpi_data_prop_read_single(data, propname, proptype, val); 834 if (ret >= 0) 835 return ret; 836 } 837 838 ret = acpi_data_get_property_array(data, propname, ACPI_TYPE_ANY, &obj); 839 if (ret) 840 return ret; 841 842 if (!val) 843 return obj->package.count; 844 845 if (proptype != DEV_PROP_STRING && nval > obj->package.count) 846 return -EOVERFLOW; 847 else if (nval <= 0) 848 return -EINVAL; 849 850 items = obj->package.elements; 851 852 switch (proptype) { 853 case DEV_PROP_U8: 854 ret = acpi_copy_property_array_u8(items, (u8 *)val, nval); 855 break; 856 case DEV_PROP_U16: 857 ret = acpi_copy_property_array_u16(items, (u16 *)val, nval); 858 break; 859 case DEV_PROP_U32: 860 ret = acpi_copy_property_array_u32(items, (u32 *)val, nval); 861 break; 862 case DEV_PROP_U64: 863 ret = acpi_copy_property_array_u64(items, (u64 *)val, nval); 864 break; 865 case DEV_PROP_STRING: 866 ret = acpi_copy_property_array_string( 867 items, (char **)val, 868 min_t(u32, nval, obj->package.count)); 869 break; 870 default: 871 ret = -EINVAL; 872 break; 873 } 874 return ret; 875 } 876 877 int acpi_dev_prop_read(const struct acpi_device *adev, const char *propname, 878 enum dev_prop_type proptype, void *val, size_t nval) 879 { 880 return adev ? acpi_data_prop_read(&adev->data, propname, proptype, val, nval) : -EINVAL; 881 } 882 883 /** 884 * acpi_node_prop_read - retrieve the value of an ACPI property with given name. 885 * @fwnode: Firmware node to get the property from. 886 * @propname: Name of the property. 887 * @proptype: Expected property type. 888 * @val: Location to store the property value (if not %NULL). 889 * @nval: Size of the array pointed to by @val. 890 * 891 * If @val is %NULL, return the number of array elements comprising the value 892 * of the property. Otherwise, read at most @nval values to the array at the 893 * location pointed to by @val. 894 */ 895 int acpi_node_prop_read(const struct fwnode_handle *fwnode, 896 const char *propname, enum dev_prop_type proptype, 897 void *val, size_t nval) 898 { 899 return acpi_data_prop_read(acpi_device_data_of_node(fwnode), 900 propname, proptype, val, nval); 901 } 902 903 /** 904 * acpi_get_next_subnode - Return the next child node handle for a fwnode 905 * @fwnode: Firmware node to find the next child node for. 906 * @child: Handle to one of the device's child nodes or a null handle. 907 */ 908 struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode, 909 struct fwnode_handle *child) 910 { 911 const struct acpi_device *adev = to_acpi_device_node(fwnode); 912 const struct list_head *head; 913 struct list_head *next; 914 915 if (!child || is_acpi_device_node(child)) { 916 struct acpi_device *child_adev; 917 918 if (adev) 919 head = &adev->children; 920 else 921 goto nondev; 922 923 if (list_empty(head)) 924 goto nondev; 925 926 if (child) { 927 adev = to_acpi_device_node(child); 928 next = adev->node.next; 929 if (next == head) { 930 child = NULL; 931 goto nondev; 932 } 933 child_adev = list_entry(next, struct acpi_device, node); 934 } else { 935 child_adev = list_first_entry(head, struct acpi_device, 936 node); 937 } 938 return acpi_fwnode_handle(child_adev); 939 } 940 941 nondev: 942 if (!child || is_acpi_data_node(child)) { 943 const struct acpi_data_node *data = to_acpi_data_node(fwnode); 944 struct acpi_data_node *dn; 945 946 if (adev) 947 head = &adev->data.subnodes; 948 else if (data) 949 head = &data->data.subnodes; 950 else 951 return NULL; 952 953 if (list_empty(head)) 954 return NULL; 955 956 if (child) { 957 dn = to_acpi_data_node(child); 958 next = dn->sibling.next; 959 if (next == head) 960 return NULL; 961 962 dn = list_entry(next, struct acpi_data_node, sibling); 963 } else { 964 dn = list_first_entry(head, struct acpi_data_node, sibling); 965 } 966 return &dn->fwnode; 967 } 968 return NULL; 969 } 970 971 /** 972 * acpi_node_get_parent - Return parent fwnode of this fwnode 973 * @fwnode: Firmware node whose parent to get 974 * 975 * Returns parent node of an ACPI device or data firmware node or %NULL if 976 * not available. 977 */ 978 struct fwnode_handle *acpi_node_get_parent(const struct fwnode_handle *fwnode) 979 { 980 if (is_acpi_data_node(fwnode)) { 981 /* All data nodes have parent pointer so just return that */ 982 return to_acpi_data_node(fwnode)->parent; 983 } else if (is_acpi_device_node(fwnode)) { 984 acpi_handle handle, parent_handle; 985 986 handle = to_acpi_device_node(fwnode)->handle; 987 if (ACPI_SUCCESS(acpi_get_parent(handle, &parent_handle))) { 988 struct acpi_device *adev; 989 990 if (!acpi_bus_get_device(parent_handle, &adev)) 991 return acpi_fwnode_handle(adev); 992 } 993 } 994 995 return NULL; 996 } 997 998 /** 999 * acpi_graph_get_next_endpoint - Get next endpoint ACPI firmware node 1000 * @fwnode: Pointer to the parent firmware node 1001 * @prev: Previous endpoint node or %NULL to get the first 1002 * 1003 * Looks up next endpoint ACPI firmware node below a given @fwnode. Returns 1004 * %NULL if there is no next endpoint, ERR_PTR() in case of error. In case 1005 * of success the next endpoint is returned. 1006 */ 1007 struct fwnode_handle *acpi_graph_get_next_endpoint( 1008 const struct fwnode_handle *fwnode, struct fwnode_handle *prev) 1009 { 1010 struct fwnode_handle *port = NULL; 1011 struct fwnode_handle *endpoint; 1012 1013 if (!prev) { 1014 do { 1015 port = fwnode_get_next_child_node(fwnode, port); 1016 /* Ports must have port property */ 1017 if (fwnode_property_present(port, "port")) 1018 break; 1019 } while (port); 1020 } else { 1021 port = fwnode_get_parent(prev); 1022 } 1023 1024 if (!port) 1025 return NULL; 1026 1027 endpoint = fwnode_get_next_child_node(port, prev); 1028 while (!endpoint) { 1029 port = fwnode_get_next_child_node(fwnode, port); 1030 if (!port) 1031 break; 1032 if (fwnode_property_present(port, "port")) 1033 endpoint = fwnode_get_next_child_node(port, NULL); 1034 } 1035 1036 if (endpoint) { 1037 /* Endpoints must have "endpoint" property */ 1038 if (!fwnode_property_present(endpoint, "endpoint")) 1039 return ERR_PTR(-EPROTO); 1040 } 1041 1042 return endpoint; 1043 } 1044 1045 /** 1046 * acpi_graph_get_child_prop_value - Return a child with a given property value 1047 * @fwnode: device fwnode 1048 * @prop_name: The name of the property to look for 1049 * @val: the desired property value 1050 * 1051 * Return the port node corresponding to a given port number. Returns 1052 * the child node on success, NULL otherwise. 1053 */ 1054 static struct fwnode_handle *acpi_graph_get_child_prop_value( 1055 const struct fwnode_handle *fwnode, const char *prop_name, 1056 unsigned int val) 1057 { 1058 struct fwnode_handle *child; 1059 1060 fwnode_for_each_child_node(fwnode, child) { 1061 u32 nr; 1062 1063 if (fwnode_property_read_u32(child, prop_name, &nr)) 1064 continue; 1065 1066 if (val == nr) 1067 return child; 1068 } 1069 1070 return NULL; 1071 } 1072 1073 1074 /** 1075 * acpi_graph_get_remote_enpoint - Parses and returns remote end of an endpoint 1076 * @fwnode: Endpoint firmware node pointing to a remote device 1077 * @parent: Firmware node of remote port parent is filled here if not %NULL 1078 * @port: Firmware node of remote port is filled here if not %NULL 1079 * @endpoint: Firmware node of remote endpoint is filled here if not %NULL 1080 * 1081 * Function parses remote end of ACPI firmware remote endpoint and fills in 1082 * fields requested by the caller. Returns %0 in case of success and 1083 * negative errno otherwise. 1084 */ 1085 int acpi_graph_get_remote_endpoint(const struct fwnode_handle *__fwnode, 1086 struct fwnode_handle **parent, 1087 struct fwnode_handle **port, 1088 struct fwnode_handle **endpoint) 1089 { 1090 struct fwnode_handle *fwnode; 1091 unsigned int port_nr, endpoint_nr; 1092 struct acpi_reference_args args; 1093 int ret; 1094 1095 memset(&args, 0, sizeof(args)); 1096 ret = acpi_node_get_property_reference(__fwnode, "remote-endpoint", 0, 1097 &args); 1098 if (ret) 1099 return ret; 1100 1101 /* 1102 * Always require two arguments with the reference: port and 1103 * endpoint indices. 1104 */ 1105 if (args.nargs != 2) 1106 return -EPROTO; 1107 1108 fwnode = acpi_fwnode_handle(args.adev); 1109 port_nr = args.args[0]; 1110 endpoint_nr = args.args[1]; 1111 1112 if (parent) 1113 *parent = fwnode; 1114 1115 if (!port && !endpoint) 1116 return 0; 1117 1118 fwnode = acpi_graph_get_child_prop_value(fwnode, "port", port_nr); 1119 if (!fwnode) 1120 return -EPROTO; 1121 1122 if (port) 1123 *port = fwnode; 1124 1125 if (!endpoint) 1126 return 0; 1127 1128 fwnode = acpi_graph_get_child_prop_value(fwnode, "endpoint", 1129 endpoint_nr); 1130 if (!fwnode) 1131 return -EPROTO; 1132 1133 *endpoint = fwnode; 1134 1135 return 0; 1136 } 1137 1138 static bool acpi_fwnode_device_is_available(const struct fwnode_handle *fwnode) 1139 { 1140 if (!is_acpi_device_node(fwnode)) 1141 return false; 1142 1143 return acpi_device_is_present(to_acpi_device_node(fwnode)); 1144 } 1145 1146 static bool acpi_fwnode_property_present(const struct fwnode_handle *fwnode, 1147 const char *propname) 1148 { 1149 return !acpi_node_prop_get(fwnode, propname, NULL); 1150 } 1151 1152 static int 1153 acpi_fwnode_property_read_int_array(const struct fwnode_handle *fwnode, 1154 const char *propname, 1155 unsigned int elem_size, void *val, 1156 size_t nval) 1157 { 1158 enum dev_prop_type type; 1159 1160 switch (elem_size) { 1161 case sizeof(u8): 1162 type = DEV_PROP_U8; 1163 break; 1164 case sizeof(u16): 1165 type = DEV_PROP_U16; 1166 break; 1167 case sizeof(u32): 1168 type = DEV_PROP_U32; 1169 break; 1170 case sizeof(u64): 1171 type = DEV_PROP_U64; 1172 break; 1173 default: 1174 return -ENXIO; 1175 } 1176 1177 return acpi_node_prop_read(fwnode, propname, type, val, nval); 1178 } 1179 1180 static int 1181 acpi_fwnode_property_read_string_array(const struct fwnode_handle *fwnode, 1182 const char *propname, const char **val, 1183 size_t nval) 1184 { 1185 return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING, 1186 val, nval); 1187 } 1188 1189 static struct fwnode_handle * 1190 acpi_fwnode_get_named_child_node(const struct fwnode_handle *fwnode, 1191 const char *childname) 1192 { 1193 struct fwnode_handle *child; 1194 1195 /* 1196 * Find first matching named child node of this fwnode. 1197 * For ACPI this will be a data only sub-node. 1198 */ 1199 fwnode_for_each_child_node(fwnode, child) 1200 if (acpi_data_node_match(child, childname)) 1201 return child; 1202 1203 return NULL; 1204 } 1205 1206 static int 1207 acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode, 1208 const char *prop, const char *nargs_prop, 1209 unsigned int args_count, unsigned int index, 1210 struct fwnode_reference_args *args) 1211 { 1212 struct acpi_reference_args acpi_args; 1213 unsigned int i; 1214 int ret; 1215 1216 ret = __acpi_node_get_property_reference(fwnode, prop, index, 1217 args_count, &acpi_args); 1218 if (ret < 0) 1219 return ret; 1220 if (!args) 1221 return 0; 1222 1223 args->nargs = acpi_args.nargs; 1224 args->fwnode = acpi_fwnode_handle(acpi_args.adev); 1225 1226 for (i = 0; i < NR_FWNODE_REFERENCE_ARGS; i++) 1227 args->args[i] = i < acpi_args.nargs ? acpi_args.args[i] : 0; 1228 1229 return 0; 1230 } 1231 1232 static struct fwnode_handle * 1233 acpi_fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode, 1234 struct fwnode_handle *prev) 1235 { 1236 struct fwnode_handle *endpoint; 1237 1238 endpoint = acpi_graph_get_next_endpoint(fwnode, prev); 1239 if (IS_ERR(endpoint)) 1240 return NULL; 1241 1242 return endpoint; 1243 } 1244 1245 static struct fwnode_handle * 1246 acpi_fwnode_graph_get_remote_endpoint(const struct fwnode_handle *fwnode) 1247 { 1248 struct fwnode_handle *endpoint = NULL; 1249 1250 acpi_graph_get_remote_endpoint(fwnode, NULL, NULL, &endpoint); 1251 1252 return endpoint; 1253 } 1254 1255 static struct fwnode_handle * 1256 acpi_fwnode_get_parent(struct fwnode_handle *fwnode) 1257 { 1258 return acpi_node_get_parent(fwnode); 1259 } 1260 1261 static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, 1262 struct fwnode_endpoint *endpoint) 1263 { 1264 struct fwnode_handle *port_fwnode = fwnode_get_parent(fwnode); 1265 1266 endpoint->local_fwnode = fwnode; 1267 1268 fwnode_property_read_u32(port_fwnode, "port", &endpoint->port); 1269 fwnode_property_read_u32(fwnode, "endpoint", &endpoint->id); 1270 1271 return 0; 1272 } 1273 1274 #define DECLARE_ACPI_FWNODE_OPS(ops) \ 1275 const struct fwnode_operations ops = { \ 1276 .device_is_available = acpi_fwnode_device_is_available, \ 1277 .property_present = acpi_fwnode_property_present, \ 1278 .property_read_int_array = \ 1279 acpi_fwnode_property_read_int_array, \ 1280 .property_read_string_array = \ 1281 acpi_fwnode_property_read_string_array, \ 1282 .get_parent = acpi_node_get_parent, \ 1283 .get_next_child_node = acpi_get_next_subnode, \ 1284 .get_named_child_node = acpi_fwnode_get_named_child_node, \ 1285 .get_reference_args = acpi_fwnode_get_reference_args, \ 1286 .graph_get_next_endpoint = \ 1287 acpi_fwnode_graph_get_next_endpoint, \ 1288 .graph_get_remote_endpoint = \ 1289 acpi_fwnode_graph_get_remote_endpoint, \ 1290 .graph_get_port_parent = acpi_fwnode_get_parent, \ 1291 .graph_parse_endpoint = acpi_fwnode_graph_parse_endpoint, \ 1292 }; \ 1293 EXPORT_SYMBOL_GPL(ops) 1294 1295 DECLARE_ACPI_FWNODE_OPS(acpi_device_fwnode_ops); 1296 DECLARE_ACPI_FWNODE_OPS(acpi_data_fwnode_ops); 1297 const struct fwnode_operations acpi_static_fwnode_ops; 1298 1299 bool is_acpi_device_node(const struct fwnode_handle *fwnode) 1300 { 1301 return !IS_ERR_OR_NULL(fwnode) && 1302 fwnode->ops == &acpi_device_fwnode_ops; 1303 } 1304 EXPORT_SYMBOL(is_acpi_device_node); 1305 1306 bool is_acpi_data_node(const struct fwnode_handle *fwnode) 1307 { 1308 return !IS_ERR_OR_NULL(fwnode) && fwnode->ops == &acpi_data_fwnode_ops; 1309 } 1310 EXPORT_SYMBOL(is_acpi_data_node); 1311