Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/fpga/tests/fpga-bridge-test.c
26426 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* KUnit test for the FPGA Bridge
4
*
5
* Copyright (C) 2023 Red Hat, Inc.
6
*
7
* Author: Marco Pagani <[email protected]>
8
*/
9
10
#include <kunit/device.h>
11
#include <kunit/test.h>
12
#include <linux/fpga/fpga-bridge.h>
13
#include <linux/module.h>
14
#include <linux/types.h>
15
16
struct bridge_stats {
17
bool enable;
18
};
19
20
struct bridge_ctx {
21
struct fpga_bridge *bridge;
22
struct device *dev;
23
struct bridge_stats stats;
24
};
25
26
/*
27
* Wrapper to avoid a cast warning when passing the action function directly
28
* to kunit_add_action().
29
*/
30
KUNIT_DEFINE_ACTION_WRAPPER(fpga_bridge_unregister_wrapper, fpga_bridge_unregister,
31
struct fpga_bridge *);
32
33
static int op_enable_set(struct fpga_bridge *bridge, bool enable)
34
{
35
struct bridge_stats *stats = bridge->priv;
36
37
stats->enable = enable;
38
39
return 0;
40
}
41
42
/*
43
* Fake FPGA bridge that implements only the enable_set op to track
44
* the state.
45
*/
46
static const struct fpga_bridge_ops fake_bridge_ops = {
47
.enable_set = op_enable_set,
48
};
49
50
/**
51
* register_test_bridge() - Register a fake FPGA bridge for testing.
52
* @test: KUnit test context object.
53
* @dev_name: name of the kunit device to be registered
54
*
55
* Return: Context of the newly registered FPGA bridge.
56
*/
57
static struct bridge_ctx *register_test_bridge(struct kunit *test, const char *dev_name)
58
{
59
struct bridge_ctx *ctx;
60
int ret;
61
62
ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
63
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
64
65
ctx->dev = kunit_device_register(test, dev_name);
66
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->dev);
67
68
ctx->bridge = fpga_bridge_register(ctx->dev, "Fake FPGA bridge", &fake_bridge_ops,
69
&ctx->stats);
70
KUNIT_ASSERT_FALSE(test, IS_ERR_OR_NULL(ctx->bridge));
71
72
ret = kunit_add_action_or_reset(test, fpga_bridge_unregister_wrapper, ctx->bridge);
73
KUNIT_ASSERT_EQ(test, ret, 0);
74
75
return ctx;
76
}
77
78
static void fpga_bridge_test_get(struct kunit *test)
79
{
80
struct bridge_ctx *ctx = test->priv;
81
struct fpga_bridge *bridge;
82
83
bridge = fpga_bridge_get(ctx->dev, NULL);
84
KUNIT_EXPECT_PTR_EQ(test, bridge, ctx->bridge);
85
86
bridge = fpga_bridge_get(ctx->dev, NULL);
87
KUNIT_EXPECT_EQ(test, PTR_ERR(bridge), -EBUSY);
88
89
fpga_bridge_put(ctx->bridge);
90
}
91
92
static void fpga_bridge_test_toggle(struct kunit *test)
93
{
94
struct bridge_ctx *ctx = test->priv;
95
int ret;
96
97
ret = fpga_bridge_disable(ctx->bridge);
98
KUNIT_EXPECT_EQ(test, ret, 0);
99
KUNIT_EXPECT_FALSE(test, ctx->stats.enable);
100
101
ret = fpga_bridge_enable(ctx->bridge);
102
KUNIT_EXPECT_EQ(test, ret, 0);
103
KUNIT_EXPECT_TRUE(test, ctx->stats.enable);
104
}
105
106
/* Test the functions for getting and controlling a list of bridges */
107
static void fpga_bridge_test_get_put_list(struct kunit *test)
108
{
109
struct list_head bridge_list;
110
struct bridge_ctx *ctx_0, *ctx_1;
111
int ret;
112
113
ctx_0 = test->priv;
114
ctx_1 = register_test_bridge(test, "fpga-bridge-test-dev-1");
115
116
INIT_LIST_HEAD(&bridge_list);
117
118
/* Get bridge 0 and add it to the list */
119
ret = fpga_bridge_get_to_list(ctx_0->dev, NULL, &bridge_list);
120
KUNIT_EXPECT_EQ(test, ret, 0);
121
122
KUNIT_EXPECT_PTR_EQ(test, ctx_0->bridge,
123
list_first_entry_or_null(&bridge_list, struct fpga_bridge, node));
124
125
/* Get bridge 1 and add it to the list */
126
ret = fpga_bridge_get_to_list(ctx_1->dev, NULL, &bridge_list);
127
KUNIT_EXPECT_EQ(test, ret, 0);
128
129
KUNIT_EXPECT_PTR_EQ(test, ctx_1->bridge,
130
list_first_entry_or_null(&bridge_list, struct fpga_bridge, node));
131
132
/* Disable an then enable both bridges from the list */
133
ret = fpga_bridges_disable(&bridge_list);
134
KUNIT_EXPECT_EQ(test, ret, 0);
135
136
KUNIT_EXPECT_FALSE(test, ctx_0->stats.enable);
137
KUNIT_EXPECT_FALSE(test, ctx_1->stats.enable);
138
139
ret = fpga_bridges_enable(&bridge_list);
140
KUNIT_EXPECT_EQ(test, ret, 0);
141
142
KUNIT_EXPECT_TRUE(test, ctx_0->stats.enable);
143
KUNIT_EXPECT_TRUE(test, ctx_1->stats.enable);
144
145
/* Put and remove both bridges from the list */
146
fpga_bridges_put(&bridge_list);
147
148
KUNIT_EXPECT_TRUE(test, list_empty(&bridge_list));
149
}
150
151
static int fpga_bridge_test_init(struct kunit *test)
152
{
153
test->priv = register_test_bridge(test, "fpga-bridge-test-dev-0");
154
155
return 0;
156
}
157
158
static struct kunit_case fpga_bridge_test_cases[] = {
159
KUNIT_CASE(fpga_bridge_test_get),
160
KUNIT_CASE(fpga_bridge_test_toggle),
161
KUNIT_CASE(fpga_bridge_test_get_put_list),
162
{}
163
};
164
165
static struct kunit_suite fpga_bridge_suite = {
166
.name = "fpga_bridge",
167
.init = fpga_bridge_test_init,
168
.test_cases = fpga_bridge_test_cases,
169
};
170
171
kunit_test_suite(fpga_bridge_suite);
172
173
MODULE_DESCRIPTION("KUnit test for the FPGA Bridge");
174
MODULE_LICENSE("GPL");
175
176