From e3954d2bd8bef8840c21935690e74e462f42abda Mon Sep 17 00:00:00 2001 From: john stultz Date: Sun, 1 May 2005 08:58:50 -0700 Subject: [PATCH] --- yaml --- r: 671 b: refs/heads/master c: 35492df5ae0f36f717448b2aea908d3a8891d1c4 h: refs/heads/master i: 669: 0457191c86f2b5b10c785f3521ef64dad4a7b844 667: 1c7b2d1a811f0fda0f8c82690ec9ee3eee312e86 663: fd970bdf2e481eec6dda5f6b7ff12068f19b50f5 655: fe3aed1890b59e4aa337f8f49c4543431fa81ba1 639: 013b7b966859cda477703ee758f8269e25830d9b v: v3 --- [refs] | 2 +- trunk/arch/i386/kernel/time.c | 2 +- trunk/arch/i386/kernel/time_hpet.c | 48 ++++++++++++---------- trunk/arch/i386/kernel/timers/timer_hpet.c | 11 +++-- trunk/arch/i386/kernel/timers/timer_tsc.c | 2 +- trunk/include/asm-i386/hpet.h | 1 + 6 files changed, 38 insertions(+), 28 deletions(-) diff --git a/[refs] b/[refs] index cfb8622c8d04..f874a79f09fc 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 5b7abc6fdcaf103f15e06c518ef0aec02a9c00e7 +refs/heads/master: 35492df5ae0f36f717448b2aea908d3a8891d1c4 diff --git a/trunk/arch/i386/kernel/time.c b/trunk/arch/i386/kernel/time.c index 4d75b373f90e..a0dcb7c87c30 100644 --- a/trunk/arch/i386/kernel/time.c +++ b/trunk/arch/i386/kernel/time.c @@ -441,7 +441,7 @@ static void __init hpet_time_init(void) set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); - if (hpet_enable() >= 0) { + if ((hpet_enable() >= 0) && hpet_use_timer) { printk("Using HPET for base-timer\n"); } diff --git a/trunk/arch/i386/kernel/time_hpet.c b/trunk/arch/i386/kernel/time_hpet.c index 244a31b04be7..10a0cbb88e75 100644 --- a/trunk/arch/i386/kernel/time_hpet.c +++ b/trunk/arch/i386/kernel/time_hpet.c @@ -26,6 +26,7 @@ static unsigned long hpet_period; /* fsecs / HPET clock */ unsigned long hpet_tick; /* hpet clks count per tick */ unsigned long hpet_address; /* hpet memory map physical address */ +int hpet_use_timer; static int use_hpet; /* can be used for runtime check of hpet */ static int boot_hpet_disable; /* boottime override for HPET timer */ @@ -73,27 +74,30 @@ static int hpet_timer_stop_set_go(unsigned long tick) hpet_writel(0, HPET_COUNTER); hpet_writel(0, HPET_COUNTER + 4); - /* - * Set up timer 0, as periodic with first interrupt to happen at - * hpet_tick, and period also hpet_tick. - */ - cfg = hpet_readl(HPET_T0_CFG); - cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | - HPET_TN_SETVAL | HPET_TN_32BIT; - hpet_writel(cfg, HPET_T0_CFG); - - /* - * The first write after writing TN_SETVAL to the config register sets - * the counter value, the second write sets the threshold. - */ - hpet_writel(tick, HPET_T0_CMP); - hpet_writel(tick, HPET_T0_CMP); + if (hpet_use_timer) { + /* + * Set up timer 0, as periodic with first interrupt to happen at + * hpet_tick, and period also hpet_tick. + */ + cfg = hpet_readl(HPET_T0_CFG); + cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | + HPET_TN_SETVAL | HPET_TN_32BIT; + hpet_writel(cfg, HPET_T0_CFG); + /* + * The first write after writing TN_SETVAL to the config register sets + * the counter value, the second write sets the threshold. + */ + hpet_writel(tick, HPET_T0_CMP); + hpet_writel(tick, HPET_T0_CMP); + } /* * Go! */ cfg = hpet_readl(HPET_CFG); - cfg |= HPET_CFG_ENABLE | HPET_CFG_LEGACY; + if (hpet_use_timer) + cfg |= HPET_CFG_LEGACY; + cfg |= HPET_CFG_ENABLE; hpet_writel(cfg, HPET_CFG); return 0; @@ -128,12 +132,11 @@ int __init hpet_enable(void) * However, we can do with one timer otherwise using the * the single HPET timer for system time. */ - if ( #ifdef CONFIG_HPET_EMULATE_RTC - !(id & HPET_ID_NUMBER) || -#endif - !(id & HPET_ID_LEGSUP)) + if (!(id & HPET_ID_NUMBER)) return -1; +#endif + hpet_period = hpet_readl(HPET_PERIOD); if ((hpet_period < HPET_MIN_PERIOD) || (hpet_period > HPET_MAX_PERIOD)) @@ -152,6 +155,8 @@ int __init hpet_enable(void) if (hpet_tick_rem > (hpet_period >> 1)) hpet_tick++; /* rounding the result */ + hpet_use_timer = id & HPET_ID_LEGSUP; + if (hpet_timer_stop_set_go(hpet_tick)) return -1; @@ -202,7 +207,8 @@ int __init hpet_enable(void) #endif #ifdef CONFIG_X86_LOCAL_APIC - wait_timer_tick = wait_hpet_tick; + if (hpet_use_timer) + wait_timer_tick = wait_hpet_tick; #endif return 0; } diff --git a/trunk/arch/i386/kernel/timers/timer_hpet.c b/trunk/arch/i386/kernel/timers/timer_hpet.c index 713134e71844..f778f471a09a 100644 --- a/trunk/arch/i386/kernel/timers/timer_hpet.c +++ b/trunk/arch/i386/kernel/timers/timer_hpet.c @@ -79,7 +79,7 @@ static unsigned long get_offset_hpet(void) eax = hpet_readl(HPET_COUNTER); eax -= hpet_last; /* hpet delta */ - + eax = min(hpet_tick, eax); /* * Time offset = (hpet delta) * ( usecs per HPET clock ) * = (hpet delta) * ( usecs per tick / HPET clocks per tick) @@ -105,9 +105,12 @@ static void mark_offset_hpet(void) last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; rdtsc(last_tsc_low, last_tsc_high); - offset = hpet_readl(HPET_T0_CMP) - hpet_tick; - if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0))) { - int lost_ticks = (offset - hpet_last) / hpet_tick; + if (hpet_use_timer) + offset = hpet_readl(HPET_T0_CMP) - hpet_tick; + else + offset = hpet_readl(HPET_COUNTER); + if (unlikely(((offset - hpet_last) >= (2*hpet_tick)) && (hpet_last != 0))) { + int lost_ticks = ((offset - hpet_last) / hpet_tick) - 1; jiffies_64 += lost_ticks; } hpet_last = offset; diff --git a/trunk/arch/i386/kernel/timers/timer_tsc.c b/trunk/arch/i386/kernel/timers/timer_tsc.c index a685994e5c8e..7926d967be00 100644 --- a/trunk/arch/i386/kernel/timers/timer_tsc.c +++ b/trunk/arch/i386/kernel/timers/timer_tsc.c @@ -477,7 +477,7 @@ static int __init init_tsc(char* override) if (cpu_has_tsc) { unsigned long tsc_quotient; #ifdef CONFIG_HPET_TIMER - if (is_hpet_enabled()){ + if (is_hpet_enabled() && hpet_use_timer) { unsigned long result, remain; printk("Using TSC for gettimeofday\n"); tsc_quotient = calibrate_tsc_hpet(NULL); diff --git a/trunk/include/asm-i386/hpet.h b/trunk/include/asm-i386/hpet.h index 6e20b079f1d3..16ef9f996e3f 100644 --- a/trunk/include/asm-i386/hpet.h +++ b/trunk/include/asm-i386/hpet.h @@ -92,6 +92,7 @@ extern unsigned long hpet_tick; /* hpet clks count per tick */ extern unsigned long hpet_address; /* hpet memory map physical address */ +extern int hpet_use_timer; extern int hpet_rtc_timer_init(void); extern int hpet_enable(void);