Skip to content

Commit 48016e7

Browse files
paulburtondlezcano
authored andcommitted
clocksource: mips-gic-timer: Register as sched_clock
The MIPS GIC timer is well suited for use as sched_clock, so register it as such. Whilst the existing gic_read_count() function matches the prototype needed by sched_clock_register() already, we split it into 2 functions in order to remove the need to evaluate the mips_cm_is64 condition within each call since sched_clock should be as fast as possible. Note the sched clock framework needs the clock source being stable in order to rely on it. So we register the MIPS GIC timer as schedule clocks only if it's, if either the system doesn't have CPU-frequency enabled or the CPU frequency is changed by means of the CPC core clock divider available on the platforms with CM3 or newer. Signed-off-by: Paul Burton <[email protected]> Co-developed-by: Serge Semin <[email protected]> [[email protected]: Register sched-clock if CM3 or !CPU-freq] Signed-off-by: Serge Semin <[email protected]> Cc: Alexey Malahov <[email protected]> Cc: Thomas Bogendoerfer <[email protected]> Cc: Ralf Baechle <[email protected]> Cc: Alessandro Zummo <[email protected]> Cc: Alexandre Belloni <[email protected]> Cc: Arnd Bergmann <[email protected]> Cc: Rob Herring <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Signed-off-by: Daniel Lezcano <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 6d2e16a commit 48016e7

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

drivers/clocksource/mips-gic-timer.c

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/notifier.h>
1717
#include <linux/of_irq.h>
1818
#include <linux/percpu.h>
19+
#include <linux/sched_clock.h>
1920
#include <linux/smp.h>
2021
#include <linux/time.h>
2122
#include <asm/mips-cps.h>
@@ -24,13 +25,10 @@ static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device);
2425
static int gic_timer_irq;
2526
static unsigned int gic_frequency;
2627

27-
static u64 notrace gic_read_count(void)
28+
static u64 notrace gic_read_count_2x32(void)
2829
{
2930
unsigned int hi, hi2, lo;
3031

31-
if (mips_cm_is64)
32-
return read_gic_counter();
33-
3432
do {
3533
hi = read_gic_counter_32h();
3634
lo = read_gic_counter_32l();
@@ -40,6 +38,19 @@ static u64 notrace gic_read_count(void)
4038
return (((u64) hi) << 32) + lo;
4139
}
4240

41+
static u64 notrace gic_read_count_64(void)
42+
{
43+
return read_gic_counter();
44+
}
45+
46+
static u64 notrace gic_read_count(void)
47+
{
48+
if (mips_cm_is64)
49+
return gic_read_count_64();
50+
51+
return gic_read_count_2x32();
52+
}
53+
4354
static int gic_next_event(unsigned long delta, struct clock_event_device *evt)
4455
{
4556
int cpu = cpumask_first(evt->cpumask);
@@ -228,6 +239,18 @@ static int __init gic_clocksource_of_init(struct device_node *node)
228239
/* And finally start the counter */
229240
clear_gic_config(GIC_CONFIG_COUNTSTOP);
230241

242+
/*
243+
* It's safe to use the MIPS GIC timer as a sched clock source only if
244+
* its ticks are stable, which is true on either the platforms with
245+
* stable CPU frequency or on the platforms with CM3 and CPU frequency
246+
* change performed by the CPC core clocks divider.
247+
*/
248+
if (mips_cm_revision() >= CM_REV_CM3 || !IS_ENABLED(CONFIG_CPU_FREQ)) {
249+
sched_clock_register(mips_cm_is64 ?
250+
gic_read_count_64 : gic_read_count_2x32,
251+
64, gic_frequency);
252+
}
253+
231254
return 0;
232255
}
233256
TIMER_OF_DECLARE(mips_gic_timer, "mti,gic-timer",

0 commit comments

Comments
 (0)