blob: aff4c5b8c378134fa0497aefa890edd53f075de4 [file] [log] [blame]
Colin Crossd8611962010-01-28 16:40:29 -08001/*
2 *
3 * Copyright (C) 2010 Google, Inc.
4 *
5 * Author:
6 * Colin Cross <ccross@google.com>
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <linux/kernel.h>
20#include <linux/clk.h>
Jean-Christop PLAGNIOL-VILLARD6d803ba2010-11-17 10:04:33 +010021#include <linux/clkdev.h>
Colin Cross4729fd72011-02-12 16:43:05 -080022#include <linux/debugfs.h>
23#include <linux/delay.h>
24#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/sched.h>
28#include <linux/seq_file.h>
29#include <linux/slab.h>
30
31#include <mach/clk.h>
Colin Crossd8611962010-01-28 16:40:29 -080032
Colin Cross71fc84c2010-06-07 20:49:46 -070033#include "board.h"
Colin Cross41cfe362011-02-12 15:52:04 -080034#include "clock.h"
Colin Crossd8611962010-01-28 16:40:29 -080035
Colin Cross4729fd72011-02-12 16:43:05 -080036/*
37 * Locking:
38 *
39 * Each struct clk has a spinlock.
40 *
41 * To avoid AB-BA locking problems, locks must always be traversed from child
42 * clock to parent clock. For example, when enabling a clock, the clock's lock
43 * is taken, and then clk_enable is called on the parent, which take's the
44 * parent clock's lock. There is one exceptions to this ordering: When dumping
45 * the clock tree through debugfs. In this case, clk_lock_all is called,
46 * which attemps to iterate through the entire list of clocks and take every
47 * clock lock. If any call to spin_trylock fails, all locked clocks are
48 * unlocked, and the process is retried. When all the locks are held,
49 * the only clock operation that can be called is clk_get_rate_all_locked.
50 *
51 * Within a single clock, no clock operation can call another clock operation
52 * on itself, except for clk_get_rate_locked and clk_set_rate_locked. Any
53 * clock operation can call any other clock operation on any of it's possible
54 * parents.
55 *
56 * An additional mutex, clock_list_lock, is used to protect the list of all
57 * clocks.
58 *
59 * The clock operations must lock internally to protect against
60 * read-modify-write on registers that are shared by multiple clocks
61 */
62static DEFINE_MUTEX(clock_list_lock);
Colin Crossd8611962010-01-28 16:40:29 -080063static LIST_HEAD(clocks);
64
Colin Crossd8611962010-01-28 16:40:29 -080065struct clk *tegra_get_clock_by_name(const char *name)
66{
67 struct clk *c;
68 struct clk *ret = NULL;
Colin Cross4729fd72011-02-12 16:43:05 -080069 mutex_lock(&clock_list_lock);
Colin Crossd8611962010-01-28 16:40:29 -080070 list_for_each_entry(c, &clocks, node) {
71 if (strcmp(c->name, name) == 0) {
72 ret = c;
73 break;
74 }
75 }
Colin Cross4729fd72011-02-12 16:43:05 -080076 mutex_unlock(&clock_list_lock);
Colin Crossd8611962010-01-28 16:40:29 -080077 return ret;
78}
79
Colin Cross4729fd72011-02-12 16:43:05 -080080/* Must be called with c->spinlock held */
81static unsigned long clk_predict_rate_from_parent(struct clk *c, struct clk *p)
Colin Cross71fc84c2010-06-07 20:49:46 -070082{
83 u64 rate;
84
Colin Cross4729fd72011-02-12 16:43:05 -080085 rate = clk_get_rate(p);
Colin Cross71fc84c2010-06-07 20:49:46 -070086
87 if (c->mul != 0 && c->div != 0) {
Colin Cross4729fd72011-02-12 16:43:05 -080088 rate *= c->mul;
Colin Cross71fc84c2010-06-07 20:49:46 -070089 do_div(rate, c->div);
90 }
91
Colin Cross4729fd72011-02-12 16:43:05 -080092 return rate;
Colin Cross71fc84c2010-06-07 20:49:46 -070093}
94
Colin Cross4729fd72011-02-12 16:43:05 -080095/* Must be called with c->spinlock held */
96unsigned long clk_get_rate_locked(struct clk *c)
97{
98 unsigned long rate;
99
100 if (c->parent)
101 rate = clk_predict_rate_from_parent(c, c->parent);
102 else
103 rate = c->rate;
104
105 return rate;
106}
107
108unsigned long clk_get_rate(struct clk *c)
109{
110 unsigned long flags;
111 unsigned long rate;
112
113 spin_lock_irqsave(&c->spinlock, flags);
114
115 rate = clk_get_rate_locked(c);
116
117 spin_unlock_irqrestore(&c->spinlock, flags);
118
119 return rate;
120}
121EXPORT_SYMBOL(clk_get_rate);
122
Colin Crossd8611962010-01-28 16:40:29 -0800123int clk_reparent(struct clk *c, struct clk *parent)
124{
Colin Crossd8611962010-01-28 16:40:29 -0800125 c->parent = parent;
Colin Crossd8611962010-01-28 16:40:29 -0800126 return 0;
127}
128
Colin Crossd8611962010-01-28 16:40:29 -0800129void clk_init(struct clk *c)
130{
Colin Cross4729fd72011-02-12 16:43:05 -0800131 spin_lock_init(&c->spinlock);
Colin Crossd8611962010-01-28 16:40:29 -0800132
133 if (c->ops && c->ops->init)
134 c->ops->init(c);
135
Colin Crossf0355302010-10-13 19:16:02 -0700136 if (!c->ops || !c->ops->enable) {
137 c->refcnt++;
138 c->set = 1;
139 if (c->parent)
140 c->state = c->parent->state;
141 else
142 c->state = ON;
143 }
144
Colin Cross4729fd72011-02-12 16:43:05 -0800145 mutex_lock(&clock_list_lock);
Colin Crossd8611962010-01-28 16:40:29 -0800146 list_add(&c->node, &clocks);
Colin Cross4729fd72011-02-12 16:43:05 -0800147 mutex_unlock(&clock_list_lock);
Colin Crossd8611962010-01-28 16:40:29 -0800148}
149
Colin Cross4729fd72011-02-12 16:43:05 -0800150int clk_enable(struct clk *c)
Colin Crossd8611962010-01-28 16:40:29 -0800151{
Colin Cross4729fd72011-02-12 16:43:05 -0800152 int ret = 0;
153 unsigned long flags;
154
155 spin_lock_irqsave(&c->spinlock, flags);
Colin Crossbd41ef52010-09-08 20:01:04 -0700156
Colin Crossd8611962010-01-28 16:40:29 -0800157 if (c->refcnt == 0) {
158 if (c->parent) {
Colin Cross4729fd72011-02-12 16:43:05 -0800159 ret = clk_enable(c->parent);
Colin Crossd8611962010-01-28 16:40:29 -0800160 if (ret)
Colin Cross4729fd72011-02-12 16:43:05 -0800161 goto out;
Colin Crossd8611962010-01-28 16:40:29 -0800162 }
163
164 if (c->ops && c->ops->enable) {
165 ret = c->ops->enable(c);
166 if (ret) {
167 if (c->parent)
Colin Cross4729fd72011-02-12 16:43:05 -0800168 clk_disable(c->parent);
169 goto out;
Colin Crossd8611962010-01-28 16:40:29 -0800170 }
171 c->state = ON;
172#ifdef CONFIG_DEBUG_FS
173 c->set = 1;
174#endif
175 }
176 }
177 c->refcnt++;
Colin Cross4729fd72011-02-12 16:43:05 -0800178out:
179 spin_unlock_irqrestore(&c->spinlock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800180 return ret;
181}
182EXPORT_SYMBOL(clk_enable);
183
Colin Cross4729fd72011-02-12 16:43:05 -0800184void clk_disable(struct clk *c)
Colin Crossd8611962010-01-28 16:40:29 -0800185{
Colin Cross4729fd72011-02-12 16:43:05 -0800186 unsigned long flags;
187
188 spin_lock_irqsave(&c->spinlock, flags);
189
Colin Crossd8611962010-01-28 16:40:29 -0800190 if (c->refcnt == 0) {
191 WARN(1, "Attempting to disable clock %s with refcnt 0", c->name);
Colin Cross4729fd72011-02-12 16:43:05 -0800192 spin_unlock_irqrestore(&c->spinlock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800193 return;
194 }
195 if (c->refcnt == 1) {
196 if (c->ops && c->ops->disable)
197 c->ops->disable(c);
198
199 if (c->parent)
Colin Cross4729fd72011-02-12 16:43:05 -0800200 clk_disable(c->parent);
Colin Crossd8611962010-01-28 16:40:29 -0800201
202 c->state = OFF;
203 }
204 c->refcnt--;
Colin Crossd8611962010-01-28 16:40:29 -0800205
Colin Cross4729fd72011-02-12 16:43:05 -0800206 spin_unlock_irqrestore(&c->spinlock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800207}
208EXPORT_SYMBOL(clk_disable);
209
Colin Crossd8611962010-01-28 16:40:29 -0800210int clk_set_parent(struct clk *c, struct clk *parent)
211{
212 int ret;
213 unsigned long flags;
Colin Cross4729fd72011-02-12 16:43:05 -0800214 unsigned long new_rate;
215 unsigned long old_rate;
216
217 spin_lock_irqsave(&c->spinlock, flags);
218
219 if (!c->ops || !c->ops->set_parent) {
220 ret = -ENOSYS;
221 goto out;
222 }
223
224 new_rate = clk_predict_rate_from_parent(c, parent);
225 old_rate = clk_get_rate_locked(c);
226
227 ret = c->ops->set_parent(c, parent);
228 if (ret)
229 goto out;
230
231out:
232 spin_unlock_irqrestore(&c->spinlock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800233 return ret;
234}
235EXPORT_SYMBOL(clk_set_parent);
236
237struct clk *clk_get_parent(struct clk *c)
238{
239 return c->parent;
240}
241EXPORT_SYMBOL(clk_get_parent);
242
Colin Cross71fc84c2010-06-07 20:49:46 -0700243int clk_set_rate_locked(struct clk *c, unsigned long rate)
244{
Colin Cross4729fd72011-02-12 16:43:05 -0800245 if (!c->ops || !c->ops->set_rate)
246 return -ENOSYS;
Colin Cross71fc84c2010-06-07 20:49:46 -0700247
248 if (rate > c->max_rate)
249 rate = c->max_rate;
250
Colin Cross4729fd72011-02-12 16:43:05 -0800251 return c->ops->set_rate(c, rate);
Colin Cross71fc84c2010-06-07 20:49:46 -0700252}
253
Colin Crossd8611962010-01-28 16:40:29 -0800254int clk_set_rate(struct clk *c, unsigned long rate)
255{
Colin Cross4729fd72011-02-12 16:43:05 -0800256 int ret;
Colin Crossd8611962010-01-28 16:40:29 -0800257 unsigned long flags;
258
Colin Cross4729fd72011-02-12 16:43:05 -0800259 spin_lock_irqsave(&c->spinlock, flags);
260
Colin Cross71fc84c2010-06-07 20:49:46 -0700261 ret = clk_set_rate_locked(c, rate);
Colin Cross4729fd72011-02-12 16:43:05 -0800262
263 spin_unlock_irqrestore(&c->spinlock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800264
265 return ret;
266}
267EXPORT_SYMBOL(clk_set_rate);
268
Colin Cross4729fd72011-02-12 16:43:05 -0800269
270/* Must be called with clocks lock and all indvidual clock locks held */
271unsigned long clk_get_rate_all_locked(struct clk *c)
Colin Crossd8611962010-01-28 16:40:29 -0800272{
Colin Cross4729fd72011-02-12 16:43:05 -0800273 u64 rate;
274 int mul = 1;
275 int div = 1;
276 struct clk *p = c;
Colin Crossd8611962010-01-28 16:40:29 -0800277
Colin Cross4729fd72011-02-12 16:43:05 -0800278 while (p) {
279 c = p;
280 if (c->mul != 0 && c->div != 0) {
281 mul *= c->mul;
282 div *= c->div;
283 }
284 p = c->parent;
285 }
Colin Crossd8611962010-01-28 16:40:29 -0800286
Colin Cross4729fd72011-02-12 16:43:05 -0800287 rate = c->rate;
288 rate *= mul;
289 do_div(rate, div);
Colin Crossd8611962010-01-28 16:40:29 -0800290
Colin Cross4729fd72011-02-12 16:43:05 -0800291 return rate;
Colin Crossd8611962010-01-28 16:40:29 -0800292}
Colin Crossd8611962010-01-28 16:40:29 -0800293
Colin Cross71fc84c2010-06-07 20:49:46 -0700294long clk_round_rate(struct clk *c, unsigned long rate)
295{
Colin Cross4729fd72011-02-12 16:43:05 -0800296 unsigned long flags;
297 long ret;
298
299 spin_lock_irqsave(&c->spinlock, flags);
300
301 if (!c->ops || !c->ops->round_rate) {
302 ret = -ENOSYS;
303 goto out;
304 }
Colin Cross71fc84c2010-06-07 20:49:46 -0700305
306 if (rate > c->max_rate)
307 rate = c->max_rate;
308
Colin Cross4729fd72011-02-12 16:43:05 -0800309 ret = c->ops->round_rate(c, rate);
310
311out:
312 spin_unlock_irqrestore(&c->spinlock, flags);
313 return ret;
Colin Cross71fc84c2010-06-07 20:49:46 -0700314}
315EXPORT_SYMBOL(clk_round_rate);
316
Colin Crossd8611962010-01-28 16:40:29 -0800317static int tegra_clk_init_one_from_table(struct tegra_clk_init_table *table)
318{
319 struct clk *c;
320 struct clk *p;
321
322 int ret = 0;
323
324 c = tegra_get_clock_by_name(table->name);
325
326 if (!c) {
327 pr_warning("Unable to initialize clock %s\n",
328 table->name);
329 return -ENODEV;
330 }
331
332 if (table->parent) {
333 p = tegra_get_clock_by_name(table->parent);
334 if (!p) {
335 pr_warning("Unable to find parent %s of clock %s\n",
336 table->parent, table->name);
337 return -ENODEV;
338 }
339
340 if (c->parent != p) {
341 ret = clk_set_parent(c, p);
342 if (ret) {
343 pr_warning("Unable to set parent %s of clock %s: %d\n",
344 table->parent, table->name, ret);
345 return -EINVAL;
346 }
347 }
348 }
349
350 if (table->rate && table->rate != clk_get_rate(c)) {
351 ret = clk_set_rate(c, table->rate);
352 if (ret) {
353 pr_warning("Unable to set clock %s to rate %lu: %d\n",
354 table->name, table->rate, ret);
355 return -EINVAL;
356 }
357 }
358
359 if (table->enabled) {
360 ret = clk_enable(c);
361 if (ret) {
362 pr_warning("Unable to enable clock %s: %d\n",
363 table->name, ret);
364 return -EINVAL;
365 }
366 }
367
368 return 0;
369}
370
371void tegra_clk_init_from_table(struct tegra_clk_init_table *table)
372{
373 for (; table->name; table++)
374 tegra_clk_init_one_from_table(table);
375}
376EXPORT_SYMBOL(tegra_clk_init_from_table);
377
378void tegra_periph_reset_deassert(struct clk *c)
379{
380 tegra2_periph_reset_deassert(c);
381}
382EXPORT_SYMBOL(tegra_periph_reset_deassert);
383
384void tegra_periph_reset_assert(struct clk *c)
385{
386 tegra2_periph_reset_assert(c);
387}
388EXPORT_SYMBOL(tegra_periph_reset_assert);
389
Colin Cross71fc84c2010-06-07 20:49:46 -0700390void __init tegra_init_clock(void)
Colin Crossd8611962010-01-28 16:40:29 -0800391{
392 tegra2_init_clocks();
Colin Cross71fc84c2010-06-07 20:49:46 -0700393}
394
Colin Crossd8611962010-01-28 16:40:29 -0800395#ifdef CONFIG_DEBUG_FS
Colin Cross4729fd72011-02-12 16:43:05 -0800396
397static int __clk_lock_all_spinlocks(void)
398{
399 struct clk *c;
400
401 list_for_each_entry(c, &clocks, node)
402 if (!spin_trylock(&c->spinlock))
403 goto unlock_spinlocks;
404
405 return 0;
406
407unlock_spinlocks:
408 list_for_each_entry_continue_reverse(c, &clocks, node)
409 spin_unlock(&c->spinlock);
410
411 return -EAGAIN;
412}
413
414static void __clk_unlock_all_spinlocks(void)
415{
416 struct clk *c;
417
418 list_for_each_entry_reverse(c, &clocks, node)
419 spin_unlock(&c->spinlock);
420}
421
422/*
423 * This function retries until it can take all locks, and may take
424 * an arbitrarily long time to complete.
425 * Must be called with irqs enabled, returns with irqs disabled
426 * Must be called with clock_list_lock held
427 */
428static void clk_lock_all(void)
429{
430 int ret;
431retry:
432 local_irq_disable();
433
434 ret = __clk_lock_all_spinlocks();
435 if (ret)
436 goto failed_spinlocks;
437
438 /* All locks taken successfully, return */
439 return;
440
441failed_spinlocks:
442 local_irq_enable();
443 yield();
444 goto retry;
445}
446
447/*
448 * Unlocks all clocks after a clk_lock_all
449 * Must be called with irqs disabled, returns with irqs enabled
450 * Must be called with clock_list_lock held
451 */
452static void clk_unlock_all(void)
453{
454 __clk_unlock_all_spinlocks();
455
456 local_irq_enable();
457}
458
Colin Crossd8611962010-01-28 16:40:29 -0800459static struct dentry *clk_debugfs_root;
460
461
462static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level)
463{
464 struct clk *child;
Colin Crossd8611962010-01-28 16:40:29 -0800465 const char *state = "uninit";
Colin Cross71fc84c2010-06-07 20:49:46 -0700466 char div[8] = {0};
Colin Crossd8611962010-01-28 16:40:29 -0800467
468 if (c->state == ON)
469 state = "on";
470 else if (c->state == OFF)
471 state = "off";
472
473 if (c->mul != 0 && c->div != 0) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700474 if (c->mul > c->div) {
475 int mul = c->mul / c->div;
476 int mul2 = (c->mul * 10 / c->div) % 10;
477 int mul3 = (c->mul * 10) % c->div;
478 if (mul2 == 0 && mul3 == 0)
479 snprintf(div, sizeof(div), "x%d", mul);
480 else if (mul3 == 0)
481 snprintf(div, sizeof(div), "x%d.%d", mul, mul2);
482 else
483 snprintf(div, sizeof(div), "x%d.%d..", mul, mul2);
484 } else {
Colin Crossd8611962010-01-28 16:40:29 -0800485 snprintf(div, sizeof(div), "%d%s", c->div / c->mul,
486 (c->div % c->mul) ? ".5" : "");
Colin Cross71fc84c2010-06-07 20:49:46 -0700487 }
Colin Crossd8611962010-01-28 16:40:29 -0800488 }
489
Colin Cross71fc84c2010-06-07 20:49:46 -0700490 seq_printf(s, "%*s%c%c%-*s %-6s %-3d %-8s %-10lu\n",
491 level * 3 + 1, "",
492 c->rate > c->max_rate ? '!' : ' ',
493 !c->set ? '*' : ' ',
Colin Crossd8611962010-01-28 16:40:29 -0800494 30 - level * 3, c->name,
Colin Cross4729fd72011-02-12 16:43:05 -0800495 state, c->refcnt, div, clk_get_rate_all_locked(c));
496
497 list_for_each_entry(child, &clocks, node) {
498 if (child->parent != c)
499 continue;
500
Colin Crossd8611962010-01-28 16:40:29 -0800501 clock_tree_show_one(s, child, level + 1);
502 }
503}
504
505static int clock_tree_show(struct seq_file *s, void *data)
506{
507 struct clk *c;
Colin Cross71fc84c2010-06-07 20:49:46 -0700508 seq_printf(s, " clock state ref div rate\n");
509 seq_printf(s, "--------------------------------------------------------------\n");
Colin Cross4729fd72011-02-12 16:43:05 -0800510
511 mutex_lock(&clock_list_lock);
512
513 clk_lock_all();
514
Colin Crossd8611962010-01-28 16:40:29 -0800515 list_for_each_entry(c, &clocks, node)
516 if (c->parent == NULL)
517 clock_tree_show_one(s, c, 0);
Colin Cross4729fd72011-02-12 16:43:05 -0800518
519 clk_unlock_all();
520
521 mutex_unlock(&clock_list_lock);
Colin Crossd8611962010-01-28 16:40:29 -0800522 return 0;
523}
524
525static int clock_tree_open(struct inode *inode, struct file *file)
526{
527 return single_open(file, clock_tree_show, inode->i_private);
528}
529
530static const struct file_operations clock_tree_fops = {
531 .open = clock_tree_open,
532 .read = seq_read,
533 .llseek = seq_lseek,
534 .release = single_release,
535};
536
537static int possible_parents_show(struct seq_file *s, void *data)
538{
539 struct clk *c = s->private;
540 int i;
541
542 for (i = 0; c->inputs[i].input; i++) {
543 char *first = (i == 0) ? "" : " ";
544 seq_printf(s, "%s%s", first, c->inputs[i].input->name);
545 }
546 seq_printf(s, "\n");
547 return 0;
548}
549
550static int possible_parents_open(struct inode *inode, struct file *file)
551{
552 return single_open(file, possible_parents_show, inode->i_private);
553}
554
555static const struct file_operations possible_parents_fops = {
556 .open = possible_parents_open,
557 .read = seq_read,
558 .llseek = seq_lseek,
559 .release = single_release,
560};
561
562static int clk_debugfs_register_one(struct clk *c)
563{
564 struct dentry *d, *child, *child_tmp;
565
566 d = debugfs_create_dir(c->name, clk_debugfs_root);
567 if (!d)
568 return -ENOMEM;
569 c->dent = d;
570
571 d = debugfs_create_u8("refcnt", S_IRUGO, c->dent, (u8 *)&c->refcnt);
572 if (!d)
573 goto err_out;
574
575 d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
576 if (!d)
577 goto err_out;
578
579 d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
580 if (!d)
581 goto err_out;
582
583 if (c->inputs) {
584 d = debugfs_create_file("possible_parents", S_IRUGO, c->dent,
585 c, &possible_parents_fops);
586 if (!d)
587 goto err_out;
588 }
589
590 return 0;
591
592err_out:
593 d = c->dent;
594 list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
595 debugfs_remove(child);
596 debugfs_remove(c->dent);
597 return -ENOMEM;
598}
599
600static int clk_debugfs_register(struct clk *c)
601{
602 int err;
603 struct clk *pa = c->parent;
604
605 if (pa && !pa->dent) {
606 err = clk_debugfs_register(pa);
607 if (err)
608 return err;
609 }
610
611 if (!c->dent) {
612 err = clk_debugfs_register_one(c);
613 if (err)
614 return err;
615 }
616 return 0;
617}
618
619static int __init clk_debugfs_init(void)
620{
621 struct clk *c;
622 struct dentry *d;
623 int err = -ENOMEM;
624
625 d = debugfs_create_dir("clock", NULL);
626 if (!d)
627 return -ENOMEM;
628 clk_debugfs_root = d;
629
630 d = debugfs_create_file("clock_tree", S_IRUGO, clk_debugfs_root, NULL,
631 &clock_tree_fops);
632 if (!d)
633 goto err_out;
634
635 list_for_each_entry(c, &clocks, node) {
636 err = clk_debugfs_register(c);
637 if (err)
638 goto err_out;
639 }
640 return 0;
641err_out:
642 debugfs_remove_recursive(clk_debugfs_root);
643 return err;
644}
645
646late_initcall(clk_debugfs_init);
647#endif