brintos

brintos / linux-shallow public Read only

0
0
Text · 122.4 KiB · daf9a2d Raw
4296 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Self tests for device tree subsystem4 */5 6#define pr_fmt(fmt) "### dt-test ### " fmt7 8#include <linux/memblock.h>9#include <linux/clk.h>10#include <linux/dma-direct.h> /* to test phys_to_dma/dma_to_phys */11#include <linux/err.h>12#include <linux/errno.h>13#include <linux/hashtable.h>14#include <linux/libfdt.h>15#include <linux/of.h>16#include <linux/of_address.h>17#include <linux/of_fdt.h>18#include <linux/of_irq.h>19#include <linux/of_platform.h>20#include <linux/list.h>21#include <linux/mutex.h>22#include <linux/slab.h>23#include <linux/device.h>24#include <linux/platform_device.h>25#include <linux/pci.h>26#include <linux/kernel.h>27 28#include <linux/i2c.h>29#include <linux/i2c-mux.h>30#include <linux/gpio/driver.h>31 32#include <linux/bitops.h>33 34#include "of_private.h"35 36static struct unittest_results {37	int passed;38	int failed;39} unittest_results;40 41#define unittest(result, fmt, ...) ({ \42	bool failed = !(result); \43	if (failed) { \44		unittest_results.failed++; \45		pr_err("FAIL %s():%i " fmt, __func__, __LINE__, ##__VA_ARGS__); \46	} else { \47		unittest_results.passed++; \48		pr_info("pass %s():%i\n", __func__, __LINE__); \49	} \50	failed; \51})52 53#ifdef CONFIG_OF_KOBJ54#define OF_KREF_READ(NODE) kref_read(&(NODE)->kobj.kref)55#else56#define OF_KREF_READ(NODE) 157#endif58 59/*60 * Expected message may have a message level other than KERN_INFO.61 * Print the expected message only if the current loglevel will allow62 * the actual message to print.63 *64 * Do not use EXPECT_BEGIN(), EXPECT_END(), EXPECT_NOT_BEGIN(), or65 * EXPECT_NOT_END() to report messages expected to be reported or not66 * reported by pr_debug().67 */68#define EXPECT_BEGIN(level, fmt, ...) \69	printk(level pr_fmt("EXPECT \\ : ") fmt, ##__VA_ARGS__)70 71#define EXPECT_END(level, fmt, ...) \72	printk(level pr_fmt("EXPECT / : ") fmt, ##__VA_ARGS__)73 74#define EXPECT_NOT_BEGIN(level, fmt, ...) \75	printk(level pr_fmt("EXPECT_NOT \\ : ") fmt, ##__VA_ARGS__)76 77#define EXPECT_NOT_END(level, fmt, ...) \78	printk(level pr_fmt("EXPECT_NOT / : ") fmt, ##__VA_ARGS__)79 80static void __init of_unittest_find_node_by_name(void)81{82	struct device_node *np;83	const char *options, *name;84 85	np = of_find_node_by_path("/testcase-data");86	name = kasprintf(GFP_KERNEL, "%pOF", np);87	unittest(np && name && !strcmp("/testcase-data", name),88		"find /testcase-data failed\n");89	of_node_put(np);90	kfree(name);91 92	/* Test if trailing '/' works */93	np = of_find_node_by_path("/testcase-data/");94	unittest(!np, "trailing '/' on /testcase-data/ should fail\n");95 96	np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");97	name = kasprintf(GFP_KERNEL, "%pOF", np);98	unittest(np && name && !strcmp("/testcase-data/phandle-tests/consumer-a", name),99		"find /testcase-data/phandle-tests/consumer-a failed\n");100	of_node_put(np);101	kfree(name);102 103	np = of_find_node_by_path("testcase-alias");104	name = kasprintf(GFP_KERNEL, "%pOF", np);105	unittest(np && name && !strcmp("/testcase-data", name),106		"find testcase-alias failed\n");107	of_node_put(np);108	kfree(name);109 110	/* Test if trailing '/' works on aliases */111	np = of_find_node_by_path("testcase-alias/");112	unittest(!np, "trailing '/' on testcase-alias/ should fail\n");113 114	np = of_find_node_by_path("testcase-alias/phandle-tests/consumer-a");115	name = kasprintf(GFP_KERNEL, "%pOF", np);116	unittest(np && name && !strcmp("/testcase-data/phandle-tests/consumer-a", name),117		"find testcase-alias/phandle-tests/consumer-a failed\n");118	of_node_put(np);119	kfree(name);120 121	np = of_find_node_by_path("/testcase-data/missing-path");122	unittest(!np, "non-existent path returned node %pOF\n", np);123	of_node_put(np);124 125	np = of_find_node_by_path("missing-alias");126	unittest(!np, "non-existent alias returned node %pOF\n", np);127	of_node_put(np);128 129	np = of_find_node_by_path("testcase-alias/missing-path");130	unittest(!np, "non-existent alias with relative path returned node %pOF\n", np);131	of_node_put(np);132 133	np = of_find_node_opts_by_path("/testcase-data:testoption", &options);134	unittest(np && !strcmp("testoption", options),135		 "option path test failed\n");136	of_node_put(np);137 138	np = of_find_node_opts_by_path("/testcase-data:test/option", &options);139	unittest(np && !strcmp("test/option", options),140		 "option path test, subcase #1 failed\n");141	of_node_put(np);142 143	np = of_find_node_opts_by_path("/testcase-data/testcase-device1:test/option", &options);144	unittest(np && !strcmp("test/option", options),145		 "option path test, subcase #2 failed\n");146	of_node_put(np);147 148	np = of_find_node_opts_by_path("/testcase-data:testoption", NULL);149	unittest(np, "NULL option path test failed\n");150	of_node_put(np);151 152	np = of_find_node_opts_by_path("testcase-alias:testaliasoption",153				       &options);154	unittest(np && !strcmp("testaliasoption", options),155		 "option alias path test failed\n");156	of_node_put(np);157 158	np = of_find_node_opts_by_path("testcase-alias:test/alias/option",159				       &options);160	unittest(np && !strcmp("test/alias/option", options),161		 "option alias path test, subcase #1 failed\n");162	of_node_put(np);163 164	np = of_find_node_opts_by_path("testcase-alias:testaliasoption", NULL);165	unittest(np, "NULL option alias path test failed\n");166	of_node_put(np);167 168	options = "testoption";169	np = of_find_node_opts_by_path("testcase-alias", &options);170	unittest(np && !options, "option clearing test failed\n");171	of_node_put(np);172 173	options = "testoption";174	np = of_find_node_opts_by_path("/", &options);175	unittest(np && !options, "option clearing root node test failed\n");176	of_node_put(np);177}178 179static void __init of_unittest_dynamic(void)180{181	struct device_node *np;182	struct property *prop;183 184	np = of_find_node_by_path("/testcase-data");185	if (!np) {186		pr_err("missing testcase data\n");187		return;188	}189 190	/* Array of 4 properties for the purpose of testing */191	prop = kcalloc(4, sizeof(*prop), GFP_KERNEL);192	if (!prop) {193		unittest(0, "kzalloc() failed\n");194		return;195	}196 197	/* Add a new property - should pass*/198	prop->name = "new-property";199	prop->value = "new-property-data";200	prop->length = strlen(prop->value) + 1;201	unittest(of_add_property(np, prop) == 0, "Adding a new property failed\n");202 203	/* Try to add an existing property - should fail */204	prop++;205	prop->name = "new-property";206	prop->value = "new-property-data-should-fail";207	prop->length = strlen(prop->value) + 1;208	unittest(of_add_property(np, prop) != 0,209		 "Adding an existing property should have failed\n");210 211	/* Try to modify an existing property - should pass */212	prop->value = "modify-property-data-should-pass";213	prop->length = strlen(prop->value) + 1;214	unittest(of_update_property(np, prop) == 0,215		 "Updating an existing property should have passed\n");216 217	/* Try to modify non-existent property - should pass*/218	prop++;219	prop->name = "modify-property";220	prop->value = "modify-missing-property-data-should-pass";221	prop->length = strlen(prop->value) + 1;222	unittest(of_update_property(np, prop) == 0,223		 "Updating a missing property should have passed\n");224 225	/* Remove property - should pass */226	unittest(of_remove_property(np, prop) == 0,227		 "Removing a property should have passed\n");228 229	/* Adding very large property - should pass */230	prop++;231	prop->name = "large-property-PAGE_SIZEx8";232	prop->length = PAGE_SIZE * 8;233	prop->value = kzalloc(prop->length, GFP_KERNEL);234	unittest(prop->value != NULL, "Unable to allocate large buffer\n");235	if (prop->value)236		unittest(of_add_property(np, prop) == 0,237			 "Adding a large property should have passed\n");238}239 240static int __init of_unittest_check_node_linkage(struct device_node *np)241{242	int count = 0, rc;243 244	for_each_child_of_node_scoped(np, child) {245		if (child->parent != np) {246			pr_err("Child node %pOFn links to wrong parent %pOFn\n",247				 child, np);248			return -EINVAL;249		}250 251		rc = of_unittest_check_node_linkage(child);252		if (rc < 0)253			return rc;254		count += rc;255	}256 257	return count + 1;258}259 260static void __init of_unittest_check_tree_linkage(void)261{262	struct device_node *np;263	int allnode_count = 0, child_count;264 265	if (!of_root)266		return;267 268	for_each_of_allnodes(np)269		allnode_count++;270	child_count = of_unittest_check_node_linkage(of_root);271 272	unittest(child_count > 0, "Device node data structure is corrupted\n");273	unittest(child_count == allnode_count,274		 "allnodes list size (%i) doesn't match sibling lists size (%i)\n",275		 allnode_count, child_count);276	pr_debug("allnodes list size (%i); sibling lists size (%i)\n", allnode_count, child_count);277}278 279static void __init of_unittest_printf_one(struct device_node *np, const char *fmt,280					  const char *expected)281{282	unsigned char *buf;283	int buf_size;284	int size, i;285 286	buf_size = strlen(expected) + 10;287	buf = kmalloc(buf_size, GFP_KERNEL);288	if (!buf)289		return;290 291	/* Baseline; check conversion with a large size limit */292	memset(buf, 0xff, buf_size);293	size = snprintf(buf, buf_size - 2, fmt, np);294 295	/* use strcmp() instead of strncmp() here to be absolutely sure strings match */296	unittest((strcmp(buf, expected) == 0) && (buf[size+1] == 0xff),297		"sprintf failed; fmt='%s' expected='%s' rslt='%s'\n",298		fmt, expected, buf);299 300	/* Make sure length limits work */301	size++;302	for (i = 0; i < 2; i++, size--) {303		/* Clear the buffer, and make sure it works correctly still */304		memset(buf, 0xff, buf_size);305		snprintf(buf, size+1, fmt, np);306		unittest(strncmp(buf, expected, size) == 0 && (buf[size+1] == 0xff),307			"snprintf failed; size=%i fmt='%s' expected='%s' rslt='%s'\n",308			size, fmt, expected, buf);309	}310	kfree(buf);311}312 313static void __init of_unittest_printf(void)314{315	struct device_node *np;316	const char *full_name = "/testcase-data/platform-tests/test-device@1/dev@100";317	char phandle_str[16] = "";318 319	np = of_find_node_by_path(full_name);320	if (!np) {321		unittest(np, "testcase data missing\n");322		return;323	}324 325	num_to_str(phandle_str, sizeof(phandle_str), np->phandle, 0);326 327	of_unittest_printf_one(np, "%pOF",  full_name);328	of_unittest_printf_one(np, "%pOFf", full_name);329	of_unittest_printf_one(np, "%pOFn", "dev");330	of_unittest_printf_one(np, "%2pOFn", "dev");331	of_unittest_printf_one(np, "%5pOFn", "  dev");332	of_unittest_printf_one(np, "%pOFnc", "dev:test-sub-device");333	of_unittest_printf_one(np, "%pOFp", phandle_str);334	of_unittest_printf_one(np, "%pOFP", "dev@100");335	of_unittest_printf_one(np, "ABC %pOFP ABC", "ABC dev@100 ABC");336	of_unittest_printf_one(np, "%10pOFP", "   dev@100");337	of_unittest_printf_one(np, "%-10pOFP", "dev@100   ");338	of_unittest_printf_one(of_root, "%pOFP", "/");339	of_unittest_printf_one(np, "%pOFF", "----");340	of_unittest_printf_one(np, "%pOFPF", "dev@100:----");341	of_unittest_printf_one(np, "%pOFPFPc", "dev@100:----:dev@100:test-sub-device");342	of_unittest_printf_one(np, "%pOFc", "test-sub-device");343	of_unittest_printf_one(np, "%pOFC",344			"\"test-sub-device\",\"test-compat2\",\"test-compat3\"");345}346 347struct node_hash {348	struct hlist_node node;349	struct device_node *np;350};351 352static DEFINE_HASHTABLE(phandle_ht, 8);353static void __init of_unittest_check_phandles(void)354{355	struct device_node *np;356	struct node_hash *nh;357	struct hlist_node *tmp;358	int i, dup_count = 0, phandle_count = 0;359 360	for_each_of_allnodes(np) {361		if (!np->phandle)362			continue;363 364		hash_for_each_possible(phandle_ht, nh, node, np->phandle) {365			if (nh->np->phandle == np->phandle) {366				pr_info("Duplicate phandle! %i used by %pOF and %pOF\n",367					np->phandle, nh->np, np);368				dup_count++;369				break;370			}371		}372 373		nh = kzalloc(sizeof(*nh), GFP_KERNEL);374		if (!nh)375			return;376 377		nh->np = np;378		hash_add(phandle_ht, &nh->node, np->phandle);379		phandle_count++;380	}381	unittest(dup_count == 0, "Found %i duplicates in %i phandles\n",382		 dup_count, phandle_count);383 384	/* Clean up */385	hash_for_each_safe(phandle_ht, i, tmp, nh, node) {386		hash_del(&nh->node);387		kfree(nh);388	}389}390 391static void __init of_unittest_parse_phandle_with_args(void)392{393	struct device_node *np;394	struct of_phandle_args args;395	int i, rc;396 397	np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");398	if (!np) {399		pr_err("missing testcase data\n");400		return;401	}402 403	rc = of_count_phandle_with_args(np, "phandle-list", "#phandle-cells");404	unittest(rc == 7, "of_count_phandle_with_args() returned %i, expected 7\n", rc);405 406	for (i = 0; i < 8; i++) {407		bool passed = true;408 409		memset(&args, 0, sizeof(args));410		rc = of_parse_phandle_with_args(np, "phandle-list",411						"#phandle-cells", i, &args);412 413		/* Test the values from tests-phandle.dtsi */414		switch (i) {415		case 0:416			passed &= !rc;417			passed &= (args.args_count == 1);418			passed &= (args.args[0] == (i + 1));419			break;420		case 1:421			passed &= !rc;422			passed &= (args.args_count == 2);423			passed &= (args.args[0] == (i + 1));424			passed &= (args.args[1] == 0);425			break;426		case 2:427			passed &= (rc == -ENOENT);428			break;429		case 3:430			passed &= !rc;431			passed &= (args.args_count == 3);432			passed &= (args.args[0] == (i + 1));433			passed &= (args.args[1] == 4);434			passed &= (args.args[2] == 3);435			break;436		case 4:437			passed &= !rc;438			passed &= (args.args_count == 2);439			passed &= (args.args[0] == (i + 1));440			passed &= (args.args[1] == 100);441			break;442		case 5:443			passed &= !rc;444			passed &= (args.args_count == 0);445			break;446		case 6:447			passed &= !rc;448			passed &= (args.args_count == 1);449			passed &= (args.args[0] == (i + 1));450			break;451		case 7:452			passed &= (rc == -ENOENT);453			break;454		default:455			passed = false;456		}457 458		unittest(passed, "index %i - data error on node %pOF rc=%i\n",459			 i, args.np, rc);460 461		if (rc == 0)462			of_node_put(args.np);463	}464 465	/* Check for missing list property */466	memset(&args, 0, sizeof(args));467	rc = of_parse_phandle_with_args(np, "phandle-list-missing",468					"#phandle-cells", 0, &args);469	unittest(rc == -ENOENT, "expected:%i got:%i\n", -ENOENT, rc);470	rc = of_count_phandle_with_args(np, "phandle-list-missing",471					"#phandle-cells");472	unittest(rc == -ENOENT, "expected:%i got:%i\n", -ENOENT, rc);473 474	/* Check for missing cells property */475	memset(&args, 0, sizeof(args));476 477	EXPECT_BEGIN(KERN_INFO,478		     "OF: /testcase-data/phandle-tests/consumer-a: could not get #phandle-cells-missing for /testcase-data/phandle-tests/provider1");479 480	rc = of_parse_phandle_with_args(np, "phandle-list",481					"#phandle-cells-missing", 0, &args);482 483	EXPECT_END(KERN_INFO,484		   "OF: /testcase-data/phandle-tests/consumer-a: could not get #phandle-cells-missing for /testcase-data/phandle-tests/provider1");485 486	unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);487 488	EXPECT_BEGIN(KERN_INFO,489		     "OF: /testcase-data/phandle-tests/consumer-a: could not get #phandle-cells-missing for /testcase-data/phandle-tests/provider1");490 491	rc = of_count_phandle_with_args(np, "phandle-list",492					"#phandle-cells-missing");493 494	EXPECT_END(KERN_INFO,495		   "OF: /testcase-data/phandle-tests/consumer-a: could not get #phandle-cells-missing for /testcase-data/phandle-tests/provider1");496 497	unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);498 499	/* Check for bad phandle in list */500	memset(&args, 0, sizeof(args));501 502	EXPECT_BEGIN(KERN_INFO,503		     "OF: /testcase-data/phandle-tests/consumer-a: could not find phandle");504 505	rc = of_parse_phandle_with_args(np, "phandle-list-bad-phandle",506					"#phandle-cells", 0, &args);507 508	EXPECT_END(KERN_INFO,509		   "OF: /testcase-data/phandle-tests/consumer-a: could not find phandle");510 511	unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);512 513	EXPECT_BEGIN(KERN_INFO,514		     "OF: /testcase-data/phandle-tests/consumer-a: could not find phandle");515 516	rc = of_count_phandle_with_args(np, "phandle-list-bad-phandle",517					"#phandle-cells");518 519	EXPECT_END(KERN_INFO,520		   "OF: /testcase-data/phandle-tests/consumer-a: could not find phandle");521 522	unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);523 524	/* Check for incorrectly formed argument list */525	memset(&args, 0, sizeof(args));526 527	EXPECT_BEGIN(KERN_INFO,528		     "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found 1");529 530	rc = of_parse_phandle_with_args(np, "phandle-list-bad-args",531					"#phandle-cells", 1, &args);532 533	EXPECT_END(KERN_INFO,534		   "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found 1");535 536	unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);537 538	EXPECT_BEGIN(KERN_INFO,539		     "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found 1");540 541	rc = of_count_phandle_with_args(np, "phandle-list-bad-args",542					"#phandle-cells");543 544	EXPECT_END(KERN_INFO,545		   "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found 1");546 547	unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);548}549 550static void __init of_unittest_parse_phandle_with_args_map(void)551{552	struct device_node *np, *p[6] = {};553	struct of_phandle_args args;554	unsigned int prefs[6];555	int i, rc;556 557	np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-b");558	if (!np) {559		pr_err("missing testcase data\n");560		return;561	}562 563	p[0] = of_find_node_by_path("/testcase-data/phandle-tests/provider0");564	p[1] = of_find_node_by_path("/testcase-data/phandle-tests/provider1");565	p[2] = of_find_node_by_path("/testcase-data/phandle-tests/provider2");566	p[3] = of_find_node_by_path("/testcase-data/phandle-tests/provider3");567	p[4] = of_find_node_by_path("/testcase-data/phandle-tests/provider4");568	p[5] = of_find_node_by_path("/testcase-data/phandle-tests/provider5");569	for (i = 0; i < ARRAY_SIZE(p); ++i) {570		if (!p[i]) {571			pr_err("missing testcase data\n");572			return;573		}574		prefs[i] = OF_KREF_READ(p[i]);575	}576 577	rc = of_count_phandle_with_args(np, "phandle-list", "#phandle-cells");578	unittest(rc == 8, "of_count_phandle_with_args() returned %i, expected 8\n", rc);579 580	for (i = 0; i < 9; i++) {581		bool passed = true;582 583		memset(&args, 0, sizeof(args));584		rc = of_parse_phandle_with_args_map(np, "phandle-list",585						    "phandle", i, &args);586 587		/* Test the values from tests-phandle.dtsi */588		switch (i) {589		case 0:590			passed &= !rc;591			passed &= (args.np == p[1]);592			passed &= (args.args_count == 1);593			passed &= (args.args[0] == 1);594			break;595		case 1:596			passed &= !rc;597			passed &= (args.np == p[3]);598			passed &= (args.args_count == 3);599			passed &= (args.args[0] == 2);600			passed &= (args.args[1] == 5);601			passed &= (args.args[2] == 3);602			break;603		case 2:604			passed &= (rc == -ENOENT);605			break;606		case 3:607			passed &= !rc;608			passed &= (args.np == p[0]);609			passed &= (args.args_count == 0);610			break;611		case 4:612			passed &= !rc;613			passed &= (args.np == p[1]);614			passed &= (args.args_count == 1);615			passed &= (args.args[0] == 3);616			break;617		case 5:618			passed &= !rc;619			passed &= (args.np == p[0]);620			passed &= (args.args_count == 0);621			break;622		case 6:623			passed &= !rc;624			passed &= (args.np == p[2]);625			passed &= (args.args_count == 2);626			passed &= (args.args[0] == 15);627			passed &= (args.args[1] == 0x20);628			break;629		case 7:630			passed &= !rc;631			passed &= (args.np == p[3]);632			passed &= (args.args_count == 3);633			passed &= (args.args[0] == 2);634			passed &= (args.args[1] == 5);635			passed &= (args.args[2] == 3);636			break;637		case 8:638			passed &= (rc == -ENOENT);639			break;640		default:641			passed = false;642		}643 644		unittest(passed, "index %i - data error on node %s rc=%i\n",645			 i, args.np->full_name, rc);646 647		if (rc == 0)648			of_node_put(args.np);649	}650 651	/* Check for missing list property */652	memset(&args, 0, sizeof(args));653	rc = of_parse_phandle_with_args_map(np, "phandle-list-missing",654					    "phandle", 0, &args);655	unittest(rc == -ENOENT, "expected:%i got:%i\n", -ENOENT, rc);656 657	/* Check for missing cells,map,mask property */658	memset(&args, 0, sizeof(args));659 660	EXPECT_BEGIN(KERN_INFO,661		     "OF: /testcase-data/phandle-tests/consumer-b: could not get #phandle-missing-cells for /testcase-data/phandle-tests/provider1");662 663	rc = of_parse_phandle_with_args_map(np, "phandle-list",664					    "phandle-missing", 0, &args);665	EXPECT_END(KERN_INFO,666		   "OF: /testcase-data/phandle-tests/consumer-b: could not get #phandle-missing-cells for /testcase-data/phandle-tests/provider1");667 668	unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);669 670	/* Check for bad phandle in list */671	memset(&args, 0, sizeof(args));672 673	EXPECT_BEGIN(KERN_INFO,674		     "OF: /testcase-data/phandle-tests/consumer-b: could not find phandle 12345678");675 676	rc = of_parse_phandle_with_args_map(np, "phandle-list-bad-phandle",677					    "phandle", 0, &args);678	EXPECT_END(KERN_INFO,679		   "OF: /testcase-data/phandle-tests/consumer-b: could not find phandle 12345678");680 681	unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);682 683	/* Check for incorrectly formed argument list */684	memset(&args, 0, sizeof(args));685 686	EXPECT_BEGIN(KERN_INFO,687		     "OF: /testcase-data/phandle-tests/consumer-b: #phandle-cells = 2 found 1");688 689	rc = of_parse_phandle_with_args_map(np, "phandle-list-bad-args",690					    "phandle", 1, &args);691	EXPECT_END(KERN_INFO,692		   "OF: /testcase-data/phandle-tests/consumer-b: #phandle-cells = 2 found 1");693 694	unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);695 696	for (i = 0; i < ARRAY_SIZE(p); ++i) {697		unittest(prefs[i] == OF_KREF_READ(p[i]),698			 "provider%d: expected:%d got:%d\n",699			 i, prefs[i], OF_KREF_READ(p[i]));700		of_node_put(p[i]);701	}702}703 704static void __init of_unittest_property_string(void)705{706	const char *strings[4];707	struct device_node *np;708	int rc;709 710	np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");711	if (!np) {712		pr_err("No testcase data in device tree\n");713		return;714	}715 716	rc = of_property_match_string(np, "phandle-list-names", "first");717	unittest(rc == 0, "first expected:0 got:%i\n", rc);718	rc = of_property_match_string(np, "phandle-list-names", "second");719	unittest(rc == 1, "second expected:1 got:%i\n", rc);720	rc = of_property_match_string(np, "phandle-list-names", "third");721	unittest(rc == 2, "third expected:2 got:%i\n", rc);722	rc = of_property_match_string(np, "phandle-list-names", "fourth");723	unittest(rc == -ENODATA, "unmatched string; rc=%i\n", rc);724	rc = of_property_match_string(np, "missing-property", "blah");725	unittest(rc == -EINVAL, "missing property; rc=%i\n", rc);726	rc = of_property_match_string(np, "empty-property", "blah");727	unittest(rc == -ENODATA, "empty property; rc=%i\n", rc);728	rc = of_property_match_string(np, "unterminated-string", "blah");729	unittest(rc == -EILSEQ, "unterminated string; rc=%i\n", rc);730 731	/* of_property_count_strings() tests */732	rc = of_property_count_strings(np, "string-property");733	unittest(rc == 1, "Incorrect string count; rc=%i\n", rc);734	rc = of_property_count_strings(np, "phandle-list-names");735	unittest(rc == 3, "Incorrect string count; rc=%i\n", rc);736	rc = of_property_count_strings(np, "unterminated-string");737	unittest(rc == -EILSEQ, "unterminated string; rc=%i\n", rc);738	rc = of_property_count_strings(np, "unterminated-string-list");739	unittest(rc == -EILSEQ, "unterminated string array; rc=%i\n", rc);740 741	/* of_property_read_string_index() tests */742	rc = of_property_read_string_index(np, "string-property", 0, strings);743	unittest(rc == 0 && !strcmp(strings[0], "foobar"), "of_property_read_string_index() failure; rc=%i\n", rc);744	strings[0] = NULL;745	rc = of_property_read_string_index(np, "string-property", 1, strings);746	unittest(rc == -ENODATA && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc);747	rc = of_property_read_string_index(np, "phandle-list-names", 0, strings);748	unittest(rc == 0 && !strcmp(strings[0], "first"), "of_property_read_string_index() failure; rc=%i\n", rc);749	rc = of_property_read_string_index(np, "phandle-list-names", 1, strings);750	unittest(rc == 0 && !strcmp(strings[0], "second"), "of_property_read_string_index() failure; rc=%i\n", rc);751	rc = of_property_read_string_index(np, "phandle-list-names", 2, strings);752	unittest(rc == 0 && !strcmp(strings[0], "third"), "of_property_read_string_index() failure; rc=%i\n", rc);753	strings[0] = NULL;754	rc = of_property_read_string_index(np, "phandle-list-names", 3, strings);755	unittest(rc == -ENODATA && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc);756	strings[0] = NULL;757	rc = of_property_read_string_index(np, "unterminated-string", 0, strings);758	unittest(rc == -EILSEQ && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc);759	rc = of_property_read_string_index(np, "unterminated-string-list", 0, strings);760	unittest(rc == 0 && !strcmp(strings[0], "first"), "of_property_read_string_index() failure; rc=%i\n", rc);761	strings[0] = NULL;762	rc = of_property_read_string_index(np, "unterminated-string-list", 2, strings); /* should fail */763	unittest(rc == -EILSEQ && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc);764	strings[1] = NULL;765 766	/* of_property_read_string_array() tests */767	rc = of_property_read_string_array(np, "string-property", strings, 4);768	unittest(rc == 1, "Incorrect string count; rc=%i\n", rc);769	rc = of_property_read_string_array(np, "phandle-list-names", strings, 4);770	unittest(rc == 3, "Incorrect string count; rc=%i\n", rc);771	rc = of_property_read_string_array(np, "unterminated-string", strings, 4);772	unittest(rc == -EILSEQ, "unterminated string; rc=%i\n", rc);773	/* -- An incorrectly formed string should cause a failure */774	rc = of_property_read_string_array(np, "unterminated-string-list", strings, 4);775	unittest(rc == -EILSEQ, "unterminated string array; rc=%i\n", rc);776	/* -- parsing the correctly formed strings should still work: */777	strings[2] = NULL;778	rc = of_property_read_string_array(np, "unterminated-string-list", strings, 2);779	unittest(rc == 2 && strings[2] == NULL, "of_property_read_string_array() failure; rc=%i\n", rc);780	strings[1] = NULL;781	rc = of_property_read_string_array(np, "phandle-list-names", strings, 1);782	unittest(rc == 1 && strings[1] == NULL, "Overwrote end of string array; rc=%i, str='%s'\n", rc, strings[1]);783}784 785#define propcmp(p1, p2) (((p1)->length == (p2)->length) && \786			(p1)->value && (p2)->value && \787			!memcmp((p1)->value, (p2)->value, (p1)->length) && \788			!strcmp((p1)->name, (p2)->name))789static void __init of_unittest_property_copy(void)790{791#ifdef CONFIG_OF_DYNAMIC792	struct property p1 = { .name = "p1", .length = 0, .value = "" };793	struct property p2 = { .name = "p2", .length = 5, .value = "abcd" };794	struct property *new;795 796	new = __of_prop_dup(&p1, GFP_KERNEL);797	unittest(new && propcmp(&p1, new), "empty property didn't copy correctly\n");798	__of_prop_free(new);799 800	new = __of_prop_dup(&p2, GFP_KERNEL);801	unittest(new && propcmp(&p2, new), "non-empty property didn't copy correctly\n");802	__of_prop_free(new);803#endif804}805 806static void __init of_unittest_changeset(void)807{808#ifdef CONFIG_OF_DYNAMIC809	int ret;810	struct property *ppadd, padd = { .name = "prop-add", .length = 1, .value = "" };811	struct property *ppname_n1,  pname_n1  = { .name = "name", .length = 3, .value = "n1"  };812	struct property *ppname_n2,  pname_n2  = { .name = "name", .length = 3, .value = "n2"  };813	struct property *ppname_n21, pname_n21 = { .name = "name", .length = 3, .value = "n21" };814	struct property *ppupdate, pupdate = { .name = "prop-update", .length = 5, .value = "abcd" };815	struct property *ppremove;816	struct device_node *n1, *n2, *n21, *n22, *nchangeset, *nremove, *parent, *np;817	static const char * const str_array[] = { "str1", "str2", "str3" };818	const u32 u32_array[] = { 1, 2, 3 };819	struct of_changeset chgset;820	const char *propstr = NULL;821 822	n1 = __of_node_dup(NULL, "n1");823	unittest(n1, "testcase setup failure\n");824 825	n2 = __of_node_dup(NULL, "n2");826	unittest(n2, "testcase setup failure\n");827 828	n21 = __of_node_dup(NULL, "n21");829	unittest(n21, "testcase setup failure %p\n", n21);830 831	nchangeset = of_find_node_by_path("/testcase-data/changeset");832	nremove = of_get_child_by_name(nchangeset, "node-remove");833	unittest(nremove, "testcase setup failure\n");834 835	ppadd = __of_prop_dup(&padd, GFP_KERNEL);836	unittest(ppadd, "testcase setup failure\n");837 838	ppname_n1  = __of_prop_dup(&pname_n1, GFP_KERNEL);839	unittest(ppname_n1, "testcase setup failure\n");840 841	ppname_n2  = __of_prop_dup(&pname_n2, GFP_KERNEL);842	unittest(ppname_n2, "testcase setup failure\n");843 844	ppname_n21 = __of_prop_dup(&pname_n21, GFP_KERNEL);845	unittest(ppname_n21, "testcase setup failure\n");846 847	ppupdate = __of_prop_dup(&pupdate, GFP_KERNEL);848	unittest(ppupdate, "testcase setup failure\n");849 850	parent = nchangeset;851	n1->parent = parent;852	n2->parent = parent;853	n21->parent = n2;854 855	ppremove = of_find_property(parent, "prop-remove", NULL);856	unittest(ppremove, "failed to find removal prop");857 858	of_changeset_init(&chgset);859 860	unittest(!of_changeset_attach_node(&chgset, n1), "fail attach n1\n");861	unittest(!of_changeset_add_property(&chgset, n1, ppname_n1), "fail add prop name\n");862 863	unittest(!of_changeset_attach_node(&chgset, n2), "fail attach n2\n");864	unittest(!of_changeset_add_property(&chgset, n2, ppname_n2), "fail add prop name\n");865 866	unittest(!of_changeset_detach_node(&chgset, nremove), "fail remove node\n");867	unittest(!of_changeset_add_property(&chgset, n21, ppname_n21), "fail add prop name\n");868 869	unittest(!of_changeset_attach_node(&chgset, n21), "fail attach n21\n");870 871	unittest(!of_changeset_add_property(&chgset, parent, ppadd), "fail add prop prop-add\n");872	unittest(!of_changeset_update_property(&chgset, parent, ppupdate), "fail update prop\n");873	unittest(!of_changeset_remove_property(&chgset, parent, ppremove), "fail remove prop\n");874	n22 = of_changeset_create_node(&chgset, n2, "n22");875	unittest(n22, "fail create n22\n");876	unittest(!of_changeset_add_prop_string(&chgset, n22, "prop-str", "abcd"),877		 "fail add prop prop-str");878	unittest(!of_changeset_add_prop_string_array(&chgset, n22, "prop-str-array",879						     (const char **)str_array,880						     ARRAY_SIZE(str_array)),881		 "fail add prop prop-str-array");882	unittest(!of_changeset_add_prop_u32_array(&chgset, n22, "prop-u32-array",883						  u32_array, ARRAY_SIZE(u32_array)),884		 "fail add prop prop-u32-array");885 886	unittest(!of_changeset_apply(&chgset), "apply failed\n");887 888	of_node_put(nchangeset);889 890	/* Make sure node names are constructed correctly */891	unittest((np = of_find_node_by_path("/testcase-data/changeset/n2/n21")),892		 "'%pOF' not added\n", n21);893	of_node_put(np);894	unittest((np = of_find_node_by_path("/testcase-data/changeset/n2/n22")),895		 "'%pOF' not added\n", n22);896	of_node_put(np);897 898	unittest(!of_changeset_revert(&chgset), "revert failed\n");899 900	unittest(!of_find_node_by_path("/testcase-data/changeset/n2/n21"),901		 "'%pOF' still present after revert\n", n21);902 903	unittest(of_property_present(parent, "prop-remove"),904		 "failed to find removed prop after revert\n");905 906	ret = of_property_read_string(parent, "prop-update", &propstr);907	unittest(!ret, "failed to find updated prop after revert\n");908	if (!ret)909		unittest(strcmp(propstr, "hello") == 0, "original value not in updated property after revert");910 911	of_changeset_destroy(&chgset);912 913	of_node_put(n1);914	of_node_put(n2);915	of_node_put(n21);916	of_node_put(n22);917#endif918}919 920static void __init __maybe_unused changeset_check_string(struct device_node *np,921							 const char *prop_name,922							 const char *expected_str)923{924	const char *str;925	int ret;926 927	ret = of_property_read_string(np, prop_name, &str);928	if (unittest(ret == 0, "failed to read %s\n", prop_name))929		return;930 931	unittest(strcmp(str, expected_str) == 0,932		 "%s value mismatch (read '%s', exp '%s')\n",933		 prop_name, str, expected_str);934}935 936static void __init __maybe_unused changeset_check_string_array(struct device_node *np,937							       const char *prop_name,938							       const char * const *expected_array,939							       unsigned int count)940{941	const char *str;942	unsigned int i;943	int ret;944	int cnt;945 946	cnt = of_property_count_strings(np, prop_name);947	if (unittest(cnt >= 0, "failed to get %s count\n", prop_name))948		return;949 950	if (unittest(cnt == count,951		     "%s count mismatch (read %d, exp %u)\n",952		     prop_name, cnt, count))953		return;954 955	for (i = 0; i < count; i++) {956		ret = of_property_read_string_index(np, prop_name, i, &str);957		if (unittest(ret == 0, "failed to read %s[%d]\n", prop_name, i))958			continue;959 960		unittest(strcmp(str, expected_array[i]) == 0,961			 "%s[%d] value mismatch (read '%s', exp '%s')\n",962			 prop_name, i, str, expected_array[i]);963	}964}965 966static void __init __maybe_unused changeset_check_u32(struct device_node *np,967						      const char *prop_name,968						      u32 expected_u32)969{970	u32 val32;971	int ret;972 973	ret = of_property_read_u32(np, prop_name, &val32);974	if (unittest(ret == 0, "failed to read %s\n", prop_name))975		return;976 977	unittest(val32 == expected_u32,978		 "%s value mismatch (read '%u', exp '%u')\n",979		 prop_name, val32, expected_u32);980}981 982static void __init __maybe_unused changeset_check_u32_array(struct device_node *np,983							    const char *prop_name,984							    const u32 *expected_array,985							    unsigned int count)986{987	unsigned int i;988	u32 val32;989	int ret;990	int cnt;991 992	cnt = of_property_count_u32_elems(np, prop_name);993	if (unittest(cnt >= 0, "failed to get %s count\n", prop_name))994		return;995 996	if (unittest(cnt == count,997		     "%s count mismatch (read %d, exp %u)\n",998		     prop_name, cnt, count))999		return;1000 1001	for (i = 0; i < count; i++) {1002		ret = of_property_read_u32_index(np, prop_name, i, &val32);1003		if (unittest(ret == 0, "failed to read %s[%d]\n", prop_name, i))1004			continue;1005 1006		unittest(val32 == expected_array[i],1007			 "%s[%d] value mismatch (read '%u', exp '%u')\n",1008			 prop_name, i, val32, expected_array[i]);1009	}1010}1011 1012static void __init __maybe_unused changeset_check_bool(struct device_node *np,1013						       const char *prop_name)1014{1015	unittest(of_property_read_bool(np, prop_name),1016		 "%s value mismatch (read 'false', exp 'true')\n", prop_name);1017}1018 1019static void __init of_unittest_changeset_prop(void)1020{1021#ifdef CONFIG_OF_DYNAMIC1022	static const char * const str_array[] = { "abc", "defg", "hij" };1023	static const u32 u32_array[] = { 123, 4567, 89, 10, 11 };1024	struct device_node *nchangeset, *np;1025	struct of_changeset chgset;1026	int ret;1027 1028	nchangeset = of_find_node_by_path("/testcase-data/changeset");1029	if (!nchangeset) {1030		pr_err("missing testcase data\n");1031		return;1032	}1033 1034	of_changeset_init(&chgset);1035 1036	np = of_changeset_create_node(&chgset, nchangeset, "test-prop");1037	if (unittest(np, "failed to create test-prop node\n"))1038		goto end_changeset_destroy;1039 1040	ret = of_changeset_add_prop_string(&chgset, np, "prop-string", "abcde");1041	unittest(ret == 0, "failed to add prop-string\n");1042 1043	ret = of_changeset_add_prop_string_array(&chgset, np, "prop-string-array",1044						 str_array, ARRAY_SIZE(str_array));1045	unittest(ret == 0, "failed to add prop-string-array\n");1046 1047	ret = of_changeset_add_prop_u32(&chgset, np, "prop-u32", 1234);1048	unittest(ret == 0, "failed to add prop-u32\n");1049 1050	ret = of_changeset_add_prop_u32_array(&chgset, np, "prop-u32-array",1051					      u32_array, ARRAY_SIZE(u32_array));1052	unittest(ret == 0, "failed to add prop-u32-array\n");1053 1054	ret = of_changeset_add_prop_bool(&chgset, np, "prop-bool");1055	unittest(ret == 0, "failed to add prop-bool\n");1056 1057	of_node_put(np);1058 1059	ret = of_changeset_apply(&chgset);1060	if (unittest(ret == 0, "failed to apply changeset\n"))1061		goto end_changeset_destroy;1062 1063	np = of_find_node_by_path("/testcase-data/changeset/test-prop");1064	if (unittest(np, "failed to find test-prop node\n"))1065		goto end_revert_changeset;1066 1067	changeset_check_string(np, "prop-string", "abcde");1068	changeset_check_string_array(np, "prop-string-array", str_array, ARRAY_SIZE(str_array));1069	changeset_check_u32(np, "prop-u32", 1234);1070	changeset_check_u32_array(np, "prop-u32-array", u32_array, ARRAY_SIZE(u32_array));1071	changeset_check_bool(np, "prop-bool");1072 1073	of_node_put(np);1074 1075end_revert_changeset:1076	ret = of_changeset_revert(&chgset);1077	unittest(ret == 0, "failed to revert changeset\n");1078 1079end_changeset_destroy:1080	of_changeset_destroy(&chgset);1081	of_node_put(nchangeset);1082#endif1083}1084 1085static void __init of_unittest_dma_get_max_cpu_address(void)1086{1087	struct device_node *np;1088	phys_addr_t cpu_addr;1089 1090	if (!IS_ENABLED(CONFIG_OF_ADDRESS))1091		return;1092 1093	np = of_find_node_by_path("/testcase-data/address-tests");1094	if (!np) {1095		pr_err("missing testcase data\n");1096		return;1097	}1098 1099	cpu_addr = of_dma_get_max_cpu_address(np);1100	unittest(cpu_addr == 0x4fffffff,1101		 "of_dma_get_max_cpu_address: wrong CPU addr %pad (expecting %x)\n",1102		 &cpu_addr, 0x4fffffff);1103}1104 1105static void __init of_unittest_dma_ranges_one(const char *path,1106		u64 expect_dma_addr, u64 expect_paddr)1107{1108#ifdef CONFIG_HAS_DMA1109	struct device_node *np;1110	const struct bus_dma_region *map = NULL;1111	int rc;1112 1113	np = of_find_node_by_path(path);1114	if (!np) {1115		pr_err("missing testcase data\n");1116		return;1117	}1118 1119	rc = of_dma_get_range(np, &map);1120 1121	unittest(!rc, "of_dma_get_range failed on node %pOF rc=%i\n", np, rc);1122 1123	if (!rc) {1124		phys_addr_t	paddr;1125		dma_addr_t	dma_addr;1126		struct device	*dev_bogus;1127 1128		dev_bogus = kzalloc(sizeof(struct device), GFP_KERNEL);1129		if (!dev_bogus) {1130			unittest(0, "kzalloc() failed\n");1131			kfree(map);1132			return;1133		}1134 1135		dev_bogus->dma_range_map = map;1136		paddr = dma_to_phys(dev_bogus, expect_dma_addr);1137		dma_addr = phys_to_dma(dev_bogus, expect_paddr);1138 1139		unittest(paddr == expect_paddr,1140			 "of_dma_get_range: wrong phys addr %pap (expecting %llx) on node %pOF\n",1141			 &paddr, expect_paddr, np);1142		unittest(dma_addr == expect_dma_addr,1143			 "of_dma_get_range: wrong DMA addr %pad (expecting %llx) on node %pOF\n",1144			 &dma_addr, expect_dma_addr, np);1145 1146		kfree(map);1147		kfree(dev_bogus);1148	}1149	of_node_put(np);1150#endif1151}1152 1153static void __init of_unittest_parse_dma_ranges(void)1154{1155	of_unittest_dma_ranges_one("/testcase-data/address-tests/device@70000000",1156		0x0, 0x20000000);1157	if (IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT))1158		of_unittest_dma_ranges_one("/testcase-data/address-tests/bus@80000000/device@1000",1159			0x100000000, 0x20000000);1160	of_unittest_dma_ranges_one("/testcase-data/address-tests/pci@90000000",1161		0x80000000, 0x20000000);1162}1163 1164static void __init of_unittest_pci_dma_ranges(void)1165{1166	struct device_node *np;1167	struct of_pci_range range;1168	struct of_pci_range_parser parser;1169	int i = 0;1170 1171	if (!IS_ENABLED(CONFIG_PCI))1172		return;1173 1174	np = of_find_node_by_path("/testcase-data/address-tests/pci@90000000");1175	if (!np) {1176		pr_err("missing testcase data\n");1177		return;1178	}1179 1180	if (of_pci_dma_range_parser_init(&parser, np)) {1181		pr_err("missing dma-ranges property\n");1182		return;1183	}1184 1185	/*1186	 * Get the dma-ranges from the device tree1187	 */1188	for_each_of_pci_range(&parser, &range) {1189		if (!i) {1190			unittest(range.size == 0x10000000,1191				 "for_each_of_pci_range wrong size on node %pOF size=%llx\n",1192				 np, range.size);1193			unittest(range.cpu_addr == 0x20000000,1194				 "for_each_of_pci_range wrong CPU addr (%llx) on node %pOF",1195				 range.cpu_addr, np);1196			unittest(range.pci_addr == 0x80000000,1197				 "for_each_of_pci_range wrong DMA addr (%llx) on node %pOF",1198				 range.pci_addr, np);1199		} else {1200			unittest(range.size == 0x10000000,1201				 "for_each_of_pci_range wrong size on node %pOF size=%llx\n",1202				 np, range.size);1203			unittest(range.cpu_addr == 0x40000000,1204				 "for_each_of_pci_range wrong CPU addr (%llx) on node %pOF",1205				 range.cpu_addr, np);1206			unittest(range.pci_addr == 0xc0000000,1207				 "for_each_of_pci_range wrong DMA addr (%llx) on node %pOF",1208				 range.pci_addr, np);1209		}1210		i++;1211	}1212 1213	of_node_put(np);1214}1215 1216static void __init of_unittest_bus_ranges(void)1217{1218	struct device_node *np;1219	struct of_range range;1220	struct of_range_parser parser;1221	struct resource res;1222	int ret, count, i = 0;1223 1224	np = of_find_node_by_path("/testcase-data/address-tests");1225	if (!np) {1226		pr_err("missing testcase data\n");1227		return;1228	}1229 1230	if (of_range_parser_init(&parser, np)) {1231		pr_err("missing ranges property\n");1232		return;1233	}1234 1235	ret = of_range_to_resource(np, 1, &res);1236	unittest(!ret, "of_range_to_resource returned error (%d) node %pOF\n",1237		ret, np);1238	unittest(resource_type(&res) == IORESOURCE_MEM,1239		"of_range_to_resource wrong resource type on node %pOF res=%pR\n",1240		np, &res);1241	unittest(res.start == 0xd0000000,1242		"of_range_to_resource wrong resource start address on node %pOF res=%pR\n",1243		np, &res);1244	unittest(resource_size(&res) == 0x20000000,1245		"of_range_to_resource wrong resource start address on node %pOF res=%pR\n",1246		np, &res);1247 1248	count = of_range_count(&parser);1249	unittest(count == 2,1250		"of_range_count wrong size on node %pOF count=%d\n",1251		np, count);1252 1253	/*1254	 * Get the "ranges" from the device tree1255	 */1256	for_each_of_range(&parser, &range) {1257		unittest(range.flags == IORESOURCE_MEM,1258			"for_each_of_range wrong flags on node %pOF flags=%x (expected %x)\n",1259			np, range.flags, IORESOURCE_MEM);1260		if (!i) {1261			unittest(range.size == 0x50000000,1262				 "for_each_of_range wrong size on node %pOF size=%llx\n",1263				 np, range.size);1264			unittest(range.cpu_addr == 0x70000000,1265				 "for_each_of_range wrong CPU addr (%llx) on node %pOF",1266				 range.cpu_addr, np);1267			unittest(range.bus_addr == 0x70000000,1268				 "for_each_of_range wrong bus addr (%llx) on node %pOF",1269				 range.pci_addr, np);1270		} else {1271			unittest(range.size == 0x20000000,1272				 "for_each_of_range wrong size on node %pOF size=%llx\n",1273				 np, range.size);1274			unittest(range.cpu_addr == 0xd0000000,1275				 "for_each_of_range wrong CPU addr (%llx) on node %pOF",1276				 range.cpu_addr, np);1277			unittest(range.bus_addr == 0x00000000,1278				 "for_each_of_range wrong bus addr (%llx) on node %pOF",1279				 range.pci_addr, np);1280		}1281		i++;1282	}1283 1284	of_node_put(np);1285}1286 1287static void __init of_unittest_bus_3cell_ranges(void)1288{1289	struct device_node *np;1290	struct of_range range;1291	struct of_range_parser parser;1292	int i = 0;1293 1294	np = of_find_node_by_path("/testcase-data/address-tests/bus@a0000000");1295	if (!np) {1296		pr_err("missing testcase data\n");1297		return;1298	}1299 1300	if (of_range_parser_init(&parser, np)) {1301		pr_err("missing ranges property\n");1302		return;1303	}1304 1305	/*1306	 * Get the "ranges" from the device tree1307	 */1308	for_each_of_range(&parser, &range) {1309		if (!i) {1310			unittest(range.flags == 0xf00baa,1311				 "for_each_of_range wrong flags on node %pOF flags=%x\n",1312				 np, range.flags);1313			unittest(range.size == 0x100000,1314				 "for_each_of_range wrong size on node %pOF size=%llx\n",1315				 np, range.size);1316			unittest(range.cpu_addr == 0xa0000000,1317				 "for_each_of_range wrong CPU addr (%llx) on node %pOF",1318				 range.cpu_addr, np);1319			unittest(range.bus_addr == 0x0,1320				 "for_each_of_range wrong bus addr (%llx) on node %pOF",1321				 range.pci_addr, np);1322		} else {1323			unittest(range.flags == 0xf00bee,1324				 "for_each_of_range wrong flags on node %pOF flags=%x\n",1325				 np, range.flags);1326			unittest(range.size == 0x200000,1327				 "for_each_of_range wrong size on node %pOF size=%llx\n",1328				 np, range.size);1329			unittest(range.cpu_addr == 0xb0000000,1330				 "for_each_of_range wrong CPU addr (%llx) on node %pOF",1331				 range.cpu_addr, np);1332			unittest(range.bus_addr == 0x100000000,1333				 "for_each_of_range wrong bus addr (%llx) on node %pOF",1334				 range.pci_addr, np);1335		}1336		i++;1337	}1338 1339	of_node_put(np);1340}1341 1342static void __init of_unittest_reg(void)1343{1344	struct device_node *np;1345	int ret;1346	u64 addr, size;1347 1348	np = of_find_node_by_path("/testcase-data/address-tests/bus@80000000/device@1000");1349	if (!np) {1350		pr_err("missing testcase data\n");1351		return;1352	}1353 1354	ret = of_property_read_reg(np, 0, &addr, &size);1355	unittest(!ret, "of_property_read_reg(%pOF) returned error %d\n",1356		np, ret);1357	unittest(addr == 0x1000, "of_property_read_reg(%pOF) untranslated address (%llx) incorrect\n",1358		np, addr);1359 1360	of_node_put(np);1361}1362 1363struct of_unittest_expected_res {1364	int index;1365	struct resource res;1366};1367 1368static void __init of_unittest_check_addr(const char *node_path,1369					  const struct of_unittest_expected_res *tab_exp,1370					  unsigned int tab_exp_count)1371{1372	const struct of_unittest_expected_res *expected;1373	struct device_node *np;1374	struct resource res;1375	unsigned int count;1376	int ret;1377 1378	if (!IS_ENABLED(CONFIG_OF_ADDRESS))1379		return;1380 1381	np = of_find_node_by_path(node_path);1382	if (!np) {1383		pr_err("missing testcase data (%s)\n", node_path);1384		return;1385	}1386 1387	expected = tab_exp;1388	count = tab_exp_count;1389	while (count--) {1390		ret = of_address_to_resource(np, expected->index, &res);1391		unittest(!ret, "of_address_to_resource(%pOF, %d) returned error %d\n",1392			 np, expected->index, ret);1393		unittest(resource_type(&res) == resource_type(&expected->res) &&1394			 res.start == expected->res.start &&1395			 resource_size(&res) == resource_size(&expected->res),1396			"of_address_to_resource(%pOF, %d) wrong resource %pR, expected %pR\n",1397			np, expected->index, &res, &expected->res);1398		expected++;1399	}1400 1401	of_node_put(np);1402}1403 1404static const struct of_unittest_expected_res of_unittest_reg_2cell_expected_res[] = {1405	{.index = 0, .res = DEFINE_RES_MEM(0xa0a01000, 0x100) },1406	{.index = 1, .res = DEFINE_RES_MEM(0xa0a02000, 0x100) },1407	{.index = 2, .res = DEFINE_RES_MEM(0xc0c01000, 0x100) },1408	{.index = 3, .res = DEFINE_RES_MEM(0xd0d01000, 0x100) },1409};1410 1411static const struct of_unittest_expected_res of_unittest_reg_3cell_expected_res[] = {1412	{.index = 0, .res = DEFINE_RES_MEM(0xa0a01000, 0x100) },1413	{.index = 1, .res = DEFINE_RES_MEM(0xa0b02000, 0x100) },1414	{.index = 2, .res = DEFINE_RES_MEM(0xc0c01000, 0x100) },1415	{.index = 3, .res = DEFINE_RES_MEM(0xc0c09000, 0x100) },1416	{.index = 4, .res = DEFINE_RES_MEM(0xd0d01000, 0x100) },1417};1418 1419static const struct of_unittest_expected_res of_unittest_reg_pci_expected_res[] = {1420	{.index = 0, .res = DEFINE_RES_MEM(0xe8001000, 0x1000) },1421	{.index = 1, .res = DEFINE_RES_MEM(0xea002000, 0x2000) },1422};1423 1424static void __init of_unittest_translate_addr(void)1425{1426	of_unittest_check_addr("/testcase-data/address-tests2/bus-2cell@10000000/device@100000",1427			       of_unittest_reg_2cell_expected_res,1428			       ARRAY_SIZE(of_unittest_reg_2cell_expected_res));1429 1430	of_unittest_check_addr("/testcase-data/address-tests2/bus-3cell@20000000/local-bus@100000/device@f1001000",1431			       of_unittest_reg_3cell_expected_res,1432			       ARRAY_SIZE(of_unittest_reg_3cell_expected_res));1433 1434	of_unittest_check_addr("/testcase-data/address-tests2/pcie@d1070000/pci@0,0/dev@0,0/local-bus@0/dev@e0000000",1435			       of_unittest_reg_pci_expected_res,1436			       ARRAY_SIZE(of_unittest_reg_pci_expected_res));1437}1438 1439static void __init of_unittest_parse_interrupts(void)1440{1441	struct device_node *np;1442	struct of_phandle_args args;1443	int i, rc;1444 1445	if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)1446		return;1447 1448	np = of_find_node_by_path("/testcase-data/interrupts/interrupts0");1449	if (!np) {1450		pr_err("missing testcase data\n");1451		return;1452	}1453 1454	for (i = 0; i < 4; i++) {1455		bool passed = true;1456 1457		memset(&args, 0, sizeof(args));1458		rc = of_irq_parse_one(np, i, &args);1459 1460		passed &= !rc;1461		passed &= (args.args_count == 1);1462		passed &= (args.args[0] == (i + 1));1463 1464		unittest(passed, "index %i - data error on node %pOF rc=%i\n",1465			 i, args.np, rc);1466	}1467	of_node_put(np);1468 1469	np = of_find_node_by_path("/testcase-data/interrupts/interrupts1");1470	if (!np) {1471		pr_err("missing testcase data\n");1472		return;1473	}1474 1475	for (i = 0; i < 4; i++) {1476		bool passed = true;1477 1478		memset(&args, 0, sizeof(args));1479		rc = of_irq_parse_one(np, i, &args);1480 1481		/* Test the values from tests-phandle.dtsi */1482		switch (i) {1483		case 0:1484			passed &= !rc;1485			passed &= (args.args_count == 1);1486			passed &= (args.args[0] == 9);1487			break;1488		case 1:1489			passed &= !rc;1490			passed &= (args.args_count == 3);1491			passed &= (args.args[0] == 10);1492			passed &= (args.args[1] == 11);1493			passed &= (args.args[2] == 12);1494			break;1495		case 2:1496			passed &= !rc;1497			passed &= (args.args_count == 2);1498			passed &= (args.args[0] == 13);1499			passed &= (args.args[1] == 14);1500			break;1501		case 3:1502			passed &= !rc;1503			passed &= (args.args_count == 2);1504			passed &= (args.args[0] == 15);1505			passed &= (args.args[1] == 16);1506			break;1507		default:1508			passed = false;1509		}1510		unittest(passed, "index %i - data error on node %pOF rc=%i\n",1511			 i, args.np, rc);1512	}1513	of_node_put(np);1514}1515 1516static void __init of_unittest_parse_interrupts_extended(void)1517{1518	struct device_node *np;1519	struct of_phandle_args args;1520	int i, rc;1521 1522	if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)1523		return;1524 1525	np = of_find_node_by_path("/testcase-data/interrupts/interrupts-extended0");1526	if (!np) {1527		pr_err("missing testcase data\n");1528		return;1529	}1530 1531	for (i = 0; i < 7; i++) {1532		bool passed = true;1533 1534		memset(&args, 0, sizeof(args));1535		rc = of_irq_parse_one(np, i, &args);1536 1537		/* Test the values from tests-phandle.dtsi */1538		switch (i) {1539		case 0:1540			passed &= !rc;1541			passed &= (args.args_count == 1);1542			passed &= (args.args[0] == 1);1543			break;1544		case 1:1545			passed &= !rc;1546			passed &= (args.args_count == 3);1547			passed &= (args.args[0] == 2);1548			passed &= (args.args[1] == 3);1549			passed &= (args.args[2] == 4);1550			break;1551		case 2:1552			passed &= !rc;1553			passed &= (args.args_count == 2);1554			passed &= (args.args[0] == 5);1555			passed &= (args.args[1] == 6);1556			break;1557		case 3:1558			passed &= !rc;1559			passed &= (args.args_count == 1);1560			passed &= (args.args[0] == 9);1561			break;1562		case 4:1563			passed &= !rc;1564			passed &= (args.args_count == 3);1565			passed &= (args.args[0] == 10);1566			passed &= (args.args[1] == 11);1567			passed &= (args.args[2] == 12);1568			break;1569		case 5:1570			passed &= !rc;1571			passed &= (args.args_count == 2);1572			passed &= (args.args[0] == 13);1573			passed &= (args.args[1] == 14);1574			break;1575		case 6:1576			/*1577			 * Tests child node that is missing property1578			 * #address-cells.  See the comments in1579			 * drivers/of/unittest-data/tests-interrupts.dtsi1580			 * nodes intmap1 and interrupts-extended01581			 */1582			passed &= !rc;1583			passed &= (args.args_count == 1);1584			passed &= (args.args[0] == 15);1585			break;1586		default:1587			passed = false;1588		}1589 1590		unittest(passed, "index %i - data error on node %pOF rc=%i\n",1591			 i, args.np, rc);1592	}1593	of_node_put(np);1594}1595 1596static const struct of_device_id match_node_table[] = {1597	{ .data = "A", .name = "name0", }, /* Name alone is lowest priority */1598	{ .data = "B", .type = "type1", }, /* followed by type alone */1599 1600	{ .data = "Ca", .name = "name2", .type = "type1", }, /* followed by both together */1601	{ .data = "Cb", .name = "name2", }, /* Only match when type doesn't match */1602	{ .data = "Cc", .name = "name2", .type = "type2", },1603 1604	{ .data = "E", .compatible = "compat3" },1605	{ .data = "G", .compatible = "compat2", },1606	{ .data = "H", .compatible = "compat2", .name = "name5", },1607	{ .data = "I", .compatible = "compat2", .type = "type1", },1608	{ .data = "J", .compatible = "compat2", .type = "type1", .name = "name8", },1609	{ .data = "K", .compatible = "compat2", .name = "name9", },1610	{}1611};1612 1613static struct {1614	const char *path;1615	const char *data;1616} match_node_tests[] = {1617	{ .path = "/testcase-data/match-node/name0", .data = "A", },1618	{ .path = "/testcase-data/match-node/name1", .data = "B", },1619	{ .path = "/testcase-data/match-node/a/name2", .data = "Ca", },1620	{ .path = "/testcase-data/match-node/b/name2", .data = "Cb", },1621	{ .path = "/testcase-data/match-node/c/name2", .data = "Cc", },1622	{ .path = "/testcase-data/match-node/name3", .data = "E", },1623	{ .path = "/testcase-data/match-node/name4", .data = "G", },1624	{ .path = "/testcase-data/match-node/name5", .data = "H", },1625	{ .path = "/testcase-data/match-node/name6", .data = "G", },1626	{ .path = "/testcase-data/match-node/name7", .data = "I", },1627	{ .path = "/testcase-data/match-node/name8", .data = "J", },1628	{ .path = "/testcase-data/match-node/name9", .data = "K", },1629};1630 1631static void __init of_unittest_match_node(void)1632{1633	struct device_node *np;1634	const struct of_device_id *match;1635	int i;1636 1637	for (i = 0; i < ARRAY_SIZE(match_node_tests); i++) {1638		np = of_find_node_by_path(match_node_tests[i].path);1639		if (!np) {1640			unittest(0, "missing testcase node %s\n",1641				match_node_tests[i].path);1642			continue;1643		}1644 1645		match = of_match_node(match_node_table, np);1646		if (!match) {1647			unittest(0, "%s didn't match anything\n",1648				match_node_tests[i].path);1649			continue;1650		}1651 1652		if (strcmp(match->data, match_node_tests[i].data) != 0) {1653			unittest(0, "%s got wrong match. expected %s, got %s\n",1654				match_node_tests[i].path, match_node_tests[i].data,1655				(const char *)match->data);1656			continue;1657		}1658		unittest(1, "passed");1659	}1660}1661 1662static struct resource test_bus_res = DEFINE_RES_MEM(0xfffffff8, 2);1663static const struct platform_device_info test_bus_info = {1664	.name = "unittest-bus",1665};1666static void __init of_unittest_platform_populate(void)1667{1668	int irq, rc;1669	struct device_node *np, *child, *grandchild;1670	struct platform_device *pdev, *test_bus;1671	const struct of_device_id match[] = {1672		{ .compatible = "test-device", },1673		{}1674	};1675 1676	np = of_find_node_by_path("/testcase-data");1677	of_platform_default_populate(np, NULL, NULL);1678 1679	/* Test that a missing irq domain returns -EPROBE_DEFER */1680	np = of_find_node_by_path("/testcase-data/testcase-device1");1681	pdev = of_find_device_by_node(np);1682	unittest(pdev, "device 1 creation failed\n");1683 1684	if (!(of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)) {1685		irq = platform_get_irq(pdev, 0);1686		unittest(irq == -EPROBE_DEFER,1687			 "device deferred probe failed - %d\n", irq);1688 1689		/* Test that a parsing failure does not return -EPROBE_DEFER */1690		np = of_find_node_by_path("/testcase-data/testcase-device2");1691		pdev = of_find_device_by_node(np);1692		unittest(pdev, "device 2 creation failed\n");1693 1694		EXPECT_BEGIN(KERN_INFO,1695			     "platform testcase-data:testcase-device2: error -ENXIO: IRQ index 0 not found");1696 1697		irq = platform_get_irq(pdev, 0);1698 1699		EXPECT_END(KERN_INFO,1700			   "platform testcase-data:testcase-device2: error -ENXIO: IRQ index 0 not found");1701 1702		unittest(irq < 0 && irq != -EPROBE_DEFER,1703			 "device parsing error failed - %d\n", irq);1704	}1705 1706	np = of_find_node_by_path("/testcase-data/platform-tests");1707	unittest(np, "No testcase data in device tree\n");1708	if (!np)1709		return;1710 1711	test_bus = platform_device_register_full(&test_bus_info);1712	rc = PTR_ERR_OR_ZERO(test_bus);1713	unittest(!rc, "testbus registration failed; rc=%i\n", rc);1714	if (rc) {1715		of_node_put(np);1716		return;1717	}1718	test_bus->dev.of_node = np;1719 1720	/*1721	 * Add a dummy resource to the test bus node after it is1722	 * registered to catch problems with un-inserted resources. The1723	 * DT code doesn't insert the resources, and it has caused the1724	 * kernel to oops in the past. This makes sure the same bug1725	 * doesn't crop up again.1726	 */1727	platform_device_add_resources(test_bus, &test_bus_res, 1);1728 1729	of_platform_populate(np, match, NULL, &test_bus->dev);1730	for_each_child_of_node(np, child) {1731		for_each_child_of_node(child, grandchild) {1732			pdev = of_find_device_by_node(grandchild);1733			unittest(pdev,1734				 "Could not create device for node '%pOFn'\n",1735				 grandchild);1736			platform_device_put(pdev);1737		}1738	}1739 1740	of_platform_depopulate(&test_bus->dev);1741	for_each_child_of_node(np, child) {1742		for_each_child_of_node(child, grandchild)1743			unittest(!of_find_device_by_node(grandchild),1744				 "device didn't get destroyed '%pOFn'\n",1745				 grandchild);1746	}1747 1748	platform_device_unregister(test_bus);1749	of_node_put(np);1750}1751 1752/**1753 *	update_node_properties - adds the properties1754 *	of np into dup node (present in live tree) and1755 *	updates parent of children of np to dup.1756 *1757 *	@np:	node whose properties are being added to the live tree1758 *	@dup:	node present in live tree to be updated1759 */1760static void update_node_properties(struct device_node *np,1761					struct device_node *dup)1762{1763	struct property *prop;1764	struct property *save_next;1765	struct device_node *child;1766	int ret;1767 1768	for_each_child_of_node(np, child)1769		child->parent = dup;1770 1771	/*1772	 * "unittest internal error: unable to add testdata property"1773	 *1774	 *    If this message reports a property in node '/__symbols__' then1775	 *    the respective unittest overlay contains a label that has the1776	 *    same name as a label in the live devicetree.  The label will1777	 *    be in the live devicetree only if the devicetree source was1778	 *    compiled with the '-@' option.  If you encounter this error,1779	 *    please consider renaming __all__ of the labels in the unittest1780	 *    overlay dts files with an odd prefix that is unlikely to be1781	 *    used in a real devicetree.1782	 */1783 1784	/*1785	 * open code for_each_property_of_node() because of_add_property()1786	 * sets prop->next to NULL1787	 */1788	for (prop = np->properties; prop != NULL; prop = save_next) {1789		save_next = prop->next;1790		ret = of_add_property(dup, prop);1791		if (ret) {1792			if (ret == -EEXIST && !strcmp(prop->name, "name"))1793				continue;1794			pr_err("unittest internal error: unable to add testdata property %pOF/%s",1795			       np, prop->name);1796		}1797	}1798}1799 1800/**1801 *	attach_node_and_children - attaches nodes1802 *	and its children to live tree.1803 *	CAUTION: misleading function name - if node @np already exists in1804 *	the live tree then children of @np are *not* attached to the live1805 *	tree.  This works for the current test devicetree nodes because such1806 *	nodes do not have child nodes.1807 *1808 *	@np:	Node to attach to live tree1809 */1810static void attach_node_and_children(struct device_node *np)1811{1812	struct device_node *next, *dup, *child;1813	unsigned long flags;1814	const char *full_name;1815 1816	full_name = kasprintf(GFP_KERNEL, "%pOF", np);1817	if (!full_name)1818		return;1819 1820	if (!strcmp(full_name, "/__local_fixups__") ||1821	    !strcmp(full_name, "/__fixups__")) {1822		kfree(full_name);1823		return;1824	}1825 1826	dup = of_find_node_by_path(full_name);1827	kfree(full_name);1828	if (dup) {1829		update_node_properties(np, dup);1830		return;1831	}1832 1833	child = np->child;1834	np->child = NULL;1835 1836	mutex_lock(&of_mutex);1837	raw_spin_lock_irqsave(&devtree_lock, flags);1838	np->sibling = np->parent->child;1839	np->parent->child = np;1840	of_node_clear_flag(np, OF_DETACHED);1841	raw_spin_unlock_irqrestore(&devtree_lock, flags);1842 1843	__of_attach_node_sysfs(np);1844	mutex_unlock(&of_mutex);1845 1846	while (child) {1847		next = child->sibling;1848		attach_node_and_children(child);1849		child = next;1850	}1851}1852 1853/**1854 *	unittest_data_add - Reads, copies data from1855 *	linked tree and attaches it to the live tree1856 */1857static int __init unittest_data_add(void)1858{1859	void *unittest_data;1860	void *unittest_data_align;1861	struct device_node *unittest_data_node = NULL, *np;1862	/*1863	 * __dtbo_testcases_begin[] and __dtbo_testcases_end[] are magically1864	 * created by cmd_wrap_S_dtbo in scripts/Makefile.dtbs1865	 */1866	extern uint8_t __dtbo_testcases_begin[];1867	extern uint8_t __dtbo_testcases_end[];1868	const int size = __dtbo_testcases_end - __dtbo_testcases_begin;1869	int rc;1870	void *ret;1871 1872	if (!size) {1873		pr_warn("%s: testcases is empty\n", __func__);1874		return -ENODATA;1875	}1876 1877	/* creating copy */1878	unittest_data = kmalloc(size + FDT_ALIGN_SIZE, GFP_KERNEL);1879	if (!unittest_data)1880		return -ENOMEM;1881 1882	unittest_data_align = PTR_ALIGN(unittest_data, FDT_ALIGN_SIZE);1883	memcpy(unittest_data_align, __dtbo_testcases_begin, size);1884 1885	ret = of_fdt_unflatten_tree(unittest_data_align, NULL, &unittest_data_node);1886	if (!ret) {1887		pr_warn("%s: unflatten testcases tree failed\n", __func__);1888		kfree(unittest_data);1889		return -ENODATA;1890	}1891	if (!unittest_data_node) {1892		pr_warn("%s: testcases tree is empty\n", __func__);1893		kfree(unittest_data);1894		return -ENODATA;1895	}1896 1897	/*1898	 * This lock normally encloses of_resolve_phandles()1899	 */1900	of_overlay_mutex_lock();1901 1902	rc = of_resolve_phandles(unittest_data_node);1903	if (rc) {1904		pr_err("%s: Failed to resolve phandles (rc=%i)\n", __func__, rc);1905		of_overlay_mutex_unlock();1906		return -EINVAL;1907	}1908 1909	/* attach the sub-tree to live tree */1910	if (!of_root) {1911		pr_warn("%s: no live tree to attach sub-tree\n", __func__);1912		kfree(unittest_data);1913		return -ENODEV;1914	}1915 1916	EXPECT_BEGIN(KERN_INFO,1917		     "Duplicate name in testcase-data, renamed to \"duplicate-name#1\"");1918 1919	np = unittest_data_node->child;1920	while (np) {1921		struct device_node *next = np->sibling;1922 1923		np->parent = of_root;1924		/* this will clear OF_DETACHED in np and children */1925		attach_node_and_children(np);1926		np = next;1927	}1928 1929	EXPECT_END(KERN_INFO,1930		   "Duplicate name in testcase-data, renamed to \"duplicate-name#1\"");1931 1932	of_overlay_mutex_unlock();1933 1934	return 0;1935}1936 1937#ifdef CONFIG_OF_OVERLAY1938static int __init overlay_data_apply(const char *overlay_name, int *ovcs_id);1939 1940static int unittest_probe(struct platform_device *pdev)1941{1942	struct device *dev = &pdev->dev;1943	struct device_node *np = dev->of_node;1944 1945	if (np == NULL) {1946		dev_err(dev, "No OF data for device\n");1947		return -EINVAL;1948 1949	}1950 1951	dev_dbg(dev, "%s for node @%pOF\n", __func__, np);1952 1953	of_platform_populate(np, NULL, NULL, &pdev->dev);1954 1955	return 0;1956}1957 1958static void unittest_remove(struct platform_device *pdev)1959{1960	struct device *dev = &pdev->dev;1961	struct device_node *np = dev->of_node;1962 1963	dev_dbg(dev, "%s for node @%pOF\n", __func__, np);1964}1965 1966static const struct of_device_id unittest_match[] = {1967	{ .compatible = "unittest", },1968	{},1969};1970 1971static struct platform_driver unittest_driver = {1972	.probe			= unittest_probe,1973	.remove_new		= unittest_remove,1974	.driver = {1975		.name		= "unittest",1976		.of_match_table	= unittest_match,1977	},1978};1979 1980/* get the platform device instantiated at the path */1981static struct platform_device *of_path_to_platform_device(const char *path)1982{1983	struct device_node *np;1984	struct platform_device *pdev;1985 1986	np = of_find_node_by_path(path);1987	if (np == NULL)1988		return NULL;1989 1990	pdev = of_find_device_by_node(np);1991	of_node_put(np);1992 1993	return pdev;1994}1995 1996/* find out if a platform device exists at that path */1997static int of_path_platform_device_exists(const char *path)1998{1999	struct platform_device *pdev;2000 2001	pdev = of_path_to_platform_device(path);2002	platform_device_put(pdev);2003	return pdev != NULL;2004}2005 2006#ifdef CONFIG_OF_GPIO2007 2008struct unittest_gpio_dev {2009	struct gpio_chip chip;2010};2011 2012static int unittest_gpio_chip_request_count;2013static int unittest_gpio_probe_count;2014static int unittest_gpio_probe_pass_count;2015 2016static int unittest_gpio_chip_request(struct gpio_chip *chip, unsigned int offset)2017{2018	unittest_gpio_chip_request_count++;2019 2020	pr_debug("%s(): %s %d %d\n", __func__, chip->label, offset,2021		 unittest_gpio_chip_request_count);2022	return 0;2023}2024 2025static int unittest_gpio_probe(struct platform_device *pdev)2026{2027	struct unittest_gpio_dev *devptr;2028	int ret;2029 2030	unittest_gpio_probe_count++;2031 2032	devptr = kzalloc(sizeof(*devptr), GFP_KERNEL);2033	if (!devptr)2034		return -ENOMEM;2035 2036	platform_set_drvdata(pdev, devptr);2037 2038	devptr->chip.fwnode = dev_fwnode(&pdev->dev);2039	devptr->chip.label = "of-unittest-gpio";2040	devptr->chip.base = -1; /* dynamic allocation */2041	devptr->chip.ngpio = 5;2042	devptr->chip.request = unittest_gpio_chip_request;2043 2044	ret = gpiochip_add_data(&devptr->chip, NULL);2045 2046	unittest(!ret,2047		 "gpiochip_add_data() for node @%pfw failed, ret = %d\n", devptr->chip.fwnode, ret);2048 2049	if (!ret)2050		unittest_gpio_probe_pass_count++;2051	return ret;2052}2053 2054static void unittest_gpio_remove(struct platform_device *pdev)2055{2056	struct unittest_gpio_dev *devptr = platform_get_drvdata(pdev);2057	struct device *dev = &pdev->dev;2058 2059	dev_dbg(dev, "%s for node @%pfw\n", __func__, devptr->chip.fwnode);2060 2061	if (devptr->chip.base != -1)2062		gpiochip_remove(&devptr->chip);2063 2064	kfree(devptr);2065}2066 2067static const struct of_device_id unittest_gpio_id[] = {2068	{ .compatible = "unittest-gpio", },2069	{}2070};2071 2072static struct platform_driver unittest_gpio_driver = {2073	.probe	= unittest_gpio_probe,2074	.remove_new = unittest_gpio_remove,2075	.driver	= {2076		.name		= "unittest-gpio",2077		.of_match_table	= unittest_gpio_id,2078	},2079};2080 2081static void __init of_unittest_overlay_gpio(void)2082{2083	int chip_request_count;2084	int probe_pass_count;2085	int ret;2086 2087	/*2088	 * tests: apply overlays before registering driver2089	 * Similar to installing a driver as a module, the2090	 * driver is registered after applying the overlays.2091	 *2092	 * The overlays are applied by overlay_data_apply()2093	 * instead of of_unittest_apply_overlay() so that they2094	 * will not be tracked.  Thus they will not be removed2095	 * by of_unittest_remove_tracked_overlays().2096	 *2097	 * - apply overlay_gpio_012098	 * - apply overlay_gpio_02a2099	 * - apply overlay_gpio_02b2100	 * - register driver2101	 *2102	 * register driver will result in2103	 *   - probe and processing gpio hog for overlay_gpio_012104	 *   - probe for overlay_gpio_02a2105	 *   - processing gpio for overlay_gpio_02b2106	 */2107 2108	probe_pass_count = unittest_gpio_probe_pass_count;2109	chip_request_count = unittest_gpio_chip_request_count;2110 2111	/*2112	 * overlay_gpio_01 contains gpio node and child gpio hog node2113	 * overlay_gpio_02a contains gpio node2114	 * overlay_gpio_02b contains child gpio hog node2115	 */2116 2117	unittest(overlay_data_apply("overlay_gpio_01", NULL),2118		 "Adding overlay 'overlay_gpio_01' failed\n");2119 2120	unittest(overlay_data_apply("overlay_gpio_02a", NULL),2121		 "Adding overlay 'overlay_gpio_02a' failed\n");2122 2123	unittest(overlay_data_apply("overlay_gpio_02b", NULL),2124		 "Adding overlay 'overlay_gpio_02b' failed\n");2125 2126	ret = platform_driver_register(&unittest_gpio_driver);2127	if (unittest(ret == 0, "could not register unittest gpio driver\n"))2128		return;2129 2130	unittest(probe_pass_count + 2 == unittest_gpio_probe_pass_count,2131		 "unittest_gpio_probe() failed or not called\n");2132 2133	unittest(chip_request_count + 2 == unittest_gpio_chip_request_count,2134		 "unittest_gpio_chip_request() called %d times (expected 1 time)\n",2135		 unittest_gpio_chip_request_count - chip_request_count);2136 2137	/*2138	 * tests: apply overlays after registering driver2139	 *2140	 * Similar to a driver built-in to the kernel, the2141	 * driver is registered before applying the overlays.2142	 *2143	 * overlay_gpio_03 contains gpio node and child gpio hog node2144	 *2145	 * - apply overlay_gpio_032146	 *2147	 * apply overlay will result in2148	 *   - probe and processing gpio hog.2149	 */2150 2151	probe_pass_count = unittest_gpio_probe_pass_count;2152	chip_request_count = unittest_gpio_chip_request_count;2153 2154	/* overlay_gpio_03 contains gpio node and child gpio hog node */2155 2156	unittest(overlay_data_apply("overlay_gpio_03", NULL),2157		 "Adding overlay 'overlay_gpio_03' failed\n");2158 2159	unittest(probe_pass_count + 1 == unittest_gpio_probe_pass_count,2160		 "unittest_gpio_probe() failed or not called\n");2161 2162	unittest(chip_request_count + 1 == unittest_gpio_chip_request_count,2163		 "unittest_gpio_chip_request() called %d times (expected 1 time)\n",2164		 unittest_gpio_chip_request_count - chip_request_count);2165 2166	/*2167	 * overlay_gpio_04a contains gpio node2168	 *2169	 * - apply overlay_gpio_04a2170	 *2171	 * apply the overlay will result in2172	 *   - probe for overlay_gpio_04a2173	 */2174 2175	probe_pass_count = unittest_gpio_probe_pass_count;2176	chip_request_count = unittest_gpio_chip_request_count;2177 2178	/* overlay_gpio_04a contains gpio node */2179 2180	unittest(overlay_data_apply("overlay_gpio_04a", NULL),2181		 "Adding overlay 'overlay_gpio_04a' failed\n");2182 2183	unittest(probe_pass_count + 1 == unittest_gpio_probe_pass_count,2184		 "unittest_gpio_probe() failed or not called\n");2185 2186	/*2187	 * overlay_gpio_04b contains child gpio hog node2188	 *2189	 * - apply overlay_gpio_04b2190	 *2191	 * apply the overlay will result in2192	 *   - processing gpio for overlay_gpio_04b2193	 */2194 2195	/* overlay_gpio_04b contains child gpio hog node */2196 2197	unittest(overlay_data_apply("overlay_gpio_04b", NULL),2198		 "Adding overlay 'overlay_gpio_04b' failed\n");2199 2200	unittest(chip_request_count + 1 == unittest_gpio_chip_request_count,2201		 "unittest_gpio_chip_request() called %d times (expected 1 time)\n",2202		 unittest_gpio_chip_request_count - chip_request_count);2203}2204 2205#else2206 2207static void __init of_unittest_overlay_gpio(void)2208{2209	/* skip tests */2210}2211 2212#endif2213 2214#if IS_BUILTIN(CONFIG_I2C)2215 2216/* get the i2c client device instantiated at the path */2217static struct i2c_client *of_path_to_i2c_client(const char *path)2218{2219	struct device_node *np;2220	struct i2c_client *client;2221 2222	np = of_find_node_by_path(path);2223	if (np == NULL)2224		return NULL;2225 2226	client = of_find_i2c_device_by_node(np);2227	of_node_put(np);2228 2229	return client;2230}2231 2232/* find out if a i2c client device exists at that path */2233static int of_path_i2c_client_exists(const char *path)2234{2235	struct i2c_client *client;2236 2237	client = of_path_to_i2c_client(path);2238	if (client)2239		put_device(&client->dev);2240	return client != NULL;2241}2242#else2243static int of_path_i2c_client_exists(const char *path)2244{2245	return 0;2246}2247#endif2248 2249enum overlay_type {2250	PDEV_OVERLAY,2251	I2C_OVERLAY2252};2253 2254static int of_path_device_type_exists(const char *path,2255		enum overlay_type ovtype)2256{2257	switch (ovtype) {2258	case PDEV_OVERLAY:2259		return of_path_platform_device_exists(path);2260	case I2C_OVERLAY:2261		return of_path_i2c_client_exists(path);2262	}2263	return 0;2264}2265 2266static const char *unittest_path(int nr, enum overlay_type ovtype)2267{2268	const char *base;2269	static char buf[256];2270 2271	switch (ovtype) {2272	case PDEV_OVERLAY:2273		base = "/testcase-data/overlay-node/test-bus";2274		break;2275	case I2C_OVERLAY:2276		base = "/testcase-data/overlay-node/test-bus/i2c-test-bus";2277		break;2278	default:2279		buf[0] = '\0';2280		return buf;2281	}2282	snprintf(buf, sizeof(buf) - 1, "%s/test-unittest%d", base, nr);2283	buf[sizeof(buf) - 1] = '\0';2284	return buf;2285}2286 2287static int of_unittest_device_exists(int unittest_nr, enum overlay_type ovtype)2288{2289	const char *path;2290 2291	path = unittest_path(unittest_nr, ovtype);2292 2293	switch (ovtype) {2294	case PDEV_OVERLAY:2295		return of_path_platform_device_exists(path);2296	case I2C_OVERLAY:2297		return of_path_i2c_client_exists(path);2298	}2299	return 0;2300}2301 2302static const char *overlay_name_from_nr(int nr)2303{2304	static char buf[256];2305 2306	snprintf(buf, sizeof(buf) - 1,2307		"overlay_%d", nr);2308	buf[sizeof(buf) - 1] = '\0';2309 2310	return buf;2311}2312 2313static const char *bus_path = "/testcase-data/overlay-node/test-bus";2314 2315#define MAX_TRACK_OVCS_IDS 2562316 2317static int track_ovcs_id[MAX_TRACK_OVCS_IDS];2318static int track_ovcs_id_overlay_nr[MAX_TRACK_OVCS_IDS];2319static int track_ovcs_id_cnt;2320 2321static void of_unittest_track_overlay(int ovcs_id, int overlay_nr)2322{2323	if (WARN_ON(track_ovcs_id_cnt >= MAX_TRACK_OVCS_IDS))2324		return;2325 2326	track_ovcs_id[track_ovcs_id_cnt] = ovcs_id;2327	track_ovcs_id_overlay_nr[track_ovcs_id_cnt] = overlay_nr;2328	track_ovcs_id_cnt++;2329}2330 2331static void of_unittest_untrack_overlay(int ovcs_id)2332{2333	if (WARN_ON(track_ovcs_id_cnt < 1))2334		return;2335 2336	track_ovcs_id_cnt--;2337 2338	/* If out of synch then test is broken.  Do not try to recover. */2339	WARN_ON(track_ovcs_id[track_ovcs_id_cnt] != ovcs_id);2340}2341 2342static void of_unittest_remove_tracked_overlays(void)2343{2344	int ret, ovcs_id, overlay_nr, save_ovcs_id;2345	const char *overlay_name;2346 2347	while (track_ovcs_id_cnt > 0) {2348 2349		ovcs_id = track_ovcs_id[track_ovcs_id_cnt - 1];2350		overlay_nr = track_ovcs_id_overlay_nr[track_ovcs_id_cnt - 1];2351		save_ovcs_id = ovcs_id;2352		ret = of_overlay_remove(&ovcs_id);2353		if (ret == -ENODEV) {2354			overlay_name = overlay_name_from_nr(overlay_nr);2355			pr_warn("%s: of_overlay_remove() for overlay \"%s\" failed, ret = %d\n",2356				__func__, overlay_name, ret);2357		}2358		of_unittest_untrack_overlay(save_ovcs_id);2359	}2360 2361}2362 2363static int __init of_unittest_apply_overlay(int overlay_nr, int *ovcs_id)2364{2365	/*2366	 * The overlay will be tracked, thus it will be removed2367	 * by of_unittest_remove_tracked_overlays().2368	 */2369 2370	const char *overlay_name;2371 2372	overlay_name = overlay_name_from_nr(overlay_nr);2373 2374	if (!overlay_data_apply(overlay_name, ovcs_id)) {2375		unittest(0, "could not apply overlay \"%s\"\n", overlay_name);2376		return -EFAULT;2377	}2378	of_unittest_track_overlay(*ovcs_id, overlay_nr);2379 2380	return 0;2381}2382 2383static int __init __of_unittest_apply_overlay_check(int overlay_nr,2384		int unittest_nr, int before, int after,2385		enum overlay_type ovtype)2386{2387	int ret, ovcs_id;2388 2389	/* unittest device must be in before state */2390	if (of_unittest_device_exists(unittest_nr, ovtype) != before) {2391		unittest(0, "%s with device @\"%s\" %s\n",2392				overlay_name_from_nr(overlay_nr),2393				unittest_path(unittest_nr, ovtype),2394				!before ? "enabled" : "disabled");2395		return -EINVAL;2396	}2397 2398	/* apply the overlay */2399	ovcs_id = 0;2400	ret = of_unittest_apply_overlay(overlay_nr, &ovcs_id);2401	if (ret != 0) {2402		/* of_unittest_apply_overlay already called unittest() */2403		return ret;2404	}2405 2406	/* unittest device must be in after state */2407	if (of_unittest_device_exists(unittest_nr, ovtype) != after) {2408		unittest(0, "%s with device @\"%s\" %s\n",2409				overlay_name_from_nr(overlay_nr),2410				unittest_path(unittest_nr, ovtype),2411				!after ? "enabled" : "disabled");2412		return -EINVAL;2413	}2414 2415	return ovcs_id;2416}2417 2418/* apply an overlay while checking before and after states */2419static int __init of_unittest_apply_overlay_check(int overlay_nr,2420		int unittest_nr, int before, int after,2421		enum overlay_type ovtype)2422{2423	int ovcs_id = __of_unittest_apply_overlay_check(overlay_nr,2424				unittest_nr, before, after, ovtype);2425	if (ovcs_id < 0)2426		return ovcs_id;2427 2428	return 0;2429}2430 2431/* apply an overlay and then revert it while checking before, after states */2432static int __init of_unittest_apply_revert_overlay_check(int overlay_nr,2433		int unittest_nr, int before, int after,2434		enum overlay_type ovtype)2435{2436	int ret, ovcs_id, save_ovcs_id;2437 2438	ovcs_id = __of_unittest_apply_overlay_check(overlay_nr, unittest_nr,2439						    before, after, ovtype);2440	if (ovcs_id < 0)2441		return ovcs_id;2442 2443	/* remove the overlay */2444	save_ovcs_id = ovcs_id;2445	ret = of_overlay_remove(&ovcs_id);2446	if (ret != 0) {2447		unittest(0, "%s failed to be destroyed @\"%s\"\n",2448				overlay_name_from_nr(overlay_nr),2449				unittest_path(unittest_nr, ovtype));2450		return ret;2451	}2452	of_unittest_untrack_overlay(save_ovcs_id);2453 2454	/* unittest device must be again in before state */2455	if (of_unittest_device_exists(unittest_nr, ovtype) != before) {2456		unittest(0, "%s with device @\"%s\" %s\n",2457				overlay_name_from_nr(overlay_nr),2458				unittest_path(unittest_nr, ovtype),2459				!before ? "enabled" : "disabled");2460		return -EINVAL;2461	}2462 2463	return 0;2464}2465 2466/* test activation of device */2467static void __init of_unittest_overlay_0(void)2468{2469	int ret;2470 2471	EXPECT_BEGIN(KERN_INFO,2472		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest0/status");2473 2474	/* device should enable */2475	ret = of_unittest_apply_overlay_check(0, 0, 0, 1, PDEV_OVERLAY);2476 2477	EXPECT_END(KERN_INFO,2478		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest0/status");2479 2480	if (ret)2481		return;2482 2483	unittest(1, "overlay test %d passed\n", 0);2484}2485 2486/* test deactivation of device */2487static void __init of_unittest_overlay_1(void)2488{2489	int ret;2490 2491	EXPECT_BEGIN(KERN_INFO,2492		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest1/status");2493 2494	/* device should disable */2495	ret = of_unittest_apply_overlay_check(1, 1, 1, 0, PDEV_OVERLAY);2496 2497	EXPECT_END(KERN_INFO,2498		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest1/status");2499 2500	if (ret)2501		return;2502 2503	unittest(1, "overlay test %d passed\n", 1);2504 2505}2506 2507/* test activation of device */2508static void __init of_unittest_overlay_2(void)2509{2510	int ret;2511 2512	EXPECT_BEGIN(KERN_INFO,2513		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest2/status");2514 2515	/* device should enable */2516	ret = of_unittest_apply_overlay_check(2, 2, 0, 1, PDEV_OVERLAY);2517 2518	EXPECT_END(KERN_INFO,2519		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest2/status");2520 2521	if (ret)2522		return;2523	unittest(1, "overlay test %d passed\n", 2);2524}2525 2526/* test deactivation of device */2527static void __init of_unittest_overlay_3(void)2528{2529	int ret;2530 2531	EXPECT_BEGIN(KERN_INFO,2532		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest3/status");2533 2534	/* device should disable */2535	ret = of_unittest_apply_overlay_check(3, 3, 1, 0, PDEV_OVERLAY);2536 2537	EXPECT_END(KERN_INFO,2538		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest3/status");2539 2540	if (ret)2541		return;2542 2543	unittest(1, "overlay test %d passed\n", 3);2544}2545 2546/* test activation of a full device node */2547static void __init of_unittest_overlay_4(void)2548{2549	/* device should disable */2550	if (of_unittest_apply_overlay_check(4, 4, 0, 1, PDEV_OVERLAY))2551		return;2552 2553	unittest(1, "overlay test %d passed\n", 4);2554}2555 2556/* test overlay apply/revert sequence */2557static void __init of_unittest_overlay_5(void)2558{2559	int ret;2560 2561	EXPECT_BEGIN(KERN_INFO,2562		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest5/status");2563 2564	/* device should disable */2565	ret = of_unittest_apply_revert_overlay_check(5, 5, 0, 1, PDEV_OVERLAY);2566 2567	EXPECT_END(KERN_INFO,2568		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest5/status");2569 2570	if (ret)2571		return;2572 2573	unittest(1, "overlay test %d passed\n", 5);2574}2575 2576/* test overlay application in sequence */2577static void __init of_unittest_overlay_6(void)2578{2579	int i, save_ovcs_id[2], ovcs_id;2580	int overlay_nr = 6, unittest_nr = 6;2581	int before = 0, after = 1;2582	const char *overlay_name;2583 2584	int ret;2585 2586	/* unittest device must be in before state */2587	for (i = 0; i < 2; i++) {2588		if (of_unittest_device_exists(unittest_nr + i, PDEV_OVERLAY)2589				!= before) {2590			unittest(0, "%s with device @\"%s\" %s\n",2591					overlay_name_from_nr(overlay_nr + i),2592					unittest_path(unittest_nr + i,2593						PDEV_OVERLAY),2594					!before ? "enabled" : "disabled");2595			return;2596		}2597	}2598 2599	/* apply the overlays */2600 2601	EXPECT_BEGIN(KERN_INFO,2602		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest6/status");2603 2604	overlay_name = overlay_name_from_nr(overlay_nr + 0);2605 2606	ret = overlay_data_apply(overlay_name, &ovcs_id);2607 2608	if (!ret) {2609		unittest(0, "could not apply overlay \"%s\"\n", overlay_name);2610			return;2611	}2612	save_ovcs_id[0] = ovcs_id;2613	of_unittest_track_overlay(ovcs_id, overlay_nr + 0);2614 2615	EXPECT_END(KERN_INFO,2616		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest6/status");2617 2618	EXPECT_BEGIN(KERN_INFO,2619		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest7/status");2620 2621	overlay_name = overlay_name_from_nr(overlay_nr + 1);2622 2623	ret = overlay_data_apply(overlay_name, &ovcs_id);2624 2625	if (!ret) {2626		unittest(0, "could not apply overlay \"%s\"\n", overlay_name);2627			return;2628	}2629	save_ovcs_id[1] = ovcs_id;2630	of_unittest_track_overlay(ovcs_id, overlay_nr + 1);2631 2632	EXPECT_END(KERN_INFO,2633		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest7/status");2634 2635 2636	for (i = 0; i < 2; i++) {2637		/* unittest device must be in after state */2638		if (of_unittest_device_exists(unittest_nr + i, PDEV_OVERLAY)2639				!= after) {2640			unittest(0, "overlay @\"%s\" failed @\"%s\" %s\n",2641					overlay_name_from_nr(overlay_nr + i),2642					unittest_path(unittest_nr + i,2643						PDEV_OVERLAY),2644					!after ? "enabled" : "disabled");2645			return;2646		}2647	}2648 2649	for (i = 1; i >= 0; i--) {2650		ovcs_id = save_ovcs_id[i];2651		if (of_overlay_remove(&ovcs_id)) {2652			unittest(0, "%s failed destroy @\"%s\"\n",2653					overlay_name_from_nr(overlay_nr + i),2654					unittest_path(unittest_nr + i,2655						PDEV_OVERLAY));2656			return;2657		}2658		of_unittest_untrack_overlay(save_ovcs_id[i]);2659	}2660 2661	for (i = 0; i < 2; i++) {2662		/* unittest device must be again in before state */2663		if (of_unittest_device_exists(unittest_nr + i, PDEV_OVERLAY)2664				!= before) {2665			unittest(0, "%s with device @\"%s\" %s\n",2666					overlay_name_from_nr(overlay_nr + i),2667					unittest_path(unittest_nr + i,2668						PDEV_OVERLAY),2669					!before ? "enabled" : "disabled");2670			return;2671		}2672	}2673 2674	unittest(1, "overlay test %d passed\n", 6);2675 2676}2677 2678/* test overlay application in sequence */2679static void __init of_unittest_overlay_8(void)2680{2681	int i, save_ovcs_id[2], ovcs_id;2682	int overlay_nr = 8, unittest_nr = 8;2683	const char *overlay_name;2684	int ret;2685 2686	/* we don't care about device state in this test */2687 2688	EXPECT_BEGIN(KERN_INFO,2689		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest8/status");2690 2691	overlay_name = overlay_name_from_nr(overlay_nr + 0);2692 2693	ret = overlay_data_apply(overlay_name, &ovcs_id);2694	if (!ret)2695		unittest(0, "could not apply overlay \"%s\"\n", overlay_name);2696 2697	EXPECT_END(KERN_INFO,2698		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest8/status");2699 2700	if (!ret)2701		return;2702 2703	save_ovcs_id[0] = ovcs_id;2704	of_unittest_track_overlay(ovcs_id, overlay_nr + 0);2705 2706	overlay_name = overlay_name_from_nr(overlay_nr + 1);2707 2708	EXPECT_BEGIN(KERN_INFO,2709		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest8/property-foo");2710 2711	/* apply the overlays */2712	ret = overlay_data_apply(overlay_name, &ovcs_id);2713 2714	EXPECT_END(KERN_INFO,2715		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest8/property-foo");2716 2717	if (!ret) {2718		unittest(0, "could not apply overlay \"%s\"\n", overlay_name);2719		return;2720	}2721 2722	save_ovcs_id[1] = ovcs_id;2723	of_unittest_track_overlay(ovcs_id, overlay_nr + 1);2724 2725	/* now try to remove first overlay (it should fail) */2726	ovcs_id = save_ovcs_id[0];2727 2728	EXPECT_BEGIN(KERN_INFO,2729		     "OF: overlay: node_overlaps_later_cs: #6 overlaps with #7 @/testcase-data/overlay-node/test-bus/test-unittest8");2730 2731	EXPECT_BEGIN(KERN_INFO,2732		     "OF: overlay: overlay #6 is not topmost");2733 2734	ret = of_overlay_remove(&ovcs_id);2735 2736	EXPECT_END(KERN_INFO,2737		   "OF: overlay: overlay #6 is not topmost");2738 2739	EXPECT_END(KERN_INFO,2740		   "OF: overlay: node_overlaps_later_cs: #6 overlaps with #7 @/testcase-data/overlay-node/test-bus/test-unittest8");2741 2742	if (!ret) {2743		/*2744		 * Should never get here.  If we do, expect a lot of2745		 * subsequent tracking and overlay removal related errors.2746		 */2747		unittest(0, "%s was destroyed @\"%s\"\n",2748				overlay_name_from_nr(overlay_nr + 0),2749				unittest_path(unittest_nr,2750					PDEV_OVERLAY));2751		return;2752	}2753 2754	/* removing them in order should work */2755	for (i = 1; i >= 0; i--) {2756		ovcs_id = save_ovcs_id[i];2757		if (of_overlay_remove(&ovcs_id)) {2758			unittest(0, "%s not destroyed @\"%s\"\n",2759					overlay_name_from_nr(overlay_nr + i),2760					unittest_path(unittest_nr,2761						PDEV_OVERLAY));2762			return;2763		}2764		of_unittest_untrack_overlay(save_ovcs_id[i]);2765	}2766 2767	unittest(1, "overlay test %d passed\n", 8);2768}2769 2770/* test insertion of a bus with parent devices */2771static void __init of_unittest_overlay_10(void)2772{2773	int ret;2774	char *child_path;2775 2776	/* device should disable */2777	ret = of_unittest_apply_overlay_check(10, 10, 0, 1, PDEV_OVERLAY);2778 2779	if (unittest(ret == 0,2780			"overlay test %d failed; overlay application\n", 10))2781		return;2782 2783	child_path = kasprintf(GFP_KERNEL, "%s/test-unittest101",2784			unittest_path(10, PDEV_OVERLAY));2785	if (unittest(child_path, "overlay test %d failed; kasprintf\n", 10))2786		return;2787 2788	ret = of_path_device_type_exists(child_path, PDEV_OVERLAY);2789	kfree(child_path);2790 2791	unittest(ret, "overlay test %d failed; no child device\n", 10);2792}2793 2794/* test insertion of a bus with parent devices (and revert) */2795static void __init of_unittest_overlay_11(void)2796{2797	int ret;2798 2799	/* device should disable */2800	ret = of_unittest_apply_revert_overlay_check(11, 11, 0, 1,2801			PDEV_OVERLAY);2802 2803	unittest(ret == 0, "overlay test %d failed; overlay apply\n", 11);2804}2805 2806#if IS_BUILTIN(CONFIG_I2C) && IS_ENABLED(CONFIG_OF_OVERLAY)2807 2808struct unittest_i2c_bus_data {2809	struct platform_device	*pdev;2810	struct i2c_adapter	adap;2811};2812 2813static int unittest_i2c_master_xfer(struct i2c_adapter *adap,2814		struct i2c_msg *msgs, int num)2815{2816	struct unittest_i2c_bus_data *std = i2c_get_adapdata(adap);2817 2818	(void)std;2819 2820	return num;2821}2822 2823static u32 unittest_i2c_functionality(struct i2c_adapter *adap)2824{2825	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;2826}2827 2828static const struct i2c_algorithm unittest_i2c_algo = {2829	.master_xfer	= unittest_i2c_master_xfer,2830	.functionality	= unittest_i2c_functionality,2831};2832 2833static int unittest_i2c_bus_probe(struct platform_device *pdev)2834{2835	struct device *dev = &pdev->dev;2836	struct device_node *np = dev->of_node;2837	struct unittest_i2c_bus_data *std;2838	struct i2c_adapter *adap;2839	int ret;2840 2841	if (np == NULL) {2842		dev_err(dev, "No OF data for device\n");2843		return -EINVAL;2844 2845	}2846 2847	dev_dbg(dev, "%s for node @%pOF\n", __func__, np);2848 2849	std = devm_kzalloc(dev, sizeof(*std), GFP_KERNEL);2850	if (!std)2851		return -ENOMEM;2852 2853	/* link them together */2854	std->pdev = pdev;2855	platform_set_drvdata(pdev, std);2856 2857	adap = &std->adap;2858	i2c_set_adapdata(adap, std);2859	adap->nr = -1;2860	strscpy(adap->name, pdev->name, sizeof(adap->name));2861	adap->class = I2C_CLASS_DEPRECATED;2862	adap->algo = &unittest_i2c_algo;2863	adap->dev.parent = dev;2864	adap->dev.of_node = dev->of_node;2865	adap->timeout = 5 * HZ;2866	adap->retries = 3;2867 2868	ret = i2c_add_numbered_adapter(adap);2869	if (ret != 0) {2870		dev_err(dev, "Failed to add I2C adapter\n");2871		return ret;2872	}2873 2874	return 0;2875}2876 2877static void unittest_i2c_bus_remove(struct platform_device *pdev)2878{2879	struct device *dev = &pdev->dev;2880	struct device_node *np = dev->of_node;2881	struct unittest_i2c_bus_data *std = platform_get_drvdata(pdev);2882 2883	dev_dbg(dev, "%s for node @%pOF\n", __func__, np);2884	i2c_del_adapter(&std->adap);2885}2886 2887static const struct of_device_id unittest_i2c_bus_match[] = {2888	{ .compatible = "unittest-i2c-bus", },2889	{},2890};2891 2892static struct platform_driver unittest_i2c_bus_driver = {2893	.probe			= unittest_i2c_bus_probe,2894	.remove_new		= unittest_i2c_bus_remove,2895	.driver = {2896		.name		= "unittest-i2c-bus",2897		.of_match_table	= unittest_i2c_bus_match,2898	},2899};2900 2901static int unittest_i2c_dev_probe(struct i2c_client *client)2902{2903	struct device *dev = &client->dev;2904	struct device_node *np = client->dev.of_node;2905 2906	if (!np) {2907		dev_err(dev, "No OF node\n");2908		return -EINVAL;2909	}2910 2911	dev_dbg(dev, "%s for node @%pOF\n", __func__, np);2912 2913	return 0;2914};2915 2916static void unittest_i2c_dev_remove(struct i2c_client *client)2917{2918	struct device *dev = &client->dev;2919	struct device_node *np = client->dev.of_node;2920 2921	dev_dbg(dev, "%s for node @%pOF\n", __func__, np);2922}2923 2924static const struct i2c_device_id unittest_i2c_dev_id[] = {2925	{ .name = "unittest-i2c-dev" },2926	{ }2927};2928 2929static struct i2c_driver unittest_i2c_dev_driver = {2930	.driver = {2931		.name = "unittest-i2c-dev",2932	},2933	.probe = unittest_i2c_dev_probe,2934	.remove = unittest_i2c_dev_remove,2935	.id_table = unittest_i2c_dev_id,2936};2937 2938#if IS_BUILTIN(CONFIG_I2C_MUX)2939 2940static int unittest_i2c_mux_select_chan(struct i2c_mux_core *muxc, u32 chan)2941{2942	return 0;2943}2944 2945static int unittest_i2c_mux_probe(struct i2c_client *client)2946{2947	int i, nchans;2948	struct device *dev = &client->dev;2949	struct i2c_adapter *adap = client->adapter;2950	struct device_node *np = client->dev.of_node, *child;2951	struct i2c_mux_core *muxc;2952	u32 reg, max_reg;2953 2954	dev_dbg(dev, "%s for node @%pOF\n", __func__, np);2955 2956	if (!np) {2957		dev_err(dev, "No OF node\n");2958		return -EINVAL;2959	}2960 2961	max_reg = (u32)-1;2962	for_each_child_of_node(np, child) {2963		if (of_property_read_u32(child, "reg", &reg))2964			continue;2965		if (max_reg == (u32)-1 || reg > max_reg)2966			max_reg = reg;2967	}2968	nchans = max_reg == (u32)-1 ? 0 : max_reg + 1;2969	if (nchans == 0) {2970		dev_err(dev, "No channels\n");2971		return -EINVAL;2972	}2973 2974	muxc = i2c_mux_alloc(adap, dev, nchans, 0, 0,2975			     unittest_i2c_mux_select_chan, NULL);2976	if (!muxc)2977		return -ENOMEM;2978	for (i = 0; i < nchans; i++) {2979		if (i2c_mux_add_adapter(muxc, 0, i)) {2980			dev_err(dev, "Failed to register mux #%d\n", i);2981			i2c_mux_del_adapters(muxc);2982			return -ENODEV;2983		}2984	}2985 2986	i2c_set_clientdata(client, muxc);2987 2988	return 0;2989};2990 2991static void unittest_i2c_mux_remove(struct i2c_client *client)2992{2993	struct device *dev = &client->dev;2994	struct device_node *np = client->dev.of_node;2995	struct i2c_mux_core *muxc = i2c_get_clientdata(client);2996 2997	dev_dbg(dev, "%s for node @%pOF\n", __func__, np);2998	i2c_mux_del_adapters(muxc);2999}3000 3001static const struct i2c_device_id unittest_i2c_mux_id[] = {3002	{ .name = "unittest-i2c-mux" },3003	{ }3004};3005 3006static struct i2c_driver unittest_i2c_mux_driver = {3007	.driver = {3008		.name = "unittest-i2c-mux",3009	},3010	.probe = unittest_i2c_mux_probe,3011	.remove = unittest_i2c_mux_remove,3012	.id_table = unittest_i2c_mux_id,3013};3014 3015#endif3016 3017static int of_unittest_overlay_i2c_init(void)3018{3019	int ret;3020 3021	ret = i2c_add_driver(&unittest_i2c_dev_driver);3022	if (unittest(ret == 0,3023			"could not register unittest i2c device driver\n"))3024		return ret;3025 3026	ret = platform_driver_register(&unittest_i2c_bus_driver);3027 3028	if (unittest(ret == 0,3029			"could not register unittest i2c bus driver\n"))3030		return ret;3031 3032#if IS_BUILTIN(CONFIG_I2C_MUX)3033 3034	EXPECT_BEGIN(KERN_INFO,3035		     "i2c i2c-1: Added multiplexed i2c bus 2");3036 3037	ret = i2c_add_driver(&unittest_i2c_mux_driver);3038 3039	EXPECT_END(KERN_INFO,3040		   "i2c i2c-1: Added multiplexed i2c bus 2");3041 3042	if (unittest(ret == 0,3043			"could not register unittest i2c mux driver\n"))3044		return ret;3045#endif3046 3047	return 0;3048}3049 3050static void of_unittest_overlay_i2c_cleanup(void)3051{3052#if IS_BUILTIN(CONFIG_I2C_MUX)3053	i2c_del_driver(&unittest_i2c_mux_driver);3054#endif3055	platform_driver_unregister(&unittest_i2c_bus_driver);3056	i2c_del_driver(&unittest_i2c_dev_driver);3057}3058 3059static void __init of_unittest_overlay_i2c_12(void)3060{3061	int ret;3062 3063	/* device should enable */3064	EXPECT_BEGIN(KERN_INFO,3065		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/i2c-test-bus/test-unittest12/status");3066 3067	ret = of_unittest_apply_overlay_check(12, 12, 0, 1, I2C_OVERLAY);3068 3069	EXPECT_END(KERN_INFO,3070		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/i2c-test-bus/test-unittest12/status");3071 3072	if (ret)3073		return;3074 3075	unittest(1, "overlay test %d passed\n", 12);3076}3077 3078/* test deactivation of device */3079static void __init of_unittest_overlay_i2c_13(void)3080{3081	int ret;3082 3083	EXPECT_BEGIN(KERN_INFO,3084		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/i2c-test-bus/test-unittest13/status");3085 3086	/* device should disable */3087	ret = of_unittest_apply_overlay_check(13, 13, 1, 0, I2C_OVERLAY);3088 3089	EXPECT_END(KERN_INFO,3090		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/i2c-test-bus/test-unittest13/status");3091 3092	if (ret)3093		return;3094 3095	unittest(1, "overlay test %d passed\n", 13);3096}3097 3098/* just check for i2c mux existence */3099static void of_unittest_overlay_i2c_14(void)3100{3101}3102 3103static void __init of_unittest_overlay_i2c_15(void)3104{3105	int ret;3106 3107	/* device should enable */3108	EXPECT_BEGIN(KERN_INFO,3109		     "i2c i2c-1: Added multiplexed i2c bus 3");3110 3111	ret = of_unittest_apply_overlay_check(15, 15, 0, 1, I2C_OVERLAY);3112 3113	EXPECT_END(KERN_INFO,3114		   "i2c i2c-1: Added multiplexed i2c bus 3");3115 3116	if (ret)3117		return;3118 3119	unittest(1, "overlay test %d passed\n", 15);3120}3121 3122#else3123 3124static inline void of_unittest_overlay_i2c_14(void) { }3125static inline void of_unittest_overlay_i2c_15(void) { }3126 3127#endif3128 3129static int of_notify(struct notifier_block *nb, unsigned long action,3130		     void *arg)3131{3132	struct of_overlay_notify_data *nd = arg;3133	struct device_node *found;3134	int ret;3135 3136	/*3137	 * For overlay_16 .. overlay_19, check that returning an error3138	 * works for each of the actions by setting an arbitrary return3139	 * error number that matches the test number.  e.g. for unittest16,3140	 * ret = -EBUSY which is -16.3141	 *3142	 * OVERLAY_INFO() for the overlays is declared to expect the same3143	 * error number, so overlay_data_apply() will return no error.3144	 *3145	 * overlay_20 will return NOTIFY_DONE3146	 */3147 3148	ret = 0;3149	of_node_get(nd->overlay);3150 3151	switch (action) {3152 3153	case OF_OVERLAY_PRE_APPLY:3154		found = of_find_node_by_name(nd->overlay, "test-unittest16");3155		if (found) {3156			of_node_put(found);3157			ret = -EBUSY;3158		}3159		break;3160 3161	case OF_OVERLAY_POST_APPLY:3162		found = of_find_node_by_name(nd->overlay, "test-unittest17");3163		if (found) {3164			of_node_put(found);3165			ret = -EEXIST;3166		}3167		break;3168 3169	case OF_OVERLAY_PRE_REMOVE:3170		found = of_find_node_by_name(nd->overlay, "test-unittest18");3171		if (found) {3172			of_node_put(found);3173			ret = -EXDEV;3174		}3175		break;3176 3177	case OF_OVERLAY_POST_REMOVE:3178		found = of_find_node_by_name(nd->overlay, "test-unittest19");3179		if (found) {3180			of_node_put(found);3181			ret = -ENODEV;3182		}3183		break;3184 3185	default:			/* should not happen */3186		of_node_put(nd->overlay);3187		ret = -EINVAL;3188		break;3189	}3190 3191	if (ret)3192		return notifier_from_errno(ret);3193 3194	return NOTIFY_DONE;3195}3196 3197static struct notifier_block of_nb = {3198	.notifier_call = of_notify,3199};3200 3201static void __init of_unittest_overlay_notify(void)3202{3203	int ovcs_id;3204	int ret;3205 3206	ret = of_overlay_notifier_register(&of_nb);3207	unittest(!ret,3208		 "of_overlay_notifier_register() failed, ret = %d\n", ret);3209	if (ret)3210		return;3211 3212	/*3213	 * The overlays are applied by overlay_data_apply()3214	 * instead of of_unittest_apply_overlay() so that they3215	 * will not be tracked.  Thus they will not be removed3216	 * by of_unittest_remove_tracked_overlays().3217	 *3218	 * Applying overlays 16 - 19 will each trigger an error for a3219	 * different action in of_notify().3220	 *3221	 * Applying overlay 20 will not trigger any error in of_notify().3222	 */3223 3224	/* ---  overlay 16  --- */3225 3226	EXPECT_BEGIN(KERN_INFO, "OF: overlay: overlay changeset pre-apply notifier error -16, target: /testcase-data/overlay-node/test-bus");3227 3228	unittest(overlay_data_apply("overlay_16", &ovcs_id),3229		 "test OF_OVERLAY_PRE_APPLY notify injected error\n");3230 3231	EXPECT_END(KERN_INFO, "OF: overlay: overlay changeset pre-apply notifier error -16, target: /testcase-data/overlay-node/test-bus");3232 3233	unittest(ovcs_id, "ovcs_id not created for overlay_16\n");3234 3235	/* ---  overlay 17  --- */3236 3237	EXPECT_BEGIN(KERN_INFO, "OF: overlay: overlay changeset post-apply notifier error -17, target: /testcase-data/overlay-node/test-bus");3238 3239	unittest(overlay_data_apply("overlay_17", &ovcs_id),3240		 "test OF_OVERLAY_POST_APPLY notify injected error\n");3241 3242	EXPECT_END(KERN_INFO, "OF: overlay: overlay changeset post-apply notifier error -17, target: /testcase-data/overlay-node/test-bus");3243 3244	unittest(ovcs_id, "ovcs_id not created for overlay_17\n");3245 3246	/* ---  overlay 18  --- */3247 3248	unittest(overlay_data_apply("overlay_18", &ovcs_id),3249		 "OF_OVERLAY_PRE_REMOVE notify injected error\n");3250 3251	unittest(ovcs_id, "ovcs_id not created for overlay_18\n");3252 3253	if (ovcs_id) {3254		EXPECT_BEGIN(KERN_INFO, "OF: overlay: overlay changeset pre-remove notifier error -18, target: /testcase-data/overlay-node/test-bus");3255 3256		ret = of_overlay_remove(&ovcs_id);3257		EXPECT_END(KERN_INFO, "OF: overlay: overlay changeset pre-remove notifier error -18, target: /testcase-data/overlay-node/test-bus");3258		if (ret == -EXDEV) {3259			/*3260			 * change set ovcs_id should still exist3261			 */3262			unittest(1, "overlay_18 of_overlay_remove() injected error for OF_OVERLAY_PRE_REMOVE\n");3263		} else {3264			unittest(0, "overlay_18 of_overlay_remove() injected error for OF_OVERLAY_PRE_REMOVE not returned\n");3265		}3266	} else {3267		unittest(1, "ovcs_id not created for overlay_18\n");3268	}3269 3270	unittest(ovcs_id, "ovcs_id removed for overlay_18\n");3271 3272	/* ---  overlay 19  --- */3273 3274	unittest(overlay_data_apply("overlay_19", &ovcs_id),3275		 "OF_OVERLAY_POST_REMOVE notify injected error\n");3276 3277	unittest(ovcs_id, "ovcs_id not created for overlay_19\n");3278 3279	if (ovcs_id) {3280		EXPECT_BEGIN(KERN_INFO, "OF: overlay: overlay changeset post-remove notifier error -19, target: /testcase-data/overlay-node/test-bus");3281		ret = of_overlay_remove(&ovcs_id);3282		EXPECT_END(KERN_INFO, "OF: overlay: overlay changeset post-remove notifier error -19, target: /testcase-data/overlay-node/test-bus");3283		if (ret == -ENODEV)3284			unittest(1, "overlay_19 of_overlay_remove() injected error for OF_OVERLAY_POST_REMOVE\n");3285		else3286			unittest(0, "overlay_19 of_overlay_remove() injected error for OF_OVERLAY_POST_REMOVE not returned\n");3287	} else {3288		unittest(1, "ovcs_id removed for overlay_19\n");3289	}3290 3291	unittest(!ovcs_id, "changeset ovcs_id = %d not removed for overlay_19\n",3292		 ovcs_id);3293 3294	/* ---  overlay 20  --- */3295 3296	unittest(overlay_data_apply("overlay_20", &ovcs_id),3297		 "overlay notify no injected error\n");3298 3299	if (ovcs_id) {3300		ret = of_overlay_remove(&ovcs_id);3301		if (ret)3302			unittest(1, "overlay_20 failed to be destroyed, ret = %d\n",3303				 ret);3304	} else {3305		unittest(1, "ovcs_id not created for overlay_20\n");3306	}3307 3308	unittest(!of_overlay_notifier_unregister(&of_nb),3309		 "of_overlay_notifier_unregister() failed, ret = %d\n", ret);3310}3311 3312static void __init of_unittest_overlay(void)3313{3314	struct device_node *bus_np = NULL;3315	unsigned int i;3316 3317	if (platform_driver_register(&unittest_driver)) {3318		unittest(0, "could not register unittest driver\n");3319		goto out;3320	}3321 3322	bus_np = of_find_node_by_path(bus_path);3323	if (bus_np == NULL) {3324		unittest(0, "could not find bus_path \"%s\"\n", bus_path);3325		goto out;3326	}3327 3328	if (of_platform_default_populate(bus_np, NULL, NULL)) {3329		unittest(0, "could not populate bus @ \"%s\"\n", bus_path);3330		goto out;3331	}3332 3333	if (!of_unittest_device_exists(100, PDEV_OVERLAY)) {3334		unittest(0, "could not find unittest0 @ \"%s\"\n",3335				unittest_path(100, PDEV_OVERLAY));3336		goto out;3337	}3338 3339	if (of_unittest_device_exists(101, PDEV_OVERLAY)) {3340		unittest(0, "unittest1 @ \"%s\" should not exist\n",3341				unittest_path(101, PDEV_OVERLAY));3342		goto out;3343	}3344 3345	unittest(1, "basic infrastructure of overlays passed");3346 3347	/* tests in sequence */3348	of_unittest_overlay_0();3349	of_unittest_overlay_1();3350	of_unittest_overlay_2();3351	of_unittest_overlay_3();3352	of_unittest_overlay_4();3353	for (i = 0; i < 3; i++)3354		of_unittest_overlay_5();3355	of_unittest_overlay_6();3356	of_unittest_overlay_8();3357 3358	of_unittest_overlay_10();3359	of_unittest_overlay_11();3360 3361#if IS_BUILTIN(CONFIG_I2C)3362	if (unittest(of_unittest_overlay_i2c_init() == 0, "i2c init failed\n"))3363		goto out;3364 3365	of_unittest_overlay_i2c_12();3366	of_unittest_overlay_i2c_13();3367	of_unittest_overlay_i2c_14();3368	of_unittest_overlay_i2c_15();3369 3370	of_unittest_overlay_i2c_cleanup();3371#endif3372 3373	of_unittest_overlay_gpio();3374 3375	of_unittest_remove_tracked_overlays();3376 3377	of_unittest_overlay_notify();3378 3379out:3380	of_node_put(bus_np);3381}3382 3383#else3384static inline void __init of_unittest_overlay(void) { }3385#endif3386 3387static void __init of_unittest_lifecycle(void)3388{3389#ifdef CONFIG_OF_DYNAMIC3390	unsigned int refcount;3391	int found_refcount_one = 0;3392	int put_count = 0;3393	struct device_node *np;3394	struct device_node *prev_sibling, *next_sibling;3395	const char *refcount_path = "/testcase-data/refcount-node";3396	const char *refcount_parent_path = "/testcase-data";3397 3398	/*3399	 * Node lifecycle tests, non-dynamic node:3400	 *3401	 * - Decrementing refcount to zero via of_node_put() should cause the3402	 *   attempt to free the node memory by of_node_release() to fail3403	 *   because the node is not a dynamic node.3404	 *3405	 * - Decrementing refcount past zero should result in additional3406	 *   errors reported.3407	 */3408 3409	np = of_find_node_by_path(refcount_path);3410	unittest(np, "find refcount_path \"%s\"\n", refcount_path);3411	if (np == NULL)3412		goto out_skip_tests;3413 3414	while (!found_refcount_one) {3415 3416		if (put_count++ > 10) {3417			unittest(0, "guardrail to avoid infinite loop\n");3418			goto out_skip_tests;3419		}3420 3421		refcount = kref_read(&np->kobj.kref);3422		if (refcount == 1)3423			found_refcount_one = 1;3424		else3425			of_node_put(np);3426	}3427 3428	EXPECT_BEGIN(KERN_INFO, "OF: ERROR: of_node_release() detected bad of_node_put() on /testcase-data/refcount-node");3429 3430	/*3431	 * refcount is now one, decrementing to zero will result in a call to3432	 * of_node_release() to free the node's memory, which should result3433	 * in an error3434	 */3435	unittest(1, "/testcase-data/refcount-node is one");3436	of_node_put(np);3437 3438	EXPECT_END(KERN_INFO, "OF: ERROR: of_node_release() detected bad of_node_put() on /testcase-data/refcount-node");3439 3440 3441	/*3442	 * expect stack trace for subsequent of_node_put():3443	 *   __refcount_sub_and_test() calls:3444	 *   refcount_warn_saturate(r, REFCOUNT_SUB_UAF)3445	 *3446	 * Not capturing entire WARN_ONCE() trace with EXPECT_*(), just3447	 * the first three lines, and the last line.3448	 */3449	EXPECT_BEGIN(KERN_INFO, "------------[ cut here ]------------");3450	EXPECT_BEGIN(KERN_INFO, "WARNING: <<all>>");3451	EXPECT_BEGIN(KERN_INFO, "refcount_t: underflow; use-after-free.");3452	EXPECT_BEGIN(KERN_INFO, "---[ end trace <<int>> ]---");3453 3454	/* refcount is now zero, this should fail */3455	unittest(1, "/testcase-data/refcount-node is zero");3456	of_node_put(np);3457 3458	EXPECT_END(KERN_INFO, "---[ end trace <<int>> ]---");3459	EXPECT_END(KERN_INFO, "refcount_t: underflow; use-after-free.");3460	EXPECT_END(KERN_INFO, "WARNING: <<all>>");3461	EXPECT_END(KERN_INFO, "------------[ cut here ]------------");3462 3463	/*3464	 * Q. do we expect to get yet another warning?3465	 * A. no, the WARNING is from WARN_ONCE()3466	 */3467	EXPECT_NOT_BEGIN(KERN_INFO, "------------[ cut here ]------------");3468	EXPECT_NOT_BEGIN(KERN_INFO, "WARNING: <<all>>");3469	EXPECT_NOT_BEGIN(KERN_INFO, "refcount_t: underflow; use-after-free.");3470	EXPECT_NOT_BEGIN(KERN_INFO, "---[ end trace <<int>> ]---");3471 3472	unittest(1, "/testcase-data/refcount-node is zero, second time");3473	of_node_put(np);3474 3475	EXPECT_NOT_END(KERN_INFO, "---[ end trace <<int>> ]---");3476	EXPECT_NOT_END(KERN_INFO, "refcount_t: underflow; use-after-free.");3477	EXPECT_NOT_END(KERN_INFO, "WARNING: <<all>>");3478	EXPECT_NOT_END(KERN_INFO, "------------[ cut here ]------------");3479 3480	/*3481	 * refcount of zero will trigger stack traces from any further3482	 * attempt to of_node_get() node "refcount-node". One example of3483	 * this is where of_unittest_check_node_linkage() will recursively3484	 * scan the tree, with 'for_each_child_of_node()' doing an3485	 * of_node_get() of the children of a node.3486	 *3487	 * Prevent the stack trace by removing node "refcount-node" from3488	 * its parent's child list.3489	 *3490	 * WARNING:  EVIL, EVIL, EVIL:3491	 *3492	 *   Directly manipulate the child list of node /testcase-data to3493	 *   remove child refcount-node.  This is ignoring all proper methods3494	 *   of removing a child and will leak a small amount of memory.3495	 */3496 3497	np = of_find_node_by_path(refcount_parent_path);3498	unittest(np, "find refcount_parent_path \"%s\"\n", refcount_parent_path);3499	unittest(np, "ERROR: devicetree live tree left in a 'bad state' if test fail\n");3500	if (np == NULL)3501		return;3502 3503	prev_sibling = np->child;3504	next_sibling = prev_sibling->sibling;3505	if (!strcmp(prev_sibling->full_name, "refcount-node")) {3506		np->child = next_sibling;3507		next_sibling = next_sibling->sibling;3508	}3509	while (next_sibling) {3510		if (!strcmp(next_sibling->full_name, "refcount-node"))3511			prev_sibling->sibling = next_sibling->sibling;3512		prev_sibling = next_sibling;3513		next_sibling = next_sibling->sibling;3514	}3515	of_node_put(np);3516 3517	return;3518 3519out_skip_tests:3520#endif3521	unittest(0, "One or more lifecycle tests skipped\n");3522}3523 3524#ifdef CONFIG_OF_OVERLAY3525 3526/*3527 * __dtbo_##overlay_name##_begin[] and __dtbo_##overlay_name##_end[] are3528 * created by cmd_wrap_S_dtbo in scripts/Makefile.dtbs3529 */3530 3531#define OVERLAY_INFO_EXTERN(overlay_name) \3532	extern uint8_t __dtbo_##overlay_name##_begin[]; \3533	extern uint8_t __dtbo_##overlay_name##_end[]3534 3535#define OVERLAY_INFO(overlay_name, expected, expected_remove) \3536{	.dtbo_begin		= __dtbo_##overlay_name##_begin, \3537	.dtbo_end		= __dtbo_##overlay_name##_end, \3538	.expected_result	= expected, \3539	.expected_result_remove	= expected_remove, \3540	.name			= #overlay_name, \3541}3542 3543struct overlay_info {3544	uint8_t		*dtbo_begin;3545	uint8_t		*dtbo_end;3546	int		expected_result;3547	int		expected_result_remove;	/* if apply failed */3548	int		ovcs_id;3549	char		*name;3550};3551 3552OVERLAY_INFO_EXTERN(overlay_base);3553OVERLAY_INFO_EXTERN(overlay);3554OVERLAY_INFO_EXTERN(overlay_0);3555OVERLAY_INFO_EXTERN(overlay_1);3556OVERLAY_INFO_EXTERN(overlay_2);3557OVERLAY_INFO_EXTERN(overlay_3);3558OVERLAY_INFO_EXTERN(overlay_4);3559OVERLAY_INFO_EXTERN(overlay_5);3560OVERLAY_INFO_EXTERN(overlay_6);3561OVERLAY_INFO_EXTERN(overlay_7);3562OVERLAY_INFO_EXTERN(overlay_8);3563OVERLAY_INFO_EXTERN(overlay_9);3564OVERLAY_INFO_EXTERN(overlay_10);3565OVERLAY_INFO_EXTERN(overlay_11);3566OVERLAY_INFO_EXTERN(overlay_12);3567OVERLAY_INFO_EXTERN(overlay_13);3568OVERLAY_INFO_EXTERN(overlay_15);3569OVERLAY_INFO_EXTERN(overlay_16);3570OVERLAY_INFO_EXTERN(overlay_17);3571OVERLAY_INFO_EXTERN(overlay_18);3572OVERLAY_INFO_EXTERN(overlay_19);3573OVERLAY_INFO_EXTERN(overlay_20);3574OVERLAY_INFO_EXTERN(overlay_gpio_01);3575OVERLAY_INFO_EXTERN(overlay_gpio_02a);3576OVERLAY_INFO_EXTERN(overlay_gpio_02b);3577OVERLAY_INFO_EXTERN(overlay_gpio_03);3578OVERLAY_INFO_EXTERN(overlay_gpio_04a);3579OVERLAY_INFO_EXTERN(overlay_gpio_04b);3580OVERLAY_INFO_EXTERN(overlay_pci_node);3581OVERLAY_INFO_EXTERN(overlay_bad_add_dup_node);3582OVERLAY_INFO_EXTERN(overlay_bad_add_dup_prop);3583OVERLAY_INFO_EXTERN(overlay_bad_phandle);3584OVERLAY_INFO_EXTERN(overlay_bad_symbol);3585OVERLAY_INFO_EXTERN(overlay_bad_unresolved);3586 3587/* entries found by name */3588static struct overlay_info overlays[] = {3589	OVERLAY_INFO(overlay_base, -9999, 0),3590	OVERLAY_INFO(overlay, 0, 0),3591	OVERLAY_INFO(overlay_0, 0, 0),3592	OVERLAY_INFO(overlay_1, 0, 0),3593	OVERLAY_INFO(overlay_2, 0, 0),3594	OVERLAY_INFO(overlay_3, 0, 0),3595	OVERLAY_INFO(overlay_4, 0, 0),3596	OVERLAY_INFO(overlay_5, 0, 0),3597	OVERLAY_INFO(overlay_6, 0, 0),3598	OVERLAY_INFO(overlay_7, 0, 0),3599	OVERLAY_INFO(overlay_8, 0, 0),3600	OVERLAY_INFO(overlay_9, 0, 0),3601	OVERLAY_INFO(overlay_10, 0, 0),3602	OVERLAY_INFO(overlay_11, 0, 0),3603	OVERLAY_INFO(overlay_12, 0, 0),3604	OVERLAY_INFO(overlay_13, 0, 0),3605	OVERLAY_INFO(overlay_15, 0, 0),3606	OVERLAY_INFO(overlay_16, -EBUSY, 0),3607	OVERLAY_INFO(overlay_17, -EEXIST, 0),3608	OVERLAY_INFO(overlay_18, 0, 0),3609	OVERLAY_INFO(overlay_19, 0, 0),3610	OVERLAY_INFO(overlay_20, 0, 0),3611	OVERLAY_INFO(overlay_gpio_01, 0, 0),3612	OVERLAY_INFO(overlay_gpio_02a, 0, 0),3613	OVERLAY_INFO(overlay_gpio_02b, 0, 0),3614	OVERLAY_INFO(overlay_gpio_03, 0, 0),3615	OVERLAY_INFO(overlay_gpio_04a, 0, 0),3616	OVERLAY_INFO(overlay_gpio_04b, 0, 0),3617	OVERLAY_INFO(overlay_pci_node, 0, 0),3618	OVERLAY_INFO(overlay_bad_add_dup_node, -EINVAL, -ENODEV),3619	OVERLAY_INFO(overlay_bad_add_dup_prop, -EINVAL, -ENODEV),3620	OVERLAY_INFO(overlay_bad_phandle, -EINVAL, 0),3621	OVERLAY_INFO(overlay_bad_symbol, -EINVAL, -ENODEV),3622	OVERLAY_INFO(overlay_bad_unresolved, -EINVAL, 0),3623	/* end marker */3624	{ }3625};3626 3627static struct device_node *overlay_base_root;3628 3629static void * __init dt_alloc_memory(u64 size, u64 align)3630{3631	void *ptr = memblock_alloc(size, align);3632 3633	if (!ptr)3634		panic("%s: Failed to allocate %llu bytes align=0x%llx\n",3635		      __func__, size, align);3636 3637	return ptr;3638}3639 3640/*3641 * Create base device tree for the overlay unittest.3642 *3643 * This is called from very early boot code.3644 *3645 * Do as much as possible the same way as done in __unflatten_device_tree3646 * and other early boot steps for the normal FDT so that the overlay base3647 * unflattened tree will have the same characteristics as the real tree3648 * (such as having memory allocated by the early allocator).  The goal3649 * is to test "the real thing" as much as possible, and test "test setup3650 * code" as little as possible.3651 *3652 * Have to stop before resolving phandles, because that uses kmalloc.3653 */3654void __init unittest_unflatten_overlay_base(void)3655{3656	struct overlay_info *info;3657	u32 data_size;3658	void *new_fdt;3659	u32 size;3660	int found = 0;3661	const char *overlay_name = "overlay_base";3662 3663	for (info = overlays; info && info->name; info++) {3664		if (!strcmp(overlay_name, info->name)) {3665			found = 1;3666			break;3667		}3668	}3669	if (!found) {3670		pr_err("no overlay data for %s\n", overlay_name);3671		return;3672	}3673 3674	info = &overlays[0];3675 3676	if (info->expected_result != -9999) {3677		pr_err("No dtb 'overlay_base' to attach\n");3678		return;3679	}3680 3681	data_size = info->dtbo_end - info->dtbo_begin;3682	if (!data_size) {3683		pr_err("No dtb 'overlay_base' to attach\n");3684		return;3685	}3686 3687	size = fdt_totalsize(info->dtbo_begin);3688	if (size != data_size) {3689		pr_err("dtb 'overlay_base' header totalsize != actual size");3690		return;3691	}3692 3693	new_fdt = dt_alloc_memory(size, roundup_pow_of_two(FDT_V17_SIZE));3694	if (!new_fdt) {3695		pr_err("alloc for dtb 'overlay_base' failed");3696		return;3697	}3698 3699	memcpy(new_fdt, info->dtbo_begin, size);3700 3701	__unflatten_device_tree(new_fdt, NULL, &overlay_base_root,3702				dt_alloc_memory, true);3703}3704 3705/*3706 * The purpose of of_unittest_overlay_data_add is to add an3707 * overlay in the normal fashion.  This is a test of the whole3708 * picture, instead of testing individual elements.3709 *3710 * A secondary purpose is to be able to verify that the contents of3711 * /proc/device-tree/ contains the updated structure and values from3712 * the overlay.  That must be verified separately in user space.3713 *3714 * Return 0 on unexpected error.3715 */3716static int __init overlay_data_apply(const char *overlay_name, int *ovcs_id)3717{3718	struct overlay_info *info;3719	int passed = 1;3720	int found = 0;3721	int ret, ret2;3722	u32 size;3723 3724	for (info = overlays; info && info->name; info++) {3725		if (!strcmp(overlay_name, info->name)) {3726			found = 1;3727			break;3728		}3729	}3730	if (!found) {3731		pr_err("no overlay data for %s\n", overlay_name);3732		return 0;3733	}3734 3735	size = info->dtbo_end - info->dtbo_begin;3736	if (!size)3737		pr_err("no overlay data for %s\n", overlay_name);3738 3739	ret = of_overlay_fdt_apply(info->dtbo_begin, size, &info->ovcs_id,3740				   NULL);3741	if (ovcs_id)3742		*ovcs_id = info->ovcs_id;3743	if (ret < 0)3744		goto out;3745 3746	pr_debug("%s applied\n", overlay_name);3747 3748out:3749	if (ret != info->expected_result) {3750		pr_err("of_overlay_fdt_apply() expected %d, ret=%d, %s\n",3751		       info->expected_result, ret, overlay_name);3752		passed = 0;3753	}3754 3755	if (ret < 0) {3756		/* changeset may be partially applied */3757		ret2 = of_overlay_remove(&info->ovcs_id);3758		if (ret2 != info->expected_result_remove) {3759			pr_err("of_overlay_remove() expected %d, ret=%d, %s\n",3760			       info->expected_result_remove, ret2,3761			       overlay_name);3762			passed = 0;3763		}3764	}3765 3766	return passed;3767}3768 3769/*3770 * The purpose of of_unittest_overlay_high_level is to add an overlay3771 * in the normal fashion.  This is a test of the whole picture,3772 * instead of individual elements.3773 *3774 * The first part of the function is _not_ normal overlay usage; it is3775 * finishing splicing the base overlay device tree into the live tree.3776 */3777static __init void of_unittest_overlay_high_level(void)3778{3779	struct device_node *last_sibling;3780	struct device_node *np;3781	struct device_node *of_symbols;3782	struct device_node *overlay_base_symbols;3783	struct device_node **pprev;3784	struct property *prop;3785	int ret;3786 3787	if (!overlay_base_root) {3788		unittest(0, "overlay_base_root not initialized\n");3789		return;3790	}3791 3792	/*3793	 * Could not fixup phandles in unittest_unflatten_overlay_base()3794	 * because kmalloc() was not yet available.3795	 */3796	of_overlay_mutex_lock();3797	of_resolve_phandles(overlay_base_root);3798	of_overlay_mutex_unlock();3799 3800 3801	/*3802	 * do not allow overlay_base to duplicate any node already in3803	 * tree, this greatly simplifies the code3804	 */3805 3806	/*3807	 * remove overlay_base_root node "__local_fixups", after3808	 * being used by of_resolve_phandles()3809	 */3810	pprev = &overlay_base_root->child;3811	for (np = overlay_base_root->child; np; np = np->sibling) {3812		if (of_node_name_eq(np, "__local_fixups__")) {3813			*pprev = np->sibling;3814			break;3815		}3816		pprev = &np->sibling;3817	}3818 3819	/* remove overlay_base_root node "__symbols__" if in live tree */3820	of_symbols = of_get_child_by_name(of_root, "__symbols__");3821	if (of_symbols) {3822		/* will have to graft properties from node into live tree */3823		pprev = &overlay_base_root->child;3824		for (np = overlay_base_root->child; np; np = np->sibling) {3825			if (of_node_name_eq(np, "__symbols__")) {3826				overlay_base_symbols = np;3827				*pprev = np->sibling;3828				break;3829			}3830			pprev = &np->sibling;3831		}3832	}3833 3834	for_each_child_of_node(overlay_base_root, np) {3835		struct device_node *base_child;3836		for_each_child_of_node(of_root, base_child) {3837			if (!strcmp(np->full_name, base_child->full_name)) {3838				unittest(0, "illegal node name in overlay_base %pOFn",3839					 np);3840				of_node_put(np);3841				of_node_put(base_child);3842				return;3843			}3844		}3845	}3846 3847	/*3848	 * overlay 'overlay_base' is not allowed to have root3849	 * properties, so only need to splice nodes into main device tree.3850	 *3851	 * root node of *overlay_base_root will not be freed, it is lost3852	 * memory.3853	 */3854 3855	for (np = overlay_base_root->child; np; np = np->sibling)3856		np->parent = of_root;3857 3858	mutex_lock(&of_mutex);3859 3860	for (last_sibling = np = of_root->child; np; np = np->sibling)3861		last_sibling = np;3862 3863	if (last_sibling)3864		last_sibling->sibling = overlay_base_root->child;3865	else3866		of_root->child = overlay_base_root->child;3867 3868	for_each_of_allnodes_from(overlay_base_root, np)3869		__of_attach_node_sysfs(np);3870 3871	if (of_symbols) {3872		struct property *new_prop;3873		for_each_property_of_node(overlay_base_symbols, prop) {3874 3875			new_prop = __of_prop_dup(prop, GFP_KERNEL);3876			if (!new_prop) {3877				unittest(0, "__of_prop_dup() of '%s' from overlay_base node __symbols__",3878					 prop->name);3879				goto err_unlock;3880			}3881			if (__of_add_property(of_symbols, new_prop)) {3882				__of_prop_free(new_prop);3883				/* "name" auto-generated by unflatten */3884				if (!strcmp(prop->name, "name"))3885					continue;3886				unittest(0, "duplicate property '%s' in overlay_base node __symbols__",3887					 prop->name);3888				goto err_unlock;3889			}3890			if (__of_add_property_sysfs(of_symbols, new_prop)) {3891				unittest(0, "unable to add property '%s' in overlay_base node __symbols__ to sysfs",3892					 prop->name);3893				goto err_unlock;3894			}3895		}3896	}3897 3898	mutex_unlock(&of_mutex);3899 3900 3901	/* now do the normal overlay usage test */3902 3903	/* ---  overlay  --- */3904 3905	EXPECT_BEGIN(KERN_ERR,3906		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/substation@100/status");3907	EXPECT_BEGIN(KERN_ERR,3908		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/fairway-1/status");3909	EXPECT_BEGIN(KERN_ERR,3910		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/fairway-1/ride@100/track@30/incline-up");3911	EXPECT_BEGIN(KERN_ERR,3912		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/fairway-1/ride@100/track@40/incline-up");3913	EXPECT_BEGIN(KERN_ERR,3914		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/lights@40000/status");3915	EXPECT_BEGIN(KERN_ERR,3916		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/lights@40000/color");3917	EXPECT_BEGIN(KERN_ERR,3918		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/lights@40000/rate");3919	EXPECT_BEGIN(KERN_ERR,3920		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/hvac_2");3921	EXPECT_BEGIN(KERN_ERR,3922		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/ride_200");3923	EXPECT_BEGIN(KERN_ERR,3924		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/ride_200_left");3925	EXPECT_BEGIN(KERN_ERR,3926		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/ride_200_right");3927 3928	ret = overlay_data_apply("overlay", NULL);3929 3930	EXPECT_END(KERN_ERR,3931		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/ride_200_right");3932	EXPECT_END(KERN_ERR,3933		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/ride_200_left");3934	EXPECT_END(KERN_ERR,3935		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/ride_200");3936	EXPECT_END(KERN_ERR,3937		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/hvac_2");3938	EXPECT_END(KERN_ERR,3939		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/lights@40000/rate");3940	EXPECT_END(KERN_ERR,3941		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/lights@40000/color");3942	EXPECT_END(KERN_ERR,3943		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/lights@40000/status");3944	EXPECT_END(KERN_ERR,3945		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/fairway-1/ride@100/track@40/incline-up");3946	EXPECT_END(KERN_ERR,3947		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/fairway-1/ride@100/track@30/incline-up");3948	EXPECT_END(KERN_ERR,3949		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/fairway-1/status");3950	EXPECT_END(KERN_ERR,3951		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/substation@100/status");3952 3953	unittest(ret, "Adding overlay 'overlay' failed\n");3954 3955	/* ---  overlay_bad_add_dup_node  --- */3956 3957	EXPECT_BEGIN(KERN_ERR,3958		     "OF: overlay: ERROR: multiple fragments add and/or delete node /testcase-data-2/substation@100/motor-1/controller");3959	EXPECT_BEGIN(KERN_ERR,3960		     "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/controller/name");3961	EXPECT_BEGIN(KERN_ERR,3962		     "OF: changeset: apply failed: REMOVE_PROPERTY /testcase-data-2/substation@100/motor-1/controller:name");3963	EXPECT_BEGIN(KERN_ERR,3964		     "OF: Error reverting changeset (-19)");3965 3966	unittest(overlay_data_apply("overlay_bad_add_dup_node", NULL),3967		 "Adding overlay 'overlay_bad_add_dup_node' failed\n");3968 3969	EXPECT_END(KERN_ERR,3970		   "OF: Error reverting changeset (-19)");3971	EXPECT_END(KERN_ERR,3972		   "OF: changeset: apply failed: REMOVE_PROPERTY /testcase-data-2/substation@100/motor-1/controller:name");3973	EXPECT_END(KERN_ERR,3974		   "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/controller/name");3975	EXPECT_END(KERN_ERR,3976		   "OF: overlay: ERROR: multiple fragments add and/or delete node /testcase-data-2/substation@100/motor-1/controller");3977 3978	/* ---  overlay_bad_add_dup_prop  --- */3979 3980	EXPECT_BEGIN(KERN_ERR,3981		     "OF: overlay: ERROR: multiple fragments add and/or delete node /testcase-data-2/substation@100/motor-1/electric");3982	EXPECT_BEGIN(KERN_ERR,3983		     "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/electric/rpm_avail");3984	EXPECT_BEGIN(KERN_ERR,3985		     "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/electric/name");3986	EXPECT_BEGIN(KERN_ERR,3987		     "OF: changeset: apply failed: REMOVE_PROPERTY /testcase-data-2/substation@100/motor-1/electric:name");3988	EXPECT_BEGIN(KERN_ERR,3989		     "OF: Error reverting changeset (-19)");3990 3991	unittest(overlay_data_apply("overlay_bad_add_dup_prop", NULL),3992		 "Adding overlay 'overlay_bad_add_dup_prop' failed\n");3993 3994	EXPECT_END(KERN_ERR,3995		   "OF: Error reverting changeset (-19)");3996	EXPECT_END(KERN_ERR,3997		   "OF: changeset: apply failed: REMOVE_PROPERTY /testcase-data-2/substation@100/motor-1/electric:name");3998	EXPECT_END(KERN_ERR,3999		   "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/electric/name");4000	EXPECT_END(KERN_ERR,4001		   "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/electric/rpm_avail");4002	EXPECT_END(KERN_ERR,4003		   "OF: overlay: ERROR: multiple fragments add and/or delete node /testcase-data-2/substation@100/motor-1/electric");4004 4005	/* ---  overlay_bad_phandle  --- */4006 4007	unittest(overlay_data_apply("overlay_bad_phandle", NULL),4008		 "Adding overlay 'overlay_bad_phandle' failed\n");4009 4010	/* ---  overlay_bad_symbol  --- */4011 4012	EXPECT_BEGIN(KERN_ERR,4013		     "OF: changeset: apply failed: REMOVE_PROPERTY /testcase-data-2/substation@100/hvac-medium-2:name");4014	EXPECT_BEGIN(KERN_ERR,4015		     "OF: Error reverting changeset (-19)");4016 4017	unittest(overlay_data_apply("overlay_bad_symbol", NULL),4018		 "Adding overlay 'overlay_bad_symbol' failed\n");4019 4020	EXPECT_END(KERN_ERR,4021		   "OF: Error reverting changeset (-19)");4022	EXPECT_END(KERN_ERR,4023		   "OF: changeset: apply failed: REMOVE_PROPERTY /testcase-data-2/substation@100/hvac-medium-2:name");4024 4025	/* ---  overlay_bad_unresolved  --- */4026 4027	EXPECT_BEGIN(KERN_ERR,4028		     "OF: resolver: node label 'this_label_does_not_exist' not found in live devicetree symbols table");4029	EXPECT_BEGIN(KERN_ERR,4030		     "OF: resolver: overlay phandle fixup failed: -22");4031 4032	unittest(overlay_data_apply("overlay_bad_unresolved", NULL),4033		 "Adding overlay 'overlay_bad_unresolved' failed\n");4034 4035	EXPECT_END(KERN_ERR,4036		   "OF: resolver: overlay phandle fixup failed: -22");4037	EXPECT_END(KERN_ERR,4038		   "OF: resolver: node label 'this_label_does_not_exist' not found in live devicetree symbols table");4039 4040	return;4041 4042err_unlock:4043	mutex_unlock(&of_mutex);4044}4045 4046static int of_unittest_pci_dev_num;4047static int of_unittest_pci_child_num;4048 4049/*4050 * PCI device tree node test driver4051 */4052static const struct pci_device_id testdrv_pci_ids[] = {4053	{ PCI_DEVICE(PCI_VENDOR_ID_REDHAT, 0x5), }, /* PCI_VENDOR_ID_REDHAT */4054	{ 0, }4055};4056 4057static int testdrv_probe(struct pci_dev *pdev, const struct pci_device_id *id)4058{4059	struct overlay_info *info;4060	struct device_node *dn;4061	int ret, ovcs_id;4062	u32 size;4063 4064	dn = pdev->dev.of_node;4065	if (!dn) {4066		dev_err(&pdev->dev, "does not find bus endpoint");4067		return -EINVAL;4068	}4069 4070	for (info = overlays; info && info->name; info++) {4071		if (!strcmp(info->name, "overlay_pci_node"))4072			break;4073	}4074	if (!info || !info->name) {4075		dev_err(&pdev->dev, "no overlay data for overlay_pci_node");4076		return -ENODEV;4077	}4078 4079	size = info->dtbo_end - info->dtbo_begin;4080	ret = of_overlay_fdt_apply(info->dtbo_begin, size, &ovcs_id, dn);4081	of_node_put(dn);4082	if (ret)4083		return ret;4084 4085	of_platform_default_populate(dn, NULL, &pdev->dev);4086	pci_set_drvdata(pdev, (void *)(uintptr_t)ovcs_id);4087 4088	return 0;4089}4090 4091static void testdrv_remove(struct pci_dev *pdev)4092{4093	int ovcs_id = (int)(uintptr_t)pci_get_drvdata(pdev);4094 4095	of_platform_depopulate(&pdev->dev);4096	of_overlay_remove(&ovcs_id);4097}4098 4099static struct pci_driver testdrv_driver = {4100	.name = "pci_dt_testdrv",4101	.id_table = testdrv_pci_ids,4102	.probe = testdrv_probe,4103	.remove = testdrv_remove,4104};4105 4106static int unittest_pci_probe(struct platform_device *pdev)4107{4108	struct resource *res;4109	struct device *dev;4110	u64 exp_addr;4111 4112	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);4113	if (!res)4114		return -ENODEV;4115 4116	dev = &pdev->dev;4117	while (dev && !dev_is_pci(dev))4118		dev = dev->parent;4119	if (!dev) {4120		pr_err("unable to find parent device\n");4121		return -ENODEV;4122	}4123 4124	exp_addr = pci_resource_start(to_pci_dev(dev), 0) + 0x100;4125	unittest(res->start == exp_addr, "Incorrect translated address %llx, expected %llx\n",4126		 (u64)res->start, exp_addr);4127 4128	of_unittest_pci_child_num++;4129 4130	return 0;4131}4132 4133static const struct of_device_id unittest_pci_of_match[] = {4134	{ .compatible = "unittest-pci" },4135	{ }4136};4137 4138static struct platform_driver unittest_pci_driver = {4139	.probe = unittest_pci_probe,4140	.driver = {4141		.name = "unittest-pci",4142		.of_match_table = unittest_pci_of_match,4143	},4144};4145 4146static int of_unittest_pci_node_verify(struct pci_dev *pdev, bool add)4147{4148	struct device_node *pnp, *np = NULL;4149	struct device *child_dev;4150	char *path = NULL;4151	const __be32 *reg;4152	int rc = 0;4153 4154	pnp = pdev->dev.of_node;4155	unittest(pnp, "Failed creating PCI dt node\n");4156	if (!pnp)4157		return -ENODEV;4158 4159	if (add) {4160		path = kasprintf(GFP_KERNEL, "%pOF/pci-ep-bus@0/unittest-pci@100", pnp);4161		np = of_find_node_by_path(path);4162		unittest(np, "Failed to get unittest-pci node under PCI node\n");4163		if (!np) {4164			rc = -ENODEV;4165			goto failed;4166		}4167 4168		reg = of_get_property(np, "reg", NULL);4169		unittest(reg, "Failed to get reg property\n");4170		if (!reg)4171			rc = -ENODEV;4172	} else {4173		path = kasprintf(GFP_KERNEL, "%pOF/pci-ep-bus@0", pnp);4174		np = of_find_node_by_path(path);4175		unittest(!np, "Child device tree node is not removed\n");4176		child_dev = device_find_any_child(&pdev->dev);4177		unittest(!child_dev, "Child device is not removed\n");4178	}4179 4180failed:4181	kfree(path);4182	if (np)4183		of_node_put(np);4184 4185	return rc;4186}4187 4188static void __init of_unittest_pci_node(void)4189{4190	struct pci_dev *pdev = NULL;4191	int rc;4192 4193	if (!IS_ENABLED(CONFIG_PCI_DYNAMIC_OF_NODES))4194		return;4195 4196	rc = pci_register_driver(&testdrv_driver);4197	unittest(!rc, "Failed to register pci test driver; rc = %d\n", rc);4198	if (rc)4199		return;4200 4201	rc = platform_driver_register(&unittest_pci_driver);4202	if (unittest(!rc, "Failed to register unittest pci driver\n")) {4203		pci_unregister_driver(&testdrv_driver);4204		return;4205	}4206 4207	while ((pdev = pci_get_device(PCI_VENDOR_ID_REDHAT, 0x5, pdev)) != NULL) {4208		of_unittest_pci_node_verify(pdev, true);4209		of_unittest_pci_dev_num++;4210	}4211	if (pdev)4212		pci_dev_put(pdev);4213 4214	unittest(of_unittest_pci_dev_num,4215		 "No test PCI device been found. Please run QEMU with '-device pci-testdev'\n");4216	unittest(of_unittest_pci_dev_num == of_unittest_pci_child_num,4217		 "Child device number %d is not expected %d", of_unittest_pci_child_num,4218		 of_unittest_pci_dev_num);4219 4220	platform_driver_unregister(&unittest_pci_driver);4221	pci_unregister_driver(&testdrv_driver);4222 4223	while ((pdev = pci_get_device(PCI_VENDOR_ID_REDHAT, 0x5, pdev)) != NULL)4224		of_unittest_pci_node_verify(pdev, false);4225	if (pdev)4226		pci_dev_put(pdev);4227}4228#else4229 4230static inline __init void of_unittest_overlay_high_level(void) {}4231static inline __init void of_unittest_pci_node(void) { }4232 4233#endif4234 4235static int __init of_unittest(void)4236{4237	struct device_node *np;4238	int res;4239 4240	pr_info("start of unittest - you will see error messages\n");4241 4242	/* Taint the kernel so we know we've run tests. */4243	add_taint(TAINT_TEST, LOCKDEP_STILL_OK);4244 4245	/* adding data for unittest */4246	res = unittest_data_add();4247	if (res)4248		return res;4249	if (!of_aliases)4250		of_aliases = of_find_node_by_path("/aliases");4251 4252	np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");4253	if (!np) {4254		pr_info("No testcase data in device tree; not running tests\n");4255		return 0;4256	}4257	of_node_put(np);4258 4259	of_unittest_check_tree_linkage();4260	of_unittest_check_phandles();4261	of_unittest_find_node_by_name();4262	of_unittest_dynamic();4263	of_unittest_parse_phandle_with_args();4264	of_unittest_parse_phandle_with_args_map();4265	of_unittest_printf();4266	of_unittest_property_string();4267	of_unittest_property_copy();4268	of_unittest_changeset();4269	of_unittest_changeset_prop();4270	of_unittest_parse_interrupts();4271	of_unittest_parse_interrupts_extended();4272	of_unittest_dma_get_max_cpu_address();4273	of_unittest_parse_dma_ranges();4274	of_unittest_pci_dma_ranges();4275	of_unittest_bus_ranges();4276	of_unittest_bus_3cell_ranges();4277	of_unittest_reg();4278	of_unittest_translate_addr();4279	of_unittest_match_node();4280	of_unittest_platform_populate();4281	of_unittest_overlay();4282	of_unittest_lifecycle();4283	of_unittest_pci_node();4284 4285	/* Double check linkage after removing testcase data */4286	of_unittest_check_tree_linkage();4287 4288	of_unittest_overlay_high_level();4289 4290	pr_info("end of unittest - %i passed, %i failed\n",4291		unittest_results.passed, unittest_results.failed);4292 4293	return 0;4294}4295late_initcall(of_unittest);4296