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

clocksource: convert ARM 32-bit up counting clocksources

Convert ixp4xx, lpc32xx, mxc, netx, pxa, sa1100, tcc8k, tegra and u300
to use the generic mmio clocksource recently introduced.

Cc: Imre Kaloz <kaloz@openwrt.org>
Cc: Krzysztof Halasa <khc@pm.waw.pl>
Acked-by: Eric Miao <eric.y.miao@gmail.com>
Acked-by: "Hans J. Koch" <hjk@hansjkoch.de>
Acked-by: Colin Cross <ccross@android.com>
Cc: Erik Gilling <konkers@android.com>
Cc: Olof Johansson <olof@lixom.net>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

+34 -145
+9
arch/arm/Kconfig
··· 366 366 select GENERIC_CLOCKEVENTS 367 367 select ARCH_REQUIRE_GPIOLIB 368 368 select CLKDEV_LOOKUP 369 + select CLKSRC_MMIO 369 370 select HAVE_SCHED_CLOCK 370 371 help 371 372 Support for Freescale MXC/iMX-based family of processors ··· 391 390 392 391 config ARCH_NETX 393 392 bool "Hilscher NetX based" 393 + select CLKSRC_MMIO 394 394 select CPU_ARM926T 395 395 select ARM_VIC 396 396 select GENERIC_CLOCKEVENTS ··· 459 457 config ARCH_IXP4XX 460 458 bool "IXP4xx-based" 461 459 depends on MMU 460 + select CLKSRC_MMIO 462 461 select CPU_XSCALE 463 462 select GENERIC_GPIO 464 463 select GENERIC_CLOCKEVENTS ··· 500 497 501 498 config ARCH_LPC32XX 502 499 bool "NXP LPC32XX" 500 + select CLKSRC_MMIO 503 501 select CPU_ARM926T 504 502 select ARCH_REQUIRE_GPIOLIB 505 503 select HAVE_IDE ··· 596 592 config ARCH_TEGRA 597 593 bool "NVIDIA Tegra" 598 594 select CLKDEV_LOOKUP 595 + select CLKSRC_MMIO 599 596 select GENERIC_TIME 600 597 select GENERIC_CLOCKEVENTS 601 598 select GENERIC_GPIO ··· 622 617 select ARCH_MTD_XIP 623 618 select ARCH_HAS_CPUFREQ 624 619 select CLKDEV_LOOKUP 620 + select CLKSRC_MMIO 625 621 select ARCH_REQUIRE_GPIOLIB 626 622 select GENERIC_CLOCKEVENTS 627 623 select HAVE_SCHED_CLOCK ··· 673 667 674 668 config ARCH_SA1100 675 669 bool "SA1100-based" 670 + select CLKSRC_MMIO 676 671 select CPU_SA1100 677 672 select ISA 678 673 select ARCH_SPARSEMEM_ENABLE ··· 810 803 811 804 config ARCH_TCC_926 812 805 bool "Telechips TCC ARM926-based systems" 806 + select CLKSRC_MMIO 813 807 select CPU_ARM926T 814 808 select HAVE_CLK 815 809 select CLKDEV_LOOKUP ··· 821 813 config ARCH_U300 822 814 bool "ST-Ericsson U300 Series" 823 815 depends on MMU 816 + select CLKSRC_MMIO 824 817 select CPU_ARM926T 825 818 select HAVE_SCHED_CLOCK 826 819 select HAVE_TCM
+2 -14
arch/arm/mach-ixp4xx/common.c
··· 419 419 /* 420 420 * clocksource 421 421 */ 422 - static cycle_t ixp4xx_get_cycles(struct clocksource *cs) 423 - { 424 - return *IXP4XX_OSTS; 425 - } 426 - 427 - static struct clocksource clocksource_ixp4xx = { 428 - .name = "OSTS", 429 - .rating = 200, 430 - .read = ixp4xx_get_cycles, 431 - .mask = CLOCKSOURCE_MASK(32), 432 - .flags = CLOCK_SOURCE_IS_CONTINUOUS, 433 - }; 434 - 435 422 unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ; 436 423 EXPORT_SYMBOL(ixp4xx_timer_freq); 437 424 static void __init ixp4xx_clocksource_init(void) 438 425 { 439 426 init_sched_clock(&cd, ixp4xx_update_sched_clock, 32, ixp4xx_timer_freq); 440 427 441 - clocksource_register_hz(&clocksource_ixp4xx, ixp4xx_timer_freq); 428 + clocksource_mmio_init(&IXP4XX_OSTS, "OSTS", ixp4xx_timer_freq, 200, 32, 429 + clocksource_mmio_readl_up); 442 430 } 443 431 444 432 /*
+3 -14
arch/arm/mach-lpc32xx/timer.c
··· 31 31 #include <mach/platform.h> 32 32 #include "common.h" 33 33 34 - static cycle_t lpc32xx_clksrc_read(struct clocksource *cs) 35 - { 36 - return (cycle_t)__raw_readl(LCP32XX_TIMER_TC(LPC32XX_TIMER1_BASE)); 37 - } 38 - 39 - static struct clocksource lpc32xx_clksrc = { 40 - .name = "lpc32xx_clksrc", 41 - .rating = 300, 42 - .read = lpc32xx_clksrc_read, 43 - .mask = CLOCKSOURCE_MASK(32), 44 - .flags = CLOCK_SOURCE_IS_CONTINUOUS, 45 - }; 46 - 47 34 static int lpc32xx_clkevt_next_event(unsigned long delta, 48 35 struct clock_event_device *dev) 49 36 { ··· 157 170 __raw_writel(0, LCP32XX_TIMER_MCR(LPC32XX_TIMER1_BASE)); 158 171 __raw_writel(LCP32XX_TIMER_CNTR_TCR_EN, 159 172 LCP32XX_TIMER_TCR(LPC32XX_TIMER1_BASE)); 160 - clocksource_register_hz(&lpc32xx_clksrc, clkrate); 173 + 174 + clocksource_mmio_init(LCP32XX_TIMER_TC(LPC32XX_TIMER1_BASE), 175 + "lpc32xx_clksrc", clkrate, 300, 32, clocksource_mmio_readl_up); 161 176 } 162 177 163 178 struct sys_timer lpc32xx_timer = {
+2 -14
arch/arm/mach-netx/time.c
··· 104 104 .handler = netx_timer_interrupt, 105 105 }; 106 106 107 - cycle_t netx_get_cycles(struct clocksource *cs) 108 - { 109 - return readl(NETX_GPIO_COUNTER_CURRENT(TIMER_CLOCKSOURCE)); 110 - } 111 - 112 - static struct clocksource clocksource_netx = { 113 - .name = "netx_timer", 114 - .rating = 200, 115 - .read = netx_get_cycles, 116 - .mask = CLOCKSOURCE_MASK(32), 117 - .flags = CLOCK_SOURCE_IS_CONTINUOUS, 118 - }; 119 - 120 107 /* 121 108 * Set up timer interrupt 122 109 */ ··· 137 150 writel(NETX_GPIO_COUNTER_CTRL_RUN, 138 151 NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKSOURCE)); 139 152 140 - clocksource_register_hz(&clocksource_netx, CLOCK_TICK_RATE); 153 + clocksource_mmio_init(NETX_GPIO_COUNTER_CURRENT(TIMER_CLOCKSOURCE), 154 + "netx_timer", CLOCK_TICK_RATE, 200, 32, clocksource_mmio_readl_up); 141 155 142 156 netx_clockevent.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, 143 157 netx_clockevent.shift);
+2 -15
arch/arm/mach-pxa/time.c
··· 105 105 .set_mode = pxa_osmr0_set_mode, 106 106 }; 107 107 108 - static cycle_t pxa_read_oscr(struct clocksource *cs) 109 - { 110 - return OSCR; 111 - } 112 - 113 - static struct clocksource cksrc_pxa_oscr0 = { 114 - .name = "oscr0", 115 - .rating = 200, 116 - .read = pxa_read_oscr, 117 - .mask = CLOCKSOURCE_MASK(32), 118 - .flags = CLOCK_SOURCE_IS_CONTINUOUS, 119 - }; 120 - 121 108 static struct irqaction pxa_ost0_irq = { 122 109 .name = "ost0", 123 110 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, ··· 121 134 122 135 init_sched_clock(&cd, pxa_update_sched_clock, 32, clock_tick_rate); 123 136 124 - clocksource_calc_mult_shift(&cksrc_pxa_oscr0, clock_tick_rate, 4); 125 137 clockevents_calc_mult_shift(&ckevt_pxa_osmr0, clock_tick_rate, 4); 126 138 ckevt_pxa_osmr0.max_delta_ns = 127 139 clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0); ··· 130 144 131 145 setup_irq(IRQ_OST0, &pxa_ost0_irq); 132 146 133 - clocksource_register_hz(&cksrc_pxa_oscr0, clock_tick_rate); 147 + clocksource_mmio_init(&OSCR, "oscr0", clock_tick_rate, 200, 32, 148 + clocksource_mmio_readl_up); 134 149 clockevents_register_device(&ckevt_pxa_osmr0); 135 150 } 136 151
+2 -14
arch/arm/mach-sa1100/time.c
··· 97 97 .set_mode = sa1100_osmr0_set_mode, 98 98 }; 99 99 100 - static cycle_t sa1100_read_oscr(struct clocksource *s) 101 - { 102 - return OSCR; 103 - } 104 - 105 - static struct clocksource cksrc_sa1100_oscr = { 106 - .name = "oscr", 107 - .rating = 200, 108 - .read = sa1100_read_oscr, 109 - .mask = CLOCKSOURCE_MASK(32), 110 - .flags = CLOCK_SOURCE_IS_CONTINUOUS, 111 - }; 112 - 113 100 static struct irqaction sa1100_timer_irq = { 114 101 .name = "ost0", 115 102 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, ··· 121 134 122 135 setup_irq(IRQ_OST0, &sa1100_timer_irq); 123 136 124 - clocksource_register_hz(&cksrc_sa1100_oscr, CLOCK_TICK_RATE); 137 + clocksource_mmio_init(&OSCR, "oscr", CLOCK_TICK_RATE, 200, 32, 138 + clocksource_mmio_readl_up); 125 139 clockevents_register_device(&ckevt_sa1100_osmr0); 126 140 } 127 141
+2 -14
arch/arm/mach-tcc8k/time.c
··· 25 25 26 26 static void __iomem *timer_base; 27 27 28 - static cycle_t tcc_get_cycles(struct clocksource *cs) 29 - { 30 - return __raw_readl(timer_base + TC32MCNT_OFFS); 31 - } 32 - 33 - static struct clocksource clocksource_tcc = { 34 - .name = "tcc_tc32", 35 - .rating = 200, 36 - .read = tcc_get_cycles, 37 - .mask = CLOCKSOURCE_MASK(32), 38 - .flags = CLOCK_SOURCE_IS_CONTINUOUS, 39 - }; 40 - 41 28 static int tcc_set_next_event(unsigned long evt, 42 29 struct clock_event_device *unused) 43 30 { ··· 89 102 { 90 103 unsigned int c = clk_get_rate(clock); 91 104 92 - clocksource_register_hz(&clocksource_tcc, c); 105 + clocksource_mmio_init(timer_base + TC32MCNT_OFFS, "tcc_tc32", c, 106 + 200, 32, clocksource_mmio_readl_up); 93 107 94 108 clockevent_tcc.mult = div_sc(c, NSEC_PER_SEC, 95 109 clockevent_tcc.shift);
+2 -14
arch/arm/mach-tegra/timer.c
··· 98 98 } 99 99 } 100 100 101 - static cycle_t tegra_clocksource_read(struct clocksource *cs) 102 - { 103 - return timer_readl(TIMERUS_CNTR_1US); 104 - } 105 - 106 101 static struct clock_event_device tegra_clockevent = { 107 102 .name = "timer0", 108 103 .rating = 300, 109 104 .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, 110 105 .set_next_event = tegra_timer_set_next_event, 111 106 .set_mode = tegra_timer_set_mode, 112 - }; 113 - 114 - static struct clocksource tegra_clocksource = { 115 - .name = "timer_us", 116 - .rating = 300, 117 - .read = tegra_clocksource_read, 118 - .mask = CLOCKSOURCE_MASK(32), 119 - .flags = CLOCK_SOURCE_IS_CONTINUOUS, 120 107 }; 121 108 122 109 static DEFINE_CLOCK_DATA(cd); ··· 221 234 init_fixed_sched_clock(&cd, tegra_update_sched_clock, 32, 222 235 1000000, SC_MULT, SC_SHIFT); 223 236 224 - if (clocksource_register_hz(&tegra_clocksource, 1000000)) { 237 + if (clocksource_mmio_init(timer_reg_base + TIMERUS_CNTR_1US, 238 + "timer_us", 1000000, 300, 32, clocksource_mmio_readl_up)) { 225 239 printk(KERN_ERR "Failed to register clocksource\n"); 226 240 BUG(); 227 241 }
+3 -15
arch/arm/mach-u300/timer.c
··· 333 333 .handler = u300_timer_interrupt, 334 334 }; 335 335 336 - /* Use general purpose timer 2 as clock source */ 337 - static cycle_t u300_get_cycles(struct clocksource *cs) 338 - { 339 - return (cycles_t) readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC); 340 - } 341 - 342 - static struct clocksource clocksource_u300_1mhz = { 343 - .name = "GPT2", 344 - .rating = 300, /* Reasonably fast and accurate clock source */ 345 - .read = u300_get_cycles, 346 - .mask = CLOCKSOURCE_MASK(32), /* 32 bits */ 347 - .flags = CLOCK_SOURCE_IS_CONTINUOUS, 348 - }; 349 - 350 336 /* 351 337 * Override the global weak sched_clock symbol with this 352 338 * local implementation which uses the clocksource to get some ··· 408 422 writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE, 409 423 U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT2); 410 424 411 - if (clocksource_register_hz(&clocksource_u300_1mhz, rate)) 425 + /* Use general purpose timer 2 as clock source */ 426 + if (clocksource_mmio_init(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC, 427 + "GPT2", rate, 300, 32, clocksource_mmio_readl_up)) 412 428 printk(KERN_ERR "timer: failed to initialize clock " 413 429 "source %s\n", clocksource_u300_1mhz.name); 414 430
+7 -31
arch/arm/plat-mxc/time.c
··· 106 106 __raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT); 107 107 } 108 108 109 - static cycle_t dummy_get_cycles(struct clocksource *cs) 110 - { 111 - return 0; 112 - } 113 - 114 - static cycle_t mx1_2_get_cycles(struct clocksource *cs) 115 - { 116 - return __raw_readl(timer_base + MX1_2_TCN); 117 - } 118 - 119 - static cycle_t v2_get_cycles(struct clocksource *cs) 120 - { 121 - return __raw_readl(timer_base + V2_TCN); 122 - } 123 - 124 - static struct clocksource clocksource_mxc = { 125 - .name = "mxc_timer1", 126 - .rating = 200, 127 - .read = dummy_get_cycles, 128 - .mask = CLOCKSOURCE_MASK(32), 129 - .flags = CLOCK_SOURCE_IS_CONTINUOUS, 130 - }; 109 + static void __iomem *sched_clock_reg; 131 110 132 111 static DEFINE_CLOCK_DATA(cd); 133 112 unsigned long long notrace sched_clock(void) 134 113 { 135 - cycle_t cyc = clocksource_mxc.read(&clocksource_mxc); 114 + cycle_t cyc = sched_clock_reg ? __raw_readl(sched_clock_reg) : 0; 136 115 137 116 return cyc_to_sched_clock(&cd, cyc, (u32)~0); 138 117 } 139 118 140 119 static void notrace mxc_update_sched_clock(void) 141 120 { 142 - cycle_t cyc = clocksource_mxc.read(&clocksource_mxc); 121 + cycle_t cyc = sched_clock_reg ? __raw_readl(sched_clock_reg) : 0; 143 122 update_sched_clock(&cd, cyc, (u32)~0); 144 123 } 145 124 146 125 static int __init mxc_clocksource_init(struct clk *timer_clk) 147 126 { 148 127 unsigned int c = clk_get_rate(timer_clk); 128 + void __iomem *reg = timer_base + (timer_is_v2() ? V2_TCN : MX1_2_TCN); 149 129 150 - if (timer_is_v2()) 151 - clocksource_mxc.read = v2_get_cycles; 152 - else 153 - clocksource_mxc.read = mx1_2_get_cycles; 130 + sched_clock_reg = reg; 154 131 155 132 init_sched_clock(&cd, mxc_update_sched_clock, 32, c); 156 - clocksource_register_hz(&clocksource_mxc, c); 157 - 158 - return 0; 133 + return clocksource_mmio_init(reg, "mxc_timer1", c, 200, 32, 134 + clocksource_mmio_readl_up); 159 135 } 160 136 161 137 /* clock event */