rptun: add rpmsg_wait/post support for recursive dispatch
Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
parent
7471d096cc
commit
be49f6b87c
@ -34,10 +34,6 @@ config RPTUN_STACKSIZE
|
||||
depends on RPTUN_THREAD
|
||||
default 4096
|
||||
|
||||
config RPTUN_RECURSIVE_DISPATCH
|
||||
bool "rptun recursive dispatch"
|
||||
default y
|
||||
|
||||
config RPTUN_LOADER
|
||||
bool "rptun loader support"
|
||||
default n
|
||||
|
@ -69,10 +69,10 @@ struct rptun_priv_s
|
||||
struct rpmsg_virtio_shm_pool shm_pool;
|
||||
struct metal_list bind;
|
||||
struct metal_list node;
|
||||
sem_t sem;
|
||||
#ifdef CONFIG_RPTUN_WORKQUEUE
|
||||
struct work_s work;
|
||||
#else
|
||||
sem_t sem;
|
||||
int tid;
|
||||
#endif
|
||||
unsigned long cmd;
|
||||
@ -119,7 +119,7 @@ rptun_get_mem(FAR struct remoteproc *rproc,
|
||||
metal_phys_addr_t da,
|
||||
FAR void *va, size_t size,
|
||||
FAR struct remoteproc_mem *buf);
|
||||
static int rptun_can_recursive(FAR struct remoteproc *rproc);
|
||||
static int rptun_wait_tx_buffer(FAR struct remoteproc *rproc);
|
||||
|
||||
static void rptun_ns_bind(FAR struct rpmsg_device *rdev,
|
||||
FAR const char *name, uint32_t dest);
|
||||
@ -152,14 +152,14 @@ static metal_phys_addr_t rptun_da_to_pa(FAR struct rptun_dev_s *dev,
|
||||
|
||||
static struct remoteproc_ops g_rptun_ops =
|
||||
{
|
||||
.init = rptun_init,
|
||||
.remove = rptun_remove,
|
||||
.config = rptun_config,
|
||||
.start = rptun_start,
|
||||
.stop = rptun_stop,
|
||||
.notify = rptun_notify,
|
||||
.get_mem = rptun_get_mem,
|
||||
.can_recursive = rptun_can_recursive,
|
||||
.init = rptun_init,
|
||||
.remove = rptun_remove,
|
||||
.config = rptun_config,
|
||||
.start = rptun_start,
|
||||
.stop = rptun_stop,
|
||||
.notify = rptun_notify,
|
||||
.get_mem = rptun_get_mem,
|
||||
.wait_tx_buffer = rptun_wait_tx_buffer,
|
||||
};
|
||||
|
||||
static const struct file_operations g_rptun_devops =
|
||||
@ -274,11 +274,39 @@ static void rptun_worker(FAR void *arg)
|
||||
remoteproc_get_notification(&priv->rproc, RPTUN_NOTIFY_ALL);
|
||||
}
|
||||
|
||||
static void rptun_post(FAR struct rptun_priv_s *priv)
|
||||
{
|
||||
int semcount;
|
||||
|
||||
nxsem_get_value(&priv->sem, &semcount);
|
||||
while (semcount++ < 1)
|
||||
{
|
||||
nxsem_post(&priv->sem);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RPTUN_WORKQUEUE
|
||||
static void rptun_wakeup(FAR struct rptun_priv_s *priv)
|
||||
{
|
||||
work_queue(HPWORK, &priv->work, rptun_worker, priv, 0);
|
||||
rptun_post(priv);
|
||||
}
|
||||
|
||||
static void rptun_in_recursive(int tid, FAR void *arg)
|
||||
{
|
||||
if (gettid() == tid)
|
||||
{
|
||||
*((FAR bool *)arg) = true;
|
||||
}
|
||||
}
|
||||
|
||||
static bool rptun_is_recursive(FAR struct rptun_priv_s *priv)
|
||||
{
|
||||
bool in = false;
|
||||
work_foreach(HPWORK, rptun_in_recursive, &in);
|
||||
return in;
|
||||
}
|
||||
|
||||
#else
|
||||
static int rptun_thread(int argc, FAR char *argv[])
|
||||
{
|
||||
@ -298,13 +326,12 @@ static int rptun_thread(int argc, FAR char *argv[])
|
||||
|
||||
static void rptun_wakeup(FAR struct rptun_priv_s *priv)
|
||||
{
|
||||
int semcount;
|
||||
rptun_post(priv);
|
||||
}
|
||||
|
||||
nxsem_get_value(&priv->sem, &semcount);
|
||||
if (semcount < 1)
|
||||
{
|
||||
nxsem_post(&priv->sem);
|
||||
}
|
||||
static bool rptun_is_recursive(FAR struct rptun_priv_s *priv)
|
||||
{
|
||||
return gettid() == priv->tid;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -434,16 +461,21 @@ rptun_get_mem(FAR struct remoteproc *rproc,
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int rptun_can_recursive(FAR struct remoteproc *rproc)
|
||||
static int rptun_wait_tx_buffer(FAR struct remoteproc *rproc)
|
||||
{
|
||||
#ifndef CONFIG_RPTUN_RECURSIVE_DISPATCH
|
||||
return false;
|
||||
#elif defined(CONFIG_RPTUN_WORKQUEUE)
|
||||
return work_in_context(HPWORK);
|
||||
#else
|
||||
FAR struct rptun_priv_s *priv = rproc->priv;
|
||||
return gettid() == priv->tid;
|
||||
#endif
|
||||
|
||||
if (!rptun_is_recursive(priv))
|
||||
{
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* Wait to wakeup */
|
||||
|
||||
nxsem_wait(&priv->sem);
|
||||
rptun_worker(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *rptun_get_priv_by_rdev(FAR struct rpmsg_device *rdev)
|
||||
@ -453,6 +485,11 @@ static void *rptun_get_priv_by_rdev(FAR struct rpmsg_device *rdev)
|
||||
struct remoteproc_virtio *rpvdev;
|
||||
struct remoteproc *rproc;
|
||||
|
||||
if (!rdev)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rvdev = metal_container_of(rdev, struct rpmsg_virtio_device, rdev);
|
||||
vdev = rvdev->vdev;
|
||||
if (!vdev)
|
||||
@ -656,6 +693,10 @@ static int rptun_dev_start(FAR struct remoteproc *rproc)
|
||||
|
||||
rptun_lock();
|
||||
|
||||
/* Register callback to mbox for receiving remote message */
|
||||
|
||||
RPTUN_REGISTER_CALLBACK(priv->dev, rptun_callback, priv);
|
||||
|
||||
/* Add priv to list */
|
||||
|
||||
metal_list_add_tail(&g_rptun_priv, &priv->node);
|
||||
@ -673,10 +714,6 @@ static int rptun_dev_start(FAR struct remoteproc *rproc)
|
||||
|
||||
rptun_unlock();
|
||||
|
||||
/* Register callback to mbox for receiving remote message */
|
||||
|
||||
RPTUN_REGISTER_CALLBACK(priv->dev, rptun_callback, priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -880,6 +917,60 @@ static metal_phys_addr_t rptun_da_to_pa(FAR struct rptun_dev_s *dev,
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
int rpmsg_wait(FAR struct rpmsg_endpoint *ept, FAR sem_t *sem)
|
||||
{
|
||||
FAR struct rptun_priv_s *priv;
|
||||
int ret;
|
||||
|
||||
if (!ept)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
priv = rptun_get_priv_by_rdev(ept->rdev);
|
||||
if (!priv || !rptun_is_recursive(priv))
|
||||
{
|
||||
return nxsem_wait_uninterruptible(sem);
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
ret = nxsem_trywait(sem);
|
||||
if (ret >= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
nxsem_wait(&priv->sem);
|
||||
rptun_worker(priv);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rpmsg_post(FAR struct rpmsg_endpoint *ept, FAR sem_t *sem)
|
||||
{
|
||||
FAR struct rptun_priv_s *priv;
|
||||
int semcount;
|
||||
int ret;
|
||||
|
||||
if (!ept)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
nxsem_get_value(sem, &semcount);
|
||||
ret = nxsem_post(sem);
|
||||
|
||||
priv = rptun_get_priv_by_rdev(ept->rdev);
|
||||
if (priv && semcount >= 0)
|
||||
{
|
||||
rptun_post(priv);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
FAR const char *rpmsg_get_cpuname(FAR struct rpmsg_device *rdev)
|
||||
{
|
||||
FAR struct rptun_priv_s *priv = rptun_get_priv_by_rdev(rdev);
|
||||
@ -1022,6 +1113,8 @@ int rptun_initialize(FAR struct rptun_dev_s *dev)
|
||||
priv->cmd = RPTUNIOC_START;
|
||||
work_queue(HPWORK, &priv->work, rptun_worker, priv, 0);
|
||||
}
|
||||
|
||||
nxsem_init(&priv->sem, 0, 0);
|
||||
#else
|
||||
if (RPTUN_IS_AUTOSTART(dev))
|
||||
{
|
||||
@ -1033,8 +1126,6 @@ int rptun_initialize(FAR struct rptun_dev_s *dev)
|
||||
nxsem_init(&priv->sem, 0, 0);
|
||||
}
|
||||
|
||||
nxsem_set_protocol(&priv->sem, SEM_PRIO_NONE);
|
||||
|
||||
snprintf(arg1, sizeof(arg1), "0x%" PRIxPTR, (uintptr_t)priv);
|
||||
argv[0] = (void *)RPTUN_GET_CPUNAME(dev);
|
||||
argv[1] = arg1;
|
||||
@ -1049,6 +1140,7 @@ int rptun_initialize(FAR struct rptun_dev_s *dev)
|
||||
goto err_driver;
|
||||
}
|
||||
#endif
|
||||
nxsem_set_protocol(&priv->sem, SEM_PRIO_NONE);
|
||||
|
||||
return OK;
|
||||
|
||||
|
@ -54,6 +54,9 @@ extern "C"
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
int rpmsg_wait(FAR struct rpmsg_endpoint *ept, FAR sem_t *sem);
|
||||
int rpmsg_post(FAR struct rpmsg_endpoint *ept, FAR sem_t *sem);
|
||||
|
||||
const char *rpmsg_get_cpuname(FAR struct rpmsg_device *rdev);
|
||||
int rpmsg_register_callback(FAR void *priv,
|
||||
rpmsg_dev_cb_t device_created,
|
||||
|
Loading…
Reference in New Issue
Block a user