Commit ad46e8f9 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull power management fix from Rafael Wysocki:
 "Fix idle states enumeration in the intel_idle driver on platforms
  supporting multiple flavors of the C6 idle state (Artem Bityutskiy)"

* tag 'pm-6.12-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  intel_idle: fix ACPI _CST matching for newer Xeon platforms
parents 12cc5240 4c411cca
...@@ -120,6 +120,12 @@ static unsigned int mwait_substates __initdata; ...@@ -120,6 +120,12 @@ static unsigned int mwait_substates __initdata;
*/ */
#define CPUIDLE_FLAG_INIT_XSTATE BIT(17) #define CPUIDLE_FLAG_INIT_XSTATE BIT(17)
/*
* Ignore the sub-state when matching mwait hints between the ACPI _CST and
* custom tables.
*/
#define CPUIDLE_FLAG_PARTIAL_HINT_MATCH BIT(18)
/* /*
* MWAIT takes an 8-bit "hint" in EAX "suggesting" * MWAIT takes an 8-bit "hint" in EAX "suggesting"
* the C-state (top nibble) and sub-state (bottom nibble) * the C-state (top nibble) and sub-state (bottom nibble)
...@@ -1043,7 +1049,8 @@ static struct cpuidle_state gnr_cstates[] __initdata = { ...@@ -1043,7 +1049,8 @@ static struct cpuidle_state gnr_cstates[] __initdata = {
.name = "C6", .name = "C6",
.desc = "MWAIT 0x20", .desc = "MWAIT 0x20",
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED | .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED |
CPUIDLE_FLAG_INIT_XSTATE, CPUIDLE_FLAG_INIT_XSTATE |
CPUIDLE_FLAG_PARTIAL_HINT_MATCH,
.exit_latency = 170, .exit_latency = 170,
.target_residency = 650, .target_residency = 650,
.enter = &intel_idle, .enter = &intel_idle,
...@@ -1052,7 +1059,8 @@ static struct cpuidle_state gnr_cstates[] __initdata = { ...@@ -1052,7 +1059,8 @@ static struct cpuidle_state gnr_cstates[] __initdata = {
.name = "C6P", .name = "C6P",
.desc = "MWAIT 0x21", .desc = "MWAIT 0x21",
.flags = MWAIT2flg(0x21) | CPUIDLE_FLAG_TLB_FLUSHED | .flags = MWAIT2flg(0x21) | CPUIDLE_FLAG_TLB_FLUSHED |
CPUIDLE_FLAG_INIT_XSTATE, CPUIDLE_FLAG_INIT_XSTATE |
CPUIDLE_FLAG_PARTIAL_HINT_MATCH,
.exit_latency = 210, .exit_latency = 210,
.target_residency = 1000, .target_residency = 1000,
.enter = &intel_idle, .enter = &intel_idle,
...@@ -1354,7 +1362,8 @@ static struct cpuidle_state srf_cstates[] __initdata = { ...@@ -1354,7 +1362,8 @@ static struct cpuidle_state srf_cstates[] __initdata = {
{ {
.name = "C6S", .name = "C6S",
.desc = "MWAIT 0x22", .desc = "MWAIT 0x22",
.flags = MWAIT2flg(0x22) | CPUIDLE_FLAG_TLB_FLUSHED, .flags = MWAIT2flg(0x22) | CPUIDLE_FLAG_TLB_FLUSHED |
CPUIDLE_FLAG_PARTIAL_HINT_MATCH,
.exit_latency = 270, .exit_latency = 270,
.target_residency = 700, .target_residency = 700,
.enter = &intel_idle, .enter = &intel_idle,
...@@ -1362,7 +1371,8 @@ static struct cpuidle_state srf_cstates[] __initdata = { ...@@ -1362,7 +1371,8 @@ static struct cpuidle_state srf_cstates[] __initdata = {
{ {
.name = "C6SP", .name = "C6SP",
.desc = "MWAIT 0x23", .desc = "MWAIT 0x23",
.flags = MWAIT2flg(0x23) | CPUIDLE_FLAG_TLB_FLUSHED, .flags = MWAIT2flg(0x23) | CPUIDLE_FLAG_TLB_FLUSHED |
CPUIDLE_FLAG_PARTIAL_HINT_MATCH,
.exit_latency = 310, .exit_latency = 310,
.target_residency = 900, .target_residency = 900,
.enter = &intel_idle, .enter = &intel_idle,
...@@ -1744,7 +1754,7 @@ static void __init intel_idle_init_cstates_acpi(struct cpuidle_driver *drv) ...@@ -1744,7 +1754,7 @@ static void __init intel_idle_init_cstates_acpi(struct cpuidle_driver *drv)
} }
} }
static bool __init intel_idle_off_by_default(u32 mwait_hint) static bool __init intel_idle_off_by_default(unsigned int flags, u32 mwait_hint)
{ {
int cstate, limit; int cstate, limit;
...@@ -1761,7 +1771,15 @@ static bool __init intel_idle_off_by_default(u32 mwait_hint) ...@@ -1761,7 +1771,15 @@ static bool __init intel_idle_off_by_default(u32 mwait_hint)
* the interesting states are ACPI_CSTATE_FFH. * the interesting states are ACPI_CSTATE_FFH.
*/ */
for (cstate = 1; cstate < limit; cstate++) { for (cstate = 1; cstate < limit; cstate++) {
if (acpi_state_table.states[cstate].address == mwait_hint) u32 acpi_hint = acpi_state_table.states[cstate].address;
u32 table_hint = mwait_hint;
if (flags & CPUIDLE_FLAG_PARTIAL_HINT_MATCH) {
acpi_hint &= ~MWAIT_SUBSTATE_MASK;
table_hint &= ~MWAIT_SUBSTATE_MASK;
}
if (acpi_hint == table_hint)
return false; return false;
} }
return true; return true;
...@@ -1771,7 +1789,10 @@ static bool __init intel_idle_off_by_default(u32 mwait_hint) ...@@ -1771,7 +1789,10 @@ static bool __init intel_idle_off_by_default(u32 mwait_hint)
static inline bool intel_idle_acpi_cst_extract(void) { return false; } static inline bool intel_idle_acpi_cst_extract(void) { return false; }
static inline void intel_idle_init_cstates_acpi(struct cpuidle_driver *drv) { } static inline void intel_idle_init_cstates_acpi(struct cpuidle_driver *drv) { }
static inline bool intel_idle_off_by_default(u32 mwait_hint) { return false; } static inline bool intel_idle_off_by_default(unsigned int flags, u32 mwait_hint)
{
return false;
}
#endif /* !CONFIG_ACPI_PROCESSOR_CSTATE */ #endif /* !CONFIG_ACPI_PROCESSOR_CSTATE */
/** /**
...@@ -2098,7 +2119,7 @@ static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv) ...@@ -2098,7 +2119,7 @@ static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv)
if ((disabled_states_mask & BIT(drv->state_count)) || if ((disabled_states_mask & BIT(drv->state_count)) ||
((icpu->use_acpi || force_use_acpi) && ((icpu->use_acpi || force_use_acpi) &&
intel_idle_off_by_default(mwait_hint) && intel_idle_off_by_default(state->flags, mwait_hint) &&
!(state->flags & CPUIDLE_FLAG_ALWAYS_ENABLE))) !(state->flags & CPUIDLE_FLAG_ALWAYS_ENABLE)))
state->flags |= CPUIDLE_FLAG_OFF; state->flags |= CPUIDLE_FLAG_OFF;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment