diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2011-09-30 20:03:37 +0200 |
---|---|---|
committer | Clark Williams <williams@redhat.com> | 2012-04-13 11:01:14 -0500 |
commit | e69882f581bd00d9fac23a5d32dedb7bff19e584 (patch) | |
tree | 3db7f96532caf47051addbb1c0c4a8c657301d6a | |
parent | 2ba7dbe93e0b4678ce77c9446a53ea30564039da (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>
-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 ad0de0c2714e..230a200763aa 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -8,6 +8,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> @@ -570,6 +571,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; @@ -577,6 +602,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; |