예제 #1
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;
}
예제 #2
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;
}
예제 #3
0
파일: mp_init.c 프로젝트: OpenNoah/u-boot
static int qemu_cpu_fixup(void)
{
	int ret;
	int cpu_num;
	int cpu_online;
	struct udevice *dev, *pdev;
	struct cpu_platdata *plat;
	char *cpu;

	/* first we need to find '/cpus' */
	for (device_find_first_child(dm_root(), &pdev);
	     pdev;
	     device_find_next_child(&pdev)) {
		if (!strcmp(pdev->name, "cpus"))
			break;
	}
	if (!pdev) {
		printf("unable to find cpus device\n");
		return -ENODEV;
	}

	/* calculate cpus that are already bound */
	cpu_num = 0;
	for (uclass_find_first_device(UCLASS_CPU, &dev);
	     dev;
	     uclass_find_next_device(&dev)) {
		cpu_num++;
	}

	/* get actual cpu number */
	cpu_online = qemu_fwcfg_online_cpus();
	if (cpu_online < 0) {
		printf("unable to get online cpu number: %d\n", cpu_online);
		return cpu_online;
	}

	/* bind addtional cpus */
	dev = NULL;
	for (; cpu_num < cpu_online; cpu_num++) {
		/*
		 * allocate device name here as device_bind_driver() does
		 * not copy device name, 8 bytes are enough for
		 * sizeof("cpu@") + 3 digits cpu number + '\0'
		 */
		cpu = malloc(8);
		if (!cpu) {
			printf("unable to allocate device name\n");
			return -ENOMEM;
		}
		sprintf(cpu, "cpu@%d", cpu_num);
		ret = device_bind_driver(pdev, "cpu_qemu", cpu, &dev);
		if (ret) {
			printf("binding cpu@%d failed: %d\n", cpu_num, ret);
			return ret;
		}
		plat = dev_get_parent_platdata(dev);
		plat->cpu_id = cpu_num;
	}
	return 0;
}
예제 #4
0
int i2c_get_chip(struct udevice *bus, uint chip_addr, struct udevice **devp)
{
	struct udevice *dev;

	debug("%s: Searching bus '%s' for address %02x: ", __func__,
	      bus->name, chip_addr);
	for (device_find_first_child(bus, &dev); dev;
			device_find_next_child(&dev)) {
		struct dm_i2c_chip store;
		struct dm_i2c_chip *chip = dev_get_parentdata(dev);
		int ret;

		if (!chip) {
			chip = &store;
			i2c_chip_ofdata_to_platdata(gd->fdt_blob,
						    dev->of_offset, chip);
		}
		if (chip->chip_addr == chip_addr) {
			ret = device_probe(dev);
			debug("found, ret=%d\n", ret);
			if (ret)
				return ret;
			*devp = dev;
			return 0;
		}
	}
	debug("not found\n");
	return i2c_bind_driver(bus, chip_addr, devp);
}
예제 #5
0
/* Test if bus childs got probed propperly*/
static int dm_test_spmi_probe(struct unit_test_state *uts)
{
	const char *name = "spmi@0";
	struct udevice *bus, *dev;

	ut_assertok(uclass_get_device(UCLASS_SPMI, 0, &bus));

	/* Check bus name */
	ut_asserteq_str(name, bus->name);

	/* Check that it has some devices */
	ut_asserteq(device_has_children(bus), true);

	ut_assertok(device_find_first_child(bus, &dev));

	/* There should be at least one child */
	ut_assertnonnull(dev);

	/* Check that only PMICs are connected to the bus */
	while (dev) {
		ut_asserteq(device_get_uclass_id(dev), UCLASS_PMIC);
		device_find_next_child(&dev);
	}

	return 0;
}
예제 #6
0
int axi_sandbox_get_emul(struct udevice *bus, ulong address,
			 enum axi_size_t size, struct udevice **emulp)
{
	struct udevice *dev;
	u32 reg[2];
	uint offset;

	switch (size) {
	case AXI_SIZE_8:
		offset = 1;
		break;
	case AXI_SIZE_16:
		offset = 2;
		break;
	case AXI_SIZE_32:
		offset = 4;
		break;
	default:
		debug("%s: Unknown AXI transfer size '%d'", bus->name, size);
		offset = 0;
	}

	/*
	 * Note: device_find_* don't activate the devices; they're activated
	 *	 as-needed below.
	 */
	for (device_find_first_child(bus, &dev);
	     dev;
	     device_find_next_child(&dev)) {
		int ret;

		ret = dev_read_u32_array(dev, "reg", reg, ARRAY_SIZE(reg));
		if (ret) {
			debug("%s: Could not read 'reg' property of %s\n",
			      bus->name, dev->name);
			continue;
		}

		/*
		 * Does the transfer's address fall into this device's address
		 * space?
		 */
		if (address >= reg[0] && address <= reg[0] + reg[1] - offset) {
			/* If yes, activate it... */
			if (device_probe(dev)) {
				debug("%s: Could not activate %s\n",
				      bus->name, dev->name);
				return -ENODEV;
			}

			/* ...and return it */
			*emulp = dev;
			return 0;
		}
	}

	return -ENODEV;
}
예제 #7
0
int cros_ec_probe(struct udevice *dev)
{
	struct ec_state *ec = dev->priv;
	struct cros_ec_dev *cdev = dev->uclass_priv;
	const void *blob = gd->fdt_blob;
	struct udevice *keyb_dev;
	int node;
	int err;

	memcpy(ec, &s_state, sizeof(*ec));
	err = cros_ec_decode_ec_flash(blob, dev_of_offset(dev), &ec->ec_config);
	if (err)
		return err;

	node = -1;
	for (device_find_first_child(dev, &keyb_dev);
	     keyb_dev;
	     device_find_next_child(&keyb_dev)) {
		if (device_get_uclass_id(keyb_dev) == UCLASS_KEYBOARD) {
			node = dev_of_offset(keyb_dev);
			break;
		}
	}
	if (node < 0) {
		debug("%s: No cros_ec keyboard found\n", __func__);
	} else if (keyscan_read_fdt_matrix(ec, blob, node)) {
		debug("%s: Could not read key matrix\n", __func__);
		return -1;
	}

	/* If we loaded EC data, check that the length matches */
	if (ec->flash_data &&
	    ec->flash_data_len != ec->ec_config.flash.length) {
		printf("EC data length is %x, expected %x, discarding data\n",
		       ec->flash_data_len, ec->ec_config.flash.length);
		os_free(ec->flash_data);
		ec->flash_data = NULL;
	}

	/* Otherwise allocate the memory */
	if (!ec->flash_data) {
		ec->flash_data_len = ec->ec_config.flash.length;
		ec->flash_data = os_malloc(ec->flash_data_len);
		if (!ec->flash_data)
			return -ENOMEM;
	}

	cdev->dev = dev;
	g_state = ec;
	return cros_ec_register(dev);
}
예제 #8
0
int spi_find_chip_select(struct udevice *bus, int cs, struct udevice **devp)
{
	struct udevice *dev;

	for (device_find_first_child(bus, &dev); dev;
	     device_find_next_child(&dev)) {
		struct dm_spi_slave_platdata *plat;

		plat = dev_get_parent_platdata(dev);
		debug("%s: plat=%p, cs=%d\n", __func__, plat, plat->cs);
		if (plat->cs == cs) {
			*devp = dev;
			return 0;
		}
	}

	return -ENODEV;
}
예제 #9
0
int pinctrl_generic_set_state(struct udevice *dev, struct udevice *config)
{
	struct udevice *child;
	int ret;

	ret = pinctrl_generic_set_state_subnode(dev, config);
	if (ret)
		return ret;

	for (device_find_first_child(config, &child);
	     child;
	     device_find_next_child(&child)) {
		ret = pinctrl_generic_set_state_subnode(dev, child);
		if (ret)
			return ret;
	}

	return 0;
}
예제 #10
0
/* Test that the child post_bind method is called */
static int dm_test_bus_child_post_bind_uclass(struct unit_test_state *uts)
{
	struct dm_test_parent_platdata *plat;
	struct udevice *bus, *dev;
	int child_count;

	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);
		ut_asserteq(2, plat->uclass_bind_flag);
		child_count++;
	}
	ut_asserteq(3, child_count);

	return 0;
}
예제 #11
0
파일: pci.c 프로젝트: OpenNoah/u-boot
static void pciinfo(struct udevice *bus, bool short_listing)
{
	struct udevice *dev;

	pciinfo_header(bus->seq, short_listing);

	for (device_find_first_child(bus, &dev);
	     dev;
	     device_find_next_child(&dev)) {
		struct pci_child_platdata *pplat;

		pplat = dev_get_parent_platdata(dev);
		if (short_listing) {
			printf("%02x.%02x.%02x   ", bus->seq,
			       PCI_DEV(pplat->devfn), PCI_FUNC(pplat->devfn));
			pci_header_show_brief(dev);
		} else {
			printf("\nFound PCI device %02x.%02x.%02x:\n", bus->seq,
			       PCI_DEV(pplat->devfn), PCI_FUNC(pplat->devfn));
			pci_header_show(dev);
		}
	}
}
예제 #12
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;
}