This is an automated email from the ASF dual-hosted git repository.

casaroli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 785be45041183f8030f0b326e670725024855556
Author: wangshaoxin <[email protected]>
AuthorDate: Fri Oct 30 04:11:07 2026 +0800

    drivers/rpmsg/rpmsg_port_uart: bound the peer wakeup in the reboot notifier
    
    rpmsg_port_uart_staywake() keeps sending the wakeup byte until the
    peer answers. The reboot notifier calls it before sending POWEROFF, so
    if the peer is already gone the reboot or poweroff blocks forever.
    
    Add rpmsg_port_uart_staywake_times(), which gives up after the given
    number of tries and returns -EAGAIN, and use 50 tries (about 5 seconds
    with the 100 ms wait per try) in the reboot notifier. The other callers
    keep waiting without a limit.
    
    Signed-off-by: wangshaoxin <[email protected]>
---
 drivers/rpmsg/rpmsg_port_uart.c | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/rpmsg/rpmsg_port_uart.c b/drivers/rpmsg/rpmsg_port_uart.c
index 766c4a3c1ab..4a0b0a28cba 100644
--- a/drivers/rpmsg/rpmsg_port_uart.c
+++ b/drivers/rpmsg/rpmsg_port_uart.c
@@ -101,6 +101,8 @@
 #define rpmsgerrdump(m,b,s)                lib_dumpbuffer(m, (FAR const 
uint8_t *)b, s)
 #define rpmsgvbs                           rpmsgerr
 
+#define rpmsg_port_uart_staywake(r)        rpmsg_port_uart_staywake_times(r, 
~0)
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
@@ -234,14 +236,16 @@ rpmsg_port_uart_send_one(FAR struct rpmsg_port_uart_s 
*rpuart, uint8_t ch)
 }
 
 /****************************************************************************
- * Name: rpmsg_port_uart_staywake
+ * Name: rpmsg_port_uart_staywake_times
  *
  * Description:
  *   Send wakeup data to peer if peer is suspended.
  *
  ****************************************************************************/
 
-static void rpmsg_port_uart_staywake(FAR struct rpmsg_port_uart_s *rpuart)
+static int
+rpmsg_port_uart_staywake_times(FAR struct rpmsg_port_uart_s *rpuart,
+                               unsigned int times)
 {
   pm_wakelock_stay(&rpuart->tx_wakelock);
 
@@ -249,12 +253,21 @@ static void rpmsg_port_uart_staywake(FAR struct 
rpmsg_port_uart_s *rpuart)
     {
       rpmsgdbg("Peer is running, no need to wakeup 0x%x 0x%x\n",
                rpuart->tx_staywake, rpuart->event.events);
-      return;
+      return 0;
     }
 
   rpmsg_port_uart_set(rpuart, RPMSG_PORT_UART_EVT_WAKING);
   for (; ; )
     {
+      if (times-- == 0)
+        {
+          rpmsg_port_uart_clear(rpuart, RPMSG_PORT_UART_EVT_WAKING);
+          pm_wakelock_relax(&rpuart->tx_wakelock);
+          rpmsgerr("Wakeup failed 0x%x 0x%lx\n",
+                   rpuart->tx_staywake, rpuart->event.events);
+          return -EAGAIN;
+        }
+
       rpmsgdbg("Try to wakeup peer 0x%x 0x%x\n",
                rpuart->tx_staywake, rpuart->event.events);
       rpmsg_port_uart_send_one(rpuart, rpuart->tx_staywake);
@@ -268,6 +281,7 @@ static void rpmsg_port_uart_staywake(FAR struct 
rpmsg_port_uart_s *rpuart)
   rpmsg_port_uart_clear(rpuart, RPMSG_PORT_UART_EVT_WAKING);
   rpmsgdbg("Wakeup peer success 0x%x 0x%x\n",
            rpuart->tx_staywake, rpuart->event.events);
+  return 0;
 }
 
 /****************************************************************************
@@ -935,7 +949,11 @@ static int rpmsg_port_uart_reboot_notifier(FAR struct 
notifier_block *nb,
   if ((action == SYS_POWER_OFF || action == SYS_RESTART) &&
       rpmsg_port_uart_check(rpuart, RPMSG_PORT_UART_EVT_CONNED))
     {
-      rpmsg_port_uart_staywake(rpuart);
+      if (rpmsg_port_uart_staywake_times(rpuart, 50) < 0)
+        {
+          rpmsgerr("Reboot wakeup timeout!\n");
+        }
+
       rpmsg_port_uart_send_one(rpuart, RPMSG_PORT_UART_POWEROFF);
     }
 

Reply via email to