[PATCH v7 066/120] ACPI: PAD: Use Parsed CPUID(0x5)
From: Ahmed S. Darwish
Date: Thu May 28 2026 - 12:21:19 EST
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 <darwi@xxxxxxxxxxxxx>
---
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