|
@@ -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 */
|