diff options
author | Russell King | 2020-04-27 19:49:32 +0100 |
---|---|---|
committer | Wolfram Sang | 2020-05-05 14:51:07 +0200 |
commit | e896be5ad1017aa710f8b979036a43d3e5b2f38d (patch) | |
tree | 160e0981610356976de67a32851e3bf200d316bc /drivers | |
parent | bb82ba690757fb483b5848d3e2f577a102e8a9c8 (diff) |
i2c: pxa: fix i2c_pxa_wait_bus_not_busy() boundary condition
Fix i2c_pxa_wait_bus_not_busy()'s boundary conditions, so that a
coincidental success and timeout results in the function returning
success.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/i2c/busses/i2c-pxa.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 7aa35def464b..c1e50c0b9756 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -416,19 +416,26 @@ static void i2c_pxa_abort(struct pxa_i2c *i2c) static int i2c_pxa_wait_bus_not_busy(struct pxa_i2c *i2c) { int timeout = DEF_TIMEOUT; + u32 isr; - while (timeout-- && readl(_ISR(i2c)) & (ISR_IBB | ISR_UB)) { - if ((readl(_ISR(i2c)) & ISR_SAD) != 0) + while (1) { + isr = readl(_ISR(i2c)); + if (!(isr & (ISR_IBB | ISR_UB))) + return 0; + + if (isr & ISR_SAD) timeout += 4; + if (!timeout--) + break; + msleep(2); show_state(i2c); } - if (timeout < 0) - show_state(i2c); + show_state(i2c); - return timeout < 0 ? I2C_RETRY : 0; + return I2C_RETRY; } static int i2c_pxa_wait_master(struct pxa_i2c *i2c) |