From 34d2458d752a2a87ef2df884ede203febde17295 Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Mon, 20 Nov 2023 11:31:27 +0800 Subject: [PATCH] clk: rockchip: Implement rockchip_clk_disable_unused() for gki Change-Id: I597fc35690d7a76dbc109e86db4045a1ddb3796d Signed-off-by: Finley Xiao --- drivers/clk/rockchip/clk.c | 34 ++++++++++++++++++++++++++++++++++ drivers/clk/rockchip/clk.h | 7 +++++++ 2 files changed, 41 insertions(+) diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index 35499a8a6c6a..1c91007e3013 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -24,6 +24,10 @@ #include #include "clk.h" +#ifdef MODULE +static HLIST_HEAD(clk_ctx_list); +#endif + /** * Register a clock branch. * Most clock branches have a form like @@ -433,6 +437,10 @@ struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, ctx->pmugrf = syscon_regmap_lookup_by_phandle(ctx->cru_node, "rockchip,pmugrf"); +#ifdef MODULE + hlist_add_head(&ctx->list_node, &clk_ctx_list); +#endif + return ctx; err_free: @@ -798,4 +806,30 @@ void rockchip_clk_unprotect(void) } EXPORT_SYMBOL_GPL(rockchip_clk_unprotect); + +void rockchip_clk_disable_unused(void) +{ + struct rockchip_clk_provider *ctx; + struct clk *clk; + struct clk_hw *hw; + int i = 0, flag = 0; + + hlist_for_each_entry(ctx, &clk_ctx_list, list_node) { + for (i = 0; i < ctx->clk_data.clk_num; i++) { + clk = ctx->clk_data.clks[i]; + if (clk && !IS_ERR(clk)) { + hw = __clk_get_hw(clk); + if (hw) + flag = clk_hw_get_flags(hw); + if (flag & CLK_IGNORE_UNUSED) + continue; + if (flag & CLK_IS_CRITICAL) + continue; + clk_prepare_enable(clk); + clk_disable_unprepare(clk); + } + } + } +} +EXPORT_SYMBOL_GPL(rockchip_clk_disable_unused); #endif /* MODULE */ diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index d0212c50c36d..ed525ebbe0d8 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -498,6 +498,7 @@ enum rockchip_pll_type { * @clk_data: holds clock related data like clk* and number of clocks. * @cru_node: device-node of the clock-provider * @grf: regmap of the general-register-files syscon + * @list_node: node in the global ctx list * @lock: maintains exclusion between callbacks for a given clock-provider. */ struct rockchip_clk_provider { @@ -506,6 +507,7 @@ struct rockchip_clk_provider { struct device_node *cru_node; struct regmap *grf; struct regmap *pmugrf; + struct hlist_node list_node; spinlock_t lock; }; @@ -1313,6 +1315,7 @@ extern void (*rk_dump_cru)(void); int rockchip_clk_protect(struct rockchip_clk_provider *ctx, unsigned int *clocks, unsigned int nclocks); void rockchip_clk_unprotect(void); +void rockchip_clk_disable_unused(void); #else static inline int rockchip_clk_protect(struct rockchip_clk_provider *ctx, unsigned int *clocks, @@ -1324,5 +1327,9 @@ static inline int rockchip_clk_protect(struct rockchip_clk_provider *ctx, static inline void rockchip_clk_unprotect(void) { } + +static inline void rockchip_clk_disable_unused(void) +{ +} #endif #endif