]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
spi: bcm2835: Enable shared interrupt support
authorMartin Sperl <kernel@martin.sperl.org>
Thu, 28 May 2020 18:58:04 +0000 (20:58 +0200)
committerMark Brown <broonie@kernel.org>
Fri, 29 May 2020 16:49:54 +0000 (17:49 +0100)
bcm2711, Rasberry Pi 4's SoC, shares one interrupt for multiple
instances of the bcm2835 SPI controller. So this enables shared
interrupt support for them.

The early bail out in the interrupt routine avoids messing with buffers
of transfers being done by other means. Otherwise, the driver can handle
receiving interrupts asserted by other controllers during an IRQ based
transfer.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
Tested-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Link: https://lore.kernel.org/r/20200528185805.28991-1-nsaenzjulienne@suse.de
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi-bcm2835.c

index 237bd306c26853aa3ba6f1c402455ea9cd18a4dc..f3e41676e825aa7e5c2daf0b934e023def60eafc 100644 (file)
@@ -379,6 +379,10 @@ static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id)
        if (bs->tx_len && cs & BCM2835_SPI_CS_DONE)
                bcm2835_wr_fifo_blind(bs, BCM2835_SPI_FIFO_SIZE);
 
+       /* check if we got interrupt enabled */
+       if (!(bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_INTR))
+               return IRQ_NONE;
+
        /* Read as many bytes as possible from FIFO */
        bcm2835_rd_fifo(bs);
        /* Write as many bytes as possible to FIFO */
@@ -1344,8 +1348,8 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
        bcm2835_wr(bs, BCM2835_SPI_CS,
                   BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX);
 
-       err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, 0,
-                              dev_name(&pdev->dev), ctlr);
+       err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt,
+                              IRQF_SHARED, dev_name(&pdev->dev), ctlr);
        if (err) {
                dev_err(&pdev->dev, "could not request IRQ: %d\n", err);
                goto out_dma_release;