Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0
2 : : /*
3 : : * Copyright (C) 2013 - 2014 Texas Instruments Incorporated - http://www.ti.com
4 : : *
5 : : * Authors:
6 : : * Jyri Sarha <jsarha@ti.com>
7 : : * Sergej Sawazki <ce3a@gmx.de>
8 : : *
9 : : * Gpio controlled clock implementation
10 : : */
11 : :
12 : : #include <linux/clk-provider.h>
13 : : #include <linux/export.h>
14 : : #include <linux/slab.h>
15 : : #include <linux/gpio/consumer.h>
16 : : #include <linux/err.h>
17 : : #include <linux/device.h>
18 : : #include <linux/platform_device.h>
19 : : #include <linux/of_device.h>
20 : :
21 : : /**
22 : : * DOC: basic gpio gated clock which can be enabled and disabled
23 : : * with gpio output
24 : : * Traits of this clock:
25 : : * prepare - clk_(un)prepare only ensures parent is (un)prepared
26 : : * enable - clk_enable and clk_disable are functional & control gpio
27 : : * rate - inherits rate from parent. No clk_set_rate support
28 : : * parent - fixed parent. No clk_set_parent support
29 : : */
30 : :
31 : 0 : static int clk_gpio_gate_enable(struct clk_hw *hw)
32 : : {
33 : : struct clk_gpio *clk = to_clk_gpio(hw);
34 : :
35 : 0 : gpiod_set_value(clk->gpiod, 1);
36 : :
37 : 0 : return 0;
38 : : }
39 : :
40 : 0 : static void clk_gpio_gate_disable(struct clk_hw *hw)
41 : : {
42 : : struct clk_gpio *clk = to_clk_gpio(hw);
43 : :
44 : 0 : gpiod_set_value(clk->gpiod, 0);
45 : 0 : }
46 : :
47 : 0 : static int clk_gpio_gate_is_enabled(struct clk_hw *hw)
48 : : {
49 : : struct clk_gpio *clk = to_clk_gpio(hw);
50 : :
51 : 0 : return gpiod_get_value(clk->gpiod);
52 : : }
53 : :
54 : : const struct clk_ops clk_gpio_gate_ops = {
55 : : .enable = clk_gpio_gate_enable,
56 : : .disable = clk_gpio_gate_disable,
57 : : .is_enabled = clk_gpio_gate_is_enabled,
58 : : };
59 : : EXPORT_SYMBOL_GPL(clk_gpio_gate_ops);
60 : :
61 : 0 : static int clk_sleeping_gpio_gate_prepare(struct clk_hw *hw)
62 : : {
63 : : struct clk_gpio *clk = to_clk_gpio(hw);
64 : :
65 : 0 : gpiod_set_value_cansleep(clk->gpiod, 1);
66 : :
67 : 0 : return 0;
68 : : }
69 : :
70 : 0 : static void clk_sleeping_gpio_gate_unprepare(struct clk_hw *hw)
71 : : {
72 : : struct clk_gpio *clk = to_clk_gpio(hw);
73 : :
74 : 0 : gpiod_set_value_cansleep(clk->gpiod, 0);
75 : 0 : }
76 : :
77 : 0 : static int clk_sleeping_gpio_gate_is_prepared(struct clk_hw *hw)
78 : : {
79 : : struct clk_gpio *clk = to_clk_gpio(hw);
80 : :
81 : 0 : return gpiod_get_value_cansleep(clk->gpiod);
82 : : }
83 : :
84 : : static const struct clk_ops clk_sleeping_gpio_gate_ops = {
85 : : .prepare = clk_sleeping_gpio_gate_prepare,
86 : : .unprepare = clk_sleeping_gpio_gate_unprepare,
87 : : .is_prepared = clk_sleeping_gpio_gate_is_prepared,
88 : : };
89 : :
90 : : /**
91 : : * DOC: basic clock multiplexer which can be controlled with a gpio output
92 : : * Traits of this clock:
93 : : * prepare - clk_prepare only ensures that parents are prepared
94 : : * rate - rate is only affected by parent switching. No clk_set_rate support
95 : : * parent - parent is adjustable through clk_set_parent
96 : : */
97 : :
98 : 0 : static u8 clk_gpio_mux_get_parent(struct clk_hw *hw)
99 : : {
100 : : struct clk_gpio *clk = to_clk_gpio(hw);
101 : :
102 : 0 : return gpiod_get_value_cansleep(clk->gpiod);
103 : : }
104 : :
105 : 0 : static int clk_gpio_mux_set_parent(struct clk_hw *hw, u8 index)
106 : : {
107 : : struct clk_gpio *clk = to_clk_gpio(hw);
108 : :
109 : 0 : gpiod_set_value_cansleep(clk->gpiod, index);
110 : :
111 : 0 : return 0;
112 : : }
113 : :
114 : : const struct clk_ops clk_gpio_mux_ops = {
115 : : .get_parent = clk_gpio_mux_get_parent,
116 : : .set_parent = clk_gpio_mux_set_parent,
117 : : .determine_rate = __clk_mux_determine_rate,
118 : : };
119 : : EXPORT_SYMBOL_GPL(clk_gpio_mux_ops);
120 : :
121 : 0 : static struct clk_hw *clk_register_gpio(struct device *dev, const char *name,
122 : : const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod,
123 : : unsigned long flags, const struct clk_ops *clk_gpio_ops)
124 : : {
125 : : struct clk_gpio *clk_gpio;
126 : : struct clk_hw *hw;
127 : 0 : struct clk_init_data init = {};
128 : : int err;
129 : :
130 [ # # ]: 0 : if (dev)
131 : : clk_gpio = devm_kzalloc(dev, sizeof(*clk_gpio), GFP_KERNEL);
132 : : else
133 : 0 : clk_gpio = kzalloc(sizeof(*clk_gpio), GFP_KERNEL);
134 : :
135 [ # # ]: 0 : if (!clk_gpio)
136 : : return ERR_PTR(-ENOMEM);
137 : :
138 : 0 : init.name = name;
139 : 0 : init.ops = clk_gpio_ops;
140 : 0 : init.flags = flags;
141 : 0 : init.parent_names = parent_names;
142 : 0 : init.num_parents = num_parents;
143 : :
144 : 0 : clk_gpio->gpiod = gpiod;
145 : 0 : clk_gpio->hw.init = &init;
146 : :
147 : 0 : hw = &clk_gpio->hw;
148 [ # # ]: 0 : if (dev)
149 : 0 : err = devm_clk_hw_register(dev, hw);
150 : : else
151 : 0 : err = clk_hw_register(NULL, hw);
152 : :
153 [ # # ]: 0 : if (!err)
154 : : return hw;
155 : :
156 [ # # ]: 0 : if (!dev) {
157 : 0 : kfree(clk_gpio);
158 : : }
159 : :
160 : 0 : return ERR_PTR(err);
161 : : }
162 : :
163 : : /**
164 : : * clk_hw_register_gpio_gate - register a gpio clock gate with the clock
165 : : * framework
166 : : * @dev: device that is registering this clock
167 : : * @name: name of this clock
168 : : * @parent_name: name of this clock's parent
169 : : * @gpiod: gpio descriptor to gate this clock
170 : : * @flags: clock flags
171 : : */
172 : 0 : struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name,
173 : : const char *parent_name, struct gpio_desc *gpiod,
174 : : unsigned long flags)
175 : : {
176 : : const struct clk_ops *ops;
177 : :
178 [ # # ]: 0 : if (gpiod_cansleep(gpiod))
179 : : ops = &clk_sleeping_gpio_gate_ops;
180 : : else
181 : : ops = &clk_gpio_gate_ops;
182 : :
183 [ # # ]: 0 : return clk_register_gpio(dev, name,
184 : 0 : (parent_name ? &parent_name : NULL),
185 : : (parent_name ? 1 : 0), gpiod, flags, ops);
186 : : }
187 : : EXPORT_SYMBOL_GPL(clk_hw_register_gpio_gate);
188 : :
189 : 0 : struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
190 : : const char *parent_name, struct gpio_desc *gpiod,
191 : : unsigned long flags)
192 : : {
193 : : struct clk_hw *hw;
194 : :
195 : 0 : hw = clk_hw_register_gpio_gate(dev, name, parent_name, gpiod, flags);
196 [ # # # # ]: 0 : if (IS_ERR(hw))
197 : : return ERR_CAST(hw);
198 : 0 : return hw->clk;
199 : : }
200 : : EXPORT_SYMBOL_GPL(clk_register_gpio_gate);
201 : :
202 : : /**
203 : : * clk_hw_register_gpio_mux - register a gpio clock mux with the clock framework
204 : : * @dev: device that is registering this clock
205 : : * @name: name of this clock
206 : : * @parent_names: names of this clock's parents
207 : : * @num_parents: number of parents listed in @parent_names
208 : : * @gpiod: gpio descriptor to gate this clock
209 : : * @flags: clock flags
210 : : */
211 : 0 : struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, const char *name,
212 : : const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod,
213 : : unsigned long flags)
214 : : {
215 [ # # ]: 0 : if (num_parents != 2) {
216 : 0 : pr_err("mux-clock %s must have 2 parents\n", name);
217 : 0 : return ERR_PTR(-EINVAL);
218 : : }
219 : :
220 : 0 : return clk_register_gpio(dev, name, parent_names, num_parents,
221 : : gpiod, flags, &clk_gpio_mux_ops);
222 : : }
223 : : EXPORT_SYMBOL_GPL(clk_hw_register_gpio_mux);
224 : :
225 : 0 : struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
226 : : const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod,
227 : : unsigned long flags)
228 : : {
229 : : struct clk_hw *hw;
230 : :
231 : 0 : hw = clk_hw_register_gpio_mux(dev, name, parent_names, num_parents,
232 : : gpiod, flags);
233 [ # # # # ]: 0 : if (IS_ERR(hw))
234 : : return ERR_CAST(hw);
235 : 0 : return hw->clk;
236 : : }
237 : : EXPORT_SYMBOL_GPL(clk_register_gpio_mux);
238 : :
239 : 0 : static int gpio_clk_driver_probe(struct platform_device *pdev)
240 : : {
241 : 0 : struct device_node *node = pdev->dev.of_node;
242 : : const char **parent_names, *gpio_name;
243 : : unsigned int num_parents;
244 : : struct gpio_desc *gpiod;
245 : : struct clk *clk;
246 : : bool is_mux;
247 : : int ret;
248 : :
249 : 0 : num_parents = of_clk_get_parent_count(node);
250 [ # # ]: 0 : if (num_parents) {
251 : 0 : parent_names = devm_kcalloc(&pdev->dev, num_parents,
252 : : sizeof(char *), GFP_KERNEL);
253 [ # # ]: 0 : if (!parent_names)
254 : : return -ENOMEM;
255 : :
256 : 0 : of_clk_parent_fill(node, parent_names, num_parents);
257 : : } else {
258 : : parent_names = NULL;
259 : : }
260 : :
261 : 0 : is_mux = of_device_is_compatible(node, "gpio-mux-clock");
262 : :
263 [ # # ]: 0 : gpio_name = is_mux ? "select" : "enable";
264 : 0 : gpiod = devm_gpiod_get(&pdev->dev, gpio_name, GPIOD_OUT_LOW);
265 [ # # ]: 0 : if (IS_ERR(gpiod)) {
266 : : ret = PTR_ERR(gpiod);
267 [ # # ]: 0 : if (ret == -EPROBE_DEFER)
268 : : pr_debug("%pOFn: %s: GPIOs not yet available, retry later\n",
269 : : node, __func__);
270 : : else
271 : 0 : pr_err("%pOFn: %s: Can't get '%s' named GPIO property\n",
272 : : node, __func__,
273 : : gpio_name);
274 : 0 : return ret;
275 : : }
276 : :
277 [ # # ]: 0 : if (is_mux)
278 : 0 : clk = clk_register_gpio_mux(&pdev->dev, node->name,
279 : : parent_names, num_parents, gpiod, 0);
280 : : else
281 [ # # ]: 0 : clk = clk_register_gpio_gate(&pdev->dev, node->name,
282 : : parent_names ? parent_names[0] : NULL, gpiod,
283 : : CLK_SET_RATE_PARENT);
284 [ # # ]: 0 : if (IS_ERR(clk))
285 : 0 : return PTR_ERR(clk);
286 : :
287 : 0 : return of_clk_add_provider(node, of_clk_src_simple_get, clk);
288 : : }
289 : :
290 : : static const struct of_device_id gpio_clk_match_table[] = {
291 : : { .compatible = "gpio-mux-clock" },
292 : : { .compatible = "gpio-gate-clock" },
293 : : { }
294 : : };
295 : :
296 : : static struct platform_driver gpio_clk_driver = {
297 : : .probe = gpio_clk_driver_probe,
298 : : .driver = {
299 : : .name = "gpio-clk",
300 : : .of_match_table = gpio_clk_match_table,
301 : : },
302 : : };
303 : 207 : builtin_platform_driver(gpio_clk_driver);
|