summaryrefslogtreecommitdiff
path: root/drivers/of/unittest.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/of/unittest.c')
-rw-r--r--drivers/of/unittest.c175
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;