blob: 1e5a2e4d893e4360f881d3ab2f600f4948c75e51 [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001// SPDX-License-Identifier: GPL-2.0
Grant Likely53a42092011-12-12 09:25:57 -07002/*
3 * Self tests for device tree subsystem
4 */
5
Grant Likelycabb7d52013-02-12 21:19:37 +00006#define pr_fmt(fmt) "### dt-test ### " fmt
Grant Likely53a42092011-12-12 09:25:57 -07007
Mike Rapoport57c8a662018-10-30 15:09:49 -07008#include <linux/memblock.h>
Grant Likely53a42092011-12-12 09:25:57 -07009#include <linux/clk.h>
10#include <linux/err.h>
11#include <linux/errno.h>
Grant Likely841ec212014-10-02 13:09:15 +010012#include <linux/hashtable.h>
Frank Rowand81d0848f2017-04-25 17:09:54 -070013#include <linux/libfdt.h>
Grant Likely53a42092011-12-12 09:25:57 -070014#include <linux/of.h>
Rob Herring04db93a2019-09-20 13:28:53 -050015#include <linux/of_address.h>
Gaurav Minochaae9304c2014-07-16 23:09:39 -070016#include <linux/of_fdt.h>
Grant Likelya9f10ca2013-10-11 22:04:23 +010017#include <linux/of_irq.h>
Rob Herring82c0f582014-04-23 17:57:40 -050018#include <linux/of_platform.h>
Grant Likely53a42092011-12-12 09:25:57 -070019#include <linux/list.h>
20#include <linux/mutex.h>
21#include <linux/slab.h>
22#include <linux/device.h>
Pantelis Antoniou177d2712014-10-28 22:35:59 +020023#include <linux/platform_device.h>
Grant Likely53a42092011-12-12 09:25:57 -070024
Pantelis Antonioud5e75502015-01-12 19:02:49 +020025#include <linux/i2c.h>
26#include <linux/i2c-mux.h>
Frank Rowandf4056e72020-02-20 12:40:20 -060027#include <linux/gpio/driver.h>
Pantelis Antonioud5e75502015-01-12 19:02:49 +020028
Pantelis Antoniou492a22a2015-04-07 22:23:49 +030029#include <linux/bitops.h>
30
Pantelis Antoniou69843392014-07-04 19:58:47 +030031#include "of_private.h"
32
Wang Long9697a552015-03-11 08:36:54 +000033static struct unittest_results {
Grant Likelya9f10ca2013-10-11 22:04:23 +010034 int passed;
35 int failed;
Wang Long9697a552015-03-11 08:36:54 +000036} unittest_results;
Grant Likelya9f10ca2013-10-11 22:04:23 +010037
Wang Long9697a552015-03-11 08:36:54 +000038#define unittest(result, fmt, ...) ({ \
Grant Likely851da972014-11-04 13:14:13 +000039 bool failed = !(result); \
40 if (failed) { \
Wang Long9697a552015-03-11 08:36:54 +000041 unittest_results.failed++; \
Grant Likelya9f10ca2013-10-11 22:04:23 +010042 pr_err("FAIL %s():%i " fmt, __func__, __LINE__, ##__VA_ARGS__); \
Grant Likelycabb7d52013-02-12 21:19:37 +000043 } else { \
Wang Long9697a552015-03-11 08:36:54 +000044 unittest_results.passed++; \
Grant Likelya9f10ca2013-10-11 22:04:23 +010045 pr_debug("pass %s():%i\n", __func__, __LINE__); \
Grant Likelycabb7d52013-02-12 21:19:37 +000046 } \
Grant Likely851da972014-11-04 13:14:13 +000047 failed; \
48})
Grant Likely53a42092011-12-12 09:25:57 -070049
Frank Rowandf4056e72020-02-20 12:40:20 -060050/*
51 * Expected message may have a message level other than KERN_INFO.
52 * Print the expected message only if the current loglevel will allow
53 * the actual message to print.
Frank Rowand0ac17432020-02-20 12:40:21 -060054 *
55 * Do not use EXPECT_BEGIN() or EXPECT_END() for messages generated by
56 * pr_debug().
Frank Rowandf4056e72020-02-20 12:40:20 -060057 */
58#define EXPECT_BEGIN(level, fmt, ...) \
59 printk(level pr_fmt("EXPECT \\ : ") fmt, ##__VA_ARGS__)
60
61#define EXPECT_END(level, fmt, ...) \
62 printk(level pr_fmt("EXPECT / : ") fmt, ##__VA_ARGS__)
63
Wang Long9697a552015-03-11 08:36:54 +000064static void __init of_unittest_find_node_by_name(void)
Grant Likelyae91ff72014-03-14 13:53:10 +000065{
66 struct device_node *np;
Rob Herring0d638a02017-06-01 15:50:55 -050067 const char *options, *name;
Grant Likelyae91ff72014-03-14 13:53:10 +000068
69 np = of_find_node_by_path("/testcase-data");
Rob Herring0d638a02017-06-01 15:50:55 -050070 name = kasprintf(GFP_KERNEL, "%pOF", np);
71 unittest(np && !strcmp("/testcase-data", name),
Grant Likelyae91ff72014-03-14 13:53:10 +000072 "find /testcase-data failed\n");
73 of_node_put(np);
Rob Herring0d638a02017-06-01 15:50:55 -050074 kfree(name);
Grant Likelyae91ff72014-03-14 13:53:10 +000075
76 /* Test if trailing '/' works */
77 np = of_find_node_by_path("/testcase-data/");
Wang Long9697a552015-03-11 08:36:54 +000078 unittest(!np, "trailing '/' on /testcase-data/ should fail\n");
Grant Likelyae91ff72014-03-14 13:53:10 +000079
80 np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
Rob Herring0d638a02017-06-01 15:50:55 -050081 name = kasprintf(GFP_KERNEL, "%pOF", np);
82 unittest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", name),
Grant Likelyae91ff72014-03-14 13:53:10 +000083 "find /testcase-data/phandle-tests/consumer-a failed\n");
84 of_node_put(np);
Rob Herring0d638a02017-06-01 15:50:55 -050085 kfree(name);
Grant Likelyae91ff72014-03-14 13:53:10 +000086
87 np = of_find_node_by_path("testcase-alias");
Rob Herring0d638a02017-06-01 15:50:55 -050088 name = kasprintf(GFP_KERNEL, "%pOF", np);
89 unittest(np && !strcmp("/testcase-data", name),
Grant Likelyae91ff72014-03-14 13:53:10 +000090 "find testcase-alias failed\n");
91 of_node_put(np);
Rob Herring0d638a02017-06-01 15:50:55 -050092 kfree(name);
Grant Likelyae91ff72014-03-14 13:53:10 +000093
94 /* Test if trailing '/' works on aliases */
95 np = of_find_node_by_path("testcase-alias/");
Wang Long9697a552015-03-11 08:36:54 +000096 unittest(!np, "trailing '/' on testcase-alias/ should fail\n");
Grant Likelyae91ff72014-03-14 13:53:10 +000097
98 np = of_find_node_by_path("testcase-alias/phandle-tests/consumer-a");
Rob Herring0d638a02017-06-01 15:50:55 -050099 name = kasprintf(GFP_KERNEL, "%pOF", np);
100 unittest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", name),
Grant Likelyae91ff72014-03-14 13:53:10 +0000101 "find testcase-alias/phandle-tests/consumer-a failed\n");
102 of_node_put(np);
Rob Herring0d638a02017-06-01 15:50:55 -0500103 kfree(name);
Grant Likelyae91ff72014-03-14 13:53:10 +0000104
105 np = of_find_node_by_path("/testcase-data/missing-path");
Rob Herring0d638a02017-06-01 15:50:55 -0500106 unittest(!np, "non-existent path returned node %pOF\n", np);
Grant Likelyae91ff72014-03-14 13:53:10 +0000107 of_node_put(np);
108
109 np = of_find_node_by_path("missing-alias");
Rob Herring0d638a02017-06-01 15:50:55 -0500110 unittest(!np, "non-existent alias returned node %pOF\n", np);
Grant Likelyae91ff72014-03-14 13:53:10 +0000111 of_node_put(np);
112
113 np = of_find_node_by_path("testcase-alias/missing-path");
Rob Herring0d638a02017-06-01 15:50:55 -0500114 unittest(!np, "non-existent alias with relative path returned node %pOF\n", np);
Grant Likelyae91ff72014-03-14 13:53:10 +0000115 of_node_put(np);
Leif Lindholm75c28c02014-11-28 11:34:28 +0000116
117 np = of_find_node_opts_by_path("/testcase-data:testoption", &options);
Wang Long9697a552015-03-11 08:36:54 +0000118 unittest(np && !strcmp("testoption", options),
Leif Lindholm75c28c02014-11-28 11:34:28 +0000119 "option path test failed\n");
120 of_node_put(np);
121
Peter Hurley8cbba1a2015-03-06 13:59:59 -0500122 np = of_find_node_opts_by_path("/testcase-data:test/option", &options);
Wang Long9697a552015-03-11 08:36:54 +0000123 unittest(np && !strcmp("test/option", options),
Peter Hurley8cbba1a2015-03-06 13:59:59 -0500124 "option path test, subcase #1 failed\n");
125 of_node_put(np);
126
Brian Norris5ca1b0d2015-03-17 12:30:32 -0700127 np = of_find_node_opts_by_path("/testcase-data/testcase-device1:test/option", &options);
Wang Long9697a552015-03-11 08:36:54 +0000128 unittest(np && !strcmp("test/option", options),
Brian Norris5ca1b0d2015-03-17 12:30:32 -0700129 "option path test, subcase #2 failed\n");
130 of_node_put(np);
131
Leif Lindholm75c28c02014-11-28 11:34:28 +0000132 np = of_find_node_opts_by_path("/testcase-data:testoption", NULL);
Wang Long9697a552015-03-11 08:36:54 +0000133 unittest(np, "NULL option path test failed\n");
Leif Lindholm75c28c02014-11-28 11:34:28 +0000134 of_node_put(np);
135
136 np = of_find_node_opts_by_path("testcase-alias:testaliasoption",
137 &options);
Wang Long9697a552015-03-11 08:36:54 +0000138 unittest(np && !strcmp("testaliasoption", options),
Leif Lindholm75c28c02014-11-28 11:34:28 +0000139 "option alias path test failed\n");
140 of_node_put(np);
141
Peter Hurley8cbba1a2015-03-06 13:59:59 -0500142 np = of_find_node_opts_by_path("testcase-alias:test/alias/option",
143 &options);
Wang Long9697a552015-03-11 08:36:54 +0000144 unittest(np && !strcmp("test/alias/option", options),
Peter Hurley8cbba1a2015-03-06 13:59:59 -0500145 "option alias path test, subcase #1 failed\n");
146 of_node_put(np);
147
Leif Lindholm75c28c02014-11-28 11:34:28 +0000148 np = of_find_node_opts_by_path("testcase-alias:testaliasoption", NULL);
Wang Long9697a552015-03-11 08:36:54 +0000149 unittest(np, "NULL option alias path test failed\n");
Leif Lindholm75c28c02014-11-28 11:34:28 +0000150 of_node_put(np);
151
152 options = "testoption";
153 np = of_find_node_opts_by_path("testcase-alias", &options);
Wang Long9697a552015-03-11 08:36:54 +0000154 unittest(np && !options, "option clearing test failed\n");
Leif Lindholm75c28c02014-11-28 11:34:28 +0000155 of_node_put(np);
156
157 options = "testoption";
158 np = of_find_node_opts_by_path("/", &options);
Wang Long9697a552015-03-11 08:36:54 +0000159 unittest(np && !options, "option clearing root node test failed\n");
Leif Lindholm75c28c02014-11-28 11:34:28 +0000160 of_node_put(np);
Grant Likelyae91ff72014-03-14 13:53:10 +0000161}
162
Wang Long9697a552015-03-11 08:36:54 +0000163static void __init of_unittest_dynamic(void)
Grant Likely7e66c5c2013-11-15 17:19:09 +0000164{
165 struct device_node *np;
166 struct property *prop;
167
168 np = of_find_node_by_path("/testcase-data");
169 if (!np) {
170 pr_err("missing testcase data\n");
171 return;
172 }
173
174 /* Array of 4 properties for the purpose of testing */
Kees Cook6396bb22018-06-12 14:03:40 -0700175 prop = kcalloc(4, sizeof(*prop), GFP_KERNEL);
Grant Likely7e66c5c2013-11-15 17:19:09 +0000176 if (!prop) {
Wang Long9697a552015-03-11 08:36:54 +0000177 unittest(0, "kzalloc() failed\n");
Grant Likely7e66c5c2013-11-15 17:19:09 +0000178 return;
179 }
180
181 /* Add a new property - should pass*/
182 prop->name = "new-property";
183 prop->value = "new-property-data";
Stefan M Schaeckeler3b9cf792018-05-21 16:26:14 -0700184 prop->length = strlen(prop->value) + 1;
Wang Long9697a552015-03-11 08:36:54 +0000185 unittest(of_add_property(np, prop) == 0, "Adding a new property failed\n");
Grant Likely7e66c5c2013-11-15 17:19:09 +0000186
187 /* Try to add an existing property - should fail */
188 prop++;
189 prop->name = "new-property";
190 prop->value = "new-property-data-should-fail";
Stefan M Schaeckeler3b9cf792018-05-21 16:26:14 -0700191 prop->length = strlen(prop->value) + 1;
Wang Long9697a552015-03-11 08:36:54 +0000192 unittest(of_add_property(np, prop) != 0,
Grant Likely7e66c5c2013-11-15 17:19:09 +0000193 "Adding an existing property should have failed\n");
194
195 /* Try to modify an existing property - should pass */
196 prop->value = "modify-property-data-should-pass";
Stefan M Schaeckeler3b9cf792018-05-21 16:26:14 -0700197 prop->length = strlen(prop->value) + 1;
Wang Long9697a552015-03-11 08:36:54 +0000198 unittest(of_update_property(np, prop) == 0,
Grant Likely7e66c5c2013-11-15 17:19:09 +0000199 "Updating an existing property should have passed\n");
200
201 /* Try to modify non-existent property - should pass*/
202 prop++;
203 prop->name = "modify-property";
204 prop->value = "modify-missing-property-data-should-pass";
Stefan M Schaeckeler3b9cf792018-05-21 16:26:14 -0700205 prop->length = strlen(prop->value) + 1;
Wang Long9697a552015-03-11 08:36:54 +0000206 unittest(of_update_property(np, prop) == 0,
Grant Likely7e66c5c2013-11-15 17:19:09 +0000207 "Updating a missing property should have passed\n");
208
209 /* Remove property - should pass */
Wang Long9697a552015-03-11 08:36:54 +0000210 unittest(of_remove_property(np, prop) == 0,
Grant Likely7e66c5c2013-11-15 17:19:09 +0000211 "Removing a property should have passed\n");
212
213 /* Adding very large property - should pass */
214 prop++;
215 prop->name = "large-property-PAGE_SIZEx8";
216 prop->length = PAGE_SIZE * 8;
217 prop->value = kzalloc(prop->length, GFP_KERNEL);
Wang Long9697a552015-03-11 08:36:54 +0000218 unittest(prop->value != NULL, "Unable to allocate large buffer\n");
Grant Likely7e66c5c2013-11-15 17:19:09 +0000219 if (prop->value)
Wang Long9697a552015-03-11 08:36:54 +0000220 unittest(of_add_property(np, prop) == 0,
Grant Likely7e66c5c2013-11-15 17:19:09 +0000221 "Adding a large property should have passed\n");
222}
223
Wang Long9697a552015-03-11 08:36:54 +0000224static int __init of_unittest_check_node_linkage(struct device_node *np)
Grant Likelyf2051d62014-10-01 17:40:22 +0100225{
Grant Likely5063e252014-10-03 16:28:27 +0100226 struct device_node *child;
Grant Likelyf2051d62014-10-01 17:40:22 +0100227 int count = 0, rc;
228
229 for_each_child_of_node(np, child) {
230 if (child->parent != np) {
Rob Herringa613b262018-08-27 20:00:19 -0500231 pr_err("Child node %pOFn links to wrong parent %pOFn\n",
232 child, np);
Julia Lawall855ff282015-10-22 11:02:50 +0200233 rc = -EINVAL;
234 goto put_child;
Grant Likelyf2051d62014-10-01 17:40:22 +0100235 }
236
Wang Long9697a552015-03-11 08:36:54 +0000237 rc = of_unittest_check_node_linkage(child);
Grant Likelyf2051d62014-10-01 17:40:22 +0100238 if (rc < 0)
Julia Lawall855ff282015-10-22 11:02:50 +0200239 goto put_child;
Grant Likelyf2051d62014-10-01 17:40:22 +0100240 count += rc;
241 }
242
243 return count + 1;
Julia Lawall855ff282015-10-22 11:02:50 +0200244put_child:
245 of_node_put(child);
246 return rc;
Grant Likelyf2051d62014-10-01 17:40:22 +0100247}
248
Wang Long9697a552015-03-11 08:36:54 +0000249static void __init of_unittest_check_tree_linkage(void)
Grant Likelyf2051d62014-10-01 17:40:22 +0100250{
251 struct device_node *np;
252 int allnode_count = 0, child_count;
253
Grant Likely5063e252014-10-03 16:28:27 +0100254 if (!of_root)
Grant Likelyf2051d62014-10-01 17:40:22 +0100255 return;
256
257 for_each_of_allnodes(np)
258 allnode_count++;
Wang Long9697a552015-03-11 08:36:54 +0000259 child_count = of_unittest_check_node_linkage(of_root);
Grant Likelyf2051d62014-10-01 17:40:22 +0100260
Wang Long9697a552015-03-11 08:36:54 +0000261 unittest(child_count > 0, "Device node data structure is corrupted\n");
Grant Likelya2166ca2015-03-29 08:59:58 +0100262 unittest(child_count == allnode_count,
Frank Rowanda6bb1212015-03-13 23:59:01 -0700263 "allnodes list size (%i) doesn't match sibling lists size (%i)\n",
264 allnode_count, child_count);
Grant Likelyf2051d62014-10-01 17:40:22 +0100265 pr_debug("allnodes list size (%i); sibling lists size (%i)\n", allnode_count, child_count);
266}
267
Pantelis Antoniouce4fecf2015-01-21 19:06:14 +0200268static void __init of_unittest_printf_one(struct device_node *np, const char *fmt,
269 const char *expected)
270{
Tobin C. Hardingd4b9e422018-03-12 15:27:23 +1100271 unsigned char *buf;
272 int buf_size;
Pantelis Antoniouce4fecf2015-01-21 19:06:14 +0200273 int size, i;
274
Tobin C. Hardingd4b9e422018-03-12 15:27:23 +1100275 buf_size = strlen(expected) + 10;
276 buf = kmalloc(buf_size, GFP_KERNEL);
277 if (!buf)
278 return;
279
Pantelis Antoniouce4fecf2015-01-21 19:06:14 +0200280 /* Baseline; check conversion with a large size limit */
Tobin C. Hardingd4b9e422018-03-12 15:27:23 +1100281 memset(buf, 0xff, buf_size);
282 size = snprintf(buf, buf_size - 2, fmt, np);
Pantelis Antoniouce4fecf2015-01-21 19:06:14 +0200283
284 /* use strcmp() instead of strncmp() here to be absolutely sure strings match */
285 unittest((strcmp(buf, expected) == 0) && (buf[size+1] == 0xff),
286 "sprintf failed; fmt='%s' expected='%s' rslt='%s'\n",
287 fmt, expected, buf);
288
289 /* Make sure length limits work */
290 size++;
291 for (i = 0; i < 2; i++, size--) {
292 /* Clear the buffer, and make sure it works correctly still */
Tobin C. Hardingd4b9e422018-03-12 15:27:23 +1100293 memset(buf, 0xff, buf_size);
Pantelis Antoniouce4fecf2015-01-21 19:06:14 +0200294 snprintf(buf, size+1, fmt, np);
295 unittest(strncmp(buf, expected, size) == 0 && (buf[size+1] == 0xff),
296 "snprintf failed; size=%i fmt='%s' expected='%s' rslt='%s'\n",
297 size, fmt, expected, buf);
298 }
Tobin C. Hardingd4b9e422018-03-12 15:27:23 +1100299 kfree(buf);
Pantelis Antoniouce4fecf2015-01-21 19:06:14 +0200300}
301
302static void __init of_unittest_printf(void)
303{
304 struct device_node *np;
305 const char *full_name = "/testcase-data/platform-tests/test-device@1/dev@100";
306 char phandle_str[16] = "";
307
308 np = of_find_node_by_path(full_name);
309 if (!np) {
310 unittest(np, "testcase data missing\n");
311 return;
312 }
313
Andrei Vagind1be35c2018-04-10 16:31:16 -0700314 num_to_str(phandle_str, sizeof(phandle_str), np->phandle, 0);
Pantelis Antoniouce4fecf2015-01-21 19:06:14 +0200315
316 of_unittest_printf_one(np, "%pOF", full_name);
317 of_unittest_printf_one(np, "%pOFf", full_name);
Rob Herring69013782018-08-27 09:05:06 -0500318 of_unittest_printf_one(np, "%pOFn", "dev");
319 of_unittest_printf_one(np, "%2pOFn", "dev");
320 of_unittest_printf_one(np, "%5pOFn", " dev");
321 of_unittest_printf_one(np, "%pOFnc", "dev:test-sub-device");
Pantelis Antoniouce4fecf2015-01-21 19:06:14 +0200322 of_unittest_printf_one(np, "%pOFp", phandle_str);
323 of_unittest_printf_one(np, "%pOFP", "dev@100");
324 of_unittest_printf_one(np, "ABC %pOFP ABC", "ABC dev@100 ABC");
325 of_unittest_printf_one(np, "%10pOFP", " dev@100");
326 of_unittest_printf_one(np, "%-10pOFP", "dev@100 ");
327 of_unittest_printf_one(of_root, "%pOFP", "/");
328 of_unittest_printf_one(np, "%pOFF", "----");
329 of_unittest_printf_one(np, "%pOFPF", "dev@100:----");
330 of_unittest_printf_one(np, "%pOFPFPc", "dev@100:----:dev@100:test-sub-device");
331 of_unittest_printf_one(np, "%pOFc", "test-sub-device");
332 of_unittest_printf_one(np, "%pOFC",
333 "\"test-sub-device\",\"test-compat2\",\"test-compat3\"");
334}
335
Grant Likely841ec212014-10-02 13:09:15 +0100336struct node_hash {
337 struct hlist_node node;
338 struct device_node *np;
339};
340
Grant Likely2118f4b2014-10-07 11:30:31 +0100341static DEFINE_HASHTABLE(phandle_ht, 8);
Wang Long9697a552015-03-11 08:36:54 +0000342static void __init of_unittest_check_phandles(void)
Grant Likely841ec212014-10-02 13:09:15 +0100343{
344 struct device_node *np;
345 struct node_hash *nh;
346 struct hlist_node *tmp;
347 int i, dup_count = 0, phandle_count = 0;
Grant Likely841ec212014-10-02 13:09:15 +0100348
Grant Likely841ec212014-10-02 13:09:15 +0100349 for_each_of_allnodes(np) {
350 if (!np->phandle)
351 continue;
352
Grant Likely2118f4b2014-10-07 11:30:31 +0100353 hash_for_each_possible(phandle_ht, nh, node, np->phandle) {
Grant Likely841ec212014-10-02 13:09:15 +0100354 if (nh->np->phandle == np->phandle) {
Rob Herring0d638a02017-06-01 15:50:55 -0500355 pr_info("Duplicate phandle! %i used by %pOF and %pOF\n",
356 np->phandle, nh->np, np);
Grant Likely841ec212014-10-02 13:09:15 +0100357 dup_count++;
358 break;
359 }
360 }
361
362 nh = kzalloc(sizeof(*nh), GFP_KERNEL);
Geert Uytterhoeven2a656cb2019-05-02 14:45:35 +0200363 if (!nh)
Grant Likely841ec212014-10-02 13:09:15 +0100364 return;
365
366 nh->np = np;
Grant Likely2118f4b2014-10-07 11:30:31 +0100367 hash_add(phandle_ht, &nh->node, np->phandle);
Grant Likely841ec212014-10-02 13:09:15 +0100368 phandle_count++;
369 }
Wang Long9697a552015-03-11 08:36:54 +0000370 unittest(dup_count == 0, "Found %i duplicates in %i phandles\n",
Grant Likely841ec212014-10-02 13:09:15 +0100371 dup_count, phandle_count);
372
373 /* Clean up */
Grant Likely2118f4b2014-10-07 11:30:31 +0100374 hash_for_each_safe(phandle_ht, i, tmp, nh, node) {
Grant Likely841ec212014-10-02 13:09:15 +0100375 hash_del(&nh->node);
376 kfree(nh);
377 }
378}
379
Wang Long9697a552015-03-11 08:36:54 +0000380static void __init of_unittest_parse_phandle_with_args(void)
Grant Likely53a42092011-12-12 09:25:57 -0700381{
382 struct device_node *np;
383 struct of_phandle_args args;
Grant Likelycabb7d52013-02-12 21:19:37 +0000384 int i, rc;
Grant Likely53a42092011-12-12 09:25:57 -0700385
Grant Likely53a42092011-12-12 09:25:57 -0700386 np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
387 if (!np) {
388 pr_err("missing testcase data\n");
389 return;
390 }
391
Grant Likelybd69f732013-02-10 22:57:21 +0000392 rc = of_count_phandle_with_args(np, "phandle-list", "#phandle-cells");
Wang Long9697a552015-03-11 08:36:54 +0000393 unittest(rc == 7, "of_count_phandle_with_args() returned %i, expected 7\n", rc);
Grant Likelybd69f732013-02-10 22:57:21 +0000394
Grant Likelyf7f951c2013-02-12 17:41:22 +0000395 for (i = 0; i < 8; i++) {
Grant Likely53a42092011-12-12 09:25:57 -0700396 bool passed = true;
Frank Rowand3db316d2015-03-14 00:02:31 -0700397
Frank Rowandeeb07c52018-10-04 20:40:21 -0700398 memset(&args, 0, sizeof(args));
Grant Likely53a42092011-12-12 09:25:57 -0700399 rc = of_parse_phandle_with_args(np, "phandle-list",
400 "#phandle-cells", i, &args);
401
402 /* Test the values from tests-phandle.dtsi */
403 switch (i) {
404 case 0:
405 passed &= !rc;
406 passed &= (args.args_count == 1);
407 passed &= (args.args[0] == (i + 1));
408 break;
409 case 1:
410 passed &= !rc;
411 passed &= (args.args_count == 2);
412 passed &= (args.args[0] == (i + 1));
413 passed &= (args.args[1] == 0);
414 break;
415 case 2:
416 passed &= (rc == -ENOENT);
417 break;
418 case 3:
419 passed &= !rc;
420 passed &= (args.args_count == 3);
421 passed &= (args.args[0] == (i + 1));
422 passed &= (args.args[1] == 4);
423 passed &= (args.args[2] == 3);
424 break;
425 case 4:
426 passed &= !rc;
427 passed &= (args.args_count == 2);
428 passed &= (args.args[0] == (i + 1));
429 passed &= (args.args[1] == 100);
430 break;
431 case 5:
432 passed &= !rc;
433 passed &= (args.args_count == 0);
434 break;
435 case 6:
436 passed &= !rc;
437 passed &= (args.args_count == 1);
438 passed &= (args.args[0] == (i + 1));
439 break;
440 case 7:
Grant Likelycabb7d52013-02-12 21:19:37 +0000441 passed &= (rc == -ENOENT);
Grant Likely53a42092011-12-12 09:25:57 -0700442 break;
443 default:
444 passed = false;
445 }
446
Rob Herring0d638a02017-06-01 15:50:55 -0500447 unittest(passed, "index %i - data error on node %pOF rc=%i\n",
448 i, args.np, rc);
Grant Likely53a42092011-12-12 09:25:57 -0700449 }
450
451 /* Check for missing list property */
Frank Rowandeeb07c52018-10-04 20:40:21 -0700452 memset(&args, 0, sizeof(args));
Grant Likely53a42092011-12-12 09:25:57 -0700453 rc = of_parse_phandle_with_args(np, "phandle-list-missing",
454 "#phandle-cells", 0, &args);
Wang Long9697a552015-03-11 08:36:54 +0000455 unittest(rc == -ENOENT, "expected:%i got:%i\n", -ENOENT, rc);
Grant Likelybd69f732013-02-10 22:57:21 +0000456 rc = of_count_phandle_with_args(np, "phandle-list-missing",
457 "#phandle-cells");
Wang Long9697a552015-03-11 08:36:54 +0000458 unittest(rc == -ENOENT, "expected:%i got:%i\n", -ENOENT, rc);
Grant Likely53a42092011-12-12 09:25:57 -0700459
460 /* Check for missing cells property */
Frank Rowandeeb07c52018-10-04 20:40:21 -0700461 memset(&args, 0, sizeof(args));
Frank Rowand0ac17432020-02-20 12:40:21 -0600462
463 EXPECT_BEGIN(KERN_INFO,
464 "OF: /testcase-data/phandle-tests/consumer-a: could not get #phandle-cells-missing for /testcase-data/phandle-tests/provider1");
465
Grant Likely53a42092011-12-12 09:25:57 -0700466 rc = of_parse_phandle_with_args(np, "phandle-list",
467 "#phandle-cells-missing", 0, &args);
Frank Rowand0ac17432020-02-20 12:40:21 -0600468
469 EXPECT_END(KERN_INFO,
470 "OF: /testcase-data/phandle-tests/consumer-a: could not get #phandle-cells-missing for /testcase-data/phandle-tests/provider1");
471
Wang Long9697a552015-03-11 08:36:54 +0000472 unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
Frank Rowand0ac17432020-02-20 12:40:21 -0600473
474 EXPECT_BEGIN(KERN_INFO,
475 "OF: /testcase-data/phandle-tests/consumer-a: could not get #phandle-cells-missing for /testcase-data/phandle-tests/provider1");
476
Grant Likelybd69f732013-02-10 22:57:21 +0000477 rc = of_count_phandle_with_args(np, "phandle-list",
478 "#phandle-cells-missing");
Frank Rowand0ac17432020-02-20 12:40:21 -0600479
480 EXPECT_END(KERN_INFO,
481 "OF: /testcase-data/phandle-tests/consumer-a: could not get #phandle-cells-missing for /testcase-data/phandle-tests/provider1");
482
Wang Long9697a552015-03-11 08:36:54 +0000483 unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
Grant Likely53a42092011-12-12 09:25:57 -0700484
485 /* Check for bad phandle in list */
Frank Rowandeeb07c52018-10-04 20:40:21 -0700486 memset(&args, 0, sizeof(args));
Frank Rowand0ac17432020-02-20 12:40:21 -0600487
488 EXPECT_BEGIN(KERN_INFO,
489 "OF: /testcase-data/phandle-tests/consumer-a: could not find phandle");
490
Grant Likely53a42092011-12-12 09:25:57 -0700491 rc = of_parse_phandle_with_args(np, "phandle-list-bad-phandle",
492 "#phandle-cells", 0, &args);
Frank Rowand0ac17432020-02-20 12:40:21 -0600493
494 EXPECT_END(KERN_INFO,
495 "OF: /testcase-data/phandle-tests/consumer-a: could not find phandle");
496
Wang Long9697a552015-03-11 08:36:54 +0000497 unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
Frank Rowand0ac17432020-02-20 12:40:21 -0600498
499 EXPECT_BEGIN(KERN_INFO,
500 "OF: /testcase-data/phandle-tests/consumer-a: could not find phandle");
501
Grant Likelybd69f732013-02-10 22:57:21 +0000502 rc = of_count_phandle_with_args(np, "phandle-list-bad-phandle",
503 "#phandle-cells");
Frank Rowand0ac17432020-02-20 12:40:21 -0600504
505 EXPECT_END(KERN_INFO,
506 "OF: /testcase-data/phandle-tests/consumer-a: could not find phandle");
507
Wang Long9697a552015-03-11 08:36:54 +0000508 unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
Grant Likely53a42092011-12-12 09:25:57 -0700509
510 /* Check for incorrectly formed argument list */
Frank Rowandeeb07c52018-10-04 20:40:21 -0700511 memset(&args, 0, sizeof(args));
Frank Rowand0ac17432020-02-20 12:40:21 -0600512
513 EXPECT_BEGIN(KERN_INFO,
514 "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found -1");
515
Grant Likely53a42092011-12-12 09:25:57 -0700516 rc = of_parse_phandle_with_args(np, "phandle-list-bad-args",
517 "#phandle-cells", 1, &args);
Frank Rowand0ac17432020-02-20 12:40:21 -0600518
519 EXPECT_END(KERN_INFO,
520 "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found -1");
521
Wang Long9697a552015-03-11 08:36:54 +0000522 unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
Frank Rowand0ac17432020-02-20 12:40:21 -0600523
524 EXPECT_BEGIN(KERN_INFO,
525 "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found -1");
526
Grant Likelybd69f732013-02-10 22:57:21 +0000527 rc = of_count_phandle_with_args(np, "phandle-list-bad-args",
528 "#phandle-cells");
Frank Rowand0ac17432020-02-20 12:40:21 -0600529
530 EXPECT_END(KERN_INFO,
531 "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found -1");
532
Wang Long9697a552015-03-11 08:36:54 +0000533 unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
Grant Likely53a42092011-12-12 09:25:57 -0700534}
535
Stephen Boyd357aa4b2018-01-30 18:36:17 -0800536static void __init of_unittest_parse_phandle_with_args_map(void)
537{
538 struct device_node *np, *p0, *p1, *p2, *p3;
539 struct of_phandle_args args;
540 int i, rc;
541
542 np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-b");
543 if (!np) {
544 pr_err("missing testcase data\n");
545 return;
546 }
547
548 p0 = of_find_node_by_path("/testcase-data/phandle-tests/provider0");
549 if (!p0) {
550 pr_err("missing testcase data\n");
551 return;
552 }
553
554 p1 = of_find_node_by_path("/testcase-data/phandle-tests/provider1");
555 if (!p1) {
556 pr_err("missing testcase data\n");
557 return;
558 }
559
560 p2 = of_find_node_by_path("/testcase-data/phandle-tests/provider2");
561 if (!p2) {
562 pr_err("missing testcase data\n");
563 return;
564 }
565
566 p3 = of_find_node_by_path("/testcase-data/phandle-tests/provider3");
567 if (!p3) {
568 pr_err("missing testcase data\n");
569 return;
570 }
571
572 rc = of_count_phandle_with_args(np, "phandle-list", "#phandle-cells");
573 unittest(rc == 7, "of_count_phandle_with_args() returned %i, expected 7\n", rc);
574
575 for (i = 0; i < 8; i++) {
576 bool passed = true;
577
Frank Rowandeeb07c52018-10-04 20:40:21 -0700578 memset(&args, 0, sizeof(args));
Stephen Boyd357aa4b2018-01-30 18:36:17 -0800579 rc = of_parse_phandle_with_args_map(np, "phandle-list",
580 "phandle", i, &args);
581
582 /* Test the values from tests-phandle.dtsi */
583 switch (i) {
584 case 0:
585 passed &= !rc;
586 passed &= (args.np == p1);
587 passed &= (args.args_count == 1);
588 passed &= (args.args[0] == 1);
589 break;
590 case 1:
591 passed &= !rc;
592 passed &= (args.np == p3);
593 passed &= (args.args_count == 3);
594 passed &= (args.args[0] == 2);
595 passed &= (args.args[1] == 5);
596 passed &= (args.args[2] == 3);
597 break;
598 case 2:
599 passed &= (rc == -ENOENT);
600 break;
601 case 3:
602 passed &= !rc;
603 passed &= (args.np == p0);
604 passed &= (args.args_count == 0);
605 break;
606 case 4:
607 passed &= !rc;
608 passed &= (args.np == p1);
609 passed &= (args.args_count == 1);
610 passed &= (args.args[0] == 3);
611 break;
612 case 5:
613 passed &= !rc;
614 passed &= (args.np == p0);
615 passed &= (args.args_count == 0);
616 break;
617 case 6:
618 passed &= !rc;
619 passed &= (args.np == p2);
620 passed &= (args.args_count == 2);
621 passed &= (args.args[0] == 15);
622 passed &= (args.args[1] == 0x20);
623 break;
624 case 7:
625 passed &= (rc == -ENOENT);
626 break;
627 default:
628 passed = false;
629 }
630
631 unittest(passed, "index %i - data error on node %s rc=%i\n",
632 i, args.np->full_name, rc);
633 }
634
635 /* Check for missing list property */
Frank Rowandeeb07c52018-10-04 20:40:21 -0700636 memset(&args, 0, sizeof(args));
Stephen Boyd357aa4b2018-01-30 18:36:17 -0800637 rc = of_parse_phandle_with_args_map(np, "phandle-list-missing",
638 "phandle", 0, &args);
639 unittest(rc == -ENOENT, "expected:%i got:%i\n", -ENOENT, rc);
640
641 /* Check for missing cells,map,mask property */
Frank Rowandeeb07c52018-10-04 20:40:21 -0700642 memset(&args, 0, sizeof(args));
Frank Rowand0ac17432020-02-20 12:40:21 -0600643
644 EXPECT_BEGIN(KERN_INFO,
645 "OF: /testcase-data/phandle-tests/consumer-b: could not get #phandle-missing-cells for /testcase-data/phandle-tests/provider1");
646
Stephen Boyd357aa4b2018-01-30 18:36:17 -0800647 rc = of_parse_phandle_with_args_map(np, "phandle-list",
648 "phandle-missing", 0, &args);
Frank Rowand0ac17432020-02-20 12:40:21 -0600649 EXPECT_END(KERN_INFO,
650 "OF: /testcase-data/phandle-tests/consumer-b: could not get #phandle-missing-cells for /testcase-data/phandle-tests/provider1");
651
Stephen Boyd357aa4b2018-01-30 18:36:17 -0800652 unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
653
654 /* Check for bad phandle in list */
Frank Rowandeeb07c52018-10-04 20:40:21 -0700655 memset(&args, 0, sizeof(args));
Frank Rowand0ac17432020-02-20 12:40:21 -0600656
657 EXPECT_BEGIN(KERN_INFO,
658 "OF: /testcase-data/phandle-tests/consumer-b: could not find phandle");
659
Stephen Boyd357aa4b2018-01-30 18:36:17 -0800660 rc = of_parse_phandle_with_args_map(np, "phandle-list-bad-phandle",
661 "phandle", 0, &args);
Frank Rowand0ac17432020-02-20 12:40:21 -0600662 EXPECT_END(KERN_INFO,
663 "OF: /testcase-data/phandle-tests/consumer-b: could not find phandle");
664
Stephen Boyd357aa4b2018-01-30 18:36:17 -0800665 unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
666
667 /* Check for incorrectly formed argument list */
Frank Rowandeeb07c52018-10-04 20:40:21 -0700668 memset(&args, 0, sizeof(args));
Frank Rowand0ac17432020-02-20 12:40:21 -0600669
670 EXPECT_BEGIN(KERN_INFO,
671 "OF: /testcase-data/phandle-tests/consumer-b: #phandle-cells = 2 found -1");
672
Stephen Boyd357aa4b2018-01-30 18:36:17 -0800673 rc = of_parse_phandle_with_args_map(np, "phandle-list-bad-args",
674 "phandle", 1, &args);
Frank Rowand0ac17432020-02-20 12:40:21 -0600675 EXPECT_END(KERN_INFO,
676 "OF: /testcase-data/phandle-tests/consumer-b: #phandle-cells = 2 found -1");
677
Stephen Boyd357aa4b2018-01-30 18:36:17 -0800678 unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
679}
680
Wang Long9697a552015-03-11 08:36:54 +0000681static void __init of_unittest_property_string(void)
Grant Likely7aff0fe2011-12-12 09:25:58 -0700682{
Grant Likelya87fa1d2014-11-03 15:15:35 +0000683 const char *strings[4];
Grant Likely7aff0fe2011-12-12 09:25:58 -0700684 struct device_node *np;
685 int rc;
686
Grant Likely7aff0fe2011-12-12 09:25:58 -0700687 np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
688 if (!np) {
689 pr_err("No testcase data in device tree\n");
690 return;
691 }
692
693 rc = of_property_match_string(np, "phandle-list-names", "first");
Wang Long9697a552015-03-11 08:36:54 +0000694 unittest(rc == 0, "first expected:0 got:%i\n", rc);
Grant Likely7aff0fe2011-12-12 09:25:58 -0700695 rc = of_property_match_string(np, "phandle-list-names", "second");
Wang Long9697a552015-03-11 08:36:54 +0000696 unittest(rc == 1, "second expected:1 got:%i\n", rc);
Grant Likely7aff0fe2011-12-12 09:25:58 -0700697 rc = of_property_match_string(np, "phandle-list-names", "third");
Wang Long9697a552015-03-11 08:36:54 +0000698 unittest(rc == 2, "third expected:2 got:%i\n", rc);
Grant Likely7aff0fe2011-12-12 09:25:58 -0700699 rc = of_property_match_string(np, "phandle-list-names", "fourth");
Wang Long9697a552015-03-11 08:36:54 +0000700 unittest(rc == -ENODATA, "unmatched string; rc=%i\n", rc);
Grant Likely7aff0fe2011-12-12 09:25:58 -0700701 rc = of_property_match_string(np, "missing-property", "blah");
Wang Long9697a552015-03-11 08:36:54 +0000702 unittest(rc == -EINVAL, "missing property; rc=%i\n", rc);
Grant Likely7aff0fe2011-12-12 09:25:58 -0700703 rc = of_property_match_string(np, "empty-property", "blah");
Wang Long9697a552015-03-11 08:36:54 +0000704 unittest(rc == -ENODATA, "empty property; rc=%i\n", rc);
Grant Likely7aff0fe2011-12-12 09:25:58 -0700705 rc = of_property_match_string(np, "unterminated-string", "blah");
Wang Long9697a552015-03-11 08:36:54 +0000706 unittest(rc == -EILSEQ, "unterminated string; rc=%i\n", rc);
Grant Likelya87fa1d2014-11-03 15:15:35 +0000707
708 /* of_property_count_strings() tests */
709 rc = of_property_count_strings(np, "string-property");
Wang Long9697a552015-03-11 08:36:54 +0000710 unittest(rc == 1, "Incorrect string count; rc=%i\n", rc);
Grant Likelya87fa1d2014-11-03 15:15:35 +0000711 rc = of_property_count_strings(np, "phandle-list-names");
Wang Long9697a552015-03-11 08:36:54 +0000712 unittest(rc == 3, "Incorrect string count; rc=%i\n", rc);
Grant Likelya87fa1d2014-11-03 15:15:35 +0000713 rc = of_property_count_strings(np, "unterminated-string");
Wang Long9697a552015-03-11 08:36:54 +0000714 unittest(rc == -EILSEQ, "unterminated string; rc=%i\n", rc);
Grant Likelya87fa1d2014-11-03 15:15:35 +0000715 rc = of_property_count_strings(np, "unterminated-string-list");
Wang Long9697a552015-03-11 08:36:54 +0000716 unittest(rc == -EILSEQ, "unterminated string array; rc=%i\n", rc);
Grant Likelya87fa1d2014-11-03 15:15:35 +0000717
718 /* of_property_read_string_index() tests */
719 rc = of_property_read_string_index(np, "string-property", 0, strings);
Wang Long9697a552015-03-11 08:36:54 +0000720 unittest(rc == 0 && !strcmp(strings[0], "foobar"), "of_property_read_string_index() failure; rc=%i\n", rc);
Grant Likelya87fa1d2014-11-03 15:15:35 +0000721 strings[0] = NULL;
722 rc = of_property_read_string_index(np, "string-property", 1, strings);
Wang Long9697a552015-03-11 08:36:54 +0000723 unittest(rc == -ENODATA && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc);
Grant Likelya87fa1d2014-11-03 15:15:35 +0000724 rc = of_property_read_string_index(np, "phandle-list-names", 0, strings);
Wang Long9697a552015-03-11 08:36:54 +0000725 unittest(rc == 0 && !strcmp(strings[0], "first"), "of_property_read_string_index() failure; rc=%i\n", rc);
Grant Likelya87fa1d2014-11-03 15:15:35 +0000726 rc = of_property_read_string_index(np, "phandle-list-names", 1, strings);
Wang Long9697a552015-03-11 08:36:54 +0000727 unittest(rc == 0 && !strcmp(strings[0], "second"), "of_property_read_string_index() failure; rc=%i\n", rc);
Grant Likelya87fa1d2014-11-03 15:15:35 +0000728 rc = of_property_read_string_index(np, "phandle-list-names", 2, strings);
Wang Long9697a552015-03-11 08:36:54 +0000729 unittest(rc == 0 && !strcmp(strings[0], "third"), "of_property_read_string_index() failure; rc=%i\n", rc);
Grant Likelya87fa1d2014-11-03 15:15:35 +0000730 strings[0] = NULL;
731 rc = of_property_read_string_index(np, "phandle-list-names", 3, strings);
Wang Long9697a552015-03-11 08:36:54 +0000732 unittest(rc == -ENODATA && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc);
Grant Likelya87fa1d2014-11-03 15:15:35 +0000733 strings[0] = NULL;
734 rc = of_property_read_string_index(np, "unterminated-string", 0, strings);
Wang Long9697a552015-03-11 08:36:54 +0000735 unittest(rc == -EILSEQ && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc);
Grant Likelya87fa1d2014-11-03 15:15:35 +0000736 rc = of_property_read_string_index(np, "unterminated-string-list", 0, strings);
Wang Long9697a552015-03-11 08:36:54 +0000737 unittest(rc == 0 && !strcmp(strings[0], "first"), "of_property_read_string_index() failure; rc=%i\n", rc);
Grant Likelya87fa1d2014-11-03 15:15:35 +0000738 strings[0] = NULL;
739 rc = of_property_read_string_index(np, "unterminated-string-list", 2, strings); /* should fail */
Wang Long9697a552015-03-11 08:36:54 +0000740 unittest(rc == -EILSEQ && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc);
Grant Likelya87fa1d2014-11-03 15:15:35 +0000741 strings[1] = NULL;
742
743 /* of_property_read_string_array() tests */
744 rc = of_property_read_string_array(np, "string-property", strings, 4);
Wang Long9697a552015-03-11 08:36:54 +0000745 unittest(rc == 1, "Incorrect string count; rc=%i\n", rc);
Grant Likelya87fa1d2014-11-03 15:15:35 +0000746 rc = of_property_read_string_array(np, "phandle-list-names", strings, 4);
Wang Long9697a552015-03-11 08:36:54 +0000747 unittest(rc == 3, "Incorrect string count; rc=%i\n", rc);
Grant Likelya87fa1d2014-11-03 15:15:35 +0000748 rc = of_property_read_string_array(np, "unterminated-string", strings, 4);
Wang Long9697a552015-03-11 08:36:54 +0000749 unittest(rc == -EILSEQ, "unterminated string; rc=%i\n", rc);
Grant Likelya87fa1d2014-11-03 15:15:35 +0000750 /* -- An incorrectly formed string should cause a failure */
751 rc = of_property_read_string_array(np, "unterminated-string-list", strings, 4);
Wang Long9697a552015-03-11 08:36:54 +0000752 unittest(rc == -EILSEQ, "unterminated string array; rc=%i\n", rc);
Grant Likelya87fa1d2014-11-03 15:15:35 +0000753 /* -- parsing the correctly formed strings should still work: */
754 strings[2] = NULL;
755 rc = of_property_read_string_array(np, "unterminated-string-list", strings, 2);
Wang Long9697a552015-03-11 08:36:54 +0000756 unittest(rc == 2 && strings[2] == NULL, "of_property_read_string_array() failure; rc=%i\n", rc);
Grant Likelya87fa1d2014-11-03 15:15:35 +0000757 strings[1] = NULL;
758 rc = of_property_read_string_array(np, "phandle-list-names", strings, 1);
Wang Long9697a552015-03-11 08:36:54 +0000759 unittest(rc == 1 && strings[1] == NULL, "Overwrote end of string array; rc=%i, str='%s'\n", rc, strings[1]);
Grant Likely7aff0fe2011-12-12 09:25:58 -0700760}
761
Pantelis Antoniou69843392014-07-04 19:58:47 +0300762#define propcmp(p1, p2) (((p1)->length == (p2)->length) && \
763 (p1)->value && (p2)->value && \
764 !memcmp((p1)->value, (p2)->value, (p1)->length) && \
765 !strcmp((p1)->name, (p2)->name))
Wang Long9697a552015-03-11 08:36:54 +0000766static void __init of_unittest_property_copy(void)
Pantelis Antoniou69843392014-07-04 19:58:47 +0300767{
768#ifdef CONFIG_OF_DYNAMIC
769 struct property p1 = { .name = "p1", .length = 0, .value = "" };
770 struct property p2 = { .name = "p2", .length = 5, .value = "abcd" };
771 struct property *new;
772
773 new = __of_prop_dup(&p1, GFP_KERNEL);
Wang Long9697a552015-03-11 08:36:54 +0000774 unittest(new && propcmp(&p1, new), "empty property didn't copy correctly\n");
Pantelis Antoniou69843392014-07-04 19:58:47 +0300775 kfree(new->value);
776 kfree(new->name);
777 kfree(new);
778
779 new = __of_prop_dup(&p2, GFP_KERNEL);
Wang Long9697a552015-03-11 08:36:54 +0000780 unittest(new && propcmp(&p2, new), "non-empty property didn't copy correctly\n");
Pantelis Antoniou69843392014-07-04 19:58:47 +0300781 kfree(new->value);
782 kfree(new->name);
783 kfree(new);
784#endif
785}
786
Wang Long9697a552015-03-11 08:36:54 +0000787static void __init of_unittest_changeset(void)
Pantelis Antoniou201c9102014-07-04 19:58:49 +0300788{
789#ifdef CONFIG_OF_DYNAMIC
Frank Rowanda4f91f02018-02-26 14:01:22 -0800790 struct property *ppadd, padd = { .name = "prop-add", .length = 1, .value = "" };
791 struct property *ppname_n1, pname_n1 = { .name = "name", .length = 3, .value = "n1" };
792 struct property *ppname_n2, pname_n2 = { .name = "name", .length = 3, .value = "n2" };
793 struct property *ppname_n21, pname_n21 = { .name = "name", .length = 3, .value = "n21" };
Pantelis Antoniou201c9102014-07-04 19:58:49 +0300794 struct property *ppupdate, pupdate = { .name = "prop-update", .length = 5, .value = "abcd" };
795 struct property *ppremove;
Frank Rowanda4f91f02018-02-26 14:01:22 -0800796 struct device_node *n1, *n2, *n21, *nchangeset, *nremove, *parent, *np;
Pantelis Antoniou201c9102014-07-04 19:58:49 +0300797 struct of_changeset chgset;
798
Frank Rowandb89dae12018-02-26 14:01:23 -0800799 n1 = __of_node_dup(NULL, "n1");
Wang Long9697a552015-03-11 08:36:54 +0000800 unittest(n1, "testcase setup failure\n");
Frank Rowanda4f91f02018-02-26 14:01:22 -0800801
Frank Rowandb89dae12018-02-26 14:01:23 -0800802 n2 = __of_node_dup(NULL, "n2");
Wang Long9697a552015-03-11 08:36:54 +0000803 unittest(n2, "testcase setup failure\n");
Frank Rowanda4f91f02018-02-26 14:01:22 -0800804
Frank Rowandb89dae12018-02-26 14:01:23 -0800805 n21 = __of_node_dup(NULL, "n21");
Wang Long9697a552015-03-11 08:36:54 +0000806 unittest(n21, "testcase setup failure %p\n", n21);
Frank Rowanda4f91f02018-02-26 14:01:22 -0800807
808 nchangeset = of_find_node_by_path("/testcase-data/changeset");
809 nremove = of_get_child_by_name(nchangeset, "node-remove");
Wang Long9697a552015-03-11 08:36:54 +0000810 unittest(nremove, "testcase setup failure\n");
Frank Rowanda4f91f02018-02-26 14:01:22 -0800811
Pantelis Antoniou201c9102014-07-04 19:58:49 +0300812 ppadd = __of_prop_dup(&padd, GFP_KERNEL);
Wang Long9697a552015-03-11 08:36:54 +0000813 unittest(ppadd, "testcase setup failure\n");
Frank Rowanda4f91f02018-02-26 14:01:22 -0800814
815 ppname_n1 = __of_prop_dup(&pname_n1, GFP_KERNEL);
816 unittest(ppname_n1, "testcase setup failure\n");
817
818 ppname_n2 = __of_prop_dup(&pname_n2, GFP_KERNEL);
819 unittest(ppname_n2, "testcase setup failure\n");
820
821 ppname_n21 = __of_prop_dup(&pname_n21, GFP_KERNEL);
822 unittest(ppname_n21, "testcase setup failure\n");
823
Pantelis Antoniou201c9102014-07-04 19:58:49 +0300824 ppupdate = __of_prop_dup(&pupdate, GFP_KERNEL);
Wang Long9697a552015-03-11 08:36:54 +0000825 unittest(ppupdate, "testcase setup failure\n");
Frank Rowanda4f91f02018-02-26 14:01:22 -0800826
827 parent = nchangeset;
Pantelis Antoniou201c9102014-07-04 19:58:49 +0300828 n1->parent = parent;
829 n2->parent = parent;
830 n21->parent = n2;
Frank Rowanda4f91f02018-02-26 14:01:22 -0800831
Pantelis Antoniou201c9102014-07-04 19:58:49 +0300832 ppremove = of_find_property(parent, "prop-remove", NULL);
Wang Long9697a552015-03-11 08:36:54 +0000833 unittest(ppremove, "failed to find removal prop");
Pantelis Antoniou201c9102014-07-04 19:58:49 +0300834
835 of_changeset_init(&chgset);
Frank Rowanda4f91f02018-02-26 14:01:22 -0800836
Wang Long9697a552015-03-11 08:36:54 +0000837 unittest(!of_changeset_attach_node(&chgset, n1), "fail attach n1\n");
Frank Rowanda4f91f02018-02-26 14:01:22 -0800838 unittest(!of_changeset_add_property(&chgset, n1, ppname_n1), "fail add prop name\n");
839
Wang Long9697a552015-03-11 08:36:54 +0000840 unittest(!of_changeset_attach_node(&chgset, n2), "fail attach n2\n");
Frank Rowanda4f91f02018-02-26 14:01:22 -0800841 unittest(!of_changeset_add_property(&chgset, n2, ppname_n2), "fail add prop name\n");
842
Wang Long9697a552015-03-11 08:36:54 +0000843 unittest(!of_changeset_detach_node(&chgset, nremove), "fail remove node\n");
Frank Rowanda4f91f02018-02-26 14:01:22 -0800844 unittest(!of_changeset_add_property(&chgset, n21, ppname_n21), "fail add prop name\n");
845
Wang Long9697a552015-03-11 08:36:54 +0000846 unittest(!of_changeset_attach_node(&chgset, n21), "fail attach n21\n");
Frank Rowanda4f91f02018-02-26 14:01:22 -0800847
848 unittest(!of_changeset_add_property(&chgset, parent, ppadd), "fail add prop prop-add\n");
Wang Long9697a552015-03-11 08:36:54 +0000849 unittest(!of_changeset_update_property(&chgset, parent, ppupdate), "fail update prop\n");
850 unittest(!of_changeset_remove_property(&chgset, parent, ppremove), "fail remove prop\n");
Frank Rowanda4f91f02018-02-26 14:01:22 -0800851
Wang Long9697a552015-03-11 08:36:54 +0000852 unittest(!of_changeset_apply(&chgset), "apply failed\n");
Pantelis Antoniou201c9102014-07-04 19:58:49 +0300853
Frank Rowanda4f91f02018-02-26 14:01:22 -0800854 of_node_put(nchangeset);
855
Grant Likelye5179582014-11-17 22:31:32 +0000856 /* Make sure node names are constructed correctly */
Wang Long9697a552015-03-11 08:36:54 +0000857 unittest((np = of_find_node_by_path("/testcase-data/changeset/n2/n21")),
Rob Herring0d638a02017-06-01 15:50:55 -0500858 "'%pOF' not added\n", n21);
Markus Elfringc46ca3c2014-12-02 13:54:00 +0100859 of_node_put(np);
Grant Likelye5179582014-11-17 22:31:32 +0000860
Wang Long9697a552015-03-11 08:36:54 +0000861 unittest(!of_changeset_revert(&chgset), "revert failed\n");
Pantelis Antoniou201c9102014-07-04 19:58:49 +0300862
863 of_changeset_destroy(&chgset);
864#endif
865}
866
Rob Herring04db93a2019-09-20 13:28:53 -0500867static void __init of_unittest_dma_ranges_one(const char *path,
868 u64 expect_dma_addr, u64 expect_paddr, u64 expect_size)
869{
870 struct device_node *np;
871 u64 dma_addr, paddr, size;
872 int rc;
873
874 np = of_find_node_by_path(path);
875 if (!np) {
876 pr_err("missing testcase data\n");
877 return;
878 }
879
880 rc = of_dma_get_range(np, &dma_addr, &paddr, &size);
881
882 unittest(!rc, "of_dma_get_range failed on node %pOF rc=%i\n", np, rc);
883 if (!rc) {
884 unittest(size == expect_size,
885 "of_dma_get_range wrong size on node %pOF size=%llx\n", np, size);
886 unittest(paddr == expect_paddr,
887 "of_dma_get_range wrong phys addr (%llx) on node %pOF", paddr, np);
888 unittest(dma_addr == expect_dma_addr,
889 "of_dma_get_range wrong DMA addr (%llx) on node %pOF", dma_addr, np);
890 }
891 of_node_put(np);
892}
893
894static void __init of_unittest_parse_dma_ranges(void)
895{
896 of_unittest_dma_ranges_one("/testcase-data/address-tests/device@70000000",
897 0x0, 0x20000000, 0x40000000);
898 of_unittest_dma_ranges_one("/testcase-data/address-tests/bus@80000000/device@1000",
899 0x10000000, 0x20000000, 0x40000000);
900 of_unittest_dma_ranges_one("/testcase-data/address-tests/pci@90000000",
901 0x80000000, 0x20000000, 0x10000000);
902}
903
904static void __init of_unittest_pci_dma_ranges(void)
905{
906 struct device_node *np;
907 struct of_pci_range range;
908 struct of_pci_range_parser parser;
909 int i = 0;
910
911 if (!IS_ENABLED(CONFIG_PCI))
912 return;
913
914 np = of_find_node_by_path("/testcase-data/address-tests/pci@90000000");
915 if (!np) {
916 pr_err("missing testcase data\n");
917 return;
918 }
919
920 if (of_pci_dma_range_parser_init(&parser, np)) {
921 pr_err("missing dma-ranges property\n");
922 return;
923 }
924
925 /*
926 * Get the dma-ranges from the device tree
927 */
928 for_each_of_pci_range(&parser, &range) {
929 if (!i) {
930 unittest(range.size == 0x10000000,
931 "for_each_of_pci_range wrong size on node %pOF size=%llx\n",
932 np, range.size);
933 unittest(range.cpu_addr == 0x20000000,
934 "for_each_of_pci_range wrong CPU addr (%llx) on node %pOF",
935 range.cpu_addr, np);
936 unittest(range.pci_addr == 0x80000000,
937 "for_each_of_pci_range wrong DMA addr (%llx) on node %pOF",
938 range.pci_addr, np);
939 } else {
940 unittest(range.size == 0x10000000,
941 "for_each_of_pci_range wrong size on node %pOF size=%llx\n",
942 np, range.size);
943 unittest(range.cpu_addr == 0x40000000,
944 "for_each_of_pci_range wrong CPU addr (%llx) on node %pOF",
945 range.cpu_addr, np);
946 unittest(range.pci_addr == 0xc0000000,
947 "for_each_of_pci_range wrong DMA addr (%llx) on node %pOF",
948 range.pci_addr, np);
949 }
950 i++;
951 }
952
953 of_node_put(np);
954}
955
Wang Long9697a552015-03-11 08:36:54 +0000956static void __init of_unittest_parse_interrupts(void)
Grant Likelya9f10ca2013-10-11 22:04:23 +0100957{
958 struct device_node *np;
959 struct of_phandle_args args;
960 int i, rc;
961
Guenter Roeckda08d8c2018-09-25 21:06:24 -0700962 if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
963 return;
964
Grant Likelya9f10ca2013-10-11 22:04:23 +0100965 np = of_find_node_by_path("/testcase-data/interrupts/interrupts0");
966 if (!np) {
967 pr_err("missing testcase data\n");
968 return;
969 }
970
971 for (i = 0; i < 4; i++) {
972 bool passed = true;
Frank Rowand3db316d2015-03-14 00:02:31 -0700973
Frank Rowandeeb07c52018-10-04 20:40:21 -0700974 memset(&args, 0, sizeof(args));
Grant Likelya9f10ca2013-10-11 22:04:23 +0100975 rc = of_irq_parse_one(np, i, &args);
976
977 passed &= !rc;
978 passed &= (args.args_count == 1);
979 passed &= (args.args[0] == (i + 1));
980
Rob Herring0d638a02017-06-01 15:50:55 -0500981 unittest(passed, "index %i - data error on node %pOF rc=%i\n",
982 i, args.np, rc);
Grant Likelya9f10ca2013-10-11 22:04:23 +0100983 }
984 of_node_put(np);
985
986 np = of_find_node_by_path("/testcase-data/interrupts/interrupts1");
987 if (!np) {
988 pr_err("missing testcase data\n");
989 return;
990 }
991
992 for (i = 0; i < 4; i++) {
993 bool passed = true;
Frank Rowand3db316d2015-03-14 00:02:31 -0700994
Frank Rowandeeb07c52018-10-04 20:40:21 -0700995 memset(&args, 0, sizeof(args));
Grant Likelya9f10ca2013-10-11 22:04:23 +0100996 rc = of_irq_parse_one(np, i, &args);
997
998 /* Test the values from tests-phandle.dtsi */
999 switch (i) {
1000 case 0:
1001 passed &= !rc;
1002 passed &= (args.args_count == 1);
1003 passed &= (args.args[0] == 9);
1004 break;
1005 case 1:
1006 passed &= !rc;
1007 passed &= (args.args_count == 3);
1008 passed &= (args.args[0] == 10);
1009 passed &= (args.args[1] == 11);
1010 passed &= (args.args[2] == 12);
1011 break;
1012 case 2:
1013 passed &= !rc;
1014 passed &= (args.args_count == 2);
1015 passed &= (args.args[0] == 13);
1016 passed &= (args.args[1] == 14);
1017 break;
1018 case 3:
1019 passed &= !rc;
1020 passed &= (args.args_count == 2);
1021 passed &= (args.args[0] == 15);
1022 passed &= (args.args[1] == 16);
1023 break;
1024 default:
1025 passed = false;
1026 }
Rob Herring0d638a02017-06-01 15:50:55 -05001027 unittest(passed, "index %i - data error on node %pOF rc=%i\n",
1028 i, args.np, rc);
Grant Likelya9f10ca2013-10-11 22:04:23 +01001029 }
1030 of_node_put(np);
1031}
1032
Wang Long9697a552015-03-11 08:36:54 +00001033static void __init of_unittest_parse_interrupts_extended(void)
Grant Likely79d97012013-09-19 16:47:37 -05001034{
1035 struct device_node *np;
1036 struct of_phandle_args args;
1037 int i, rc;
1038
Guenter Roeckda08d8c2018-09-25 21:06:24 -07001039 if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
1040 return;
1041
Grant Likely79d97012013-09-19 16:47:37 -05001042 np = of_find_node_by_path("/testcase-data/interrupts/interrupts-extended0");
1043 if (!np) {
1044 pr_err("missing testcase data\n");
1045 return;
1046 }
1047
1048 for (i = 0; i < 7; i++) {
1049 bool passed = true;
Frank Rowand3db316d2015-03-14 00:02:31 -07001050
Frank Rowandeeb07c52018-10-04 20:40:21 -07001051 memset(&args, 0, sizeof(args));
Grant Likely79d97012013-09-19 16:47:37 -05001052 rc = of_irq_parse_one(np, i, &args);
1053
1054 /* Test the values from tests-phandle.dtsi */
1055 switch (i) {
1056 case 0:
1057 passed &= !rc;
1058 passed &= (args.args_count == 1);
1059 passed &= (args.args[0] == 1);
1060 break;
1061 case 1:
1062 passed &= !rc;
1063 passed &= (args.args_count == 3);
1064 passed &= (args.args[0] == 2);
1065 passed &= (args.args[1] == 3);
1066 passed &= (args.args[2] == 4);
1067 break;
1068 case 2:
1069 passed &= !rc;
1070 passed &= (args.args_count == 2);
1071 passed &= (args.args[0] == 5);
1072 passed &= (args.args[1] == 6);
1073 break;
1074 case 3:
1075 passed &= !rc;
1076 passed &= (args.args_count == 1);
1077 passed &= (args.args[0] == 9);
1078 break;
1079 case 4:
1080 passed &= !rc;
1081 passed &= (args.args_count == 3);
1082 passed &= (args.args[0] == 10);
1083 passed &= (args.args[1] == 11);
1084 passed &= (args.args[2] == 12);
1085 break;
1086 case 5:
1087 passed &= !rc;
1088 passed &= (args.args_count == 2);
1089 passed &= (args.args[0] == 13);
1090 passed &= (args.args[1] == 14);
1091 break;
1092 case 6:
1093 passed &= !rc;
1094 passed &= (args.args_count == 1);
1095 passed &= (args.args[0] == 15);
1096 break;
1097 default:
1098 passed = false;
1099 }
1100
Rob Herring0d638a02017-06-01 15:50:55 -05001101 unittest(passed, "index %i - data error on node %pOF rc=%i\n",
1102 i, args.np, rc);
Grant Likely79d97012013-09-19 16:47:37 -05001103 }
1104 of_node_put(np);
1105}
1106
Frank Rowandafaed7a2015-03-14 00:00:36 -07001107static const struct of_device_id match_node_table[] = {
Grant Likely1f42e5d2014-02-18 21:38:55 +00001108 { .data = "A", .name = "name0", }, /* Name alone is lowest priority */
1109 { .data = "B", .type = "type1", }, /* followed by type alone */
1110
1111 { .data = "Ca", .name = "name2", .type = "type1", }, /* followed by both together */
1112 { .data = "Cb", .name = "name2", }, /* Only match when type doesn't match */
1113 { .data = "Cc", .name = "name2", .type = "type2", },
1114
1115 { .data = "E", .compatible = "compat3" },
1116 { .data = "G", .compatible = "compat2", },
1117 { .data = "H", .compatible = "compat2", .name = "name5", },
1118 { .data = "I", .compatible = "compat2", .type = "type1", },
1119 { .data = "J", .compatible = "compat2", .type = "type1", .name = "name8", },
1120 { .data = "K", .compatible = "compat2", .name = "name9", },
1121 {}
1122};
1123
1124static struct {
1125 const char *path;
1126 const char *data;
1127} match_node_tests[] = {
1128 { .path = "/testcase-data/match-node/name0", .data = "A", },
1129 { .path = "/testcase-data/match-node/name1", .data = "B", },
1130 { .path = "/testcase-data/match-node/a/name2", .data = "Ca", },
1131 { .path = "/testcase-data/match-node/b/name2", .data = "Cb", },
1132 { .path = "/testcase-data/match-node/c/name2", .data = "Cc", },
1133 { .path = "/testcase-data/match-node/name3", .data = "E", },
1134 { .path = "/testcase-data/match-node/name4", .data = "G", },
1135 { .path = "/testcase-data/match-node/name5", .data = "H", },
1136 { .path = "/testcase-data/match-node/name6", .data = "G", },
1137 { .path = "/testcase-data/match-node/name7", .data = "I", },
1138 { .path = "/testcase-data/match-node/name8", .data = "J", },
1139 { .path = "/testcase-data/match-node/name9", .data = "K", },
1140};
1141
Wang Long9697a552015-03-11 08:36:54 +00001142static void __init of_unittest_match_node(void)
Grant Likely1f42e5d2014-02-18 21:38:55 +00001143{
1144 struct device_node *np;
1145 const struct of_device_id *match;
1146 int i;
1147
1148 for (i = 0; i < ARRAY_SIZE(match_node_tests); i++) {
1149 np = of_find_node_by_path(match_node_tests[i].path);
1150 if (!np) {
Wang Long9697a552015-03-11 08:36:54 +00001151 unittest(0, "missing testcase node %s\n",
Grant Likely1f42e5d2014-02-18 21:38:55 +00001152 match_node_tests[i].path);
1153 continue;
1154 }
1155
1156 match = of_match_node(match_node_table, np);
1157 if (!match) {
Wang Long9697a552015-03-11 08:36:54 +00001158 unittest(0, "%s didn't match anything\n",
Grant Likely1f42e5d2014-02-18 21:38:55 +00001159 match_node_tests[i].path);
1160 continue;
1161 }
1162
1163 if (strcmp(match->data, match_node_tests[i].data) != 0) {
Wang Long9697a552015-03-11 08:36:54 +00001164 unittest(0, "%s got wrong match. expected %s, got %s\n",
Grant Likely1f42e5d2014-02-18 21:38:55 +00001165 match_node_tests[i].path, match_node_tests[i].data,
1166 (const char *)match->data);
1167 continue;
1168 }
Wang Long9697a552015-03-11 08:36:54 +00001169 unittest(1, "passed");
Grant Likely1f42e5d2014-02-18 21:38:55 +00001170 }
1171}
1172
Grant Likelyd2329fb2016-01-04 13:13:21 +01001173static struct resource test_bus_res = {
1174 .start = 0xfffffff8,
1175 .end = 0xfffffff9,
1176 .flags = IORESOURCE_MEM,
1177};
Grant Likely37791b62015-03-27 20:30:04 -07001178static const struct platform_device_info test_bus_info = {
1179 .name = "unittest-bus",
Grant Likely851da972014-11-04 13:14:13 +00001180};
Wang Long9697a552015-03-11 08:36:54 +00001181static void __init of_unittest_platform_populate(void)
Rob Herring82c0f582014-04-23 17:57:40 -05001182{
Grant Likely851da972014-11-04 13:14:13 +00001183 int irq, rc;
1184 struct device_node *np, *child, *grandchild;
Grant Likely37791b62015-03-27 20:30:04 -07001185 struct platform_device *pdev, *test_bus;
Frank Rowandafaed7a2015-03-14 00:00:36 -07001186 const struct of_device_id match[] = {
Rob Herringfb2caa52014-05-13 10:07:54 -05001187 { .compatible = "test-device", },
1188 {}
1189 };
Rob Herring82c0f582014-04-23 17:57:40 -05001190
1191 np = of_find_node_by_path("/testcase-data");
Kefeng Wang146dedb2016-06-01 14:53:10 +08001192 of_platform_default_populate(np, NULL, NULL);
Rob Herring82c0f582014-04-23 17:57:40 -05001193
1194 /* Test that a missing irq domain returns -EPROBE_DEFER */
1195 np = of_find_node_by_path("/testcase-data/testcase-device1");
1196 pdev = of_find_device_by_node(np);
Wang Long9697a552015-03-11 08:36:54 +00001197 unittest(pdev, "device 1 creation failed\n");
Rob Herring7d1cdc82014-05-13 10:07:29 -05001198
Guenter Roeckda08d8c2018-09-25 21:06:24 -07001199 if (!(of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)) {
1200 irq = platform_get_irq(pdev, 0);
1201 unittest(irq == -EPROBE_DEFER,
1202 "device deferred probe failed - %d\n", irq);
Rob Herring82c0f582014-04-23 17:57:40 -05001203
Guenter Roeckda08d8c2018-09-25 21:06:24 -07001204 /* Test that a parsing failure does not return -EPROBE_DEFER */
1205 np = of_find_node_by_path("/testcase-data/testcase-device2");
1206 pdev = of_find_device_by_node(np);
1207 unittest(pdev, "device 2 creation failed\n");
Frank Rowand0ac17432020-02-20 12:40:21 -06001208
1209 EXPECT_BEGIN(KERN_INFO,
1210 "platform testcase-data:testcase-device2: IRQ index 0 not found");
1211
Guenter Roeckda08d8c2018-09-25 21:06:24 -07001212 irq = platform_get_irq(pdev, 0);
Frank Rowand0ac17432020-02-20 12:40:21 -06001213
1214 EXPECT_END(KERN_INFO,
1215 "platform testcase-data:testcase-device2: IRQ index 0 not found");
1216
Guenter Roeckda08d8c2018-09-25 21:06:24 -07001217 unittest(irq < 0 && irq != -EPROBE_DEFER,
1218 "device parsing error failed - %d\n", irq);
1219 }
Rob Herring82c0f582014-04-23 17:57:40 -05001220
Frank Rowand716e1d42015-03-13 23:57:40 -07001221 np = of_find_node_by_path("/testcase-data/platform-tests");
Grant Likelya2166ca2015-03-29 08:59:58 +01001222 unittest(np, "No testcase data in device tree\n");
Frank Rowand716e1d42015-03-13 23:57:40 -07001223 if (!np)
Rob Herringfb2caa52014-05-13 10:07:54 -05001224 return;
Grant Likely851da972014-11-04 13:14:13 +00001225
Grant Likely37791b62015-03-27 20:30:04 -07001226 test_bus = platform_device_register_full(&test_bus_info);
1227 rc = PTR_ERR_OR_ZERO(test_bus);
Grant Likelya2166ca2015-03-29 08:59:58 +01001228 unittest(!rc, "testbus registration failed; rc=%i\n", rc);
Nishka Dasguptaa7bcae52019-08-15 11:52:18 +05301229 if (rc) {
1230 of_node_put(np);
Grant Likely851da972014-11-04 13:14:13 +00001231 return;
Nishka Dasguptaa7bcae52019-08-15 11:52:18 +05301232 }
Grant Likely37791b62015-03-27 20:30:04 -07001233 test_bus->dev.of_node = np;
Rob Herringfb2caa52014-05-13 10:07:54 -05001234
Grant Likelyd2329fb2016-01-04 13:13:21 +01001235 /*
1236 * Add a dummy resource to the test bus node after it is
1237 * registered to catch problems with un-inserted resources. The
1238 * DT code doesn't insert the resources, and it has caused the
1239 * kernel to oops in the past. This makes sure the same bug
1240 * doesn't crop up again.
1241 */
1242 platform_device_add_resources(test_bus, &test_bus_res, 1);
1243
Grant Likely37791b62015-03-27 20:30:04 -07001244 of_platform_populate(np, match, NULL, &test_bus->dev);
Rob Herringfb2caa52014-05-13 10:07:54 -05001245 for_each_child_of_node(np, child) {
Rob Herringfb2caa52014-05-13 10:07:54 -05001246 for_each_child_of_node(child, grandchild)
Wang Long9697a552015-03-11 08:36:54 +00001247 unittest(of_find_device_by_node(grandchild),
Rob Herringa613b262018-08-27 20:00:19 -05001248 "Could not create device for node '%pOFn'\n",
1249 grandchild);
Rob Herringfb2caa52014-05-13 10:07:54 -05001250 }
Grant Likely851da972014-11-04 13:14:13 +00001251
Grant Likely37791b62015-03-27 20:30:04 -07001252 of_platform_depopulate(&test_bus->dev);
Grant Likely851da972014-11-04 13:14:13 +00001253 for_each_child_of_node(np, child) {
1254 for_each_child_of_node(child, grandchild)
Wang Long9697a552015-03-11 08:36:54 +00001255 unittest(!of_find_device_by_node(grandchild),
Rob Herringa613b262018-08-27 20:00:19 -05001256 "device didn't get destroyed '%pOFn'\n",
1257 grandchild);
Grant Likely851da972014-11-04 13:14:13 +00001258 }
1259
Grant Likely37791b62015-03-27 20:30:04 -07001260 platform_device_unregister(test_bus);
Grant Likely851da972014-11-04 13:14:13 +00001261 of_node_put(np);
Rob Herring82c0f582014-04-23 17:57:40 -05001262}
1263
Gaurav Minochaae9304c2014-07-16 23:09:39 -07001264/**
1265 * update_node_properties - adds the properties
1266 * of np into dup node (present in live tree) and
1267 * updates parent of children of np to dup.
1268 *
Frank Rowand5babefb2018-10-12 19:38:26 -07001269 * @np: node whose properties are being added to the live tree
Gaurav Minochaae9304c2014-07-16 23:09:39 -07001270 * @dup: node present in live tree to be updated
1271 */
1272static void update_node_properties(struct device_node *np,
1273 struct device_node *dup)
1274{
1275 struct property *prop;
Frank Rowand5babefb2018-10-12 19:38:26 -07001276 struct property *save_next;
Gaurav Minochaae9304c2014-07-16 23:09:39 -07001277 struct device_node *child;
Frank Rowand5babefb2018-10-12 19:38:26 -07001278 int ret;
Gaurav Minochaae9304c2014-07-16 23:09:39 -07001279
1280 for_each_child_of_node(np, child)
1281 child->parent = dup;
Frank Rowand5babefb2018-10-12 19:38:26 -07001282
1283 /*
1284 * "unittest internal error: unable to add testdata property"
1285 *
1286 * If this message reports a property in node '/__symbols__' then
1287 * the respective unittest overlay contains a label that has the
1288 * same name as a label in the live devicetree. The label will
1289 * be in the live devicetree only if the devicetree source was
1290 * compiled with the '-@' option. If you encounter this error,
1291 * please consider renaming __all__ of the labels in the unittest
1292 * overlay dts files with an odd prefix that is unlikely to be
1293 * used in a real devicetree.
1294 */
1295
1296 /*
1297 * open code for_each_property_of_node() because of_add_property()
1298 * sets prop->next to NULL
1299 */
1300 for (prop = np->properties; prop != NULL; prop = save_next) {
1301 save_next = prop->next;
1302 ret = of_add_property(dup, prop);
Frank Rowandfd25ffd2019-01-24 15:22:13 -08001303 if (ret) {
1304 if (ret == -EEXIST && !strcmp(prop->name, "name"))
1305 continue;
Frank Rowand5babefb2018-10-12 19:38:26 -07001306 pr_err("unittest internal error: unable to add testdata property %pOF/%s",
1307 np, prop->name);
Frank Rowandfd25ffd2019-01-24 15:22:13 -08001308 }
Frank Rowand5babefb2018-10-12 19:38:26 -07001309 }
Gaurav Minochaae9304c2014-07-16 23:09:39 -07001310}
1311
1312/**
1313 * attach_node_and_children - attaches nodes
Frank Rowand89716dc2019-01-24 15:22:14 -08001314 * and its children to live tree.
1315 * CAUTION: misleading function name - if node @np already exists in
1316 * the live tree then children of @np are *not* attached to the live
1317 * tree. This works for the current test devicetree nodes because such
1318 * nodes do not have child nodes.
Gaurav Minochaae9304c2014-07-16 23:09:39 -07001319 *
1320 * @np: Node to attach to live tree
1321 */
Frank Rowand5babefb2018-10-12 19:38:26 -07001322static void attach_node_and_children(struct device_node *np)
Gaurav Minochaae9304c2014-07-16 23:09:39 -07001323{
Grant Likely5063e252014-10-03 16:28:27 +01001324 struct device_node *next, *dup, *child;
Gaurav Minocha3ce04b42015-01-10 23:19:51 -08001325 unsigned long flags;
Rob Herring0d638a02017-06-01 15:50:55 -05001326 const char *full_name;
Gaurav Minochaae9304c2014-07-16 23:09:39 -07001327
Rob Herring0d638a02017-06-01 15:50:55 -05001328 full_name = kasprintf(GFP_KERNEL, "%pOF", np);
Frank Rowand5babefb2018-10-12 19:38:26 -07001329
1330 if (!strcmp(full_name, "/__local_fixups__") ||
Erhard Furtner2aacace2019-11-26 02:48:04 +01001331 !strcmp(full_name, "/__fixups__")) {
1332 kfree(full_name);
Frank Rowand5babefb2018-10-12 19:38:26 -07001333 return;
Erhard Furtner2aacace2019-11-26 02:48:04 +01001334 }
Frank Rowand5babefb2018-10-12 19:38:26 -07001335
Rob Herring0d638a02017-06-01 15:50:55 -05001336 dup = of_find_node_by_path(full_name);
1337 kfree(full_name);
Grant Likely5063e252014-10-03 16:28:27 +01001338 if (dup) {
1339 update_node_properties(np, dup);
Frank Rowand5babefb2018-10-12 19:38:26 -07001340 return;
Grant Likely5063e252014-10-03 16:28:27 +01001341 }
Gaurav Minochaae9304c2014-07-16 23:09:39 -07001342
Grant Likely5063e252014-10-03 16:28:27 +01001343 child = np->child;
1344 np->child = NULL;
Gaurav Minocha3ce04b42015-01-10 23:19:51 -08001345
1346 mutex_lock(&of_mutex);
1347 raw_spin_lock_irqsave(&devtree_lock, flags);
1348 np->sibling = np->parent->child;
1349 np->parent->child = np;
1350 of_node_clear_flag(np, OF_DETACHED);
1351 raw_spin_unlock_irqrestore(&devtree_lock, flags);
1352
1353 __of_attach_node_sysfs(np);
1354 mutex_unlock(&of_mutex);
1355
Grant Likely5063e252014-10-03 16:28:27 +01001356 while (child) {
1357 next = child->sibling;
1358 attach_node_and_children(child);
1359 child = next;
Gaurav Minochaae9304c2014-07-16 23:09:39 -07001360 }
Gaurav Minochaae9304c2014-07-16 23:09:39 -07001361}
1362
1363/**
Wang Long9697a552015-03-11 08:36:54 +00001364 * unittest_data_add - Reads, copies data from
Gaurav Minochaae9304c2014-07-16 23:09:39 -07001365 * linked tree and attaches it to the live tree
1366 */
Wang Long9697a552015-03-11 08:36:54 +00001367static int __init unittest_data_add(void)
Gaurav Minochaae9304c2014-07-16 23:09:39 -07001368{
Wang Long9697a552015-03-11 08:36:54 +00001369 void *unittest_data;
1370 struct device_node *unittest_data_node, *np;
Frank Rowandc8547112015-03-14 00:04:24 -07001371 /*
1372 * __dtb_testcases_begin[] and __dtb_testcases_end[] are magically
1373 * created by cmd_dt_S_dtb in scripts/Makefile.lib
1374 */
Gaurav Minochaae9304c2014-07-16 23:09:39 -07001375 extern uint8_t __dtb_testcases_begin[];
1376 extern uint8_t __dtb_testcases_end[];
1377 const int size = __dtb_testcases_end - __dtb_testcases_begin;
Grant Likely2eb46da2014-10-02 14:36:46 +01001378 int rc;
Gaurav Minochaae9304c2014-07-16 23:09:39 -07001379
Gaurav Minochab951f9d2014-07-26 12:48:50 -07001380 if (!size) {
Gaurav Minochaae9304c2014-07-16 23:09:39 -07001381 pr_warn("%s: No testcase data to attach; not running tests\n",
1382 __func__);
1383 return -ENODATA;
1384 }
1385
1386 /* creating copy */
Wang Long9697a552015-03-11 08:36:54 +00001387 unittest_data = kmemdup(__dtb_testcases_begin, size, GFP_KERNEL);
Geert Uytterhoeven2a656cb2019-05-02 14:45:35 +02001388 if (!unittest_data)
Gaurav Minochaae9304c2014-07-16 23:09:39 -07001389 return -ENOMEM;
Geert Uytterhoeven2a656cb2019-05-02 14:45:35 +02001390
Gavin Shanc4263232016-05-03 23:22:50 +10001391 of_fdt_unflatten_tree(unittest_data, NULL, &unittest_data_node);
Wang Long9697a552015-03-11 08:36:54 +00001392 if (!unittest_data_node) {
Gaurav Minochab951f9d2014-07-26 12:48:50 -07001393 pr_warn("%s: No tree to attach; not running tests\n", __func__);
Navid Emamdooste13de8f2019-10-04 13:58:43 -05001394 kfree(unittest_data);
Gaurav Minochab951f9d2014-07-26 12:48:50 -07001395 return -ENODATA;
1396 }
Frank Rowandf948d6d2017-10-17 16:36:29 -07001397
1398 /*
Frank Rowand39a751a2018-02-12 00:19:42 -08001399 * This lock normally encloses of_resolve_phandles()
Frank Rowandf948d6d2017-10-17 16:36:29 -07001400 */
1401 of_overlay_mutex_lock();
1402
Wang Long9697a552015-03-11 08:36:54 +00001403 rc = of_resolve_phandles(unittest_data_node);
Grant Likely2eb46da2014-10-02 14:36:46 +01001404 if (rc) {
1405 pr_err("%s: Failed to resolve phandles (rc=%i)\n", __func__, rc);
Frank Rowandf948d6d2017-10-17 16:36:29 -07001406 of_overlay_mutex_unlock();
Grant Likely2eb46da2014-10-02 14:36:46 +01001407 return -EINVAL;
1408 }
Gaurav Minochab951f9d2014-07-26 12:48:50 -07001409
Grant Likely5063e252014-10-03 16:28:27 +01001410 if (!of_root) {
Wang Long9697a552015-03-11 08:36:54 +00001411 of_root = unittest_data_node;
Gaurav Minochab951f9d2014-07-26 12:48:50 -07001412 for_each_of_allnodes(np)
1413 __of_attach_node_sysfs(np);
1414 of_aliases = of_find_node_by_path("/aliases");
1415 of_chosen = of_find_node_by_path("/chosen");
Frank Rowandf948d6d2017-10-17 16:36:29 -07001416 of_overlay_mutex_unlock();
Gaurav Minochab951f9d2014-07-26 12:48:50 -07001417 return 0;
1418 }
Gaurav Minochaae9304c2014-07-16 23:09:39 -07001419
Frank Rowand0ac17432020-02-20 12:40:21 -06001420 EXPECT_BEGIN(KERN_INFO,
1421 "Duplicate name in testcase-data, renamed to \"duplicate-name#1\"");
1422
Gaurav Minochaae9304c2014-07-16 23:09:39 -07001423 /* attach the sub-tree to live tree */
Wang Long9697a552015-03-11 08:36:54 +00001424 np = unittest_data_node->child;
Grant Likely5063e252014-10-03 16:28:27 +01001425 while (np) {
1426 struct device_node *next = np->sibling;
Frank Rowand3db316d2015-03-14 00:02:31 -07001427
Grant Likely5063e252014-10-03 16:28:27 +01001428 np->parent = of_root;
1429 attach_node_and_children(np);
1430 np = next;
1431 }
Frank Rowandf948d6d2017-10-17 16:36:29 -07001432
Frank Rowand0ac17432020-02-20 12:40:21 -06001433 EXPECT_END(KERN_INFO,
1434 "Duplicate name in testcase-data, renamed to \"duplicate-name#1\"");
1435
Frank Rowandf948d6d2017-10-17 16:36:29 -07001436 of_overlay_mutex_unlock();
1437
Grant Likely5063e252014-10-03 16:28:27 +01001438 return 0;
Gaurav Minochaae9304c2014-07-16 23:09:39 -07001439}
1440
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001441#ifdef CONFIG_OF_OVERLAY
Arnd Bergmann202fbf42018-03-13 14:15:42 +01001442static int __init overlay_data_apply(const char *overlay_name, int *overlay_id);
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001443
Wang Long9697a552015-03-11 08:36:54 +00001444static int unittest_probe(struct platform_device *pdev)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001445{
1446 struct device *dev = &pdev->dev;
1447 struct device_node *np = dev->of_node;
1448
1449 if (np == NULL) {
1450 dev_err(dev, "No OF data for device\n");
1451 return -EINVAL;
1452
1453 }
1454
Rob Herring0d638a02017-06-01 15:50:55 -05001455 dev_dbg(dev, "%s for node @%pOF\n", __func__, np);
Pantelis Antoniou6b1271d2014-12-19 14:34:34 +02001456
1457 of_platform_populate(np, NULL, NULL, &pdev->dev);
1458
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001459 return 0;
1460}
1461
Wang Long9697a552015-03-11 08:36:54 +00001462static int unittest_remove(struct platform_device *pdev)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001463{
1464 struct device *dev = &pdev->dev;
1465 struct device_node *np = dev->of_node;
1466
Rob Herring0d638a02017-06-01 15:50:55 -05001467 dev_dbg(dev, "%s for node @%pOF\n", __func__, np);
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001468 return 0;
1469}
1470
Grant Likelya2166ca2015-03-29 08:59:58 +01001471static const struct of_device_id unittest_match[] = {
Wang Long9697a552015-03-11 08:36:54 +00001472 { .compatible = "unittest", },
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001473 {},
1474};
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001475
Wang Long9697a552015-03-11 08:36:54 +00001476static struct platform_driver unittest_driver = {
1477 .probe = unittest_probe,
1478 .remove = unittest_remove,
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001479 .driver = {
Wang Long9697a552015-03-11 08:36:54 +00001480 .name = "unittest",
Wang Long9697a552015-03-11 08:36:54 +00001481 .of_match_table = of_match_ptr(unittest_match),
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001482 },
1483};
1484
1485/* get the platform device instantiated at the path */
1486static struct platform_device *of_path_to_platform_device(const char *path)
1487{
1488 struct device_node *np;
1489 struct platform_device *pdev;
1490
1491 np = of_find_node_by_path(path);
1492 if (np == NULL)
1493 return NULL;
1494
1495 pdev = of_find_device_by_node(np);
1496 of_node_put(np);
1497
1498 return pdev;
1499}
1500
1501/* find out if a platform device exists at that path */
1502static int of_path_platform_device_exists(const char *path)
1503{
1504 struct platform_device *pdev;
1505
1506 pdev = of_path_to_platform_device(path);
1507 platform_device_put(pdev);
1508 return pdev != NULL;
1509}
1510
Frank Rowand485bb192020-02-27 22:16:29 -06001511#ifdef CONFIG_OF_GPIO
1512
1513struct unittest_gpio_dev {
1514 struct gpio_chip chip;
1515};
1516
1517static int unittest_gpio_chip_request_count;
1518static int unittest_gpio_probe_count;
1519static int unittest_gpio_probe_pass_count;
1520
1521static int unittest_gpio_chip_request(struct gpio_chip *chip, unsigned int offset)
1522{
1523 unittest_gpio_chip_request_count++;
1524
1525 pr_debug("%s(): %s %d %d\n", __func__, chip->label, offset,
1526 unittest_gpio_chip_request_count);
1527 return 0;
1528}
1529
1530static int unittest_gpio_probe(struct platform_device *pdev)
1531{
1532 struct unittest_gpio_dev *devptr;
1533 int ret;
1534
1535 unittest_gpio_probe_count++;
1536
1537 devptr = kzalloc(sizeof(*devptr), GFP_KERNEL);
1538 if (!devptr)
1539 return -ENOMEM;
1540
1541 platform_set_drvdata(pdev, devptr);
1542
1543 devptr->chip.of_node = pdev->dev.of_node;
1544 devptr->chip.label = "of-unittest-gpio";
1545 devptr->chip.base = -1; /* dynamic allocation */
1546 devptr->chip.ngpio = 5;
1547 devptr->chip.request = unittest_gpio_chip_request;
1548
1549 ret = gpiochip_add_data(&devptr->chip, NULL);
1550
1551 unittest(!ret,
1552 "gpiochip_add_data() for node @%pOF failed, ret = %d\n", devptr->chip.of_node, ret);
1553
1554 if (!ret)
1555 unittest_gpio_probe_pass_count++;
1556 return ret;
1557}
1558
1559static int unittest_gpio_remove(struct platform_device *pdev)
1560{
1561 struct unittest_gpio_dev *gdev = platform_get_drvdata(pdev);
1562 struct device *dev = &pdev->dev;
1563 struct device_node *np = pdev->dev.of_node;
1564
1565 dev_dbg(dev, "%s for node @%pOF\n", __func__, np);
1566
1567 if (!gdev)
1568 return -EINVAL;
1569
1570 if (gdev->chip.base != -1)
1571 gpiochip_remove(&gdev->chip);
1572
1573 platform_set_drvdata(pdev, NULL);
1574 kfree(pdev);
1575
1576 return 0;
1577}
1578
1579static const struct of_device_id unittest_gpio_id[] = {
1580 { .compatible = "unittest-gpio", },
1581 {}
1582};
1583
1584static struct platform_driver unittest_gpio_driver = {
1585 .probe = unittest_gpio_probe,
1586 .remove = unittest_gpio_remove,
1587 .driver = {
1588 .name = "unittest-gpio",
1589 .of_match_table = of_match_ptr(unittest_gpio_id),
1590 },
1591};
1592
1593static void __init of_unittest_overlay_gpio(void)
1594{
1595 int chip_request_count;
1596 int probe_pass_count;
1597 int ret;
1598
1599 /*
1600 * tests: apply overlays before registering driver
1601 * Similar to installing a driver as a module, the
1602 * driver is registered after applying the overlays.
1603 *
1604 * - apply overlay_gpio_01
1605 * - apply overlay_gpio_02a
1606 * - apply overlay_gpio_02b
1607 * - register driver
1608 *
1609 * register driver will result in
1610 * - probe and processing gpio hog for overlay_gpio_01
1611 * - probe for overlay_gpio_02a
1612 * - processing gpio for overlay_gpio_02b
1613 */
1614
1615 probe_pass_count = unittest_gpio_probe_pass_count;
1616 chip_request_count = unittest_gpio_chip_request_count;
1617
1618 /*
1619 * overlay_gpio_01 contains gpio node and child gpio hog node
1620 * overlay_gpio_02a contains gpio node
1621 * overlay_gpio_02b contains child gpio hog node
1622 */
1623
1624 unittest(overlay_data_apply("overlay_gpio_01", NULL),
1625 "Adding overlay 'overlay_gpio_01' failed\n");
1626
1627 unittest(overlay_data_apply("overlay_gpio_02a", NULL),
1628 "Adding overlay 'overlay_gpio_02a' failed\n");
1629
1630 unittest(overlay_data_apply("overlay_gpio_02b", NULL),
1631 "Adding overlay 'overlay_gpio_02b' failed\n");
1632
1633 /*
1634 * messages are the result of the probes, after the
1635 * driver is registered
1636 */
1637
1638 EXPECT_BEGIN(KERN_INFO,
1639 "GPIO line <<int>> (line-B-input) hogged as input\n");
1640
1641 EXPECT_BEGIN(KERN_INFO,
1642 "GPIO line <<int>> (line-A-input) hogged as input\n");
1643
1644 ret = platform_driver_register(&unittest_gpio_driver);
1645 if (unittest(ret == 0, "could not register unittest gpio driver\n"))
1646 return;
1647
1648 EXPECT_END(KERN_INFO,
1649 "GPIO line <<int>> (line-A-input) hogged as input\n");
1650 EXPECT_END(KERN_INFO,
1651 "GPIO line <<int>> (line-B-input) hogged as input\n");
1652
1653 unittest(probe_pass_count + 2 == unittest_gpio_probe_pass_count,
1654 "unittest_gpio_probe() failed or not called\n");
1655
1656 unittest(chip_request_count + 2 == unittest_gpio_chip_request_count,
1657 "unittest_gpio_chip_request() called %d times (expected 1 time)\n",
1658 unittest_gpio_chip_request_count - chip_request_count);
1659
1660 /*
1661 * tests: apply overlays after registering driver
1662 *
1663 * Similar to a driver built-in to the kernel, the
1664 * driver is registered before applying the overlays.
1665 *
1666 * overlay_gpio_03 contains gpio node and child gpio hog node
1667 *
1668 * - apply overlay_gpio_03
1669 *
1670 * apply overlay will result in
1671 * - probe and processing gpio hog.
1672 */
1673
1674 probe_pass_count = unittest_gpio_probe_pass_count;
1675 chip_request_count = unittest_gpio_chip_request_count;
1676
1677 EXPECT_BEGIN(KERN_INFO,
1678 "GPIO line <<int>> (line-D-input) hogged as input\n");
1679
1680 /* overlay_gpio_03 contains gpio node and child gpio hog node */
1681
1682 unittest(overlay_data_apply("overlay_gpio_03", NULL),
1683 "Adding overlay 'overlay_gpio_03' failed\n");
1684
1685 EXPECT_END(KERN_INFO,
1686 "GPIO line <<int>> (line-D-input) hogged as input\n");
1687
1688 unittest(probe_pass_count + 1 == unittest_gpio_probe_pass_count,
1689 "unittest_gpio_probe() failed or not called\n");
1690
1691 unittest(chip_request_count + 1 == unittest_gpio_chip_request_count,
1692 "unittest_gpio_chip_request() called %d times (expected 1 time)\n",
1693 unittest_gpio_chip_request_count - chip_request_count);
1694
1695 /*
1696 * overlay_gpio_04a contains gpio node
1697 *
1698 * - apply overlay_gpio_04a
1699 *
1700 * apply the overlay will result in
1701 * - probe for overlay_gpio_04a
1702 */
1703
1704 probe_pass_count = unittest_gpio_probe_pass_count;
1705 chip_request_count = unittest_gpio_chip_request_count;
1706
1707 /* overlay_gpio_04a contains gpio node */
1708
1709 unittest(overlay_data_apply("overlay_gpio_04a", NULL),
1710 "Adding overlay 'overlay_gpio_04a' failed\n");
1711
1712 unittest(probe_pass_count + 1 == unittest_gpio_probe_pass_count,
1713 "unittest_gpio_probe() failed or not called\n");
1714
1715 /*
1716 * overlay_gpio_04b contains child gpio hog node
1717 *
1718 * - apply overlay_gpio_04b
1719 *
1720 * apply the overlay will result in
1721 * - processing gpio for overlay_gpio_04b
1722 */
1723
1724 EXPECT_BEGIN(KERN_INFO,
1725 "GPIO line <<int>> (line-C-input) hogged as input\n");
1726
1727 /* overlay_gpio_04b contains child gpio hog node */
1728
1729 unittest(overlay_data_apply("overlay_gpio_04b", NULL),
1730 "Adding overlay 'overlay_gpio_04b' failed\n");
1731
1732 EXPECT_END(KERN_INFO,
1733 "GPIO line <<int>> (line-C-input) hogged as input\n");
1734
1735 unittest(chip_request_count + 1 == unittest_gpio_chip_request_count,
1736 "unittest_gpio_chip_request() called %d times (expected 1 time)\n",
1737 unittest_gpio_chip_request_count - chip_request_count);
1738}
1739
1740#else
1741
1742static void __init of_unittest_overlay_gpio(void)
1743{
1744 /* skip tests */
1745}
1746
1747#endif
1748
Arnd Bergmann4252de32015-03-04 20:49:47 +01001749#if IS_BUILTIN(CONFIG_I2C)
Pantelis Antonioud5e75502015-01-12 19:02:49 +02001750
1751/* get the i2c client device instantiated at the path */
1752static struct i2c_client *of_path_to_i2c_client(const char *path)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001753{
Pantelis Antonioud5e75502015-01-12 19:02:49 +02001754 struct device_node *np;
1755 struct i2c_client *client;
1756
1757 np = of_find_node_by_path(path);
1758 if (np == NULL)
1759 return NULL;
1760
1761 client = of_find_i2c_device_by_node(np);
1762 of_node_put(np);
1763
1764 return client;
1765}
1766
1767/* find out if a i2c client device exists at that path */
1768static int of_path_i2c_client_exists(const char *path)
1769{
1770 struct i2c_client *client;
1771
1772 client = of_path_to_i2c_client(path);
1773 if (client)
1774 put_device(&client->dev);
1775 return client != NULL;
1776}
1777#else
1778static int of_path_i2c_client_exists(const char *path)
1779{
1780 return 0;
1781}
1782#endif
1783
1784enum overlay_type {
1785 PDEV_OVERLAY,
1786 I2C_OVERLAY
1787};
1788
1789static int of_path_device_type_exists(const char *path,
1790 enum overlay_type ovtype)
1791{
1792 switch (ovtype) {
1793 case PDEV_OVERLAY:
1794 return of_path_platform_device_exists(path);
1795 case I2C_OVERLAY:
1796 return of_path_i2c_client_exists(path);
1797 }
1798 return 0;
1799}
1800
Wang Long9697a552015-03-11 08:36:54 +00001801static const char *unittest_path(int nr, enum overlay_type ovtype)
Pantelis Antonioud5e75502015-01-12 19:02:49 +02001802{
1803 const char *base;
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001804 static char buf[256];
1805
Pantelis Antonioud5e75502015-01-12 19:02:49 +02001806 switch (ovtype) {
1807 case PDEV_OVERLAY:
1808 base = "/testcase-data/overlay-node/test-bus";
1809 break;
1810 case I2C_OVERLAY:
1811 base = "/testcase-data/overlay-node/test-bus/i2c-test-bus";
1812 break;
1813 default:
1814 buf[0] = '\0';
1815 return buf;
1816 }
Wang Long9697a552015-03-11 08:36:54 +00001817 snprintf(buf, sizeof(buf) - 1, "%s/test-unittest%d", base, nr);
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001818 buf[sizeof(buf) - 1] = '\0';
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001819 return buf;
1820}
1821
Wang Long9697a552015-03-11 08:36:54 +00001822static int of_unittest_device_exists(int unittest_nr, enum overlay_type ovtype)
Pantelis Antonioud5e75502015-01-12 19:02:49 +02001823{
1824 const char *path;
1825
Wang Long9697a552015-03-11 08:36:54 +00001826 path = unittest_path(unittest_nr, ovtype);
Pantelis Antonioud5e75502015-01-12 19:02:49 +02001827
1828 switch (ovtype) {
1829 case PDEV_OVERLAY:
1830 return of_path_platform_device_exists(path);
1831 case I2C_OVERLAY:
1832 return of_path_i2c_client_exists(path);
1833 }
1834 return 0;
1835}
1836
Frank Rowand39a751a2018-02-12 00:19:42 -08001837static const char *overlay_name_from_nr(int nr)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001838{
1839 static char buf[256];
1840
1841 snprintf(buf, sizeof(buf) - 1,
Frank Rowand39a751a2018-02-12 00:19:42 -08001842 "overlay_%d", nr);
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001843 buf[sizeof(buf) - 1] = '\0';
1844
1845 return buf;
1846}
1847
1848static const char *bus_path = "/testcase-data/overlay-node/test-bus";
1849
Pantelis Antoniou492a22a2015-04-07 22:23:49 +03001850/* it is guaranteed that overlay ids are assigned in sequence */
1851#define MAX_UNITTEST_OVERLAYS 256
1852static unsigned long overlay_id_bits[BITS_TO_LONGS(MAX_UNITTEST_OVERLAYS)];
1853static int overlay_first_id = -1;
1854
1855static void of_unittest_track_overlay(int id)
1856{
1857 if (overlay_first_id < 0)
1858 overlay_first_id = id;
1859 id -= overlay_first_id;
1860
1861 /* we shouldn't need that many */
1862 BUG_ON(id >= MAX_UNITTEST_OVERLAYS);
1863 overlay_id_bits[BIT_WORD(id)] |= BIT_MASK(id);
1864}
1865
1866static void of_unittest_untrack_overlay(int id)
1867{
1868 if (overlay_first_id < 0)
1869 return;
1870 id -= overlay_first_id;
1871 BUG_ON(id >= MAX_UNITTEST_OVERLAYS);
1872 overlay_id_bits[BIT_WORD(id)] &= ~BIT_MASK(id);
1873}
1874
1875static void of_unittest_destroy_tracked_overlays(void)
1876{
Frank Rowand24789c52017-10-17 16:36:26 -07001877 int id, ret, defers, ovcs_id;
Pantelis Antoniou492a22a2015-04-07 22:23:49 +03001878
1879 if (overlay_first_id < 0)
1880 return;
1881
1882 /* try until no defers */
1883 do {
1884 defers = 0;
1885 /* remove in reverse order */
1886 for (id = MAX_UNITTEST_OVERLAYS - 1; id >= 0; id--) {
1887 if (!(overlay_id_bits[BIT_WORD(id)] & BIT_MASK(id)))
1888 continue;
1889
Frank Rowand24789c52017-10-17 16:36:26 -07001890 ovcs_id = id + overlay_first_id;
1891 ret = of_overlay_remove(&ovcs_id);
Sergey Senozhatsky815d74b2016-03-02 20:24:49 +09001892 if (ret == -ENODEV) {
1893 pr_warn("%s: no overlay to destroy for #%d\n",
1894 __func__, id + overlay_first_id);
1895 continue;
1896 }
Pantelis Antoniou492a22a2015-04-07 22:23:49 +03001897 if (ret != 0) {
1898 defers++;
1899 pr_warn("%s: overlay destroy failed for #%d\n",
1900 __func__, id + overlay_first_id);
1901 continue;
1902 }
1903
1904 overlay_id_bits[BIT_WORD(id)] &= ~BIT_MASK(id);
1905 }
1906 } while (defers > 0);
1907}
1908
Frank Rowand8c329652018-10-04 20:39:24 -07001909static int __init of_unittest_apply_overlay(int overlay_nr, int *overlay_id)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001910{
Frank Rowand39a751a2018-02-12 00:19:42 -08001911 const char *overlay_name;
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001912
Frank Rowand39a751a2018-02-12 00:19:42 -08001913 overlay_name = overlay_name_from_nr(overlay_nr);
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001914
Dan Carpenter82747322018-03-14 23:08:28 +03001915 if (!overlay_data_apply(overlay_name, overlay_id)) {
Frank Rowand39a751a2018-02-12 00:19:42 -08001916 unittest(0, "could not apply overlay \"%s\"\n",
1917 overlay_name);
Dan Carpenter82747322018-03-14 23:08:28 +03001918 return -EFAULT;
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001919 }
Frank Rowand24789c52017-10-17 16:36:26 -07001920 of_unittest_track_overlay(*overlay_id);
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001921
Frank Rowand54587be2018-03-08 14:39:05 -08001922 return 0;
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001923}
1924
1925/* apply an overlay while checking before and after states */
Frank Rowand39a751a2018-02-12 00:19:42 -08001926static int __init of_unittest_apply_overlay_check(int overlay_nr,
1927 int unittest_nr, int before, int after,
1928 enum overlay_type ovtype)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001929{
Frank Rowand24789c52017-10-17 16:36:26 -07001930 int ret, ovcs_id;
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001931
Wang Long9697a552015-03-11 08:36:54 +00001932 /* unittest device must not be in before state */
1933 if (of_unittest_device_exists(unittest_nr, ovtype) != before) {
Frank Rowand39a751a2018-02-12 00:19:42 -08001934 unittest(0, "%s with device @\"%s\" %s\n",
1935 overlay_name_from_nr(overlay_nr),
Wang Long9697a552015-03-11 08:36:54 +00001936 unittest_path(unittest_nr, ovtype),
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001937 !before ? "enabled" : "disabled");
1938 return -EINVAL;
1939 }
1940
Frank Rowand24789c52017-10-17 16:36:26 -07001941 ovcs_id = 0;
Frank Rowand8c329652018-10-04 20:39:24 -07001942 ret = of_unittest_apply_overlay(overlay_nr, &ovcs_id);
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001943 if (ret != 0) {
Wang Long9697a552015-03-11 08:36:54 +00001944 /* of_unittest_apply_overlay already called unittest() */
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001945 return ret;
1946 }
1947
Wang Long9697a552015-03-11 08:36:54 +00001948 /* unittest device must be to set to after state */
1949 if (of_unittest_device_exists(unittest_nr, ovtype) != after) {
Frank Rowand39a751a2018-02-12 00:19:42 -08001950 unittest(0, "%s failed to create @\"%s\" %s\n",
1951 overlay_name_from_nr(overlay_nr),
Wang Long9697a552015-03-11 08:36:54 +00001952 unittest_path(unittest_nr, ovtype),
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001953 !after ? "enabled" : "disabled");
1954 return -EINVAL;
1955 }
1956
1957 return 0;
1958}
1959
1960/* apply an overlay and then revert it while checking before, after states */
Frank Rowand39a751a2018-02-12 00:19:42 -08001961static int __init of_unittest_apply_revert_overlay_check(int overlay_nr,
Wang Long9697a552015-03-11 08:36:54 +00001962 int unittest_nr, int before, int after,
Pantelis Antonioud5e75502015-01-12 19:02:49 +02001963 enum overlay_type ovtype)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001964{
Frank Rowand24789c52017-10-17 16:36:26 -07001965 int ret, ovcs_id;
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001966
Wang Long9697a552015-03-11 08:36:54 +00001967 /* unittest device must be in before state */
1968 if (of_unittest_device_exists(unittest_nr, ovtype) != before) {
Frank Rowand39a751a2018-02-12 00:19:42 -08001969 unittest(0, "%s with device @\"%s\" %s\n",
1970 overlay_name_from_nr(overlay_nr),
Wang Long9697a552015-03-11 08:36:54 +00001971 unittest_path(unittest_nr, ovtype),
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001972 !before ? "enabled" : "disabled");
1973 return -EINVAL;
1974 }
1975
1976 /* apply the overlay */
Frank Rowand24789c52017-10-17 16:36:26 -07001977 ovcs_id = 0;
Frank Rowand8c329652018-10-04 20:39:24 -07001978 ret = of_unittest_apply_overlay(overlay_nr, &ovcs_id);
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001979 if (ret != 0) {
Wang Long9697a552015-03-11 08:36:54 +00001980 /* of_unittest_apply_overlay already called unittest() */
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001981 return ret;
1982 }
1983
Wang Long9697a552015-03-11 08:36:54 +00001984 /* unittest device must be in after state */
1985 if (of_unittest_device_exists(unittest_nr, ovtype) != after) {
Frank Rowand39a751a2018-02-12 00:19:42 -08001986 unittest(0, "%s failed to create @\"%s\" %s\n",
1987 overlay_name_from_nr(overlay_nr),
Wang Long9697a552015-03-11 08:36:54 +00001988 unittest_path(unittest_nr, ovtype),
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001989 !after ? "enabled" : "disabled");
1990 return -EINVAL;
1991 }
1992
Frank Rowand24789c52017-10-17 16:36:26 -07001993 ret = of_overlay_remove(&ovcs_id);
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001994 if (ret != 0) {
Frank Rowand39a751a2018-02-12 00:19:42 -08001995 unittest(0, "%s failed to be destroyed @\"%s\"\n",
1996 overlay_name_from_nr(overlay_nr),
Wang Long9697a552015-03-11 08:36:54 +00001997 unittest_path(unittest_nr, ovtype));
Pantelis Antoniou177d2712014-10-28 22:35:59 +02001998 return ret;
1999 }
2000
Wang Long9697a552015-03-11 08:36:54 +00002001 /* unittest device must be again in before state */
2002 if (of_unittest_device_exists(unittest_nr, PDEV_OVERLAY) != before) {
Frank Rowand39a751a2018-02-12 00:19:42 -08002003 unittest(0, "%s with device @\"%s\" %s\n",
2004 overlay_name_from_nr(overlay_nr),
Wang Long9697a552015-03-11 08:36:54 +00002005 unittest_path(unittest_nr, ovtype),
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002006 !before ? "enabled" : "disabled");
2007 return -EINVAL;
2008 }
2009
2010 return 0;
2011}
2012
2013/* test activation of device */
Frank Rowand39a751a2018-02-12 00:19:42 -08002014static void __init of_unittest_overlay_0(void)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002015{
Frank Rowand0ac17432020-02-20 12:40:21 -06002016 int ret;
2017
2018 EXPECT_BEGIN(KERN_INFO,
2019 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest0/status");
2020
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002021 /* device should enable */
Frank Rowand0ac17432020-02-20 12:40:21 -06002022 ret = of_unittest_apply_overlay_check(0, 0, 0, 1, PDEV_OVERLAY);
2023
2024 EXPECT_END(KERN_INFO,
2025 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest0/status");
2026
2027 if (ret)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002028 return;
2029
Wang Long9697a552015-03-11 08:36:54 +00002030 unittest(1, "overlay test %d passed\n", 0);
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002031}
2032
2033/* test deactivation of device */
Frank Rowand39a751a2018-02-12 00:19:42 -08002034static void __init of_unittest_overlay_1(void)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002035{
Frank Rowand0ac17432020-02-20 12:40:21 -06002036 int ret;
2037
2038 EXPECT_BEGIN(KERN_INFO,
2039 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest1/status");
2040
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002041 /* device should disable */
Frank Rowand0ac17432020-02-20 12:40:21 -06002042 ret = of_unittest_apply_overlay_check(1, 1, 1, 0, PDEV_OVERLAY);
2043
2044 EXPECT_END(KERN_INFO,
2045 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest1/status");
2046
2047 if (ret)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002048 return;
2049
Wang Long9697a552015-03-11 08:36:54 +00002050 unittest(1, "overlay test %d passed\n", 1);
Frank Rowand0ac17432020-02-20 12:40:21 -06002051
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002052}
2053
2054/* test activation of device */
Frank Rowand39a751a2018-02-12 00:19:42 -08002055static void __init of_unittest_overlay_2(void)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002056{
Frank Rowand0ac17432020-02-20 12:40:21 -06002057 int ret;
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002058
Frank Rowand0ac17432020-02-20 12:40:21 -06002059 EXPECT_BEGIN(KERN_INFO,
2060 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest2/status");
2061
2062 /* device should enable */
2063 ret = of_unittest_apply_overlay_check(2, 2, 0, 1, PDEV_OVERLAY);
2064
2065 EXPECT_END(KERN_INFO,
2066 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest2/status");
2067
2068 if (ret)
2069 return;
Wang Long9697a552015-03-11 08:36:54 +00002070 unittest(1, "overlay test %d passed\n", 2);
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002071}
2072
2073/* test deactivation of device */
Frank Rowand39a751a2018-02-12 00:19:42 -08002074static void __init of_unittest_overlay_3(void)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002075{
Frank Rowand0ac17432020-02-20 12:40:21 -06002076 int ret;
2077
2078 EXPECT_BEGIN(KERN_INFO,
2079 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest3/status");
2080
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002081 /* device should disable */
Frank Rowand0ac17432020-02-20 12:40:21 -06002082 ret = of_unittest_apply_overlay_check(3, 3, 1, 0, PDEV_OVERLAY);
2083
2084 EXPECT_END(KERN_INFO,
2085 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest3/status");
2086
2087 if (ret)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002088 return;
2089
Wang Long9697a552015-03-11 08:36:54 +00002090 unittest(1, "overlay test %d passed\n", 3);
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002091}
2092
2093/* test activation of a full device node */
Frank Rowand39a751a2018-02-12 00:19:42 -08002094static void __init of_unittest_overlay_4(void)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002095{
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002096 /* device should disable */
Frank Rowand06c46972018-03-08 14:39:04 -08002097 if (of_unittest_apply_overlay_check(4, 4, 0, 1, PDEV_OVERLAY))
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002098 return;
2099
Wang Long9697a552015-03-11 08:36:54 +00002100 unittest(1, "overlay test %d passed\n", 4);
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002101}
2102
2103/* test overlay apply/revert sequence */
Frank Rowand39a751a2018-02-12 00:19:42 -08002104static void __init of_unittest_overlay_5(void)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002105{
Frank Rowand0ac17432020-02-20 12:40:21 -06002106 int ret;
2107
2108 EXPECT_BEGIN(KERN_INFO,
2109 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest5/status");
2110
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002111 /* device should disable */
Frank Rowand0ac17432020-02-20 12:40:21 -06002112 ret = of_unittest_apply_revert_overlay_check(5, 5, 0, 1, PDEV_OVERLAY);
2113
2114 EXPECT_END(KERN_INFO,
2115 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest5/status");
2116
2117 if (ret)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002118 return;
2119
Wang Long9697a552015-03-11 08:36:54 +00002120 unittest(1, "overlay test %d passed\n", 5);
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002121}
2122
2123/* test overlay application in sequence */
Frank Rowand39a751a2018-02-12 00:19:42 -08002124static void __init of_unittest_overlay_6(void)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002125{
Frank Rowand06c46972018-03-08 14:39:04 -08002126 int i, ov_id[2], ovcs_id;
Wang Long9697a552015-03-11 08:36:54 +00002127 int overlay_nr = 6, unittest_nr = 6;
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002128 int before = 0, after = 1;
Frank Rowand39a751a2018-02-12 00:19:42 -08002129 const char *overlay_name;
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002130
Frank Rowand0ac17432020-02-20 12:40:21 -06002131 int ret;
2132
Wang Long9697a552015-03-11 08:36:54 +00002133 /* unittest device must be in before state */
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002134 for (i = 0; i < 2; i++) {
Wang Long9697a552015-03-11 08:36:54 +00002135 if (of_unittest_device_exists(unittest_nr + i, PDEV_OVERLAY)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002136 != before) {
Frank Rowand39a751a2018-02-12 00:19:42 -08002137 unittest(0, "%s with device @\"%s\" %s\n",
2138 overlay_name_from_nr(overlay_nr + i),
Wang Long9697a552015-03-11 08:36:54 +00002139 unittest_path(unittest_nr + i,
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002140 PDEV_OVERLAY),
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002141 !before ? "enabled" : "disabled");
2142 return;
2143 }
2144 }
2145
2146 /* apply the overlays */
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002147
Frank Rowand0ac17432020-02-20 12:40:21 -06002148 EXPECT_BEGIN(KERN_INFO,
2149 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest6/status");
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002150
Frank Rowand0ac17432020-02-20 12:40:21 -06002151 overlay_name = overlay_name_from_nr(overlay_nr + 0);
2152
2153 ret = overlay_data_apply(overlay_name, &ovcs_id);
2154
2155 if (!ret) {
2156 unittest(0, "could not apply overlay \"%s\"\n", overlay_name);
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002157 return;
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002158 }
Frank Rowand0ac17432020-02-20 12:40:21 -06002159 ov_id[0] = ovcs_id;
2160 of_unittest_track_overlay(ov_id[0]);
2161
2162 EXPECT_END(KERN_INFO,
2163 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest6/status");
2164
2165 EXPECT_BEGIN(KERN_INFO,
2166 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest7/status");
2167
2168 overlay_name = overlay_name_from_nr(overlay_nr + 1);
2169
2170 ret = overlay_data_apply(overlay_name, &ovcs_id);
2171
2172 if (!ret) {
2173 unittest(0, "could not apply overlay \"%s\"\n", overlay_name);
2174 return;
2175 }
2176 ov_id[1] = ovcs_id;
2177 of_unittest_track_overlay(ov_id[1]);
2178
2179 EXPECT_END(KERN_INFO,
2180 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest7/status");
2181
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002182
2183 for (i = 0; i < 2; i++) {
Wang Long9697a552015-03-11 08:36:54 +00002184 /* unittest device must be in after state */
2185 if (of_unittest_device_exists(unittest_nr + i, PDEV_OVERLAY)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002186 != after) {
Wang Long9697a552015-03-11 08:36:54 +00002187 unittest(0, "overlay @\"%s\" failed @\"%s\" %s\n",
Frank Rowand39a751a2018-02-12 00:19:42 -08002188 overlay_name_from_nr(overlay_nr + i),
Wang Long9697a552015-03-11 08:36:54 +00002189 unittest_path(unittest_nr + i,
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002190 PDEV_OVERLAY),
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002191 !after ? "enabled" : "disabled");
2192 return;
2193 }
2194 }
2195
2196 for (i = 1; i >= 0; i--) {
Frank Rowand24789c52017-10-17 16:36:26 -07002197 ovcs_id = ov_id[i];
Frank Rowand06c46972018-03-08 14:39:04 -08002198 if (of_overlay_remove(&ovcs_id)) {
Frank Rowand39a751a2018-02-12 00:19:42 -08002199 unittest(0, "%s failed destroy @\"%s\"\n",
2200 overlay_name_from_nr(overlay_nr + i),
Wang Long9697a552015-03-11 08:36:54 +00002201 unittest_path(unittest_nr + i,
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002202 PDEV_OVERLAY));
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002203 return;
2204 }
Pantelis Antoniou492a22a2015-04-07 22:23:49 +03002205 of_unittest_untrack_overlay(ov_id[i]);
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002206 }
2207
2208 for (i = 0; i < 2; i++) {
Wang Long9697a552015-03-11 08:36:54 +00002209 /* unittest device must be again in before state */
2210 if (of_unittest_device_exists(unittest_nr + i, PDEV_OVERLAY)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002211 != before) {
Frank Rowand39a751a2018-02-12 00:19:42 -08002212 unittest(0, "%s with device @\"%s\" %s\n",
2213 overlay_name_from_nr(overlay_nr + i),
Wang Long9697a552015-03-11 08:36:54 +00002214 unittest_path(unittest_nr + i,
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002215 PDEV_OVERLAY),
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002216 !before ? "enabled" : "disabled");
2217 return;
2218 }
2219 }
2220
Wang Long9697a552015-03-11 08:36:54 +00002221 unittest(1, "overlay test %d passed\n", 6);
Frank Rowand0ac17432020-02-20 12:40:21 -06002222
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002223}
2224
2225/* test overlay application in sequence */
Frank Rowand39a751a2018-02-12 00:19:42 -08002226static void __init of_unittest_overlay_8(void)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002227{
Frank Rowand06c46972018-03-08 14:39:04 -08002228 int i, ov_id[2], ovcs_id;
Wang Long9697a552015-03-11 08:36:54 +00002229 int overlay_nr = 8, unittest_nr = 8;
Frank Rowand39a751a2018-02-12 00:19:42 -08002230 const char *overlay_name;
Frank Rowand0ac17432020-02-20 12:40:21 -06002231 int ret;
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002232
2233 /* we don't care about device state in this test */
2234
Frank Rowand0ac17432020-02-20 12:40:21 -06002235 EXPECT_BEGIN(KERN_INFO,
2236 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest8/status");
2237
2238 overlay_name = overlay_name_from_nr(overlay_nr + 0);
2239
2240 ret = overlay_data_apply(overlay_name, &ovcs_id);
2241 if (!ret)
2242 unittest(0, "could not apply overlay \"%s\"\n", overlay_name);
2243
2244 EXPECT_END(KERN_INFO,
2245 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest8/status");
2246
2247 if (!ret)
2248 return;
2249
2250 ov_id[0] = ovcs_id;
2251 of_unittest_track_overlay(ov_id[0]);
2252
2253 overlay_name = overlay_name_from_nr(overlay_nr + 1);
2254
2255 EXPECT_BEGIN(KERN_INFO,
2256 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest8/property-foo");
2257
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002258 /* apply the overlays */
Frank Rowand0ac17432020-02-20 12:40:21 -06002259 ret = overlay_data_apply(overlay_name, &ovcs_id);
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002260
Frank Rowand0ac17432020-02-20 12:40:21 -06002261 EXPECT_END(KERN_INFO,
2262 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest8/property-foo");
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002263
Frank Rowand0ac17432020-02-20 12:40:21 -06002264 if (!ret) {
2265 unittest(0, "could not apply overlay \"%s\"\n", overlay_name);
2266 return;
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002267 }
2268
Frank Rowand0ac17432020-02-20 12:40:21 -06002269 ov_id[1] = ovcs_id;
2270 of_unittest_track_overlay(ov_id[1]);
2271
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002272 /* now try to remove first overlay (it should fail) */
Frank Rowand24789c52017-10-17 16:36:26 -07002273 ovcs_id = ov_id[0];
Frank Rowand0ac17432020-02-20 12:40:21 -06002274
2275 EXPECT_BEGIN(KERN_INFO,
2276 "OF: overlay: node_overlaps_later_cs: #6 overlaps with #7 @/testcase-data/overlay-node/test-bus/test-unittest8");
2277
2278 EXPECT_BEGIN(KERN_INFO,
2279 "OF: overlay: overlay #6 is not topmost");
2280
2281 ret = of_overlay_remove(&ovcs_id);
2282
2283 EXPECT_END(KERN_INFO,
2284 "OF: overlay: overlay #6 is not topmost");
2285
2286 EXPECT_END(KERN_INFO,
2287 "OF: overlay: node_overlaps_later_cs: #6 overlaps with #7 @/testcase-data/overlay-node/test-bus/test-unittest8");
2288
2289 if (!ret) {
Frank Rowand39a751a2018-02-12 00:19:42 -08002290 unittest(0, "%s was destroyed @\"%s\"\n",
2291 overlay_name_from_nr(overlay_nr + 0),
Wang Long9697a552015-03-11 08:36:54 +00002292 unittest_path(unittest_nr,
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002293 PDEV_OVERLAY));
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002294 return;
2295 }
2296
2297 /* removing them in order should work */
2298 for (i = 1; i >= 0; i--) {
Frank Rowand24789c52017-10-17 16:36:26 -07002299 ovcs_id = ov_id[i];
Frank Rowand06c46972018-03-08 14:39:04 -08002300 if (of_overlay_remove(&ovcs_id)) {
Frank Rowand39a751a2018-02-12 00:19:42 -08002301 unittest(0, "%s not destroyed @\"%s\"\n",
2302 overlay_name_from_nr(overlay_nr + i),
Wang Long9697a552015-03-11 08:36:54 +00002303 unittest_path(unittest_nr,
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002304 PDEV_OVERLAY));
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002305 return;
2306 }
Pantelis Antoniou492a22a2015-04-07 22:23:49 +03002307 of_unittest_untrack_overlay(ov_id[i]);
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002308 }
2309
Wang Long9697a552015-03-11 08:36:54 +00002310 unittest(1, "overlay test %d passed\n", 8);
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002311}
2312
Pantelis Antoniou6b1271d2014-12-19 14:34:34 +02002313/* test insertion of a bus with parent devices */
Frank Rowand39a751a2018-02-12 00:19:42 -08002314static void __init of_unittest_overlay_10(void)
Pantelis Antoniou6b1271d2014-12-19 14:34:34 +02002315{
2316 int ret;
2317 char *child_path;
2318
2319 /* device should disable */
Wang Long9697a552015-03-11 08:36:54 +00002320 ret = of_unittest_apply_overlay_check(10, 10, 0, 1, PDEV_OVERLAY);
Frank Rowand0ac17432020-02-20 12:40:21 -06002321
Wang Long9697a552015-03-11 08:36:54 +00002322 if (unittest(ret == 0,
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002323 "overlay test %d failed; overlay application\n", 10))
Pantelis Antoniou6b1271d2014-12-19 14:34:34 +02002324 return;
2325
Wang Long9697a552015-03-11 08:36:54 +00002326 child_path = kasprintf(GFP_KERNEL, "%s/test-unittest101",
2327 unittest_path(10, PDEV_OVERLAY));
2328 if (unittest(child_path, "overlay test %d failed; kasprintf\n", 10))
Pantelis Antoniou6b1271d2014-12-19 14:34:34 +02002329 return;
2330
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002331 ret = of_path_device_type_exists(child_path, PDEV_OVERLAY);
Pantelis Antoniou6b1271d2014-12-19 14:34:34 +02002332 kfree(child_path);
Frank Rowand54587be2018-03-08 14:39:05 -08002333
2334 unittest(ret, "overlay test %d failed; no child device\n", 10);
Pantelis Antoniou6b1271d2014-12-19 14:34:34 +02002335}
2336
2337/* test insertion of a bus with parent devices (and revert) */
Frank Rowand39a751a2018-02-12 00:19:42 -08002338static void __init of_unittest_overlay_11(void)
Pantelis Antoniou6b1271d2014-12-19 14:34:34 +02002339{
2340 int ret;
2341
2342 /* device should disable */
Wang Long9697a552015-03-11 08:36:54 +00002343 ret = of_unittest_apply_revert_overlay_check(11, 11, 0, 1,
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002344 PDEV_OVERLAY);
Frank Rowand0ac17432020-02-20 12:40:21 -06002345
Frank Rowand54587be2018-03-08 14:39:05 -08002346 unittest(ret == 0, "overlay test %d failed; overlay apply\n", 11);
Pantelis Antoniou6b1271d2014-12-19 14:34:34 +02002347}
2348
Arnd Bergmann4252de32015-03-04 20:49:47 +01002349#if IS_BUILTIN(CONFIG_I2C) && IS_ENABLED(CONFIG_OF_OVERLAY)
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002350
Wang Long9697a552015-03-11 08:36:54 +00002351struct unittest_i2c_bus_data {
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002352 struct platform_device *pdev;
2353 struct i2c_adapter adap;
2354};
2355
Wang Long9697a552015-03-11 08:36:54 +00002356static int unittest_i2c_master_xfer(struct i2c_adapter *adap,
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002357 struct i2c_msg *msgs, int num)
2358{
Wang Long9697a552015-03-11 08:36:54 +00002359 struct unittest_i2c_bus_data *std = i2c_get_adapdata(adap);
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002360
2361 (void)std;
2362
2363 return num;
2364}
2365
Wang Long9697a552015-03-11 08:36:54 +00002366static u32 unittest_i2c_functionality(struct i2c_adapter *adap)
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002367{
2368 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
2369}
2370
Wang Long9697a552015-03-11 08:36:54 +00002371static const struct i2c_algorithm unittest_i2c_algo = {
2372 .master_xfer = unittest_i2c_master_xfer,
2373 .functionality = unittest_i2c_functionality,
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002374};
2375
Wang Long9697a552015-03-11 08:36:54 +00002376static int unittest_i2c_bus_probe(struct platform_device *pdev)
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002377{
2378 struct device *dev = &pdev->dev;
2379 struct device_node *np = dev->of_node;
Wang Long9697a552015-03-11 08:36:54 +00002380 struct unittest_i2c_bus_data *std;
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002381 struct i2c_adapter *adap;
2382 int ret;
2383
2384 if (np == NULL) {
2385 dev_err(dev, "No OF data for device\n");
2386 return -EINVAL;
2387
2388 }
2389
Rob Herring0d638a02017-06-01 15:50:55 -05002390 dev_dbg(dev, "%s for node @%pOF\n", __func__, np);
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002391
2392 std = devm_kzalloc(dev, sizeof(*std), GFP_KERNEL);
Geert Uytterhoeven2a656cb2019-05-02 14:45:35 +02002393 if (!std)
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002394 return -ENOMEM;
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002395
2396 /* link them together */
2397 std->pdev = pdev;
2398 platform_set_drvdata(pdev, std);
2399
2400 adap = &std->adap;
2401 i2c_set_adapdata(adap, std);
2402 adap->nr = -1;
2403 strlcpy(adap->name, pdev->name, sizeof(adap->name));
2404 adap->class = I2C_CLASS_DEPRECATED;
Wang Long9697a552015-03-11 08:36:54 +00002405 adap->algo = &unittest_i2c_algo;
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002406 adap->dev.parent = dev;
2407 adap->dev.of_node = dev->of_node;
2408 adap->timeout = 5 * HZ;
2409 adap->retries = 3;
2410
2411 ret = i2c_add_numbered_adapter(adap);
2412 if (ret != 0) {
2413 dev_err(dev, "Failed to add I2C adapter\n");
2414 return ret;
2415 }
2416
2417 return 0;
2418}
2419
Wang Long9697a552015-03-11 08:36:54 +00002420static int unittest_i2c_bus_remove(struct platform_device *pdev)
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002421{
2422 struct device *dev = &pdev->dev;
2423 struct device_node *np = dev->of_node;
Wang Long9697a552015-03-11 08:36:54 +00002424 struct unittest_i2c_bus_data *std = platform_get_drvdata(pdev);
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002425
Rob Herring0d638a02017-06-01 15:50:55 -05002426 dev_dbg(dev, "%s for node @%pOF\n", __func__, np);
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002427 i2c_del_adapter(&std->adap);
2428
2429 return 0;
2430}
2431
Grant Likelya2166ca2015-03-29 08:59:58 +01002432static const struct of_device_id unittest_i2c_bus_match[] = {
Wang Long9697a552015-03-11 08:36:54 +00002433 { .compatible = "unittest-i2c-bus", },
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002434 {},
2435};
2436
Wang Long9697a552015-03-11 08:36:54 +00002437static struct platform_driver unittest_i2c_bus_driver = {
2438 .probe = unittest_i2c_bus_probe,
2439 .remove = unittest_i2c_bus_remove,
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002440 .driver = {
Wang Long9697a552015-03-11 08:36:54 +00002441 .name = "unittest-i2c-bus",
2442 .of_match_table = of_match_ptr(unittest_i2c_bus_match),
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002443 },
2444};
2445
Wang Long9697a552015-03-11 08:36:54 +00002446static int unittest_i2c_dev_probe(struct i2c_client *client,
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002447 const struct i2c_device_id *id)
2448{
2449 struct device *dev = &client->dev;
2450 struct device_node *np = client->dev.of_node;
2451
2452 if (!np) {
2453 dev_err(dev, "No OF node\n");
2454 return -EINVAL;
2455 }
2456
Rob Herring0d638a02017-06-01 15:50:55 -05002457 dev_dbg(dev, "%s for node @%pOF\n", __func__, np);
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002458
2459 return 0;
2460};
2461
Wang Long9697a552015-03-11 08:36:54 +00002462static int unittest_i2c_dev_remove(struct i2c_client *client)
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002463{
2464 struct device *dev = &client->dev;
2465 struct device_node *np = client->dev.of_node;
2466
Rob Herring0d638a02017-06-01 15:50:55 -05002467 dev_dbg(dev, "%s for node @%pOF\n", __func__, np);
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002468 return 0;
2469}
2470
Wang Long9697a552015-03-11 08:36:54 +00002471static const struct i2c_device_id unittest_i2c_dev_id[] = {
2472 { .name = "unittest-i2c-dev" },
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002473 { }
2474};
2475
Wang Long9697a552015-03-11 08:36:54 +00002476static struct i2c_driver unittest_i2c_dev_driver = {
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002477 .driver = {
Wang Long9697a552015-03-11 08:36:54 +00002478 .name = "unittest-i2c-dev",
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002479 },
Wang Long9697a552015-03-11 08:36:54 +00002480 .probe = unittest_i2c_dev_probe,
2481 .remove = unittest_i2c_dev_remove,
2482 .id_table = unittest_i2c_dev_id,
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002483};
2484
Arnd Bergmann4252de32015-03-04 20:49:47 +01002485#if IS_BUILTIN(CONFIG_I2C_MUX)
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002486
Peter Rosinb6e3b712016-04-20 08:42:47 +02002487static int unittest_i2c_mux_select_chan(struct i2c_mux_core *muxc, u32 chan)
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002488{
2489 return 0;
2490}
2491
Wang Long9697a552015-03-11 08:36:54 +00002492static int unittest_i2c_mux_probe(struct i2c_client *client,
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002493 const struct i2c_device_id *id)
2494{
Frank Rowand06c46972018-03-08 14:39:04 -08002495 int i, nchans;
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002496 struct device *dev = &client->dev;
Wolfram Sang272d28b2019-06-10 11:51:56 +02002497 struct i2c_adapter *adap = client->adapter;
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002498 struct device_node *np = client->dev.of_node, *child;
Peter Rosinb6e3b712016-04-20 08:42:47 +02002499 struct i2c_mux_core *muxc;
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002500 u32 reg, max_reg;
2501
Rob Herring0d638a02017-06-01 15:50:55 -05002502 dev_dbg(dev, "%s for node @%pOF\n", __func__, np);
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002503
2504 if (!np) {
2505 dev_err(dev, "No OF node\n");
2506 return -EINVAL;
2507 }
2508
2509 max_reg = (u32)-1;
2510 for_each_child_of_node(np, child) {
Frank Rowand06c46972018-03-08 14:39:04 -08002511 if (of_property_read_u32(child, "reg", &reg))
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002512 continue;
2513 if (max_reg == (u32)-1 || reg > max_reg)
2514 max_reg = reg;
2515 }
2516 nchans = max_reg == (u32)-1 ? 0 : max_reg + 1;
2517 if (nchans == 0) {
2518 dev_err(dev, "No channels\n");
2519 return -EINVAL;
2520 }
2521
Peter Rosinb6e3b712016-04-20 08:42:47 +02002522 muxc = i2c_mux_alloc(adap, dev, nchans, 0, 0,
2523 unittest_i2c_mux_select_chan, NULL);
2524 if (!muxc)
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002525 return -ENOMEM;
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002526 for (i = 0; i < nchans; i++) {
Frank Rowand06c46972018-03-08 14:39:04 -08002527 if (i2c_mux_add_adapter(muxc, 0, i, 0)) {
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002528 dev_err(dev, "Failed to register mux #%d\n", i);
Peter Rosinb6e3b712016-04-20 08:42:47 +02002529 i2c_mux_del_adapters(muxc);
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002530 return -ENODEV;
2531 }
2532 }
2533
Peter Rosinb6e3b712016-04-20 08:42:47 +02002534 i2c_set_clientdata(client, muxc);
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002535
2536 return 0;
2537};
2538
Wang Long9697a552015-03-11 08:36:54 +00002539static int unittest_i2c_mux_remove(struct i2c_client *client)
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002540{
2541 struct device *dev = &client->dev;
2542 struct device_node *np = client->dev.of_node;
Peter Rosinb6e3b712016-04-20 08:42:47 +02002543 struct i2c_mux_core *muxc = i2c_get_clientdata(client);
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002544
Rob Herring0d638a02017-06-01 15:50:55 -05002545 dev_dbg(dev, "%s for node @%pOF\n", __func__, np);
Peter Rosinb6e3b712016-04-20 08:42:47 +02002546 i2c_mux_del_adapters(muxc);
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002547 return 0;
2548}
2549
Wang Long9697a552015-03-11 08:36:54 +00002550static const struct i2c_device_id unittest_i2c_mux_id[] = {
2551 { .name = "unittest-i2c-mux" },
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002552 { }
2553};
2554
Wang Long9697a552015-03-11 08:36:54 +00002555static struct i2c_driver unittest_i2c_mux_driver = {
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002556 .driver = {
Wang Long9697a552015-03-11 08:36:54 +00002557 .name = "unittest-i2c-mux",
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002558 },
Wang Long9697a552015-03-11 08:36:54 +00002559 .probe = unittest_i2c_mux_probe,
2560 .remove = unittest_i2c_mux_remove,
2561 .id_table = unittest_i2c_mux_id,
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002562};
2563
2564#endif
2565
Wang Long9697a552015-03-11 08:36:54 +00002566static int of_unittest_overlay_i2c_init(void)
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002567{
2568 int ret;
2569
Wang Long9697a552015-03-11 08:36:54 +00002570 ret = i2c_add_driver(&unittest_i2c_dev_driver);
2571 if (unittest(ret == 0,
2572 "could not register unittest i2c device driver\n"))
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002573 return ret;
2574
Wang Long9697a552015-03-11 08:36:54 +00002575 ret = platform_driver_register(&unittest_i2c_bus_driver);
Frank Rowand0ac17432020-02-20 12:40:21 -06002576
Wang Long9697a552015-03-11 08:36:54 +00002577 if (unittest(ret == 0,
2578 "could not register unittest i2c bus driver\n"))
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002579 return ret;
2580
Arnd Bergmann4252de32015-03-04 20:49:47 +01002581#if IS_BUILTIN(CONFIG_I2C_MUX)
Frank Rowand0ac17432020-02-20 12:40:21 -06002582
2583 EXPECT_BEGIN(KERN_INFO,
2584 "i2c i2c-1: Added multiplexed i2c bus 2");
2585
Wang Long9697a552015-03-11 08:36:54 +00002586 ret = i2c_add_driver(&unittest_i2c_mux_driver);
Frank Rowand0ac17432020-02-20 12:40:21 -06002587
2588 EXPECT_END(KERN_INFO,
2589 "i2c i2c-1: Added multiplexed i2c bus 2");
2590
Wang Long9697a552015-03-11 08:36:54 +00002591 if (unittest(ret == 0,
2592 "could not register unittest i2c mux driver\n"))
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002593 return ret;
2594#endif
2595
2596 return 0;
2597}
2598
Wang Long9697a552015-03-11 08:36:54 +00002599static void of_unittest_overlay_i2c_cleanup(void)
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002600{
Arnd Bergmann4252de32015-03-04 20:49:47 +01002601#if IS_BUILTIN(CONFIG_I2C_MUX)
Wang Long9697a552015-03-11 08:36:54 +00002602 i2c_del_driver(&unittest_i2c_mux_driver);
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002603#endif
Wang Long9697a552015-03-11 08:36:54 +00002604 platform_driver_unregister(&unittest_i2c_bus_driver);
2605 i2c_del_driver(&unittest_i2c_dev_driver);
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002606}
2607
Frank Rowand39a751a2018-02-12 00:19:42 -08002608static void __init of_unittest_overlay_i2c_12(void)
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002609{
Frank Rowand0ac17432020-02-20 12:40:21 -06002610 int ret;
2611
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002612 /* device should enable */
Frank Rowand0ac17432020-02-20 12:40:21 -06002613 EXPECT_BEGIN(KERN_INFO,
2614 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/i2c-test-bus/test-unittest12/status");
2615
2616 ret = of_unittest_apply_overlay_check(12, 12, 0, 1, I2C_OVERLAY);
2617
2618 EXPECT_END(KERN_INFO,
2619 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/i2c-test-bus/test-unittest12/status");
2620
2621 if (ret)
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002622 return;
2623
Wang Long9697a552015-03-11 08:36:54 +00002624 unittest(1, "overlay test %d passed\n", 12);
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002625}
2626
2627/* test deactivation of device */
Frank Rowand39a751a2018-02-12 00:19:42 -08002628static void __init of_unittest_overlay_i2c_13(void)
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002629{
Frank Rowand0ac17432020-02-20 12:40:21 -06002630 int ret;
2631
2632 EXPECT_BEGIN(KERN_INFO,
2633 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/i2c-test-bus/test-unittest13/status");
2634
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002635 /* device should disable */
Frank Rowand0ac17432020-02-20 12:40:21 -06002636 ret = of_unittest_apply_overlay_check(13, 13, 1, 0, I2C_OVERLAY);
2637
2638 EXPECT_END(KERN_INFO,
2639 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/i2c-test-bus/test-unittest13/status");
2640
2641 if (ret)
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002642 return;
2643
Wang Long9697a552015-03-11 08:36:54 +00002644 unittest(1, "overlay test %d passed\n", 13);
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002645}
2646
2647/* just check for i2c mux existence */
Wang Long9697a552015-03-11 08:36:54 +00002648static void of_unittest_overlay_i2c_14(void)
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002649{
2650}
2651
Frank Rowand39a751a2018-02-12 00:19:42 -08002652static void __init of_unittest_overlay_i2c_15(void)
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002653{
Frank Rowand0ac17432020-02-20 12:40:21 -06002654 int ret;
2655
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002656 /* device should enable */
Frank Rowand0ac17432020-02-20 12:40:21 -06002657 EXPECT_BEGIN(KERN_INFO,
2658 "i2c i2c-1: Added multiplexed i2c bus 3");
2659
2660 ret = of_unittest_apply_overlay_check(15, 15, 0, 1, I2C_OVERLAY);
2661
2662 EXPECT_END(KERN_INFO,
2663 "i2c i2c-1: Added multiplexed i2c bus 3");
2664
2665 if (ret)
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002666 return;
2667
Wang Long9697a552015-03-11 08:36:54 +00002668 unittest(1, "overlay test %d passed\n", 15);
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002669}
2670
2671#else
2672
Wang Long9697a552015-03-11 08:36:54 +00002673static inline void of_unittest_overlay_i2c_14(void) { }
2674static inline void of_unittest_overlay_i2c_15(void) { }
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002675
2676#endif
2677
Wang Long9697a552015-03-11 08:36:54 +00002678static void __init of_unittest_overlay(void)
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002679{
2680 struct device_node *bus_np = NULL;
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002681
Frank Rowand06c46972018-03-08 14:39:04 -08002682 if (platform_driver_register(&unittest_driver)) {
Wang Long9697a552015-03-11 08:36:54 +00002683 unittest(0, "could not register unittest driver\n");
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002684 goto out;
2685 }
2686
2687 bus_np = of_find_node_by_path(bus_path);
2688 if (bus_np == NULL) {
Wang Long9697a552015-03-11 08:36:54 +00002689 unittest(0, "could not find bus_path \"%s\"\n", bus_path);
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002690 goto out;
2691 }
2692
Frank Rowand06c46972018-03-08 14:39:04 -08002693 if (of_platform_default_populate(bus_np, NULL, NULL)) {
Wang Long9697a552015-03-11 08:36:54 +00002694 unittest(0, "could not populate bus @ \"%s\"\n", bus_path);
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002695 goto out;
2696 }
2697
Wang Long9697a552015-03-11 08:36:54 +00002698 if (!of_unittest_device_exists(100, PDEV_OVERLAY)) {
2699 unittest(0, "could not find unittest0 @ \"%s\"\n",
2700 unittest_path(100, PDEV_OVERLAY));
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002701 goto out;
2702 }
2703
Wang Long9697a552015-03-11 08:36:54 +00002704 if (of_unittest_device_exists(101, PDEV_OVERLAY)) {
2705 unittest(0, "unittest1 @ \"%s\" should not exist\n",
2706 unittest_path(101, PDEV_OVERLAY));
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002707 goto out;
2708 }
2709
Wang Long9697a552015-03-11 08:36:54 +00002710 unittest(1, "basic infrastructure of overlays passed");
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002711
2712 /* tests in sequence */
Wang Long9697a552015-03-11 08:36:54 +00002713 of_unittest_overlay_0();
2714 of_unittest_overlay_1();
2715 of_unittest_overlay_2();
2716 of_unittest_overlay_3();
2717 of_unittest_overlay_4();
2718 of_unittest_overlay_5();
2719 of_unittest_overlay_6();
2720 of_unittest_overlay_8();
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002721
Wang Long9697a552015-03-11 08:36:54 +00002722 of_unittest_overlay_10();
2723 of_unittest_overlay_11();
Pantelis Antoniou6b1271d2014-12-19 14:34:34 +02002724
Arnd Bergmann4252de32015-03-04 20:49:47 +01002725#if IS_BUILTIN(CONFIG_I2C)
Wang Long9697a552015-03-11 08:36:54 +00002726 if (unittest(of_unittest_overlay_i2c_init() == 0, "i2c init failed\n"))
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002727 goto out;
2728
Wang Long9697a552015-03-11 08:36:54 +00002729 of_unittest_overlay_i2c_12();
2730 of_unittest_overlay_i2c_13();
2731 of_unittest_overlay_i2c_14();
2732 of_unittest_overlay_i2c_15();
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002733
Wang Long9697a552015-03-11 08:36:54 +00002734 of_unittest_overlay_i2c_cleanup();
Pantelis Antonioud5e75502015-01-12 19:02:49 +02002735#endif
2736
Frank Rowandf4056e72020-02-20 12:40:20 -06002737 of_unittest_overlay_gpio();
2738
Pantelis Antoniou492a22a2015-04-07 22:23:49 +03002739 of_unittest_destroy_tracked_overlays();
2740
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002741out:
2742 of_node_put(bus_np);
2743}
2744
2745#else
Wang Long9697a552015-03-11 08:36:54 +00002746static inline void __init of_unittest_overlay(void) { }
Pantelis Antoniou177d2712014-10-28 22:35:59 +02002747#endif
2748
Frank Rowand60a00042017-07-19 09:25:20 -07002749#ifdef CONFIG_OF_OVERLAY
2750
Frank Rowand81d0848f2017-04-25 17:09:54 -07002751/*
2752 * __dtb_ot_begin[] and __dtb_ot_end[] are created by cmd_dt_S_dtb
2753 * in scripts/Makefile.lib
2754 */
2755
2756#define OVERLAY_INFO_EXTERN(name) \
2757 extern uint8_t __dtb_##name##_begin[]; \
2758 extern uint8_t __dtb_##name##_end[]
2759
Frank Rowand39a751a2018-02-12 00:19:42 -08002760#define OVERLAY_INFO(overlay_name, expected) \
2761{ .dtb_begin = __dtb_##overlay_name##_begin, \
2762 .dtb_end = __dtb_##overlay_name##_end, \
2763 .expected_result = expected, \
2764 .name = #overlay_name, \
Frank Rowand81d0848f2017-04-25 17:09:54 -07002765}
2766
2767struct overlay_info {
Frank Rowand39a751a2018-02-12 00:19:42 -08002768 uint8_t *dtb_begin;
2769 uint8_t *dtb_end;
2770 int expected_result;
2771 int overlay_id;
2772 char *name;
Frank Rowand81d0848f2017-04-25 17:09:54 -07002773};
2774
2775OVERLAY_INFO_EXTERN(overlay_base);
2776OVERLAY_INFO_EXTERN(overlay);
Frank Rowand39a751a2018-02-12 00:19:42 -08002777OVERLAY_INFO_EXTERN(overlay_0);
2778OVERLAY_INFO_EXTERN(overlay_1);
2779OVERLAY_INFO_EXTERN(overlay_2);
2780OVERLAY_INFO_EXTERN(overlay_3);
2781OVERLAY_INFO_EXTERN(overlay_4);
2782OVERLAY_INFO_EXTERN(overlay_5);
2783OVERLAY_INFO_EXTERN(overlay_6);
2784OVERLAY_INFO_EXTERN(overlay_7);
2785OVERLAY_INFO_EXTERN(overlay_8);
2786OVERLAY_INFO_EXTERN(overlay_9);
2787OVERLAY_INFO_EXTERN(overlay_10);
2788OVERLAY_INFO_EXTERN(overlay_11);
2789OVERLAY_INFO_EXTERN(overlay_12);
2790OVERLAY_INFO_EXTERN(overlay_13);
2791OVERLAY_INFO_EXTERN(overlay_15);
Frank Rowandf4056e72020-02-20 12:40:20 -06002792OVERLAY_INFO_EXTERN(overlay_gpio_01);
2793OVERLAY_INFO_EXTERN(overlay_gpio_02a);
2794OVERLAY_INFO_EXTERN(overlay_gpio_02b);
2795OVERLAY_INFO_EXTERN(overlay_gpio_03);
2796OVERLAY_INFO_EXTERN(overlay_gpio_04a);
2797OVERLAY_INFO_EXTERN(overlay_gpio_04b);
Frank Rowanda68238a2018-10-04 20:34:33 -07002798OVERLAY_INFO_EXTERN(overlay_bad_add_dup_node);
Frank Rowand2fe0e872018-10-04 20:36:18 -07002799OVERLAY_INFO_EXTERN(overlay_bad_add_dup_prop);
Frank Rowand81d0848f2017-04-25 17:09:54 -07002800OVERLAY_INFO_EXTERN(overlay_bad_phandle);
Frank Rowand60a00042017-07-19 09:25:20 -07002801OVERLAY_INFO_EXTERN(overlay_bad_symbol);
Frank Rowand81d0848f2017-04-25 17:09:54 -07002802
Frank Rowand160b1d42018-10-04 20:41:03 -07002803/* entries found by name */
Frank Rowand81d0848f2017-04-25 17:09:54 -07002804static struct overlay_info overlays[] = {
2805 OVERLAY_INFO(overlay_base, -9999),
2806 OVERLAY_INFO(overlay, 0),
Frank Rowand39a751a2018-02-12 00:19:42 -08002807 OVERLAY_INFO(overlay_0, 0),
2808 OVERLAY_INFO(overlay_1, 0),
2809 OVERLAY_INFO(overlay_2, 0),
2810 OVERLAY_INFO(overlay_3, 0),
2811 OVERLAY_INFO(overlay_4, 0),
2812 OVERLAY_INFO(overlay_5, 0),
2813 OVERLAY_INFO(overlay_6, 0),
2814 OVERLAY_INFO(overlay_7, 0),
2815 OVERLAY_INFO(overlay_8, 0),
2816 OVERLAY_INFO(overlay_9, 0),
2817 OVERLAY_INFO(overlay_10, 0),
2818 OVERLAY_INFO(overlay_11, 0),
2819 OVERLAY_INFO(overlay_12, 0),
2820 OVERLAY_INFO(overlay_13, 0),
2821 OVERLAY_INFO(overlay_15, 0),
Frank Rowandf4056e72020-02-20 12:40:20 -06002822 OVERLAY_INFO(overlay_gpio_01, 0),
2823 OVERLAY_INFO(overlay_gpio_02a, 0),
2824 OVERLAY_INFO(overlay_gpio_02b, 0),
2825 OVERLAY_INFO(overlay_gpio_03, 0),
2826 OVERLAY_INFO(overlay_gpio_04a, 0),
2827 OVERLAY_INFO(overlay_gpio_04b, 0),
Frank Rowanda68238a2018-10-04 20:34:33 -07002828 OVERLAY_INFO(overlay_bad_add_dup_node, -EINVAL),
Frank Rowand2fe0e872018-10-04 20:36:18 -07002829 OVERLAY_INFO(overlay_bad_add_dup_prop, -EINVAL),
Frank Rowand81d0848f2017-04-25 17:09:54 -07002830 OVERLAY_INFO(overlay_bad_phandle, -EINVAL),
Frank Rowand60a00042017-07-19 09:25:20 -07002831 OVERLAY_INFO(overlay_bad_symbol, -EINVAL),
Frank Rowand160b1d42018-10-04 20:41:03 -07002832 /* end marker */
2833 {.dtb_begin = NULL, .dtb_end = NULL, .expected_result = 0, .name = NULL}
Frank Rowand81d0848f2017-04-25 17:09:54 -07002834};
2835
2836static struct device_node *overlay_base_root;
2837
Rob Herring0fa1c572018-01-05 15:32:33 -06002838static void * __init dt_alloc_memory(u64 size, u64 align)
2839{
Mike Rapoport8a7f97b2019-03-11 23:30:31 -07002840 void *ptr = memblock_alloc(size, align);
2841
2842 if (!ptr)
2843 panic("%s: Failed to allocate %llu bytes align=0x%llx\n",
2844 __func__, size, align);
2845
2846 return ptr;
Rob Herring0fa1c572018-01-05 15:32:33 -06002847}
2848
Frank Rowand81d0848f2017-04-25 17:09:54 -07002849/*
2850 * Create base device tree for the overlay unittest.
2851 *
2852 * This is called from very early boot code.
2853 *
2854 * Do as much as possible the same way as done in __unflatten_device_tree
2855 * and other early boot steps for the normal FDT so that the overlay base
2856 * unflattened tree will have the same characteristics as the real tree
2857 * (such as having memory allocated by the early allocator). The goal
2858 * is to test "the real thing" as much as possible, and test "test setup
2859 * code" as little as possible.
2860 *
2861 * Have to stop before resolving phandles, because that uses kmalloc.
2862 */
2863void __init unittest_unflatten_overlay_base(void)
2864{
2865 struct overlay_info *info;
2866 u32 data_size;
Frank Rowand39a751a2018-02-12 00:19:42 -08002867 void *new_fdt;
Frank Rowand81d0848f2017-04-25 17:09:54 -07002868 u32 size;
Frank Rowand160b1d42018-10-04 20:41:03 -07002869 int found = 0;
2870 const char *overlay_name = "overlay_base";
2871
2872 for (info = overlays; info && info->name; info++) {
2873 if (!strcmp(overlay_name, info->name)) {
2874 found = 1;
2875 break;
2876 }
2877 }
2878 if (!found) {
2879 pr_err("no overlay data for %s\n", overlay_name);
2880 return;
2881 }
Frank Rowand81d0848f2017-04-25 17:09:54 -07002882
2883 info = &overlays[0];
2884
2885 if (info->expected_result != -9999) {
2886 pr_err("No dtb 'overlay_base' to attach\n");
2887 return;
2888 }
2889
2890 data_size = info->dtb_end - info->dtb_begin;
2891 if (!data_size) {
2892 pr_err("No dtb 'overlay_base' to attach\n");
2893 return;
2894 }
2895
2896 size = fdt_totalsize(info->dtb_begin);
2897 if (size != data_size) {
2898 pr_err("dtb 'overlay_base' header totalsize != actual size");
2899 return;
2900 }
2901
Frank Rowand39a751a2018-02-12 00:19:42 -08002902 new_fdt = dt_alloc_memory(size, roundup_pow_of_two(FDT_V17_SIZE));
2903 if (!new_fdt) {
Frank Rowand81d0848f2017-04-25 17:09:54 -07002904 pr_err("alloc for dtb 'overlay_base' failed");
2905 return;
2906 }
2907
Frank Rowand39a751a2018-02-12 00:19:42 -08002908 memcpy(new_fdt, info->dtb_begin, size);
Frank Rowand81d0848f2017-04-25 17:09:54 -07002909
Frank Rowand39a751a2018-02-12 00:19:42 -08002910 __unflatten_device_tree(new_fdt, NULL, &overlay_base_root,
Rob Herring0fa1c572018-01-05 15:32:33 -06002911 dt_alloc_memory, true);
Frank Rowand81d0848f2017-04-25 17:09:54 -07002912}
2913
2914/*
2915 * The purpose of of_unittest_overlay_data_add is to add an
2916 * overlay in the normal fashion. This is a test of the whole
2917 * picture, instead of testing individual elements.
2918 *
2919 * A secondary purpose is to be able to verify that the contents of
2920 * /proc/device-tree/ contains the updated structure and values from
2921 * the overlay. That must be verified separately in user space.
2922 *
2923 * Return 0 on unexpected error.
2924 */
Frank Rowand39a751a2018-02-12 00:19:42 -08002925static int __init overlay_data_apply(const char *overlay_name, int *overlay_id)
Frank Rowand81d0848f2017-04-25 17:09:54 -07002926{
2927 struct overlay_info *info;
Frank Rowand39a751a2018-02-12 00:19:42 -08002928 int found = 0;
Frank Rowand81d0848f2017-04-25 17:09:54 -07002929 int ret;
2930 u32 size;
Frank Rowand81d0848f2017-04-25 17:09:54 -07002931
Frank Rowand160b1d42018-10-04 20:41:03 -07002932 for (info = overlays; info && info->name; info++) {
Frank Rowand39a751a2018-02-12 00:19:42 -08002933 if (!strcmp(overlay_name, info->name)) {
2934 found = 1;
Frank Rowand81d0848f2017-04-25 17:09:54 -07002935 break;
Frank Rowand39a751a2018-02-12 00:19:42 -08002936 }
Frank Rowand81d0848f2017-04-25 17:09:54 -07002937 }
Frank Rowand39a751a2018-02-12 00:19:42 -08002938 if (!found) {
2939 pr_err("no overlay data for %s\n", overlay_name);
Frank Rowand81d0848f2017-04-25 17:09:54 -07002940 return 0;
Frank Rowand39a751a2018-02-12 00:19:42 -08002941 }
Frank Rowand81d0848f2017-04-25 17:09:54 -07002942
2943 size = info->dtb_end - info->dtb_begin;
Frank Rowand54587be2018-03-08 14:39:05 -08002944 if (!size)
Frank Rowand39a751a2018-02-12 00:19:42 -08002945 pr_err("no overlay data for %s\n", overlay_name);
Frank Rowand81d0848f2017-04-25 17:09:54 -07002946
Frank Rowand39a751a2018-02-12 00:19:42 -08002947 ret = of_overlay_fdt_apply(info->dtb_begin, size, &info->overlay_id);
2948 if (overlay_id)
2949 *overlay_id = info->overlay_id;
2950 if (ret < 0)
2951 goto out;
Frank Rowand81d0848f2017-04-25 17:09:54 -07002952
Frank Rowand39a751a2018-02-12 00:19:42 -08002953 pr_debug("%s applied\n", overlay_name);
Frank Rowand81d0848f2017-04-25 17:09:54 -07002954
2955out:
Frank Rowand39a751a2018-02-12 00:19:42 -08002956 if (ret != info->expected_result)
2957 pr_err("of_overlay_fdt_apply() expected %d, ret=%d, %s\n",
2958 info->expected_result, ret, overlay_name);
2959
Frank Rowand81d0848f2017-04-25 17:09:54 -07002960 return (ret == info->expected_result);
2961}
2962
2963/*
2964 * The purpose of of_unittest_overlay_high_level is to add an overlay
2965 * in the normal fashion. This is a test of the whole picture,
2966 * instead of individual elements.
2967 *
2968 * The first part of the function is _not_ normal overlay usage; it is
2969 * finishing splicing the base overlay device tree into the live tree.
2970 */
2971static __init void of_unittest_overlay_high_level(void)
2972{
2973 struct device_node *last_sibling;
2974 struct device_node *np;
2975 struct device_node *of_symbols;
2976 struct device_node *overlay_base_symbols;
2977 struct device_node **pprev;
2978 struct property *prop;
Frank Rowand0ac17432020-02-20 12:40:21 -06002979 int ret;
Frank Rowand81d0848f2017-04-25 17:09:54 -07002980
2981 if (!overlay_base_root) {
2982 unittest(0, "overlay_base_root not initialized\n");
2983 return;
2984 }
2985
2986 /*
2987 * Could not fixup phandles in unittest_unflatten_overlay_base()
2988 * because kmalloc() was not yet available.
2989 */
Frank Rowandf948d6d2017-10-17 16:36:29 -07002990 of_overlay_mutex_lock();
Frank Rowand81d0848f2017-04-25 17:09:54 -07002991 of_resolve_phandles(overlay_base_root);
Frank Rowandf948d6d2017-10-17 16:36:29 -07002992 of_overlay_mutex_unlock();
2993
Frank Rowand81d0848f2017-04-25 17:09:54 -07002994
2995 /*
2996 * do not allow overlay_base to duplicate any node already in
2997 * tree, this greatly simplifies the code
2998 */
2999
3000 /*
3001 * remove overlay_base_root node "__local_fixups", after
3002 * being used by of_resolve_phandles()
3003 */
3004 pprev = &overlay_base_root->child;
3005 for (np = overlay_base_root->child; np; np = np->sibling) {
Rob Herringb3e46d12018-08-27 08:37:06 -05003006 if (of_node_name_eq(np, "__local_fixups__")) {
Frank Rowand81d0848f2017-04-25 17:09:54 -07003007 *pprev = np->sibling;
3008 break;
3009 }
3010 pprev = &np->sibling;
3011 }
3012
3013 /* remove overlay_base_root node "__symbols__" if in live tree */
3014 of_symbols = of_get_child_by_name(of_root, "__symbols__");
3015 if (of_symbols) {
3016 /* will have to graft properties from node into live tree */
3017 pprev = &overlay_base_root->child;
3018 for (np = overlay_base_root->child; np; np = np->sibling) {
Rob Herringb3e46d12018-08-27 08:37:06 -05003019 if (of_node_name_eq(np, "__symbols__")) {
Frank Rowand81d0848f2017-04-25 17:09:54 -07003020 overlay_base_symbols = np;
3021 *pprev = np->sibling;
3022 break;
3023 }
3024 pprev = &np->sibling;
3025 }
3026 }
3027
Rob Herringb610e2f2018-08-27 08:38:08 -05003028 for_each_child_of_node(overlay_base_root, np) {
3029 struct device_node *base_child;
3030 for_each_child_of_node(of_root, base_child) {
3031 if (!strcmp(np->full_name, base_child->full_name)) {
3032 unittest(0, "illegal node name in overlay_base %pOFn",
3033 np);
3034 return;
3035 }
Frank Rowand81d0848f2017-04-25 17:09:54 -07003036 }
3037 }
3038
3039 /*
3040 * overlay 'overlay_base' is not allowed to have root
3041 * properties, so only need to splice nodes into main device tree.
3042 *
3043 * root node of *overlay_base_root will not be freed, it is lost
3044 * memory.
3045 */
3046
3047 for (np = overlay_base_root->child; np; np = np->sibling)
3048 np->parent = of_root;
3049
3050 mutex_lock(&of_mutex);
3051
Arnd Bergmannee320b32017-04-28 11:44:11 +02003052 for (last_sibling = np = of_root->child; np; np = np->sibling)
Frank Rowand81d0848f2017-04-25 17:09:54 -07003053 last_sibling = np;
3054
3055 if (last_sibling)
3056 last_sibling->sibling = overlay_base_root->child;
3057 else
3058 of_root->child = overlay_base_root->child;
3059
3060 for_each_of_allnodes_from(overlay_base_root, np)
3061 __of_attach_node_sysfs(np);
3062
3063 if (of_symbols) {
Frank Rowand39a751a2018-02-12 00:19:42 -08003064 struct property *new_prop;
Frank Rowand81d0848f2017-04-25 17:09:54 -07003065 for_each_property_of_node(overlay_base_symbols, prop) {
Frank Rowand39a751a2018-02-12 00:19:42 -08003066
3067 new_prop = __of_prop_dup(prop, GFP_KERNEL);
3068 if (!new_prop) {
3069 unittest(0, "__of_prop_dup() of '%s' from overlay_base node __symbols__",
Frank Rowand81d0848f2017-04-25 17:09:54 -07003070 prop->name);
Dan Carpenter8756cd12017-05-03 22:49:50 +03003071 goto err_unlock;
Frank Rowand81d0848f2017-04-25 17:09:54 -07003072 }
Frank Rowand06c46972018-03-08 14:39:04 -08003073 if (__of_add_property(of_symbols, new_prop)) {
3074 /* "name" auto-generated by unflatten */
3075 if (!strcmp(new_prop->name, "name"))
Frank Rowand39a751a2018-02-12 00:19:42 -08003076 continue;
Frank Rowand39a751a2018-02-12 00:19:42 -08003077 unittest(0, "duplicate property '%s' in overlay_base node __symbols__",
3078 prop->name);
3079 goto err_unlock;
3080 }
Frank Rowand06c46972018-03-08 14:39:04 -08003081 if (__of_add_property_sysfs(of_symbols, new_prop)) {
Frank Rowand39a751a2018-02-12 00:19:42 -08003082 unittest(0, "unable to add property '%s' in overlay_base node __symbols__ to sysfs",
Frank Rowand81d0848f2017-04-25 17:09:54 -07003083 prop->name);
Dan Carpenter8756cd12017-05-03 22:49:50 +03003084 goto err_unlock;
Frank Rowand81d0848f2017-04-25 17:09:54 -07003085 }
3086 }
3087 }
3088
3089 mutex_unlock(&of_mutex);
3090
3091
3092 /* now do the normal overlay usage test */
3093
Frank Rowand0ac17432020-02-20 12:40:21 -06003094 EXPECT_BEGIN(KERN_ERR,
3095 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/substation@100/status");
3096 EXPECT_BEGIN(KERN_ERR,
3097 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/fairway-1/status");
3098 EXPECT_BEGIN(KERN_ERR,
3099 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/fairway-1/ride@100/track@30/incline-up");
3100 EXPECT_BEGIN(KERN_ERR,
3101 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/fairway-1/ride@100/track@40/incline-up");
3102 EXPECT_BEGIN(KERN_ERR,
3103 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/lights@40000/status");
3104 EXPECT_BEGIN(KERN_ERR,
3105 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/lights@40000/color");
3106 EXPECT_BEGIN(KERN_ERR,
3107 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/lights@40000/rate");
3108 EXPECT_BEGIN(KERN_ERR,
3109 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/hvac_2");
3110 EXPECT_BEGIN(KERN_ERR,
3111 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/ride_200");
3112 EXPECT_BEGIN(KERN_ERR,
3113 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/ride_200_left");
3114 EXPECT_BEGIN(KERN_ERR,
3115 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/ride_200_right");
3116
3117 ret = overlay_data_apply("overlay", NULL);
3118
3119 EXPECT_END(KERN_ERR,
3120 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/ride_200_right");
3121 EXPECT_END(KERN_ERR,
3122 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/ride_200_left");
3123 EXPECT_END(KERN_ERR,
3124 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/ride_200");
3125 EXPECT_END(KERN_ERR,
3126 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/hvac_2");
3127 EXPECT_END(KERN_ERR,
3128 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/lights@40000/rate");
3129 EXPECT_END(KERN_ERR,
3130 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/lights@40000/color");
3131 EXPECT_END(KERN_ERR,
3132 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/lights@40000/status");
3133 EXPECT_END(KERN_ERR,
3134 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/fairway-1/ride@100/track@40/incline-up");
3135 EXPECT_END(KERN_ERR,
3136 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/fairway-1/ride@100/track@30/incline-up");
3137 EXPECT_END(KERN_ERR,
3138 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/fairway-1/status");
3139 EXPECT_END(KERN_ERR,
3140 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/substation@100/status");
3141
3142 unittest(ret, "Adding overlay 'overlay' failed\n");
3143
3144 EXPECT_BEGIN(KERN_ERR,
3145 "OF: overlay: ERROR: multiple fragments add and/or delete node /testcase-data-2/substation@100/motor-1/controller");
3146 EXPECT_BEGIN(KERN_ERR,
3147 "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/controller/name");
Frank Rowand81d0848f2017-04-25 17:09:54 -07003148
Frank Rowanda68238a2018-10-04 20:34:33 -07003149 unittest(overlay_data_apply("overlay_bad_add_dup_node", NULL),
3150 "Adding overlay 'overlay_bad_add_dup_node' failed\n");
3151
Frank Rowand0ac17432020-02-20 12:40:21 -06003152 EXPECT_END(KERN_ERR,
3153 "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/controller/name");
3154 EXPECT_END(KERN_ERR,
3155 "OF: overlay: ERROR: multiple fragments add and/or delete node /testcase-data-2/substation@100/motor-1/controller");
3156
3157 EXPECT_BEGIN(KERN_ERR,
3158 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/substation@100/motor-1/rpm_avail");
3159 EXPECT_BEGIN(KERN_ERR,
3160 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/substation@100/motor-1/rpm_avail");
3161 EXPECT_BEGIN(KERN_ERR,
3162 "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/rpm_avail");
3163
Frank Rowand2fe0e872018-10-04 20:36:18 -07003164 unittest(overlay_data_apply("overlay_bad_add_dup_prop", NULL),
3165 "Adding overlay 'overlay_bad_add_dup_prop' failed\n");
3166
Frank Rowand0ac17432020-02-20 12:40:21 -06003167 EXPECT_END(KERN_ERR,
3168 "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/rpm_avail");
3169 EXPECT_END(KERN_ERR,
3170 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/substation@100/motor-1/rpm_avail");
3171 EXPECT_END(KERN_ERR,
3172 "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/substation@100/motor-1/rpm_avail");
3173
Frank Rowand39a751a2018-02-12 00:19:42 -08003174 unittest(overlay_data_apply("overlay_bad_phandle", NULL),
Frank Rowand81d0848f2017-04-25 17:09:54 -07003175 "Adding overlay 'overlay_bad_phandle' failed\n");
Frank Rowand60a00042017-07-19 09:25:20 -07003176
Frank Rowand39a751a2018-02-12 00:19:42 -08003177 unittest(overlay_data_apply("overlay_bad_symbol", NULL),
Frank Rowand60a00042017-07-19 09:25:20 -07003178 "Adding overlay 'overlay_bad_symbol' failed\n");
3179
Dan Carpenter8756cd12017-05-03 22:49:50 +03003180 return;
3181
3182err_unlock:
3183 mutex_unlock(&of_mutex);
Frank Rowand81d0848f2017-04-25 17:09:54 -07003184}
3185
3186#else
3187
3188static inline __init void of_unittest_overlay_high_level(void) {}
3189
3190#endif
3191
Wang Long9697a552015-03-11 08:36:54 +00003192static int __init of_unittest(void)
Grant Likely53a42092011-12-12 09:25:57 -07003193{
3194 struct device_node *np;
Gaurav Minochaae9304c2014-07-16 23:09:39 -07003195 int res;
3196
Frank Rowand0ac17432020-02-20 12:40:21 -06003197 pr_info("start of unittest - you will see error messages\n");
3198
Wang Long9697a552015-03-11 08:36:54 +00003199 /* adding data for unittest */
Brendan Higgins935665c2019-02-19 15:54:22 -08003200
3201 if (IS_ENABLED(CONFIG_UML))
3202 unittest_unflatten_overlay_base();
3203
Wang Long9697a552015-03-11 08:36:54 +00003204 res = unittest_data_add();
Gaurav Minochaae9304c2014-07-16 23:09:39 -07003205 if (res)
3206 return res;
Grant Likely788ec2f2014-11-19 17:13:44 +00003207 if (!of_aliases)
3208 of_aliases = of_find_node_by_path("/aliases");
Grant Likely53a42092011-12-12 09:25:57 -07003209
3210 np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
3211 if (!np) {
3212 pr_info("No testcase data in device tree; not running tests\n");
3213 return 0;
3214 }
3215 of_node_put(np);
3216
Wang Long9697a552015-03-11 08:36:54 +00003217 of_unittest_check_tree_linkage();
3218 of_unittest_check_phandles();
3219 of_unittest_find_node_by_name();
3220 of_unittest_dynamic();
3221 of_unittest_parse_phandle_with_args();
Stephen Boyd357aa4b2018-01-30 18:36:17 -08003222 of_unittest_parse_phandle_with_args_map();
Pantelis Antoniouce4fecf2015-01-21 19:06:14 +02003223 of_unittest_printf();
Wang Long9697a552015-03-11 08:36:54 +00003224 of_unittest_property_string();
3225 of_unittest_property_copy();
3226 of_unittest_changeset();
3227 of_unittest_parse_interrupts();
3228 of_unittest_parse_interrupts_extended();
Rob Herring04db93a2019-09-20 13:28:53 -05003229 of_unittest_parse_dma_ranges();
3230 of_unittest_pci_dma_ranges();
Wang Long9697a552015-03-11 08:36:54 +00003231 of_unittest_match_node();
3232 of_unittest_platform_populate();
3233 of_unittest_overlay();
Gaurav Minochaae9304c2014-07-16 23:09:39 -07003234
Grant Likelyf2051d62014-10-01 17:40:22 +01003235 /* Double check linkage after removing testcase data */
Wang Long9697a552015-03-11 08:36:54 +00003236 of_unittest_check_tree_linkage();
Grant Likelyf2051d62014-10-01 17:40:22 +01003237
Frank Rowand81d0848f2017-04-25 17:09:54 -07003238 of_unittest_overlay_high_level();
3239
Wang Long9697a552015-03-11 08:36:54 +00003240 pr_info("end of unittest - %i passed, %i failed\n",
3241 unittest_results.passed, unittest_results.failed);
Grant Likelyf2051d62014-10-01 17:40:22 +01003242
Grant Likely53a42092011-12-12 09:25:57 -07003243 return 0;
3244}
Wang Long9697a552015-03-11 08:36:54 +00003245late_initcall(of_unittest);