From c366c20899358d21971d364cfefeb1cba725b799 Mon Sep 17 00:00:00 2001 From: Shawn Nematbakhsh Date: Fri, 8 Aug 2014 11:42:18 -0700 Subject: [PATCH] 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 Change-Id: Ie441637f499980a349022e281379ad2cc825b1aa Reviewed-on: https://chromium-review.googlesource.com/211649 Reviewed-by: Alec Berg Reviewed-by: Randall Spangler --- common/host_command_master.c | 7 +++++-- 1 file 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);