From patchwork Tue Sep 25 13:41:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 974427 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42KMyG5mt6z9s3C for ; Tue, 25 Sep 2018 23:54:46 +1000 (AEST) Received: from localhost ([::1]:53211 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g4nnY-0008HJ-C6 for incoming@patchwork.ozlabs.org; Tue, 25 Sep 2018 09:54:44 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40323) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g4ngi-0002Rr-Dx for qemu-devel@nongnu.org; Tue, 25 Sep 2018 09:47:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g4nbL-0003jm-Gt for qemu-devel@nongnu.org; Tue, 25 Sep 2018 09:42:11 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:48606) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1g4nbL-0002rg-6k for qemu-devel@nongnu.org; Tue, 25 Sep 2018 09:42:07 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1g4nbB-00018Y-9h for qemu-devel@nongnu.org; Tue, 25 Sep 2018 14:41:57 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Tue, 25 Sep 2018 14:41:32 +0100 Message-Id: <20180925134144.21741-10-peter.maydell@linaro.org> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180925134144.21741-1-peter.maydell@linaro.org> References: <20180925134144.21741-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 09/21] aspeed/i2c: Fix receive done interrupt handling X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Guenter Roeck The AST2500 datasheet says: I2CD10 Interrupt Status Register bit 2 Receive Done Interrupt status S/W needs to clear this status bit to allow next data receiving The Rx interrupt done interrupt status bit needs to be cleared explicitly before the next byte can be received, and must therefore not be auto-cleared. Also, receiving the next byte must be delayed until the bit has been cleared. Signed-off-by: Guenter Roeck Signed-off-by: Cédric Le Goater Message-id: 20180914063506.20815-4-clg@kaod.org Signed-off-by: Peter Maydell --- hw/i2c/aspeed_i2c.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c index ce16efc1367..a2dfa827604 100644 --- a/hw/i2c/aspeed_i2c.c +++ b/hw/i2c/aspeed_i2c.c @@ -252,7 +252,8 @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value) aspeed_i2c_set_state(bus, I2CD_MACTIVE); } - if (bus->cmd & (I2CD_M_RX_CMD | I2CD_M_S_RX_CMD_LAST)) { + if ((bus->cmd & (I2CD_M_RX_CMD | I2CD_M_S_RX_CMD_LAST)) && + !(bus->intr_status & I2CD_INTR_RX_DONE)) { aspeed_i2c_handle_rx_cmd(bus); } @@ -274,6 +275,7 @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset, uint64_t value, unsigned size) { AspeedI2CBus *bus = opaque; + bool handle_rx; switch (offset) { case I2CD_FUN_CTRL_REG: @@ -294,11 +296,17 @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset, bus->intr_ctrl = value & 0x7FFF; break; case I2CD_INTR_STS_REG: + handle_rx = (bus->intr_status & I2CD_INTR_RX_DONE) && + (value & I2CD_INTR_RX_DONE); bus->intr_status &= ~(value & 0x7FFF); if (!bus->intr_status) { bus->controller->intr_status &= ~(1 << bus->id); qemu_irq_lower(bus->controller->irq); } + if (handle_rx && (bus->cmd & (I2CD_M_RX_CMD | I2CD_M_S_RX_CMD_LAST))) { + aspeed_i2c_handle_rx_cmd(bus); + aspeed_i2c_bus_raise_interrupt(bus); + } break; case I2CD_DEV_ADDR_REG: qemu_log_mask(LOG_UNIMP, "%s: slave mode not implemented\n",