Commit 0583fe47 authored by Rob Herring's avatar Rob Herring

ARM: convert arm/arm64 arch timer to use CLKSRC_OF init

This converts arm and arm64 to use CLKSRC_OF DT based initialization for
the arch timer. A new function arch_timer_arch_init is added to allow for
arch specific setup.

This has a side effect of enabling sched_clock on omap5 and exynos5. There
should not be any reason not to use the arch timers for sched_clock.
Signed-off-by: default avatarRob Herring <rob.herring@calxeda.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Tony Lindgren <tony@atomide.com>
Cc: Simon Horman <horms@verge.net.au>
Cc: Magnus Damm <magnus.damm@gmail.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-samsung-soc@vger.kernel.org
Cc: linux-omap@vger.kernel.org
Cc: linux-sh@vger.kernel.org
Acked-by: default avatarSantosh Shilimkar <santosh.shilimkar@ti.com>
parent f414f13f
...@@ -10,8 +10,7 @@ ...@@ -10,8 +10,7 @@
#include <clocksource/arm_arch_timer.h> #include <clocksource/arm_arch_timer.h>
#ifdef CONFIG_ARM_ARCH_TIMER #ifdef CONFIG_ARM_ARCH_TIMER
int arch_timer_of_register(void); int arch_timer_arch_init(void);
int arch_timer_sched_clock_init(void);
/* /*
* These register accessors are marked inline so the compiler can * These register accessors are marked inline so the compiler can
...@@ -110,16 +109,6 @@ static inline void __cpuinit arch_counter_set_user_access(void) ...@@ -110,16 +109,6 @@ static inline void __cpuinit arch_counter_set_user_access(void)
asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl)); asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl));
} }
#else
static inline int arch_timer_of_register(void)
{
return -ENXIO;
}
static inline int arch_timer_sched_clock_init(void)
{
return -ENXIO;
}
#endif #endif
#endif #endif
...@@ -39,26 +39,15 @@ static void __init arch_timer_delay_timer_register(void) ...@@ -39,26 +39,15 @@ static void __init arch_timer_delay_timer_register(void)
register_current_timer_delay(&arch_delay_timer); register_current_timer_delay(&arch_delay_timer);
} }
int __init arch_timer_of_register(void) int __init arch_timer_arch_init(void)
{
int ret;
ret = arch_timer_init();
if (ret)
return ret;
arch_timer_delay_timer_register();
return 0;
}
int __init arch_timer_sched_clock_init(void)
{ {
u32 arch_timer_rate = arch_timer_get_rate(); u32 arch_timer_rate = arch_timer_get_rate();
if (arch_timer_rate == 0) if (arch_timer_rate == 0)
return -ENXIO; return -ENXIO;
arch_timer_delay_timer_register();
/* Cache the sched_clock multiplier to save a divide in the hot path. */ /* Cache the sched_clock multiplier to save a divide in the hot path. */
sched_clock_mult = NSEC_PER_SEC / arch_timer_rate; sched_clock_mult = NSEC_PER_SEC / arch_timer_rate;
sched_clock_func = arch_timer_sched_clock; sched_clock_func = arch_timer_sched_clock;
......
...@@ -216,7 +216,6 @@ DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)") ...@@ -216,7 +216,6 @@ DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)")
.map_io = exynos5_dt_map_io, .map_io = exynos5_dt_map_io,
.init_machine = exynos5_dt_machine_init, .init_machine = exynos5_dt_machine_init,
.init_late = exynos_init_late, .init_late = exynos_init_late,
.init_time = exynos4_timer_init,
.dt_compat = exynos5_dt_compat, .dt_compat = exynos5_dt_compat,
.restart = exynos5_restart, .restart = exynos5_restart,
.reserve = exynos5_reserve, .reserve = exynos5_reserve,
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include <linux/percpu.h> #include <linux/percpu.h>
#include <linux/of.h> #include <linux/of.h>
#include <asm/arch_timer.h>
#include <asm/localtimer.h> #include <asm/localtimer.h>
#include <plat/cpu.h> #include <plat/cpu.h>
...@@ -469,11 +468,6 @@ static void __init exynos4_timer_resources(void) ...@@ -469,11 +468,6 @@ static void __init exynos4_timer_resources(void)
void __init exynos4_timer_init(void) void __init exynos4_timer_init(void)
{ {
if (soc_is_exynos5440()) {
arch_timer_of_register();
return;
}
if ((soc_is_exynos4210()) || (soc_is_exynos5250())) if ((soc_is_exynos4210()) || (soc_is_exynos5250()))
mct_int_type = MCT_INT_SPI; mct_int_type = MCT_INT_SPI;
else else
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
*/ */
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clkdev.h> #include <linux/clkdev.h>
#include <linux/clocksource.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/irq.h> #include <linux/irq.h>
...@@ -28,7 +29,6 @@ ...@@ -28,7 +29,6 @@
#include <linux/amba/bus.h> #include <linux/amba/bus.h>
#include <linux/clk-provider.h> #include <linux/clk-provider.h>
#include <asm/arch_timer.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/cputype.h> #include <asm/cputype.h>
#include <asm/smp_plat.h> #include <asm/smp_plat.h>
...@@ -118,9 +118,6 @@ static void __init highbank_timer_init(void) ...@@ -118,9 +118,6 @@ static void __init highbank_timer_init(void)
sp804_clocksource_and_sched_clock_init(timer_base + 0x20, "timer1"); sp804_clocksource_and_sched_clock_init(timer_base + 0x20, "timer1");
sp804_clockevents_init(timer_base, irq, "timer0"); sp804_clockevents_init(timer_base, irq, "timer0");
arch_timer_of_register();
arch_timer_sched_clock_init();
clocksource_of_init(); clocksource_of_init();
} }
......
...@@ -46,7 +46,6 @@ ...@@ -46,7 +46,6 @@
#include <asm/smp_twd.h> #include <asm/smp_twd.h>
#include <asm/sched_clock.h> #include <asm/sched_clock.h>
#include <asm/arch_timer.h>
#include "omap_hwmod.h" #include "omap_hwmod.h"
#include "omap_device.h" #include "omap_device.h"
#include <plat/counter-32k.h> #include <plat/counter-32k.h>
...@@ -624,9 +623,7 @@ void __init omap5_realtime_timer_init(void) ...@@ -624,9 +623,7 @@ void __init omap5_realtime_timer_init(void)
omap5_sync32k_timer_init(); omap5_sync32k_timer_init();
realtime_counter_init(); realtime_counter_init();
err = arch_timer_of_register(); clocksource_of_init();
if (err)
pr_err("%s: arch_timer_register failed %d\n", __func__, err);
} }
#endif /* CONFIG_SOC_OMAP5 */ #endif /* CONFIG_SOC_OMAP5 */
......
...@@ -90,6 +90,5 @@ DT_MACHINE_START(KZM9D_DT, "kzm9d") ...@@ -90,6 +90,5 @@ DT_MACHINE_START(KZM9D_DT, "kzm9d")
.init_irq = emev2_init_irq, .init_irq = emev2_init_irq,
.init_machine = kzm9d_add_standard_devices, .init_machine = kzm9d_add_standard_devices,
.init_late = shmobile_init_late, .init_late = shmobile_init_late,
.init_time = shmobile_timer_init,
.dt_compat = kzm9d_boards_compat_dt, .dt_compat = kzm9d_boards_compat_dt,
MACHINE_END MACHINE_END
...@@ -456,7 +456,6 @@ DT_MACHINE_START(EMEV2_DT, "Generic Emma Mobile EV2 (Flattened Device Tree)") ...@@ -456,7 +456,6 @@ DT_MACHINE_START(EMEV2_DT, "Generic Emma Mobile EV2 (Flattened Device Tree)")
.nr_irqs = NR_IRQS_LEGACY, .nr_irqs = NR_IRQS_LEGACY,
.init_irq = irqchip_init, .init_irq = irqchip_init,
.init_machine = emev2_add_standard_devices_dt, .init_machine = emev2_add_standard_devices_dt,
.init_time = shmobile_timer_init,
.dt_compat = emev2_boards_compat_dt, .dt_compat = emev2_boards_compat_dt,
MACHINE_END MACHINE_END
......
...@@ -906,7 +906,6 @@ DT_MACHINE_START(R8A7740_DT, "Generic R8A7740 (Flattened Device Tree)") ...@@ -906,7 +906,6 @@ DT_MACHINE_START(R8A7740_DT, "Generic R8A7740 (Flattened Device Tree)")
.init_irq = r8a7740_init_irq, .init_irq = r8a7740_init_irq,
.handle_irq = shmobile_handle_irq_intc, .handle_irq = shmobile_handle_irq_intc,
.init_machine = r8a7740_add_standard_devices_dt, .init_machine = r8a7740_add_standard_devices_dt,
.init_time = shmobile_timer_init,
.dt_compat = r8a7740_boards_compat_dt, .dt_compat = r8a7740_boards_compat_dt,
MACHINE_END MACHINE_END
......
...@@ -1175,7 +1175,6 @@ DT_MACHINE_START(SH7372_DT, "Generic SH7372 (Flattened Device Tree)") ...@@ -1175,7 +1175,6 @@ DT_MACHINE_START(SH7372_DT, "Generic SH7372 (Flattened Device Tree)")
.init_irq = sh7372_init_irq, .init_irq = sh7372_init_irq,
.handle_irq = shmobile_handle_irq_intc, .handle_irq = shmobile_handle_irq_intc,
.init_machine = sh7372_add_standard_devices_dt, .init_machine = sh7372_add_standard_devices_dt,
.init_time = shmobile_timer_init,
.dt_compat = sh7372_boards_compat_dt, .dt_compat = sh7372_boards_compat_dt,
MACHINE_END MACHINE_END
......
...@@ -923,7 +923,6 @@ DT_MACHINE_START(SH73A0_DT, "Generic SH73A0 (Flattened Device Tree)") ...@@ -923,7 +923,6 @@ DT_MACHINE_START(SH73A0_DT, "Generic SH73A0 (Flattened Device Tree)")
.nr_irqs = NR_IRQS_LEGACY, .nr_irqs = NR_IRQS_LEGACY,
.init_irq = sh73a0_init_irq_dt, .init_irq = sh73a0_init_irq_dt,
.init_machine = sh73a0_add_standard_devices_dt, .init_machine = sh73a0_add_standard_devices_dt,
.init_time = shmobile_timer_init,
.dt_compat = sh73a0_boards_compat_dt, .dt_compat = sh73a0_boards_compat_dt,
MACHINE_END MACHINE_END
#endif /* CONFIG_USE_OF */ #endif /* CONFIG_USE_OF */
...@@ -19,10 +19,8 @@ ...@@ -19,10 +19,8 @@
* *
*/ */
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/clocksource.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <asm/arch_timer.h>
#include <asm/mach/time.h>
#include <asm/smp_twd.h>
void __init shmobile_setup_delay(unsigned int max_cpu_core_mhz, void __init shmobile_setup_delay(unsigned int max_cpu_core_mhz,
unsigned int mult, unsigned int div) unsigned int mult, unsigned int div)
...@@ -63,6 +61,5 @@ void __init shmobile_earlytimer_init(void) ...@@ -63,6 +61,5 @@ void __init shmobile_earlytimer_init(void)
void __init shmobile_timer_init(void) void __init shmobile_timer_init(void)
{ {
arch_timer_of_register(); clocksource_of_init();
arch_timer_sched_clock_init();
} }
/* /*
* Versatile Express V2M Motherboard Support * Versatile Express V2M Motherboard Support
*/ */
#include <linux/clocksource.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/amba/bus.h> #include <linux/amba/bus.h>
#include <linux/amba/mmci.h> #include <linux/amba/mmci.h>
...@@ -23,7 +24,6 @@ ...@@ -23,7 +24,6 @@
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
#include <linux/vexpress.h> #include <linux/vexpress.h>
#include <asm/arch_timer.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/sizes.h> #include <asm/sizes.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
...@@ -446,10 +446,7 @@ static void __init v2m_dt_timer_init(void) ...@@ -446,10 +446,7 @@ static void __init v2m_dt_timer_init(void)
irq_of_parse_and_map(node, 0)); irq_of_parse_and_map(node, 0));
} }
arch_timer_of_register(); versatile_sched_clock_init(vexpress_get_24mhz_clock_base(),
if (arch_timer_sched_clock_init() != 0)
versatile_sched_clock_init(vexpress_get_24mhz_clock_base(),
24000000); 24000000);
} }
......
...@@ -23,21 +23,13 @@ ...@@ -23,21 +23,13 @@
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <asm/arch_timer.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/time.h>
static void __init virt_init(void) static void __init virt_init(void)
{ {
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
} }
static void __init virt_timer_init(void)
{
WARN_ON(arch_timer_of_register() != 0);
WARN_ON(arch_timer_sched_clock_init() != 0);
}
static const char *virt_dt_match[] = { static const char *virt_dt_match[] = {
"linux,dummy-virt", "linux,dummy-virt",
NULL NULL
...@@ -47,7 +39,6 @@ extern struct smp_operations virt_smp_ops; ...@@ -47,7 +39,6 @@ extern struct smp_operations virt_smp_ops;
DT_MACHINE_START(VIRT, "Dummy Virtual Machine") DT_MACHINE_START(VIRT, "Dummy Virtual Machine")
.init_irq = irqchip_init, .init_irq = irqchip_init,
.init_time = virt_timer_init,
.init_machine = virt_init, .init_machine = virt_init,
.smp = smp_ops(virt_smp_ops), .smp = smp_ops(virt_smp_ops),
.dt_compat = virt_dt_match, .dt_compat = virt_dt_match,
......
...@@ -130,4 +130,9 @@ static inline u64 arch_counter_get_cntvct(void) ...@@ -130,4 +130,9 @@ static inline u64 arch_counter_get_cntvct(void)
return cval; return cval;
} }
static inline int arch_timer_arch_init(void)
{
return 0;
}
#endif #endif
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/clocksource.h>
#include <clocksource/arm_arch_timer.h> #include <clocksource/arm_arch_timer.h>
...@@ -77,10 +78,11 @@ void __init time_init(void) ...@@ -77,10 +78,11 @@ void __init time_init(void)
{ {
u32 arch_timer_rate; u32 arch_timer_rate;
if (arch_timer_init()) clocksource_of_init();
panic("Unable to initialise architected timer.\n");
arch_timer_rate = arch_timer_get_rate(); arch_timer_rate = arch_timer_get_rate();
if (!arch_timer_rate)
panic("Unable to initialise architected timer.\n");
/* Cache the sched_clock multiplier to save a divide in the hot path. */ /* Cache the sched_clock multiplier to save a divide in the hot path. */
sched_clock_mult = NSEC_PER_SEC / arch_timer_rate; sched_clock_mult = NSEC_PER_SEC / arch_timer_rate;
......
...@@ -62,6 +62,7 @@ config CLKSRC_DBX500_PRCMU_SCHED_CLOCK ...@@ -62,6 +62,7 @@ config CLKSRC_DBX500_PRCMU_SCHED_CLOCK
config ARM_ARCH_TIMER config ARM_ARCH_TIMER
bool bool
select CLKSRC_OF if OF
config CLKSRC_METAG_GENERIC config CLKSRC_METAG_GENERIC
def_bool y if METAG def_bool y if METAG
......
...@@ -337,22 +337,14 @@ static int __init arch_timer_register(void) ...@@ -337,22 +337,14 @@ static int __init arch_timer_register(void)
return err; return err;
} }
static const struct of_device_id arch_timer_of_match[] __initconst = { static void __init arch_timer_init(struct device_node *np)
{ .compatible = "arm,armv7-timer", },
{ .compatible = "arm,armv8-timer", },
{},
};
int __init arch_timer_init(void)
{ {
struct device_node *np;
u32 freq; u32 freq;
int i; int i;
np = of_find_matching_node(NULL, arch_timer_of_match); if (arch_timer_get_rate()) {
if (!np) { pr_warn("arch_timer: multiple nodes in dt, skipping\n");
pr_err("arch_timer: can't find DT node\n"); return;
return -ENODEV;
} }
/* Try to determine the frequency from the device tree or CNTFRQ */ /* Try to determine the frequency from the device tree or CNTFRQ */
...@@ -378,7 +370,7 @@ int __init arch_timer_init(void) ...@@ -378,7 +370,7 @@ int __init arch_timer_init(void)
if (!arch_timer_ppi[PHYS_SECURE_PPI] || if (!arch_timer_ppi[PHYS_SECURE_PPI] ||
!arch_timer_ppi[PHYS_NONSECURE_PPI]) { !arch_timer_ppi[PHYS_NONSECURE_PPI]) {
pr_warn("arch_timer: No interrupt available, giving up\n"); pr_warn("arch_timer: No interrupt available, giving up\n");
return -EINVAL; return;
} }
} }
...@@ -387,5 +379,8 @@ int __init arch_timer_init(void) ...@@ -387,5 +379,8 @@ int __init arch_timer_init(void)
else else
arch_timer_read_counter = arch_counter_get_cntpct; arch_timer_read_counter = arch_counter_get_cntpct;
return arch_timer_register(); arch_timer_register();
arch_timer_arch_init();
} }
CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_init);
CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_init);
...@@ -31,18 +31,12 @@ ...@@ -31,18 +31,12 @@
#ifdef CONFIG_ARM_ARCH_TIMER #ifdef CONFIG_ARM_ARCH_TIMER
extern int arch_timer_init(void);
extern u32 arch_timer_get_rate(void); extern u32 arch_timer_get_rate(void);
extern u64 (*arch_timer_read_counter)(void); extern u64 (*arch_timer_read_counter)(void);
extern struct timecounter *arch_timer_get_timecounter(void); extern struct timecounter *arch_timer_get_timecounter(void);
#else #else
static inline int arch_timer_init(void)
{
return -ENXIO;
}
static inline u32 arch_timer_get_rate(void) static inline u32 arch_timer_get_rate(void)
{ {
return 0; return 0;
......
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