Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 671
b: refs/heads/master
c: 35492df
h: refs/heads/master
i:
  669: 0457191
  667: 1c7b2d1
  663: fd970bd
  655: fe3aed1
  639: 013b7b9
v: v3
  • Loading branch information
john stultz authored and Linus Torvalds committed May 1, 2005
1 parent 54c6777 commit e3954d2
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 28 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5b7abc6fdcaf103f15e06c518ef0aec02a9c00e7
refs/heads/master: 35492df5ae0f36f717448b2aea908d3a8891d1c4
2 changes: 1 addition & 1 deletion trunk/arch/i386/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}

Expand Down
48 changes: 27 additions & 21 deletions trunk/arch/i386/kernel/time_hpet.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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))
Expand All @@ -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;

Expand Down Expand Up @@ -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;
}
Expand Down
11 changes: 7 additions & 4 deletions trunk/arch/i386/kernel/timers/timer_hpet.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/i386/kernel/timers/timer_tsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-i386/hpet.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit e3954d2

Please sign in to comment.