drivers: serial: stm32: Implement PM_DEVICE mode support
Implement PM_DEVICE support and treatment of _pm_action hook. Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
This commit is contained in:
parent
4422de5692
commit
a439c04eb4
1 changed files with 71 additions and 1 deletions
|
@ -22,6 +22,7 @@
|
||||||
#include <zephyr/drivers/uart.h>
|
#include <zephyr/drivers/uart.h>
|
||||||
#include <zephyr/drivers/clock_control.h>
|
#include <zephyr/drivers/clock_control.h>
|
||||||
#include <zephyr/pm/policy.h>
|
#include <zephyr/pm/policy.h>
|
||||||
|
#include <zephyr/pm/device.h>
|
||||||
|
|
||||||
#ifdef CONFIG_UART_ASYNC_API
|
#ifdef CONFIG_UART_ASYNC_API
|
||||||
#include <zephyr/drivers/dma/dma_stm32.h>
|
#include <zephyr/drivers/dma/dma_stm32.h>
|
||||||
|
@ -1693,6 +1694,73 @@ static int uart_stm32_init(const struct device *dev)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM_DEVICE
|
||||||
|
static void uart_stm32_suspend_setup(const struct device *dev)
|
||||||
|
{
|
||||||
|
const struct uart_stm32_config *config = dev->config;
|
||||||
|
|
||||||
|
#ifdef USART_ISR_BUSY
|
||||||
|
/* Make sure that no USART transfer is on-going */
|
||||||
|
while (LL_USART_IsActiveFlag_BUSY(config->usart) == 1) {
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
while (LL_USART_IsActiveFlag_TC(config->usart) == 0) {
|
||||||
|
}
|
||||||
|
#ifdef USART_ISR_REACK
|
||||||
|
/* Make sure that USART is ready for reception */
|
||||||
|
while (LL_USART_IsActiveFlag_REACK(config->usart) == 0) {
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* Clear OVERRUN flag */
|
||||||
|
LL_USART_ClearFlag_ORE(config->usart);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int uart_stm32_pm_action(const struct device *dev,
|
||||||
|
enum pm_device_action action)
|
||||||
|
{
|
||||||
|
const struct uart_stm32_config *config = dev->config;
|
||||||
|
struct uart_stm32_data *data = dev->data;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case PM_DEVICE_ACTION_RESUME:
|
||||||
|
/* Set pins to active state */
|
||||||
|
err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enable clock */
|
||||||
|
err = clock_control_on(data->clock, (clock_control_subsys_t)&config->pclken[0]);
|
||||||
|
if (err != 0) {
|
||||||
|
LOG_ERR("Could not enable (LP)UART clock");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PM_DEVICE_ACTION_SUSPEND:
|
||||||
|
uart_stm32_suspend_setup(dev);
|
||||||
|
/* Stop device clock */
|
||||||
|
err = clock_control_off(data->clock, (clock_control_subsys_t)&config->pclken[0]);
|
||||||
|
if (err != 0) {
|
||||||
|
LOG_ERR("Could not enable (LP)UART clock");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move pins to sleep state */
|
||||||
|
err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_PM_DEVICE */
|
||||||
|
|
||||||
#ifdef CONFIG_UART_ASYNC_API
|
#ifdef CONFIG_UART_ASYNC_API
|
||||||
|
|
||||||
/* src_dev and dest_dev should be 'MEMORY' or 'PERIPHERAL'. */
|
/* src_dev and dest_dev should be 'MEMORY' or 'PERIPHERAL'. */
|
||||||
|
@ -1797,9 +1865,11 @@ static struct uart_stm32_data uart_stm32_data_##index = { \
|
||||||
UART_DMA_CHANNEL(index, tx, TX, MEMORY, PERIPHERAL) \
|
UART_DMA_CHANNEL(index, tx, TX, MEMORY, PERIPHERAL) \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
|
PM_DEVICE_DT_INST_DEFINE(index, uart_stm32_pm_action); \
|
||||||
|
\
|
||||||
DEVICE_DT_INST_DEFINE(index, \
|
DEVICE_DT_INST_DEFINE(index, \
|
||||||
&uart_stm32_init, \
|
&uart_stm32_init, \
|
||||||
NULL, \
|
PM_DEVICE_DT_INST_GET(index), \
|
||||||
&uart_stm32_data_##index, &uart_stm32_cfg_##index, \
|
&uart_stm32_data_##index, &uart_stm32_cfg_##index, \
|
||||||
PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \
|
PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \
|
||||||
&uart_stm32_driver_api); \
|
&uart_stm32_driver_api); \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue