Skip to content

Commit 4472287

Browse files
committed
clk: Introduce of_clk_get_hw_from_clkspec()
We want to get struct clk_hw pointers from a DT clk specifier (i.e. a clocks property) so that we can find parent clks without searching for globally unique clk names. This should save time by avoiding the global string search for clks that are external to the clock controller providing the clk and let us move away from string comparisons in general. Introduce of_clk_get_hw_from_clkspec() which is largely the DT parsing part of finding clks implemented in clkdev.c and have that return a clk_hw pointer instead of converting that into a clk pointer. This lets us push up the clk pointer creation to the caller in clk_get() and avoids the need to push the dev_id and con_id throughout the DT parsing code. 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> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
1 parent 2447883 commit 4472287

File tree

3 files changed

+69
-65
lines changed

3 files changed

+69
-65
lines changed

drivers/clk/clk.c

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4065,6 +4065,42 @@ void devm_of_clk_del_provider(struct device *dev)
40654065
}
40664066
EXPORT_SYMBOL(devm_of_clk_del_provider);
40674067

4068+
int of_parse_clkspec(const struct device_node *np, int index, const char *name,
4069+
struct of_phandle_args *out_args)
4070+
{
4071+
int ret = -ENOENT;
4072+
4073+
/* Walk up the tree of devices looking for a clock property that matches */
4074+
while (np) {
4075+
/*
4076+
* For named clocks, first look up the name in the
4077+
* "clock-names" property. If it cannot be found, then index
4078+
* will be an error code and of_parse_phandle_with_args() will
4079+
* return -EINVAL.
4080+
*/
4081+
if (name)
4082+
index = of_property_match_string(np, "clock-names", name);
4083+
ret = of_parse_phandle_with_args(np, "clocks", "#clock-cells",
4084+
index, out_args);
4085+
if (!ret)
4086+
break;
4087+
if (name && index >= 0)
4088+
break;
4089+
4090+
/*
4091+
* No matching clock found on this node. If the parent node
4092+
* has a "clock-ranges" property, then we can try one of its
4093+
* clocks.
4094+
*/
4095+
np = np->parent;
4096+
if (np && !of_get_property(np, "clock-ranges", NULL))
4097+
break;
4098+
index = 0;
4099+
}
4100+
4101+
return ret;
4102+
}
4103+
40684104
static struct clk_hw *
40694105
__of_clk_get_hw_from_provider(struct of_clk_provider *provider,
40704106
struct of_phandle_args *clkspec)
@@ -4080,16 +4116,14 @@ __of_clk_get_hw_from_provider(struct of_clk_provider *provider,
40804116
return __clk_get_hw(clk);
40814117
}
40824118

4083-
struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
4084-
const char *dev_id, const char *con_id)
4119+
struct clk_hw *of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec)
40854120
{
40864121
struct of_clk_provider *provider;
40874122
struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
40884123

40894124
if (!clkspec)
40904125
return ERR_PTR(-EINVAL);
40914126

4092-
/* Check if we have such a provider in our array */
40934127
mutex_lock(&of_clk_mutex);
40944128
list_for_each_entry(provider, &of_clk_providers, link) {
40954129
if (provider->node == clkspec->np) {
@@ -4100,7 +4134,7 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
41004134
}
41014135
mutex_unlock(&of_clk_mutex);
41024136

4103-
return clk_hw_create_clk(hw, dev_id, con_id);
4137+
return hw;
41044138
}
41054139

41064140
/**
@@ -4113,7 +4147,9 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
41134147
*/
41144148
struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
41154149
{
4116-
return __of_clk_get_from_provider(clkspec, NULL, __func__);
4150+
struct clk_hw *hw = of_clk_get_hw_from_clkspec(clkspec);
4151+
4152+
return clk_hw_create_clk(hw, NULL, __func__);
41174153
}
41184154
EXPORT_SYMBOL_GPL(of_clk_get_from_provider);
41194155

drivers/clk/clk.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
struct clk_hw;
88

99
#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
10-
struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
11-
const char *dev_id, const char *con_id);
10+
int of_parse_clkspec(const struct device_node *np, int index, const char *name,
11+
struct of_phandle_args *out_args);
12+
struct clk_hw *of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec);
1213
#endif
1314

1415
#ifdef CONFIG_COMMON_CLK

drivers/clk/clkdev.c

Lines changed: 25 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -28,69 +28,37 @@ static LIST_HEAD(clocks);
2828
static DEFINE_MUTEX(clocks_mutex);
2929

3030
#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
31-
static struct clk *__of_clk_get(struct device_node *np, int index,
32-
const char *dev_id, const char *con_id)
31+
static struct clk_hw *of_clk_get_hw(struct device_node *np,
32+
int index, const char *con_id)
3333
{
34+
int ret;
35+
struct clk_hw *hw;
3436
struct of_phandle_args clkspec;
35-
struct clk *clk;
36-
int rc;
3737

38-
rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", index,
39-
&clkspec);
40-
if (rc)
41-
return ERR_PTR(rc);
38+
ret = of_parse_clkspec(np, index, con_id, &clkspec);
39+
if (ret)
40+
return ERR_PTR(ret);
4241

43-
clk = __of_clk_get_from_provider(&clkspec, dev_id, con_id);
42+
hw = of_clk_get_hw_from_clkspec(&clkspec);
4443
of_node_put(clkspec.np);
4544

46-
return clk;
45+
return hw;
4746
}
4847

49-
struct clk *of_clk_get(struct device_node *np, int index)
48+
static struct clk *__of_clk_get(struct device_node *np,
49+
int index, const char *dev_id,
50+
const char *con_id)
5051
{
51-
return __of_clk_get(np, index, np->full_name, NULL);
52+
struct clk_hw *hw = of_clk_get_hw(np, index, con_id);
53+
54+
return clk_hw_create_clk(hw, dev_id, con_id);
5255
}
53-
EXPORT_SYMBOL(of_clk_get);
5456

55-
static struct clk *__of_clk_get_by_name(struct device_node *np,
56-
const char *dev_id,
57-
const char *name)
57+
struct clk *of_clk_get(struct device_node *np, int index)
5858
{
59-
struct clk *clk = ERR_PTR(-ENOENT);
60-
61-
/* Walk up the tree of devices looking for a clock that matches */
62-
while (np) {
63-
int index = 0;
64-
65-
/*
66-
* For named clocks, first look up the name in the
67-
* "clock-names" property. If it cannot be found, then
68-
* index will be an error code, and of_clk_get() will fail.
69-
*/
70-
if (name)
71-
index = of_property_match_string(np, "clock-names", name);
72-
clk = __of_clk_get(np, index, dev_id, name);
73-
if (!IS_ERR(clk)) {
74-
break;
75-
} else if (name && index >= 0) {
76-
if (PTR_ERR(clk) != -EPROBE_DEFER)
77-
pr_err("ERROR: could not get clock %pOF:%s(%i)\n",
78-
np, name ? name : "", index);
79-
return clk;
80-
}
81-
82-
/*
83-
* No matching clock found on this node. If the parent node
84-
* has a "clock-ranges" property, then we can try one of its
85-
* clocks.
86-
*/
87-
np = np->parent;
88-
if (np && !of_get_property(np, "clock-ranges", NULL))
89-
break;
90-
}
91-
92-
return clk;
59+
return __of_clk_get(np, index, np->full_name, NULL);
9360
}
61+
EXPORT_SYMBOL(of_clk_get);
9462

9563
/**
9664
* of_clk_get_by_name() - Parse and lookup a clock referenced by a device node
@@ -106,15 +74,14 @@ struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
10674
if (!np)
10775
return ERR_PTR(-ENOENT);
10876

109-
return __of_clk_get_by_name(np, np->full_name, name);
77+
return __of_clk_get(np, -1, np->full_name, name);
11078
}
11179
EXPORT_SYMBOL(of_clk_get_by_name);
11280

11381
#else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */
11482

115-
static struct clk *__of_clk_get_by_name(struct device_node *np,
116-
const char *dev_id,
117-
const char *name)
83+
static struct clk_hw *of_clk_get_hw(struct device_node *np,
84+
int index, const char *con_id)
11885
{
11986
return ERR_PTR(-ENOENT);
12087
}
@@ -187,12 +154,12 @@ EXPORT_SYMBOL(clk_get_sys);
187154
struct clk *clk_get(struct device *dev, const char *con_id)
188155
{
189156
const char *dev_id = dev ? dev_name(dev) : NULL;
190-
struct clk *clk;
157+
struct clk_hw *hw;
191158

192159
if (dev && dev->of_node) {
193-
clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id);
194-
if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
195-
return clk;
160+
hw = of_clk_get_hw(dev->of_node, 0, con_id);
161+
if (!IS_ERR(hw) || PTR_ERR(hw) == -EPROBE_DEFER)
162+
return clk_hw_create_clk(hw, dev_id, con_id);
196163
}
197164

198165
return clk_get_sys(dev_id, con_id);

0 commit comments

Comments
 (0)