Skip to content

Commit d690bd1

Browse files
committed
clk: Add test managed clk provider/consumer APIs
Unit tests are more ergonomic and simpler to understand if they don't have to hoist a bunch of code into the test harness init and exit functions. Add some test managed wrappers for the clk APIs so that clk unit tests can write more code in the actual test and less code in the harness. Only add APIs that are used for now. More wrappers can be added in the future as necessary. Cc: Brendan Higgins <[email protected]> Cc: David Gow <[email protected]> Cc: Rae Moar <[email protected]> Signed-off-by: Stephen Boyd <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 5ac7973 commit d690bd1

File tree

5 files changed

+255
-0
lines changed

5 files changed

+255
-0
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.. SPDX-License-Identifier: GPL-2.0
2+
3+
========
4+
Clk API
5+
========
6+
7+
The KUnit clk API is used to test clk providers and clk consumers.
8+
9+
.. kernel-doc:: drivers/clk/clk_kunit_helpers.c
10+
:export:

Documentation/dev-tools/kunit/api/index.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ API Reference
99
test
1010
resource
1111
functionredirection
12+
clk
1213
of
1314
platformdevice
1415

@@ -34,6 +35,10 @@ Documentation/dev-tools/kunit/api/functionredirection.rst
3435
Driver KUnit API
3536
================
3637

38+
Documentation/dev-tools/kunit/api/clk.rst
39+
40+
- Documents the KUnit clk API
41+
3742
Documentation/dev-tools/kunit/api/of.rst
3843

3944
- Documents the KUnit device tree (OF) API

drivers/clk/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ ifeq ($(CONFIG_OF), y)
1818
obj-$(CONFIG_COMMON_CLK) += clk-conf.o
1919
endif
2020

21+
# KUnit specific helpers
22+
ifeq ($(CONFIG_COMMON_CLK), y)
23+
obj-$(CONFIG_KUNIT) += clk_kunit_helpers.o
24+
endif
25+
2126
# hardware specific clock types
2227
# please keep this section sorted lexicographically by file path name
2328
obj-$(CONFIG_COMMON_CLK_APPLE_NCO) += clk-apple-nco.o

drivers/clk/clk_kunit_helpers.c

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
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");

include/kunit/clk.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef _CLK_KUNIT_H
3+
#define _CLK_KUNIT_H
4+
5+
struct clk;
6+
struct clk_hw;
7+
struct device;
8+
struct device_node;
9+
struct kunit;
10+
11+
struct clk *
12+
clk_get_kunit(struct kunit *test, struct device *dev, const char *con_id);
13+
struct clk *
14+
of_clk_get_kunit(struct kunit *test, struct device_node *np, int index);
15+
16+
struct clk *
17+
clk_hw_get_clk_kunit(struct kunit *test, struct clk_hw *hw, const char *con_id);
18+
struct clk *
19+
clk_hw_get_clk_prepared_enabled_kunit(struct kunit *test, struct clk_hw *hw,
20+
const char *con_id);
21+
22+
int clk_prepare_enable_kunit(struct kunit *test, struct clk *clk);
23+
24+
int clk_hw_register_kunit(struct kunit *test, struct device *dev, struct clk_hw *hw);
25+
int of_clk_hw_register_kunit(struct kunit *test, struct device_node *node,
26+
struct clk_hw *hw);
27+
28+
#endif

0 commit comments

Comments
 (0)