3535
3636#define TIMER_SYNC_TICKS 3
3737
38- struct sun5i_timer {
38+ /* Pointless struct to minimise diff */
39+ struct _sun5i_timer {
3940 void __iomem * base ;
4041 struct clk * clk ;
4142 struct notifier_block clk_rate_cb ;
4243 u32 ticks_per_jiffy ;
4344};
4445
45- #define to_sun5i_timer (x ) \
46- container_of(x, struct sun5i_timer, clk_rate_cb)
47-
48- struct sun5i_timer_clksrc {
49- struct sun5i_timer timer ;
46+ struct sun5i_timer {
47+ struct _sun5i_timer timer ;
5048 struct clocksource clksrc ;
51- };
52-
53- #define to_sun5i_timer_clksrc (x ) \
54- container_of(x, struct sun5i_timer_clksrc, clksrc)
55-
56- struct sun5i_timer_clkevt {
57- struct sun5i_timer timer ;
5849 struct clock_event_device clkevt ;
5950};
6051
61- #define to_sun5i_timer_clkevt (x ) \
62- container_of(x, struct sun5i_timer_clkevt, clkevt)
52+ #define nb_to_sun5i_timer (x ) \
53+ container_of(x, struct sun5i_timer, timer.clk_rate_cb)
54+ #define clksrc_to_sun5i_timer (x ) \
55+ container_of(x, struct sun5i_timer, clksrc)
56+ #define clkevt_to_sun5i_timer (x ) \
57+ container_of(x, struct sun5i_timer, clkevt)
6358
6459/*
6560 * When we disable a timer, we need to wait at least for 2 cycles of
6661 * the timer source clock. We will use for that the clocksource timer
6762 * that is already setup and runs at the same frequency than the other
6863 * timers, and we never will be disabled.
6964 */
70- static void sun5i_clkevt_sync (struct sun5i_timer_clkevt * ce )
65+ static void sun5i_clkevt_sync (struct sun5i_timer * ce )
7166{
7267 u32 old = readl (ce -> timer .base + TIMER_CNTVAL_LO_REG (1 ));
7368
7469 while ((old - readl (ce -> timer .base + TIMER_CNTVAL_LO_REG (1 ))) < TIMER_SYNC_TICKS )
7570 cpu_relax ();
7671}
7772
78- static void sun5i_clkevt_time_stop (struct sun5i_timer_clkevt * ce , u8 timer )
73+ static void sun5i_clkevt_time_stop (struct sun5i_timer * ce , u8 timer )
7974{
8075 u32 val = readl (ce -> timer .base + TIMER_CTL_REG (timer ));
8176 writel (val & ~TIMER_CTL_ENABLE , ce -> timer .base + TIMER_CTL_REG (timer ));
8277
8378 sun5i_clkevt_sync (ce );
8479}
8580
86- static void sun5i_clkevt_time_setup (struct sun5i_timer_clkevt * ce , u8 timer , u32 delay )
81+ static void sun5i_clkevt_time_setup (struct sun5i_timer * ce , u8 timer , u32 delay )
8782{
8883 writel (delay , ce -> timer .base + TIMER_INTVAL_LO_REG (timer ));
8984}
9085
91- static void sun5i_clkevt_time_start (struct sun5i_timer_clkevt * ce , u8 timer , bool periodic )
86+ static void sun5i_clkevt_time_start (struct sun5i_timer * ce , u8 timer , bool periodic )
9287{
9388 u32 val = readl (ce -> timer .base + TIMER_CTL_REG (timer ));
9489
@@ -103,15 +98,15 @@ static void sun5i_clkevt_time_start(struct sun5i_timer_clkevt *ce, u8 timer, boo
10398
10499static int sun5i_clkevt_shutdown (struct clock_event_device * clkevt )
105100{
106- struct sun5i_timer_clkevt * ce = to_sun5i_timer_clkevt (clkevt );
101+ struct sun5i_timer * ce = clkevt_to_sun5i_timer (clkevt );
107102
108103 sun5i_clkevt_time_stop (ce , 0 );
109104 return 0 ;
110105}
111106
112107static int sun5i_clkevt_set_oneshot (struct clock_event_device * clkevt )
113108{
114- struct sun5i_timer_clkevt * ce = to_sun5i_timer_clkevt (clkevt );
109+ struct sun5i_timer * ce = clkevt_to_sun5i_timer (clkevt );
115110
116111 sun5i_clkevt_time_stop (ce , 0 );
117112 sun5i_clkevt_time_start (ce , 0 , false);
@@ -120,7 +115,7 @@ static int sun5i_clkevt_set_oneshot(struct clock_event_device *clkevt)
120115
121116static int sun5i_clkevt_set_periodic (struct clock_event_device * clkevt )
122117{
123- struct sun5i_timer_clkevt * ce = to_sun5i_timer_clkevt (clkevt );
118+ struct sun5i_timer * ce = clkevt_to_sun5i_timer (clkevt );
124119
125120 sun5i_clkevt_time_stop (ce , 0 );
126121 sun5i_clkevt_time_setup (ce , 0 , ce -> timer .ticks_per_jiffy );
@@ -131,7 +126,7 @@ static int sun5i_clkevt_set_periodic(struct clock_event_device *clkevt)
131126static int sun5i_clkevt_next_event (unsigned long evt ,
132127 struct clock_event_device * clkevt )
133128{
134- struct sun5i_timer_clkevt * ce = to_sun5i_timer_clkevt (clkevt );
129+ struct sun5i_timer * ce = clkevt_to_sun5i_timer (clkevt );
135130
136131 sun5i_clkevt_time_stop (ce , 0 );
137132 sun5i_clkevt_time_setup (ce , 0 , evt - TIMER_SYNC_TICKS );
@@ -142,7 +137,7 @@ static int sun5i_clkevt_next_event(unsigned long evt,
142137
143138static irqreturn_t sun5i_timer_interrupt (int irq , void * dev_id )
144139{
145- struct sun5i_timer_clkevt * ce = dev_id ;
140+ struct sun5i_timer * ce = dev_id ;
146141
147142 writel (0x1 , ce -> timer .base + TIMER_IRQ_ST_REG );
148143 ce -> clkevt .event_handler (& ce -> clkevt );
@@ -152,17 +147,16 @@ static irqreturn_t sun5i_timer_interrupt(int irq, void *dev_id)
152147
153148static u64 sun5i_clksrc_read (struct clocksource * clksrc )
154149{
155- struct sun5i_timer_clksrc * cs = to_sun5i_timer_clksrc (clksrc );
150+ struct sun5i_timer * cs = clksrc_to_sun5i_timer (clksrc );
156151
157152 return ~readl (cs -> timer .base + TIMER_CNTVAL_LO_REG (1 ));
158153}
159154
160- static int sun5i_rate_cb_clksrc (struct notifier_block * nb ,
161- unsigned long event , void * data )
155+ static int sun5i_rate_cb (struct notifier_block * nb ,
156+ unsigned long event , void * data )
162157{
163158 struct clk_notifier_data * ndata = data ;
164- struct sun5i_timer * timer = to_sun5i_timer (nb );
165- struct sun5i_timer_clksrc * cs = container_of (timer , struct sun5i_timer_clksrc , timer );
159+ struct sun5i_timer * cs = nb_to_sun5i_timer (nb );
166160
167161 switch (event ) {
168162 case PRE_RATE_CHANGE :
@@ -171,6 +165,8 @@ static int sun5i_rate_cb_clksrc(struct notifier_block *nb,
171165
172166 case POST_RATE_CHANGE :
173167 clocksource_register_hz (& cs -> clksrc , ndata -> new_rate );
168+ clockevents_update_freq (& cs -> clkevt , ndata -> new_rate );
169+ cs -> timer .ticks_per_jiffy = DIV_ROUND_UP (ndata -> new_rate , HZ );
174170 break ;
175171
176172 default :
@@ -181,41 +177,12 @@ static int sun5i_rate_cb_clksrc(struct notifier_block *nb,
181177}
182178
183179static int __init sun5i_setup_clocksource (struct device_node * node ,
184- void __iomem * base ,
185- struct clk * clk , int irq )
180+ struct sun5i_timer * cs ,
181+ unsigned long rate )
186182{
187- struct sun5i_timer_clksrc * cs ;
188- unsigned long rate ;
183+ void __iomem * base = cs -> timer .base ;
189184 int ret ;
190185
191- cs = kzalloc (sizeof (* cs ), GFP_KERNEL );
192- if (!cs )
193- return - ENOMEM ;
194-
195- ret = clk_prepare_enable (clk );
196- if (ret ) {
197- pr_err ("Couldn't enable parent clock\n" );
198- goto err_free ;
199- }
200-
201- rate = clk_get_rate (clk );
202- if (!rate ) {
203- pr_err ("Couldn't get parent clock rate\n" );
204- ret = - EINVAL ;
205- goto err_disable_clk ;
206- }
207-
208- cs -> timer .base = base ;
209- cs -> timer .clk = clk ;
210- cs -> timer .clk_rate_cb .notifier_call = sun5i_rate_cb_clksrc ;
211- cs -> timer .clk_rate_cb .next = NULL ;
212-
213- ret = clk_notifier_register (clk , & cs -> timer .clk_rate_cb );
214- if (ret ) {
215- pr_err ("Unable to register clock notifier.\n" );
216- goto err_disable_clk ;
217- }
218-
219186 writel (~0 , base + TIMER_INTVAL_LO_REG (1 ));
220187 writel (TIMER_CTL_ENABLE | TIMER_CTL_RELOAD ,
221188 base + TIMER_CTL_REG (1 ));
@@ -229,72 +196,20 @@ static int __init sun5i_setup_clocksource(struct device_node *node,
229196 ret = clocksource_register_hz (& cs -> clksrc , rate );
230197 if (ret ) {
231198 pr_err ("Couldn't register clock source.\n" );
232- goto err_remove_notifier ;
199+ return ret ;
233200 }
234201
235202 return 0 ;
236-
237- err_remove_notifier :
238- clk_notifier_unregister (clk , & cs -> timer .clk_rate_cb );
239- err_disable_clk :
240- clk_disable_unprepare (clk );
241- err_free :
242- kfree (cs );
243- return ret ;
244- }
245-
246- static int sun5i_rate_cb_clkevt (struct notifier_block * nb ,
247- unsigned long event , void * data )
248- {
249- struct clk_notifier_data * ndata = data ;
250- struct sun5i_timer * timer = to_sun5i_timer (nb );
251- struct sun5i_timer_clkevt * ce = container_of (timer , struct sun5i_timer_clkevt , timer );
252-
253- if (event == POST_RATE_CHANGE ) {
254- clockevents_update_freq (& ce -> clkevt , ndata -> new_rate );
255- ce -> timer .ticks_per_jiffy = DIV_ROUND_UP (ndata -> new_rate , HZ );
256- }
257-
258- return NOTIFY_DONE ;
259203}
260204
261- static int __init sun5i_setup_clockevent (struct device_node * node , void __iomem * base ,
262- struct clk * clk , int irq )
205+ static int __init sun5i_setup_clockevent (struct device_node * node ,
206+ struct sun5i_timer * ce ,
207+ unsigned long rate , int irq )
263208{
264- struct sun5i_timer_clkevt * ce ;
265- unsigned long rate ;
209+ void __iomem * base = ce -> timer .base ;
266210 int ret ;
267211 u32 val ;
268212
269- ce = kzalloc (sizeof (* ce ), GFP_KERNEL );
270- if (!ce )
271- return - ENOMEM ;
272-
273- ret = clk_prepare_enable (clk );
274- if (ret ) {
275- pr_err ("Couldn't enable parent clock\n" );
276- goto err_free ;
277- }
278-
279- rate = clk_get_rate (clk );
280- if (!rate ) {
281- pr_err ("Couldn't get parent clock rate\n" );
282- ret = - EINVAL ;
283- goto err_disable_clk ;
284- }
285-
286- ce -> timer .base = base ;
287- ce -> timer .ticks_per_jiffy = DIV_ROUND_UP (rate , HZ );
288- ce -> timer .clk = clk ;
289- ce -> timer .clk_rate_cb .notifier_call = sun5i_rate_cb_clkevt ;
290- ce -> timer .clk_rate_cb .next = NULL ;
291-
292- ret = clk_notifier_register (clk , & ce -> timer .clk_rate_cb );
293- if (ret ) {
294- pr_err ("Unable to register clock notifier.\n" );
295- goto err_disable_clk ;
296- }
297-
298213 ce -> clkevt .name = node -> name ;
299214 ce -> clkevt .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT ;
300215 ce -> clkevt .set_next_event = sun5i_clkevt_next_event ;
@@ -317,27 +232,25 @@ static int __init sun5i_setup_clockevent(struct device_node *node, void __iomem
317232 "sun5i_timer0" , ce );
318233 if (ret ) {
319234 pr_err ("Unable to register interrupt\n" );
320- goto err_remove_notifier ;
235+ return ret ;
321236 }
322237
323238 return 0 ;
324-
325- err_remove_notifier :
326- clk_notifier_unregister (clk , & ce -> timer .clk_rate_cb );
327- err_disable_clk :
328- clk_disable_unprepare (clk );
329- err_free :
330- kfree (ce );
331- return ret ;
332239}
333240
334241static int __init sun5i_timer_init (struct device_node * node )
335242{
243+ struct sun5i_timer * st ;
336244 struct reset_control * rstc ;
337245 void __iomem * timer_base ;
338246 struct clk * clk ;
247+ unsigned long rate ;
339248 int irq , ret ;
340249
250+ st = kzalloc (sizeof (* st ), GFP_KERNEL );
251+ if (!st )
252+ return - ENOMEM ;
253+
341254 timer_base = of_io_request_and_map (node , 0 , of_node_full_name (node ));
342255 if (IS_ERR (timer_base )) {
343256 pr_err ("Can't map registers\n" );
@@ -356,15 +269,48 @@ static int __init sun5i_timer_init(struct device_node *node)
356269 return PTR_ERR (clk );
357270 }
358271
272+ ret = clk_prepare_enable (clk );
273+ if (ret ) {
274+ pr_err ("Couldn't enable parent clock\n" );
275+ goto err_free ;
276+ }
277+
278+ rate = clk_get_rate (clk );
279+ if (!rate ) {
280+ pr_err ("Couldn't get parent clock rate\n" );
281+ ret = - EINVAL ;
282+ goto err_disable_clk ;
283+ }
284+
285+ st -> timer .base = timer_base ;
286+ st -> timer .ticks_per_jiffy = DIV_ROUND_UP (rate , HZ );
287+ st -> timer .clk = clk ;
288+ st -> timer .clk_rate_cb .notifier_call = sun5i_rate_cb ;
289+ st -> timer .clk_rate_cb .next = NULL ;
290+
291+ ret = clk_notifier_register (clk , & st -> timer .clk_rate_cb );
292+ if (ret ) {
293+ pr_err ("Unable to register clock notifier.\n" );
294+ goto err_disable_clk ;
295+ }
296+
359297 rstc = of_reset_control_get (node , NULL );
360298 if (!IS_ERR (rstc ))
361299 reset_control_deassert (rstc );
362300
363- ret = sun5i_setup_clocksource (node , timer_base , clk , irq );
301+ ret = sun5i_setup_clocksource (node , st , rate );
364302 if (ret )
365- return ret ;
303+ goto err_remove_notifier ;
366304
367- return sun5i_setup_clockevent (node , timer_base , clk , irq );
305+ return sun5i_setup_clockevent (node , st , rate , irq );
306+
307+ err_remove_notifier :
308+ clk_notifier_unregister (clk , & st -> timer .clk_rate_cb );
309+ err_disable_clk :
310+ clk_disable_unprepare (clk );
311+ err_free :
312+ kfree (st );
313+ return ret ;
368314}
369315TIMER_OF_DECLARE (sun5i_a13 , "allwinner,sun5i-a13-hstimer" ,
370316 sun5i_timer_init );
0 commit comments