aspeed/i2c: interrupts should be cleared by software only

aspeed i2c interrupts should be cleared by software only, and the bus
interrupt should be lowered when all interrupts have been cleared.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-id: 20180914063506.20815-2-clg@kaod.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
[PMM: drop TODO comment describing an issue which is
 fixed later in the patch series, and clean up commit message]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Cédric Le Goater 2018-09-25 14:02:31 +01:00 committed by Peter Maydell
parent b148ed4665
commit 5540cb97f7

View File

@ -52,6 +52,13 @@
#define I2CD_AC_TIMING_REG2 0x08 /* Clock and AC Timing Control #1 */
#define I2CD_INTR_CTRL_REG 0x0c /* I2CD Interrupt Control */
#define I2CD_INTR_STS_REG 0x10 /* I2CD Interrupt Status */
#define I2CD_INTR_SLAVE_ADDR_MATCH (0x1 << 31) /* 0: addr1 1: addr2 */
#define I2CD_INTR_SLAVE_ADDR_RX_PENDING (0x1 << 30)
/* bits[19-16] Reserved */
/* All bits below are cleared by writing 1 */
#define I2CD_INTR_SLAVE_INACTIVE_TIMEOUT (0x1 << 15)
#define I2CD_INTR_SDA_DL_TIMEOUT (0x1 << 14)
#define I2CD_INTR_BUS_RECOVER_DONE (0x1 << 13)
#define I2CD_INTR_SMBUS_ALERT (0x1 << 12) /* Bus [0-3] only */
@ -59,7 +66,7 @@
#define I2CD_INTR_SMBUS_DEV_ALERT_ADDR (0x1 << 10) /* Removed */
#define I2CD_INTR_SMBUS_DEF_ADDR (0x1 << 9) /* Removed */
#define I2CD_INTR_GCALL_ADDR (0x1 << 8) /* Removed */
#define I2CD_INTR_SLAVE_MATCH (0x1 << 7) /* use RX_DONE */
#define I2CD_INTR_SLAVE_ADDR_RX_MATCH (0x1 << 7) /* use RX_DONE */
#define I2CD_INTR_SCL_TIMEOUT (0x1 << 6)
#define I2CD_INTR_ABNORMAL (0x1 << 5)
#define I2CD_INTR_NORMAL_STOP (0x1 << 4)
@ -188,7 +195,6 @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
{
bus->cmd &= ~0xFFFF;
bus->cmd |= value & 0xFFFF;
bus->intr_status = 0;
if (bus->cmd & I2CD_M_START_CMD) {
uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
@ -284,8 +290,10 @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
break;
case I2CD_INTR_STS_REG:
bus->intr_status &= ~(value & 0x7FFF);
bus->controller->intr_status &= ~(1 << bus->id);
qemu_irq_lower(bus->controller->irq);
if (!bus->intr_status) {
bus->controller->intr_status &= ~(1 << bus->id);
qemu_irq_lower(bus->controller->irq);
}
break;
case I2CD_DEV_ADDR_REG:
qemu_log_mask(LOG_UNIMP, "%s: slave mode not implemented\n",