kernel/resource: refactor __request_region to allow external locking
[platform/kernel/linux-starfive.git] / kernel / resource_kunit.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Test cases for API provided by resource.c and ioport.h
4  */
5
6 #include <kunit/test.h>
7 #include <linux/ioport.h>
8 #include <linux/kernel.h>
9 #include <linux/string.h>
10
11 #define R0_START        0x0000
12 #define R0_END          0xffff
13 #define R1_START        0x1234
14 #define R1_END          0x2345
15 #define R2_START        0x4567
16 #define R2_END          0x5678
17 #define R3_START        0x6789
18 #define R3_END          0x789a
19 #define R4_START        0x2000
20 #define R4_END          0x7000
21
22 static struct resource r0 = { .start = R0_START, .end = R0_END };
23 static struct resource r1 = { .start = R1_START, .end = R1_END };
24 static struct resource r2 = { .start = R2_START, .end = R2_END };
25 static struct resource r3 = { .start = R3_START, .end = R3_END };
26 static struct resource r4 = { .start = R4_START, .end = R4_END };
27
28 struct result {
29         struct resource *r1;
30         struct resource *r2;
31         struct resource r;
32         bool ret;
33 };
34
35 static struct result results_for_union[] = {
36         {
37                 .r1 = &r1, .r2 = &r0, .r.start = R0_START, .r.end = R0_END, .ret = true,
38         }, {
39                 .r1 = &r2, .r2 = &r0, .r.start = R0_START, .r.end = R0_END, .ret = true,
40         }, {
41                 .r1 = &r3, .r2 = &r0, .r.start = R0_START, .r.end = R0_END, .ret = true,
42         }, {
43                 .r1 = &r4, .r2 = &r0, .r.start = R0_START, .r.end = R0_END, .ret = true,
44         }, {
45                 .r1 = &r2, .r2 = &r1, .ret = false,
46         }, {
47                 .r1 = &r3, .r2 = &r1, .ret = false,
48         }, {
49                 .r1 = &r4, .r2 = &r1, .r.start = R1_START, .r.end = R4_END, .ret = true,
50         }, {
51                 .r1 = &r2, .r2 = &r3, .ret = false,
52         }, {
53                 .r1 = &r2, .r2 = &r4, .r.start = R4_START, .r.end = R4_END, .ret = true,
54         }, {
55                 .r1 = &r3, .r2 = &r4, .r.start = R4_START, .r.end = R3_END, .ret = true,
56         },
57 };
58
59 static struct result results_for_intersection[] = {
60         {
61                 .r1 = &r1, .r2 = &r0, .r.start = R1_START, .r.end = R1_END, .ret = true,
62         }, {
63                 .r1 = &r2, .r2 = &r0, .r.start = R2_START, .r.end = R2_END, .ret = true,
64         }, {
65                 .r1 = &r3, .r2 = &r0, .r.start = R3_START, .r.end = R3_END, .ret = true,
66         }, {
67                 .r1 = &r4, .r2 = &r0, .r.start = R4_START, .r.end = R4_END, .ret = true,
68         }, {
69                 .r1 = &r2, .r2 = &r1, .ret = false,
70         }, {
71                 .r1 = &r3, .r2 = &r1, .ret = false,
72         }, {
73                 .r1 = &r4, .r2 = &r1, .r.start = R4_START, .r.end = R1_END, .ret = true,
74         }, {
75                 .r1 = &r2, .r2 = &r3, .ret = false,
76         }, {
77                 .r1 = &r2, .r2 = &r4, .r.start = R2_START, .r.end = R2_END, .ret = true,
78         }, {
79                 .r1 = &r3, .r2 = &r4, .r.start = R3_START, .r.end = R4_END, .ret = true,
80         },
81 };
82
83 static void resource_do_test(struct kunit *test, bool ret, struct resource *r,
84                              bool exp_ret, struct resource *exp_r,
85                              struct resource *r1, struct resource *r2)
86 {
87         KUNIT_EXPECT_EQ_MSG(test, ret, exp_ret, "Resources %pR %pR", r1, r2);
88         KUNIT_EXPECT_EQ_MSG(test, r->start, exp_r->start, "Start elements are not equal");
89         KUNIT_EXPECT_EQ_MSG(test, r->end, exp_r->end, "End elements are not equal");
90 }
91
92 static void resource_do_union_test(struct kunit *test, struct result *r)
93 {
94         struct resource result;
95         bool ret;
96
97         memset(&result, 0, sizeof(result));
98         ret = resource_union(r->r1, r->r2, &result);
99         resource_do_test(test, ret, &result, r->ret, &r->r, r->r1, r->r2);
100
101         memset(&result, 0, sizeof(result));
102         ret = resource_union(r->r2, r->r1, &result);
103         resource_do_test(test, ret, &result, r->ret, &r->r, r->r2, r->r1);
104 }
105
106 static void resource_test_union(struct kunit *test)
107 {
108         struct result *r = results_for_union;
109         unsigned int i = 0;
110
111         do {
112                 resource_do_union_test(test, &r[i]);
113         } while (++i < ARRAY_SIZE(results_for_union));
114 }
115
116 static void resource_do_intersection_test(struct kunit *test, struct result *r)
117 {
118         struct resource result;
119         bool ret;
120
121         memset(&result, 0, sizeof(result));
122         ret = resource_intersection(r->r1, r->r2, &result);
123         resource_do_test(test, ret, &result, r->ret, &r->r, r->r1, r->r2);
124
125         memset(&result, 0, sizeof(result));
126         ret = resource_intersection(r->r2, r->r1, &result);
127         resource_do_test(test, ret, &result, r->ret, &r->r, r->r2, r->r1);
128 }
129
130 static void resource_test_intersection(struct kunit *test)
131 {
132         struct result *r = results_for_intersection;
133         unsigned int i = 0;
134
135         do {
136                 resource_do_intersection_test(test, &r[i]);
137         } while (++i < ARRAY_SIZE(results_for_intersection));
138 }
139
140 static struct kunit_case resource_test_cases[] = {
141         KUNIT_CASE(resource_test_union),
142         KUNIT_CASE(resource_test_intersection),
143         {}
144 };
145
146 static struct kunit_suite resource_test_suite = {
147         .name = "resource",
148         .test_cases = resource_test_cases,
149 };
150 kunit_test_suite(resource_test_suite);
151
152 MODULE_LICENSE("GPL");