From patchwork Fri Nov 24 12:11:50 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Chevallier X-Patchwork-Id: 10074007 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 F181E60375 for ; Fri, 24 Nov 2017 12:21:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DD78F29FA6 for ; Fri, 24 Nov 2017 12:21:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CE9DC2A30C; Fri, 24 Nov 2017 12:21:11 +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=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CE40829FA6 for ; Fri, 24 Nov 2017 12:21:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753565AbdKXMVK (ORCPT ); Fri, 24 Nov 2017 07:21:10 -0500 Received: from idris.smile.fr ([91.216.209.19]:62088 "EHLO idris.smile.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753460AbdKXMVJ (ORCPT ); Fri, 24 Nov 2017 07:21:09 -0500 X-Greylist: delayed 587 seconds by postgrey-1.27 at vger.kernel.org; Fri, 24 Nov 2017 07:21:08 EST Received: from localhost (localhost [127.0.0.1]) by idris.smile.fr (Postfix) with ESMTP id BFBE21EE679D; Fri, 24 Nov 2017 13:11:20 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at smile.fr Received: from idris.smile.fr ([127.0.0.1]) by localhost (bluemind-mta.prod.vitry.intranet [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id pBaCykg17aJc; Fri, 24 Nov 2017 13:11:20 +0100 (CET) Received: from smile-e5570.sigfox.io (unknown [217.114.201.133]) by idris.smile.fr (Postfix) with ESMTPSA id 839BD1EE6794; Fri, 24 Nov 2017 13:11:20 +0100 (CET) From: Maxime Chevallier To: linux-spi@vger.kernel.org Cc: broonie@kernel.org, linux-kernel@vger.kernel.org, gregory.clement@free-electrons.com, miquel.raynal@free-electrons.com, Maxime Chevallier Subject: [PATCH] spi: a3700: Fix event detection when waiting for interrupt Date: Fri, 24 Nov 2017 13:11:50 +0100 Message-Id: <1511525510-29964-1-git-send-email-maxime.chevallier@smile.fr> X-Mailer: git-send-email 2.1.4 Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When waiting for an interrupt event, there is a short window where an interrupt can occur before we start waiting for it, but after the initial flag checking. The current implementation documents that case, but clears the wait_mask before doing the check, making it non-effective. The function also returns early in some cases, skipping the part where we mask the interrupt that we waited for. This commit reworks the function so that we correctly check for the wait_mask before clearing it, and we always mask the interrupt if we enabled it previously. Signed-off-by: Maxime Chevallier --- drivers/spi/spi-armada-3700.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi-armada-3700.c b/drivers/spi/spi-armada-3700.c index 77fe55c..fe58685 100644 --- a/drivers/spi/spi-armada-3700.c +++ b/drivers/spi/spi-armada-3700.c @@ -333,6 +333,7 @@ static bool a3700_spi_wait_completion(struct spi_device *spi) { struct a3700_spi *a3700_spi; unsigned int timeout; + bool completed = true; unsigned int ctrl_reg; unsigned long timeout_jiffies; @@ -357,10 +358,9 @@ static bool a3700_spi_wait_completion(struct spi_device *spi) timeout = wait_for_completion_timeout(&a3700_spi->done, timeout_jiffies); - a3700_spi->wait_mask = 0; if (timeout) - return true; + goto done; /* there might be the case that right after we checked the * status bits in this routine and before start to wait for @@ -372,12 +372,16 @@ static bool a3700_spi_wait_completion(struct spi_device *spi) */ ctrl_reg = spireg_read(a3700_spi, A3700_SPI_IF_CTRL_REG); if (a3700_spi->wait_mask & ctrl_reg) - return true; + goto done; + /* Timeout was reached */ + completed = false; +done: spireg_write(a3700_spi, A3700_SPI_INT_MASK_REG, 0); - /* Timeout was reached */ - return false; + a3700_spi->wait_mask = 0; + + return completed; } static bool a3700_spi_transfer_wait(struct spi_device *spi,