drivers/rpmsg: add signals router for rpmsg router

Now the rpmsg router transport also support get the signals, and
this signals value is modified by other physical rpmsg transport
(port, virtio) other routed by the rpmsg router.

Signed-off-by: yintao <yintao@xiaomi.com>
This commit is contained in:
yintao
2025-01-12 19:20:05 +08:00
committed by Alan C. Assis
parent 492abaa052
commit f671ec648e
4 changed files with 99 additions and 8 deletions
+32
View File
@@ -32,8 +32,10 @@
#include <nuttx/rwsem.h>
#include <nuttx/semaphore.h>
#include <nuttx/rpmsg/rpmsg.h>
#include <rpmsg/rpmsg_internal.h>
#include "rpmsg_ping.h"
#include "rpmsg_router.h"
#include "rpmsg_test.h"
/****************************************************************************
@@ -587,6 +589,36 @@ void rpmsg_dump_all(void)
void rpmsg_modify_signals(FAR struct rpmsg_s *rpmsg,
int setflags, int clrflags)
{
FAR struct rpmsg_device *rdev = rpmsg->rdev;
FAR struct rpmsg_endpoint *ept;
FAR struct metal_list *node;
bool needlock;
atomic_fetch_and(&rpmsg->signals, ~clrflags);
atomic_fetch_or(&rpmsg->signals, setflags);
/* Send signal to Router Hub */
needlock = !up_interrupt_context() && !sched_idletask();
if (needlock)
{
metal_mutex_acquire(&rdev->lock);
}
metal_list_for_each(&rdev->endpoints, node)
{
ept = metal_container_of(node, struct rpmsg_endpoint, node);
if (!strncmp(ept->name, RPMSG_ROUTER_NAME,
RPMSG_ROUTER_NAME_LEN))
{
rpmsg_ept_incref(ept);
ept->cb(ept, NULL, 0, RPMSG_ADDR_ANY, NULL);
rpmsg_ept_decref(ept);
}
}
if (needlock)
{
metal_mutex_release(&rdev->lock);
}
}
+4 -2
View File
@@ -29,8 +29,6 @@
#include <nuttx/rpmsg/rpmsg.h>
#ifdef CONFIG_RPMSG_ROUTER
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@@ -43,6 +41,10 @@
#define RPMSG_ROUTER_CREATE 1
#define RPMSG_ROUTER_DESTROY 2
#define RPMSG_ROUTER_SUSPEND 3
#define RPMSG_ROUTER_RESUME 4
#ifdef CONFIG_RPMSG_ROUTER
/****************************************************************************
* Public Types
+25 -6
View File
@@ -683,15 +683,34 @@ static int rpmsg_router_cb(FAR struct rpmsg_endpoint *ept,
if (msg->cmd == RPMSG_ROUTER_DESTROY)
{
edge = ept->priv;
if (edge)
if (edge == NULL)
{
rpmsg_router_edge_destroy(edge);
ept->priv = NULL;
return 0;
return -EINVAL;
}
return -EINVAL;
rpmsg_router_edge_destroy(edge);
ept->priv = NULL;
return 0;
}
else if (msg->cmd == RPMSG_ROUTER_SUSPEND ||
msg->cmd == RPMSG_ROUTER_RESUME)
{
edge = ept->priv;
if (edge == NULL)
{
return -EINVAL;
}
if (msg->cmd == RPMSG_ROUTER_SUSPEND)
{
rpmsg_modify_signals(&edge->rpmsg, 0, RPMSG_SIGNAL_RUNNING);
}
else
{
rpmsg_modify_signals(&edge->rpmsg, RPMSG_SIGNAL_RUNNING, 0);
}
return 0;
}
/* Create the router edge device */
+38
View File
@@ -35,6 +35,7 @@
#include <nuttx/mutex.h>
#include <nuttx/kmalloc.h>
#include <nuttx/wqueue.h>
#include <rpmsg/rpmsg_internal.h>
#include "rpmsg_router.h"
@@ -59,6 +60,7 @@
struct rpmsg_router_hub_s
{
struct rpmsg_endpoint ept[2];
struct work_s work;
char cpuname[2][RPMSG_ROUTER_CPUNAME_LEN];
mutex_t lock;
};
@@ -359,6 +361,31 @@ static void rpmsg_router_bound(FAR struct rpmsg_endpoint *ept)
}
}
/****************************************************************************
* Name: rpmsg_router_notify_edge
****************************************************************************/
static void rpmsg_router_notify_edge(FAR void *arg)
{
FAR struct rpmsg_endpoint *ept = arg;
FAR struct rpmsg_router_hub_s *hub = ept->priv;
struct rpmsg_router_s msg;
int i;
msg.cmd = rpmsg_is_running(ept->rdev) ?
RPMSG_ROUTER_RESUME : RPMSG_ROUTER_SUSPEND;
for (i = 0; i < 2; i++)
{
if (strcmp(rpmsg_get_cpuname(ept->rdev), hub->cpuname[i]))
{
rpmsg_send(&hub->ept[i], &msg, sizeof(msg));
}
}
rpmsg_ept_decref(&hub->ept[0]);
rpmsg_ept_decref(&hub->ept[1]);
}
/****************************************************************************
* Name: rpmsg_router_cb
****************************************************************************/
@@ -366,6 +393,17 @@ static void rpmsg_router_bound(FAR struct rpmsg_endpoint *ept)
static int rpmsg_router_cb(FAR struct rpmsg_endpoint *ept, FAR void *data,
size_t len, uint32_t src, FAR void *priv)
{
FAR struct rpmsg_router_hub_s *hub = ept->priv;
/* Send pm signal to the other edge core */
if (data == NULL)
{
rpmsg_ept_incref(&hub->ept[0]);
rpmsg_ept_incref(&hub->ept[1]);
work_queue(HPWORK, &hub->work, rpmsg_router_notify_edge, ept, 0);
}
return 0;
}