serial: stm32: add pm_runtime support

Use pm_runtime for clock management.

Signed-off-by: Bich Hemon <bich.hemon@st.com>
Signed-off-by: Erwan Le Ray <erwan.leray@st.com>

Link: https://lore.kernel.org/r/1560433800-12255-5-git-send-email-erwan.leray@st.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Erwan Le Ray 2019-06-13 15:49:54 +02:00 committed by Greg Kroah-Hartman
parent 94616d9a9d
commit fb6dcef62d

View file

@ -882,13 +882,13 @@ static void stm32_pm(struct uart_port *port, unsigned int state,
switch (state) {
case UART_PM_STATE_ON:
clk_prepare_enable(stm32port->clk);
pm_runtime_get_sync(port->dev);
break;
case UART_PM_STATE_OFF:
spin_lock_irqsave(&port->lock, flags);
stm32_clr_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit));
spin_unlock_irqrestore(&port->lock, flags);
clk_disable_unprepare(stm32port->clk);
pm_runtime_put_sync(port->dev);
break;
}
}
@ -1186,6 +1186,11 @@ static int stm32_serial_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, &stm32port->port);
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
pm_runtime_put_sync(&pdev->dev);
return 0;
err_wirq:
@ -1207,6 +1212,9 @@ static int stm32_serial_remove(struct platform_device *pdev)
struct uart_port *port = platform_get_drvdata(pdev);
struct stm32_port *stm32_port = to_stm32_port(port);
struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
int err;
pm_runtime_get_sync(&pdev->dev);
stm32_clr_bits(port, ofs->cr3, USART_CR3_DMAR);
@ -1235,7 +1243,12 @@ static int stm32_serial_remove(struct platform_device *pdev)
clk_disable_unprepare(stm32_port->clk);
return uart_remove_one_port(&stm32_usart_driver, port);
err = uart_remove_one_port(&stm32_usart_driver, port);
pm_runtime_disable(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev);
return err;
}
@ -1392,7 +1405,29 @@ static int stm32_serial_resume(struct device *dev)
}
#endif /* CONFIG_PM_SLEEP */
static int __maybe_unused stm32_serial_runtime_suspend(struct device *dev)
{
struct uart_port *port = dev_get_drvdata(dev);
struct stm32_port *stm32port = container_of(port,
struct stm32_port, port);
clk_disable_unprepare(stm32port->clk);
return 0;
}
static int __maybe_unused stm32_serial_runtime_resume(struct device *dev)
{
struct uart_port *port = dev_get_drvdata(dev);
struct stm32_port *stm32port = container_of(port,
struct stm32_port, port);
return clk_prepare_enable(stm32port->clk);
}
static const struct dev_pm_ops stm32_serial_pm_ops = {
SET_RUNTIME_PM_OPS(stm32_serial_runtime_suspend,
stm32_serial_runtime_resume, NULL)
SET_SYSTEM_SLEEP_PM_OPS(stm32_serial_suspend, stm32_serial_resume)
};