aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBoris BREZILLON <b.brezillon@overkiz.com>2013-12-21 04:34:47 -0500
committerMike Turquette <mturquette@linaro.org>2013-12-23 02:14:27 -0500
commit5279fc402ae59361a224d641d5823b21b4206232 (patch)
tree0d6ab9695d994cedc85c32b08f6e8d211acf4207 /drivers
parente8ab2f11bb8fa73280ce7d0fca3c22be456437df (diff)
clk: add clk accuracy retrieval support
The clock accuracy is expressed in ppb (parts per billion) and represents the possible clock drift. Say you have a clock (e.g. an oscillator) which provides a fixed clock of 20MHz with an accuracy of +- 20Hz. This accuracy expressed in ppb is 20Hz/20MHz = 1000 ppb (or 1 ppm). Clock users may need the clock accuracy information in order to choose the best clock (the one with the best accuracy) across several available clocks. This patch adds clk accuracy retrieval support for common clk framework by means of a new function called clk_get_accuracy. This function returns the given clock accuracy expressed in ppb. In order to get the clock accuracy, this implementation adds one callback called recalc_accuracy to the clk_ops structure. This callback is given the parent clock accuracy (if the clock is not a root clock) and should recalculate the given clock accuracy. This callback is optional and may be implemented if the clock is not a perfect clock (accuracy != 0 ppb). Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com> Signed-off-by: Mike Turquette <mturquette@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clk/clk.c100
1 files changed, 93 insertions, 7 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 83127363ad4c..fbe08f618d59 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -104,10 +104,11 @@ static void clk_summary_show_one(struct seq_file *s, struct clk *c, int level)
104 if (!c) 104 if (!c)
105 return; 105 return;
106 106
107 seq_printf(s, "%*s%-*s %-11d %-12d %-10lu", 107 seq_printf(s, "%*s%-*s %-11d %-12d %-10lu %-11lu",
108 level * 3 + 1, "", 108 level * 3 + 1, "",
109 30 - level * 3, c->name, 109 30 - level * 3, c->name,
110 c->enable_count, c->prepare_count, clk_get_rate(c)); 110 c->enable_count, c->prepare_count, clk_get_rate(c),
111 clk_get_accuracy(c));
111 seq_printf(s, "\n"); 112 seq_printf(s, "\n");
112} 113}
113 114
@@ -129,8 +130,8 @@ static int clk_summary_show(struct seq_file *s, void *data)
129{ 130{
130 struct clk *c; 131 struct clk *c;
131 132
132 seq_printf(s, " clock enable_cnt prepare_cnt rate\n"); 133 seq_printf(s, " clock enable_cnt prepare_cnt rate accuracy\n");
133 seq_printf(s, "---------------------------------------------------------------------\n"); 134 seq_printf(s, "---------------------------------------------------------------------------------\n");
134 135
135 clk_prepare_lock(); 136 clk_prepare_lock();
136 137
@@ -167,6 +168,7 @@ static void clk_dump_one(struct seq_file *s, struct clk *c, int level)
167 seq_printf(s, "\"enable_count\": %d,", c->enable_count); 168 seq_printf(s, "\"enable_count\": %d,", c->enable_count);
168 seq_printf(s, "\"prepare_count\": %d,", c->prepare_count); 169 seq_printf(s, "\"prepare_count\": %d,", c->prepare_count);
169 seq_printf(s, "\"rate\": %lu", clk_get_rate(c)); 170 seq_printf(s, "\"rate\": %lu", clk_get_rate(c));
171 seq_printf(s, "\"accuracy\": %lu", clk_get_accuracy(c));
170} 172}
171 173
172static void clk_dump_subtree(struct seq_file *s, struct clk *c, int level) 174static void clk_dump_subtree(struct seq_file *s, struct clk *c, int level)
@@ -248,6 +250,11 @@ static int clk_debug_create_one(struct clk *clk, struct dentry *pdentry)
248 if (!d) 250 if (!d)
249 goto err_out; 251 goto err_out;
250 252
253 d = debugfs_create_u32("clk_accuracy", S_IRUGO, clk->dentry,
254 (u32 *)&clk->accuracy);
255 if (!d)
256 goto err_out;
257
251 d = debugfs_create_x32("clk_flags", S_IRUGO, clk->dentry, 258 d = debugfs_create_x32("clk_flags", S_IRUGO, clk->dentry,
252 (u32 *)&clk->flags); 259 (u32 *)&clk->flags);
253 if (!d) 260 if (!d)
@@ -603,6 +610,14 @@ out:
603 return ret; 610 return ret;
604} 611}
605 612
613unsigned long __clk_get_accuracy(struct clk *clk)
614{
615 if (!clk)
616 return 0;
617
618 return clk->accuracy;
619}
620
606unsigned long __clk_get_flags(struct clk *clk) 621unsigned long __clk_get_flags(struct clk *clk)
607{ 622{
608 return !clk ? 0 : clk->flags; 623 return !clk ? 0 : clk->flags;
@@ -1017,6 +1032,59 @@ static int __clk_notify(struct clk *clk, unsigned long msg,
1017} 1032}
1018 1033
1019/** 1034/**
1035 * __clk_recalc_accuracies
1036 * @clk: first clk in the subtree
1037 *
1038 * Walks the subtree of clks starting with clk and recalculates accuracies as
1039 * it goes. Note that if a clk does not implement the .recalc_accuracy
1040 * callback then it is assumed that the clock will take on the accuracy of it's
1041 * parent.
1042 *
1043 * Caller must hold prepare_lock.
1044 */
1045static void __clk_recalc_accuracies(struct clk *clk)
1046{
1047 unsigned long parent_accuracy = 0;
1048 struct clk *child;
1049
1050 if (clk->parent)
1051 parent_accuracy = clk->parent->accuracy;
1052
1053 if (clk->ops->recalc_accuracy)
1054 clk->accuracy = clk->ops->recalc_accuracy(clk->hw,
1055 parent_accuracy);
1056 else
1057 clk->accuracy = parent_accuracy;
1058
1059 hlist_for_each_entry(child, &clk->children, child_node)
1060 __clk_recalc_accuracies(child);
1061}
1062
1063/**
1064 * clk_get_accuracy - return the accuracy of clk
1065 * @clk: the clk whose accuracy is being returned
1066 *
1067 * Simply returns the cached accuracy of the clk, unless
1068 * CLK_GET_ACCURACY_NOCACHE flag is set, which means a recalc_rate will be
1069 * issued.
1070 * If clk is NULL then returns 0.
1071 */
1072long clk_get_accuracy(struct clk *clk)
1073{
1074 unsigned long accuracy;
1075
1076 clk_prepare_lock();
1077 if (clk && (clk->flags & CLK_GET_ACCURACY_NOCACHE))
1078 __clk_recalc_accuracies(clk);
1079
1080 accuracy = __clk_get_accuracy(clk);
1081 clk_prepare_unlock();
1082
1083 return accuracy;
1084}
1085EXPORT_SYMBOL_GPL(clk_get_accuracy);
1086
1087/**
1020 * __clk_recalc_rates 1088 * __clk_recalc_rates
1021 * @clk: first clk in the subtree 1089 * @clk: first clk in the subtree
1022 * @msg: notification type (see include/linux/clk.h) 1090 * @msg: notification type (see include/linux/clk.h)
@@ -1552,6 +1620,7 @@ void __clk_reparent(struct clk *clk, struct clk *new_parent)
1552{ 1620{
1553 clk_reparent(clk, new_parent); 1621 clk_reparent(clk, new_parent);
1554 clk_debug_reparent(clk, new_parent); 1622 clk_debug_reparent(clk, new_parent);
1623 __clk_recalc_accuracies(clk);
1555 __clk_recalc_rates(clk, POST_RATE_CHANGE); 1624 __clk_recalc_rates(clk, POST_RATE_CHANGE);
1556} 1625}
1557 1626
@@ -1622,11 +1691,13 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
1622 /* do the re-parent */ 1691 /* do the re-parent */
1623 ret = __clk_set_parent(clk, parent, p_index); 1692 ret = __clk_set_parent(clk, parent, p_index);
1624 1693
1625 /* propagate rate recalculation accordingly */ 1694 /* propagate rate an accuracy recalculation accordingly */
1626 if (ret) 1695 if (ret) {
1627 __clk_recalc_rates(clk, ABORT_RATE_CHANGE); 1696 __clk_recalc_rates(clk, ABORT_RATE_CHANGE);
1628 else 1697 } else {
1629 __clk_recalc_rates(clk, POST_RATE_CHANGE); 1698 __clk_recalc_rates(clk, POST_RATE_CHANGE);
1699 __clk_recalc_accuracies(clk);
1700 }
1630 1701
1631out: 1702out:
1632 clk_prepare_unlock(); 1703 clk_prepare_unlock();
@@ -1731,6 +1802,21 @@ int __clk_init(struct device *dev, struct clk *clk)
1731 hlist_add_head(&clk->child_node, &clk_orphan_list); 1802 hlist_add_head(&clk->child_node, &clk_orphan_list);
1732 1803
1733 /* 1804 /*
1805 * Set clk's accuracy. The preferred method is to use
1806 * .recalc_accuracy. For simple clocks and lazy developers the default
1807 * fallback is to use the parent's accuracy. If a clock doesn't have a
1808 * parent (or is orphaned) then accuracy is set to zero (perfect
1809 * clock).
1810 */
1811 if (clk->ops->recalc_accuracy)
1812 clk->accuracy = clk->ops->recalc_accuracy(clk->hw,
1813 __clk_get_accuracy(clk->parent));
1814 else if (clk->parent)
1815 clk->accuracy = clk->parent->accuracy;
1816 else
1817 clk->accuracy = 0;
1818
1819 /*
1734 * Set clk's rate. The preferred method is to use .recalc_rate. For 1820 * Set clk's rate. The preferred method is to use .recalc_rate. For
1735 * simple clocks and lazy developers the default fallback is to use the 1821 * simple clocks and lazy developers the default fallback is to use the
1736 * parent's rate. If a clock doesn't have a parent (or is orphaned) 1822 * parent's rate. If a clock doesn't have a parent (or is orphaned)