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(&params);
-  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)