hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/arch/mips/kernel/cevt-r4k.c
....@@ -8,6 +8,7 @@
88 */
99 #include <linux/clockchips.h>
1010 #include <linux/interrupt.h>
11
+#include <linux/cpufreq.h>
1112 #include <linux/percpu.h>
1213 #include <linux/smp.h>
1314 #include <linux/irq.h>
....@@ -250,8 +251,52 @@
250251 return MIPS_CPU_IRQ_BASE + cp0_compare_irq;
251252 }
252253
254
+#ifdef CONFIG_CPU_FREQ
255
+
256
+static unsigned long mips_ref_freq;
257
+
258
+static int r4k_cpufreq_callback(struct notifier_block *nb,
259
+ unsigned long val, void *data)
260
+{
261
+ struct cpufreq_freqs *freq = data;
262
+ struct clock_event_device *cd;
263
+ unsigned long rate;
264
+ int cpu;
265
+
266
+ if (!mips_ref_freq)
267
+ mips_ref_freq = freq->old;
268
+
269
+ if (val == CPUFREQ_POSTCHANGE) {
270
+ rate = cpufreq_scale(mips_hpt_frequency, mips_ref_freq,
271
+ freq->new);
272
+
273
+ for_each_cpu(cpu, freq->policy->cpus) {
274
+ cd = &per_cpu(mips_clockevent_device, cpu);
275
+
276
+ clockevents_update_freq(cd, rate);
277
+ }
278
+ }
279
+
280
+ return 0;
281
+}
282
+
283
+static struct notifier_block r4k_cpufreq_notifier = {
284
+ .notifier_call = r4k_cpufreq_callback,
285
+};
286
+
287
+static int __init r4k_register_cpufreq_notifier(void)
288
+{
289
+ return cpufreq_register_notifier(&r4k_cpufreq_notifier,
290
+ CPUFREQ_TRANSITION_NOTIFIER);
291
+
292
+}
293
+core_initcall(r4k_register_cpufreq_notifier);
294
+
295
+#endif /* !CONFIG_CPU_FREQ */
296
+
253297 int r4k_clockevent_init(void)
254298 {
299
+ unsigned long flags = IRQF_PERCPU | IRQF_TIMER | IRQF_SHARED;
255300 unsigned int cpu = smp_processor_id();
256301 struct clock_event_device *cd;
257302 unsigned int irq, min_delta;
....@@ -291,7 +336,9 @@
291336
292337 cp0_timer_irq_installed = 1;
293338
294
- setup_irq(irq, &c0_compare_irqaction);
339
+ if (request_irq(irq, c0_compare_interrupt, flags, "timer",
340
+ c0_compare_interrupt))
341
+ pr_err("Failed to request irq %d (timer)\n", irq);
295342
296343 return 0;
297344 }