diff options
Diffstat (limited to 'arch/powerpc/include/asm/delay.h')
| -rw-r--r-- | arch/powerpc/include/asm/delay.h | 36 | 
1 files changed, 36 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/delay.h b/arch/powerpc/include/asm/delay.h index f9200a65c63..1e2eb41fa05 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,38 @@ 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 each evaluation of + *         @condition + * + * The process spins until the condition evaluates to true (non-zero) or the + * timeout elapses.  The return value of this macro is the value of + * @condition when the loop terminates. This allows you to determine the cause + * of the loop terminates.  If the return value is zero, then you know a + * timeout has occurred. + * + * 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)                          \ +({                                                                             \ +	typeof(condition) __ret;                                               \ +	unsigned long __loops = tb_ticks_per_usec * timeout;                   \ +	unsigned long __start = get_tbl();                                     \ +	while (!(__ret = (condition)) && (tb_ticks_since(__start) <= __loops)) \ +		if (delay)                                                     \ +			udelay(delay);                                         \ +		else                                                           \ +			cpu_relax();                                           \ +	__ret;		                                                       \ +}) +  #endif /* __KERNEL__ */  #endif /* _ASM_POWERPC_DELAY_H */  |