diff options
author | Jon Medhurst <tixy@linaro.org> | 2012-07-09 11:27:22 +0100 |
---|---|---|
committer | Jon Medhurst <tixy@linaro.org> | 2012-07-09 14:26:08 +0100 |
commit | 6e84acc531b9f6e999481f94876e9e06ffe189a4 (patch) | |
tree | 151b925853007d8e5dfecc4cd6dd1b051173fa61 | |
parent | 9233943b16b3e6996553e417fd39fddb4682493e (diff) |
ARM: vexpress: TC2 use sp804 timer as sched_clocktracking-tracking-armlt-tc2-ll-20120710.0
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.dts | 1 | ||||
-rw-r--r-- | arch/arm/kernel/arch_timer.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/v2m.c | 17 |
3 files changed, 23 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 eadd587d35c7..6c863d5d29da 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/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c index dd58035621f7..0925c702b0ef 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 fde26adaef32..ddf4cb388fa7 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 = { @@ -628,8 +632,11 @@ static void __init v2m_dt_init_irq(void) of_irq_init(vexpress_irq_match); } +extern bool __init arch_timer_broken_for_sched_clock(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 +648,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); } |