[PATCH 1/2 v8] powerpc: introduce macro spin_event_timeout()
Jon Smirl
jonsmirl at gmail.com
Tue May 26 03:46:47 EST 2009
On Tue, May 19, 2009 at 3:26 PM, Timur Tabi <timur at 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 <timur at 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 at ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>
--
Jon Smirl
jonsmirl at gmail.com
More information about the Linuxppc-dev
mailing list