aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/clk/clk.c18
-rw-r--r--include/linux/clk-provider.h2
2 files changed, 13 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)
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 4c58dbdb0e66..27d8f96dd283 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -255,11 +255,13 @@ struct clk_ops {
255 * @hw: parent clk_hw pointer (used for clk providers with internal clks) 255 * @hw: parent clk_hw pointer (used for clk providers with internal clks)
256 * @fw_name: parent name local to provider registering clk 256 * @fw_name: parent name local to provider registering clk
257 * @name: globally unique parent name (used as a fallback) 257 * @name: globally unique parent name (used as a fallback)
258 * @index: parent index local to provider registering clk (if @fw_name absent)
258 */ 259 */
259struct clk_parent_data { 260struct clk_parent_data {
260 const struct clk_hw *hw; 261 const struct clk_hw *hw;
261 const char *fw_name; 262 const char *fw_name;
262 const char *name; 263 const char *name;
264 int index;
263}; 265};
264 266
265/** 267/**