diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2011-09-30 20:03:37 +0200 |
---|---|---|
committer | Clark Williams <williams@redhat.com> | 2012-04-10 16:36:22 -0500 |
commit | 22c4d1e4cd58f8e4c5a13968503d46b492b33c61 (patch) | |
tree | 92a1f0fdcfe122fd6a4dcecd47a2a337db49a4e8 /arch/x86/kernel | |
parent | cc5fb59ccae5a1cdb25767874251368b3c0a6c6d (diff) |
x86: hpet: Disable MSI on Lenovo W510
MSI based per cpu timers lose interrupts when intel_idle() is enabled
- independent of the c-state. With idle=poll the problem cannot be
observed. We have no idea yet, whether this is a W510 specific issue
or a general chipset oddity. Blacklist the known problem machine.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/hpet.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 1bb0bf4d92cd..d86b82190b80 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -9,6 +9,7 @@ #include <linux/slab.h> #include <linux/hpet.h> #include <linux/init.h> +#include <linux/dmi.h> #include <linux/cpu.h> #include <linux/pm.h> #include <linux/io.h> @@ -568,6 +569,30 @@ static void init_one_hpet_msi_clockevent(struct hpet_dev *hdev, int cpu) #define RESERVE_TIMERS 0 #endif +static int __init dmi_disable_hpet_msi(const struct dmi_system_id *d) +{ + hpet_msi_disable = 1; + return 0; +} + +static struct dmi_system_id __initdata dmi_hpet_table[] = { + /* + * MSI based per cpu timers lose interrupts when intel_idle() + * is enabled - independent of the c-state. With idle=poll the + * problem cannot be observed. We have no idea yet, whether + * this is a W510 specific issue or a general chipset oddity. + */ + { + .callback = dmi_disable_hpet_msi, + .ident = "Lenovo W510", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W510"), + }, + }, + {} +}; + static void hpet_msi_capability_lookup(unsigned int start_timer) { unsigned int id; @@ -575,6 +600,8 @@ static void hpet_msi_capability_lookup(unsigned int start_timer) unsigned int num_timers_used = 0; int i; + dmi_check_system(dmi_hpet_table); + if (hpet_msi_disable) return; |