aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk
diff options
context:
space:
mode:
authorMike Turquette <mturquette@linaro.org>2014-02-19 00:21:25 -0500
committerMaxime Ripard <maxime.ripard@free-electrons.com>2014-09-27 02:57:38 -0400
commite59c5371fb9d8268d1c043172e88cecab9dc934f (patch)
tree54acf05ccfffdc1dc17dd3c0adb92f54332e0bb0 /drivers/clk
parentcfe4c93b58924b3764cd7269d3d953049405e938 (diff)
clk: introduce clk_set_phase function & callback
A common operation for a clock signal generator is to shift the phase of that signal. This patch introduces a new function to the clk.h API to dynamically adjust the phase of a clock signal. Additionally this patch introduces support for the new function in the common clock framework via the .set_phase call back in struct clk_ops. Signed-off-by: Mike Turquette <mturquette@linaro.org> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> Reviewed-by: Heiko Stuebner <heiko@sntech.de> Acked-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'drivers/clk')
-rw-r--r--drivers/clk/clk.c85
1 files changed, 81 insertions, 4 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index b76fa69b44cb..d87661af0c72 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -117,11 +117,11 @@ static void clk_summary_show_one(struct seq_file *s, struct clk *c, int level)
117 if (!c) 117 if (!c)
118 return; 118 return;
119 119
120 seq_printf(s, "%*s%-*s %11d %12d %11lu %10lu\n", 120 seq_printf(s, "%*s%-*s %11d %12d %11lu %10lu %-3d\n",
121 level * 3 + 1, "", 121 level * 3 + 1, "",
122 30 - level * 3, c->name, 122 30 - level * 3, c->name,
123 c->enable_count, c->prepare_count, clk_get_rate(c), 123 c->enable_count, c->prepare_count, clk_get_rate(c),
124 clk_get_accuracy(c)); 124 clk_get_accuracy(c), clk_get_phase(c));
125} 125}
126 126
127static void clk_summary_show_subtree(struct seq_file *s, struct clk *c, 127static void clk_summary_show_subtree(struct seq_file *s, struct clk *c,
@@ -143,8 +143,8 @@ static int clk_summary_show(struct seq_file *s, void *data)
143 struct clk *c; 143 struct clk *c;
144 struct hlist_head **lists = (struct hlist_head **)s->private; 144 struct hlist_head **lists = (struct hlist_head **)s->private;
145 145
146 seq_puts(s, " clock enable_cnt prepare_cnt rate accuracy\n"); 146 seq_puts(s, " clock enable_cnt prepare_cnt rate accuracy phase\n");
147 seq_puts(s, "--------------------------------------------------------------------------------\n"); 147 seq_puts(s, "----------------------------------------------------------------------------------------\n");
148 148
149 clk_prepare_lock(); 149 clk_prepare_lock();
150 150
@@ -180,6 +180,7 @@ static void clk_dump_one(struct seq_file *s, struct clk *c, int level)
180 seq_printf(s, "\"prepare_count\": %d,", c->prepare_count); 180 seq_printf(s, "\"prepare_count\": %d,", c->prepare_count);
181 seq_printf(s, "\"rate\": %lu", clk_get_rate(c)); 181 seq_printf(s, "\"rate\": %lu", clk_get_rate(c));
182 seq_printf(s, "\"accuracy\": %lu", clk_get_accuracy(c)); 182 seq_printf(s, "\"accuracy\": %lu", clk_get_accuracy(c));
183 seq_printf(s, "\"phase\": %d", clk_get_phase(c));
183} 184}
184 185
185static void clk_dump_subtree(struct seq_file *s, struct clk *c, int level) 186static void clk_dump_subtree(struct seq_file *s, struct clk *c, int level)
@@ -264,6 +265,11 @@ static int clk_debug_create_one(struct clk *clk, struct dentry *pdentry)
264 if (!d) 265 if (!d)
265 goto err_out; 266 goto err_out;
266 267
268 d = debugfs_create_u32("clk_phase", S_IRUGO, clk->dentry,
269 (u32 *)&clk->phase);
270 if (!d)
271 goto err_out;
272
267 d = debugfs_create_x32("clk_flags", S_IRUGO, clk->dentry, 273 d = debugfs_create_x32("clk_flags", S_IRUGO, clk->dentry,
268 (u32 *)&clk->flags); 274 (u32 *)&clk->flags);
269 if (!d) 275 if (!d)
@@ -1739,6 +1745,77 @@ out:
1739EXPORT_SYMBOL_GPL(clk_set_parent); 1745EXPORT_SYMBOL_GPL(clk_set_parent);
1740 1746
1741/** 1747/**
1748 * clk_set_phase - adjust the phase shift of a clock signal
1749 * @clk: clock signal source
1750 * @degrees: number of degrees the signal is shifted
1751 *
1752 * Shifts the phase of a clock signal by the specified
1753 * degrees. Returns 0 on success, -EERROR otherwise.
1754 *
1755 * This function makes no distinction about the input or reference
1756 * signal that we adjust the clock signal phase against. For example
1757 * phase locked-loop clock signal generators we may shift phase with
1758 * respect to feedback clock signal input, but for other cases the
1759 * clock phase may be shifted with respect to some other, unspecified
1760 * signal.
1761 *
1762 * Additionally the concept of phase shift does not propagate through
1763 * the clock tree hierarchy, which sets it apart from clock rates and
1764 * clock accuracy. A parent clock phase attribute does not have an
1765 * impact on the phase attribute of a child clock.
1766 */
1767int clk_set_phase(struct clk *clk, int degrees)
1768{
1769 int ret = 0;
1770
1771 if (!clk)
1772 goto out;
1773
1774 /* sanity check degrees */
1775 degrees %= 360;
1776 if (degrees < 0)
1777 degrees += 360;
1778
1779 clk_prepare_lock();
1780
1781 if (!clk->ops->set_phase)
1782 goto out_unlock;
1783
1784 ret = clk->ops->set_phase(clk->hw, degrees);
1785
1786 if (!ret)
1787 clk->phase = degrees;
1788
1789out_unlock:
1790 clk_prepare_unlock();
1791
1792out:
1793 return ret;
1794}
1795
1796/**
1797 * clk_get_phase - return the phase shift of a clock signal
1798 * @clk: clock signal source
1799 *
1800 * Returns the phase shift of a clock node in degrees, otherwise returns
1801 * -EERROR.
1802 */
1803int clk_get_phase(struct clk *clk)
1804{
1805 int ret = 0;
1806
1807 if (!clk)
1808 goto out;
1809
1810 clk_prepare_lock();
1811 ret = clk->phase;
1812 clk_prepare_unlock();
1813
1814out:
1815 return ret;
1816}
1817
1818/**
1742 * __clk_init - initialize the data structures in a struct clk 1819 * __clk_init - initialize the data structures in a struct clk
1743 * @dev: device initializing this clk, placeholder for now 1820 * @dev: device initializing this clk, placeholder for now
1744 * @clk: clk being initialized 1821 * @clk: clk being initialized