| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * acpi_utils.c - ACPI Utility Functions ($Revision: 10 $) |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> |
|---|
| 5 | 6 | * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> |
|---|
| 6 | | - * |
|---|
| 7 | | - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 10 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 11 | | - * the Free Software Foundation; either version 2 of the License, or (at |
|---|
| 12 | | - * your option) any later version. |
|---|
| 13 | | - * |
|---|
| 14 | | - * This program is distributed in the hope that it will be useful, but |
|---|
| 15 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 16 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 17 | | - * General Public License for more details. |
|---|
| 18 | | - * |
|---|
| 19 | | - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 20 | 7 | */ |
|---|
| 21 | 8 | |
|---|
| 22 | 9 | #include <linux/kernel.h> |
|---|
| .. | .. |
|---|
| 117 | 104 | " [%c]\n", |
|---|
| 118 | 105 | i, format_string[i]); |
|---|
| 119 | 106 | return AE_BAD_DATA; |
|---|
| 120 | | - break; |
|---|
| 121 | 107 | } |
|---|
| 122 | 108 | break; |
|---|
| 123 | 109 | |
|---|
| .. | .. |
|---|
| 142 | 128 | " expecting [%c]\n", |
|---|
| 143 | 129 | i, format_string[i]); |
|---|
| 144 | 130 | return AE_BAD_DATA; |
|---|
| 145 | | - break; |
|---|
| 146 | 131 | } |
|---|
| 147 | 132 | break; |
|---|
| 148 | 133 | case ACPI_TYPE_LOCAL_REFERENCE: |
|---|
| .. | .. |
|---|
| 157 | 142 | " expecting [%c]\n", |
|---|
| 158 | 143 | i, format_string[i]); |
|---|
| 159 | 144 | return AE_BAD_DATA; |
|---|
| 160 | | - break; |
|---|
| 161 | 145 | } |
|---|
| 162 | 146 | break; |
|---|
| 163 | 147 | |
|---|
| .. | .. |
|---|
| 168 | 152 | i)); |
|---|
| 169 | 153 | /* TBD: handle nested packages... */ |
|---|
| 170 | 154 | return AE_SUPPORT; |
|---|
| 171 | | - break; |
|---|
| 172 | 155 | } |
|---|
| 173 | 156 | } |
|---|
| 174 | 157 | |
|---|
| .. | .. |
|---|
| 468 | 451 | |
|---|
| 469 | 452 | /** |
|---|
| 470 | 453 | * acpi_handle_path: Return the object path of handle |
|---|
| 454 | + * @handle: ACPI device handle |
|---|
| 471 | 455 | * |
|---|
| 472 | 456 | * Caller must free the returned buffer |
|---|
| 473 | 457 | */ |
|---|
| .. | .. |
|---|
| 486 | 470 | |
|---|
| 487 | 471 | /** |
|---|
| 488 | 472 | * acpi_handle_printk: Print message with ACPI prefix and object path |
|---|
| 473 | + * @level: log level |
|---|
| 474 | + * @handle: ACPI device handle |
|---|
| 475 | + * @fmt: format string |
|---|
| 489 | 476 | * |
|---|
| 490 | 477 | * This function is called through acpi_handle_<level> macros and prints |
|---|
| 491 | 478 | * a message with ACPI prefix and object path. This function acquires |
|---|
| .. | .. |
|---|
| 514 | 501 | #if defined(CONFIG_DYNAMIC_DEBUG) |
|---|
| 515 | 502 | /** |
|---|
| 516 | 503 | * __acpi_handle_debug: pr_debug with ACPI prefix and object path |
|---|
| 504 | + * @descriptor: Dynamic Debug descriptor |
|---|
| 505 | + * @handle: ACPI device handle |
|---|
| 506 | + * @fmt: format string |
|---|
| 517 | 507 | * |
|---|
| 518 | 508 | * This function is called through acpi_handle_debug macro and debug |
|---|
| 519 | 509 | * prints a message with ACPI prefix and object path. This function |
|---|
| .. | .. |
|---|
| 612 | 602 | } |
|---|
| 613 | 603 | |
|---|
| 614 | 604 | /** |
|---|
| 605 | + * acpi_evaluate_reg: Evaluate _REG method to register OpRegion presence |
|---|
| 606 | + * @handle: ACPI device handle |
|---|
| 607 | + * @space_id: ACPI address space id to register OpRegion presence for |
|---|
| 608 | + * @function: Parameter to pass to _REG one of ACPI_REG_CONNECT or |
|---|
| 609 | + * ACPI_REG_DISCONNECT |
|---|
| 610 | + * |
|---|
| 611 | + * Evaluate device's _REG method to register OpRegion presence. |
|---|
| 612 | + */ |
|---|
| 613 | +acpi_status acpi_evaluate_reg(acpi_handle handle, u8 space_id, u32 function) |
|---|
| 614 | +{ |
|---|
| 615 | + struct acpi_object_list arg_list; |
|---|
| 616 | + union acpi_object params[2]; |
|---|
| 617 | + |
|---|
| 618 | + params[0].type = ACPI_TYPE_INTEGER; |
|---|
| 619 | + params[0].integer.value = space_id; |
|---|
| 620 | + params[1].type = ACPI_TYPE_INTEGER; |
|---|
| 621 | + params[1].integer.value = function; |
|---|
| 622 | + arg_list.count = 2; |
|---|
| 623 | + arg_list.pointer = params; |
|---|
| 624 | + |
|---|
| 625 | + return acpi_evaluate_object(handle, "_REG", &arg_list, NULL); |
|---|
| 626 | +} |
|---|
| 627 | +EXPORT_SYMBOL(acpi_evaluate_reg); |
|---|
| 628 | + |
|---|
| 629 | +/** |
|---|
| 615 | 630 | * acpi_evaluate_dsm - evaluate device's _DSM method |
|---|
| 616 | 631 | * @handle: ACPI device handle |
|---|
| 617 | 632 | * @guid: GUID of requested functions, should be 16 bytes |
|---|
| .. | .. |
|---|
| 708 | 723 | EXPORT_SYMBOL(acpi_check_dsm); |
|---|
| 709 | 724 | |
|---|
| 710 | 725 | /** |
|---|
| 726 | + * acpi_dev_hid_uid_match - Match device by supplied HID and UID |
|---|
| 727 | + * @adev: ACPI device to match. |
|---|
| 728 | + * @hid2: Hardware ID of the device. |
|---|
| 729 | + * @uid2: Unique ID of the device, pass NULL to not check _UID. |
|---|
| 730 | + * |
|---|
| 731 | + * Matches HID and UID in @adev with given @hid2 and @uid2. |
|---|
| 732 | + * Returns true if matches. |
|---|
| 733 | + */ |
|---|
| 734 | +bool acpi_dev_hid_uid_match(struct acpi_device *adev, |
|---|
| 735 | + const char *hid2, const char *uid2) |
|---|
| 736 | +{ |
|---|
| 737 | + const char *hid1 = acpi_device_hid(adev); |
|---|
| 738 | + const char *uid1 = acpi_device_uid(adev); |
|---|
| 739 | + |
|---|
| 740 | + if (strcmp(hid1, hid2)) |
|---|
| 741 | + return false; |
|---|
| 742 | + |
|---|
| 743 | + if (!uid2) |
|---|
| 744 | + return true; |
|---|
| 745 | + |
|---|
| 746 | + return uid1 && !strcmp(uid1, uid2); |
|---|
| 747 | +} |
|---|
| 748 | +EXPORT_SYMBOL(acpi_dev_hid_uid_match); |
|---|
| 749 | + |
|---|
| 750 | +/** |
|---|
| 711 | 751 | * acpi_dev_found - Detect presence of a given ACPI device in the namespace. |
|---|
| 712 | 752 | * @hid: Hardware ID of the device. |
|---|
| 713 | 753 | * |
|---|
| .. | .. |
|---|
| 738 | 778 | EXPORT_SYMBOL(acpi_dev_found); |
|---|
| 739 | 779 | |
|---|
| 740 | 780 | struct acpi_dev_match_info { |
|---|
| 741 | | - const char *dev_name; |
|---|
| 742 | 781 | struct acpi_device_id hid[2]; |
|---|
| 743 | 782 | const char *uid; |
|---|
| 744 | 783 | s64 hrv; |
|---|
| 745 | 784 | }; |
|---|
| 746 | 785 | |
|---|
| 747 | | -static int acpi_dev_match_cb(struct device *dev, void *data) |
|---|
| 786 | +static int acpi_dev_match_cb(struct device *dev, const void *data) |
|---|
| 748 | 787 | { |
|---|
| 749 | 788 | struct acpi_device *adev = to_acpi_device(dev); |
|---|
| 750 | | - struct acpi_dev_match_info *match = data; |
|---|
| 789 | + const struct acpi_dev_match_info *match = data; |
|---|
| 751 | 790 | unsigned long long hrv; |
|---|
| 752 | 791 | acpi_status status; |
|---|
| 753 | 792 | |
|---|
| .. | .. |
|---|
| 757 | 796 | if (match->uid && (!adev->pnp.unique_id || |
|---|
| 758 | 797 | strcmp(adev->pnp.unique_id, match->uid))) |
|---|
| 759 | 798 | return 0; |
|---|
| 760 | | - |
|---|
| 761 | | - match->dev_name = acpi_dev_name(adev); |
|---|
| 762 | 799 | |
|---|
| 763 | 800 | if (match->hrv == -1) |
|---|
| 764 | 801 | return 1; |
|---|
| .. | .. |
|---|
| 806 | 843 | EXPORT_SYMBOL(acpi_dev_present); |
|---|
| 807 | 844 | |
|---|
| 808 | 845 | /** |
|---|
| 809 | | - * acpi_dev_get_first_match_name - Return name of first match of ACPI device |
|---|
| 846 | + * acpi_dev_get_first_match_dev - Return the first match of ACPI device |
|---|
| 810 | 847 | * @hid: Hardware ID of the device. |
|---|
| 811 | 848 | * @uid: Unique ID of the device, pass NULL to not check _UID |
|---|
| 812 | 849 | * @hrv: Hardware Revision of the device, pass -1 to not check _HRV |
|---|
| 813 | 850 | * |
|---|
| 814 | | - * Return device name if a matching device was present |
|---|
| 851 | + * Return the first match of ACPI device if a matching device was present |
|---|
| 815 | 852 | * at the moment of invocation, or NULL otherwise. |
|---|
| 853 | + * |
|---|
| 854 | + * The caller is responsible to call put_device() on the returned device. |
|---|
| 816 | 855 | * |
|---|
| 817 | 856 | * See additional information in acpi_dev_present() as well. |
|---|
| 818 | 857 | */ |
|---|
| 819 | | -const char * |
|---|
| 820 | | -acpi_dev_get_first_match_name(const char *hid, const char *uid, s64 hrv) |
|---|
| 858 | +struct acpi_device * |
|---|
| 859 | +acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv) |
|---|
| 821 | 860 | { |
|---|
| 822 | 861 | struct acpi_dev_match_info match = {}; |
|---|
| 823 | 862 | struct device *dev; |
|---|
| .. | .. |
|---|
| 827 | 866 | match.hrv = hrv; |
|---|
| 828 | 867 | |
|---|
| 829 | 868 | dev = bus_find_device(&acpi_bus_type, NULL, &match, acpi_dev_match_cb); |
|---|
| 830 | | - return dev ? match.dev_name : NULL; |
|---|
| 869 | + return dev ? to_acpi_device(dev) : NULL; |
|---|
| 831 | 870 | } |
|---|
| 832 | | -EXPORT_SYMBOL(acpi_dev_get_first_match_name); |
|---|
| 871 | +EXPORT_SYMBOL(acpi_dev_get_first_match_dev); |
|---|
| 833 | 872 | |
|---|
| 834 | 873 | /* |
|---|
| 835 | 874 | * acpi_backlight= handling, this is done here rather then in video_detect.c |
|---|