9
9
#include <linux/err.h>
10
10
#include <linux/ioport.h>
11
11
#include <linux/io.h>
12
- #include <linux/platform_device.h>
12
+ #include <linux/of_address.h>
13
+ #include <linux/of_irq.h>
14
+ #include <linux/sched_clock.h>
13
15
#include <linux/syscore_ops.h>
14
- #include <linux/atmel_tc .h>
16
+ #include <soc/at91/atmel_tcb .h>
15
17
16
18
17
19
/*
28
30
* source, used in either periodic or oneshot mode. This runs
29
31
* at 32 KiHZ, and can handle delays of up to two seconds.
30
32
*
31
- * A boot clocksource and clockevent source are also currently needed,
32
- * unless the relevant platforms (ARM/AT91, AVR32/AT32) are changed so
33
- * this code can be used when init_timers() is called, well before most
34
- * devices are set up. (Some low end AT91 parts, which can run uClinux,
35
- * have only the timers in one TC block... they currently don't support
36
- * the tclib code, because of that initialization issue.)
37
- *
38
33
* REVISIT behavior during system suspend states... we should disable
39
34
* all clocks and save the power. Easily done for clockevent devices,
40
35
* but clocksources won't necessarily get the needed notifications.
@@ -112,7 +107,6 @@ static void tc_clksrc_resume(struct clocksource *cs)
112
107
}
113
108
114
109
static struct clocksource clksrc = {
115
- .name = "tcb_clksrc" ,
116
110
.rating = 200 ,
117
111
.read = tc_get_cycles ,
118
112
.mask = CLOCKSOURCE_MASK (32 ),
@@ -121,6 +115,16 @@ static struct clocksource clksrc = {
121
115
.resume = tc_clksrc_resume ,
122
116
};
123
117
118
+ static u64 notrace tc_sched_clock_read (void )
119
+ {
120
+ return tc_get_cycles (& clksrc );
121
+ }
122
+
123
+ static u64 notrace tc_sched_clock_read32 (void )
124
+ {
125
+ return tc_get_cycles32 (& clksrc );
126
+ }
127
+
124
128
#ifdef CONFIG_GENERIC_CLOCKEVENTS
125
129
126
130
struct tc_clkevt_device {
@@ -214,7 +218,6 @@ static int tc_next_event(unsigned long delta, struct clock_event_device *d)
214
218
215
219
static struct tc_clkevt_device clkevt = {
216
220
.clkevt = {
217
- .name = "tc_clkevt" ,
218
221
.features = CLOCK_EVT_FEAT_PERIODIC |
219
222
CLOCK_EVT_FEAT_ONESHOT ,
220
223
/* Should be lower than at91rm9200's system timer */
@@ -330,39 +333,74 @@ static void __init tcb_setup_single_chan(struct atmel_tc *tc, int mck_divisor_id
330
333
writel (ATMEL_TC_SYNC , tcaddr + ATMEL_TC_BCR );
331
334
}
332
335
333
- static int __init tcb_clksrc_init (void )
334
- {
335
- static char bootinfo [] __initdata
336
- = KERN_DEBUG "%s: tc%d at %d.%03d MHz\n" ;
336
+ static const u8 atmel_tcb_divisors [5 ] = { 2 , 8 , 32 , 128 , 0 , };
337
+
338
+ static const struct of_device_id atmel_tcb_of_match [] = {
339
+ { .compatible = "atmel,at91rm9200-tcb" , .data = (void * )16 , },
340
+ { .compatible = "atmel,at91sam9x5-tcb" , .data = (void * )32 , },
341
+ { /* sentinel */ }
342
+ };
337
343
338
- struct platform_device * pdev ;
339
- struct atmel_tc * tc ;
344
+ static int __init tcb_clksrc_init (struct device_node * node )
345
+ {
346
+ struct atmel_tc tc ;
340
347
struct clk * t0_clk ;
348
+ const struct of_device_id * match ;
349
+ u64 (* tc_sched_clock )(void );
341
350
u32 rate , divided_rate = 0 ;
342
351
int best_divisor_idx = -1 ;
343
352
int clk32k_divisor_idx = -1 ;
353
+ int bits ;
344
354
int i ;
345
355
int ret ;
346
356
347
- tc = atmel_tc_alloc (CONFIG_ATMEL_TCB_CLKSRC_BLOCK );
348
- if (!tc ) {
349
- pr_debug ("can't alloc TC for clocksource\n" );
350
- return - ENODEV ;
357
+ /* Protect against multiple calls */
358
+ if (tcaddr )
359
+ return 0 ;
360
+
361
+ tc .regs = of_iomap (node -> parent , 0 );
362
+ if (!tc .regs )
363
+ return - ENXIO ;
364
+
365
+ t0_clk = of_clk_get_by_name (node -> parent , "t0_clk" );
366
+ if (IS_ERR (t0_clk ))
367
+ return PTR_ERR (t0_clk );
368
+
369
+ tc .slow_clk = of_clk_get_by_name (node -> parent , "slow_clk" );
370
+ if (IS_ERR (tc .slow_clk ))
371
+ return PTR_ERR (tc .slow_clk );
372
+
373
+ tc .clk [0 ] = t0_clk ;
374
+ tc .clk [1 ] = of_clk_get_by_name (node -> parent , "t1_clk" );
375
+ if (IS_ERR (tc .clk [1 ]))
376
+ tc .clk [1 ] = t0_clk ;
377
+ tc .clk [2 ] = of_clk_get_by_name (node -> parent , "t2_clk" );
378
+ if (IS_ERR (tc .clk [2 ]))
379
+ tc .clk [2 ] = t0_clk ;
380
+
381
+ tc .irq [2 ] = of_irq_get (node -> parent , 2 );
382
+ if (tc .irq [2 ] <= 0 ) {
383
+ tc .irq [2 ] = of_irq_get (node -> parent , 0 );
384
+ if (tc .irq [2 ] <= 0 )
385
+ return - EINVAL ;
351
386
}
352
- tcaddr = tc -> regs ;
353
- pdev = tc -> pdev ;
354
387
355
- t0_clk = tc -> clk [0 ];
388
+ match = of_match_node (atmel_tcb_of_match , node -> parent );
389
+ bits = (uintptr_t )match -> data ;
390
+
391
+ for (i = 0 ; i < ARRAY_SIZE (tc .irq ); i ++ )
392
+ writel (ATMEL_TC_ALL_IRQ , tc .regs + ATMEL_TC_REG (i , IDR ));
393
+
356
394
ret = clk_prepare_enable (t0_clk );
357
395
if (ret ) {
358
396
pr_debug ("can't enable T0 clk\n" );
359
- goto err_free_tc ;
397
+ return ret ;
360
398
}
361
399
362
400
/* How fast will we be counting? Pick something over 5 MHz. */
363
401
rate = (u32 ) clk_get_rate (t0_clk );
364
- for (i = 0 ; i < 5 ; i ++ ) {
365
- unsigned divisor = atmel_tc_divisors [i ];
402
+ for (i = 0 ; i < ARRAY_SIZE ( atmel_tcb_divisors ) ; i ++ ) {
403
+ unsigned divisor = atmel_tcb_divisors [i ];
366
404
unsigned tmp ;
367
405
368
406
/* remember 32 KiHz clock for later */
@@ -381,27 +419,31 @@ static int __init tcb_clksrc_init(void)
381
419
best_divisor_idx = i ;
382
420
}
383
421
384
-
385
- printk ( bootinfo , clksrc . name , CONFIG_ATMEL_TCB_CLKSRC_BLOCK ,
386
- divided_rate / 1000000 ,
422
+ clksrc . name = kbasename ( node -> parent -> full_name );
423
+ clkevt . clkevt . name = kbasename ( node -> parent -> full_name );
424
+ pr_debug ( "%s at %d.%03d MHz\n" , clksrc . name , divided_rate / 1000000 ,
387
425
((divided_rate % 1000000 ) + 500 ) / 1000 );
388
426
389
- if (tc -> tcb_config && tc -> tcb_config -> counter_width == 32 ) {
427
+ tcaddr = tc .regs ;
428
+
429
+ if (bits == 32 ) {
390
430
/* use apropriate function to read 32 bit counter */
391
431
clksrc .read = tc_get_cycles32 ;
392
432
/* setup ony channel 0 */
393
- tcb_setup_single_chan (tc , best_divisor_idx );
433
+ tcb_setup_single_chan (& tc , best_divisor_idx );
434
+ tc_sched_clock = tc_sched_clock_read32 ;
394
435
} else {
395
- /* tclib will give us three clocks no matter what the
436
+ /* we have three clocks no matter what the
396
437
* underlying platform supports.
397
438
*/
398
- ret = clk_prepare_enable (tc -> clk [1 ]);
439
+ ret = clk_prepare_enable (tc . clk [1 ]);
399
440
if (ret ) {
400
441
pr_debug ("can't enable T1 clk\n" );
401
442
goto err_disable_t0 ;
402
443
}
403
444
/* setup both channel 0 & 1 */
404
- tcb_setup_dual_chan (tc , best_divisor_idx );
445
+ tcb_setup_dual_chan (& tc , best_divisor_idx );
446
+ tc_sched_clock = tc_sched_clock_read ;
405
447
}
406
448
407
449
/* and away we go! */
@@ -410,24 +452,26 @@ static int __init tcb_clksrc_init(void)
410
452
goto err_disable_t1 ;
411
453
412
454
/* channel 2: periodic and oneshot timer support */
413
- ret = setup_clkevents (tc , clk32k_divisor_idx );
455
+ ret = setup_clkevents (& tc , clk32k_divisor_idx );
414
456
if (ret )
415
457
goto err_unregister_clksrc ;
416
458
459
+ sched_clock_register (tc_sched_clock , 32 , divided_rate );
460
+
417
461
return 0 ;
418
462
419
463
err_unregister_clksrc :
420
464
clocksource_unregister (& clksrc );
421
465
422
466
err_disable_t1 :
423
- if (! tc -> tcb_config || tc -> tcb_config -> counter_width != 32 )
424
- clk_disable_unprepare (tc -> clk [1 ]);
467
+ if (bits != 32 )
468
+ clk_disable_unprepare (tc . clk [1 ]);
425
469
426
470
err_disable_t0 :
427
471
clk_disable_unprepare (t0_clk );
428
472
429
- err_free_tc :
430
- atmel_tc_free ( tc );
473
+ tcaddr = NULL ;
474
+
431
475
return ret ;
432
476
}
433
- arch_initcall ( tcb_clksrc_init );
477
+ TIMER_OF_DECLARE ( atmel_tcb_clksrc , "atmel,tcb-timer" , tcb_clksrc_init );
0 commit comments