aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2013-07-29 07:25:00 -0400
committerMike Turquette <mturquette@linaro.org>2013-08-19 15:27:17 -0400
commit71472c0c06cf9a3d1540762ea205654c584e3bc4 (patch)
tree22db34b3c7bc0d0053fcfac2c95d77adf09107de /include
parent4935b22c46ea5e2dc44ef0b72db50741649eb3a4 (diff)
clk: add support for clock reparent on set_rate
Add core support to allow clock implementations to select the best parent clock when rounding a rate, e.g. the one which can provide the closest clock rate to that requested. This is by way of adding a new clock op, determine_rate(), which is like round_rate() but has an extra parameter to allow the clock implementation to optionally select a different parent clock. The core then takes care of reparenting the clock when setting the rate. The parent change takes place with the help of some new private data members. struct clk::new_parent specifies a clock's new parent (NULL indicates no change), and struct clk::new_child specifies a clock's new child (whose new_parent member points back to it). The purpose of these are to allow correct walking of the future tree for notifications prior to actually reparenting any clocks, specifically to skip child clocks who are being reparented to another clock (they will be notified via the new parent), and to include any new child clock. These pointers are set by clk_calc_subtree(), and the new_child pointer gets cleared when a child is actually reparented to avoid duplicate POST_RATE_CHANGE notifications. Each place where round_rate() is called, determine_rate() is checked first and called in preference. This restructures a few of the call sites to simplify the logic into if/else blocks. Signed-off-by: James Hogan <james.hogan@imgtec.com> Reviewed-by: Stephen Boyd <sboyd@codeaurora.org> Cc: Mike Turquette <mturquette@linaro.org> Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Mike Turquette <mturquette@linaro.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/clk-private.h3
-rw-r--r--include/linux/clk-provider.h7
2 files changed, 10 insertions, 0 deletions
diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h
index dd7adff76e81..8138c94409f3 100644
--- a/include/linux/clk-private.h
+++ b/include/linux/clk-private.h
@@ -33,8 +33,11 @@ struct clk {
33 const char **parent_names; 33 const char **parent_names;
34 struct clk **parents; 34 struct clk **parents;
35 u8 num_parents; 35 u8 num_parents;
36 u8 new_parent_index;
36 unsigned long rate; 37 unsigned long rate;
37 unsigned long new_rate; 38 unsigned long new_rate;
39 struct clk *new_parent;
40 struct clk *new_child;
38 unsigned long flags; 41 unsigned long flags;
39 unsigned int enable_count; 42 unsigned int enable_count;
40 unsigned int prepare_count; 43 unsigned int prepare_count;
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index a83409285a7f..4f525b37c6fd 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -79,6 +79,10 @@ struct clk_hw;
79 * @round_rate: Given a target rate as input, returns the closest rate actually 79 * @round_rate: Given a target rate as input, returns the closest rate actually
80 * supported by the clock. 80 * supported by the clock.
81 * 81 *
82 * @determine_rate: Given a target rate as input, returns the closest rate
83 * actually supported by the clock, and optionally the parent clock
84 * that should be used to provide the clock rate.
85 *
82 * @get_parent: Queries the hardware to determine the parent of a clock. The 86 * @get_parent: Queries the hardware to determine the parent of a clock. The
83 * return value is a u8 which specifies the index corresponding to 87 * return value is a u8 which specifies the index corresponding to
84 * the parent clock. This index can be applied to either the 88 * the parent clock. This index can be applied to either the
@@ -126,6 +130,9 @@ struct clk_ops {
126 unsigned long parent_rate); 130 unsigned long parent_rate);
127 long (*round_rate)(struct clk_hw *hw, unsigned long, 131 long (*round_rate)(struct clk_hw *hw, unsigned long,
128 unsigned long *); 132 unsigned long *);
133 long (*determine_rate)(struct clk_hw *hw, unsigned long rate,
134 unsigned long *best_parent_rate,
135 struct clk **best_parent_clk);
129 int (*set_parent)(struct clk_hw *hw, u8 index); 136 int (*set_parent)(struct clk_hw *hw, u8 index);
130 u8 (*get_parent)(struct clk_hw *hw); 137 u8 (*get_parent)(struct clk_hw *hw);
131 int (*set_rate)(struct clk_hw *hw, unsigned long, 138 int (*set_rate)(struct clk_hw *hw, unsigned long,