From a4db0afed48082cc08967e44194ac333fceb941a Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Fri, 7 Apr 2023 15:37:44 +0800 Subject: [PATCH] clk: rockchip: Implement rockchip_clk_protect() Signed-off-by: Finley Xiao Change-Id: I85ee79b594f86a6852bcdc8cde8eb5ac95e9ee19 --- drivers/clk/rockchip/clk.c | 53 ++++++++++++++++++++++++++++++++++++++ drivers/clk/rockchip/clk.h | 16 ++++++++++++ 2 files changed, 69 insertions(+) diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index 3cea6b7eb306..1e1f656943d5 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -707,3 +707,56 @@ rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx, &rk_clk_panic_block); } EXPORT_SYMBOL_GPL(rockchip_register_restart_notifier); + +#ifdef MODULE +static struct clk **protect_clocks; +static unsigned int protect_nclocks; + +int rockchip_clk_protect(struct rockchip_clk_provider *ctx, + unsigned int *clocks, unsigned int nclocks) +{ + struct clk *clk = NULL; + int i = 0; + + if (protect_clocks || !ctx || !clocks || !ctx->clk_data.clks) + return 0; + + protect_clocks = kcalloc(nclocks, sizeof(void *), GFP_KERNEL); + if (!protect_clocks) + return -ENOMEM; + + for (i = 0; i < nclocks; i++) { + if (clocks[i] >= ctx->clk_data.clk_num) { + pr_err("%s: invalid clock id %u\n", __func__, clocks[i]); + continue; + } + clk = ctx->clk_data.clks[clocks[i]]; + if (clk) { + clk_prepare_enable(clk); + protect_clocks[i] = clk; + } + } + protect_nclocks = nclocks; + + return 0; +} +EXPORT_SYMBOL_GPL(rockchip_clk_protect); + +void rockchip_clk_unprotect(void) +{ + int i = 0; + + if (!protect_clocks || !protect_nclocks) + return; + + for (i = 0; i < protect_nclocks; i++) { + if (protect_clocks[i]) + clk_disable_unprepare(protect_clocks[i]); + } + protect_nclocks = 0; + kfree(protect_clocks); + protect_clocks = NULL; + +} +EXPORT_SYMBOL_GPL(rockchip_clk_unprotect); +#endif /* MODULE */ diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index bef79f659dd7..5c57bed61266 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -1294,4 +1294,20 @@ static inline void rockchip_register_softrst(struct device_node *np, #endif extern void (*rk_dump_cru)(void); +#if IS_MODULE(CONFIG_COMMON_CLK_ROCKCHIP) +int rockchip_clk_protect(struct rockchip_clk_provider *ctx, + unsigned int *clocks, unsigned int nclocks); +void rockchip_clk_unprotect(void); +#else +static inline int rockchip_clk_protect(struct rockchip_clk_provider *ctx, + unsigned int *clocks, + unsigned int nclocks) +{ + return -EOPNOTSUPP; +} + +static inline void rockchip_clk_unprotect(void) +{ +} +#endif #endif