This source file includes following definitions.
- to_ti_32k
- ti_32k_read_cycles
- omap_32k_read_sched_clock
- ti_32k_timer_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 #include <linux/init.h>
28 #include <linux/time.h>
29 #include <linux/sched_clock.h>
30 #include <linux/clocksource.h>
31 #include <linux/of.h>
32 #include <linux/of_address.h>
33
34
35
36
37
38
39
40
41 #define OMAP2_32KSYNCNT_REV_OFF 0x0
42 #define OMAP2_32KSYNCNT_REV_SCHEME (0x3 << 30)
43 #define OMAP2_32KSYNCNT_CR_OFF_LOW 0x10
44 #define OMAP2_32KSYNCNT_CR_OFF_HIGH 0x30
45
46 struct ti_32k {
47 void __iomem *base;
48 void __iomem *counter;
49 struct clocksource cs;
50 };
51
52 static inline struct ti_32k *to_ti_32k(struct clocksource *cs)
53 {
54 return container_of(cs, struct ti_32k, cs);
55 }
56
57 static u64 notrace ti_32k_read_cycles(struct clocksource *cs)
58 {
59 struct ti_32k *ti = to_ti_32k(cs);
60
61 return (u64)readl_relaxed(ti->counter);
62 }
63
64 static struct ti_32k ti_32k_timer = {
65 .cs = {
66 .name = "32k_counter",
67 .rating = 250,
68 .read = ti_32k_read_cycles,
69 .mask = CLOCKSOURCE_MASK(32),
70 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
71 },
72 };
73
74 static u64 notrace omap_32k_read_sched_clock(void)
75 {
76 return ti_32k_read_cycles(&ti_32k_timer.cs);
77 }
78
79 static int __init ti_32k_timer_init(struct device_node *np)
80 {
81 int ret;
82
83 ti_32k_timer.base = of_iomap(np, 0);
84 if (!ti_32k_timer.base) {
85 pr_err("Can't ioremap 32k timer base\n");
86 return -ENXIO;
87 }
88
89 if (!of_machine_is_compatible("ti,am43"))
90 ti_32k_timer.cs.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
91
92 ti_32k_timer.counter = ti_32k_timer.base;
93
94
95
96
97
98
99
100
101 if (readl_relaxed(ti_32k_timer.base + OMAP2_32KSYNCNT_REV_OFF) &
102 OMAP2_32KSYNCNT_REV_SCHEME)
103 ti_32k_timer.counter += OMAP2_32KSYNCNT_CR_OFF_HIGH;
104 else
105 ti_32k_timer.counter += OMAP2_32KSYNCNT_CR_OFF_LOW;
106
107 ret = clocksource_register_hz(&ti_32k_timer.cs, 32768);
108 if (ret) {
109 pr_err("32k_counter: can't register clocksource\n");
110 return ret;
111 }
112
113 sched_clock_register(omap_32k_read_sched_clock, 32, 32768);
114 pr_info("OMAP clocksource: 32k_counter at 32768 Hz\n");
115
116 return 0;
117 }
118 TIMER_OF_DECLARE(ti_32k_timer, "ti,omap-counter32k",
119 ti_32k_timer_init);