]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.4.170/spi-bcm2835-avoid-finishing-transfer-prematurely-in-irq-mode.patch
fixes for 4.19
[thirdparty/kernel/stable-queue.git] / releases / 4.4.170 / spi-bcm2835-avoid-finishing-transfer-prematurely-in-irq-mode.patch
CommitLineData
326a9cc7
GKH
1From 56c1723426d3cfd4723bfbfce531d7b38bae6266 Mon Sep 17 00:00:00 2001
2From: Lukas Wunner <lukas@wunner.de>
3Date: Thu, 8 Nov 2018 08:06:10 +0100
4Subject: spi: bcm2835: Avoid finishing transfer prematurely in IRQ mode
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9From: Lukas Wunner <lukas@wunner.de>
10
11commit 56c1723426d3cfd4723bfbfce531d7b38bae6266 upstream.
12
13The IRQ handler bcm2835_spi_interrupt() first reads as much as possible
14from the RX FIFO, then writes as much as possible to the TX FIFO.
15Afterwards it decides whether the transfer is finished by checking if
16the TX FIFO is empty.
17
18If very few bytes were written to the TX FIFO, they may already have
19been transmitted by the time the FIFO's emptiness is checked. As a
20result, the transfer will be declared finished and the chip will be
21reset without reading the corresponding received bytes from the RX FIFO.
22
23The odds of this happening increase with a high clock frequency (such
24that the TX FIFO drains quickly) and either passing "threadirqs" on the
25command line or enabling CONFIG_PREEMPT_RT_BASE (such that the IRQ
26handler may be preempted between filling the TX FIFO and checking its
27emptiness).
28
29Fix by instead checking whether rx_len has reached zero, which means
30that the transfer has been received in full. This is also more
31efficient as it avoids one bus read access per interrupt. Note that
32bcm2835_spi_transfer_one_poll() likewise uses rx_len to determine
33whether the transfer has finished.
34
35Signed-off-by: Lukas Wunner <lukas@wunner.de>
36Fixes: e34ff011c70e ("spi: bcm2835: move to the transfer_one driver model")
37Cc: stable@vger.kernel.org # v4.1+
38Cc: Mathias Duckeck <m.duckeck@kunbus.de>
39Cc: Frank Pavlic <f.pavlic@kunbus.de>
40Cc: Martin Sperl <kernel@martin.sperl.org>
41Cc: Noralf Trønnes <noralf@tronnes.org>
42Signed-off-by: Mark Brown <broonie@kernel.org>
43Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
44
45---
46 drivers/spi/spi-bcm2835.c | 3 +--
47 1 file changed, 1 insertion(+), 2 deletions(-)
48
49--- a/drivers/spi/spi-bcm2835.c
50+++ b/drivers/spi/spi-bcm2835.c
51@@ -155,8 +155,7 @@ static irqreturn_t bcm2835_spi_interrupt
52 /* Write as many bytes as possible to FIFO */
53 bcm2835_wr_fifo(bs);
54
55- /* based on flags decide if we can finish the transfer */
56- if (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_DONE) {
57+ if (!bs->rx_len) {
58 /* Transfer complete - reset SPI HW */
59 bcm2835_spi_reset_hw(master);
60 /* wake up the framework */