Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/clk/clk-fixed-rate_test.c
26278 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* KUnit test for clk fixed rate basic type
4
*/
5
#include <linux/clk.h>
6
#include <linux/clk-provider.h>
7
#include <linux/completion.h>
8
#include <linux/of.h>
9
#include <linux/platform_device.h>
10
11
#include <kunit/clk.h>
12
#include <kunit/of.h>
13
#include <kunit/platform_device.h>
14
#include <kunit/resource.h>
15
#include <kunit/test.h>
16
17
#include "clk-fixed-rate_test.h"
18
19
/**
20
* struct clk_hw_fixed_rate_kunit_params - Parameters to pass to __clk_hw_register_fixed_rate()
21
* @dev: device registering clk
22
* @np: device_node of device registering clk
23
* @name: name of clk
24
* @parent_name: parent name of clk
25
* @parent_hw: clk_hw pointer to parent of clk
26
* @parent_data: parent_data describing parent of clk
27
* @flags: clk framework flags
28
* @fixed_rate: frequency of clk
29
* @fixed_accuracy: accuracy of clk
30
* @clk_fixed_flags: fixed rate specific clk flags
31
*/
32
struct clk_hw_fixed_rate_kunit_params {
33
struct device *dev;
34
struct device_node *np;
35
const char *name;
36
const char *parent_name;
37
const struct clk_hw *parent_hw;
38
const struct clk_parent_data *parent_data;
39
unsigned long flags;
40
unsigned long fixed_rate;
41
unsigned long fixed_accuracy;
42
unsigned long clk_fixed_flags;
43
};
44
45
static int
46
clk_hw_register_fixed_rate_kunit_init(struct kunit_resource *res, void *context)
47
{
48
struct clk_hw_fixed_rate_kunit_params *params = context;
49
struct clk_hw *hw;
50
51
hw = __clk_hw_register_fixed_rate(params->dev, params->np,
52
params->name,
53
params->parent_name,
54
params->parent_hw,
55
params->parent_data,
56
params->flags,
57
params->fixed_rate,
58
params->fixed_accuracy,
59
params->clk_fixed_flags,
60
false);
61
if (IS_ERR(hw))
62
return PTR_ERR(hw);
63
64
res->data = hw;
65
66
return 0;
67
}
68
69
static void clk_hw_register_fixed_rate_kunit_exit(struct kunit_resource *res)
70
{
71
struct clk_hw *hw = res->data;
72
73
clk_hw_unregister_fixed_rate(hw);
74
}
75
76
/**
77
* clk_hw_register_fixed_rate_kunit() - Test managed __clk_hw_register_fixed_rate()
78
* @test: The test context
79
* @params: Arguments to __clk_hw_register_fixed_rate()
80
*
81
* Return: Registered fixed rate clk_hw or ERR_PTR on failure
82
*/
83
static struct clk_hw *
84
clk_hw_register_fixed_rate_kunit(struct kunit *test,
85
struct clk_hw_fixed_rate_kunit_params *params)
86
{
87
struct clk_hw *hw;
88
89
hw = kunit_alloc_resource(test,
90
clk_hw_register_fixed_rate_kunit_init,
91
clk_hw_register_fixed_rate_kunit_exit,
92
GFP_KERNEL, params);
93
if (!hw)
94
return ERR_PTR(-EINVAL);
95
96
return hw;
97
}
98
99
/**
100
* clk_hw_unregister_fixed_rate_kunit() - Test managed clk_hw_unregister_fixed_rate()
101
* @test: The test context
102
* @hw: fixed rate clk to unregister upon test completion
103
*
104
* Automatically unregister @hw when @test is complete via
105
* clk_hw_unregister_fixed_rate().
106
*
107
* Return: 0 on success or negative errno on failure
108
*/
109
static int clk_hw_unregister_fixed_rate_kunit(struct kunit *test, struct clk_hw *hw)
110
{
111
if (!kunit_alloc_resource(test, NULL,
112
clk_hw_register_fixed_rate_kunit_exit,
113
GFP_KERNEL, hw))
114
return -ENOMEM;
115
116
return 0;
117
}
118
119
/*
120
* Test that clk_get_rate() on a fixed rate clk registered with
121
* clk_hw_register_fixed_rate() gets the proper frequency.
122
*/
123
static void clk_fixed_rate_rate_test(struct kunit *test)
124
{
125
struct clk_hw *hw;
126
struct clk *clk;
127
const unsigned long fixed_rate = 230000;
128
129
hw = clk_hw_register_fixed_rate(NULL, "test-fixed-rate", NULL, 0, fixed_rate);
130
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
131
KUNIT_ASSERT_EQ(test, 0, clk_hw_unregister_fixed_rate_kunit(test, hw));
132
133
clk = clk_hw_get_clk_prepared_enabled_kunit(test, hw, __func__);
134
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, clk);
135
136
KUNIT_EXPECT_EQ(test, fixed_rate, clk_get_rate(clk));
137
}
138
139
/*
140
* Test that clk_get_accuracy() on a fixed rate clk registered via
141
* clk_hw_register_fixed_rate_with_accuracy() gets the proper accuracy.
142
*/
143
static void clk_fixed_rate_accuracy_test(struct kunit *test)
144
{
145
struct clk_hw *hw;
146
struct clk *clk;
147
const unsigned long fixed_accuracy = 5000;
148
149
hw = clk_hw_register_fixed_rate_with_accuracy(NULL, "test-fixed-rate",
150
NULL, 0, 0,
151
fixed_accuracy);
152
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
153
KUNIT_ASSERT_EQ(test, 0, clk_hw_unregister_fixed_rate_kunit(test, hw));
154
155
clk = clk_hw_get_clk_kunit(test, hw, __func__);
156
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, clk);
157
158
KUNIT_EXPECT_EQ(test, fixed_accuracy, clk_get_accuracy(clk));
159
}
160
161
/* Test suite for a fixed rate clk without any parent */
162
static struct kunit_case clk_fixed_rate_test_cases[] = {
163
KUNIT_CASE(clk_fixed_rate_rate_test),
164
KUNIT_CASE(clk_fixed_rate_accuracy_test),
165
{}
166
};
167
168
static struct kunit_suite clk_fixed_rate_suite = {
169
.name = "clk_fixed_rate",
170
.test_cases = clk_fixed_rate_test_cases,
171
};
172
173
/*
174
* Test that clk_get_parent() on a fixed rate clk gets the proper parent.
175
*/
176
static void clk_fixed_rate_parent_test(struct kunit *test)
177
{
178
struct clk_hw *hw, *parent_hw;
179
struct clk *expected_parent, *actual_parent;
180
struct clk *clk;
181
const char *parent_name = "test-fixed-rate-parent";
182
struct clk_hw_fixed_rate_kunit_params parent_params = {
183
.name = parent_name,
184
};
185
186
parent_hw = clk_hw_register_fixed_rate_kunit(test, &parent_params);
187
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent_hw);
188
KUNIT_ASSERT_STREQ(test, parent_name, clk_hw_get_name(parent_hw));
189
190
expected_parent = clk_hw_get_clk_kunit(test, parent_hw, __func__);
191
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, expected_parent);
192
193
hw = clk_hw_register_fixed_rate(NULL, "test-fixed-rate", parent_name, 0, 0);
194
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
195
KUNIT_ASSERT_EQ(test, 0, clk_hw_unregister_fixed_rate_kunit(test, hw));
196
197
clk = clk_hw_get_clk_kunit(test, hw, __func__);
198
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, clk);
199
200
actual_parent = clk_get_parent(clk);
201
KUNIT_EXPECT_TRUE(test, clk_is_match(expected_parent, actual_parent));
202
}
203
204
/*
205
* Test that clk_get_rate() on a fixed rate clk ignores the parent rate.
206
*/
207
static void clk_fixed_rate_parent_rate_test(struct kunit *test)
208
{
209
struct clk_hw *hw, *parent_hw;
210
struct clk *clk;
211
const unsigned long expected_rate = 1405;
212
const unsigned long parent_rate = 90402;
213
const char *parent_name = "test-fixed-rate-parent";
214
struct clk_hw_fixed_rate_kunit_params parent_params = {
215
.name = parent_name,
216
.fixed_rate = parent_rate,
217
};
218
219
parent_hw = clk_hw_register_fixed_rate_kunit(test, &parent_params);
220
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent_hw);
221
KUNIT_ASSERT_STREQ(test, parent_name, clk_hw_get_name(parent_hw));
222
223
hw = clk_hw_register_fixed_rate(NULL, "test-fixed-rate", parent_name, 0,
224
expected_rate);
225
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
226
KUNIT_ASSERT_EQ(test, 0, clk_hw_unregister_fixed_rate_kunit(test, hw));
227
228
clk = clk_hw_get_clk_prepared_enabled_kunit(test, hw, __func__);
229
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, clk);
230
231
KUNIT_EXPECT_EQ(test, expected_rate, clk_get_rate(clk));
232
}
233
234
/*
235
* Test that clk_get_accuracy() on a fixed rate clk ignores the parent accuracy.
236
*/
237
static void clk_fixed_rate_parent_accuracy_test(struct kunit *test)
238
{
239
struct clk_hw *hw, *parent_hw;
240
struct clk *clk;
241
const unsigned long expected_accuracy = 900;
242
const unsigned long parent_accuracy = 24000;
243
const char *parent_name = "test-fixed-rate-parent";
244
struct clk_hw_fixed_rate_kunit_params parent_params = {
245
.name = parent_name,
246
.fixed_accuracy = parent_accuracy,
247
};
248
249
parent_hw = clk_hw_register_fixed_rate_kunit(test, &parent_params);
250
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent_hw);
251
KUNIT_ASSERT_STREQ(test, parent_name, clk_hw_get_name(parent_hw));
252
253
hw = clk_hw_register_fixed_rate_with_accuracy(NULL, "test-fixed-rate",
254
parent_name, 0, 0,
255
expected_accuracy);
256
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
257
KUNIT_ASSERT_EQ(test, 0, clk_hw_unregister_fixed_rate_kunit(test, hw));
258
259
clk = clk_hw_get_clk_kunit(test, hw, __func__);
260
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, clk);
261
262
KUNIT_EXPECT_EQ(test, expected_accuracy, clk_get_accuracy(clk));
263
}
264
265
/* Test suite for a fixed rate clk with a parent */
266
static struct kunit_case clk_fixed_rate_parent_test_cases[] = {
267
KUNIT_CASE(clk_fixed_rate_parent_test),
268
KUNIT_CASE(clk_fixed_rate_parent_rate_test),
269
KUNIT_CASE(clk_fixed_rate_parent_accuracy_test),
270
{}
271
};
272
273
static struct kunit_suite clk_fixed_rate_parent_suite = {
274
.name = "clk_fixed_rate_parent",
275
.test_cases = clk_fixed_rate_parent_test_cases,
276
};
277
278
struct clk_fixed_rate_of_test_context {
279
struct device *dev;
280
struct platform_driver pdrv;
281
struct completion probed;
282
};
283
284
static inline struct clk_fixed_rate_of_test_context *
285
pdev_to_clk_fixed_rate_of_test_context(struct platform_device *pdev)
286
{
287
return container_of(to_platform_driver(pdev->dev.driver),
288
struct clk_fixed_rate_of_test_context,
289
pdrv);
290
}
291
292
/*
293
* Test that of_fixed_clk_setup() registers a fixed rate clk with the proper
294
* rate.
295
*/
296
static void clk_fixed_rate_of_probe_test(struct kunit *test)
297
{
298
struct clk_fixed_rate_of_test_context *ctx = test->priv;
299
struct device *dev = ctx->dev;
300
struct clk *clk;
301
302
clk = clk_get_kunit(test, dev, NULL);
303
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, clk);
304
305
KUNIT_ASSERT_EQ(test, 0, clk_prepare_enable_kunit(test, clk));
306
KUNIT_EXPECT_EQ(test, TEST_FIXED_FREQUENCY, clk_get_rate(clk));
307
}
308
309
/*
310
* Test that of_fixed_clk_setup() registers a fixed rate clk with the proper
311
* accuracy.
312
*/
313
static void clk_fixed_rate_of_accuracy_test(struct kunit *test)
314
{
315
struct clk_fixed_rate_of_test_context *ctx = test->priv;
316
struct device *dev = ctx->dev;
317
struct clk *clk;
318
319
clk = clk_get_kunit(test, dev, NULL);
320
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, clk);
321
322
KUNIT_EXPECT_EQ(test, TEST_FIXED_ACCURACY, clk_get_accuracy(clk));
323
}
324
325
static struct kunit_case clk_fixed_rate_of_cases[] = {
326
KUNIT_CASE(clk_fixed_rate_of_probe_test),
327
KUNIT_CASE(clk_fixed_rate_of_accuracy_test),
328
{}
329
};
330
331
static int clk_fixed_rate_of_test_probe(struct platform_device *pdev)
332
{
333
struct clk_fixed_rate_of_test_context *ctx;
334
335
ctx = pdev_to_clk_fixed_rate_of_test_context(pdev);
336
ctx->dev = &pdev->dev;
337
complete(&ctx->probed);
338
339
return 0;
340
}
341
342
static int clk_fixed_rate_of_init(struct kunit *test)
343
{
344
struct clk_fixed_rate_of_test_context *ctx;
345
static const struct of_device_id match_table[] = {
346
{ .compatible = "test,single-clk-consumer" },
347
{ }
348
};
349
350
KUNIT_ASSERT_EQ(test, 0, of_overlay_apply_kunit(test, kunit_clk_fixed_rate_test));
351
352
ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
353
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
354
test->priv = ctx;
355
356
ctx->pdrv.probe = clk_fixed_rate_of_test_probe;
357
ctx->pdrv.driver.of_match_table = match_table;
358
ctx->pdrv.driver.name = __func__;
359
ctx->pdrv.driver.owner = THIS_MODULE;
360
init_completion(&ctx->probed);
361
362
KUNIT_ASSERT_EQ(test, 0, kunit_platform_driver_register(test, &ctx->pdrv));
363
KUNIT_ASSERT_NE(test, 0, wait_for_completion_timeout(&ctx->probed, HZ));
364
365
return 0;
366
}
367
368
static struct kunit_suite clk_fixed_rate_of_suite = {
369
.name = "clk_fixed_rate_of",
370
.init = clk_fixed_rate_of_init,
371
.test_cases = clk_fixed_rate_of_cases,
372
};
373
374
kunit_test_suites(
375
&clk_fixed_rate_suite,
376
&clk_fixed_rate_of_suite,
377
&clk_fixed_rate_parent_suite,
378
);
379
MODULE_LICENSE("GPL");
380
MODULE_DESCRIPTION("KUnit test for clk fixed rate basic type");
381
382