From 6e6ba062fda71882d0a3d51eee673d0106fb7a11 Mon Sep 17 00:00:00 2001 From: zhengshaobo1 Date: Mon, 18 Sep 2023 11:22:42 +0800 Subject: [PATCH] clock flags add CLK_OPS_PARENT_ENABLE, parents need enable during gate/ungate, set rate and re-parent Signed-off-by: zhengshaobo1 --- drivers/clk/clk.c | 43 +++++++++++++++++++++++++++++++- include/nuttx/clk/clk_provider.h | 1 + 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 862750aea4f68..c935b1d1ee691 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -495,6 +495,12 @@ static void clk_change_rate(FAR struct clk_s *clk, uint32_t best_parent_rate) if (clk->new_parent && clk->new_parent != clk->parent) { + if (clk->flags & CLK_OPS_PARENT_ENABLE) + { + clk_enable(old_parent); + clk_enable(clk->new_parent); + } + if (clk->enable_count) { clk_enable(clk->new_parent); @@ -519,6 +525,12 @@ static void clk_change_rate(FAR struct clk_s *clk, uint32_t best_parent_rate) clk_disable(clk); clk_disable(old_parent); } + + if (clk->flags & CLK_OPS_PARENT_ENABLE) + { + clk_disable(clk->new_parent); + clk_disable(old_parent); + } } if (!skip_set_rate && clk->ops->set_rate) @@ -789,9 +801,14 @@ static void clk_disable_unused_subtree(FAR struct clk_s *clk) clk_disable_unused_subtree(child); } + if (clk->flags & CLK_OPS_PARENT_ENABLE) + { + clk_enable(clk->parent); + } + if (clk->enable_count) { - return; + goto out; } if (clk_is_enabled(clk)) @@ -805,6 +822,12 @@ static void clk_disable_unused_subtree(FAR struct clk_s *clk) clk->ops->disable(clk); } } + +out: + if (clk->flags & CLK_OPS_PARENT_ENABLE) + { + clk_disable(clk->parent); + } } /**************************************************************************** @@ -1062,6 +1085,12 @@ int clk_set_parent(FAR struct clk_s *clk, FAR struct clk_s *parent) old_parent = clk->parent; + if (clk->flags & CLK_OPS_PARENT_ENABLE) + { + clk_enable(old_parent); + clk_enable(parent); + } + if (clk->enable_count) { clk_enable(parent); @@ -1085,6 +1114,12 @@ int clk_set_parent(FAR struct clk_s *clk, FAR struct clk_s *parent) clk_disable(parent); } + if (clk->flags & CLK_OPS_PARENT_ENABLE) + { + clk_disable(parent); + clk_disable(old_parent); + } + goto out; } @@ -1094,6 +1129,12 @@ int clk_set_parent(FAR struct clk_s *clk, FAR struct clk_s *parent) clk_disable(old_parent); } + if (clk->flags & CLK_OPS_PARENT_ENABLE) + { + clk_disable(parent); + clk_disable(old_parent); + } + __clk_recalc_rate(clk); out: diff --git a/include/nuttx/clk/clk_provider.h b/include/nuttx/clk/clk_provider.h index 9427cc94a9f59..72903c0301176 100644 --- a/include/nuttx/clk/clk_provider.h +++ b/include/nuttx/clk/clk_provider.h @@ -40,6 +40,7 @@ #define CLK_SET_RATE_GATE 0x01 #define CLK_SET_PARENT_GATE 0x02 #define CLK_SET_RATE_PARENT 0x04 +#define CLK_OPS_PARENT_ENABLE 0x08 #define CLK_GET_RATE_NOCACHE 0x10 #define CLK_NAME_IS_STATIC 0x20 #define CLK_PARENT_NAME_IS_STATIC 0x40