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 <liaoao@xiaomi.com>
This commit is contained in:
liaoao
2025-02-07 17:14:52 +08:00
committed by Xiang Xiao
parent abe28e1bcf
commit de5ec3be6c
2 changed files with 104 additions and 4 deletions
+52 -2
View File
@@ -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:
+52 -2
View File
@@ -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: