Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Rob 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: Santosh Shilimkar <santosh.shilimkar@ti.com>

+29 -87
+1 -12
arch/arm/include/asm/arch_timer.h
··· 10 10 #include <clocksource/arm_arch_timer.h> 11 11 12 12 #ifdef CONFIG_ARM_ARCH_TIMER 13 - int arch_timer_of_register(void); 14 - int arch_timer_sched_clock_init(void); 13 + int arch_timer_arch_init(void); 15 14 16 15 /* 17 16 * These register accessors are marked inline so the compiler can ··· 108 109 cntkctl &= ~((3 << 8) | (7 << 0)); 109 110 110 111 asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl)); 111 - } 112 - #else 113 - static inline int arch_timer_of_register(void) 114 - { 115 - return -ENXIO; 116 - } 117 - 118 - static inline int arch_timer_sched_clock_init(void) 119 - { 120 - return -ENXIO; 121 112 } 122 113 #endif 123 114
+3 -14
arch/arm/kernel/arch_timer.c
··· 39 39 register_current_timer_delay(&arch_delay_timer); 40 40 } 41 41 42 - int __init arch_timer_of_register(void) 43 - { 44 - int ret; 45 - 46 - ret = arch_timer_init(); 47 - if (ret) 48 - return ret; 49 - 50 - arch_timer_delay_timer_register(); 51 - 52 - return 0; 53 - } 54 - 55 - int __init arch_timer_sched_clock_init(void) 42 + int __init arch_timer_arch_init(void) 56 43 { 57 44 u32 arch_timer_rate = arch_timer_get_rate(); 58 45 59 46 if (arch_timer_rate == 0) 60 47 return -ENXIO; 48 + 49 + arch_timer_delay_timer_register(); 61 50 62 51 /* Cache the sched_clock multiplier to save a divide in the hot path. */ 63 52 sched_clock_mult = NSEC_PER_SEC / arch_timer_rate;
-1
arch/arm/mach-exynos/mach-exynos5-dt.c
··· 216 216 .map_io = exynos5_dt_map_io, 217 217 .init_machine = exynos5_dt_machine_init, 218 218 .init_late = exynos_init_late, 219 - .init_time = exynos4_timer_init, 220 219 .dt_compat = exynos5_dt_compat, 221 220 .restart = exynos5_restart, 222 221 .reserve = exynos5_reserve,
-6
arch/arm/mach-exynos/mct.c
··· 21 21 #include <linux/percpu.h> 22 22 #include <linux/of.h> 23 23 24 - #include <asm/arch_timer.h> 25 24 #include <asm/localtimer.h> 26 25 27 26 #include <plat/cpu.h> ··· 468 469 469 470 void __init exynos4_timer_init(void) 470 471 { 471 - if (soc_is_exynos5440()) { 472 - arch_timer_of_register(); 473 - return; 474 - } 475 - 476 472 if ((soc_is_exynos4210()) || (soc_is_exynos5250())) 477 473 mct_int_type = MCT_INT_SPI; 478 474 else
+1 -4
arch/arm/mach-highbank/highbank.c
··· 15 15 */ 16 16 #include <linux/clk.h> 17 17 #include <linux/clkdev.h> 18 + #include <linux/clocksource.h> 18 19 #include <linux/dma-mapping.h> 19 20 #include <linux/io.h> 20 21 #include <linux/irq.h> ··· 29 28 #include <linux/amba/bus.h> 30 29 #include <linux/clk-provider.h> 31 30 32 - #include <asm/arch_timer.h> 33 31 #include <asm/cacheflush.h> 34 32 #include <asm/cputype.h> 35 33 #include <asm/smp_plat.h> ··· 117 117 118 118 sp804_clocksource_and_sched_clock_init(timer_base + 0x20, "timer1"); 119 119 sp804_clockevents_init(timer_base, irq, "timer0"); 120 - 121 - arch_timer_of_register(); 122 - arch_timer_sched_clock_init(); 123 120 124 121 clocksource_of_init(); 125 122 }
+1 -4
arch/arm/mach-omap2/timer.c
··· 46 46 #include <asm/smp_twd.h> 47 47 #include <asm/sched_clock.h> 48 48 49 - #include <asm/arch_timer.h> 50 49 #include "omap_hwmod.h" 51 50 #include "omap_device.h" 52 51 #include <plat/counter-32k.h> ··· 623 624 omap5_sync32k_timer_init(); 624 625 realtime_counter_init(); 625 626 626 - err = arch_timer_of_register(); 627 - if (err) 628 - pr_err("%s: arch_timer_register failed %d\n", __func__, err); 627 + clocksource_of_init(); 629 628 } 630 629 #endif /* CONFIG_SOC_OMAP5 */ 631 630
-1
arch/arm/mach-shmobile/board-kzm9d.c
··· 90 90 .init_irq = emev2_init_irq, 91 91 .init_machine = kzm9d_add_standard_devices, 92 92 .init_late = shmobile_init_late, 93 - .init_time = shmobile_timer_init, 94 93 .dt_compat = kzm9d_boards_compat_dt, 95 94 MACHINE_END
-1
arch/arm/mach-shmobile/setup-emev2.c
··· 456 456 .nr_irqs = NR_IRQS_LEGACY, 457 457 .init_irq = irqchip_init, 458 458 .init_machine = emev2_add_standard_devices_dt, 459 - .init_time = shmobile_timer_init, 460 459 .dt_compat = emev2_boards_compat_dt, 461 460 MACHINE_END 462 461
-1
arch/arm/mach-shmobile/setup-r8a7740.c
··· 906 906 .init_irq = r8a7740_init_irq, 907 907 .handle_irq = shmobile_handle_irq_intc, 908 908 .init_machine = r8a7740_add_standard_devices_dt, 909 - .init_time = shmobile_timer_init, 910 909 .dt_compat = r8a7740_boards_compat_dt, 911 910 MACHINE_END 912 911
-1
arch/arm/mach-shmobile/setup-sh7372.c
··· 1175 1175 .init_irq = sh7372_init_irq, 1176 1176 .handle_irq = shmobile_handle_irq_intc, 1177 1177 .init_machine = sh7372_add_standard_devices_dt, 1178 - .init_time = shmobile_timer_init, 1179 1178 .dt_compat = sh7372_boards_compat_dt, 1180 1179 MACHINE_END 1181 1180
-1
arch/arm/mach-shmobile/setup-sh73a0.c
··· 923 923 .nr_irqs = NR_IRQS_LEGACY, 924 924 .init_irq = sh73a0_init_irq_dt, 925 925 .init_machine = sh73a0_add_standard_devices_dt, 926 - .init_time = shmobile_timer_init, 927 926 .dt_compat = sh73a0_boards_compat_dt, 928 927 MACHINE_END 929 928 #endif /* CONFIG_USE_OF */
+2 -5
arch/arm/mach-shmobile/timer.c
··· 19 19 * 20 20 */ 21 21 #include <linux/platform_device.h> 22 + #include <linux/clocksource.h> 22 23 #include <linux/delay.h> 23 - #include <asm/arch_timer.h> 24 - #include <asm/mach/time.h> 25 - #include <asm/smp_twd.h> 26 24 27 25 void __init shmobile_setup_delay(unsigned int max_cpu_core_mhz, 28 26 unsigned int mult, unsigned int div) ··· 61 63 62 64 void __init shmobile_timer_init(void) 63 65 { 64 - arch_timer_of_register(); 65 - arch_timer_sched_clock_init(); 66 + clocksource_of_init(); 66 67 }
+2 -5
arch/arm/mach-vexpress/v2m.c
··· 1 1 /* 2 2 * Versatile Express V2M Motherboard Support 3 3 */ 4 + #include <linux/clocksource.h> 4 5 #include <linux/device.h> 5 6 #include <linux/amba/bus.h> 6 7 #include <linux/amba/mmci.h> ··· 24 23 #include <linux/regulator/machine.h> 25 24 #include <linux/vexpress.h> 26 25 27 - #include <asm/arch_timer.h> 28 26 #include <asm/mach-types.h> 29 27 #include <asm/sizes.h> 30 28 #include <asm/mach/arch.h> ··· 446 446 irq_of_parse_and_map(node, 0)); 447 447 } 448 448 449 - arch_timer_of_register(); 450 - 451 - if (arch_timer_sched_clock_init() != 0) 452 - versatile_sched_clock_init(vexpress_get_24mhz_clock_base(), 449 + versatile_sched_clock_init(vexpress_get_24mhz_clock_base(), 453 450 24000000); 454 451 } 455 452
-9
arch/arm/mach-virt/virt.c
··· 23 23 #include <linux/of_platform.h> 24 24 #include <linux/smp.h> 25 25 26 - #include <asm/arch_timer.h> 27 26 #include <asm/mach/arch.h> 28 - #include <asm/mach/time.h> 29 27 30 28 static void __init virt_init(void) 31 29 { 32 30 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 33 - } 34 - 35 - static void __init virt_timer_init(void) 36 - { 37 - WARN_ON(arch_timer_of_register() != 0); 38 - WARN_ON(arch_timer_sched_clock_init() != 0); 39 31 } 40 32 41 33 static const char *virt_dt_match[] = { ··· 39 47 40 48 DT_MACHINE_START(VIRT, "Dummy Virtual Machine") 41 49 .init_irq = irqchip_init, 42 - .init_time = virt_timer_init, 43 50 .init_machine = virt_init, 44 51 .smp = smp_ops(virt_smp_ops), 45 52 .dt_compat = virt_dt_match,
+5
arch/arm64/include/asm/arch_timer.h
··· 130 130 return cval; 131 131 } 132 132 133 + static inline int arch_timer_arch_init(void) 134 + { 135 + return 0; 136 + } 137 + 133 138 #endif
+4 -2
arch/arm64/kernel/time.c
··· 32 32 #include <linux/timer.h> 33 33 #include <linux/irq.h> 34 34 #include <linux/delay.h> 35 + #include <linux/clocksource.h> 35 36 36 37 #include <clocksource/arm_arch_timer.h> 37 38 ··· 78 77 { 79 78 u32 arch_timer_rate; 80 79 81 - if (arch_timer_init()) 82 - panic("Unable to initialise architected timer.\n"); 80 + clocksource_of_init(); 83 81 84 82 arch_timer_rate = arch_timer_get_rate(); 83 + if (!arch_timer_rate) 84 + panic("Unable to initialise architected timer.\n"); 85 85 86 86 /* Cache the sched_clock multiplier to save a divide in the hot path. */ 87 87 sched_clock_mult = NSEC_PER_SEC / arch_timer_rate;
+1
drivers/clocksource/Kconfig
··· 62 62 63 63 config ARM_ARCH_TIMER 64 64 bool 65 + select CLKSRC_OF if OF 65 66 66 67 config CLKSRC_METAG_GENERIC 67 68 def_bool y if METAG
+9 -14
drivers/clocksource/arm_arch_timer.c
··· 337 337 return err; 338 338 } 339 339 340 - static const struct of_device_id arch_timer_of_match[] __initconst = { 341 - { .compatible = "arm,armv7-timer", }, 342 - { .compatible = "arm,armv8-timer", }, 343 - {}, 344 - }; 345 - 346 - int __init arch_timer_init(void) 340 + static void __init arch_timer_init(struct device_node *np) 347 341 { 348 - struct device_node *np; 349 342 u32 freq; 350 343 int i; 351 344 352 - np = of_find_matching_node(NULL, arch_timer_of_match); 353 - if (!np) { 354 - pr_err("arch_timer: can't find DT node\n"); 355 - return -ENODEV; 345 + if (arch_timer_get_rate()) { 346 + pr_warn("arch_timer: multiple nodes in dt, skipping\n"); 347 + return; 356 348 } 357 349 358 350 /* Try to determine the frequency from the device tree or CNTFRQ */ ··· 370 378 if (!arch_timer_ppi[PHYS_SECURE_PPI] || 371 379 !arch_timer_ppi[PHYS_NONSECURE_PPI]) { 372 380 pr_warn("arch_timer: No interrupt available, giving up\n"); 373 - return -EINVAL; 381 + return; 374 382 } 375 383 } 376 384 ··· 379 387 else 380 388 arch_timer_read_counter = arch_counter_get_cntpct; 381 389 382 - return arch_timer_register(); 390 + arch_timer_register(); 391 + arch_timer_arch_init(); 383 392 } 393 + CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_init); 394 + CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_init);
-6
include/clocksource/arm_arch_timer.h
··· 31 31 32 32 #ifdef CONFIG_ARM_ARCH_TIMER 33 33 34 - extern int arch_timer_init(void); 35 34 extern u32 arch_timer_get_rate(void); 36 35 extern u64 (*arch_timer_read_counter)(void); 37 36 extern struct timecounter *arch_timer_get_timecounter(void); 38 37 39 38 #else 40 - 41 - static inline int arch_timer_init(void) 42 - { 43 - return -ENXIO; 44 - } 45 39 46 40 static inline u32 arch_timer_get_rate(void) 47 41 {