From mboxrd@z Thu Jan 1 00:00:00 1970 From: ola@adapteva.com (Ola Jeppsson) Date: Sun, 22 Mar 2015 23:55:53 +0100 Subject: [PATCH] arm: zynq: Fix system clock with multi_v7_defconfig Message-ID: <550F4879.3020207@adapteva.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org As mentioned in this commit: arm: zynq: Don't use arm_global_timer with cpufreq 61f1fc7e9258a169ac8afb5ddf657a181e60d052 arm_global_timer depends on the CPU frequency. With cpufreq altering the CPU frequency arm_global_timer will not maintain a stable time base. So arm_global_timer must not be the clocksource when cpufreq is enabled. The above commit tries to solve this at build time by only selecting CONFIG_ARM_GLOBAL_TIMER if CONFIG_CPU_FREQ is disabled. This is not always sufficient because other machs can also enable CONFIG_ARM_GLOBAL_TIMER. Therefore: If built with CONFIG_CPU_FREQ and CONFIG_ARM_GLOBAL_TIMER, disable (on Zynq) the arm_global_timer devicetree node at boot before clock sources are initialized. This ensures that arm_global_timer will not be selected clocksource. Signed-off-by: Ola Jeppsson --- arch/arm/mach-zynq/Makefile | 4 ++++ arch/arm/mach-zynq/common.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/arch/arm/mach-zynq/Makefile b/arch/arm/mach-zynq/Makefile index b03a97e..ec94b04 100644 --- a/arch/arm/mach-zynq/Makefile +++ b/arch/arm/mach-zynq/Makefile @@ -2,6 +2,10 @@ # Makefile for the linux kernel. # +ifeq ($(CONFIG_CPU_FREQ)-$(CONFIG_ARM_GLOBAL_TIMER), y-y) + CFLAGS_common.o += -DDISABLE_ARM_GLOBAL_TIMER +endif + # Common support obj-y := common.o slcr.o pm.o obj-$(CONFIG_SMP) += headsmp.o platsmp.o diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c index c887196..0619ef4 100644 --- a/arch/arm/mach-zynq/common.c +++ b/arch/arm/mach-zynq/common.c @@ -148,10 +148,38 @@ out: platform_device_register_full(&devinfo); } +#ifdef DISABLE_ARM_GLOBAL_TIMER +static struct property zynq_disable_arm_global_timer_prop = { + .name = "status", + .length = sizeof("disabled"), + .value = "disabled" +}; + +static void __init zynq_maybe_disable_arm_global_timer(void) +{ + struct device_node *np; + + np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-global-timer"); + if (!np) + return; + + pr_info("%s: disabling arm_global_timer node\n", __func__); + + if (of_update_property(np, &zynq_disable_arm_global_timer_prop)) + pr_warn("%s: could not disable arm_global_timer node\n", + __func__); +} +#else +static void __init zynq_maybe_disable_arm_global_timer(void) +{ +} +#endif + static void __init zynq_timer_init(void) { zynq_early_slcr_init(); + zynq_maybe_disable_arm_global_timer(); zynq_clock_init(); of_clk_init(NULL); clocksource_of_init(); -- 2.3.3