forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 61598093bbdd283a7edc367d900f223070ead8d2
kernel/drivers/clk/ti/autoidle.c
....@@ -35,7 +35,44 @@
3535 #define AUTOIDLE_LOW 0x1
3636
3737 static LIST_HEAD(autoidle_clks);
38
-static LIST_HEAD(clk_hw_omap_clocks);
38
+
39
+/*
40
+ * we have some non-atomic read/write
41
+ * operations behind it, so lets
42
+ * take one lock for handling autoidle
43
+ * of all clocks
44
+ */
45
+static DEFINE_SPINLOCK(autoidle_spinlock);
46
+
47
+static int _omap2_clk_deny_idle(struct clk_hw_omap *clk)
48
+{
49
+ if (clk->ops && clk->ops->deny_idle) {
50
+ unsigned long irqflags;
51
+
52
+ spin_lock_irqsave(&autoidle_spinlock, irqflags);
53
+ clk->autoidle_count++;
54
+ if (clk->autoidle_count == 1)
55
+ clk->ops->deny_idle(clk);
56
+
57
+ spin_unlock_irqrestore(&autoidle_spinlock, irqflags);
58
+ }
59
+ return 0;
60
+}
61
+
62
+static int _omap2_clk_allow_idle(struct clk_hw_omap *clk)
63
+{
64
+ if (clk->ops && clk->ops->allow_idle) {
65
+ unsigned long irqflags;
66
+
67
+ spin_lock_irqsave(&autoidle_spinlock, irqflags);
68
+ clk->autoidle_count--;
69
+ if (clk->autoidle_count == 0)
70
+ clk->ops->allow_idle(clk);
71
+
72
+ spin_unlock_irqrestore(&autoidle_spinlock, irqflags);
73
+ }
74
+ return 0;
75
+}
3976
4077 /**
4178 * omap2_clk_deny_idle - disable autoidle on an OMAP clock
....@@ -45,12 +82,20 @@
4582 */
4683 int omap2_clk_deny_idle(struct clk *clk)
4784 {
48
- struct clk_hw_omap *c;
85
+ struct clk_hw *hw;
4986
50
- c = to_clk_hw_omap(__clk_get_hw(clk));
51
- if (c->ops && c->ops->deny_idle)
52
- c->ops->deny_idle(c);
53
- return 0;
87
+ if (!clk)
88
+ return -EINVAL;
89
+
90
+ hw = __clk_get_hw(clk);
91
+
92
+ if (omap2_clk_is_hw_omap(hw)) {
93
+ struct clk_hw_omap *c = to_clk_hw_omap(hw);
94
+
95
+ return _omap2_clk_deny_idle(c);
96
+ }
97
+
98
+ return -EINVAL;
5499 }
55100
56101 /**
....@@ -61,12 +106,20 @@
61106 */
62107 int omap2_clk_allow_idle(struct clk *clk)
63108 {
64
- struct clk_hw_omap *c;
109
+ struct clk_hw *hw;
65110
66
- c = to_clk_hw_omap(__clk_get_hw(clk));
67
- if (c->ops && c->ops->allow_idle)
68
- c->ops->allow_idle(c);
69
- return 0;
111
+ if (!clk)
112
+ return -EINVAL;
113
+
114
+ hw = __clk_get_hw(clk);
115
+
116
+ if (omap2_clk_is_hw_omap(hw)) {
117
+ struct clk_hw_omap *c = to_clk_hw_omap(hw);
118
+
119
+ return _omap2_clk_allow_idle(c);
120
+ }
121
+
122
+ return -EINVAL;
70123 }
71124
72125 static void _allow_autoidle(struct clk_ti_autoidle *clk)
....@@ -168,26 +221,6 @@
168221 }
169222
170223 /**
171
- * omap2_init_clk_hw_omap_clocks - initialize an OMAP clock
172
- * @hw: struct clk_hw * to initialize
173
- *
174
- * Add an OMAP clock @clk to the internal list of OMAP clocks. Used
175
- * temporarily for autoidle handling, until this support can be
176
- * integrated into the common clock framework code in some way. No
177
- * return value.
178
- */
179
-void omap2_init_clk_hw_omap_clocks(struct clk_hw *hw)
180
-{
181
- struct clk_hw_omap *c;
182
-
183
- if (clk_hw_get_flags(hw) & CLK_IS_BASIC)
184
- return;
185
-
186
- c = to_clk_hw_omap(hw);
187
- list_add(&c->node, &clk_hw_omap_clocks);
188
-}
189
-
190
-/**
191224 * omap2_clk_enable_autoidle_all - enable autoidle on all OMAP clocks that
192225 * support it
193226 *
....@@ -198,11 +231,11 @@
198231 */
199232 int omap2_clk_enable_autoidle_all(void)
200233 {
201
- struct clk_hw_omap *c;
234
+ int ret;
202235
203
- list_for_each_entry(c, &clk_hw_omap_clocks, node)
204
- if (c->ops && c->ops->allow_idle)
205
- c->ops->allow_idle(c);
236
+ ret = omap2_clk_for_each(_omap2_clk_allow_idle);
237
+ if (ret)
238
+ return ret;
206239
207240 _clk_generic_allow_autoidle_all();
208241
....@@ -220,11 +253,11 @@
220253 */
221254 int omap2_clk_disable_autoidle_all(void)
222255 {
223
- struct clk_hw_omap *c;
256
+ int ret;
224257
225
- list_for_each_entry(c, &clk_hw_omap_clocks, node)
226
- if (c->ops && c->ops->deny_idle)
227
- c->ops->deny_idle(c);
258
+ ret = omap2_clk_for_each(_omap2_clk_deny_idle);
259
+ if (ret)
260
+ return ret;
228261
229262 _clk_generic_deny_autoidle_all();
230263