diff options
author | Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com> | 2015-08-13 10:09:28 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-08-14 11:35:19 -0400 |
commit | 74346841e6f5df5f7b83d5904435d273c507dba6 (patch) | |
tree | 1c035bdb2b0f0c3ec90677b185ade11273c41725 | |
parent | 16ea9b8ac45bf11d48af6013283e141e8ed86348 (diff) |
spi/spi-xilinx: Fix spurious IRQ ACK on irq mode
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 <ekigwana@scires.com>
Tested-by: Edward Kigwana <ekigwana@scires.com>
Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Cc: stable@vger.kernel.org
-rw-r--r-- | drivers/spi/spi-xilinx.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c index 7abf6792cc11..a339c1e9997a 100644 --- a/drivers/spi/spi-xilinx.c +++ b/drivers/spi/spi-xilinx.c | |||
@@ -249,19 +249,23 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
249 | xspi->tx_ptr = t->tx_buf; | 249 | xspi->tx_ptr = t->tx_buf; |
250 | xspi->rx_ptr = t->rx_buf; | 250 | xspi->rx_ptr = t->rx_buf; |
251 | remaining_words = t->len / xspi->bytes_per_word; | 251 | remaining_words = t->len / xspi->bytes_per_word; |
252 | reinit_completion(&xspi->done); | ||
253 | 252 | ||
254 | if (xspi->irq >= 0 && remaining_words > xspi->buffer_size) { | 253 | if (xspi->irq >= 0 && remaining_words > xspi->buffer_size) { |
254 | u32 isr; | ||
255 | use_irq = true; | 255 | use_irq = true; |
256 | xspi->write_fn(XSPI_INTR_TX_EMPTY, | ||
257 | xspi->regs + XIPIF_V123B_IISR_OFFSET); | ||
258 | /* Enable the global IPIF interrupt */ | ||
259 | xspi->write_fn(XIPIF_V123B_GINTR_ENABLE, | ||
260 | xspi->regs + XIPIF_V123B_DGIER_OFFSET); | ||
261 | /* Inhibit irq to avoid spurious irqs on tx_empty*/ | 256 | /* Inhibit irq to avoid spurious irqs on tx_empty*/ |
262 | cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET); | 257 | cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET); |
263 | xspi->write_fn(cr | XSPI_CR_TRANS_INHIBIT, | 258 | xspi->write_fn(cr | XSPI_CR_TRANS_INHIBIT, |
264 | xspi->regs + XSPI_CR_OFFSET); | 259 | xspi->regs + XSPI_CR_OFFSET); |
260 | /* ACK old irqs (if any) */ | ||
261 | isr = xspi->read_fn(xspi->regs + XIPIF_V123B_IISR_OFFSET); | ||
262 | if (isr) | ||
263 | xspi->write_fn(isr, | ||
264 | xspi->regs + XIPIF_V123B_IISR_OFFSET); | ||
265 | /* Enable the global IPIF interrupt */ | ||
266 | xspi->write_fn(XIPIF_V123B_GINTR_ENABLE, | ||
267 | xspi->regs + XIPIF_V123B_DGIER_OFFSET); | ||
268 | reinit_completion(&xspi->done); | ||
265 | } | 269 | } |
266 | 270 | ||
267 | while (remaining_words) { | 271 | while (remaining_words) { |