/* 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; }
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; }
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; };
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"); }
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; }
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; }
/** * 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); }
/* 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; }
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); }
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; }
/* 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; }
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; }
/* 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; }
/* 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; }
/** * 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; }
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); }
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; }
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; }
/** * 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; }
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; }
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 }
/* 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; }
/* 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; }
/** * _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; }
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; }
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 }