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

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

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