Commit d8e332d4 authored by David Woodhouse's avatar David Woodhouse Committed by Ben Hutchings

x86/platform: Fix Geode LX timekeeping in the generic x86 build

commit 03da3ff1 upstream.

In 2007, commit 07190a08 ("Mark TSC on GeodeLX reliable")
bypassed verification of the TSC on Geode LX. However, this code
(now in the check_system_tsc_reliable() function in
arch/x86/kernel/tsc.c) was only present if CONFIG_MGEODE_LX was
set.

OpenWRT has recently started building its generic Geode target
for Geode GX, not LX, to include support for additional
platforms. This broke the timekeeping on LX-based devices,
because the TSC wasn't marked as reliable:
https://dev.openwrt.org/ticket/20531

By adding a runtime check on is_geode_lx(), we can also include
the fix if CONFIG_MGEODEGX1 or CONFIG_X86_GENERIC are set, thus
fixing the problem.
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
Cc: Andres Salomon <dilinger@queued.net>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Marcelo Tosatti <marcelo@kvack.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1442409003.131189.87.camel@infradead.orgSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
parent 7aa36cdf
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <asm/hypervisor.h> #include <asm/hypervisor.h>
#include <asm/nmi.h> #include <asm/nmi.h>
#include <asm/x86_init.h> #include <asm/x86_init.h>
#include <asm/geode.h>
unsigned int __read_mostly cpu_khz; /* TSC clocks / usec, not used here */ unsigned int __read_mostly cpu_khz; /* TSC clocks / usec, not used here */
EXPORT_SYMBOL(cpu_khz); EXPORT_SYMBOL(cpu_khz);
...@@ -802,15 +803,17 @@ EXPORT_SYMBOL_GPL(mark_tsc_unstable); ...@@ -802,15 +803,17 @@ EXPORT_SYMBOL_GPL(mark_tsc_unstable);
static void __init check_system_tsc_reliable(void) static void __init check_system_tsc_reliable(void)
{ {
#ifdef CONFIG_MGEODE_LX #if defined(CONFIG_MGEODEGX1) || defined(CONFIG_MGEODE_LX) || defined(CONFIG_X86_GENERIC)
/* RTSC counts during suspend */ if (is_geode_lx()) {
/* RTSC counts during suspend */
#define RTSC_SUSP 0x100 #define RTSC_SUSP 0x100
unsigned long res_low, res_high; unsigned long res_low, res_high;
rdmsr_safe(MSR_GEODE_BUSCONT_CONF0, &res_low, &res_high); rdmsr_safe(MSR_GEODE_BUSCONT_CONF0, &res_low, &res_high);
/* Geode_LX - the OLPC CPU has a very reliable TSC */ /* Geode_LX - the OLPC CPU has a very reliable TSC */
if (res_low & RTSC_SUSP) if (res_low & RTSC_SUSP)
tsc_clocksource_reliable = 1; tsc_clocksource_reliable = 1;
}
#endif #endif
if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE))
tsc_clocksource_reliable = 1; tsc_clocksource_reliable = 1;
......
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