summaryrefslogtreecommitdiff
path: root/test/dm
diff options
context:
space:
mode:
Diffstat (limited to 'test/dm')
-rw-r--r--test/dm/Makefile1
-rw-r--r--test/dm/bus.c242
-rw-r--r--test/dm/cmd_dm.c35
-rw-r--r--test/dm/core.c64
-rw-r--r--test/dm/test-driver.c11
-rw-r--r--test/dm/test-fdt.c164
-rw-r--r--test/dm/test-main.c4
-rw-r--r--test/dm/test.dts42
8 files changed, 512 insertions, 51 deletions
diff --git a/test/dm/Makefile b/test/dm/Makefile
index c0f2135..5c2415e 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -5,6 +5,7 @@
#
obj-$(CONFIG_CMD_DM) += cmd_dm.o
+obj-$(CONFIG_DM_TEST) += bus.o
obj-$(CONFIG_DM_TEST) += test-driver.o
obj-$(CONFIG_DM_TEST) += test-fdt.o
obj-$(CONFIG_DM_TEST) += test-main.o
diff --git a/test/dm/bus.c b/test/dm/bus.c
new file mode 100644
index 0000000..873d64e
--- /dev/null
+++ b/test/dm/bus.c
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/root.h>
+#include <dm/test.h>
+#include <dm/ut.h>
+#include <dm/util.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum {
+ FLAG_CHILD_PROBED = 10,
+ FLAG_CHILD_REMOVED = -7,
+};
+
+static struct dm_test_state *test_state;
+
+static int testbus_drv_probe(struct udevice *dev)
+{
+ return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
+}
+
+static int testbus_child_pre_probe(struct udevice *dev)
+{
+ struct dm_test_parent_data *parent_data = dev_get_parentdata(dev);
+
+ parent_data->flag += FLAG_CHILD_PROBED;
+
+ return 0;
+}
+
+static int testbus_child_post_remove(struct udevice *dev)
+{
+ struct dm_test_parent_data *parent_data = dev_get_parentdata(dev);
+ struct dm_test_state *dms = test_state;
+
+ parent_data->flag += FLAG_CHILD_REMOVED;
+ if (dms)
+ dms->removed = dev;
+
+ return 0;
+}
+
+static const struct udevice_id testbus_ids[] = {
+ {
+ .compatible = "denx,u-boot-test-bus",
+ .data = DM_TEST_TYPE_FIRST },
+ { }
+};
+
+U_BOOT_DRIVER(testbus_drv) = {
+ .name = "testbus_drv",
+ .of_match = testbus_ids,
+ .id = UCLASS_TEST_BUS,
+ .probe = testbus_drv_probe,
+ .priv_auto_alloc_size = sizeof(struct dm_test_priv),
+ .platdata_auto_alloc_size = sizeof(struct dm_test_pdata),
+ .per_child_auto_alloc_size = sizeof(struct dm_test_parent_data),
+ .child_pre_probe = testbus_child_pre_probe,
+ .child_post_remove = testbus_child_post_remove,
+};
+
+UCLASS_DRIVER(testbus) = {
+ .name = "testbus",
+ .id = UCLASS_TEST_BUS,
+};
+
+/* Test that we can probe for children */
+static int dm_test_bus_children(struct dm_test_state *dms)
+{
+ int num_devices = 4;
+ struct udevice *bus;
+ struct uclass *uc;
+
+ ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
+ ut_asserteq(num_devices, list_count_items(&uc->dev_head));
+
+ /* Probe the bus, which should yield 3 more devices */
+ ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
+ num_devices += 3;
+
+ ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
+ ut_asserteq(num_devices, list_count_items(&uc->dev_head));
+
+ ut_assert(!dm_check_devices(dms, num_devices));
+
+ return 0;
+}
+DM_TEST(dm_test_bus_children, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test our functions for accessing children */
+static int dm_test_bus_children_funcs(struct dm_test_state *dms)
+{
+ const void *blob = gd->fdt_blob;
+ struct udevice *bus, *dev;
+ int node;
+
+ ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
+
+ /* device_get_child() */
+ ut_assertok(device_get_child(bus, 0, &dev));
+ ut_asserteq(-ENODEV, device_get_child(bus, 4, &dev));
+ ut_assertok(device_get_child_by_seq(bus, 5, &dev));
+ ut_assert(dev->flags & DM_FLAG_ACTIVATED);
+ ut_asserteq_str("c-test@5", dev->name);
+
+ /* Device with sequence number 0 should be accessible */
+ ut_asserteq(-ENODEV, device_find_child_by_seq(bus, -1, true, &dev));
+ ut_assertok(device_find_child_by_seq(bus, 0, true, &dev));
+ ut_assert(!(dev->flags & DM_FLAG_ACTIVATED));
+ ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 0, false, &dev));
+ ut_assertok(device_get_child_by_seq(bus, 0, &dev));
+ ut_assert(dev->flags & DM_FLAG_ACTIVATED);
+
+ /* There is no device with sequence number 2 */
+ ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, false, &dev));
+ ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, true, &dev));
+ ut_asserteq(-ENODEV, device_get_child_by_seq(bus, 2, &dev));
+
+ /* Looking for something that is not a child */
+ node = fdt_path_offset(blob, "/junk");
+ ut_asserteq(-ENODEV, device_find_child_by_of_offset(bus, node, &dev));
+ node = fdt_path_offset(blob, "/d-test");
+ ut_asserteq(-ENODEV, device_find_child_by_of_offset(bus, node, &dev));
+
+ /* Find a valid child */
+ node = fdt_path_offset(blob, "/some-bus/c-test@1");
+ ut_assertok(device_find_child_by_of_offset(bus, node, &dev));
+ ut_assert(!(dev->flags & DM_FLAG_ACTIVATED));
+ ut_assertok(device_get_child_by_of_offset(bus, node, &dev));
+ ut_assert(dev->flags & DM_FLAG_ACTIVATED);
+
+ return 0;
+}
+DM_TEST(dm_test_bus_children_funcs, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that the bus can store data about each child */
+static int dm_test_bus_parent_data(struct dm_test_state *dms)
+{
+ struct dm_test_parent_data *parent_data;
+ struct udevice *bus, *dev;
+ struct uclass *uc;
+ int value;
+
+ ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
+
+ /* Check that parent data is allocated */
+ ut_assertok(device_find_child_by_seq(bus, 0, true, &dev));
+ ut_asserteq_ptr(NULL, dev_get_parentdata(dev));
+ ut_assertok(device_get_child_by_seq(bus, 0, &dev));
+ parent_data = dev_get_parentdata(dev);
+ ut_assert(NULL != parent_data);
+
+ /* Check that it starts at 0 and goes away when device is removed */
+ parent_data->sum += 5;
+ ut_asserteq(5, parent_data->sum);
+ device_remove(dev);
+ ut_asserteq_ptr(NULL, dev_get_parentdata(dev));
+
+ /* Check that we can do this twice */
+ ut_assertok(device_get_child_by_seq(bus, 0, &dev));
+ parent_data = dev_get_parentdata(dev);
+ ut_assert(NULL != parent_data);
+ parent_data->sum += 5;
+ ut_asserteq(5, parent_data->sum);
+
+ /* Add parent data to all children */
+ ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
+ value = 5;
+ uclass_foreach_dev(dev, uc) {
+ /* Ignore these if they are not on this bus */
+ if (dev->parent != bus) {
+ ut_asserteq_ptr(NULL, dev_get_parentdata(dev));
+ continue;
+ }
+ ut_assertok(device_probe(dev));
+ parent_data = dev_get_parentdata(dev);
+
+ parent_data->sum = value;
+ value += 5;
+ }
+
+ /* Check it is still there */
+ value = 5;
+ uclass_foreach_dev(dev, uc) {
+ /* Ignore these if they are not on this bus */
+ if (dev->parent != bus)
+ continue;
+ parent_data = dev_get_parentdata(dev);
+
+ ut_asserteq(value, parent_data->sum);
+ value += 5;
+ }
+
+ return 0;
+}
+
+DM_TEST(dm_test_bus_parent_data, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that the bus ops are called when a child is probed/removed */
+static int dm_test_bus_parent_ops(struct dm_test_state *dms)
+{
+ struct dm_test_parent_data *parent_data;
+ struct udevice *bus, *dev;
+ struct uclass *uc;
+
+ test_state = dms;
+ ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
+ ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
+
+ uclass_foreach_dev(dev, uc) {
+ /* Ignore these if they are not on this bus */
+ if (dev->parent != bus)
+ continue;
+ ut_asserteq_ptr(NULL, dev_get_parentdata(dev));
+
+ ut_assertok(device_probe(dev));
+ parent_data = dev_get_parentdata(dev);
+ ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag);
+ }
+
+ uclass_foreach_dev(dev, uc) {
+ /* Ignore these if they are not on this bus */
+ if (dev->parent != bus)
+ continue;
+ parent_data = dev_get_parentdata(dev);
+ ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag);
+ ut_assertok(device_remove(dev));
+ ut_asserteq_ptr(NULL, dev_get_parentdata(dev));
+ ut_asserteq_ptr(dms->removed, dev);
+ }
+ test_state = NULL;
+
+ return 0;
+}
+DM_TEST(dm_test_bus_parent_ops, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
diff --git a/test/dm/cmd_dm.c b/test/dm/cmd_dm.c
index 96f10f3..26980d2 100644
--- a/test/dm/cmd_dm.c
+++ b/test/dm/cmd_dm.c
@@ -16,6 +16,24 @@
#include <dm/test.h>
#include <dm/uclass-internal.h>
+/**
+ * dm_display_line() - Display information about a single device
+ *
+ * Displays a single line of information with an option prefix
+ *
+ * @dev: Device to display
+ * @buf: Prefix to display at the start of the line
+ */
+static void dm_display_line(struct udevice *dev, char *buf)
+{
+ printf("%s- %c %s @ %08lx", buf,
+ dev->flags & DM_FLAG_ACTIVATED ? '*' : ' ',
+ dev->name, (ulong)map_to_sysmem(dev));
+ if (dev->req_seq != -1)
+ printf(", %d", dev->req_seq);
+ puts("\n");
+}
+
static int display_succ(struct udevice *in, char *buf)
{
int len;
@@ -23,10 +41,7 @@ static int display_succ(struct udevice *in, char *buf)
char local[16];
struct udevice *pos, *n, *prev = NULL;
- printf("%s- %c %s @ %08lx", buf,
- in->flags & DM_FLAG_ACTIVATED ? '*' : ' ',
- in->name, (ulong)map_to_sysmem(in));
- puts("\n");
+ dm_display_line(in, buf);
if (list_empty(&in->child_head))
return 0;
@@ -81,12 +96,10 @@ static int do_dm_dump_uclass(cmd_tbl_t *cmdtp, int flag, int argc,
continue;
printf("uclass %d: %s\n", id, uc->uc_drv->name);
- for (ret = uclass_first_device(id, &dev);
- dev;
- ret = uclass_next_device(&dev)) {
- printf(" %c %s @ %08lx:\n",
- dev->flags & DM_FLAG_ACTIVATED ? '*' : ' ',
- dev->name, (ulong)map_to_sysmem(dev));
+ if (list_empty(&uc->dev_head))
+ continue;
+ list_for_each_entry(dev, &uc->dev_head, uclass_node) {
+ dm_display_line(dev, "");
}
puts("\n");
}
@@ -135,7 +148,7 @@ static int do_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
U_BOOT_CMD(
dm, 2, 1, do_dm,
"Driver model low level access",
- "tree Dump driver model tree\n"
+ "tree Dump driver model tree ('*' = activated)\n"
"dm uclass Dump list of instances for each uclass"
TEST_HELP
);
diff --git a/test/dm/core.c b/test/dm/core.c
index be3646b..b0cfb42 100644
--- a/test/dm/core.c
+++ b/test/dm/core.c
@@ -25,6 +25,7 @@ enum {
TEST_INTVAL2 = 3,
TEST_INTVAL3 = 6,
TEST_INTVAL_MANUAL = 101112,
+ TEST_INTVAL_PRE_RELOC = 7,
};
static const struct dm_test_pdata test_pdata[] = {
@@ -37,6 +38,10 @@ static const struct dm_test_pdata test_pdata_manual = {
.ping_add = TEST_INTVAL_MANUAL,
};
+static const struct dm_test_pdata test_pdata_pre_reloc = {
+ .ping_add = TEST_INTVAL_PRE_RELOC,
+};
+
U_BOOT_DEVICE(dm_test_info1) = {
.name = "test_drv",
.platdata = &test_pdata[0],
@@ -57,6 +62,11 @@ static struct driver_info driver_info_manual = {
.platdata = &test_pdata_manual,
};
+static struct driver_info driver_info_pre_reloc = {
+ .name = "test_pre_reloc_drv",
+ .platdata = &test_pdata_manual,
+};
+
/* Test that binding with platdata occurs correctly */
static int dm_test_autobind(struct dm_test_state *dms)
{
@@ -71,7 +81,7 @@ static int dm_test_autobind(struct dm_test_state *dms)
ut_asserteq(0, list_count_items(&gd->dm_root->child_head));
ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_POST_BIND]);
- ut_assertok(dm_scan_platdata());
+ ut_assertok(dm_scan_platdata(false));
/* We should have our test class now at least, plus more children */
ut_assert(1 < list_count_items(&gd->uclass_root));
@@ -106,7 +116,7 @@ static int dm_test_autoprobe(struct dm_test_state *dms)
ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]);
/* The root device should not be activated until needed */
- ut_assert(!(dms->root->flags & DM_FLAG_ACTIVATED));
+ ut_assert(dms->root->flags & DM_FLAG_ACTIVATED);
/*
* We should be able to find the three test devices, and they should
@@ -181,7 +191,7 @@ static int dm_test_lifecycle(struct dm_test_state *dms)
memcpy(op_count, dm_testdrv_op_count, sizeof(op_count));
- ut_assertok(device_bind_by_name(dms->root, &driver_info_manual,
+ ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual,
&dev));
ut_assert(dev);
ut_assert(dm_testdrv_op_count[DM_TEST_OP_BIND]
@@ -232,15 +242,15 @@ static int dm_test_ordering(struct dm_test_state *dms)
struct udevice *dev, *dev_penultimate, *dev_last, *test_dev;
int pingret;
- ut_assertok(device_bind_by_name(dms->root, &driver_info_manual,
+ ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual,
&dev));
ut_assert(dev);
/* Bind two new devices (numbers 4 and 5) */
- ut_assertok(device_bind_by_name(dms->root, &driver_info_manual,
+ ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual,
&dev_penultimate));
ut_assert(dev_penultimate);
- ut_assertok(device_bind_by_name(dms->root, &driver_info_manual,
+ ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual,
&dev_last));
ut_assert(dev_last);
@@ -255,7 +265,8 @@ static int dm_test_ordering(struct dm_test_state *dms)
ut_assert(dev_last == test_dev);
/* Add back the original device 3, now in position 5 */
- ut_assertok(device_bind_by_name(dms->root, &driver_info_manual, &dev));
+ ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual,
+ &dev));
ut_assert(dev);
/* Try ping */
@@ -375,8 +386,8 @@ static int dm_test_leak(struct dm_test_state *dms)
if (!start.uordblks)
puts("Warning: Please add '#define DEBUG' to the top of common/dlmalloc.c\n");
- ut_assertok(dm_scan_platdata());
- ut_assertok(dm_scan_fdt(gd->fdt_blob));
+ ut_assertok(dm_scan_platdata(false));
+ ut_assertok(dm_scan_fdt(gd->fdt_blob, false));
/* Scanning the uclass is enough to probe all the devices */
for (id = UCLASS_ROOT; id < UCLASS_COUNT; id++) {
@@ -444,8 +455,8 @@ static int create_children(struct dm_test_state *dms, struct udevice *parent,
for (i = 0; i < count; i++) {
struct dm_test_pdata *pdata;
- ut_assertok(device_bind_by_name(parent, &driver_info_manual,
- &dev));
+ ut_assertok(device_bind_by_name(parent, false,
+ &driver_info_manual, &dev));
pdata = calloc(1, sizeof(*pdata));
pdata->ping_add = key + i;
dev->platdata = pdata;
@@ -542,3 +553,34 @@ static int dm_test_children(struct dm_test_state *dms)
return 0;
}
DM_TEST(dm_test_children, 0);
+
+/* Test that pre-relocation devices work as expected */
+static int dm_test_pre_reloc(struct dm_test_state *dms)
+{
+ struct udevice *dev;
+
+ /* The normal driver should refuse to bind before relocation */
+ ut_asserteq(-EPERM, device_bind_by_name(dms->root, true,
+ &driver_info_manual, &dev));
+
+ /* But this one is marked pre-reloc */
+ ut_assertok(device_bind_by_name(dms->root, true,
+ &driver_info_pre_reloc, &dev));
+
+ return 0;
+}
+DM_TEST(dm_test_pre_reloc, 0);
+
+static int dm_test_uclass_before_ready(struct dm_test_state *dms)
+{
+ struct uclass *uc;
+
+ ut_assertok(uclass_get(UCLASS_TEST, &uc));
+
+ memset(gd, '\0', sizeof(*gd));
+ ut_asserteq_ptr(NULL, uclass_find(UCLASS_TEST));
+
+ return 0;
+}
+
+DM_TEST(dm_test_uclass_before_ready, 0);
diff --git a/test/dm/test-driver.c b/test/dm/test-driver.c
index 0f1a37b..bc6a6e7 100644
--- a/test/dm/test-driver.c
+++ b/test/dm/test-driver.c
@@ -144,3 +144,14 @@ U_BOOT_DRIVER(test_manual_drv) = {
.remove = test_manual_remove,
.unbind = test_manual_unbind,
};
+
+U_BOOT_DRIVER(test_pre_reloc_drv) = {
+ .name = "test_pre_reloc_drv",
+ .id = UCLASS_TEST,
+ .ops = &test_manual_ops,
+ .bind = test_manual_bind,
+ .probe = test_manual_probe,
+ .remove = test_manual_remove,
+ .unbind = test_manual_unbind,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index 98e3936..cd2c389 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -39,7 +39,8 @@ static int testfdt_ofdata_to_platdata(struct udevice *dev)
pdata->ping_add = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
"ping-add", -1);
- pdata->base = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg");
+ pdata->base = fdtdec_get_addr(gd->fdt_blob, dev->of_offset,
+ "ping-expect");
return 0;
}
@@ -90,55 +91,170 @@ UCLASS_DRIVER(testfdt) = {
.id = UCLASS_TEST_FDT,
};
+int dm_check_devices(struct dm_test_state *dms, int num_devices)
+{
+ struct udevice *dev;
+ int ret;
+ int i;
+
+ /*
+ * Now check that the ping adds are what we expect. This is using the
+ * ping-add property in each node.
+ */
+ for (i = 0; i < num_devices; i++) {
+ uint32_t base;
+
+ ret = uclass_get_device(UCLASS_TEST_FDT, i, &dev);
+ ut_assert(!ret);
+
+ /*
+ * Get the 'ping-expect' property, which tells us what the
+ * ping add should be. We don't use the platdata because we
+ * want to test the code that sets that up
+ * (testfdt_drv_probe()).
+ */
+ base = fdtdec_get_addr(gd->fdt_blob, dev->of_offset,
+ "ping-expect");
+ debug("dev=%d, base=%d: %s\n", i, base,
+ fdt_get_name(gd->fdt_blob, dev->of_offset, NULL));
+
+ ut_assert(!dm_check_operations(dms, dev, base,
+ dev_get_priv(dev)));
+ }
+
+ return 0;
+}
+
/* Test that FDT-based binding works correctly */
static int dm_test_fdt(struct dm_test_state *dms)
{
- const int num_drivers = 3;
+ const int num_devices = 4;
struct udevice *dev;
struct uclass *uc;
int ret;
int i;
- ret = dm_scan_fdt(gd->fdt_blob);
+ ret = dm_scan_fdt(gd->fdt_blob, false);
ut_assert(!ret);
ret = uclass_get(UCLASS_TEST_FDT, &uc);
ut_assert(!ret);
- /* These are num_drivers compatible root-level device tree nodes */
- ut_asserteq(num_drivers, list_count_items(&uc->dev_head));
+ /* These are num_devices compatible root-level device tree nodes */
+ ut_asserteq(num_devices, list_count_items(&uc->dev_head));
/* Each should have no platdata / priv */
- for (i = 0; i < num_drivers; i++) {
+ for (i = 0; i < num_devices; i++) {
ret = uclass_find_device(UCLASS_TEST_FDT, i, &dev);
ut_assert(!ret);
ut_assert(!dev_get_priv(dev));
ut_assert(!dev->platdata);
}
+ ut_assertok(dm_check_devices(dms, num_devices));
+
+ return 0;
+}
+DM_TEST(dm_test_fdt, 0);
+
+static int dm_test_fdt_pre_reloc(struct dm_test_state *dms)
+{
+ struct uclass *uc;
+ int ret;
+
+ ret = dm_scan_fdt(gd->fdt_blob, true);
+ ut_assert(!ret);
+
+ ret = uclass_get(UCLASS_TEST_FDT, &uc);
+ ut_assert(!ret);
+
+ /* These is only one pre-reloc device */
+ ut_asserteq(1, list_count_items(&uc->dev_head));
+
+ return 0;
+}
+DM_TEST(dm_test_fdt_pre_reloc, 0);
+
+/* Test that sequence numbers are allocated properly */
+static int dm_test_fdt_uclass_seq(struct dm_test_state *dms)
+{
+ struct udevice *dev;
+
+ /* A few basic santiy tests */
+ ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 3, true, &dev));
+ ut_asserteq_str("b-test", dev->name);
+
+ ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 0, true, &dev));
+ ut_asserteq_str("a-test", dev->name);
+
+ ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 5,
+ true, &dev));
+ ut_asserteq_ptr(NULL, dev);
+
+ /* Test aliases */
+ ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 6, &dev));
+ ut_asserteq_str("e-test", dev->name);
+
+ ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 7,
+ true, &dev));
+
/*
- * Now check that the ping adds are what we expect. This is using the
- * ping-add property in each node.
+ * Note that c-test nodes are not probed since it is not a top-level
+ * node
*/
- for (i = 0; i < num_drivers; i++) {
- uint32_t base;
+ ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 3, &dev));
+ ut_asserteq_str("b-test", dev->name);
- ret = uclass_get_device(UCLASS_TEST_FDT, i, &dev);
- ut_assert(!ret);
+ /*
+ * d-test wants sequence number 3 also, but it can't have it because
+ * b-test gets it first.
+ */
+ ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 2, &dev));
+ ut_asserteq_str("d-test", dev->name);
- /*
- * Get the 'reg' property, which tells us what the ping add
- * should be. We don't use the platdata because we want
- * to test the code that sets that up (testfdt_drv_probe()).
- */
- base = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg");
- debug("dev=%d, base=%d: %s\n", i, base,
- fdt_get_name(gd->fdt_blob, dev->of_offset, NULL));
+ /* d-test actually gets 0 */
+ ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 0, &dev));
+ ut_asserteq_str("d-test", dev->name);
- ut_assert(!dm_check_operations(dms, dev, base,
- dev_get_priv(dev)));
- }
+ /* initially no one wants seq 1 */
+ ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_TEST_FDT, 1,
+ &dev));
+ ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
+ ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 1, &dev));
+
+ /* But now that it is probed, we can find it */
+ ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 1, &dev));
+ ut_asserteq_str("a-test", dev->name);
return 0;
}
-DM_TEST(dm_test_fdt, 0);
+DM_TEST(dm_test_fdt_uclass_seq, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that we can find a device by device tree offset */
+static int dm_test_fdt_offset(struct dm_test_state *dms)
+{
+ const void *blob = gd->fdt_blob;
+ struct udevice *dev;
+ int node;
+
+ node = fdt_path_offset(blob, "/e-test");
+ ut_assert(node > 0);
+ ut_assertok(uclass_get_device_by_of_offset(UCLASS_TEST_FDT, node,
+ &dev));
+ ut_asserteq_str("e-test", dev->name);
+
+ /* This node should not be bound */
+ node = fdt_path_offset(blob, "/junk");
+ ut_assert(node > 0);
+ ut_asserteq(-ENODEV, uclass_get_device_by_of_offset(UCLASS_TEST_FDT,
+ node, &dev));
+
+ /* This is not a top level node so should not be probed */
+ node = fdt_path_offset(blob, "/some-bus/c-test@5");
+ ut_assert(node > 0);
+ ut_asserteq(-ENODEV, uclass_get_device_by_of_offset(UCLASS_TEST_FDT,
+ node, &dev));
+
+ return 0;
+}
+DM_TEST(dm_test_fdt_offset, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
diff --git a/test/dm/test-main.c b/test/dm/test-main.c
index fbdae68..94ce72a 100644
--- a/test/dm/test-main.c
+++ b/test/dm/test-main.c
@@ -89,11 +89,11 @@ int dm_test_main(void)
ut_assertok(dm_test_init(dms));
if (test->flags & DM_TESTF_SCAN_PDATA)
- ut_assertok(dm_scan_platdata());
+ ut_assertok(dm_scan_platdata(false));
if (test->flags & DM_TESTF_PROBE_TEST)
ut_assertok(do_autoprobe(dms));
if (test->flags & DM_TESTF_SCAN_FDT)
- ut_assertok(dm_scan_fdt(gd->fdt_blob));
+ ut_assertok(dm_scan_fdt(gd->fdt_blob, false));
if (test->func(dms))
break;
diff --git a/test/dm/test.dts b/test/dm/test.dts
index ec5364f..8489595 100644
--- a/test/dm/test.dts
+++ b/test/dm/test.dts
@@ -6,10 +6,22 @@
#address-cells = <1>;
#size-cells = <0>;
+ aliases {
+ console = &uart0;
+ testfdt6 = "/e-test";
+ };
+
+ uart0: serial {
+ compatible = "sandbox,serial";
+ u-boot,dm-pre-reloc;
+ };
+
a-test {
reg = <0>;
compatible = "denx,u-boot-fdt-test";
+ ping-expect = <0>;
ping-add = <0>;
+ u-boot,dm-pre-reloc;
};
junk {
@@ -24,23 +36,47 @@
b-test {
reg = <3>;
compatible = "denx,u-boot-fdt-test";
+ ping-expect = <3>;
ping-add = <3>;
};
some-bus {
#address-cells = <1>;
#size-cells = <0>;
- reg = <4>;
+ compatible = "denx,u-boot-test-bus";
+ reg = <3>;
+ ping-expect = <4>;
ping-add = <4>;
- c-test {
+ c-test@5 {
compatible = "denx,u-boot-fdt-test";
reg = <5>;
+ ping-expect = <5>;
ping-add = <5>;
};
+ c-test@0 {
+ compatible = "denx,u-boot-fdt-test";
+ reg = <0>;
+ ping-expect = <6>;
+ ping-add = <6>;
+ };
+ c-test@1 {
+ compatible = "denx,u-boot-fdt-test";
+ reg = <1>;
+ ping-expect = <7>;
+ ping-add = <7>;
+ };
};
d-test {
- reg = <6>;
+ reg = <3>;
+ ping-expect = <6>;
+ ping-add = <6>;
+ compatible = "google,another-fdt-test";
+ };
+
+ e-test {
+ reg = <3>;
+ ping-expect = <6>;
ping-add = <6>;
compatible = "google,another-fdt-test";
};