[PATCH] aspeed/i2c: lower bus interrupt when all interrupts have been cleared

From: CÃdric Le Goater
Date: Thu Sep 13 2018 - 11:44:32 EST


Also include some documentation on the interrupt status bits and how
they should be cleared. Also, the model does not implement correctly
the RX_DONE bit behavior which should be cleared to allow more data to
be received. Yet to be fixed.

Signed-off-by: CÃdric Le Goater <clg@xxxxxxxx>
---
hw/i2c/aspeed_i2c.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
index c762c7366ad9..275377c2ab38 100644
--- a/hw/i2c/aspeed_i2c.c
+++ b/hw/i2c/aspeed_i2c.c
@@ -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,11 +66,16 @@
#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)
#define I2CD_INTR_ARBIT_LOSS (0x1 << 3)
+
+/*
+ * TODO: handle correctly I2CD_INTR_RX_DONE which needs to be cleared
+ * to allow next data to be received.
+ */
#define I2CD_INTR_RX_DONE (0x1 << 2)
#define I2CD_INTR_TX_NAK (0x1 << 1)
#define I2CD_INTR_TX_ACK (0x1 << 0)
@@ -284,8 +296,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",
--
2.17.1