2 * sched_clock.c: support for extending counters to full 64-bit ns counter
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
8 #include <linux/clocksource.h>
9 #include <linux/init.h>
10 #include <linux/jiffies.h>
11 #include <linux/kernel.h>
12 #include <linux/sched.h>
13 #include <linux/timer.h>
15 #include <asm/sched_clock.h>
17 static void sched_clock_poll(unsigned long wrap_ticks
);
18 static DEFINE_TIMER(sched_clock_timer
, sched_clock_poll
, 0, 0);
19 static void (*sched_clock_update_fn
)(void);
21 static void sched_clock_poll(unsigned long wrap_ticks
)
23 mod_timer(&sched_clock_timer
, round_jiffies(jiffies
+ wrap_ticks
));
24 sched_clock_update_fn();
27 void __init
init_sched_clock(struct clock_data
*cd
, void (*update
)(void),
28 unsigned int clock_bits
, unsigned long rate
)
34 sched_clock_update_fn
= update
;
36 /* calculate the mult/shift to convert counter ticks to ns. */
37 clocks_calc_mult_shift(&cd
->mult
, &cd
->shift
, rate
, NSEC_PER_SEC
, 0);
48 /* calculate how many ns until we wrap */
49 wrap
= cyc_to_ns((1ULL << clock_bits
) - 1, cd
->mult
, cd
->shift
);
50 do_div(wrap
, NSEC_PER_MSEC
);
53 /* calculate the ns resolution of this counter */
54 res
= cyc_to_ns(1ULL, cd
->mult
, cd
->shift
);
55 pr_info("sched_clock: %u bits at %lu%cHz, resolution %lluns, wraps every %lums\n",
56 clock_bits
, r
, r_unit
, res
, w
);
59 * Start the timer to keep sched_clock() properly updated and
60 * sets the initial epoch.
62 sched_clock_timer
.data
= msecs_to_jiffies(w
- (w
/ 10));
66 * Ensure that sched_clock() starts off at 0ns
71 void __init
sched_clock_postinit(void)
73 sched_clock_poll(sched_clock_timer
.data
);