summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2014-08-08 11:42:18 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-08-09 02:38:05 +0000
commitc366c20899358d21971d364cfefeb1cba725b799 (patch)
treeef42600dc30c30969b078d0fa67d586313f5c8b0
parent0815df9cbf1104a2c7fabdd4197358d54cdc8922 (diff)
downloadchrome-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>
-rw-r--r--common/host_command_master.c7
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);