@@ -558,10 +558,15 @@ static void p8_i2c_status_data_request(struct p8_i2c_master *master,
rc = p8_i2c_fifo_write(master, master->obuf,
req->offset_bytes);
}
+
+ /* For read, wait address phase to complete */
+ if (rc || req->op != SMBUS_WRITE)
+ break;
+
/* For writes, transition to data phase now */
- if (rc == 0 && req->op == SMBUS_WRITE)
- master->state = state_data;
- break;
+ master->state = state_data;
+ fifo_free -= req->offset_bytes;
+ /* Fall through */
case state_data:
/* Sanity check */
if (master->bytes_sent >= req->rw_len) {
@@ -583,6 +588,11 @@ static void p8_i2c_status_data_request(struct p8_i2c_master *master,
count = fifo_count;
rc = p8_i2c_fifo_read(master, buf, count);
} else {
+ /* Delay the data transfer if the slave isn't ready */
+ if ((status & I2C_STAT_SCL_INPUT_LEVEL) ||
+ !(status & I2C_STAT_SDA_INPUT_LEVEL))
+ break;
+
if (count > fifo_free)
count = fifo_free;
rc = p8_i2c_fifo_write(master, buf, count);
Different from SMBUS_READ, SMBUS_WRITE needn't wait for ACK from slave device after sending register offset. That means the register offset and data can be sent to I2C bus in one shoot if the FIFO has enough spare space. However, the code isn't doing this. The patch fixes it to get a bit more performance for SMBUS_WRITE. Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com> --- hw/p8-i2c.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)