aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/quirks.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/quirks.c')
-rw-r--r--arch/x86/kernel/quirks.c112
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}
48DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_intel_irqbalance); 48DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH,
49DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance); 49 quirk_intel_irqbalance);
50DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_intel_irqbalance); 50DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH,
51 quirk_intel_irqbalance);
52DECLARE_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;
56static enum { 59static 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
62static void __iomem *rcba_base; 66static void __iomem *rcba_base;
@@ -146,17 +150,17 @@ static void ich_force_enable_hpet(struct pci_dev *dev)
146} 150}
147 151
148DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0, 152DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0,
149 ich_force_enable_hpet); 153 ich_force_enable_hpet);
150DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, 154DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1,
151 ich_force_enable_hpet); 155 ich_force_enable_hpet);
152DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, 156DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0,
153 ich_force_enable_hpet); 157 ich_force_enable_hpet);
154DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, 158DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1,
155 ich_force_enable_hpet); 159 ich_force_enable_hpet);
156DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31, 160DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31,
157 ich_force_enable_hpet); 161 ich_force_enable_hpet);
158DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1, 162DECLARE_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
162static struct pci_dev *cached_dev; 166static 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 */
243static 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
249DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,
250 old_ich_force_enable_hpet_user);
251DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12,
252 old_ich_force_enable_hpet_user);
253DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,
254 old_ich_force_enable_hpet_user);
255DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12,
256 old_ich_force_enable_hpet_user);
235DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, 257DECLARE_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);
237DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_12, 259DECLARE_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
263static 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
280static 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
319DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235,
320 vt8237_force_enable_hpet);
321DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237,
322 vt8237_force_enable_hpet);
323
239 324
240void force_hpet_resume(void) 325void 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 }