diff options
Diffstat (limited to 'arch/arm/plat-samsung/clock.c')
-rw-r--r-- | arch/arm/plat-samsung/clock.c | 114 |
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 | */ |
65 | DEFINE_SPINLOCK(clocks_lock); | 65 | DEFINE_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 | 68 | struct clk *s3c2410_wdtclk; | |
69 | static int clk_null_enable(struct clk *clk, int enable) | 69 | static 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 | } |
76 | arch_initcall(s3c_wdt_reset_init); | ||
73 | 77 | ||
74 | static 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 | |||
90 | static 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 | |||
98 | struct 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 | ||
137 | void clk_put(struct clk *clk) | 80 | static int clk_null_enable(struct clk *clk, int enable) |
138 | { | 81 | { |
139 | module_put(clk->owner); | 82 | return 0; |
140 | } | 83 | } |
141 | 84 | ||
142 | int clk_enable(struct clk *clk) | 85 | int 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 | ||
244 | EXPORT_SYMBOL(clk_get); | ||
245 | EXPORT_SYMBOL(clk_put); | ||
246 | EXPORT_SYMBOL(clk_enable); | 187 | EXPORT_SYMBOL(clk_enable); |
247 | EXPORT_SYMBOL(clk_disable); | 188 | EXPORT_SYMBOL(clk_disable); |
248 | EXPORT_SYMBOL(clk_get_rate); | 189 | EXPORT_SYMBOL(clk_get_rate); |
@@ -265,7 +206,6 @@ struct clk_ops clk_ops_def_setrate = { | |||
265 | 206 | ||
266 | struct clk clk_xtal = { | 207 | struct 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 | ||
274 | struct clk clk_ext = { | 214 | struct clk clk_ext = { |
275 | .name = "ext", | 215 | .name = "ext", |
276 | .id = -1, | ||
277 | }; | 216 | }; |
278 | 217 | ||
279 | struct clk clk_epll = { | 218 | struct clk clk_epll = { |
280 | .name = "epll", | 219 | .name = "epll", |
281 | .id = -1, | ||
282 | }; | 220 | }; |
283 | 221 | ||
284 | struct clk clk_mpll = { | 222 | struct 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 | ||
290 | struct clk clk_upll = { | 227 | struct 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 | ||
297 | struct clk clk_f = { | 233 | struct 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 | ||
305 | struct clk clk_h = { | 240 | struct 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 | ||
314 | struct clk clk_p = { | 248 | struct 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 | ||
323 | struct clk clk_usb_bus = { | 256 | struct 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 | ||
331 | struct clk s3c24xx_uclk = { | 263 | struct 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; | |||
458 | static int clk_debugfs_register_one(struct clk *c) | 386 | static 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 | ||
490 | err_out: | 415 | err_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 | ||