Commit | Line | Data |
---|---|---|
9e682348 MP |
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 <marpagan@redhat.com> | |
8 | */ | |
9 | ||
4d2bc3f7 | 10 | #include <kunit/device.h> |
9e682348 | 11 | #include <kunit/test.h> |
9e682348 MP |
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; | |
4d2bc3f7 | 22 | struct device *dev; |
9e682348 MP |
23 | struct bridge_stats stats; |
24 | }; | |
25 | ||
26 | static int op_enable_set(struct fpga_bridge *bridge, bool enable) | |
27 | { | |
28 | struct bridge_stats *stats = bridge->priv; | |
29 | ||
30 | stats->enable = enable; | |
31 | ||
32 | return 0; | |
33 | } | |
34 | ||
35 | /* | |
36 | * Fake FPGA bridge that implements only the enable_set op to track | |
37 | * the state. | |
38 | */ | |
39 | static const struct fpga_bridge_ops fake_bridge_ops = { | |
40 | .enable_set = op_enable_set, | |
41 | }; | |
42 | ||
43 | /** | |
44 | * register_test_bridge() - Register a fake FPGA bridge for testing. | |
45 | * @test: KUnit test context object. | |
4d2bc3f7 | 46 | * @dev_name: name of the kunit device to be registered |
9e682348 MP |
47 | * |
48 | * Return: Context of the newly registered FPGA bridge. | |
49 | */ | |
4d2bc3f7 | 50 | static struct bridge_ctx *register_test_bridge(struct kunit *test, const char *dev_name) |
9e682348 MP |
51 | { |
52 | struct bridge_ctx *ctx; | |
53 | ||
54 | ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL); | |
55 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); | |
56 | ||
4d2bc3f7 MP |
57 | ctx->dev = kunit_device_register(test, dev_name); |
58 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->dev); | |
9e682348 | 59 | |
4d2bc3f7 | 60 | ctx->bridge = fpga_bridge_register(ctx->dev, "Fake FPGA bridge", &fake_bridge_ops, |
9e682348 MP |
61 | &ctx->stats); |
62 | KUNIT_ASSERT_FALSE(test, IS_ERR_OR_NULL(ctx->bridge)); | |
63 | ||
64 | return ctx; | |
65 | } | |
66 | ||
4d2bc3f7 | 67 | static void unregister_test_bridge(struct kunit *test, struct bridge_ctx *ctx) |
9e682348 MP |
68 | { |
69 | fpga_bridge_unregister(ctx->bridge); | |
4d2bc3f7 | 70 | kunit_device_unregister(test, ctx->dev); |
9e682348 MP |
71 | } |
72 | ||
73 | static void fpga_bridge_test_get(struct kunit *test) | |
74 | { | |
75 | struct bridge_ctx *ctx = test->priv; | |
76 | struct fpga_bridge *bridge; | |
77 | ||
4d2bc3f7 | 78 | bridge = fpga_bridge_get(ctx->dev, NULL); |
9e682348 MP |
79 | KUNIT_EXPECT_PTR_EQ(test, bridge, ctx->bridge); |
80 | ||
4d2bc3f7 | 81 | bridge = fpga_bridge_get(ctx->dev, NULL); |
9e682348 MP |
82 | KUNIT_EXPECT_EQ(test, PTR_ERR(bridge), -EBUSY); |
83 | ||
84 | fpga_bridge_put(ctx->bridge); | |
85 | } | |
86 | ||
87 | static void fpga_bridge_test_toggle(struct kunit *test) | |
88 | { | |
89 | struct bridge_ctx *ctx = test->priv; | |
90 | int ret; | |
91 | ||
92 | ret = fpga_bridge_disable(ctx->bridge); | |
93 | KUNIT_EXPECT_EQ(test, ret, 0); | |
94 | KUNIT_EXPECT_FALSE(test, ctx->stats.enable); | |
95 | ||
96 | ret = fpga_bridge_enable(ctx->bridge); | |
97 | KUNIT_EXPECT_EQ(test, ret, 0); | |
98 | KUNIT_EXPECT_TRUE(test, ctx->stats.enable); | |
99 | } | |
100 | ||
101 | /* Test the functions for getting and controlling a list of bridges */ | |
102 | static void fpga_bridge_test_get_put_list(struct kunit *test) | |
103 | { | |
104 | struct list_head bridge_list; | |
105 | struct bridge_ctx *ctx_0, *ctx_1; | |
106 | int ret; | |
107 | ||
108 | ctx_0 = test->priv; | |
4d2bc3f7 | 109 | ctx_1 = register_test_bridge(test, "fpga-bridge-test-dev-1"); |
9e682348 MP |
110 | |
111 | INIT_LIST_HEAD(&bridge_list); | |
112 | ||
113 | /* Get bridge 0 and add it to the list */ | |
4d2bc3f7 | 114 | ret = fpga_bridge_get_to_list(ctx_0->dev, NULL, &bridge_list); |
9e682348 MP |
115 | KUNIT_EXPECT_EQ(test, ret, 0); |
116 | ||
117 | KUNIT_EXPECT_PTR_EQ(test, ctx_0->bridge, | |
118 | list_first_entry_or_null(&bridge_list, struct fpga_bridge, node)); | |
119 | ||
120 | /* Get bridge 1 and add it to the list */ | |
4d2bc3f7 | 121 | ret = fpga_bridge_get_to_list(ctx_1->dev, NULL, &bridge_list); |
9e682348 MP |
122 | KUNIT_EXPECT_EQ(test, ret, 0); |
123 | ||
124 | KUNIT_EXPECT_PTR_EQ(test, ctx_1->bridge, | |
125 | list_first_entry_or_null(&bridge_list, struct fpga_bridge, node)); | |
126 | ||
127 | /* Disable an then enable both bridges from the list */ | |
128 | ret = fpga_bridges_disable(&bridge_list); | |
129 | KUNIT_EXPECT_EQ(test, ret, 0); | |
130 | ||
131 | KUNIT_EXPECT_FALSE(test, ctx_0->stats.enable); | |
132 | KUNIT_EXPECT_FALSE(test, ctx_1->stats.enable); | |
133 | ||
134 | ret = fpga_bridges_enable(&bridge_list); | |
135 | KUNIT_EXPECT_EQ(test, ret, 0); | |
136 | ||
137 | KUNIT_EXPECT_TRUE(test, ctx_0->stats.enable); | |
138 | KUNIT_EXPECT_TRUE(test, ctx_1->stats.enable); | |
139 | ||
140 | /* Put and remove both bridges from the list */ | |
141 | fpga_bridges_put(&bridge_list); | |
142 | ||
143 | KUNIT_EXPECT_TRUE(test, list_empty(&bridge_list)); | |
144 | ||
4d2bc3f7 | 145 | unregister_test_bridge(test, ctx_1); |
9e682348 MP |
146 | } |
147 | ||
148 | static int fpga_bridge_test_init(struct kunit *test) | |
149 | { | |
4d2bc3f7 | 150 | test->priv = register_test_bridge(test, "fpga-bridge-test-dev-0"); |
9e682348 MP |
151 | |
152 | return 0; | |
153 | } | |
154 | ||
155 | static void fpga_bridge_test_exit(struct kunit *test) | |
156 | { | |
4d2bc3f7 | 157 | unregister_test_bridge(test, test->priv); |
9e682348 MP |
158 | } |
159 | ||
160 | static struct kunit_case fpga_bridge_test_cases[] = { | |
161 | KUNIT_CASE(fpga_bridge_test_get), | |
162 | KUNIT_CASE(fpga_bridge_test_toggle), | |
163 | KUNIT_CASE(fpga_bridge_test_get_put_list), | |
164 | {} | |
165 | }; | |
166 | ||
167 | static struct kunit_suite fpga_bridge_suite = { | |
168 | .name = "fpga_bridge", | |
169 | .init = fpga_bridge_test_init, | |
170 | .exit = fpga_bridge_test_exit, | |
171 | .test_cases = fpga_bridge_test_cases, | |
172 | }; | |
173 | ||
174 | kunit_test_suite(fpga_bridge_suite); | |
175 | ||
176 | MODULE_LICENSE("GPL"); |