1*d690bd11SStephen Boyd // SPDX-License-Identifier: GPL-2.0
2*d690bd11SStephen Boyd /*
3*d690bd11SStephen Boyd * KUnit helpers for clk providers and consumers
4*d690bd11SStephen Boyd */
5*d690bd11SStephen Boyd #include <linux/clk.h>
6*d690bd11SStephen Boyd #include <linux/clk-provider.h>
7*d690bd11SStephen Boyd #include <linux/err.h>
8*d690bd11SStephen Boyd #include <linux/kernel.h>
9*d690bd11SStephen Boyd #include <linux/slab.h>
10*d690bd11SStephen Boyd
11*d690bd11SStephen Boyd #include <kunit/clk.h>
12*d690bd11SStephen Boyd #include <kunit/resource.h>
13*d690bd11SStephen Boyd
14*d690bd11SStephen Boyd KUNIT_DEFINE_ACTION_WRAPPER(clk_disable_unprepare_wrapper,
15*d690bd11SStephen Boyd clk_disable_unprepare, struct clk *);
16*d690bd11SStephen Boyd /**
17*d690bd11SStephen Boyd * clk_prepare_enable_kunit() - Test managed clk_prepare_enable()
18*d690bd11SStephen Boyd * @test: The test context
19*d690bd11SStephen Boyd * @clk: clk to prepare and enable
20*d690bd11SStephen Boyd *
21*d690bd11SStephen Boyd * Return: 0 on success, or negative errno on failure.
22*d690bd11SStephen Boyd */
clk_prepare_enable_kunit(struct kunit * test,struct clk * clk)23*d690bd11SStephen Boyd int clk_prepare_enable_kunit(struct kunit *test, struct clk *clk)
24*d690bd11SStephen Boyd {
25*d690bd11SStephen Boyd int ret;
26*d690bd11SStephen Boyd
27*d690bd11SStephen Boyd ret = clk_prepare_enable(clk);
28*d690bd11SStephen Boyd if (ret)
29*d690bd11SStephen Boyd return ret;
30*d690bd11SStephen Boyd
31*d690bd11SStephen Boyd return kunit_add_action_or_reset(test, clk_disable_unprepare_wrapper,
32*d690bd11SStephen Boyd clk);
33*d690bd11SStephen Boyd }
34*d690bd11SStephen Boyd EXPORT_SYMBOL_GPL(clk_prepare_enable_kunit);
35*d690bd11SStephen Boyd
36*d690bd11SStephen Boyd KUNIT_DEFINE_ACTION_WRAPPER(clk_put_wrapper, clk_put, struct clk *);
37*d690bd11SStephen Boyd
__clk_get_kunit(struct kunit * test,struct clk * clk)38*d690bd11SStephen Boyd static struct clk *__clk_get_kunit(struct kunit *test, struct clk *clk)
39*d690bd11SStephen Boyd {
40*d690bd11SStephen Boyd int ret;
41*d690bd11SStephen Boyd
42*d690bd11SStephen Boyd if (IS_ERR(clk))
43*d690bd11SStephen Boyd return clk;
44*d690bd11SStephen Boyd
45*d690bd11SStephen Boyd ret = kunit_add_action_or_reset(test, clk_put_wrapper, clk);
46*d690bd11SStephen Boyd if (ret)
47*d690bd11SStephen Boyd return ERR_PTR(ret);
48*d690bd11SStephen Boyd
49*d690bd11SStephen Boyd return clk;
50*d690bd11SStephen Boyd }
51*d690bd11SStephen Boyd
52*d690bd11SStephen Boyd /**
53*d690bd11SStephen Boyd * clk_get_kunit() - Test managed clk_get()
54*d690bd11SStephen Boyd * @test: The test context
55*d690bd11SStephen Boyd * @dev: device for clock "consumer"
56*d690bd11SStephen Boyd * @con_id: clock consumer ID
57*d690bd11SStephen Boyd *
58*d690bd11SStephen Boyd * Just like clk_get(), except the clk is managed by the test case and is
59*d690bd11SStephen Boyd * automatically put with clk_put() after the test case concludes.
60*d690bd11SStephen Boyd *
61*d690bd11SStephen Boyd * Return: new clk consumer or ERR_PTR on failure.
62*d690bd11SStephen Boyd */
63*d690bd11SStephen Boyd struct clk *
clk_get_kunit(struct kunit * test,struct device * dev,const char * con_id)64*d690bd11SStephen Boyd clk_get_kunit(struct kunit *test, struct device *dev, const char *con_id)
65*d690bd11SStephen Boyd {
66*d690bd11SStephen Boyd struct clk *clk;
67*d690bd11SStephen Boyd
68*d690bd11SStephen Boyd clk = clk_get(dev, con_id);
69*d690bd11SStephen Boyd
70*d690bd11SStephen Boyd return __clk_get_kunit(test, clk);
71*d690bd11SStephen Boyd }
72*d690bd11SStephen Boyd EXPORT_SYMBOL_GPL(clk_get_kunit);
73*d690bd11SStephen Boyd
74*d690bd11SStephen Boyd /**
75*d690bd11SStephen Boyd * of_clk_get_kunit() - Test managed of_clk_get()
76*d690bd11SStephen Boyd * @test: The test context
77*d690bd11SStephen Boyd * @np: device_node for clock "consumer"
78*d690bd11SStephen Boyd * @index: index in 'clocks' property of @np
79*d690bd11SStephen Boyd *
80*d690bd11SStephen Boyd * Just like of_clk_get(), except the clk is managed by the test case and is
81*d690bd11SStephen Boyd * automatically put with clk_put() after the test case concludes.
82*d690bd11SStephen Boyd *
83*d690bd11SStephen Boyd * Return: new clk consumer or ERR_PTR on failure.
84*d690bd11SStephen Boyd */
85*d690bd11SStephen Boyd struct clk *
of_clk_get_kunit(struct kunit * test,struct device_node * np,int index)86*d690bd11SStephen Boyd of_clk_get_kunit(struct kunit *test, struct device_node *np, int index)
87*d690bd11SStephen Boyd {
88*d690bd11SStephen Boyd struct clk *clk;
89*d690bd11SStephen Boyd
90*d690bd11SStephen Boyd clk = of_clk_get(np, index);
91*d690bd11SStephen Boyd
92*d690bd11SStephen Boyd return __clk_get_kunit(test, clk);
93*d690bd11SStephen Boyd }
94*d690bd11SStephen Boyd EXPORT_SYMBOL_GPL(of_clk_get_kunit);
95*d690bd11SStephen Boyd
96*d690bd11SStephen Boyd /**
97*d690bd11SStephen Boyd * clk_hw_get_clk_kunit() - Test managed clk_hw_get_clk()
98*d690bd11SStephen Boyd * @test: The test context
99*d690bd11SStephen Boyd * @hw: clk_hw associated with the clk being consumed
100*d690bd11SStephen Boyd * @con_id: connection ID string on device
101*d690bd11SStephen Boyd *
102*d690bd11SStephen Boyd * Just like clk_hw_get_clk(), except the clk is managed by the test case and
103*d690bd11SStephen Boyd * is automatically put with clk_put() after the test case concludes.
104*d690bd11SStephen Boyd *
105*d690bd11SStephen Boyd * Return: new clk consumer or ERR_PTR on failure.
106*d690bd11SStephen Boyd */
107*d690bd11SStephen Boyd struct clk *
clk_hw_get_clk_kunit(struct kunit * test,struct clk_hw * hw,const char * con_id)108*d690bd11SStephen Boyd clk_hw_get_clk_kunit(struct kunit *test, struct clk_hw *hw, const char *con_id)
109*d690bd11SStephen Boyd {
110*d690bd11SStephen Boyd struct clk *clk;
111*d690bd11SStephen Boyd
112*d690bd11SStephen Boyd clk = clk_hw_get_clk(hw, con_id);
113*d690bd11SStephen Boyd
114*d690bd11SStephen Boyd return __clk_get_kunit(test, clk);
115*d690bd11SStephen Boyd }
116*d690bd11SStephen Boyd EXPORT_SYMBOL_GPL(clk_hw_get_clk_kunit);
117*d690bd11SStephen Boyd
118*d690bd11SStephen Boyd /**
119*d690bd11SStephen Boyd * clk_hw_get_clk_prepared_enabled_kunit() - Test managed clk_hw_get_clk() + clk_prepare_enable()
120*d690bd11SStephen Boyd * @test: The test context
121*d690bd11SStephen Boyd * @hw: clk_hw associated with the clk being consumed
122*d690bd11SStephen Boyd * @con_id: connection ID string on device
123*d690bd11SStephen Boyd *
124*d690bd11SStephen Boyd * Just like
125*d690bd11SStephen Boyd *
126*d690bd11SStephen Boyd * .. code-block:: c
127*d690bd11SStephen Boyd *
128*d690bd11SStephen Boyd * struct clk *clk = clk_hw_get_clk(...);
129*d690bd11SStephen Boyd * clk_prepare_enable(clk);
130*d690bd11SStephen Boyd *
131*d690bd11SStephen Boyd * except the clk is managed by the test case and is automatically disabled and
132*d690bd11SStephen Boyd * unprepared with clk_disable_unprepare() and put with clk_put() after the
133*d690bd11SStephen Boyd * test case concludes.
134*d690bd11SStephen Boyd *
135*d690bd11SStephen Boyd * Return: new clk consumer that is prepared and enabled or ERR_PTR on failure.
136*d690bd11SStephen Boyd */
137*d690bd11SStephen Boyd struct clk *
clk_hw_get_clk_prepared_enabled_kunit(struct kunit * test,struct clk_hw * hw,const char * con_id)138*d690bd11SStephen Boyd clk_hw_get_clk_prepared_enabled_kunit(struct kunit *test, struct clk_hw *hw,
139*d690bd11SStephen Boyd const char *con_id)
140*d690bd11SStephen Boyd {
141*d690bd11SStephen Boyd int ret;
142*d690bd11SStephen Boyd struct clk *clk;
143*d690bd11SStephen Boyd
144*d690bd11SStephen Boyd clk = clk_hw_get_clk_kunit(test, hw, con_id);
145*d690bd11SStephen Boyd if (IS_ERR(clk))
146*d690bd11SStephen Boyd return clk;
147*d690bd11SStephen Boyd
148*d690bd11SStephen Boyd ret = clk_prepare_enable_kunit(test, clk);
149*d690bd11SStephen Boyd if (ret)
150*d690bd11SStephen Boyd return ERR_PTR(ret);
151*d690bd11SStephen Boyd
152*d690bd11SStephen Boyd return clk;
153*d690bd11SStephen Boyd }
154*d690bd11SStephen Boyd EXPORT_SYMBOL_GPL(clk_hw_get_clk_prepared_enabled_kunit);
155*d690bd11SStephen Boyd
156*d690bd11SStephen Boyd KUNIT_DEFINE_ACTION_WRAPPER(clk_hw_unregister_wrapper,
157*d690bd11SStephen Boyd clk_hw_unregister, struct clk_hw *);
158*d690bd11SStephen Boyd
159*d690bd11SStephen Boyd /**
160*d690bd11SStephen Boyd * clk_hw_register_kunit() - Test managed clk_hw_register()
161*d690bd11SStephen Boyd * @test: The test context
162*d690bd11SStephen Boyd * @dev: device that is registering this clock
163*d690bd11SStephen Boyd * @hw: link to hardware-specific clock data
164*d690bd11SStephen Boyd *
165*d690bd11SStephen Boyd * Just like clk_hw_register(), except the clk registration is managed by the
166*d690bd11SStephen Boyd * test case and is automatically unregistered after the test case concludes.
167*d690bd11SStephen Boyd *
168*d690bd11SStephen Boyd * Return: 0 on success or a negative errno value on failure.
169*d690bd11SStephen Boyd */
clk_hw_register_kunit(struct kunit * test,struct device * dev,struct clk_hw * hw)170*d690bd11SStephen Boyd int clk_hw_register_kunit(struct kunit *test, struct device *dev, struct clk_hw *hw)
171*d690bd11SStephen Boyd {
172*d690bd11SStephen Boyd int ret;
173*d690bd11SStephen Boyd
174*d690bd11SStephen Boyd ret = clk_hw_register(dev, hw);
175*d690bd11SStephen Boyd if (ret)
176*d690bd11SStephen Boyd return ret;
177*d690bd11SStephen Boyd
178*d690bd11SStephen Boyd return kunit_add_action_or_reset(test, clk_hw_unregister_wrapper, hw);
179*d690bd11SStephen Boyd }
180*d690bd11SStephen Boyd EXPORT_SYMBOL_GPL(clk_hw_register_kunit);
181*d690bd11SStephen Boyd
182*d690bd11SStephen Boyd /**
183*d690bd11SStephen Boyd * of_clk_hw_register_kunit() - Test managed of_clk_hw_register()
184*d690bd11SStephen Boyd * @test: The test context
185*d690bd11SStephen Boyd * @node: device_node of device that is registering this clock
186*d690bd11SStephen Boyd * @hw: link to hardware-specific clock data
187*d690bd11SStephen Boyd *
188*d690bd11SStephen Boyd * Just like of_clk_hw_register(), except the clk registration is managed by
189*d690bd11SStephen Boyd * the test case and is automatically unregistered after the test case
190*d690bd11SStephen Boyd * concludes.
191*d690bd11SStephen Boyd *
192*d690bd11SStephen Boyd * Return: 0 on success or a negative errno value on failure.
193*d690bd11SStephen Boyd */
of_clk_hw_register_kunit(struct kunit * test,struct device_node * node,struct clk_hw * hw)194*d690bd11SStephen Boyd int of_clk_hw_register_kunit(struct kunit *test, struct device_node *node, struct clk_hw *hw)
195*d690bd11SStephen Boyd {
196*d690bd11SStephen Boyd int ret;
197*d690bd11SStephen Boyd
198*d690bd11SStephen Boyd ret = of_clk_hw_register(node, hw);
199*d690bd11SStephen Boyd if (ret)
200*d690bd11SStephen Boyd return ret;
201*d690bd11SStephen Boyd
202*d690bd11SStephen Boyd return kunit_add_action_or_reset(test, clk_hw_unregister_wrapper, hw);
203*d690bd11SStephen Boyd }
204*d690bd11SStephen Boyd EXPORT_SYMBOL_GPL(of_clk_hw_register_kunit);
205*d690bd11SStephen Boyd
206*d690bd11SStephen Boyd MODULE_LICENSE("GPL");
207*d690bd11SStephen Boyd MODULE_DESCRIPTION("KUnit helpers for clk providers and consumers");
208