summaryrefslogtreecommitdiff
path: root/include/linux/clk-provider.h
diff options
context:
space:
mode:
authorStephen Boyd <sboyd@kernel.org>2019-04-12 21:31:47 +0300
committerStephen Boyd <sboyd@kernel.org>2019-04-20 00:52:58 +0300
commitfc0c209c147f35ed2648adda09db39fcad89e334 (patch)
tree9d7ee8d13adf947cf816eb8ab310bd849ee53780 /include/linux/clk-provider.h
parent89a5ddcc799d5d7dbcf6197b79dafc1dc9f997f5 (diff)
downloadlinux-fc0c209c147f35ed2648adda09db39fcad89e334.tar.xz
clk: Allow parents to be specified without string names
The common clk framework is lacking in ability to describe the clk topology without specifying strings for every possible parent-child link. There are a few drawbacks to the current approach: 1) String comparisons are used for everything, including describing topologies that are 'local' to a single clock controller. 2) clk providers (e.g. i2c clk drivers) need to create globally unique clk names to avoid collisions in the clk namespace, leading to awkward name generation code in various clk drivers. 3) DT bindings may not fully describe the clk topology and linkages between clk controllers because drivers can easily rely on globally unique strings to describe connections between clks. This leads to confusing DT bindings, complicated clk name generation code, and inefficient string comparisons during clk registration just so that the clk framework can detect the topology of the clk tree. Furthermore, some drivers call clk_get() and then __clk_get_name() to extract the globally unique clk name just so they can specify the parent of the clk they're registering. We have of_clk_parent_fill() but that mostly only works for single clks registered from a DT node, which isn't the norm. Let's simplify this all by introducing two new ways of specifying clk parents. The first method is an array of pointers to clk_hw structures corresponding to the parents at that index. This works for clks that are registered when we have access to all the clk_hw pointers for the parents. The second method is a mix of clk_hw pointers and strings of local and global parent clk names. If the .fw_name member of the map is set we'll look for that clk by performing a DT based lookup of the device the clk is registered with and the .name specified in the map. If that fails, we'll fallback to the .name member and perform a global clk name lookup like we've always done before. Using either one of these new methods is entirely optional. Existing drivers will continue to work, and they can migrate to this new approach as they see fit. Eventually, we'll want to get rid of the 'parent_names' array in struct clk_init_data and use one of these new methods instead. Cc: Miquel Raynal <miquel.raynal@bootlin.com> Cc: Jerome Brunet <jbrunet@baylibre.com> Cc: Russell King <linux@armlinux.org.uk> Cc: Michael Turquette <mturquette@baylibre.com> Cc: Jeffrey Hugo <jhugo@codeaurora.org> Cc: Chen-Yu Tsai <wens@csie.org> Cc: Rob Herring <robh@kernel.org> Tested-by: Jeffrey Hugo <jhugo@codeaurora.org> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Diffstat (limited to 'include/linux/clk-provider.h')
-rw-r--r--include/linux/clk-provider.h19
1 files changed, 19 insertions, 0 deletions
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 7d2d97e15b76..4c58dbdb0e66 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -251,19 +251,38 @@ struct clk_ops {
};
/**
+ * struct clk_parent_data - clk parent information
+ * @hw: parent clk_hw pointer (used for clk providers with internal clks)
+ * @fw_name: parent name local to provider registering clk
+ * @name: globally unique parent name (used as a fallback)
+ */
+struct clk_parent_data {
+ const struct clk_hw *hw;
+ const char *fw_name;
+ const char *name;
+};
+
+/**
* struct clk_init_data - holds init data that's common to all clocks and is
* shared between the clock provider and the common clock framework.
*
* @name: clock name
* @ops: operations this clock supports
* @parent_names: array of string names for all possible parents
+ * @parent_data: array of parent data for all possible parents (when some
+ * parents are external to the clk controller)
+ * @parent_hws: array of pointers to all possible parents (when all parents
+ * are internal to the clk controller)
* @num_parents: number of possible parents
* @flags: framework-level hints and quirks
*/
struct clk_init_data {
const char *name;
const struct clk_ops *ops;
+ /* Only one of the following three should be assigned */
const char * const *parent_names;
+ const struct clk_parent_data *parent_data;
+ const struct clk_hw **parent_hws;
u8 num_parents;
unsigned long flags;
};