| 
									
										
										
										
											2005-11-14 17:22:01 +11:00
										 |  |  | #ifndef _ASM_POWERPC_DELAY_H
 | 
					
						
							|  |  |  | #define _ASM_POWERPC_DELAY_H
 | 
					
						
							| 
									
										
										
										
											2005-12-16 22:43:46 +01:00
										 |  |  | #ifdef __KERNEL__
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-26 05:21:41 +00:00
										 |  |  | #include <asm/time.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright 1996, Paul Mackerras. | 
					
						
							| 
									
										
										
										
											2009-05-26 05:21:41 +00:00
										 |  |  |  * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved. | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version | 
					
						
							|  |  |  |  * 2 of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * PPC64 Support added by Dave Engebretsen, Todd Inglett, Mike Corrigan, | 
					
						
							|  |  |  |  * Anton Blanchard. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-18 13:44:17 +11:00
										 |  |  | extern void __delay(unsigned long loops); | 
					
						
							|  |  |  | extern void udelay(unsigned long usecs); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-15 14:11:22 +10:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * On shared processor machines the generic implementation of mdelay can | 
					
						
							|  |  |  |  * result in large errors. While each iteration of the loop inside mdelay | 
					
						
							|  |  |  |  * is supposed to take 1ms, the hypervisor could sleep our partition for | 
					
						
							|  |  |  |  * longer (eg 10ms). With the right timing these errors can add up. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Since there is no 32bit overflow issue on 64bit kernels, just call | 
					
						
							|  |  |  |  * udelay directly. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #ifdef CONFIG_PPC64
 | 
					
						
							|  |  |  | #define mdelay(n)	udelay((n) * 1000)
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-26 05:21:41 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * 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();                                           \ | 
					
						
							| 
									
										
										
										
											2009-06-29 13:40:51 +00:00
										 |  |  | 	if (!__ret)                                                            \ | 
					
						
							|  |  |  | 		__ret = (condition);                                           \ | 
					
						
							| 
									
										
										
										
											2009-05-26 05:21:41 +00:00
										 |  |  | 	__ret;		                                                       \ | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-16 22:43:46 +01:00
										 |  |  | #endif /* __KERNEL__ */
 | 
					
						
							| 
									
										
										
										
											2005-11-14 17:22:01 +11:00
										 |  |  | #endif /* _ASM_POWERPC_DELAY_H */
 |