diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2017-01-24 10:23:42 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-02-01 08:33:08 +0100 |
commit | 9d5f2c151ec01949e4cc02333bc843b128110f55 (patch) | |
tree | 64475960cd90d1cb8ac8e5dec8528c8f4d12ff50 /arch | |
parent | 50f5972cc23179e90e8452998bcb609694a9d927 (diff) |
ARC: udelay: fix inline assembler by adding LP_COUNT to clobber list
commit 36425cd67052e3becf325fd4d3ba5691791ef7e4 upstream.
commit 3c7c7a2fc8811bc ("ARC: Don't use "+l" inline asm constraint")
modified the inline assembly to setup LP_COUNT register manually and NOT
rely on gcc to do it (with the +l inline assembler contraint hint, now
being retired in the compiler)
However the fix was flawed as we didn't add LP_COUNT to asm clobber list,
meaning gcc doesn't know that LP_COUNT or zero-delay-loops are in action
in the inline asm.
This resulted in some fun - as nested ZOL loops were being generared
| mov lp_count,250000 ;16 # tmp235,
| lp .L__GCC__LP14 # <======= OUTER LOOP (gcc generated)
| .L14:
| ld r2, [r5] # MEM[(volatile u32 *)prephitmp_43], w
| dmb 1
| breq r2, -1, @.L21 #, w,,
| bbit0 r2,1,@.L13 # w,,
| ld r4,[r7] ;25 # loops_per_jiffy, loops_per_jiffy
| mpymu r3,r4,r6 #, loops_per_jiffy, tmp234
|
| mov lp_count, r3 # <====== INNER LOOP (from inline asm)
| lp 1f
| nop
| 1:
| nop_s
| .L__GCC__LP14: ; loop end, start is @.L14 #,
This caused issues with drivers relying on sane behaviour of udelay
friends.
With LP_COUNT added to clobber list, gcc doesn't generate the outer
loop in say above case.
Addresses STAR 9001146134
Reported-by: Joao Pinto <jpinto@synopsys.com>
Fixes: 3c7c7a2fc8811bc ("ARC: Don't use "+l" inline asm constraint")
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arc/include/asm/delay.h | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/arch/arc/include/asm/delay.h b/arch/arc/include/asm/delay.h index a36e8601114d..d5da2115d78a 100644 --- a/arch/arc/include/asm/delay.h +++ b/arch/arc/include/asm/delay.h @@ -26,7 +26,9 @@ static inline void __delay(unsigned long loops) " lp 1f \n" " nop \n" "1: \n" - : : "r"(loops)); + : + : "r"(loops) + : "lp_count"); } extern void __bad_udelay(void); |