提交 b8e24343 编写于 作者: M Mark Rutland

arm: arch_timer: standardise counter reading

We're currently inconsistent with respect to our accesses to the
physical and virtual counters, mixing and matching the two.

This patch introduces and uses a function pointer for accessing the
correct counter based on whether we're using physical or virtual
interrupts. All current accesses to the counter accessors are redirected
through it.

When the driver is moved out to drivers/clocksource, there's the
possibility that code called before the timer code is initialised will
attempt to call arch_timer_read_counter (e.g. sched_clock for AArch64).
To avoid having to have to check whether the timer has been initialised
either in arch_timer_read_counter or one of it's callers, a default
implementation is assigned that simply returns 0.
Signed-off-by: NMark Rutland <mark.rutland@arm.com>
Acked-by: NCatalin Marinas <catalin.marinas@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
上级 ef01c1d1
...@@ -272,51 +272,37 @@ static int arch_timer_available(void) ...@@ -272,51 +272,37 @@ static int arch_timer_available(void)
return 0; return 0;
} }
static u32 notrace arch_counter_get_cntpct32(void) /*
{ * Some external users of arch_timer_read_counter (e.g. sched_clock) may try to
cycle_t cnt = arch_counter_get_cntpct(); * call it before it has been initialised. Rather than incur a performance
* penalty checking for initialisation, provide a default implementation that
/* * won't lead to time appearing to jump backwards.
* The sched_clock infrastructure only knows about counters
* with at most 32bits. Forget about the upper 24 bits for the
* time being...
*/ */
return (u32)cnt; static u64 arch_timer_read_zero(void)
{
return 0;
} }
static u32 notrace arch_counter_get_cntvct32(void) u64 (*arch_timer_read_counter)(void) = arch_timer_read_zero;
{
cycle_t cnt = arch_counter_get_cntvct();
/* static u32 arch_timer_read_counter32(void)
* The sched_clock infrastructure only knows about counters {
* with at most 32bits. Forget about the upper 24 bits for the return arch_timer_read_counter();
* time being...
*/
return (u32)cnt;
} }
static cycle_t arch_counter_read(struct clocksource *cs) static cycle_t arch_counter_read(struct clocksource *cs)
{ {
/* return arch_timer_read_counter();
* Always use the physical counter for the clocksource.
* CNTHCTL.PL1PCTEN must be set to 1.
*/
return arch_counter_get_cntpct();
} }
static unsigned long arch_timer_read_current_timer(void) static unsigned long arch_timer_read_current_timer(void)
{ {
return arch_counter_get_cntpct(); return arch_timer_read_counter();
} }
static cycle_t arch_counter_read_cc(const struct cyclecounter *cc) static cycle_t arch_counter_read_cc(const struct cyclecounter *cc)
{ {
/* return arch_timer_read_counter();
* Always use the physical counter for the clocksource.
* CNTHCTL.PL1PCTEN must be set to 1.
*/
return arch_counter_get_cntpct();
} }
static struct clocksource clocksource_counter = { static struct clocksource clocksource_counter = {
...@@ -484,23 +470,23 @@ int __init arch_timer_of_register(void) ...@@ -484,23 +470,23 @@ int __init arch_timer_of_register(void)
} }
} }
if (arch_timer_use_virtual)
arch_timer_read_counter = arch_counter_get_cntvct;
else
arch_timer_read_counter = arch_counter_get_cntpct;
return arch_timer_register(); return arch_timer_register();
} }
int __init arch_timer_sched_clock_init(void) int __init arch_timer_sched_clock_init(void)
{ {
u32 (*cnt32)(void);
int err; int err;
err = arch_timer_available(); err = arch_timer_available();
if (err) if (err)
return err; return err;
if (arch_timer_use_virtual) setup_sched_clock(arch_timer_read_counter32,
cnt32 = arch_counter_get_cntvct32; 32, arch_timer_rate);
else
cnt32 = arch_counter_get_cntpct32;
setup_sched_clock(cnt32, 32, arch_timer_rate);
return 0; return 0;
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册