[PATCH v7 066/120] ACPI: PAD: Use Parsed CPUID(0x5)

"Ahmed S. Darwish" <[email protected]> Thu, 28 May 2026 17:38:28 +0200
Newsgroups dev.linux.lists.x86-cpuid,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
Use parsed CPUID(0x5), plus CPUID(0x5) APIs, instead of doing ugly bitwise
operations and a direct CPUID query.

Note, preserve EDX walk semantics: the original code shifted EDX by
MWAIT_SUBSTATE_SIZE before entering the loop, hence skipping the C0
substate count.  Start the parsed lookup at C1 for the same reason.

Note, the original "&& edx" loop condition avoided trailing zero nibbles
but dropping it should not be problematic: zero substate counts are always
ignored.

Signed-off-by: Ahmed S. Darwish <[email protected]>
---
 drivers/acpi/acpi_pad.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c
index ec94b09bb747..45b1793cd3b4 100644
--- a/drivers/acpi/acpi_pad.c
+++ b/drivers/acpi/acpi_pad.c
@@ -38,27 +38,27 @@ static unsigned char tsc_marked_unstable;
 
 static void power_saving_mwait_init(void)
 {
-	unsigned int eax, ebx, ecx, edx;
+	const struct leaf_0x5_0 *l5 = cpuid_leaf(&boot_cpu_data, 0x5);
 	unsigned int highest_cstate = 0;
 	unsigned int highest_subcstate = 0;
 	int i;
 
-	if (!boot_cpu_has(X86_FEATURE_MWAIT))
+	if (!l5 || !boot_cpu_has(X86_FEATURE_MWAIT))
 		return;
 
-	cpuid(CPUID_LEAF_MWAIT, &eax, &ebx, &ecx, &edx);
-
-	if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) ||
-	    !(ecx & CPUID5_ECX_INTERRUPT_BREAK))
+	if (!l5->mwait_ext || !l5->mwait_irq_break)
 		return;
 
-	edx >>= MWAIT_SUBSTATE_SIZE;
-	for (i = 0; i < 7 && edx; i++, edx >>= MWAIT_SUBSTATE_SIZE) {
-		if (edx & MWAIT_SUBSTATE_MASK) {
-			highest_cstate = i;
-			highest_subcstate = edx & MWAIT_SUBSTATE_MASK;
-		}
+	for (i = 0; i < 7; i++) {
+		unsigned int nsubstates = cpuid_mwait_n_substates(l5, i + 1);
+
+		if (!nsubstates)
+			continue;
+
+		highest_cstate = i;
+		highest_subcstate = nsubstates;
 	}
+
 	power_saving_mwait_eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) |
 		(highest_subcstate - 1);
 
-- 
2.54.0