From 9eadbed788df453289b5927327bd22edb542f472 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 3 Aug 2026 20:11:10 +0200 Subject: [PATCH] intel_idle: Avoid using deep idle states during initialization Commit c0f691388992 ("intel_idle: Use subsys_initcall_sync() for initialization") effectively made intel_idle initialize earlier which turns out to interfere with USB EHCI probing on some platforms [1]. Investigation led to the conclusion that this was related to allowing package idle states to be used earlier than before. Work around that issue by making intel_idle set a CPU latency QoS request to prevent package idle states from being used on all platforms supported by it for the duration of the device_initcall() initialization phase. Fixes: c0f691388992 ("intel_idle: Use subsys_initcall_sync() for initialization") Reported-by: Julian Silver Tested-by: Julian Silver Closes: https://lore.kernel.org/linux-acpi/3353bdf3-4f33-44b1-809b-b0378bee5816@gmail.com/ Signed-off-by: Rafael J. Wysocki Link: https://patch.msgid.link/5120454.31r3eYUQgx@rafael.j.wysocki --- drivers/idle/intel_idle.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index d74b478db280..49c4ac9c7bb6 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -2697,6 +2698,9 @@ static void __init cmdline_table_adjust(struct cpuidle_driver *drv) pr_info("Failed to adjust C-states with data from 'intel_idle.table'\n"); } +#define INTEL_IDLE_INIT_QOS 20 +static struct pm_qos_request qos_req __initdata; + static int __init intel_idle_init(void) { const struct x86_cpu_id *id; @@ -2766,6 +2770,13 @@ static int __init intel_idle_init(void) if (retval) pr_warn("failed to initialized sysfs"); + /* + * Some platforms, in particular the Intel S1200BTL motherboard, have a + * problem with using package idle states too early, so prevent that + * from taking place until the device_initcall() phase is over. + */ + cpu_latency_qos_add_request(&qos_req, INTEL_IDLE_INIT_QOS); + retval = cpuidle_register_driver(&intel_idle_driver); if (retval) { struct cpuidle_driver *drv = cpuidle_get_driver(); @@ -2790,6 +2801,9 @@ static int __init intel_idle_init(void) intel_idle_cpuidle_devices_uninit(); cpuidle_unregister_driver(&intel_idle_driver); init_driver_fail: + if (cpu_latency_qos_request_active((&qos_req))) + cpu_latency_qos_remove_request(&qos_req); + intel_idle_sysfs_uninit(); free_percpu(intel_idle_cpuidle_devices); return retval; @@ -2797,6 +2811,15 @@ static int __init intel_idle_init(void) } subsys_initcall_sync(intel_idle_init); +static int __init intel_idle_init_complete(void) +{ + if (cpu_latency_qos_request_active((&qos_req))) + cpu_latency_qos_remove_request(&qos_req); + + return 0; +} +device_initcall_sync(intel_idle_init_complete); + /* * We are not really modular, but we used to support that. Meaning we also * support "intel_idle.max_cstate=..." at boot and also a read-only export of