/* Test that block devices can be created */ static int dm_test_blk_base(struct unit_test_state *uts) { struct udevice *blk1, *blk3, *dev; /* Make sure there are no block devices */ ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_BLK, 0, &dev)); /* Create two, one the parent of the other */ ut_assertok(blk_create_device(gd->dm_root, "sandbox_host_blk", "test", IF_TYPE_HOST, 1, 512, 2, &blk1)); ut_assertok(blk_create_device(blk1, "sandbox_host_blk", "test", IF_TYPE_HOST, 3, 512, 2, &blk3)); /* Check we can find them */ ut_asserteq(-ENODEV, blk_get_device(IF_TYPE_HOST, 0, &dev)); ut_assertok(blk_get_device(IF_TYPE_HOST, 1, &dev)); ut_asserteq_ptr(blk1, dev); ut_assertok(blk_get_device(IF_TYPE_HOST, 3, &dev)); ut_asserteq_ptr(blk3, dev); /* Check we can iterate */ ut_assertok(blk_first_device(IF_TYPE_HOST, &dev)); ut_asserteq_ptr(blk1, dev); ut_assertok(blk_next_device(&dev)); ut_asserteq_ptr(blk3, dev); return 0; }
/* 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; }
/* Test that we can iterate through children */ static int dm_test_bus_children_iterators(struct unit_test_state *uts) { struct udevice *bus, *dev, *child; /* Walk through the children one by one */ ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); ut_assertok(device_find_first_child(bus, &dev)); ut_asserteq_str("c-test@5", dev->name); ut_assertok(device_find_next_child(&dev)); ut_asserteq_str("c-test@0", dev->name); ut_assertok(device_find_next_child(&dev)); ut_asserteq_str("c-test@1", dev->name); ut_assertok(device_find_next_child(&dev)); ut_asserteq_ptr(dev, NULL); /* Move to the next child without using device_find_first_child() */ ut_assertok(device_find_child_by_seq(bus, 5, true, &dev)); ut_asserteq_str("c-test@5", dev->name); ut_assertok(device_find_next_child(&dev)); ut_asserteq_str("c-test@0", dev->name); /* Try a device with no children */ ut_assertok(device_find_first_child(dev, &child)); ut_asserteq_ptr(child, NULL); return 0; }
/* Test that the bus can store data about each child */ static int test_bus_parent_data(struct unit_test_state *uts) { 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_parent_priv(dev)); ut_assertok(device_get_child_by_seq(bus, 0, &dev)); parent_data = dev_get_parent_priv(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_parent_priv(dev)); /* Check that we can do this twice */ ut_assertok(device_get_child_by_seq(bus, 0, &dev)); parent_data = dev_get_parent_priv(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_parent_priv(dev)); continue; } ut_assertok(device_probe(dev)); parent_data = dev_get_parent_priv(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_parent_priv(dev); ut_asserteq(value, parent_data->sum); value += 5; } return 0; }
/** * lib_memcpy() - unit test for memcpy() * * Test memcpy() with varied alignment and length of the copied buffer. * * @uts: unit test state * Return: 0 = success, 1 = failure */ static int lib_memcpy(struct unit_test_state *uts) { u8 buf1[BUFLEN]; u8 buf2[BUFLEN]; int offset1, offset2, len; void *ptr; init_buffer(buf1, MASK); for (offset1 = 0; offset1 <= SWEEP; ++offset1) { for (offset2 = 0; offset2 <= SWEEP; ++offset2) { for (len = 1; len < BUFLEN - SWEEP; ++len) { init_buffer(buf2, 0); ptr = memcpy(buf2 + offset2, buf1 + offset1, len); ut_asserteq_ptr(buf2 + offset2, (u8 *)ptr); if (test_memmove(uts, buf2, MASK, offset1, offset2, len)) { debug("%s: failure %d, %d, %d\n", __func__, offset1, offset2, len); return CMD_RET_FAILURE; } } } } return 0; }
static int dm_test_uclass_devices_find_by_name(struct unit_test_state *uts) { struct udevice *finddev; struct udevice *testdev; int findret, ret; /* * For each test device found in fdt like: "a-test", "b-test", etc., * use its name and try to find it by uclass_find_device_by_name(). * Then, on success check if: * - current 'testdev' name is equal to the returned 'finddev' name * - current 'testdev' pointer is equal to the returned 'finddev' * * We assume that, each uclass's device name is unique, so if not, then * this will fail on checking condition: testdev == finddev, since the * uclass_find_device_by_name(), returns the first device by given name. */ for (ret = uclass_find_first_device(UCLASS_TEST_FDT, &testdev); testdev; ret = uclass_find_next_device(&testdev)) { ut_assertok(ret); ut_assert(testdev); findret = uclass_find_device_by_name(UCLASS_TEST_FDT, testdev->name, &finddev); ut_assertok(findret); ut_assert(testdev); ut_asserteq_str(testdev->name, finddev->name); ut_asserteq_ptr(testdev, finddev); } return 0; }
/* * Test that the bus' uclass' child_pre_probe() is called before the * device's probe() method */ static int dm_test_bus_child_pre_probe_uclass(struct unit_test_state *uts) { struct udevice *bus, *dev; int child_count; /* * See testfdt_drv_probe() which effectively checks that the uclass * flag is set before that method is called */ ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); for (device_find_first_child(bus, &dev), child_count = 0; dev; device_find_next_child(&dev)) { struct dm_test_priv *priv = dev_get_priv(dev); /* Check that things happened in the right order */ ut_asserteq_ptr(NULL, priv); ut_assertok(device_probe(dev)); priv = dev_get_priv(dev); ut_assert(priv != NULL); ut_asserteq(1, priv->uclass_flag); ut_asserteq(1, priv->uclass_total); child_count++; } ut_asserteq(3, child_count); return 0; }
/* Test regulator autoset method */ static int dm_test_power_regulator_autoset(struct unit_test_state *uts) { const char *platname; struct udevice *dev, *dev_autoset; /* * Test the BUCK1 with fdt properties * - min-microvolt = max-microvolt = 1200000 * - min-microamp = max-microamp = 200000 * - always-on = set * - boot-on = not set * Expected output state: uV=1200000; uA=200000; output enabled */ platname = regulator_names[BUCK1][PLATNAME]; ut_assertok(regulator_autoset_by_name(platname, &dev_autoset)); /* Check, that the returned device is proper */ ut_assertok(regulator_get_by_platname(platname, &dev)); ut_asserteq_ptr(dev, dev_autoset); /* Check the setup after autoset */ ut_asserteq(regulator_get_value(dev), SANDBOX_BUCK1_AUTOSET_EXPECTED_UV); ut_asserteq(regulator_get_current(dev), SANDBOX_BUCK1_AUTOSET_EXPECTED_UA); ut_asserteq(regulator_get_enable(dev), SANDBOX_BUCK1_AUTOSET_EXPECTED_ENABLE); return 0; }
/* Test that block devices work correctly with USB */ static int dm_test_blk_usb(struct unit_test_state *uts) { struct udevice *usb_dev, *dev; struct blk_desc *dev_desc; /* Get a flash device */ state_set_skip_delays(true); ut_assertok(usb_init()); ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &usb_dev)); ut_assertok(blk_get_device_by_str("usb", "0", &dev_desc)); /* The parent should be a block device */ ut_assertok(blk_get_device(IF_TYPE_USB, 0, &dev)); ut_asserteq_ptr(usb_dev, dev_get_parent(dev)); /* Check we have one block device for each mass storage device */ ut_asserteq(6, count_blk_devices()); /* Now go around again, making sure the old devices were unbound */ ut_assertok(usb_stop()); ut_assertok(usb_init()); ut_asserteq(6, count_blk_devices()); ut_assertok(usb_stop()); return 0; }
/* Test that block device numbering works as expected */ static int dm_test_blk_devnum(struct unit_test_state *uts) { struct udevice *dev, *mmc_dev, *parent; int i; /* * Probe the devices, with the first one being probed last. This is the * one with no alias / sequence numnber. */ ut_assertok(uclass_get_device(UCLASS_MMC, 1, &dev)); ut_assertok(uclass_get_device(UCLASS_MMC, 2, &dev)); ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev)); for (i = 0; i < 3; i++) { struct blk_desc *desc; /* Check that the bblock device is attached */ ut_assertok(uclass_get_device_by_seq(UCLASS_MMC, i, &mmc_dev)); ut_assertok(blk_find_device(IF_TYPE_MMC, i, &dev)); parent = dev_get_parent(dev); ut_asserteq_ptr(parent, mmc_dev); ut_asserteq(trailing_strtol(mmc_dev->name), i); /* * Check that the block device devnum matches its parent's * sequence number */ desc = dev_get_uclass_platdata(dev); ut_asserteq(desc->devnum, i); } return 0; }
/* Test obtaining an LED by label */ static int dm_test_led_label(struct unit_test_state *uts) { struct udevice *dev, *cmp; ut_assertok(led_get_by_label("sandbox:red", &dev)); ut_asserteq(1, device_active(dev)); ut_assertok(uclass_get_device(UCLASS_LED, 1, &cmp)); ut_asserteq_ptr(dev, cmp); ut_assertok(led_get_by_label("sandbox:green", &dev)); ut_asserteq(1, device_active(dev)); ut_assertok(uclass_get_device(UCLASS_LED, 2, &cmp)); ut_asserteq_ptr(dev, cmp); ut_asserteq(-ENODEV, led_get_by_label("sandbox:blue", &dev)); return 0; }
/* Test that we can find block devices without probing them */ static int dm_test_blk_find(struct unit_test_state *uts) { struct udevice *blk, *dev; ut_assertok(blk_create_device(gd->dm_root, "sandbox_host_blk", "test", IF_TYPE_HOST, 1, 512, 2, &blk)); ut_asserteq(-ENODEV, blk_find_device(IF_TYPE_HOST, 0, &dev)); ut_assertok(blk_find_device(IF_TYPE_HOST, 1, &dev)); ut_asserteq_ptr(blk, dev); ut_asserteq(false, device_active(dev)); /* Now activate it */ ut_assertok(blk_get_device(IF_TYPE_HOST, 1, &dev)); ut_asserteq_ptr(blk, dev); ut_asserteq(true, device_active(dev)); return 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; }
/* Test that sequence numbers are allocated properly */ static int dm_test_fdt_uclass_seq(struct unit_test_state *uts) { 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, 8, 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)); /* * Note that c-test nodes are not probed since it is not a top-level * node */ ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 3, &dev)); ut_asserteq_str("b-test", dev->name); /* * 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); /* d-test actually gets 0 */ ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 0, &dev)); ut_asserteq_str("d-test", dev->name); /* 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, 4, &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("f-test", dev->name); return 0; }
/* Test we can access a regmap through syscon */ static int dm_test_regmap_syscon(struct unit_test_state *uts) { struct regmap *map; map = syscon_get_regmap_by_driver_data(SYSCON0); ut_assertok_ptr(map); ut_asserteq(1, map->range_count); map = syscon_get_regmap_by_driver_data(SYSCON1); ut_assertok_ptr(map); ut_asserteq(4, map->range_count); map = syscon_get_regmap_by_driver_data(SYSCON_COUNT); ut_asserteq_ptr(ERR_PTR(-ENODEV), map); ut_asserteq(0x10, map_to_sysmem(syscon_get_first_range(SYSCON0))); ut_asserteq(0x20, map_to_sysmem(syscon_get_first_range(SYSCON1))); ut_asserteq_ptr(ERR_PTR(-ENODEV), syscon_get_first_range(SYSCON_COUNT)); return 0; }
/* Base test of register maps */ static int dm_test_regmap_base(struct unit_test_state *uts) { struct udevice *dev; struct regmap *map; ofnode node; int i; ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev)); map = syscon_get_regmap(dev); ut_assertok_ptr(map); ut_asserteq(1, map->range_count); ut_asserteq(0x10, map->ranges[0].start); ut_asserteq(4, map->ranges[0].size); ut_asserteq(0x10, map_to_sysmem(regmap_get_range(map, 0))); ut_assertok(uclass_get_device(UCLASS_SYSCON, 1, &dev)); map = syscon_get_regmap(dev); ut_assertok_ptr(map); ut_asserteq(4, map->range_count); ut_asserteq(0x20, map->ranges[0].start); for (i = 0; i < 4; i++) { const unsigned long addr = 0x20 + 8 * i; ut_asserteq(addr, map->ranges[i].start); ut_asserteq(5 + i, map->ranges[i].size); ut_asserteq(addr, map_to_sysmem(regmap_get_range(map, i))); } /* Check that we can't pretend a different device is a syscon */ ut_assertok(uclass_get_device(UCLASS_I2C, 0, &dev)); map = syscon_get_regmap(dev); ut_asserteq_ptr(ERR_PTR(-ENOEXEC), map); /* A different device can be a syscon by using Linux-compat API */ node = ofnode_path("/syscon@2"); ut_assert(ofnode_valid(node)); map = syscon_node_to_regmap(node); ut_assertok_ptr(map); ut_asserteq(4, map->range_count); ut_asserteq(0x40, map->ranges[0].start); for (i = 0; i < 4; i++) { const unsigned long addr = 0x40 + 8 * i; ut_asserteq(addr, map->ranges[i].start); ut_asserteq(5 + i, map->ranges[i].size); ut_asserteq(addr, map_to_sysmem(regmap_get_range(map, i))); } return 0; }
static int dm_test_uclass_before_ready(struct unit_test_state *uts) { struct uclass *uc; ut_assertok(uclass_get(UCLASS_TEST, &uc)); gd->dm_root = NULL; gd->dm_root_f = NULL; memset(&gd->uclass_root, '\0', sizeof(gd->uclass_root)); ut_asserteq_ptr(NULL, uclass_find(UCLASS_TEST)); return 0; }
/* Base test of register maps */ static int dm_test_regmap_base(struct unit_test_state *uts) { struct udevice *dev; struct regmap *map; int i; ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev)); map = syscon_get_regmap(dev); ut_assertok_ptr(map); ut_asserteq(1, map->range_count); ut_asserteq(0x10, map->base); ut_asserteq(0x10, map->range->start); ut_asserteq(4, map->range->size); ut_asserteq_ptr(&map->base_range, map->range); ut_asserteq(0x10, map_to_sysmem(regmap_get_range(map, 0))); ut_assertok(uclass_get_device(UCLASS_SYSCON, 1, &dev)); map = syscon_get_regmap(dev); ut_assertok_ptr(map); ut_asserteq(4, map->range_count); ut_asserteq(0x20, map->base); ut_assert(&map->base_range != map->range); for (i = 0; i < 4; i++) { const unsigned long addr = 0x20 + 8 * i; ut_asserteq(addr, map->range[i].start); ut_asserteq(5 + i, map->range[i].size); ut_asserteq(addr, map_to_sysmem(regmap_get_range(map, i))); } /* Check that we can't pretend a different device is a syscon */ ut_assertok(uclass_get_device(UCLASS_I2C, 0, &dev)); map = syscon_get_regmap(dev); ut_asserteq_ptr(ERR_PTR(-ENOEXEC), map); return 0; }
/* Test that sandbox anonymous GPIOs work correctly */ static int dm_test_gpio_anon(struct dm_test_state *dms) { unsigned int offset, gpio; struct udevice *dev; const char *name; int offset_count; /* And the anonymous bank */ ut_assertok(gpio_lookup_name("14", &dev, &offset, &gpio)); ut_asserteq_str(dev->name, "gpio_sandbox"); ut_asserteq(14, offset); ut_asserteq(14, gpio); name = gpio_get_bank_info(dev, &offset_count); ut_asserteq_ptr(NULL, name); ut_asserteq(CONFIG_SANDBOX_GPIO_COUNT, offset_count); return 0; }
static int dm_test_dma_rx(struct unit_test_state *uts) { struct udevice *dev; struct dma dma_tx, dma_rx; u8 src_buf[512]; u8 dst_buf[512]; void *dst_ptr; size_t len = 512; u32 meta1, meta2; int i; ut_assertok(uclass_get_device_by_name(UCLASS_DMA, "dma", &dev)); ut_assertok(dma_get_by_name(dev, "tx0", &dma_tx)); ut_assertok(dma_get_by_name(dev, "rx0", &dma_rx)); ut_assertok(dma_enable(&dma_tx)); ut_assertok(dma_enable(&dma_rx)); memset(dst_buf, 0, len); for (i = 0; i < len; i++) src_buf[i] = i; meta1 = 0xADADDEAD; meta2 = 0; dst_ptr = NULL; ut_assertok(dma_prepare_rcv_buf(&dma_tx, dst_buf, len)); ut_assertok(dma_send(&dma_tx, src_buf, len, &meta1)); ut_asserteq(len, dma_receive(&dma_rx, &dst_ptr, &meta2)); ut_asserteq(0xADADDEAD, meta2); ut_asserteq_ptr(dst_buf, dst_ptr); ut_assertok(dma_disable(&dma_tx)); ut_assertok(dma_disable(&dma_rx)); ut_assertok(dma_free(&dma_tx)); ut_assertok(dma_free(&dma_rx)); ut_assertok(memcmp(src_buf, dst_buf, len)); return 0; }
static int dm_test_uclass_devices_get_by_name(struct unit_test_state *uts) { struct udevice *finddev; struct udevice *testdev; int ret, findret; /* * For each test device found in fdt like: "a-test", "b-test", etc., * use its name and try to get it by uclass_get_device_by_name(). * On success check if: * - returned finddev' is active * - current 'testdev' name is equal to the returned 'finddev' name * - current 'testdev' pointer is equal to the returned 'finddev' * * We asserts that the 'testdev' is active on each loop entry, so we * could be sure that the 'finddev' is activated too, but for sure * we check it again. * * We assume that, each uclass's device name is unique, so if not, then * this will fail on checking condition: testdev == finddev, since the * uclass_get_device_by_name(), returns the first device by given name. */ for (ret = uclass_first_device(UCLASS_TEST_FDT, &testdev); testdev; ret = uclass_next_device(&testdev)) { ut_assertok(ret); ut_assert(testdev); ut_assert(device_active(testdev)); findret = uclass_get_device_by_name(UCLASS_TEST_FDT, testdev->name, &finddev); ut_assertok(findret); ut_assert(finddev); ut_assert(device_active(finddev)); ut_asserteq_str(testdev->name, finddev->name); ut_asserteq_ptr(testdev, finddev); } return 0; }
/* Test regulator get method */ static int dm_test_power_regulator_get(struct unit_test_state *uts) { struct dm_regulator_uclass_platdata *uc_pdata; struct udevice *dev_by_devname; struct udevice *dev_by_platname; const char *devname; const char *platname; int i; for (i = 0; i < OUTPUT_COUNT; i++) { /* * Do the test for each regulator's devname and platname, * which are related to a single device. */ devname = regulator_names[i][DEVNAME]; platname = regulator_names[i][PLATNAME]; /* * Check, that regulator_get_by_devname() function, returns * a device with the name equal to the requested one. */ ut_assertok(regulator_get_by_devname(devname, &dev_by_devname)); ut_asserteq_str(devname, dev_by_devname->name); /* * Check, that regulator_get_by_platname() function, returns * a device with the name equal to the requested one. */ ut_assertok(regulator_get_by_platname(platname, &dev_by_platname)); uc_pdata = dev_get_uclass_platdata(dev_by_platname); ut_assert(uc_pdata); ut_asserteq_str(platname, uc_pdata->name); /* * Check, that the pointers returned by both get functions, * points to the same regulator device. */ ut_asserteq_ptr(dev_by_devname, dev_by_platname); } return 0; }
/** * lib_memset() - unit test for memset() * * Test memset() with varied alignment and length of the changed buffer. * * @uts: unit test state * Return: 0 = success, 1 = failure */ static int lib_memset(struct unit_test_state *uts) { u8 buf[BUFLEN]; int offset, len; void *ptr; for (offset = 0; offset <= SWEEP; ++offset) { for (len = 1; len < BUFLEN - SWEEP; ++len) { init_buffer(buf, 0); ptr = memset(buf + offset, MASK, len); ut_asserteq_ptr(buf + offset, (u8 *)ptr); if (test_memset(uts, buf, MASK, offset, len)) { debug("%s: failure %d, %d\n", __func__, offset, len); return CMD_RET_FAILURE; } } } return 0; }
static int dm_test_children(struct unit_test_state *uts) { struct dm_test_state *dms = uts->priv; struct udevice *top[NODE_COUNT]; struct udevice *child[NODE_COUNT]; struct udevice *grandchild[NODE_COUNT]; struct udevice *dev; int total; int ret; int i; /* We don't care about the numbering for this test */ dms->skip_post_probe = 1; ut_assert(NODE_COUNT > 5); /* First create 10 top-level children */ ut_assertok(create_children(uts, dms->root, NODE_COUNT, 0, top)); /* Now a few have their own children */ ut_assertok(create_children(uts, top[2], NODE_COUNT, 2, NULL)); ut_assertok(create_children(uts, top[5], NODE_COUNT, 5, child)); /* And grandchildren */ for (i = 0; i < NODE_COUNT; i++) ut_assertok(create_children(uts, child[i], NODE_COUNT, 50 * i, i == 2 ? grandchild : NULL)); /* Check total number of devices */ total = NODE_COUNT * (3 + NODE_COUNT); ut_asserteq(total, dm_testdrv_op_count[DM_TEST_OP_BIND]); /* Try probing one of the grandchildren */ ut_assertok(uclass_get_device(UCLASS_TEST, NODE_COUNT * 3 + 2 * NODE_COUNT, &dev)); ut_asserteq_ptr(grandchild[0], dev); /* * This should have probed the child and top node also, for a total * of 3 nodes. */ ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_PROBE]); /* Probe the other grandchildren */ for (i = 1; i < NODE_COUNT; i++) ut_assertok(device_probe(grandchild[i])); ut_asserteq(2 + NODE_COUNT, dm_testdrv_op_count[DM_TEST_OP_PROBE]); /* Probe everything */ for (ret = uclass_first_device(UCLASS_TEST, &dev); dev; ret = uclass_next_device(&dev)) ; ut_assertok(ret); ut_asserteq(total, dm_testdrv_op_count[DM_TEST_OP_PROBE]); /* Remove a top-level child and check that the children are removed */ ut_assertok(device_remove(top[2])); ut_asserteq(NODE_COUNT + 1, dm_testdrv_op_count[DM_TEST_OP_REMOVE]); dm_testdrv_op_count[DM_TEST_OP_REMOVE] = 0; /* Try one with grandchildren */ ut_assertok(uclass_get_device(UCLASS_TEST, 5, &dev)); ut_asserteq_ptr(dev, top[5]); ut_assertok(device_remove(dev)); ut_asserteq(1 + NODE_COUNT * (1 + NODE_COUNT), dm_testdrv_op_count[DM_TEST_OP_REMOVE]); /* Try the same with unbind */ ut_assertok(device_unbind(top[2])); ut_asserteq(NODE_COUNT + 1, dm_testdrv_op_count[DM_TEST_OP_UNBIND]); dm_testdrv_op_count[DM_TEST_OP_UNBIND] = 0; /* Try one with grandchildren */ ut_assertok(uclass_get_device(UCLASS_TEST, 5, &dev)); ut_asserteq_ptr(dev, top[6]); ut_assertok(device_unbind(top[5])); ut_asserteq(1 + NODE_COUNT * (1 + NODE_COUNT), dm_testdrv_op_count[DM_TEST_OP_UNBIND]); return 0; }
/* Test that we can find buses and chip-selects */ static int dm_test_spi_find(struct dm_test_state *dms) { struct sandbox_state *state = state_get_current(); struct spi_slave *slave; struct udevice *bus, *dev; const int busnum = 0, cs = 0, mode = 0, speed = 1000000, cs_b = 1; struct spi_cs_info info; int of_offset; ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_SPI, busnum, false, &bus)); /* * spi_post_bind() will bind devices to chip selects. Check this then * remove the emulation and the slave device. */ ut_asserteq(0, uclass_get_device_by_seq(UCLASS_SPI, busnum, &bus)); ut_assertok(spi_cs_info(bus, cs, &info)); of_offset = info.dev->of_offset; device_remove(info.dev); device_unbind(info.dev); /* * Even though the device is gone, the sandbox SPI drivers always * reports that CS 0 is present */ ut_assertok(spi_cs_info(bus, cs, &info)); ut_asserteq_ptr(NULL, info.dev); /* This finds nothing because we removed the device */ ut_asserteq(-ENODEV, spi_find_bus_and_cs(busnum, cs, &bus, &dev)); ut_asserteq(-ENODEV, spi_get_bus_and_cs(busnum, cs, speed, mode, NULL, 0, &bus, &slave)); /* * This forces the device to be re-added, but there is no emulation * connected so the probe will fail. We require that bus is left * alone on failure, and that the spi_get_bus_and_cs() does not add * a 'partially-inited' device. */ ut_asserteq(-ENODEV, spi_find_bus_and_cs(busnum, cs, &bus, &dev)); ut_asserteq(-ENOENT, spi_get_bus_and_cs(busnum, cs, speed, mode, "spi_flash_std", "name", &bus, &slave)); sandbox_sf_unbind_emul(state_get_current(), busnum, cs); ut_assertok(spi_cs_info(bus, cs, &info)); ut_asserteq_ptr(NULL, info.dev); /* Add the emulation and try again */ ut_assertok(sandbox_sf_bind_emul(state, busnum, cs, bus, of_offset, "name")); ut_assertok(spi_find_bus_and_cs(busnum, cs, &bus, &dev)); ut_assertok(spi_get_bus_and_cs(busnum, cs, speed, mode, "spi_flash_std", "name", &bus, &slave)); ut_assertok(spi_cs_info(bus, cs, &info)); ut_asserteq_ptr(info.dev, slave->dev); /* We should be able to add something to another chip select */ ut_assertok(sandbox_sf_bind_emul(state, busnum, cs_b, bus, of_offset, "name")); ut_assertok(spi_get_bus_and_cs(busnum, cs_b, speed, mode, "spi_flash_std", "name", &bus, &slave)); ut_assertok(spi_cs_info(bus, cs_b, &info)); ut_asserteq_ptr(info.dev, slave->dev); /* * Since we are about to destroy all devices, we must tell sandbox * to forget the emulation device */ sandbox_sf_unbind_emul(state_get_current(), busnum, cs); sandbox_sf_unbind_emul(state_get_current(), busnum, cs_b); return 0; }
/* Test that we can find GPIOs using phandles */ static int dm_test_gpio_phandles(struct dm_test_state *dms) { struct gpio_desc desc, desc_list[8], desc_list2[8]; struct udevice *dev, *gpio_a, *gpio_b; ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev)); ut_asserteq_str("a-test", dev->name); ut_assertok(gpio_request_by_name(dev, "test-gpios", 1, &desc, 0)); ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio_a)); ut_assertok(uclass_get_device(UCLASS_GPIO, 2, &gpio_b)); ut_asserteq_str("base-gpios", gpio_a->name); ut_asserteq(true, !!device_active(gpio_a)); ut_asserteq_ptr(gpio_a, desc.dev); ut_asserteq(4, desc.offset); /* GPIOF_INPUT is the sandbox GPIO driver default */ ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_a, 4, NULL)); ut_assertok(dm_gpio_free(dev, &desc)); ut_asserteq(-ENOENT, gpio_request_by_name(dev, "test-gpios", 3, &desc, 0)); ut_asserteq_ptr(NULL, desc.dev); ut_asserteq(desc.offset, 0); ut_asserteq(-ENOENT, gpio_request_by_name(dev, "test-gpios", 5, &desc, 0)); /* Last GPIO is ignord as it comes after <0> */ ut_asserteq(3, gpio_request_list_by_name(dev, "test-gpios", desc_list, ARRAY_SIZE(desc_list), 0)); ut_asserteq(-EBUSY, gpio_request_list_by_name(dev, "test-gpios", desc_list2, ARRAY_SIZE(desc_list2), 0)); ut_assertok(gpio_free_list(dev, desc_list, 3)); ut_asserteq(3, gpio_request_list_by_name(dev, "test-gpios", desc_list, ARRAY_SIZE(desc_list), GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE)); ut_asserteq_ptr(gpio_a, desc_list[0].dev); ut_asserteq(1, desc_list[0].offset); ut_asserteq_ptr(gpio_a, desc_list[1].dev); ut_asserteq(4, desc_list[1].offset); ut_asserteq_ptr(gpio_b, desc_list[2].dev); ut_asserteq(5, desc_list[2].offset); ut_asserteq(1, dm_gpio_get_value(desc_list)); ut_assertok(gpio_free_list(dev, desc_list, 3)); ut_asserteq(6, gpio_request_list_by_name(dev, "test2-gpios", desc_list, ARRAY_SIZE(desc_list), 0)); /* This was set to output previously, so still will be */ ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_a, 1, NULL)); /* Active low should invert the input value */ ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_b, 6, NULL)); ut_asserteq(1, dm_gpio_get_value(&desc_list[2])); ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_b, 7, NULL)); ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_b, 8, NULL)); ut_asserteq(0, dm_gpio_get_value(&desc_list[4])); ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_b, 9, NULL)); ut_asserteq(1, dm_gpio_get_value(&desc_list[5])); return 0; }
static int test_bus_parent_platdata(struct unit_test_state *uts) { struct dm_test_parent_platdata *plat; struct udevice *bus, *dev; int child_count; /* Check that the bus has no children */ ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus)); device_find_first_child(bus, &dev); ut_asserteq_ptr(NULL, dev); ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); for (device_find_first_child(bus, &dev), child_count = 0; dev; device_find_next_child(&dev)) { /* Check that platform data is allocated */ plat = dev_get_parent_platdata(dev); ut_assert(plat != NULL); /* * Check that it is not affected by the device being * probed/removed */ plat->count++; ut_asserteq(1, plat->count); device_probe(dev); device_remove(dev); ut_asserteq_ptr(plat, dev_get_parent_platdata(dev)); ut_asserteq(1, plat->count); ut_assertok(device_probe(dev)); child_count++; } ut_asserteq(3, child_count); /* Removing the bus should also have no effect (it is still bound) */ device_remove(bus); for (device_find_first_child(bus, &dev), child_count = 0; dev; device_find_next_child(&dev)) { /* Check that platform data is allocated */ plat = dev_get_parent_platdata(dev); ut_assert(plat != NULL); ut_asserteq(1, plat->count); child_count++; } ut_asserteq(3, child_count); /* Unbind all the children */ do { device_find_first_child(bus, &dev); if (dev) device_unbind(dev); } while (dev); /* Now the child platdata should be removed and re-added */ device_probe(bus); for (device_find_first_child(bus, &dev), child_count = 0; dev; device_find_next_child(&dev)) { /* Check that platform data is allocated */ plat = dev_get_parent_platdata(dev); ut_assert(plat != NULL); ut_asserteq(0, plat->count); child_count++; } ut_asserteq(3, child_count); return 0; }
/* Test that sandbox GPIOs work correctly */ static int dm_test_gpio(struct dm_test_state *dms) { unsigned int offset, gpio; struct dm_gpio_ops *ops; struct udevice *dev; const char *name; int offset_count; char buf[80]; /* * We expect to get 3 banks. One is anonymous (just numbered) and * comes from platdata. The other two are named a (20 gpios) * and b (10 gpios) and come from the device tree. See * test/dm/test.dts. */ ut_assertok(gpio_lookup_name("b4", &dev, &offset, &gpio)); ut_asserteq_str(dev->name, "extra-gpios"); ut_asserteq(4, offset); ut_asserteq(CONFIG_SANDBOX_GPIO_COUNT + 20 + 4, gpio); name = gpio_get_bank_info(dev, &offset_count); ut_asserteq_str("b", name); ut_asserteq(10, offset_count); /* Get the operations for this device */ ops = gpio_get_ops(dev); ut_assert(ops->get_state); /* Cannot get a value until it is reserved */ ut_asserteq(-1, ops->get_value(dev, offset)); /* * Now some tests that use the 'sandbox' back door. All GPIOs * should default to input, include b4 that we are using here. */ ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf))); ut_asserteq_str("b4: in: 0 [ ]", buf); /* Change it to an output */ sandbox_gpio_set_direction(dev, offset, 1); ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf))); ut_asserteq_str("b4: out: 0 [ ]", buf); sandbox_gpio_set_value(dev, offset, 1); ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf))); ut_asserteq_str("b4: out: 1 [ ]", buf); ut_assertok(ops->request(dev, offset, "testing")); ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf))); ut_asserteq_str("b4: out: 1 [x] testing", buf); /* Change the value a bit */ ut_asserteq(1, ops->get_value(dev, offset)); ut_assertok(ops->set_value(dev, offset, 0)); ut_asserteq(0, ops->get_value(dev, offset)); ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf))); ut_asserteq_str("b4: out: 0 [x] testing", buf); ut_assertok(ops->set_value(dev, offset, 1)); ut_asserteq(1, ops->get_value(dev, offset)); /* Make it an input */ ut_assertok(ops->direction_input(dev, offset)); ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf))); ut_asserteq_str("b4: in: 1 [x] testing", buf); sandbox_gpio_set_value(dev, offset, 0); ut_asserteq(0, sandbox_gpio_get_value(dev, offset)); ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf))); ut_asserteq_str("b4: in: 0 [x] testing", buf); ut_assertok(ops->free(dev, offset)); ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf))); ut_asserteq_str("b4: in: 0 [ ]", buf); /* Check the 'a' bank also */ ut_assertok(gpio_lookup_name("a15", &dev, &offset, &gpio)); ut_asserteq_str(dev->name, "base-gpios"); ut_asserteq(15, offset); ut_asserteq(CONFIG_SANDBOX_GPIO_COUNT + 15, gpio); name = gpio_get_bank_info(dev, &offset_count); ut_asserteq_str("a", name); ut_asserteq(20, offset_count); /* And the anonymous bank */ ut_assertok(gpio_lookup_name("14", &dev, &offset, &gpio)); ut_asserteq_str(dev->name, "gpio_sandbox"); ut_asserteq(14, offset); ut_asserteq(14, gpio); name = gpio_get_bank_info(dev, &offset_count); ut_asserteq_ptr(NULL, name); ut_asserteq(CONFIG_SANDBOX_GPIO_COUNT, offset_count); return 0; }