xref: /openbmc/linux/drivers/clk/clk-fixed-factor.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
1e1bd55e5SStephen Boyd // SPDX-License-Identifier: GPL-2.0
2f0948f59SSascha Hauer /*
3f0948f59SSascha Hauer  * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
4f0948f59SSascha Hauer  */
5f0948f59SSascha Hauer #include <linux/module.h>
6f0948f59SSascha Hauer #include <linux/clk-provider.h>
7f0948f59SSascha Hauer #include <linux/slab.h>
8f0948f59SSascha Hauer #include <linux/err.h>
979b16641SGregory CLEMENT #include <linux/of.h>
10971451b3SRicardo Ribalda Delgado #include <linux/platform_device.h>
11f0948f59SSascha Hauer 
12f0948f59SSascha Hauer /*
13f0948f59SSascha Hauer  * DOC: basic fixed multiplier and divider clock that cannot gate
14f0948f59SSascha Hauer  *
15f0948f59SSascha Hauer  * Traits of this clock:
16f0948f59SSascha Hauer  * prepare - clk_prepare only ensures that parents are prepared
17f0948f59SSascha Hauer  * enable - clk_enable only ensures that parents are enabled
18f0948f59SSascha Hauer  * rate - rate is fixed.  clk->rate = parent->rate / div * mult
19f0948f59SSascha Hauer  * parent - fixed parent.  No clk_set_parent support
20f0948f59SSascha Hauer  */
21f0948f59SSascha Hauer 
clk_factor_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)22f0948f59SSascha Hauer static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
23f0948f59SSascha Hauer 		unsigned long parent_rate)
24f0948f59SSascha Hauer {
25f0948f59SSascha Hauer 	struct clk_fixed_factor *fix = to_clk_fixed_factor(hw);
26bab53301SHaojian Zhuang 	unsigned long long int rate;
27f0948f59SSascha Hauer 
28bab53301SHaojian Zhuang 	rate = (unsigned long long int)parent_rate * fix->mult;
29bab53301SHaojian Zhuang 	do_div(rate, fix->div);
30bab53301SHaojian Zhuang 	return (unsigned long)rate;
31f0948f59SSascha Hauer }
32f0948f59SSascha Hauer 
clk_factor_round_rate(struct clk_hw * hw,unsigned long rate,unsigned long * prate)33f0948f59SSascha Hauer static long clk_factor_round_rate(struct clk_hw *hw, unsigned long rate,
34f0948f59SSascha Hauer 				unsigned long *prate)
35f0948f59SSascha Hauer {
36f0948f59SSascha Hauer 	struct clk_fixed_factor *fix = to_clk_fixed_factor(hw);
37f0948f59SSascha Hauer 
3898d8a60eSStephen Boyd 	if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) {
39f0948f59SSascha Hauer 		unsigned long best_parent;
40f0948f59SSascha Hauer 
41f0948f59SSascha Hauer 		best_parent = (rate / fix->mult) * fix->div;
422f508a95SStephen Boyd 		*prate = clk_hw_round_rate(clk_hw_get_parent(hw), best_parent);
43f0948f59SSascha Hauer 	}
44f0948f59SSascha Hauer 
45f0948f59SSascha Hauer 	return (*prate / fix->div) * fix->mult;
46f0948f59SSascha Hauer }
47f0948f59SSascha Hauer 
clk_factor_set_rate(struct clk_hw * hw,unsigned long rate,unsigned long parent_rate)48f0948f59SSascha Hauer static int clk_factor_set_rate(struct clk_hw *hw, unsigned long rate,
49f0948f59SSascha Hauer 				unsigned long parent_rate)
50f0948f59SSascha Hauer {
513037e9eaSDaniel Thompson 	/*
523037e9eaSDaniel Thompson 	 * We must report success but we can do so unconditionally because
533037e9eaSDaniel Thompson 	 * clk_factor_round_rate returns values that ensure this call is a
543037e9eaSDaniel Thompson 	 * nop.
553037e9eaSDaniel Thompson 	 */
563037e9eaSDaniel Thompson 
57f0948f59SSascha Hauer 	return 0;
58f0948f59SSascha Hauer }
59f0948f59SSascha Hauer 
603037e9eaSDaniel Thompson const struct clk_ops clk_fixed_factor_ops = {
61f0948f59SSascha Hauer 	.round_rate = clk_factor_round_rate,
62f0948f59SSascha Hauer 	.set_rate = clk_factor_set_rate,
63f0948f59SSascha Hauer 	.recalc_rate = clk_factor_recalc_rate,
64f0948f59SSascha Hauer };
65f0948f59SSascha Hauer EXPORT_SYMBOL_GPL(clk_fixed_factor_ops);
66f0948f59SSascha Hauer 
devm_clk_hw_register_fixed_factor_release(struct device * dev,void * res)670b9266d2SDaniel Palmer static void devm_clk_hw_register_fixed_factor_release(struct device *dev, void *res)
680b9266d2SDaniel Palmer {
6950ce6826SDmitry Baryshkov 	struct clk_fixed_factor *fix = res;
7050ce6826SDmitry Baryshkov 
7150ce6826SDmitry Baryshkov 	/*
7250ce6826SDmitry Baryshkov 	 * We can not use clk_hw_unregister_fixed_factor, since it will kfree()
7350ce6826SDmitry Baryshkov 	 * the hw, resulting in double free. Just unregister the hw and let
7450ce6826SDmitry Baryshkov 	 * devres code kfree() it.
7550ce6826SDmitry Baryshkov 	 */
7650ce6826SDmitry Baryshkov 	clk_hw_unregister(&fix->hw);
770b9266d2SDaniel Palmer }
780b9266d2SDaniel Palmer 
79ecbf3f17SStephen Boyd static struct clk_hw *
__clk_hw_register_fixed_factor(struct device * dev,struct device_node * np,const char * name,const char * parent_name,const struct clk_hw * parent_hw,int index,unsigned long flags,unsigned int mult,unsigned int div,bool devm)80ecbf3f17SStephen Boyd __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
816ebd5247SMarijn Suijten 		const char *name, const char *parent_name,
826ebd5247SMarijn Suijten 		const struct clk_hw *parent_hw, int index,
830b9266d2SDaniel Palmer 		unsigned long flags, unsigned int mult, unsigned int div,
840b9266d2SDaniel Palmer 		bool devm)
85f0948f59SSascha Hauer {
86f0948f59SSascha Hauer 	struct clk_fixed_factor *fix;
87e4818d61SStephen Boyd 	struct clk_init_data init = { };
88ecbf3f17SStephen Boyd 	struct clk_parent_data pdata = { .index = index };
890759ac8aSStephen Boyd 	struct clk_hw *hw;
900759ac8aSStephen Boyd 	int ret;
91f0948f59SSascha Hauer 
920b9266d2SDaniel Palmer 	/* You can't use devm without a dev */
930b9266d2SDaniel Palmer 	if (devm && !dev)
940b9266d2SDaniel Palmer 		return ERR_PTR(-EINVAL);
950b9266d2SDaniel Palmer 
960b9266d2SDaniel Palmer 	if (devm)
970b9266d2SDaniel Palmer 		fix = devres_alloc(devm_clk_hw_register_fixed_factor_release,
980b9266d2SDaniel Palmer 				sizeof(*fix), GFP_KERNEL);
990b9266d2SDaniel Palmer 	else
100f0948f59SSascha Hauer 		fix = kmalloc(sizeof(*fix), GFP_KERNEL);
101d122db7eSStephen Boyd 	if (!fix)
102f0948f59SSascha Hauer 		return ERR_PTR(-ENOMEM);
103f0948f59SSascha Hauer 
104f0948f59SSascha Hauer 	/* struct clk_fixed_factor assignments */
105f0948f59SSascha Hauer 	fix->mult = mult;
106f0948f59SSascha Hauer 	fix->div = div;
107f0948f59SSascha Hauer 	fix->hw.init = &init;
108f0948f59SSascha Hauer 
109f0948f59SSascha Hauer 	init.name = name;
110f0948f59SSascha Hauer 	init.ops = &clk_fixed_factor_ops;
11190b6c5c7SStephen Boyd 	init.flags = flags;
112ecbf3f17SStephen Boyd 	if (parent_name)
113f0948f59SSascha Hauer 		init.parent_names = &parent_name;
1146ebd5247SMarijn Suijten 	else if (parent_hw)
1156ebd5247SMarijn Suijten 		init.parent_hws = &parent_hw;
116ecbf3f17SStephen Boyd 	else
117ecbf3f17SStephen Boyd 		init.parent_data = &pdata;
118f0948f59SSascha Hauer 	init.num_parents = 1;
119f0948f59SSascha Hauer 
1200759ac8aSStephen Boyd 	hw = &fix->hw;
121ecbf3f17SStephen Boyd 	if (dev)
1220759ac8aSStephen Boyd 		ret = clk_hw_register(dev, hw);
123ecbf3f17SStephen Boyd 	else
124ecbf3f17SStephen Boyd 		ret = of_clk_hw_register(np, hw);
1250759ac8aSStephen Boyd 	if (ret) {
1260b9266d2SDaniel Palmer 		if (devm)
1270b9266d2SDaniel Palmer 			devres_free(fix);
1280b9266d2SDaniel Palmer 		else
129f0948f59SSascha Hauer 			kfree(fix);
1300759ac8aSStephen Boyd 		hw = ERR_PTR(ret);
1310b9266d2SDaniel Palmer 	} else if (devm)
1320b9266d2SDaniel Palmer 		devres_add(dev, fix);
133f0948f59SSascha Hauer 
1340759ac8aSStephen Boyd 	return hw;
1350759ac8aSStephen Boyd }
136ecbf3f17SStephen Boyd 
1370c125f87SMarek Vasut /**
1380c125f87SMarek Vasut  * devm_clk_hw_register_fixed_factor_index - Register a fixed factor clock with
1390c125f87SMarek Vasut  * parent from DT index
1400c125f87SMarek Vasut  * @dev: device that is registering this clock
1410c125f87SMarek Vasut  * @name: name of this clock
1420c125f87SMarek Vasut  * @index: index of phandle in @dev 'clocks' property
1430c125f87SMarek Vasut  * @flags: fixed factor flags
1440c125f87SMarek Vasut  * @mult: multiplier
1450c125f87SMarek Vasut  * @div: divider
1460c125f87SMarek Vasut  *
1470c125f87SMarek Vasut  * Return: Pointer to fixed factor clk_hw structure that was registered or
1480c125f87SMarek Vasut  * an error pointer.
1490c125f87SMarek Vasut  */
devm_clk_hw_register_fixed_factor_index(struct device * dev,const char * name,unsigned int index,unsigned long flags,unsigned int mult,unsigned int div)1500c125f87SMarek Vasut struct clk_hw *devm_clk_hw_register_fixed_factor_index(struct device *dev,
1510c125f87SMarek Vasut 		const char *name, unsigned int index, unsigned long flags,
1520c125f87SMarek Vasut 		unsigned int mult, unsigned int div)
1530c125f87SMarek Vasut {
1546ebd5247SMarijn Suijten 	return __clk_hw_register_fixed_factor(dev, NULL, name, NULL, NULL, index,
1550c125f87SMarek Vasut 					      flags, mult, div, true);
1560c125f87SMarek Vasut }
1570c125f87SMarek Vasut EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor_index);
1580c125f87SMarek Vasut 
1596ebd5247SMarijn Suijten /**
1606ebd5247SMarijn Suijten  * devm_clk_hw_register_fixed_factor_parent_hw - Register a fixed factor clock with
1616ebd5247SMarijn Suijten  * pointer to parent clock
1626ebd5247SMarijn Suijten  * @dev: device that is registering this clock
1636ebd5247SMarijn Suijten  * @name: name of this clock
1646ebd5247SMarijn Suijten  * @parent_hw: pointer to parent clk
1656ebd5247SMarijn Suijten  * @flags: fixed factor flags
1666ebd5247SMarijn Suijten  * @mult: multiplier
1676ebd5247SMarijn Suijten  * @div: divider
1686ebd5247SMarijn Suijten  *
1696ebd5247SMarijn Suijten  * Return: Pointer to fixed factor clk_hw structure that was registered or
1706ebd5247SMarijn Suijten  * an error pointer.
1716ebd5247SMarijn Suijten  */
devm_clk_hw_register_fixed_factor_parent_hw(struct device * dev,const char * name,const struct clk_hw * parent_hw,unsigned long flags,unsigned int mult,unsigned int div)1726ebd5247SMarijn Suijten struct clk_hw *devm_clk_hw_register_fixed_factor_parent_hw(struct device *dev,
1736ebd5247SMarijn Suijten 		const char *name, const struct clk_hw *parent_hw,
1746ebd5247SMarijn Suijten 		unsigned long flags, unsigned int mult, unsigned int div)
1756ebd5247SMarijn Suijten {
1766ebd5247SMarijn Suijten 	return __clk_hw_register_fixed_factor(dev, NULL, name, NULL, parent_hw,
1776ebd5247SMarijn Suijten 					      -1, flags, mult, div, true);
1786ebd5247SMarijn Suijten }
1796ebd5247SMarijn Suijten EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor_parent_hw);
1806ebd5247SMarijn Suijten 
clk_hw_register_fixed_factor_parent_hw(struct device * dev,const char * name,const struct clk_hw * parent_hw,unsigned long flags,unsigned int mult,unsigned int div)1816ebd5247SMarijn Suijten struct clk_hw *clk_hw_register_fixed_factor_parent_hw(struct device *dev,
1826ebd5247SMarijn Suijten 		const char *name, const struct clk_hw *parent_hw,
1836ebd5247SMarijn Suijten 		unsigned long flags, unsigned int mult, unsigned int div)
1846ebd5247SMarijn Suijten {
1856ebd5247SMarijn Suijten 	return __clk_hw_register_fixed_factor(dev, NULL, name, NULL,
1866ebd5247SMarijn Suijten 					      parent_hw, -1, flags, mult, div,
1876ebd5247SMarijn Suijten 					      false);
1886ebd5247SMarijn Suijten }
1896ebd5247SMarijn Suijten EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor_parent_hw);
1906ebd5247SMarijn Suijten 
clk_hw_register_fixed_factor(struct device * dev,const char * name,const char * parent_name,unsigned long flags,unsigned int mult,unsigned int div)191ecbf3f17SStephen Boyd struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
192ecbf3f17SStephen Boyd 		const char *name, const char *parent_name, unsigned long flags,
193ecbf3f17SStephen Boyd 		unsigned int mult, unsigned int div)
194ecbf3f17SStephen Boyd {
1956ebd5247SMarijn Suijten 	return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, NULL, -1,
1960b9266d2SDaniel Palmer 					      flags, mult, div, false);
197ecbf3f17SStephen Boyd }
1980759ac8aSStephen Boyd EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor);
1990759ac8aSStephen Boyd 
clk_register_fixed_factor(struct device * dev,const char * name,const char * parent_name,unsigned long flags,unsigned int mult,unsigned int div)2000759ac8aSStephen Boyd struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
2010759ac8aSStephen Boyd 		const char *parent_name, unsigned long flags,
2020759ac8aSStephen Boyd 		unsigned int mult, unsigned int div)
2030759ac8aSStephen Boyd {
2040759ac8aSStephen Boyd 	struct clk_hw *hw;
2050759ac8aSStephen Boyd 
2060759ac8aSStephen Boyd 	hw = clk_hw_register_fixed_factor(dev, name, parent_name, flags, mult,
2070759ac8aSStephen Boyd 					  div);
2080759ac8aSStephen Boyd 	if (IS_ERR(hw))
2090759ac8aSStephen Boyd 		return ERR_CAST(hw);
2100759ac8aSStephen Boyd 	return hw->clk;
211f0948f59SSascha Hauer }
2125cfe10bbSMike Turquette EXPORT_SYMBOL_GPL(clk_register_fixed_factor);
2135cfe10bbSMike Turquette 
clk_unregister_fixed_factor(struct clk * clk)214cbf9591fSMasahiro Yamada void clk_unregister_fixed_factor(struct clk *clk)
215cbf9591fSMasahiro Yamada {
216cbf9591fSMasahiro Yamada 	struct clk_hw *hw;
217cbf9591fSMasahiro Yamada 
218cbf9591fSMasahiro Yamada 	hw = __clk_get_hw(clk);
219cbf9591fSMasahiro Yamada 	if (!hw)
220cbf9591fSMasahiro Yamada 		return;
221cbf9591fSMasahiro Yamada 
222cbf9591fSMasahiro Yamada 	clk_unregister(clk);
223cbf9591fSMasahiro Yamada 	kfree(to_clk_fixed_factor(hw));
224cbf9591fSMasahiro Yamada }
225cbf9591fSMasahiro Yamada EXPORT_SYMBOL_GPL(clk_unregister_fixed_factor);
226cbf9591fSMasahiro Yamada 
clk_hw_unregister_fixed_factor(struct clk_hw * hw)2270759ac8aSStephen Boyd void clk_hw_unregister_fixed_factor(struct clk_hw *hw)
2280759ac8aSStephen Boyd {
2290759ac8aSStephen Boyd 	struct clk_fixed_factor *fix;
2300759ac8aSStephen Boyd 
2310759ac8aSStephen Boyd 	fix = to_clk_fixed_factor(hw);
2320759ac8aSStephen Boyd 
2330759ac8aSStephen Boyd 	clk_hw_unregister(hw);
2340759ac8aSStephen Boyd 	kfree(fix);
2350759ac8aSStephen Boyd }
2360759ac8aSStephen Boyd EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_factor);
2370759ac8aSStephen Boyd 
devm_clk_hw_register_fixed_factor(struct device * dev,const char * name,const char * parent_name,unsigned long flags,unsigned int mult,unsigned int div)2380b9266d2SDaniel Palmer struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev,
2390b9266d2SDaniel Palmer 		const char *name, const char *parent_name, unsigned long flags,
2400b9266d2SDaniel Palmer 		unsigned int mult, unsigned int div)
2410b9266d2SDaniel Palmer {
2426ebd5247SMarijn Suijten 	return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, NULL, -1,
2430b9266d2SDaniel Palmer 			flags, mult, div, true);
2440b9266d2SDaniel Palmer }
2450b9266d2SDaniel Palmer EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor);
2460b9266d2SDaniel Palmer 
24779b16641SGregory CLEMENT #ifdef CONFIG_OF
_of_fixed_factor_clk_setup(struct device_node * node)248ecbf3f17SStephen Boyd static struct clk_hw *_of_fixed_factor_clk_setup(struct device_node *node)
24979b16641SGregory CLEMENT {
250ecbf3f17SStephen Boyd 	struct clk_hw *hw;
25179b16641SGregory CLEMENT 	const char *clk_name = node->name;
25279b16641SGregory CLEMENT 	u32 div, mult;
253971451b3SRicardo Ribalda Delgado 	int ret;
25479b16641SGregory CLEMENT 
25579b16641SGregory CLEMENT 	if (of_property_read_u32(node, "clock-div", &div)) {
256e665f029SRob Herring 		pr_err("%s Fixed factor clock <%pOFn> must have a clock-div property\n",
257e665f029SRob Herring 			__func__, node);
258971451b3SRicardo Ribalda Delgado 		return ERR_PTR(-EIO);
25979b16641SGregory CLEMENT 	}
26079b16641SGregory CLEMENT 
26179b16641SGregory CLEMENT 	if (of_property_read_u32(node, "clock-mult", &mult)) {
262e665f029SRob Herring 		pr_err("%s Fixed factor clock <%pOFn> must have a clock-mult property\n",
263e665f029SRob Herring 			__func__, node);
264971451b3SRicardo Ribalda Delgado 		return ERR_PTR(-EIO);
26579b16641SGregory CLEMENT 	}
26679b16641SGregory CLEMENT 
26779b16641SGregory CLEMENT 	of_property_read_string(node, "clock-output-names", &clk_name);
26879b16641SGregory CLEMENT 
2696ebd5247SMarijn Suijten 	hw = __clk_hw_register_fixed_factor(NULL, node, clk_name, NULL, NULL, 0,
270c33ed612SSamuel Holland 					    0, mult, div, false);
271ecbf3f17SStephen Boyd 	if (IS_ERR(hw)) {
272f6dab423SRajan Vaja 		/*
273f6dab423SRajan Vaja 		 * Clear OF_POPULATED flag so that clock registration can be
274f6dab423SRajan Vaja 		 * attempted again from probe function.
275f6dab423SRajan Vaja 		 */
276f6dab423SRajan Vaja 		of_node_clear_flag(node, OF_POPULATED);
277ecbf3f17SStephen Boyd 		return ERR_CAST(hw);
278f6dab423SRajan Vaja 	}
279971451b3SRicardo Ribalda Delgado 
280ecbf3f17SStephen Boyd 	ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
281971451b3SRicardo Ribalda Delgado 	if (ret) {
282ecbf3f17SStephen Boyd 		clk_hw_unregister_fixed_factor(hw);
283971451b3SRicardo Ribalda Delgado 		return ERR_PTR(ret);
284971451b3SRicardo Ribalda Delgado 	}
285971451b3SRicardo Ribalda Delgado 
286ecbf3f17SStephen Boyd 	return hw;
287971451b3SRicardo Ribalda Delgado }
288971451b3SRicardo Ribalda Delgado 
289971451b3SRicardo Ribalda Delgado /**
290971451b3SRicardo Ribalda Delgado  * of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock
29152ba4fa4SKrzysztof Kozlowski  * @node:	device node for the clock
292971451b3SRicardo Ribalda Delgado  */
of_fixed_factor_clk_setup(struct device_node * node)293971451b3SRicardo Ribalda Delgado void __init of_fixed_factor_clk_setup(struct device_node *node)
294971451b3SRicardo Ribalda Delgado {
295971451b3SRicardo Ribalda Delgado 	_of_fixed_factor_clk_setup(node);
29679b16641SGregory CLEMENT }
29779b16641SGregory CLEMENT CLK_OF_DECLARE(fixed_factor_clk, "fixed-factor-clock",
29879b16641SGregory CLEMENT 		of_fixed_factor_clk_setup);
299971451b3SRicardo Ribalda Delgado 
of_fixed_factor_clk_remove(struct platform_device * pdev)300*27237f4bSUwe Kleine-König static void of_fixed_factor_clk_remove(struct platform_device *pdev)
301971451b3SRicardo Ribalda Delgado {
302ecbf3f17SStephen Boyd 	struct clk_hw *clk = platform_get_drvdata(pdev);
303971451b3SRicardo Ribalda Delgado 
304f98e8a57SRicardo Ribalda Delgado 	of_clk_del_provider(pdev->dev.of_node);
305ecbf3f17SStephen Boyd 	clk_hw_unregister_fixed_factor(clk);
306971451b3SRicardo Ribalda Delgado }
307971451b3SRicardo Ribalda Delgado 
of_fixed_factor_clk_probe(struct platform_device * pdev)308971451b3SRicardo Ribalda Delgado static int of_fixed_factor_clk_probe(struct platform_device *pdev)
309971451b3SRicardo Ribalda Delgado {
310ecbf3f17SStephen Boyd 	struct clk_hw *clk;
311971451b3SRicardo Ribalda Delgado 
312971451b3SRicardo Ribalda Delgado 	/*
313971451b3SRicardo Ribalda Delgado 	 * This function is not executed when of_fixed_factor_clk_setup
314971451b3SRicardo Ribalda Delgado 	 * succeeded.
315971451b3SRicardo Ribalda Delgado 	 */
316971451b3SRicardo Ribalda Delgado 	clk = _of_fixed_factor_clk_setup(pdev->dev.of_node);
317971451b3SRicardo Ribalda Delgado 	if (IS_ERR(clk))
318971451b3SRicardo Ribalda Delgado 		return PTR_ERR(clk);
319971451b3SRicardo Ribalda Delgado 
320971451b3SRicardo Ribalda Delgado 	platform_set_drvdata(pdev, clk);
321971451b3SRicardo Ribalda Delgado 
322971451b3SRicardo Ribalda Delgado 	return 0;
323971451b3SRicardo Ribalda Delgado }
324971451b3SRicardo Ribalda Delgado 
325971451b3SRicardo Ribalda Delgado static const struct of_device_id of_fixed_factor_clk_ids[] = {
326971451b3SRicardo Ribalda Delgado 	{ .compatible = "fixed-factor-clock" },
327971451b3SRicardo Ribalda Delgado 	{ }
328971451b3SRicardo Ribalda Delgado };
329971451b3SRicardo Ribalda Delgado MODULE_DEVICE_TABLE(of, of_fixed_factor_clk_ids);
330971451b3SRicardo Ribalda Delgado 
331971451b3SRicardo Ribalda Delgado static struct platform_driver of_fixed_factor_clk_driver = {
332971451b3SRicardo Ribalda Delgado 	.driver = {
333971451b3SRicardo Ribalda Delgado 		.name = "of_fixed_factor_clk",
334971451b3SRicardo Ribalda Delgado 		.of_match_table = of_fixed_factor_clk_ids,
335971451b3SRicardo Ribalda Delgado 	},
336971451b3SRicardo Ribalda Delgado 	.probe = of_fixed_factor_clk_probe,
337*27237f4bSUwe Kleine-König 	.remove_new = of_fixed_factor_clk_remove,
338971451b3SRicardo Ribalda Delgado };
339971451b3SRicardo Ribalda Delgado builtin_platform_driver(of_fixed_factor_clk_driver);
34079b16641SGregory CLEMENT #endif
341