Commit 4ff29ff8e8723a41e7defd8bc78a7b16cbf940a2
1 parent
b1f6cfe48c
Exists in
master
and in
20 other branches
sh: clkfwk: Consolidate the ALWAYS_ENABLED / NEEDS_INIT mess.
There is no real distinction here in behaviour, either a clock needs to be enabled on initialiation or not. The ALWAYS_ENABLED flag was always intended to only apply to clocks that were physically always on and could simply not be disabled at all from software. Unfortunately over time this was abused and the meaning became a bit blurry. So, we kill off both of all of those paths now, as well as the newer NEEDS_INIT flag, and consolidate on a CLK_ENABLE_ON_INIT. Clocks that need to be enabled on initialization can set this, and it will purposely enable them and bump the refcount up. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Showing 8 changed files with 44 additions and 75 deletions Side-by-side Diff
arch/sh/include/asm/clock.h
... | ... | @@ -37,8 +37,7 @@ |
37 | 37 | unsigned long arch_flags; |
38 | 38 | }; |
39 | 39 | |
40 | -#define CLK_ALWAYS_ENABLED (1 << 0) | |
41 | -#define CLK_NEEDS_INIT (1 << 2) | |
40 | +#define CLK_ENABLE_ON_INIT (1 << 0) | |
42 | 41 | |
43 | 42 | /* Should be defined by processor-specific code */ |
44 | 43 | void arch_init_clk_ops(struct clk_ops **, int type); |
arch/sh/kernel/cpu/clock.c
... | ... | @@ -43,26 +43,26 @@ |
43 | 43 | */ |
44 | 44 | static struct clk master_clk = { |
45 | 45 | .name = "master_clk", |
46 | - .flags = CLK_ALWAYS_ENABLED, | |
46 | + .flags = CLK_ENABLE_ON_INIT, | |
47 | 47 | .rate = CONFIG_SH_PCLK_FREQ, |
48 | 48 | }; |
49 | 49 | |
50 | 50 | static struct clk module_clk = { |
51 | 51 | .name = "module_clk", |
52 | 52 | .parent = &master_clk, |
53 | - .flags = CLK_ALWAYS_ENABLED, | |
53 | + .flags = CLK_ENABLE_ON_INIT, | |
54 | 54 | }; |
55 | 55 | |
56 | 56 | static struct clk bus_clk = { |
57 | 57 | .name = "bus_clk", |
58 | 58 | .parent = &master_clk, |
59 | - .flags = CLK_ALWAYS_ENABLED, | |
59 | + .flags = CLK_ENABLE_ON_INIT, | |
60 | 60 | }; |
61 | 61 | |
62 | 62 | static struct clk cpu_clk = { |
63 | 63 | .name = "cpu_clk", |
64 | 64 | .parent = &master_clk, |
65 | - .flags = CLK_ALWAYS_ENABLED, | |
65 | + .flags = CLK_ENABLE_ON_INIT, | |
66 | 66 | }; |
67 | 67 | |
68 | 68 | /* |
69 | 69 | |
70 | 70 | |
... | ... | @@ -93,40 +93,12 @@ |
93 | 93 | } |
94 | 94 | } |
95 | 95 | |
96 | -static void __clk_init(struct clk *clk) | |
97 | -{ | |
98 | - /* | |
99 | - * See if this is the first time we're enabling the clock, some | |
100 | - * clocks that are always enabled still require "special" | |
101 | - * initialization. This is especially true if the clock mode | |
102 | - * changes and the clock needs to hunt for the proper set of | |
103 | - * divisors to use before it can effectively recalc. | |
104 | - */ | |
105 | - | |
106 | - if (clk->flags & CLK_NEEDS_INIT) { | |
107 | - if (clk->ops && clk->ops->init) | |
108 | - clk->ops->init(clk); | |
109 | - | |
110 | - clk->flags &= ~CLK_NEEDS_INIT; | |
111 | - } | |
112 | -} | |
113 | - | |
114 | 96 | static int __clk_enable(struct clk *clk) |
115 | 97 | { |
116 | - if (!clk) | |
117 | - return -EINVAL; | |
98 | + if (clk->usecount++ == 0) { | |
99 | + if (clk->parent) | |
100 | + __clk_enable(clk->parent); | |
118 | 101 | |
119 | - clk->usecount++; | |
120 | - | |
121 | - /* nothing to do if always enabled */ | |
122 | - if (clk->flags & CLK_ALWAYS_ENABLED) | |
123 | - return 0; | |
124 | - | |
125 | - if (clk->usecount == 1) { | |
126 | - __clk_init(clk); | |
127 | - | |
128 | - __clk_enable(clk->parent); | |
129 | - | |
130 | 102 | if (clk->ops && clk->ops->enable) |
131 | 103 | clk->ops->enable(clk); |
132 | 104 | } |
... | ... | @@ -139,6 +111,9 @@ |
139 | 111 | unsigned long flags; |
140 | 112 | int ret; |
141 | 113 | |
114 | + if (!clk) | |
115 | + return -EINVAL; | |
116 | + | |
142 | 117 | spin_lock_irqsave(&clock_lock, flags); |
143 | 118 | ret = __clk_enable(clk); |
144 | 119 | spin_unlock_irqrestore(&clock_lock, flags); |
145 | 120 | |
... | ... | @@ -149,21 +124,11 @@ |
149 | 124 | |
150 | 125 | static void __clk_disable(struct clk *clk) |
151 | 126 | { |
152 | - if (!clk) | |
153 | - return; | |
154 | - | |
155 | - clk->usecount--; | |
156 | - | |
157 | - WARN_ON(clk->usecount < 0); | |
158 | - | |
159 | - if (clk->flags & CLK_ALWAYS_ENABLED) | |
160 | - return; | |
161 | - | |
162 | - if (clk->usecount == 0) { | |
127 | + if (clk->usecount > 0 && !(--clk->usecount)) { | |
163 | 128 | if (likely(clk->ops && clk->ops->disable)) |
164 | 129 | clk->ops->disable(clk); |
165 | - | |
166 | - __clk_disable(clk->parent); | |
130 | + if (likely(clk->parent)) | |
131 | + __clk_disable(clk->parent); | |
167 | 132 | } |
168 | 133 | } |
169 | 134 | |
... | ... | @@ -171,6 +136,9 @@ |
171 | 136 | { |
172 | 137 | unsigned long flags; |
173 | 138 | |
139 | + if (!clk) | |
140 | + return; | |
141 | + | |
174 | 142 | spin_lock_irqsave(&clock_lock, flags); |
175 | 143 | __clk_disable(clk); |
176 | 144 | spin_unlock_irqrestore(&clock_lock, flags); |
... | ... | @@ -211,6 +179,7 @@ |
211 | 179 | mutex_lock(&clock_list_sem); |
212 | 180 | |
213 | 181 | INIT_LIST_HEAD(&clk->children); |
182 | + clk->usecount = 0; | |
214 | 183 | |
215 | 184 | if (clk->parent) |
216 | 185 | list_add(&clk->sibling, &clk->parent->children); |
217 | 186 | |
... | ... | @@ -218,19 +187,10 @@ |
218 | 187 | list_add(&clk->sibling, &root_clks); |
219 | 188 | |
220 | 189 | list_add(&clk->node, &clock_list); |
221 | - clk->usecount = 0; | |
222 | - clk->flags |= CLK_NEEDS_INIT; | |
223 | - | |
190 | + if (clk->ops->init) | |
191 | + clk->ops->init(clk); | |
224 | 192 | mutex_unlock(&clock_list_sem); |
225 | 193 | |
226 | - if (clk->flags & CLK_ALWAYS_ENABLED) { | |
227 | - __clk_init(clk); | |
228 | - pr_debug( "Clock '%s' is ALWAYS_ENABLED\n", clk->name); | |
229 | - if (clk->ops && clk->ops->enable) | |
230 | - clk->ops->enable(clk); | |
231 | - pr_debug( "Enabled."); | |
232 | - } | |
233 | - | |
234 | 194 | return 0; |
235 | 195 | } |
236 | 196 | EXPORT_SYMBOL_GPL(clk_register); |
... | ... | @@ -244,6 +204,15 @@ |
244 | 204 | } |
245 | 205 | EXPORT_SYMBOL_GPL(clk_unregister); |
246 | 206 | |
207 | +static void clk_enable_init_clocks(void) | |
208 | +{ | |
209 | + struct clk *clkp; | |
210 | + | |
211 | + list_for_each_entry(clkp, &clock_list, node) | |
212 | + if (clkp->flags & CLK_ENABLE_ON_INIT) | |
213 | + clk_enable(clkp); | |
214 | +} | |
215 | + | |
247 | 216 | unsigned long clk_get_rate(struct clk *clk) |
248 | 217 | { |
249 | 218 | return clk->rate; |
... | ... | @@ -404,9 +373,7 @@ |
404 | 373 | |
405 | 374 | p += sprintf(p, "%-12s\t: %ld.%02ldMHz\t%s\n", clk->name, |
406 | 375 | rate / 1000000, (rate % 1000000) / 10000, |
407 | - ((clk->flags & CLK_ALWAYS_ENABLED) || | |
408 | - clk->usecount > 0) ? | |
409 | - "enabled" : "disabled"); | |
376 | + (clk->usecount > 0) ? "enabled" : "disabled"); | |
410 | 377 | } |
411 | 378 | |
412 | 379 | return p - buf; |
... | ... | @@ -495,6 +462,9 @@ |
495 | 462 | |
496 | 463 | /* Kick the child clocks.. */ |
497 | 464 | recalculate_root_clocks(); |
465 | + | |
466 | + /* Enable the necessary init clocks */ | |
467 | + clk_enable_init_clocks(); | |
498 | 468 | |
499 | 469 | return ret; |
500 | 470 | } |
arch/sh/kernel/cpu/sh4/clock-sh4-202.c
... | ... | @@ -46,7 +46,7 @@ |
46 | 46 | |
47 | 47 | static struct clk sh4202_emi_clk = { |
48 | 48 | .name = "emi_clk", |
49 | - .flags = CLK_ALWAYS_ENABLED, | |
49 | + .flags = CLK_ENABLE_ON_INIT, | |
50 | 50 | .ops = &sh4202_emi_clk_ops, |
51 | 51 | }; |
52 | 52 | |
... | ... | @@ -62,7 +62,7 @@ |
62 | 62 | |
63 | 63 | static struct clk sh4202_femi_clk = { |
64 | 64 | .name = "femi_clk", |
65 | - .flags = CLK_ALWAYS_ENABLED, | |
65 | + .flags = CLK_ENABLE_ON_INIT, | |
66 | 66 | .ops = &sh4202_femi_clk_ops, |
67 | 67 | }; |
68 | 68 | |
... | ... | @@ -140,7 +140,7 @@ |
140 | 140 | |
141 | 141 | static struct clk sh4202_shoc_clk = { |
142 | 142 | .name = "shoc_clk", |
143 | - .flags = CLK_ALWAYS_ENABLED, | |
143 | + .flags = CLK_ENABLE_ON_INIT, | |
144 | 144 | .ops = &sh4202_shoc_clk_ops, |
145 | 145 | }; |
146 | 146 |
arch/sh/kernel/cpu/sh4a/clock-sh7763.c
arch/sh/kernel/cpu/sh4a/clock-sh7780.c
arch/sh/kernel/cpu/sh4a/clock-sh7785.c
... | ... | @@ -88,7 +88,7 @@ |
88 | 88 | |
89 | 89 | static struct clk sh7785_shyway_clk = { |
90 | 90 | .name = "shyway_clk", |
91 | - .flags = CLK_ALWAYS_ENABLED, | |
91 | + .flags = CLK_ENABLE_ON_INIT, | |
92 | 92 | .ops = &sh7785_shyway_clk_ops, |
93 | 93 | }; |
94 | 94 | |
... | ... | @@ -104,7 +104,7 @@ |
104 | 104 | |
105 | 105 | static struct clk sh7785_ddr_clk = { |
106 | 106 | .name = "ddr_clk", |
107 | - .flags = CLK_ALWAYS_ENABLED, | |
107 | + .flags = CLK_ENABLE_ON_INIT, | |
108 | 108 | .ops = &sh7785_ddr_clk_ops, |
109 | 109 | }; |
110 | 110 | |
... | ... | @@ -120,7 +120,7 @@ |
120 | 120 | |
121 | 121 | static struct clk sh7785_ram_clk = { |
122 | 122 | .name = "ram_clk", |
123 | - .flags = CLK_ALWAYS_ENABLED, | |
123 | + .flags = CLK_ENABLE_ON_INIT, | |
124 | 124 | .ops = &sh7785_ram_clk_ops, |
125 | 125 | }; |
126 | 126 |
arch/sh/kernel/cpu/sh4a/clock-sh7786.c
... | ... | @@ -91,7 +91,7 @@ |
91 | 91 | |
92 | 92 | static struct clk sh7786_shyway_clk = { |
93 | 93 | .name = "shyway_clk", |
94 | - .flags = CLK_ALWAYS_ENABLED, | |
94 | + .flags = CLK_ENABLE_ON_INIT, | |
95 | 95 | .ops = &sh7786_shyway_clk_ops, |
96 | 96 | }; |
97 | 97 | |
... | ... | @@ -107,7 +107,7 @@ |
107 | 107 | |
108 | 108 | static struct clk sh7786_ddr_clk = { |
109 | 109 | .name = "ddr_clk", |
110 | - .flags = CLK_ALWAYS_ENABLED, | |
110 | + .flags = CLK_ENABLE_ON_INIT, | |
111 | 111 | .ops = &sh7786_ddr_clk_ops, |
112 | 112 | }; |
113 | 113 |