i8254_restore is called from apm_default_resume() to reload

the countdown register.
this should not be necessary but there are broken laptops that
do not restore the countdown register on resume.
when it happnes, it messes up the hardclock interval and system clock,
which leads to the infamous "calcru: negative time" problem.

Submitted by:	kjc, iwasaki
Reviewed by:	Steve O'Hara-Smith <steveo@eircom.net> and committers.
Obtained from:	PAO3
This commit is contained in:
Mitsuru IWASAKI 1999-10-30 14:56:01 +00:00
parent 840c0de7aa
commit 29803c2003
9 changed files with 114 additions and 0 deletions

View File

@ -690,6 +690,28 @@ set_timer_freq(u_int freq, int intr_freq)
write_eflags(ef);
}
/*
* i8254_restore is called from apm_default_resume() to reload
* the countdown register.
* this should not be necessary but there are broken laptops that
* do not restore the countdown register on resume.
* when it happnes, it messes up the hardclock interval and system clock,
* which leads to the infamous "calcru: negative time" problem.
*/
void
i8254_restore(void)
{
u_long ef;
ef = read_eflags();
disable_intr();
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
CLOCK_UNLOCK();
write_eflags(ef);
}
/*
* Initialize 8254 timer 0 early so that it can be used in DELAY().
* XXX initialization of other timers is unintentionally left blank.

View File

@ -44,6 +44,7 @@ int acquire_timer1 __P((int mode));
int release_timer1 __P((void));
#endif
int sysbeep __P((int pitch, int period));
void i8254_restore __P((void));
#endif /* KERNEL */

View File

@ -690,6 +690,28 @@ set_timer_freq(u_int freq, int intr_freq)
write_eflags(ef);
}
/*
* i8254_restore is called from apm_default_resume() to reload
* the countdown register.
* this should not be necessary but there are broken laptops that
* do not restore the countdown register on resume.
* when it happnes, it messes up the hardclock interval and system clock,
* which leads to the infamous "calcru: negative time" problem.
*/
void
i8254_restore(void)
{
u_long ef;
ef = read_eflags();
disable_intr();
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
CLOCK_UNLOCK();
write_eflags(ef);
}
/*
* Initialize 8254 timer 0 early so that it can be used in DELAY().
* XXX initialization of other timers is unintentionally left blank.

View File

@ -404,6 +404,7 @@ apm_default_resume(void *arg)
/* modified for adjkerntz */
pl = splsoftclock();
i8254_restore(); /* restore timer_freq and hz */
inittodr(0); /* adjust time to RTC */
microtime(&resume_time);
getmicrotime(&tmp_time);

View File

@ -404,6 +404,7 @@ apm_default_resume(void *arg)
/* modified for adjkerntz */
pl = splsoftclock();
i8254_restore(); /* restore timer_freq and hz */
inittodr(0); /* adjust time to RTC */
microtime(&resume_time);
getmicrotime(&tmp_time);

View File

@ -690,6 +690,28 @@ set_timer_freq(u_int freq, int intr_freq)
write_eflags(ef);
}
/*
* i8254_restore is called from apm_default_resume() to reload
* the countdown register.
* this should not be necessary but there are broken laptops that
* do not restore the countdown register on resume.
* when it happnes, it messes up the hardclock interval and system clock,
* which leads to the infamous "calcru: negative time" problem.
*/
void
i8254_restore(void)
{
u_long ef;
ef = read_eflags();
disable_intr();
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
CLOCK_UNLOCK();
write_eflags(ef);
}
/*
* Initialize 8254 timer 0 early so that it can be used in DELAY().
* XXX initialization of other timers is unintentionally left blank.

View File

@ -44,6 +44,7 @@ int acquire_timer1 __P((int mode));
int release_timer1 __P((void));
#endif
int sysbeep __P((int pitch, int period));
void i8254_restore __P((void));
#endif /* KERNEL */

View File

@ -690,6 +690,28 @@ set_timer_freq(u_int freq, int intr_freq)
write_eflags(ef);
}
/*
* i8254_restore is called from apm_default_resume() to reload
* the countdown register.
* this should not be necessary but there are broken laptops that
* do not restore the countdown register on resume.
* when it happnes, it messes up the hardclock interval and system clock,
* which leads to the infamous "calcru: negative time" problem.
*/
void
i8254_restore(void)
{
u_long ef;
ef = read_eflags();
disable_intr();
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
CLOCK_UNLOCK();
write_eflags(ef);
}
/*
* Initialize 8254 timer 0 early so that it can be used in DELAY().
* XXX initialization of other timers is unintentionally left blank.

View File

@ -690,6 +690,28 @@ set_timer_freq(u_int freq, int intr_freq)
write_eflags(ef);
}
/*
* i8254_restore is called from apm_default_resume() to reload
* the countdown register.
* this should not be necessary but there are broken laptops that
* do not restore the countdown register on resume.
* when it happnes, it messes up the hardclock interval and system clock,
* which leads to the infamous "calcru: negative time" problem.
*/
void
i8254_restore(void)
{
u_long ef;
ef = read_eflags();
disable_intr();
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
CLOCK_UNLOCK();
write_eflags(ef);
}
/*
* Initialize 8254 timer 0 early so that it can be used in DELAY().
* XXX initialization of other timers is unintentionally left blank.