From 439164663e5d1753360ff84ea4d5c598459e5d50 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Tue, 7 Aug 2012 17:59:53 +0100 Subject: openrisc: delay: fix loops calculation for __const_udelay The openrisc implementation of __const_udelay casts the result of a 32-bit multiplication to 64 bits and passes the top 32 bits to __delay. Since there are no casts on the arguments, this results in a __delay of zero, regardless of the xloops parameter. This patch fixes the problem by casting xloops to (unsigned long long), ensuring that the multiplication is not truncated. Cc: Jon Masters Signed-off-by: Will Deacon Signed-off-by: Jonas Bonn --- arch/openrisc/lib/delay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/openrisc/lib/delay.c') diff --git a/arch/openrisc/lib/delay.c b/arch/openrisc/lib/delay.c index 01d9740ae6f..0c12407d3d5 100644 --- a/arch/openrisc/lib/delay.c +++ b/arch/openrisc/lib/delay.c @@ -41,7 +41,7 @@ inline void __const_udelay(unsigned long xloops) { unsigned long long loops; - loops = xloops * loops_per_jiffy * HZ; + loops = (unsigned long long)xloops * loops_per_jiffy * HZ; __delay(loops >> 32); } -- cgit v1.2.3-70-g09d2 From 807607f79b9d0ed81561746e4e1121905e75cf0f Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Tue, 7 Aug 2012 17:59:54 +0100 Subject: openrisc: delay: fix handling of counter overflow 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 Signed-off-by: Will Deacon Signed-off-by: Jonas Bonn --- arch/openrisc/lib/delay.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/openrisc/lib/delay.c') diff --git a/arch/openrisc/lib/delay.c b/arch/openrisc/lib/delay.c index 0c12407d3d5..c330767c921 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); -- cgit v1.2.3-70-g09d2