@@ -251,12 +251,15 @@ static void uart_ambiq_poll_out(const struct device *dev, unsigned char c)
251
251
{
252
252
struct uart_ambiq_data * data = dev -> data ;
253
253
uint32_t flag = 0 ;
254
+ unsigned int key ;
254
255
255
256
/* Wait for space in FIFO */
256
257
do {
257
258
am_hal_uart_flags_get (data -> uart_handler , & flag );
258
259
} while (flag & UART0_FR_TXFF_Msk );
259
260
261
+ key = irq_lock ();
262
+
260
263
/* If an interrupt transmission is in progress, the pm constraint is already managed by the
261
264
* call of uart_ambiq_irq_tx_[en|dis]able
262
265
*/
@@ -267,10 +270,13 @@ static void uart_ambiq_poll_out(const struct device *dev, unsigned char c)
267
270
* transmission has completed
268
271
*/
269
272
uart_ambiq_pm_policy_state_lock_get (dev );
273
+ am_hal_uart_interrupt_enable (data -> uart_handler , AM_HAL_UART_INT_TXCMP );
270
274
}
271
275
272
276
/* Send a character */
273
277
am_hal_uart_fifo_write (data -> uart_handler , & c , 1 , NULL );
278
+
279
+ irq_unlock (key );
274
280
}
275
281
276
282
static 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
302
308
{
303
309
struct uart_ambiq_data * data = dev -> data ;
304
310
int num_tx = 0U ;
311
+ unsigned int key ;
312
+
313
+ /* Lock interrupts to prevent nested interrupts or thread switch */
314
+ key = irq_lock ();
305
315
306
316
am_hal_uart_fifo_write (data -> uart_handler , (uint8_t * )tx_data , len , & num_tx );
307
317
318
+ irq_unlock (key );
319
+
308
320
return num_tx ;
309
321
}
310
322
@@ -322,14 +334,18 @@ static void uart_ambiq_irq_tx_enable(const struct device *dev)
322
334
{
323
335
const struct uart_ambiq_config * cfg = dev -> config ;
324
336
struct uart_ambiq_data * data = dev -> data ;
337
+ unsigned int key ;
325
338
339
+ key = irq_lock ();
326
340
data -> tx_poll_trans_on = false;
327
341
data -> tx_int_trans_on = true;
328
342
uart_ambiq_pm_policy_state_lock_get (dev );
329
343
330
344
am_hal_uart_interrupt_enable (data -> uart_handler ,
331
345
(AM_HAL_UART_INT_TX | AM_HAL_UART_INT_TXCMP ));
332
346
347
+ irq_unlock (key );
348
+
333
349
if (!data -> sw_call_txdrdy ) {
334
350
return ;
335
351
}
@@ -367,12 +383,17 @@ static void uart_ambiq_irq_tx_enable(const struct device *dev)
367
383
static void uart_ambiq_irq_tx_disable (const struct device * dev )
368
384
{
369
385
struct uart_ambiq_data * data = dev -> data ;
386
+ unsigned int key ;
387
+
388
+ key = irq_lock ();
370
389
371
390
data -> sw_call_txdrdy = true;
372
391
am_hal_uart_interrupt_disable (data -> uart_handler ,
373
392
(AM_HAL_UART_INT_TX | AM_HAL_UART_INT_TXCMP ));
374
393
data -> tx_int_trans_on = false;
375
394
uart_ambiq_pm_policy_state_lock_put (dev );
395
+
396
+ irq_unlock (key );
376
397
}
377
398
378
399
static int uart_ambiq_irq_tx_complete (const struct device * dev )
@@ -526,24 +547,42 @@ static int uart_ambiq_init(const struct device *dev)
526
547
#ifdef CONFIG_PM_DEVICE
527
548
static int uart_ambiq_pm_action (const struct device * dev , enum pm_device_action action )
528
549
{
550
+ const struct uart_ambiq_config * config = dev -> config ;
529
551
struct uart_ambiq_data * data = dev -> data ;
530
- uint32_t ret ;
531
552
am_hal_sysctrl_power_state_e status ;
553
+ int err ;
532
554
533
555
switch (action ) {
534
556
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
+ }
535
562
status = AM_HAL_SYSCTRL_WAKE ;
536
563
break ;
537
564
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
+ }
538
577
status = AM_HAL_SYSCTRL_DEEPSLEEP ;
539
578
break ;
540
579
default :
541
580
return - ENOTSUP ;
542
581
}
543
582
544
- ret = am_hal_uart_power_control (data -> uart_handler , status , true);
583
+ err = am_hal_uart_power_control (data -> uart_handler , status , true);
545
584
546
- if (ret != AM_HAL_STATUS_SUCCESS ) {
585
+ if (err != AM_HAL_STATUS_SUCCESS ) {
547
586
return - EPERM ;
548
587
} else {
549
588
return 0 ;
@@ -558,6 +597,7 @@ void uart_ambiq_isr(const struct device *dev)
558
597
uint32_t status = 0 ;
559
598
560
599
am_hal_uart_interrupt_status_get (data -> uart_handler , & status , false);
600
+ am_hal_uart_interrupt_clear (data -> uart_handler , status );
561
601
562
602
if (status & AM_HAL_UART_INT_TXCMP ) {
563
603
if (data -> tx_poll_trans_on ) {
@@ -605,7 +645,6 @@ void uart_ambiq_isr(const struct device *dev)
605
645
k_work_reschedule (& data -> async .rx .timeout_work , K_USEC (data -> async .rx .timeout ));
606
646
}
607
647
#endif /* CONFIG_UART_ASYNC_API */
608
- am_hal_uart_interrupt_clear (data -> uart_handler , status );
609
648
}
610
649
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
611
650
0 commit comments