xref: /freebsd/sys/x86/isa/clock.c (revision 4f1f4356f3012928b463f9ef1710fb908e48b1e2)
1 /*-
2  * Copyright (c) 1990 The Regents of the University of California.
3  * Copyright (c) 2010 Alexander Motin <mav@FreeBSD.org>
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * William Jolitz and Don Ahn.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  *	from: @(#)clock.c	7.2 (Berkeley) 5/12/91
34  */
35 
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD$");
38 
39 /*
40  * Routines to handle clock hardware.
41  */
42 
43 #include "opt_clock.h"
44 #include "opt_isa.h"
45 #include "opt_mca.h"
46 
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/bus.h>
50 #include <sys/lock.h>
51 #include <sys/kdb.h>
52 #include <sys/mutex.h>
53 #include <sys/proc.h>
54 #include <sys/kernel.h>
55 #include <sys/module.h>
56 #include <sys/rman.h>
57 #include <sys/sched.h>
58 #include <sys/smp.h>
59 #include <sys/sysctl.h>
60 #include <sys/timeet.h>
61 #include <sys/timetc.h>
62 
63 #include <machine/clock.h>
64 #include <machine/cpu.h>
65 #include <machine/intr_machdep.h>
66 #include <machine/ppireg.h>
67 #include <machine/timerreg.h>
68 
69 #ifdef PC98
70 #include <pc98/pc98/pc98_machdep.h>
71 #else
72 #include <isa/rtc.h>
73 #endif
74 #ifdef DEV_ISA
75 #ifdef PC98
76 #include <pc98/cbus/cbus.h>
77 #else
78 #include <isa/isareg.h>
79 #endif
80 #include <isa/isavar.h>
81 #endif
82 
83 #ifdef DEV_MCA
84 #include <i386/bios/mca_machdep.h>
85 #endif
86 
87 int	clkintr_pending;
88 #ifndef TIMER_FREQ
89 #ifdef PC98
90 #define TIMER_FREQ   2457600
91 #else
92 #define TIMER_FREQ   1193182
93 #endif
94 #endif
95 u_int	i8254_freq = TIMER_FREQ;
96 TUNABLE_INT("hw.i8254.freq", &i8254_freq);
97 int	i8254_max_count;
98 static int i8254_real_max_count;
99 
100 struct mtx clock_lock;
101 static	struct intsrc *i8254_intsrc;
102 static	uint16_t i8254_lastcount;
103 static	uint16_t i8254_offset;
104 static	int	(*i8254_pending)(struct intsrc *);
105 static	int	i8254_ticked;
106 
107 struct attimer_softc {
108 	int intr_en;
109 	int port_rid, intr_rid;
110 	struct resource *port_res;
111 	struct resource *intr_res;
112 #ifdef PC98
113 	int port_rid2;
114 	struct resource *port_res2;
115 #endif
116 	void *intr_handler;
117 	struct timecounter tc;
118 	struct eventtimer et;
119 	uint32_t	intr_period;
120 };
121 static struct attimer_softc *attimer_sc = NULL;
122 
123 /* Values for timerX_state: */
124 #define	RELEASED	0
125 #define	RELEASE_PENDING	1
126 #define	ACQUIRED	2
127 #define	ACQUIRE_PENDING	3
128 
129 static	u_char	timer2_state;
130 
131 static	unsigned i8254_get_timecount(struct timecounter *tc);
132 static	void	set_i8254_freq(u_int freq, uint32_t intr_period);
133 
134 static int
135 clkintr(void *arg)
136 {
137 	struct attimer_softc *sc = (struct attimer_softc *)arg;
138 
139 	if (sc->intr_period != 0) {
140 		mtx_lock_spin(&clock_lock);
141 		if (i8254_ticked)
142 			i8254_ticked = 0;
143 		else {
144 			i8254_offset += i8254_max_count;
145 			i8254_lastcount = 0;
146 		}
147 		clkintr_pending = 0;
148 		mtx_unlock_spin(&clock_lock);
149 	}
150 
151 	if (sc && sc->et.et_active)
152 		sc->et.et_event_cb(&sc->et, sc->et.et_arg);
153 
154 #ifdef DEV_MCA
155 	/* Reset clock interrupt by asserting bit 7 of port 0x61 */
156 	if (MCA_system)
157 		outb(0x61, inb(0x61) | 0x80);
158 #endif
159 	return (FILTER_HANDLED);
160 }
161 
162 int
163 timer_spkr_acquire(void)
164 {
165 	int mode;
166 
167 #ifdef PC98
168 	mode = TIMER_SEL1 | TIMER_SQWAVE | TIMER_16BIT;
169 #else
170 	mode = TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT;
171 #endif
172 
173 	if (timer2_state != RELEASED)
174 		return (-1);
175 	timer2_state = ACQUIRED;
176 
177 	/*
178 	 * This access to the timer registers is as atomic as possible
179 	 * because it is a single instruction.  We could do better if we
180 	 * knew the rate.  Use of splclock() limits glitches to 10-100us,
181 	 * and this is probably good enough for timer2, so we aren't as
182 	 * careful with it as with timer0.
183 	 */
184 #ifdef PC98
185 	outb(TIMER_MODE, TIMER_SEL1 | (mode & 0x3f));
186 #else
187 	outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f));
188 #endif
189 	ppi_spkr_on();		/* enable counter2 output to speaker */
190 	return (0);
191 }
192 
193 int
194 timer_spkr_release(void)
195 {
196 
197 	if (timer2_state != ACQUIRED)
198 		return (-1);
199 	timer2_state = RELEASED;
200 #ifdef PC98
201 	outb(TIMER_MODE, TIMER_SEL1 | TIMER_SQWAVE | TIMER_16BIT);
202 #else
203 	outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT);
204 #endif
205 	ppi_spkr_off();		/* disable counter2 output to speaker */
206 	return (0);
207 }
208 
209 void
210 timer_spkr_setfreq(int freq)
211 {
212 
213 	freq = i8254_freq / freq;
214 	mtx_lock_spin(&clock_lock);
215 #ifdef PC98
216 	outb(TIMER_CNTR1, freq & 0xff);
217 	outb(TIMER_CNTR1, freq >> 8);
218 #else
219 	outb(TIMER_CNTR2, freq & 0xff);
220 	outb(TIMER_CNTR2, freq >> 8);
221 #endif
222 	mtx_unlock_spin(&clock_lock);
223 }
224 
225 static int
226 getit(void)
227 {
228 	int high, low;
229 
230 	mtx_lock_spin(&clock_lock);
231 
232 	/* Select timer0 and latch counter value. */
233 	outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
234 
235 	low = inb(TIMER_CNTR0);
236 	high = inb(TIMER_CNTR0);
237 
238 	mtx_unlock_spin(&clock_lock);
239 	return ((high << 8) | low);
240 }
241 
242 /*
243  * Wait "n" microseconds.
244  * Relies on timer 1 counting down from (i8254_freq / hz)
245  * Note: timer had better have been programmed before this is first used!
246  */
247 void
248 DELAY(int n)
249 {
250 	int delta, prev_tick, tick, ticks_left;
251 
252 #ifdef DELAYDEBUG
253 	int getit_calls = 1;
254 	int n1;
255 	static int state = 0;
256 #endif
257 
258 	if (tsc_freq != 0 && !tsc_is_broken) {
259 		uint64_t start, end, now;
260 
261 		sched_pin();
262 		start = rdtsc();
263 		end = start + (tsc_freq * n) / 1000000;
264 		do {
265 			cpu_spinwait();
266 			now = rdtsc();
267 		} while (now < end || (now > start && end < start));
268 		sched_unpin();
269 		return;
270 	}
271 #ifdef DELAYDEBUG
272 	if (state == 0) {
273 		state = 1;
274 		for (n1 = 1; n1 <= 10000000; n1 *= 10)
275 			DELAY(n1);
276 		state = 2;
277 	}
278 	if (state == 1)
279 		printf("DELAY(%d)...", n);
280 #endif
281 	/*
282 	 * Read the counter first, so that the rest of the setup overhead is
283 	 * counted.  Guess the initial overhead is 20 usec (on most systems it
284 	 * takes about 1.5 usec for each of the i/o's in getit().  The loop
285 	 * takes about 6 usec on a 486/33 and 13 usec on a 386/20.  The
286 	 * multiplications and divisions to scale the count take a while).
287 	 *
288 	 * However, if ddb is active then use a fake counter since reading
289 	 * the i8254 counter involves acquiring a lock.  ddb must not do
290 	 * locking for many reasons, but it calls here for at least atkbd
291 	 * input.
292 	 */
293 #ifdef KDB
294 	if (kdb_active)
295 		prev_tick = 1;
296 	else
297 #endif
298 		prev_tick = getit();
299 	n -= 0;			/* XXX actually guess no initial overhead */
300 	/*
301 	 * Calculate (n * (i8254_freq / 1e6)) without using floating point
302 	 * and without any avoidable overflows.
303 	 */
304 	if (n <= 0)
305 		ticks_left = 0;
306 	else if (n < 256)
307 		/*
308 		 * Use fixed point to avoid a slow division by 1000000.
309 		 * 39099 = 1193182 * 2^15 / 10^6 rounded to nearest.
310 		 * 2^15 is the first power of 2 that gives exact results
311 		 * for n between 0 and 256.
312 		 */
313 		ticks_left = ((u_int)n * 39099 + (1 << 15) - 1) >> 15;
314 	else
315 		/*
316 		 * Don't bother using fixed point, although gcc-2.7.2
317 		 * generates particularly poor code for the long long
318 		 * division, since even the slow way will complete long
319 		 * before the delay is up (unless we're interrupted).
320 		 */
321 		ticks_left = ((u_int)n * (long long)i8254_freq + 999999)
322 			     / 1000000;
323 
324 	while (ticks_left > 0) {
325 #ifdef KDB
326 		if (kdb_active) {
327 #ifdef PC98
328 			outb(0x5f, 0);
329 #else
330 			inb(0x84);
331 #endif
332 			tick = prev_tick - 1;
333 			if (tick <= 0)
334 				tick = i8254_max_count;
335 		} else
336 #endif
337 			tick = getit();
338 #ifdef DELAYDEBUG
339 		++getit_calls;
340 #endif
341 		delta = prev_tick - tick;
342 		prev_tick = tick;
343 		if (delta < 0) {
344 			delta += i8254_max_count;
345 			/*
346 			 * Guard against i8254_max_count being wrong.
347 			 * This shouldn't happen in normal operation,
348 			 * but it may happen if set_i8254_freq() is
349 			 * traced.
350 			 */
351 			if (delta < 0)
352 				delta = 0;
353 		}
354 		ticks_left -= delta;
355 	}
356 #ifdef DELAYDEBUG
357 	if (state == 1)
358 		printf(" %d calls to getit() at %d usec each\n",
359 		       getit_calls, (n + 5) / getit_calls);
360 #endif
361 }
362 
363 static void
364 set_i8254_freq(u_int freq, uint32_t intr_period)
365 {
366 	int new_i8254_real_max_count;
367 
368 	mtx_lock_spin(&clock_lock);
369 	i8254_freq = freq;
370 	if (intr_period == 0)
371 		new_i8254_real_max_count = 0x10000;
372 	else {
373 		new_i8254_real_max_count =
374 		    min(((uint64_t)i8254_freq * intr_period) >> 32, 0x10000);
375 	}
376 	if (new_i8254_real_max_count != i8254_real_max_count) {
377 		i8254_real_max_count = new_i8254_real_max_count;
378 		if (i8254_real_max_count == 0x10000)
379 			i8254_max_count = 0xffff;
380 		else
381 			i8254_max_count = i8254_real_max_count;
382 		outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
383 		outb(TIMER_CNTR0, i8254_real_max_count & 0xff);
384 		outb(TIMER_CNTR0, i8254_real_max_count >> 8);
385 	}
386 	mtx_unlock_spin(&clock_lock);
387 }
388 
389 static void
390 i8254_restore(void)
391 {
392 
393 	mtx_lock_spin(&clock_lock);
394 	outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
395 	outb(TIMER_CNTR0, i8254_real_max_count & 0xff);
396 	outb(TIMER_CNTR0, i8254_real_max_count >> 8);
397 	mtx_unlock_spin(&clock_lock);
398 }
399 
400 #ifndef __amd64__
401 /*
402  * Restore all the timers non-atomically (XXX: should be atomically).
403  *
404  * This function is called from pmtimer_resume() to restore all the timers.
405  * This should not be necessary, but there are broken laptops that do not
406  * restore all the timers on resume.
407  * As long as pmtimer is not part of amd64 suport, skip this for the amd64
408  * case.
409  */
410 void
411 timer_restore(void)
412 {
413 
414 	i8254_restore();		/* restore i8254_freq and hz */
415 #ifndef PC98
416 	atrtc_restore();		/* reenable RTC interrupts */
417 #endif
418 }
419 #endif
420 
421 /* This is separate from startrtclock() so that it can be called early. */
422 void
423 i8254_init(void)
424 {
425 
426 	mtx_init(&clock_lock, "clk", NULL, MTX_SPIN | MTX_NOPROFILE);
427 #ifdef PC98
428 	if (pc98_machine_type & M_8M)
429 		i8254_freq = 1996800L; /* 1.9968 MHz */
430 #endif
431 	set_i8254_freq(i8254_freq, 0);
432 }
433 
434 void
435 startrtclock()
436 {
437 
438 	init_TSC();
439 }
440 
441 void
442 cpu_initclocks(void)
443 {
444 
445 	init_TSC_tc();
446 	cpu_initclocks_bsp();
447 }
448 
449 static int
450 sysctl_machdep_i8254_freq(SYSCTL_HANDLER_ARGS)
451 {
452 	int error;
453 	u_int freq;
454 
455 	/*
456 	 * Use `i8254' instead of `timer' in external names because `timer'
457 	 * is is too generic.  Should use it everywhere.
458 	 */
459 	freq = i8254_freq;
460 	error = sysctl_handle_int(oidp, &freq, 0, req);
461 	if (error == 0 && req->newptr != NULL) {
462 		if (attimer_sc) {
463 			set_i8254_freq(freq, attimer_sc->intr_period);
464 			attimer_sc->tc.tc_frequency = freq;
465 		} else {
466 			set_i8254_freq(freq, 0);
467 		}
468 	}
469 	return (error);
470 }
471 
472 SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW,
473     0, sizeof(u_int), sysctl_machdep_i8254_freq, "IU", "");
474 
475 static unsigned
476 i8254_get_timecount(struct timecounter *tc)
477 {
478 	device_t dev = (device_t)tc->tc_priv;
479 	struct attimer_softc *sc = device_get_softc(dev);
480 	register_t flags;
481 	uint16_t count;
482 	u_int high, low;
483 
484 	if (sc->intr_period == 0)
485 		return (i8254_max_count - getit());
486 
487 #ifdef __amd64__
488 	flags = read_rflags();
489 #else
490 	flags = read_eflags();
491 #endif
492 	mtx_lock_spin(&clock_lock);
493 
494 	/* Select timer0 and latch counter value. */
495 	outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
496 
497 	low = inb(TIMER_CNTR0);
498 	high = inb(TIMER_CNTR0);
499 	count = i8254_max_count - ((high << 8) | low);
500 	if (count < i8254_lastcount ||
501 	    (!i8254_ticked && (clkintr_pending ||
502 	    ((count < 20 || (!(flags & PSL_I) &&
503 	    count < i8254_max_count / 2u)) &&
504 	    i8254_pending != NULL && i8254_pending(i8254_intsrc))))) {
505 		i8254_ticked = 1;
506 		i8254_offset += i8254_max_count;
507 	}
508 	i8254_lastcount = count;
509 	count += i8254_offset;
510 	mtx_unlock_spin(&clock_lock);
511 	return (count);
512 }
513 
514 static int
515 attimer_start(struct eventtimer *et,
516     struct bintime *first, struct bintime *period)
517 {
518 	device_t dev = (device_t)et->et_priv;
519 	struct attimer_softc *sc = device_get_softc(dev);
520 
521 	sc->intr_period = period->frac >> 32;
522 	set_i8254_freq(i8254_freq, sc->intr_period);
523 	if (!sc->intr_en) {
524 		i8254_intsrc->is_pic->pic_enable_source(i8254_intsrc);
525 		sc->intr_en = 1;
526 	}
527 	return (0);
528 }
529 
530 static int
531 attimer_stop(struct eventtimer *et)
532 {
533 	device_t dev = (device_t)et->et_priv;
534 	struct attimer_softc *sc = device_get_softc(dev);
535 
536 	sc->intr_period = 0;
537 	set_i8254_freq(i8254_freq, sc->intr_period);
538 	return (0);
539 }
540 
541 #ifdef DEV_ISA
542 /*
543  * Attach to the ISA PnP descriptors for the timer
544  */
545 static struct isa_pnp_id attimer_ids[] = {
546 	{ 0x0001d041 /* PNP0100 */, "AT timer" },
547 	{ 0 }
548 };
549 
550 #ifdef PC98
551 static void
552 pc98_alloc_resource(device_t dev)
553 {
554 	static bus_addr_t iat1[] = {0, 2, 4, 6};
555 	static bus_addr_t iat2[] = {0, 4};
556 	struct attimer_softc *sc;
557 
558 	sc = device_get_softc(dev);
559 
560 	sc->port_rid = 0;
561 	bus_set_resource(dev, SYS_RES_IOPORT, sc->port_rid, IO_TIMER1, 1);
562 	sc->port_res = isa_alloc_resourcev(dev, SYS_RES_IOPORT,
563 	    &sc->port_rid, iat1, 4, RF_ACTIVE);
564 	if (sc->port_res == NULL)
565 		device_printf(dev, "Warning: Couldn't map I/O.\n");
566 	else
567 		isa_load_resourcev(sc->port_res, iat1, 4);
568 
569 	sc->port_rid2 = 4;
570 	bus_set_resource(dev, SYS_RES_IOPORT, sc->port_rid2, TIMER_CNTR1, 1);
571 	sc->port_res2 = isa_alloc_resourcev(dev, SYS_RES_IOPORT,
572 	    &sc->port_rid2, iat2, 2, RF_ACTIVE);
573 	if (sc->port_res2 == NULL)
574 		device_printf(dev, "Warning: Couldn't map I/O.\n");
575 	else
576 		isa_load_resourcev(sc->port_res2, iat2, 2);
577 }
578 
579 static void
580 pc98_release_resource(device_t dev)
581 {
582 	struct attimer_softc *sc;
583 
584 	sc = device_get_softc(dev);
585 
586 	if (sc->port_res)
587 		bus_release_resource(dev, SYS_RES_IOPORT, sc->port_rid,
588 		    sc->port_res);
589 	if (sc->port_res2)
590 		bus_release_resource(dev, SYS_RES_IOPORT, sc->port_rid2,
591 		    sc->port_res2);
592 }
593 #endif
594 
595 static int
596 attimer_probe(device_t dev)
597 {
598 	int result;
599 
600 	result = ISA_PNP_PROBE(device_get_parent(dev), dev, attimer_ids);
601 	/* ENOENT means no PnP-ID, device is hinted. */
602 	if (result == ENOENT) {
603 		device_set_desc(dev, "AT timer");
604 #ifdef PC98
605 		/* To print resources correctly. */
606 		pc98_alloc_resource(dev);
607 		pc98_release_resource(dev);
608 #endif
609 		return (BUS_PROBE_LOW_PRIORITY);
610 	}
611 	return (result);
612 }
613 
614 static int
615 attimer_attach(device_t dev)
616 {
617 	struct attimer_softc *sc;
618 	u_long s;
619 	int i;
620 
621 	attimer_sc = sc = device_get_softc(dev);
622 	bzero(sc, sizeof(struct attimer_softc));
623 #ifdef PC98
624 	pc98_alloc_resource(dev);
625 #else
626 	if (!(sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT,
627 	    &sc->port_rid, IO_TIMER1, IO_TIMER1 + 3, 4, RF_ACTIVE)))
628 		device_printf(dev,"Warning: Couldn't map I/O.\n");
629 #endif
630 	i8254_intsrc = intr_lookup_source(0);
631 	if (i8254_intsrc != NULL)
632 		i8254_pending = i8254_intsrc->is_pic->pic_source_pending;
633 	set_i8254_freq(i8254_freq, 0);
634 	sc->tc.tc_get_timecount = i8254_get_timecount;
635 	sc->tc.tc_counter_mask = 0xffff;
636 	sc->tc.tc_frequency = i8254_freq;
637 	sc->tc.tc_name = "i8254";
638 	sc->tc.tc_quality = 0;
639 	sc->tc.tc_priv = dev;
640 	tc_init(&sc->tc);
641 	if (resource_int_value(device_get_name(dev), device_get_unit(dev),
642 	    "clock", &i) != 0 || i != 0) {
643 	    	sc->intr_rid = 0;
644 		while (bus_get_resource(dev, SYS_RES_IRQ, sc->intr_rid,
645 		    &s, NULL) == 0 && s != 0)
646 			sc->intr_rid++;
647 		if (!(sc->intr_res = bus_alloc_resource(dev, SYS_RES_IRQ,
648 		    &sc->intr_rid, 0, 0, 1, RF_ACTIVE))) {
649 			device_printf(dev,"Can't map interrupt.\n");
650 			return (0);
651 		}
652 		/* Dirty hack, to make bus_setup_intr to not enable source. */
653 		i8254_intsrc->is_handlers++;
654 		if ((bus_setup_intr(dev, sc->intr_res,
655 		    INTR_MPSAFE | INTR_TYPE_CLK,
656 		    (driver_filter_t *)clkintr, NULL,
657 		    sc, &sc->intr_handler))) {
658 			device_printf(dev, "Can't setup interrupt.\n");
659 			i8254_intsrc->is_handlers--;
660 			return (0);
661 		}
662 		i8254_intsrc->is_handlers--;
663 		i8254_intsrc->is_pic->pic_enable_intr(i8254_intsrc);
664 		sc->et.et_name = "i8254";
665 		sc->et.et_flags = ET_FLAGS_PERIODIC;
666 		sc->et.et_quality = 100;
667 		sc->et.et_frequency = i8254_freq;
668 		sc->et.et_min_period.sec = 0;
669 		sc->et.et_min_period.frac =
670 		    ((0x0002LLU << 48) / i8254_freq) << 16;
671 		sc->et.et_max_period.sec = 0xffff / i8254_freq;
672 		sc->et.et_max_period.frac =
673 		    ((0xfffeLLU << 48) / i8254_freq) << 16;
674 		sc->et.et_start = attimer_start;
675 		sc->et.et_stop = attimer_stop;
676 		sc->et.et_priv = dev;
677 		et_register(&sc->et);
678 	}
679 	return(0);
680 }
681 
682 static int
683 attimer_resume(device_t dev)
684 {
685 
686 	i8254_restore();
687 	return (0);
688 }
689 
690 static device_method_t attimer_methods[] = {
691 	/* Device interface */
692 	DEVMETHOD(device_probe,		attimer_probe),
693 	DEVMETHOD(device_attach,	attimer_attach),
694 	DEVMETHOD(device_detach,	bus_generic_detach),
695 	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
696 	DEVMETHOD(device_suspend,	bus_generic_suspend),
697 	DEVMETHOD(device_resume,	attimer_resume),
698 	{ 0, 0 }
699 };
700 
701 static driver_t attimer_driver = {
702 	"attimer",
703 	attimer_methods,
704 	sizeof(struct attimer_softc),
705 };
706 
707 static devclass_t attimer_devclass;
708 
709 DRIVER_MODULE(attimer, isa, attimer_driver, attimer_devclass, 0, 0);
710 DRIVER_MODULE(attimer, acpi, attimer_driver, attimer_devclass, 0, 0);
711 
712 #endif /* DEV_ISA */
713