Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add turn on and off actions for device drivers #65258

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion drivers/gpio/gpio_mcux_lpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <errno.h>
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/pm/device.h>
#include <zephyr/irq.h>
#include <soc.h>
#include <fsl_common.h>
Expand Down Expand Up @@ -414,6 +415,26 @@ static int gpio_mcux_lpc_init(const struct device *dev)
return 0;
}

#ifdef CONFIG_PM_DEVICE
static int gpio_mcux_lpc_pm_action(const struct device *dev, enum pm_device_action action)
{
switch (action) {
case PM_DEVICE_ACTION_RESUME:
break;
case PM_DEVICE_ACTION_SUSPEND:
break;
case PM_DEVICE_ACTION_TURN_OFF:
break;
case PM_DEVICE_ACTION_TURN_ON:
gpio_mcux_lpc_init(dev);
break;
default:
return -ENOTSUP;
}
return 0;
}
#endif /*CONFIG_PM_DEVICE*/

static const struct gpio_driver_api gpio_mcux_lpc_driver_api = {
.pin_configure = gpio_mcux_lpc_configure,
.port_get_raw = gpio_mcux_lpc_port_get_raw,
Expand Down Expand Up @@ -465,7 +486,10 @@ static const struct gpio_driver_api gpio_mcux_lpc_driver_api = {
\
static struct gpio_mcux_lpc_data gpio_mcux_lpc_data_##n; \
\
DEVICE_DT_INST_DEFINE(n, lpc_gpio_init_##n, NULL, \
PM_DEVICE_DT_INST_DEFINE(n, gpio_mcux_lpc_pm_action); \
\
DEVICE_DT_INST_DEFINE(n, lpc_gpio_init_##n, \
PM_DEVICE_DT_INST_GET(n), \
&gpio_mcux_lpc_data_##n, \
&gpio_mcux_lpc_config_##n, PRE_KERNEL_1, \
CONFIG_GPIO_INIT_PRIORITY, \
Expand Down
66 changes: 65 additions & 1 deletion drivers/serial/uart_mcux_flexcomm.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
#include <zephyr/device.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/pm/policy.h>
#include <zephyr/irq.h>
#include <zephyr/pm/device.h>
#include <fsl_usart.h>
#include <soc.h>
#include <fsl_device_registers.h>
Expand Down Expand Up @@ -86,8 +88,29 @@ struct mcux_flexcomm_data {
#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
struct uart_config uart_config;
#endif
bool pm_policy_state_on;
};

static void mcux_flexcomm_pm_policy_state_lock_get(const struct device *dev)
{
struct mcux_flexcomm_data *data = dev->data;

if (!data->pm_policy_state_on) {
data->pm_policy_state_on = true;
pm_policy_device_power_lock_get(dev);
}
}

static void mcux_flexcomm_pm_policy_state_lock_put(const struct device *dev)
{
struct mcux_flexcomm_data *data = dev->data;

if (data->pm_policy_state_on) {
data->pm_policy_state_on = false;
pm_policy_device_power_lock_put(dev);
}
}

static int mcux_flexcomm_poll_in(const struct device *dev, unsigned char *c)
{
const struct mcux_flexcomm_config *config = dev->config;
Expand Down Expand Up @@ -179,6 +202,12 @@ static void mcux_flexcomm_irq_tx_enable(const struct device *dev)
const struct mcux_flexcomm_config *config = dev->config;
uint32_t mask = kUSART_TxLevelInterruptEnable;

/* Indicates that this device started a transaction that should
* not be interrupted by putting the SoC in states that would
* interfere with this transfer.
*/
mcux_flexcomm_pm_policy_state_lock_get(dev);

USART_EnableInterrupts(config->base, mask);
}

Expand All @@ -187,6 +216,8 @@ static void mcux_flexcomm_irq_tx_disable(const struct device *dev)
const struct mcux_flexcomm_config *config = dev->config;
uint32_t mask = kUSART_TxLevelInterruptEnable;

mcux_flexcomm_pm_policy_state_lock_put(dev);

USART_DisableInterrupts(config->base, mask);
}

Expand Down Expand Up @@ -467,10 +498,14 @@ static int mcux_flexcomm_uart_tx(const struct device *dev, const uint8_t *buf,
/* Enable TX DMA requests */
USART_EnableTxDMA(config->base, true);

/* Do not allow the system to suspend until the transmission has completed */
mcux_flexcomm_pm_policy_state_lock_get(dev);

/* Trigger the DMA to start transfer */
ret = dma_start(config->tx_dma.dev, config->tx_dma.channel);
if (ret) {
irq_unlock(key);
mcux_flexcomm_pm_policy_state_lock_put(dev);
return ret;
}

Expand Down Expand Up @@ -993,6 +1028,8 @@ static void mcux_flexcomm_isr(const struct device *dev)
data->tx_data.xfer_buf = NULL;

async_user_callback(dev, &tx_done_event);

mcux_flexcomm_pm_policy_state_lock_put(dev);
}

}
Expand Down Expand Up @@ -1067,6 +1104,31 @@ static int mcux_flexcomm_init(const struct device *dev)
return 0;
}

#ifdef CONFIG_PM_DEVICE
static uint32_t usart_intenset;
static int mcux_flexcomm_pm_action(const struct device *dev, enum pm_device_action action)
{
const struct mcux_flexcomm_config *config = dev->config;

switch (action) {
case PM_DEVICE_ACTION_RESUME:
break;
case PM_DEVICE_ACTION_SUSPEND:
break;
case PM_DEVICE_ACTION_TURN_OFF:
usart_intenset = USART_GetEnabledInterrupts(config->base);
return 0;
case PM_DEVICE_ACTION_TURN_ON:
mcux_flexcomm_init(dev);
USART_EnableInterrupts(config->base, usart_intenset);
return 0;
default:
return -ENOTSUP;
}
return 0;
}
#endif /*CONFIG_PM_DEVICE*/

static const struct uart_driver_api mcux_flexcomm_driver_api = {
.poll_in = mcux_flexcomm_poll_in,
.poll_out = mcux_flexcomm_poll_out,
Expand Down Expand Up @@ -1202,9 +1264,11 @@ static const struct mcux_flexcomm_config mcux_flexcomm_##n##_config = { \
\
static const struct mcux_flexcomm_config mcux_flexcomm_##n##_config; \
\
PM_DEVICE_DT_INST_DEFINE(n, mcux_flexcomm_pm_action); \
\
DEVICE_DT_INST_DEFINE(n, \
&mcux_flexcomm_init, \
NULL, \
PM_DEVICE_DT_INST_GET(n), \
&mcux_flexcomm_##n##_data, \
&mcux_flexcomm_##n##_config, \
PRE_KERNEL_1, \
Expand Down
Loading