From b57e43b4d068d8803e57c1aaed40060212e5634c Mon Sep 17 00:00:00 2001 From: dulibo1 Date: Fri, 15 Sep 2023 15:52:49 +0800 Subject: [PATCH] clk:fix some issues when use rpmsg clk 1.check the rpmsg name when clk_register. 2.clk_get rpmsg clk print error: clk/clk.c:1231:3: runtime error: null pointer passed as argument 2, which is declared to never be null 3.fix some function miss keyword FAR. 4.clk_disable_unused may disable rpmsg clk which disable the clk that maybe used by others Signed-off-by: dulibo1 --- drivers/clk/clk.c | 78 +++++++++++++++++++------------- drivers/clk/clk_mux.c | 6 +-- drivers/clk/clk_rpmsg.c | 36 +++++++++------ include/nuttx/clk/clk_provider.h | 8 ++-- 4 files changed, 75 insertions(+), 53 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index c935b1d1ee..a745852176 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -85,6 +85,7 @@ static struct clk_s *__clk_lookup(FAR const char *name, static int __clk_register(FAR struct clk_s *clk); static void clk_disable_unused_subtree(FAR struct clk_s *clk); +static FAR struct clk_s *clk_lookup(FAR const char *name); /* File system methods */ @@ -729,6 +730,11 @@ static int __clk_register(FAR struct clk_s *clk) return -EINVAL; } + if (clk_lookup(clk->name)) + { + return -EEXIST; + } + if (clk->ops->set_rate && !((clk->ops->round_rate || clk->ops->determine_rate) && clk->ops->recalc_rate)) @@ -830,6 +836,36 @@ out: } } +static FAR struct clk_s *clk_lookup(FAR const char *name) +{ + FAR struct clk_s *root_clk = NULL; + FAR struct clk_s *ret = NULL; + irqstate_t flags; + + flags = clk_list_lock(); + list_for_every_entry(&g_clk_root_list, root_clk, struct clk_s, node) + { + ret = __clk_lookup(name, root_clk); + if (ret) + { + goto out; + } + } + + list_for_every_entry(&g_clk_orphan_list, root_clk, struct clk_s, node) + { + ret = __clk_lookup(name, root_clk); + if (ret) + { + goto out; + } + } + +out: + clk_list_unlock(flags); + return ret; +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -1004,46 +1040,23 @@ int clk_is_enabled(FAR struct clk_s *clk) FAR struct clk_s *clk_get(FAR const char *name) { - FAR struct clk_s *root_clk = NULL; - FAR struct clk_s *ret = NULL; - irqstate_t flags; + FAR struct clk_s *clk; if (!name) { return NULL; } - flags = clk_list_lock(); - - list_for_every_entry(&g_clk_root_list, root_clk, struct clk_s, node) - { - ret = __clk_lookup(name, root_clk); - if (ret) - { - goto out; - } - } - - list_for_every_entry(&g_clk_orphan_list, root_clk, struct clk_s, node) - { - ret = __clk_lookup(name, root_clk); - if (ret) - { - goto out; - } - } - -out: - clk_list_unlock(flags); + clk = clk_lookup(name); #ifdef CONFIG_CLK_RPMSG - if (ret == NULL) + if (clk == NULL) { - ret = clk_register_rpmsg(name, CLK_GET_RATE_NOCACHE); + clk = clk_register_rpmsg(name, CLK_GET_RATE_NOCACHE); } #endif - return ret; + return clk; } int clk_set_parent(FAR struct clk_s *clk, FAR struct clk_s *parent) @@ -1222,9 +1235,12 @@ FAR struct clk_s *clk_register(FAR const char *name, clk->num_parents = num_parents; clk->flags = flags; - clk->private_data = (char *)clk + off; - memcpy(clk->private_data, private_data, private_size); - off += private_size; + if (private_data) + { + clk->private_data = (char *)clk + off; + memcpy(clk->private_data, private_data, private_size); + off += private_size; + } for (i = 0; i < num_parents; i++) { diff --git a/drivers/clk/clk_mux.c b/drivers/clk/clk_mux.c index 58bc1b1f59..fc7c4ae768 100644 --- a/drivers/clk/clk_mux.c +++ b/drivers/clk/clk_mux.c @@ -85,8 +85,8 @@ static int clk_mux_set_parent(FAR struct clk_s *clk, uint8_t index) static uint32_t clk_mux_determine_rate(FAR struct clk_s *clk, uint32_t rate, - uint32_t *best_parent_rate, - struct clk_s **best_parent_p) + FAR uint32_t *best_parent_rate, + FAR struct clk_s **best_parent_p) { FAR struct clk_mux_s *mux = to_clk_mux(clk); FAR struct clk_s *parent; @@ -173,7 +173,7 @@ const struct clk_ops_s g_clk_mux_ro_ops = ****************************************************************************/ FAR struct clk_s *clk_register_mux(FAR const char *name, - const char * const *parent_names, + FAR const char * const *parent_names, uint8_t num_parents, uint8_t flags, uint32_t reg, uint8_t shift, uint8_t width, diff --git a/drivers/clk/clk_rpmsg.c b/drivers/clk/clk_rpmsg.c index 374f1ee3dd..a6735710f2 100644 --- a/drivers/clk/clk_rpmsg.c +++ b/drivers/clk/clk_rpmsg.c @@ -71,7 +71,7 @@ struct clk_rpmsg_server_s struct clk_rpmsg_s { FAR struct clk_s *clk; - uint32_t count; + bool enable; struct list_node node; }; @@ -314,20 +314,22 @@ static int clk_rpmsg_enable_handler(FAR struct rpmsg_endpoint *ept, { FAR struct clk_rpmsg_enable_s *msg = data; FAR struct clk_rpmsg_s *clkrp = clk_rpmsg_get_clk(ept, msg->name); + int ret = -ENOENT; - if (clkrp) + if (clkrp && !clkrp->enable) { - msg->header.result = clk_enable(clkrp->clk); - if (!msg->header.result) + ret = clk_enable(clkrp->clk); + if (ret >= 0) { - clkrp->count++; + clkrp->enable = true; } } - else + else if (clkrp && clkrp->enable) { - msg->header.result = -ENOENT; + ret = 0; } + msg->header.result = ret; return rpmsg_send(ept, msg, sizeof(*msg)); } @@ -337,18 +339,22 @@ static int clk_rpmsg_disable_handler(FAR struct rpmsg_endpoint *ept, { FAR struct clk_rpmsg_disable_s *msg = data; FAR struct clk_rpmsg_s *clkrp = clk_rpmsg_get_clk(ept, msg->name); + int ret = -ENOENT; - if (clkrp) + if (clkrp && clkrp->enable) { - clk_disable(clkrp->clk); - clkrp->count--; - msg->header.result = 0; + ret = clk_disable(clkrp->clk); + if (ret >= 0) + { + clkrp->enable = false; + } } - else + else if (clkrp && !clkrp->enable) { - msg->header.result = -ENOENT; + ret = 0; } + msg->header.result = ret; return rpmsg_send(ept, msg, sizeof(*msg)); } @@ -457,7 +463,7 @@ static int clk_rpmsg_isenabled_handler(FAR struct rpmsg_endpoint *ept, if (clkrp) { - msg->header.result = clk_is_enabled(clkrp->clk); + msg->header.result = clkrp->enable; } else { @@ -536,7 +542,7 @@ static void clk_rpmsg_server_unbind(FAR struct rpmsg_endpoint *ept) list_for_every_entry_safe(&priv->clk_list, clkrp, clkrp_tmp, struct clk_rpmsg_s, node) { - while (clkrp->count--) + if (clkrp->enable) { clk_disable(clkrp->clk); } diff --git a/include/nuttx/clk/clk_provider.h b/include/nuttx/clk/clk_provider.h index 72903c0301..0bec2f7ce6 100644 --- a/include/nuttx/clk/clk_provider.h +++ b/include/nuttx/clk/clk_provider.h @@ -114,10 +114,10 @@ struct clk_ops_s CODE int (*is_enabled)(FAR struct clk_s *clk); CODE uint32_t (*recalc_rate)(FAR struct clk_s *clk, uint32_t parent_rate); CODE uint32_t (*round_rate)(FAR struct clk_s *clk, - uint32_t rate, uint32_t *parent_rate); + uint32_t rate, FAR uint32_t *parent_rate); CODE uint32_t (*determine_rate)(FAR struct clk_s *clk, uint32_t rate, - uint32_t *best_parent_rate, - struct clk_s **best_parent_clk); + FAR uint32_t *best_parent_rate, + FAR struct clk_s **best_parent_clk); CODE int (*set_parent)(FAR struct clk_s *clk, uint8_t index); CODE uint8_t (*get_parent)(FAR struct clk_s *clk); CODE int (*set_rate)(FAR struct clk_s *clk, uint32_t rate, @@ -243,7 +243,7 @@ FAR struct clk_s *clk_register_multiplier(FAR const char *name, uint8_t clk_multiplier_flags); FAR struct clk_s *clk_register_mux(FAR const char *name, - const char * const *parent_names, + FAR const char * const *parent_names, uint8_t num_parents, uint8_t flags, uint32_t reg, uint8_t shift, uint8_t width, uint8_t clk_mux_flags);