aboutsummaryrefslogtreecommitdiff
path: root/hw/i2c
diff options
context:
space:
mode:
authorCédric Le Goater <clg@kaod.org>2018-09-25 14:02:31 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-09-25 14:14:07 +0100
commit5540cb97f711d191bae6cde89a03a8a9c306b638 (patch)
tree8b67639490c750a3ff55ab53b1de92b8cc4a351d /hw/i2c
parentb148ed466514c8b50e7cf6fb45985a1ab98db1f8 (diff)
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>
Diffstat (limited to 'hw/i2c')
-rw-r--r--hw/i2c/aspeed_i2c.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
index c762c7366a..9a3a232fb8 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,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",