From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755685AbbISRve (ORCPT ); Sat, 19 Sep 2015 13:51:34 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:33341 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755057AbbISRtn (ORCPT ); Sat, 19 Sep 2015 13:49:43 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Edward Kigwana , Ricardo Ribalda Delgado , Mark Brown Subject: [PATCH 4.2 099/120] spi/spi-xilinx: Fix spurious IRQ ACK on irq mode Date: Sat, 19 Sep 2015 10:28:59 -0700 Message-Id: <20150919171727.789090006@linuxfoundation.org> X-Mailer: git-send-email 2.5.3 In-Reply-To: <20150919171712.735441938@linuxfoundation.org> References: <20150919171712.735441938@linuxfoundation.org> User-Agent: quilt/0.64 MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.2-stable review patch. If anyone has any objections, please let me know. ------------------ From: Ricardo Ribalda Delgado commit 74346841e6f5df5f7b83d5904435d273c507dba6 upstream. The ACK of an inexistent IRQ can trigger an spurious IRQ that breaks the txrx logic. This has been observed on axi_quad_spi:3.2 core. This patch only ACKs IRQs that have not been Acknowledge jet. Reported-by: Edward Kigwana Tested-by: Edward Kigwana Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/spi/spi-xilinx.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) --- a/drivers/spi/spi-xilinx.c +++ b/drivers/spi/spi-xilinx.c @@ -249,19 +249,23 @@ static int xilinx_spi_txrx_bufs(struct s xspi->tx_ptr = t->tx_buf; xspi->rx_ptr = t->rx_buf; remaining_words = t->len / xspi->bytes_per_word; - reinit_completion(&xspi->done); if (xspi->irq >= 0 && remaining_words > xspi->buffer_size) { + u32 isr; use_irq = true; - xspi->write_fn(XSPI_INTR_TX_EMPTY, - xspi->regs + XIPIF_V123B_IISR_OFFSET); - /* Enable the global IPIF interrupt */ - xspi->write_fn(XIPIF_V123B_GINTR_ENABLE, - xspi->regs + XIPIF_V123B_DGIER_OFFSET); /* Inhibit irq to avoid spurious irqs on tx_empty*/ cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET); xspi->write_fn(cr | XSPI_CR_TRANS_INHIBIT, xspi->regs + XSPI_CR_OFFSET); + /* ACK old irqs (if any) */ + isr = xspi->read_fn(xspi->regs + XIPIF_V123B_IISR_OFFSET); + if (isr) + xspi->write_fn(isr, + xspi->regs + XIPIF_V123B_IISR_OFFSET); + /* Enable the global IPIF interrupt */ + xspi->write_fn(XIPIF_V123B_GINTR_ENABLE, + xspi->regs + XIPIF_V123B_DGIER_OFFSET); + reinit_completion(&xspi->done); } while (remaining_words) {