diff options
Diffstat (limited to 'drivers/spi/spi-stm32.c')
| -rw-r--r-- | drivers/spi/spi-stm32.c | 24 | 
1 files changed, 17 insertions, 7 deletions
diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c index 8ffcffbb8157..05618a618939 100644 --- a/drivers/spi/spi-stm32.c +++ b/drivers/spi/spi-stm32.c @@ -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);  | 
