Commit 38586428 authored by Serge Semin's avatar Serge Semin Committed by Thomas Bogendoerfer

mips: csrc-r4k: Mark R4K timer as unstable if CPU freq changes

Commit 07d69579 ("MIPS: Don't register r4k sched clock when CPUFREQ
enabled") disabled the r4k-clock usage for scheduler ticks counting due
to the scheduler being non-tolerant for unstable clocks sources. For the
same reason the clock should be used in the system clocksource framework
with care. As soon as CPU frequency changes the clocksource framework
should be notified about this by marking the R4K timer being unstable
(which it really is, since the ticks rate has been changed synchronously
with the CPU frequency).
Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Paul Burton <paulburton@kernel.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: devicetree@vger.kernel.org
Signed-off-by: default avatarThomas Bogendoerfer <tsbogend@alpha.franken.de>
parent ed26aacf
...@@ -1108,6 +1108,7 @@ config CSRC_IOASIC ...@@ -1108,6 +1108,7 @@ config CSRC_IOASIC
bool bool
config CSRC_R4K config CSRC_R4K
select CLOCKSOURCE_WATCHDOG if CPU_FREQ
bool bool
config CSRC_SB1250 config CSRC_SB1250
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
* Copyright (C) 2007 by Ralf Baechle * Copyright (C) 2007 by Ralf Baechle
*/ */
#include <linux/clocksource.h> #include <linux/clocksource.h>
#include <linux/cpufreq.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/sched_clock.h> #include <linux/sched_clock.h>
...@@ -65,6 +66,45 @@ static bool rdhwr_count_usable(void) ...@@ -65,6 +66,45 @@ static bool rdhwr_count_usable(void)
return false; return false;
} }
#ifdef CONFIG_CPU_FREQ
static bool __read_mostly r4k_clock_unstable;
static void r4k_clocksource_unstable(char *reason)
{
if (r4k_clock_unstable)
return;
r4k_clock_unstable = true;
pr_info("R4K timer is unstable due to %s\n", reason);
clocksource_mark_unstable(&clocksource_mips);
}
static int r4k_cpufreq_callback(struct notifier_block *nb,
unsigned long val, void *data)
{
if (val == CPUFREQ_POSTCHANGE)
r4k_clocksource_unstable("CPU frequency change");
return 0;
}
static struct notifier_block r4k_cpufreq_notifier = {
.notifier_call = r4k_cpufreq_callback,
};
static int __init r4k_register_cpufreq_notifier(void)
{
return cpufreq_register_notifier(&r4k_cpufreq_notifier,
CPUFREQ_TRANSITION_NOTIFIER);
}
core_initcall(r4k_register_cpufreq_notifier);
#endif /* !CONFIG_CPU_FREQ */
int __init init_r4k_clocksource(void) int __init init_r4k_clocksource(void)
{ {
if (!cpu_has_counter || !mips_hpt_frequency) if (!cpu_has_counter || !mips_hpt_frequency)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment