aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--Documentation/clk.txt4
-rw-r--r--drivers/clk/clk.c100
-rw-r--r--include/linux/clk-private.h1
-rw-r--r--include/linux/clk-provider.h11
-rw-r--r--include/linux/clk.h17
5 files changed, 126 insertions, 7 deletions
diff --git a/Documentation/clk.txt b/Documentation/clk.txt
index 3aeb5c440442..eb20198783cd 100644
--- a/Documentation/clk.txt
+++ b/Documentation/clk.txt
@@ -77,6 +77,8 @@ the operations defined in clk.h:
77 int (*set_parent)(struct clk_hw *hw, u8 index); 77 int (*set_parent)(struct clk_hw *hw, u8 index);
78 u8 (*get_parent)(struct clk_hw *hw); 78 u8 (*get_parent)(struct clk_hw *hw);
79 int (*set_rate)(struct clk_hw *hw, unsigned long); 79 int (*set_rate)(struct clk_hw *hw, unsigned long);
80 unsigned long (*recalc_accuracy)(struct clk_hw *hw,
81 unsigned long parent_accuracy);
80 void (*init)(struct clk_hw *hw); 82 void (*init)(struct clk_hw *hw);
81 }; 83 };
82 84
@@ -202,6 +204,8 @@ optional or must be evaluated on a case-by-case basis.
202.set_parent | | | n | y | n | 204.set_parent | | | n | y | n |
203.get_parent | | | n | y | n | 205.get_parent | | | n | y | n |
204 | | | | | | 206 | | | | | |
207.recalc_accuracy| | | | | |
208 | | | | | |
205.init | | | | | | 209.init | | | | | |
206 ----------------------------------------------------------- 210 -----------------------------------------------------------
207[1] either one of round_rate or determine_rate is required. 211[1] either one of round_rate or determine_rate is required.
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)
diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h
index 8138c94409f3..accb517e77e9 100644
--- a/include/linux/clk-private.h
+++ b/include/linux/clk-private.h
@@ -41,6 +41,7 @@ struct clk {
41 unsigned long flags; 41 unsigned long flags;
42 unsigned int enable_count; 42 unsigned int enable_count;
43 unsigned int prepare_count; 43 unsigned int prepare_count;
44 unsigned long accuracy;
44 struct hlist_head children; 45 struct hlist_head children;
45 struct hlist_node child_node; 46 struct hlist_node child_node;
46 unsigned int notifier_count; 47 unsigned int notifier_count;
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 7e59253b8603..16d182c28ce6 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -29,6 +29,7 @@
29#define CLK_IS_BASIC BIT(5) /* Basic clk, can't do a to_clk_foo() */ 29#define CLK_IS_BASIC BIT(5) /* Basic clk, can't do a to_clk_foo() */
30#define CLK_GET_RATE_NOCACHE BIT(6) /* do not use the cached clk rate */ 30#define CLK_GET_RATE_NOCACHE BIT(6) /* do not use the cached clk rate */
31#define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */ 31#define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */
32#define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */
32 33
33struct clk_hw; 34struct clk_hw;
34 35
@@ -108,6 +109,13 @@ struct clk_hw;
108 * which is likely helpful for most .set_rate implementation. 109 * which is likely helpful for most .set_rate implementation.
109 * Returns 0 on success, -EERROR otherwise. 110 * Returns 0 on success, -EERROR otherwise.
110 * 111 *
112 * @recalc_accuracy: Recalculate the accuracy of this clock. The clock accuracy
113 * is expressed in ppb (parts per billion). The parent accuracy is
114 * an input parameter.
115 * Returns the calculated accuracy. Optional - if this op is not
116 * set then clock accuracy will be initialized to parent accuracy
117 * or 0 (perfect clock) if clock has no parent.
118 *
111 * The clk_enable/clk_disable and clk_prepare/clk_unprepare pairs allow 119 * The clk_enable/clk_disable and clk_prepare/clk_unprepare pairs allow
112 * implementations to split any work between atomic (enable) and sleepable 120 * implementations to split any work between atomic (enable) and sleepable
113 * (prepare) contexts. If enabling a clock requires code that might sleep, 121 * (prepare) contexts. If enabling a clock requires code that might sleep,
@@ -139,6 +147,8 @@ struct clk_ops {
139 u8 (*get_parent)(struct clk_hw *hw); 147 u8 (*get_parent)(struct clk_hw *hw);
140 int (*set_rate)(struct clk_hw *hw, unsigned long, 148 int (*set_rate)(struct clk_hw *hw, unsigned long,
141 unsigned long); 149 unsigned long);
150 unsigned long (*recalc_accuracy)(struct clk_hw *hw,
151 unsigned long parent_accuracy);
142 void (*init)(struct clk_hw *hw); 152 void (*init)(struct clk_hw *hw);
143}; 153};
144 154
@@ -433,6 +443,7 @@ struct clk *clk_get_parent_by_index(struct clk *clk, u8 index);
433unsigned int __clk_get_enable_count(struct clk *clk); 443unsigned int __clk_get_enable_count(struct clk *clk);
434unsigned int __clk_get_prepare_count(struct clk *clk); 444unsigned int __clk_get_prepare_count(struct clk *clk);
435unsigned long __clk_get_rate(struct clk *clk); 445unsigned long __clk_get_rate(struct clk *clk);
446unsigned long __clk_get_accuracy(struct clk *clk);
436unsigned long __clk_get_flags(struct clk *clk); 447unsigned long __clk_get_flags(struct clk *clk);
437bool __clk_is_prepared(struct clk *clk); 448bool __clk_is_prepared(struct clk *clk);
438bool __clk_is_enabled(struct clk *clk); 449bool __clk_is_enabled(struct clk *clk);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 9a6d04524b1a..0dd91148165e 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -82,6 +82,23 @@ int clk_notifier_register(struct clk *clk, struct notifier_block *nb);
82 82
83int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb); 83int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb);
84 84
85/**
86 * clk_get_accuracy - obtain the clock accuracy in ppb (parts per billion)
87 * for a clock source.
88 * @clk: clock source
89 *
90 * This gets the clock source accuracy expressed in ppb.
91 * A perfect clock returns 0.
92 */
93long clk_get_accuracy(struct clk *clk);
94
95#else
96
97static inline long clk_get_accuracy(struct clk *clk)
98{
99 return -ENOTSUPP;
100}
101
85#endif 102#endif
86 103
87/** 104/**