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

ACPI: processor: Introduce acpi_processor_osc()

The processor _OSC method is already used for a workaround introduced
in commit a21211672c9a ("ACPI / processor: Request native thermal
interrupt handling via _OSC"), but in accordance with ACPI 6.5 (and
earlier), it should be used for negotiating all of the processor
capabilities instead of _PDC (which has been deprecated since ACPI 3.0
and got removed from ACPI 6.5 entirely).

Create a new callback function called acpi_processor_osc() to be invoked
for every processor object and processor device in the ACPI namespace, in
analogy with the already existing acpi_hwp_native_thermal_lvt_osc().

Make this function implement the workaround mentioned above and convey
all of the OSPM processor support information to the platform firmware
by setting all of the appropriate processor capabilities bits before
evaluating _OSC for the given processor. For this purpose, make it
call arch_acpi_set_proc_cap_bits() and modify the latter to set
ACPI_PROC_CAP_COLLAB_PROC_PERF along with the other processor
capabilities bits.

Suggested-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Michal Wilczynski <michal.wilczynski@intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ rjw: Subject and changelog edits, whitespace fixup ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Michal Wilczynski and committed by
Rafael J. Wysocki
5ba30be7 b9e8d016

+33 -1
+3
arch/x86/include/asm/acpi.h
··· 115 115 if (cpu_has(c, X86_FEATURE_ACPI)) 116 116 *cap |= ACPI_PROC_CAP_T_FFH; 117 117 118 + if (cpu_has(c, X86_FEATURE_HWP)) 119 + *cap |= ACPI_PROC_CAP_COLLAB_PROC_PERF; 120 + 118 121 /* 119 122 * If mwait/monitor is unsupported, C_C1_FFH and 120 123 * C2/C3_FFH will be disabled.
+29 -1
drivers/acpi/acpi_processor.c
··· 559 559 return !invalid_logical_cpuid(cpuid); 560 560 } 561 561 562 + /* vendor specific UUID indicating an Intel platform */ 563 + static u8 sb_uuid_str[] = "4077A616-290C-47BE-9EBD-D87058713953"; 562 564 static bool acpi_hwp_native_thermal_lvt_set; 565 + 566 + static acpi_status __init acpi_processor_osc(acpi_handle handle, u32 lvl, 567 + void *context, void **rv) 568 + { 569 + u32 capbuf[2] = {}; 570 + struct acpi_osc_context osc_context = { 571 + .uuid_str = sb_uuid_str, 572 + .rev = 1, 573 + .cap.length = 8, 574 + .cap.pointer = capbuf, 575 + }; 576 + acpi_status status; 577 + 578 + if (!processor_physically_present(handle)) 579 + return AE_OK; 580 + 581 + arch_acpi_set_proc_cap_bits(&capbuf[OSC_SUPPORT_DWORD]); 582 + 583 + status = acpi_run_osc(handle, &osc_context); 584 + if (ACPI_FAILURE(status)) 585 + return status; 586 + 587 + kfree(osc_context.ret.pointer); 588 + 589 + return AE_OK; 590 + } 591 + 563 592 static acpi_status __init acpi_hwp_native_thermal_lvt_osc(acpi_handle handle, 564 593 u32 lvl, 565 594 void *context, 566 595 void **rv) 567 596 { 568 - u8 sb_uuid_str[] = "4077A616-290C-47BE-9EBD-D87058713953"; 569 597 u32 capbuf[2]; 570 598 struct acpi_osc_context osc_context = { 571 599 .uuid_str = sb_uuid_str,
+1
include/acpi/proc_cap_intel.h
··· 19 19 #define ACPI_PROC_CAP_C_C1_FFH (0x0100) 20 20 #define ACPI_PROC_CAP_C_C2C3_FFH (0x0200) 21 21 #define ACPI_PROC_CAP_SMP_P_HWCOORD (0x0800) 22 + #define ACPI_PROC_CAP_COLLAB_PROC_PERF (0x1000) 22 23 23 24 #define ACPI_PROC_CAP_EST_CAPABILITY_SMP (ACPI_PROC_CAP_SMP_C1PT | \ 24 25 ACPI_PROC_CAP_C_C1_HALT | \