@@ -110,6 +110,19 @@ LOG_MODULE_REGISTER(uart_nrfx_uarte, CONFIG_UART_LOG_LEVEL);
110110#define UARTE_ANY_LOW_POWER 1
111111#endif
112112
113+ BUILD_ASSERT (NRF_GPD_FAST_ACTIVE1 == 0 );
114+ /* Macro must resolve to literal 0 or 1 */
115+ #define INSTANCE_IS_FAST (unused , prefix , idx , _ ) \
116+ COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(UARTE(idx)), \
117+ (COND_CODE_1(UTIL_AND(IS_ENABLED(CONFIG_SOC_NRF54H20_GPD), \
118+ DT_NODE_HAS_PROP(UARTE(idx), power_domains)), \
119+ (COND_CODE_0(DT_PHA(UARTE(idx), power_domains, id), (1), (0))),\
120+ (0))), (0))
121+
122+ #if UARTE_FOR_EACH_INSTANCE (INSTANCE_IS_FAST , (|| ), (0 ))
123+ #define UARTE_ANY_FAST 1
124+ #endif
125+
113126#ifdef UARTE_ANY_CACHE
114127/* uart120 instance does not retain BAUDRATE register when ENABLE=0. When this instance
115128 * is used then baudrate must be set after enabling the peripheral and not before.
@@ -269,6 +282,21 @@ struct uarte_nrfx_data {
269282 (IS_ENABLED(UARTE_ANY_LOW_POWER) && \
270283 !IS_ENABLED(CONFIG_PM_DEVICE) && \
271284 (_config->flags & UARTE_CFG_FLAG_LOW_POWER))
285+
286+ /** @brief Check if device has PM that works in ISR safe mode.
287+ *
288+ * Only fast UARTE instance does not work in that mode so check PM configuration
289+ * flags only if there is any fast instance present.
290+ *
291+ * @retval true if device PM is ISR safe.
292+ * @retval false if device PM is not ISR safe.
293+ */
294+ #define IS_PM_ISR_SAFE (dev ) \
295+ (!IS_ENABLED(UARTE_ANY_FAST) ||\
296+ COND_CODE_1(CONFIG_PM_DEVICE,\
297+ ((dev->pm_base->flags & BIT(PM_DEVICE_FLAG_ISR_SAFE))), \
298+ (0)))
299+
272300/**
273301 * @brief Structure for UARTE configuration.
274302 */
@@ -873,6 +901,20 @@ static int uarte_nrfx_tx(const struct device *dev, const uint8_t *buf,
873901 }
874902
875903 if (IS_ENABLED (CONFIG_PM_DEVICE_RUNTIME )) {
904+ if (!IS_PM_ISR_SAFE (dev ) && k_is_in_isr ()) {
905+ /* If instance does not support PM from ISR device shall
906+ * already be turned on.
907+ */
908+ enum pm_device_state state ;
909+ int err ;
910+
911+ err = pm_device_state_get (dev , & state );
912+ (void )err ;
913+ __ASSERT_NO_MSG (err == 0 );
914+ if (state != PM_DEVICE_STATE_ACTIVE ) {
915+ return - ENOTSUP ;
916+ }
917+ }
876918 pm_device_runtime_get (dev );
877919 }
878920
@@ -941,6 +983,10 @@ static void notify_rx_disable(const struct device *dev)
941983 };
942984
943985 user_callback (dev , (struct uart_event * )& evt );
986+
987+ if (IS_ENABLED (CONFIG_PM_DEVICE_RUNTIME )) {
988+ pm_device_runtime_put_async (dev , K_NO_WAIT );
989+ }
944990}
945991
946992#ifdef UARTE_HAS_FRAME_TIMEOUT
@@ -1015,6 +1061,24 @@ static int uarte_nrfx_rx_enable(const struct device *dev, uint8_t *buf,
10151061 async_rx -> next_buf = NULL ;
10161062 async_rx -> next_buf_len = 0 ;
10171063
1064+ if (IS_ENABLED (CONFIG_PM_DEVICE_RUNTIME )) {
1065+ if (!IS_PM_ISR_SAFE (dev ) && k_is_in_isr ()) {
1066+ /* If instance does not support PM from ISR device shall
1067+ * already be turned on.
1068+ */
1069+ enum pm_device_state state ;
1070+ int err ;
1071+
1072+ err = pm_device_state_get (dev , & state );
1073+ (void )err ;
1074+ __ASSERT_NO_MSG (err == 0 );
1075+ if (state != PM_DEVICE_STATE_ACTIVE ) {
1076+ return - ENOTSUP ;
1077+ }
1078+ }
1079+ pm_device_runtime_get (dev );
1080+ }
1081+
10181082 if (IS_ENABLED (CONFIG_PM_DEVICE_RUNTIME ) || LOW_POWER_ENABLED (cfg )) {
10191083 if (async_rx -> flush_cnt ) {
10201084 int cpy_len = MIN (len , async_rx -> flush_cnt );
@@ -1068,9 +1132,7 @@ static int uarte_nrfx_rx_enable(const struct device *dev, uint8_t *buf,
10681132
10691133 async_rx -> enabled = true;
10701134
1071- if (IS_ENABLED (CONFIG_PM_DEVICE_RUNTIME )) {
1072- pm_device_runtime_get (dev );
1073- } else if (LOW_POWER_ENABLED (cfg )) {
1135+ if (LOW_POWER_ENABLED (cfg )) {
10741136 unsigned int key = irq_lock ();
10751137
10761138 uarte_enable_locked (dev , UARTE_FLAG_LOW_POWER_RX );
@@ -1543,9 +1605,7 @@ static void rxto_isr(const struct device *dev)
15431605 nrf_uarte_event_clear (uarte , NRF_UARTE_EVENT_RXDRDY );
15441606#endif
15451607
1546- if (IS_ENABLED (CONFIG_PM_DEVICE_RUNTIME )) {
1547- pm_device_runtime_put (dev );
1548- } else if (LOW_POWER_ENABLED (config )) {
1608+ if (LOW_POWER_ENABLED (config )) {
15491609 uint32_t key = irq_lock ();
15501610
15511611 uarte_disable_locked (dev , UARTE_FLAG_LOW_POWER_RX );
@@ -1570,7 +1630,7 @@ static void txstopped_isr(const struct device *dev)
15701630 if (IS_ENABLED (CONFIG_PM_DEVICE_RUNTIME )) {
15711631 nrf_uarte_int_disable (uarte , NRF_UARTE_INT_TXSTOPPED_MASK );
15721632 if (data -> flags & UARTE_FLAG_POLL_OUT ) {
1573- pm_device_runtime_put (dev );
1633+ pm_device_runtime_put_async (dev , K_NO_WAIT );
15741634 data -> flags &= ~UARTE_FLAG_POLL_OUT ;
15751635 }
15761636 } else if (LOW_POWER_ENABLED (config )) {
@@ -1633,11 +1693,11 @@ static void txstopped_isr(const struct device *dev)
16331693 data -> async -> tx .buf = NULL ;
16341694 data -> async -> tx .len = 0 ;
16351695
1696+ user_callback (dev , & evt );
1697+
16361698 if (IS_ENABLED (CONFIG_PM_DEVICE_RUNTIME )) {
1637- pm_device_runtime_put (dev );
1699+ pm_device_runtime_put_async (dev , K_NO_WAIT );
16381700 }
1639-
1640- user_callback (dev , & evt );
16411701}
16421702
16431703static void rxdrdy_isr (const struct device * dev )
@@ -1824,6 +1884,22 @@ static void uarte_nrfx_poll_out(const struct device *dev, unsigned char c)
18241884 }
18251885
18261886 if (IS_ENABLED (CONFIG_PM_DEVICE_RUNTIME )) {
1887+ if (!IS_PM_ISR_SAFE (dev ) && k_is_in_isr ()) {
1888+ /* If instance does not support PM from ISR device shall
1889+ * already be turned on.
1890+ */
1891+ enum pm_device_state state ;
1892+ int err ;
1893+
1894+ err = pm_device_state_get (dev , & state );
1895+ (void )err ;
1896+ __ASSERT_NO_MSG (err == 0 );
1897+ if (state != PM_DEVICE_STATE_ACTIVE ) {
1898+ irq_unlock (key );
1899+ return ;
1900+ }
1901+ }
1902+
18271903 if (!(data -> flags & UARTE_FLAG_POLL_OUT )) {
18281904 data -> flags |= UARTE_FLAG_POLL_OUT ;
18291905 pm_device_runtime_get (dev );
@@ -2417,7 +2493,8 @@ static int uarte_instance_init(const struct device *dev,
24172493 } \
24182494 \
24192495 PM_DEVICE_DT_DEFINE(UARTE(idx), uarte_nrfx_pm_action, \
2420- PM_DEVICE_ISR_SAFE); \
2496+ COND_CODE_1(INSTANCE_IS_FAST(_, /*empty*/ , idx , _),\
2497+ (0), (PM_DEVICE_ISR_SAFE))); \
24212498 \
24222499 DEVICE_DT_DEFINE(UARTE(idx), \
24232500 uarte_##idx##_init, \
0 commit comments