hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/clk/rockchip/clk.c
....@@ -24,6 +24,10 @@
2424 #include <linux/rational.h>
2525 #include "clk.h"
2626
27
+#ifdef MODULE
28
+static HLIST_HEAD(clk_ctx_list);
29
+#endif
30
+
2731 /**
2832 * Register a clock branch.
2933 * Most clock branches have a form like
....@@ -185,6 +189,14 @@
185189 struct clk_hw *p_parent;
186190 unsigned long scale;
187191
192
+ if (rate == 0) {
193
+ pr_warn("%s p_rate(%ld), rate(%ld), maybe invalid frequency setting!\n",
194
+ clk_hw_get_name(hw), *parent_rate, rate);
195
+ *m = 0;
196
+ *n = 1;
197
+ return;
198
+ }
199
+
188200 p_rate = clk_hw_get_rate(clk_hw_get_parent(hw));
189201 if ((rate * 20 > p_rate) && (p_rate % rate != 0)) {
190202 p_parent = clk_hw_get_parent(clk_hw_get_parent(hw));
....@@ -221,6 +233,13 @@
221233 * for m and n. In the result it will be the nearest rate left shifted
222234 * by (scale - fd->nwidth) bits.
223235 */
236
+ if (*parent_rate == 0) {
237
+ pr_warn("%s p_rate(%ld), rate(%ld), maybe invalid frequency setting!\n",
238
+ clk_hw_get_name(hw), *parent_rate, rate);
239
+ *m = 0;
240
+ *n = 1;
241
+ return;
242
+ }
224243 scale = fls_long(*parent_rate / rate - 1);
225244 if (scale > fd->nwidth)
226245 rate <<= scale - fd->nwidth;
....@@ -417,6 +436,10 @@
417436 "rockchip,grf");
418437 ctx->pmugrf = syscon_regmap_lookup_by_phandle(ctx->cru_node,
419438 "rockchip,pmugrf");
439
+
440
+#ifdef MODULE
441
+ hlist_add_head(&ctx->list_node, &clk_ctx_list);
442
+#endif
420443
421444 return ctx;
422445
....@@ -783,4 +806,30 @@
783806
784807 }
785808 EXPORT_SYMBOL_GPL(rockchip_clk_unprotect);
809
+
810
+void rockchip_clk_disable_unused(void)
811
+{
812
+ struct rockchip_clk_provider *ctx;
813
+ struct clk *clk;
814
+ struct clk_hw *hw;
815
+ int i = 0, flag = 0;
816
+
817
+ hlist_for_each_entry(ctx, &clk_ctx_list, list_node) {
818
+ for (i = 0; i < ctx->clk_data.clk_num; i++) {
819
+ clk = ctx->clk_data.clks[i];
820
+ if (clk && !IS_ERR(clk)) {
821
+ hw = __clk_get_hw(clk);
822
+ if (hw)
823
+ flag = clk_hw_get_flags(hw);
824
+ if (flag & CLK_IGNORE_UNUSED)
825
+ continue;
826
+ if (flag & CLK_IS_CRITICAL)
827
+ continue;
828
+ clk_prepare_enable(clk);
829
+ clk_disable_unprepare(clk);
830
+ }
831
+ }
832
+ }
833
+}
834
+EXPORT_SYMBOL_GPL(rockchip_clk_disable_unused);
786835 #endif /* MODULE */