Lines Matching +full:clock +full:- +full:div
34 #include "clock.h"
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
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,
47 * clock lock. If any call to spin_trylock fails, all locked clocks are
49 * the only clock operation that can be called is clk_get_rate_all_locked.
51 * Within a single clock, no clock operation can call another clock operation
53 * clock operation can call any other clock operation on any of it's possible
59 * The clock operations must lock internally to protect against
60 * read-modify-write on registers that are shared by multiple clocks
71 if (strcmp(c->name, name) == 0) { in tegra_get_clock_by_name()
80 /* Must be called with c->spinlock held */
87 if (c->mul != 0 && c->div != 0) { in clk_predict_rate_from_parent()
88 rate *= c->mul; in clk_predict_rate_from_parent()
89 rate += c->div - 1; /* round up */ in clk_predict_rate_from_parent()
90 do_div(rate, c->div); in clk_predict_rate_from_parent()
96 /* Must be called with c->spinlock held */
101 if (c->parent) in clk_get_rate_locked()
102 rate = clk_predict_rate_from_parent(c, c->parent); in clk_get_rate_locked()
104 rate = c->rate; in clk_get_rate_locked()
114 spin_lock_irqsave(&c->spinlock, flags); in clk_get_rate()
118 spin_unlock_irqrestore(&c->spinlock, flags); in clk_get_rate()
126 c->parent = parent; in clk_reparent()
132 spin_lock_init(&c->spinlock); in clk_init()
134 if (c->ops && c->ops->init) in clk_init()
135 c->ops->init(c); in clk_init()
137 if (!c->ops || !c->ops->enable) { in clk_init()
138 c->refcnt++; in clk_init()
139 c->set = true; in clk_init()
140 if (c->parent) in clk_init()
141 c->state = c->parent->state; in clk_init()
143 c->state = ON; in clk_init()
147 list_add(&c->node, &clocks); in clk_init()
156 spin_lock_irqsave(&c->spinlock, flags); in clk_enable()
158 if (c->refcnt == 0) { in clk_enable()
159 if (c->parent) { in clk_enable()
160 ret = clk_enable(c->parent); in clk_enable()
165 if (c->ops && c->ops->enable) { in clk_enable()
166 ret = c->ops->enable(c); in clk_enable()
168 if (c->parent) in clk_enable()
169 clk_disable(c->parent); in clk_enable()
172 c->state = ON; in clk_enable()
173 c->set = true; in clk_enable()
176 c->refcnt++; in clk_enable()
178 spin_unlock_irqrestore(&c->spinlock, flags); in clk_enable()
187 spin_lock_irqsave(&c->spinlock, flags); in clk_disable()
189 if (c->refcnt == 0) { in clk_disable()
190 WARN(1, "Attempting to disable clock %s with refcnt 0", c->name); in clk_disable()
191 spin_unlock_irqrestore(&c->spinlock, flags); in clk_disable()
194 if (c->refcnt == 1) { in clk_disable()
195 if (c->ops && c->ops->disable) in clk_disable()
196 c->ops->disable(c); in clk_disable()
198 if (c->parent) in clk_disable()
199 clk_disable(c->parent); in clk_disable()
201 c->state = OFF; in clk_disable()
203 c->refcnt--; in clk_disable()
205 spin_unlock_irqrestore(&c->spinlock, flags); in clk_disable()
216 spin_lock_irqsave(&c->spinlock, flags); in clk_set_parent()
218 if (!c->ops || !c->ops->set_parent) { in clk_set_parent()
219 ret = -ENOSYS; in clk_set_parent()
226 ret = c->ops->set_parent(c, parent); in clk_set_parent()
231 spin_unlock_irqrestore(&c->spinlock, flags); in clk_set_parent()
238 return c->parent; in clk_get_parent()
246 if (!c->ops || !c->ops->set_rate) in clk_set_rate_locked()
247 return -ENOSYS; in clk_set_rate_locked()
249 if (rate > c->max_rate) in clk_set_rate_locked()
250 rate = c->max_rate; in clk_set_rate_locked()
252 if (c->ops && c->ops->round_rate) { in clk_set_rate_locked()
253 new_rate = c->ops->round_rate(c, rate); in clk_set_rate_locked()
261 return c->ops->set_rate(c, rate); in clk_set_rate_locked()
269 spin_lock_irqsave(&c->spinlock, flags); in clk_set_rate()
273 spin_unlock_irqrestore(&c->spinlock, flags); in clk_set_rate()
280 /* Must be called with clocks lock and all indvidual clock locks held */
285 int div = 1; in clk_get_rate_all_locked() local
290 if (c->mul != 0 && c->div != 0) { in clk_get_rate_all_locked()
291 mul *= c->mul; in clk_get_rate_all_locked()
292 div *= c->div; in clk_get_rate_all_locked()
294 p = c->parent; in clk_get_rate_all_locked()
297 rate = c->rate; in clk_get_rate_all_locked()
299 do_div(rate, div); in clk_get_rate_all_locked()
309 spin_lock_irqsave(&c->spinlock, flags); in clk_round_rate()
311 if (!c->ops || !c->ops->round_rate) { in clk_round_rate()
312 ret = -ENOSYS; in clk_round_rate()
316 if (rate > c->max_rate) in clk_round_rate()
317 rate = c->max_rate; in clk_round_rate()
319 ret = c->ops->round_rate(c, rate); in clk_round_rate()
322 spin_unlock_irqrestore(&c->spinlock, flags); in clk_round_rate()
334 c = tegra_get_clock_by_name(table->name); in tegra_clk_init_one_from_table()
337 pr_warning("Unable to initialize clock %s\n", in tegra_clk_init_one_from_table()
338 table->name); in tegra_clk_init_one_from_table()
339 return -ENODEV; in tegra_clk_init_one_from_table()
342 if (table->parent) { in tegra_clk_init_one_from_table()
343 p = tegra_get_clock_by_name(table->parent); in tegra_clk_init_one_from_table()
345 pr_warning("Unable to find parent %s of clock %s\n", in tegra_clk_init_one_from_table()
346 table->parent, table->name); in tegra_clk_init_one_from_table()
347 return -ENODEV; in tegra_clk_init_one_from_table()
350 if (c->parent != p) { in tegra_clk_init_one_from_table()
353 pr_warning("Unable to set parent %s of clock %s: %d\n", in tegra_clk_init_one_from_table()
354 table->parent, table->name, ret); in tegra_clk_init_one_from_table()
355 return -EINVAL; in tegra_clk_init_one_from_table()
360 if (table->rate && table->rate != clk_get_rate(c)) { in tegra_clk_init_one_from_table()
361 ret = clk_set_rate(c, table->rate); in tegra_clk_init_one_from_table()
363 pr_warning("Unable to set clock %s to rate %lu: %d\n", in tegra_clk_init_one_from_table()
364 table->name, table->rate, ret); in tegra_clk_init_one_from_table()
365 return -EINVAL; in tegra_clk_init_one_from_table()
369 if (table->enabled) { in tegra_clk_init_one_from_table()
372 pr_warning("Unable to enable clock %s: %d\n", in tegra_clk_init_one_from_table()
373 table->name, ret); in tegra_clk_init_one_from_table()
374 return -EINVAL; in tegra_clk_init_one_from_table()
383 for (; table->name; table++) in tegra_clk_init_from_table()
390 BUG_ON(!c->ops->reset); in tegra_periph_reset_deassert()
391 c->ops->reset(c, false); in tegra_periph_reset_deassert()
397 BUG_ON(!c->ops->reset); in tegra_periph_reset_assert()
398 c->ops->reset(c, true); in tegra_periph_reset_assert()
409 if (!spin_trylock(&c->spinlock)) in __clk_lock_all_spinlocks()
416 spin_unlock(&c->spinlock); in __clk_lock_all_spinlocks()
418 return -EAGAIN; in __clk_lock_all_spinlocks()
426 spin_unlock(&c->spinlock); in __clk_unlock_all_spinlocks()
473 char div[8] = {0}; in clock_tree_show_one() local
475 if (c->state == ON) in clock_tree_show_one()
477 else if (c->state == OFF) in clock_tree_show_one()
480 if (c->mul != 0 && c->div != 0) { in clock_tree_show_one()
481 if (c->mul > c->div) { in clock_tree_show_one()
482 int mul = c->mul / c->div; in clock_tree_show_one()
483 int mul2 = (c->mul * 10 / c->div) % 10; in clock_tree_show_one()
484 int mul3 = (c->mul * 10) % c->div; in clock_tree_show_one()
486 snprintf(div, sizeof(div), "x%d", mul); in clock_tree_show_one()
488 snprintf(div, sizeof(div), "x%d.%d", mul, mul2); in clock_tree_show_one()
490 snprintf(div, sizeof(div), "x%d.%d..", mul, mul2); in clock_tree_show_one()
492 snprintf(div, sizeof(div), "%d%s", c->div / c->mul, in clock_tree_show_one()
493 (c->div % c->mul) ? ".5" : ""); in clock_tree_show_one()
497 seq_printf(s, "%*s%c%c%-*s %-6s %-3d %-8s %-10lu\n", in clock_tree_show_one()
499 c->rate > c->max_rate ? '!' : ' ', in clock_tree_show_one()
500 !c->set ? '*' : ' ', in clock_tree_show_one()
501 30 - level * 3, c->name, in clock_tree_show_one()
502 state, c->refcnt, div, clk_get_rate_all_locked(c)); in clock_tree_show_one()
505 if (child->parent != c) in clock_tree_show_one()
515 seq_printf(s, " clock state ref div rate\n"); in clock_tree_show()
516 seq_printf(s, "--------------------------------------------------------------\n"); in clock_tree_show()
523 if (c->parent == NULL) in clock_tree_show()
534 return single_open(file, clock_tree_show, inode->i_private); in clock_tree_open()
546 struct clk *c = s->private; in possible_parents_show()
549 for (i = 0; c->inputs[i].input; i++) { in possible_parents_show()
551 seq_printf(s, "%s%s", first, c->inputs[i].input->name); in possible_parents_show()
559 return single_open(file, possible_parents_show, inode->i_private); in possible_parents_open()
573 d = debugfs_create_dir(c->name, clk_debugfs_root); in clk_debugfs_register_one()
575 return -ENOMEM; in clk_debugfs_register_one()
576 c->dent = d; in clk_debugfs_register_one()
578 d = debugfs_create_u8("refcnt", S_IRUGO, c->dent, (u8 *)&c->refcnt); in clk_debugfs_register_one()
582 d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate); in clk_debugfs_register_one()
586 d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags); in clk_debugfs_register_one()
590 if (c->inputs) { in clk_debugfs_register_one()
591 d = debugfs_create_file("possible_parents", S_IRUGO, c->dent, in clk_debugfs_register_one()
600 debugfs_remove_recursive(c->dent); in clk_debugfs_register_one()
601 return -ENOMEM; in clk_debugfs_register_one()
607 struct clk *pa = c->parent; in clk_debugfs_register()
609 if (pa && !pa->dent) { in clk_debugfs_register()
615 if (!c->dent) { in clk_debugfs_register()
627 int err = -ENOMEM; in clk_debugfs_init()
629 d = debugfs_create_dir("clock", NULL); in clk_debugfs_init()
631 return -ENOMEM; in clk_debugfs_init()