[PATCH 2/2] ARM: delay: allow timer-based delay implementation to be selected
Will Deacon
will.deacon at arm.com
Tue Jun 26 06:49:44 EDT 2012
On Mon, Jun 25, 2012 at 10:39:10PM +0100, Stephen Boyd wrote:
> On 06/22/12 08:09, Will Deacon wrote:
> > diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c
> > index dbbeec4..675cee0 100644
> > --- a/arch/arm/kernel/arch_timer.c
> > +++ b/arch/arm/kernel/arch_timer.c
> > @@ -32,6 +32,8 @@ static int arch_timer_ppi2;
> >
> > static struct clock_event_device __percpu **arch_timer_evt;
> >
> > +extern void init_current_timer_delay(unsigned long freq);
>
> Can we find a home for this in some header file?
I wondered about that...
The reason I didn't add it to a header file is that we really don't want it
to be called willy-nilly across the kernel. In fact, it must be called
exactly once by the clocksource backing read_current_timer when it knows
that the timer is live and ticking.
I suppose I could allow the function to fail if it's called after we've
calibrated. What do you reckon?
> > +static void __timer_const_udelay(unsigned long xloops)
> > +{
> > + unsigned long long loops = xloops;
> > + loops *= loops_per_jiffy;
> > + __timer_delay(loops >> 30);
> > +}
>
> Is it ok to have a 64 bit multiply here? It seems the assembly version
> tries to keep it all 32 bit math.
It's actually a 32-bit multiply with a 64-bit result, so it's just a umull:
00000050 <__timer_const_udelay>:
50: e3003000 movw r3, #0
54: e3403000 movt r3, #0
58: e5932000 ldr r2, [r3]
5c: e0832290 umull r2, r3, r0, r2
60: e1a00f22 lsr r0, r2, #30
64: e1800103 orr r0, r0, r3, lsl #2
68: eaffffe4 b 0 <__timer_delay>
> > +
> > +static void __timer_udelay(unsigned long usecs)
> > +{
> > + __timer_const_udelay(usecs * ((2199023U * HZ) >> 11));
> > +}
>
> It's unfortunate that we have to duplicate the same code and constants
> in both C and assembly. With my approach we convert delay.S into C and
> avoid the duplication.
It's probably easy enough to have a #define for the multiplier, I can do
that for v2.
> > +
> > +void __init init_current_timer_delay(unsigned long freq)
> > +{
> > + pr_info("Switching to timer-based delay loop\n");
>
> Might be worth printing the frequency here too.
Could do, but the timer itself probably prints that information already (at
least it does the arch timer).
Cheers,
Will
More information about the linux-arm-kernel
mailing list