Subject: port-i386/4808: 8253 timer0 needs to be reseted after resume from hybernation on some laptop.
To: None <gnats-bugs@gnats.netbsd.org>
From: None <enami@but-b.or.jp>
List: netbsd-bugs
Date: 01/12/1998 21:35:20
>Number:         4808
>Category:       port-i386
>Synopsis:       8253 timer0 needs to be reseted after resume from hybernation on some laptop.
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Jan 12 04:50:02 1998
>Last-Modified:
>Originator:     enami tsugutomo
>Organization:
>Release:        NetBSD-current as of 1998Jan12
>Environment:
System: NetBSD reticle.enami.but-b.or.jp 1.3A NetBSD 1.3A (RETICLE) #48: Sat Jan 10 18:39:23 JST 1998 enami@reticle.enami.but-b.or.jp:/a/tmp/pcmcia/kernel/compile/RETICLE i386


>Description:
	8253 timer0 (used to get tick) needs to be reseted after
	resume from hybernation on some laptop (e.g. NEC mobio), since
	it probably in wrong mode.

	Otherwise, clock interrupt rate decrease to about 18 timers per
	second (normally, it is 100 times per second).  And beep by ^g
	become longer or clock delays.

>How-To-Repeat:
	Make such laptop hybernate then resume.  And:

	(1) type ^g; it beeps longer than normal.
	(2) type date;sleep 10;date with timing your clock.

>Fix:
	Here is a workaround works for me which reset mode of timer0
	after resume.
	(Note that this patch also includes patch that does
	s/IO_TIMER1/TIMER_CNTR0/g on i386/isa/clock.c.  Both symbols
	are same value but latter is more apropriate to use in clock.c).

Index: include/cpu.h
===================================================================
RCS file: /a/cvsroot/NetBSD/src/sys/arch/i386/include/cpu.h,v
retrieving revision 1.1.1.8
diff -u -r1.1.1.8 cpu.h
--- cpu.h	1997/11/27 20:21:45	1.1.1.8
+++ cpu.h	1998/01/11 02:31:33
@@ -148,6 +148,7 @@
 
 /* clock.c */
 void	startrtclock __P((void));
+void	init_isa_timer __P((void));
 
 /* npx.c */
 void	npxdrop __P((void));
Index: i386/apm.c
===================================================================
RCS file: /a/cvsroot/NetBSD/src/sys/arch/i386/i386/apm.c,v
retrieving revision 1.1.1.11
diff -u -r1.1.1.11 apm.c
--- apm.c	1997/11/13 16:13:30	1.1.1.11
+++ apm.c	1998/01/11 02:31:53
@@ -179,6 +179,7 @@
 #else
 int	apm_v11_enabled = 1;
 #endif
+int	apm_init_isa_timer = 1;
 
 /* variables used during operation (XXX cgd) */
 struct apm_connect_info apminfo;
@@ -462,12 +463,16 @@
 
 	case APM_NORMAL_RESUME:
 		DPRINTF(APMDEBUG_EVENTS, ("apmev: resume system\n"));
+		if (apm_init_isa_timer)
+			init_isa_timer();
 		inittodr(time.tv_sec);
 		apm_record_event(sc, regs->bx);
 		break;
 
 	case APM_CRIT_RESUME:
 		DPRINTF(APMDEBUG_EVENTS, ("apmev: critical resume system"));
+		if (apm_init_isa_timer)
+			init_isa_timer();
 		inittodr(time.tv_sec);
 		apm_record_event(sc, regs->bx);
 		break;
Index: isa/clock.c
===================================================================
RCS file: /a/cvsroot/NetBSD/src/sys/arch/i386/isa/clock.c,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 clock.c
--- clock.c	1997/02/13 14:49:05	1.1.1.5
+++ clock.c	1998/01/11 02:31:22
@@ -165,6 +165,18 @@
 u_short	isa_timer_lsb_table[256];	/* timer->usec conversion for LSB */
 
 void
+init_isa_timer()
+{
+
+	/* Initialize 8253 clock */
+	outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
+
+	/* Correct rounding will buy us a better precision in timekeeping */
+	outb(TIMER_CNTR0, isa_timer_count % 256);
+	outb(TIMER_CNTR0, isa_timer_count / 256);
+}
+
+void
 startrtclock()
 {
 	int s;
@@ -243,12 +255,7 @@
 		}
 	}
 
-	/* initialize 8253 clock */
-	outb(TIMER_MODE, TIMER_SEL0|TIMER_RATEGEN|TIMER_16BIT);
-
-	/* Correct rounding will buy us a better precision in timekeeping */
-	outb(IO_TIMER1, isa_timer_count % 256);
-	outb(IO_TIMER1, isa_timer_count / 256);
+	init_isa_timer();
 
 	/* Check diagnostic status */
 	if ((s = mc146818_read(NULL, NVRAM_DIAG)) != 0) { /* XXX softc */
>Audit-Trail:
>Unformatted: