diff options
author | Jan Glauber <jglauber@cavium.com> | 2016-09-21 02:51:04 -0400 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2016-09-21 17:04:42 -0400 |
commit | 38caa925ee67d2359f45a4a9cd1afa2e23a9eece (patch) | |
tree | 830aa97b646f82ec4e519dfa194625abf572571f /drivers/i2c | |
parent | de919ff6a0060510b099405d9b8f9413aba9ae14 (diff) |
i2c: octeon: Fix high-level controller status check
In case the high-level controller (HLC) is used the status code is
reported at a different location. Check that location after HLC
write operations if the ready bit is not set and return an appropriate
error code instead of always returning -EAGAIN.
Signed-off-by: Jan Glauber <jglauber@cavium.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-octeon-core.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/drivers/i2c/busses/i2c-octeon-core.c b/drivers/i2c/busses/i2c-octeon-core.c index 7d4df8383b38..5e63b17f935d 100644 --- a/drivers/i2c/busses/i2c-octeon-core.c +++ b/drivers/i2c/busses/i2c-octeon-core.c | |||
@@ -215,7 +215,16 @@ static int octeon_i2c_hlc_wait(struct octeon_i2c *i2c) | |||
215 | 215 | ||
216 | static int octeon_i2c_check_status(struct octeon_i2c *i2c, int final_read) | 216 | static int octeon_i2c_check_status(struct octeon_i2c *i2c, int final_read) |
217 | { | 217 | { |
218 | u8 stat = octeon_i2c_stat_read(i2c); | 218 | u8 stat; |
219 | |||
220 | /* | ||
221 | * This is ugly... in HLC mode the status is not in the status register | ||
222 | * but in the lower 8 bits of SW_TWSI. | ||
223 | */ | ||
224 | if (i2c->hlc_enabled) | ||
225 | stat = __raw_readq(i2c->twsi_base + SW_TWSI(i2c)); | ||
226 | else | ||
227 | stat = octeon_i2c_stat_read(i2c); | ||
219 | 228 | ||
220 | switch (stat) { | 229 | switch (stat) { |
221 | /* Everything is fine */ | 230 | /* Everything is fine */ |
@@ -453,7 +462,7 @@ static int octeon_i2c_hlc_read(struct octeon_i2c *i2c, struct i2c_msg *msgs) | |||
453 | 462 | ||
454 | cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c)); | 463 | cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c)); |
455 | if ((cmd & SW_TWSI_R) == 0) | 464 | if ((cmd & SW_TWSI_R) == 0) |
456 | return -EAGAIN; | 465 | return octeon_i2c_check_status(i2c, false); |
457 | 466 | ||
458 | for (i = 0, j = msgs[0].len - 1; i < msgs[0].len && i < 4; i++, j--) | 467 | for (i = 0, j = msgs[0].len - 1; i < msgs[0].len && i < 4; i++, j--) |
459 | msgs[0].buf[j] = (cmd >> (8 * i)) & 0xff; | 468 | msgs[0].buf[j] = (cmd >> (8 * i)) & 0xff; |
@@ -506,9 +515,7 @@ static int octeon_i2c_hlc_write(struct octeon_i2c *i2c, struct i2c_msg *msgs) | |||
506 | 515 | ||
507 | cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c)); | 516 | cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c)); |
508 | if ((cmd & SW_TWSI_R) == 0) | 517 | if ((cmd & SW_TWSI_R) == 0) |
509 | return -EAGAIN; | 518 | return octeon_i2c_check_status(i2c, false); |
510 | |||
511 | ret = octeon_i2c_check_status(i2c, false); | ||
512 | 519 | ||
513 | err: | 520 | err: |
514 | return ret; | 521 | return ret; |
@@ -553,7 +560,7 @@ static int octeon_i2c_hlc_comp_read(struct octeon_i2c *i2c, struct i2c_msg *msgs | |||
553 | 560 | ||
554 | cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c)); | 561 | cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c)); |
555 | if ((cmd & SW_TWSI_R) == 0) | 562 | if ((cmd & SW_TWSI_R) == 0) |
556 | return -EAGAIN; | 563 | return octeon_i2c_check_status(i2c, false); |
557 | 564 | ||
558 | for (i = 0, j = msgs[1].len - 1; i < msgs[1].len && i < 4; i++, j--) | 565 | for (i = 0, j = msgs[1].len - 1; i < msgs[1].len && i < 4; i++, j--) |
559 | msgs[1].buf[j] = (cmd >> (8 * i)) & 0xff; | 566 | msgs[1].buf[j] = (cmd >> (8 * i)) & 0xff; |
@@ -617,9 +624,7 @@ static int octeon_i2c_hlc_comp_write(struct octeon_i2c *i2c, struct i2c_msg *msg | |||
617 | 624 | ||
618 | cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c)); | 625 | cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c)); |
619 | if ((cmd & SW_TWSI_R) == 0) | 626 | if ((cmd & SW_TWSI_R) == 0) |
620 | return -EAGAIN; | 627 | return octeon_i2c_check_status(i2c, false); |
621 | |||
622 | ret = octeon_i2c_check_status(i2c, false); | ||
623 | 628 | ||
624 | err: | 629 | err: |
625 | return ret; | 630 | return ret; |