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"
13 #include "tick-internal.h"
16 static u64
jiffies_read(struct clocksource
*cs
)
22 * The Jiffies based clocksource is the lowest common
23 * denominator clock source which should function on
24 * all systems. It has the same coarse resolution as
25 * the timer interrupt frequency HZ and it suffers
26 * inaccuracies caused by missed or lost timer
27 * interrupts and the inability for the timer
28 * interrupt hardware to accurately tick at the
29 * requested HZ value. It is also not recommended
30 * for "tick-less" systems.
32 static struct clocksource clocksource_jiffies
= {
34 .rating
= 1, /* lowest valid rating*/
35 .uncertainty_margin
= 32 * NSEC_PER_MSEC
,
37 .mask
= CLOCKSOURCE_MASK(32),
38 .mult
= TICK_NSEC
<< JIFFIES_SHIFT
, /* details above */
39 .shift
= JIFFIES_SHIFT
,
43 __cacheline_aligned_in_smp
DEFINE_RAW_SPINLOCK(jiffies_lock
);
44 __cacheline_aligned_in_smp seqcount_raw_spinlock_t jiffies_seq
=
45 SEQCNT_RAW_SPINLOCK_ZERO(jiffies_seq
, &jiffies_lock
);
47 #if (BITS_PER_LONG < 64)
48 u64
get_jiffies_64(void)
54 seq
= read_seqcount_begin(&jiffies_seq
);
56 } while (read_seqcount_retry(&jiffies_seq
, seq
));
59 EXPORT_SYMBOL(get_jiffies_64
);
62 EXPORT_SYMBOL(jiffies
);
64 static int __init
init_jiffies_clocksource(void)
66 return __clocksource_register(&clocksource_jiffies
);
69 core_initcall(init_jiffies_clocksource
);
71 struct clocksource
* __init __weak
clocksource_default_clock(void)
73 return &clocksource_jiffies
;
76 static struct clocksource refined_jiffies
;
78 int register_refined_jiffies(long cycles_per_second
)
80 u64 nsec_per_tick
, shift_hz
;
85 refined_jiffies
= clocksource_jiffies
;
86 refined_jiffies
.name
= "refined-jiffies";
87 refined_jiffies
.rating
++;
89 /* Calc cycles per tick */
90 cycles_per_tick
= (cycles_per_second
+ HZ
/2)/HZ
;
91 /* shift_hz stores hz<<8 for extra accuracy */
92 shift_hz
= (u64
)cycles_per_second
<< 8;
93 shift_hz
+= cycles_per_tick
/2;
94 do_div(shift_hz
, cycles_per_tick
);
95 /* Calculate nsec_per_tick using shift_hz */
96 nsec_per_tick
= (u64
)NSEC_PER_SEC
<< 8;
97 nsec_per_tick
+= (u32
)shift_hz
/2;
98 do_div(nsec_per_tick
, (u32
)shift_hz
);
100 refined_jiffies
.mult
= ((u32
)nsec_per_tick
) << JIFFIES_SHIFT
;
102 __clocksource_register(&refined_jiffies
);