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