acpipmtimer.c revision 1.6 1 /* $NetBSD: acpipmtimer.c,v 1.6 2008/04/08 12:07:25 cegger Exp $ */
2
3 #include <sys/cdefs.h>
4 __KERNEL_RCSID(0, "$NetBSD: acpipmtimer.c,v 1.6 2008/04/08 12:07:25 cegger Exp $");
5
6 #include <sys/types.h>
7
8 #include <sys/systm.h>
9 #include <sys/device.h>
10 #include <sys/malloc.h>
11 #include <sys/bus.h>
12 #include <sys/time.h>
13 #include <sys/timetc.h>
14
15 #include <dev/ic/acpipmtimer.h>
16
17 #define ACPI_PM_TIMER_FREQUENCY 3579545
18
19 struct hwtc {
20 struct timecounter tc;
21 bus_space_tag_t t;
22 bus_space_handle_t h;
23 bus_size_t off;
24 };
25
26 static u_int acpihwtimer_read_safe(struct timecounter *);
27 static u_int acpihwtimer_read_fast(struct timecounter *);
28
29 int
30 acpipmtimer_attach(struct device *dev,
31 bus_space_tag_t t, bus_space_handle_t h, bus_size_t off,
32 int flags)
33 {
34 struct hwtc *tc;
35
36 tc = malloc(sizeof(struct hwtc), M_DEVBUF, M_WAITOK|M_ZERO);
37 if (!tc)
38 return (-1);
39
40 tc->tc.tc_name = device_xname(dev);
41 tc->tc.tc_frequency = ACPI_PM_TIMER_FREQUENCY;
42 if (flags & ACPIPMT_32BIT)
43 tc->tc.tc_counter_mask = 0xffffffff;
44 else
45 tc->tc.tc_counter_mask = 0x00ffffff;
46 if (flags & ACPIPMT_BADLATCH) {
47 tc->tc.tc_get_timecount = acpihwtimer_read_safe;
48 tc->tc.tc_quality = 900;
49 } else {
50 tc->tc.tc_get_timecount = acpihwtimer_read_fast;
51 tc->tc.tc_quality = 1000;
52 }
53
54 tc->t = t;
55 tc->h = h;
56 tc->off = off;
57
58 tc->tc.tc_priv = tc;
59 tc_init(&tc->tc);
60 aprint_normal("%s: %d-bit timer\n", tc->tc.tc_name,
61 (flags & ACPIPMT_32BIT ? 32 : 24));
62 return (0);
63 }
64
65 #define r(h) bus_space_read_4(h->t, h->h, h->off)
66
67 static u_int
68 acpihwtimer_read_safe(struct timecounter *tc)
69 {
70 struct hwtc *h = tc->tc_priv;
71 uint32_t t1, t2, t3;
72
73 t2 = r(h);
74 t3 = r(h);
75 do {
76 t1 = t2;
77 t2 = t3;
78 t3 = r(h);
79 } while ((t1 > t2) || (t2 > t3));
80 return (t2);
81 }
82
83 static u_int
84 acpihwtimer_read_fast(struct timecounter *tc)
85 {
86 struct hwtc *h = tc->tc_priv;
87
88 return r(h);
89 }
90