The root cause is irqs come between PLL register reading
and getting system time, an interrupt handle could take
more than 2ms, which will make the time reading and register
reading unalignment, see below:
1. pll reg read, it is still not locked;
2. here comes an interrupt, and its handler could spent > 2ms;
3. time reading, found current time already > expiration time(1.2ms),
and we treated the pll lock fail;
There are two method could fix it, one is disable interrupt
during pll lock bit and time expiration check, the other is
to add a second time read after time expiration to make sure
the pll didn't lock during the time we set. I choose the seconde
choise, since it impacts kernel less than disable interrupt;
Signed-off-by: Anson Huang <b20788@freescale.com>
#define AUDIO_VIDEO_MIN_CLK_FREQ 650000000
#define AUDIO_VIDEO_MAX_CLK_FREQ 1300000000
+/* We need to check the exp status again after timer expiration,
+ * as there might be interrupt coming between the first time exp
+ * and the time reading, then the time reading may be several ms
+ * after the exp checking due to the irq handle, so we need to
+ * check it to make sure the exp return the right value after
+ * timer expiration. */
#define WAIT(exp, timeout) \
({ \
struct timespec nstimeofday; \
while (!(exp)) { \
getnstimeofday(&curtime); \
if ((curtime.tv_nsec - nstimeofday.tv_nsec) > (timeout)) { \
- result = 0; \
+ if (!(exp)) \
+ result = 0; \
break; \
} \
} \