This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit de5ec3be6cab5d18c6055bef6a2c1fcf8d393334 Author: liaoao <[email protected]> AuthorDate: Fri Feb 7 17:14:52 2025 +0800 drivers/rpmsg_port_spi/slave: notify remote core when reboot Now rpmsg_port_spi/slave support send shutdown command to remote core to notify then local core will reboot, so remote core can notify all the rpmsg services to do the unregister. Signed-off-by: liaoao <[email protected]> --- drivers/rpmsg/rpmsg_port_spi.c | 54 ++++++++++++++++++++++++++++++++++-- drivers/rpmsg/rpmsg_port_spi_slave.c | 54 ++++++++++++++++++++++++++++++++++-- 2 files changed, 104 insertions(+), 4 deletions(-) diff --git a/drivers/rpmsg/rpmsg_port_spi.c b/drivers/rpmsg/rpmsg_port_spi.c index 8f355e86560..ad74cbcb475 100644 --- a/drivers/rpmsg/rpmsg_port_spi.c +++ b/drivers/rpmsg/rpmsg_port_spi.c @@ -35,6 +35,7 @@ #include <nuttx/power/pm.h> #include <nuttx/irq.h> #include <nuttx/mutex.h> +#include <nuttx/reboot_notifier.h> #include <nuttx/spinlock.h> #include "rpmsg_port.h" @@ -50,6 +51,8 @@ # define rpmsg_port_spi_crc16(hdr) 0 #endif +#define RPMSG_PORT_SPI_CMD_TIMEOUT 1000 + #define BYTES2WORDS(s,b) ((b) / ((s)->nbits >> 3)) /**************************************************************************** @@ -110,6 +113,8 @@ struct rpmsg_port_spi_s struct wdog_s wdog; struct pm_wakelock_s wakelock; #endif + volatile bool shutdown; + struct notifier_block nb; /* Used for flow control */ @@ -312,13 +317,17 @@ static void rpmsg_port_spi_exchange(FAR struct rpmsg_port_spi_s *rpspi) return; } + txhdr = rpspi->cmdhdr; if (rpspi->state == RPMSG_PORT_SPI_STATE_UNCONNECTED) { - txhdr = rpspi->cmdhdr; txhdr->cmd = RPMSG_PORT_SPI_CMD_CONNECT; strlcpy((FAR char *)(txhdr + 1), rpspi->port.rpmsg.cpuname, RPMSG_NAME_SIZE); } + else if (rpspi->shutdown) + { + txhdr->cmd = RPMSG_PORT_SPI_CMD_SHUTDOWN; + } else if (rpspi->txavail > 0 && rpmsg_port_queue_nused(&rpspi->port.txq) > 0) { @@ -330,7 +339,6 @@ static void rpmsg_port_spi_exchange(FAR struct rpmsg_port_spi_s *rpspi) } else { - txhdr = rpspi->cmdhdr; txhdr->cmd = RPMSG_PORT_SPI_CMD_AVAIL; } @@ -367,6 +375,10 @@ static void rpmsg_port_spi_complete_handler(FAR void *arg) rpmsg_port_queue_return_buffer(&rpspi->port.txq, rpspi->txhdr); rpspi->txhdr = NULL; } + else if (rpspi->cmdhdr->cmd == RPMSG_PORT_SPI_CMD_SHUTDOWN) + { + rpspi->shutdown = false; + } if (rpspi->rxhdr->crc != 0) { @@ -710,6 +722,41 @@ rpmsg_port_spi_init_hardware(FAR struct rpmsg_port_spi_s *rpspi, return 0; } +/**************************************************************************** + * Name: rpmsg_port_spi_reboot_handler + ****************************************************************************/ + +static int +rpmsg_port_spi_reboot_handler(FAR struct notifier_block *nb, + unsigned long action, FAR void *data) +{ + FAR struct rpmsg_port_spi_s *rpspi = + container_of(nb, struct rpmsg_port_spi_s, nb); + int timeout = RPMSG_PORT_SPI_CMD_TIMEOUT / 10; + + if ((action == SYS_POWER_OFF || action == SYS_RESTART) && + rpspi->state == RPMSG_PORT_SPI_STATE_CONNECTED) + { + rpspi->shutdown = true; + IOEXP_WRITEPIN(rpspi->ioe, rpspi->mreq, 1); + + /* Wait until shutdown cmd has been sent done. */ + + while (timeout >= 0 && rpspi->shutdown) + { + usleep(10000); + timeout--; + } + + if (timeout < 0) + { + rpmsgerr("send cmd shutdown cmd timedout\n"); + } + } + + return 0; +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -792,6 +839,9 @@ rpmsg_port_spi_initialize(FAR const struct rpmsg_port_config_s *cfg, PM_IDLE_DOMAIN, PM_NORMAL); #endif + rpspi->nb.notifier_call = rpmsg_port_spi_reboot_handler; + register_reboot_notifier(&rpspi->nb); + return 0; out: diff --git a/drivers/rpmsg/rpmsg_port_spi_slave.c b/drivers/rpmsg/rpmsg_port_spi_slave.c index 71495b3254b..46c527abce3 100644 --- a/drivers/rpmsg/rpmsg_port_spi_slave.c +++ b/drivers/rpmsg/rpmsg_port_spi_slave.c @@ -35,6 +35,7 @@ #include <nuttx/power/pm.h> #include <nuttx/irq.h> #include <nuttx/mutex.h> +#include <nuttx/reboot_notifier.h> #include <nuttx/spinlock.h> #include "rpmsg_port.h" @@ -50,6 +51,8 @@ # define rpmsg_port_spi_crc16(hdr) 0 #endif +#define RPMSG_PORT_SPI_CMD_TIMEOUT 1000 + #define BYTES2WORDS(s,b) ((b) / ((s)->nbits >> 3)) /**************************************************************************** @@ -111,6 +114,8 @@ struct rpmsg_port_spi_s struct wdog_s wdog; struct pm_wakelock_s wakelock; #endif + volatile bool shutdown; + struct notifier_block nb; /* Used for flow control */ @@ -274,13 +279,17 @@ static void rpmsg_port_spi_exchange(FAR struct rpmsg_port_spi_s *rpspi) return; } + txhdr = rpspi->cmdhdr; if (rpspi->state == RPMSG_PORT_SPI_STATE_UNCONNECTED) { - txhdr = rpspi->cmdhdr; txhdr->cmd = RPMSG_PORT_SPI_CMD_CONNECT; strlcpy((FAR char *)(txhdr + 1), rpspi->port.rpmsg.cpuname, RPMSG_NAME_SIZE); } + else if (rpspi->shutdown) + { + txhdr->cmd = RPMSG_PORT_SPI_CMD_SHUTDOWN; + } else if (rpspi->txavail > 0 && rpmsg_port_queue_nused(&rpspi->port.txq) > 0) { @@ -292,7 +301,6 @@ static void rpmsg_port_spi_exchange(FAR struct rpmsg_port_spi_s *rpspi) } else { - txhdr = rpspi->cmdhdr; txhdr->cmd = RPMSG_PORT_SPI_CMD_AVAIL; } @@ -428,6 +436,10 @@ static void rpmsg_port_spi_slave_notify(FAR struct spi_slave_dev_s *dev, rpmsg_port_queue_return_buffer(&rpspi->port.txq, rpspi->txhdr); rpspi->txhdr = NULL; } + else if (rpspi->cmdhdr->cmd == RPMSG_PORT_SPI_CMD_SHUTDOWN) + { + rpspi->shutdown = false; + } if (rpspi->rxhdr->crc != 0) { @@ -743,6 +755,41 @@ rpmsg_port_spi_init_hardware(FAR struct rpmsg_port_spi_s *rpspi, return 0; } +/**************************************************************************** + * Name: rpmsg_port_spi_reboot_handler + ****************************************************************************/ + +static int +rpmsg_port_spi_reboot_handler(FAR struct notifier_block *nb, + unsigned long action, FAR void *data) +{ + FAR struct rpmsg_port_spi_s *rpspi = + container_of(nb, struct rpmsg_port_spi_s, nb); + int timeout = RPMSG_PORT_SPI_CMD_TIMEOUT / 10; + + if ((action == SYS_POWER_OFF || action == SYS_RESTART) && + rpspi->state == RPMSG_PORT_SPI_STATE_CONNECTED) + { + rpspi->shutdown = true; + rpmsg_port_spi_exchange(rpspi); + + /* Wait until shutdown cmd has been sent done. */ + + while (timeout >= 0 && rpspi->shutdown) + { + usleep(10000); + timeout--; + } + + if (timeout < 0) + { + rpmsgerr("send cmd shutdown cmd timedout\n"); + } + } + + return 0; +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -818,6 +865,9 @@ rpmsg_port_spi_slave_initialize(FAR const struct rpmsg_port_config_s *cfg, PM_IDLE_DOMAIN, PM_NORMAL); #endif + rpspi->nb.notifier_call = rpmsg_port_spi_reboot_handler; + register_reboot_notifier(&rpspi->nb); + return 0; out:
