From patchwork Fri Nov 18 19:40:10 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Russell King (Oracle)" X-Patchwork-Id: 9437269 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 430366047D for ; Fri, 18 Nov 2016 19:42:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 37F42299D2 for ; Fri, 18 Nov 2016 19:42:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2C38B299E9; Fri, 18 Nov 2016 19:42:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id BD9DD299D2 for ; Fri, 18 Nov 2016 19:42:20 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1c7p1m-0007FM-Hx; Fri, 18 Nov 2016 19:40:50 +0000 Received: from pandora.armlinux.org.uk ([2001:4d48:ad52:3201:214:fdff:fe10:1be6]) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1c7p1Z-0007BE-Re for linux-arm-kernel@lists.infradead.org; Fri, 18 Nov 2016 19:40:39 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=armlinux.org.uk; s=pandora-2014; h=Date:Sender:Message-Id:Content-Type:Content-Transfer-Encoding:References:In-Reply-To:MIME-Version:Subject:Cc:To:From; bh=1agCsm5y5CBQl9KjhKkMuVoqzOBw2YSDML0KVPE2Xhk=; b=cFlfdOObgNk9La/6JUncEMuTxAxs7I7+dsLW3dq7Fn0ag7y34mzO5pZagObo7ZbZhmZ/EB/nxgXjOPhmCE6OBKmd46tjf6/3rhJ8aagMhLBSj53cRzNAsna5gu7ZOzbID7JZf3Y4gc1Nl/fbbnzgoKlkBDFvt1Oo3/sWtvT7zJs=; Received: from e0022681537dd.dyn.armlinux.org.uk ([2001:4d48:ad52:3201:222:68ff:fe15:37dd]:43862 helo=rmk-PC.armlinux.org.uk) by pandora.armlinux.org.uk with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1c7p1A-0006oX-1D; Fri, 18 Nov 2016 19:40:12 +0000 Received: from rmk by rmk-PC.armlinux.org.uk with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1c7p18-0000R6-4w; Fri, 18 Nov 2016 19:40:10 +0000 From: Russell King To: Andrew Jackson , Liviu Dudau , Mika Westerberg , Wolfram Sang , Jarkko Nikula , Andy Shevchenko Subject: [PATCH 2/2] i2c: designware: fix rx fifo depth tracking MIME-Version: 1.0 In-Reply-To: <20161118193542.GO1041@n2100.armlinux.org.uk> References: <20161118193542.GO1041@n2100.armlinux.org.uk> Content-Disposition: inline Message-Id: Date: Fri, 18 Nov 2016 19:40:10 +0000 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20161118_114038_350095_83E9A490 X-CRM114-Status: GOOD ( 12.97 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-i2c@vger.kernel.org, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP When loading the TX fifo to receive bytes on the I2C bus, we incorrectly count the number of bytes: rx_limit = dev->rx_fifo_depth - dw_readl(dev, DW_IC_RXFLR); while (buf_len > 0 && tx_limit > 0 && rx_limit > 0) { if (rx_limit - dev->rx_outstanding <= 0) break; rx_limit--; dev->rx_outstanding++; } DW_IC_RXFLR indicates how many bytes are available to be read in the FIFO, dev->rx_fifo_depth is the FIFO size, and dev->rx_outstanding is the number of bytes that we've requested to be read so far, but which have not been read. Firstly, increasing dev->rx_outstanding and decreasing rx_limit and then comparing them results in each byte consuming "two" bytes in this tracking, so this is obviously wrong. Secondly, the number of bytes that _could_ be received into the FIFO at any time is the number of bytes we have so far requested but not yet read from the FIFO - in other words dev->rx_outstanding. So, in order to request enough bytes to fill the RX FIFO, we need to request dev->rx_fifo_depth - dev->rx_outstanding bytes. Modifying the code thusly results in us reaching the maximum number of bytes outstanding each time we queue more "receive" operations, provided the transfer allows that to happen. Signed-off-by: Russell King Reviewed-by: Mika Westerberg Acked-by: Jarkko Nikula --- With this applied, I now get: [ 1.726388] i2c_designware 7ffa0000.i2c: transfer terminated early - interrupt latency too high? [ 1.733813] tda998x 0-0070: Error -5 reading from 0x900 [ 1.737708] tda998x 0-0070: failed to read edid block 0: -5 [ 1.743683] tda998x 0-0070: failed to read EDID which is a more graceful failure than letting DRM detect the bad transfer by checking the EDID checksum and hoping that the untransferred bytes don't result in the EDID checksum succeeding. drivers/i2c/busses/i2c-designware-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 11e866d05368..9703fe392543 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c @@ -611,7 +611,7 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev) if (msgs[dev->msg_write_idx].flags & I2C_M_RD) { /* avoid rx buffer overrun */ - if (rx_limit - dev->rx_outstanding <= 0) + if (dev->rx_outstanding >= dev->rx_fifo_depth) break; dw_writel(dev, cmd | 0x100, DW_IC_DATA_CMD);