Commit ad46e8f9 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+29 −8
Original line number Diff line number Diff line
@@ -120,6 +120,12 @@ static unsigned int mwait_substates __initdata;
 */
#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"
 * the C-state (top nibble) and sub-state (bottom nibble)
@@ -1043,7 +1049,8 @@ static struct cpuidle_state gnr_cstates[] __initdata = {
		.name = "C6",
		.desc = "MWAIT 0x20",
		.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED |
					   CPUIDLE_FLAG_INIT_XSTATE,
					   CPUIDLE_FLAG_INIT_XSTATE |
					   CPUIDLE_FLAG_PARTIAL_HINT_MATCH,
		.exit_latency = 170,
		.target_residency = 650,
		.enter = &intel_idle,
@@ -1052,7 +1059,8 @@ static struct cpuidle_state gnr_cstates[] __initdata = {
		.name = "C6P",
		.desc = "MWAIT 0x21",
		.flags = MWAIT2flg(0x21) | CPUIDLE_FLAG_TLB_FLUSHED |
					   CPUIDLE_FLAG_INIT_XSTATE,
					   CPUIDLE_FLAG_INIT_XSTATE |
					   CPUIDLE_FLAG_PARTIAL_HINT_MATCH,
		.exit_latency = 210,
		.target_residency = 1000,
		.enter = &intel_idle,
@@ -1354,7 +1362,8 @@ static struct cpuidle_state srf_cstates[] __initdata = {
	{
		.name = "C6S",
		.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,
		.target_residency = 700,
		.enter = &intel_idle,
@@ -1362,7 +1371,8 @@ static struct cpuidle_state srf_cstates[] __initdata = {
	{
		.name = "C6SP",
		.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,
		.target_residency = 900,
		.enter = &intel_idle,
@@ -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;

@@ -1761,7 +1771,15 @@ static bool __init intel_idle_off_by_default(u32 mwait_hint)
	 * the interesting states are ACPI_CSTATE_FFH.
	 */
	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 true;
@@ -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 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 */

/**
@@ -2098,7 +2119,7 @@ static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv)

		if ((disabled_states_mask & BIT(drv->state_count)) ||
		    ((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_OFF;