hc
2024-05-10 37f49e37ab4cb5d0bc4c60eb5c6d4dd57db767bb
kernel/drivers/clocksource/mips-gic-timer.c
....@@ -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>
....@@ -23,13 +24,13 @@
2324 static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device);
2425 static int gic_timer_irq;
2526 static unsigned int gic_frequency;
27
+static bool __read_mostly gic_clock_unstable;
2628
27
-static u64 notrace gic_read_count(void)
29
+static void gic_clocksource_unstable(char *reason);
30
+
31
+static u64 notrace gic_read_count_2x32(void)
2832 {
2933 unsigned int hi, hi2, lo;
30
-
31
- if (mips_cm_is64)
32
- return read_gic_counter();
3334
3435 do {
3536 hi = read_gic_counter_32h();
....@@ -38,6 +39,19 @@
3839 } while (hi2 != hi);
3940
4041 return (((u64) hi) << 32) + lo;
42
+}
43
+
44
+static u64 notrace gic_read_count_64(void)
45
+{
46
+ return read_gic_counter();
47
+}
48
+
49
+static u64 notrace gic_read_count(void)
50
+{
51
+ if (mips_cm_is64)
52
+ return gic_read_count_64();
53
+
54
+ return gic_read_count_2x32();
4155 }
4256
4357 static int gic_next_event(unsigned long delta, struct clock_event_device *evt)
....@@ -67,7 +81,7 @@
6781 return IRQ_HANDLED;
6882 }
6983
70
-struct irqaction gic_compare_irqaction = {
84
+static struct irqaction gic_compare_irqaction = {
7185 .handler = gic_compare_interrupt,
7286 .percpu_dev_id = &gic_clockevent_device,
7387 .flags = IRQF_PERCPU | IRQF_TIMER,
....@@ -114,8 +128,10 @@
114128 {
115129 struct clk_notifier_data *cnd = data;
116130
117
- if (action == POST_RATE_CHANGE)
131
+ if (action == POST_RATE_CHANGE) {
132
+ gic_clocksource_unstable("ref clock rate change");
118133 on_each_cpu(gic_update_frequency, (void *)cnd->new_rate, 1);
134
+ }
119135
120136 return NOTIFY_OK;
121137 }
....@@ -155,11 +171,23 @@
155171 }
156172
157173 static struct clocksource gic_clocksource = {
158
- .name = "GIC",
159
- .read = gic_hpt_read,
160
- .flags = CLOCK_SOURCE_IS_CONTINUOUS,
161
- .archdata = { .vdso_clock_mode = VDSO_CLOCK_GIC },
174
+ .name = "GIC",
175
+ .read = gic_hpt_read,
176
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
177
+ .vdso_clock_mode = VDSO_CLOCKMODE_GIC,
162178 };
179
+
180
+static void gic_clocksource_unstable(char *reason)
181
+{
182
+ if (gic_clock_unstable)
183
+ return;
184
+
185
+ gic_clock_unstable = true;
186
+
187
+ pr_info("GIC timer is unstable due to %s\n", reason);
188
+
189
+ clocksource_mark_unstable(&gic_clocksource);
190
+}
163191
164192 static int __init __gic_clocksource_init(void)
165193 {
....@@ -228,6 +256,18 @@
228256 /* And finally start the counter */
229257 clear_gic_config(GIC_CONFIG_COUNTSTOP);
230258
259
+ /*
260
+ * It's safe to use the MIPS GIC timer as a sched clock source only if
261
+ * its ticks are stable, which is true on either the platforms with
262
+ * stable CPU frequency or on the platforms with CM3 and CPU frequency
263
+ * change performed by the CPC core clocks divider.
264
+ */
265
+ if (mips_cm_revision() >= CM_REV_CM3 || !IS_ENABLED(CONFIG_CPU_FREQ)) {
266
+ sched_clock_register(mips_cm_is64 ?
267
+ gic_read_count_64 : gic_read_count_2x32,
268
+ 64, gic_frequency);
269
+ }
270
+
231271 return 0;
232272 }
233273 TIMER_OF_DECLARE(mips_gic_timer, "mti,gic-timer",