Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 67774
b: refs/heads/master
c: d54bd57
h: refs/heads/master
v: v3
  • Loading branch information
Venki Pallipadi authored and Thomas Gleixner committed Oct 12, 2007
1 parent 84d4566 commit bdacc8b
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 610bf2f143b9c5cda768a2d428d66d3a16769930
refs/heads/master: d54bd57d6580250e6551261f3b15c45a9d90c77b
102 changes: 102 additions & 0 deletions trunk/arch/x86/kernel/quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <linux/pci.h>
#include <linux/irq.h>

#include <asm/hpet.h>

#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_SMP) && defined(CONFIG_PCI)

static void __devinit quirk_intel_irqbalance(struct pci_dev *dev)
Expand Down Expand Up @@ -47,3 +49,103 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quir
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_intel_irqbalance);
#endif

#if defined(CONFIG_HPET_TIMER)
unsigned long force_hpet_address;

static void __iomem *rcba_base;

void ich_force_hpet_resume(void)
{
u32 val;

if (!force_hpet_address)
return;

if (rcba_base == NULL)
BUG();

/* read the Function Disable register, dword mode only */
val = readl(rcba_base + 0x3404);
if (!(val & 0x80)) {
/* HPET disabled in HPTC. Trying to enable */
writel(val | 0x80, rcba_base + 0x3404);
}

val = readl(rcba_base + 0x3404);
if (!(val & 0x80))
BUG();
else
printk(KERN_DEBUG "Force enabled HPET at resume\n");

return;
}

static void ich_force_enable_hpet(struct pci_dev *dev)
{
u32 val;
u32 uninitialized_var(rcba);
int err = 0;

if (hpet_address || force_hpet_address)
return;

pci_read_config_dword(dev, 0xF0, &rcba);
rcba &= 0xFFFFC000;
if (rcba == 0) {
printk(KERN_DEBUG "RCBA disabled. Cannot force enable HPET\n");
return;
}

/* use bits 31:14, 16 kB aligned */
rcba_base = ioremap_nocache(rcba, 0x4000);
if (rcba_base == NULL) {
printk(KERN_DEBUG "ioremap failed. Cannot force enable HPET\n");
return;
}

/* read the Function Disable register, dword mode only */
val = readl(rcba_base + 0x3404);

if (val & 0x80) {
/* HPET is enabled in HPTC. Just not reported by BIOS */
val = val & 0x3;
force_hpet_address = 0xFED00000 | (val << 12);
printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
force_hpet_address);
iounmap(rcba_base);
return;
}

/* HPET disabled in HPTC. Trying to enable */
writel(val | 0x80, rcba_base + 0x3404);

val = readl(rcba_base + 0x3404);
if (!(val & 0x80)) {
err = 1;
} else {
val = val & 0x3;
force_hpet_address = 0xFED00000 | (val << 12);
}

if (err) {
force_hpet_address = 0;
iounmap(rcba_base);
printk(KERN_DEBUG "Failed to force enable HPET\n");
} else {
printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
force_hpet_address);
}
}

DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0,
ich_force_enable_hpet);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1,
ich_force_enable_hpet);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1,
ich_force_enable_hpet);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31,
ich_force_enable_hpet);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1,
ich_force_enable_hpet);
#endif
1 change: 1 addition & 0 deletions trunk/include/asm-x86/hpet.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ extern unsigned long hpet_address;
extern int is_hpet_enabled(void);
extern int hpet_enable(void);
extern unsigned long hpet_readl(unsigned long a);
extern void ich_force_hpet_resume(void);

#ifdef CONFIG_HPET_EMULATE_RTC

Expand Down

0 comments on commit bdacc8b

Please sign in to comment.