ceph-fix-buffer-free-while-holding-i_ceph_lock-in-__.patch
kvm-arm-arm64-only-skip-mmio-insn-once.patch
libceph-allow-ceph_buffer_put-to-receive-a-null-ceph.patch
+spi-bcm2835aux-ensure-interrupts-are-enabled-for-sha.patch
+spi-bcm2835aux-unifying-code-between-polling-and-int.patch
+spi-bcm2835aux-remove-dangerous-uncontrolled-read-of.patch
+spi-bcm2835aux-fix-corruptions-for-longer-spi-transf.patch
--- /dev/null
+From ae3ddc4620c76ec3d965007c8448f9aeb2fda364 Mon Sep 17 00:00:00 2001
+From: Rob Herring <robh@kernel.org>
+Date: Thu, 3 May 2018 13:09:44 -0500
+Subject: spi: bcm2835aux: ensure interrupts are enabled for shared handler
+
+[ Upstream commit bc519d9574618e47a0c788000fb78da95e18d953 ]
+
+The BCM2835 AUX SPI has a shared interrupt line (with AUX UART).
+Downstream fixes this with an AUX irqchip to demux the IRQ sources and a
+DT change which breaks compatibility with older kernels. The AUX irqchip
+was already rejected for upstream[1] and the DT change would break
+working systems if the DTB is updated to a newer one. The latter issue
+was brought to my attention by Alex Graf.
+
+The root cause however is a bug in the shared handler. Shared handlers
+must check that interrupts are actually enabled before servicing the
+interrupt. Add a check that the TXEMPTY or IDLE interrupts are enabled.
+
+[1] https://patchwork.kernel.org/patch/9781221/
+
+Cc: Alexander Graf <agraf@suse.de>
+Cc: Marc Zyngier <marc.zyngier@arm.com>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Eric Anholt <eric@anholt.net>
+Cc: Stefan Wahren <stefan.wahren@i2se.com>
+Cc: Florian Fainelli <f.fainelli@gmail.com>
+Cc: Ray Jui <rjui@broadcom.com>
+Cc: Scott Branden <sbranden@broadcom.com>
+Cc: bcm-kernel-feedback-list@broadcom.com
+Cc: linux-spi@vger.kernel.org
+Cc: linux-rpi-kernel@lists.infradead.org
+Cc: linux-arm-kernel@lists.infradead.org
+Signed-off-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-bcm2835aux.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/spi/spi-bcm2835aux.c b/drivers/spi/spi-bcm2835aux.c
+index 7de6f8472a810..6f4c6aa801f14 100644
+--- a/drivers/spi/spi-bcm2835aux.c
++++ b/drivers/spi/spi-bcm2835aux.c
+@@ -187,6 +187,11 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
+ struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
+ irqreturn_t ret = IRQ_NONE;
+
++ /* IRQ may be shared, so return if our interrupts are disabled */
++ if (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_CNTL1) &
++ (BCM2835_AUX_SPI_CNTL1_TXEMPTY | BCM2835_AUX_SPI_CNTL1_IDLE)))
++ return ret;
++
+ /* check if we have data to read */
+ while (bs->rx_len &&
+ (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) &
+--
+2.20.1
+
--- /dev/null
+From 9e335820204e094b899f46ad4af6c5efab81b3c5 Mon Sep 17 00:00:00 2001
+From: Martin Sperl <kernel@martin.sperl.org>
+Date: Sat, 30 Mar 2019 09:31:00 +0000
+Subject: spi: bcm2835aux: fix corruptions for longer spi transfers
+
+[ Upstream commit 73b114ee7db1750c0b535199fae383b109bd61d0 ]
+
+On long running tests with a mcp2517fd can controller it showed that
+on rare occations the data read shows corruptions for longer spi transfers.
+
+Example of a 22 byte transfer:
+
+expected (as captured on logic analyzer):
+FF FF 78 00 00 00 08 06 00 00 91 20 77 56 84 85 86 87 88 89 8a 8b
+
+read by the driver:
+FF FF 78 00 00 00 08 06 00 00 91 20 77 56 84 88 89 8a 00 00 8b 9b
+
+To fix this use BCM2835_AUX_SPI_STAT_RX_LVL to determine when we may
+read data from the fifo reliably without any corruption.
+
+Surprisingly the only values ever empirically read in
+BCM2835_AUX_SPI_STAT_RX_LVL are 0x00, 0x10, 0x20 and 0x30.
+So whenever the mask is not 0 we can read from the fifo in a safe manner.
+
+The patch has now been tested intensively and we are no longer
+able to reproduce the "RX" issue any longer.
+
+Fixes: 1ea29b39f4c812ec ("spi: bcm2835aux: add bcm2835 auxiliary spi device...")
+Reported-by: Hubert Denkmair <h.denkmair@intence.de>
+Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
+Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-bcm2835aux.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/spi/spi-bcm2835aux.c b/drivers/spi/spi-bcm2835aux.c
+index 4d233356772aa..ca655593c5e0e 100644
+--- a/drivers/spi/spi-bcm2835aux.c
++++ b/drivers/spi/spi-bcm2835aux.c
+@@ -183,12 +183,12 @@ static void bcm2835aux_spi_reset_hw(struct bcm2835aux_spi *bs)
+
+ static void bcm2835aux_spi_transfer_helper(struct bcm2835aux_spi *bs)
+ {
++ u32 stat = bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT);
++
+ /* check if we have data to read */
+- while (bs->rx_len &&
+- (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) &
+- BCM2835_AUX_SPI_STAT_RX_EMPTY))) {
++ for (; bs->rx_len && (stat & BCM2835_AUX_SPI_STAT_RX_LVL);
++ stat = bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT))
+ bcm2835aux_rd_fifo(bs);
+- }
+
+ /* check if we have data to write */
+ while (bs->tx_len &&
+--
+2.20.1
+
--- /dev/null
+From 733b92e36e8ed466fa8014818d2134b19b8ca2af Mon Sep 17 00:00:00 2001
+From: Martin Sperl <kernel@martin.sperl.org>
+Date: Sat, 30 Mar 2019 09:30:59 +0000
+Subject: spi: bcm2835aux: remove dangerous uncontrolled read of fifo
+
+[ Upstream commit c7de8500fd8ecbb544846dd5f11dca578c3777e1 ]
+
+This read of the fifo is a potential candidate for a race condition
+as the spi transfer is not necessarily finished and so can lead to
+an early read of the fifo that still misses data.
+
+So it has been removed.
+
+Fixes: 1ea29b39f4c812ec ("spi: bcm2835aux: add bcm2835 auxiliary spi device...")
+Suggested-by: Hubert Denkmair <h.denkmair@intence.de>
+Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
+Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-bcm2835aux.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/drivers/spi/spi-bcm2835aux.c b/drivers/spi/spi-bcm2835aux.c
+index 5b2c2b2e13396..4d233356772aa 100644
+--- a/drivers/spi/spi-bcm2835aux.c
++++ b/drivers/spi/spi-bcm2835aux.c
+@@ -197,13 +197,6 @@ static void bcm2835aux_spi_transfer_helper(struct bcm2835aux_spi *bs)
+ BCM2835_AUX_SPI_STAT_TX_FULL))) {
+ bcm2835aux_wr_fifo(bs);
+ }
+-
+- /* and check if we have reached "done" */
+- while (bs->rx_len &&
+- (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) &
+- BCM2835_AUX_SPI_STAT_BUSY))) {
+- bcm2835aux_rd_fifo(bs);
+- }
+ }
+
+ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
+--
+2.20.1
+
--- /dev/null
+From d6542581eeb73b57afbfa58c26e6ff2900a3e883 Mon Sep 17 00:00:00 2001
+From: Martin Sperl <kernel@martin.sperl.org>
+Date: Sat, 30 Mar 2019 09:30:58 +0000
+Subject: spi: bcm2835aux: unifying code between polling and interrupt driven
+ code
+
+[ Upstream commit 7188a6f0eee3f1fae5d826cfc6d569657ff950ec ]
+
+Sharing more code between polling and interrupt-driven mode.
+
+Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
+Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-bcm2835aux.c | 51 +++++++++++++-----------------------
+ 1 file changed, 18 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/spi/spi-bcm2835aux.c b/drivers/spi/spi-bcm2835aux.c
+index 6f4c6aa801f14..5b2c2b2e13396 100644
+--- a/drivers/spi/spi-bcm2835aux.c
++++ b/drivers/spi/spi-bcm2835aux.c
+@@ -181,23 +181,13 @@ static void bcm2835aux_spi_reset_hw(struct bcm2835aux_spi *bs)
+ BCM2835_AUX_SPI_CNTL0_CLEARFIFO);
+ }
+
+-static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
++static void bcm2835aux_spi_transfer_helper(struct bcm2835aux_spi *bs)
+ {
+- struct spi_master *master = dev_id;
+- struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
+- irqreturn_t ret = IRQ_NONE;
+-
+- /* IRQ may be shared, so return if our interrupts are disabled */
+- if (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_CNTL1) &
+- (BCM2835_AUX_SPI_CNTL1_TXEMPTY | BCM2835_AUX_SPI_CNTL1_IDLE)))
+- return ret;
+-
+ /* check if we have data to read */
+ while (bs->rx_len &&
+ (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) &
+ BCM2835_AUX_SPI_STAT_RX_EMPTY))) {
+ bcm2835aux_rd_fifo(bs);
+- ret = IRQ_HANDLED;
+ }
+
+ /* check if we have data to write */
+@@ -206,7 +196,6 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
+ (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) &
+ BCM2835_AUX_SPI_STAT_TX_FULL))) {
+ bcm2835aux_wr_fifo(bs);
+- ret = IRQ_HANDLED;
+ }
+
+ /* and check if we have reached "done" */
+@@ -214,8 +203,21 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
+ (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) &
+ BCM2835_AUX_SPI_STAT_BUSY))) {
+ bcm2835aux_rd_fifo(bs);
+- ret = IRQ_HANDLED;
+ }
++}
++
++static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
++{
++ struct spi_master *master = dev_id;
++ struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
++
++ /* IRQ may be shared, so return if our interrupts are disabled */
++ if (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_CNTL1) &
++ (BCM2835_AUX_SPI_CNTL1_TXEMPTY | BCM2835_AUX_SPI_CNTL1_IDLE)))
++ return IRQ_NONE;
++
++ /* do common fifo handling */
++ bcm2835aux_spi_transfer_helper(bs);
+
+ /* and if rx_len is 0 then wake up completion and disable spi */
+ if (!bs->rx_len) {
+@@ -223,8 +225,7 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
+ complete(&master->xfer_completion);
+ }
+
+- /* and return */
+- return ret;
++ return IRQ_HANDLED;
+ }
+
+ static int __bcm2835aux_spi_transfer_one_irq(struct spi_master *master,
+@@ -270,7 +271,6 @@ static int bcm2835aux_spi_transfer_one_poll(struct spi_master *master,
+ {
+ struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
+ unsigned long timeout;
+- u32 stat;
+
+ /* configure spi */
+ bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]);
+@@ -281,24 +281,9 @@ static int bcm2835aux_spi_transfer_one_poll(struct spi_master *master,
+
+ /* loop until finished the transfer */
+ while (bs->rx_len) {
+- /* read status */
+- stat = bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT);
+-
+- /* fill in tx fifo with remaining data */
+- if ((bs->tx_len) && (!(stat & BCM2835_AUX_SPI_STAT_TX_FULL))) {
+- bcm2835aux_wr_fifo(bs);
+- continue;
+- }
+
+- /* read data from fifo for both cases */
+- if (!(stat & BCM2835_AUX_SPI_STAT_RX_EMPTY)) {
+- bcm2835aux_rd_fifo(bs);
+- continue;
+- }
+- if (!(stat & BCM2835_AUX_SPI_STAT_BUSY)) {
+- bcm2835aux_rd_fifo(bs);
+- continue;
+- }
++ /* do common fifo handling */
++ bcm2835aux_spi_transfer_helper(bs);
+
+ /* there is still data pending to read check the timeout */
+ if (bs->rx_len && time_after(jiffies, timeout)) {
+--
+2.20.1
+