diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-eg20t.c')
-rw-r--r-- | drivers/i2c/busses/i2c-eg20t.c | 44 |
1 files changed, 21 insertions, 23 deletions
diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c index ca8877641040..f086131cb1c7 100644 --- a/drivers/i2c/busses/i2c-eg20t.c +++ b/drivers/i2c/busses/i2c-eg20t.c | |||
@@ -271,30 +271,36 @@ static inline bool ktime_lt(const ktime_t cmp1, const ktime_t cmp2) | |||
271 | /** | 271 | /** |
272 | * pch_i2c_wait_for_bus_idle() - check the status of bus. | 272 | * pch_i2c_wait_for_bus_idle() - check the status of bus. |
273 | * @adap: Pointer to struct i2c_algo_pch_data. | 273 | * @adap: Pointer to struct i2c_algo_pch_data. |
274 | * @timeout: waiting time counter (us). | 274 | * @timeout: waiting time counter (ms). |
275 | */ | 275 | */ |
276 | static s32 pch_i2c_wait_for_bus_idle(struct i2c_algo_pch_data *adap, | 276 | static s32 pch_i2c_wait_for_bus_idle(struct i2c_algo_pch_data *adap, |
277 | s32 timeout) | 277 | s32 timeout) |
278 | { | 278 | { |
279 | void __iomem *p = adap->pch_base_address; | 279 | void __iomem *p = adap->pch_base_address; |
280 | ktime_t ns_val; | 280 | int schedule = 0; |
281 | unsigned long end = jiffies + msecs_to_jiffies(timeout); | ||
282 | |||
283 | while (ioread32(p + PCH_I2CSR) & I2CMBB_BIT) { | ||
284 | if (time_after(jiffies, end)) { | ||
285 | pch_dbg(adap, "I2CSR = %x\n", ioread32(p + PCH_I2CSR)); | ||
286 | pch_err(adap, "%s: Timeout Error.return%d\n", | ||
287 | __func__, -ETIME); | ||
288 | pch_i2c_init(adap); | ||
281 | 289 | ||
282 | if ((ioread32(p + PCH_I2CSR) & I2CMBB_BIT) == 0) | 290 | return -ETIME; |
283 | return 0; | 291 | } |
284 | 292 | ||
285 | /* MAX timeout value is timeout*1000*1000nsec */ | 293 | if (!schedule) |
286 | ns_val = ktime_add_ns(ktime_get(), timeout*1000*1000); | 294 | /* Retry after some usecs */ |
287 | do { | 295 | udelay(5); |
288 | msleep(20); | 296 | else |
289 | if ((ioread32(p + PCH_I2CSR) & I2CMBB_BIT) == 0) | 297 | /* Wait a bit more without consuming CPU */ |
290 | return 0; | 298 | usleep_range(20, 1000); |
291 | } while (ktime_lt(ktime_get(), ns_val)); | ||
292 | 299 | ||
293 | pch_dbg(adap, "I2CSR = %x\n", ioread32(p + PCH_I2CSR)); | 300 | schedule = 1; |
294 | pch_err(adap, "%s: Timeout Error.return%d\n", __func__, -ETIME); | 301 | } |
295 | pch_i2c_init(adap); | ||
296 | 302 | ||
297 | return -ETIME; | 303 | return 0; |
298 | } | 304 | } |
299 | 305 | ||
300 | /** | 306 | /** |
@@ -778,8 +784,6 @@ static s32 pch_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
778 | struct i2c_msg *pmsg; | 784 | struct i2c_msg *pmsg; |
779 | u32 i = 0; | 785 | u32 i = 0; |
780 | u32 status; | 786 | u32 status; |
781 | u32 msglen; | ||
782 | u32 subaddrlen; | ||
783 | s32 ret; | 787 | s32 ret; |
784 | 788 | ||
785 | struct i2c_algo_pch_data *adap = i2c_adap->algo_data; | 789 | struct i2c_algo_pch_data *adap = i2c_adap->algo_data; |
@@ -804,12 +808,6 @@ static s32 pch_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
804 | status = pmsg->flags; | 808 | status = pmsg->flags; |
805 | pch_dbg(adap, | 809 | pch_dbg(adap, |
806 | "After invoking I2C_MODE_SEL :flag= 0x%x\n", status); | 810 | "After invoking I2C_MODE_SEL :flag= 0x%x\n", status); |
807 | /* calculate sub address length and message length */ | ||
808 | /* these are applicable only for buffer mode */ | ||
809 | subaddrlen = pmsg->buf[0]; | ||
810 | /* calculate actual message length excluding | ||
811 | * the sub address fields */ | ||
812 | msglen = (pmsg->len) - (subaddrlen + 1); | ||
813 | 811 | ||
814 | if ((status & (I2C_M_RD)) != false) { | 812 | if ((status & (I2C_M_RD)) != false) { |
815 | ret = pch_i2c_readbytes(i2c_adap, pmsg, (i + 1 == num), | 813 | ret = pch_i2c_readbytes(i2c_adap, pmsg, (i + 1 == num), |