spi: bcm2835aux: ensure interrupts are enabled for shared handler
authorRob Herring <[email protected]>
Thu, 3 May 2018 18:09:44 +0000 (13:09 -0500)
committerMark Brown <[email protected]>
Thu, 3 May 2018 23:09:02 +0000 (08:09 +0900)
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 <[email protected]>
Cc: Marc Zyngier <[email protected]>
Cc: Mark Brown <[email protected]>
Cc: Eric Anholt <[email protected]>
Cc: Stefan Wahren <[email protected]>
Cc: Florian Fainelli <[email protected]>
Cc: Ray Jui <[email protected]>
Cc: Scott Branden <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Rob Herring <[email protected]>
Reviewed-by: Eric Anholt <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
drivers/spi/spi-bcm2835aux.c

index 1431cb98fe403a4b7039195bf172bf47bceb6702..3094d818cf06d4751122611bc2eb807e71d965fd 100644 (file)
@@ -184,6 +184,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) &