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/12/28 05:25:37 UTC

[incubator-nuttx] 01/02: regulator/rpmsg: pending in wait ept ready for regulator client

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 a22dae19c157cda10608e6128d9360d5b495c4e6
Author: zhuyanlin <zh...@xiaomi.com>
AuthorDate: Thu Dec 23 17:16:26 2021 +0800

    regulator/rpmsg: pending in wait ept ready for regulator client
    
    Signed-off-by: zhuyanlin <zh...@xiaomi.com>
---
 drivers/power/Kconfig           |   1 +
 drivers/power/regulator_rpmsg.c | 165 +++++++++++++++++++++++++++++-----------
 include/nuttx/power/regulator.h |   7 +-
 3 files changed, 127 insertions(+), 46 deletions(-)

diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index eb1a3d4..4eaec85 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -353,6 +353,7 @@ config REGULATOR
 
 config REGULATOR_RPMSG
 	bool "Regulator rpmsg driver support"
+	depends on OPENAMP
 	default n
 	---help---
 		The rpmsg regulator driver implements the common regulator APIs, inside which
diff --git a/drivers/power/regulator_rpmsg.c b/drivers/power/regulator_rpmsg.c
index b0b2cd8..d9b4502 100644
--- a/drivers/power/regulator_rpmsg.c
+++ b/drivers/power/regulator_rpmsg.c
@@ -86,11 +86,17 @@ struct regulator_rpmsg_cookie_s
   sem_t                             sem;
 };
 
-struct regulator_rpmsg_priv_s
+struct regulator_rpmsg_client_s
 {
   struct rpmsg_endpoint             ept;
   FAR const char                   *cpuname;
   struct list_node                  node;
+  sem_t                             sem;
+};
+
+struct regulator_rpmsg_server_s
+{
+  struct rpmsg_endpoint             ept;
   struct list_node                  regulator_list;
 };
 
@@ -124,6 +130,17 @@ static int regulator_rpmsg_isenabled_handler(FAR struct rpmsg_endpoint *ept,
                                              FAR void *data, size_t len,
                                              uint32_t src, FAR void *priv_);
 
+static void regulator_rpmsg_client_created(struct rpmsg_device *rdev,
+                                           FAR void *priv_);
+static void regulator_rpmsg_client_destroy(struct rpmsg_device *rdev,
+                                           FAR void *priv_);
+
+static void regulator_rpmsg_server_unbind(FAR struct rpmsg_endpoint *ept);
+static void regulator_rpmsg_server_bind(FAR struct rpmsg_device *rdev,
+                                        FAR void *priv_,
+                                        FAR const char *name,
+                                        uint32_t dest);
+
 static int regulator_rpmsg_set_voltage(FAR struct regulator_dev_s *rdev,
                                        int min_uv, int max_uv,
                                        FAR unsigned *selector);
@@ -162,26 +179,46 @@ static const struct regulator_ops_s g_regulator_rpmsg_ops =
  * Private Functions
  ****************************************************************************/
 
-static struct regulator_rpmsg_priv_s *
+static struct regulator_rpmsg_client_s *
 regulator_rpmsg_get_priv(FAR const char *name)
 {
-  FAR struct regulator_rpmsg_priv_s *priv;
+  FAR struct regulator_rpmsg_client_s *priv;
+  FAR const char *slash = strchr(name, '/');
+
+  if (!slash)
+    {
+      return NULL;
+    }
 
   nxmutex_lock(&g_regulator_rpmsg_lock);
 
   list_for_every_entry(&g_regulator_rpmsg_priv, priv,
-                       struct regulator_rpmsg_priv_s, node)
+                       struct regulator_rpmsg_client_s, node)
     {
-      size_t len = strlen(priv->cpuname);
-
-      if (!strncmp(priv->cpuname, name, len) &&
-         (name[len] == '/' || name[len] == 0))
+      if (!strncmp(priv->cpuname, name, slash - name))
         {
           goto out; /* Find the target, exit */
         }
     }
 
-  priv = NULL;
+  priv = kmm_zalloc(sizeof(struct regulator_rpmsg_client_s));
+  if (!priv)
+    {
+      goto out;
+    }
+
+  priv->cpuname = strndup(name, slash - name);
+
+  list_add_head(&g_regulator_rpmsg_priv, &priv->node);
+
+  nxmutex_unlock(&g_regulator_rpmsg_lock);
+
+  rpmsg_register_callback(priv,
+                          regulator_rpmsg_client_created,
+                          regulator_rpmsg_client_destroy,
+                          NULL);
+
+  return priv;
 
 out:
   nxmutex_unlock(&g_regulator_rpmsg_lock);
@@ -190,14 +227,27 @@ out:
 
 static struct rpmsg_endpoint *regulator_rpmsg_get_ept(FAR const char **name)
 {
-  FAR struct regulator_rpmsg_priv_s *priv;
+  FAR struct regulator_rpmsg_client_s *priv;
+  int ret = 0;
 
   priv = regulator_rpmsg_get_priv(*name);
-  if (priv == NULL)
+
+  if (!priv)
     {
       return NULL;
     }
 
+  if (!is_rpmsg_ept_ready(&priv->ept))
+    {
+      ret = nxsem_wait_uninterruptible(&priv->sem);
+      if (ret < 0)
+        {
+          return NULL;
+        }
+
+      nxsem_post(&priv->sem);
+    }
+
   *name += strlen(priv->cpuname) + 1;
 
   return &priv->ept;
@@ -206,7 +256,7 @@ static struct rpmsg_endpoint *regulator_rpmsg_get_ept(FAR const char **name)
 static FAR struct regulator_s *
 regulator_rpmsg_get_reg(FAR struct rpmsg_endpoint *ept, FAR const char *name)
 {
-  FAR struct regulator_rpmsg_priv_s *priv = ept->priv;
+  FAR struct regulator_rpmsg_server_s *priv = ept->priv;
   FAR struct list_node *regulator_list = &priv->regulator_list;
   FAR struct regulator_rpmsg_s *reg;
 
@@ -237,48 +287,47 @@ regulator_rpmsg_get_reg(FAR struct rpmsg_endpoint *ept, FAR const char *name)
   return reg->regulator;
 }
 
-static void regulator_rpmsg_device_created(struct rpmsg_device *rdev,
+static void regulator_rpmsg_client_created(struct rpmsg_device *rdev,
                                            FAR void *priv_)
 {
-  FAR struct regulator_rpmsg_priv_s *priv;
-  int ret;
+  FAR struct regulator_rpmsg_client_s *priv = priv_;
 
-  priv = kmm_zalloc(sizeof(struct regulator_rpmsg_priv_s));
   if (!priv)
     {
       return;
     }
 
-  priv->ept.priv = priv;
-  priv->cpuname  = rpmsg_get_cpuname(rdev);
+  if (!strcmp(priv->cpuname, rpmsg_get_cpuname(rdev)))
+    {
+      priv->ept.priv = priv;
 
-  list_initialize(&priv->regulator_list);
-  nxmutex_lock(&g_regulator_rpmsg_lock);
-  list_add_head(&g_regulator_rpmsg_priv, &priv->node);
-  nxmutex_unlock(&g_regulator_rpmsg_lock);
+      rpmsg_create_ept(&priv->ept, rdev, REGULATOR_RPMSG_EPT_NAME,
+                       RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
+                       regulator_rpmsg_ept_cb, NULL);
 
-  ret = rpmsg_create_ept(&priv->ept, rdev, REGULATOR_RPMSG_EPT_NAME,
-                         RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
-                         regulator_rpmsg_ept_cb, NULL);
-  if (ret)
-    {
-      free(priv);
+      nxsem_post(&priv->sem);
     }
 }
 
-static void regulator_rpmsg_device_destroy(struct rpmsg_device *rdev,
+static void regulator_rpmsg_client_destroy(struct rpmsg_device *rdev,
                                            FAR void *priv_)
 {
-  FAR struct regulator_rpmsg_priv_s *priv;
-  FAR struct regulator_rpmsg_s *reg;
-
-  priv = regulator_rpmsg_get_priv(rpmsg_get_cpuname(rdev));
+  FAR struct regulator_rpmsg_client_s *priv = priv_;
 
   if (!priv)
     {
       return;
     }
 
+  nxsem_wait(&priv->sem);
+  rpmsg_destroy_ept(&priv->ept);
+}
+
+static void regulator_rpmsg_server_unbind(FAR struct rpmsg_endpoint *ept)
+{
+  FAR struct regulator_rpmsg_server_s *priv = ept->priv;
+  FAR struct regulator_rpmsg_s *reg;
+
   list_for_every_entry(&priv->regulator_list, reg,
                        struct regulator_rpmsg_s, node)
     {
@@ -292,14 +341,37 @@ static void regulator_rpmsg_device_destroy(struct rpmsg_device *rdev,
       kmm_free(reg);
     }
 
-  nxmutex_lock(&g_regulator_rpmsg_lock);
-  list_delete(&priv->node);
-  nxmutex_unlock(&g_regulator_rpmsg_lock);
+  rpmsg_destroy_ept(ept);
 
-  rpmsg_destroy_ept(&priv->ept);
   kmm_free(priv);
 }
 
+static void regulator_rpmsg_server_bind(FAR struct rpmsg_device *rdev,
+                                        FAR void *priv_,
+                                        FAR const char *name,
+                                        uint32_t dest)
+{
+  FAR struct regulator_rpmsg_server_s *priv;
+
+  if (!strcmp(name, REGULATOR_RPMSG_EPT_NAME))
+    {
+      priv = kmm_zalloc(sizeof(struct regulator_rpmsg_server_s));
+      if (!priv)
+        {
+          return;
+        }
+
+      priv->ept.priv = priv;
+
+      list_initialize(&priv->regulator_list);
+
+      rpmsg_create_ept(&priv->ept, rdev, name,
+                       RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
+                       regulator_rpmsg_ept_cb,
+                       regulator_rpmsg_server_unbind);
+    }
+}
+
 static int regulator_rpmsg_ept_cb(FAR struct rpmsg_endpoint *ept,
                                   FAR void *data, size_t len,
                                   uint32_t src, FAR void *priv_)
@@ -584,6 +656,7 @@ static int regulator_rpmsg_is_enabled(FAR struct regulator_dev_s *rdev)
 FAR struct regulator_dev_s *regulator_rpmsg_get(FAR const char *name)
 {
   FAR struct regulator_desc_s *desc;
+  FAR struct regulator_dev_s *dev;
 
   desc = kmm_zalloc(sizeof(struct regulator_desc_s));
   if (!desc)
@@ -593,11 +666,17 @@ FAR struct regulator_dev_s *regulator_rpmsg_get(FAR const char *name)
 
   desc->name = name;
 
-  return regulator_register(desc, &g_regulator_rpmsg_ops, NULL);
+  dev = regulator_register(desc, &g_regulator_rpmsg_ops, NULL);
+  if (!dev)
+    {
+      kmm_free(desc);
+    }
+
+  return dev;
 }
 
 /****************************************************************************
- * Name: regulator_rpmsg_init
+ * Name: regulator_rpmsg_server_init
  *
  * Description:
  *
@@ -610,10 +689,10 @@ FAR struct regulator_dev_s *regulator_rpmsg_get(FAR const char *name)
  *
  ****************************************************************************/
 
-int regulator_rpmsg_init(void)
+int regulator_rpmsg_server_init(void)
 {
   return rpmsg_register_callback(NULL,
-                                 regulator_rpmsg_device_created,
-                                 regulator_rpmsg_device_destroy,
-                                 NULL);
+                                 NULL,
+                                 NULL,
+                                 regulator_rpmsg_server_bind);
 }
diff --git a/include/nuttx/power/regulator.h b/include/nuttx/power/regulator.h
index 9809cd2..bec5c37 100644
--- a/include/nuttx/power/regulator.h
+++ b/include/nuttx/power/regulator.h
@@ -197,19 +197,20 @@ int regulator_gpio_init(FAR struct ioexpander_dev_s *iodev,
 FAR struct regulator_dev_s *regulator_rpmsg_get(FAR const char *name);
 
 /****************************************************************************
- * Name: regulator_rpmsg_init
+ * Name: regulator_rpmsg_server_init
  *
  * Description:
  *
+ *   Establish rpmsg channel for the operations of the remote regulator
+ *
  * Input Parameters:
  *
  * Returned Value:
- *
  *   Zero (OK) on success; a negated errno on failure
  *
  ****************************************************************************/
 
-int regulator_rpmsg_init(void);
+int regulator_rpmsg_server_init(void);
 
 #endif