diff options
Diffstat (limited to 'drivers/of/unittest.c')
| -rw-r--r-- | drivers/of/unittest.c | 175 | 
1 files changed, 86 insertions, 89 deletions
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 481ba8682ebf..70992103c07d 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -911,11 +911,18 @@ static void __init of_unittest_dma_ranges_one(const char *path,  	if (!rc) {  		phys_addr_t	paddr;  		dma_addr_t	dma_addr; -		struct device	dev_bogus; +		struct device	*dev_bogus; -		dev_bogus.dma_range_map = map; -		paddr = dma_to_phys(&dev_bogus, expect_dma_addr); -		dma_addr = phys_to_dma(&dev_bogus, expect_paddr); +		dev_bogus = kzalloc(sizeof(struct device), GFP_KERNEL); +		if (!dev_bogus) { +			unittest(0, "kzalloc() failed\n"); +			kfree(map); +			return; +		} + +		dev_bogus->dma_range_map = map; +		paddr = dma_to_phys(dev_bogus, expect_dma_addr); +		dma_addr = phys_to_dma(dev_bogus, expect_paddr);  		unittest(paddr == expect_paddr,  			 "of_dma_get_range: wrong phys addr %pap (expecting %llx) on node %pOF\n", @@ -925,6 +932,7 @@ static void __init of_unittest_dma_ranges_one(const char *path,  			 &dma_addr, expect_dma_addr, np);  		kfree(map); +		kfree(dev_bogus);  	}  	of_node_put(np);  #endif @@ -934,8 +942,9 @@ static void __init of_unittest_parse_dma_ranges(void)  {  	of_unittest_dma_ranges_one("/testcase-data/address-tests/device@70000000",  		0x0, 0x20000000); -	of_unittest_dma_ranges_one("/testcase-data/address-tests/bus@80000000/device@1000", -		0x100000000, 0x20000000); +	if (IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT)) +		of_unittest_dma_ranges_one("/testcase-data/address-tests/bus@80000000/device@1000", +			0x100000000, 0x20000000);  	of_unittest_dma_ranges_one("/testcase-data/address-tests/pci@90000000",  		0x80000000, 0x20000000);  } @@ -1492,7 +1501,7 @@ static int __init unittest_data_add(void)  }  #ifdef CONFIG_OF_OVERLAY -static int __init overlay_data_apply(const char *overlay_name, int *overlay_id); +static int __init overlay_data_apply(const char *overlay_name, int *ovcs_id);  static int unittest_probe(struct platform_device *pdev)  { @@ -1657,7 +1666,7 @@ static void __init of_unittest_overlay_gpio(void)  	 * The overlays are applied by overlay_data_apply()  	 * instead of of_unittest_apply_overlay() so that they  	 * will not be tracked.  Thus they will not be removed -	 * by of_unittest_destroy_tracked_overlays(). +	 * by of_unittest_remove_tracked_overlays().  	 *  	 * - apply overlay_gpio_01  	 * - apply overlay_gpio_02a @@ -1905,86 +1914,70 @@ static const char *overlay_name_from_nr(int nr)  static const char *bus_path = "/testcase-data/overlay-node/test-bus"; -/* FIXME: it is NOT guaranteed that overlay ids are assigned in sequence */ - -#define MAX_UNITTEST_OVERLAYS	256 -static unsigned long overlay_id_bits[BITS_TO_LONGS(MAX_UNITTEST_OVERLAYS)]; -static int overlay_first_id = -1; +#define MAX_TRACK_OVCS_IDS 256 -static long of_unittest_overlay_tracked(int id) -{ -	if (WARN_ON(id >= MAX_UNITTEST_OVERLAYS)) -		return 0; -	return overlay_id_bits[BIT_WORD(id)] & BIT_MASK(id); -} +static int track_ovcs_id[MAX_TRACK_OVCS_IDS]; +static int track_ovcs_id_overlay_nr[MAX_TRACK_OVCS_IDS]; +static int track_ovcs_id_cnt; -static void of_unittest_track_overlay(int id) +static void of_unittest_track_overlay(int ovcs_id, int overlay_nr)  { -	if (overlay_first_id < 0) -		overlay_first_id = id; -	id -= overlay_first_id; - -	if (WARN_ON(id >= MAX_UNITTEST_OVERLAYS)) +	if (WARN_ON(track_ovcs_id_cnt >= MAX_TRACK_OVCS_IDS))  		return; -	overlay_id_bits[BIT_WORD(id)] |= BIT_MASK(id); + +	track_ovcs_id[track_ovcs_id_cnt] = ovcs_id; +	track_ovcs_id_overlay_nr[track_ovcs_id_cnt] = overlay_nr; +	track_ovcs_id_cnt++;  } -static void of_unittest_untrack_overlay(int id) +static void of_unittest_untrack_overlay(int ovcs_id)  { -	if (overlay_first_id < 0) +	if (WARN_ON(track_ovcs_id_cnt < 1))  		return; -	id -= overlay_first_id; -	if (WARN_ON(id >= MAX_UNITTEST_OVERLAYS)) -		return; -	overlay_id_bits[BIT_WORD(id)] &= ~BIT_MASK(id); -} -static void of_unittest_destroy_tracked_overlays(void) -{ -	int id, ret, defers, ovcs_id; +	track_ovcs_id_cnt--; -	if (overlay_first_id < 0) -		return; +	/* If out of synch then test is broken.  Do not try to recover. */ +	WARN_ON(track_ovcs_id[track_ovcs_id_cnt] != ovcs_id); +} -	/* try until no defers */ -	do { -		defers = 0; -		/* remove in reverse order */ -		for (id = MAX_UNITTEST_OVERLAYS - 1; id >= 0; id--) { -			if (!of_unittest_overlay_tracked(id)) -				continue; +static void of_unittest_remove_tracked_overlays(void) +{ +	int ret, ovcs_id, overlay_nr, save_ovcs_id; +	const char *overlay_name; -			ovcs_id = id + overlay_first_id; -			ret = of_overlay_remove(&ovcs_id); -			if (ret == -ENODEV) { -				pr_warn("%s: no overlay to destroy for #%d\n", -					__func__, id + overlay_first_id); -				continue; -			} -			if (ret != 0) { -				defers++; -				pr_warn("%s: overlay destroy failed for #%d\n", -					__func__, id + overlay_first_id); -				continue; -			} +	while (track_ovcs_id_cnt > 0) { -			of_unittest_untrack_overlay(id); +		ovcs_id = track_ovcs_id[track_ovcs_id_cnt - 1]; +		overlay_nr = track_ovcs_id_overlay_nr[track_ovcs_id_cnt - 1]; +		save_ovcs_id = ovcs_id; +		ret = of_overlay_remove(&ovcs_id); +		if (ret == -ENODEV) { +			overlay_name = overlay_name_from_nr(overlay_nr); +			pr_warn("%s: of_overlay_remove() for overlay \"%s\" failed, ret = %d\n", +				__func__, overlay_name, ret);  		} -	} while (defers > 0); +		of_unittest_untrack_overlay(save_ovcs_id); +	} +  } -static int __init of_unittest_apply_overlay(int overlay_nr, int *overlay_id) +static int __init of_unittest_apply_overlay(int overlay_nr, int *ovcs_id)  { +	/* +	 * The overlay will be tracked, thus it will be removed +	 * by of_unittest_remove_tracked_overlays(). +	 */ +  	const char *overlay_name;  	overlay_name = overlay_name_from_nr(overlay_nr); -	if (!overlay_data_apply(overlay_name, overlay_id)) { -		unittest(0, "could not apply overlay \"%s\"\n", -				overlay_name); +	if (!overlay_data_apply(overlay_name, ovcs_id)) { +		unittest(0, "could not apply overlay \"%s\"\n", overlay_name);  		return -EFAULT;  	} -	of_unittest_track_overlay(*overlay_id); +	of_unittest_track_overlay(*ovcs_id, overlay_nr);  	return 0;  } @@ -2029,7 +2022,7 @@ static int __init of_unittest_apply_revert_overlay_check(int overlay_nr,  		int unittest_nr, int before, int after,  		enum overlay_type ovtype)  { -	int ret, ovcs_id, save_id; +	int ret, ovcs_id, save_ovcs_id;  	/* unittest device must be in before state */  	if (of_unittest_device_exists(unittest_nr, ovtype) != before) { @@ -2057,7 +2050,7 @@ static int __init of_unittest_apply_revert_overlay_check(int overlay_nr,  		return -EINVAL;  	} -	save_id = ovcs_id; +	save_ovcs_id = ovcs_id;  	ret = of_overlay_remove(&ovcs_id);  	if (ret != 0) {  		unittest(0, "%s failed to be destroyed @\"%s\"\n", @@ -2065,7 +2058,7 @@ static int __init of_unittest_apply_revert_overlay_check(int overlay_nr,  				unittest_path(unittest_nr, ovtype));  		return ret;  	} -	of_unittest_untrack_overlay(save_id); +	of_unittest_untrack_overlay(save_ovcs_id);  	/* unittest device must be again in before state */  	if (of_unittest_device_exists(unittest_nr, PDEV_OVERLAY) != before) { @@ -2192,7 +2185,7 @@ static void __init of_unittest_overlay_5(void)  /* test overlay application in sequence */  static void __init of_unittest_overlay_6(void)  { -	int i, ov_id[2], ovcs_id; +	int i, save_ovcs_id[2], ovcs_id;  	int overlay_nr = 6, unittest_nr = 6;  	int before = 0, after = 1;  	const char *overlay_name; @@ -2225,8 +2218,8 @@ static void __init of_unittest_overlay_6(void)  		unittest(0, "could not apply overlay \"%s\"\n", overlay_name);  			return;  	} -	ov_id[0] = ovcs_id; -	of_unittest_track_overlay(ov_id[0]); +	save_ovcs_id[0] = ovcs_id; +	of_unittest_track_overlay(ovcs_id, overlay_nr + 0);  	EXPECT_END(KERN_INFO,  		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest6/status"); @@ -2242,8 +2235,8 @@ static void __init of_unittest_overlay_6(void)  		unittest(0, "could not apply overlay \"%s\"\n", overlay_name);  			return;  	} -	ov_id[1] = ovcs_id; -	of_unittest_track_overlay(ov_id[1]); +	save_ovcs_id[1] = ovcs_id; +	of_unittest_track_overlay(ovcs_id, overlay_nr + 1);  	EXPECT_END(KERN_INFO,  		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data/overlay-node/test-bus/test-unittest7/status"); @@ -2263,7 +2256,7 @@ static void __init of_unittest_overlay_6(void)  	}  	for (i = 1; i >= 0; i--) { -		ovcs_id = ov_id[i]; +		ovcs_id = save_ovcs_id[i];  		if (of_overlay_remove(&ovcs_id)) {  			unittest(0, "%s failed destroy @\"%s\"\n",  					overlay_name_from_nr(overlay_nr + i), @@ -2271,7 +2264,7 @@ static void __init of_unittest_overlay_6(void)  						PDEV_OVERLAY));  			return;  		} -		of_unittest_untrack_overlay(ov_id[i]); +		of_unittest_untrack_overlay(save_ovcs_id[i]);  	}  	for (i = 0; i < 2; i++) { @@ -2294,7 +2287,7 @@ static void __init of_unittest_overlay_6(void)  /* test overlay application in sequence */  static void __init of_unittest_overlay_8(void)  { -	int i, ov_id[2], ovcs_id; +	int i, save_ovcs_id[2], ovcs_id;  	int overlay_nr = 8, unittest_nr = 8;  	const char *overlay_name;  	int ret; @@ -2316,8 +2309,8 @@ static void __init of_unittest_overlay_8(void)  	if (!ret)  		return; -	ov_id[0] = ovcs_id; -	of_unittest_track_overlay(ov_id[0]); +	save_ovcs_id[0] = ovcs_id; +	of_unittest_track_overlay(ovcs_id, overlay_nr + 0);  	overlay_name = overlay_name_from_nr(overlay_nr + 1); @@ -2335,11 +2328,11 @@ static void __init of_unittest_overlay_8(void)  		return;  	} -	ov_id[1] = ovcs_id; -	of_unittest_track_overlay(ov_id[1]); +	save_ovcs_id[1] = ovcs_id; +	of_unittest_track_overlay(ovcs_id, overlay_nr + 1);  	/* now try to remove first overlay (it should fail) */ -	ovcs_id = ov_id[0]; +	ovcs_id = save_ovcs_id[0];  	EXPECT_BEGIN(KERN_INFO,  		     "OF: overlay: node_overlaps_later_cs: #6 overlaps with #7 @/testcase-data/overlay-node/test-bus/test-unittest8"); @@ -2356,6 +2349,10 @@ static void __init of_unittest_overlay_8(void)  		   "OF: overlay: node_overlaps_later_cs: #6 overlaps with #7 @/testcase-data/overlay-node/test-bus/test-unittest8");  	if (!ret) { +		/* +		 * Should never get here.  If we do, expect a lot of +		 * subsequent tracking and overlay removal related errors. +		 */  		unittest(0, "%s was destroyed @\"%s\"\n",  				overlay_name_from_nr(overlay_nr + 0),  				unittest_path(unittest_nr, @@ -2365,7 +2362,7 @@ static void __init of_unittest_overlay_8(void)  	/* removing them in order should work */  	for (i = 1; i >= 0; i--) { -		ovcs_id = ov_id[i]; +		ovcs_id = save_ovcs_id[i];  		if (of_overlay_remove(&ovcs_id)) {  			unittest(0, "%s not destroyed @\"%s\"\n",  					overlay_name_from_nr(overlay_nr + i), @@ -2373,7 +2370,7 @@ static void __init of_unittest_overlay_8(void)  						PDEV_OVERLAY));  			return;  		} -		of_unittest_untrack_overlay(ov_id[i]); +		of_unittest_untrack_overlay(save_ovcs_id[i]);  	}  	unittest(1, "overlay test %d passed\n", 8); @@ -2805,7 +2802,7 @@ static void __init of_unittest_overlay(void)  	of_unittest_overlay_gpio(); -	of_unittest_destroy_tracked_overlays(); +	of_unittest_remove_tracked_overlays();  out:  	of_node_put(bus_np); @@ -2837,7 +2834,7 @@ struct overlay_info {  	uint8_t		*dtb_begin;  	uint8_t		*dtb_end;  	int		expected_result; -	int		overlay_id; +	int		ovcs_id;  	char		*name;  }; @@ -2991,7 +2988,7 @@ void __init unittest_unflatten_overlay_base(void)   *   * Return 0 on unexpected error.   */ -static int __init overlay_data_apply(const char *overlay_name, int *overlay_id) +static int __init overlay_data_apply(const char *overlay_name, int *ovcs_id)  {  	struct overlay_info *info;  	int found = 0; @@ -3013,9 +3010,9 @@ static int __init overlay_data_apply(const char *overlay_name, int *overlay_id)  	if (!size)  		pr_err("no overlay data for %s\n", overlay_name); -	ret = of_overlay_fdt_apply(info->dtb_begin, size, &info->overlay_id); -	if (overlay_id) -		*overlay_id = info->overlay_id; +	ret = of_overlay_fdt_apply(info->dtb_begin, size, &info->ovcs_id); +	if (ovcs_id) +		*ovcs_id = info->ovcs_id;  	if (ret < 0)  		goto out;  |