From patchwork Mon Jan 16 09:05:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 9518283 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 1737A6020B for ; Mon, 16 Jan 2017 09:16:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DDE4328342 for ; Mon, 16 Jan 2017 09:16:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D263D2842E; Mon, 16 Jan 2017 09:16:46 +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.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 67E6928342 for ; Mon, 16 Jan 2017 09:16:46 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1cT3PC-0001Ze-1j; Mon, 16 Jan 2017 09:16:46 +0000 Received: from thoth.sbs.de ([192.35.17.2]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cT3FL-0003lf-J7 for linux-arm-kernel@lists.infradead.org; Mon, 16 Jan 2017 09:06:37 +0000 Received: from mail3.siemens.de (mail3.siemens.de [139.25.208.14]) by thoth.sbs.de (8.15.2/8.15.2) with ESMTPS id v0G964qq009713 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 16 Jan 2017 10:06:04 +0100 Received: from md1f2u6c.ww002.siemens.net ([139.22.129.45]) by mail3.siemens.de (8.15.2/8.15.2) with ESMTP id v0G9629p024131; Mon, 16 Jan 2017 10:06:03 +0100 From: Jan Kiszka To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 1/2] spi: pxa2xx: Prepare for edge-triggered interrupts Date: Mon, 16 Jan 2017 10:05:59 +0100 Message-Id: <6fe26505e67790b27eed28fd7451b51e70b7e8ba.1484557560.git.jan.kiszka@siemens.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: References: In-Reply-To: References: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170116_010635_936845_41FC4A7D X-CRM114-Status: GOOD ( 15.48 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Robert Jarzmik , linux-kernel@vger.kernel.org, Haojian Zhuang , Jarkko Nikula , Andy Shevchenko , Mika Westerberg , Sascha Weisenberger , Daniel Mack MIME-Version: 1.0 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 using the a device with edge-triggered interrupts, such as MSIs, the interrupt handler has to ensure that there is a point in time during its execution where all interrupts sources are silent so that a new event can trigger a new interrupt again. This is achieved here by looping over SSSR evaluation. We need to take into account that SSCR1 may be changed by the transfer handler, thus we need to redo the mask calculation, at least regarding the volatile interrupt enable bit (TIE). Signed-off-by: Jan Kiszka --- drivers/spi/spi-pxa2xx.c | 50 +++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index dd7b5b4..24bf549 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -737,6 +737,7 @@ static irqreturn_t ssp_int(int irq, void *dev_id) struct driver_data *drv_data = dev_id; u32 sccr1_reg; u32 mask = drv_data->mask_sr; + irqreturn_t ret = IRQ_NONE; u32 status; /* @@ -760,37 +761,42 @@ static irqreturn_t ssp_int(int irq, void *dev_id) sccr1_reg = pxa2xx_spi_read(drv_data, SSCR1); - /* Ignore possible writes if we don't need to write */ - if (!(sccr1_reg & SSCR1_TIE)) - mask &= ~SSSR_TFS; - /* Ignore RX timeout interrupt if it is disabled */ if (!(sccr1_reg & SSCR1_TINTE)) mask &= ~SSSR_TINT; - if (!(status & mask)) - return IRQ_NONE; + while (1) { + /* Ignore possible writes if we don't need to write */ + if (!(sccr1_reg & SSCR1_TIE)) + mask &= ~SSSR_TFS; - if (!drv_data->master->cur_msg) { + if (!(status & mask)) + return ret; - pxa2xx_spi_write(drv_data, SSCR0, - pxa2xx_spi_read(drv_data, SSCR0) - & ~SSCR0_SSE); - pxa2xx_spi_write(drv_data, SSCR1, - pxa2xx_spi_read(drv_data, SSCR1) - & ~drv_data->int_cr1); - if (!pxa25x_ssp_comp(drv_data)) - pxa2xx_spi_write(drv_data, SSTO, 0); - write_SSSR_CS(drv_data, drv_data->clear_sr); + if (!drv_data->master->cur_msg) { - dev_err(&drv_data->pdev->dev, - "bad message state in interrupt handler\n"); + pxa2xx_spi_write(drv_data, SSCR0, + pxa2xx_spi_read(drv_data, SSCR0) + & ~SSCR0_SSE); + pxa2xx_spi_write(drv_data, SSCR1, + pxa2xx_spi_read(drv_data, SSCR1) + & ~drv_data->int_cr1); + if (!pxa25x_ssp_comp(drv_data)) + pxa2xx_spi_write(drv_data, SSTO, 0); + write_SSSR_CS(drv_data, drv_data->clear_sr); - /* Never fail */ - return IRQ_HANDLED; - } + dev_err(&drv_data->pdev->dev, + "bad message state in interrupt handler\n"); - return drv_data->transfer_handler(drv_data); + /* Never fail */ + return IRQ_HANDLED; + } + + ret |= drv_data->transfer_handler(drv_data); + + status = pxa2xx_spi_read(drv_data, SSSR); + sccr1_reg = pxa2xx_spi_read(drv_data, SSCR1); + } } /*