1616#include <linux/irqreturn.h>
1717#include <linux/reset.h>
1818#include <linux/slab.h>
19- #include <linux/of.h>
20- #include <linux/of_address.h>
21- #include <linux/of_irq.h>
19+ #include <linux/platform_device.h>
2220
2321#define TIMER_IRQ_EN_REG 0x00
2422#define TIMER_IRQ_EN (val ) BIT(val)
@@ -171,41 +169,42 @@ static int sun5i_rate_cb(struct notifier_block *nb,
171169 return NOTIFY_DONE ;
172170}
173171
174- static int __init sun5i_setup_clocksource (struct device_node * node ,
175- struct sun5i_timer * cs ,
176- unsigned long rate )
172+ static int sun5i_setup_clocksource (struct platform_device * pdev ,
173+ unsigned long rate )
177174{
175+ struct sun5i_timer * cs = platform_get_drvdata (pdev );
178176 void __iomem * base = cs -> base ;
179177 int ret ;
180178
181179 writel (~0 , base + TIMER_INTVAL_LO_REG (1 ));
182180 writel (TIMER_CTL_ENABLE | TIMER_CTL_RELOAD ,
183181 base + TIMER_CTL_REG (1 ));
184182
185- cs -> clksrc .name = node -> name ;
183+ cs -> clksrc .name = pdev -> dev . of_node -> name ;
186184 cs -> clksrc .rating = 340 ;
187185 cs -> clksrc .read = sun5i_clksrc_read ;
188186 cs -> clksrc .mask = CLOCKSOURCE_MASK (32 );
189187 cs -> clksrc .flags = CLOCK_SOURCE_IS_CONTINUOUS ;
190188
191189 ret = clocksource_register_hz (& cs -> clksrc , rate );
192190 if (ret ) {
193- pr_err ( "Couldn't register clock source.\n" );
191+ dev_err ( & pdev -> dev , "Couldn't register clock source.\n" );
194192 return ret ;
195193 }
196194
197195 return 0 ;
198196}
199197
200- static int __init sun5i_setup_clockevent (struct device_node * node ,
201- struct sun5i_timer * ce ,
202- unsigned long rate , int irq )
198+ static int sun5i_setup_clockevent (struct platform_device * pdev ,
199+ unsigned long rate , int irq )
203200{
201+ struct device * dev = & pdev -> dev ;
202+ struct sun5i_timer * ce = platform_get_drvdata (pdev );
204203 void __iomem * base = ce -> base ;
205204 int ret ;
206205 u32 val ;
207206
208- ce -> clkevt .name = node -> name ;
207+ ce -> clkevt .name = dev -> of_node -> name ;
209208 ce -> clkevt .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT ;
210209 ce -> clkevt .set_next_event = sun5i_clkevt_next_event ;
211210 ce -> clkevt .set_state_shutdown = sun5i_clkevt_shutdown ;
@@ -223,58 +222,55 @@ static int __init sun5i_setup_clockevent(struct device_node *node,
223222 clockevents_config_and_register (& ce -> clkevt , rate ,
224223 TIMER_SYNC_TICKS , 0xffffffff );
225224
226- ret = request_irq (irq , sun5i_timer_interrupt , IRQF_TIMER | IRQF_IRQPOLL ,
227- "sun5i_timer0" , ce );
225+ ret = devm_request_irq (dev , irq , sun5i_timer_interrupt ,
226+ IRQF_TIMER | IRQF_IRQPOLL ,
227+ "sun5i_timer0" , ce );
228228 if (ret ) {
229- pr_err ( "Unable to register interrupt\n" );
229+ dev_err ( dev , "Unable to register interrupt\n" );
230230 return ret ;
231231 }
232232
233233 return 0 ;
234234}
235235
236- static int __init sun5i_timer_init (struct device_node * node )
236+ static int sun5i_timer_probe (struct platform_device * pdev )
237237{
238+ struct device * dev = & pdev -> dev ;
238239 struct sun5i_timer * st ;
239240 struct reset_control * rstc ;
240241 void __iomem * timer_base ;
241242 struct clk * clk ;
242243 unsigned long rate ;
243244 int irq , ret ;
244245
245- st = kzalloc ( sizeof (* st ), GFP_KERNEL );
246+ st = devm_kzalloc ( dev , sizeof (* st ), GFP_KERNEL );
246247 if (!st )
247248 return - ENOMEM ;
248249
249- timer_base = of_io_request_and_map (node , 0 , of_node_full_name (node ));
250+ platform_set_drvdata (pdev , st );
251+
252+ timer_base = devm_platform_ioremap_resource (pdev , 0 );
250253 if (IS_ERR (timer_base )) {
251- pr_err ( "Can't map registers\n" );
254+ dev_err ( dev , "Can't map registers\n" );
252255 return PTR_ERR (timer_base );
253256 }
254257
255- irq = irq_of_parse_and_map ( node , 0 );
256- if (irq <= 0 ) {
257- pr_err ( "Can't parse IRQ\n" );
258- return - EINVAL ;
258+ irq = platform_get_irq ( pdev , 0 );
259+ if (irq < 0 ) {
260+ dev_err ( dev , "Can't get IRQ\n" );
261+ return irq ;
259262 }
260263
261- clk = of_clk_get ( node , 0 );
264+ clk = devm_clk_get_enabled ( dev , NULL );
262265 if (IS_ERR (clk )) {
263- pr_err ( "Can't get timer clock\n" );
266+ dev_err ( dev , "Can't get timer clock\n" );
264267 return PTR_ERR (clk );
265268 }
266269
267- ret = clk_prepare_enable (clk );
268- if (ret ) {
269- pr_err ("Couldn't enable parent clock\n" );
270- goto err_free ;
271- }
272-
273270 rate = clk_get_rate (clk );
274271 if (!rate ) {
275- pr_err ("Couldn't get parent clock rate\n" );
276- ret = - EINVAL ;
277- goto err_disable_clk ;
272+ dev_err (dev , "Couldn't get parent clock rate\n" );
273+ return - EINVAL ;
278274 }
279275
280276 st -> base = timer_base ;
@@ -283,31 +279,52 @@ static int __init sun5i_timer_init(struct device_node *node)
283279 st -> clk_rate_cb .notifier_call = sun5i_rate_cb ;
284280 st -> clk_rate_cb .next = NULL ;
285281
286- ret = clk_notifier_register ( clk , & st -> clk_rate_cb );
282+ ret = devm_clk_notifier_register ( dev , clk , & st -> clk_rate_cb );
287283 if (ret ) {
288- pr_err ( "Unable to register clock notifier.\n" );
289- goto err_disable_clk ;
284+ dev_err ( dev , "Unable to register clock notifier.\n" );
285+ return ret ;
290286 }
291287
292- rstc = of_reset_control_get ( node , NULL );
293- if (! IS_ERR ( rstc ) )
288+ rstc = devm_reset_control_get_optional_exclusive ( dev , NULL );
289+ if (rstc )
294290 reset_control_deassert (rstc );
295291
296- ret = sun5i_setup_clocksource (node , st , rate );
292+ ret = sun5i_setup_clocksource (pdev , rate );
293+ if (ret )
294+ return ret ;
295+
296+ ret = sun5i_setup_clockevent (pdev , rate , irq );
297297 if (ret )
298- goto err_remove_notifier ;
298+ goto err_unreg_clocksource ;
299299
300- return sun5i_setup_clockevent ( node , st , rate , irq ) ;
300+ return 0 ;
301301
302- err_remove_notifier :
303- clk_notifier_unregister (clk , & st -> clk_rate_cb );
304- err_disable_clk :
305- clk_disable_unprepare (clk );
306- err_free :
307- kfree (st );
302+ err_unreg_clocksource :
303+ clocksource_unregister (& st -> clksrc );
308304 return ret ;
309305}
310- TIMER_OF_DECLARE (sun5i_a13 , "allwinner,sun5i-a13-hstimer" ,
311- sun5i_timer_init );
312- TIMER_OF_DECLARE (sun7i_a20 , "allwinner,sun7i-a20-hstimer" ,
313- sun5i_timer_init );
306+
307+ static void sun5i_timer_remove (struct platform_device * pdev )
308+ {
309+ struct sun5i_timer * st = platform_get_drvdata (pdev );
310+
311+ clocksource_unregister (& st -> clksrc );
312+ }
313+
314+ static const struct of_device_id sun5i_timer_of_match [] = {
315+ { .compatible = "allwinner,sun5i-a13-hstimer" },
316+ { .compatible = "allwinner,sun7i-a20-hstimer" },
317+ {},
318+ };
319+ MODULE_DEVICE_TABLE (of , sun5i_timer_of_match );
320+
321+ static struct platform_driver sun5i_timer_driver = {
322+ .probe = sun5i_timer_probe ,
323+ .remove_new = sun5i_timer_remove ,
324+ .driver = {
325+ .name = "sun5i-timer" ,
326+ .of_match_table = sun5i_timer_of_match ,
327+ .suppress_bind_attrs = true,
328+ },
329+ };
330+ module_platform_driver (sun5i_timer_driver );
0 commit comments