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

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

Pull ACPI updates from Rafael Wysocki:
"These include new ACPICA material, a rework of the ACPI thermal
driver, a switch-over of the ACPI processor driver to using _OSC
instead of (long deprecated) _PDC for CPU initialization, a rework of
firmware notifications handling in several drivers, fixes and cleanups
for suspend-to-idle handling on AMD systems, ACPI backlight driver
updates and more.

Specifics:

- Update the ACPICA code in the kernel to upstream revision 20230628
including the following changes:
- Suppress a GCC 12 dangling-pointer warning (Philip Prindeville)
- Reformat the ACPI_STATE_COMMON macro and its users (George Guo)
- Replace the ternary operator with ACPI_MIN() (Jiangshan Yi)
- Add support for _DSC as per ACPI 6.5 (Saket Dumbre)
- Remove a duplicate macro from zephyr header (Najumon B.A)
- Add data structures for GED and _EVT tracking (Jose Marinho)
- Fix misspelled CDAT DSMAS define (Dave Jiang)
- Simplify an error message in acpi_ds_result_push() (Christophe
Jaillet)
- Add a struct size macro related to SRAT (Dave Jiang)
- Add AML_NO_OPERAND_RESOLVE flag to Timer (Abhishek Mainkar)
- Add support for RISC-V external interrupt controllers in MADT
(Sunil V L)
- Add RHCT flags, CMO and MMU nodes (Sunil V L)
- Change ACPICA version to 20230628 (Bob Moore)

- Introduce new wrappers for ACPICA notify handler install/remove and
convert multiple drivers to using their own Notify() handlers
instead of the ACPI bus type .notify() slated for removal (Michal
Wilczynski)

- Add backlight=native DMI quirk for Apple iMac12,1 and iMac12,2
(Hans de Goede)

- Put ACPI video and its child devices explicitly into D0 on boot to
avoid platform firmware confusion (Kai-Heng Feng)

- Add backlight=native DMI quirk for Lenovo Ideapad Z470 (Jiri Slaby)

- Support obtaining physical CPU ID from MADT on LoongArch (Bibo Mao)

- Convert ACPI CPU initialization to using _OSC instead of _PDC that
has been depreceted since 2018 and dropped from the specification
in ACPI 6.5 (Michal Wilczynski, Rafael Wysocki)

- Drop non-functional nocrt parameter from ACPI thermal (Mario
Limonciello)

- Clean up the ACPI thermal driver, rework the handling of firmware
notifications in it and make it provide a table of generic trip
point structures to the core during initialization (Rafael Wysocki)

- Defer enumeration of devices with _DEP pointing to IVSC (Wentong
Wu)

- Install SystemCMOS address space handler for ACPI000E (TAD) to meet
platform firmware expectations on some platforms (Zhang Rui)

- Fix finding the generic error data in the ACPi extlog driver for
compatibility with old and new firmware interface versions
(Xiaochun Lee)

- Remove assorted unused declarations of functions (Yue Haibing)

- Move AMBA bus scan handling into arm64 specific directory (Sudeep
Holla)

- Fix and clean up suspend-to-idle interface for AMD systems (Mario
Limonciello, Andy Shevchenko)

- Fix string truncation warning in pnpacpi_add_device() (Sunil V L)"

* tag 'acpi-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (66 commits)
ACPI: x86: s2idle: Add a function to get LPS0 constraint for a device
ACPI: x86: s2idle: Add for_each_lpi_constraint() helper
ACPI: x86: s2idle: Add more debugging for AMD constraints parsing
ACPI: x86: s2idle: Fix a logic error parsing AMD constraints table
ACPI: x86: s2idle: Catch multiple ACPI_TYPE_PACKAGE objects
ACPI: x86: s2idle: Post-increment variables when getting constraints
ACPI: Adjust #ifdef for *_lps0_dev use
ACPI: TAD: Install SystemCMOS address space handler for ACPI000E
ACPI: Remove assorted unused declarations of functions
ACPI: extlog: Fix finding the generic error data for v3 structure
PNP: ACPI: Fix string truncation warning
ACPI: Remove unused extern declaration acpi_paddr_to_node()
ACPI: video: Add backlight=native DMI quirk for Apple iMac12,1 and iMac12,2
ACPI: video: Put ACPI video and its child devices into D0 on boot
ACPI: processor: LoongArch: Get physical ID from MADT
ACPI: scan: Defer enumeration of devices with a _DEP pointing to IVSC device
ACPI: thermal: Eliminate code duplication from acpi_thermal_notify()
ACPI: thermal: Drop unnecessary thermal zone callbacks
ACPI: thermal: Rework thermal_get_trend()
ACPI: thermal: Use trip point table to register thermal zones
...

+971 -584
-4
Documentation/admin-guide/kernel-parameters.txt
··· 6333 6333 -1: disable all critical trip points in all thermal zones 6334 6334 <degrees C>: override all critical trip points 6335 6335 6336 - thermal.nocrt= [HW,ACPI] 6337 - Set to disable actions on ACPI thermal zone 6338 - critical and hot trip points. 6339 - 6340 6336 thermal.off= [HW,ACPI] 6341 6337 1: disable ACPI thermal control 6342 6338
+3 -3
arch/ia64/include/asm/acpi.h
··· 11 11 12 12 #ifdef __KERNEL__ 13 13 14 - #include <acpi/pdc_intel.h> 14 + #include <acpi/proc_cap_intel.h> 15 15 16 16 #include <linux/init.h> 17 17 #include <linux/numa.h> ··· 69 69 #endif 70 70 71 71 static inline bool arch_has_acpi_pdc(void) { return true; } 72 - static inline void arch_acpi_set_pdc_bits(u32 *buf) 72 + static inline void arch_acpi_set_proc_cap_bits(u32 *cap) 73 73 { 74 - buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP; 74 + *cap |= ACPI_PROC_CAP_EST_CAPABILITY_SMP; 75 75 } 76 76 77 77 #ifdef CONFIG_ACPI_NUMA
+16 -8
arch/x86/include/asm/acpi.h
··· 6 6 * Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 7 7 * Copyright (C) 2001 Patrick Mochel <mochel@osdl.org> 8 8 */ 9 - #include <acpi/pdc_intel.h> 9 + #include <acpi/proc_cap_intel.h> 10 10 11 11 #include <asm/numa.h> 12 12 #include <asm/fixmap.h> ··· 102 102 c->x86_vendor == X86_VENDOR_CENTAUR); 103 103 } 104 104 105 - static inline void arch_acpi_set_pdc_bits(u32 *buf) 105 + static inline void arch_acpi_set_proc_cap_bits(u32 *cap) 106 106 { 107 107 struct cpuinfo_x86 *c = &cpu_data(0); 108 108 109 - buf[2] |= ACPI_PDC_C_CAPABILITY_SMP; 109 + *cap |= ACPI_PROC_CAP_C_CAPABILITY_SMP; 110 + 111 + /* Enable coordination with firmware's _TSD info */ 112 + *cap |= ACPI_PROC_CAP_SMP_T_SWCOORD; 110 113 111 114 if (cpu_has(c, X86_FEATURE_EST)) 112 - buf[2] |= ACPI_PDC_EST_CAPABILITY_SWSMP; 115 + *cap |= ACPI_PROC_CAP_EST_CAPABILITY_SWSMP; 113 116 114 117 if (cpu_has(c, X86_FEATURE_ACPI)) 115 - buf[2] |= ACPI_PDC_T_FFH; 118 + *cap |= ACPI_PROC_CAP_T_FFH; 119 + 120 + if (cpu_has(c, X86_FEATURE_HWP)) 121 + *cap |= ACPI_PROC_CAP_COLLAB_PROC_PERF; 116 122 117 123 /* 118 - * If mwait/monitor is unsupported, C2/C3_FFH will be disabled 124 + * If mwait/monitor is unsupported, C_C1_FFH and 125 + * C2/C3_FFH will be disabled. 119 126 */ 120 - if (!cpu_has(c, X86_FEATURE_MWAIT)) 121 - buf[2] &= ~(ACPI_PDC_C_C2C3_FFH); 127 + if (!cpu_has(c, X86_FEATURE_MWAIT) || 128 + boot_option_idle_override == IDLE_NOMWAIT) 129 + *cap &= ~(ACPI_PROC_CAP_C_C1_FFH | ACPI_PROC_CAP_C_C2C3_FFH); 122 130 } 123 131 124 132 static inline bool acpi_has_cpu_in_madt(void)
+4 -4
arch/x86/xen/enlighten_pv.c
··· 79 79 #ifdef CONFIG_ACPI 80 80 #include <linux/acpi.h> 81 81 #include <asm/acpi.h> 82 - #include <acpi/pdc_intel.h> 82 + #include <acpi/proc_cap_intel.h> 83 83 #include <acpi/processor.h> 84 84 #include <xen/interface/platform.h> 85 85 #endif ··· 288 288 289 289 native_cpuid(&ax, &bx, &cx, &dx); 290 290 291 - /* Ask the Hypervisor whether to clear ACPI_PDC_C_C2C3_FFH. If so, 291 + /* Ask the Hypervisor whether to clear ACPI_PROC_CAP_C_C2C3_FFH. If so, 292 292 * don't expose MWAIT_LEAF and let ACPI pick the IOPORT version of C3. 293 293 */ 294 294 buf[0] = ACPI_PDC_REVISION_ID; 295 295 buf[1] = 1; 296 - buf[2] = (ACPI_PDC_C_CAPABILITY_SMP | ACPI_PDC_EST_CAPABILITY_SWSMP); 296 + buf[2] = (ACPI_PROC_CAP_C_CAPABILITY_SMP | ACPI_PROC_CAP_EST_CAPABILITY_SWSMP); 297 297 298 298 set_xen_guest_handle(op.u.set_pminfo.pdc, buf); 299 299 300 300 if ((HYPERVISOR_platform_op(&op) == 0) && 301 - (buf[2] & (ACPI_PDC_C_C1_FFH | ACPI_PDC_C_C2C3_FFH))) { 301 + (buf[2] & (ACPI_PROC_CAP_C_C1_FFH | ACPI_PROC_CAP_C_C2C3_FFH))) { 302 302 cpuid_leaf5_ecx_val = cx; 303 303 cpuid_leaf5_edx_val = dx; 304 304 }
-1
drivers/acpi/Makefile
··· 50 50 acpi-y += acpi_apd.o 51 51 acpi-y += acpi_platform.o 52 52 acpi-y += acpi_pnp.o 53 - acpi-$(CONFIG_ARM_AMBA) += acpi_amba.o 54 53 acpi-y += power.o 55 54 acpi-y += event.o 56 55 acpi-y += evged.o
+19 -8
drivers/acpi/ac.c
··· 34 34 35 35 static int acpi_ac_add(struct acpi_device *device); 36 36 static void acpi_ac_remove(struct acpi_device *device); 37 - static void acpi_ac_notify(struct acpi_device *device, u32 event); 37 + static void acpi_ac_notify(acpi_handle handle, u32 event, void *data); 38 38 39 39 static const struct acpi_device_id ac_device_ids[] = { 40 40 {"ACPI0003", 0}, ··· 54 54 .name = "ac", 55 55 .class = ACPI_AC_CLASS, 56 56 .ids = ac_device_ids, 57 - .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, 58 57 .ops = { 59 58 .add = acpi_ac_add, 60 59 .remove = acpi_ac_remove, 61 - .notify = acpi_ac_notify, 62 60 }, 63 61 .drv.pm = &acpi_ac_pm, 64 62 }; ··· 126 128 }; 127 129 128 130 /* Driver Model */ 129 - static void acpi_ac_notify(struct acpi_device *device, u32 event) 131 + static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) 130 132 { 133 + struct acpi_device *device = data; 131 134 struct acpi_ac *ac = acpi_driver_data(device); 132 135 133 136 if (!ac) ··· 234 235 235 236 result = acpi_ac_get_state(ac); 236 237 if (result) 237 - goto end; 238 + goto err_release_ac; 238 239 239 240 psy_cfg.drv_data = ac; 240 241 ··· 247 248 &ac->charger_desc, &psy_cfg); 248 249 if (IS_ERR(ac->charger)) { 249 250 result = PTR_ERR(ac->charger); 250 - goto end; 251 + goto err_release_ac; 251 252 } 252 253 253 254 pr_info("%s [%s] (%s)\n", acpi_device_name(device), ··· 255 256 256 257 ac->battery_nb.notifier_call = acpi_ac_battery_notify; 257 258 register_acpi_notifier(&ac->battery_nb); 258 - end: 259 + 260 + result = acpi_dev_install_notify_handler(device, ACPI_ALL_NOTIFY, 261 + acpi_ac_notify); 259 262 if (result) 260 - kfree(ac); 263 + goto err_unregister; 264 + 265 + return 0; 266 + 267 + err_unregister: 268 + power_supply_unregister(ac->charger); 269 + unregister_acpi_notifier(&ac->battery_nb); 270 + err_release_ac: 271 + kfree(ac); 261 272 262 273 return result; 263 274 } ··· 306 297 307 298 ac = acpi_driver_data(device); 308 299 300 + acpi_dev_remove_notify_handler(device, ACPI_ALL_NOTIFY, 301 + acpi_ac_notify); 309 302 power_supply_unregister(ac->charger); 310 303 unregister_acpi_notifier(&ac->battery_nb); 311 304
+1 -1
drivers/acpi/acpi_amba.c drivers/acpi/arm64/amba.c
··· 17 17 #include <linux/kernel.h> 18 18 #include <linux/module.h> 19 19 20 - #include "internal.h" 20 + #include "init.h" 21 21 22 22 static const struct acpi_device_id amba_id_list[] = { 23 23 {"ARMH0061", 0}, /* PL061 GPIO Device */
+18 -7
drivers/acpi/acpi_cmos_rtc.c
··· 51 51 return AE_OK; 52 52 } 53 53 54 - static int acpi_install_cmos_rtc_space_handler(struct acpi_device *adev, 55 - const struct acpi_device_id *id) 54 + int acpi_install_cmos_rtc_space_handler(acpi_handle handle) 56 55 { 57 56 acpi_status status; 58 57 59 - status = acpi_install_address_space_handler(adev->handle, 58 + status = acpi_install_address_space_handler(handle, 60 59 ACPI_ADR_SPACE_CMOS, 61 60 &acpi_cmos_rtc_space_handler, 62 61 NULL, NULL); ··· 66 67 67 68 return 1; 68 69 } 70 + EXPORT_SYMBOL_GPL(acpi_install_cmos_rtc_space_handler); 69 71 70 - static void acpi_remove_cmos_rtc_space_handler(struct acpi_device *adev) 72 + void acpi_remove_cmos_rtc_space_handler(acpi_handle handle) 71 73 { 72 - if (ACPI_FAILURE(acpi_remove_address_space_handler(adev->handle, 74 + if (ACPI_FAILURE(acpi_remove_address_space_handler(handle, 73 75 ACPI_ADR_SPACE_CMOS, &acpi_cmos_rtc_space_handler))) 74 76 pr_err("Error removing CMOS-RTC region handler\n"); 77 + } 78 + EXPORT_SYMBOL_GPL(acpi_remove_cmos_rtc_space_handler); 79 + 80 + static int acpi_cmos_rtc_attach_handler(struct acpi_device *adev, const struct acpi_device_id *id) 81 + { 82 + return acpi_install_cmos_rtc_space_handler(adev->handle); 83 + } 84 + 85 + static void acpi_cmos_rtc_detach_handler(struct acpi_device *adev) 86 + { 87 + acpi_remove_cmos_rtc_space_handler(adev->handle); 75 88 } 76 89 77 90 static struct acpi_scan_handler cmos_rtc_handler = { 78 91 .ids = acpi_cmos_rtc_ids, 79 - .attach = acpi_install_cmos_rtc_space_handler, 80 - .detach = acpi_remove_cmos_rtc_space_handler, 92 + .attach = acpi_cmos_rtc_attach_handler, 93 + .detach = acpi_cmos_rtc_detach_handler, 81 94 }; 82 95 83 96 void __init acpi_cmos_rtc_init(void)
+1 -1
drivers/acpi/acpi_extlog.c
··· 172 172 fru_text = ""; 173 173 sec_type = (guid_t *)gdata->section_type; 174 174 if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) { 175 - struct cper_sec_mem_err *mem = (void *)(gdata + 1); 175 + struct cper_sec_mem_err *mem = acpi_hest_get_payload(gdata); 176 176 177 177 if (gdata->error_data_length >= sizeof(*mem)) 178 178 trace_extlog_mem_event(mem, err_seq, fru_id, fru_text,
+92 -32
drivers/acpi/acpi_processor.c
··· 9 9 * Copyright (C) 2013, Intel Corporation 10 10 * Rafael J. Wysocki <rafael.j.wysocki@intel.com> 11 11 */ 12 + #define pr_fmt(fmt) "ACPI: " fmt 12 13 13 14 #include <linux/acpi.h> 14 15 #include <linux/device.h> 16 + #include <linux/dmi.h> 15 17 #include <linux/kernel.h> 16 18 #include <linux/module.h> 17 19 #include <linux/pci.h> ··· 22 20 #include <acpi/processor.h> 23 21 24 22 #include <asm/cpu.h> 23 + 24 + #include <xen/xen.h> 25 25 26 26 #include "internal.h" 27 27 ··· 512 508 } 513 509 #endif /* CONFIG_ACPI_HOTPLUG_CPU */ 514 510 515 - #ifdef CONFIG_X86 516 - static bool acpi_hwp_native_thermal_lvt_set; 517 - static acpi_status __init acpi_hwp_native_thermal_lvt_osc(acpi_handle handle, 518 - u32 lvl, 519 - void *context, 520 - void **rv) 511 + #ifdef CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC 512 + bool __init processor_physically_present(acpi_handle handle) 521 513 { 522 - u8 sb_uuid_str[] = "4077A616-290C-47BE-9EBD-D87058713953"; 523 - u32 capbuf[2]; 514 + int cpuid, type; 515 + u32 acpi_id; 516 + acpi_status status; 517 + acpi_object_type acpi_type; 518 + unsigned long long tmp; 519 + union acpi_object object = {}; 520 + struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; 521 + 522 + status = acpi_get_type(handle, &acpi_type); 523 + if (ACPI_FAILURE(status)) 524 + return false; 525 + 526 + switch (acpi_type) { 527 + case ACPI_TYPE_PROCESSOR: 528 + status = acpi_evaluate_object(handle, NULL, NULL, &buffer); 529 + if (ACPI_FAILURE(status)) 530 + return false; 531 + acpi_id = object.processor.proc_id; 532 + break; 533 + case ACPI_TYPE_DEVICE: 534 + status = acpi_evaluate_integer(handle, METHOD_NAME__UID, 535 + NULL, &tmp); 536 + if (ACPI_FAILURE(status)) 537 + return false; 538 + acpi_id = tmp; 539 + break; 540 + default: 541 + return false; 542 + } 543 + 544 + if (xen_initial_domain()) 545 + /* 546 + * When running as a Xen dom0 the number of processors Linux 547 + * sees can be different from the real number of processors on 548 + * the system, and we still need to execute _PDC or _OSC for 549 + * all of them. 550 + */ 551 + return xen_processor_present(acpi_id); 552 + 553 + type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0; 554 + cpuid = acpi_get_cpuid(handle, type, acpi_id); 555 + 556 + return !invalid_logical_cpuid(cpuid); 557 + } 558 + 559 + /* vendor specific UUID indicating an Intel platform */ 560 + static u8 sb_uuid_str[] = "4077A616-290C-47BE-9EBD-D87058713953"; 561 + 562 + static acpi_status __init acpi_processor_osc(acpi_handle handle, u32 lvl, 563 + void *context, void **rv) 564 + { 565 + u32 capbuf[2] = {}; 524 566 struct acpi_osc_context osc_context = { 525 567 .uuid_str = sb_uuid_str, 526 568 .rev = 1, 527 569 .cap.length = 8, 528 570 .cap.pointer = capbuf, 529 571 }; 572 + acpi_status status; 530 573 531 - if (acpi_hwp_native_thermal_lvt_set) 532 - return AE_CTRL_TERMINATE; 574 + if (!processor_physically_present(handle)) 575 + return AE_OK; 533 576 534 - capbuf[0] = 0x0000; 535 - capbuf[1] = 0x1000; /* set bit 12 */ 577 + arch_acpi_set_proc_cap_bits(&capbuf[OSC_SUPPORT_DWORD]); 536 578 537 - if (ACPI_SUCCESS(acpi_run_osc(handle, &osc_context))) { 538 - if (osc_context.ret.pointer && osc_context.ret.length > 1) { 539 - u32 *capbuf_ret = osc_context.ret.pointer; 579 + status = acpi_run_osc(handle, &osc_context); 580 + if (ACPI_FAILURE(status)) 581 + return status; 540 582 541 - if (capbuf_ret[1] & 0x1000) { 542 - acpi_handle_info(handle, 543 - "_OSC native thermal LVT Acked\n"); 544 - acpi_hwp_native_thermal_lvt_set = true; 545 - } 546 - } 547 - kfree(osc_context.ret.pointer); 548 - } 583 + kfree(osc_context.ret.pointer); 549 584 550 585 return AE_OK; 551 586 } 552 587 553 - void __init acpi_early_processor_osc(void) 588 + static bool __init acpi_early_processor_osc(void) 554 589 { 555 - if (boot_cpu_has(X86_FEATURE_HWP)) { 556 - acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, 557 - ACPI_UINT32_MAX, 558 - acpi_hwp_native_thermal_lvt_osc, 559 - NULL, NULL, NULL); 560 - acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID, 561 - acpi_hwp_native_thermal_lvt_osc, 562 - NULL, NULL); 590 + acpi_status status; 591 + 592 + acpi_proc_quirk_mwait_check(); 593 + 594 + status = acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, 595 + ACPI_UINT32_MAX, acpi_processor_osc, NULL, 596 + NULL, NULL); 597 + if (ACPI_FAILURE(status)) 598 + return false; 599 + 600 + status = acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID, acpi_processor_osc, 601 + NULL, NULL); 602 + if (ACPI_FAILURE(status)) 603 + return false; 604 + 605 + return true; 606 + } 607 + 608 + void __init acpi_early_processor_control_setup(void) 609 + { 610 + if (acpi_early_processor_osc()) { 611 + pr_info("_OSC evaluated successfully for all CPUs\n"); 612 + } else { 613 + pr_info("_OSC evaluation for CPUs failed, trying _PDC\n"); 614 + acpi_early_processor_set_pdc(); 563 615 } 564 616 } 565 617 #endif
+22 -5
drivers/acpi/acpi_tad.c
··· 557 557 static int acpi_tad_remove(struct platform_device *pdev) 558 558 { 559 559 struct device *dev = &pdev->dev; 560 + acpi_handle handle = ACPI_HANDLE(dev); 560 561 struct acpi_tad_driver_data *dd = dev_get_drvdata(dev); 561 562 562 563 device_init_wakeup(dev, false); ··· 578 577 579 578 pm_runtime_put_sync(dev); 580 579 pm_runtime_disable(dev); 580 + acpi_remove_cmos_rtc_space_handler(handle); 581 581 return 0; 582 582 } 583 583 ··· 591 589 unsigned long long caps; 592 590 int ret; 593 591 592 + ret = acpi_install_cmos_rtc_space_handler(handle); 593 + if (ret < 0) { 594 + dev_info(dev, "Unable to install space handler\n"); 595 + return -ENODEV; 596 + } 594 597 /* 595 598 * Initialization failure messages are mostly about firmware issues, so 596 599 * print them at the "info" level. ··· 603 596 status = acpi_evaluate_integer(handle, "_GCP", NULL, &caps); 604 597 if (ACPI_FAILURE(status)) { 605 598 dev_info(dev, "Unable to get capabilities\n"); 606 - return -ENODEV; 599 + ret = -ENODEV; 600 + goto remove_handler; 607 601 } 608 602 609 603 if (!(caps & ACPI_TAD_AC_WAKE)) { 610 604 dev_info(dev, "Unsupported capabilities\n"); 611 - return -ENODEV; 605 + ret = -ENODEV; 606 + goto remove_handler; 612 607 } 613 608 614 609 if (!acpi_has_method(handle, "_PRW")) { 615 610 dev_info(dev, "Missing _PRW\n"); 616 - return -ENODEV; 611 + ret = -ENODEV; 612 + goto remove_handler; 617 613 } 618 614 619 615 dd = devm_kzalloc(dev, sizeof(*dd), GFP_KERNEL); 620 - if (!dd) 621 - return -ENOMEM; 616 + if (!dd) { 617 + ret = -ENOMEM; 618 + goto remove_handler; 619 + } 622 620 623 621 dd->capabilities = caps; 624 622 dev_set_drvdata(dev, dd); ··· 665 653 666 654 fail: 667 655 acpi_tad_remove(pdev); 656 + /* Don't fallthrough because cmos rtc space handler is removed in acpi_tad_remove() */ 657 + return ret; 658 + 659 + remove_handler: 660 + acpi_remove_cmos_rtc_space_handler(handle); 668 661 return ret; 669 662 } 670 663
+23 -3
drivers/acpi/acpi_video.c
··· 77 77 static LIST_HEAD(video_bus_head); 78 78 static int acpi_video_bus_add(struct acpi_device *device); 79 79 static void acpi_video_bus_remove(struct acpi_device *device); 80 - static void acpi_video_bus_notify(struct acpi_device *device, u32 event); 80 + static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data); 81 81 82 82 /* 83 83 * Indices in the _BCL method response: the first two items are special, ··· 104 104 .ops = { 105 105 .add = acpi_video_bus_add, 106 106 .remove = acpi_video_bus_remove, 107 - .notify = acpi_video_bus_notify, 108 107 }, 109 108 }; 110 109 ··· 1526 1527 acpi_osi_is_win8() ? 0 : 1); 1527 1528 } 1528 1529 1529 - static void acpi_video_bus_notify(struct acpi_device *device, u32 event) 1530 + static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) 1530 1531 { 1532 + struct acpi_device *device = data; 1531 1533 struct acpi_video_bus *video = acpi_driver_data(device); 1532 1534 struct input_dev *input; 1533 1535 int keycode = 0; ··· 2027 2027 if (error) 2028 2028 goto err_put_video; 2029 2029 2030 + /* 2031 + * HP ZBook Fury 16 G10 requires ACPI video's child devices have _PS0 2032 + * evaluated to have functional panel brightness control. 2033 + */ 2034 + acpi_device_fix_up_power_extended(device); 2035 + 2030 2036 pr_info("%s [%s] (multi-head: %s rom: %s post: %s)\n", 2031 2037 ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), 2032 2038 video->flags.multihead ? "yes" : "no", ··· 2059 2053 2060 2054 acpi_video_bus_add_notify_handler(video); 2061 2055 2056 + error = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY, 2057 + acpi_video_bus_notify); 2058 + if (error) 2059 + goto err_remove; 2060 + 2062 2061 return 0; 2063 2062 2063 + err_remove: 2064 + mutex_lock(&video_list_lock); 2065 + list_del(&video->entry); 2066 + mutex_unlock(&video_list_lock); 2067 + acpi_video_bus_remove_notify_handler(video); 2068 + acpi_video_bus_unregister_backlight(video); 2064 2069 err_put_video: 2065 2070 acpi_video_bus_put_devices(video); 2066 2071 kfree(video->attached_array); ··· 2091 2074 return; 2092 2075 2093 2076 video = acpi_driver_data(device); 2077 + 2078 + acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY, 2079 + acpi_video_bus_notify); 2094 2080 2095 2081 mutex_lock(&video_list_lock); 2096 2082 list_del(&video->entry);
+2
drivers/acpi/acpica/acdebug.h
··· 287 287 288 288 void acpi_db_uint32_to_hex_string(u32 value, char *buffer); 289 289 290 + void acpi_db_generate_interrupt(char *gsiv_arg); 291 + 290 292 #endif /* __ACDEBUG_H__ */
+1
drivers/acpi/acpica/acglobal.h
··· 129 129 ACPI_GLOBAL(void *, acpi_gbl_table_handler_context); 130 130 ACPI_GLOBAL(acpi_interface_handler, acpi_gbl_interface_handler); 131 131 ACPI_GLOBAL(struct acpi_sci_handler_info *, acpi_gbl_sci_handler_list); 132 + ACPI_GLOBAL(struct acpi_ged_handler_info *, acpi_gbl_ged_handler_list); 132 133 133 134 /* Owner ID support */ 134 135
+27 -11
drivers/acpi/acpica/aclocal.h
··· 543 543 u32 pkg_length; 544 544 }; 545 545 546 + /* Information about the interrupt ID and _EVT of a GED device */ 547 + 548 + struct acpi_ged_handler_info { 549 + struct acpi_ged_handler_info *next; 550 + u32 int_id; /* The interrupt ID that triggers the execution ofthe evt_method. */ 551 + struct acpi_namespace_node *evt_method; /* The _EVT method to be executed when an interrupt with ID = int_ID is received */ 552 + }; 553 + 546 554 /***************************************************************************** 547 555 * 548 556 * Generic "state" object for stacks ··· 568 560 u8 descriptor_type; /* To differentiate various internal objs */\ 569 561 u8 flags; \ 570 562 u16 value; \ 571 - u16 state; 563 + u16 state 572 564 573 565 /* There are 2 bytes available here until the next natural alignment boundary */ 574 566 575 567 struct acpi_common_state { 576 - ACPI_STATE_COMMON}; 568 + ACPI_STATE_COMMON; 569 + }; 577 570 578 571 /* 579 572 * Update state - used to traverse complex objects such as packages 580 573 */ 581 574 struct acpi_update_state { 582 - ACPI_STATE_COMMON union acpi_operand_object *object; 575 + ACPI_STATE_COMMON; 576 + union acpi_operand_object *object; 583 577 }; 584 578 585 579 /* 586 580 * Pkg state - used to traverse nested package structures 587 581 */ 588 582 struct acpi_pkg_state { 589 - ACPI_STATE_COMMON u32 index; 583 + ACPI_STATE_COMMON; 584 + u32 index; 590 585 union acpi_operand_object *source_object; 591 586 union acpi_operand_object *dest_object; 592 587 struct acpi_walk_state *walk_state; ··· 602 591 * Allows nesting of these constructs 603 592 */ 604 593 struct acpi_control_state { 605 - ACPI_STATE_COMMON u16 opcode; 594 + ACPI_STATE_COMMON; 595 + u16 opcode; 606 596 union acpi_parse_object *predicate_op; 607 597 u8 *aml_predicate_start; /* Start of if/while predicate */ 608 598 u8 *package_end; /* End of if/while block */ ··· 614 602 * Scope state - current scope during namespace lookups 615 603 */ 616 604 struct acpi_scope_state { 617 - ACPI_STATE_COMMON struct acpi_namespace_node *node; 605 + ACPI_STATE_COMMON; 606 + struct acpi_namespace_node *node; 618 607 }; 619 608 620 609 struct acpi_pscope_state { 621 - ACPI_STATE_COMMON u32 arg_count; /* Number of fixed arguments */ 610 + ACPI_STATE_COMMON; 611 + u32 arg_count; /* Number of fixed arguments */ 622 612 union acpi_parse_object *op; /* Current op being parsed */ 623 613 u8 *arg_end; /* Current argument end */ 624 614 u8 *pkg_end; /* Current package end */ ··· 632 618 * states are created when there are nested control methods executing. 633 619 */ 634 620 struct acpi_thread_state { 635 - ACPI_STATE_COMMON u8 current_sync_level; /* Mutex Sync (nested acquire) level */ 621 + ACPI_STATE_COMMON; 622 + u8 current_sync_level; /* Mutex Sync (nested acquire) level */ 636 623 struct acpi_walk_state *walk_state_list; /* Head of list of walk_states for this thread */ 637 624 union acpi_operand_object *acquired_mutex_list; /* List of all currently acquired mutexes */ 638 625 acpi_thread_id thread_id; /* Running thread ID */ ··· 644 629 * AML arguments 645 630 */ 646 631 struct acpi_result_values { 647 - ACPI_STATE_COMMON 648 - union acpi_operand_object *obj_desc[ACPI_RESULTS_FRAME_OBJ_NUM]; 632 + ACPI_STATE_COMMON; 633 + union acpi_operand_object *obj_desc[ACPI_RESULTS_FRAME_OBJ_NUM]; 649 634 }; 650 635 651 636 typedef ··· 667 652 * handler/dispatcher. 668 653 */ 669 654 struct acpi_notify_info { 670 - ACPI_STATE_COMMON u8 handler_list_id; 655 + ACPI_STATE_COMMON; 656 + u8 handler_list_id; 671 657 struct acpi_namespace_node *node; 672 658 union acpi_operand_object *handler_list_head; 673 659 struct acpi_global_notify_handler *global;
+3
drivers/acpi/acpica/acpredef.h
··· 440 440 {{"_DOS", METHOD_1ARGS(ACPI_TYPE_INTEGER), 441 441 METHOD_NO_RETURN_VALUE}}, 442 442 443 + {{"_DSC", METHOD_0ARGS, 444 + METHOD_RETURNS(ACPI_RTYPE_INTEGER)}}, 445 + 443 446 {{"_DSD", METHOD_0ARGS, /* ACPI 6.0 */ 444 447 METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Pkgs) each: 1 Buf, 1 Pkg */ 445 448 PACKAGE_INFO(ACPI_PTYPE2_UUID_PAIR, ACPI_RTYPE_BUFFER, 1,
+58
drivers/acpi/acpica/dbcmds.c
··· 1010 1010 acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT); 1011 1011 } 1012 1012 1013 + /******************************************************************************* 1014 + * 1015 + * FUNCTION: acpi_db_generate_ged 1016 + * 1017 + * PARAMETERS: ged_arg - Raw GED number, ascii string 1018 + * 1019 + * RETURN: None 1020 + * 1021 + * DESCRIPTION: Simulate firing of a GED 1022 + * 1023 + ******************************************************************************/ 1024 + 1025 + void acpi_db_generate_interrupt(char *gsiv_arg) 1026 + { 1027 + u32 gsiv_number; 1028 + struct acpi_ged_handler_info *ged_info = acpi_gbl_ged_handler_list; 1029 + 1030 + if (!ged_info) { 1031 + acpi_os_printf("No GED handling present\n"); 1032 + } 1033 + 1034 + gsiv_number = strtoul(gsiv_arg, NULL, 0); 1035 + 1036 + while (ged_info) { 1037 + 1038 + if (ged_info->int_id == gsiv_number) { 1039 + struct acpi_object_list arg_list; 1040 + union acpi_object arg0; 1041 + acpi_handle evt_handle = ged_info->evt_method; 1042 + acpi_status status; 1043 + 1044 + acpi_os_printf("Evaluate GED _EVT (GSIV=%d)\n", 1045 + gsiv_number); 1046 + 1047 + if (!evt_handle) { 1048 + acpi_os_printf("Undefined _EVT method\n"); 1049 + return; 1050 + } 1051 + 1052 + arg0.integer.type = ACPI_TYPE_INTEGER; 1053 + arg0.integer.value = gsiv_number; 1054 + 1055 + arg_list.count = 1; 1056 + arg_list.pointer = &arg0; 1057 + 1058 + status = 1059 + acpi_evaluate_object(evt_handle, NULL, &arg_list, 1060 + NULL); 1061 + if (ACPI_FAILURE(status)) { 1062 + acpi_os_printf("Could not evaluate _EVT\n"); 1063 + return; 1064 + } 1065 + 1066 + } 1067 + ged_info = ged_info->next; 1068 + } 1069 + } 1070 + 1013 1071 #if (!ACPI_REDUCED_HARDWARE) 1014 1072 /******************************************************************************* 1015 1073 *
+8
drivers/acpi/acpica/dbinput.c
··· 106 106 CMD_THREADS, 107 107 108 108 CMD_TEST, 109 + CMD_INTERRUPT, 109 110 #endif 110 111 }; 111 112 ··· 186 185 {"THREADS", 3}, 187 186 188 187 {"TEST", 1}, 188 + {"INTERRUPT", 1}, 189 189 #endif 190 190 {NULL, 0} 191 191 }; ··· 320 318 {1, " Gpes", "Display info on all GPE devices\n"}, 321 319 {1, " Sci", "Generate an SCI\n"}, 322 320 {1, " Sleep [SleepState]", "Simulate sleep/wake sequence(s) (0-5)\n"}, 321 + {1, " Interrupt <GSIV>", "Simulate an interrupt\n"}, 323 322 #endif 324 323 {0, NULL, NULL} 325 324 }; ··· 1065 1062 case CMD_EVENT: 1066 1063 1067 1064 acpi_os_printf("Event command not implemented\n"); 1065 + break; 1066 + 1067 + case CMD_INTERRUPT: 1068 + 1069 + acpi_db_generate_interrupt(acpi_gbl_db_args[1]); 1068 1070 break; 1069 1071 1070 1072 case CMD_GPE:
+2 -2
drivers/acpi/acpica/dswstate.c
··· 146 146 147 147 if (!object) { 148 148 ACPI_ERROR((AE_INFO, 149 - "Null Object! Obj=%p State=%p Num=%u", 150 - object, walk_state, walk_state->result_count)); 149 + "Null Object! State=%p Num=%u", 150 + walk_state, walk_state->result_count)); 151 151 return (AE_BAD_PARAMETER); 152 152 } 153 153
+1 -2
drivers/acpi/acpica/exserial.c
··· 343 343 /* Copy the input buffer data to the transfer buffer */ 344 344 345 345 buffer = buffer_desc->buffer.pointer; 346 - data_length = (buffer_length < source_desc->buffer.length ? 347 - buffer_length : source_desc->buffer.length); 346 + data_length = ACPI_MIN(buffer_length, source_desc->buffer.length); 348 347 memcpy(buffer, source_desc->buffer.pointer, data_length); 349 348 350 349 /* Lock entire transaction if requested */
+1 -1
drivers/acpi/acpica/psopcode.c
··· 603 603 604 604 /* 7E */ ACPI_OP("Timer", ARGP_TIMER_OP, ARGI_TIMER_OP, ACPI_TYPE_ANY, 605 605 AML_CLASS_EXECUTE, AML_TYPE_EXEC_0A_0T_1R, 606 - AML_FLAGS_EXEC_0A_0T_1R), 606 + AML_FLAGS_EXEC_0A_0T_1R | AML_NO_OPERAND_RESOLVE), 607 607 608 608 /* ACPI 5.0 opcodes */ 609 609
+5
drivers/acpi/acpica/utdebug.c
··· 37 37 { 38 38 acpi_size current_sp; 39 39 40 + #pragma GCC diagnostic push 41 + #if defined(__GNUC__) && __GNUC__ >= 12 42 + #pragma GCC diagnostic ignored "-Wdangling-pointer=" 43 + #endif 40 44 acpi_gbl_entry_stack_pointer = &current_sp; 45 + #pragma GCC diagnostic pop 41 46 } 42 47 43 48 /*******************************************************************************
+1
drivers/acpi/arm64/Makefile
··· 3 3 obj-$(CONFIG_ACPI_IORT) += iort.o 4 4 obj-$(CONFIG_ACPI_GTDT) += gtdt.o 5 5 obj-$(CONFIG_ACPI_APMT) += apmt.o 6 + obj-$(CONFIG_ARM_AMBA) += amba.o 6 7 obj-y += dma.o init.o
+2
drivers/acpi/arm64/init.c
··· 10 10 acpi_apmt_init(); 11 11 if (IS_ENABLED(CONFIG_ACPI_IORT)) 12 12 acpi_iort_init(); 13 + if (IS_ENABLED(CONFIG_ARM_AMBA)) 14 + acpi_amba_init(); 13 15 }
+1
drivers/acpi/arm64/init.h
··· 4 4 void __init acpi_agdi_init(void); 5 5 void __init acpi_apmt_init(void); 6 6 void __init acpi_iort_init(void); 7 + void __init acpi_amba_init(void);
+19 -5
drivers/acpi/battery.c
··· 1034 1034 } 1035 1035 1036 1036 /* Driver Interface */ 1037 - static void acpi_battery_notify(struct acpi_device *device, u32 event) 1037 + static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) 1038 1038 { 1039 + struct acpi_device *device = data; 1039 1040 struct acpi_battery *battery = acpi_driver_data(device); 1040 1041 struct power_supply *old; 1041 1042 ··· 1213 1212 1214 1213 device_init_wakeup(&device->dev, 1); 1215 1214 1216 - return result; 1215 + result = acpi_dev_install_notify_handler(device, ACPI_ALL_NOTIFY, 1216 + acpi_battery_notify); 1217 + if (result) 1218 + goto fail_pm; 1217 1219 1220 + return 0; 1221 + 1222 + fail_pm: 1223 + device_init_wakeup(&device->dev, 0); 1224 + unregister_pm_notifier(&battery->pm_nb); 1218 1225 fail: 1219 1226 sysfs_remove_battery(battery); 1220 1227 mutex_destroy(&battery->lock); 1221 1228 mutex_destroy(&battery->sysfs_lock); 1222 1229 kfree(battery); 1230 + 1223 1231 return result; 1224 1232 } 1225 1233 ··· 1238 1228 1239 1229 if (!device || !acpi_driver_data(device)) 1240 1230 return; 1241 - device_init_wakeup(&device->dev, 0); 1231 + 1242 1232 battery = acpi_driver_data(device); 1233 + 1234 + acpi_dev_remove_notify_handler(device, ACPI_ALL_NOTIFY, 1235 + acpi_battery_notify); 1236 + 1237 + device_init_wakeup(&device->dev, 0); 1243 1238 unregister_pm_notifier(&battery->pm_nb); 1244 1239 sysfs_remove_battery(battery); 1240 + 1245 1241 mutex_destroy(&battery->lock); 1246 1242 mutex_destroy(&battery->sysfs_lock); 1247 1243 kfree(battery); ··· 1280 1264 .name = "battery", 1281 1265 .class = ACPI_BATTERY_CLASS, 1282 1266 .ids = battery_device_ids, 1283 - .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, 1284 1267 .ops = { 1285 1268 .add = acpi_battery_add, 1286 1269 .remove = acpi_battery_remove, 1287 - .notify = acpi_battery_notify, 1288 1270 }, 1289 1271 .drv.pm = &acpi_battery_pm, 1290 1272 };
+28 -5
drivers/acpi/bus.c
··· 554 554 acpi_os_wait_events_complete(); 555 555 } 556 556 557 + int acpi_dev_install_notify_handler(struct acpi_device *adev, 558 + u32 handler_type, 559 + acpi_notify_handler handler) 560 + { 561 + acpi_status status; 562 + 563 + status = acpi_install_notify_handler(adev->handle, handler_type, 564 + handler, adev); 565 + if (ACPI_FAILURE(status)) 566 + return -ENODEV; 567 + 568 + return 0; 569 + } 570 + EXPORT_SYMBOL_GPL(acpi_dev_install_notify_handler); 571 + 572 + void acpi_dev_remove_notify_handler(struct acpi_device *adev, 573 + u32 handler_type, 574 + acpi_notify_handler handler) 575 + { 576 + acpi_remove_notify_handler(adev->handle, handler_type, handler); 577 + acpi_os_wait_events_complete(); 578 + } 579 + EXPORT_SYMBOL_GPL(acpi_dev_remove_notify_handler); 580 + 557 581 /* Handle events targeting \_SB device (at present only graceful shutdown) */ 558 582 559 583 #define ACPI_SB_NOTIFY_SHUTDOWN_REQUEST 0x81 ··· 1029 1005 return -ENOSYS; 1030 1006 1031 1007 ret = acpi_drv->ops.add(acpi_dev); 1032 - if (ret) 1008 + if (ret) { 1009 + acpi_dev->driver_data = NULL; 1033 1010 return ret; 1011 + } 1034 1012 1035 1013 pr_debug("Driver [%s] successfully bound to device [%s]\n", 1036 1014 acpi_drv->name, acpi_dev->pnp.bus_id); ··· 1322 1296 goto error1; 1323 1297 } 1324 1298 1325 - /* Set capability bits for _OSC under processor scope */ 1326 - acpi_early_processor_osc(); 1327 - 1328 1299 /* 1329 1300 * _OSC method may exist in module level code, 1330 1301 * so it must be run after ACPI_FULL_INITIALIZATION ··· 1337 1314 1338 1315 acpi_sysfs_init(); 1339 1316 1340 - acpi_early_processor_set_pdc(); 1317 + acpi_early_processor_control_setup(); 1341 1318 1342 1319 /* 1343 1320 * Maybe EC region is required at bus_scan/acpi_get_devices. So it
+12 -3
drivers/acpi/hed.c
··· 42 42 * it is used by HEST Generic Hardware Error Source with notify type 43 43 * SCI. 44 44 */ 45 - static void acpi_hed_notify(struct acpi_device *device, u32 event) 45 + static void acpi_hed_notify(acpi_handle handle, u32 event, void *data) 46 46 { 47 47 blocking_notifier_call_chain(&acpi_hed_notify_list, 0, NULL); 48 48 } 49 49 50 50 static int acpi_hed_add(struct acpi_device *device) 51 51 { 52 + int err; 53 + 52 54 /* Only one hardware error device */ 53 55 if (hed_handle) 54 56 return -EINVAL; 55 57 hed_handle = device->handle; 56 - return 0; 58 + 59 + err = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY, 60 + acpi_hed_notify); 61 + if (err) 62 + hed_handle = NULL; 63 + 64 + return err; 57 65 } 58 66 59 67 static void acpi_hed_remove(struct acpi_device *device) 60 68 { 69 + acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY, 70 + acpi_hed_notify); 61 71 hed_handle = NULL; 62 72 } 63 73 ··· 78 68 .ops = { 79 69 .add = acpi_hed_add, 80 70 .remove = acpi_hed_remove, 81 - .notify = acpi_hed_notify, 82 71 }, 83 72 }; 84 73 module_acpi_driver(acpi_hed_driver);
+4 -12
drivers/acpi/internal.h
··· 28 28 void acpi_platform_init(void); 29 29 void acpi_pnp_init(void); 30 30 void acpi_int340x_thermal_init(void); 31 - #ifdef CONFIG_ARM_AMBA 32 - void acpi_amba_init(void); 33 - #else 34 - static inline void acpi_amba_init(void) {} 35 - #endif 36 31 int acpi_sysfs_init(void); 37 32 void acpi_gpe_apply_masked_gpes(void); 38 33 void acpi_container_init(void); ··· 123 128 /* -------------------------------------------------------------------------- 124 129 Power Resource 125 130 -------------------------------------------------------------------------- */ 126 - int acpi_power_init(void); 127 131 void acpi_power_resources_list_free(struct list_head *list); 128 132 int acpi_extract_power_resources(union acpi_object *package, unsigned int start, 129 133 struct list_head *list); ··· 146 152 Processor 147 153 -------------------------------------------------------------------------- */ 148 154 #ifdef CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC 155 + void acpi_early_processor_control_setup(void); 149 156 void acpi_early_processor_set_pdc(void); 150 - #else 151 - static inline void acpi_early_processor_set_pdc(void) {} 152 - #endif 153 157 154 - #ifdef CONFIG_X86 155 - void acpi_early_processor_osc(void); 158 + void acpi_proc_quirk_mwait_check(void); 159 + bool processor_physically_present(acpi_handle handle); 156 160 #else 157 - static inline void acpi_early_processor_osc(void) {} 161 + static inline void acpi_early_processor_control_setup(void) {} 158 162 #endif 159 163 160 164 /* --------------------------------------------------------------------------
+28 -14
drivers/acpi/nfit/core.c
··· 3282 3282 acpi_put_table(table); 3283 3283 } 3284 3284 3285 + static void acpi_nfit_notify(acpi_handle handle, u32 event, void *data) 3286 + { 3287 + struct acpi_device *adev = data; 3288 + 3289 + device_lock(&adev->dev); 3290 + __acpi_nfit_notify(&adev->dev, handle, event); 3291 + device_unlock(&adev->dev); 3292 + } 3293 + 3294 + static void acpi_nfit_remove_notify_handler(void *data) 3295 + { 3296 + struct acpi_device *adev = data; 3297 + 3298 + acpi_dev_remove_notify_handler(adev, ACPI_DEVICE_NOTIFY, 3299 + acpi_nfit_notify); 3300 + } 3301 + 3285 3302 void acpi_nfit_shutdown(void *data) 3286 3303 { 3287 3304 struct acpi_nfit_desc *acpi_desc = data; ··· 3385 3368 3386 3369 if (rc) 3387 3370 return rc; 3388 - return devm_add_action_or_reset(dev, acpi_nfit_shutdown, acpi_desc); 3389 - } 3390 3371 3391 - static void acpi_nfit_remove(struct acpi_device *adev) 3392 - { 3393 - /* see acpi_nfit_unregister */ 3372 + rc = devm_add_action_or_reset(dev, acpi_nfit_shutdown, acpi_desc); 3373 + if (rc) 3374 + return rc; 3375 + 3376 + rc = acpi_dev_install_notify_handler(adev, ACPI_DEVICE_NOTIFY, 3377 + acpi_nfit_notify); 3378 + if (rc) 3379 + return rc; 3380 + 3381 + return devm_add_action_or_reset(dev, acpi_nfit_remove_notify_handler, 3382 + adev); 3394 3383 } 3395 3384 3396 3385 static void acpi_nfit_update_notify(struct device *dev, acpi_handle handle) ··· 3469 3446 } 3470 3447 EXPORT_SYMBOL_GPL(__acpi_nfit_notify); 3471 3448 3472 - static void acpi_nfit_notify(struct acpi_device *adev, u32 event) 3473 - { 3474 - device_lock(&adev->dev); 3475 - __acpi_nfit_notify(&adev->dev, adev->handle, event); 3476 - device_unlock(&adev->dev); 3477 - } 3478 - 3479 3449 static const struct acpi_device_id acpi_nfit_ids[] = { 3480 3450 { "ACPI0012", 0 }, 3481 3451 { "", 0 }, ··· 3480 3464 .ids = acpi_nfit_ids, 3481 3465 .ops = { 3482 3466 .add = acpi_nfit_add, 3483 - .remove = acpi_nfit_remove, 3484 - .notify = acpi_nfit_notify, 3485 3467 }, 3486 3468 }; 3487 3469
+29
drivers/acpi/processor_core.c
··· 132 132 return -EINVAL; 133 133 } 134 134 135 + /* 136 + * Retrieve LoongArch CPU physical id 137 + */ 138 + static int map_core_pic_id(struct acpi_subtable_header *entry, 139 + int device_declaration, u32 acpi_id, phys_cpuid_t *phys_id) 140 + { 141 + struct acpi_madt_core_pic *core_pic = 142 + container_of(entry, struct acpi_madt_core_pic, header); 143 + 144 + if (!(core_pic->flags & ACPI_MADT_ENABLED)) 145 + return -ENODEV; 146 + 147 + /* device_declaration means Device object in DSDT, in LoongArch 148 + * system, logical processor acpi_id is required in _UID property 149 + * of DSDT table, so we should check device_declaration here 150 + */ 151 + if (device_declaration && (core_pic->processor_id == acpi_id)) { 152 + *phys_id = core_pic->core_id; 153 + return 0; 154 + } 155 + 156 + return -EINVAL; 157 + } 158 + 135 159 static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt, 136 160 int type, u32 acpi_id) 137 161 { ··· 188 164 break; 189 165 } else if (header->type == ACPI_MADT_TYPE_RINTC) { 190 166 if (!map_rintc_hartid(header, type, acpi_id, &phys_id)) 167 + break; 168 + } else if (header->type == ACPI_MADT_TYPE_CORE_PIC) { 169 + if (!map_core_pic_id(header, type, acpi_id, &phys_id)) 191 170 break; 192 171 } 193 172 entry += header->length; ··· 243 216 map_x2apic_id(header, type, acpi_id, &phys_id); 244 217 else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) 245 218 map_gicc_mpidr(header, type, acpi_id, &phys_id); 219 + else if (header->type == ACPI_MADT_TYPE_CORE_PIC) 220 + map_core_pic_id(header, type, acpi_id, &phys_id); 246 221 247 222 exit: 248 223 kfree(buffer.pointer);
+2 -95
drivers/acpi/processor_pdc.c
··· 9 9 10 10 #define pr_fmt(fmt) "ACPI: " fmt 11 11 12 - #include <linux/dmi.h> 13 12 #include <linux/slab.h> 14 13 #include <linux/acpi.h> 15 14 #include <acpi/processor.h> 16 15 17 - #include <xen/xen.h> 18 - 19 16 #include "internal.h" 20 - 21 - static bool __init processor_physically_present(acpi_handle handle) 22 - { 23 - int cpuid, type; 24 - u32 acpi_id; 25 - acpi_status status; 26 - acpi_object_type acpi_type; 27 - unsigned long long tmp; 28 - union acpi_object object = { 0 }; 29 - struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; 30 - 31 - status = acpi_get_type(handle, &acpi_type); 32 - if (ACPI_FAILURE(status)) 33 - return false; 34 - 35 - switch (acpi_type) { 36 - case ACPI_TYPE_PROCESSOR: 37 - status = acpi_evaluate_object(handle, NULL, NULL, &buffer); 38 - if (ACPI_FAILURE(status)) 39 - return false; 40 - acpi_id = object.processor.proc_id; 41 - break; 42 - case ACPI_TYPE_DEVICE: 43 - status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp); 44 - if (ACPI_FAILURE(status)) 45 - return false; 46 - acpi_id = tmp; 47 - break; 48 - default: 49 - return false; 50 - } 51 - 52 - if (xen_initial_domain()) 53 - /* 54 - * When running as a Xen dom0 the number of processors Linux 55 - * sees can be different from the real number of processors on 56 - * the system, and we still need to execute _PDC for all of 57 - * them. 58 - */ 59 - return xen_processor_present(acpi_id); 60 - 61 - type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0; 62 - cpuid = acpi_get_cpuid(handle, type, acpi_id); 63 - 64 - return !invalid_logical_cpuid(cpuid); 65 - } 66 17 67 18 static void acpi_set_pdc_bits(u32 *buf) 68 19 { 69 20 buf[0] = ACPI_PDC_REVISION_ID; 70 21 buf[1] = 1; 71 22 72 - /* Enable coordination with firmware's _TSD info */ 73 - buf[2] = ACPI_PDC_SMP_T_SWCOORD; 74 - 75 23 /* Twiddle arch-specific bits needed for _PDC */ 76 - arch_acpi_set_pdc_bits(buf); 24 + arch_acpi_set_proc_cap_bits(&buf[2]); 77 25 } 78 26 79 27 static struct acpi_object_list *acpi_processor_alloc_pdc(void) ··· 71 123 { 72 124 acpi_status status = AE_OK; 73 125 74 - if (boot_option_idle_override == IDLE_NOMWAIT) { 75 - /* 76 - * If mwait is disabled for CPU C-states, the C2C3_FFH access 77 - * mode will be disabled in the parameter of _PDC object. 78 - * Of course C1_FFH access mode will also be disabled. 79 - */ 80 - union acpi_object *obj; 81 - u32 *buffer = NULL; 82 - 83 - obj = pdc_in->pointer; 84 - buffer = (u32 *)(obj->buffer.pointer); 85 - buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH); 86 - 87 - } 88 126 status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL); 89 127 90 128 if (ACPI_FAILURE(status)) ··· 108 174 return AE_OK; 109 175 } 110 176 111 - static int __init set_no_mwait(const struct dmi_system_id *id) 112 - { 113 - pr_notice("%s detected - disabling mwait for CPU C-states\n", 114 - id->ident); 115 - boot_option_idle_override = IDLE_NOMWAIT; 116 - return 0; 117 - } 118 - 119 - static const struct dmi_system_id processor_idle_dmi_table[] __initconst = { 120 - { 121 - set_no_mwait, "Extensa 5220", { 122 - DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), 123 - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 124 - DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), 125 - DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL}, 126 - {}, 127 - }; 128 - 129 - static void __init processor_dmi_check(void) 130 - { 131 - /* 132 - * Check whether the system is DMI table. If yes, OSPM 133 - * should not use mwait for CPU-states. 134 - */ 135 - dmi_check_system(processor_idle_dmi_table); 136 - } 137 - 138 177 void __init acpi_early_processor_set_pdc(void) 139 178 { 140 - processor_dmi_check(); 179 + acpi_proc_quirk_mwait_check(); 141 180 142 181 acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, 143 182 ACPI_UINT32_MAX,
+3 -1
drivers/acpi/scan.c
··· 795 795 /* List of HIDs for which we honor deps of matching ACPI devs, when checking _DEP lists. */ 796 796 static const char * const acpi_honor_dep_ids[] = { 797 797 "INT3472", /* Camera sensor PMIC / clk and regulator info */ 798 + "INTC1059", /* IVSC (TGL) driver must be loaded to allow i2c access to camera sensors */ 799 + "INTC1095", /* IVSC (ADL) driver must be loaded to allow i2c access to camera sensors */ 800 + "INTC100A", /* IVSC (RPL) driver must be loaded to allow i2c access to camera sensors */ 798 801 NULL 799 802 }; 800 803 ··· 2619 2616 acpi_watchdog_init(); 2620 2617 acpi_pnp_init(); 2621 2618 acpi_int340x_thermal_init(); 2622 - acpi_amba_init(); 2623 2619 acpi_init_lpit(); 2624 2620 2625 2621 acpi_scan_add_handler(&generic_device_handler);
+219 -251
drivers/acpi/thermal.c
··· 82 82 module_param(tzp, int, 0444); 83 83 MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds."); 84 84 85 - static int nocrt; 86 - module_param(nocrt, int, 0); 87 - MODULE_PARM_DESC(nocrt, "Set to take no action upon ACPI thermal zone critical trips points."); 88 - 89 85 static int off; 90 86 module_param(off, int, 0); 91 87 MODULE_PARM_DESC(off, "Set to disable ACPI thermal support."); ··· 92 96 93 97 static struct workqueue_struct *acpi_thermal_pm_queue; 94 98 95 - struct acpi_thermal_critical { 96 - unsigned long temperature; 97 - bool valid; 98 - }; 99 - 100 - struct acpi_thermal_hot { 99 + struct acpi_thermal_trip { 101 100 unsigned long temperature; 102 101 bool valid; 103 102 }; 104 103 105 104 struct acpi_thermal_passive { 105 + struct acpi_thermal_trip trip; 106 106 struct acpi_handle_list devices; 107 - unsigned long temperature; 108 107 unsigned long tc1; 109 108 unsigned long tc2; 110 109 unsigned long tsp; 111 - bool valid; 112 110 }; 113 111 114 112 struct acpi_thermal_active { 113 + struct acpi_thermal_trip trip; 115 114 struct acpi_handle_list devices; 116 - unsigned long temperature; 117 - bool valid; 118 - bool enabled; 119 115 }; 120 116 121 117 struct acpi_thermal_trips { 122 - struct acpi_thermal_critical critical; 123 - struct acpi_thermal_hot hot; 118 + struct acpi_thermal_trip critical; 119 + struct acpi_thermal_trip hot; 124 120 struct acpi_thermal_passive passive; 125 121 struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE]; 126 122 }; ··· 125 137 unsigned long polling_frequency; 126 138 volatile u8 zombie; 127 139 struct acpi_thermal_trips trips; 140 + struct thermal_trip *trip_table; 128 141 struct acpi_handle_list devices; 129 142 struct thermal_zone_device *thermal_zone; 130 143 int kelvin_offset; /* in millidegrees */ ··· 179 190 return 0; 180 191 } 181 192 182 - static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) 193 + static int acpi_thermal_temp(struct acpi_thermal *tz, int temp_deci_k) 194 + { 195 + if (temp_deci_k == THERMAL_TEMP_INVALID) 196 + return THERMAL_TEMP_INVALID; 197 + 198 + return deci_kelvin_to_millicelsius_with_offset(temp_deci_k, 199 + tz->kelvin_offset); 200 + } 201 + 202 + static void __acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) 183 203 { 184 204 acpi_status status; 185 205 unsigned long long tmp; ··· 253 255 } 254 256 255 257 /* Passive (optional) */ 256 - if (((flag & ACPI_TRIPS_PASSIVE) && tz->trips.passive.valid) || 258 + if (((flag & ACPI_TRIPS_PASSIVE) && tz->trips.passive.trip.valid) || 257 259 flag == ACPI_TRIPS_INIT) { 258 - valid = tz->trips.passive.valid; 260 + valid = tz->trips.passive.trip.valid; 259 261 if (psv == -1) { 260 262 status = AE_SUPPORT; 261 263 } else if (psv > 0) { ··· 267 269 } 268 270 269 271 if (ACPI_FAILURE(status)) { 270 - tz->trips.passive.valid = false; 272 + tz->trips.passive.trip.valid = false; 271 273 } else { 272 - tz->trips.passive.temperature = tmp; 273 - tz->trips.passive.valid = true; 274 + tz->trips.passive.trip.temperature = tmp; 275 + tz->trips.passive.trip.valid = true; 274 276 if (flag == ACPI_TRIPS_INIT) { 275 277 status = acpi_evaluate_integer(tz->device->handle, 276 278 "_TC1", NULL, &tmp); 277 279 if (ACPI_FAILURE(status)) 278 - tz->trips.passive.valid = false; 280 + tz->trips.passive.trip.valid = false; 279 281 else 280 282 tz->trips.passive.tc1 = tmp; 281 283 282 284 status = acpi_evaluate_integer(tz->device->handle, 283 285 "_TC2", NULL, &tmp); 284 286 if (ACPI_FAILURE(status)) 285 - tz->trips.passive.valid = false; 287 + tz->trips.passive.trip.valid = false; 286 288 else 287 289 tz->trips.passive.tc2 = tmp; 288 290 289 291 status = acpi_evaluate_integer(tz->device->handle, 290 292 "_TSP", NULL, &tmp); 291 293 if (ACPI_FAILURE(status)) 292 - tz->trips.passive.valid = false; 294 + tz->trips.passive.trip.valid = false; 293 295 else 294 296 tz->trips.passive.tsp = tmp; 295 297 } 296 298 } 297 299 } 298 - if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.passive.valid) { 300 + if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.passive.trip.valid) { 299 301 memset(&devices, 0, sizeof(struct acpi_handle_list)); 300 302 status = acpi_evaluate_reference(tz->device->handle, "_PSL", 301 303 NULL, &devices); 302 304 if (ACPI_FAILURE(status)) { 303 305 acpi_handle_info(tz->device->handle, 304 306 "Invalid passive threshold\n"); 305 - tz->trips.passive.valid = false; 307 + tz->trips.passive.trip.valid = false; 306 308 } else { 307 - tz->trips.passive.valid = true; 309 + tz->trips.passive.trip.valid = true; 308 310 } 309 311 310 312 if (memcmp(&tz->trips.passive.devices, &devices, ··· 315 317 } 316 318 } 317 319 if ((flag & ACPI_TRIPS_PASSIVE) || (flag & ACPI_TRIPS_DEVICES)) { 318 - if (valid != tz->trips.passive.valid) 320 + if (valid != tz->trips.passive.trip.valid) 319 321 ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "state"); 320 322 } 321 323 322 324 /* Active (optional) */ 323 325 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 324 326 char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; 325 - valid = tz->trips.active[i].valid; 327 + valid = tz->trips.active[i].trip.valid; 326 328 327 329 if (act == -1) 328 330 break; /* disable all active trip points */ 329 331 330 332 if (flag == ACPI_TRIPS_INIT || ((flag & ACPI_TRIPS_ACTIVE) && 331 - tz->trips.active[i].valid)) { 333 + tz->trips.active[i].trip.valid)) { 332 334 status = acpi_evaluate_integer(tz->device->handle, 333 335 name, NULL, &tmp); 334 336 if (ACPI_FAILURE(status)) { 335 - tz->trips.active[i].valid = false; 337 + tz->trips.active[i].trip.valid = false; 336 338 if (i == 0) 337 339 break; 338 340 ··· 340 342 break; 341 343 342 344 if (i == 1) 343 - tz->trips.active[0].temperature = celsius_to_deci_kelvin(act); 345 + tz->trips.active[0].trip.temperature = 346 + celsius_to_deci_kelvin(act); 344 347 else 345 348 /* 346 349 * Don't allow override higher than 347 350 * the next higher trip point 348 351 */ 349 - tz->trips.active[i-1].temperature = 352 + tz->trips.active[i-1].trip.temperature = 350 353 min_t(unsigned long, 351 - tz->trips.active[i-2].temperature, 354 + tz->trips.active[i-2].trip.temperature, 352 355 celsius_to_deci_kelvin(act)); 353 356 354 357 break; 355 358 } else { 356 - tz->trips.active[i].temperature = tmp; 357 - tz->trips.active[i].valid = true; 359 + tz->trips.active[i].trip.temperature = tmp; 360 + tz->trips.active[i].trip.valid = true; 358 361 } 359 362 } 360 363 361 364 name[2] = 'L'; 362 - if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.active[i].valid) { 365 + if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.active[i].trip.valid) { 363 366 memset(&devices, 0, sizeof(struct acpi_handle_list)); 364 367 status = acpi_evaluate_reference(tz->device->handle, 365 368 name, NULL, &devices); 366 369 if (ACPI_FAILURE(status)) { 367 370 acpi_handle_info(tz->device->handle, 368 371 "Invalid active%d threshold\n", i); 369 - tz->trips.active[i].valid = false; 372 + tz->trips.active[i].trip.valid = false; 370 373 } else { 371 - tz->trips.active[i].valid = true; 374 + tz->trips.active[i].trip.valid = true; 372 375 } 373 376 374 377 if (memcmp(&tz->trips.active[i].devices, &devices, ··· 380 381 } 381 382 } 382 383 if ((flag & ACPI_TRIPS_ACTIVE) || (flag & ACPI_TRIPS_DEVICES)) 383 - if (valid != tz->trips.active[i].valid) 384 + if (valid != tz->trips.active[i].trip.valid) 384 385 ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "state"); 385 386 386 - if (!tz->trips.active[i].valid) 387 + if (!tz->trips.active[i].trip.valid) 387 388 break; 388 389 } 389 390 ··· 397 398 ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "device"); 398 399 } 399 400 } 401 + } 402 + 403 + static int acpi_thermal_adjust_trip(struct thermal_trip *trip, void *data) 404 + { 405 + struct acpi_thermal_trip *acpi_trip = trip->priv; 406 + struct acpi_thermal *tz = data; 407 + 408 + if (!acpi_trip) 409 + return 0; 410 + 411 + if (acpi_trip->valid) 412 + trip->temperature = acpi_thermal_temp(tz, acpi_trip->temperature); 413 + else 414 + trip->temperature = THERMAL_TEMP_INVALID; 400 415 401 416 return 0; 402 417 } 403 418 419 + static void acpi_thermal_adjust_thermal_zone(struct thermal_zone_device *thermal, 420 + unsigned long data) 421 + { 422 + struct acpi_thermal *tz = thermal_zone_device_priv(thermal); 423 + int flag = data == ACPI_THERMAL_NOTIFY_THRESHOLDS ? 424 + ACPI_TRIPS_THRESHOLDS : ACPI_TRIPS_DEVICES; 425 + 426 + __acpi_thermal_trips_update(tz, flag); 427 + 428 + for_each_thermal_trip(tz->thermal_zone, acpi_thermal_adjust_trip, tz); 429 + } 430 + 431 + static void acpi_queue_thermal_check(struct acpi_thermal *tz) 432 + { 433 + if (!work_pending(&tz->thermal_check_work)) 434 + queue_work(acpi_thermal_pm_queue, &tz->thermal_check_work); 435 + } 436 + 437 + static void acpi_thermal_trips_update(struct acpi_thermal *tz, u32 event) 438 + { 439 + struct acpi_device *adev = tz->device; 440 + 441 + /* 442 + * Use thermal_zone_device_exec() to carry out the trip points 443 + * update, so as to protect thermal_get_trend() from getting stale 444 + * trip point temperatures and to prevent thermal_zone_device_update() 445 + * invoked from acpi_thermal_check_fn() from producing inconsistent 446 + * results. 447 + */ 448 + thermal_zone_device_exec(tz->thermal_zone, 449 + acpi_thermal_adjust_thermal_zone, event); 450 + acpi_queue_thermal_check(tz); 451 + acpi_bus_generate_netlink_event(adev->pnp.device_class, 452 + dev_name(&adev->dev), event, 0); 453 + } 454 + 404 455 static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) 405 456 { 406 - int i, ret = acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT); 407 457 bool valid; 458 + int i; 408 459 409 - if (ret) 410 - return ret; 460 + __acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT); 411 461 412 462 valid = tz->trips.critical.valid | 413 463 tz->trips.hot.valid | 414 - tz->trips.passive.valid; 464 + tz->trips.passive.trip.valid; 415 465 416 466 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) 417 - valid = valid || tz->trips.active[i].valid; 467 + valid = valid || tz->trips.active[i].trip.valid; 418 468 419 469 if (!valid) { 420 470 pr_warn(FW_BUG "No valid trip found\n"); ··· 491 443 return 0; 492 444 } 493 445 494 - static int thermal_get_trip_type(struct thermal_zone_device *thermal, 495 - int trip, enum thermal_trip_type *type) 446 + static int thermal_get_trend(struct thermal_zone_device *thermal, 447 + int trip_index, enum thermal_trend *trend) 496 448 { 497 449 struct acpi_thermal *tz = thermal_zone_device_priv(thermal); 498 - int i; 450 + struct acpi_thermal_trip *acpi_trip; 451 + int t, i; 499 452 500 - if (!tz || trip < 0) 453 + if (!tz || trip_index < 0) 501 454 return -EINVAL; 502 455 503 - if (tz->trips.critical.valid) { 504 - if (!trip) { 505 - *type = THERMAL_TRIP_CRITICAL; 506 - return 0; 507 - } 508 - trip--; 509 - } 456 + if (tz->trips.critical.valid) 457 + trip_index--; 510 458 511 - if (tz->trips.hot.valid) { 512 - if (!trip) { 513 - *type = THERMAL_TRIP_HOT; 514 - return 0; 515 - } 516 - trip--; 517 - } 459 + if (tz->trips.hot.valid) 460 + trip_index--; 518 461 519 - if (tz->trips.passive.valid) { 520 - if (!trip) { 521 - *type = THERMAL_TRIP_PASSIVE; 522 - return 0; 523 - } 524 - trip--; 525 - } 526 - 527 - for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].valid; i++) { 528 - if (!trip) { 529 - *type = THERMAL_TRIP_ACTIVE; 530 - return 0; 531 - } 532 - trip--; 533 - } 534 - 535 - return -EINVAL; 536 - } 537 - 538 - static int thermal_get_trip_temp(struct thermal_zone_device *thermal, 539 - int trip, int *temp) 540 - { 541 - struct acpi_thermal *tz = thermal_zone_device_priv(thermal); 542 - int i; 543 - 544 - if (!tz || trip < 0) 462 + if (trip_index < 0) 545 463 return -EINVAL; 546 464 547 - if (tz->trips.critical.valid) { 548 - if (!trip) { 549 - *temp = deci_kelvin_to_millicelsius_with_offset( 550 - tz->trips.critical.temperature, 551 - tz->kelvin_offset); 552 - return 0; 553 - } 554 - trip--; 555 - } 465 + acpi_trip = &tz->trips.passive.trip; 466 + if (acpi_trip->valid && !trip_index--) { 467 + t = tz->trips.passive.tc1 * (tz->temperature - 468 + tz->last_temperature) + 469 + tz->trips.passive.tc2 * (tz->temperature - 470 + acpi_trip->temperature); 471 + if (t > 0) 472 + *trend = THERMAL_TREND_RAISING; 473 + else if (t < 0) 474 + *trend = THERMAL_TREND_DROPPING; 475 + else 476 + *trend = THERMAL_TREND_STABLE; 556 477 557 - if (tz->trips.hot.valid) { 558 - if (!trip) { 559 - *temp = deci_kelvin_to_millicelsius_with_offset( 560 - tz->trips.hot.temperature, 561 - tz->kelvin_offset); 562 - return 0; 563 - } 564 - trip--; 565 - } 566 - 567 - if (tz->trips.passive.valid) { 568 - if (!trip) { 569 - *temp = deci_kelvin_to_millicelsius_with_offset( 570 - tz->trips.passive.temperature, 571 - tz->kelvin_offset); 572 - return 0; 573 - } 574 - trip--; 575 - } 576 - 577 - for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && 578 - tz->trips.active[i].valid; i++) { 579 - if (!trip) { 580 - *temp = deci_kelvin_to_millicelsius_with_offset( 581 - tz->trips.active[i].temperature, 582 - tz->kelvin_offset); 583 - return 0; 584 - } 585 - trip--; 586 - } 587 - 588 - return -EINVAL; 589 - } 590 - 591 - static int thermal_get_crit_temp(struct thermal_zone_device *thermal, 592 - int *temperature) 593 - { 594 - struct acpi_thermal *tz = thermal_zone_device_priv(thermal); 595 - 596 - if (tz->trips.critical.valid) { 597 - *temperature = deci_kelvin_to_millicelsius_with_offset( 598 - tz->trips.critical.temperature, 599 - tz->kelvin_offset); 600 478 return 0; 601 479 } 602 480 603 - return -EINVAL; 604 - } 481 + t = acpi_thermal_temp(tz, tz->temperature); 605 482 606 - static int thermal_get_trend(struct thermal_zone_device *thermal, 607 - int trip, enum thermal_trend *trend) 608 - { 609 - struct acpi_thermal *tz = thermal_zone_device_priv(thermal); 610 - enum thermal_trip_type type; 611 - int i; 612 - 613 - if (thermal_get_trip_type(thermal, trip, &type)) 614 - return -EINVAL; 615 - 616 - if (type == THERMAL_TRIP_ACTIVE) { 617 - int trip_temp; 618 - int temp = deci_kelvin_to_millicelsius_with_offset( 619 - tz->temperature, tz->kelvin_offset); 620 - if (thermal_get_trip_temp(thermal, trip, &trip_temp)) 621 - return -EINVAL; 622 - 623 - if (temp > trip_temp) { 624 - *trend = THERMAL_TREND_RAISING; 625 - return 0; 626 - } else { 627 - /* Fall back on default trend */ 628 - return -EINVAL; 483 + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 484 + acpi_trip = &tz->trips.active[i].trip; 485 + if (acpi_trip->valid && !trip_index--) { 486 + if (t > acpi_thermal_temp(tz, acpi_trip->temperature)) { 487 + *trend = THERMAL_TREND_RAISING; 488 + return 0; 489 + } 490 + break; 629 491 } 630 492 } 631 493 632 - /* 633 - * tz->temperature has already been updated by generic thermal layer, 634 - * before this callback being invoked 635 - */ 636 - i = tz->trips.passive.tc1 * (tz->temperature - tz->last_temperature) + 637 - tz->trips.passive.tc2 * (tz->temperature - tz->trips.passive.temperature); 638 - 639 - if (i > 0) 640 - *trend = THERMAL_TREND_RAISING; 641 - else if (i < 0) 642 - *trend = THERMAL_TREND_DROPPING; 643 - else 644 - *trend = THERMAL_TREND_STABLE; 645 - 646 - return 0; 494 + return -EINVAL; 647 495 } 648 496 649 497 static void acpi_thermal_zone_device_hot(struct thermal_zone_device *thermal) ··· 581 637 if (tz->trips.hot.valid) 582 638 trip++; 583 639 584 - if (tz->trips.passive.valid) { 640 + if (tz->trips.passive.trip.valid) { 585 641 trip++; 586 642 for (i = 0; i < tz->trips.passive.devices.count; i++) { 587 643 handle = tz->trips.passive.devices.handles[i]; ··· 606 662 } 607 663 608 664 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 609 - if (!tz->trips.active[i].valid) 665 + if (!tz->trips.active[i].trip.valid) 610 666 break; 611 667 612 668 trip++; ··· 653 709 .bind = acpi_thermal_bind_cooling_device, 654 710 .unbind = acpi_thermal_unbind_cooling_device, 655 711 .get_temp = thermal_get_temp, 656 - .get_trip_type = thermal_get_trip_type, 657 - .get_trip_temp = thermal_get_trip_temp, 658 - .get_crit_temp = thermal_get_crit_temp, 659 712 .get_trend = thermal_get_trend, 660 713 .hot = acpi_thermal_zone_device_hot, 661 714 .critical = acpi_thermal_zone_device_critical, ··· 686 745 687 746 static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) 688 747 { 689 - int trips = 0; 748 + struct acpi_thermal_trip *acpi_trip; 749 + struct thermal_trip *trip; 750 + int passive_delay = 0; 751 + int trip_count = 0; 690 752 int result; 691 - acpi_status status; 692 753 int i; 693 754 694 755 if (tz->trips.critical.valid) 695 - trips++; 756 + trip_count++; 696 757 697 758 if (tz->trips.hot.valid) 698 - trips++; 759 + trip_count++; 699 760 700 - if (tz->trips.passive.valid) 701 - trips++; 761 + if (tz->trips.passive.trip.valid) { 762 + trip_count++; 763 + passive_delay = tz->trips.passive.tsp * 100; 764 + } 702 765 703 - for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].valid; 704 - i++, trips++); 766 + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].trip.valid; i++) 767 + trip_count++; 705 768 706 - if (tz->trips.passive.valid) 707 - tz->thermal_zone = thermal_zone_device_register("acpitz", trips, 0, tz, 708 - &acpi_thermal_zone_ops, NULL, 709 - tz->trips.passive.tsp * 100, 710 - tz->polling_frequency * 100); 711 - else 712 - tz->thermal_zone = 713 - thermal_zone_device_register("acpitz", trips, 0, tz, 714 - &acpi_thermal_zone_ops, NULL, 715 - 0, tz->polling_frequency * 100); 769 + trip = kcalloc(trip_count, sizeof(*trip), GFP_KERNEL); 770 + if (!trip) 771 + return -ENOMEM; 716 772 717 - if (IS_ERR(tz->thermal_zone)) 718 - return -ENODEV; 773 + tz->trip_table = trip; 774 + 775 + if (tz->trips.critical.valid) { 776 + trip->type = THERMAL_TRIP_CRITICAL; 777 + trip->temperature = acpi_thermal_temp(tz, tz->trips.critical.temperature); 778 + trip++; 779 + } 780 + 781 + if (tz->trips.hot.valid) { 782 + trip->type = THERMAL_TRIP_HOT; 783 + trip->temperature = acpi_thermal_temp(tz, tz->trips.hot.temperature); 784 + trip++; 785 + } 786 + 787 + acpi_trip = &tz->trips.passive.trip; 788 + if (acpi_trip->valid) { 789 + trip->type = THERMAL_TRIP_PASSIVE; 790 + trip->temperature = acpi_thermal_temp(tz, acpi_trip->temperature); 791 + trip->priv = acpi_trip; 792 + trip++; 793 + } 794 + 795 + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 796 + acpi_trip = &tz->trips.active[i].trip; 797 + 798 + if (!acpi_trip->valid) 799 + break; 800 + 801 + trip->type = THERMAL_TRIP_ACTIVE; 802 + trip->temperature = acpi_thermal_temp(tz, acpi_trip->temperature); 803 + trip->priv = acpi_trip; 804 + trip++; 805 + } 806 + 807 + tz->thermal_zone = thermal_zone_device_register_with_trips("acpitz", 808 + tz->trip_table, 809 + trip_count, 810 + 0, tz, 811 + &acpi_thermal_zone_ops, 812 + NULL, 813 + passive_delay, 814 + tz->polling_frequency * 100); 815 + if (IS_ERR(tz->thermal_zone)) { 816 + result = PTR_ERR(tz->thermal_zone); 817 + goto free_trip_table; 818 + } 719 819 720 820 result = acpi_thermal_zone_sysfs_add(tz); 721 821 if (result) 722 822 goto unregister_tzd; 723 823 724 - status = acpi_bus_attach_private_data(tz->device->handle, 725 - tz->thermal_zone); 726 - if (ACPI_FAILURE(status)) { 727 - result = -ENODEV; 728 - goto remove_links; 729 - } 730 - 731 824 result = thermal_zone_device_enable(tz->thermal_zone); 732 825 if (result) 733 - goto acpi_bus_detach; 826 + goto remove_links; 734 827 735 828 dev_info(&tz->device->dev, "registered as thermal_zone%d\n", 736 829 thermal_zone_device_id(tz->thermal_zone)); 737 830 738 831 return 0; 739 832 740 - acpi_bus_detach: 741 - acpi_bus_detach_private_data(tz->device->handle); 742 833 remove_links: 743 834 acpi_thermal_zone_sysfs_remove(tz); 744 835 unregister_tzd: 745 836 thermal_zone_device_unregister(tz->thermal_zone); 837 + free_trip_table: 838 + kfree(tz->trip_table); 746 839 747 840 return result; 748 841 } ··· 785 810 { 786 811 acpi_thermal_zone_sysfs_remove(tz); 787 812 thermal_zone_device_unregister(tz->thermal_zone); 813 + kfree(tz->trip_table); 788 814 tz->thermal_zone = NULL; 789 - acpi_bus_detach_private_data(tz->device->handle); 790 815 } 791 816 792 817 ··· 794 819 Driver Interface 795 820 -------------------------------------------------------------------------- */ 796 821 797 - static void acpi_queue_thermal_check(struct acpi_thermal *tz) 822 + static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) 798 823 { 799 - if (!work_pending(&tz->thermal_check_work)) 800 - queue_work(acpi_thermal_pm_queue, &tz->thermal_check_work); 801 - } 802 - 803 - static void acpi_thermal_notify(struct acpi_device *device, u32 event) 804 - { 824 + struct acpi_device *device = data; 805 825 struct acpi_thermal *tz = acpi_driver_data(device); 806 826 807 827 if (!tz) ··· 807 837 acpi_queue_thermal_check(tz); 808 838 break; 809 839 case ACPI_THERMAL_NOTIFY_THRESHOLDS: 810 - acpi_thermal_trips_update(tz, ACPI_TRIPS_THRESHOLDS); 811 - acpi_queue_thermal_check(tz); 812 - acpi_bus_generate_netlink_event(device->pnp.device_class, 813 - dev_name(&device->dev), event, 0); 814 - break; 815 840 case ACPI_THERMAL_NOTIFY_DEVICES: 816 - acpi_thermal_trips_update(tz, ACPI_TRIPS_DEVICES); 817 - acpi_queue_thermal_check(tz); 818 - acpi_bus_generate_netlink_event(device->pnp.device_class, 819 - dev_name(&device->dev), event, 0); 841 + acpi_thermal_trips_update(tz, event); 820 842 break; 821 843 default: 822 844 acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n", ··· 959 997 960 998 pr_info("%s [%s] (%ld C)\n", acpi_device_name(device), 961 999 acpi_device_bid(device), deci_kelvin_to_celsius(tz->temperature)); 962 - goto end; 963 1000 1001 + result = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY, 1002 + acpi_thermal_notify); 1003 + if (result) 1004 + goto flush_wq; 1005 + 1006 + return 0; 1007 + 1008 + flush_wq: 1009 + flush_workqueue(acpi_thermal_pm_queue); 1010 + acpi_thermal_unregister_thermal_zone(tz); 964 1011 free_memory: 965 1012 kfree(tz); 966 - end: 1013 + 967 1014 return result; 968 1015 } 969 1016 ··· 983 1012 if (!device || !acpi_driver_data(device)) 984 1013 return; 985 1014 986 - flush_workqueue(acpi_thermal_pm_queue); 987 1015 tz = acpi_driver_data(device); 988 1016 1017 + acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY, 1018 + acpi_thermal_notify); 1019 + 1020 + flush_workqueue(acpi_thermal_pm_queue); 989 1021 acpi_thermal_unregister_thermal_zone(tz); 1022 + 990 1023 kfree(tz); 991 1024 } 992 1025 ··· 1005 1030 static int acpi_thermal_resume(struct device *dev) 1006 1031 { 1007 1032 struct acpi_thermal *tz; 1008 - int i, j, power_state, result; 1033 + int i, j, power_state; 1009 1034 1010 1035 if (!dev) 1011 1036 return -EINVAL; ··· 1015 1040 return -EINVAL; 1016 1041 1017 1042 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 1018 - if (!tz->trips.active[i].valid) 1043 + if (!tz->trips.active[i].trip.valid) 1019 1044 break; 1020 1045 1021 - tz->trips.active[i].enabled = true; 1022 1046 for (j = 0; j < tz->trips.active[i].devices.count; j++) { 1023 - result = acpi_bus_update_power( 1024 - tz->trips.active[i].devices.handles[j], 1025 - &power_state); 1026 - if (result || (power_state != ACPI_STATE_D0)) { 1027 - tz->trips.active[i].enabled = false; 1028 - break; 1029 - } 1047 + acpi_bus_update_power(tz->trips.active[i].devices.handles[j], 1048 + &power_state); 1030 1049 } 1031 1050 } 1032 1051 ··· 1047 1078 .ops = { 1048 1079 .add = acpi_thermal_add, 1049 1080 .remove = acpi_thermal_remove, 1050 - .notify = acpi_thermal_notify, 1051 1081 }, 1052 1082 .drv.pm = &acpi_thermal_pm, 1053 1083 }; ··· 1062 1094 static int thermal_nocrt(const struct dmi_system_id *d) { 1063 1095 pr_notice("%s detected: disabling all critical thermal trip point actions.\n", 1064 1096 d->ident); 1065 - nocrt = 1; 1097 + crt = -1; 1066 1098 return 0; 1067 1099 } 1068 1100 static int thermal_tzp(const struct dmi_system_id *d) {
+27
drivers/acpi/video_detect.c
··· 446 446 }, 447 447 }, 448 448 { 449 + /* https://bugzilla.suse.com/show_bug.cgi?id=1208724 */ 450 + .callback = video_detect_force_native, 451 + /* Lenovo Ideapad Z470 */ 452 + .matches = { 453 + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 454 + DMI_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Z470"), 455 + }, 456 + }, 457 + { 449 458 /* https://bugzilla.redhat.com/show_bug.cgi?id=1187004 */ 450 459 .callback = video_detect_force_native, 451 460 /* Lenovo Ideapad Z570 */ ··· 493 484 .matches = { 494 485 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), 495 486 DMI_MATCH(DMI_PRODUCT_NAME, "iMac11,3"), 487 + }, 488 + }, 489 + { 490 + /* https://gitlab.freedesktop.org/drm/amd/-/issues/1838 */ 491 + .callback = video_detect_force_native, 492 + /* Apple iMac12,1 */ 493 + .matches = { 494 + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), 495 + DMI_MATCH(DMI_PRODUCT_NAME, "iMac12,1"), 496 + }, 497 + }, 498 + { 499 + /* https://gitlab.freedesktop.org/drm/amd/-/issues/2753 */ 500 + .callback = video_detect_force_native, 501 + /* Apple iMac12,2 */ 502 + .matches = { 503 + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), 504 + DMI_MATCH(DMI_PRODUCT_NAME, "iMac12,2"), 496 505 }, 497 506 }, 498 507 {
+69 -38
drivers/acpi/x86/s2idle.c
··· 94 94 static int lpi_constraints_table_size; 95 95 static int rev_id; 96 96 97 + #define for_each_lpi_constraint(entry) \ 98 + for (int i = 0; \ 99 + entry = &lpi_constraints_table[i], i < lpi_constraints_table_size; \ 100 + i++) 101 + 97 102 static void lpi_device_get_constraints_amd(void) 98 103 { 99 104 union acpi_object *out_obj; ··· 118 113 union acpi_object *package = &out_obj->package.elements[i]; 119 114 120 115 if (package->type == ACPI_TYPE_PACKAGE) { 116 + if (lpi_constraints_table) { 117 + acpi_handle_err(lps0_device_handle, 118 + "Duplicate constraints list\n"); 119 + goto free_acpi_buffer; 120 + } 121 + 121 122 lpi_constraints_table = kcalloc(package->package.count, 122 123 sizeof(*lpi_constraints_table), 123 124 GFP_KERNEL); ··· 134 123 acpi_handle_debug(lps0_device_handle, 135 124 "LPI: constraints list begin:\n"); 136 125 137 - for (j = 0; j < package->package.count; ++j) { 126 + for (j = 0; j < package->package.count; j++) { 138 127 union acpi_object *info_obj = &package->package.elements[j]; 139 128 struct lpi_device_constraint_amd dev_info = {}; 140 129 struct lpi_constraints *list; 141 130 acpi_status status; 142 131 143 - for (k = 0; k < info_obj->package.count; ++k) { 144 - union acpi_object *obj = &info_obj->package.elements[k]; 132 + list = &lpi_constraints_table[lpi_constraints_table_size]; 145 133 146 - list = &lpi_constraints_table[lpi_constraints_table_size]; 147 - list->min_dstate = -1; 134 + for (k = 0; k < info_obj->package.count; k++) { 135 + union acpi_object *obj = &info_obj->package.elements[k]; 148 136 149 137 switch (k) { 150 138 case 0: ··· 159 149 dev_info.min_dstate = obj->integer.value; 160 150 break; 161 151 } 162 - 163 - if (!dev_info.enabled || !dev_info.name || 164 - !dev_info.min_dstate) 165 - continue; 166 - 167 - status = acpi_get_handle(NULL, dev_info.name, 168 - &list->handle); 169 - if (ACPI_FAILURE(status)) 170 - continue; 171 - 172 - acpi_handle_debug(lps0_device_handle, 173 - "Name:%s\n", dev_info.name); 174 - 175 - list->min_dstate = dev_info.min_dstate; 176 - 177 - if (list->min_dstate < 0) { 178 - acpi_handle_debug(lps0_device_handle, 179 - "Incomplete constraint defined\n"); 180 - continue; 181 - } 182 152 } 153 + 154 + acpi_handle_debug(lps0_device_handle, 155 + "Name:%s, Enabled: %d, States: %d, MinDstate: %d\n", 156 + dev_info.name, 157 + dev_info.enabled, 158 + dev_info.function_states, 159 + dev_info.min_dstate); 160 + 161 + if (!dev_info.enabled || !dev_info.name || 162 + !dev_info.min_dstate) 163 + continue; 164 + 165 + status = acpi_get_handle(NULL, dev_info.name, &list->handle); 166 + if (ACPI_FAILURE(status)) 167 + continue; 168 + 169 + list->min_dstate = dev_info.min_dstate; 170 + 183 171 lpi_constraints_table_size++; 184 172 } 185 173 } ··· 222 214 if (!package) 223 215 continue; 224 216 225 - for (j = 0; j < package->package.count; ++j) { 217 + for (j = 0; j < package->package.count; j++) { 226 218 union acpi_object *element = 227 219 &(package->package.elements[j]); 228 220 ··· 254 246 255 247 constraint->min_dstate = -1; 256 248 257 - for (j = 0; j < package_count; ++j) { 249 + for (j = 0; j < package_count; j++) { 258 250 union acpi_object *info_obj = &info.package[j]; 259 251 union acpi_object *cnstr_pkg; 260 252 union acpi_object *obj; ··· 299 291 ACPI_FREE(out_obj); 300 292 } 301 293 294 + /** 295 + * acpi_get_lps0_constraint - Get the LPS0 constraint for a device. 296 + * @adev: Device to get the constraint for. 297 + * 298 + * The LPS0 constraint is the shallowest (minimum) power state in which the 299 + * device can be so as to allow the platform as a whole to achieve additional 300 + * energy conservation by utilizing a system-wide low-power state. 301 + * 302 + * Returns: 303 + * - ACPI power state value of the constraint for @adev on success. 304 + * - Otherwise, ACPI_STATE_UNKNOWN. 305 + */ 306 + int acpi_get_lps0_constraint(struct acpi_device *adev) 307 + { 308 + struct lpi_constraints *entry; 309 + 310 + for_each_lpi_constraint(entry) { 311 + if (adev->handle == entry->handle) 312 + return entry->min_dstate; 313 + } 314 + 315 + return ACPI_STATE_UNKNOWN; 316 + } 317 + 302 318 static void lpi_check_constraints(void) 303 319 { 304 - int i; 320 + struct lpi_constraints *entry; 305 321 306 - for (i = 0; i < lpi_constraints_table_size; ++i) { 307 - acpi_handle handle = lpi_constraints_table[i].handle; 308 - struct acpi_device *adev = acpi_fetch_acpi_dev(handle); 322 + for_each_lpi_constraint(entry) { 323 + struct acpi_device *adev = acpi_fetch_acpi_dev(entry->handle); 309 324 310 325 if (!adev) 311 326 continue; 312 327 313 - acpi_handle_debug(handle, 328 + acpi_handle_debug(entry->handle, 314 329 "LPI: required min power state:%s current power state:%s\n", 315 - acpi_power_state_string(lpi_constraints_table[i].min_dstate), 330 + acpi_power_state_string(entry->min_dstate), 316 331 acpi_power_state_string(adev->power.state)); 317 332 318 333 if (!adev->flags.power_manageable) { 319 - acpi_handle_info(handle, "LPI: Device not power manageable\n"); 320 - lpi_constraints_table[i].handle = NULL; 334 + acpi_handle_info(entry->handle, "LPI: Device not power manageable\n"); 335 + entry->handle = NULL; 321 336 continue; 322 337 } 323 338 324 - if (adev->power.state < lpi_constraints_table[i].min_dstate) 325 - acpi_handle_info(handle, 339 + if (adev->power.state < entry->min_dstate) 340 + acpi_handle_info(entry->handle, 326 341 "LPI: Constraint not met; min power state:%s current power state:%s\n", 327 - acpi_power_state_string(lpi_constraints_table[i].min_dstate), 342 + acpi_power_state_string(entry->min_dstate), 328 343 acpi_power_state_string(adev->power.state)); 329 344 } 330 345 }
+35
drivers/acpi/x86/utils.c
··· 518 518 return false; 519 519 } 520 520 EXPORT_SYMBOL_GPL(acpi_quirk_skip_acpi_ac_and_battery); 521 + 522 + /* This section provides a workaround for a specific x86 system 523 + * which requires disabling of mwait to work correctly. 524 + */ 525 + static int __init acpi_proc_quirk_set_no_mwait(const struct dmi_system_id *id) 526 + { 527 + pr_notice("%s detected - disabling mwait for CPU C-states\n", 528 + id->ident); 529 + boot_option_idle_override = IDLE_NOMWAIT; 530 + return 0; 531 + } 532 + 533 + static const struct dmi_system_id acpi_proc_quirk_mwait_dmi_table[] __initconst = { 534 + { 535 + .callback = acpi_proc_quirk_set_no_mwait, 536 + .ident = "Extensa 5220", 537 + .matches = { 538 + DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), 539 + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 540 + DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), 541 + DMI_MATCH(DMI_BOARD_NAME, "Columbia"), 542 + }, 543 + .driver_data = NULL, 544 + }, 545 + {} 546 + }; 547 + 548 + void __init acpi_proc_quirk_mwait_check(void) 549 + { 550 + /* 551 + * Check whether the system is DMI table. If yes, OSPM 552 + * should not use mwait for CPU-states. 553 + */ 554 + dmi_check_system(acpi_proc_quirk_mwait_dmi_table); 555 + }
+3
drivers/pnp/pnpacpi/core.c
··· 254 254 else 255 255 strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name)); 256 256 257 + /* Handle possible string truncation */ 258 + dev->name[sizeof(dev->name) - 1] = '\0'; 259 + 257 260 if (dev->active) 258 261 pnpacpi_parse_allocated_resource(dev); 259 262
+21 -1
drivers/thermal/thermal_core.c
··· 348 348 struct thermal_trip trip; 349 349 350 350 /* Ignore disabled trip points */ 351 - if (test_bit(trip_id, &tz->trips_disabled)) 351 + if (test_bit(trip_id, &tz->trips_disabled) || 352 + trip.temperature == THERMAL_TEMP_INVALID) 352 353 return; 353 354 354 355 __thermal_zone_get_trip(tz, trip_id, &trip); ··· 496 495 mutex_unlock(&tz->lock); 497 496 } 498 497 EXPORT_SYMBOL_GPL(thermal_zone_device_update); 498 + 499 + /** 500 + * thermal_zone_device_exec - Run a callback under the zone lock. 501 + * @tz: Thermal zone. 502 + * @cb: Callback to run. 503 + * @data: Data to pass to the callback. 504 + */ 505 + void thermal_zone_device_exec(struct thermal_zone_device *tz, 506 + void (*cb)(struct thermal_zone_device *, 507 + unsigned long), 508 + unsigned long data) 509 + { 510 + mutex_lock(&tz->lock); 511 + 512 + cb(tz, data); 513 + 514 + mutex_unlock(&tz->lock); 515 + } 516 + EXPORT_SYMBOL_GPL(thermal_zone_device_exec); 499 517 500 518 static void thermal_zone_device_check(struct work_struct *work) 501 519 {
-4
drivers/thermal/thermal_core.h
··· 54 54 int for_each_thermal_governor(int (*cb)(struct thermal_governor *, void *), 55 55 void *thermal_governor); 56 56 57 - int __for_each_thermal_trip(struct thermal_zone_device *, 58 - int (*cb)(struct thermal_trip *, void *), 59 - void *); 60 - 61 57 struct thermal_zone_device *thermal_zone_get_by_id(int id); 62 58 63 59 struct thermal_attr {
+8 -10
drivers/thermal/thermal_trip.c
··· 9 9 */ 10 10 #include "thermal_core.h" 11 11 12 - int __for_each_thermal_trip(struct thermal_zone_device *tz, 13 - int (*cb)(struct thermal_trip *, void *), 14 - void *data) 12 + int for_each_thermal_trip(struct thermal_zone_device *tz, 13 + int (*cb)(struct thermal_trip *, void *), 14 + void *data) 15 15 { 16 16 int i, ret; 17 - struct thermal_trip trip; 18 17 19 18 lockdep_assert_held(&tz->lock); 20 19 20 + if (!tz->trips) 21 + return -ENODATA; 22 + 21 23 for (i = 0; i < tz->num_trips; i++) { 22 - 23 - ret = __thermal_zone_get_trip(tz, i, &trip); 24 - if (ret) 25 - return ret; 26 - 27 - ret = cb(&trip, data); 24 + ret = cb(&tz->trips[i], data); 28 25 if (ret) 29 26 return ret; 30 27 } 31 28 32 29 return 0; 33 30 } 31 + EXPORT_SYMBOL_GPL(for_each_thermal_trip); 34 32 35 33 int thermal_zone_get_num_trips(struct thermal_zone_device *tz) 36 34 {
+1
include/acpi/acnames.h
··· 22 22 #define METHOD_NAME__DDN "_DDN" 23 23 #define METHOD_NAME__DIS "_DIS" 24 24 #define METHOD_NAME__DMA "_DMA" 25 + #define METHOD_NAME__EVT "_EVT" 25 26 #define METHOD_NAME__HID "_HID" 26 27 #define METHOD_NAME__INI "_INI" 27 28 #define METHOD_NAME__PLD "_PLD"
+15 -2
include/acpi/acpi_bus.h
··· 515 515 int acpi_bus_get_private_data(acpi_handle, void **); 516 516 int acpi_bus_attach_private_data(acpi_handle, void *); 517 517 void acpi_bus_detach_private_data(acpi_handle); 518 + int acpi_dev_install_notify_handler(struct acpi_device *adev, 519 + u32 handler_type, 520 + acpi_notify_handler handler); 521 + void acpi_dev_remove_notify_handler(struct acpi_device *adev, 522 + u32 handler_type, 523 + acpi_notify_handler handler); 518 524 extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32); 519 525 extern int register_acpi_notifier(struct notifier_block *); 520 526 extern int unregister_acpi_notifier(struct notifier_block *); ··· 569 563 const struct acpi_device_id *ids); 570 564 void acpi_set_modalias(struct acpi_device *adev, const char *default_id, 571 565 char *modalias, size_t len); 572 - int acpi_create_dir(struct acpi_device *); 573 - void acpi_remove_dir(struct acpi_device *); 574 566 575 567 static inline bool acpi_device_enumerated(struct acpi_device *adev) 576 568 { ··· 649 645 #ifdef CONFIG_X86 650 646 bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *status); 651 647 bool acpi_quirk_skip_acpi_ac_and_battery(void); 648 + int acpi_install_cmos_rtc_space_handler(acpi_handle handle); 649 + void acpi_remove_cmos_rtc_space_handler(acpi_handle handle); 652 650 #else 653 651 static inline bool acpi_device_override_status(struct acpi_device *adev, 654 652 unsigned long long *status) ··· 660 654 static inline bool acpi_quirk_skip_acpi_ac_and_battery(void) 661 655 { 662 656 return false; 657 + } 658 + static inline int acpi_install_cmos_rtc_space_handler(acpi_handle handle) 659 + { 660 + return 1; 661 + } 662 + static inline void acpi_remove_cmos_rtc_space_handler(acpi_handle handle) 663 + { 663 664 } 664 665 #endif 665 666
+1 -3
include/acpi/acpixf.h
··· 12 12 13 13 /* Current ACPICA subsystem version in YYYYMMDD format */ 14 14 15 - #define ACPI_CA_VERSION 0x20230331 15 + #define ACPI_CA_VERSION 0x20230628 16 16 17 17 #include <acpi/acconfig.h> 18 18 #include <acpi/actypes.h> ··· 969 969 acpi_object_handler handler, 970 970 void **data, 971 971 void (*callback)(void *))) 972 - 973 - void acpi_run_debugger(char *batch_buffer); 974 972 975 973 void acpi_set_debugger_thread_id(acpi_thread_id thread_id); 976 974
+1 -1
include/acpi/actbl1.h
··· 402 402 403 403 /* Flags for subtable above */ 404 404 405 - #define ACPI_CEDT_DSMAS_NON_VOLATILE (1 << 2) 405 + #define ACPI_CDAT_DSMAS_NON_VOLATILE (1 << 2) 406 406 407 407 /* Subtable 1: Device scoped Latency and Bandwidth Information Structure (DSLBIS) */ 408 408
+74 -2
include/acpi/actbl2.h
··· 893 893 ACPI_MADT_TYPE_BIO_PIC = 22, 894 894 ACPI_MADT_TYPE_LPC_PIC = 23, 895 895 ACPI_MADT_TYPE_RINTC = 24, 896 - ACPI_MADT_TYPE_RESERVED = 25, /* 25 to 0x7F are reserved */ 896 + ACPI_MADT_TYPE_IMSIC = 25, 897 + ACPI_MADT_TYPE_APLIC = 26, 898 + ACPI_MADT_TYPE_PLIC = 27, 899 + ACPI_MADT_TYPE_RESERVED = 28, /* 28 to 0x7F are reserved */ 897 900 ACPI_MADT_TYPE_OEM_RESERVED = 0x80 /* 0x80 to 0xFF are reserved for OEM use */ 898 901 }; 899 902 ··· 1264 1261 u32 flags; 1265 1262 u64 hart_id; 1266 1263 u32 uid; /* ACPI processor UID */ 1264 + u32 ext_intc_id; /* External INTC Id */ 1265 + u64 imsic_addr; /* IMSIC base address */ 1266 + u32 imsic_size; /* IMSIC size */ 1267 1267 }; 1268 1268 1269 1269 /* Values for RISC-V INTC Version field above */ ··· 1275 1269 ACPI_MADT_RINTC_VERSION_NONE = 0, 1276 1270 ACPI_MADT_RINTC_VERSION_V1 = 1, 1277 1271 ACPI_MADT_RINTC_VERSION_RESERVED = 2 /* 2 and greater are reserved */ 1272 + }; 1273 + 1274 + /* 25: RISC-V IMSIC */ 1275 + struct acpi_madt_imsic { 1276 + struct acpi_subtable_header header; 1277 + u8 version; 1278 + u8 reserved; 1279 + u32 flags; 1280 + u16 num_ids; 1281 + u16 num_guest_ids; 1282 + u8 guest_index_bits; 1283 + u8 hart_index_bits; 1284 + u8 group_index_bits; 1285 + u8 group_index_shift; 1286 + }; 1287 + 1288 + /* 26: RISC-V APLIC */ 1289 + struct acpi_madt_aplic { 1290 + struct acpi_subtable_header header; 1291 + u8 version; 1292 + u8 id; 1293 + u32 flags; 1294 + u8 hw_id[8]; 1295 + u16 num_idcs; 1296 + u16 num_sources; 1297 + u32 gsi_base; 1298 + u64 base_addr; 1299 + u32 size; 1300 + }; 1301 + 1302 + /* 27: RISC-V PLIC */ 1303 + struct acpi_madt_plic { 1304 + struct acpi_subtable_header header; 1305 + u8 version; 1306 + u8 id; 1307 + u8 hw_id[8]; 1308 + u16 num_irqs; 1309 + u16 max_prio; 1310 + u32 flags; 1311 + u32 size; 1312 + u64 base_addr; 1313 + u32 gsi_base; 1278 1314 }; 1279 1315 1280 1316 /* 80: OEM data */ ··· 2778 2730 2779 2731 struct acpi_table_rhct { 2780 2732 struct acpi_table_header header; /* Common ACPI table header */ 2781 - u32 reserved; 2733 + u32 flags; /* RHCT flags */ 2782 2734 u64 time_base_freq; 2783 2735 u32 node_count; 2784 2736 u32 node_offset; 2785 2737 }; 2786 2738 2739 + /* RHCT Flags */ 2740 + 2741 + #define ACPI_RHCT_TIMER_CANNOT_WAKEUP_CPU (1) 2787 2742 /* 2788 2743 * RHCT subtables 2789 2744 */ ··· 2800 2749 2801 2750 enum acpi_rhct_node_type { 2802 2751 ACPI_RHCT_NODE_TYPE_ISA_STRING = 0x0000, 2752 + ACPI_RHCT_NODE_TYPE_CMO = 0x0001, 2753 + ACPI_RHCT_NODE_TYPE_MMU = 0x0002, 2754 + ACPI_RHCT_NODE_TYPE_RESERVED = 0x0003, 2803 2755 ACPI_RHCT_NODE_TYPE_HART_INFO = 0xFFFF, 2804 2756 }; 2805 2757 ··· 2814 2760 struct acpi_rhct_isa_string { 2815 2761 u16 isa_length; 2816 2762 char isa[]; 2763 + }; 2764 + 2765 + struct acpi_rhct_cmo_node { 2766 + u8 reserved; /* Must be zero */ 2767 + u8 cbom_size; /* CBOM size in powerof 2 */ 2768 + u8 cbop_size; /* CBOP size in powerof 2 */ 2769 + u8 cboz_size; /* CBOZ size in powerof 2 */ 2770 + }; 2771 + 2772 + struct acpi_rhct_mmu_node { 2773 + u8 reserved; /* Must be zero */ 2774 + u8 mmu_type; /* Virtual Address Scheme */ 2775 + }; 2776 + 2777 + enum acpi_rhct_mmu_type { 2778 + ACPI_RHCT_MMU_TYPE_SV39 = 0, 2779 + ACPI_RHCT_MMU_TYPE_SV48 = 1, 2780 + ACPI_RHCT_MMU_TYPE_SV57 = 2 2817 2781 }; 2818 2782 2819 2783 /* Hart Info node structure */
+3 -1
include/acpi/actbl3.h
··· 279 279 * 6: ACPI_SRAT_TYPE_GENERIC_PORT_AFFINITY 280 280 */ 281 281 282 + #define ACPI_SRAT_DEVICE_HANDLE_SIZE 16 283 + 282 284 struct acpi_srat_generic_affinity { 283 285 struct acpi_subtable_header header; 284 286 u8 reserved; 285 287 u8 device_handle_type; 286 288 u32 proximity_domain; 287 - u8 device_handle[16]; 289 + u8 device_handle[ACPI_SRAT_DEVICE_HANDLE_SIZE]; 288 290 u32 flags; 289 291 u32 reserved1; 290 292 };
-36
include/acpi/pdc_intel.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - 3 - /* _PDC bit definition for Intel processors */ 4 - 5 - #ifndef __PDC_INTEL_H__ 6 - #define __PDC_INTEL_H__ 7 - 8 - #define ACPI_PDC_P_FFH (0x0001) 9 - #define ACPI_PDC_C_C1_HALT (0x0002) 10 - #define ACPI_PDC_T_FFH (0x0004) 11 - #define ACPI_PDC_SMP_C1PT (0x0008) 12 - #define ACPI_PDC_SMP_C2C3 (0x0010) 13 - #define ACPI_PDC_SMP_P_SWCOORD (0x0020) 14 - #define ACPI_PDC_SMP_C_SWCOORD (0x0040) 15 - #define ACPI_PDC_SMP_T_SWCOORD (0x0080) 16 - #define ACPI_PDC_C_C1_FFH (0x0100) 17 - #define ACPI_PDC_C_C2C3_FFH (0x0200) 18 - #define ACPI_PDC_SMP_P_HWCOORD (0x0800) 19 - 20 - #define ACPI_PDC_EST_CAPABILITY_SMP (ACPI_PDC_SMP_C1PT | \ 21 - ACPI_PDC_C_C1_HALT | \ 22 - ACPI_PDC_P_FFH) 23 - 24 - #define ACPI_PDC_EST_CAPABILITY_SWSMP (ACPI_PDC_SMP_C1PT | \ 25 - ACPI_PDC_C_C1_HALT | \ 26 - ACPI_PDC_SMP_P_SWCOORD | \ 27 - ACPI_PDC_SMP_P_HWCOORD | \ 28 - ACPI_PDC_P_FFH) 29 - 30 - #define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \ 31 - ACPI_PDC_SMP_C1PT | \ 32 - ACPI_PDC_C_C1_HALT | \ 33 - ACPI_PDC_C_C1_FFH | \ 34 - ACPI_PDC_C_C2C3_FFH) 35 - 36 - #endif /* __PDC_INTEL_H__ */
+1
include/acpi/platform/aclinux.h
··· 182 182 #ifdef ACPI_USE_STANDARD_HEADERS 183 183 #include <stddef.h> 184 184 #include <unistd.h> 185 + #include <stdint.h> 185 186 186 187 #define ACPI_OFFSET(d, f) offsetof(d, f) 187 188 #endif
-3
include/acpi/platform/aczephyr.h
··· 10 10 #ifndef __ACZEPHYR_H__ 11 11 #define __ACZEPHYR_H__ 12 12 13 - #define SEEK_SET FS_SEEK_SET 14 - #define SEEK_END FS_SEEK_END 15 - 16 13 #define ACPI_MACHINE_WIDTH 64 17 14 18 15 #define ACPI_NO_ERROR_MESSAGES
+40
include/acpi/proc_cap_intel.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + /* Vendor specific processor capabilities bit definition 4 + * for Intel processors. Those bits are used to convey OSPM 5 + * power management capabilities to the platform. 6 + */ 7 + 8 + #ifndef __PROC_CAP_INTEL_H__ 9 + #define __PROC_CAP_INTEL_H__ 10 + 11 + #define ACPI_PROC_CAP_P_FFH (0x0001) 12 + #define ACPI_PROC_CAP_C_C1_HALT (0x0002) 13 + #define ACPI_PROC_CAP_T_FFH (0x0004) 14 + #define ACPI_PROC_CAP_SMP_C1PT (0x0008) 15 + #define ACPI_PROC_CAP_SMP_C2C3 (0x0010) 16 + #define ACPI_PROC_CAP_SMP_P_SWCOORD (0x0020) 17 + #define ACPI_PROC_CAP_SMP_C_SWCOORD (0x0040) 18 + #define ACPI_PROC_CAP_SMP_T_SWCOORD (0x0080) 19 + #define ACPI_PROC_CAP_C_C1_FFH (0x0100) 20 + #define ACPI_PROC_CAP_C_C2C3_FFH (0x0200) 21 + #define ACPI_PROC_CAP_SMP_P_HWCOORD (0x0800) 22 + #define ACPI_PROC_CAP_COLLAB_PROC_PERF (0x1000) 23 + 24 + #define ACPI_PROC_CAP_EST_CAPABILITY_SMP (ACPI_PROC_CAP_SMP_C1PT | \ 25 + ACPI_PROC_CAP_C_C1_HALT | \ 26 + ACPI_PROC_CAP_P_FFH) 27 + 28 + #define ACPI_PROC_CAP_EST_CAPABILITY_SWSMP (ACPI_PROC_CAP_SMP_C1PT | \ 29 + ACPI_PROC_CAP_C_C1_HALT | \ 30 + ACPI_PROC_CAP_SMP_P_SWCOORD | \ 31 + ACPI_PROC_CAP_SMP_P_HWCOORD | \ 32 + ACPI_PROC_CAP_P_FFH) 33 + 34 + #define ACPI_PROC_CAP_C_CAPABILITY_SMP (ACPI_PROC_CAP_SMP_C2C3 | \ 35 + ACPI_PROC_CAP_SMP_C1PT | \ 36 + ACPI_PROC_CAP_C_C1_HALT | \ 37 + ACPI_PROC_CAP_C_C1_FFH | \ 38 + ACPI_PROC_CAP_C_C2C3_FFH) 39 + 40 + #endif /* __PROC_CAP_INTEL_H__ */
+8 -4
include/linux/acpi.h
··· 477 477 return 0; 478 478 } 479 479 #endif 480 - extern int acpi_paddr_to_node(u64 start_addr, u64 size); 481 - 482 480 extern int pnpacpi_disabled; 483 481 484 482 #define PXM_INVAL (-1) ··· 1098 1100 1099 1101 acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state, 1100 1102 u32 val_a, u32 val_b); 1101 - #ifdef CONFIG_X86 1103 + #if defined(CONFIG_SUSPEND) && defined(CONFIG_X86) 1102 1104 struct acpi_s2idle_dev_ops { 1103 1105 struct list_head list_node; 1104 1106 void (*prepare)(void); ··· 1107 1109 }; 1108 1110 int acpi_register_lps0_dev(struct acpi_s2idle_dev_ops *arg); 1109 1111 void acpi_unregister_lps0_dev(struct acpi_s2idle_dev_ops *arg); 1110 - #endif /* CONFIG_X86 */ 1112 + int acpi_get_lps0_constraint(struct acpi_device *adev); 1113 + #else /* CONFIG_SUSPEND && CONFIG_X86 */ 1114 + static inline int acpi_get_lps0_constraint(struct device *dev) 1115 + { 1116 + return ACPI_STATE_UNKNOWN; 1117 + } 1118 + #endif /* CONFIG_SUSPEND && CONFIG_X86 */ 1111 1119 #ifndef CONFIG_IA64 1112 1120 void arch_reserve_mem_area(acpi_physical_address addr, size_t size); 1113 1121 #else
+9
include/linux/thermal.h
··· 81 81 * @temperature: temperature value in miliCelsius 82 82 * @hysteresis: relative hysteresis in miliCelsius 83 83 * @type: trip point type 84 + * @priv: pointer to driver data associated with this trip 84 85 */ 85 86 struct thermal_trip { 86 87 int temperature; 87 88 int hysteresis; 88 89 enum thermal_trip_type type; 90 + void *priv; 89 91 }; 90 92 91 93 struct thermal_cooling_device_ops { ··· 289 287 int thermal_zone_set_trip(struct thermal_zone_device *tz, int trip_id, 290 288 const struct thermal_trip *trip); 291 289 290 + int for_each_thermal_trip(struct thermal_zone_device *tz, 291 + int (*cb)(struct thermal_trip *, void *), 292 + void *data); 292 293 int thermal_zone_get_num_trips(struct thermal_zone_device *tz); 293 294 294 295 int thermal_zone_get_crit_temp(struct thermal_zone_device *tz, int *temp); ··· 328 323 struct thermal_cooling_device *); 329 324 void thermal_zone_device_update(struct thermal_zone_device *, 330 325 enum thermal_notify_event); 326 + void thermal_zone_device_exec(struct thermal_zone_device *tz, 327 + void (*cb)(struct thermal_zone_device *, 328 + unsigned long), 329 + unsigned long data); 331 330 332 331 struct thermal_cooling_device *thermal_cooling_device_register(const char *, 333 332 void *, const struct thermal_cooling_device_ops *);