On Tue, 2009-03-10 at 17:11 -0500, Timur Tabi wrote: > The macro spin_event_timeout() takes a condition and timeout value > (in microseconds) as parameters. It spins until either the condition is true > or the timeout expires. It returns zero if the timeout expires first, > non-zero > otherwise. > > This primary purpose of this macro is to poll on a hardware register until a > status bit changes. The timeout ensures that the loop still terminates if the > bit doesn't change as expected. This macro makes it easier for driver > developers to perform this kind of operation properly.
I've missed the history here but why is that arch code ? it could be used by more drivers... though there's always the idea that spinning is bad :-) Cheers, Ben. > Signed-off-by: Timur Tabi <ti...@freescale.com> > --- > > v5: ported to arch/powerpc, made it powerpc-specific, eliminated udelay > > v4: removed cpu_relax (redundant), changed timeout to unsigned long > > v3: eliminated secondary evaluation of condition, replaced jiffies with udelay > > v2: added cpu_relax and time_before > > arch/powerpc/include/asm/delay.h | 32 ++++++++++++++++++++++++++++++++ > 1 files changed, 32 insertions(+), 0 deletions(-) > > diff --git a/arch/powerpc/include/asm/delay.h > b/arch/powerpc/include/asm/delay.h > index f9200a6..aadec70 100644 > --- a/arch/powerpc/include/asm/delay.h > +++ b/arch/powerpc/include/asm/delay.h > @@ -2,6 +2,8 @@ > #define _ASM_POWERPC_DELAY_H > #ifdef __KERNEL__ > > +#include <asm/time.h> > + > /* > * Copyright 1996, Paul Mackerras. > * > @@ -30,5 +32,35 @@ extern void udelay(unsigned long usecs); > #define mdelay(n) udelay((n) * 1000) > #endif > > +/** > + * spin_event_timeout - spin until a condition gets true or a timeout elapses > + * @condition: a C expression to evalate > + * @timeout: timeout, in microseconds > + * > + * The process spins until the @condition evaluates to true (non-zero) or > + * the @timeout elapses. > + * > + * This primary purpose of this macro is to poll on a hardware register > + * until a status bit changes. The timeout ensures that the loop still > + * terminates if the bit never changes. > + * > + * The return value is non-zero if the condition evaluates to true first, or > + * zero if the timeout elapses first. > + */ > +#define spin_event_timeout(condition, timeout) \ > +({ \ > + unsigned long __start = get_tbl(); \ > + unsigned long __loops = tb_ticks_per_usec * timeout; \ > + int __ret = 1; \ > + while (!(condition)) { \ > + if (tb_ticks_since(__start) > __loops) { \ > + __ret = 0; \ > + break; \ > + } \ > + cpu_relax(); \ > + } \ > + __ret; \ > +}) > + > #endif /* __KERNEL__ */ > #endif /* _ASM_POWERPC_DELAY_H */ _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev