4
4
5
5
#include <linux/interrupt.h>
6
6
#include <linux/clockchips.h>
7
+ #include <linux/slab.h>
7
8
8
9
#include "timer-of.h"
9
10
20
21
21
22
#define SYS_CTR_CLK_DIV 0x3
22
23
23
- static void __iomem * sys_ctr_base __ro_after_init ;
24
- static u32 cmpcr __ro_after_init ;
24
+ struct sysctr_private {
25
+ u32 cmpcr ;
26
+ };
25
27
26
- static void sysctr_timer_enable (bool enable )
28
+ static void sysctr_timer_enable (struct clock_event_device * evt , bool enable )
27
29
{
28
- writel (enable ? cmpcr | SYS_CTR_EN : cmpcr , sys_ctr_base + CMPCR );
30
+ struct timer_of * to = to_timer_of (evt );
31
+ struct sysctr_private * priv = to -> private_data ;
32
+ void __iomem * base = timer_of_base (to );
33
+
34
+ writel (enable ? priv -> cmpcr | SYS_CTR_EN : priv -> cmpcr , base + CMPCR );
29
35
}
30
36
31
- static void sysctr_irq_acknowledge (void )
37
+ static void sysctr_irq_acknowledge (struct clock_event_device * evt )
32
38
{
33
39
/*
34
40
* clear the enable bit(EN =0) will clear
35
41
* the status bit(ISTAT = 0), then the interrupt
36
42
* signal will be negated(acknowledged).
37
43
*/
38
- sysctr_timer_enable (false);
44
+ sysctr_timer_enable (evt , false);
39
45
}
40
46
41
- static inline u64 sysctr_read_counter (void )
47
+ static inline u64 sysctr_read_counter (struct clock_event_device * evt )
42
48
{
49
+ struct timer_of * to = to_timer_of (evt );
50
+ void __iomem * base = timer_of_base (to );
43
51
u32 cnt_hi , tmp_hi , cnt_lo ;
44
52
45
53
do {
46
- cnt_hi = readl_relaxed (sys_ctr_base + CNTCV_HI );
47
- cnt_lo = readl_relaxed (sys_ctr_base + CNTCV_LO );
48
- tmp_hi = readl_relaxed (sys_ctr_base + CNTCV_HI );
54
+ cnt_hi = readl_relaxed (base + CNTCV_HI );
55
+ cnt_lo = readl_relaxed (base + CNTCV_LO );
56
+ tmp_hi = readl_relaxed (base + CNTCV_HI );
49
57
} while (tmp_hi != cnt_hi );
50
58
51
59
return ((u64 ) cnt_hi << 32 ) | cnt_lo ;
@@ -54,22 +62,24 @@ static inline u64 sysctr_read_counter(void)
54
62
static int sysctr_set_next_event (unsigned long delta ,
55
63
struct clock_event_device * evt )
56
64
{
65
+ struct timer_of * to = to_timer_of (evt );
66
+ void __iomem * base = timer_of_base (to );
57
67
u32 cmp_hi , cmp_lo ;
58
68
u64 next ;
59
69
60
- sysctr_timer_enable (false);
70
+ sysctr_timer_enable (evt , false);
61
71
62
- next = sysctr_read_counter ();
72
+ next = sysctr_read_counter (evt );
63
73
64
74
next += delta ;
65
75
66
76
cmp_hi = (next >> 32 ) & 0x00fffff ;
67
77
cmp_lo = next & 0xffffffff ;
68
78
69
- writel_relaxed (cmp_hi , sys_ctr_base + CMPCV_HI );
70
- writel_relaxed (cmp_lo , sys_ctr_base + CMPCV_LO );
79
+ writel_relaxed (cmp_hi , base + CMPCV_HI );
80
+ writel_relaxed (cmp_lo , base + CMPCV_LO );
71
81
72
- sysctr_timer_enable (true);
82
+ sysctr_timer_enable (evt , true);
73
83
74
84
return 0 ;
75
85
}
@@ -81,7 +91,7 @@ static int sysctr_set_state_oneshot(struct clock_event_device *evt)
81
91
82
92
static int sysctr_set_state_shutdown (struct clock_event_device * evt )
83
93
{
84
- sysctr_timer_enable (false);
94
+ sysctr_timer_enable (evt , false);
85
95
86
96
return 0 ;
87
97
}
@@ -90,7 +100,7 @@ static irqreturn_t sysctr_timer_interrupt(int irq, void *dev_id)
90
100
{
91
101
struct clock_event_device * evt = dev_id ;
92
102
93
- sysctr_irq_acknowledge ();
103
+ sysctr_irq_acknowledge (evt );
94
104
95
105
evt -> event_handler (evt );
96
106
@@ -117,34 +127,36 @@ static struct timer_of to_sysctr = {
117
127
},
118
128
};
119
129
120
- static void __init sysctr_clockevent_init (void )
121
- {
122
- to_sysctr .clkevt .cpumask = cpu_possible_mask ;
123
-
124
- clockevents_config_and_register (& to_sysctr .clkevt ,
125
- timer_of_rate (& to_sysctr ),
126
- 0xff , 0x7fffffff );
127
- }
128
-
129
130
static int __init sysctr_timer_init (struct device_node * np )
130
131
{
131
- int ret = 0 ;
132
+ struct sysctr_private * priv ;
133
+ void __iomem * base ;
134
+ int ret ;
135
+
136
+ priv = kzalloc (sizeof (struct sysctr_private ), GFP_KERNEL );
137
+ if (!priv )
138
+ return - ENOMEM ;
132
139
133
140
ret = timer_of_init (np , & to_sysctr );
134
- if (ret )
141
+ if (ret ) {
142
+ kfree (priv );
135
143
return ret ;
144
+ }
136
145
137
146
if (!of_property_read_bool (np , "nxp,no-divider" )) {
138
147
/* system counter clock is divided by 3 internally */
139
148
to_sysctr .of_clk .rate /= SYS_CTR_CLK_DIV ;
140
149
}
141
150
142
- sys_ctr_base = timer_of_base (& to_sysctr );
143
- cmpcr = readl (sys_ctr_base + CMPCR );
144
- cmpcr &= ~SYS_CTR_EN ;
151
+ to_sysctr .clkevt .cpumask = cpu_possible_mask ;
152
+ to_sysctr .private_data = priv ;
145
153
146
- sysctr_clockevent_init ();
154
+ base = timer_of_base (& to_sysctr );
155
+ priv -> cmpcr = readl (base + CMPCR ) & ~SYS_CTR_EN ;
147
156
157
+ clockevents_config_and_register (& to_sysctr .clkevt ,
158
+ timer_of_rate (& to_sysctr ),
159
+ 0xff , 0x7fffffff );
148
160
return 0 ;
149
161
}
150
162
TIMER_OF_DECLARE (sysctr_timer , "nxp,sysctr-timer" , sysctr_timer_init );
0 commit comments