aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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