spi: xilinx: add force_irq for QSPI mode
authorVadim Fedorenko <vadfed@meta.com>
Tue, 14 Feb 2023 13:59:28 +0000 (05:59 -0800)
committerMark Brown <broonie@kernel.org>
Tue, 14 Feb 2023 18:04:59 +0000 (18:04 +0000)
Xilinx PG158 page 80 [1] states that master transaction inhibit bit must
be set to properly setup the transaction in QSPI mode. Add the force_irq
flag to follow this sequence.

[1] https://docs.xilinx.com/r/en-US/pg153-axi-quad-spi/Dual/Quad-SPI-Mode-Transactions

Signed-off-by: Vadim Fedorenko <vadfed@meta.com>
Link: https://lore.kernel.org/r/20230214135928.1253205-1-vadfed@meta.com
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi-xilinx.c
include/linux/spi/xilinx_spi.h

index 7377d3b81302282b28b9e6494162c1302583c5f5..1411548f4255366a749297e8c57f04a576ea5982 100644 (file)
@@ -83,7 +83,7 @@ struct xilinx_spi {
        void __iomem    *regs;  /* virt. address of the control registers */
 
        int             irq;
-
+       bool force_irq;         /* force irq to setup master inhibit */
        u8 *rx_ptr;             /* pointer in the Tx buffer */
        const u8 *tx_ptr;       /* pointer in the Rx buffer */
        u8 bytes_per_word;
@@ -248,7 +248,8 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
        xspi->rx_ptr = t->rx_buf;
        remaining_words = t->len / xspi->bytes_per_word;
 
-       if (xspi->irq >= 0 &&  remaining_words > xspi->buffer_size) {
+       if (xspi->irq >= 0 &&
+           (xspi->force_irq || remaining_words > xspi->buffer_size)) {
                u32 isr;
                use_irq = true;
                /* Inhibit irq to avoid spurious irqs on tx_empty*/
@@ -393,6 +394,7 @@ static int xilinx_spi_probe(struct platform_device *pdev)
        struct resource *res;
        int ret, num_cs = 0, bits_per_word;
        struct spi_master *master;
+       bool force_irq = false;
        u32 tmp;
        u8 i;
 
@@ -400,6 +402,7 @@ static int xilinx_spi_probe(struct platform_device *pdev)
        if (pdata) {
                num_cs = pdata->num_chipselect;
                bits_per_word = pdata->bits_per_word;
+               force_irq = pdata->force_irq;
        } else {
                of_property_read_u32(pdev->dev.of_node, "xlnx,num-ss-bits",
                                          &num_cs);
@@ -477,6 +480,8 @@ static int xilinx_spi_probe(struct platform_device *pdev)
                                dev_name(&pdev->dev), xspi);
                if (ret)
                        return ret;
+
+               xspi->force_irq = force_irq;
        }
 
        /* SPI controller initializations */
index c15d69d28e6810dd38a23546207448104a8ddefc..3934ce789d877bc5624d21fc589bbd403e848b0b 100644 (file)
@@ -15,6 +15,7 @@ struct xspi_platform_data {
        u8 bits_per_word;
        struct spi_board_info *devices;
        u8 num_devices;
+       bool force_irq;
 };
 
 #endif /* __LINUX_SPI_XILINX_SPI_H */