diff options
author | Shawn Nematbakhsh <shawnn@chromium.org> | 2014-08-08 11:42:18 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-08-09 02:38:05 +0000 |
commit | c366c20899358d21971d364cfefeb1cba725b799 (patch) | |
tree | ef42600dc30c30969b078d0fa67d586313f5c8b0 /common/host_command_master.c | |
parent | 0815df9cbf1104a2c7fabdd4197358d54cdc8922 (diff) | |
download | chrome-ec-c366c20899358d21971d364cfefeb1cba725b799.tar.gz |
Hold I2C lock through entire PD read transaction
I2C reads from the PD happen in two separate transactions, but no stop
condition is set after the first transcation. Therefore, it is necessary
to lock the I2C bus across both transactions to prevent other tasks
from using the bus in between.
BUG=chrome-os-partner:29839
TEST=Manual on Samus. Boot to recovery screen, plug + unplug power
supply, verify that no I2C error messages are printed to console.
Then repeat 100x.
BRANCH=None.
Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Change-Id: Ie441637f499980a349022e281379ad2cc825b1aa
Reviewed-on: https://chromium-review.googlesource.com/211649
Reviewed-by: Alec Berg <alecaberg@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'common/host_command_master.c')
-rw-r--r-- | common/host_command_master.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/common/host_command_master.c b/common/host_command_master.c index 15748d4e82..a669f22111 100644 --- a/common/host_command_master.c +++ b/common/host_command_master.c @@ -83,8 +83,8 @@ static int pd_host_command_internal(int command, int version, &req_buf[0], outsize + sizeof(rq) + 1, &resp_buf[0], 2, I2C_XFER_START); i2c_set_timeout(I2C_PORT_PD_MCU, 0); - i2c_lock(I2C_PORT_PD_MCU, 0); if (ret) { + i2c_lock(I2C_PORT_PD_MCU, 0); CPRINTF("[%T i2c transaction 1 failed: %d]\n", ret); return -ret; } @@ -97,13 +97,16 @@ static int pd_host_command_internal(int command, int version, ret); if (resp_len > (insize + sizeof(rs))) { + /* Do a dummy read to generate stop condition */ + i2c_xfer(I2C_PORT_PD_MCU, CONFIG_USB_PD_I2C_SLAVE_ADDR, + 0, 0, &resp_buf[2], 1, I2C_XFER_STOP); + i2c_lock(I2C_PORT_PD_MCU, 0); CPRINTF("[%T response size is too large %d > %d]\n", resp_len, insize + sizeof(rs)); return -EC_RES_RESPONSE_TOO_BIG; } /* Receive remaining data */ - i2c_lock(I2C_PORT_PD_MCU, 1); ret = i2c_xfer(I2C_PORT_PD_MCU, CONFIG_USB_PD_I2C_SLAVE_ADDR, 0, 0, &resp_buf[2], resp_len, I2C_XFER_STOP); i2c_lock(I2C_PORT_PD_MCU, 0); |