Skip to content

Commit 0d114e9

Browse files
VCASTMgregkh
authored andcommitted
serial: stm32: move dma_request_chan() before clk_prepare_enable()
If dma_request_chan() returns a PROBE_DEFER error, clk_disable_unprepare() will be called and USART clock will be disabled. But early console can be still active on the same USART. While moving dma_request_chan() before clk_prepare_enable(), the clock won't be taken in case of a DMA PROBE_DEFER error, and so it doesn't need to be disabled. Then USART is still clocked for early console. Fixes: a7770a4 ("serial: stm32: defer probe for dma devices") Reported-by: Uwe Kleine-König <[email protected]> Signed-off-by: Valentin Caron <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent b30e668 commit 0d114e9

File tree

1 file changed

+23
-24
lines changed

1 file changed

+23
-24
lines changed

drivers/tty/serial/stm32-usart.c

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,22 +1680,10 @@ static int stm32_usart_serial_probe(struct platform_device *pdev)
16801680
if (!stm32port->info)
16811681
return -EINVAL;
16821682

1683-
ret = stm32_usart_init_port(stm32port, pdev);
1684-
if (ret)
1685-
return ret;
1686-
1687-
if (stm32port->wakeup_src) {
1688-
device_set_wakeup_capable(&pdev->dev, true);
1689-
ret = dev_pm_set_wake_irq(&pdev->dev, stm32port->port.irq);
1690-
if (ret)
1691-
goto err_deinit_port;
1692-
}
1693-
16941683
stm32port->rx_ch = dma_request_chan(&pdev->dev, "rx");
1695-
if (PTR_ERR(stm32port->rx_ch) == -EPROBE_DEFER) {
1696-
ret = -EPROBE_DEFER;
1697-
goto err_wakeirq;
1698-
}
1684+
if (PTR_ERR(stm32port->rx_ch) == -EPROBE_DEFER)
1685+
return -EPROBE_DEFER;
1686+
16991687
/* Fall back in interrupt mode for any non-deferral error */
17001688
if (IS_ERR(stm32port->rx_ch))
17011689
stm32port->rx_ch = NULL;
@@ -1709,6 +1697,17 @@ static int stm32_usart_serial_probe(struct platform_device *pdev)
17091697
if (IS_ERR(stm32port->tx_ch))
17101698
stm32port->tx_ch = NULL;
17111699

1700+
ret = stm32_usart_init_port(stm32port, pdev);
1701+
if (ret)
1702+
goto err_dma_tx;
1703+
1704+
if (stm32port->wakeup_src) {
1705+
device_set_wakeup_capable(&pdev->dev, true);
1706+
ret = dev_pm_set_wake_irq(&pdev->dev, stm32port->port.irq);
1707+
if (ret)
1708+
goto err_deinit_port;
1709+
}
1710+
17121711
if (stm32port->rx_ch && stm32_usart_of_dma_rx_probe(stm32port, pdev)) {
17131712
/* Fall back in interrupt mode */
17141713
dma_release_channel(stm32port->rx_ch);
@@ -1745,19 +1744,11 @@ static int stm32_usart_serial_probe(struct platform_device *pdev)
17451744
pm_runtime_set_suspended(&pdev->dev);
17461745
pm_runtime_put_noidle(&pdev->dev);
17471746

1748-
if (stm32port->tx_ch) {
1747+
if (stm32port->tx_ch)
17491748
stm32_usart_of_dma_tx_remove(stm32port, pdev);
1750-
dma_release_channel(stm32port->tx_ch);
1751-
}
1752-
17531749
if (stm32port->rx_ch)
17541750
stm32_usart_of_dma_rx_remove(stm32port, pdev);
17551751

1756-
err_dma_rx:
1757-
if (stm32port->rx_ch)
1758-
dma_release_channel(stm32port->rx_ch);
1759-
1760-
err_wakeirq:
17611752
if (stm32port->wakeup_src)
17621753
dev_pm_clear_wake_irq(&pdev->dev);
17631754

@@ -1767,6 +1758,14 @@ static int stm32_usart_serial_probe(struct platform_device *pdev)
17671758

17681759
stm32_usart_deinit_port(stm32port);
17691760

1761+
err_dma_tx:
1762+
if (stm32port->tx_ch)
1763+
dma_release_channel(stm32port->tx_ch);
1764+
1765+
err_dma_rx:
1766+
if (stm32port->rx_ch)
1767+
dma_release_channel(stm32port->rx_ch);
1768+
17701769
return ret;
17711770
}
17721771

0 commit comments

Comments
 (0)