aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Belloni <alexandre.belloni@bootlin.com>2019-04-26 17:47:12 -0400
committerDaniel Lezcano <daniel.lezcano@linaro.org>2019-05-02 15:55:58 -0400
commitf712a1e8e59e8f42b5a9ec3887a4ad079bb18175 (patch)
treeaa753707d19573143e78a9104fdefbda19c8ea4e
parent86232bfd28d71db4a50562cf81ff88ef58a6d401 (diff)
clocksource/drivers/tcb_clksrc: Use tcb as sched_clock
Now that the driver is registered early enough, use the TCB as the sched_clock which is much more accurate than the jiffies implementation. Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-rw-r--r--drivers/clocksource/tcb_clksrc.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c
index bf68504da94a..9de8c10ab546 100644
--- a/drivers/clocksource/tcb_clksrc.c
+++ b/drivers/clocksource/tcb_clksrc.c
@@ -11,6 +11,7 @@
11#include <linux/io.h> 11#include <linux/io.h>
12#include <linux/of_address.h> 12#include <linux/of_address.h>
13#include <linux/of_irq.h> 13#include <linux/of_irq.h>
14#include <linux/sched_clock.h>
14#include <linux/syscore_ops.h> 15#include <linux/syscore_ops.h>
15#include <soc/at91/atmel_tcb.h> 16#include <soc/at91/atmel_tcb.h>
16 17
@@ -114,6 +115,16 @@ static struct clocksource clksrc = {
114 .resume = tc_clksrc_resume, 115 .resume = tc_clksrc_resume,
115}; 116};
116 117
118static u64 notrace tc_sched_clock_read(void)
119{
120 return tc_get_cycles(&clksrc);
121}
122
123static u64 notrace tc_sched_clock_read32(void)
124{
125 return tc_get_cycles32(&clksrc);
126}
127
117#ifdef CONFIG_GENERIC_CLOCKEVENTS 128#ifdef CONFIG_GENERIC_CLOCKEVENTS
118 129
119struct tc_clkevt_device { 130struct tc_clkevt_device {
@@ -335,6 +346,7 @@ static int __init tcb_clksrc_init(struct device_node *node)
335 struct atmel_tc tc; 346 struct atmel_tc tc;
336 struct clk *t0_clk; 347 struct clk *t0_clk;
337 const struct of_device_id *match; 348 const struct of_device_id *match;
349 u64 (*tc_sched_clock)(void);
338 u32 rate, divided_rate = 0; 350 u32 rate, divided_rate = 0;
339 int best_divisor_idx = -1; 351 int best_divisor_idx = -1;
340 int clk32k_divisor_idx = -1; 352 int clk32k_divisor_idx = -1;
@@ -419,6 +431,7 @@ static int __init tcb_clksrc_init(struct device_node *node)
419 clksrc.read = tc_get_cycles32; 431 clksrc.read = tc_get_cycles32;
420 /* setup ony channel 0 */ 432 /* setup ony channel 0 */
421 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;
422 } else { 435 } else {
423 /* we have three clocks no matter what the 436 /* we have three clocks no matter what the
424 * underlying platform supports. 437 * underlying platform supports.
@@ -430,6 +443,7 @@ static int __init tcb_clksrc_init(struct device_node *node)
430 } 443 }
431 /* setup both channel 0 & 1 */ 444 /* setup both channel 0 & 1 */
432 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;
433 } 447 }
434 448
435 /* and away we go! */ 449 /* and away we go! */
@@ -442,6 +456,8 @@ static int __init tcb_clksrc_init(struct device_node *node)
442 if (ret) 456 if (ret)
443 goto err_unregister_clksrc; 457 goto err_unregister_clksrc;
444 458
459 sched_clock_register(tc_sched_clock, 32, divided_rate);
460
445 return 0; 461 return 0;
446 462
447err_unregister_clksrc: 463err_unregister_clksrc: