@@ -251,12 +251,15 @@ static void uart_ambiq_poll_out(const struct device *dev, unsigned char c)
251251{
252252 struct uart_ambiq_data * data = dev -> data ;
253253 uint32_t flag = 0 ;
254+ unsigned int key ;
254255
255256 /* Wait for space in FIFO */
256257 do {
257258 am_hal_uart_flags_get (data -> uart_handler , & flag );
258259 } while (flag & UART0_FR_TXFF_Msk );
259260
261+ key = irq_lock ();
262+
260263 /* If an interrupt transmission is in progress, the pm constraint is already managed by the
261264 * call of uart_ambiq_irq_tx_[en|dis]able
262265 */
@@ -267,10 +270,13 @@ static void uart_ambiq_poll_out(const struct device *dev, unsigned char c)
267270 * transmission has completed
268271 */
269272 uart_ambiq_pm_policy_state_lock_get (dev );
273+ am_hal_uart_interrupt_enable (data -> uart_handler , AM_HAL_UART_INT_TXCMP );
270274 }
271275
272276 /* Send a character */
273277 am_hal_uart_fifo_write (data -> uart_handler , & c , 1 , NULL );
278+
279+ irq_unlock (key );
274280}
275281
276282static int uart_ambiq_err_check (const struct device * dev )
@@ -302,9 +308,15 @@ static int uart_ambiq_fifo_fill(const struct device *dev, const uint8_t *tx_data
302308{
303309 struct uart_ambiq_data * data = dev -> data ;
304310 int num_tx = 0U ;
311+ unsigned int key ;
312+
313+ /* Lock interrupts to prevent nested interrupts or thread switch */
314+ key = irq_lock ();
305315
306316 am_hal_uart_fifo_write (data -> uart_handler , (uint8_t * )tx_data , len , & num_tx );
307317
318+ irq_unlock (key );
319+
308320 return num_tx ;
309321}
310322
@@ -322,14 +334,18 @@ static void uart_ambiq_irq_tx_enable(const struct device *dev)
322334{
323335 const struct uart_ambiq_config * cfg = dev -> config ;
324336 struct uart_ambiq_data * data = dev -> data ;
337+ unsigned int key ;
325338
339+ key = irq_lock ();
326340 data -> tx_poll_trans_on = false;
327341 data -> tx_int_trans_on = true;
328342 uart_ambiq_pm_policy_state_lock_get (dev );
329343
330344 am_hal_uart_interrupt_enable (data -> uart_handler ,
331345 (AM_HAL_UART_INT_TX | AM_HAL_UART_INT_TXCMP ));
332346
347+ irq_unlock (key );
348+
333349 if (!data -> sw_call_txdrdy ) {
334350 return ;
335351 }
@@ -367,12 +383,17 @@ static void uart_ambiq_irq_tx_enable(const struct device *dev)
367383static void uart_ambiq_irq_tx_disable (const struct device * dev )
368384{
369385 struct uart_ambiq_data * data = dev -> data ;
386+ unsigned int key ;
387+
388+ key = irq_lock ();
370389
371390 data -> sw_call_txdrdy = true;
372391 am_hal_uart_interrupt_disable (data -> uart_handler ,
373392 (AM_HAL_UART_INT_TX | AM_HAL_UART_INT_TXCMP ));
374393 data -> tx_int_trans_on = false;
375394 uart_ambiq_pm_policy_state_lock_put (dev );
395+
396+ irq_unlock (key );
376397}
377398
378399static int uart_ambiq_irq_tx_complete (const struct device * dev )
@@ -526,24 +547,42 @@ static int uart_ambiq_init(const struct device *dev)
526547#ifdef CONFIG_PM_DEVICE
527548static int uart_ambiq_pm_action (const struct device * dev , enum pm_device_action action )
528549{
550+ const struct uart_ambiq_config * config = dev -> config ;
529551 struct uart_ambiq_data * data = dev -> data ;
530- uint32_t ret ;
531552 am_hal_sysctrl_power_state_e status ;
553+ int err ;
532554
533555 switch (action ) {
534556 case PM_DEVICE_ACTION_RESUME :
557+ /* Set pins to active state */
558+ err = pinctrl_apply_state (config -> pincfg , PINCTRL_STATE_DEFAULT );
559+ if (err < 0 ) {
560+ return err ;
561+ }
535562 status = AM_HAL_SYSCTRL_WAKE ;
536563 break ;
537564 case PM_DEVICE_ACTION_SUSPEND :
565+ /* Move pins to sleep state */
566+ err = pinctrl_apply_state (config -> pincfg , PINCTRL_STATE_SLEEP );
567+ if ((err < 0 ) && (err != - ENOENT )) {
568+ /*
569+ * If returning -ENOENT, no pins where defined for sleep mode :
570+ * Do not output on console (might sleep already) when going to sleep,
571+ * "(LP)UART pinctrl sleep state not available"
572+ * and don't block PM suspend.
573+ * Else return the error.
574+ */
575+ return err ;
576+ }
538577 status = AM_HAL_SYSCTRL_DEEPSLEEP ;
539578 break ;
540579 default :
541580 return - ENOTSUP ;
542581 }
543582
544- ret = am_hal_uart_power_control (data -> uart_handler , status , true);
583+ err = am_hal_uart_power_control (data -> uart_handler , status , true);
545584
546- if (ret != AM_HAL_STATUS_SUCCESS ) {
585+ if (err != AM_HAL_STATUS_SUCCESS ) {
547586 return - EPERM ;
548587 } else {
549588 return 0 ;
@@ -558,6 +597,7 @@ void uart_ambiq_isr(const struct device *dev)
558597 uint32_t status = 0 ;
559598
560599 am_hal_uart_interrupt_status_get (data -> uart_handler , & status , false);
600+ am_hal_uart_interrupt_clear (data -> uart_handler , status );
561601
562602 if (status & AM_HAL_UART_INT_TXCMP ) {
563603 if (data -> tx_poll_trans_on ) {
@@ -605,7 +645,6 @@ void uart_ambiq_isr(const struct device *dev)
605645 k_work_reschedule (& data -> async .rx .timeout_work , K_USEC (data -> async .rx .timeout ));
606646 }
607647#endif /* CONFIG_UART_ASYNC_API */
608- am_hal_uart_interrupt_clear (data -> uart_handler , status );
609648}
610649#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
611650
0 commit comments