clocksource/drivers/tcb_clksrc: Use tcb as sched_clock
authorAlexandre Belloni <alexandre.belloni@bootlin.com>
Fri, 26 Apr 2019 21:47:12 +0000 (23:47 +0200)
committerDaniel Lezcano <daniel.lezcano@linaro.org>
Thu, 2 May 2019 19:55:58 +0000 (21:55 +0200)
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>
drivers/clocksource/tcb_clksrc.c

index bf68504..9de8c10 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/io.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/sched_clock.h>
 #include <linux/syscore_ops.h>
 #include <soc/at91/atmel_tcb.h>
 
@@ -114,6 +115,16 @@ static struct clocksource clksrc = {
        .resume         = tc_clksrc_resume,
 };
 
+static u64 notrace tc_sched_clock_read(void)
+{
+       return tc_get_cycles(&clksrc);
+}
+
+static u64 notrace tc_sched_clock_read32(void)
+{
+       return tc_get_cycles32(&clksrc);
+}
+
 #ifdef CONFIG_GENERIC_CLOCKEVENTS
 
 struct tc_clkevt_device {
@@ -335,6 +346,7 @@ static int __init tcb_clksrc_init(struct device_node *node)
        struct atmel_tc tc;
        struct clk *t0_clk;
        const struct of_device_id *match;
+       u64 (*tc_sched_clock)(void);
        u32 rate, divided_rate = 0;
        int best_divisor_idx = -1;
        int clk32k_divisor_idx = -1;
@@ -419,6 +431,7 @@ static int __init tcb_clksrc_init(struct device_node *node)
                clksrc.read = tc_get_cycles32;
                /* setup ony channel 0 */
                tcb_setup_single_chan(&tc, best_divisor_idx);
+               tc_sched_clock = tc_sched_clock_read32;
        } else {
                /* we have three clocks no matter what the
                 * underlying platform supports.
@@ -430,6 +443,7 @@ static int __init tcb_clksrc_init(struct device_node *node)
                }
                /* setup both channel 0 & 1 */
                tcb_setup_dual_chan(&tc, best_divisor_idx);
+               tc_sched_clock = tc_sched_clock_read;
        }
 
        /* and away we go! */
@@ -442,6 +456,8 @@ static int __init tcb_clksrc_init(struct device_node *node)
        if (ret)
                goto err_unregister_clksrc;
 
+       sched_clock_register(tc_sched_clock, 32, divided_rate);
+
        return 0;
 
 err_unregister_clksrc: