1 // SPDX-License-Identifier: GPL-2.0+
3 * This file contains the jiffies based clocksource.
5 * Copyright (C) 2004, 2005 IBM, John Stultz (johnstul@us.ibm.com)
7 #include <linux/clocksource.h>
8 #include <linux/jiffies.h>
9 #include <linux/module.h>
10 #include <linux/init.h>
12 #include "timekeeping.h"
15 /* Since jiffies uses a simple TICK_NSEC multiplier
16 * conversion, the .shift value could be zero. However
17 * this would make NTP adjustments impossible as they are
18 * in units of 1/2^.shift. Thus we use JIFFIES_SHIFT to
19 * shift both the nominator and denominator the same
20 * amount, and give ntp adjustments in units of 1/2^8
22 * The value 8 is somewhat carefully chosen, as anything
23 * larger can result in overflows. TICK_NSEC grows as HZ
24 * shrinks, so values greater than 8 overflow 32bits when
28 #define JIFFIES_SHIFT 6
30 #define JIFFIES_SHIFT 7
32 #define JIFFIES_SHIFT 8
35 static u64
jiffies_read(struct clocksource
*cs
)
41 * The Jiffies based clocksource is the lowest common
42 * denominator clock source which should function on
43 * all systems. It has the same coarse resolution as
44 * the timer interrupt frequency HZ and it suffers
45 * inaccuracies caused by missed or lost timer
46 * interrupts and the inability for the timer
47 * interrupt hardware to accuratly tick at the
48 * requested HZ value. It is also not recommended
49 * for "tick-less" systems.
51 static struct clocksource clocksource_jiffies
= {
53 .rating
= 1, /* lowest valid rating*/
55 .mask
= CLOCKSOURCE_MASK(32),
56 .mult
= TICK_NSEC
<< JIFFIES_SHIFT
, /* details above */
57 .shift
= JIFFIES_SHIFT
,
61 __cacheline_aligned_in_smp
DEFINE_RAW_SPINLOCK(jiffies_lock
);
62 __cacheline_aligned_in_smp seqcount_t jiffies_seq
;
64 #if (BITS_PER_LONG < 64)
65 u64
get_jiffies_64(void)
71 seq
= read_seqcount_begin(&jiffies_seq
);
73 } while (read_seqcount_retry(&jiffies_seq
, seq
));
76 EXPORT_SYMBOL(get_jiffies_64
);
79 EXPORT_SYMBOL(jiffies
);
81 static int __init
init_jiffies_clocksource(void)
83 return __clocksource_register(&clocksource_jiffies
);
86 core_initcall(init_jiffies_clocksource
);
88 struct clocksource
* __init __weak
clocksource_default_clock(void)
90 return &clocksource_jiffies
;
93 static struct clocksource refined_jiffies
;
95 int register_refined_jiffies(long cycles_per_second
)
97 u64 nsec_per_tick
, shift_hz
;
102 refined_jiffies
= clocksource_jiffies
;
103 refined_jiffies
.name
= "refined-jiffies";
104 refined_jiffies
.rating
++;
106 /* Calc cycles per tick */
107 cycles_per_tick
= (cycles_per_second
+ HZ
/2)/HZ
;
108 /* shift_hz stores hz<<8 for extra accuracy */
109 shift_hz
= (u64
)cycles_per_second
<< 8;
110 shift_hz
+= cycles_per_tick
/2;
111 do_div(shift_hz
, cycles_per_tick
);
112 /* Calculate nsec_per_tick using shift_hz */
113 nsec_per_tick
= (u64
)NSEC_PER_SEC
<< 8;
114 nsec_per_tick
+= (u32
)shift_hz
/2;
115 do_div(nsec_per_tick
, (u32
)shift_hz
);
117 refined_jiffies
.mult
= ((u32
)nsec_per_tick
) << JIFFIES_SHIFT
;
119 __clocksource_register(&refined_jiffies
);