From: Antonio Borneo <antonio.borneo@xxxxxx> The spi disable could potentially require some time to finish. It has to be executed at the end of a transfer, but there is no reason to call it in the irq handler. Simplify the irq handler by moving out the spi disable. The synchronization through xfer_completion is used to defer the execution of spi disable. Signed-off-by: Antonio Borneo <antonio.borneo@xxxxxx> Signed-off-by: Alain Volmat <alain.volmat@xxxxxx> --- drivers/spi/spi-stm32.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c index 0eda9903e11e..1a703c4a65db 100644 --- a/drivers/spi/spi-stm32.c +++ b/drivers/spi/spi-stm32.c @@ -874,7 +874,6 @@ static irqreturn_t stm32f4_spi_irq_thread(int irq, void *dev_id) struct spi_master *master = dev_id; struct stm32_spi *spi = spi_master_get_devdata(master); - stm32f4_spi_disable(spi); complete(&spi->xfer_completion); return IRQ_HANDLED; @@ -963,15 +962,18 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id) if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0))) stm32h7_spi_read_rxfifo(spi); - writel_relaxed(ifcr, spi->base + STM32H7_SPI_IFCR); - - spin_unlock_irqrestore(&spi->lock, flags); - if (end) { - stm32h7_spi_disable(spi); + /* Disable interrupts and clear status flags */ + writel_relaxed(0, spi->base + STM32H7_SPI_IER); + writel_relaxed(STM32H7_SPI_IFCR_ALL, + spi->base + STM32H7_SPI_IFCR); + complete(&spi->xfer_completion); + } else { + writel_relaxed(ifcr, spi->base + STM32H7_SPI_IFCR); } + spin_unlock_irqrestore(&spi->lock, flags); return IRQ_HANDLED; } @@ -1039,10 +1041,8 @@ static void stm32f4_spi_dma_tx_cb(void *data) { struct stm32_spi *spi = data; - if (spi->cur_comm == SPI_SIMPLEX_TX || spi->cur_comm == SPI_3WIRE_TX) { - stm32f4_spi_disable(spi); + if (spi->cur_comm == SPI_SIMPLEX_TX || spi->cur_comm == SPI_3WIRE_TX) complete(&spi->xfer_completion); - } } /** @@ -1055,7 +1055,6 @@ static void stm32f4_spi_dma_rx_cb(void *data) { struct stm32_spi *spi = data; - stm32f4_spi_disable(spi); complete(&spi->xfer_completion); } @@ -1697,9 +1696,10 @@ static int stm32_spi_transfer_one(struct spi_master *master, if (!ret) { dev_err(spi->dev, "SPI transfer timeout (%u ms)\n", xfer_time); spi->xfer_status = -ETIMEDOUT; - spi->cfg->disable(spi); } + spi->cfg->disable(spi); + spi_finalize_current_transfer(master); return spi->xfer_status; -- 2.7.4