Skip to content

Commit 9004207

Browse files
mmahadevan108kartben
authored andcommitted
drivers: uart: Add PM action for NXP UART Flexcomm driver
Add power action callback handlers to the driver. Signed-off-by: Mahesh Mahadevan <[email protected]>
1 parent d035847 commit 9004207

File tree

2 files changed

+98
-5
lines changed

2 files changed

+98
-5
lines changed

drivers/serial/uart_mcux_flexcomm.c

Lines changed: 93 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
#include <zephyr/device.h>
1515
#include <zephyr/drivers/uart.h>
1616
#include <zephyr/drivers/clock_control.h>
17+
#include <zephyr/pm/policy.h>
1718
#include <zephyr/irq.h>
19+
#include <zephyr/pm/device.h>
1820
#include <fsl_usart.h>
1921
#include <soc.h>
2022
#include <fsl_device_registers.h>
@@ -86,8 +88,33 @@ struct mcux_flexcomm_data {
8688
#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
8789
struct uart_config uart_config;
8890
#endif
91+
#ifdef CONFIG_PM_POLICY_DEVICE_CONSTRAINTS
92+
bool pm_policy_state_lock;
93+
#endif
8994
};
9095

96+
#ifdef CONFIG_PM_POLICY_DEVICE_CONSTRAINTS
97+
static void mcux_flexcomm_pm_policy_state_lock_get(const struct device *dev)
98+
{
99+
struct mcux_flexcomm_data *data = dev->data;
100+
101+
if (!data->pm_policy_state_lock) {
102+
data->pm_policy_state_lock = true;
103+
pm_policy_device_power_lock_get(dev);
104+
}
105+
}
106+
107+
static void mcux_flexcomm_pm_policy_state_lock_put(const struct device *dev)
108+
{
109+
struct mcux_flexcomm_data *data = dev->data;
110+
111+
if (data->pm_policy_state_lock) {
112+
data->pm_policy_state_lock = false;
113+
pm_policy_device_power_lock_put(dev);
114+
}
115+
}
116+
#endif
117+
91118
static int mcux_flexcomm_poll_in(const struct device *dev, unsigned char *c)
92119
{
93120
const struct mcux_flexcomm_config *config = dev->config;
@@ -179,6 +206,14 @@ static void mcux_flexcomm_irq_tx_enable(const struct device *dev)
179206
const struct mcux_flexcomm_config *config = dev->config;
180207
uint32_t mask = kUSART_TxLevelInterruptEnable;
181208

209+
/* Indicates that this device started a transaction that should
210+
* not be interrupted by putting the SoC in states that would
211+
* interfere with this transfer.
212+
*/
213+
#ifdef CONFIG_PM_POLICY_DEVICE_CONSTRAINTS
214+
mcux_flexcomm_pm_policy_state_lock_get(dev);
215+
#endif
216+
182217
USART_EnableInterrupts(config->base, mask);
183218
}
184219

@@ -187,6 +222,10 @@ static void mcux_flexcomm_irq_tx_disable(const struct device *dev)
187222
const struct mcux_flexcomm_config *config = dev->config;
188223
uint32_t mask = kUSART_TxLevelInterruptEnable;
189224

225+
#ifdef CONFIG_PM_POLICY_DEVICE_CONSTRAINTS
226+
mcux_flexcomm_pm_policy_state_lock_put(dev);
227+
#endif
228+
190229
USART_DisableInterrupts(config->base, mask);
191230
}
192231

@@ -467,11 +506,19 @@ static int mcux_flexcomm_uart_tx(const struct device *dev, const uint8_t *buf,
467506
/* Enable TX DMA requests */
468507
USART_EnableTxDMA(config->base, true);
469508

509+
/* Do not allow the system to suspend until the transmission has completed */
510+
#ifdef CONFIG_PM_POLICY_DEVICE_CONSTRAINTS
511+
mcux_flexcomm_pm_policy_state_lock_get(dev);
512+
#endif
513+
470514
/* Trigger the DMA to start transfer */
471515
ret = dma_start(config->tx_dma.dev, config->tx_dma.channel);
472516
if (ret) {
473517
irq_unlock(key);
474-
return ret;
518+
#ifdef CONFIG_PM_POLICY_DEVICE_CONSTRAINTS
519+
mcux_flexcomm_pm_policy_state_lock_put(dev);
520+
#endif
521+
return ret;
475522
}
476523

477524
/* Schedule a TX abort for @param timeout */
@@ -993,15 +1040,18 @@ static void mcux_flexcomm_isr(const struct device *dev)
9931040
data->tx_data.xfer_buf = NULL;
9941041

9951042
async_user_callback(dev, &tx_done_event);
1043+
1044+
#ifdef CONFIG_PM_POLICY_DEVICE_CONSTRAINTS
1045+
mcux_flexcomm_pm_policy_state_lock_put(dev);
1046+
#endif
9961047
}
9971048

9981049
}
9991050
#endif /* CONFIG_UART_ASYNC_API */
10001051
}
10011052
#endif /* CONFIG_UART_MCUX_FLEXCOMM_ISR_SUPPORT */
10021053

1003-
1004-
static int mcux_flexcomm_init(const struct device *dev)
1054+
static int mcux_flexcomm_init_common(const struct device *dev)
10051055
{
10061056
const struct mcux_flexcomm_config *config = dev->config;
10071057
#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
@@ -1067,6 +1117,42 @@ static int mcux_flexcomm_init(const struct device *dev)
10671117
return 0;
10681118
}
10691119

1120+
static uint32_t usart_intenset;
1121+
static int mcux_flexcomm_pm_action(const struct device *dev, enum pm_device_action action)
1122+
{
1123+
const struct mcux_flexcomm_config *config = dev->config;
1124+
1125+
usart_intenset = USART_GetEnabledInterrupts(config->base);
1126+
1127+
switch (action) {
1128+
case PM_DEVICE_ACTION_RESUME:
1129+
break;
1130+
case PM_DEVICE_ACTION_SUSPEND:
1131+
break;
1132+
case PM_DEVICE_ACTION_TURN_OFF:
1133+
break;
1134+
case PM_DEVICE_ACTION_TURN_ON:
1135+
int ret = mcux_flexcomm_init_common(dev);
1136+
1137+
if (ret) {
1138+
return ret;
1139+
}
1140+
USART_EnableInterrupts(config->base, usart_intenset);
1141+
break;
1142+
default:
1143+
return -ENOTSUP;
1144+
}
1145+
return 0;
1146+
}
1147+
1148+
static int mcux_flexcomm_init(const struct device *dev)
1149+
{
1150+
/* Rest of the init is done from the PM_DEVICE_TURN_ON action
1151+
* which is invoked by pm_device_driver_init().
1152+
*/
1153+
return pm_device_driver_init(dev, mcux_flexcomm_pm_action);
1154+
}
1155+
10701156
static DEVICE_API(uart, mcux_flexcomm_driver_api) = {
10711157
.poll_in = mcux_flexcomm_poll_in,
10721158
.poll_out = mcux_flexcomm_poll_out,
@@ -1202,9 +1288,11 @@ static const struct mcux_flexcomm_config mcux_flexcomm_##n##_config = { \
12021288
\
12031289
static const struct mcux_flexcomm_config mcux_flexcomm_##n##_config; \
12041290
\
1291+
PM_DEVICE_DT_INST_DEFINE(n, mcux_flexcomm_pm_action); \
1292+
\
12051293
DEVICE_DT_INST_DEFINE(n, \
1206-
mcux_flexcomm_init, \
1207-
NULL, \
1294+
&mcux_flexcomm_init, \
1295+
PM_DEVICE_DT_INST_GET(n), \
12081296
&mcux_flexcomm_##n##_data, \
12091297
&mcux_flexcomm_##n##_config, \
12101298
PRE_KERNEL_1, \

dts/arm/nxp/nxp_rw6xx_common.dtsi

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@
225225
resets = <&rstctl1 NXP_SYSCON_RESET(0, 8)>;
226226
dmas = <&dma0 0>, <&dma0 1>;
227227
dma-names = "rx", "tx";
228+
zephyr,disabling-power-states = <&suspend>;
228229
status = "disabled";
229230
};
230231

@@ -236,6 +237,7 @@
236237
resets = <&rstctl1 NXP_SYSCON_RESET(0, 9)>;
237238
dmas = <&dma0 2>, <&dma0 3>;
238239
dma-names = "rx", "tx";
240+
zephyr,disabling-power-states = <&suspend>;
239241
status = "disabled";
240242
};
241243

@@ -247,6 +249,7 @@
247249
resets = <&rstctl1 NXP_SYSCON_RESET(0, 10)>;
248250
dmas = <&dma0 4>, <&dma0 5>;
249251
dma-names = "rx", "tx";
252+
zephyr,disabling-power-states = <&suspend>;
250253
status = "disabled";
251254
};
252255

@@ -258,6 +261,7 @@
258261
resets = <&rstctl1 NXP_SYSCON_RESET(0, 11)>;
259262
dmas = <&dma0 6>, <&dma0 7>;
260263
dma-names = "rx", "tx";
264+
zephyr,disabling-power-states = <&suspend>;
261265
status = "disabled";
262266
};
263267

@@ -269,6 +273,7 @@
269273
resets = <&rstctl1 NXP_SYSCON_RESET(0, 22)>;
270274
dmas = <&dma0 26>, <&dma0 27>;
271275
dma-names = "rx", "tx";
276+
zephyr,disabling-power-states = <&suspend>;
272277
status = "disabled";
273278
};
274279

0 commit comments

Comments
 (0)