diff options
-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 | ||