From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.1 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A2DF1C432C3 for ; Sat, 16 Nov 2019 15:44:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7BFDA20830 for ; Sat, 16 Nov 2019 15:44:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1573919076; bh=by66fafWIkFfkatStvHYRKlIhFEru2T56686wGJEHj4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=rJeSxCZOt7J1lDmbqR6ugImvm7CpBC1nMdibNR7OTcUg4M/asyEvMla7izkHR1JON gc4tulP+0INm073w9dlGhAbg8uMCLQNYkLRky8ADQRE34AnS56OP41rSQSxMMB2D5j +7znHcHeVOEx1H9D3epZ1Ul2BjtsKqqtFLHienyk= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729022AbfKPPoe (ORCPT ); Sat, 16 Nov 2019 10:44:34 -0500 Received: from mail.kernel.org ([198.145.29.99]:49264 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728968AbfKPPo1 (ORCPT ); Sat, 16 Nov 2019 10:44:27 -0500 Received: from sasha-vm.mshome.net (unknown [50.234.116.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 30A5C2072D; Sat, 16 Nov 2019 15:44:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1573919066; bh=by66fafWIkFfkatStvHYRKlIhFEru2T56686wGJEHj4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=M732/L/InWX7ylwULntQBASo+DgSH3XomiCAHcmyr97R9JNQEdk7qD6Me17SY+jV0 r9cCzuogJeDc9NGJlQL2l3jrYCzheWRV8CxTnuBxzithYgUFZnCym8KGaJ6/H1AoEs SYvVsANqyWreL6WckIA9RMwrVtYzD9cBb//coQ0I= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Masahiro Yamada , Wolfram Sang , Sasha Levin , linux-i2c@vger.kernel.org Subject: [PATCH AUTOSEL 4.19 139/237] i2c: uniphier-f: fix race condition when IRQ is cleared Date: Sat, 16 Nov 2019 10:39:34 -0500 Message-Id: <20191116154113.7417-139-sashal@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191116154113.7417-1-sashal@kernel.org> References: <20191116154113.7417-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Masahiro Yamada [ Upstream commit eaba68785c2d24ebf1f0d46c24e11b79cc2f94c7 ] The current IRQ handler clears all the IRQ status bits when it bails out. This is dangerous because it might clear away the status bits that have just been set while processing the current handler. If this happens, the IRQ event for the latest transfer is lost forever. The IRQ status bits must be cleared *before* the next transfer is kicked. Fixes: 6a62974b667f ("i2c: uniphier_f: add UniPhier FIFO-builtin I2C driver") Signed-off-by: Masahiro Yamada Signed-off-by: Wolfram Sang Signed-off-by: Sasha Levin --- drivers/i2c/busses/i2c-uniphier-f.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-uniphier-f.c b/drivers/i2c/busses/i2c-uniphier-f.c index bbd5b137aa216..928ea9930d17e 100644 --- a/drivers/i2c/busses/i2c-uniphier-f.c +++ b/drivers/i2c/busses/i2c-uniphier-f.c @@ -143,9 +143,10 @@ static void uniphier_fi2c_set_irqs(struct uniphier_fi2c_priv *priv) writel(priv->enabled_irqs, priv->membase + UNIPHIER_FI2C_IE); } -static void uniphier_fi2c_clear_irqs(struct uniphier_fi2c_priv *priv) +static void uniphier_fi2c_clear_irqs(struct uniphier_fi2c_priv *priv, + u32 mask) { - writel(-1, priv->membase + UNIPHIER_FI2C_IC); + writel(mask, priv->membase + UNIPHIER_FI2C_IC); } static void uniphier_fi2c_stop(struct uniphier_fi2c_priv *priv) @@ -172,6 +173,8 @@ 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; @@ -250,8 +253,6 @@ static irqreturn_t uniphier_fi2c_interrupt(int irq, void *dev_id) } handled: - uniphier_fi2c_clear_irqs(priv); - spin_unlock(&priv->lock); return IRQ_HANDLED; @@ -340,7 +341,7 @@ static int uniphier_fi2c_master_xfer_one(struct i2c_adapter *adap, priv->flags |= UNIPHIER_FI2C_STOP; reinit_completion(&priv->comp); - uniphier_fi2c_clear_irqs(priv); + uniphier_fi2c_clear_irqs(priv, U32_MAX); writel(UNIPHIER_FI2C_RST_TBRST | UNIPHIER_FI2C_RST_RBRST, priv->membase + UNIPHIER_FI2C_RST); /* reset TX/RX FIFO */ -- 2.20.1