1 /* 2 * arch/sh/kernel/cpu/clock.c - SuperH clock framework 3 * 4 * Copyright (C) 2005 Paul Mundt 5 * 6 * This clock framework is derived from the OMAP version by: 7 * 8 * Copyright (C) 2004 Nokia Corporation 9 * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> 10 * 11 * This file is subject to the terms and conditions of the GNU General Public 12 * License. See the file "COPYING" in the main directory of this archive 13 * for more details. 14 */ 15 #include <linux/kernel.h> 16 #include <linux/init.h> 17 #include <linux/module.h> 18 #include <linux/list.h> 19 #include <linux/kref.h> 20 #include <linux/seq_file.h> 21 #include <linux/err.h> 22 #include <asm/clock.h> 23 #include <asm/timer.h> 24 25 static LIST_HEAD(clock_list); 26 static DEFINE_SPINLOCK(clock_lock); 27 static DECLARE_MUTEX(clock_list_sem); 28 29 /* 30 * Each subtype is expected to define the init routines for these clocks, 31 * as each subtype (or processor family) will have these clocks at the 32 * very least. These are all provided through the CPG, which even some of 33 * the more quirky parts (such as ST40, SH4-202, etc.) still have. 34 * 35 * The processor-specific code is expected to register any additional 36 * clock sources that are of interest. 37 */ 38 static struct clk master_clk = { 39 .name = "master_clk", 40 .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES, 41 .rate = CONFIG_SH_PCLK_FREQ, 42 }; 43 44 static struct clk module_clk = { 45 .name = "module_clk", 46 .parent = &master_clk, 47 .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES, 48 }; 49 50 static struct clk bus_clk = { 51 .name = "bus_clk", 52 .parent = &master_clk, 53 .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES, 54 }; 55 56 static struct clk cpu_clk = { 57 .name = "cpu_clk", 58 .parent = &master_clk, 59 .flags = CLK_ALWAYS_ENABLED, 60 }; 61 62 /* 63 * The ordering of these clocks matters, do not change it. 64 */ 65 static struct clk *onchip_clocks[] = { 66 &master_clk, 67 &module_clk, 68 &bus_clk, 69 &cpu_clk, 70 }; 71 72 static void propagate_rate(struct clk *clk) 73 { 74 struct clk *clkp; 75 76 list_for_each_entry(clkp, &clock_list, node) { 77 if (likely(clkp->parent != clk)) 78 continue; 79 if (likely(clkp->ops && clkp->ops->recalc)) 80 clkp->ops->recalc(clkp); 81 } 82 } 83 84 int __clk_enable(struct clk *clk) 85 { 86 /* 87 * See if this is the first time we're enabling the clock, some 88 * clocks that are always enabled still require "special" 89 * initialization. This is especially true if the clock mode 90 * changes and the clock needs to hunt for the proper set of 91 * divisors to use before it can effectively recalc. 92 */ 93 if (unlikely(atomic_read(&clk->kref.refcount) == 1)) 94 if (clk->ops && clk->ops->init) 95 clk->ops->init(clk); 96 97 if (clk->flags & CLK_ALWAYS_ENABLED) 98 return 0; 99 100 if (likely(clk->ops && clk->ops->enable)) 101 clk->ops->enable(clk); 102 103 kref_get(&clk->kref); 104 return 0; 105 } 106 107 int clk_enable(struct clk *clk) 108 { 109 unsigned long flags; 110 int ret; 111 112 spin_lock_irqsave(&clock_lock, flags); 113 ret = __clk_enable(clk); 114 spin_unlock_irqrestore(&clock_lock, flags); 115 116 return ret; 117 } 118 119 static void clk_kref_release(struct kref *kref) 120 { 121 /* Nothing to do */ 122 } 123 124 void __clk_disable(struct clk *clk) 125 { 126 if (clk->flags & CLK_ALWAYS_ENABLED) 127 return; 128 129 kref_put(&clk->kref, clk_kref_release); 130 } 131 132 void clk_disable(struct clk *clk) 133 { 134 unsigned long flags; 135 136 spin_lock_irqsave(&clock_lock, flags); 137 __clk_disable(clk); 138 spin_unlock_irqrestore(&clock_lock, flags); 139 } 140 141 int clk_register(struct clk *clk) 142 { 143 down(&clock_list_sem); 144 145 list_add(&clk->node, &clock_list); 146 kref_init(&clk->kref); 147 148 up(&clock_list_sem); 149 150 return 0; 151 } 152 153 void clk_unregister(struct clk *clk) 154 { 155 down(&clock_list_sem); 156 list_del(&clk->node); 157 up(&clock_list_sem); 158 } 159 160 inline unsigned long clk_get_rate(struct clk *clk) 161 { 162 return clk->rate; 163 } 164 165 int clk_set_rate(struct clk *clk, unsigned long rate) 166 { 167 int ret = -EOPNOTSUPP; 168 169 if (likely(clk->ops && clk->ops->set_rate)) { 170 unsigned long flags; 171 172 spin_lock_irqsave(&clock_lock, flags); 173 ret = clk->ops->set_rate(clk, rate); 174 spin_unlock_irqrestore(&clock_lock, flags); 175 } 176 177 if (unlikely(clk->flags & CLK_RATE_PROPAGATES)) 178 propagate_rate(clk); 179 180 return ret; 181 } 182 183 void clk_recalc_rate(struct clk *clk) 184 { 185 if (likely(clk->ops && clk->ops->recalc)) { 186 unsigned long flags; 187 188 spin_lock_irqsave(&clock_lock, flags); 189 clk->ops->recalc(clk); 190 spin_unlock_irqrestore(&clock_lock, flags); 191 } 192 193 if (unlikely(clk->flags & CLK_RATE_PROPAGATES)) 194 propagate_rate(clk); 195 } 196 197 struct clk *clk_get(const char *id) 198 { 199 struct clk *p, *clk = ERR_PTR(-ENOENT); 200 201 down(&clock_list_sem); 202 list_for_each_entry(p, &clock_list, node) { 203 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { 204 clk = p; 205 break; 206 } 207 } 208 up(&clock_list_sem); 209 210 return clk; 211 } 212 213 void clk_put(struct clk *clk) 214 { 215 if (clk && !IS_ERR(clk)) 216 module_put(clk->owner); 217 } 218 219 void __init __attribute__ ((weak)) 220 arch_init_clk_ops(struct clk_ops **ops, int type) 221 { 222 } 223 224 int __init clk_init(void) 225 { 226 int i, ret = 0; 227 228 BUG_ON(unlikely(!master_clk.rate)); 229 230 for (i = 0; i < ARRAY_SIZE(onchip_clocks); i++) { 231 struct clk *clk = onchip_clocks[i]; 232 233 arch_init_clk_ops(&clk->ops, i); 234 ret |= clk_register(clk); 235 clk_enable(clk); 236 } 237 238 /* Kick the child clocks.. */ 239 propagate_rate(&master_clk); 240 propagate_rate(&bus_clk); 241 242 return ret; 243 } 244 245 int show_clocks(struct seq_file *m) 246 { 247 struct clk *clk; 248 249 list_for_each_entry_reverse(clk, &clock_list, node) { 250 unsigned long rate = clk_get_rate(clk); 251 252 /* 253 * Don't bother listing dummy clocks with no ancestry 254 * that only support enable and disable ops. 255 */ 256 if (unlikely(!rate && !clk->parent)) 257 continue; 258 259 seq_printf(m, "%-12s\t: %ld.%02ldMHz\n", clk->name, 260 rate / 1000000, (rate % 1000000) / 10000); 261 } 262 263 return 0; 264 } 265 266 EXPORT_SYMBOL_GPL(clk_register); 267 EXPORT_SYMBOL_GPL(clk_unregister); 268 EXPORT_SYMBOL_GPL(clk_get); 269 EXPORT_SYMBOL_GPL(clk_put); 270 EXPORT_SYMBOL_GPL(clk_enable); 271 EXPORT_SYMBOL_GPL(clk_disable); 272 EXPORT_SYMBOL_GPL(__clk_enable); 273 EXPORT_SYMBOL_GPL(__clk_disable); 274 EXPORT_SYMBOL_GPL(clk_get_rate); 275 EXPORT_SYMBOL_GPL(clk_set_rate); 276 EXPORT_SYMBOL_GPL(clk_recalc_rate); 277