diff options
| -rw-r--r-- | arch/x86/kernel/quirks.c | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index d13858818100..f6a11b9b1f98 100644 --- a/arch/x86/kernel/quirks.c +++ b/arch/x86/kernel/quirks.c | |||
| @@ -354,9 +354,27 @@ static void ati_force_hpet_resume(void) | |||
| 354 | printk(KERN_DEBUG "Force enabled HPET at resume\n"); | 354 | printk(KERN_DEBUG "Force enabled HPET at resume\n"); |
| 355 | } | 355 | } |
| 356 | 356 | ||
| 357 | static u32 ati_ixp4x0_rev(struct pci_dev *dev) | ||
| 358 | { | ||
| 359 | u32 d; | ||
| 360 | u8 b; | ||
| 361 | |||
| 362 | pci_read_config_byte(dev, 0xac, &b); | ||
| 363 | b &= ~(1<<5); | ||
| 364 | pci_write_config_byte(dev, 0xac, b); | ||
| 365 | pci_read_config_dword(dev, 0x70, &d); | ||
| 366 | d |= 1<<8; | ||
| 367 | pci_write_config_dword(dev, 0x70, d); | ||
| 368 | pci_read_config_dword(dev, 0x8, &d); | ||
| 369 | d &= 0xff; | ||
| 370 | dev_printk(KERN_DEBUG, &dev->dev, "SB4X0 revision 0x%x\n", d); | ||
| 371 | return d; | ||
| 372 | } | ||
| 373 | |||
| 357 | static void ati_force_enable_hpet(struct pci_dev *dev) | 374 | static void ati_force_enable_hpet(struct pci_dev *dev) |
| 358 | { | 375 | { |
| 359 | u32 uninitialized_var(val); | 376 | u32 d, val; |
| 377 | u8 b; | ||
| 360 | 378 | ||
| 361 | if (hpet_address || force_hpet_address) | 379 | if (hpet_address || force_hpet_address) |
| 362 | return; | 380 | return; |
| @@ -366,14 +384,33 @@ static void ati_force_enable_hpet(struct pci_dev *dev) | |||
| 366 | return; | 384 | return; |
| 367 | } | 385 | } |
| 368 | 386 | ||
| 387 | d = ati_ixp4x0_rev(dev); | ||
| 388 | if (d < 0x82) | ||
| 389 | return; | ||
| 390 | |||
| 391 | /* base address */ | ||
| 369 | pci_write_config_dword(dev, 0x14, 0xfed00000); | 392 | pci_write_config_dword(dev, 0x14, 0xfed00000); |
| 370 | pci_read_config_dword(dev, 0x14, &val); | 393 | pci_read_config_dword(dev, 0x14, &val); |
| 394 | |||
| 395 | /* enable interrupt */ | ||
| 396 | outb(0x72, 0xcd6); b = inb(0xcd7); | ||
| 397 | b |= 0x1; | ||
| 398 | outb(0x72, 0xcd6); outb(b, 0xcd7); | ||
| 399 | outb(0x72, 0xcd6); b = inb(0xcd7); | ||
| 400 | if (!(b & 0x1)) | ||
| 401 | return; | ||
| 402 | pci_read_config_dword(dev, 0x64, &d); | ||
| 403 | d |= (1<<10); | ||
| 404 | pci_write_config_dword(dev, 0x64, d); | ||
| 405 | pci_read_config_dword(dev, 0x64, &d); | ||
| 406 | if (!(d & (1<<10))) | ||
| 407 | return; | ||
| 408 | |||
| 371 | force_hpet_address = val; | 409 | force_hpet_address = val; |
| 372 | force_hpet_resume_type = ATI_FORCE_HPET_RESUME; | 410 | force_hpet_resume_type = ATI_FORCE_HPET_RESUME; |
| 373 | dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at 0x%lx\n", | 411 | dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at 0x%lx\n", |
| 374 | force_hpet_address); | 412 | force_hpet_address); |
| 375 | cached_dev = dev; | 413 | cached_dev = dev; |
| 376 | return; | ||
| 377 | } | 414 | } |
| 378 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS, | 415 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS, |
| 379 | ati_force_enable_hpet); | 416 | ati_force_enable_hpet); |
