void print_mmc_devices(char separator) { struct udevice *dev; char *mmc_type; bool first = true; for (uclass_first_device(UCLASS_MMC, &dev); dev; uclass_next_device(&dev), first = false) { struct mmc *m = mmc_get_mmc_dev(dev); if (!first) { printf("%c", separator); if (separator != '\n') puts(" "); } if (m->has_init) mmc_type = IS_SD(m) ? "SD" : "eMMC"; else mmc_type = NULL; printf("%s: %d", m->cfg->name, mmc_get_blk_desc(m)->devnum); if (mmc_type) printf(" (%s)", mmc_type); } printf("\n"); }
/* Remove and recreate everything, check for memory leaks */ static int dm_test_leak(struct dm_test_state *dms) { int i; for (i = 0; i < 2; i++) { struct udevice *dev; int ret; int id; dm_leak_check_start(dms); ut_assertok(dm_scan_platdata(false)); ut_assertok(dm_scan_fdt(gd->fdt_blob, false)); /* Scanning the uclass is enough to probe all the devices */ for (id = UCLASS_ROOT; id < UCLASS_COUNT; id++) { for (ret = uclass_first_device(UCLASS_TEST, &dev); dev; ret = uclass_next_device(&dev)) ; ut_assertok(ret); } ut_assertok(dm_leak_check_end(dms)); } return 0; }
int gpio_lookup_name(const char *name, struct device **devp, unsigned int *offsetp, unsigned int *gpiop) { struct gpio_dev_priv *uc_priv; struct device *dev; int ret; if (devp) *devp = NULL; for (ret = uclass_first_device(UCLASS_GPIO, &dev); dev; ret = uclass_next_device(&dev)) { ulong offset; int len; uc_priv = dev->uclass_priv; len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0; if (!strncmp(name, uc_priv->bank_name, len)) { if (strict_strtoul(name + len, 10, &offset)) continue; if (devp) *devp = dev; if (offsetp) *offsetp = offset; if (gpiop) *gpiop = uc_priv->gpio_base + offset; return 0; } } return ret ? ret : -EINVAL; }
void eth_set_current_to_next(void) { struct eth_uclass_priv *uc_priv; uc_priv = eth_get_uclass_priv(); if (uc_priv->current) uclass_next_device(&uc_priv->current); if (!uc_priv->current) uclass_first_device(UCLASS_ETH, &uc_priv->current); }
/* Ensure all the test devices are probed */ static int do_autoprobe(struct dm_test_state *dms) { struct udevice *dev; int ret; /* Scanning the uclass is enough to probe all the devices */ for (ret = uclass_first_device(UCLASS_TEST, &dev); dev; ret = uclass_next_device(&dev)) ; return ret; }
int eth_initialize(void) { int num_devices = 0; struct udevice *dev; eth_common_init(); /* * Devices need to write the hwaddr even if not started so that Linux * will have access to the hwaddr that u-boot stored for the device. * This is accomplished by attempting to probe each device and calling * their write_hwaddr() operation. */ uclass_first_device(UCLASS_ETH, &dev); if (!dev) { printf("No ethernet found.\n"); bootstage_error(BOOTSTAGE_ID_NET_ETH_START); } else { char *ethprime = getenv("ethprime"); struct udevice *prime_dev = NULL; if (ethprime) prime_dev = eth_get_dev_by_name(ethprime); if (prime_dev) { eth_set_dev(prime_dev); eth_current_changed(); } else { eth_set_dev(NULL); } bootstage_mark(BOOTSTAGE_ID_NET_ETH_INIT); do { if (num_devices) printf(", "); printf("eth%d: %s", dev->seq, dev->name); if (ethprime && dev == prime_dev) printf(" [PRIME]"); eth_write_hwaddr(dev); uclass_next_device(&dev); num_devices++; } while (dev); putc('\n'); } return num_devices; }
static int do_gpio_status(bool all, const char *gpio_name) { struct udevice *dev; int banklen; int flags; int ret; flags = 0; if (gpio_name && !*gpio_name) gpio_name = NULL; for (ret = uclass_first_device(UCLASS_GPIO, &dev); dev; ret = uclass_next_device(&dev)) { const char *bank_name; int num_bits; flags |= FLAG_SHOW_BANK; if (all) flags |= FLAG_SHOW_ALL; bank_name = gpio_get_bank_info(dev, &num_bits); if (!num_bits) { debug("GPIO device %s has no bits\n", dev->name); continue; } banklen = bank_name ? strlen(bank_name) : 0; if (!gpio_name || !bank_name || !strncmp(gpio_name, bank_name, banklen)) { const char *p = NULL; int offset; p = gpio_name + banklen; if (gpio_name && *p) { offset = simple_strtoul(p, NULL, 10); gpio_get_description(dev, bank_name, offset, &flags); } else { for (offset = 0; offset < num_bits; offset++) { gpio_get_description(dev, bank_name, offset, &flags); } } } /* Add a newline between bank names */ if (!(flags & FLAG_SHOW_BANK)) flags |= FLAG_SHOW_NEWLINE; } return ret; }
static int dm_test_uclass_devices_get(struct unit_test_state *uts) { struct udevice *dev; int ret; for (ret = uclass_first_device(UCLASS_TEST, &dev); dev; ret = uclass_next_device(&dev)) { ut_assert(!ret); ut_assert(dev); ut_assert(device_active(dev)); } return 0; }
int gpio_lookup_name(const char *name, struct udevice **devp, unsigned int *offsetp, unsigned int *gpiop) { struct gpio_dev_priv *uc_priv = NULL; struct udevice *dev; ulong offset; int numeric; int ret; if (devp) *devp = NULL; numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1; for (ret = uclass_first_device(UCLASS_GPIO, &dev); dev; ret = uclass_next_device(&dev)) { int len; uc_priv = dev->uclass_priv; if (numeric != -1) { offset = numeric - uc_priv->gpio_base; /* Allow GPIOs to be numbered from 0 */ if (offset >= 0 && offset < uc_priv->gpio_count) break; } len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0; if (!strncasecmp(name, uc_priv->bank_name, len)) { if (!strict_strtoul(name + len, 10, &offset)) break; } } if (!dev) return ret ? ret : -EINVAL; if (devp) *devp = dev; if (offsetp) *offsetp = offset; if (gpiop) *gpiop = uc_priv->gpio_base + offset; return 0; }
int reset_walk(enum reset_t type) { struct udevice *dev; int ret = -ENOSYS; while (ret != -EINPROGRESS && type < RESET_COUNT) { for (uclass_first_device(UCLASS_RESET, &dev); dev; uclass_next_device(&dev)) { ret = reset_request(dev, type); if (ret == -EINPROGRESS) break; } type++; } return ret; }
int blk_next_device(struct udevice **devp) { struct blk_desc *desc; int ret, if_type; desc = dev_get_uclass_platdata(*devp); if_type = desc->if_type; do { ret = uclass_next_device(devp); if (ret) return ret; if (!*devp) return -ENODEV; desc = dev_get_uclass_platdata(*devp); if (desc->if_type == if_type) return 0; } while (1); }
unsigned long flash_init(void) { unsigned long size = 0; struct udevice *dev; int bank; /* probe every MTD device */ for (uclass_first_device(UCLASS_MTD, &dev); dev; uclass_next_device(&dev)) { /* nop */ } /* calc total flash size */ for (bank = 0; bank < CONFIG_SYS_MAX_FLASH_BANKS; ++bank) size += flash_info[bank].size; return size; }
/* Remove and recreate everything, check for memory leaks */ static int dm_test_leak(struct dm_test_state *dms) { int i; for (i = 0; i < 2; i++) { struct mallinfo start, end; struct udevice *dev; int ret; int id; start = mallinfo(); if (!start.uordblks) puts("Warning: Please add '#define DEBUG' to the top of common/dlmalloc.c\n"); ut_assertok(dm_scan_platdata()); ut_assertok(dm_scan_fdt(gd->fdt_blob)); /* Scanning the uclass is enough to probe all the devices */ for (id = UCLASS_ROOT; id < UCLASS_COUNT; id++) { for (ret = uclass_first_device(UCLASS_TEST, &dev); dev; ret = uclass_next_device(&dev)) ; ut_assertok(ret); } /* Don't delete the root class, since we started with that */ for (id = UCLASS_ROOT + 1; id < UCLASS_COUNT; id++) { struct uclass *uc; uc = uclass_find(id); if (!uc) continue; ut_assertok(uclass_destroy(uc)); } end = mallinfo(); ut_asserteq(start.uordblks, end.uordblks); } 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; }
int blk_first_device(int if_type, struct udevice **devp) { struct blk_desc *desc; int ret; ret = uclass_first_device(UCLASS_BLK, devp); if (ret) return ret; if (!*devp) return -ENODEV; do { desc = dev_get_uclass_platdata(*devp); if (desc->if_type == if_type) return 0; ret = uclass_next_device(devp); if (ret) return ret; } while (*devp); return -ENODEV; }
/** * gpio_to_device() - Convert global GPIO number to device, number * gpio: The numeric representation of the GPIO * * Convert the GPIO number to an entry in the list of GPIOs * or GPIO blocks registered with the GPIO controller. Returns * entry on success, NULL on error. */ static int gpio_to_device(unsigned int gpio, struct device **devp, unsigned int *offset) { struct gpio_dev_priv *uc_priv; struct device *dev; int ret; for (ret = uclass_first_device(UCLASS_GPIO, &dev); dev; ret = uclass_next_device(&dev)) { uc_priv = dev->uclass_priv; if (gpio >= uc_priv->gpio_base && gpio < uc_priv->gpio_base + uc_priv->gpio_count) { *devp = dev; *offset = gpio - uc_priv->gpio_base; return 0; } } /* No such GPIO */ return ret ? ret : -EINVAL; }
/** * gpio_to_device() - Convert global GPIO number to device, number * * Convert the GPIO number to an entry in the list of GPIOs * or GPIO blocks registered with the GPIO controller. Returns * entry on success, NULL on error. * * @gpio: The numeric representation of the GPIO * @desc: Returns description (desc->flags will always be 0) * @return 0 if found, -ENOENT if not found */ static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc) { struct gpio_dev_priv *uc_priv; struct udevice *dev; int ret; for (ret = uclass_first_device(UCLASS_GPIO, &dev); dev; ret = uclass_next_device(&dev)) { uc_priv = dev_get_uclass_priv(dev); if (gpio >= uc_priv->gpio_base && gpio < uc_priv->gpio_base + uc_priv->gpio_count) { desc->dev = dev; desc->offset = gpio - uc_priv->gpio_base; desc->flags = 0; return 0; } } /* No such GPIO */ return ret ? ret : -ENOENT; }
int dma_get_device(u32 transfer_type, struct udevice **devp) { struct udevice *dev; int ret; for (ret = uclass_first_device(UCLASS_DMA, &dev); dev && !ret; ret = uclass_next_device(&dev)) { struct dma_dev_priv *uc_priv; uc_priv = dev_get_uclass_priv(dev); if (uc_priv->supported & transfer_type) break; } if (!dev) { pr_err("No DMA device found that supports %x type\n", transfer_type); return -EPROTONOSUPPORT; } *devp = dev; return ret; }
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; }