diff options
author | Tomeu Vizoso <tomeu.vizoso@collabora.com> | 2015-01-23 06:03:30 -0500 |
---|---|---|
committer | Michael Turquette <mturquette@linaro.org> | 2015-02-02 17:22:19 -0500 |
commit | 035a61c314eb3dab5bcc5683afaf4d412689858a (patch) | |
tree | 3c325fc76191cf1319c4a3399dfdd9f777033d6d /drivers/clk/clkdev.c | |
parent | af0f349b2996f9f3d83e5aac1edf58fff727a0e0 (diff) |
clk: Make clk API return per-user struct clk instances
Moves clock state to struct clk_core, but takes care to change as little API as
possible.
struct clk_hw still has a pointer to a struct clk, which is the
implementation's per-user clk instance, for backwards compatibility.
The struct clk that clk_get_parent() returns isn't owned by the caller, but by
the clock implementation, so the former shouldn't call clk_put() on it.
Because some boards in mach-omap2 still register clocks statically, their clock
registration had to be updated to take into account that the clock information
is stored in struct clk_core now.
Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Tested-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Michael Turquette <mturquette@linaro.org>
[mturquette@linaro.org: adapted clk_has_parent to struct clk_core
applied OMAP3+ DPLL fix from Tero & Tony]
Diffstat (limited to 'drivers/clk/clkdev.c')
-rw-r--r-- | drivers/clk/clkdev.c | 84 |
1 files changed, 65 insertions, 19 deletions
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index da4bda8b7fc7..901d242f38ea 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/mutex.h> | 19 | #include <linux/mutex.h> |
20 | #include <linux/clk.h> | 20 | #include <linux/clk.h> |
21 | #include <linux/clkdev.h> | 21 | #include <linux/clkdev.h> |
22 | #include <linux/clk-provider.h> | ||
22 | #include <linux/of.h> | 23 | #include <linux/of.h> |
23 | 24 | ||
24 | #include "clk.h" | 25 | #include "clk.h" |
@@ -53,7 +54,7 @@ struct clk *of_clk_get_by_clkspec(struct of_phandle_args *clkspec) | |||
53 | return clk; | 54 | return clk; |
54 | } | 55 | } |
55 | 56 | ||
56 | struct clk *of_clk_get(struct device_node *np, int index) | 57 | static struct clk *__of_clk_get(struct device_node *np, int index) |
57 | { | 58 | { |
58 | struct of_phandle_args clkspec; | 59 | struct of_phandle_args clkspec; |
59 | struct clk *clk; | 60 | struct clk *clk; |
@@ -69,20 +70,24 @@ struct clk *of_clk_get(struct device_node *np, int index) | |||
69 | 70 | ||
70 | clk = of_clk_get_by_clkspec(&clkspec); | 71 | clk = of_clk_get_by_clkspec(&clkspec); |
71 | of_node_put(clkspec.np); | 72 | of_node_put(clkspec.np); |
73 | |||
74 | return clk; | ||
75 | } | ||
76 | |||
77 | struct clk *of_clk_get(struct device_node *np, int index) | ||
78 | { | ||
79 | struct clk *clk = __of_clk_get(np, index); | ||
80 | |||
81 | if (!IS_ERR(clk)) | ||
82 | clk = __clk_create_clk(__clk_get_hw(clk), np->full_name, NULL); | ||
83 | |||
72 | return clk; | 84 | return clk; |
73 | } | 85 | } |
74 | EXPORT_SYMBOL(of_clk_get); | 86 | EXPORT_SYMBOL(of_clk_get); |
75 | 87 | ||
76 | /** | 88 | static struct clk *__of_clk_get_by_name(struct device_node *np, |
77 | * of_clk_get_by_name() - Parse and lookup a clock referenced by a device node | 89 | const char *dev_id, |
78 | * @np: pointer to clock consumer node | 90 | const char *name) |
79 | * @name: name of consumer's clock input, or NULL for the first clock reference | ||
80 | * | ||
81 | * This function parses the clocks and clock-names properties, | ||
82 | * and uses them to look up the struct clk from the registered list of clock | ||
83 | * providers. | ||
84 | */ | ||
85 | struct clk *of_clk_get_by_name(struct device_node *np, const char *name) | ||
86 | { | 91 | { |
87 | struct clk *clk = ERR_PTR(-ENOENT); | 92 | struct clk *clk = ERR_PTR(-ENOENT); |
88 | 93 | ||
@@ -97,9 +102,11 @@ struct clk *of_clk_get_by_name(struct device_node *np, const char *name) | |||
97 | */ | 102 | */ |
98 | if (name) | 103 | if (name) |
99 | index = of_property_match_string(np, "clock-names", name); | 104 | index = of_property_match_string(np, "clock-names", name); |
100 | clk = of_clk_get(np, index); | 105 | clk = __of_clk_get(np, index); |
101 | if (!IS_ERR(clk)) | 106 | if (!IS_ERR(clk)) { |
107 | clk = __clk_create_clk(__clk_get_hw(clk), dev_id, name); | ||
102 | break; | 108 | break; |
109 | } | ||
103 | else if (name && index >= 0) { | 110 | else if (name && index >= 0) { |
104 | if (PTR_ERR(clk) != -EPROBE_DEFER) | 111 | if (PTR_ERR(clk) != -EPROBE_DEFER) |
105 | pr_err("ERROR: could not get clock %s:%s(%i)\n", | 112 | pr_err("ERROR: could not get clock %s:%s(%i)\n", |
@@ -119,7 +126,33 @@ struct clk *of_clk_get_by_name(struct device_node *np, const char *name) | |||
119 | 126 | ||
120 | return clk; | 127 | return clk; |
121 | } | 128 | } |
129 | |||
130 | /** | ||
131 | * of_clk_get_by_name() - Parse and lookup a clock referenced by a device node | ||
132 | * @np: pointer to clock consumer node | ||
133 | * @name: name of consumer's clock input, or NULL for the first clock reference | ||
134 | * | ||
135 | * This function parses the clocks and clock-names properties, | ||
136 | * and uses them to look up the struct clk from the registered list of clock | ||
137 | * providers. | ||
138 | */ | ||
139 | struct clk *of_clk_get_by_name(struct device_node *np, const char *name) | ||
140 | { | ||
141 | if (!np) | ||
142 | return ERR_PTR(-ENOENT); | ||
143 | |||
144 | return __of_clk_get_by_name(np, np->full_name, name); | ||
145 | } | ||
122 | EXPORT_SYMBOL(of_clk_get_by_name); | 146 | EXPORT_SYMBOL(of_clk_get_by_name); |
147 | |||
148 | #else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */ | ||
149 | |||
150 | static struct clk *__of_clk_get_by_name(struct device_node *np, | ||
151 | const char *dev_id, | ||
152 | const char *name) | ||
153 | { | ||
154 | return ERR_PTR(-ENOENT); | ||
155 | } | ||
123 | #endif | 156 | #endif |
124 | 157 | ||
125 | /* | 158 | /* |
@@ -168,14 +201,29 @@ static struct clk_lookup *clk_find(const char *dev_id, const char *con_id) | |||
168 | struct clk *clk_get_sys(const char *dev_id, const char *con_id) | 201 | struct clk *clk_get_sys(const char *dev_id, const char *con_id) |
169 | { | 202 | { |
170 | struct clk_lookup *cl; | 203 | struct clk_lookup *cl; |
204 | struct clk *clk = NULL; | ||
171 | 205 | ||
172 | mutex_lock(&clocks_mutex); | 206 | mutex_lock(&clocks_mutex); |
207 | |||
173 | cl = clk_find(dev_id, con_id); | 208 | cl = clk_find(dev_id, con_id); |
174 | if (cl && !__clk_get(cl->clk)) | 209 | if (!cl) |
210 | goto out; | ||
211 | |||
212 | if (!__clk_get(cl->clk)) { | ||
175 | cl = NULL; | 213 | cl = NULL; |
214 | goto out; | ||
215 | } | ||
216 | |||
217 | #if defined(CONFIG_COMMON_CLK) | ||
218 | clk = __clk_create_clk(__clk_get_hw(cl->clk), dev_id, con_id); | ||
219 | #else | ||
220 | clk = cl->clk; | ||
221 | #endif | ||
222 | |||
223 | out: | ||
176 | mutex_unlock(&clocks_mutex); | 224 | mutex_unlock(&clocks_mutex); |
177 | 225 | ||
178 | return cl ? cl->clk : ERR_PTR(-ENOENT); | 226 | return cl ? clk : ERR_PTR(-ENOENT); |
179 | } | 227 | } |
180 | EXPORT_SYMBOL(clk_get_sys); | 228 | EXPORT_SYMBOL(clk_get_sys); |
181 | 229 | ||
@@ -185,10 +233,8 @@ struct clk *clk_get(struct device *dev, const char *con_id) | |||
185 | struct clk *clk; | 233 | struct clk *clk; |
186 | 234 | ||
187 | if (dev) { | 235 | if (dev) { |
188 | clk = of_clk_get_by_name(dev->of_node, con_id); | 236 | clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id); |
189 | if (!IS_ERR(clk)) | 237 | if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER) |
190 | return clk; | ||
191 | if (PTR_ERR(clk) == -EPROBE_DEFER) | ||
192 | return clk; | 238 | return clk; |
193 | } | 239 | } |
194 | 240 | ||