.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> |
---|
3 | | - * |
---|
4 | | - * This program is free software; you can redistribute it and/or modify |
---|
5 | | - * it under the terms of the GNU General Public License version 2 as |
---|
6 | | - * published by the Free Software Foundation. |
---|
7 | | - * |
---|
8 | | - * Standard functionality for the common clock API. |
---|
9 | 4 | */ |
---|
10 | 5 | #include <linux/module.h> |
---|
11 | 6 | #include <linux/clk-provider.h> |
---|
.. | .. |
---|
69 | 64 | }; |
---|
70 | 65 | EXPORT_SYMBOL_GPL(clk_fixed_factor_ops); |
---|
71 | 66 | |
---|
72 | | -struct clk_hw *clk_hw_register_fixed_factor(struct device *dev, |
---|
73 | | - const char *name, const char *parent_name, unsigned long flags, |
---|
74 | | - unsigned int mult, unsigned int div) |
---|
| 67 | +static struct clk_hw * |
---|
| 68 | +__clk_hw_register_fixed_factor(struct device *dev, struct device_node *np, |
---|
| 69 | + const char *name, const char *parent_name, int index, |
---|
| 70 | + unsigned long flags, unsigned int mult, unsigned int div) |
---|
75 | 71 | { |
---|
76 | 72 | struct clk_fixed_factor *fix; |
---|
77 | | - struct clk_init_data init = {}; |
---|
| 73 | + struct clk_init_data init = { }; |
---|
| 74 | + struct clk_parent_data pdata = { .index = index }; |
---|
78 | 75 | struct clk_hw *hw; |
---|
79 | 76 | int ret; |
---|
80 | 77 | |
---|
.. | .. |
---|
89 | 86 | |
---|
90 | 87 | init.name = name; |
---|
91 | 88 | init.ops = &clk_fixed_factor_ops; |
---|
92 | | - init.flags = flags | CLK_IS_BASIC; |
---|
93 | | - init.parent_names = &parent_name; |
---|
| 89 | + init.flags = flags; |
---|
| 90 | + if (parent_name) |
---|
| 91 | + init.parent_names = &parent_name; |
---|
| 92 | + else |
---|
| 93 | + init.parent_data = &pdata; |
---|
94 | 94 | init.num_parents = 1; |
---|
95 | 95 | |
---|
96 | 96 | hw = &fix->hw; |
---|
97 | | - ret = clk_hw_register(dev, hw); |
---|
| 97 | + if (dev) |
---|
| 98 | + ret = clk_hw_register(dev, hw); |
---|
| 99 | + else |
---|
| 100 | + ret = of_clk_hw_register(np, hw); |
---|
98 | 101 | if (ret) { |
---|
99 | 102 | kfree(fix); |
---|
100 | 103 | hw = ERR_PTR(ret); |
---|
101 | 104 | } |
---|
102 | 105 | |
---|
103 | 106 | return hw; |
---|
| 107 | +} |
---|
| 108 | + |
---|
| 109 | +struct clk_hw *clk_hw_register_fixed_factor(struct device *dev, |
---|
| 110 | + const char *name, const char *parent_name, unsigned long flags, |
---|
| 111 | + unsigned int mult, unsigned int div) |
---|
| 112 | +{ |
---|
| 113 | + return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, -1, |
---|
| 114 | + flags, mult, div); |
---|
104 | 115 | } |
---|
105 | 116 | EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor); |
---|
106 | 117 | |
---|
.. | .. |
---|
148 | 159 | { /* Sentinel */ }, |
---|
149 | 160 | }; |
---|
150 | 161 | |
---|
151 | | -static struct clk *_of_fixed_factor_clk_setup(struct device_node *node) |
---|
| 162 | +static struct clk_hw *_of_fixed_factor_clk_setup(struct device_node *node) |
---|
152 | 163 | { |
---|
153 | | - struct clk *clk; |
---|
| 164 | + struct clk_hw *hw; |
---|
154 | 165 | const char *clk_name = node->name; |
---|
155 | | - const char *parent_name; |
---|
156 | 166 | unsigned long flags = 0; |
---|
157 | 167 | u32 div, mult; |
---|
158 | 168 | int ret; |
---|
159 | 169 | |
---|
160 | 170 | if (of_property_read_u32(node, "clock-div", &div)) { |
---|
161 | | - pr_err("%s Fixed factor clock <%s> must have a clock-div property\n", |
---|
162 | | - __func__, node->name); |
---|
| 171 | + pr_err("%s Fixed factor clock <%pOFn> must have a clock-div property\n", |
---|
| 172 | + __func__, node); |
---|
163 | 173 | return ERR_PTR(-EIO); |
---|
164 | 174 | } |
---|
165 | 175 | |
---|
166 | 176 | if (of_property_read_u32(node, "clock-mult", &mult)) { |
---|
167 | | - pr_err("%s Fixed factor clock <%s> must have a clock-mult property\n", |
---|
168 | | - __func__, node->name); |
---|
| 177 | + pr_err("%s Fixed factor clock <%pOFn> must have a clock-mult property\n", |
---|
| 178 | + __func__, node); |
---|
169 | 179 | return ERR_PTR(-EIO); |
---|
170 | 180 | } |
---|
171 | 181 | |
---|
172 | 182 | of_property_read_string(node, "clock-output-names", &clk_name); |
---|
173 | | - parent_name = of_clk_get_parent_name(node, 0); |
---|
174 | 183 | |
---|
175 | 184 | if (of_match_node(set_rate_parent_matches, node)) |
---|
176 | 185 | flags |= CLK_SET_RATE_PARENT; |
---|
177 | 186 | |
---|
178 | | - clk = clk_register_fixed_factor(NULL, clk_name, parent_name, flags, |
---|
179 | | - mult, div); |
---|
180 | | - if (IS_ERR(clk)) { |
---|
| 187 | + hw = __clk_hw_register_fixed_factor(NULL, node, clk_name, NULL, 0, |
---|
| 188 | + flags, mult, div); |
---|
| 189 | + if (IS_ERR(hw)) { |
---|
181 | 190 | /* |
---|
182 | | - * If parent clock is not registered, registration would fail. |
---|
183 | 191 | * Clear OF_POPULATED flag so that clock registration can be |
---|
184 | 192 | * attempted again from probe function. |
---|
185 | 193 | */ |
---|
186 | 194 | of_node_clear_flag(node, OF_POPULATED); |
---|
187 | | - return clk; |
---|
| 195 | + return ERR_CAST(hw); |
---|
188 | 196 | } |
---|
189 | 197 | |
---|
190 | | - ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); |
---|
| 198 | + ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw); |
---|
191 | 199 | if (ret) { |
---|
192 | | - clk_unregister(clk); |
---|
| 200 | + clk_hw_unregister_fixed_factor(hw); |
---|
193 | 201 | return ERR_PTR(ret); |
---|
194 | 202 | } |
---|
195 | 203 | |
---|
196 | | - return clk; |
---|
| 204 | + return hw; |
---|
197 | 205 | } |
---|
198 | 206 | |
---|
199 | 207 | /** |
---|
200 | 208 | * of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock |
---|
| 209 | + * @node: device node for the clock |
---|
201 | 210 | */ |
---|
202 | 211 | void __init of_fixed_factor_clk_setup(struct device_node *node) |
---|
203 | 212 | { |
---|
.. | .. |
---|
208 | 217 | |
---|
209 | 218 | static int of_fixed_factor_clk_remove(struct platform_device *pdev) |
---|
210 | 219 | { |
---|
211 | | - struct clk *clk = platform_get_drvdata(pdev); |
---|
| 220 | + struct clk_hw *clk = platform_get_drvdata(pdev); |
---|
212 | 221 | |
---|
213 | 222 | of_clk_del_provider(pdev->dev.of_node); |
---|
214 | | - clk_unregister_fixed_factor(clk); |
---|
| 223 | + clk_hw_unregister_fixed_factor(clk); |
---|
215 | 224 | |
---|
216 | 225 | return 0; |
---|
217 | 226 | } |
---|
218 | 227 | |
---|
219 | 228 | static int of_fixed_factor_clk_probe(struct platform_device *pdev) |
---|
220 | 229 | { |
---|
221 | | - struct clk *clk; |
---|
| 230 | + struct clk_hw *clk; |
---|
222 | 231 | |
---|
223 | 232 | /* |
---|
224 | 233 | * This function is not executed when of_fixed_factor_clk_setup |
---|