diff options
Diffstat (limited to 'arch/x86/kernel/quirks.c')
-rw-r--r-- | arch/x86/kernel/quirks.c | 112 |
1 files changed, 100 insertions, 12 deletions
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index d769e204f942..a4ce1911efdf 100644 --- a/arch/x86/kernel/quirks.c +++ b/arch/x86/kernel/quirks.c | |||
@@ -45,9 +45,12 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) | |||
45 | if (!(config & 0x2)) | 45 | if (!(config & 0x2)) |
46 | pci_write_config_byte(dev, 0xf4, config); | 46 | pci_write_config_byte(dev, 0xf4, config); |
47 | } | 47 | } |
48 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_intel_irqbalance); | 48 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, |
49 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance); | 49 | quirk_intel_irqbalance); |
50 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_intel_irqbalance); | 50 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, |
51 | quirk_intel_irqbalance); | ||
52 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, | ||
53 | quirk_intel_irqbalance); | ||
51 | #endif | 54 | #endif |
52 | 55 | ||
53 | #if defined(CONFIG_HPET_TIMER) | 56 | #if defined(CONFIG_HPET_TIMER) |
@@ -56,7 +59,8 @@ unsigned long force_hpet_address; | |||
56 | static enum { | 59 | static enum { |
57 | NONE_FORCE_HPET_RESUME, | 60 | NONE_FORCE_HPET_RESUME, |
58 | OLD_ICH_FORCE_HPET_RESUME, | 61 | OLD_ICH_FORCE_HPET_RESUME, |
59 | ICH_FORCE_HPET_RESUME | 62 | ICH_FORCE_HPET_RESUME, |
63 | VT8237_FORCE_HPET_RESUME | ||
60 | } force_hpet_resume_type; | 64 | } force_hpet_resume_type; |
61 | 65 | ||
62 | static void __iomem *rcba_base; | 66 | static void __iomem *rcba_base; |
@@ -146,17 +150,17 @@ static void ich_force_enable_hpet(struct pci_dev *dev) | |||
146 | } | 150 | } |
147 | 151 | ||
148 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0, | 152 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0, |
149 | ich_force_enable_hpet); | 153 | ich_force_enable_hpet); |
150 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, | 154 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, |
151 | ich_force_enable_hpet); | 155 | ich_force_enable_hpet); |
152 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, | 156 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, |
153 | ich_force_enable_hpet); | 157 | ich_force_enable_hpet); |
154 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, | 158 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, |
155 | ich_force_enable_hpet); | 159 | ich_force_enable_hpet); |
156 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31, | 160 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31, |
157 | ich_force_enable_hpet); | 161 | ich_force_enable_hpet); |
158 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1, | 162 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1, |
159 | ich_force_enable_hpet); | 163 | ich_force_enable_hpet); |
160 | 164 | ||
161 | 165 | ||
162 | static struct pci_dev *cached_dev; | 166 | static struct pci_dev *cached_dev; |
@@ -232,10 +236,91 @@ static void old_ich_force_enable_hpet(struct pci_dev *dev) | |||
232 | printk(KERN_DEBUG "Failed to force enable HPET\n"); | 236 | printk(KERN_DEBUG "Failed to force enable HPET\n"); |
233 | } | 237 | } |
234 | 238 | ||
239 | /* | ||
240 | * Undocumented chipset features. Make sure that the user enforced | ||
241 | * this. | ||
242 | */ | ||
243 | static void old_ich_force_enable_hpet_user(struct pci_dev *dev) | ||
244 | { | ||
245 | if (hpet_force_user) | ||
246 | old_ich_force_enable_hpet(dev); | ||
247 | } | ||
248 | |||
249 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, | ||
250 | old_ich_force_enable_hpet_user); | ||
251 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, | ||
252 | old_ich_force_enable_hpet_user); | ||
253 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, | ||
254 | old_ich_force_enable_hpet_user); | ||
255 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, | ||
256 | old_ich_force_enable_hpet_user); | ||
235 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, | 257 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, |
236 | old_ich_force_enable_hpet); | 258 | old_ich_force_enable_hpet); |
237 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_12, | 259 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_12, |
238 | old_ich_force_enable_hpet); | 260 | old_ich_force_enable_hpet); |
261 | |||
262 | |||
263 | static void vt8237_force_hpet_resume(void) | ||
264 | { | ||
265 | u32 val; | ||
266 | |||
267 | if (!force_hpet_address || !cached_dev) | ||
268 | return; | ||
269 | |||
270 | val = 0xfed00000 | 0x80; | ||
271 | pci_write_config_dword(cached_dev, 0x68, val); | ||
272 | |||
273 | pci_read_config_dword(cached_dev, 0x68, &val); | ||
274 | if (val & 0x80) | ||
275 | printk(KERN_DEBUG "Force enabled HPET at resume\n"); | ||
276 | else | ||
277 | BUG(); | ||
278 | } | ||
279 | |||
280 | static void vt8237_force_enable_hpet(struct pci_dev *dev) | ||
281 | { | ||
282 | u32 uninitialized_var(val); | ||
283 | |||
284 | if (!hpet_force_user || hpet_address || force_hpet_address) | ||
285 | return; | ||
286 | |||
287 | pci_read_config_dword(dev, 0x68, &val); | ||
288 | /* | ||
289 | * Bit 7 is HPET enable bit. | ||
290 | * Bit 31:10 is HPET base address (contrary to what datasheet claims) | ||
291 | */ | ||
292 | if (val & 0x80) { | ||
293 | force_hpet_address = (val & ~0x3ff); | ||
294 | printk(KERN_DEBUG "HPET at base address 0x%lx\n", | ||
295 | force_hpet_address); | ||
296 | return; | ||
297 | } | ||
298 | |||
299 | /* | ||
300 | * HPET is disabled. Trying enabling at FED00000 and check | ||
301 | * whether it sticks | ||
302 | */ | ||
303 | val = 0xfed00000 | 0x80; | ||
304 | pci_write_config_dword(dev, 0x68, val); | ||
305 | |||
306 | pci_read_config_dword(dev, 0x68, &val); | ||
307 | if (val & 0x80) { | ||
308 | force_hpet_address = (val & ~0x3ff); | ||
309 | printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n", | ||
310 | force_hpet_address); | ||
311 | cached_dev = dev; | ||
312 | force_hpet_resume_type = VT8237_FORCE_HPET_RESUME; | ||
313 | return; | ||
314 | } | ||
315 | |||
316 | printk(KERN_DEBUG "Failed to force enable HPET\n"); | ||
317 | } | ||
318 | |||
319 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, | ||
320 | vt8237_force_enable_hpet); | ||
321 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, | ||
322 | vt8237_force_enable_hpet); | ||
323 | |||
239 | 324 | ||
240 | void force_hpet_resume(void) | 325 | void force_hpet_resume(void) |
241 | { | 326 | { |
@@ -246,6 +331,9 @@ void force_hpet_resume(void) | |||
246 | case OLD_ICH_FORCE_HPET_RESUME: | 331 | case OLD_ICH_FORCE_HPET_RESUME: |
247 | return old_ich_force_hpet_resume(); | 332 | return old_ich_force_hpet_resume(); |
248 | 333 | ||
334 | case VT8237_FORCE_HPET_RESUME: | ||
335 | return vt8237_force_hpet_resume(); | ||
336 | |||
249 | default: | 337 | default: |
250 | break; | 338 | break; |
251 | } | 339 | } |