summaryrefslogtreecommitdiffstats
path: root/sys/isa
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2005-07-13 15:43:21 +0000
committerjhb <jhb@FreeBSD.org>2005-07-13 15:43:21 +0000
commit4084c7b256b0ebcd271a8fae55578eb399b5b0b9 (patch)
tree2f4a166053a53ae4578b02bfab1bf64d501e548c /sys/isa
parent373a6e31c98580fa8ace2a9d298d7ff62371d45b (diff)
downloadFreeBSD-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.c44
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
OpenPOWER on IntegriCloud