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; |