Merge v5.14-rc3 into usb-next
[linux-2.6-microblaze.git] / drivers / spi / spi-stm32.c
index 8ffcffb..05618a6 100644 (file)
@@ -884,15 +884,18 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id)
        ier = readl_relaxed(spi->base + STM32H7_SPI_IER);
 
        mask = ier;
-       /* EOTIE is triggered on EOT, SUSP and TXC events. */
+       /*
+        * EOTIE enables irq from EOT, SUSP and TXC events. We need to set
+        * SUSP to acknowledge it later. TXC is automatically cleared
+        */
+
        mask |= STM32H7_SPI_SR_SUSP;
        /*
-        * When TXTF is set, DXPIE and TXPIE are cleared. So in case of
-        * Full-Duplex, need to poll RXP event to know if there are remaining
-        * data, before disabling SPI.
+        * DXPIE is set in Full-Duplex, one IT will be raised if TXP and RXP
+        * are set. So in case of Full-Duplex, need to poll TXP and RXP event.
         */
-       if (spi->rx_buf && !spi->cur_usedma)
-               mask |= STM32H7_SPI_SR_RXP;
+       if ((spi->cur_comm == SPI_FULL_DUPLEX) && !spi->cur_usedma)
+               mask |= STM32H7_SPI_SR_TXP | STM32H7_SPI_SR_RXP;
 
        if (!(sr & mask)) {
                dev_warn(spi->dev, "spurious IT (sr=0x%08x, ier=0x%08x)\n",
@@ -1925,6 +1928,7 @@ static int stm32_spi_probe(struct platform_device *pdev)
                master->can_dma = stm32_spi_can_dma;
 
        pm_runtime_set_active(&pdev->dev);
+       pm_runtime_get_noresume(&pdev->dev);
        pm_runtime_enable(&pdev->dev);
 
        ret = spi_register_master(master);
@@ -1940,6 +1944,8 @@ static int stm32_spi_probe(struct platform_device *pdev)
 
 err_pm_disable:
        pm_runtime_disable(&pdev->dev);
+       pm_runtime_put_noidle(&pdev->dev);
+       pm_runtime_set_suspended(&pdev->dev);
 err_dma_release:
        if (spi->dma_tx)
                dma_release_channel(spi->dma_tx);
@@ -1956,9 +1962,14 @@ static int stm32_spi_remove(struct platform_device *pdev)
        struct spi_master *master = platform_get_drvdata(pdev);
        struct stm32_spi *spi = spi_master_get_devdata(master);
 
+       pm_runtime_get_sync(&pdev->dev);
+
        spi_unregister_master(master);
        spi->cfg->disable(spi);
 
+       pm_runtime_disable(&pdev->dev);
+       pm_runtime_put_noidle(&pdev->dev);
+       pm_runtime_set_suspended(&pdev->dev);
        if (master->dma_tx)
                dma_release_channel(master->dma_tx);
        if (master->dma_rx)
@@ -1966,7 +1977,6 @@ static int stm32_spi_remove(struct platform_device *pdev)
 
        clk_disable_unprepare(spi->clk);
 
-       pm_runtime_disable(&pdev->dev);
 
        pinctrl_pm_select_sleep_state(&pdev->dev);