summaryrefslogtreecommitdiffstats
path: root/drivers/clk
diff options
context:
space:
mode:
authorStephen Boyd <sboyd@kernel.org>2019-04-12 14:31:49 -0400
committerStephen Boyd <sboyd@kernel.org>2019-04-19 17:53:19 -0400
commit601b6e93304a65f8f7c37168763ab9ba5b195ce5 (patch)
tree614df84355a990933b5b07955761c7fcb568ca03 /drivers/clk
parentdde4eff47c82c52a72af333d9e55370eee6d95d6 (diff)
clk: Allow parents to be specified via clkspec index
Some clk providers are simple DT nodes that only have a 'clocks' property without having an associated 'clock-names' property. In these cases, we want to let these clk providers point to their parent clks without having to dereference the 'clocks' property at probe time to figure out the parent's globally unique clk name. Let's add an 'index' property to the parent_data structure so that clk providers can indicate that their parent is a particular index in the 'clocks' DT property. 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> Tested-by: Jeffrey Hugo <jhugo@codeaurora.org> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Diffstat (limited to 'drivers/clk')
-rw-r--r--drivers/clk/clk.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 50f5c73de688..dc05cb339761 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -44,6 +44,7 @@ struct clk_parent_map {
44 struct clk_core *core; 44 struct clk_core *core;
45 const char *fw_name; 45 const char *fw_name;
46 const char *name; 46 const char *name;
47 int index;
47}; 48};
48 49
49struct clk_core { 50struct clk_core {
@@ -326,7 +327,8 @@ static struct clk_core *clk_core_lookup(const char *name)
326/** 327/**
327 * clk_core_get - Find the clk_core parent of a clk 328 * clk_core_get - Find the clk_core parent of a clk
328 * @core: clk to find parent of 329 * @core: clk to find parent of
329 * @name: name to search for 330 * @name: name to search for (if string based)
331 * @index: index to use for search (if DT index based)
330 * 332 *
331 * This is the preferred method for clk providers to find the parent of a 333 * This is the preferred method for clk providers to find the parent of a
332 * clk when that parent is external to the clk controller. The parent_names 334 * clk when that parent is external to the clk controller. The parent_names
@@ -358,22 +360,23 @@ static struct clk_core *clk_core_lookup(const char *name)
358 * provider knows about the clk but it isn't provided on this system. 360 * provider knows about the clk but it isn't provided on this system.
359 * A valid clk_core pointer when the clk can be found in the provider. 361 * A valid clk_core pointer when the clk can be found in the provider.
360 */ 362 */
361static struct clk_core *clk_core_get(struct clk_core *core, const char *name) 363static struct clk_core *clk_core_get(struct clk_core *core, const char *name,
364 int index)
362{ 365{
363 struct clk_hw *hw = ERR_PTR(-ENOENT); 366 struct clk_hw *hw = ERR_PTR(-ENOENT);
364 struct device *dev = core->dev; 367 struct device *dev = core->dev;
365 const char *dev_id = dev ? dev_name(dev) : NULL; 368 const char *dev_id = dev ? dev_name(dev) : NULL;
366 struct device_node *np = core->of_node; 369 struct device_node *np = core->of_node;
367 370
368 if (np) 371 if (np && index >= 0)
369 hw = of_clk_get_hw(np, -1, name); 372 hw = of_clk_get_hw(np, index, name);
370 373
371 /* 374 /*
372 * If the DT search above couldn't find the provider or the provider 375 * If the DT search above couldn't find the provider or the provider
373 * didn't know about this clk, fallback to looking up via clkdev based 376 * didn't know about this clk, fallback to looking up via clkdev based
374 * clk_lookups 377 * clk_lookups
375 */ 378 */
376 if (PTR_ERR(hw) == -ENOENT) 379 if (PTR_ERR(hw) == -ENOENT && name)
377 hw = clk_find_hw(dev_id, name); 380 hw = clk_find_hw(dev_id, name);
378 381
379 if (IS_ERR(hw)) 382 if (IS_ERR(hw))
@@ -397,8 +400,7 @@ static void clk_core_fill_parent_index(struct clk_core *core, u8 index)
397 if (!parent) 400 if (!parent)
398 parent = ERR_PTR(-EPROBE_DEFER); 401 parent = ERR_PTR(-EPROBE_DEFER);
399 } else { 402 } else {
400 if (entry->fw_name) 403 parent = clk_core_get(core, entry->fw_name, entry->index);
401 parent = clk_core_get(core, entry->fw_name);
402 if (IS_ERR(parent) && PTR_ERR(parent) == -ENOENT) 404 if (IS_ERR(parent) && PTR_ERR(parent) == -ENOENT)
403 parent = clk_core_lookup(entry->name); 405 parent = clk_core_lookup(entry->name);
404 } 406 }
@@ -3443,6 +3445,7 @@ static int clk_core_populate_parent_map(struct clk_core *core)
3443 3445
3444 /* Copy everything over because it might be __initdata */ 3446 /* Copy everything over because it might be __initdata */
3445 for (i = 0, parent = parents; i < num_parents; i++, parent++) { 3447 for (i = 0, parent = parents; i < num_parents; i++, parent++) {
3448 parent->index = -1;
3446 if (parent_names) { 3449 if (parent_names) {
3447 /* throw a WARN if any entries are NULL */ 3450 /* throw a WARN if any entries are NULL */
3448 WARN(!parent_names[i], 3451 WARN(!parent_names[i],
@@ -3452,6 +3455,7 @@ static int clk_core_populate_parent_map(struct clk_core *core)
3452 true); 3455 true);
3453 } else if (parent_data) { 3456 } else if (parent_data) {
3454 parent->hw = parent_data[i].hw; 3457 parent->hw = parent_data[i].hw;
3458 parent->index = parent_data[i].index;
3455 ret = clk_cpy_name(&parent->fw_name, 3459 ret = clk_cpy_name(&parent->fw_name,
3456 parent_data[i].fw_name, false); 3460 parent_data[i].fw_name, false);
3457 if (!ret) 3461 if (!ret)