ACPI: processor: Introduce acpi_processor_osc()

The processor _OSC method is already used for a workaround introduced
in commit a21211672c ("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>
This commit is contained in:
Michal Wilczynski 2023-07-10 17:03:35 +03:00 committed by Rafael J. Wysocki
parent b9e8d0168a
commit 5ba30be7fd
3 changed files with 33 additions and 1 deletions

View File

@ -115,6 +115,9 @@ static inline void arch_acpi_set_proc_cap_bits(u32 *cap)
if (cpu_has(c, X86_FEATURE_ACPI)) if (cpu_has(c, X86_FEATURE_ACPI))
*cap |= ACPI_PROC_CAP_T_FFH; *cap |= ACPI_PROC_CAP_T_FFH;
if (cpu_has(c, X86_FEATURE_HWP))
*cap |= ACPI_PROC_CAP_COLLAB_PROC_PERF;
/* /*
* If mwait/monitor is unsupported, C_C1_FFH and * If mwait/monitor is unsupported, C_C1_FFH and
* C2/C3_FFH will be disabled. * C2/C3_FFH will be disabled.

View File

@ -559,13 +559,41 @@ bool __init processor_physically_present(acpi_handle handle)
return !invalid_logical_cpuid(cpuid); return !invalid_logical_cpuid(cpuid);
} }
/* vendor specific UUID indicating an Intel platform */
static u8 sb_uuid_str[] = "4077A616-290C-47BE-9EBD-D87058713953";
static bool acpi_hwp_native_thermal_lvt_set; static bool acpi_hwp_native_thermal_lvt_set;
static acpi_status __init acpi_processor_osc(acpi_handle handle, u32 lvl,
void *context, void **rv)
{
u32 capbuf[2] = {};
struct acpi_osc_context osc_context = {
.uuid_str = sb_uuid_str,
.rev = 1,
.cap.length = 8,
.cap.pointer = capbuf,
};
acpi_status status;
if (!processor_physically_present(handle))
return AE_OK;
arch_acpi_set_proc_cap_bits(&capbuf[OSC_SUPPORT_DWORD]);
status = acpi_run_osc(handle, &osc_context);
if (ACPI_FAILURE(status))
return status;
kfree(osc_context.ret.pointer);
return AE_OK;
}
static acpi_status __init acpi_hwp_native_thermal_lvt_osc(acpi_handle handle, static acpi_status __init acpi_hwp_native_thermal_lvt_osc(acpi_handle handle,
u32 lvl, u32 lvl,
void *context, void *context,
void **rv) void **rv)
{ {
u8 sb_uuid_str[] = "4077A616-290C-47BE-9EBD-D87058713953";
u32 capbuf[2]; u32 capbuf[2];
struct acpi_osc_context osc_context = { struct acpi_osc_context osc_context = {
.uuid_str = sb_uuid_str, .uuid_str = sb_uuid_str,

View File

@ -19,6 +19,7 @@
#define ACPI_PROC_CAP_C_C1_FFH (0x0100) #define ACPI_PROC_CAP_C_C1_FFH (0x0100)
#define ACPI_PROC_CAP_C_C2C3_FFH (0x0200) #define ACPI_PROC_CAP_C_C2C3_FFH (0x0200)
#define ACPI_PROC_CAP_SMP_P_HWCOORD (0x0800) #define ACPI_PROC_CAP_SMP_P_HWCOORD (0x0800)
#define ACPI_PROC_CAP_COLLAB_PROC_PERF (0x1000)
#define ACPI_PROC_CAP_EST_CAPABILITY_SMP (ACPI_PROC_CAP_SMP_C1PT | \ #define ACPI_PROC_CAP_EST_CAPABILITY_SMP (ACPI_PROC_CAP_SMP_C1PT | \
ACPI_PROC_CAP_C_C1_HALT | \ ACPI_PROC_CAP_C_C1_HALT | \