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