diff options
author | jhb <jhb@FreeBSD.org> | 2005-07-13 15:43:21 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2005-07-13 15:43:21 +0000 |
commit | 4084c7b256b0ebcd271a8fae55578eb399b5b0b9 (patch) | |
tree | 2f4a166053a53ae4578b02bfab1bf64d501e548c /sys/isa | |
parent | 373a6e31c98580fa8ace2a9d298d7ff62371d45b (diff) | |
download | FreeBSD-src-4084c7b256b0ebcd271a8fae55578eb399b5b0b9.zip FreeBSD-src-4084c7b256b0ebcd271a8fae55578eb399b5b0b9.tar.gz |
Fixup some more fallout from the lapic/i8254 changes:
- Make sure timer0_max_count is set to a correct value in the lapic case.
- Revert i8254_restore() to explicitly reprogram timer 0 rather than
calling set_timer_freq() to do it. set_timer_freq() only reprograms
the counter if the max count changes which it never does on resume. This
unbreaks suspend/resume for several people.
Tested by: marks, others
Reviewed by: bde
MFC after: 3 days
Diffstat (limited to 'sys/isa')
-rw-r--r-- | sys/isa/atrtc.c | 44 |
1 files changed, 20 insertions, 24 deletions
diff --git a/sys/isa/atrtc.c b/sys/isa/atrtc.c index 3570be1..a4ae751 100644 --- a/sys/isa/atrtc.c +++ b/sys/isa/atrtc.c @@ -110,6 +110,7 @@ int statclock_disable; #endif u_int timer_freq = TIMER_FREQ; int timer0_max_count; +int timer0_real_max_count; int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ struct mtx clock_lock; #define RTC_LOCK mtx_lock_spin(&clock_lock) @@ -117,7 +118,6 @@ struct mtx clock_lock; static int beeping = 0; static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31}; -static u_int hardclock_max_count; static struct intsrc *i8254_intsrc; static u_int32_t i8254_lastcount; static u_int32_t i8254_offset; @@ -531,21 +531,24 @@ fail: static void set_timer_freq(u_int freq, int intr_freq) { - int new_timer0_max_count; + int new_timer0_real_max_count; i8254_timecounter.tc_frequency = freq; mtx_lock_spin(&clock_lock); timer_freq = freq; - new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq); - if (using_lapic_timer) { - outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); - outb(TIMER_CNTR0, 0); - outb(TIMER_CNTR0, 0); - } else if (new_timer0_max_count != timer0_max_count) { - timer0_max_count = new_timer0_max_count; + if (using_lapic_timer) + new_timer0_real_max_count = 0x10000; + else + new_timer0_real_max_count = TIMER_DIV(intr_freq); + if (new_timer0_real_max_count != timer0_real_max_count) { + timer0_real_max_count = new_timer0_real_max_count; + if (timer0_real_max_count == 0x10000) + timer0_max_count = 0xffff; + else + timer0_max_count = timer0_real_max_count; outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); - outb(TIMER_CNTR0, timer0_max_count & 0xff); - outb(TIMER_CNTR0, timer0_max_count >> 8); + outb(TIMER_CNTR0, timer0_real_max_count & 0xff); + outb(TIMER_CNTR0, timer0_real_max_count >> 8); } mtx_unlock_spin(&clock_lock); } @@ -554,7 +557,11 @@ static void i8254_restore(void) { - set_timer_freq(timer_freq, hz); + mtx_lock_spin(&clock_lock); + outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); + outb(TIMER_CNTR0, timer0_real_max_count & 0xff); + outb(TIMER_CNTR0, timer0_real_max_count >> 8); + mtx_unlock_spin(&clock_lock); } static void @@ -876,19 +883,8 @@ SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW, static unsigned i8254_simple_get_timecount(struct timecounter *tc) { - u_int count; - u_int high, low; - mtx_lock_spin(&clock_lock); - - /* Select timer0 and latch counter value. */ - outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); - - low = inb(TIMER_CNTR0); - high = inb(TIMER_CNTR0); - count = 0xffff - ((high << 8) | low); - mtx_unlock_spin(&clock_lock); - return (count); + return (timer0_max_count - getit()); } static unsigned |