Will Deacon
2012-06-20 14:10:22 UTC
If the counter overflows during a __delay operation, we will exit the
loop prematurely. For example, calling __delay(0x100) with the counter
at 0xffffff00 gives us a target of 0x0. The unsigned comparison in the
while loop will likely be false on the first iteration (if the counter
is now anything other than 0) and we will return early.
This patch fixes the problem by comparing deltas in the loop rather than
absolute values.
Cc: Jon Masters <jcm at redhat.com>
Signed-off-by: Will Deacon <will.deacon at arm.com>
---
arch/openrisc/lib/delay.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/openrisc/lib/delay.c b/arch/openrisc/lib/delay.c
index 0c12407..c330767 100644
--- a/arch/openrisc/lib/delay.c
+++ b/arch/openrisc/lib/delay.c
@@ -30,9 +30,9 @@ int __devinit read_current_timer(unsigned long *timer_value)
void __delay(unsigned long cycles)
{
- cycles_t target = get_cycles() + cycles;
+ cycles_t start = get_cycles();
- while (get_cycles() < target)
+ while ((get_cycles() - start) < cycles)
cpu_relax();
}
EXPORT_SYMBOL(__delay);
loop prematurely. For example, calling __delay(0x100) with the counter
at 0xffffff00 gives us a target of 0x0. The unsigned comparison in the
while loop will likely be false on the first iteration (if the counter
is now anything other than 0) and we will return early.
This patch fixes the problem by comparing deltas in the loop rather than
absolute values.
Cc: Jon Masters <jcm at redhat.com>
Signed-off-by: Will Deacon <will.deacon at arm.com>
---
arch/openrisc/lib/delay.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/openrisc/lib/delay.c b/arch/openrisc/lib/delay.c
index 0c12407..c330767 100644
--- a/arch/openrisc/lib/delay.c
+++ b/arch/openrisc/lib/delay.c
@@ -30,9 +30,9 @@ int __devinit read_current_timer(unsigned long *timer_value)
void __delay(unsigned long cycles)
{
- cycles_t target = get_cycles() + cycles;
+ cycles_t start = get_cycles();
- while (get_cycles() < target)
+ while ((get_cycles() - start) < cycles)
cpu_relax();
}
EXPORT_SYMBOL(__delay);
--
1.7.4.1
1.7.4.1