diff options
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/therm_throt.c | 3 | ||||
| -rw-r--r-- | drivers/acpi/acpi_processor.c | 52 | ||||
| -rw-r--r-- | drivers/acpi/bus.c | 3 | ||||
| -rw-r--r-- | drivers/acpi/internal.h | 6 |
4 files changed, 64 insertions, 0 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c index 2c5aaf8c2e2f..05538582a809 100644 --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c | |||
| @@ -385,6 +385,9 @@ static void intel_thermal_interrupt(void) | |||
| 385 | { | 385 | { |
| 386 | __u64 msr_val; | 386 | __u64 msr_val; |
| 387 | 387 | ||
| 388 | if (static_cpu_has(X86_FEATURE_HWP)) | ||
| 389 | wrmsrl_safe(MSR_HWP_STATUS, 0); | ||
| 390 | |||
| 388 | rdmsrl(MSR_IA32_THERM_STATUS, msr_val); | 391 | rdmsrl(MSR_IA32_THERM_STATUS, msr_val); |
| 389 | 392 | ||
| 390 | /* Check for violation of core thermal thresholds*/ | 393 | /* Check for violation of core thermal thresholds*/ |
diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index b5e54f2da53d..0d92d0f915e9 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c | |||
| @@ -491,6 +491,58 @@ static void acpi_processor_remove(struct acpi_device *device) | |||
| 491 | } | 491 | } |
| 492 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ | 492 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ |
| 493 | 493 | ||
| 494 | #ifdef CONFIG_X86 | ||
| 495 | static bool acpi_hwp_native_thermal_lvt_set; | ||
| 496 | static acpi_status __init acpi_hwp_native_thermal_lvt_osc(acpi_handle handle, | ||
| 497 | u32 lvl, | ||
| 498 | void *context, | ||
| 499 | void **rv) | ||
| 500 | { | ||
| 501 | u8 sb_uuid_str[] = "4077A616-290C-47BE-9EBD-D87058713953"; | ||
| 502 | u32 capbuf[2]; | ||
| 503 | struct acpi_osc_context osc_context = { | ||
| 504 | .uuid_str = sb_uuid_str, | ||
| 505 | .rev = 1, | ||
| 506 | .cap.length = 8, | ||
| 507 | .cap.pointer = capbuf, | ||
| 508 | }; | ||
| 509 | |||
| 510 | if (acpi_hwp_native_thermal_lvt_set) | ||
| 511 | return AE_CTRL_TERMINATE; | ||
| 512 | |||
| 513 | capbuf[0] = 0x0000; | ||
| 514 | capbuf[1] = 0x1000; /* set bit 12 */ | ||
| 515 | |||
| 516 | if (ACPI_SUCCESS(acpi_run_osc(handle, &osc_context))) { | ||
| 517 | if (osc_context.ret.pointer && osc_context.ret.length > 1) { | ||
| 518 | u32 *capbuf_ret = osc_context.ret.pointer; | ||
| 519 | |||
| 520 | if (capbuf_ret[1] & 0x1000) { | ||
| 521 | acpi_handle_info(handle, | ||
| 522 | "_OSC native thermal LVT Acked\n"); | ||
| 523 | acpi_hwp_native_thermal_lvt_set = true; | ||
| 524 | } | ||
| 525 | } | ||
| 526 | kfree(osc_context.ret.pointer); | ||
| 527 | } | ||
| 528 | |||
| 529 | return AE_OK; | ||
| 530 | } | ||
| 531 | |||
| 532 | void __init acpi_early_processor_osc(void) | ||
| 533 | { | ||
| 534 | if (boot_cpu_has(X86_FEATURE_HWP)) { | ||
| 535 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, | ||
| 536 | ACPI_UINT32_MAX, | ||
| 537 | acpi_hwp_native_thermal_lvt_osc, | ||
| 538 | NULL, NULL, NULL); | ||
| 539 | acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID, | ||
| 540 | acpi_hwp_native_thermal_lvt_osc, | ||
| 541 | NULL, NULL); | ||
| 542 | } | ||
| 543 | } | ||
| 544 | #endif | ||
| 545 | |||
| 494 | /* | 546 | /* |
| 495 | * The following ACPI IDs are known to be suitable for representing as | 547 | * The following ACPI IDs are known to be suitable for representing as |
| 496 | * processor devices. | 548 | * processor devices. |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 891c42d1cd65..f9081b791b81 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
| @@ -1005,6 +1005,9 @@ static int __init acpi_bus_init(void) | |||
| 1005 | goto error1; | 1005 | goto error1; |
| 1006 | } | 1006 | } |
| 1007 | 1007 | ||
| 1008 | /* Set capability bits for _OSC under processor scope */ | ||
| 1009 | acpi_early_processor_osc(); | ||
| 1010 | |||
| 1008 | /* | 1011 | /* |
| 1009 | * _OSC method may exist in module level code, | 1012 | * _OSC method may exist in module level code, |
| 1010 | * so it must be run after ACPI_FULL_INITIALIZATION | 1013 | * so it must be run after ACPI_FULL_INITIALIZATION |
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 1e6833a5cd44..6f41c73f82bb 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
| @@ -138,6 +138,12 @@ void acpi_early_processor_set_pdc(void); | |||
| 138 | static inline void acpi_early_processor_set_pdc(void) {} | 138 | static inline void acpi_early_processor_set_pdc(void) {} |
| 139 | #endif | 139 | #endif |
| 140 | 140 | ||
| 141 | #ifdef CONFIG_X86 | ||
| 142 | void acpi_early_processor_osc(void); | ||
| 143 | #else | ||
| 144 | static inline void acpi_early_processor_osc(void) {} | ||
| 145 | #endif | ||
| 146 | |||
| 141 | /* -------------------------------------------------------------------------- | 147 | /* -------------------------------------------------------------------------- |
| 142 | Embedded Controller | 148 | Embedded Controller |
| 143 | -------------------------------------------------------------------------- */ | 149 | -------------------------------------------------------------------------- */ |
