aspeed/i2c: Handle receive command in separate function
Receive command handling may have to be deferred if a previous receive done interrupt was not yet acknowledged. Move receive command handling into a separate function to prepare for the necessary changes. Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Cédric Le Goater <clg@kaod.org> Message-id: 20180914063506.20815-3-clg@kaod.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
5540cb97f7
commit
7bd9c60d4e
@ -187,6 +187,26 @@ static uint8_t aspeed_i2c_get_state(AspeedI2CBus *bus)
|
||||
return (bus->cmd >> I2CD_TX_STATE_SHIFT) & I2CD_TX_STATE_MASK;
|
||||
}
|
||||
|
||||
static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus)
|
||||
{
|
||||
int ret;
|
||||
|
||||
aspeed_i2c_set_state(bus, I2CD_MRXD);
|
||||
ret = i2c_recv(bus->bus);
|
||||
if (ret < 0) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: read failed\n", __func__);
|
||||
ret = 0xff;
|
||||
} else {
|
||||
bus->intr_status |= I2CD_INTR_RX_DONE;
|
||||
}
|
||||
bus->buf = (ret & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
|
||||
if (bus->cmd & I2CD_M_S_RX_CMD_LAST) {
|
||||
i2c_nack(bus->bus);
|
||||
}
|
||||
bus->cmd &= ~(I2CD_M_RX_CMD | I2CD_M_S_RX_CMD_LAST);
|
||||
aspeed_i2c_set_state(bus, I2CD_MACTIVE);
|
||||
}
|
||||
|
||||
/*
|
||||
* The state machine needs some refinement. It is only used to track
|
||||
* invalid STOP commands for the moment.
|
||||
@ -233,22 +253,7 @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
|
||||
}
|
||||
|
||||
if (bus->cmd & (I2CD_M_RX_CMD | I2CD_M_S_RX_CMD_LAST)) {
|
||||
int ret;
|
||||
|
||||
aspeed_i2c_set_state(bus, I2CD_MRXD);
|
||||
ret = i2c_recv(bus->bus);
|
||||
if (ret < 0) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: read failed\n", __func__);
|
||||
ret = 0xff;
|
||||
} else {
|
||||
bus->intr_status |= I2CD_INTR_RX_DONE;
|
||||
}
|
||||
bus->buf = (ret & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
|
||||
if (bus->cmd & I2CD_M_S_RX_CMD_LAST) {
|
||||
i2c_nack(bus->bus);
|
||||
}
|
||||
bus->cmd &= ~(I2CD_M_RX_CMD | I2CD_M_S_RX_CMD_LAST);
|
||||
aspeed_i2c_set_state(bus, I2CD_MACTIVE);
|
||||
aspeed_i2c_handle_rx_cmd(bus);
|
||||
}
|
||||
|
||||
if (bus->cmd & I2CD_M_STOP_CMD) {
|
||||
|
Loading…
Reference in New Issue
Block a user