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:36 UTC

[incubator-nuttx] branch master updated (cbd82f1 -> 1f87ded)

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git.


    from cbd82f1  compile/flags: remove redundant -fomit-frame-pointer from board flags
     new a22dae1  regulator/rpmsg: pending in wait ept ready for regulator client
     new 1f87ded  driver:clk: clk pending on semaphore waiting on IPC ready

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 drivers/clk/clk_rpmsg.c          | 220 ++++++++++++++++++++++++---------------
 drivers/power/Kconfig            |   1 +
 drivers/power/regulator_rpmsg.c  | 165 +++++++++++++++++++++--------
 include/nuttx/clk/clk_provider.h |   2 +-
 include/nuttx/power/regulator.h  |   7 +-
 5 files changed, 266 insertions(+), 129 deletions(-)

[incubator-nuttx] 02/02: driver:clk: clk pending on semaphore waiting on IPC ready

Posted by xi...@apache.org.
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 1f87ded9c2bee7b3e1397c458e93d7e7f3c9ad0c
Author: zhuyanlin <zh...@xiaomi.com>
AuthorDate: Fri Dec 24 18:44:47 2021 +0800

    driver:clk: clk pending on semaphore waiting on IPC ready
    
    Signed-off-by: zhuyanlin <zh...@xiaomi.com>
---
 drivers/clk/clk_rpmsg.c          | 220 ++++++++++++++++++++++++---------------
 include/nuttx/clk/clk_provider.h |   2 +-
 2 files changed, 139 insertions(+), 83 deletions(-)

diff --git a/drivers/clk/clk_rpmsg.c b/drivers/clk/clk_rpmsg.c
index 1276cc1..f96387d 100644
--- a/drivers/clk/clk_rpmsg.c
+++ b/drivers/clk/clk_rpmsg.c
@@ -56,12 +56,18 @@
  * Private Types
  ****************************************************************************/
 
-struct clk_rpmsg_priv_s
+struct clk_rpmsg_client_s
 {
   struct rpmsg_endpoint     ept;
-  struct list_node          clk_list;
   struct list_node          node;
   FAR const char            *cpuname;
+  sem_t                     sem;
+};
+
+struct clk_rpmsg_server_s
+{
+  struct rpmsg_endpoint     ept;
+  struct list_node          clk_list;
 };
 
 struct clk_rpmsg_s
@@ -117,7 +123,8 @@ begin_packed_struct struct clk_rpmsg_setphase_s
  * Private Function Prototypes
  ****************************************************************************/
 
-static FAR struct clk_rpmsg_priv_s *clk_rpmsg_get_priv(FAR const char *name);
+static FAR struct clk_rpmsg_client_s *
+clk_rpmsg_get_priv(FAR const char *name);
 static FAR struct rpmsg_endpoint *clk_rpmsg_get_ept(FAR const char **name);
 static FAR struct clk_rpmsg_s *
 clk_rpmsg_get_clk(FAR struct rpmsg_endpoint *ept,
@@ -148,11 +155,17 @@ static int clk_rpmsg_isenabled_handler(FAR struct rpmsg_endpoint *ept,
                                        FAR void *data, size_t len,
                                        uint32_t src, FAR void *priv);
 
-static void clk_rpmsg_device_created(FAR struct rpmsg_device *rdev,
+static void clk_rpmsg_client_created(FAR struct rpmsg_device *rdev,
                                      FAR void *priv_);
-static void clk_rpmsg_device_destroy(FAR struct rpmsg_device *rdev,
+static void clk_rpmsg_client_destroy(FAR struct rpmsg_device *rdev,
                                      FAR void *priv_);
 
+static void clk_rpmsg_server_bind(FAR struct rpmsg_device *rdev,
+                                  FAR void *priv_,
+                                  FAR const char *name,
+                                  uint32_t dest);
+static void clk_rpmsg_server_unbind(FAR struct rpmsg_endpoint *ept);
+
 static int clk_rpmsg_ept_cb(FAR struct rpmsg_endpoint *ept,
                             FAR void *data, size_t len,
                             uint32_t src, FAR void *priv);
@@ -199,25 +212,45 @@ static const rpmsg_ept_cb g_clk_rpmsg_handler[] =
  * Private Functions
  ****************************************************************************/
 
-static FAR struct clk_rpmsg_priv_s *clk_rpmsg_get_priv(FAR const char *name)
+static FAR struct clk_rpmsg_client_s *
+clk_rpmsg_get_priv(FAR const char *name)
 {
-  FAR struct clk_rpmsg_priv_s *priv;
+  FAR struct clk_rpmsg_client_s *priv;
+  FAR const char *slash = strchr(name, '/');
+
+  if (!slash)
+    {
+      return NULL;
+    }
 
   nxmutex_lock(&g_clk_rpmsg_lock);
 
   list_for_every_entry(&g_clk_rpmsg_priv, priv,
-                       struct clk_rpmsg_priv_s, node)
+                       struct clk_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;
         }
     }
 
-  priv = NULL;
+  priv = kmm_zalloc(sizeof(struct clk_rpmsg_client_s));
+  if (!priv)
+    {
+      goto out;
+    }
+
+  priv->cpuname = strndup(name, slash - name);
+
+  list_add_head(&g_clk_rpmsg_priv, &priv->node);
+
+  nxmutex_unlock(&g_clk_rpmsg_lock);
+
+  rpmsg_register_callback(priv,
+                          clk_rpmsg_client_created,
+                          clk_rpmsg_client_destroy,
+                          NULL);
+  return priv;
 
 out:
   nxmutex_unlock(&g_clk_rpmsg_lock);
@@ -226,7 +259,7 @@ out:
 
 static FAR struct rpmsg_endpoint *clk_rpmsg_get_ept(FAR const char **name)
 {
-  FAR struct clk_rpmsg_priv_s *priv;
+  FAR struct clk_rpmsg_client_s *priv;
 
   priv = clk_rpmsg_get_priv(*name);
   if (priv == NULL)
@@ -242,7 +275,7 @@ static FAR struct rpmsg_endpoint *clk_rpmsg_get_ept(FAR const char **name)
 static FAR struct clk_rpmsg_s *
 clk_rpmsg_get_clk(FAR struct rpmsg_endpoint *ept, FAR const char *name)
 {
-  FAR struct clk_rpmsg_priv_s *priv = ept->priv;
+  FAR struct clk_rpmsg_server_s *priv = ept->priv;
   FAR struct list_node *clk_list = &priv->clk_list;
   FAR struct clk_rpmsg_s *clkrp;
 
@@ -273,8 +306,8 @@ clk_rpmsg_get_clk(FAR struct rpmsg_endpoint *ept, FAR const char *name)
 }
 
 static int clk_rpmsg_enable_handler(FAR struct rpmsg_endpoint *ept,
-                                     FAR void *data, size_t len,
-                                     uint32_t src, FAR void *priv)
+                                    FAR void *data, size_t len,
+                                    uint32_t src, FAR void *priv)
 {
   FAR struct clk_rpmsg_enable_s *msg = data;
   FAR struct clk_rpmsg_s *clkrp = clk_rpmsg_get_clk(ept, msg->name);
@@ -335,9 +368,10 @@ static int clk_rpmsg_getrate_handler(FAR struct rpmsg_endpoint *ept,
   return rpmsg_send(ept, msg, sizeof(*msg));
 }
 
-static int clk_rpmsg_roundrate_handler(FAR struct rpmsg_endpoint *ept,
-                                       FAR void *data, size_t len,
-                                       uint32_t src, FAR void *priv)
+static int
+clk_rpmsg_roundrate_handler(FAR struct rpmsg_endpoint *ept,
+                            FAR void *data, size_t len,
+                            uint32_t src, FAR void *priv)
 {
   FAR struct clk_rpmsg_roundrate_s *msg = data;
   FAR struct clk_rpmsg_s *clkrp = clk_rpmsg_get_clk(ept, msg->name);
@@ -355,8 +389,8 @@ static int clk_rpmsg_roundrate_handler(FAR struct rpmsg_endpoint *ept,
 }
 
 static int clk_rpmsg_setrate_handler(FAR struct rpmsg_endpoint *ept,
-                                       FAR void *data, size_t len,
-                                       uint32_t src, FAR void *priv)
+                                     FAR void *data, size_t len,
+                                     uint32_t src, FAR void *priv)
 {
   FAR struct clk_rpmsg_setrate_s *msg = data;
   FAR struct clk_rpmsg_s *clkrp = clk_rpmsg_get_clk(ept, msg->name);
@@ -374,8 +408,8 @@ static int clk_rpmsg_setrate_handler(FAR struct rpmsg_endpoint *ept,
 }
 
 static int clk_rpmsg_setphase_handler(FAR struct rpmsg_endpoint *ept,
-                                       FAR void *data, size_t len,
-                                       uint32_t src, FAR void *priv)
+                                      FAR void *data, size_t len,
+                                      uint32_t src, FAR void *priv)
 {
   FAR struct clk_rpmsg_setphase_s *msg = data;
   FAR struct clk_rpmsg_s *clkrp = clk_rpmsg_get_clk(ept, msg->name);
@@ -393,8 +427,8 @@ static int clk_rpmsg_setphase_handler(FAR struct rpmsg_endpoint *ept,
 }
 
 static int clk_rpmsg_getphase_handler(FAR struct rpmsg_endpoint *ept,
-                                       FAR void *data, size_t len,
-                                       uint32_t src, FAR void *priv)
+                                      FAR void *data, size_t len,
+                                      uint32_t src, FAR void *priv)
 {
   FAR struct clk_rpmsg_getphase_s *msg = data;
   FAR struct clk_rpmsg_s *clkrp = clk_rpmsg_get_clk(ept, msg->name);
@@ -461,48 +495,37 @@ static int64_t clk_rpmsg_sendrecv(FAR struct rpmsg_endpoint *ept,
   return cookie.result;
 }
 
-static void clk_rpmsg_device_created(FAR struct rpmsg_device *rdev,
-                                     FAR void *priv_)
+static void clk_rpmsg_server_bind(FAR struct rpmsg_device *rdev,
+                                  FAR void *priv_,
+                                  FAR const char *name,
+                                  uint32_t dest)
 {
-  struct clk_rpmsg_priv_s *priv;
-  int ret;
+  FAR struct clk_rpmsg_server_s *priv;
 
-  priv = kmm_zalloc(sizeof(struct clk_rpmsg_priv_s));
-  if (!priv)
+  if (!strcmp(name, CLK_RPMSG_EPT_NAME))
     {
-      return;
-    }
-
-  priv->ept.priv = priv;
-  priv->cpuname  = rpmsg_get_cpuname(rdev);
+      priv = kmm_zalloc(sizeof(struct clk_rpmsg_server_s));
+      if (!priv)
+        {
+          return;
+        }
 
-  list_initialize(&priv->clk_list);
+      priv->ept.priv = priv;
 
-  nxmutex_lock(&g_clk_rpmsg_lock);
-  list_add_head(&g_clk_rpmsg_priv, &priv->node);
-  nxmutex_unlock(&g_clk_rpmsg_lock);
+      list_initialize(&priv->clk_list);
 
-  ret = rpmsg_create_ept(&priv->ept, rdev, CLK_RPMSG_EPT_NAME,
-                         RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
-                         clk_rpmsg_ept_cb, NULL);
-  if (ret)
-    {
-      free(priv);
+      rpmsg_create_ept(&priv->ept, rdev, name,
+                       RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
+                       clk_rpmsg_ept_cb,
+                       clk_rpmsg_server_unbind);
     }
 }
 
-static void clk_rpmsg_device_destroy(FAR struct rpmsg_device *rdev,
-                                     FAR void *priv_)
+static void clk_rpmsg_server_unbind(FAR struct rpmsg_endpoint *ept)
 {
-  struct clk_rpmsg_s *clkrp;
-  struct clk_rpmsg_s *clkrp_tmp;
-  struct clk_rpmsg_priv_s *priv;
-
-  priv = clk_rpmsg_get_priv(rpmsg_get_cpuname(rdev));
-  if (!priv)
-    {
-      return;
-    }
+  FAR struct clk_rpmsg_server_s *priv = ept->priv;
+  FAR struct clk_rpmsg_s *clkrp_tmp;
+  FAR struct clk_rpmsg_s *clkrp;
 
   list_for_every_entry_safe(&priv->clk_list, clkrp, clkrp_tmp,
                             struct clk_rpmsg_s, node)
@@ -516,14 +539,47 @@ static void clk_rpmsg_device_destroy(FAR struct rpmsg_device *rdev,
       kmm_free(clkrp);
     }
 
-  nxmutex_lock(&g_clk_rpmsg_lock);
-  list_delete(&priv->node);
-  nxmutex_unlock(&g_clk_rpmsg_lock);
+  rpmsg_destroy_ept(ept);
 
-  rpmsg_destroy_ept(&priv->ept);
   kmm_free(priv);
 }
 
+static void clk_rpmsg_client_created(FAR struct rpmsg_device *rdev,
+                                     FAR void *priv_)
+{
+  struct clk_rpmsg_client_s *priv = priv_;
+
+  if (!priv)
+    {
+      return;
+    }
+
+  if (!strcmp(priv->cpuname, rpmsg_get_cpuname(rdev)))
+    {
+      priv->ept.priv = priv;
+
+      rpmsg_create_ept(&priv->ept, rdev, CLK_RPMSG_EPT_NAME,
+                       RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
+                       clk_rpmsg_ept_cb, NULL);
+
+      nxsem_post(&priv->sem);
+    }
+}
+
+static void clk_rpmsg_client_destroy(FAR struct rpmsg_device *rdev,
+                                     FAR void *priv_)
+{
+  struct clk_rpmsg_client_s *priv = priv_;
+
+  if (!priv)
+    {
+      return;
+    }
+
+  nxsem_wait(&priv->sem);
+  rpmsg_destroy_ept(&priv->ept);
+}
+
 static int clk_rpmsg_ept_cb(FAR struct rpmsg_endpoint *ept, FAR void *data,
                             size_t len, uint32_t src, FAR void *priv)
 {
@@ -566,7 +622,7 @@ static int clk_rpmsg_enable(FAR struct clk_s *clk)
       return -ENODEV;
     }
 
-  len = sizeof(*msg) + B2C(strlen(name) + 1);
+  len = sizeof(*msg) + strlen(name) + 1;
 
   msg = rpmsg_get_tx_payload_buffer(ept, &size, true);
   if (!msg)
@@ -576,7 +632,7 @@ static int clk_rpmsg_enable(FAR struct clk_s *clk)
 
   DEBUGASSERT(len <= size);
 
-  cstr2bstr(msg->name, name);
+  strcpy(msg->name, name);
 
   return clk_rpmsg_sendrecv(ept, CLK_RPMSG_ENABLE,
                            (struct clk_rpmsg_header_s *)msg,
@@ -597,7 +653,7 @@ static void clk_rpmsg_disable(FAR struct clk_s *clk)
     return;
     }
 
-  len = sizeof(*msg) + B2C(strlen(name) + 1);
+  len = sizeof(*msg) + strlen(name) + 1;
 
   msg = rpmsg_get_tx_payload_buffer(ept, &size, true);
   if (!msg)
@@ -607,7 +663,7 @@ static void clk_rpmsg_disable(FAR struct clk_s *clk)
 
   DEBUGASSERT(len <= size);
 
-  cstr2bstr(msg->name, name);
+  strcpy(msg->name, name);
 
   clk_rpmsg_sendrecv(ept, CLK_RPMSG_DISABLE,
                     (struct clk_rpmsg_header_s *)msg, len);
@@ -627,7 +683,7 @@ static int clk_rpmsg_is_enabled(FAR struct clk_s *clk)
       return -ENODEV;
     }
 
-  len = sizeof(*msg) + B2C(strlen(name) + 1);
+  len = sizeof(*msg) + strlen(name) + 1;
 
   msg = rpmsg_get_tx_payload_buffer(ept, &size, true);
   if (!msg)
@@ -637,7 +693,7 @@ static int clk_rpmsg_is_enabled(FAR struct clk_s *clk)
 
   DEBUGASSERT(len <= size);
 
-  cstr2bstr(msg->name, name);
+  strcpy(msg->name, name);
 
   return clk_rpmsg_sendrecv(ept, CLK_RPMSG_ISENABLED,
                            (struct clk_rpmsg_header_s *)msg, len);
@@ -659,7 +715,7 @@ static uint32_t clk_rpmsg_round_rate(FAR struct clk_s *clk, uint32_t rate,
       return 0;
     }
 
-  len = sizeof(*msg) + B2C(strlen(name) + 1);
+  len = sizeof(*msg) + strlen(name) + 1;
 
   msg = rpmsg_get_tx_payload_buffer(ept, &size, true);
   if (!msg)
@@ -670,7 +726,7 @@ static uint32_t clk_rpmsg_round_rate(FAR struct clk_s *clk, uint32_t rate,
   DEBUGASSERT(len <= size);
 
   msg->rate = rate;
-  cstr2bstr(msg->name, name);
+  strcpy(msg->name, name);
 
   ret = clk_rpmsg_sendrecv(ept, CLK_RPMSG_ROUNDRATE,
                           (struct clk_rpmsg_header_s *)msg, len);
@@ -697,7 +753,7 @@ static int clk_rpmsg_set_rate(FAR struct clk_s *clk, uint32_t rate,
       return -ENODEV;
     }
 
-  len = sizeof(*msg) + B2C(strlen(name) + 1);
+  len = sizeof(*msg) + strlen(name) + 1;
 
   msg = rpmsg_get_tx_payload_buffer(ept, &size, true);
   if (!msg)
@@ -708,7 +764,7 @@ static int clk_rpmsg_set_rate(FAR struct clk_s *clk, uint32_t rate,
   DEBUGASSERT(len <= size);
 
   msg->rate = rate;
-  cstr2bstr(msg->name, name);
+  strcpy(msg->name, name);
 
   return clk_rpmsg_sendrecv(ept, CLK_RPMSG_SETRATE,
                            (struct clk_rpmsg_header_s *)msg, len);
@@ -730,7 +786,7 @@ static uint32_t clk_rpmsg_recalc_rate(FAR struct clk_s *clk,
       return 0;
     }
 
-  len = sizeof(*msg) + B2C(strlen(name) + 1);
+  len = sizeof(*msg) + strlen(name) + 1;
 
   msg = rpmsg_get_tx_payload_buffer(ept, &size, true);
   if (!msg)
@@ -740,7 +796,7 @@ static uint32_t clk_rpmsg_recalc_rate(FAR struct clk_s *clk,
 
   DEBUGASSERT(len <= size);
 
-  cstr2bstr(msg->name, name);
+  strcpy(msg->name, name);
 
   ret = clk_rpmsg_sendrecv(ept, CLK_RPMSG_GETRATE,
                           (struct clk_rpmsg_header_s *)msg, len);
@@ -766,7 +822,7 @@ static int clk_rpmsg_get_phase(FAR struct clk_s *clk)
       return -ENODEV;
     }
 
-  len = sizeof(*msg) + B2C(strlen(name) + 1);
+  len = sizeof(*msg) + strlen(name) + 1;
 
   msg = rpmsg_get_tx_payload_buffer(ept, &size, true);
   if (!msg)
@@ -776,7 +832,7 @@ static int clk_rpmsg_get_phase(FAR struct clk_s *clk)
 
   DEBUGASSERT(len <= size);
 
-  cstr2bstr(msg->name, name);
+  strcpy(msg->name, name);
 
   return clk_rpmsg_sendrecv(ept, CLK_RPMSG_GETPHASE,
                            (struct clk_rpmsg_header_s *)msg, len);
@@ -796,7 +852,7 @@ static int clk_rpmsg_set_phase(FAR struct clk_s *clk, int degrees)
       return -ENODEV;
     }
 
-  len = sizeof(*msg) + B2C(strlen(name) + 1);
+  len = sizeof(*msg) + strlen(name) + 1;
 
   msg = rpmsg_get_tx_payload_buffer(ept, &size, true);
   if (!msg)
@@ -807,7 +863,7 @@ static int clk_rpmsg_set_phase(FAR struct clk_s *clk, int degrees)
   DEBUGASSERT(len <= size);
 
   msg->degrees = degrees;
-  cstr2bstr(msg->name, name);
+  strcpy(msg->name, name);
 
   return clk_rpmsg_sendrecv(ept, CLK_RPMSG_SETPHASE,
                            (struct clk_rpmsg_header_s *)msg, len);
@@ -844,10 +900,10 @@ FAR struct clk_s *clk_register_rpmsg(FAR const char *name, uint8_t flags)
                       &g_clk_rpmsg_ops, NULL, 0);
 }
 
-int clk_rpmsg_initialize(void)
+int clk_rpmsg_server_initialize(void)
 {
   return rpmsg_register_callback(NULL,
-                                 clk_rpmsg_device_created,
-                                 clk_rpmsg_device_destroy,
-                                 NULL);
+                                 NULL,
+                                 NULL,
+                                 clk_rpmsg_server_bind);
 }
diff --git a/include/nuttx/clk/clk_provider.h b/include/nuttx/clk/clk_provider.h
index 455240e..8dbd1a9 100644
--- a/include/nuttx/clk/clk_provider.h
+++ b/include/nuttx/clk/clk_provider.h
@@ -250,7 +250,7 @@ FAR struct clk_s *clk_register_mux(FAR const char *name,
 #ifdef CONFIG_CLK_RPMSG
 FAR struct clk_s *clk_register_rpmsg(FAR const char *name, uint8_t flags);
 
-int clk_rpmsg_initialize(void);
+int clk_rpmsg_server_initialize(void);
 #endif
 
 #undef EXTERN

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

Posted by xi...@apache.org.
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