From patchwork Thu Sep 3 20:20:12 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wolfram Sang X-Patchwork-Id: 7119241 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id EE89D9F36E for ; Thu, 3 Sep 2015 20:23:36 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 18B9520713 for ; Thu, 3 Sep 2015 20:23:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2BF6020708 for ; Thu, 3 Sep 2015 20:23:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754257AbbICUXe (ORCPT ); Thu, 3 Sep 2015 16:23:34 -0400 Received: from sauhun.de ([89.238.76.85]:48434 "EHLO pokefinder.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751483AbbICUXe (ORCPT ); Thu, 3 Sep 2015 16:23:34 -0400 Received: from p4fe253c4.dip0.t-ipconnect.de ([79.226.83.196]:39709 helo=localhost) by pokefinder.org with esmtpsa (TLS1.2:RSA_AES_128_CBC_SHA1:128) (Exim 4.80) (envelope-from ) id 1ZXb2c-0003Rn-FC; Thu, 03 Sep 2015 22:23:26 +0200 From: Wolfram Sang To: linux-i2c@vger.kernel.org Cc: linux-sh@vger.kernel.org, Magnus Damm , Simon Horman , Laurent Pinchart , Geert Uytterhoeven , Wolfram Sang , Kuninori Morimoto , Yoshihiro Kaneko , Sergei Shtylyov Subject: [PATCH 8/9] i2c: rcar: revoke START request early Date: Thu, 3 Sep 2015 22:20:12 +0200 Message-Id: <1441311613-2681-9-git-send-email-wsa@the-dreams.de> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1441311613-2681-1-git-send-email-wsa@the-dreams.de> References: <1441311613-2681-1-git-send-email-wsa@the-dreams.de> Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Wolfram Sang If we don't clear START generation as soon as possible, it may cause another message to be generated. To keep the race window as small as possible, we clear it right at the beginning of the interrupt. We don't need checking since we always want to stop START and STOP generation on the next occasion after we started it. This patch improves the situation but sadly does not completely fix it. It is still to be researched if we can do better given this HW design. Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-rcar.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index 06bd8c45c6af9d..2afa3683a3de4e 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -84,6 +84,7 @@ #define RCAR_BUS_PHASE_START (MDBS | MIE | ESG) #define RCAR_BUS_PHASE_DATA (MDBS | MIE) +#define RCAR_BUS_MASK_DATA (~(ESG | FSB) & 0xFF) #define RCAR_BUS_PHASE_STOP (MDBS | MIE | FSB) #define RCAR_IRQ_SEND (MNR | MAL | MST | MAT | MDE) @@ -288,13 +289,6 @@ static int rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr) if (!(msr & MDE)) return 0; - /* - * If address transfer phase finished, - * goto data phase. - */ - if (msr & MAT) - rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA); - if (priv->pos < msg->len) { /* * Prepare next data to ICRXTX register. @@ -346,11 +340,7 @@ static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr) return 0; if (msr & MAT) { - /* - * Address transfer phase finished, - * but, there is no data at this point. - * Do nothing. - */ + /* Address transfer phase finished, but no data at this point. */ } else if (priv->pos < msg->len) { /* * get received data @@ -366,8 +356,6 @@ static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr) */ if (priv->pos + 1 >= msg->len) rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP); - else - rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA); if (priv->pos == msg->len && !(priv->flags & ID_LAST_MSG)) rcar_i2c_next_msg(priv); @@ -435,7 +423,11 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv) static irqreturn_t rcar_i2c_irq(int irq, void *ptr) { struct rcar_i2c_priv *priv = ptr; - u32 msr; + u32 msr, val; + + /* Clear START or STOP as soon as we can */ + val = rcar_i2c_read(priv, ICMCR); + rcar_i2c_write(priv, ICMCR, val & RCAR_BUS_MASK_DATA); msr = rcar_i2c_read(priv, ICMSR); @@ -457,7 +449,6 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr) /* Nack */ if (msr & MNR) { /* HW automatically sends STOP after received NACK */ - rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA); rcar_i2c_write(priv, ICMIER, RCAR_IRQ_STOP); rcar_i2c_flags_set(priv, ID_NACK); goto out;