diff options
author | Scott <scollyer@chromium.org> | 2016-09-08 18:43:10 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-09-12 19:53:32 -0700 |
commit | c5c14ef348bf5203975d6ccc6cc6af918ef4b577 (patch) | |
tree | 33bb1971ad557ef026a48774fc0115e7d5bbcd04 /chip | |
parent | 017606c927ccde36cf39a299170f85df8f3de402 (diff) | |
download | chrome-ec-c5c14ef348bf5203975d6ccc6cc6af918ef4b577.tar.gz |
Cr50: I2CS: Clear IRQ at beginning of ISR
If the host sends a back to back I2CS write followed by a read of the
access register, then the read IRQ can be missed by FW because it was
clearing this bit at the end of the ISR. This would result in a
following write to have the incorrect number of bytes since the
address register byte from the read that wasn't processed gets left in
the HW write fifo.
BRANCH=none
BUG=chrome-os-partner:40397
TEST=manual
The issue was happening at the beginning of depthcharge. Without this
fix, I would see the Cr50 console message:
'data size mismatch for reg 0x0 rx 2, need 1'
After moving the IRQ clear could not reproduce this message. In
addition, the debug I2CS log showed that there was a read transaction
immediately following the write.
Change-Id: I9854dde6880a789e0acb2b1f6a06b43c73a5a2df
Signed-off-by: Scott <scollyer@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/382687
Commit-Ready: Scott Collyer <scollyer@chromium.org>
Tested-by: Scott Collyer <scollyer@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/g/i2cs.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/chip/g/i2cs.c b/chip/g/i2cs.c index e53702f89d..77a39a5a1e 100644 --- a/chip/g/i2cs.c +++ b/chip/g/i2cs.c @@ -119,6 +119,9 @@ DECLARE_HOOK(HOOK_INIT, i2cs_init, HOOK_PRIO_DEFAULT); /* Process the 'end of a write cycle' interrupt. */ static void _i2cs_write_complete_int(void) { + /* Reset the IRQ condition. */ + GWRITE_FIELD(I2CS, INT_STATE, INTR_WRITE_COMPLETE, 1); + if (write_complete_handler_) { uint16_t bytes_written; uint16_t bytes_processed; @@ -164,9 +167,6 @@ static void _i2cs_write_complete_int(void) /* Invoke the callback to process the message. */ write_complete_handler_(i2cs_buffer, bytes_processed); } - - /* Reset the IRQ condition. */ - GWRITE_FIELD(I2CS, INT_STATE, INTR_WRITE_COMPLETE, 1); } DECLARE_IRQ(GC_IRQNUM_I2CS0_INTR_WRITE_COMPLETE_INT, _i2cs_write_complete_int, 1); |