aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Medhurst <tixy@linaro.org>2012-07-09 11:27:22 +0100
committerJon Medhurst <tixy@linaro.org>2012-07-17 10:00:49 +0100
commitfbc200f27568cb1fede7c7524f60221c1fd4c241 (patch)
tree514047ca92f9b7d86d992f826f3f59967c2cd69c
parent62bdd1751892deeaaf38a0dff1cf03428b3e06ab (diff)
ARM: vexpress: TC2 use sp804 timer as sched_clock
Use SP804 timer as sched_clock instead of arch timers as work-around until the arch timers have been fixed. Inspired by patch from Morten Rasmussen <Morten.Rasmussen@arm.com> with the same description but made configurable by a device tree hack, to enable a single kernel binary to be used with multiple CoreTiles. Signed-off-by: Jon Medhurst <tixy@linaro.org>
-rw-r--r--arch/arm/boot/dts/vexpress-v2p-ca15-tc2.dts1
-rw-r--r--arch/arm/include/asm/arch_timer.h5
-rw-r--r--arch/arm/kernel/arch_timer.c10
-rw-r--r--arch/arm/mach-vexpress/v2m.c15
4 files changed, 26 insertions, 5 deletions
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15-tc2.dts b/arch/arm/boot/dts/vexpress-v2p-ca15-tc2.dts
index 2d94277251b..958e8f710c1 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca15-tc2.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15-tc2.dts
@@ -211,6 +211,7 @@
<1 14 0xf08>,
<1 11 0xf08>,
<1 10 0xf08>;
+ broken-for-sched-clock = <1>;
};
pmu {
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
index ed2e95d46e2..b02eba0fe82 100644
--- a/arch/arm/include/asm/arch_timer.h
+++ b/arch/arm/include/asm/arch_timer.h
@@ -4,6 +4,7 @@
#ifdef CONFIG_ARM_ARCH_TIMER
int arch_timer_of_register(void);
int arch_timer_sched_clock_init(void);
+bool arch_timer_broken_for_sched_clock(void);
#else
static inline int arch_timer_of_register(void)
{
@@ -14,6 +15,10 @@ static inline int arch_timer_sched_clock_init(void)
{
return -ENXIO;
}
+static inline bool arch_timer_broken_for_sched_clock(void)
+{
+ return false;
+}
#endif
#endif
diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c
index dd58035621f..0925c702b0e 100644
--- a/arch/arm/kernel/arch_timer.c
+++ b/arch/arm/kernel/arch_timer.c
@@ -314,6 +314,16 @@ static const struct of_device_id arch_timer_of_match[] __initconst = {
{},
};
+bool __init arch_timer_broken_for_sched_clock(void)
+{
+ u32 broken = false;
+ struct device_node *np;
+ np = of_find_matching_node(NULL, arch_timer_of_match);
+ if (np)
+ of_property_read_u32(np, "broken-for-sched-clock", &broken);
+ return broken;
+}
+
int __init arch_timer_of_register(void)
{
struct device_node *np;
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index fde26adaef3..d2dfa02cefe 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -69,7 +69,8 @@ static void __init v2m_sysctl_init(void __iomem *base)
writel(scctrl, base + SCCTRL);
}
-static void __init v2m_sp804_init(void __iomem *base, unsigned int irq)
+static void __init v2m_sp804_init(void __iomem *base, unsigned int irq,
+ int use_sched_clock)
{
if (WARN_ON(!base || irq == NO_IRQ))
return;
@@ -77,14 +78,17 @@ static void __init v2m_sp804_init(void __iomem *base, unsigned int irq)
writel(0, base + TIMER_1_BASE + TIMER_CTRL);
writel(0, base + TIMER_2_BASE + TIMER_CTRL);
- sp804_clocksource_init(base + TIMER_2_BASE, "v2m-timer1");
+ if (use_sched_clock)
+ sp804_clocksource_and_sched_clock_init(base + TIMER_2_BASE, "v2m-timer1");
+ else
+ sp804_clocksource_init(base + TIMER_2_BASE, "v2m-timer1");
sp804_clockevents_init(base + TIMER_1_BASE, irq, "v2m-timer0");
}
static void __init v2m_timer_init(void)
{
v2m_sysctl_init(ioremap(V2M_SYSCTL, SZ_4K));
- v2m_sp804_init(ioremap(V2M_TIMER01, SZ_4K), IRQ_V2M_TIMER0);
+ v2m_sp804_init(ioremap(V2M_TIMER01, SZ_4K), IRQ_V2M_TIMER0, 0);
}
static struct sys_timer v2m_timer = {
@@ -630,6 +634,7 @@ static void __init v2m_dt_init_irq(void)
static void __init v2m_dt_timer_init(void)
{
+ int sp804_sched_clock = arch_timer_broken_for_sched_clock();
struct device_node *node;
const char *path;
int err;
@@ -641,11 +646,11 @@ static void __init v2m_dt_timer_init(void)
if (WARN_ON(err))
return;
node = of_find_node_by_path(path);
- v2m_sp804_init(of_iomap(node, 0), irq_of_parse_and_map(node, 0));
+ v2m_sp804_init(of_iomap(node, 0), irq_of_parse_and_map(node, 0), sp804_sched_clock);
if (arch_timer_of_register() != 0)
twd_local_timer_of_register();
- if (arch_timer_sched_clock_init() != 0)
+ if (!sp804_sched_clock && arch_timer_sched_clock_init() != 0)
versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000);
}