Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'acpi-5.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull ACPI updates from Rafael Wysocki:
"These rework the handling of ACPI device objects to use the driver
core facilities for managing child ones instead of some questionable
home-grown ways without the requisite locking and reference counting,
clean up the EC driver, improve suspend-to-idle handling on x86, add
some systems to the ACPI backlight quirk list, fix some assorted
issues, clean up code and improve documentation.

Specifics:

- Use facilities provided by the driver core and some additional
helpers to handle the children of a given ACPI device object in
multiple places instead of using the children and node list heads
in struct acpi_device which is error prone (Rafael Wysocki).

- Fix ACPI-related device reference counting issue in the hisi_lpc
bus driver (Yang Yingliang).

- Drop the children and node list heads that are not needed any more
from struct acpi_device (Rafael Wysocki).

- Drop driver member from struct acpi_device (Uwe Kleine-König).

- Drop redundant check from acpi_device_remove() (Uwe Kleine-König).

- Prepare the CPPC library for handling backwards-compatible future
_CPC return package formats gracefully (Rafael Wysocki).

- Clean up the ACPI EC driver after previous changes in it (Hans de
Goede).

- Drop leftover acpi_processor_get_limit_info() declaration (Riwen
Lu).

- Split out thermal initialization from ACPI PSS (Riwen Lu).

- Annotate more functions in the ACPI CPU idle driver to live in the
cpuidle section (Guilherme G. Piccoli).

- Fix _EINJ vs "special purpose" EFI memory regions (Dan Williams).

- Implement a better fix to avoid spamming the console with old error
logs (Tony Luck).

- Fix typo in a comment in the APEI code (Xiang wangx).

- Save NVS memory during transitions into S3 on Lenovo G40-45 (Manyi
Li).

- Add support for upcoming AMD uPEP device ID AMDI008 to the ACPI
suspend-to-idle driver for x86 platforms (Shyam Sundar S K).

- Clean up checks related to the ACPI_FADT_LOW_POWER_S0 platform flag
in the LPIT table driver and the suspend-to-idle driver for x86
platforms (Rafael Wysocki).

- Print information messages regarding declared LPS0 idle support in
the platform firmware (Rafael Wysocki).

- Fix missing check in register_device_clock() in the ACPI driver for
Intel SoCs (huhai).

- Fix ACS setup in the VIOT table parser (Eric Auger).

- Skip IRQ override on AMD Zen platforms where it's harmful
(Chuanhong Guo).

- Use native backlight on Dell Inspiron N4010 (Hans de Goede).

- Use native backlight on some TongFang devices (Werner Sembach).

- Drop X86 dependency from the ACPI backlight driver Kconfig (Riwen
Lu).

- Shorten the quirk list in the ACPI backlight driver by identifying
Clevo by board_name only (Werner Sembach).

- Remove useless NULL pointer checks from 2 ACPI PCI link management
functions (Andrey Strachuk).

- Fix obsolete example in the ACPI EINJ documentation (Qifu Zhang).

- Update links and references to _DSD-related documents (Sudeep
Holla)"

* tag 'acpi-5.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (46 commits)
ACPI/PCI: Remove useless NULL pointer checks
ACPI: CPPC: Do not prevent CPPC from working in the future
ACPI: PM: x86: Print messages regarding LPS0 idle support
ACPI: resource: skip IRQ override on AMD Zen platforms
Documentation: ACPI: EINJ: Fix obsolete example
ACPI: video: Use native backlight on Dell Inspiron N4010
ACPI: PM: s2idle: Use LPS0 idle if ACPI_FADT_LOW_POWER_S0 is unset
Revert "ACPI / PM: LPIT: Register sysfs attributes based on FADT"
ACPI: video: Shortening quirk list by identifying Clevo by board_name only
ACPI: video: Force backlight native for some TongFang devices
ACPI: PM: s2idle: Add support for upcoming AMD uPEP HID AMDI008
ACPI: VIOT: Fix ACS setup
ACPI: bus: Drop unused list heads from struct acpi_device
hisi_lpc: Use acpi_dev_for_each_child()
bus: hisi_lpc: fix missing platform_device_put() in hisi_lpc_acpi_probe()
ACPI: bus: Drop driver member of struct acpi_device
ACPI: bus: Drop redundant check in acpi_device_remove()
ACPI: APEI: Fix _EINJ vs EFI_MEMORY_SP
ACPI: LPSS: Fix missing check in register_device_clock()
ACPI: APEI: Better fix to avoid spamming the console with old error logs
...

+757 -657
+7 -4
Documentation/firmware-guide/acpi/DSD-properties-rules.rst
··· 21 21 22 22 In the ACPI _DSD context it is an element of the sub-package following the 23 23 generic Device Properties UUID in the _DSD return package as specified in the 24 - Device Properties UUID definition document [1]_. 24 + section titled "Well-Known _DSD UUIDs and Data Structure Formats" sub-section 25 + "Device Properties UUID" in _DSD (Device Specific Data) Implementation Guide 26 + document [1]_. 25 27 26 28 It also may be regarded as the definition of a key and the associated data type 27 29 that can be returned by _DSD in the Device Properties UUID sub-package for a ··· 38 36 associated with an additional key (name) allowing the subset to be referred 39 37 to as a whole (and to be treated as a separate entity). The canonical 40 38 representation of property subsets is via the mechanism specified in the 41 - Hierarchical Properties Extension UUID definition document [2]_. 39 + section titled "Well-Known _DSD UUIDs and Data Structure Formats" sub-section 40 + "Hierarchical Data Extension UUID" in _DSD (Device Specific Data) 41 + Implementation Guide document [1]_. 42 42 43 43 Property sets may be hierarchical. That is, a property set may contain 44 44 multiple property subsets that each may contain property subsets of its ··· 100 96 References 101 97 ========== 102 98 103 - .. [1] https://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf 104 - .. [2] https://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.1.pdf 99 + .. [1] https://github.com/UEFI/DSD-Guide
+1 -1
Documentation/firmware-guide/acpi/apei/einj.rst
··· 168 168 0x00000008 Memory Correctable 169 169 0x00000010 Memory Uncorrectable non-fatal 170 170 # echo 0x12345000 > param1 # Set memory address for injection 171 - # echo $((-1 << 12)) > param2 # Mask 0xfffffffffffff000 - anywhere in this page 171 + # echo 0xfffffffffffff000 > param2 # Mask - anywhere in this page 172 172 # echo 0x8 > error_type # Choose correctable memory error 173 173 # echo 1 > error_inject # Inject now 174 174
+2 -2
drivers/acpi/Kconfig
··· 210 210 211 211 config ACPI_VIDEO 212 212 tristate "Video" 213 - depends on X86 && BACKLIGHT_CLASS_DEVICE 213 + depends on BACKLIGHT_CLASS_DEVICE 214 214 depends on INPUT 215 215 select THERMAL 216 216 help ··· 255 255 256 256 config ACPI_CPU_FREQ_PSS 257 257 bool 258 - select THERMAL 259 258 260 259 config ACPI_PROCESSOR_CSTATE 261 260 def_bool y ··· 286 287 depends on X86 || IA64 || ARM64 || LOONGARCH 287 288 select ACPI_PROCESSOR_IDLE 288 289 select ACPI_CPU_FREQ_PSS if X86 || IA64 || LOONGARCH 290 + select THERMAL 289 291 default y 290 292 help 291 293 This driver adds support for the ACPI Processor package. It is required
+2 -3
drivers/acpi/Makefile
··· 109 109 obj-$(CONFIG_ACPI_PFRUT) += pfr_update.o pfr_telemetry.o 110 110 111 111 # processor has its own "processor." module_param namespace 112 - processor-y := processor_driver.o 112 + processor-y := processor_driver.o processor_thermal.o 113 113 processor-$(CONFIG_ACPI_PROCESSOR_IDLE) += processor_idle.o 114 - processor-$(CONFIG_ACPI_CPU_FREQ_PSS) += processor_throttling.o \ 115 - processor_thermal.o 114 + processor-$(CONFIG_ACPI_CPU_FREQ_PSS) += processor_throttling.o 116 115 processor-$(CONFIG_CPU_FREQ) += processor_perflib.o 117 116 118 117 obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o
-6
drivers/acpi/acpi_lpit.c
··· 109 109 if (!info->iomem_addr) 110 110 return; 111 111 112 - if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) 113 - return; 114 - 115 112 /* Silently fail, if cpuidle attribute group is not present */ 116 113 sysfs_add_file_to_group(&cpu_subsys.dev_root->kobj, 117 114 &dev_attr_low_power_idle_system_residency_us.attr, 118 115 "cpuidle"); 119 116 } else if (info->gaddr.space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) { 120 - if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) 121 - return; 122 - 123 117 /* Silently fail, if cpuidle attribute group is not present */ 124 118 sysfs_add_file_to_group(&cpu_subsys.dev_root->kobj, 125 119 &dev_attr_low_power_idle_cpu_residency_us.attr,
+3
drivers/acpi/acpi_lpss.c
··· 422 422 if (!lpss_clk_dev) 423 423 lpt_register_clock_device(); 424 424 425 + if (IS_ERR(lpss_clk_dev)) 426 + return PTR_ERR(lpss_clk_dev); 427 + 425 428 clk_data = platform_get_drvdata(lpss_clk_dev); 426 429 if (!clk_data) 427 430 return -ENODEV;
+16 -25
drivers/acpi/acpi_video.c
··· 1150 1150 return 0; 1151 1151 } 1152 1152 1153 - static int 1154 - acpi_video_bus_get_one_device(struct acpi_device *device, 1155 - struct acpi_video_bus *video) 1153 + static int acpi_video_bus_get_one_device(struct acpi_device *device, void *arg) 1156 1154 { 1157 - unsigned long long device_id; 1158 - int status, device_type; 1159 - struct acpi_video_device *data; 1155 + struct acpi_video_bus *video = arg; 1160 1156 struct acpi_video_device_attrib *attribute; 1157 + struct acpi_video_device *data; 1158 + unsigned long long device_id; 1159 + acpi_status status; 1160 + int device_type; 1161 1161 1162 - status = 1163 - acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); 1164 - /* Some device omits _ADR, we skip them instead of fail */ 1162 + status = acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); 1163 + /* Skip devices without _ADR instead of failing. */ 1165 1164 if (ACPI_FAILURE(status)) 1166 - return 0; 1165 + goto exit; 1167 1166 1168 1167 data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL); 1169 - if (!data) 1168 + if (!data) { 1169 + dev_dbg(&device->dev, "Cannot attach\n"); 1170 1170 return -ENOMEM; 1171 + } 1171 1172 1172 1173 strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME); 1173 1174 strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); ··· 1231 1230 list_add_tail(&data->entry, &video->video_device_list); 1232 1231 mutex_unlock(&video->device_list_lock); 1233 1232 1234 - return status; 1233 + exit: 1234 + video->child_count++; 1235 + return 0; 1235 1236 } 1236 1237 1237 1238 /* ··· 1545 1542 acpi_video_bus_get_devices(struct acpi_video_bus *video, 1546 1543 struct acpi_device *device) 1547 1544 { 1548 - int status = 0; 1549 - struct acpi_device *dev; 1550 - 1551 1545 /* 1552 1546 * There are systems where video module known to work fine regardless 1553 1547 * of broken _DOD and ignoring returned value here doesn't cause ··· 1552 1552 */ 1553 1553 acpi_video_device_enumerate(video); 1554 1554 1555 - list_for_each_entry(dev, &device->children, node) { 1556 - 1557 - status = acpi_video_bus_get_one_device(dev, video); 1558 - if (status) { 1559 - dev_err(&dev->dev, "Can't attach device\n"); 1560 - break; 1561 - } 1562 - video->child_count++; 1563 - } 1564 - return status; 1555 + return acpi_dev_for_each_child(device, acpi_video_bus_get_one_device, video); 1565 1556 } 1566 1557 1567 1558 /* acpi_video interface */
+1 -1
drivers/acpi/apei/apei-base.c
··· 3 3 * apei-base.c - ACPI Platform Error Interface (APEI) supporting 4 4 * infrastructure 5 5 * 6 - * APEI allows to report errors (for example from the chipset) to the 6 + * APEI allows to report errors (for example from the chipset) to 7 7 * the operating system. This improves NMI handling especially. In 8 8 * addition it supports error serialization and error injection. 9 9 *
+23 -8
drivers/acpi/apei/bert.c
··· 29 29 30 30 #undef pr_fmt 31 31 #define pr_fmt(fmt) "BERT: " fmt 32 + 33 + #define ACPI_BERT_PRINT_MAX_RECORDS 5 32 34 #define ACPI_BERT_PRINT_MAX_LEN 1024 33 35 34 36 static int bert_disable; 35 37 38 + /* 39 + * Print "all" the error records in the BERT table, but avoid huge spam to 40 + * the console if the BIOS included oversize records, or too many records. 41 + * Skipping some records here does not lose anything because the full 42 + * data is available to user tools in: 43 + * /sys/firmware/acpi/tables/data/BERT 44 + */ 36 45 static void __init bert_print_all(struct acpi_bert_region *region, 37 46 unsigned int region_len) 38 47 { 39 48 struct acpi_hest_generic_status *estatus = 40 49 (struct acpi_hest_generic_status *)region; 41 50 int remain = region_len; 51 + int printed = 0, skipped = 0; 42 52 u32 estatus_len; 43 53 44 54 while (remain >= sizeof(struct acpi_bert_region)) { ··· 56 46 if (remain < estatus_len) { 57 47 pr_err(FW_BUG "Truncated status block (length: %u).\n", 58 48 estatus_len); 59 - return; 49 + break; 60 50 } 61 51 62 52 /* No more error records. */ 63 53 if (!estatus->block_status) 64 - return; 54 + break; 65 55 66 56 if (cper_estatus_check(estatus)) { 67 57 pr_err(FW_BUG "Invalid error record.\n"); 68 - return; 58 + break; 69 59 } 70 60 71 - pr_info_once("Error records from previous boot:\n"); 72 - if (region_len < ACPI_BERT_PRINT_MAX_LEN) 61 + if (estatus_len < ACPI_BERT_PRINT_MAX_LEN && 62 + printed < ACPI_BERT_PRINT_MAX_RECORDS) { 63 + pr_info_once("Error records from previous boot:\n"); 73 64 cper_estatus_print(KERN_INFO HW_ERR, estatus); 74 - else 75 - pr_info_once("Max print length exceeded, table data is available at:\n" 76 - "/sys/firmware/acpi/tables/data/BERT"); 65 + printed++; 66 + } else { 67 + skipped++; 68 + } 77 69 78 70 /* 79 71 * Because the boot error source is "one-time polled" type, ··· 87 75 estatus = (void *)estatus + estatus_len; 88 76 remain -= estatus_len; 89 77 } 78 + 79 + if (skipped) 80 + pr_info(HW_ERR "Skipped %d error records\n", skipped); 90 81 } 91 82 92 83 static int __init setup_bert_disable(char *str)
+2
drivers/acpi/apei/einj.c
··· 546 546 != REGION_INTERSECTS) && 547 547 (region_intersects(base_addr, size, IORESOURCE_MEM, IORES_DESC_PERSISTENT_MEMORY) 548 548 != REGION_INTERSECTS) && 549 + (region_intersects(base_addr, size, IORESOURCE_MEM, IORES_DESC_SOFT_RESERVED) 550 + != REGION_INTERSECTS) && 549 551 !arch_is_platform_page(base_addr))) 550 552 return -EINVAL; 551 553
+30 -17
drivers/acpi/bus.c
··· 464 464 static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) 465 465 { 466 466 struct acpi_device *adev; 467 - struct acpi_driver *driver; 468 467 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; 469 468 bool hotplug_event = false; 470 469 ··· 515 516 if (!adev) 516 517 goto err; 517 518 518 - driver = adev->driver; 519 - if (driver && driver->ops.notify && 520 - (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS)) 521 - driver->ops.notify(adev, type); 519 + if (adev->dev.driver) { 520 + struct acpi_driver *driver = to_acpi_driver(adev->dev.driver); 521 + 522 + if (driver && driver->ops.notify && 523 + (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS)) 524 + driver->ops.notify(adev, type); 525 + } 522 526 523 527 if (!hotplug_event) { 524 528 acpi_bus_put_acpi_device(adev); ··· 540 538 static void acpi_notify_device(acpi_handle handle, u32 event, void *data) 541 539 { 542 540 struct acpi_device *device = data; 541 + struct acpi_driver *acpi_drv = to_acpi_driver(device->dev.driver); 543 542 544 - device->driver->ops.notify(device, event); 543 + acpi_drv->ops.notify(device, event); 545 544 } 546 545 547 546 static void acpi_notify_device_fixed(void *data) ··· 1035 1032 if (ret) 1036 1033 return ret; 1037 1034 1038 - acpi_dev->driver = acpi_drv; 1039 - 1040 1035 pr_debug("Driver [%s] successfully bound to device [%s]\n", 1041 1036 acpi_drv->name, acpi_dev->pnp.bus_id); 1042 1037 ··· 1044 1043 if (acpi_drv->ops.remove) 1045 1044 acpi_drv->ops.remove(acpi_dev); 1046 1045 1047 - acpi_dev->driver = NULL; 1048 1046 acpi_dev->driver_data = NULL; 1049 1047 return ret; 1050 1048 } ··· 1059 1059 static void acpi_device_remove(struct device *dev) 1060 1060 { 1061 1061 struct acpi_device *acpi_dev = to_acpi_device(dev); 1062 - struct acpi_driver *acpi_drv = acpi_dev->driver; 1062 + struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver); 1063 1063 1064 - if (acpi_drv) { 1065 - if (acpi_drv->ops.notify) 1066 - acpi_device_remove_notify_handler(acpi_dev); 1067 - if (acpi_drv->ops.remove) 1068 - acpi_drv->ops.remove(acpi_dev); 1069 - } 1070 - acpi_dev->driver = NULL; 1064 + if (acpi_drv->ops.notify) 1065 + acpi_device_remove_notify_handler(acpi_dev); 1066 + 1067 + if (acpi_drv->ops.remove) 1068 + acpi_drv->ops.remove(acpi_dev); 1069 + 1071 1070 acpi_dev->driver_data = NULL; 1072 1071 1073 1072 put_device(dev); ··· 1100 1101 1101 1102 return adwc->fn(to_acpi_device(dev), adwc->data); 1102 1103 } 1104 + EXPORT_SYMBOL_GPL(acpi_dev_for_each_child); 1103 1105 1104 1106 int acpi_dev_for_each_child(struct acpi_device *adev, 1105 1107 int (*fn)(struct acpi_device *, void *), void *data) ··· 1111 1111 }; 1112 1112 1113 1113 return device_for_each_child(&adev->dev, &adwc, acpi_dev_for_one_check); 1114 + } 1115 + 1116 + int acpi_dev_for_each_child_reverse(struct acpi_device *adev, 1117 + int (*fn)(struct acpi_device *, void *), 1118 + void *data) 1119 + { 1120 + struct acpi_dev_walk_context adwc = { 1121 + .fn = fn, 1122 + .data = data, 1123 + }; 1124 + 1125 + return device_for_each_child_reverse(&adev->dev, &adwc, acpi_dev_for_one_check); 1114 1126 } 1115 1127 1116 1128 /* -------------------------------------------------------------------------- ··· 1414 1402 1415 1403 pci_mmcfg_late_init(); 1416 1404 acpi_iort_init(); 1405 + acpi_viot_early_init(); 1417 1406 acpi_hest_init(); 1418 1407 acpi_ghes_init(); 1419 1408 acpi_scan_init();
+9 -8
drivers/acpi/container.c
··· 23 23 24 24 #ifdef CONFIG_ACPI_CONTAINER 25 25 26 + static int check_offline(struct acpi_device *adev, void *not_used) 27 + { 28 + if (acpi_scan_is_offline(adev, false)) 29 + return 0; 30 + 31 + return -EBUSY; 32 + } 33 + 26 34 static int acpi_container_offline(struct container_dev *cdev) 27 35 { 28 - struct acpi_device *adev = ACPI_COMPANION(&cdev->dev); 29 - struct acpi_device *child; 30 - 31 36 /* Check all of the dependent devices' physical companions. */ 32 - list_for_each_entry(child, &adev->children, node) 33 - if (!acpi_scan_is_offline(child, false)) 34 - return -EBUSY; 35 - 36 - return 0; 37 + return acpi_dev_for_each_child(ACPI_COMPANION(&cdev->dev), check_offline, NULL); 37 38 } 38 39 39 40 static void acpi_container_release(struct device *dev)
+24 -30
drivers/acpi/cppc_acpi.c
··· 618 618 return 0; 619 619 } 620 620 621 - /* Check if CPPC revision + num_ent combination is supported */ 622 - static bool is_cppc_supported(int revision, int num_ent) 623 - { 624 - int expected_num_ent; 625 - 626 - switch (revision) { 627 - case CPPC_V2_REV: 628 - expected_num_ent = CPPC_V2_NUM_ENT; 629 - break; 630 - case CPPC_V3_REV: 631 - expected_num_ent = CPPC_V3_NUM_ENT; 632 - break; 633 - default: 634 - pr_debug("Firmware exports unsupported CPPC revision: %d\n", 635 - revision); 636 - return false; 637 - } 638 - 639 - if (expected_num_ent != num_ent) { 640 - pr_debug("Firmware exports %d entries. Expected: %d for CPPC rev:%d\n", 641 - num_ent, expected_num_ent, revision); 642 - return false; 643 - } 644 - 645 - return true; 646 - } 647 - 648 621 /* 649 622 * An example CPC table looks like the following. 650 623 * ··· 706 733 cpc_obj->type, pr->id); 707 734 goto out_free; 708 735 } 709 - cpc_ptr->num_entries = num_ent; 710 736 711 737 /* Second entry should be revision. */ 712 738 cpc_obj = &out_obj->package.elements[1]; ··· 716 744 cpc_obj->type, pr->id); 717 745 goto out_free; 718 746 } 719 - cpc_ptr->version = cpc_rev; 720 747 721 - if (!is_cppc_supported(cpc_rev, num_ent)) 748 + if (cpc_rev < CPPC_V2_REV) { 749 + pr_debug("Unsupported _CPC Revision (%d) for CPU:%d\n", cpc_rev, 750 + pr->id); 722 751 goto out_free; 752 + } 753 + 754 + /* 755 + * Disregard _CPC if the number of entries in the return pachage is not 756 + * as expected, but support future revisions being proper supersets of 757 + * the v3 and only causing more entries to be returned by _CPC. 758 + */ 759 + if ((cpc_rev == CPPC_V2_REV && num_ent != CPPC_V2_NUM_ENT) || 760 + (cpc_rev == CPPC_V3_REV && num_ent != CPPC_V3_NUM_ENT) || 761 + (cpc_rev > CPPC_V3_REV && num_ent <= CPPC_V3_NUM_ENT)) { 762 + pr_debug("Unexpected number of _CPC return package entries (%d) for CPU:%d\n", 763 + num_ent, pr->id); 764 + goto out_free; 765 + } 766 + if (cpc_rev > CPPC_V3_REV) { 767 + num_ent = CPPC_V3_NUM_ENT; 768 + cpc_rev = CPPC_V3_REV; 769 + } 770 + 771 + cpc_ptr->num_entries = num_ent; 772 + cpc_ptr->version = cpc_rev; 723 773 724 774 /* Iterate through remaining entries in _CPC */ 725 775 for (i = 2; i < num_ent; i++) {
+22
drivers/acpi/device_pm.c
··· 369 369 } 370 370 EXPORT_SYMBOL_GPL(acpi_device_fix_up_power); 371 371 372 + static int fix_up_power_if_applicable(struct acpi_device *adev, void *not_used) 373 + { 374 + if (adev->status.present && adev->status.enabled) 375 + acpi_device_fix_up_power(adev); 376 + 377 + return 0; 378 + } 379 + 380 + /** 381 + * acpi_device_fix_up_power_extended - Force device and its children into D0. 382 + * @adev: Parent device object whose power state is to be fixed up. 383 + * 384 + * Call acpi_device_fix_up_power() for @adev and its children so long as they 385 + * are reported as present and enabled. 386 + */ 387 + void acpi_device_fix_up_power_extended(struct acpi_device *adev) 388 + { 389 + acpi_device_fix_up_power(adev); 390 + acpi_dev_for_each_child(adev, fix_up_power_if_applicable, NULL); 391 + } 392 + EXPORT_SYMBOL_GPL(acpi_device_fix_up_power_extended); 393 + 372 394 int acpi_device_update_power(struct acpi_device *device, int *state_p) 373 395 { 374 396 int state;
+1 -1
drivers/acpi/device_sysfs.c
··· 376 376 return -EINVAL; 377 377 378 378 if ((!acpi_device->handler || !acpi_device->handler->hotplug.enabled) 379 - && !acpi_device->driver) 379 + && !d->driver) 380 380 return -ENODEV; 381 381 382 382 status = acpi_get_type(acpi_device->handle, &not_used);
+48 -92
drivers/acpi/ec.c
··· 180 180 static struct workqueue_struct *ec_query_wq; 181 181 182 182 static int EC_FLAGS_CORRECT_ECDT; /* Needs ECDT port address correction */ 183 - static int EC_FLAGS_IGNORE_DSDT_GPE; /* Needs ECDT GPE as correction setting */ 184 183 static int EC_FLAGS_TRUST_DSDT_GPE; /* Needs DSDT GPE as correction setting */ 185 184 static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */ 186 185 ··· 1406 1407 if (ec->data_addr == 0 || ec->command_addr == 0) 1407 1408 return AE_OK; 1408 1409 1409 - if (boot_ec && boot_ec_is_ecdt && EC_FLAGS_IGNORE_DSDT_GPE) { 1410 - /* 1411 - * Always inherit the GPE number setting from the ECDT 1412 - * EC. 1413 - */ 1414 - ec->gpe = boot_ec->gpe; 1415 - } else { 1416 - /* Get GPE bit assignment (EC events). */ 1417 - /* TODO: Add support for _GPE returning a package */ 1418 - status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp); 1419 - if (ACPI_SUCCESS(status)) 1420 - ec->gpe = tmp; 1410 + /* Get GPE bit assignment (EC events). */ 1411 + /* TODO: Add support for _GPE returning a package */ 1412 + status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp); 1413 + if (ACPI_SUCCESS(status)) 1414 + ec->gpe = tmp; 1415 + /* 1416 + * Errors are non-fatal, allowing for ACPI Reduced Hardware 1417 + * platforms which use GpioInt instead of GPE. 1418 + */ 1421 1419 1422 - /* 1423 - * Errors are non-fatal, allowing for ACPI Reduced Hardware 1424 - * platforms which use GpioInt instead of GPE. 1425 - */ 1426 - } 1427 1420 /* Use the global lock for all EC transactions? */ 1428 1421 tmp = 0; 1429 1422 acpi_evaluate_integer(handle, "_GLK", NULL, &tmp); ··· 1617 1626 } 1618 1627 1619 1628 if (boot_ec && ec->command_addr == boot_ec->command_addr && 1620 - ec->data_addr == boot_ec->data_addr && 1621 - !EC_FLAGS_TRUST_DSDT_GPE) { 1629 + ec->data_addr == boot_ec->data_addr) { 1622 1630 /* 1623 - * Trust PNP0C09 namespace location rather than 1624 - * ECDT ID. But trust ECDT GPE rather than _GPE 1625 - * because of ASUS quirks, so do not change 1626 - * boot_ec->gpe to ec->gpe. 1631 + * Trust PNP0C09 namespace location rather than ECDT ID. 1632 + * But trust ECDT GPE rather than _GPE because of ASUS 1633 + * quirks. So do not change boot_ec->gpe to ec->gpe, 1634 + * except when the TRUST_DSDT_GPE quirk is set. 1627 1635 */ 1628 1636 boot_ec->handle = ec->handle; 1637 + 1638 + if (EC_FLAGS_TRUST_DSDT_GPE) 1639 + boot_ec->gpe = ec->gpe; 1640 + 1629 1641 acpi_handle_debug(ec->handle, "duplicated.\n"); 1630 1642 acpi_ec_free(ec); 1631 1643 ec = boot_ec; ··· 1856 1862 return 0; 1857 1863 } 1858 1864 1859 - /* 1860 - * Some DSDTs contain wrong GPE setting. 1861 - * Asus FX502VD/VE, GL702VMK, X550VXK, X580VD 1862 - * https://bugzilla.kernel.org/show_bug.cgi?id=195651 1863 - */ 1864 - static int ec_honor_ecdt_gpe(const struct dmi_system_id *id) 1865 - { 1866 - pr_debug("Detected system needing ignore DSDT GPE setting.\n"); 1867 - EC_FLAGS_IGNORE_DSDT_GPE = 1; 1868 - return 0; 1869 - } 1870 - 1871 1865 static const struct dmi_system_id ec_dmi_table[] __initconst = { 1872 1866 { 1873 - ec_correct_ecdt, "MSI MS-171F", { 1874 - DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star"), 1875 - DMI_MATCH(DMI_PRODUCT_NAME, "MS-171F"),}, NULL}, 1867 + /* 1868 + * MSI MS-171F 1869 + * https://bugzilla.kernel.org/show_bug.cgi?id=12461 1870 + */ 1871 + .callback = ec_correct_ecdt, 1872 + .matches = { 1873 + DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star"), 1874 + DMI_MATCH(DMI_PRODUCT_NAME, "MS-171F"), 1875 + }, 1876 + }, 1876 1877 { 1877 - ec_honor_ecdt_gpe, "ASUS FX502VD", { 1878 - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 1879 - DMI_MATCH(DMI_PRODUCT_NAME, "FX502VD"),}, NULL}, 1878 + /* 1879 + * HP Pavilion Gaming Laptop 15-cx0xxx 1880 + * https://bugzilla.kernel.org/show_bug.cgi?id=209989 1881 + */ 1882 + .callback = ec_honor_dsdt_gpe, 1883 + .matches = { 1884 + DMI_MATCH(DMI_SYS_VENDOR, "HP"), 1885 + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Gaming Laptop 15-cx0xxx"), 1886 + }, 1887 + }, 1880 1888 { 1881 - ec_honor_ecdt_gpe, "ASUS FX502VE", { 1882 - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 1883 - DMI_MATCH(DMI_PRODUCT_NAME, "FX502VE"),}, NULL}, 1884 - { 1885 - ec_honor_ecdt_gpe, "ASUS GL702VMK", { 1886 - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 1887 - DMI_MATCH(DMI_PRODUCT_NAME, "GL702VMK"),}, NULL}, 1888 - { 1889 - ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X505BA", { 1890 - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 1891 - DMI_MATCH(DMI_PRODUCT_NAME, "X505BA"),}, NULL}, 1892 - { 1893 - ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X505BP", { 1894 - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 1895 - DMI_MATCH(DMI_PRODUCT_NAME, "X505BP"),}, NULL}, 1896 - { 1897 - ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X542BA", { 1898 - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 1899 - DMI_MATCH(DMI_PRODUCT_NAME, "X542BA"),}, NULL}, 1900 - { 1901 - ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X542BP", { 1902 - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 1903 - DMI_MATCH(DMI_PRODUCT_NAME, "X542BP"),}, NULL}, 1904 - { 1905 - ec_honor_ecdt_gpe, "ASUS X550VXK", { 1906 - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 1907 - DMI_MATCH(DMI_PRODUCT_NAME, "X550VXK"),}, NULL}, 1908 - { 1909 - ec_honor_ecdt_gpe, "ASUS X580VD", { 1910 - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 1911 - DMI_MATCH(DMI_PRODUCT_NAME, "X580VD"),}, NULL}, 1912 - { 1913 - /* https://bugzilla.kernel.org/show_bug.cgi?id=209989 */ 1914 - ec_honor_dsdt_gpe, "HP Pavilion Gaming Laptop 15-cx0xxx", { 1915 - DMI_MATCH(DMI_SYS_VENDOR, "HP"), 1916 - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Gaming Laptop 15-cx0xxx"),}, NULL}, 1917 - { 1918 - ec_clear_on_resume, "Samsung hardware", { 1919 - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL}, 1920 - {}, 1889 + /* 1890 + * Samsung hardware 1891 + * https://bugzilla.kernel.org/show_bug.cgi?id=44161 1892 + */ 1893 + .callback = ec_clear_on_resume, 1894 + .matches = { 1895 + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), 1896 + }, 1897 + }, 1898 + {} 1921 1899 }; 1922 1900 1923 1901 void __init acpi_ec_ecdt_probe(void) ··· 2167 2201 2168 2202 static const struct dmi_system_id acpi_ec_no_wakeup[] = { 2169 2203 { 2170 - .ident = "Thinkpad X1 Carbon 6th", 2171 2204 .matches = { 2172 2205 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 2173 2206 DMI_MATCH(DMI_PRODUCT_FAMILY, "Thinkpad X1 Carbon 6th"), 2174 2207 }, 2175 2208 }, 2176 2209 { 2177 - .ident = "ThinkPad X1 Carbon 6th", 2178 - .matches = { 2179 - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 2180 - DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Carbon 6th"), 2181 - }, 2182 - }, 2183 - { 2184 - .ident = "ThinkPad X1 Yoga 3rd", 2185 2210 .matches = { 2186 2211 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 2187 2212 DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Yoga 3rd"), 2188 2213 }, 2189 2214 }, 2190 2215 { 2191 - .ident = "HP ZHAN 66 Pro", 2192 2216 .matches = { 2193 2217 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 2194 2218 DMI_MATCH(DMI_PRODUCT_FAMILY, "103C_5336AN HP ZHAN 66 Pro"),
+96 -43
drivers/acpi/glue.c
··· 77 77 #define FIND_CHILD_MIN_SCORE 1 78 78 #define FIND_CHILD_MAX_SCORE 2 79 79 80 + static int match_any(struct acpi_device *adev, void *not_used) 81 + { 82 + return 1; 83 + } 84 + 85 + static bool acpi_dev_has_children(struct acpi_device *adev) 86 + { 87 + return acpi_dev_for_each_child(adev, match_any, NULL) > 0; 88 + } 89 + 80 90 static int find_child_checks(struct acpi_device *adev, bool check_children) 81 91 { 82 92 unsigned long long sta; 83 93 acpi_status status; 84 94 85 - if (check_children && list_empty(&adev->children)) 95 + if (check_children && !acpi_dev_has_children(adev)) 86 96 return -ENODEV; 87 97 88 98 status = acpi_evaluate_integer(adev->handle, "_STA", NULL, &sta); ··· 115 105 return FIND_CHILD_MAX_SCORE; 116 106 } 117 107 108 + struct find_child_walk_data { 109 + struct acpi_device *adev; 110 + u64 address; 111 + int score; 112 + bool check_sta; 113 + bool check_children; 114 + }; 115 + 116 + static int check_one_child(struct acpi_device *adev, void *data) 117 + { 118 + struct find_child_walk_data *wd = data; 119 + int score; 120 + 121 + if (!adev->pnp.type.bus_address || acpi_device_adr(adev) != wd->address) 122 + return 0; 123 + 124 + if (!wd->adev) { 125 + /* 126 + * This is the first matching object, so save it. If it is not 127 + * necessary to look for any other matching objects, stop the 128 + * search. 129 + */ 130 + wd->adev = adev; 131 + return !(wd->check_sta || wd->check_children); 132 + } 133 + 134 + /* 135 + * There is more than one matching device object with the same _ADR 136 + * value. That really is unexpected, so we are kind of beyond the scope 137 + * of the spec here. We have to choose which one to return, though. 138 + * 139 + * First, get the score for the previously found object and terminate 140 + * the walk if it is maximum. 141 + */ 142 + if (!wd->score) { 143 + score = find_child_checks(wd->adev, wd->check_children); 144 + if (score == FIND_CHILD_MAX_SCORE) 145 + return 1; 146 + 147 + wd->score = score; 148 + } 149 + /* 150 + * Second, if the object that has just been found has a better score, 151 + * replace the previously found one with it and terminate the walk if 152 + * the new score is maximum. 153 + */ 154 + score = find_child_checks(adev, wd->check_children); 155 + if (score > wd->score) { 156 + wd->adev = adev; 157 + if (score == FIND_CHILD_MAX_SCORE) 158 + return 1; 159 + 160 + wd->score = score; 161 + } 162 + 163 + /* Continue, because there may be better matches. */ 164 + return 0; 165 + } 166 + 167 + static struct acpi_device *acpi_find_child(struct acpi_device *parent, 168 + u64 address, bool check_children, 169 + bool check_sta) 170 + { 171 + struct find_child_walk_data wd = { 172 + .address = address, 173 + .check_children = check_children, 174 + .check_sta = check_sta, 175 + .adev = NULL, 176 + .score = 0, 177 + }; 178 + 179 + if (parent) 180 + acpi_dev_for_each_child(parent, check_one_child, &wd); 181 + 182 + return wd.adev; 183 + } 184 + 118 185 struct acpi_device *acpi_find_child_device(struct acpi_device *parent, 119 186 u64 address, bool check_children) 120 187 { 121 - struct acpi_device *adev, *ret = NULL; 122 - int ret_score = 0; 123 - 124 - if (!parent) 125 - return NULL; 126 - 127 - list_for_each_entry(adev, &parent->children, node) { 128 - acpi_bus_address addr = acpi_device_adr(adev); 129 - int score; 130 - 131 - if (!adev->pnp.type.bus_address || addr != address) 132 - continue; 133 - 134 - if (!ret) { 135 - /* This is the first matching object. Save it. */ 136 - ret = adev; 137 - continue; 138 - } 139 - /* 140 - * There is more than one matching device object with the same 141 - * _ADR value. That really is unexpected, so we are kind of 142 - * beyond the scope of the spec here. We have to choose which 143 - * one to return, though. 144 - * 145 - * First, check if the previously found object is good enough 146 - * and return it if so. Second, do the same for the object that 147 - * we've just found. 148 - */ 149 - if (!ret_score) { 150 - ret_score = find_child_checks(ret, check_children); 151 - if (ret_score == FIND_CHILD_MAX_SCORE) 152 - return ret; 153 - } 154 - score = find_child_checks(adev, check_children); 155 - if (score == FIND_CHILD_MAX_SCORE) { 156 - return adev; 157 - } else if (score > ret_score) { 158 - ret = adev; 159 - ret_score = score; 160 - } 161 - } 162 - return ret; 188 + return acpi_find_child(parent, address, check_children, true); 163 189 } 164 190 EXPORT_SYMBOL_GPL(acpi_find_child_device); 191 + 192 + struct acpi_device *acpi_find_child_by_adr(struct acpi_device *adev, 193 + acpi_bus_address adr) 194 + { 195 + return acpi_find_child(adev, adr, false, false); 196 + } 197 + EXPORT_SYMBOL_GPL(acpi_find_child_by_adr); 165 198 166 199 static void acpi_physnode_link_name(char *buf, unsigned int node_id) 167 200 {
+4 -4
drivers/acpi/pci_link.c
··· 95 95 case ACPI_RESOURCE_TYPE_IRQ: 96 96 { 97 97 struct acpi_resource_irq *p = &resource->data.irq; 98 - if (!p || !p->interrupt_count) { 98 + if (!p->interrupt_count) { 99 99 acpi_handle_debug(handle, 100 100 "Blank _PRS IRQ resource\n"); 101 101 return AE_OK; ··· 121 121 { 122 122 struct acpi_resource_extended_irq *p = 123 123 &resource->data.extended_irq; 124 - if (!p || !p->interrupt_count) { 124 + if (!p->interrupt_count) { 125 125 acpi_handle_debug(handle, 126 126 "Blank _PRS EXT IRQ resource\n"); 127 127 return AE_OK; ··· 182 182 case ACPI_RESOURCE_TYPE_IRQ: 183 183 { 184 184 struct acpi_resource_irq *p = &resource->data.irq; 185 - if (!p || !p->interrupt_count) { 185 + if (!p->interrupt_count) { 186 186 /* 187 187 * IRQ descriptors may have no IRQ# bits set, 188 188 * particularly those w/ _STA disabled ··· 197 197 { 198 198 struct acpi_resource_extended_irq *p = 199 199 &resource->data.extended_irq; 200 - if (!p || !p->interrupt_count) { 200 + if (!p->interrupt_count) { 201 201 /* 202 202 * extended IRQ descriptors must 203 203 * return at least 1 IRQ
+8 -64
drivers/acpi/processor_driver.c
··· 139 139 } 140 140 141 141 #ifdef CONFIG_ACPI_CPU_FREQ_PSS 142 - static int acpi_pss_perf_init(struct acpi_processor *pr, 143 - struct acpi_device *device) 142 + static void acpi_pss_perf_init(struct acpi_processor *pr) 144 143 { 145 - int result = 0; 146 - 147 144 acpi_processor_ppc_has_changed(pr, 0); 148 145 149 146 acpi_processor_get_throttling_info(pr); 150 147 151 148 if (pr->flags.throttling) 152 149 pr->flags.limit = 1; 153 - 154 - pr->cdev = thermal_cooling_device_register("Processor", device, 155 - &processor_cooling_ops); 156 - if (IS_ERR(pr->cdev)) { 157 - result = PTR_ERR(pr->cdev); 158 - return result; 159 - } 160 - 161 - dev_dbg(&device->dev, "registered as cooling_device%d\n", 162 - pr->cdev->id); 163 - 164 - result = sysfs_create_link(&device->dev.kobj, 165 - &pr->cdev->device.kobj, 166 - "thermal_cooling"); 167 - if (result) { 168 - dev_err(&device->dev, 169 - "Failed to create sysfs link 'thermal_cooling'\n"); 170 - goto err_thermal_unregister; 171 - } 172 - 173 - result = sysfs_create_link(&pr->cdev->device.kobj, 174 - &device->dev.kobj, 175 - "device"); 176 - if (result) { 177 - dev_err(&pr->cdev->device, 178 - "Failed to create sysfs link 'device'\n"); 179 - goto err_remove_sysfs_thermal; 180 - } 181 - 182 - return 0; 183 - 184 - err_remove_sysfs_thermal: 185 - sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); 186 - err_thermal_unregister: 187 - thermal_cooling_device_unregister(pr->cdev); 188 - 189 - return result; 190 - } 191 - 192 - static void acpi_pss_perf_exit(struct acpi_processor *pr, 193 - struct acpi_device *device) 194 - { 195 - if (pr->cdev) { 196 - sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); 197 - sysfs_remove_link(&pr->cdev->device.kobj, "device"); 198 - thermal_cooling_device_unregister(pr->cdev); 199 - pr->cdev = NULL; 200 - } 201 150 } 202 151 #else 203 - static inline int acpi_pss_perf_init(struct acpi_processor *pr, 204 - struct acpi_device *device) 205 - { 206 - return 0; 207 - } 208 - 209 - static inline void acpi_pss_perf_exit(struct acpi_processor *pr, 210 - struct acpi_device *device) {} 152 + static inline void acpi_pss_perf_init(struct acpi_processor *pr) {} 211 153 #endif /* CONFIG_ACPI_CPU_FREQ_PSS */ 212 154 213 155 static int __acpi_processor_start(struct acpi_device *device) ··· 171 229 if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver) 172 230 acpi_processor_power_init(pr); 173 231 174 - result = acpi_pss_perf_init(pr, device); 232 + acpi_pss_perf_init(pr); 233 + 234 + result = acpi_processor_thermal_init(pr, device); 175 235 if (result) 176 236 goto err_power_exit; 177 237 ··· 183 239 return 0; 184 240 185 241 result = -ENODEV; 186 - acpi_pss_perf_exit(pr, device); 242 + acpi_processor_thermal_exit(pr, device); 187 243 188 244 err_power_exit: 189 245 acpi_processor_power_exit(pr); ··· 221 277 return 0; 222 278 acpi_processor_power_exit(pr); 223 279 224 - acpi_pss_perf_exit(pr, device); 225 - 226 280 acpi_cppc_processor_exit(pr); 281 + 282 + acpi_processor_thermal_exit(pr, device); 227 283 228 284 return 0; 229 285 }
+3 -3
drivers/acpi/processor_idle.c
··· 607 607 * @cx: Target state context 608 608 * @index: index of target state 609 609 */ 610 - static int acpi_idle_enter_bm(struct cpuidle_driver *drv, 610 + static int __cpuidle acpi_idle_enter_bm(struct cpuidle_driver *drv, 611 611 struct acpi_processor *pr, 612 612 struct acpi_processor_cx *cx, 613 613 int index) ··· 664 664 return index; 665 665 } 666 666 667 - static int acpi_idle_enter(struct cpuidle_device *dev, 667 + static int __cpuidle acpi_idle_enter(struct cpuidle_device *dev, 668 668 struct cpuidle_driver *drv, int index) 669 669 { 670 670 struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); ··· 693 693 return index; 694 694 } 695 695 696 - static int acpi_idle_enter_s2idle(struct cpuidle_device *dev, 696 + static int __cpuidle acpi_idle_enter_s2idle(struct cpuidle_device *dev, 697 697 struct cpuidle_driver *drv, int index) 698 698 { 699 699 struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu);
+54
drivers/acpi/processor_thermal.c
··· 266 266 .get_cur_state = processor_get_cur_state, 267 267 .set_cur_state = processor_set_cur_state, 268 268 }; 269 + 270 + int acpi_processor_thermal_init(struct acpi_processor *pr, 271 + struct acpi_device *device) 272 + { 273 + int result = 0; 274 + 275 + pr->cdev = thermal_cooling_device_register("Processor", device, 276 + &processor_cooling_ops); 277 + if (IS_ERR(pr->cdev)) { 278 + result = PTR_ERR(pr->cdev); 279 + return result; 280 + } 281 + 282 + dev_dbg(&device->dev, "registered as cooling_device%d\n", 283 + pr->cdev->id); 284 + 285 + result = sysfs_create_link(&device->dev.kobj, 286 + &pr->cdev->device.kobj, 287 + "thermal_cooling"); 288 + if (result) { 289 + dev_err(&device->dev, 290 + "Failed to create sysfs link 'thermal_cooling'\n"); 291 + goto err_thermal_unregister; 292 + } 293 + 294 + result = sysfs_create_link(&pr->cdev->device.kobj, 295 + &device->dev.kobj, 296 + "device"); 297 + if (result) { 298 + dev_err(&pr->cdev->device, 299 + "Failed to create sysfs link 'device'\n"); 300 + goto err_remove_sysfs_thermal; 301 + } 302 + 303 + return 0; 304 + 305 + err_remove_sysfs_thermal: 306 + sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); 307 + err_thermal_unregister: 308 + thermal_cooling_device_unregister(pr->cdev); 309 + 310 + return result; 311 + } 312 + 313 + void acpi_processor_thermal_exit(struct acpi_processor *pr, 314 + struct acpi_device *device) 315 + { 316 + if (pr->cdev) { 317 + sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); 318 + sysfs_remove_link(&pr->cdev->device.kobj, "device"); 319 + thermal_cooling_device_unregister(pr->cdev); 320 + pr->cdev = NULL; 321 + } 322 + }
+24 -21
drivers/acpi/property.c
··· 1012 1012 propname, proptype, val, nval); 1013 1013 } 1014 1014 1015 + static int stop_on_next(struct acpi_device *adev, void *data) 1016 + { 1017 + struct acpi_device **ret_p = data; 1018 + 1019 + if (!*ret_p) { 1020 + *ret_p = adev; 1021 + return 1; 1022 + } 1023 + 1024 + /* Skip until the "previous" object is found. */ 1025 + if (*ret_p == adev) 1026 + *ret_p = NULL; 1027 + 1028 + return 0; 1029 + } 1030 + 1015 1031 /** 1016 1032 * acpi_get_next_subnode - Return the next child node handle for a fwnode 1017 1033 * @fwnode: Firmware node to find the next child node for. ··· 1036 1020 struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode, 1037 1021 struct fwnode_handle *child) 1038 1022 { 1039 - const struct acpi_device *adev = to_acpi_device_node(fwnode); 1040 - const struct list_head *head; 1041 - struct list_head *next; 1023 + struct acpi_device *adev = to_acpi_device_node(fwnode); 1042 1024 1043 1025 if ((!child || is_acpi_device_node(child)) && adev) { 1044 - struct acpi_device *child_adev; 1026 + struct acpi_device *child_adev = to_acpi_device_node(child); 1045 1027 1046 - head = &adev->children; 1047 - if (list_empty(head)) 1048 - goto nondev; 1028 + acpi_dev_for_each_child(adev, stop_on_next, &child_adev); 1029 + if (child_adev) 1030 + return acpi_fwnode_handle(child_adev); 1049 1031 1050 - if (child) { 1051 - adev = to_acpi_device_node(child); 1052 - next = adev->node.next; 1053 - if (next == head) { 1054 - child = NULL; 1055 - goto nondev; 1056 - } 1057 - child_adev = list_entry(next, struct acpi_device, node); 1058 - } else { 1059 - child_adev = list_first_entry(head, struct acpi_device, 1060 - node); 1061 - } 1062 - return acpi_fwnode_handle(child_adev); 1032 + child = NULL; 1063 1033 } 1064 1034 1065 - nondev: 1066 1035 if (!child || is_acpi_data_node(child)) { 1067 1036 const struct acpi_data_node *data = to_acpi_data_node(fwnode); 1037 + const struct list_head *head; 1038 + struct list_head *next; 1068 1039 struct acpi_data_node *dn; 1069 1040 1070 1041 /*
+10
drivers/acpi/resource.c
··· 416 416 { 417 417 int i; 418 418 419 + #ifdef CONFIG_X86 420 + /* 421 + * IRQ override isn't needed on modern AMD Zen systems and 422 + * this override breaks active low IRQs on AMD Ryzen 6000 and 423 + * newer systems. Skip it. 424 + */ 425 + if (boot_cpu_has(X86_FEATURE_ZEN)) 426 + return false; 427 + #endif 428 + 419 429 for (i = 0; i < ARRAY_SIZE(skip_override_table); i++) { 420 430 const struct irq_override_cmp *entry = &skip_override_table[i]; 421 431
+30 -40
drivers/acpi/scan.c
··· 334 334 return error; 335 335 } 336 336 337 - static int acpi_scan_bus_check(struct acpi_device *adev) 337 + static int acpi_scan_bus_check(struct acpi_device *adev, void *not_used) 338 338 { 339 339 struct acpi_scan_handler *handler = adev->handler; 340 - struct acpi_device *child; 341 340 int error; 342 341 343 342 acpi_bus_get_status(adev); ··· 352 353 dev_warn(&adev->dev, "Namespace scan failure\n"); 353 354 return error; 354 355 } 355 - list_for_each_entry(child, &adev->children, node) { 356 - error = acpi_scan_bus_check(child); 357 - if (error) 358 - return error; 359 - } 360 - return 0; 356 + return acpi_dev_for_each_child(adev, acpi_scan_bus_check, NULL); 361 357 } 362 358 363 359 static int acpi_generic_hotplug_event(struct acpi_device *adev, u32 type) 364 360 { 365 361 switch (type) { 366 362 case ACPI_NOTIFY_BUS_CHECK: 367 - return acpi_scan_bus_check(adev); 363 + return acpi_scan_bus_check(adev, NULL); 368 364 case ACPI_NOTIFY_DEVICE_CHECK: 369 365 return acpi_scan_device_check(adev); 370 366 case ACPI_NOTIFY_EJECT_REQUEST: ··· 465 471 struct acpi_device_bus_id *acpi_device_bus_id; 466 472 467 473 mutex_lock(&acpi_device_lock); 468 - if (device->parent) 469 - list_del(&device->node); 470 474 471 475 list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) 472 476 if (!strcmp(acpi_device_bus_id->bus_id, ··· 480 488 } 481 489 482 490 list_del(&device->wakeup_list); 491 + 483 492 mutex_unlock(&acpi_device_lock); 484 493 485 494 acpi_power_add_remove_device(device, false); ··· 673 680 * ------- 674 681 * Link this device to its parent and siblings. 675 682 */ 676 - INIT_LIST_HEAD(&device->children); 677 - INIT_LIST_HEAD(&device->node); 678 683 INIT_LIST_HEAD(&device->wakeup_list); 679 684 INIT_LIST_HEAD(&device->physical_node_list); 680 685 INIT_LIST_HEAD(&device->del_list); ··· 712 721 list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); 713 722 } 714 723 715 - if (device->parent) 716 - list_add_tail(&device->node, &device->parent->children); 717 - 718 724 if (device->wakeup.flags.valid) 719 725 list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list); 720 726 ··· 739 751 740 752 err: 741 753 mutex_lock(&acpi_device_lock); 742 - 743 - if (device->parent) 744 - list_del(&device->node); 745 754 746 755 list_del(&device->wakeup_list); 747 756 ··· 2172 2187 return ret; 2173 2188 } 2174 2189 2175 - static void acpi_bus_attach(struct acpi_device *device, bool first_pass) 2190 + static int acpi_bus_attach(struct acpi_device *device, void *first_pass) 2176 2191 { 2177 - struct acpi_device *child; 2178 2192 bool skip = !first_pass && device->flags.visited; 2179 2193 acpi_handle ejd; 2180 2194 int ret; ··· 2190 2206 device->flags.initialized = false; 2191 2207 acpi_device_clear_enumerated(device); 2192 2208 device->flags.power_manageable = 0; 2193 - return; 2209 + return 0; 2194 2210 } 2195 2211 if (device->handler) 2196 2212 goto ok; ··· 2208 2224 2209 2225 ret = acpi_scan_attach_handler(device); 2210 2226 if (ret < 0) 2211 - return; 2227 + return 0; 2212 2228 2213 2229 device->flags.match_driver = true; 2214 2230 if (ret > 0 && !device->flags.enumeration_by_parent) { ··· 2218 2234 2219 2235 ret = device_attach(&device->dev); 2220 2236 if (ret < 0) 2221 - return; 2237 + return 0; 2222 2238 2223 2239 if (device->pnp.type.platform_id || device->flags.enumeration_by_parent) 2224 2240 acpi_default_enumeration(device); 2225 2241 else 2226 2242 acpi_device_set_enumerated(device); 2227 2243 2228 - ok: 2229 - list_for_each_entry(child, &device->children, node) 2230 - acpi_bus_attach(child, first_pass); 2244 + ok: 2245 + acpi_dev_for_each_child(device, acpi_bus_attach, first_pass); 2231 2246 2232 2247 if (!skip && device->handler && device->handler->hotplug.notify_online) 2233 2248 device->handler->hotplug.notify_online(device); 2249 + 2250 + return 0; 2234 2251 } 2235 2252 2236 2253 static int acpi_dev_get_first_consumer_dev_cb(struct acpi_dep_data *dep, void *data) ··· 2259 2274 cdw = container_of(work, struct acpi_scan_clear_dep_work, work); 2260 2275 2261 2276 acpi_scan_lock_acquire(); 2262 - acpi_bus_attach(cdw->adev, true); 2277 + acpi_bus_attach(cdw->adev, (void *)true); 2263 2278 acpi_scan_lock_release(); 2264 2279 2265 2280 acpi_dev_put(cdw->adev); ··· 2417 2432 if (!device) 2418 2433 return -ENODEV; 2419 2434 2420 - acpi_bus_attach(device, true); 2435 + acpi_bus_attach(device, (void *)true); 2421 2436 2422 2437 if (!acpi_bus_scan_second_pass) 2423 2438 return 0; ··· 2431 2446 acpi_bus_check_add_2, NULL, NULL, 2432 2447 (void **)&device); 2433 2448 2434 - acpi_bus_attach(device, false); 2449 + acpi_bus_attach(device, NULL); 2435 2450 2436 2451 return 0; 2437 2452 } 2438 2453 EXPORT_SYMBOL(acpi_bus_scan); 2439 2454 2440 - /** 2441 - * acpi_bus_trim - Detach scan handlers and drivers from ACPI device objects. 2442 - * @adev: Root of the ACPI namespace scope to walk. 2443 - * 2444 - * Must be called under acpi_scan_lock. 2445 - */ 2446 - void acpi_bus_trim(struct acpi_device *adev) 2455 + static int acpi_bus_trim_one(struct acpi_device *adev, void *not_used) 2447 2456 { 2448 2457 struct acpi_scan_handler *handler = adev->handler; 2449 - struct acpi_device *child; 2450 2458 2451 - list_for_each_entry_reverse(child, &adev->children, node) 2452 - acpi_bus_trim(child); 2459 + acpi_dev_for_each_child_reverse(adev, acpi_bus_trim_one, NULL); 2453 2460 2454 2461 adev->flags.match_driver = false; 2455 2462 if (handler) { ··· 2459 2482 acpi_device_set_power(adev, ACPI_STATE_D3_COLD); 2460 2483 adev->flags.initialized = false; 2461 2484 acpi_device_clear_enumerated(adev); 2485 + 2486 + return 0; 2487 + } 2488 + 2489 + /** 2490 + * acpi_bus_trim - Detach scan handlers and drivers from ACPI device objects. 2491 + * @adev: Root of the ACPI namespace scope to walk. 2492 + * 2493 + * Must be called under acpi_scan_lock. 2494 + */ 2495 + void acpi_bus_trim(struct acpi_device *adev) 2496 + { 2497 + acpi_bus_trim_one(adev, NULL); 2462 2498 } 2463 2499 EXPORT_SYMBOL_GPL(acpi_bus_trim); 2464 2500
+11
drivers/acpi/sleep.c
··· 360 360 DMI_MATCH(DMI_PRODUCT_NAME, "80E3"), 361 361 }, 362 362 }, 363 + { 364 + .callback = init_nvs_save_s3, 365 + .ident = "Lenovo G40-45", 366 + .matches = { 367 + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 368 + DMI_MATCH(DMI_PRODUCT_NAME, "80E1"), 369 + }, 370 + }, 363 371 /* 364 372 * ThinkPad X1 Tablet(2016) cannot do suspend-to-idle using 365 373 * the Low Power S0 Idle firmware interface (see ··· 824 816 825 817 void __weak acpi_s2idle_setup(void) 826 818 { 819 + if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) 820 + pr_info("Efficient low-power S0 idle declared\n"); 821 + 827 822 s2idle_set_ops(&acpi_s2idle_ops); 828 823 } 829 824
+48 -25
drivers/acpi/video_detect.c
··· 349 349 }, 350 350 { 351 351 .callback = video_detect_force_native, 352 + /* Dell Inspiron N4010 */ 353 + .matches = { 354 + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 355 + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron N4010"), 356 + }, 357 + }, 358 + { 359 + .callback = video_detect_force_native, 352 360 /* Dell Vostro V131 */ 353 361 .matches = { 354 362 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ··· 438 430 .callback = video_detect_force_native, 439 431 .ident = "Clevo NL5xRU", 440 432 .matches = { 441 - DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 442 - DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), 443 - }, 444 - }, 445 - { 446 - .callback = video_detect_force_native, 447 - .ident = "Clevo NL5xRU", 448 - .matches = { 449 - DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"), 450 - DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), 451 - }, 452 - }, 453 - { 454 - .callback = video_detect_force_native, 455 - .ident = "Clevo NL5xRU", 456 - .matches = { 457 - DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), 458 433 DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), 459 434 }, 460 435 }, ··· 461 470 .callback = video_detect_force_native, 462 471 .ident = "Clevo NL5xNU", 463 472 .matches = { 473 + DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"), 474 + }, 475 + }, 476 + /* 477 + * The TongFang PF5PU1G, PF4NU1F, PF5NU1G, and PF5LUXG/TUXEDO BA15 Gen10, 478 + * Pulse 14/15 Gen1, and Pulse 15 Gen2 have the same problem as the Clevo 479 + * NL5xRU and NL5xNU/TUXEDO Aura 15 Gen1 and Gen2. See the description 480 + * above. 481 + */ 482 + { 483 + .callback = video_detect_force_native, 484 + .ident = "TongFang PF5PU1G", 485 + .matches = { 486 + DMI_MATCH(DMI_BOARD_NAME, "PF5PU1G"), 487 + }, 488 + }, 489 + { 490 + .callback = video_detect_force_native, 491 + .ident = "TongFang PF4NU1F", 492 + .matches = { 493 + DMI_MATCH(DMI_BOARD_NAME, "PF4NU1F"), 494 + }, 495 + }, 496 + { 497 + .callback = video_detect_force_native, 498 + .ident = "TongFang PF4NU1F", 499 + .matches = { 464 500 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 465 - DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"), 501 + DMI_MATCH(DMI_BOARD_NAME, "PULSE1401"), 466 502 }, 467 503 }, 468 504 { 469 505 .callback = video_detect_force_native, 470 - .ident = "Clevo NL5xNU", 506 + .ident = "TongFang PF5NU1G", 471 507 .matches = { 472 - DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"), 473 - DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"), 508 + DMI_MATCH(DMI_BOARD_NAME, "PF5NU1G"), 474 509 }, 475 510 }, 476 511 { 477 512 .callback = video_detect_force_native, 478 - .ident = "Clevo NL5xNU", 513 + .ident = "TongFang PF5NU1G", 479 514 .matches = { 480 - DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), 481 - DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"), 515 + DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 516 + DMI_MATCH(DMI_BOARD_NAME, "PULSE1501"), 482 517 }, 483 518 }, 484 - 519 + { 520 + .callback = video_detect_force_native, 521 + .ident = "TongFang PF5LUXG", 522 + .matches = { 523 + DMI_MATCH(DMI_BOARD_NAME, "PF5LUXG"), 524 + }, 525 + }, 485 526 /* 486 527 * Desktops which falsely report a backlight and which our heuristics 487 528 * for this do not catch.
+20 -6
drivers/acpi/viot.c
··· 249 249 } 250 250 251 251 /** 252 + * acpi_viot_early_init - Test the presence of VIOT and enable ACS 253 + * 254 + * If the VIOT does exist, ACS must be enabled. This cannot be 255 + * done in acpi_viot_init() which is called after the bus scan 256 + */ 257 + void __init acpi_viot_early_init(void) 258 + { 259 + #ifdef CONFIG_PCI 260 + acpi_status status; 261 + struct acpi_table_header *hdr; 262 + 263 + status = acpi_get_table(ACPI_SIG_VIOT, 0, &hdr); 264 + if (ACPI_FAILURE(status)) 265 + return; 266 + pci_request_acs(); 267 + acpi_put_table(hdr); 268 + #endif 269 + } 270 + 271 + /** 252 272 * acpi_viot_init - Parse the VIOT table 253 273 * 254 274 * Parse the VIOT table, prepare the list of endpoints to be used during DMA ··· 338 318 dev_id <= ep->bdf_end) { 339 319 epid = ((domain_nr - ep->segment_start) << 16) + 340 320 dev_id - ep->bdf_start + ep->endpoint_id; 341 - 342 - /* 343 - * If we found a PCI range managed by the viommu, we're 344 - * the one that has to request ACS. 345 - */ 346 - pci_request_acs(); 347 321 348 322 return viot_dev_iommu_init(&pdev->dev, ep->viommu, 349 323 epid);
+10 -7
drivers/acpi/x86/s2idle.c
··· 369 369 if (lps0_device_handle) 370 370 return 0; 371 371 372 - if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) 373 - return 0; 374 - 375 372 if (acpi_s2idle_vendor_amd()) { 376 373 /* AMD0004, AMD0005, AMDI0005: 377 374 * - Should use rev_id 0x0 ··· 394 397 lps0_dsm_func_mask = (lps0_dsm_func_mask << 1) | 0x1; 395 398 acpi_handle_debug(adev->handle, "_DSM UUID %s: Adjusted function mask: 0x%x\n", 396 399 ACPI_LPS0_DSM_UUID_AMD, lps0_dsm_func_mask); 397 - } else if (lps0_dsm_func_mask_microsoft > 0 && !strcmp(hid, "AMDI0007")) { 400 + } else if (lps0_dsm_func_mask_microsoft > 0 && 401 + (!strcmp(hid, "AMDI0007") || 402 + !strcmp(hid, "AMDI0008"))) { 398 403 lps0_dsm_func_mask_microsoft = -EINVAL; 399 404 acpi_handle_debug(adev->handle, "_DSM Using AMD method\n"); 400 405 } ··· 418 419 lpi_device_get_constraints(); 419 420 420 421 /* 421 - * Use suspend-to-idle by default if the default suspend mode was not 422 - * set from the command line. 422 + * Use suspend-to-idle by default if ACPI_FADT_LOW_POWER_S0 is set in 423 + * the FADT and the default suspend mode was not set from the command 424 + * line. 423 425 */ 424 - if (mem_sleep_default > PM_SUSPEND_MEM && !acpi_sleep_default_s3) 426 + if ((acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) && 427 + mem_sleep_default > PM_SUSPEND_MEM && !acpi_sleep_default_s3) { 425 428 mem_sleep_current = PM_SUSPEND_TO_IDLE; 429 + pr_info("Low-power S0 idle used by default for system suspend\n"); 430 + } 426 431 427 432 /* 428 433 * Some LPS0 systems, like ASUS Zenbook UX430UNR/i7-8550U, require the
+101 -103
drivers/bus/hisi_lpc.c
··· 379 379 380 380 /* 381 381 * hisi_lpc_acpi_set_io_res - set the resources for a child 382 - * @child: the device node to be updated the I/O resource 382 + * @adev: ACPI companion of the device node to be updated the I/O resource 383 383 * @hostdev: the device node associated with host controller 384 384 * @res: double pointer to be set to the address of translated resources 385 385 * @num_res: pointer to variable to hold the number of translated resources ··· 390 390 * host-relative address resource. This function will return the translated 391 391 * logical PIO addresses for each child devices resources. 392 392 */ 393 - static int hisi_lpc_acpi_set_io_res(struct device *child, 393 + static int hisi_lpc_acpi_set_io_res(struct acpi_device *adev, 394 394 struct device *hostdev, 395 395 const struct resource **res, int *num_res) 396 396 { 397 - struct acpi_device *adev; 398 - struct acpi_device *host; 397 + struct acpi_device *host = to_acpi_device(adev->dev.parent); 399 398 struct resource_entry *rentry; 400 399 LIST_HEAD(resource_list); 401 400 struct resource *resources; 402 401 int count; 403 402 int i; 404 403 405 - if (!child || !hostdev) 406 - return -EINVAL; 407 - 408 - host = to_acpi_device(hostdev); 409 - adev = to_acpi_device(child); 410 - 411 404 if (!adev->status.present) { 412 - dev_dbg(child, "device is not present\n"); 405 + dev_dbg(&adev->dev, "device is not present\n"); 413 406 return -EIO; 414 407 } 415 408 416 409 if (acpi_device_enumerated(adev)) { 417 - dev_dbg(child, "has been enumerated\n"); 410 + dev_dbg(&adev->dev, "has been enumerated\n"); 418 411 return -EIO; 419 412 } 420 413 ··· 418 425 */ 419 426 count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); 420 427 if (count <= 0) { 421 - dev_dbg(child, "failed to get resources\n"); 428 + dev_dbg(&adev->dev, "failed to get resources\n"); 422 429 return count ? count : -EIO; 423 430 } 424 431 ··· 447 454 continue; 448 455 ret = hisi_lpc_acpi_xlat_io_res(adev, host, &resources[i]); 449 456 if (ret) { 450 - dev_err(child, "translate IO range %pR failed (%d)\n", 457 + dev_err(&adev->dev, "translate IO range %pR failed (%d)\n", 451 458 &resources[i], ret); 452 459 return ret; 453 460 } ··· 464 471 return 0; 465 472 } 466 473 474 + static int hisi_lpc_acpi_clear_enumerated(struct acpi_device *adev, void *not_used) 475 + { 476 + acpi_device_clear_enumerated(adev); 477 + return 0; 478 + } 479 + 467 480 struct hisi_lpc_acpi_cell { 468 481 const char *hid; 469 482 const char *name; ··· 479 480 480 481 static void hisi_lpc_acpi_remove(struct device *hostdev) 481 482 { 482 - struct acpi_device *adev = ACPI_COMPANION(hostdev); 483 - struct acpi_device *child; 484 - 485 483 device_for_each_child(hostdev, NULL, hisi_lpc_acpi_remove_subdev); 484 + acpi_dev_for_each_child(ACPI_COMPANION(hostdev), 485 + hisi_lpc_acpi_clear_enumerated, NULL); 486 + } 486 487 487 - list_for_each_entry(child, &adev->children, node) 488 - acpi_device_clear_enumerated(child); 488 + static int hisi_lpc_acpi_add_child(struct acpi_device *child, void *data) 489 + { 490 + const char *hid = acpi_device_hid(child); 491 + struct device *hostdev = data; 492 + const struct hisi_lpc_acpi_cell *cell; 493 + struct platform_device *pdev; 494 + const struct resource *res; 495 + bool found = false; 496 + int num_res; 497 + int ret; 498 + 499 + ret = hisi_lpc_acpi_set_io_res(child, hostdev, &res, &num_res); 500 + if (ret) { 501 + dev_warn(hostdev, "set resource fail (%d)\n", ret); 502 + return ret; 503 + } 504 + 505 + cell = (struct hisi_lpc_acpi_cell []){ 506 + /* ipmi */ 507 + { 508 + .hid = "IPI0001", 509 + .name = "hisi-lpc-ipmi", 510 + }, 511 + /* 8250-compatible uart */ 512 + { 513 + .hid = "HISI1031", 514 + .name = "serial8250", 515 + .pdata = (struct plat_serial8250_port []) { 516 + { 517 + .iobase = res->start, 518 + .uartclk = 1843200, 519 + .iotype = UPIO_PORT, 520 + .flags = UPF_BOOT_AUTOCONF, 521 + }, 522 + {} 523 + }, 524 + .pdata_size = 2 * 525 + sizeof(struct plat_serial8250_port), 526 + }, 527 + {} 528 + }; 529 + 530 + for (; cell && cell->name; cell++) { 531 + if (!strcmp(cell->hid, hid)) { 532 + found = true; 533 + break; 534 + } 535 + } 536 + 537 + if (!found) { 538 + dev_warn(hostdev, 539 + "could not find cell for child device (%s), discarding\n", 540 + hid); 541 + return 0; 542 + } 543 + 544 + pdev = platform_device_alloc(cell->name, PLATFORM_DEVID_AUTO); 545 + if (!pdev) 546 + return -ENOMEM; 547 + 548 + pdev->dev.parent = hostdev; 549 + ACPI_COMPANION_SET(&pdev->dev, child); 550 + 551 + ret = platform_device_add_resources(pdev, res, num_res); 552 + if (ret) 553 + goto fail; 554 + 555 + ret = platform_device_add_data(pdev, cell->pdata, cell->pdata_size); 556 + if (ret) 557 + goto fail; 558 + 559 + ret = platform_device_add(pdev); 560 + if (ret) 561 + goto fail; 562 + 563 + acpi_device_set_enumerated(child); 564 + return 0; 565 + 566 + fail: 567 + platform_device_put(pdev); 568 + return ret; 489 569 } 490 570 491 571 /* ··· 579 501 */ 580 502 static int hisi_lpc_acpi_probe(struct device *hostdev) 581 503 { 582 - struct acpi_device *adev = ACPI_COMPANION(hostdev); 583 - struct acpi_device *child; 584 504 int ret; 585 505 586 506 /* Only consider the children of the host */ 587 - list_for_each_entry(child, &adev->children, node) { 588 - const char *hid = acpi_device_hid(child); 589 - const struct hisi_lpc_acpi_cell *cell; 590 - struct platform_device *pdev; 591 - const struct resource *res; 592 - bool found = false; 593 - int num_res; 507 + ret = acpi_dev_for_each_child(ACPI_COMPANION(hostdev), 508 + hisi_lpc_acpi_add_child, hostdev); 509 + if (ret) 510 + hisi_lpc_acpi_remove(hostdev); 594 511 595 - ret = hisi_lpc_acpi_set_io_res(&child->dev, &adev->dev, &res, 596 - &num_res); 597 - if (ret) { 598 - dev_warn(hostdev, "set resource fail (%d)\n", ret); 599 - goto fail; 600 - } 601 - 602 - cell = (struct hisi_lpc_acpi_cell []){ 603 - /* ipmi */ 604 - { 605 - .hid = "IPI0001", 606 - .name = "hisi-lpc-ipmi", 607 - }, 608 - /* 8250-compatible uart */ 609 - { 610 - .hid = "HISI1031", 611 - .name = "serial8250", 612 - .pdata = (struct plat_serial8250_port []) { 613 - { 614 - .iobase = res->start, 615 - .uartclk = 1843200, 616 - .iotype = UPIO_PORT, 617 - .flags = UPF_BOOT_AUTOCONF, 618 - }, 619 - {} 620 - }, 621 - .pdata_size = 2 * 622 - sizeof(struct plat_serial8250_port), 623 - }, 624 - {} 625 - }; 626 - 627 - for (; cell && cell->name; cell++) { 628 - if (!strcmp(cell->hid, hid)) { 629 - found = true; 630 - break; 631 - } 632 - } 633 - 634 - if (!found) { 635 - dev_warn(hostdev, 636 - "could not find cell for child device (%s), discarding\n", 637 - hid); 638 - continue; 639 - } 640 - 641 - pdev = platform_device_alloc(cell->name, PLATFORM_DEVID_AUTO); 642 - if (!pdev) { 643 - ret = -ENOMEM; 644 - goto fail; 645 - } 646 - 647 - pdev->dev.parent = hostdev; 648 - ACPI_COMPANION_SET(&pdev->dev, child); 649 - 650 - ret = platform_device_add_resources(pdev, res, num_res); 651 - if (ret) 652 - goto fail; 653 - 654 - ret = platform_device_add_data(pdev, cell->pdata, 655 - cell->pdata_size); 656 - if (ret) 657 - goto fail; 658 - 659 - ret = platform_device_add(pdev); 660 - if (ret) 661 - goto fail; 662 - 663 - acpi_device_set_enumerated(child); 664 - } 665 - 666 - return 0; 667 - 668 - fail: 669 - hisi_lpc_acpi_remove(hostdev); 670 512 return ret; 671 513 } 672 514
+24 -7
drivers/mfd/mfd-core.c
··· 60 60 EXPORT_SYMBOL(mfd_cell_disable); 61 61 62 62 #if IS_ENABLED(CONFIG_ACPI) 63 + struct match_ids_walk_data { 64 + struct acpi_device_id *ids; 65 + struct acpi_device *adev; 66 + }; 67 + 68 + static int match_device_ids(struct acpi_device *adev, void *data) 69 + { 70 + struct match_ids_walk_data *wd = data; 71 + 72 + if (!acpi_match_device_ids(adev, wd->ids)) { 73 + wd->adev = adev; 74 + return 1; 75 + } 76 + 77 + return 0; 78 + } 79 + 63 80 static void mfd_acpi_add_device(const struct mfd_cell *cell, 64 81 struct platform_device *pdev) 65 82 { 66 83 const struct mfd_cell_acpi_match *match = cell->acpi_match; 67 - struct acpi_device *parent, *child; 68 84 struct acpi_device *adev = NULL; 85 + struct acpi_device *parent; 69 86 70 87 parent = ACPI_COMPANION(pdev->dev.parent); 71 88 if (!parent) ··· 100 83 if (match) { 101 84 if (match->pnpid) { 102 85 struct acpi_device_id ids[2] = {}; 86 + struct match_ids_walk_data wd = { 87 + .adev = NULL, 88 + .ids = ids, 89 + }; 103 90 104 91 strlcpy(ids[0].id, match->pnpid, sizeof(ids[0].id)); 105 - list_for_each_entry(child, &parent->children, node) { 106 - if (!acpi_match_device_ids(child, ids)) { 107 - adev = child; 108 - break; 109 - } 110 - } 92 + acpi_dev_for_each_child(parent, match_device_ids, &wd); 93 + adev = wd.adev; 111 94 } else { 112 95 adev = acpi_find_child_device(parent, match->adr, false); 113 96 }
+2 -5
drivers/mmc/host/sdhci-acpi.c
··· 775 775 { 776 776 struct device *dev = &pdev->dev; 777 777 const struct sdhci_acpi_slot *slot; 778 - struct acpi_device *device, *child; 779 778 const struct dmi_system_id *id; 779 + struct acpi_device *device; 780 780 struct sdhci_acpi_host *c; 781 781 struct sdhci_host *host; 782 782 struct resource *iomem; ··· 796 796 slot = sdhci_acpi_get_slot(device); 797 797 798 798 /* Power on the SDHCI controller and its children */ 799 - acpi_device_fix_up_power(device); 800 - list_for_each_entry(child, &device->children, node) 801 - if (child->status.present && child->status.enabled) 802 - acpi_device_fix_up_power(child); 799 + acpi_device_fix_up_power_extended(device); 803 800 804 801 if (sdhci_acpi_byt_defer(dev)) 805 802 return -EPROBE_DEFER;
+3 -8
drivers/mmc/host/sdhci-pci-core.c
··· 1240 1240 #ifdef CONFIG_ACPI 1241 1241 static void intel_mrfld_mmc_fix_up_power_slot(struct sdhci_pci_slot *slot) 1242 1242 { 1243 - struct acpi_device *device, *child; 1243 + struct acpi_device *device; 1244 1244 1245 1245 device = ACPI_COMPANION(&slot->chip->pdev->dev); 1246 - if (!device) 1247 - return; 1248 - 1249 - acpi_device_fix_up_power(device); 1250 - list_for_each_entry(child, &device->children, node) 1251 - if (child->status.present && child->status.enabled) 1252 - acpi_device_fix_up_power(child); 1246 + if (device) 1247 + acpi_device_fix_up_power_extended(device); 1253 1248 } 1254 1249 #else 1255 1250 static inline void intel_mrfld_mmc_fix_up_power_slot(struct sdhci_pci_slot *slot) {}
+27 -26
drivers/platform/x86/thinkpad_acpi.c
··· 6842 6842 6843 6843 /* --------------------------------------------------------------------- */ 6844 6844 6845 + static int __init tpacpi_evaluate_bcl(struct acpi_device *adev, void *not_used) 6846 + { 6847 + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 6848 + union acpi_object *obj; 6849 + acpi_status status; 6850 + int rc; 6851 + 6852 + status = acpi_evaluate_object(adev->handle, "_BCL", NULL, &buffer); 6853 + if (ACPI_FAILURE(status)) 6854 + return 0; 6855 + 6856 + obj = buffer.pointer; 6857 + if (!obj || obj->type != ACPI_TYPE_PACKAGE) { 6858 + acpi_handle_info(adev->handle, 6859 + "Unknown _BCL data, please report this to %s\n", 6860 + TPACPI_MAIL); 6861 + rc = 0; 6862 + } else { 6863 + rc = obj->package.count; 6864 + } 6865 + kfree(obj); 6866 + 6867 + return rc; 6868 + } 6869 + 6845 6870 /* 6846 6871 * Call _BCL method of video device. On some ThinkPads this will 6847 6872 * switch the firmware to the ACPI brightness control mode. ··· 6874 6849 6875 6850 static int __init tpacpi_query_bcl_levels(acpi_handle handle) 6876 6851 { 6877 - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 6878 - union acpi_object *obj; 6879 - struct acpi_device *device, *child; 6880 - int rc; 6852 + struct acpi_device *device; 6881 6853 6882 6854 device = acpi_fetch_acpi_dev(handle); 6883 6855 if (!device) 6884 6856 return 0; 6885 6857 6886 - rc = 0; 6887 - list_for_each_entry(child, &device->children, node) { 6888 - acpi_status status = acpi_evaluate_object(child->handle, "_BCL", 6889 - NULL, &buffer); 6890 - if (ACPI_FAILURE(status)) { 6891 - buffer.length = ACPI_ALLOCATE_BUFFER; 6892 - continue; 6893 - } 6894 - 6895 - obj = (union acpi_object *)buffer.pointer; 6896 - if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { 6897 - pr_err("Unknown _BCL data, please report this to %s\n", 6898 - TPACPI_MAIL); 6899 - rc = 0; 6900 - } else { 6901 - rc = obj->package.count; 6902 - } 6903 - break; 6904 - } 6905 - 6906 - kfree(buffer.pointer); 6907 - return rc; 6858 + return acpi_dev_for_each_child(device, tpacpi_evaluate_bcl, NULL); 6908 6859 } 6909 6860 6910 6861
+67 -50
drivers/soundwire/slave.c
··· 127 127 return true; 128 128 } 129 129 130 + struct sdw_acpi_child_walk_data { 131 + struct sdw_bus *bus; 132 + struct acpi_device *adev; 133 + struct sdw_slave_id id; 134 + bool ignore_unique_id; 135 + }; 136 + 137 + static int sdw_acpi_check_duplicate(struct acpi_device *adev, void *data) 138 + { 139 + struct sdw_acpi_child_walk_data *cwd = data; 140 + struct sdw_bus *bus = cwd->bus; 141 + struct sdw_slave_id id; 142 + 143 + if (adev == cwd->adev) 144 + return 0; 145 + 146 + if (!find_slave(bus, adev, &id)) 147 + return 0; 148 + 149 + if (cwd->id.sdw_version != id.sdw_version || cwd->id.mfg_id != id.mfg_id || 150 + cwd->id.part_id != id.part_id || cwd->id.class_id != id.class_id) 151 + return 0; 152 + 153 + if (cwd->id.unique_id != id.unique_id) { 154 + dev_dbg(bus->dev, 155 + "Valid unique IDs 0x%x 0x%x for Slave mfg_id 0x%04x, part_id 0x%04x\n", 156 + cwd->id.unique_id, id.unique_id, cwd->id.mfg_id, 157 + cwd->id.part_id); 158 + cwd->ignore_unique_id = false; 159 + return 0; 160 + } 161 + 162 + dev_err(bus->dev, 163 + "Invalid unique IDs 0x%x 0x%x for Slave mfg_id 0x%04x, part_id 0x%04x\n", 164 + cwd->id.unique_id, id.unique_id, cwd->id.mfg_id, cwd->id.part_id); 165 + return -ENODEV; 166 + } 167 + 168 + static int sdw_acpi_find_one(struct acpi_device *adev, void *data) 169 + { 170 + struct sdw_bus *bus = data; 171 + struct sdw_acpi_child_walk_data cwd = { 172 + .bus = bus, 173 + .adev = adev, 174 + .ignore_unique_id = true, 175 + }; 176 + int ret; 177 + 178 + if (!find_slave(bus, adev, &cwd.id)) 179 + return 0; 180 + 181 + /* Brute-force O(N^2) search for duplicates. */ 182 + ret = acpi_dev_for_each_child(ACPI_COMPANION(bus->dev), 183 + sdw_acpi_check_duplicate, &cwd); 184 + if (ret) 185 + return ret; 186 + 187 + if (cwd.ignore_unique_id) 188 + cwd.id.unique_id = SDW_IGNORED_UNIQUE_ID; 189 + 190 + /* Ignore errors and continue. */ 191 + sdw_slave_add(bus, &cwd.id, acpi_fwnode_handle(adev)); 192 + return 0; 193 + } 194 + 130 195 /* 131 196 * sdw_acpi_find_slaves() - Find Slave devices in Master ACPI node 132 197 * @bus: SDW bus instance ··· 200 135 */ 201 136 int sdw_acpi_find_slaves(struct sdw_bus *bus) 202 137 { 203 - struct acpi_device *adev, *parent; 204 - struct acpi_device *adev2, *parent2; 138 + struct acpi_device *parent; 205 139 206 140 parent = ACPI_COMPANION(bus->dev); 207 141 if (!parent) { ··· 208 144 return -ENODEV; 209 145 } 210 146 211 - list_for_each_entry(adev, &parent->children, node) { 212 - struct sdw_slave_id id; 213 - struct sdw_slave_id id2; 214 - bool ignore_unique_id = true; 215 - 216 - if (!find_slave(bus, adev, &id)) 217 - continue; 218 - 219 - /* brute-force O(N^2) search for duplicates */ 220 - parent2 = parent; 221 - list_for_each_entry(adev2, &parent2->children, node) { 222 - 223 - if (adev == adev2) 224 - continue; 225 - 226 - if (!find_slave(bus, adev2, &id2)) 227 - continue; 228 - 229 - if (id.sdw_version != id2.sdw_version || 230 - id.mfg_id != id2.mfg_id || 231 - id.part_id != id2.part_id || 232 - id.class_id != id2.class_id) 233 - continue; 234 - 235 - if (id.unique_id != id2.unique_id) { 236 - dev_dbg(bus->dev, 237 - "Valid unique IDs 0x%x 0x%x for Slave mfg_id 0x%04x, part_id 0x%04x\n", 238 - id.unique_id, id2.unique_id, id.mfg_id, id.part_id); 239 - ignore_unique_id = false; 240 - } else { 241 - dev_err(bus->dev, 242 - "Invalid unique IDs 0x%x 0x%x for Slave mfg_id 0x%04x, part_id 0x%04x\n", 243 - id.unique_id, id2.unique_id, id.mfg_id, id.part_id); 244 - return -ENODEV; 245 - } 246 - } 247 - 248 - if (ignore_unique_id) 249 - id.unique_id = SDW_IGNORED_UNIQUE_ID; 250 - 251 - /* 252 - * don't error check for sdw_slave_add as we want to continue 253 - * adding Slaves 254 - */ 255 - sdw_slave_add(bus, &id, acpi_fwnode_handle(adev)); 256 - } 257 - 258 - return 0; 147 + return acpi_dev_for_each_child(parent, sdw_acpi_find_one, bus); 259 148 } 260 149 261 150 #endif
+8 -23
drivers/thunderbolt/acpi.c
··· 301 301 return tb_is_switch(dev) || tb_is_usb4_port_device(dev); 302 302 } 303 303 304 - static struct acpi_device *tb_acpi_find_port(struct acpi_device *adev, 305 - const struct tb_port *port) 306 - { 307 - struct acpi_device *port_adev; 308 - 309 - if (!adev) 310 - return NULL; 311 - 312 - /* 313 - * Device routers exists under the downstream facing USB4 port 314 - * of the parent router. Their _ADR is always 0. 315 - */ 316 - list_for_each_entry(port_adev, &adev->children, node) { 317 - if (acpi_device_adr(port_adev) == port->port) 318 - return port_adev; 319 - } 320 - 321 - return NULL; 322 - } 323 - 324 304 static struct acpi_device *tb_acpi_switch_find_companion(struct tb_switch *sw) 325 305 { 326 306 struct acpi_device *adev = NULL; 327 307 struct tb_switch *parent_sw; 328 308 309 + /* 310 + * Device routers exists under the downstream facing USB4 port 311 + * of the parent router. Their _ADR is always 0. 312 + */ 329 313 parent_sw = tb_switch_parent(sw); 330 314 if (parent_sw) { 331 315 struct tb_port *port = tb_port_at(tb_route(sw), parent_sw); 332 316 struct acpi_device *port_adev; 333 317 334 - port_adev = tb_acpi_find_port(ACPI_COMPANION(&parent_sw->dev), port); 318 + port_adev = acpi_find_child_by_adr(ACPI_COMPANION(&parent_sw->dev), 319 + port->port); 335 320 if (port_adev) 336 321 adev = acpi_find_child_device(port_adev, 0, false); 337 322 } else { ··· 349 364 if (tb_is_switch(dev)) 350 365 return tb_acpi_switch_find_companion(tb_to_switch(dev)); 351 366 else if (tb_is_usb4_port_device(dev)) 352 - return tb_acpi_find_port(ACPI_COMPANION(dev->parent), 353 - tb_to_usb4_port_device(dev)->port); 367 + return acpi_find_child_by_adr(ACPI_COMPANION(dev->parent), 368 + tb_to_usb4_port_device(dev)->port->port); 354 369 return NULL; 355 370 } 356 371
+1 -17
drivers/usb/core/usb-acpi.c
··· 124 124 */ 125 125 #define USB_ACPI_LOCATION_VALID (1 << 31) 126 126 127 - static struct acpi_device *usb_acpi_find_port(struct acpi_device *parent, 128 - int raw) 129 - { 130 - struct acpi_device *adev; 131 - 132 - if (!parent) 133 - return NULL; 134 - 135 - list_for_each_entry(adev, &parent->children, node) { 136 - if (acpi_device_adr(adev) == raw) 137 - return adev; 138 - } 139 - 140 - return acpi_find_child_device(parent, raw, false); 141 - } 142 - 143 127 static struct acpi_device * 144 128 usb_acpi_get_companion_for_port(struct usb_port *port_dev) 145 129 { ··· 154 170 port1 = port_dev->portnum; 155 171 } 156 172 157 - return usb_acpi_find_port(adev, port1); 173 + return acpi_find_child_by_adr(adev, port1); 158 174 } 159 175 160 176 static struct acpi_device *
+6 -3
include/acpi/acpi_bus.h
··· 365 365 acpi_handle handle; /* no handle for fixed hardware */ 366 366 struct fwnode_handle fwnode; 367 367 struct acpi_device *parent; 368 - struct list_head children; 369 - struct list_head node; 370 368 struct list_head wakeup_list; 371 369 struct list_head del_list; 372 370 struct acpi_device_status status; ··· 377 379 struct acpi_device_data data; 378 380 struct acpi_scan_handler *handler; 379 381 struct acpi_hotplug_context *hp; 380 - struct acpi_driver *driver; 381 382 const struct acpi_gpio_mapping *driver_gpios; 382 383 void *driver_data; 383 384 struct device dev; ··· 480 483 int acpi_bus_for_each_dev(int (*fn)(struct device *, void *), void *data); 481 484 int acpi_dev_for_each_child(struct acpi_device *adev, 482 485 int (*fn)(struct acpi_device *, void *), void *data); 486 + int acpi_dev_for_each_child_reverse(struct acpi_device *adev, 487 + int (*fn)(struct acpi_device *, void *), 488 + void *data); 483 489 484 490 /* 485 491 * Events ··· 521 521 int acpi_device_set_power(struct acpi_device *device, int state); 522 522 int acpi_bus_init_power(struct acpi_device *device); 523 523 int acpi_device_fix_up_power(struct acpi_device *device); 524 + void acpi_device_fix_up_power_extended(struct acpi_device *adev); 524 525 int acpi_bus_update_power(acpi_handle handle, int *state_p); 525 526 int acpi_device_update_power(struct acpi_device *device, int *state_p); 526 527 bool acpi_bus_power_manageable(acpi_handle handle); ··· 623 622 } 624 623 struct acpi_device *acpi_find_child_device(struct acpi_device *parent, 625 624 u64 address, bool check_children); 625 + struct acpi_device *acpi_find_child_by_adr(struct acpi_device *adev, 626 + acpi_bus_address adr); 626 627 int acpi_is_root_bridge(acpi_handle); 627 628 struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle); 628 629
+1 -1
include/acpi/cppc_acpi.h
··· 17 17 #include <acpi/pcc.h> 18 18 #include <acpi/processor.h> 19 19 20 - /* Support CPPCv2 and CPPCv3 */ 20 + /* CPPCv2 and CPPCv3 support */ 21 21 #define CPPC_V2_REV 2 22 22 #define CPPC_V3_REV 3 23 23 #define CPPC_V2_NUM_ENT 21
+6 -3
include/acpi/processor.h
··· 441 441 #endif /* CONFIG_ACPI_PROCESSOR_IDLE */ 442 442 443 443 /* in processor_thermal.c */ 444 - int acpi_processor_get_limit_info(struct acpi_processor *pr); 444 + int acpi_processor_thermal_init(struct acpi_processor *pr, 445 + struct acpi_device *device); 446 + void acpi_processor_thermal_exit(struct acpi_processor *pr, 447 + struct acpi_device *device); 445 448 extern const struct thermal_cooling_device_ops processor_cooling_ops; 446 - #if defined(CONFIG_ACPI_CPU_FREQ_PSS) & defined(CONFIG_CPU_FREQ) 449 + #ifdef CONFIG_CPU_FREQ 447 450 void acpi_thermal_cpufreq_init(struct cpufreq_policy *policy); 448 451 void acpi_thermal_cpufreq_exit(struct cpufreq_policy *policy); 449 452 #else ··· 458 455 { 459 456 return; 460 457 } 461 - #endif /* CONFIG_ACPI_CPU_FREQ_PSS */ 458 + #endif /* CONFIG_CPU_FREQ */ 462 459 463 460 #endif
+2
include/linux/acpi_viot.h
··· 6 6 #include <linux/acpi.h> 7 7 8 8 #ifdef CONFIG_ACPI_VIOT 9 + void __init acpi_viot_early_init(void); 9 10 void __init acpi_viot_init(void); 10 11 int viot_iommu_configure(struct device *dev); 11 12 #else 13 + static inline void acpi_viot_early_init(void) {} 12 14 static inline void acpi_viot_init(void) {} 13 15 static inline int viot_iommu_configure(struct device *dev) 14 16 {