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