On Tue, May 19, 2009 at 3:26 PM, Timur Tabi <ti...@freescale.com> 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 the result of the condition when the loop > was terminated. > > 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 just tried using this. The !rc has the effect of making the error return be zero instead the normal not zero. /* Wait for command send status zero = ready */ spin_event_timeout(!(in_be16(&psc_dma->psc_regs->sr_csr.status) & MPC52xx_PSC_SR_CMDSEND), 100, 0, rc); if (rc == 0) { pr_err("timeout on ac97 bus (rdy)\n"); return -ENODEV; } I want the register to be zero, would this be more obvious? /* Wait for command send status zero = ready */ spin_event_timeout((in_be16(&psc_dma->psc_regs->sr_csr.status) & MPC52xx_PSC_SR_CMDSEND), 100, 0, rc); if (rc != 0) { pr_err("timeout on ac97 bus (rdy)\n"); return -ENODEV; } > > Signed-off-by: Timur Tabi <ti...@freescale.com> > --- > > v8: added a copyright notice > > arch/powerpc/include/asm/delay.h | 33 +++++++++++++++++++++++++++++++++ > 1 files changed, 33 insertions(+), 0 deletions(-) > > diff --git a/arch/powerpc/include/asm/delay.h > b/arch/powerpc/include/asm/delay.h > index f9200a6..af4a270 100644 > --- a/arch/powerpc/include/asm/delay.h > +++ b/arch/powerpc/include/asm/delay.h > @@ -2,8 +2,11 @@ > #define _ASM_POWERPC_DELAY_H > #ifdef __KERNEL__ > > +#include <asm/time.h> > + > /* > * Copyright 1996, Paul Mackerras. > + * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved. > * > * This program is free software; you can redistribute it and/or > * modify it under the terms of the GNU General Public License > @@ -30,5 +33,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 > + * @delay: the number of microseconds to delay between eache evaluation of > + * @condition > + * @rc: the last value of the condition > + * > + * The process spins until the condition evaluates to true (non-zero) or the > + * timeout elapses. Upon exit, @rc contains the value of the condition. This > + * allows you to test the condition without incurring any side effects. > + * > + * 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 even if the bit never changes. The delay is for devices that > + * need a delay in between successive reads. > + * > + * gcc will optimize out the if-statement if @delay is a constant. > + */ > +#define spin_event_timeout(condition, timeout, delay, rc) \ > +{ \ > + unsigned long __loops = tb_ticks_per_usec * timeout; \ > + unsigned long __start = get_tbl(); \ > + while (!(rc = (condition)) && (tb_ticks_since(__start) <= __loops)) \ > + if (delay) \ > + udelay(delay); \ > + else \ > + cpu_relax(); \ > +} > + > #endif /* __KERNEL__ */ > #endif /* _ASM_POWERPC_DELAY_H */ > -- > 1.6.0.6 > > _______________________________________________ > Linuxppc-dev mailing list > Linuxppc-dev@ozlabs.org > https://ozlabs.org/mailman/listinfo/linuxppc-dev > -- Jon Smirl jonsm...@gmail.com _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev