diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-05-11 16:14:53 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-05-11 16:14:53 -0400 |
commit | 4ff29ff8e8723a41e7defd8bc78a7b16cbf940a2 (patch) | |
tree | 0e277d27eee3af89e66856458dce29e6ba3f4721 | |
parent | b1f6cfe48c3cb1dfa77db3d2f42f765febaef9bc (diff) |
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>
-rw-r--r-- | arch/sh/include/asm/clock.h | 3 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/clock.c | 94 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4/clock-sh4-202.c | 6 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/clock-sh7763.c | 2 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/clock-sh7780.c | 2 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 6 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/clock-sh7786.c | 4 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/clock-shx3.c | 2 |
8 files changed, 44 insertions, 75 deletions
diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index 5dc8b73a2bd5..246f9ebbed23 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h | |||
@@ -37,8 +37,7 @@ struct clk { | |||
37 | unsigned long arch_flags; | 37 | unsigned long arch_flags; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | #define CLK_ALWAYS_ENABLED (1 << 0) | 40 | #define CLK_ENABLE_ON_INIT (1 << 0) |
41 | #define CLK_NEEDS_INIT (1 << 2) | ||
42 | 41 | ||
43 | /* Should be defined by processor-specific code */ | 42 | /* Should be defined by processor-specific code */ |
44 | void arch_init_clk_ops(struct clk_ops **, int type); | 43 | void arch_init_clk_ops(struct clk_ops **, int type); |
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 0a06df8cde2b..c683be5ba8b2 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c | |||
@@ -43,26 +43,26 @@ static DEFINE_MUTEX(clock_list_sem); | |||
43 | */ | 43 | */ |
44 | static struct clk master_clk = { | 44 | static struct clk master_clk = { |
45 | .name = "master_clk", | 45 | .name = "master_clk", |
46 | .flags = CLK_ALWAYS_ENABLED, | 46 | .flags = CLK_ENABLE_ON_INIT, |
47 | .rate = CONFIG_SH_PCLK_FREQ, | 47 | .rate = CONFIG_SH_PCLK_FREQ, |
48 | }; | 48 | }; |
49 | 49 | ||
50 | static struct clk module_clk = { | 50 | static struct clk module_clk = { |
51 | .name = "module_clk", | 51 | .name = "module_clk", |
52 | .parent = &master_clk, | 52 | .parent = &master_clk, |
53 | .flags = CLK_ALWAYS_ENABLED, | 53 | .flags = CLK_ENABLE_ON_INIT, |
54 | }; | 54 | }; |
55 | 55 | ||
56 | static struct clk bus_clk = { | 56 | static struct clk bus_clk = { |
57 | .name = "bus_clk", | 57 | .name = "bus_clk", |
58 | .parent = &master_clk, | 58 | .parent = &master_clk, |
59 | .flags = CLK_ALWAYS_ENABLED, | 59 | .flags = CLK_ENABLE_ON_INIT, |
60 | }; | 60 | }; |
61 | 61 | ||
62 | static struct clk cpu_clk = { | 62 | static struct clk cpu_clk = { |
63 | .name = "cpu_clk", | 63 | .name = "cpu_clk", |
64 | .parent = &master_clk, | 64 | .parent = &master_clk, |
65 | .flags = CLK_ALWAYS_ENABLED, | 65 | .flags = CLK_ENABLE_ON_INIT, |
66 | }; | 66 | }; |
67 | 67 | ||
68 | /* | 68 | /* |
@@ -93,39 +93,11 @@ void propagate_rate(struct clk *tclk) | |||
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 | static int __clk_enable(struct clk *clk) | 96 | static int __clk_enable(struct clk *clk) |
115 | { | 97 | { |
116 | if (!clk) | 98 | if (clk->usecount++ == 0) { |
117 | return -EINVAL; | 99 | if (clk->parent) |
118 | 100 | __clk_enable(clk->parent); | |
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 | 101 | ||
130 | if (clk->ops && clk->ops->enable) | 102 | if (clk->ops && clk->ops->enable) |
131 | clk->ops->enable(clk); | 103 | clk->ops->enable(clk); |
@@ -139,6 +111,9 @@ int clk_enable(struct clk *clk) | |||
139 | unsigned long flags; | 111 | unsigned long flags; |
140 | int ret; | 112 | int ret; |
141 | 113 | ||
114 | if (!clk) | ||
115 | return -EINVAL; | ||
116 | |||
142 | spin_lock_irqsave(&clock_lock, flags); | 117 | spin_lock_irqsave(&clock_lock, flags); |
143 | ret = __clk_enable(clk); | 118 | ret = __clk_enable(clk); |
144 | spin_unlock_irqrestore(&clock_lock, flags); | 119 | spin_unlock_irqrestore(&clock_lock, flags); |
@@ -149,21 +124,11 @@ EXPORT_SYMBOL_GPL(clk_enable); | |||
149 | 124 | ||
150 | static void __clk_disable(struct clk *clk) | 125 | static void __clk_disable(struct clk *clk) |
151 | { | 126 | { |
152 | if (!clk) | 127 | if (clk->usecount > 0 && !(--clk->usecount)) { |
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) { | ||
163 | if (likely(clk->ops && clk->ops->disable)) | 128 | if (likely(clk->ops && clk->ops->disable)) |
164 | clk->ops->disable(clk); | 129 | clk->ops->disable(clk); |
165 | 130 | if (likely(clk->parent)) | |
166 | __clk_disable(clk->parent); | 131 | __clk_disable(clk->parent); |
167 | } | 132 | } |
168 | } | 133 | } |
169 | 134 | ||
@@ -171,6 +136,9 @@ void clk_disable(struct clk *clk) | |||
171 | { | 136 | { |
172 | unsigned long flags; | 137 | unsigned long flags; |
173 | 138 | ||
139 | if (!clk) | ||
140 | return; | ||
141 | |||
174 | spin_lock_irqsave(&clock_lock, flags); | 142 | spin_lock_irqsave(&clock_lock, flags); |
175 | __clk_disable(clk); | 143 | __clk_disable(clk); |
176 | spin_unlock_irqrestore(&clock_lock, flags); | 144 | spin_unlock_irqrestore(&clock_lock, flags); |
@@ -211,6 +179,7 @@ int clk_register(struct clk *clk) | |||
211 | mutex_lock(&clock_list_sem); | 179 | mutex_lock(&clock_list_sem); |
212 | 180 | ||
213 | INIT_LIST_HEAD(&clk->children); | 181 | INIT_LIST_HEAD(&clk->children); |
182 | clk->usecount = 0; | ||
214 | 183 | ||
215 | if (clk->parent) | 184 | if (clk->parent) |
216 | list_add(&clk->sibling, &clk->parent->children); | 185 | list_add(&clk->sibling, &clk->parent->children); |
@@ -218,19 +187,10 @@ int clk_register(struct clk *clk) | |||
218 | list_add(&clk->sibling, &root_clks); | 187 | list_add(&clk->sibling, &root_clks); |
219 | 188 | ||
220 | list_add(&clk->node, &clock_list); | 189 | list_add(&clk->node, &clock_list); |
221 | clk->usecount = 0; | 190 | if (clk->ops->init) |
222 | clk->flags |= CLK_NEEDS_INIT; | 191 | clk->ops->init(clk); |
223 | |||
224 | mutex_unlock(&clock_list_sem); | 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 | return 0; | 194 | return 0; |
235 | } | 195 | } |
236 | EXPORT_SYMBOL_GPL(clk_register); | 196 | EXPORT_SYMBOL_GPL(clk_register); |
@@ -244,6 +204,15 @@ void clk_unregister(struct clk *clk) | |||
244 | } | 204 | } |
245 | EXPORT_SYMBOL_GPL(clk_unregister); | 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 | unsigned long clk_get_rate(struct clk *clk) | 216 | unsigned long clk_get_rate(struct clk *clk) |
248 | { | 217 | { |
249 | return clk->rate; | 218 | return clk->rate; |
@@ -404,9 +373,7 @@ static int show_clocks(char *buf, char **start, off_t off, | |||
404 | 373 | ||
405 | p += sprintf(p, "%-12s\t: %ld.%02ldMHz\t%s\n", clk->name, | 374 | p += sprintf(p, "%-12s\t: %ld.%02ldMHz\t%s\n", clk->name, |
406 | rate / 1000000, (rate % 1000000) / 10000, | 375 | rate / 1000000, (rate % 1000000) / 10000, |
407 | ((clk->flags & CLK_ALWAYS_ENABLED) || | 376 | (clk->usecount > 0) ? "enabled" : "disabled"); |
408 | clk->usecount > 0) ? | ||
409 | "enabled" : "disabled"); | ||
410 | } | 377 | } |
411 | 378 | ||
412 | return p - buf; | 379 | return p - buf; |
@@ -496,6 +463,9 @@ int __init clk_init(void) | |||
496 | /* Kick the child clocks.. */ | 463 | /* Kick the child clocks.. */ |
497 | recalculate_root_clocks(); | 464 | recalculate_root_clocks(); |
498 | 465 | ||
466 | /* Enable the necessary init clocks */ | ||
467 | clk_enable_init_clocks(); | ||
468 | |||
499 | return ret; | 469 | return ret; |
500 | } | 470 | } |
501 | 471 | ||
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c index 628d50ea6f6b..0caca9f99fe8 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c | |||
@@ -46,7 +46,7 @@ static struct clk_ops sh4202_emi_clk_ops = { | |||
46 | 46 | ||
47 | static struct clk sh4202_emi_clk = { | 47 | static struct clk sh4202_emi_clk = { |
48 | .name = "emi_clk", | 48 | .name = "emi_clk", |
49 | .flags = CLK_ALWAYS_ENABLED, | 49 | .flags = CLK_ENABLE_ON_INIT, |
50 | .ops = &sh4202_emi_clk_ops, | 50 | .ops = &sh4202_emi_clk_ops, |
51 | }; | 51 | }; |
52 | 52 | ||
@@ -62,7 +62,7 @@ static struct clk_ops sh4202_femi_clk_ops = { | |||
62 | 62 | ||
63 | static struct clk sh4202_femi_clk = { | 63 | static struct clk sh4202_femi_clk = { |
64 | .name = "femi_clk", | 64 | .name = "femi_clk", |
65 | .flags = CLK_ALWAYS_ENABLED, | 65 | .flags = CLK_ENABLE_ON_INIT, |
66 | .ops = &sh4202_femi_clk_ops, | 66 | .ops = &sh4202_femi_clk_ops, |
67 | }; | 67 | }; |
68 | 68 | ||
@@ -140,7 +140,7 @@ static struct clk_ops sh4202_shoc_clk_ops = { | |||
140 | 140 | ||
141 | static struct clk sh4202_shoc_clk = { | 141 | static struct clk sh4202_shoc_clk = { |
142 | .name = "shoc_clk", | 142 | .name = "shoc_clk", |
143 | .flags = CLK_ALWAYS_ENABLED, | 143 | .flags = CLK_ENABLE_ON_INIT, |
144 | .ops = &sh4202_shoc_clk_ops, | 144 | .ops = &sh4202_shoc_clk_ops, |
145 | }; | 145 | }; |
146 | 146 | ||
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c index db51cffc5d5b..21bd70f9ee45 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c | |||
@@ -78,7 +78,7 @@ static struct clk_ops sh7763_shyway_clk_ops = { | |||
78 | 78 | ||
79 | static struct clk sh7763_shyway_clk = { | 79 | static struct clk sh7763_shyway_clk = { |
80 | .name = "shyway_clk", | 80 | .name = "shyway_clk", |
81 | .flags = CLK_ALWAYS_ENABLED, | 81 | .flags = CLK_ENABLE_ON_INIT, |
82 | .ops = &sh7763_shyway_clk_ops, | 82 | .ops = &sh7763_shyway_clk_ops, |
83 | }; | 83 | }; |
84 | 84 | ||
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c index ba8dacc4ba23..4c11f8917e40 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c | |||
@@ -84,7 +84,7 @@ static struct clk_ops sh7780_shyway_clk_ops = { | |||
84 | 84 | ||
85 | static struct clk sh7780_shyway_clk = { | 85 | static struct clk sh7780_shyway_clk = { |
86 | .name = "shyway_clk", | 86 | .name = "shyway_clk", |
87 | .flags = CLK_ALWAYS_ENABLED, | 87 | .flags = CLK_ENABLE_ON_INIT, |
88 | .ops = &sh7780_shyway_clk_ops, | 88 | .ops = &sh7780_shyway_clk_ops, |
89 | }; | 89 | }; |
90 | 90 | ||
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index 52691eaeb9ba..edd432894bd9 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c | |||
@@ -88,7 +88,7 @@ static struct clk_ops sh7785_shyway_clk_ops = { | |||
88 | 88 | ||
89 | static struct clk sh7785_shyway_clk = { | 89 | static struct clk sh7785_shyway_clk = { |
90 | .name = "shyway_clk", | 90 | .name = "shyway_clk", |
91 | .flags = CLK_ALWAYS_ENABLED, | 91 | .flags = CLK_ENABLE_ON_INIT, |
92 | .ops = &sh7785_shyway_clk_ops, | 92 | .ops = &sh7785_shyway_clk_ops, |
93 | }; | 93 | }; |
94 | 94 | ||
@@ -104,7 +104,7 @@ static struct clk_ops sh7785_ddr_clk_ops = { | |||
104 | 104 | ||
105 | static struct clk sh7785_ddr_clk = { | 105 | static struct clk sh7785_ddr_clk = { |
106 | .name = "ddr_clk", | 106 | .name = "ddr_clk", |
107 | .flags = CLK_ALWAYS_ENABLED, | 107 | .flags = CLK_ENABLE_ON_INIT, |
108 | .ops = &sh7785_ddr_clk_ops, | 108 | .ops = &sh7785_ddr_clk_ops, |
109 | }; | 109 | }; |
110 | 110 | ||
@@ -120,7 +120,7 @@ static struct clk_ops sh7785_ram_clk_ops = { | |||
120 | 120 | ||
121 | static struct clk sh7785_ram_clk = { | 121 | static struct clk sh7785_ram_clk = { |
122 | .name = "ram_clk", | 122 | .name = "ram_clk", |
123 | .flags = CLK_ALWAYS_ENABLED, | 123 | .flags = CLK_ENABLE_ON_INIT, |
124 | .ops = &sh7785_ram_clk_ops, | 124 | .ops = &sh7785_ram_clk_ops, |
125 | }; | 125 | }; |
126 | 126 | ||
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c index 2e00ff436c63..2825494f85dc 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c | |||
@@ -91,7 +91,7 @@ static struct clk_ops sh7786_shyway_clk_ops = { | |||
91 | 91 | ||
92 | static struct clk sh7786_shyway_clk = { | 92 | static struct clk sh7786_shyway_clk = { |
93 | .name = "shyway_clk", | 93 | .name = "shyway_clk", |
94 | .flags = CLK_ALWAYS_ENABLED, | 94 | .flags = CLK_ENABLE_ON_INIT, |
95 | .ops = &sh7786_shyway_clk_ops, | 95 | .ops = &sh7786_shyway_clk_ops, |
96 | }; | 96 | }; |
97 | 97 | ||
@@ -107,7 +107,7 @@ static struct clk_ops sh7786_ddr_clk_ops = { | |||
107 | 107 | ||
108 | static struct clk sh7786_ddr_clk = { | 108 | static struct clk sh7786_ddr_clk = { |
109 | .name = "ddr_clk", | 109 | .name = "ddr_clk", |
110 | .flags = CLK_ALWAYS_ENABLED, | 110 | .flags = CLK_ENABLE_ON_INIT, |
111 | .ops = &sh7786_ddr_clk_ops, | 111 | .ops = &sh7786_ddr_clk_ops, |
112 | }; | 112 | }; |
113 | 113 | ||
diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c index 770934e68281..6e5c864cf40f 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c | |||
@@ -95,7 +95,7 @@ static struct clk_ops shx3_shyway_clk_ops = { | |||
95 | 95 | ||
96 | static struct clk shx3_shyway_clk = { | 96 | static struct clk shx3_shyway_clk = { |
97 | .name = "shyway_clk", | 97 | .name = "shyway_clk", |
98 | .flags = CLK_ALWAYS_ENABLED, | 98 | .flags = CLK_ENABLE_ON_INIT, |
99 | .ops = &shx3_shyway_clk_ops, | 99 | .ops = &shx3_shyway_clk_ops, |
100 | }; | 100 | }; |
101 | 101 | ||