From 0e341af835fdf553820a1fa98341b93ab32ce466 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Sat, 6 Nov 2010 23:03:53 +0530 Subject: ARM: ftrace: enable function graph tracer Add the options to enable the function graph tracer on ARM. Function graph tracer support requires frame pointers, so exclude Thumb-2 and also make sure FRAME_POINTER gets enabled when FUNCTION_GRAPH_TRACER is used, since FUNCTION_TRACER doesn't "select FRAME_POINTER" when ARM_UNWIND is used. Therefore, with GCC 4.4.0+, you get plain function tracing without frame pointers, but you'll need them if you want function graph tracing. Acked-by: Catalin Marinas Signed-off-by: Rabin Vincent --- arch/arm/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 8ae3d48d504c..bd620a481bee 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -14,6 +14,7 @@ config ARM select HAVE_FUNCTION_TRACER if (!XIP_KERNEL) select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL) select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL) + select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL) select HAVE_GENERIC_DMA_COHERENT select HAVE_KERNEL_GZIP select HAVE_KERNEL_LZO -- cgit v1.2.3 From 89c3dedf477da9c8d42d3a63d16875e52f74108b Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Mon, 22 Nov 2010 12:35:41 -0800 Subject: arm: kconfig: enable SMP for MSM targets This just adds ARCH_MSM_SCORPIONMP to allow SMP selection for MSM. MSM is unique in that it doesn't enable SCU or TWD. Signed-off-by: Daniel Walker --- arch/arm/Kconfig | 9 +++++---- arch/arm/mach-msm/Kconfig | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index db524e75c4a2..1a61017a54c8 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1205,10 +1205,11 @@ config SMP depends on EXPERIMENTAL depends on GENERIC_CLOCKEVENTS depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \ - MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\ - ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 + MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \ + ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \ + ARCH_MSM_SCORPIONMP select USE_GENERIC_SMP_HELPERS - select HAVE_ARM_SCU + select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP help This enables support for systems with more than one CPU. If you have a system with only one CPU, like most personal computers, say N. If @@ -1291,7 +1292,7 @@ config LOCAL_TIMERS bool "Use local timer interrupts" depends on SMP default y - select HAVE_ARM_TWD + select HAVE_ARM_TWD if !ARCH_MSM_SCORPIONMP help Enable support for local timers on SMP platforms, rather then the legacy IPI broadcast method. Local timers allows the system diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index dbbcfeb919db..31e5fd63ec9a 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig @@ -49,6 +49,8 @@ endchoice config MSM_SOC_REV_A bool +config ARCH_MSM_SCORPIONMP + bool config ARCH_MSM_ARM11 bool -- cgit v1.2.3 From 176bfc44417544724e6df0831a7f576f4a56283d Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Tue, 7 Sep 2010 13:33:05 -0700 Subject: arm: kconfig: dis-allow hotplug on MSM MSM doesn't support hotplug, so we prevent it from being selected in Kconfig. Signed-off-by: Daniel Walker --- arch/arm/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1a61017a54c8..c8fa1443e2c1 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1284,6 +1284,7 @@ config NR_CPUS config HOTPLUG_CPU bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" depends on SMP && HOTPLUG && EXPERIMENTAL + depends on !ARCH_MSM help Say Y here to experiment with turning CPUs off and on. CPUs can be controlled through /sys/devices/system/cpu. -- cgit v1.2.3 From 112f38a4a31668eb6a7d91d128296a26afdf7c4b Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 15 Dec 2010 19:23:07 +0000 Subject: ARM: sched_clock: provide common infrastructure for sched_clock() Provide common sched_clock() infrastructure for platforms to use to create a 64-bit ns based sched_clock() implementation from a counter running at a non-variable clock rate. This implementation is based upon maintaining an epoch for the counter and an epoch for the nanosecond time. When we desire a sched_clock() time, we calculate the number of counter ticks since the last epoch update, convert this to nanoseconds and add to the epoch nanoseconds. We regularly refresh these epochs within the counter wrap interval. We perform a similar calculation as above, and store the new epochs. We read and write the epochs in such a way that sched_clock() can easily (and locklessly) detect when an update is in progress, and repeat the loading of these constants when they're known not to be stable. The one caveat is that sched_clock() is not called in the middle of an update. We achieve that by disabling IRQs. Finally, if the clock rate is known at compile time, the counter to ns conversion factors can be specified, allowing sched_clock() to be tightly optimized. We ensure that these factors are correct by providing an initialization function which performs a run-time check. Acked-by: Peter Zijlstra Tested-by: Santosh Shilimkar Tested-by: Will Deacon Tested-by: Mikael Pettersson Tested-by: Eric Miao Tested-by: Olof Johansson Tested-by: Jamie Iles Reviewed-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/Kconfig | 3 + arch/arm/include/asm/sched_clock.h | 118 +++++++++++++++++++++++++++++++++++++ arch/arm/kernel/Makefile | 1 + arch/arm/kernel/sched_clock.c | 69 ++++++++++++++++++++++ 4 files changed, 191 insertions(+) create mode 100644 arch/arm/include/asm/sched_clock.h create mode 100644 arch/arm/kernel/sched_clock.c (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 49778bb43782..ed7a0a729d9c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -38,6 +38,9 @@ config HAVE_PWM config SYS_SUPPORTS_APM_EMULATION bool +config HAVE_SCHED_CLOCK + bool + config GENERIC_GPIO bool diff --git a/arch/arm/include/asm/sched_clock.h b/arch/arm/include/asm/sched_clock.h new file mode 100644 index 000000000000..a84628be1a7b --- /dev/null +++ b/arch/arm/include/asm/sched_clock.h @@ -0,0 +1,118 @@ +/* + * sched_clock.h: support for extending counters to full 64-bit ns counter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef ASM_SCHED_CLOCK +#define ASM_SCHED_CLOCK + +#include +#include + +struct clock_data { + u64 epoch_ns; + u32 epoch_cyc; + u32 epoch_cyc_copy; + u32 mult; + u32 shift; +}; + +#define DEFINE_CLOCK_DATA(name) struct clock_data name + +static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift) +{ + return (cyc * mult) >> shift; +} + +/* + * Atomically update the sched_clock epoch. Your update callback will + * be called from a timer before the counter wraps - read the current + * counter value, and call this function to safely move the epochs + * forward. Only use this from the update callback. + */ +static inline void update_sched_clock(struct clock_data *cd, u32 cyc, u32 mask) +{ + unsigned long flags; + u64 ns = cd->epoch_ns + + cyc_to_ns((cyc - cd->epoch_cyc) & mask, cd->mult, cd->shift); + + /* + * Write epoch_cyc and epoch_ns in a way that the update is + * detectable in cyc_to_fixed_sched_clock(). + */ + raw_local_irq_save(flags); + cd->epoch_cyc = cyc; + smp_wmb(); + cd->epoch_ns = ns; + smp_wmb(); + cd->epoch_cyc_copy = cyc; + raw_local_irq_restore(flags); +} + +/* + * If your clock rate is known at compile time, using this will allow + * you to optimize the mult/shift loads away. This is paired with + * init_fixed_sched_clock() to ensure that your mult/shift are correct. + */ +static inline unsigned long long cyc_to_fixed_sched_clock(struct clock_data *cd, + u32 cyc, u32 mask, u32 mult, u32 shift) +{ + u64 epoch_ns; + u32 epoch_cyc; + + /* + * Load the epoch_cyc and epoch_ns atomically. We do this by + * ensuring that we always write epoch_cyc, epoch_ns and + * epoch_cyc_copy in strict order, and read them in strict order. + * If epoch_cyc and epoch_cyc_copy are not equal, then we're in + * the middle of an update, and we should repeat the load. + */ + do { + epoch_cyc = cd->epoch_cyc; + smp_rmb(); + epoch_ns = cd->epoch_ns; + smp_rmb(); + } while (epoch_cyc != cd->epoch_cyc_copy); + + return epoch_ns + cyc_to_ns((cyc - epoch_cyc) & mask, mult, shift); +} + +/* + * Otherwise, you need to use this, which will obtain the mult/shift + * from the clock_data structure. Use init_sched_clock() with this. + */ +static inline unsigned long long cyc_to_sched_clock(struct clock_data *cd, + u32 cyc, u32 mask) +{ + return cyc_to_fixed_sched_clock(cd, cyc, mask, cd->mult, cd->shift); +} + +/* + * Initialize the clock data - calculate the appropriate multiplier + * and shift. Also setup a timer to ensure that the epoch is refreshed + * at the appropriate time interval, which will call your update + * handler. + */ +void init_sched_clock(struct clock_data *, void (*)(void), + unsigned int, unsigned long); + +/* + * Use this initialization function rather than init_sched_clock() if + * you're using cyc_to_fixed_sched_clock, which will warn if your + * constants are incorrect. + */ +static inline void init_fixed_sched_clock(struct clock_data *cd, + void (*update)(void), unsigned int bits, unsigned long rate, + u32 mult, u32 shift) +{ + init_sched_clock(cd, update, bits, rate); + if (cd->mult != mult || cd->shift != shift) { + pr_crit("sched_clock: wrong multiply/shift: %u>>%u vs calculated %u>>%u\n" + "sched_clock: fix multiply/shift to avoid scheduler hiccups\n", + mult, shift, cd->mult, cd->shift); + } +} + +#endif diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 679851a9f589..fd3ec49bfba6 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_MODULES) += armksyms.o module.o obj-$(CONFIG_ARTHUR) += arthur.o obj-$(CONFIG_ISA_DMA) += dma-isa.o obj-$(CONFIG_PCI) += bios32.o isa.o +obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c new file mode 100644 index 000000000000..2cdcc9287c74 --- /dev/null +++ b/arch/arm/kernel/sched_clock.c @@ -0,0 +1,69 @@ +/* + * sched_clock.c: support for extending counters to full 64-bit ns counter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include + +#include + +static void sched_clock_poll(unsigned long wrap_ticks); +static DEFINE_TIMER(sched_clock_timer, sched_clock_poll, 0, 0); +static void (*sched_clock_update_fn)(void); + +static void sched_clock_poll(unsigned long wrap_ticks) +{ + mod_timer(&sched_clock_timer, round_jiffies(jiffies + wrap_ticks)); + sched_clock_update_fn(); +} + +void __init init_sched_clock(struct clock_data *cd, void (*update)(void), + unsigned int clock_bits, unsigned long rate) +{ + unsigned long r, w; + u64 res, wrap; + char r_unit; + + sched_clock_update_fn = update; + + /* calculate the mult/shift to convert counter ticks to ns. */ + clocks_calc_mult_shift(&cd->mult, &cd->shift, rate, NSEC_PER_SEC, 60); + + r = rate; + if (r >= 4000000) { + r /= 1000000; + r_unit = 'M'; + } else { + r /= 1000; + r_unit = 'k'; + } + + /* calculate how many ns until we wrap */ + wrap = cyc_to_ns((1ULL << clock_bits) - 1, cd->mult, cd->shift); + do_div(wrap, NSEC_PER_MSEC); + w = wrap; + + /* calculate the ns resolution of this counter */ + res = cyc_to_ns(1ULL, cd->mult, cd->shift); + pr_info("sched_clock: %u bits at %lu%cHz, resolution %lluns, wraps every %lums\n", + clock_bits, r, r_unit, res, w); + + /* + * Start the timer to keep sched_clock() properly updated and + * sets the initial epoch. + */ + sched_clock_timer.data = msecs_to_jiffies(w - (w / 10)); + sched_clock_poll(sched_clock_timer.data); + + /* + * Ensure that sched_clock() starts off at 0ns + */ + cd->epoch_ns = 0; +} -- cgit v1.2.3 From 5b0d495c067d843c52fc1f9edbca29d5e9368b10 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 15 Dec 2010 21:23:13 +0000 Subject: ARM: ixp4xx: convert sched_clock() to use new infrastructure Convert ixp4xx to use the new sched_clock() infrastructure for extending 32bit counters to full 64-bit nanoseconds. Tested-by: Mikael Pettersson Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/mach-ixp4xx/common.c | 31 ++++++++++++++++++++----------- 2 files changed, 21 insertions(+), 11 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ed7a0a729d9c..6f58bce687f3 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -437,6 +437,7 @@ config ARCH_IXP4XX select CPU_XSCALE select GENERIC_GPIO select GENERIC_CLOCKEVENTS + select HAVE_SCHED_CLOCK select DMABOUNCE if PCI help Support for Intel's IXP4XX (XScale) family of processors. diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index e0b91d8ef644..4dbfcbb9163c 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -398,6 +399,23 @@ void __init ixp4xx_sys_init(void) ixp4xx_exp_bus_size >> 20); } +/* + * sched_clock() + */ +static DEFINE_CLOCK_DATA(cd); + +unsigned long long notrace sched_clock(void) +{ + u32 cyc = *IXP4XX_OSTS; + return cyc_to_sched_clock(&cd, cyc, (u32)~0); +} + +static void notrace ixp4xx_update_sched_clock(void) +{ + u32 cyc = *IXP4XX_OSTS; + update_sched_clock(&cd, cyc, (u32)~0); +} + /* * clocksource */ @@ -418,18 +436,9 @@ unsigned long ixp4xx_timer_freq = FREQ; EXPORT_SYMBOL(ixp4xx_timer_freq); static void __init ixp4xx_clocksource_init(void) { - clocksource_register_hz(&clocksource_ixp4xx, ixp4xx_timer_freq); -} - -/* - * sched_clock() - */ -unsigned long long notrace sched_clock(void) -{ - cycle_t cyc = ixp4xx_get_cycles(NULL); - struct clocksource *cs = &clocksource_ixp4xx; + init_sched_clock(&cd, ixp4xx_update_sched_clock, 32, ixp4xx_timer_freq); - return clocksource_cyc2ns(cyc, cs->mult, cs->shift); + clocksource_register_hz(&clocksource_ixp4xx, ixp4xx_timer_freq); } /* -- cgit v1.2.3 From 28bb7bc61a8cd48716d38d9c153fdc524f09870a Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 15 Dec 2010 21:46:48 +0000 Subject: ARM: mmp: convert sched_clock() to use new infrastructure Convert mmp to use the new sched_clock() infrastructure for extending 32bit counters to full 64-bit nanoseconds. Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/mach-mmp/time.c | 32 +++++++++++--------------------- 2 files changed, 12 insertions(+), 21 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 6f58bce687f3..0208e1e9ed79 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -513,6 +513,7 @@ config ARCH_MMP select ARCH_REQUIRE_GPIOLIB select COMMON_CLKDEV select GENERIC_CLOCKEVENTS + select HAVE_SCHED_CLOCK select TICK_ONESHOT select PLAT_PXA select SPARSE_IRQ diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c index a2ea33d04e63..aeb9ae23e6ce 100644 --- a/arch/arm/mach-mmp/time.c +++ b/arch/arm/mach-mmp/time.c @@ -26,8 +26,8 @@ #include #include #include -#include +#include #include #include #include @@ -42,23 +42,7 @@ #define MAX_DELTA (0xfffffffe) #define MIN_DELTA (16) -#define TCR2NS_SCALE_FACTOR 10 - -static unsigned long tcr2ns_scale; - -static void __init set_tcr2ns_scale(unsigned long tcr_rate) -{ - unsigned long long v = 1000000000ULL << TCR2NS_SCALE_FACTOR; - do_div(v, tcr_rate); - tcr2ns_scale = v; - /* - * We want an even value to automatically clear the top bit - * returned by cnt32_to_63() without an additional run time - * instruction. So if the LSB is 1 then round it up. - */ - if (tcr2ns_scale & 1) - tcr2ns_scale++; -} +static DEFINE_CLOCK_DATA(cd); /* * FIXME: the timer needs some delay to stablize the counter capture @@ -77,8 +61,14 @@ static inline uint32_t timer_read(void) unsigned long long notrace sched_clock(void) { - unsigned long long v = cnt32_to_63(timer_read()); - return (v * tcr2ns_scale) >> TCR2NS_SCALE_FACTOR; + u32 cyc = timer_read(); + return cyc_to_sched_clock(&cd, cyc, (u32)~0); +} + +static void notrace mmp_update_sched_clock(void) +{ + u32 cyc = timer_read(); + update_sched_clock(&cd, cyc, (u32)~0); } static irqreturn_t timer_interrupt(int irq, void *dev_id) @@ -185,7 +175,7 @@ void __init timer_init(int irq) { timer_config(); - set_tcr2ns_scale(CLOCK_TICK_RATE); + init_sched_clock(&cd, mmp_update_sched_clock, 32, CLOCK_TICK_RATE); ckevt.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt.shift); ckevt.max_delta_ns = clockevent_delta2ns(MAX_DELTA, &ckevt); -- cgit v1.2.3 From 7ce830188199c23aaeaf0c5ccc28b73c32b6df02 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 15 Dec 2010 21:48:15 +0000 Subject: ARM: pxa: convert sched_clock() to use new infrastructure Convert pxa to use the new sched_clock() infrastructure for extending 32bit counters to full 64-bit nanoseconds. Tested-by: Eric Miao Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/mach-pxa/time.c | 29 +++++++++-------------------- 2 files changed, 10 insertions(+), 20 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 0208e1e9ed79..23035d65252c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -593,6 +593,7 @@ config ARCH_PXA select COMMON_CLKDEV select ARCH_REQUIRE_GPIOLIB select GENERIC_CLOCKEVENTS + select HAVE_SCHED_CLOCK select TICK_ONESHOT select PLAT_PXA select SPARSE_IRQ diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index b8d9dff00ad1..e7f64d9b4f2d 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c @@ -17,11 +17,11 @@ #include #include #include -#include #include #include #include +#include #include /* @@ -32,29 +32,18 @@ * long as there is always less than 582 seconds between successive * calls to sched_clock() which should always be the case in practice. */ +static DEFINE_CLOCK_DATA(cd); -#define OSCR2NS_SCALE_FACTOR 10 - -static unsigned long oscr2ns_scale; - -static void __init set_oscr2ns_scale(unsigned long oscr_rate) +unsigned long long notrace sched_clock(void) { - unsigned long long v = 1000000000ULL << OSCR2NS_SCALE_FACTOR; - do_div(v, oscr_rate); - oscr2ns_scale = v; - /* - * We want an even value to automatically clear the top bit - * returned by cnt32_to_63() without an additional run time - * instruction. So if the LSB is 1 then round it up. - */ - if (oscr2ns_scale & 1) - oscr2ns_scale++; + u32 cyc = OSCR; + return cyc_to_sched_clock(&cd, cyc, (u32)~0); } -unsigned long long notrace sched_clock(void) +static void notrace pxa_update_sched_clock(void) { - unsigned long long v = cnt32_to_63(OSCR); - return (v * oscr2ns_scale) >> OSCR2NS_SCALE_FACTOR; + u32 cyc = OSCR; + update_sched_clock(&cd, cyc, (u32)~0); } @@ -144,7 +133,7 @@ static void __init pxa_timer_init(void) OIER = 0; OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3; - set_oscr2ns_scale(clock_tick_rate); + init_sched_clock(&cd, pxa_update_sched_clock, 32, clock_tick_rate); ckevt_pxa_osmr0.mult = div_sc(clock_tick_rate, NSEC_PER_SEC, ckevt_pxa_osmr0.shift); -- cgit v1.2.3 From 5094b92f1c7d0f21c5d4411ba7415bac0684210f Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 15 Dec 2010 21:49:06 +0000 Subject: ARM: sa1100: convert sched_clock() to use new infrastructure Convert sa1100 to use the new sched_clock() infrastructure for extending 32bit counters to full 64-bit nanoseconds. Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/mach-sa1100/generic.c | 23 ----------------------- arch/arm/mach-sa1100/time.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 23 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 23035d65252c..0e1a9667a869 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -642,6 +642,7 @@ config ARCH_SA1100 select CPU_FREQ select GENERIC_CLOCKEVENTS select HAVE_CLK + select HAVE_SCHED_CLOCK select TICK_ONESHOT select ARCH_REQUIRE_GPIOLIB help diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index 33b4969e9d51..fbc224d88e6f 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c @@ -16,9 +16,7 @@ #include #include #include -#include /* just for sched_clock() - funny that */ #include -#include #include #include @@ -109,27 +107,6 @@ unsigned int sa11x0_getspeed(unsigned int cpu) return cclk_frequency_100khz[PPCR & 0xf] * 100; } -/* - * This is the SA11x0 sched_clock implementation. This has - * a resolution of 271ns, and a maximum value of 32025597s (370 days). - * - * The return value is guaranteed to be monotonic in that range as - * long as there is always less than 582 seconds between successive - * calls to this function. - * - * ( * 1E9 / 3686400 => * 78125 / 288) - */ -unsigned long long notrace sched_clock(void) -{ - unsigned long long v = cnt32_to_63(OSCR); - - /* the <<1 gets rid of the cnt_32_to_63 top bit saving on a bic insn */ - v *= 78125<<1; - do_div(v, 288<<1); - - return v; -} - /* * Default power-off for SA1100 */ diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c index 96154f578cd5..ae4f3d80416f 100644 --- a/arch/arm/mach-sa1100/time.c +++ b/arch/arm/mach-sa1100/time.c @@ -12,12 +12,39 @@ #include #include #include +#include /* just for sched_clock() - funny that */ #include #include #include +#include #include +/* + * This is the SA11x0 sched_clock implementation. + */ +static DEFINE_CLOCK_DATA(cd); + +/* + * Constants generated by clocks_calc_mult_shift(m, s, 3.6864MHz, + * NSEC_PER_SEC, 60). + * This gives a resolution of about 271ns and a wrap period of about 19min. + */ +#define SC_MULT 2275555556u +#define SC_SHIFT 23 + +unsigned long long notrace sched_clock(void) +{ + u32 cyc = OSCR; + return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT); +} + +static void notrace sa1100_update_sched_clock(void) +{ + u32 cyc = OSCR; + update_sched_clock(&cd, cyc, (u32)~0); +} + #define MIN_OSCR_DELTA 2 static irqreturn_t sa1100_ost0_interrupt(int irq, void *dev_id) @@ -96,6 +123,9 @@ static void __init sa1100_timer_init(void) OIER = 0; /* disable any timer interrupts */ OSSR = 0xf; /* clear status on all timers */ + init_fixed_sched_clock(&cd, sa1100_update_sched_clock, 32, + 3686400, SC_MULT, SC_SHIFT); + ckevt_sa1100_osmr0.mult = div_sc(3686400, NSEC_PER_SEC, ckevt_sa1100_osmr0.shift); ckevt_sa1100_osmr0.max_delta_ns = -- cgit v1.2.3 From e3f4c0ab916334e861fc49eeb2673a8c13e978e7 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 15 Dec 2010 21:49:42 +0000 Subject: ARM: tegra: convert sched_clock() to use new infrastructure Convert tegra to use the new sched_clock() infrastructure for extending 32bit counters to full 64-bit nanoseconds. Tested-by: Olof Johansson Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/mach-tegra/timer.c | 23 +++++++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 0e1a9667a869..ec7b0274d46a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -570,6 +570,7 @@ config ARCH_TEGRA select GENERIC_CLOCKEVENTS select GENERIC_GPIO select HAVE_CLK + select HAVE_SCHED_CLOCK select COMMON_CLKDEV select ARCH_HAS_BARRIERS if CACHE_L2X0 select ARCH_HAS_CPUFREQ diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c index c52bd84652e5..7b8ad1f98f44 100644 --- a/arch/arm/mach-tegra/timer.c +++ b/arch/arm/mach-tegra/timer.c @@ -26,10 +26,10 @@ #include #include #include -#include #include #include +#include #include #include @@ -111,9 +111,25 @@ static struct clocksource tegra_clocksource = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; +static DEFINE_CLOCK_DATA(cd); + +/* + * Constants generated by clocks_calc_mult_shift(m, s, 1MHz, NSEC_PER_SEC, 60). + * This gives a resolution of about 1us and a wrap period of about 1h11min. + */ +#define SC_MULT 4194304000u +#define SC_SHIFT 22 + unsigned long long notrace sched_clock(void) { - return cnt32_to_63(timer_readl(TIMERUS_CNTR_1US)) * 1000; + u32 cyc = timer_readl(TIMERUS_CNTR_1US); + return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT); +} + +static void notrace tegra_update_sched_clock(void) +{ + u32 cyc = timer_readl(TIMERUS_CNTR_1US); + update_sched_clock(&cd, cyc, (u32)~0); } static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id) @@ -158,6 +174,9 @@ static void __init tegra_init_timer(void) WARN(1, "Unknown clock rate"); } + init_fixed_sched_clock(&cd, tegra_update_sched_clock, 32, + 1000000, SC_MULT, SC_SHIFT); + if (clocksource_register_hz(&tegra_clocksource, 1000000)) { printk(KERN_ERR "Failed to register clocksource\n"); BUG(); -- cgit v1.2.3 From 5c21b7ca2c1cca3758a1d357dd57987c96ad1aa0 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 15 Dec 2010 21:50:14 +0000 Subject: ARM: u300: convert sched_clock() to use new infrastructure Convert u300 to use the new sched_clock() infrastructure for extending 32bit counters to full 64-bit nanoseconds. Acked-by: Linus Walleij Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/mach-u300/timer.c | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ec7b0274d46a..d5bd266ee565 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -790,6 +790,7 @@ config ARCH_U300 bool "ST-Ericsson U300 Series" depends on MMU select CPU_ARM926T + select HAVE_SCHED_CLOCK select HAVE_TCM select ARM_AMBA select ARM_VIC diff --git a/arch/arm/mach-u300/timer.c b/arch/arm/mach-u300/timer.c index 6c68fe797903..3ec58bd2d6e4 100644 --- a/arch/arm/mach-u300/timer.c +++ b/arch/arm/mach-u300/timer.c @@ -22,6 +22,7 @@ #include /* Generic stuff */ +#include #include #include #include @@ -353,12 +354,18 @@ static struct clocksource clocksource_u300_1mhz = { * this wraps around for now, since it is just a relative time * stamp. (Inspired by OMAP implementation.) */ +static DEFINE_CLOCK_DATA(cd); + unsigned long long notrace sched_clock(void) { - return clocksource_cyc2ns(clocksource_u300_1mhz.read( - &clocksource_u300_1mhz), - clocksource_u300_1mhz.mult, - clocksource_u300_1mhz.shift); + u32 cyc = readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC); + return cyc_to_sched_clock(&cd, cyc, (u32)~0); +} + +static void notrace u300_update_sched_clock(void) +{ + u32 cyc = readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC); + update_sched_clock(&cd, cyc, (u32)~0); } @@ -376,6 +383,8 @@ static void __init u300_timer_init(void) clk_enable(clk); rate = clk_get_rate(clk); + init_sched_clock(&cd, u300_update_sched_clock, 32, rate); + /* * Disable the "OS" and "DD" timers - these are designed for Symbian! * Example usage in cnh1601578 cpu subsystem pd_timer_app.c -- cgit v1.2.3 From 08f26b1ef25a2f7b52afcb805d260fd5a000a7f6 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 15 Dec 2010 21:52:10 +0000 Subject: ARM: iop: convert sched_clock() to use new infrastructure Convert iop platforms to use the new sched_clock() infrastructure for extending 32bit counters to full 64-bit nanoseconds. Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/plat-iop/time.c | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index d5bd266ee565..58e2fe30715b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -992,6 +992,7 @@ config ARCH_ACORN config PLAT_IOP bool select GENERIC_CLOCKEVENTS + select HAVE_SCHED_CLOCK config PLAT_ORION bool diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c index d03a93295e60..2db6e60d149d 100644 --- a/arch/arm/plat-iop/time.c +++ b/arch/arm/plat-iop/time.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -50,15 +51,21 @@ static struct clocksource iop_clocksource = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; +static DEFINE_CLOCK_DATA(cd); + /* * IOP sched_clock() implementation via its clocksource. */ unsigned long long notrace sched_clock(void) { - cycle_t cyc = iop_clocksource_read(NULL); - struct clocksource *cs = &iop_clocksource; + u32 cyc = 0xffffffffu - read_tcr1(); + return cyc_to_sched_clock(&cd, cyc, (u32)~0); +} - return clocksource_cyc2ns(cyc, cs->mult, cs->shift); +static void notrace iop_update_sched_clock(void) +{ + u32 cyc = 0xffffffffu - read_tcr1(); + update_sched_clock(&cd, cyc, (u32)~0); } /* @@ -144,6 +151,8 @@ void __init iop_init_time(unsigned long tick_rate) { u32 timer_ctl; + init_sched_clock(&cd, iop_update_sched_clock, 32, tick_rate); + ticks_per_jiffy = DIV_ROUND_CLOSEST(tick_rate, HZ); iop_tick_rate = tick_rate; -- cgit v1.2.3 From dc548fbbd2ecd0fc3b02301d551e5f8e19ae58fd Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 15 Dec 2010 21:53:51 +0000 Subject: ARM: omap: convert sched_clock() to use new infrastructure Convert omap to use the new sched_clock() infrastructure for extending 32bit counters to full 64-bit nanoseconds. Tested-by: Santosh Shilimkar Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/plat-omap/counter_32k.c | 24 ++++++++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 58e2fe30715b..726279fe3f53 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -839,6 +839,7 @@ config ARCH_OMAP select ARCH_REQUIRE_GPIOLIB select ARCH_HAS_CPUFREQ select GENERIC_CLOCKEVENTS + select HAVE_SCHED_CLOCK select ARCH_HAS_HOLES_MEMORYMODEL help Support for TI's OMAP platform (OMAP1/2/3/4). diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c index aed301bfa2f9..1b558efbe732 100644 --- a/arch/arm/plat-omap/counter_32k.c +++ b/arch/arm/plat-omap/counter_32k.c @@ -18,6 +18,8 @@ #include #include +#include + #include #include @@ -110,10 +112,25 @@ static struct clocksource clocksource_32k = { * Returns current time from boot in nsecs. It's OK for this to wrap * around for now, as it's just a relative time stamp. */ +static DEFINE_CLOCK_DATA(cd); + +/* + * Constants generated by clocks_calc_mult_shift(m, s, 32768, NSEC_PER_SEC, 60). + * This gives a resolution of about 30us and a wrap period of about 36hrs. + */ +#define SC_MULT 4000000000u +#define SC_SHIFT 17 + unsigned long long notrace sched_clock(void) { - return clocksource_cyc2ns(clocksource_32k.read(&clocksource_32k), - clocksource_32k.mult, clocksource_32k.shift); + u32 cyc = clocksource_32k.read(&clocksource_32k); + return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT); +} + +static void notrace omap_update_sched_clock(void) +{ + u32 cyc = clocksource_32k.read(&clocksource_32k); + update_sched_clock(&cd, cyc, (u32)~0); } /** @@ -171,6 +188,9 @@ static int __init omap_init_clocksource_32k(void) if (clocksource_register_hz(&clocksource_32k, 32768)) printk(err, clocksource_32k.name); + + init_fixed_sched_clock(&cd, omap_update_sched_clock, 32, + 32768, SC_MULT, SC_SHIFT); } return 0; } -- cgit v1.2.3 From f06a1624621527ef597ae4b3b795553fc1b2eff2 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 15 Dec 2010 21:55:06 +0000 Subject: ARM: orion: convert sched_clock() to use new infrastructure Convert orion platforms to use the new sched_clock() infrastructure for extending 32bit counters to full 64-bit nanoseconds. Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/plat-orion/time.c | 44 +++++++++----------------------------------- 2 files changed, 10 insertions(+), 35 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 726279fe3f53..92e8c0174dd0 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -997,6 +997,7 @@ config PLAT_IOP config PLAT_ORION bool + select HAVE_SCHED_CLOCK config PLAT_PXA bool diff --git a/arch/arm/plat-orion/time.c b/arch/arm/plat-orion/time.c index 123f96f4194f..c3da2478b2aa 100644 --- a/arch/arm/plat-orion/time.c +++ b/arch/arm/plat-orion/time.c @@ -13,11 +13,11 @@ #include #include -#include #include #include #include #include +#include #include #include #include @@ -44,52 +44,26 @@ static u32 ticks_per_jiffy; /* * Orion's sched_clock implementation. It has a resolution of - * at least 7.5ns (133MHz TCLK) and a maximum value of 834 days. - * - * Because the hardware timer period is quite short (21 secs if - * 200MHz TCLK) and because cnt32_to_63() needs to be called at - * least once per half period to work properly, a kernel timer is - * set up to ensure this requirement is always met. + * at least 7.5ns (133MHz TCLK). */ -#define TCLK2NS_SCALE_FACTOR 8 - -static unsigned long tclk2ns_scale; +static DEFINE_CLOCK_DATA(cd); unsigned long long notrace sched_clock(void) { - unsigned long long v = cnt32_to_63(0xffffffff - readl(TIMER0_VAL)); - return (v * tclk2ns_scale) >> TCLK2NS_SCALE_FACTOR; + u32 cyc = 0xffffffff - readl(TIMER0_VAL); + return cyc_to_sched_clock(&cd, cyc, (u32)~0); } -static struct timer_list cnt32_to_63_keepwarm_timer; -static void cnt32_to_63_keepwarm(unsigned long data) +static void notrace orion_update_sched_clock(void) { - mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data)); - (void) sched_clock(); + u32 cyc = 0xffffffff - readl(TIMER0_VAL); + update_sched_clock(&cd, cyc, (u32)~0); } static void __init setup_sched_clock(unsigned long tclk) { - unsigned long long v; - unsigned long data; - - v = NSEC_PER_SEC; - v <<= TCLK2NS_SCALE_FACTOR; - v += tclk/2; - do_div(v, tclk); - /* - * We want an even value to automatically clear the top bit - * returned by cnt32_to_63() without an additional run time - * instruction. So if the LSB is 1 then round it up. - */ - if (v & 1) - v++; - tclk2ns_scale = v; - - data = (0xffffffffUL / tclk / 2 - 2) * HZ; - setup_timer(&cnt32_to_63_keepwarm_timer, cnt32_to_63_keepwarm, data); - mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data)); + init_sched_clock(&cd, orion_update_sched_clock, 32, tclk); } /* -- cgit v1.2.3 From 1da0c89c66753860ccfe81eb327c25db46c2a24a Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 15 Dec 2010 21:56:47 +0000 Subject: ARM: versatile: convert sched_clock() to use new infrastructure Convert versatile platforms to use the new sched_clock() infrastructure for extending 32bit counters to full 64-bit nanoseconds. Tested-by: Will Deacon Signed-off-by: Russell King --- arch/arm/Kconfig | 2 + arch/arm/mach-realview/core.c | 10 +++++ arch/arm/mach-versatile/core.c | 10 +++++ arch/arm/plat-versatile/include/plat/sched_clock.h | 6 +++ arch/arm/plat-versatile/sched-clock.c | 48 ++++++++++++---------- 5 files changed, 54 insertions(+), 22 deletions(-) create mode 100644 arch/arm/plat-versatile/include/plat/sched_clock.h (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 92e8c0174dd0..34311f40d713 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -236,6 +236,7 @@ config ARCH_REALVIEW bool "ARM Ltd. RealView family" select ARM_AMBA select COMMON_CLKDEV + select HAVE_SCHED_CLOCK select ICST select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB @@ -250,6 +251,7 @@ config ARCH_VERSATILE select ARM_AMBA select ARM_VIC select COMMON_CLKDEV + select HAVE_SCHED_CLOCK select ICST select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 07c08151dfe6..3d653e05b75d 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -52,6 +52,8 @@ #include #include +#include + #include "core.h" /* used by entry-macro.S and platsmp.c */ @@ -657,6 +659,12 @@ void realview_leds_event(led_event_t ledevt) } #endif /* CONFIG_LEDS */ +/* + * The sched_clock counter + */ +#define REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + \ + REALVIEW_SYS_24MHz_OFFSET) + /* * Where is the timer (VA)? */ @@ -672,6 +680,8 @@ void __init realview_timer_init(unsigned int timer_irq) { u32 val; + versatile_sched_clock_init(REFCOUNTER, 24000000); + /* * set clock frequency: * REALVIEW_REFCLK is 32KHz diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index e38acb0f89c8..56cdc2257424 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -51,6 +51,8 @@ #include #include +#include + #include "core.h" /* @@ -885,6 +887,12 @@ void __init versatile_init(void) #endif } +/* + * The sched_clock counter + */ +#define REFCOUNTER (__io_address(VERSATILE_SYS_BASE) + \ + VERSATILE_SYS_24MHz_OFFSET) + /* * Where is the timer (VA)? */ @@ -900,6 +908,8 @@ static void __init versatile_timer_init(void) { u32 val; + versatile_sched_clock_init(REFCOUNTER, 24000000); + /* * set clock frequency: * VERSATILE_REFCLK is 32KHz diff --git a/arch/arm/plat-versatile/include/plat/sched_clock.h b/arch/arm/plat-versatile/include/plat/sched_clock.h new file mode 100644 index 000000000000..5c3e4fc9fa0c --- /dev/null +++ b/arch/arm/plat-versatile/include/plat/sched_clock.h @@ -0,0 +1,6 @@ +#ifndef ARM_PLAT_SCHED_CLOCK_H +#define ARM_PLAT_SCHED_CLOCK_H + +void versatile_sched_clock_init(void __iomem *, unsigned long); + +#endif diff --git a/arch/arm/plat-versatile/sched-clock.c b/arch/arm/plat-versatile/sched-clock.c index 42efd14ed4b3..3d6a4c292cab 100644 --- a/arch/arm/plat-versatile/sched-clock.c +++ b/arch/arm/plat-versatile/sched-clock.c @@ -18,37 +18,41 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include #include #include -#include -#include -#include +#include +#include -#ifdef VERSATILE_SYS_BASE -#define REFCOUNTER (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET) -#endif - -#ifdef REALVIEW_SYS_BASE -#define REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET) -#endif +static DEFINE_CLOCK_DATA(cd); +static void __iomem *ctr; /* - * This is the Realview and Versatile sched_clock implementation. This - * has a resolution of 41.7ns, and a maximum value of about 35583 days. - * - * The return value is guaranteed to be monotonic in that range as - * long as there is always less than 89 seconds between successive - * calls to this function. + * Constants generated by clocks_calc_mult_shift(m, s, 24MHz, NSEC_PER_SEC, 60). + * This gives a resolution of about 41ns and a wrap period of about 178s. */ +#define SC_MULT 2796202667u +#define SC_SHIFT 26 + unsigned long long notrace sched_clock(void) { - unsigned long long v = cnt32_to_63(readl(REFCOUNTER)); + if (ctr) { + u32 cyc = readl(ctr); + return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, + SC_MULT, SC_SHIFT); + } else + return 0; +} - /* the <<1 gets rid of the cnt_32_to_63 top bit saving on a bic insn */ - v *= 125<<1; - do_div(v, 3<<1); +static void notrace versatile_update_sched_clock(void) +{ + u32 cyc = readl(ctr); + update_sched_clock(&cd, cyc, (u32)~0); +} - return v; +void __init versatile_sched_clock_init(void __iomem *reg, unsigned long rate) +{ + ctr = reg; + init_fixed_sched_clock(&cd, versatile_update_sched_clock, + 32, rate, SC_MULT, SC_SHIFT); } -- cgit v1.2.3 From 0af85dda39d9b673aca8c0ebae004ea70f3efc93 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 15 Dec 2010 21:58:50 +0000 Subject: ARM: vexpress: add sched_clock() for Versatile Express Add a sched_clock() implementation to Versatile Express using the new sched_clock() infrastructure for extending 32bit counters to full 64-bit nanoseconds. Tested-by: Will Deacon Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/mach-vexpress/v2m.c | 4 ++++ arch/arm/plat-versatile/Makefile | 5 +++-- 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 34311f40d713..17b5ff0db1dc 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -268,6 +268,7 @@ config ARCH_VEXPRESS select COMMON_CLKDEV select GENERIC_CLOCKEVENTS select HAVE_CLK + select HAVE_SCHED_CLOCK select ICST select PLAT_VERSATILE help diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index 7eaa232180a5..8c283100a9a0 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c @@ -22,6 +22,8 @@ #include #include +#include + #include #include "core.h" @@ -50,6 +52,8 @@ void __init v2m_map_io(struct map_desc *tile, size_t num) static void __init v2m_timer_init(void) { + versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000); + writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL); writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL); diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile index 5cf88e8427b1..8bb6ba6d3572 100644 --- a/arch/arm/plat-versatile/Makefile +++ b/arch/arm/plat-versatile/Makefile @@ -1,7 +1,8 @@ obj-y := clock.o obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o -obj-$(CONFIG_ARCH_REALVIEW) += sched-clock.o -obj-$(CONFIG_ARCH_VERSATILE) += sched-clock.o +ifneq ($(CONFIG_ARCH_INTEGRATOR),y) +obj-y += sched-clock.o +endif ifeq ($(CONFIG_LEDS_CLASS),y) obj-$(CONFIG_ARCH_REALVIEW) += leds.o obj-$(CONFIG_ARCH_VERSATILE) += leds.o -- cgit v1.2.3