aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-samsung/clock.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-samsung/clock.c')
-rw-r--r--arch/arm/plat-samsung/clock.c114
1 files changed, 18 insertions, 96 deletions
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c
index 772892826ff..3b4451979d1 100644
--- a/arch/arm/plat-samsung/clock.c
+++ b/arch/arm/plat-samsung/clock.c
@@ -64,79 +64,22 @@ static LIST_HEAD(clocks);
64 */ 64 */
65DEFINE_SPINLOCK(clocks_lock); 65DEFINE_SPINLOCK(clocks_lock);
66 66
67/* enable and disable calls for use with the clk struct */ 67/* Global watchdog clock used by arch_wtd_reset() callback */
68 68struct clk *s3c2410_wdtclk;
69static int clk_null_enable(struct clk *clk, int enable) 69static int __init s3c_wdt_reset_init(void)
70{ 70{
71 s3c2410_wdtclk = clk_get(NULL, "watchdog");
72 if (IS_ERR(s3c2410_wdtclk))
73 printk(KERN_WARNING "%s: warning: cannot get watchdog clock\n", __func__);
71 return 0; 74 return 0;
72} 75}
76arch_initcall(s3c_wdt_reset_init);
73 77
74static int dev_is_s3c_uart(struct device *dev) 78/* enable and disable calls for use with the clk struct */
75{
76 struct platform_device **pdev = s3c24xx_uart_devs;
77 int i;
78 for (i = 0; i < ARRAY_SIZE(s3c24xx_uart_devs); i++, pdev++)
79 if (*pdev && dev == &(*pdev)->dev)
80 return 1;
81 return 0;
82}
83
84/*
85 * Serial drivers call get_clock() very early, before platform bus
86 * has been set up, this requires a special check to let them get
87 * a proper clock
88 */
89
90static int dev_is_platform_device(struct device *dev)
91{
92 return dev->bus == &platform_bus_type ||
93 (dev->bus == NULL && dev_is_s3c_uart(dev));
94}
95
96/* Clock API calls */
97
98struct clk *clk_get(struct device *dev, const char *id)
99{
100 struct clk *p;
101 struct clk *clk = ERR_PTR(-ENOENT);
102 int idno;
103
104 if (dev == NULL || !dev_is_platform_device(dev))
105 idno = -1;
106 else
107 idno = to_platform_device(dev)->id;
108
109 spin_lock(&clocks_lock);
110
111 list_for_each_entry(p, &clocks, list) {
112 if (p->id == idno &&
113 strcmp(id, p->name) == 0 &&
114 try_module_get(p->owner)) {
115 clk = p;
116 break;
117 }
118 }
119
120 /* check for the case where a device was supplied, but the
121 * clock that was being searched for is not device specific */
122
123 if (IS_ERR(clk)) {
124 list_for_each_entry(p, &clocks, list) {
125 if (p->id == -1 && strcmp(id, p->name) == 0 &&
126 try_module_get(p->owner)) {
127 clk = p;
128 break;
129 }
130 }
131 }
132
133 spin_unlock(&clocks_lock);
134 return clk;
135}
136 79
137void clk_put(struct clk *clk) 80static int clk_null_enable(struct clk *clk, int enable)
138{ 81{
139 module_put(clk->owner); 82 return 0;
140} 83}
141 84
142int clk_enable(struct clk *clk) 85int clk_enable(struct clk *clk)
@@ -241,8 +184,6 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
241 return ret; 184 return ret;
242} 185}
243 186
244EXPORT_SYMBOL(clk_get);
245EXPORT_SYMBOL(clk_put);
246EXPORT_SYMBOL(clk_enable); 187EXPORT_SYMBOL(clk_enable);
247EXPORT_SYMBOL(clk_disable); 188EXPORT_SYMBOL(clk_disable);
248EXPORT_SYMBOL(clk_get_rate); 189EXPORT_SYMBOL(clk_get_rate);
@@ -265,7 +206,6 @@ struct clk_ops clk_ops_def_setrate = {
265 206
266struct clk clk_xtal = { 207struct clk clk_xtal = {
267 .name = "xtal", 208 .name = "xtal",
268 .id = -1,
269 .rate = 0, 209 .rate = 0,
270 .parent = NULL, 210 .parent = NULL,
271 .ctrlbit = 0, 211 .ctrlbit = 0,
@@ -273,30 +213,25 @@ struct clk clk_xtal = {
273 213
274struct clk clk_ext = { 214struct clk clk_ext = {
275 .name = "ext", 215 .name = "ext",
276 .id = -1,
277}; 216};
278 217
279struct clk clk_epll = { 218struct clk clk_epll = {
280 .name = "epll", 219 .name = "epll",
281 .id = -1,
282}; 220};
283 221
284struct clk clk_mpll = { 222struct clk clk_mpll = {
285 .name = "mpll", 223 .name = "mpll",
286 .id = -1,
287 .ops = &clk_ops_def_setrate, 224 .ops = &clk_ops_def_setrate,
288}; 225};
289 226
290struct clk clk_upll = { 227struct clk clk_upll = {
291 .name = "upll", 228 .name = "upll",
292 .id = -1,
293 .parent = NULL, 229 .parent = NULL,
294 .ctrlbit = 0, 230 .ctrlbit = 0,
295}; 231};
296 232
297struct clk clk_f = { 233struct clk clk_f = {
298 .name = "fclk", 234 .name = "fclk",
299 .id = -1,
300 .rate = 0, 235 .rate = 0,
301 .parent = &clk_mpll, 236 .parent = &clk_mpll,
302 .ctrlbit = 0, 237 .ctrlbit = 0,
@@ -304,7 +239,6 @@ struct clk clk_f = {
304 239
305struct clk clk_h = { 240struct clk clk_h = {
306 .name = "hclk", 241 .name = "hclk",
307 .id = -1,
308 .rate = 0, 242 .rate = 0,
309 .parent = NULL, 243 .parent = NULL,
310 .ctrlbit = 0, 244 .ctrlbit = 0,
@@ -313,7 +247,6 @@ struct clk clk_h = {
313 247
314struct clk clk_p = { 248struct clk clk_p = {
315 .name = "pclk", 249 .name = "pclk",
316 .id = -1,
317 .rate = 0, 250 .rate = 0,
318 .parent = NULL, 251 .parent = NULL,
319 .ctrlbit = 0, 252 .ctrlbit = 0,
@@ -322,7 +255,6 @@ struct clk clk_p = {
322 255
323struct clk clk_usb_bus = { 256struct clk clk_usb_bus = {
324 .name = "usb-bus", 257 .name = "usb-bus",
325 .id = -1,
326 .rate = 0, 258 .rate = 0,
327 .parent = &clk_upll, 259 .parent = &clk_upll,
328}; 260};
@@ -330,7 +262,6 @@ struct clk clk_usb_bus = {
330 262
331struct clk s3c24xx_uclk = { 263struct clk s3c24xx_uclk = {
332 .name = "uclk", 264 .name = "uclk",
333 .id = -1,
334}; 265};
335 266
336/* initialise the clock system */ 267/* initialise the clock system */
@@ -346,14 +277,11 @@ int s3c24xx_register_clock(struct clk *clk)
346 if (clk->enable == NULL) 277 if (clk->enable == NULL)
347 clk->enable = clk_null_enable; 278 clk->enable = clk_null_enable;
348 279
349 /* add to the list of available clocks */ 280 /* fill up the clk_lookup structure and register it*/
350 281 clk->lookup.dev_id = clk->devname;
351 /* Quick check to see if this clock has already been registered. */ 282 clk->lookup.con_id = clk->name;
352 BUG_ON(clk->list.prev != clk->list.next); 283 clk->lookup.clk = clk;
353 284 clkdev_add(&clk->lookup);
354 spin_lock(&clocks_lock);
355 list_add(&clk->list, &clocks);
356 spin_unlock(&clocks_lock);
357 285
358 return 0; 286 return 0;
359} 287}
@@ -458,15 +386,12 @@ static struct dentry *clk_debugfs_root;
458static int clk_debugfs_register_one(struct clk *c) 386static int clk_debugfs_register_one(struct clk *c)
459{ 387{
460 int err; 388 int err;
461 struct dentry *d, *child, *child_tmp; 389 struct dentry *d;
462 struct clk *pa = c->parent; 390 struct clk *pa = c->parent;
463 char s[255]; 391 char s[255];
464 char *p = s; 392 char *p = s;
465 393
466 p += sprintf(p, "%s", c->name); 394 p += sprintf(p, "%s", c->devname);
467
468 if (c->id >= 0)
469 sprintf(p, ":%d", c->id);
470 395
471 d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root); 396 d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root);
472 if (!d) 397 if (!d)
@@ -488,10 +413,7 @@ static int clk_debugfs_register_one(struct clk *c)
488 return 0; 413 return 0;
489 414
490err_out: 415err_out:
491 d = c->dent; 416 debugfs_remove_recursive(c->dent);
492 list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
493 debugfs_remove(child);
494 debugfs_remove(c->dent);
495 return err; 417 return err;
496} 418}
497 419