acpi_timer.c revision 1.1 1 /* $NetBSD: acpi_timer.c,v 1.1 2006/06/21 17:47:23 drochner Exp $ */
2
3 #include <sys/types.h>
4
5 #ifdef __HAVE_TIMECOUNTER
6
7 #include <sys/systm.h>
8 #include <sys/time.h>
9 #include <sys/timetc.h>
10 #include <dev/acpi/acpica.h>
11 #include <dev/acpi/acpi_timer.h>
12
13 static u_int acpitimer_read(struct timecounter *);
14
15 static struct timecounter acpi_timecounter = {
16 acpitimer_read,
17 0,
18 0x00ffffff,
19 PM_TIMER_FREQUENCY,
20 "ACPI_PM_TMR",
21 900
22 };
23
24 int
25 acpitimer_init()
26 {
27 uint32_t bits;
28 ACPI_STATUS res;
29
30 res = AcpiGetTimerResolution(&bits);
31 if (res != AE_OK)
32 return (-1);
33
34 if (bits == 32)
35 acpi_timecounter.tc_counter_mask = 0xffffffff;
36 tc_init(&acpi_timecounter);
37
38 printf("acpitimer: %d bits\n", bits);
39
40 return (0);
41 }
42
43 /*
44 * Some chipsets (PIIX4 variants) do not latch correctly; there
45 * is a chance that a transition is hit.
46 * For now, just be conservative. We might detect the situation later
47 * (by testing, or chipset quirks).
48 */
49 static u_int
50 acpitimer_read(struct timecounter *tc)
51 {
52 uint32_t t1, t2, t3;
53
54 AcpiGetTimer(&t2);
55 AcpiGetTimer(&t3);
56 do {
57 t1 = t2;
58 t2 = t3;
59 AcpiGetTimer(&t3);
60 } while ((t1 > t2) || (t2 > t3));
61 return (t2);
62 }
63
64 #else
65
66 int
67 acpitimer_init()
68 {
69
70 return (0);
71 }
72
73 #endif
74