Merge tag 'clksrc-cleanup-for-3.10-part2' of git://sources.calxeda.com/kernel/linux into late/clksrc
This is the 2nd part of ARM timer clean-ups for 3.10. This series has the following changes: - Add sched_clock selection logic to select the highest frequency clock - Use full 64-bit arch timer counter for sched_clock - Convert arch timer, sp804 and integrator-cp timers to CLKSRC_OF and adapt all users to use clocksource_of_init * tag 'clksrc-cleanup-for-3.10-part2' of git://sources.calxeda.com/kernel/linux: devtree: add binding documentation for sp804 ARM: integrator-cp: convert use CLKSRC_OF for timer init ARM: versatile: use OF init for sp804 timer ARM: versatile: add versatile dtbs to dtbs target ARM: vexpress: remove extra timer-sp control register clearing ARM: dts: vexpress: disable CA9 core tile sp804 timer ARM: vexpress: remove sp804 OF init ARM: highbank: use OF init for sp804 timer ARM: timer-sp: convert to use CLKSRC_OF init OF: add empty of_device_is_available for !OF ARM: convert arm/arm64 arch timer to use CLKSRC_OF init ARM: make machine_desc->init_time default to clocksource_of_init ARM: arch_timer: use full 64-bit counter for sched_clock ARM: make sched_clock just call a function pointer ARM: sched_clock: allow changing to higher frequency counter Signed-off-by: Olof Johansson <olof@lixom.net> This has a nasty set of conflicts with the exynos MCT code, which was moved in a separate branch, and then fixed up when merged in, but still conflicts a bit here. It should have been sorted out by this merge though.
This commit is contained in:
@@ -22,9 +22,11 @@ static unsigned long arch_timer_read_counter_long(void)
|
||||
return arch_timer_read_counter();
|
||||
}
|
||||
|
||||
static u32 arch_timer_read_counter_u32(void)
|
||||
static u32 sched_clock_mult __read_mostly;
|
||||
|
||||
static unsigned long long notrace arch_timer_sched_clock(void)
|
||||
{
|
||||
return arch_timer_read_counter();
|
||||
return arch_timer_read_counter() * sched_clock_mult;
|
||||
}
|
||||
|
||||
static struct delay_timer arch_delay_timer;
|
||||
@@ -37,25 +39,20 @@ static void __init arch_timer_delay_timer_register(void)
|
||||
register_current_timer_delay(&arch_delay_timer);
|
||||
}
|
||||
|
||||
int __init arch_timer_of_register(void)
|
||||
int __init arch_timer_arch_init(void)
|
||||
{
|
||||
int ret;
|
||||
u32 arch_timer_rate = arch_timer_get_rate();
|
||||
|
||||
ret = arch_timer_init();
|
||||
if (ret)
|
||||
return ret;
|
||||
if (arch_timer_rate == 0)
|
||||
return -ENXIO;
|
||||
|
||||
arch_timer_delay_timer_register();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init arch_timer_sched_clock_init(void)
|
||||
{
|
||||
if (arch_timer_get_rate() == 0)
|
||||
return -ENXIO;
|
||||
|
||||
setup_sched_clock(arch_timer_read_counter_u32,
|
||||
32, arch_timer_get_rate());
|
||||
/* Cache the sched_clock multiplier to save a divide in the hot path. */
|
||||
sched_clock_mult = NSEC_PER_SEC / arch_timer_rate;
|
||||
sched_clock_func = arch_timer_sched_clock;
|
||||
pr_info("sched_clock: ARM arch timer >56 bits at %ukHz, resolution %uns\n",
|
||||
arch_timer_rate / 1000, sched_clock_mult);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@ struct clock_data {
|
||||
u64 epoch_ns;
|
||||
u32 epoch_cyc;
|
||||
u32 epoch_cyc_copy;
|
||||
unsigned long rate;
|
||||
u32 mult;
|
||||
u32 shift;
|
||||
bool suspended;
|
||||
@@ -113,11 +114,14 @@ void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate)
|
||||
u64 res, wrap;
|
||||
char r_unit;
|
||||
|
||||
if (cd.rate > rate)
|
||||
return;
|
||||
|
||||
BUG_ON(bits > 32);
|
||||
WARN_ON(!irqs_disabled());
|
||||
WARN_ON(read_sched_clock != jiffy_sched_clock_read);
|
||||
read_sched_clock = read;
|
||||
sched_clock_mask = (1 << bits) - 1;
|
||||
cd.rate = rate;
|
||||
|
||||
/* calculate the mult/shift to convert counter ticks to ns. */
|
||||
clocks_calc_mult_shift(&cd.mult, &cd.shift, rate, NSEC_PER_SEC, 0);
|
||||
@@ -161,12 +165,19 @@ void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate)
|
||||
pr_debug("Registered %pF as sched_clock source\n", read);
|
||||
}
|
||||
|
||||
unsigned long long notrace sched_clock(void)
|
||||
static unsigned long long notrace sched_clock_32(void)
|
||||
{
|
||||
u32 cyc = read_sched_clock();
|
||||
return cyc_to_sched_clock(cyc, sched_clock_mask);
|
||||
}
|
||||
|
||||
unsigned long long __read_mostly (*sched_clock_func)(void) = sched_clock_32;
|
||||
|
||||
unsigned long long notrace sched_clock(void)
|
||||
{
|
||||
return sched_clock_func();
|
||||
}
|
||||
|
||||
void __init sched_clock_postinit(void)
|
||||
{
|
||||
/*
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/profile.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/irq.h>
|
||||
|
||||
#include <asm/thread_info.h>
|
||||
@@ -115,6 +116,10 @@ int __init register_persistent_clock(clock_access_fn read_boot,
|
||||
|
||||
void __init time_init(void)
|
||||
{
|
||||
machine_desc->init_time();
|
||||
if (machine_desc->init_time)
|
||||
machine_desc->init_time();
|
||||
else
|
||||
clocksource_of_init();
|
||||
|
||||
sched_clock_postinit();
|
||||
}
|
||||
|
Reference in New Issue
Block a user