Use HPET address detected by quirk, when it is not listed by BIOS and register HPET as a clocksource.
Signed-off-by: Venkatesh Pallipadi <[EMAIL PROTECTED]> Index: linux-2.6.21-rc-mm/arch/x86_64/kernel/hpet.c =================================================================== --- linux-2.6.21-rc-mm.orig/arch/x86_64/kernel/hpet.c +++ linux-2.6.21-rc-mm/arch/x86_64/kernel/hpet.c @@ -12,7 +12,7 @@ #include <asm/timex.h> #include <asm/hpet.h> -int nohpet __initdata = 1; +int nohpet __initdata; unsigned long hpet_address; unsigned long hpet_period; /* fsecs / HPET clock */ @@ -106,18 +106,21 @@ int hpet_timer_stop_set_go(unsigned long return 0; } -int hpet_arch_init(void) +static int init_basic_hpet_done __initdata; + +static int __init init_basic_hpet(void) { unsigned int id; - if (!hpet_address) - return -1; + if (init_basic_hpet_done) + return 0; + set_fixmap_nocache(FIX_HPET_BASE, hpet_address); __set_fixmap(VSYSCALL_HPET, hpet_address, PAGE_KERNEL_VSYSCALL_NOCACHE); -/* - * Read the period, compute tick and quotient. - */ + /* + * Read the period, compute tick and quotient. + */ id = hpet_readl(HPET_ID); @@ -130,6 +133,26 @@ int hpet_arch_init(void) hpet_tick = (FSEC_PER_TICK + hpet_period / 2) / hpet_period; + printk(KERN_DEBUG "HPET: hpet_period %lu, hpet_tick %lu\n", hpet_period, + hpet_tick); + + init_basic_hpet_done = 1; + return 0; +} + +int __init hpet_arch_init(void) +{ + unsigned int id; + int ret; + + if (!hpet_address) + return -1; + + ret = init_basic_hpet(); + if (ret) + return ret; + + id = hpet_readl(HPET_ID); hpet_use_timer = (id & HPET_ID_LEGSUP); return hpet_timer_stop_set_go(hpet_tick); @@ -451,16 +474,14 @@ __setup("nohpet", nohpet_setup); /* FSEC = 10^-15 NSEC = 10^-9 */ #define FSEC_PER_NSEC 1000000 -static void *hpet_ptr; - static cycle_t notrace read_hpet(void) { - return (cycle_t)readl(hpet_ptr); + return (cycle_t)hpet_readl(HPET_COUNTER); } static cycle_t __vsyscall_fn vread_hpet(void) { - return readl((void __iomem *)fix_to_virt(VSYSCALL_HPET) + 0xf0); + return readl((void __iomem *)fix_to_virt(VSYSCALL_HPET) + HPET_COUNTER); } struct clocksource clocksource_hpet = { @@ -476,20 +497,8 @@ struct clocksource clocksource_hpet = { static int __init init_hpet_clocksource(void) { - unsigned long hpet_period; - void __iomem *hpet_base; u64 tmp; - if (!hpet_address) - return -ENODEV; - - /* calculate the hpet address: */ - hpet_base = ioremap_nocache(hpet_address, HPET_MMAP_SIZE); - hpet_ptr = hpet_base + HPET_COUNTER; - - /* calculate the frequency: */ - hpet_period = readl(hpet_base + HPET_PERIOD); - /* * hpet period is in femto seconds per cycle * so we need to convert this to ns/cyc units @@ -508,4 +517,38 @@ static int __init init_hpet_clocksource( return clocksource_register(&clocksource_hpet); } -module_init(init_hpet_clocksource); +static int __init init_hpet_generic_timer(void) +{ + int ret; + + if (nohpet) + return -ENODEV; + + if (!hpet_address) + hpet_address = force_hpet_address; + + if (!hpet_address) + return -ENODEV; + + ret = init_basic_hpet(); + if (ret) + return ret; + + ret = init_hpet_clocksource(); + if (!ret) { + printk(KERN_DEBUG "Successfully registered HPET clocksource\n"); + } else { + printk(KERN_DEBUG "HPET clocksource init failed\n"); + } + + if (ret) { + unsigned int cfg; + cfg = hpet_readl(HPET_CFG); + cfg &= (~HPET_CFG_ENABLE); + hpet_writel(cfg, HPET_CFG); + } + + return ret; +} + +module_init(init_hpet_generic_timer); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/