blob: ef9b494f961a76debd236b8b376d9a3a65a6a4bc [file] [log] [blame]
Colin Crossd8611962010-01-28 16:40:29 -08001/*
2 *
3 * Copyright (C) 2010 Google, Inc.
Prashant Gaikwad96a1bd12012-08-06 11:57:42 +05304 * Copyright (c) 2012 NVIDIA CORPORATION. All rights reserved.
Colin Crossd8611962010-01-28 16:40:29 -08005 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/clk.h>
Jean-Christop PLAGNIOL-VILLARD6d803ba2010-11-17 10:04:33 +010022#include <linux/clkdev.h>
Colin Cross4729fd72011-02-12 16:43:05 -080023#include <linux/debugfs.h>
24#include <linux/delay.h>
25#include <linux/init.h>
26#include <linux/list.h>
27#include <linux/module.h>
28#include <linux/sched.h>
29#include <linux/seq_file.h>
30#include <linux/slab.h>
31
32#include <mach/clk.h>
Colin Crossd8611962010-01-28 16:40:29 -080033
Colin Cross71fc84c2010-06-07 20:49:46 -070034#include "board.h"
Colin Cross41cfe362011-02-12 15:52:04 -080035#include "clock.h"
Colin Crossd8611962010-01-28 16:40:29 -080036
Colin Cross4729fd72011-02-12 16:43:05 -080037/*
38 * Locking:
39 *
40 * Each struct clk has a spinlock.
41 *
42 * To avoid AB-BA locking problems, locks must always be traversed from child
43 * clock to parent clock. For example, when enabling a clock, the clock's lock
44 * is taken, and then clk_enable is called on the parent, which take's the
45 * parent clock's lock. There is one exceptions to this ordering: When dumping
46 * the clock tree through debugfs. In this case, clk_lock_all is called,
47 * which attemps to iterate through the entire list of clocks and take every
48 * clock lock. If any call to spin_trylock fails, all locked clocks are
49 * unlocked, and the process is retried. When all the locks are held,
50 * the only clock operation that can be called is clk_get_rate_all_locked.
51 *
52 * Within a single clock, no clock operation can call another clock operation
53 * on itself, except for clk_get_rate_locked and clk_set_rate_locked. Any
54 * clock operation can call any other clock operation on any of it's possible
55 * parents.
56 *
57 * An additional mutex, clock_list_lock, is used to protect the list of all
58 * clocks.
59 *
60 * The clock operations must lock internally to protect against
61 * read-modify-write on registers that are shared by multiple clocks
62 */
63static DEFINE_MUTEX(clock_list_lock);
Colin Crossd8611962010-01-28 16:40:29 -080064static LIST_HEAD(clocks);
65
Prashant Gaikwad96a1bd12012-08-06 11:57:42 +053066#ifndef CONFIG_COMMON_CLK
Colin Crossd8611962010-01-28 16:40:29 -080067struct clk *tegra_get_clock_by_name(const char *name)
68{
69 struct clk *c;
70 struct clk *ret = NULL;
Colin Cross4729fd72011-02-12 16:43:05 -080071 mutex_lock(&clock_list_lock);
Colin Crossd8611962010-01-28 16:40:29 -080072 list_for_each_entry(c, &clocks, node) {
73 if (strcmp(c->name, name) == 0) {
74 ret = c;
75 break;
76 }
77 }
Colin Cross4729fd72011-02-12 16:43:05 -080078 mutex_unlock(&clock_list_lock);
Colin Crossd8611962010-01-28 16:40:29 -080079 return ret;
80}
81
Colin Cross4729fd72011-02-12 16:43:05 -080082/* Must be called with c->spinlock held */
83static unsigned long clk_predict_rate_from_parent(struct clk *c, struct clk *p)
Colin Cross71fc84c2010-06-07 20:49:46 -070084{
85 u64 rate;
86
Colin Cross4729fd72011-02-12 16:43:05 -080087 rate = clk_get_rate(p);
Colin Cross71fc84c2010-06-07 20:49:46 -070088
89 if (c->mul != 0 && c->div != 0) {
Colin Cross4729fd72011-02-12 16:43:05 -080090 rate *= c->mul;
Colin Cross421186e2011-02-12 18:21:47 -080091 rate += c->div - 1; /* round up */
Colin Cross71fc84c2010-06-07 20:49:46 -070092 do_div(rate, c->div);
93 }
94
Colin Cross4729fd72011-02-12 16:43:05 -080095 return rate;
Colin Cross71fc84c2010-06-07 20:49:46 -070096}
97
Colin Cross4729fd72011-02-12 16:43:05 -080098/* Must be called with c->spinlock held */
99unsigned long clk_get_rate_locked(struct clk *c)
100{
101 unsigned long rate;
102
103 if (c->parent)
104 rate = clk_predict_rate_from_parent(c, c->parent);
105 else
106 rate = c->rate;
107
108 return rate;
109}
110
111unsigned long clk_get_rate(struct clk *c)
112{
113 unsigned long flags;
114 unsigned long rate;
115
116 spin_lock_irqsave(&c->spinlock, flags);
117
118 rate = clk_get_rate_locked(c);
119
120 spin_unlock_irqrestore(&c->spinlock, flags);
121
122 return rate;
123}
124EXPORT_SYMBOL(clk_get_rate);
125
Colin Crossd8611962010-01-28 16:40:29 -0800126int clk_reparent(struct clk *c, struct clk *parent)
127{
Colin Crossd8611962010-01-28 16:40:29 -0800128 c->parent = parent;
Colin Crossd8611962010-01-28 16:40:29 -0800129 return 0;
130}
131
Colin Crossd8611962010-01-28 16:40:29 -0800132void clk_init(struct clk *c)
133{
Colin Cross4729fd72011-02-12 16:43:05 -0800134 spin_lock_init(&c->spinlock);
Colin Crossd8611962010-01-28 16:40:29 -0800135
136 if (c->ops && c->ops->init)
137 c->ops->init(c);
138
Colin Crossf0355302010-10-13 19:16:02 -0700139 if (!c->ops || !c->ops->enable) {
140 c->refcnt++;
Colin Cross4db4afb2011-02-20 23:35:07 -0800141 c->set = true;
Colin Crossf0355302010-10-13 19:16:02 -0700142 if (c->parent)
143 c->state = c->parent->state;
144 else
145 c->state = ON;
146 }
147
Colin Cross4729fd72011-02-12 16:43:05 -0800148 mutex_lock(&clock_list_lock);
Colin Crossd8611962010-01-28 16:40:29 -0800149 list_add(&c->node, &clocks);
Colin Cross4729fd72011-02-12 16:43:05 -0800150 mutex_unlock(&clock_list_lock);
Colin Crossd8611962010-01-28 16:40:29 -0800151}
152
Colin Cross4729fd72011-02-12 16:43:05 -0800153int clk_enable(struct clk *c)
Colin Crossd8611962010-01-28 16:40:29 -0800154{
Colin Cross4729fd72011-02-12 16:43:05 -0800155 int ret = 0;
156 unsigned long flags;
157
158 spin_lock_irqsave(&c->spinlock, flags);
Colin Crossbd41ef52010-09-08 20:01:04 -0700159
Colin Crossd8611962010-01-28 16:40:29 -0800160 if (c->refcnt == 0) {
161 if (c->parent) {
Colin Cross4729fd72011-02-12 16:43:05 -0800162 ret = clk_enable(c->parent);
Colin Crossd8611962010-01-28 16:40:29 -0800163 if (ret)
Colin Cross4729fd72011-02-12 16:43:05 -0800164 goto out;
Colin Crossd8611962010-01-28 16:40:29 -0800165 }
166
167 if (c->ops && c->ops->enable) {
168 ret = c->ops->enable(c);
169 if (ret) {
170 if (c->parent)
Colin Cross4729fd72011-02-12 16:43:05 -0800171 clk_disable(c->parent);
172 goto out;
Colin Crossd8611962010-01-28 16:40:29 -0800173 }
174 c->state = ON;
Colin Cross4db4afb2011-02-20 23:35:07 -0800175 c->set = true;
Colin Crossd8611962010-01-28 16:40:29 -0800176 }
177 }
178 c->refcnt++;
Colin Cross4729fd72011-02-12 16:43:05 -0800179out:
180 spin_unlock_irqrestore(&c->spinlock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800181 return ret;
182}
183EXPORT_SYMBOL(clk_enable);
184
Colin Cross4729fd72011-02-12 16:43:05 -0800185void clk_disable(struct clk *c)
Colin Crossd8611962010-01-28 16:40:29 -0800186{
Colin Cross4729fd72011-02-12 16:43:05 -0800187 unsigned long flags;
188
189 spin_lock_irqsave(&c->spinlock, flags);
190
Colin Crossd8611962010-01-28 16:40:29 -0800191 if (c->refcnt == 0) {
192 WARN(1, "Attempting to disable clock %s with refcnt 0", c->name);
Colin Cross4729fd72011-02-12 16:43:05 -0800193 spin_unlock_irqrestore(&c->spinlock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800194 return;
195 }
196 if (c->refcnt == 1) {
197 if (c->ops && c->ops->disable)
198 c->ops->disable(c);
199
200 if (c->parent)
Colin Cross4729fd72011-02-12 16:43:05 -0800201 clk_disable(c->parent);
Colin Crossd8611962010-01-28 16:40:29 -0800202
203 c->state = OFF;
204 }
205 c->refcnt--;
Colin Crossd8611962010-01-28 16:40:29 -0800206
Colin Cross4729fd72011-02-12 16:43:05 -0800207 spin_unlock_irqrestore(&c->spinlock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800208}
209EXPORT_SYMBOL(clk_disable);
210
Colin Crossd8611962010-01-28 16:40:29 -0800211int clk_set_parent(struct clk *c, struct clk *parent)
212{
213 int ret;
214 unsigned long flags;
Colin Cross4729fd72011-02-12 16:43:05 -0800215 unsigned long new_rate;
216 unsigned long old_rate;
217
218 spin_lock_irqsave(&c->spinlock, flags);
219
220 if (!c->ops || !c->ops->set_parent) {
221 ret = -ENOSYS;
222 goto out;
223 }
224
225 new_rate = clk_predict_rate_from_parent(c, parent);
226 old_rate = clk_get_rate_locked(c);
227
228 ret = c->ops->set_parent(c, parent);
229 if (ret)
230 goto out;
231
232out:
233 spin_unlock_irqrestore(&c->spinlock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800234 return ret;
235}
236EXPORT_SYMBOL(clk_set_parent);
237
238struct clk *clk_get_parent(struct clk *c)
239{
240 return c->parent;
241}
242EXPORT_SYMBOL(clk_get_parent);
243
Colin Cross71fc84c2010-06-07 20:49:46 -0700244int clk_set_rate_locked(struct clk *c, unsigned long rate)
245{
Colin Cross421186e2011-02-12 18:21:47 -0800246 long new_rate;
247
Colin Cross4729fd72011-02-12 16:43:05 -0800248 if (!c->ops || !c->ops->set_rate)
249 return -ENOSYS;
Colin Cross71fc84c2010-06-07 20:49:46 -0700250
251 if (rate > c->max_rate)
252 rate = c->max_rate;
253
Colin Cross421186e2011-02-12 18:21:47 -0800254 if (c->ops && c->ops->round_rate) {
255 new_rate = c->ops->round_rate(c, rate);
256
257 if (new_rate < 0)
258 return new_rate;
259
260 rate = new_rate;
261 }
262
Colin Cross4729fd72011-02-12 16:43:05 -0800263 return c->ops->set_rate(c, rate);
Colin Cross71fc84c2010-06-07 20:49:46 -0700264}
265
Colin Crossd8611962010-01-28 16:40:29 -0800266int clk_set_rate(struct clk *c, unsigned long rate)
267{
Colin Cross4729fd72011-02-12 16:43:05 -0800268 int ret;
Colin Crossd8611962010-01-28 16:40:29 -0800269 unsigned long flags;
270
Colin Cross4729fd72011-02-12 16:43:05 -0800271 spin_lock_irqsave(&c->spinlock, flags);
272
Colin Cross71fc84c2010-06-07 20:49:46 -0700273 ret = clk_set_rate_locked(c, rate);
Colin Cross4729fd72011-02-12 16:43:05 -0800274
275 spin_unlock_irqrestore(&c->spinlock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800276
277 return ret;
278}
279EXPORT_SYMBOL(clk_set_rate);
280
Colin Cross4729fd72011-02-12 16:43:05 -0800281
282/* Must be called with clocks lock and all indvidual clock locks held */
283unsigned long clk_get_rate_all_locked(struct clk *c)
Colin Crossd8611962010-01-28 16:40:29 -0800284{
Colin Cross4729fd72011-02-12 16:43:05 -0800285 u64 rate;
286 int mul = 1;
287 int div = 1;
288 struct clk *p = c;
Colin Crossd8611962010-01-28 16:40:29 -0800289
Colin Cross4729fd72011-02-12 16:43:05 -0800290 while (p) {
291 c = p;
292 if (c->mul != 0 && c->div != 0) {
293 mul *= c->mul;
294 div *= c->div;
295 }
296 p = c->parent;
297 }
Colin Crossd8611962010-01-28 16:40:29 -0800298
Colin Cross4729fd72011-02-12 16:43:05 -0800299 rate = c->rate;
300 rate *= mul;
301 do_div(rate, div);
Colin Crossd8611962010-01-28 16:40:29 -0800302
Colin Cross4729fd72011-02-12 16:43:05 -0800303 return rate;
Colin Crossd8611962010-01-28 16:40:29 -0800304}
Colin Crossd8611962010-01-28 16:40:29 -0800305
Colin Cross71fc84c2010-06-07 20:49:46 -0700306long clk_round_rate(struct clk *c, unsigned long rate)
307{
Colin Cross4729fd72011-02-12 16:43:05 -0800308 unsigned long flags;
309 long ret;
310
311 spin_lock_irqsave(&c->spinlock, flags);
312
313 if (!c->ops || !c->ops->round_rate) {
314 ret = -ENOSYS;
315 goto out;
316 }
Colin Cross71fc84c2010-06-07 20:49:46 -0700317
318 if (rate > c->max_rate)
319 rate = c->max_rate;
320
Colin Cross4729fd72011-02-12 16:43:05 -0800321 ret = c->ops->round_rate(c, rate);
322
323out:
324 spin_unlock_irqrestore(&c->spinlock, flags);
325 return ret;
Colin Cross71fc84c2010-06-07 20:49:46 -0700326}
327EXPORT_SYMBOL(clk_round_rate);
328
Colin Crossd8611962010-01-28 16:40:29 -0800329static int tegra_clk_init_one_from_table(struct tegra_clk_init_table *table)
330{
331 struct clk *c;
332 struct clk *p;
333
334 int ret = 0;
335
336 c = tegra_get_clock_by_name(table->name);
337
338 if (!c) {
339 pr_warning("Unable to initialize clock %s\n",
340 table->name);
341 return -ENODEV;
342 }
343
344 if (table->parent) {
345 p = tegra_get_clock_by_name(table->parent);
346 if (!p) {
347 pr_warning("Unable to find parent %s of clock %s\n",
348 table->parent, table->name);
349 return -ENODEV;
350 }
351
352 if (c->parent != p) {
353 ret = clk_set_parent(c, p);
354 if (ret) {
355 pr_warning("Unable to set parent %s of clock %s: %d\n",
356 table->parent, table->name, ret);
357 return -EINVAL;
358 }
359 }
360 }
361
362 if (table->rate && table->rate != clk_get_rate(c)) {
363 ret = clk_set_rate(c, table->rate);
364 if (ret) {
365 pr_warning("Unable to set clock %s to rate %lu: %d\n",
366 table->name, table->rate, ret);
367 return -EINVAL;
368 }
369 }
370
371 if (table->enabled) {
372 ret = clk_enable(c);
373 if (ret) {
374 pr_warning("Unable to enable clock %s: %d\n",
375 table->name, ret);
376 return -EINVAL;
377 }
378 }
379
380 return 0;
381}
382
383void tegra_clk_init_from_table(struct tegra_clk_init_table *table)
384{
385 for (; table->name; table++)
386 tegra_clk_init_one_from_table(table);
387}
388EXPORT_SYMBOL(tegra_clk_init_from_table);
389
390void tegra_periph_reset_deassert(struct clk *c)
391{
Peter De Schrijver742face2011-12-14 17:03:15 +0200392 BUG_ON(!c->ops->reset);
393 c->ops->reset(c, false);
Colin Crossd8611962010-01-28 16:40:29 -0800394}
395EXPORT_SYMBOL(tegra_periph_reset_deassert);
396
397void tegra_periph_reset_assert(struct clk *c)
398{
Peter De Schrijver742face2011-12-14 17:03:15 +0200399 BUG_ON(!c->ops->reset);
400 c->ops->reset(c, true);
Colin Crossd8611962010-01-28 16:40:29 -0800401}
402EXPORT_SYMBOL(tegra_periph_reset_assert);
403
Peter De Schrijver4fccf752012-01-09 05:35:11 +0000404/* Several extended clock configuration bits (e.g., clock routing, clock
405 * phase control) are included in PLL and peripheral clock source
406 * registers. */
407int tegra_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
408{
409 int ret = 0;
410 unsigned long flags;
411
412 spin_lock_irqsave(&c->spinlock, flags);
413
414 if (!c->ops || !c->ops->clk_cfg_ex) {
415 ret = -ENOSYS;
416 goto out;
417 }
418 ret = c->ops->clk_cfg_ex(c, p, setting);
419
420out:
421 spin_unlock_irqrestore(&c->spinlock, flags);
422
423 return ret;
424}
425
Colin Crossd8611962010-01-28 16:40:29 -0800426#ifdef CONFIG_DEBUG_FS
Colin Cross4729fd72011-02-12 16:43:05 -0800427
428static int __clk_lock_all_spinlocks(void)
429{
430 struct clk *c;
431
432 list_for_each_entry(c, &clocks, node)
433 if (!spin_trylock(&c->spinlock))
434 goto unlock_spinlocks;
435
436 return 0;
437
438unlock_spinlocks:
439 list_for_each_entry_continue_reverse(c, &clocks, node)
440 spin_unlock(&c->spinlock);
441
442 return -EAGAIN;
443}
444
445static void __clk_unlock_all_spinlocks(void)
446{
447 struct clk *c;
448
449 list_for_each_entry_reverse(c, &clocks, node)
450 spin_unlock(&c->spinlock);
451}
452
453/*
454 * This function retries until it can take all locks, and may take
455 * an arbitrarily long time to complete.
456 * Must be called with irqs enabled, returns with irqs disabled
457 * Must be called with clock_list_lock held
458 */
459static void clk_lock_all(void)
460{
461 int ret;
462retry:
463 local_irq_disable();
464
465 ret = __clk_lock_all_spinlocks();
466 if (ret)
467 goto failed_spinlocks;
468
469 /* All locks taken successfully, return */
470 return;
471
472failed_spinlocks:
473 local_irq_enable();
474 yield();
475 goto retry;
476}
477
478/*
479 * Unlocks all clocks after a clk_lock_all
480 * Must be called with irqs disabled, returns with irqs enabled
481 * Must be called with clock_list_lock held
482 */
483static void clk_unlock_all(void)
484{
485 __clk_unlock_all_spinlocks();
486
487 local_irq_enable();
488}
489
Colin Crossd8611962010-01-28 16:40:29 -0800490static struct dentry *clk_debugfs_root;
491
492
493static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level)
494{
495 struct clk *child;
Colin Crossd8611962010-01-28 16:40:29 -0800496 const char *state = "uninit";
Colin Cross71fc84c2010-06-07 20:49:46 -0700497 char div[8] = {0};
Colin Crossd8611962010-01-28 16:40:29 -0800498
499 if (c->state == ON)
500 state = "on";
501 else if (c->state == OFF)
502 state = "off";
503
504 if (c->mul != 0 && c->div != 0) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700505 if (c->mul > c->div) {
506 int mul = c->mul / c->div;
507 int mul2 = (c->mul * 10 / c->div) % 10;
508 int mul3 = (c->mul * 10) % c->div;
509 if (mul2 == 0 && mul3 == 0)
510 snprintf(div, sizeof(div), "x%d", mul);
511 else if (mul3 == 0)
512 snprintf(div, sizeof(div), "x%d.%d", mul, mul2);
513 else
514 snprintf(div, sizeof(div), "x%d.%d..", mul, mul2);
515 } else {
Colin Crossd8611962010-01-28 16:40:29 -0800516 snprintf(div, sizeof(div), "%d%s", c->div / c->mul,
517 (c->div % c->mul) ? ".5" : "");
Colin Cross71fc84c2010-06-07 20:49:46 -0700518 }
Colin Crossd8611962010-01-28 16:40:29 -0800519 }
520
Colin Cross71fc84c2010-06-07 20:49:46 -0700521 seq_printf(s, "%*s%c%c%-*s %-6s %-3d %-8s %-10lu\n",
522 level * 3 + 1, "",
523 c->rate > c->max_rate ? '!' : ' ',
524 !c->set ? '*' : ' ',
Colin Crossd8611962010-01-28 16:40:29 -0800525 30 - level * 3, c->name,
Colin Cross4729fd72011-02-12 16:43:05 -0800526 state, c->refcnt, div, clk_get_rate_all_locked(c));
527
528 list_for_each_entry(child, &clocks, node) {
529 if (child->parent != c)
530 continue;
531
Colin Crossd8611962010-01-28 16:40:29 -0800532 clock_tree_show_one(s, child, level + 1);
533 }
534}
535
536static int clock_tree_show(struct seq_file *s, void *data)
537{
538 struct clk *c;
Colin Cross71fc84c2010-06-07 20:49:46 -0700539 seq_printf(s, " clock state ref div rate\n");
540 seq_printf(s, "--------------------------------------------------------------\n");
Colin Cross4729fd72011-02-12 16:43:05 -0800541
542 mutex_lock(&clock_list_lock);
543
544 clk_lock_all();
545
Colin Crossd8611962010-01-28 16:40:29 -0800546 list_for_each_entry(c, &clocks, node)
547 if (c->parent == NULL)
548 clock_tree_show_one(s, c, 0);
Colin Cross4729fd72011-02-12 16:43:05 -0800549
550 clk_unlock_all();
551
552 mutex_unlock(&clock_list_lock);
Colin Crossd8611962010-01-28 16:40:29 -0800553 return 0;
554}
555
556static int clock_tree_open(struct inode *inode, struct file *file)
557{
558 return single_open(file, clock_tree_show, inode->i_private);
559}
560
561static const struct file_operations clock_tree_fops = {
562 .open = clock_tree_open,
563 .read = seq_read,
564 .llseek = seq_lseek,
565 .release = single_release,
566};
567
568static int possible_parents_show(struct seq_file *s, void *data)
569{
570 struct clk *c = s->private;
571 int i;
572
573 for (i = 0; c->inputs[i].input; i++) {
574 char *first = (i == 0) ? "" : " ";
575 seq_printf(s, "%s%s", first, c->inputs[i].input->name);
576 }
577 seq_printf(s, "\n");
578 return 0;
579}
580
581static int possible_parents_open(struct inode *inode, struct file *file)
582{
583 return single_open(file, possible_parents_show, inode->i_private);
584}
585
586static const struct file_operations possible_parents_fops = {
587 .open = possible_parents_open,
588 .read = seq_read,
589 .llseek = seq_lseek,
590 .release = single_release,
591};
592
593static int clk_debugfs_register_one(struct clk *c)
594{
Al Viro12520c42011-07-16 12:37:57 -0400595 struct dentry *d;
Colin Crossd8611962010-01-28 16:40:29 -0800596
597 d = debugfs_create_dir(c->name, clk_debugfs_root);
598 if (!d)
599 return -ENOMEM;
600 c->dent = d;
601
602 d = debugfs_create_u8("refcnt", S_IRUGO, c->dent, (u8 *)&c->refcnt);
603 if (!d)
604 goto err_out;
605
606 d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
607 if (!d)
608 goto err_out;
609
610 d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
611 if (!d)
612 goto err_out;
613
614 if (c->inputs) {
615 d = debugfs_create_file("possible_parents", S_IRUGO, c->dent,
616 c, &possible_parents_fops);
617 if (!d)
618 goto err_out;
619 }
620
621 return 0;
622
623err_out:
Al Viro12520c42011-07-16 12:37:57 -0400624 debugfs_remove_recursive(c->dent);
Colin Crossd8611962010-01-28 16:40:29 -0800625 return -ENOMEM;
626}
627
628static int clk_debugfs_register(struct clk *c)
629{
630 int err;
631 struct clk *pa = c->parent;
632
633 if (pa && !pa->dent) {
634 err = clk_debugfs_register(pa);
635 if (err)
636 return err;
637 }
638
639 if (!c->dent) {
640 err = clk_debugfs_register_one(c);
641 if (err)
642 return err;
643 }
644 return 0;
645}
646
Shawn Guo390e0cf2012-05-02 17:08:06 +0800647int __init tegra_clk_debugfs_init(void)
Colin Crossd8611962010-01-28 16:40:29 -0800648{
649 struct clk *c;
650 struct dentry *d;
651 int err = -ENOMEM;
652
653 d = debugfs_create_dir("clock", NULL);
654 if (!d)
655 return -ENOMEM;
656 clk_debugfs_root = d;
657
658 d = debugfs_create_file("clock_tree", S_IRUGO, clk_debugfs_root, NULL,
659 &clock_tree_fops);
660 if (!d)
661 goto err_out;
662
663 list_for_each_entry(c, &clocks, node) {
664 err = clk_debugfs_register(c);
665 if (err)
666 goto err_out;
667 }
668 return 0;
669err_out:
670 debugfs_remove_recursive(clk_debugfs_root);
671 return err;
672}
Colin Crossd8611962010-01-28 16:40:29 -0800673#endif
Prashant Gaikwad96a1bd12012-08-06 11:57:42 +0530674#else
675
676void tegra_clk_add(struct clk *clk)
677{
678 struct clk_tegra *c = to_clk_tegra(__clk_get_hw(clk));
679
680 mutex_lock(&clock_list_lock);
681 list_add(&c->node, &clocks);
682 mutex_unlock(&clock_list_lock);
683}
684
685struct clk *tegra_get_clock_by_name(const char *name)
686{
687 struct clk_tegra *c;
688 struct clk *ret = NULL;
689 mutex_lock(&clock_list_lock);
690 list_for_each_entry(c, &clocks, node) {
691 if (strcmp(__clk_get_name(c->hw.clk), name) == 0) {
692 ret = c->hw.clk;
693 break;
694 }
695 }
696 mutex_unlock(&clock_list_lock);
697 return ret;
698}
699
700static int tegra_clk_init_one_from_table(struct tegra_clk_init_table *table)
701{
702 struct clk *c;
703 struct clk *p;
704 struct clk *parent;
705
706 int ret = 0;
707
708 c = tegra_get_clock_by_name(table->name);
709
710 if (!c) {
711 pr_warn("Unable to initialize clock %s\n",
712 table->name);
713 return -ENODEV;
714 }
715
716 parent = clk_get_parent(c);
717
718 if (table->parent) {
719 p = tegra_get_clock_by_name(table->parent);
720 if (!p) {
721 pr_warn("Unable to find parent %s of clock %s\n",
722 table->parent, table->name);
723 return -ENODEV;
724 }
725
726 if (parent != p) {
727 ret = clk_set_parent(c, p);
728 if (ret) {
729 pr_warn("Unable to set parent %s of clock %s: %d\n",
730 table->parent, table->name, ret);
731 return -EINVAL;
732 }
733 }
734 }
735
736 if (table->rate && table->rate != clk_get_rate(c)) {
737 ret = clk_set_rate(c, table->rate);
738 if (ret) {
739 pr_warn("Unable to set clock %s to rate %lu: %d\n",
740 table->name, table->rate, ret);
741 return -EINVAL;
742 }
743 }
744
745 if (table->enabled) {
746 ret = clk_prepare_enable(c);
747 if (ret) {
748 pr_warn("Unable to enable clock %s: %d\n",
749 table->name, ret);
750 return -EINVAL;
751 }
752 }
753
754 return 0;
755}
756
757void tegra_clk_init_from_table(struct tegra_clk_init_table *table)
758{
759 for (; table->name; table++)
760 tegra_clk_init_one_from_table(table);
761}
762
763void tegra_periph_reset_deassert(struct clk *c)
764{
765 struct clk_tegra *clk = to_clk_tegra(__clk_get_hw(c));
766 BUG_ON(!clk->reset);
767 clk->reset(__clk_get_hw(c), false);
768}
769EXPORT_SYMBOL(tegra_periph_reset_deassert);
770
771void tegra_periph_reset_assert(struct clk *c)
772{
773 struct clk_tegra *clk = to_clk_tegra(__clk_get_hw(c));
774 BUG_ON(!clk->reset);
775 clk->reset(__clk_get_hw(c), true);
776}
777EXPORT_SYMBOL(tegra_periph_reset_assert);
778
779/* Several extended clock configuration bits (e.g., clock routing, clock
780 * phase control) are included in PLL and peripheral clock source
781 * registers. */
782int tegra_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
783{
784 int ret = 0;
785 struct clk_tegra *clk = to_clk_tegra(__clk_get_hw(c));
786
787 if (!clk->clk_cfg_ex) {
788 ret = -ENOSYS;
789 goto out;
790 }
791 ret = clk->clk_cfg_ex(__clk_get_hw(c), p, setting);
792
793out:
794 return ret;
795}
796#endif /* !CONFIG_COMMON_CLK */