You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/07/27 02:38:15 UTC
[incubator-nuttx] 01/02: drivers/rptun: Start/stop remote processor
in the background thread
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/incubator-nuttx.git
commit 068353bba735e84656c4a30ce75261be683e6268
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Thu Jul 15 15:47:42 2021 +0800
drivers/rptun: Start/stop remote processor in the background thread
to avoid blocking the main thread initialization process
Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
Change-Id: Ib8ab2a661ee9540bb03d9d4d851a8d8ee212404e
---
drivers/rptun/rptun.c | 94 +++++++++++++++++++++++++++++++++++----------------
1 file changed, 64 insertions(+), 30 deletions(-)
diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c
index 14a115b..3711952 100644
--- a/drivers/rptun/rptun.c
+++ b/drivers/rptun/rptun.c
@@ -48,6 +48,8 @@
# define ALIGN_UP(s, a) (((s) + (a) - 1) & ~((a) - 1))
#endif
+#define RPTUNIOC_NONE 0
+
/****************************************************************************
* Private Types
****************************************************************************/
@@ -61,6 +63,7 @@ struct rptun_priv_s
struct metal_list bind;
struct metal_list node;
sem_t sem;
+ unsigned long cmd;
};
struct rptun_bind_s
@@ -169,19 +172,37 @@ static int rptun_thread(int argc, FAR char *argv[])
FAR struct rptun_priv_s *priv;
priv = (FAR struct rptun_priv_s *)((uintptr_t)strtoul(argv[2], NULL, 0));
+ remoteproc_init(&priv->rproc, &g_rptun_ops, priv);
while (1)
{
nxsem_wait_uninterruptible(&priv->sem);
- remoteproc_get_notification(&priv->rproc, RPTUN_NOTIFY_ALL);
+ switch (priv->cmd)
+ {
+ case RPTUNIOC_START:
+ if (priv->rproc.state == RPROC_OFFLINE)
+ {
+ rptun_dev_start(&priv->rproc);
+ }
+ break;
+
+ case RPTUNIOC_STOP:
+ if (priv->rproc.state != RPROC_OFFLINE)
+ {
+ rptun_dev_stop(&priv->rproc);
+ }
+ break;
+ }
+
+ priv->cmd = RPTUNIOC_NONE;
+ remoteproc_get_notification(&priv->rproc, RPTUN_NOTIFY_ALL);
}
return 0;
}
-static int rptun_callback(FAR void *arg, uint32_t vqid)
+static void rptun_wakeup(FAR struct rptun_priv_s *priv)
{
- FAR struct rptun_priv_s *priv = arg;
int semcount;
nxsem_get_value(&priv->sem, &semcount);
@@ -189,7 +210,11 @@ static int rptun_callback(FAR void *arg, uint32_t vqid)
{
nxsem_post(&priv->sem);
}
+}
+static int rptun_callback(FAR void *arg, uint32_t vqid)
+{
+ rptun_wakeup(arg);
return OK;
}
@@ -553,22 +578,18 @@ static int rptun_dev_ioctl(FAR struct file *filep, int cmd,
{
FAR struct inode *inode = filep->f_inode;
FAR struct rptun_priv_s *priv = inode->i_private;
- int ret = -ENOTTY;
+ int ret = OK;
switch (cmd)
{
case RPTUNIOC_START:
- if (priv->rproc.state == RPROC_OFFLINE)
- {
- ret = rptun_dev_start(&priv->rproc);
- }
+ case RPTUNIOC_STOP:
+ priv->cmd = cmd;
+ rptun_wakeup(priv);
break;
- case RPTUNIOC_STOP:
- if (priv->rproc.state != RPROC_OFFLINE)
- {
- ret = rptun_dev_stop(&priv->rproc);
- }
+ default:
+ ret = -ENOTTY;
break;
}
@@ -802,7 +823,7 @@ int rptun_initialize(FAR struct rptun_dev_s *dev)
int ret;
ret = metal_init(¶ms);
- if (ret)
+ if (ret < 0)
{
return ret;
}
@@ -810,18 +831,32 @@ int rptun_initialize(FAR struct rptun_dev_s *dev)
priv = kmm_zalloc(sizeof(struct rptun_priv_s));
if (priv == NULL)
{
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto err_mem;
}
- snprintf(arg1, 16, "0x%" PRIxPTR, (uintptr_t)priv);
+ priv->dev = dev;
+ if (RPTUN_IS_AUTOSTART(dev))
+ {
+ priv->cmd = RPTUNIOC_START;
+ }
+
+ metal_list_init(&priv->bind);
+ nxsem_init(&priv->sem, 0, RPTUN_IS_AUTOSTART(dev) ? 1 : 0);
+ nxsem_set_protocol(&priv->sem, SEM_PRIO_NONE);
+
+ snprintf(name, 32, "/dev/rptun/%s", RPTUN_GET_CPUNAME(dev));
+ ret = register_driver(name, &g_rptun_devops, 0666, priv);
+ if (ret < 0)
+ {
+ goto err_driver;
+ }
+ snprintf(arg1, 16, "0x%" PRIxPTR, (uintptr_t)priv);
argv[0] = (void *)RPTUN_GET_CPUNAME(dev);
argv[1] = arg1;
argv[2] = NULL;
- nxsem_init(&priv->sem, 0, 0);
- nxsem_set_protocol(&priv->sem, SEM_PRIO_NONE);
-
ret = kthread_create("rptun",
CONFIG_RPTUN_PRIORITY,
CONFIG_RPTUN_STACKSIZE,
@@ -829,22 +864,21 @@ int rptun_initialize(FAR struct rptun_dev_s *dev)
argv);
if (ret < 0)
{
- kmm_free(priv);
- return ret;
+ goto err_thread;
}
- priv->dev = dev;
+ return OK;
- metal_list_init(&priv->bind);
- remoteproc_init(&priv->rproc, &g_rptun_ops, priv);
+err_thread:
+ unregister_driver(name);
- if (RPTUN_IS_AUTOSTART(dev))
- {
- rptun_dev_start(&priv->rproc);
- }
+err_driver:
+ nxsem_destroy(&priv->sem);
+ kmm_free(priv);
- snprintf(name, 32, "/dev/rptun/%s", RPTUN_GET_CPUNAME(dev));
- return register_driver(name, &g_rptun_devops, 0666, priv);
+err_mem:
+ metal_finish();
+ return ret;
}
int rptun_boot(FAR const char *cpuname)