예제 #1
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;
}
예제 #2
0
파일: osd.c 프로젝트: Noltari/u-boot
static int do_show_osd(cmd_tbl_t *cmdtp, int flag, int argc,
		       char * const argv[])
{
	struct udevice *osd;

	if (argc == 1) {
		/* show all OSDs */
		struct uclass *uc;
		int res;

		res = uclass_get(UCLASS_VIDEO_OSD, &uc);
		if (res) {
			printf("Error while getting OSD uclass (err=%d)\n",
			       res);
			return CMD_RET_FAILURE;
		}

		uclass_foreach_dev(osd, uc)
			show_osd(osd);
	} else {
		int i, res;

		/* show specific OSD */
		i = simple_strtoul(argv[1], NULL, 10);

		res = uclass_get_device_by_seq(UCLASS_VIDEO_OSD, i, &osd);
		if (res) {
			printf("Invalid osd %d: err=%d\n", i, res);
			return CMD_RET_FAILURE;
		}
		show_osd(osd);
	}

	return CMD_RET_SUCCESS;
}
예제 #3
0
int rproc_load(int id, ulong addr, ulong size)
{
	struct udevice *dev = NULL;
	struct dm_rproc_uclass_pdata *uc_pdata;
	const struct dm_rproc_ops *ops;
	int ret;

	ret = uclass_get_device_by_seq(UCLASS_REMOTEPROC, id, &dev);
	if (ret) {
		debug("Unknown remote processor id '%d' requested(%d)\n",
		      id, ret);
		return ret;
	}

	uc_pdata = dev_get_uclass_platdata(dev);

	ops = rproc_get_ops(dev);
	if (!ops) {
		debug("%s driver has no ops?\n", dev->name);
		return -EINVAL;
	}

	debug("Loading to '%s' from address 0x%08lX size of %lu bytes\n",
	      uc_pdata->name, addr, size);
	if (ops->load)
		return ops->load(dev, addr, size);

	debug("%s: data corruption?? mandatory function is missing!\n",
	      dev->name);

	return -EINVAL;
};
예제 #4
0
static void serial_find_console_or_panic(void)
{
#ifdef CONFIG_OF_CONTROL
	int node;

	/* Check for a chosen console */
	node = fdtdec_get_chosen_node(gd->fdt_blob, "stdout-path");
	if (node < 0)
		node = fdtdec_get_alias_node(gd->fdt_blob, "console");
	if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node, &cur_dev))
		return;

	/*
	 * If the console is not marked to be bound before relocation, bind
	 * it anyway.
	 */
	if (node > 0 &&
	    !lists_bind_fdt(gd->dm_root, gd->fdt_blob, node, &cur_dev)) {
		if (!device_probe(cur_dev))
			return;
		cur_dev = NULL;
	}
#endif
	/*
	 * Failing that, get the device with sequence number 0, or in extremis
	 * just the first serial device we can find. But we insist on having
	 * a console (even if it is silent).
	 */
	if (uclass_get_device_by_seq(UCLASS_SERIAL, 0, &cur_dev) &&
	    (uclass_first_device(UCLASS_SERIAL, &cur_dev) || !cur_dev))
		panic("No serial driver found");
}
예제 #5
0
int board_late_init(void)
{
#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
	watchdog_dev = NULL;

	if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) {
		debug("Watchdog: Not found by seq!\n");
		if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
			puts("Watchdog: Not found!\n");
			return 0;
		}
	}

	wdt_start(watchdog_dev, 0, 0);
	puts("Watchdog: Started\n");
#endif /* !CONFIG_SPL_BUILD && CONFIG_WDT */
#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SYSRESET_MICROBLAZE)
	int ret;

	ret = device_bind_driver(gd->dm_root, "mb_soft_reset",
				 "reset_soft", NULL);
	if (ret)
		printf("Warning: No reset driver: ret=%d\n", ret);
#endif
	return 0;
}
예제 #6
0
파일: i2c-uclass.c 프로젝트: Noltari/u-boot
int i2c_get_chip_for_busnum(int busnum, int chip_addr, uint offset_len,
			    struct udevice **devp)
{
	struct udevice *bus;
	int ret;

	ret = uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus);
	if (ret) {
		debug("Cannot find I2C bus %d\n", busnum);
		return ret;
	}

	/* detect the presence of the chip on the bus */
	ret = i2c_probe_chip(bus, chip_addr, 0);
	debug("%s: bus='%s', address %02x, ret=%d\n", __func__, bus->name,
	      chip_addr, ret);
	if (ret) {
		debug("Cannot detect I2C chip %02x on bus %d\n", chip_addr,
		      busnum);
		return ret;
	}

	ret = i2c_get_chip(bus, chip_addr, offset_len, devp);
	if (ret) {
		debug("Cannot find I2C chip %02x on bus %d\n", chip_addr,
		      busnum);
		return ret;
	}

	return 0;
}
예제 #7
0
/**
 * pinctrl_select_state_simple() - simple implementation of pinctrl_select_state
 *
 * @dev: peripheral device
 * @return: 0 on success, or negative error code on failure
 */
static int pinctrl_select_state_simple(struct udevice *dev)
{
	struct udevice *pctldev;
	struct pinctrl_ops *ops;
	int ret;

	/*
	 * For most system, there is only one pincontroller device. But in
	 * case of multiple pincontroller devices, probe the one with sequence
	 * number 0 (defined by alias) to avoid race condition.
	 */
	ret = uclass_get_device_by_seq(UCLASS_PINCTRL, 0, &pctldev);
	if (ret)
		/* if not found, get the first one */
		ret = uclass_get_device(UCLASS_PINCTRL, 0, &pctldev);
	if (ret)
		return ret;

	ops = pinctrl_get_ops(pctldev);
	if (!ops->set_state_simple) {
		dev_dbg(dev, "set_state_simple op missing\n");
		return -ENOSYS;
	}

	return ops->set_state_simple(pctldev, dev);
}
예제 #8
0
파일: blk.c 프로젝트: Noltari/u-boot
/* 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;
}
예제 #9
0
static int set_ethaddr_from_at24mac(void)
{
	const int ETH_ADDR_LEN = 6;
	unsigned char ethaddr[ETH_ADDR_LEN];
	const char *ETHADDR_NAME = "ethaddr";
	struct udevice *bus, *dev;

	if (getenv(ETHADDR_NAME))
		return 0;

	if (uclass_get_device_by_seq(UCLASS_I2C, AT24MAC_ON_I2C_BUS, &bus)) {
		printf("Cannot find I2C bus\n");
		return -1;
	}

	if (dm_i2c_probe(bus, AT24MAC_ADDR, 0, &dev)) {
		printf("Failed to probe I2C device chip\n");
		return -1;
	}

	if (dm_i2c_read(dev, AT24MAC_REG, ethaddr, ETH_ADDR_LEN)) {
		printf("Failed to read ethernet address from AT24MAC\n");
		return -1;
	}

	if (!is_valid_ethaddr(ethaddr)) {
		printf("The ethernet address read from AT24MAC is not valid\n");
		return -1;
	}

	return eth_setenv_enetaddr(ETHADDR_NAME, ethaddr);
}
예제 #10
0
파일: board_k2g.c 프로젝트: Noltari/u-boot
static int k2g_alt_board_detect(void)
{
#ifndef CONFIG_DM_I2C
	int rc;

	rc = i2c_set_bus_num(1);
	if (rc)
		return rc;

	rc = i2c_probe(K2G_GP_AUDIO_CODEC_ADDRESS);
	if (rc)
		return rc;
#else
	struct udevice *bus, *dev;
	int rc;

	rc = uclass_get_device_by_seq(UCLASS_I2C, 1, &bus);
	if (rc)
		return rc;
	rc = dm_i2c_probe(bus, K2G_GP_AUDIO_CODEC_ADDRESS, 0, &dev);
	if (rc)
		return rc;
#endif
	ti_i2c_eeprom_am_set("66AK2GGP", "1.0X");

	return 0;
}
예제 #11
0
파일: blk.c 프로젝트: Noltari/u-boot
/* 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;
}
예제 #12
0
int pci_get_bus(int busnum, struct udevice **busp)
{
	int ret;

	ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, busp);

	/* Since buses may not be numbered yet try a little harder with bus 0 */
	if (ret == -ENODEV) {
		ret = uclass_first_device_err(UCLASS_PCI, busp);
		if (ret)
			return ret;
		ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, busp);
	}

	return ret;
}
예제 #13
0
/* Test that sandbox PCI bus numbering works correctly */
static int dm_test_pci_busnum(struct unit_test_state *uts)
{
	struct udevice *bus;

	ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 0, &bus));

	return 0;
}
예제 #14
0
/* Simple RTC sanity check */
static int dm_test_rtc_base(struct dm_test_state *dms)
{
	struct udevice *dev;

	ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_RTC, 2, &dev));
	ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev));
	ut_assertok(uclass_get_device(UCLASS_RTC, 1, &dev));

	return 0;
}
예제 #15
0
파일: osd.c 프로젝트: Noltari/u-boot
/**
 * cmd_osd_set_osd_num() - Set the OSD selected for operation
 *
 * Set the OSD device, which will be used by all subsequent OSD commands.
 *
 * Devices are identified by their uclass sequence number (as listed by 'osd
 * show').
 *
 * @osdnum: The OSD device to be selected, identified by its sequence number.
 * Return: 0 if OK, -ve on error
 */
static int cmd_osd_set_osd_num(unsigned int osdnum)
{
	struct udevice *osd;
	int res;

	res = uclass_get_device_by_seq(UCLASS_VIDEO_OSD, osdnum, &osd);
	if (res) {
		printf("%s: No OSD %u (err = %d)\n", __func__, osdnum, res);
		return res;
	}
	osd_cur = osd;

	return 0;
}
예제 #16
0
int i2c_probe(uint8_t chip_addr)
{
	struct udevice *bus, *dev;
	int ret;

	ret = uclass_get_device_by_seq(UCLASS_I2C, cur_busnum, &bus);
	if (ret) {
		debug("Cannot find I2C bus %d: err=%d\n", cur_busnum, ret);
		return ret;
	}

	if (!bus)
		return -ENOENT;

	return dm_i2c_probe(bus, chip_addr, 0, &dev);
}
예제 #17
0
static void serial_find_console_or_panic(void)
{
	struct udevice *dev;

#ifdef CONFIG_OF_CONTROL
	int node;

	/* Check for a chosen console */
	node = fdtdec_get_chosen_node(gd->fdt_blob, "stdout-path");
	if (node < 0)
		node = fdt_path_offset(gd->fdt_blob, "console");
	if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node, &dev)) {
		gd->cur_serial_dev = dev;
		return;
	}

	/*
	 * If the console is not marked to be bound before relocation, bind
	 * it anyway.
	 */
	if (node > 0 &&
	    !lists_bind_fdt(gd->dm_root, gd->fdt_blob, node, &dev)) {
		if (!device_probe(dev)) {
			gd->cur_serial_dev = dev;
			return;
		}
	}
#endif
	/*
	 * Try to use CONFIG_CONS_INDEX if available (it is numbered from 1!).
	 *
	 * Failing that, get the device with sequence number 0, or in extremis
	 * just the first serial device we can find. But we insist on having
	 * a console (even if it is silent).
	 */
#ifdef CONFIG_CONS_INDEX
#define INDEX (CONFIG_CONS_INDEX - 1)
#else
#define INDEX 0
#endif
	if (uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &dev) &&
	    uclass_get_device(UCLASS_SERIAL, INDEX, &dev) &&
	    (uclass_first_device(UCLASS_SERIAL, &dev) || !dev))
		panic("No serial driver found");
#undef INDEX
	gd->cur_serial_dev = dev;
}
예제 #18
0
int board_init(void)
{
#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
	if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) {
		debug("Watchdog: Not found by seq!\n");
		if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
			puts("Watchdog: Not found!\n");
			return 0;
		}
	}

	wdt_start(watchdog_dev, 0, 0);
	puts("Watchdog: Started\n");
# endif

	return 0;
}
예제 #19
0
/**
 * ti_i2c_set_alen - Set chip's i2c address length
 * @bus_addr - I2C bus number
 * @dev_addr - I2C eeprom id
 * @alen     - I2C address length in bytes
 *
 * DM_I2C by default sets the address length to be used to 1. This
 * function allows this address length to be changed to match the
 * eeprom used for board detection.
 */
int __maybe_unused ti_i2c_set_alen(int bus_addr, int dev_addr, int alen)
{
	struct udevice *dev;
	struct udevice *bus;
	int rc;

	rc = uclass_get_device_by_seq(UCLASS_I2C, bus_addr, &bus);
	if (rc)
		return rc;
	rc = i2c_get_chip(bus, dev_addr, 1, &dev);
	if (rc)
		return rc;
	rc = i2c_set_chip_offset_len(dev, alen);
	if (rc)
		return rc;

	return 0;
}
예제 #20
0
int i2c_get_chip_for_busnum(int busnum, int chip_addr, struct udevice **devp)
{
	struct udevice *bus;
	int ret;

	ret = uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus);
	if (ret) {
		debug("Cannot find I2C bus %d\n", busnum);
		return ret;
	}
	ret = i2c_get_chip(bus, chip_addr, devp);
	if (ret) {
		debug("Cannot find I2C chip %02x on bus %d\n", chip_addr,
		      busnum);
		return ret;
	}

	return 0;
}
예제 #21
0
static void serial_find_console_or_panic(void)
{
	const void *blob = gd->fdt_blob;
	struct udevice *dev;
	int node;

	if (CONFIG_IS_ENABLED(OF_CONTROL) && blob) {
		/* Check for a chosen console */
		node = fdtdec_get_chosen_node(blob, "stdout-path");
		if (node < 0) {
			const char *str, *p, *name;

			/*
			 * Deal with things like
			 *	stdout-path = "serial0:115200n8";
			 *
			 * We need to look up the alias and then follow it to
			 * the correct node.
			 */
			str = fdtdec_get_chosen_prop(blob, "stdout-path");
			if (str) {
				p = strchr(str, ':');
				name = fdt_get_alias_namelen(blob, str,
						p ? p - str : strlen(str));
				if (name)
					node = fdt_path_offset(blob, name);
			}
		}
		if (node < 0)
			node = fdt_path_offset(blob, "console");
		if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node,
						    &dev)) {
			gd->cur_serial_dev = dev;
			return;
		}

		/*
		* If the console is not marked to be bound before relocation,
		* bind it anyway.
		*/
		if (node > 0 &&
		    !lists_bind_fdt(gd->dm_root, blob, node, &dev)) {
			if (!device_probe(dev)) {
				gd->cur_serial_dev = dev;
				return;
			}
		}
	}
	if (!SPL_BUILD || !CONFIG_IS_ENABLED(OF_CONTROL) || !blob) {
		/*
		* Try to use CONFIG_CONS_INDEX if available (it is numbered
		* from 1!).
		*
		* Failing that, get the device with sequence number 0, or in
		* extremis just the first serial device we can find. But we
		* insist on having a console (even if it is silent).
		*/
#ifdef CONFIG_CONS_INDEX
#define INDEX (CONFIG_CONS_INDEX - 1)
#else
#define INDEX 0
#endif
		if (!uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &dev) ||
		    !uclass_get_device(UCLASS_SERIAL, INDEX, &dev) ||
		    (!uclass_first_device(UCLASS_SERIAL, &dev) && dev)) {
			gd->cur_serial_dev = dev;
			return;
		}
#undef INDEX
	}

#ifdef CONFIG_REQUIRE_SERIAL_CONSOLE
	panic_str("No serial driver found");
#endif
}
예제 #22
0
파일: pci.c 프로젝트: OpenNoah/u-boot
/* PCI Configuration Space access commands
 *
 * Syntax:
 *	pci display[.b, .w, .l] bus.device.function} [addr] [len]
 *	pci next[.b, .w, .l] bus.device.function [addr]
 *      pci modify[.b, .w, .l] bus.device.function [addr]
 *      pci write[.b, .w, .l] bus.device.function addr value
 */
static int do_pci(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	ulong addr = 0, value = 0, cmd_size = 0;
	enum pci_size_t size = PCI_SIZE_32;
#ifdef CONFIG_DM_PCI
	struct udevice *dev, *bus;
#else
	pci_dev_t dev;
#endif
	int busnum = 0;
	pci_dev_t bdf = 0;
	char cmd = 's';
	int ret = 0;

	if (argc > 1)
		cmd = argv[1][0];

	switch (cmd) {
	case 'd':		/* display */
	case 'n':		/* next */
	case 'm':		/* modify */
	case 'w':		/* write */
		/* Check for a size specification. */
		cmd_size = cmd_get_data_size(argv[1], 4);
		size = (cmd_size == 4) ? PCI_SIZE_32 : cmd_size - 1;
		if (argc > 3)
			addr = simple_strtoul(argv[3], NULL, 16);
		if (argc > 4)
			value = simple_strtoul(argv[4], NULL, 16);
	case 'h':		/* header */
#ifdef CONFIG_DM_PCI
	case 'b':		/* bars */
#endif
		if (argc < 3)
			goto usage;
		if ((bdf = get_pci_dev(argv[2])) == -1)
			return 1;
		break;
#if defined(CONFIG_DM_PCI)
	case 'e':
		pci_init();
		return 0;
#endif
	case 'r': /* no break */
	default:		/* scan bus */
		value = 1; /* short listing */
		if (argc > 1) {
			if (cmd != 'r' && argv[argc-1][0] == 'l') {
				value = 0;
				argc--;
			}
			if (argc > 1)
				busnum = simple_strtoul(argv[1], NULL, 16);
		}
#ifdef CONFIG_DM_PCI
		ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, &bus);
		if (ret) {
			printf("No such bus\n");
			return CMD_RET_FAILURE;
		}
		if (cmd == 'r')
			pci_show_regions(bus);
		else
			pciinfo(bus, value);
#else
		pciinfo(busnum, value);
#endif
		return 0;
	}

#ifdef CONFIG_DM_PCI
	ret = dm_pci_bus_find_bdf(bdf, &dev);
	if (ret) {
		printf("No such device\n");
		return CMD_RET_FAILURE;
	}
#else
	dev = bdf;
#endif

	switch (argv[1][0]) {
	case 'h':		/* header */
		pci_header_show(dev);
		break;
	case 'd':		/* display */
		return pci_cfg_display(dev, addr, size, value);
	case 'n':		/* next */
		if (argc < 4)
			goto usage;
		ret = pci_cfg_modify(dev, addr, size, value, 0);
		break;
	case 'm':		/* modify */
		if (argc < 4)
			goto usage;
		ret = pci_cfg_modify(dev, addr, size, value, 1);
		break;
	case 'w':		/* write */
		if (argc < 5)
			goto usage;
#ifdef CONFIG_DM_PCI
		ret = dm_pci_write_config(dev, addr, value, size);
#else
		ret = pci_cfg_write(dev, addr, size, value);
#endif
		break;
#ifdef CONFIG_DM_PCI

	case 'b':		/* bars */
		return pci_bar_show(dev);
#endif
	default:
		ret = CMD_RET_USAGE;
		break;
	}

	return ret;
 usage:
	return CMD_RET_USAGE;
}
예제 #23
0
파일: spi.c 프로젝트: KunYi/uboot-samx6i
/* 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;
}
예제 #24
0
/**
 * _rproc_ops_wrapper() - wrapper for invoking remote proc driver callback
 * @id:		id of the remote processor
 * @op:		one of rproc_ops that indicate what operation to invoke
 *
 * Most of the checks and verification for remoteproc operations are more
 * or less same for almost all operations. This allows us to put a wrapper
 * and use the common checks to allow the driver to function appropriately.
 *
 * Return: 0 if all ok, else appropriate error value.
 */
static int _rproc_ops_wrapper(int id, enum rproc_ops op)
{
	struct udevice *dev = NULL;
	struct dm_rproc_uclass_pdata *uc_pdata;
	const struct dm_rproc_ops *ops;
	int (*fn)(struct udevice *dev);
	bool mandatory = false;
	char *op_str;
	int ret;

	ret = uclass_get_device_by_seq(UCLASS_REMOTEPROC, id, &dev);
	if (ret) {
		debug("Unknown remote processor id '%d' requested(%d)\n",
		      id, ret);
		return ret;
	}

	uc_pdata = dev_get_uclass_platdata(dev);

	ops = rproc_get_ops(dev);
	if (!ops) {
		debug("%s driver has no ops?\n", dev->name);
		return -EINVAL;
	}
	switch (op) {
	case RPROC_START:
		fn = ops->start;
		mandatory = true;
		op_str = "Starting";
		break;
	case RPROC_STOP:
		fn = ops->stop;
		op_str = "Stopping";
		break;
	case RPROC_RESET:
		fn = ops->reset;
		op_str = "Resetting";
		break;
	case RPROC_RUNNING:
		fn = ops->is_running;
		op_str = "Checking if running:";
		break;
	case RPROC_PING:
		fn = ops->ping;
		op_str = "Pinging";
		break;
	default:
		debug("what is '%d' operation??\n", op);
		return -EINVAL;
	}

	debug("%s %s...\n", op_str, uc_pdata->name);
	if (fn)
		return fn(dev);

	if (mandatory)
		debug("%s: data corruption?? mandatory function is missing!\n",
		      dev->name);

	return -ENOSYS;
}
예제 #25
0
int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
		       const char *drv_name, const char *dev_name,
		       struct udevice **busp, struct spi_slave **devp)
{
	struct udevice *bus, *dev;
	struct dm_spi_slave_platdata *plat;
	bool created = false;
	int ret;

	ret = uclass_get_device_by_seq(UCLASS_SPI, busnum, &bus);
	if (ret) {
		printf("Invalid bus %d (err=%d)\n", busnum, ret);
		return ret;
	}
	ret = spi_find_chip_select(bus, cs, &dev);

	/*
	 * If there is no such device, create one automatically. This means
	 * that we don't need a device tree node or platform data for the
	 * SPI flash chip - we will bind to the correct driver.
	 */
	if (ret == -ENODEV && drv_name) {
		debug("%s: Binding new device '%s', busnum=%d, cs=%d, driver=%s\n",
		      __func__, dev_name, busnum, cs, drv_name);
		ret = device_bind_driver(bus, drv_name, dev_name, &dev);
		if (ret)
			return ret;
		plat = dev_get_parent_platdata(dev);
		plat->cs = cs;
		plat->max_hz = speed;
		plat->mode = mode;
		created = true;
	} else if (ret) {
		printf("Invalid chip select %d:%d (err=%d)\n", busnum, cs,
		       ret);
		return ret;
	}

	if (!device_active(dev)) {
		struct spi_slave *slave;

		ret = device_probe(dev);
		if (ret)
			goto err;
		slave = dev_get_parent_priv(dev);
		slave->dev = dev;
	}

	plat = dev_get_parent_platdata(dev);
	if (!speed) {
		speed = plat->max_hz;
		mode = plat->mode;
	}
	ret = spi_set_speed_mode(bus, speed, mode);
	if (ret)
		goto err;

	*busp = bus;
	*devp = dev_get_parent_priv(dev);
	debug("%s: bus=%p, slave=%p\n", __func__, bus, *devp);

	return 0;

err:
	debug("%s: Error path, created=%d, device '%s'\n", __func__,
	      created, dev->name);
	if (created) {
		device_remove(dev);
		device_unbind(dev);
	}

	return ret;
}
예제 #26
0
static void serial_find_console_or_panic(void)
{
	const void *blob = gd->fdt_blob;
	struct udevice *dev;
#ifdef CONFIG_SERIAL_SEARCH_ALL
	int ret;
#endif

	if (CONFIG_IS_ENABLED(OF_PLATDATA)) {
		uclass_first_device(UCLASS_SERIAL, &dev);
		if (dev) {
			gd->cur_serial_dev = dev;
			return;
		}
	} else if (CONFIG_IS_ENABLED(OF_CONTROL) && blob) {
		/* Live tree has support for stdout */
		if (of_live_active()) {
			struct device_node *np = of_get_stdout();

			if (np && !uclass_get_device_by_ofnode(UCLASS_SERIAL,
					np_to_ofnode(np), &dev)) {
				gd->cur_serial_dev = dev;
				return;
			}
		} else {
			if (!serial_check_stdout(blob, &dev)) {
				gd->cur_serial_dev = dev;
				return;
			}
		}
	}
	if (!SPL_BUILD || !CONFIG_IS_ENABLED(OF_CONTROL) || !blob) {
		/*
		 * Try to use CONFIG_CONS_INDEX if available (it is numbered
		 * from 1!).
		 *
		 * Failing that, get the device with sequence number 0, or in
		 * extremis just the first working serial device we can find.
		 * But we insist on having a console (even if it is silent).
		 */
#ifdef CONFIG_CONS_INDEX
#define INDEX (CONFIG_CONS_INDEX - 1)
#else
#define INDEX 0
#endif

#ifdef CONFIG_SERIAL_SEARCH_ALL
		if (!uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &dev) ||
		    !uclass_get_device(UCLASS_SERIAL, INDEX, &dev)) {
			if (dev->flags & DM_FLAG_ACTIVATED) {
				gd->cur_serial_dev = dev;
				return;
			}
		}

		/* Search for any working device */
		for (ret = uclass_first_device_check(UCLASS_SERIAL, &dev);
		     dev;
		     ret = uclass_next_device_check(&dev)) {
			if (!ret) {
				/* Device did succeed probing */
				gd->cur_serial_dev = dev;
				return;
			}
		}
#else
		if (!uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &dev) ||
		    !uclass_get_device(UCLASS_SERIAL, INDEX, &dev) ||
		    (!uclass_first_device(UCLASS_SERIAL, &dev) && dev)) {
			gd->cur_serial_dev = dev;
			return;
		}
#endif

#undef INDEX
	}

#ifdef CONFIG_REQUIRE_SERIAL_CONSOLE
	panic_str("No serial driver found");
#endif
}