From patchwork Thu Dec 6 03:55:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 152982 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp10074212ljp; Wed, 5 Dec 2018 19:56:54 -0800 (PST) X-Google-Smtp-Source: AFSGD/UtXY1U7AdnQbRMqta6d7Gcj1831Wj6UyMotZvn/+3LPTzw0EETVAcJUmvhQ+HGlG+f7wAN X-Received: by 2002:a63:5207:: with SMTP id g7mr23070753pgb.253.1544068614084; Wed, 05 Dec 2018 19:56:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544068614; cv=none; d=google.com; s=arc-20160816; b=L6PsLqMVp/iZOVhw3j3eF8WYnOqNVA2bkhUv7ZakMegAXercd0l4zKEcsoSE9skyVj iLkwhdqQIdENIS2ho5cfTZbmRwEaDTFHRxJhl61qLGoD1GVdfN64wVIDEtguyKXjRdrh G7EK5gTsEPVSLoZdy/osN00u5Oy/gT2ZD5h4pVGPFSo3KMPKXCkztCuz1IybQbwS90Qw 9RL/UBYSZ8rvvufxUMfM96e46khlS/w+kPPX43NkWzOz1Ocv+SeOisDTL7ZsihHAX66r oFNvC5cR3i/m2vLzmFmH90Ngy2FKn8b5xJaZZSdToyQtPAGq/vTXOD6kXRzH7NCFR18k rjDw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:dkim-filter; bh=2y2cw2qzebvkA+Mtv/XDf/lXFAsgLnN70QsGjRHK68c=; b=CIqNNjZFprcybXlZ15vc9vgQrCyUqMY7lzKbJBFhM0q5m9mrUwr+yKvr0nfmV0EBSR fyQ6zBUONjg7GljOQAxt9ieOk+xVcd0xmatydvCmcYPDssqt6PAv5IVbIAD4y16ySyYE fdOuZmbAe5u6005clgUXchlAKmo7DUIEAq3v43983Rf9ZBLymLCobHMQS8mSwytDJbP+ Efa/jsH2ymvvmQVhNP7eCSDqSKQ7PNFLmMpSxMoJwJa2etLssA7sNoXnMX5CyCNIVyfr Ov2gjycj1WwAMDjxdZmTbHBX7Oak0G3T+ejfLVNoz4vCQMmP2B7jI0FRZfXfmQWLAYqh ZSxw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@nifty.com header.s=dec2015msa header.b=kPHi2dOE; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q66si21497796pfb.231.2018.12.05.19.56.53; Wed, 05 Dec 2018 19:56:54 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@nifty.com header.s=dec2015msa header.b=kPHi2dOE; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729103AbeLFD4w (ORCPT + 31 others); Wed, 5 Dec 2018 22:56:52 -0500 Received: from conuserg-09.nifty.com ([210.131.2.76]:59213 "EHLO conuserg-09.nifty.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729058AbeLFD4u (ORCPT ); Wed, 5 Dec 2018 22:56:50 -0500 Received: from pug.e01.socionext.com (p14092-ipngnfx01kyoto.kyoto.ocn.ne.jp [153.142.97.92]) (authenticated) by conuserg-09.nifty.com with ESMTP id wB63trS6007398; Thu, 6 Dec 2018 12:55:54 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conuserg-09.nifty.com wB63trS6007398 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1544068555; bh=2y2cw2qzebvkA+Mtv/XDf/lXFAsgLnN70QsGjRHK68c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kPHi2dOEi3qWH6h8XKwY274U9vnp6zKg7l3nNiKvf+kib3GV6+hakUNhgUnJJv/NF QHc/hlsIotcEtGB5VC2dt/W9jOMZqqbgx8hd5vZ3ylxiudEBtz8JnBgUwak7qri5rt Zpt+7C4FpNFZjl8l8IW8KZNAfoQ1ZMIV8KPl+Aiiilu2M+0j9fYu5OskyJ4UINipp7 kdkbPwV862Vny5wy2cJZ1alQv9PL7LDEz2AIMbYuPxYGX7ZvElrn9bsnDorMCu/2CW oWeUxwZPvHto49Ojo8gn5cZ4aIXQT+MsT1D4wDwCF9w4GI/LiHEO9CTKWOrP9c6CJ/ 1zoDG2ayu67Zw== X-Nifty-SrcIP: [153.142.97.92] From: Masahiro Yamada To: linux-i2c@vger.kernel.org Cc: Masahiro Yamada , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/4] i2c: uniphier-f: fix timeout error after reading 8 bytes Date: Thu, 6 Dec 2018 12:55:25 +0900 Message-Id: <1544068528-27657-2-git-send-email-yamada.masahiro@socionext.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1544068528-27657-1-git-send-email-yamada.masahiro@socionext.com> References: <1544068528-27657-1-git-send-email-yamada.masahiro@socionext.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org I was totally screwed up in commit eaba68785c2d ("i2c: uniphier-f: fix race condition when IRQ is cleared"). Since that commit, if the number of read bytes is multiple of the FIFO size (8, 16, 24... bytes), the STOP condition could be issued twice, depending on the timing. If this happens, the controller will go wrong, resulting in the timeout error. It was more than 3 years ago when I wrote this driver, so my memory about this hardware was vague. Please let me correct the description in the commit log of eaba68785c2d. Clearing the IRQ status on exiting the IRQ handler is absolutely fine. This controller makes a pause while any IRQ status is asserted. If the IRQ status is cleared first, the hardware may start the next transaction before the IRQ handler finishes what it supposed to do. This partially reverts the bad commit with clear comments so that I will never repeat this mistake. I also investigated what is happening at the last moment of the read mode. The UNIPHIER_FI2C_INT_RF interrupt is asserted a bit earlier (by half a period of the clock cycle) than UNIPHIER_FI2C_INT_RB. I consulted a hardware engineer, and I got the following information: UNIPHIER_FI2C_INT_RF asserted at the falling edge of SCL at the 8th bit. UNIPHIER_FI2C_INT_RB asserted at the rising edge of SCL at the 9th (ACK) bit. In order to avoid calling uniphier_fi2c_stop() twice, check the latter interrupt. I also commented this because it is obscure hardware internal. Fixes: eaba68785c2d ("i2c: uniphier-f: fix race condition when IRQ is cleared") Signed-off-by: Masahiro Yamada --- drivers/i2c/busses/i2c-uniphier-f.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) -- 2.7.4 diff --git a/drivers/i2c/busses/i2c-uniphier-f.c b/drivers/i2c/busses/i2c-uniphier-f.c index dd38474..fad2b00 100644 --- a/drivers/i2c/busses/i2c-uniphier-f.c +++ b/drivers/i2c/busses/i2c-uniphier-f.c @@ -173,8 +173,6 @@ static irqreturn_t uniphier_fi2c_interrupt(int irq, void *dev_id) "interrupt: enabled_irqs=%04x, irq_status=%04x\n", priv->enabled_irqs, irq_status); - uniphier_fi2c_clear_irqs(priv, irq_status); - if (irq_status & UNIPHIER_FI2C_INT_STOP) goto complete; @@ -214,7 +212,13 @@ static irqreturn_t uniphier_fi2c_interrupt(int irq, void *dev_id) if (irq_status & (UNIPHIER_FI2C_INT_RF | UNIPHIER_FI2C_INT_RB)) { uniphier_fi2c_drain_rxfifo(priv); - if (!priv->len) + /* + * If the number of bytes to read is multiple of the FIFO size + * (msg->len == 8, 16, 24, ...), the INT_RF bit is set a little + * earlier than INT_RB. We wait for INT_RB to confirm the + * completion of the current message. + */ + if (!priv->len && (irq_status & UNIPHIER_FI2C_INT_RB)) goto data_done; if (unlikely(priv->flags & UNIPHIER_FI2C_MANUAL_NACK)) { @@ -253,6 +257,13 @@ static irqreturn_t uniphier_fi2c_interrupt(int irq, void *dev_id) } handled: + /* + * This controller makes a pause while any bit of the IRQ status is + * asserted. Clear the asserted bit to kick the controller just before + * exiting the handler. + */ + uniphier_fi2c_clear_irqs(priv, irq_status); + spin_unlock(&priv->lock); return IRQ_HANDLED;