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.c69
1 files changed, 68 insertions, 1 deletions
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c
index 1fbc5380e27c..fbe32e7c3f5f 100644
--- a/arch/x86/kernel/quirks.c
+++ b/arch/x86/kernel/quirks.c
@@ -59,7 +59,8 @@ unsigned long force_hpet_address;
59static enum { 59static enum {
60 NONE_FORCE_HPET_RESUME, 60 NONE_FORCE_HPET_RESUME,
61 OLD_ICH_FORCE_HPET_RESUME, 61 OLD_ICH_FORCE_HPET_RESUME,
62 ICH_FORCE_HPET_RESUME 62 ICH_FORCE_HPET_RESUME,
63 VT8237_FORCE_HPET_RESUME
63} force_hpet_resume_type; 64} force_hpet_resume_type;
64 65
65static void __iomem *rcba_base; 66static void __iomem *rcba_base;
@@ -240,6 +241,69 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,
240DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_12, 241DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_12,
241 old_ich_force_enable_hpet); 242 old_ich_force_enable_hpet);
242 243
244
245static void vt8237_force_hpet_resume(void)
246{
247 u32 val;
248
249 if (!force_hpet_address || !cached_dev)
250 return;
251
252 val = 0xfed00000 | 0x80;
253 pci_write_config_dword(cached_dev, 0x68, val);
254
255 pci_read_config_dword(cached_dev, 0x68, &val);
256 if (val & 0x80)
257 printk(KERN_DEBUG "Force enabled HPET at resume\n");
258 else
259 BUG();
260}
261
262static void vt8237_force_enable_hpet(struct pci_dev *dev)
263{
264 u32 uninitialized_var(val);
265
266 if (!hpet_force_user || hpet_address || force_hpet_address)
267 return;
268
269 pci_read_config_dword(dev, 0x68, &val);
270 /*
271 * Bit 7 is HPET enable bit.
272 * Bit 31:10 is HPET base address (contrary to what datasheet claims)
273 */
274 if (val & 0x80) {
275 force_hpet_address = (val & ~0x3ff);
276 printk(KERN_DEBUG "HPET at base address 0x%lx\n",
277 force_hpet_address);
278 return;
279 }
280
281 /*
282 * HPET is disabled. Trying enabling at FED00000 and check
283 * whether it sticks
284 */
285 val = 0xfed00000 | 0x80;
286 pci_write_config_dword(dev, 0x68, val);
287
288 pci_read_config_dword(dev, 0x68, &val);
289 if (val & 0x80) {
290 force_hpet_address = (val & ~0x3ff);
291 printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
292 force_hpet_address);
293 cached_dev = dev;
294 force_hpet_resume_type = VT8237_FORCE_HPET_RESUME;
295 return;
296 }
297
298 printk(KERN_DEBUG "Failed to force enable HPET\n");
299}
300
301DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235,
302 vt8237_force_enable_hpet);
303DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237,
304 vt8237_force_enable_hpet);
305
306
243void force_hpet_resume(void) 307void force_hpet_resume(void)
244{ 308{
245 switch (force_hpet_resume_type) { 309 switch (force_hpet_resume_type) {
@@ -249,6 +313,9 @@ void force_hpet_resume(void)
249 case OLD_ICH_FORCE_HPET_RESUME: 313 case OLD_ICH_FORCE_HPET_RESUME:
250 return old_ich_force_hpet_resume(); 314 return old_ich_force_hpet_resume();
251 315
316 case VT8237_FORCE_HPET_RESUME:
317 return vt8237_force_hpet_resume();
318
252 default: 319 default:
253 break; 320 break;
254 } 321 }