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); }
