aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2009-05-11 16:14:53 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-05-11 16:14:53 -0400
commit4ff29ff8e8723a41e7defd8bc78a7b16cbf940a2 (patch)
tree0e277d27eee3af89e66856458dce29e6ba3f4721
parentb1f6cfe48c3cb1dfa77db3d2f42f765febaef9bc (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.h3
-rw-r--r--arch/sh/kernel/cpu/clock.c94
-rw-r--r--arch/sh/kernel/cpu/sh4/clock-sh4-202.c6
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7763.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7780.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7785.c6
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7786.c4
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-shx3.c2
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 */
44void arch_init_clk_ops(struct clk_ops **, int type); 43void 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 */
44static struct clk master_clk = { 44static 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
50static struct clk module_clk = { 50static 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
56static struct clk bus_clk = { 56static 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
62static struct clk cpu_clk = { 62static 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
96static 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
114static int __clk_enable(struct clk *clk) 96static 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
150static void __clk_disable(struct clk *clk) 125static 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}
236EXPORT_SYMBOL_GPL(clk_register); 196EXPORT_SYMBOL_GPL(clk_register);
@@ -244,6 +204,15 @@ void clk_unregister(struct clk *clk)
244} 204}
245EXPORT_SYMBOL_GPL(clk_unregister); 205EXPORT_SYMBOL_GPL(clk_unregister);
246 206
207static 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
247unsigned long clk_get_rate(struct clk *clk) 216unsigned 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
47static struct clk sh4202_emi_clk = { 47static 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
63static struct clk sh4202_femi_clk = { 63static 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
141static struct clk sh4202_shoc_clk = { 141static 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
79static struct clk sh7763_shyway_clk = { 79static 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
85static struct clk sh7780_shyway_clk = { 85static 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
89static struct clk sh7785_shyway_clk = { 89static 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
105static struct clk sh7785_ddr_clk = { 105static 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
121static struct clk sh7785_ram_clk = { 121static 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
92static struct clk sh7786_shyway_clk = { 92static 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
108static struct clk sh7786_ddr_clk = { 108static 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
96static struct clk shx3_shyway_clk = { 96static 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