Current __udelay implementation will cause internal overflow on the
first multiplication.
Basically, the multiplication is:
X = usecs * 2**64 / (100000 / HZ)
And maximum input usecs value is 5000 (MAX_UDELAY_MS * 1000).
If usecs == 5000 and HZ == 1000, X is 5 * 2**64. Of course this can
not be held in 64bit variable.
How should we avoid the overflow?
1. Use smaller HZ.
HZ < 200 should be OK.
2. Use smaller MAX_UDELAY_MS.
The arch specific delay.h can provide its own MAX_UDELAY_MS.
MAX_UDELAY_MS == 1 should be OK.
3. Use smaller multiplier.
This example should be OK (but lose some precision on larger HZ)
#if HZ < (1000 / MAX_UDELAY_MS)
usecs *= (0x8000000000000000UL / (500000 / HZ));
#elif HZ < ((1000 / MAX_UDELAY_MS) << 1)
usecs *= (0x8000000000000000UL / (500000 / HZ)) >> 1;
lpj <<= 1
#elif HZ < ((1000 / MAX_UDELAY_MS) << 2)
usecs *= (0x8000000000000000UL / (500000 / HZ)) >> 2;
lpj <<= 2
#else
usecs *= (0x8000000000000000UL / (500000 / HZ)) >> 3;
lpj <<= 3
#endif
Any idea?
---
Atsushi Nemoto
|