int fit_add_verification_data(const char *keydir, void *keydest, void *fit, const char *comment, int require_keys, const char *engine_id) { int images_noffset, confs_noffset; int noffset; int ret; /* Find images parent node offset */ images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); if (images_noffset < 0) { printf("Can't find images parent node '%s' (%s)\n", FIT_IMAGES_PATH, fdt_strerror(images_noffset)); return images_noffset; } /* Process its subnodes, print out component images details */ for (noffset = fdt_first_subnode(fit, images_noffset); noffset >= 0; noffset = fdt_next_subnode(fit, noffset)) { /* * Direct child node of the images parent node, * i.e. component image node. */ ret = fit_image_add_verification_data(keydir, keydest, fit, noffset, comment, require_keys, engine_id); if (ret) return ret; } /* If there are no keys, we can't sign configurations */ if (!IMAGE_ENABLE_SIGN || !keydir) return 0; /* Find configurations parent node offset */ confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH); if (confs_noffset < 0) { printf("Can't find images parent node '%s' (%s)\n", FIT_CONFS_PATH, fdt_strerror(confs_noffset)); return -ENOENT; } /* Process its subnodes, print out component images details */ for (noffset = fdt_first_subnode(fit, confs_noffset); noffset >= 0; noffset = fdt_next_subnode(fit, noffset)) { ret = fit_config_add_verification_data(keydir, keydest, fit, noffset, comment, require_keys, engine_id); if (ret) return ret; } return 0; }
static void setup_axp803_rails(const void *fdt) { int node; bool dc1sw = false; /* locate the PMIC DT node, bail out if not found */ node = fdt_node_offset_by_compatible(fdt, -1, "x-powers,axp803"); if (node == -FDT_ERR_NOTFOUND) { WARN("BL31: PMIC: No AXP803 DT node, skipping initial setup.\n"); return; } if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL)) { axp_clrbits(0x8f, BIT(4)); axp_setbits(0x30, BIT(2)); INFO("PMIC: AXP803: Enabling DRIVEVBUS\n"); } /* descend into the "regulators" subnode */ node = fdt_first_subnode(fdt, node); /* iterate over all regulators to find used ones */ for (node = fdt_first_subnode(fdt, node); node != -FDT_ERR_NOTFOUND; node = fdt_next_subnode(fdt, node)) { struct axp_regulator *reg; const char *name; int length; /* We only care if it's always on or referenced. */ if (!should_enable_regulator(fdt, node)) continue; name = fdt_get_name(fdt, node, &length); for (reg = regulators; reg->dt_name; reg++) { if (!strncmp(name, reg->dt_name, length)) { setup_regulator(fdt, node, reg); break; } } if (!strncmp(name, "dc1sw", length)) { /* Delay DC1SW enablement to avoid overheating. */ dc1sw = true; continue; } } /* * If DLDO2 is enabled after DC1SW, the PMIC overheats and shuts * down. So always enable DC1SW as the very last regulator. */ if (dc1sw) { INFO("PMIC: AXP803: Enabling DC1SW\n"); axp_setbits(0x12, BIT(7)); } }
static void parse_node(const char *dtb, int node, void (*mem_cb)(uint32_t addr, uint32_t length)) { int parent = node; node = fdt_first_subnode(dtb, node); while(node >= 0) { const void *dt; int plen; dt = fdt_getprop(dtb, node, "device_type", &plen); #ifdef DEBUG_DTB const char *nn; nn = fdt_get_name(dtb, node, NULL); if(dt != NULL && nn != NULL) { printf("DTB: found device_type property for %s: %s\n", nn, (const char *)dt); } else if(nn != NULL) printf("DTB: found node %s\n", nn); else printf("DTB: unknown node\n"); #endif if(dt != NULL && !strcmp((const char *)dt, "memory")) { parse_reg(dtb, node, parent, mem_cb); } parse_node(dtb, node, mem_cb); node = fdt_next_subnode(dtb, node); } }
static int led_gpio_bind(struct udevice *parent) { const void *blob = gd->fdt_blob; struct udevice *dev; int node; int ret; for (node = fdt_first_subnode(blob, dev_of_offset(parent)); node > 0; node = fdt_next_subnode(blob, node)) { struct led_uclass_plat *uc_plat; const char *label; label = fdt_getprop(blob, node, "label", NULL); if (!label) { debug("%s: node %s has no label\n", __func__, fdt_get_name(blob, node, NULL)); return -EINVAL; } ret = device_bind_driver_to_node(parent, "gpio_led", fdt_get_name(blob, node, NULL), node, &dev); if (ret) return ret; uc_plat = dev_get_uclass_platdata(dev); uc_plat->label = label; } return 0; }
static int do_pinctrl_pins(const void *blob, int node, const char *child_name) { int child, len; const char *node_name; child = fdt_first_subnode(blob, node); if (child < 0) return -EINVAL; node_name = fdt_get_name(blob, child, &len); while (node_name) { if (!strcmp(child_name, node_name)) return do_pinctr_pin(blob, child, node_name); child = fdt_next_subnode(blob, child); if (child < 0) break; node_name = fdt_get_name(blob, child, &len); } return -EFAULT; }
/* Find the I2C buses selected by this mux */ static int i2c_mux_post_bind(struct udevice *mux) { const void *blob = gd->fdt_blob; int ret; int offset; debug("%s: %s\n", __func__, mux->name); /* * There is no compatible string in the sub-nodes, so we must manually * bind these */ for (offset = fdt_first_subnode(blob, mux->of_offset); offset > 0; offset = fdt_next_subnode(blob, offset)) { struct udevice *dev; const char *name; name = fdt_get_name(blob, offset, NULL); ret = device_bind_driver_to_node(mux, "i2c_mux_bus_drv", name, offset, &dev); debug(" - bind ret=%d, %s\n", ret, dev ? dev->name : NULL); if (ret) return ret; } return 0; }
int dm_scan_fdt_node(struct udevice *parent, const void *blob, int offset, bool pre_reloc_only) { int ret = 0, err; for (offset = fdt_first_subnode(blob, offset); offset > 0; offset = fdt_next_subnode(blob, offset)) { if (pre_reloc_only && !fdt_getprop(blob, offset, "u-boot,dm-pre-reloc", NULL)) continue; if (!fdtdec_get_is_enabled(blob, offset)) { dm_dbg(" - ignoring disabled device\n"); continue; } err = lists_bind_fdt(parent, blob, offset, NULL); if (err && !ret) { ret = err; debug("%s: ret=%d\n", fdt_get_name(blob, offset, NULL), ret); } } if (ret) dm_warn("Some drivers failed to bind\n"); return ret; }
static int get_mrc_entry(struct udevice **devp, struct fmap_entry *entry) { const void *blob = gd->fdt_blob; int node, spi_node, mrc_node; int upto; int ret; /* Find the flash chip within the SPI controller node */ upto = 0; spi_node = fdtdec_next_alias(blob, "spi", COMPAT_INTEL_ICH_SPI, &upto); if (spi_node < 0) return -ENOENT; node = fdt_first_subnode(blob, spi_node); if (node < 0) return -ECHILD; /* Find the place where we put the MRC cache */ mrc_node = fdt_subnode_offset(blob, node, "rw-mrc-cache"); if (mrc_node < 0) return -EPERM; if (fdtdec_read_fmap_entry(blob, mrc_node, "rm-mrc-cache", entry)) return -EINVAL; if (devp) { debug("getting sf\n"); ret = uclass_get_device_by_of_offset(UCLASS_SPI_FLASH, node, devp); debug("ret = %d\n", ret); if (ret) return ret; } return 0; }
static int fit_config_add_verification_data(const char *keydir, void *keydest, void *fit, int conf_noffset, const char *comment, int require_keys) { const char *conf_name; int noffset; conf_name = fit_get_name(fit, conf_noffset, NULL); /* Process all hash subnodes of the configuration node */ for (noffset = fdt_first_subnode(fit, conf_noffset); noffset >= 0; noffset = fdt_next_subnode(fit, noffset)) { const char *node_name; int ret = 0; node_name = fit_get_name(fit, noffset, NULL); if (!strncmp(node_name, FIT_SIG_NODENAME, strlen(FIT_SIG_NODENAME))) { ret = fit_config_process_sig(keydir, keydest, fit, conf_name, conf_noffset, noffset, comment, require_keys); } if (ret) return ret; } return 0; }
int gpio_ich6_pinctrl_init(void) { int pin_node; int node; int ret; int gpiobase; int iobase_offset; int iobase = -1; /* * Get the memory/io base address to configure every pins. * IOBASE is used to configure the mode/pads * GPIOBASE is used to configure the direction and default value */ gpiobase = gpio_ich6_get_base(PCI_CFG_GPIOBASE); if (gpiobase < 0) { debug("%s: invalid GPIOBASE address (%08x)\n", __func__, gpiobase); return -EINVAL; } /* This is not an error to not have a pinctrl node */ node = fdtdec_next_compatible(gd->fdt_blob, 0, COMPAT_INTEL_X86_PINCTRL); if (node <= 0) { debug("%s: no pinctrl node\n", __func__); return 0; } /* * Get the IOBASE, this is not mandatory as this is not * supported by all the CPU */ iobase_offset = fdtdec_get_int(gd->fdt_blob, node, "io-base", -1); if (iobase_offset == -1) { debug("%s: io-base offset not present\n", __func__); } else { iobase = gpio_ich6_get_base(iobase_offset); if (IS_ERR_VALUE(iobase)) { debug("%s: invalid IOBASE address (%08x)\n", __func__, iobase); return -EINVAL; } } for (pin_node = fdt_first_subnode(gd->fdt_blob, node); pin_node > 0; pin_node = fdt_next_subnode(gd->fdt_blob, pin_node)) { /* Configure the pin */ ret = _gpio_ich6_pinctrl_cfg_pin(gpiobase, iobase, pin_node); if (ret != 0) { debug("%s: invalid configuration for the pin %d\n", __func__, pin_node); return ret; } } return 0; }
static uint32_t get_cpu_freq(void) { void *fdt = get_fdt_virt(); int cpus_node = fdt_path_offset(fdt, "/cpus"); int cpu_node = fdt_first_subnode(fdt, cpus_node); const char *prop = "clock-frequency"; return fdt_getprop_u32_default_node(fdt, cpu_node, 0, prop, 0); }
unsigned long get_tbclk (void) { void *fdt = get_fdt_virt(); int cpus_node = fdt_path_offset(fdt, "/cpus"); int cpu_node = fdt_first_subnode(fdt, cpus_node); const char *prop = "timebase-frequency"; return fdt_getprop_u32_default_node(fdt, cpu_node, 0, prop, 0); }
static size_t remove_reserved_memory( const void *fdt, Heap_Area *areas, size_t area_count ) { int node; node = fdt_path_offset_namelen( fdt, reserved_memory_path, (int) sizeof(reserved_memory_path) - 1 ); if (node >= 0) { node = fdt_first_subnode(fdt, node); while (node >= 0) { int len; const void *val; uintptr_t area_begin; uintptr_t area_end; uintptr_t hole_begin; uintptr_t hole_end; Heap_Area *area; val = fdt_getprop(fdt, node, "reg", &len); if (len == 8) { hole_begin = fdt32_to_cpu(((fdt32_t *) val)[0]); hole_end = hole_begin + fdt32_to_cpu(((fdt32_t *) val)[1]); } else { rtems_panic("unexpected reserved memory area"); } area = find_area(areas, area_count, hole_begin); area_begin = (uintptr_t) area->begin; area_end = area_begin + (uintptr_t) area->size; area->size = hole_begin - area_begin; if (hole_end <= area_end) { if (area_count >= AREA_COUNT_MAX) { rtems_panic("too many reserved memory areas"); } area = &areas[area_count]; ++area_count; area->begin = (void *) hole_end; area->size = area_end - hole_end; } node = fdt_next_subnode(fdt, node); } } return area_count; }
static int copy_spd(struct pei_data *peid) { const int gpio_vector[] = {41, 42, 43, 10, -1}; int spd_index; const void *blob = gd->fdt_blob; int node, spd_node; int ret, i; for (i = 0; ; i++) { if (gpio_vector[i] == -1) break; ret = gpio_requestf(gpio_vector[i], "spd_id%d", i); if (ret) { debug("%s: Could not request gpio %d\n", __func__, gpio_vector[i]); return ret; } } spd_index = gpio_get_values_as_int(gpio_vector); debug("spd index %d\n", spd_index); node = fdtdec_next_compatible(blob, 0, COMPAT_MEMORY_SPD); if (node < 0) { printf("SPD data not found.\n"); return -ENOENT; } for (spd_node = fdt_first_subnode(blob, node); spd_node > 0; spd_node = fdt_next_subnode(blob, spd_node)) { const char *data; int len; if (fdtdec_get_int(blob, spd_node, "reg", -1) != spd_index) continue; data = fdt_getprop(blob, spd_node, "data", &len); if (len < sizeof(peid->spd_data[0])) { printf("Missing SPD data\n"); return -EINVAL; } debug("Using SDRAM SPD data for '%s'\n", fdt_get_name(blob, spd_node, NULL)); memcpy(peid->spd_data[0], data, sizeof(peid->spd_data[0])); break; } if (spd_node < 0) { printf("No SPD data found for index %d\n", spd_index); return -ENOENT; } return 0; }
static int gpio_dwapb_bind(struct udevice *dev) { struct gpio_dwapb_platdata *plat = dev_get_platdata(dev); const void *blob = gd->fdt_blob; struct udevice *subdev; fdt_addr_t base; int ret, node, bank = 0; /* If this is a child device, there is nothing to do here */ if (plat) return 0; base = fdtdec_get_addr(blob, dev_of_offset(dev), "reg"); if (base == FDT_ADDR_T_NONE) { debug("Can't get the GPIO register base address\n"); return -ENXIO; } for (node = fdt_first_subnode(blob, dev_of_offset(dev)); node > 0; node = fdt_next_subnode(blob, node)) { if (!fdtdec_get_bool(blob, node, "gpio-controller")) continue; plat = NULL; plat = calloc(1, sizeof(*plat)); if (!plat) return -ENOMEM; plat->base = base; plat->bank = bank; plat->pins = fdtdec_get_int(blob, node, "snps,nr-gpios", 0); plat->name = fdt_stringlist_get(blob, node, "bank-name", 0, NULL); if (ret) goto err; ret = device_bind(dev, dev->driver, plat->name, plat, -1, &subdev); if (ret) goto err; dev_set_of_offset(subdev, node); bank++; } return 0; err: free(plat); return ret; }
int cros_ec_decode_ec_flash(const void *blob, struct fdt_cros_ec *config) { int flash_node, node; node = fdtdec_next_compatible(blob, 0, COMPAT_GOOGLE_CROS_EC); if (node < 0) { debug("Failed to find chrome-ec node'\n"); return -1; } flash_node = fdt_subnode_offset(blob, node, "flash"); if (flash_node < 0) { debug("Failed to find flash node\n"); return -1; } if (fdtdec_read_fmap_entry(blob, flash_node, "flash", &config->flash)) { debug("Failed to decode flash node in chrome-ec'\n"); return -1; } config->flash_erase_value = fdtdec_get_int(blob, flash_node, "erase-value", -1); for (node = fdt_first_subnode(blob, flash_node); node >= 0; node = fdt_next_subnode(blob, node)) { const char *name = fdt_get_name(blob, node, NULL); enum ec_flash_region region; if (0 == strcmp(name, "ro")) { region = EC_FLASH_REGION_RO; } else if (0 == strcmp(name, "rw")) { region = EC_FLASH_REGION_RW; } else if (0 == strcmp(name, "wp-ro")) { region = EC_FLASH_REGION_WP_RO; } else { debug("Unknown EC flash region name '%s'\n", name); return -1; } if (fdtdec_read_fmap_entry(blob, node, "reg", &config->region[region])) { debug("Failed to decode flash region in chrome-ec'\n"); return -1; } } return 0; }
/** * fit_image_add_verification_data() - calculate/set verig. data for image node * * This adds hash and signature values for an component image node. * * All existing hash subnodes are checked, if algorithm property is set to * one of the supported hash algorithms, hash value is computed and * corresponding hash node property is set, for example: * * Input component image node structure: * * o image@1 (at image_noffset) * | - data = [binary data] * o hash@1 * |- algo = "sha1" * * Output component image node structure: * * o image@1 (at image_noffset) * | - data = [binary data] * o hash@1 * |- algo = "sha1" * |- value = sha1(data) * * For signature details, please see doc/uImage.FIT/signature.txt * * @keydir Directory containing *.key and *.crt files (or NULL) * @keydest FDT Blob to write public keys into (NULL if none) * @fit: Pointer to the FIT format image header * @image_noffset: Requested component image node * @comment: Comment to add to signature nodes * @require_keys: Mark all keys as 'required' * @return: 0 on success, <0 on failure */ int fit_image_add_verification_data(const char *keydir, void *keydest, void *fit, int image_noffset, const char *comment, int require_keys) { const char *image_name; const void *data; size_t size; int noffset; /* Get image data and data length */ if (fit_image_get_data(fit, image_noffset, &data, &size)) { printf("Can't get image data/size\n"); return -1; } image_name = fit_get_name(fit, image_noffset, NULL); /* Process all hash subnodes of the component image node */ for (noffset = fdt_first_subnode(fit, image_noffset); noffset >= 0; noffset = fdt_next_subnode(fit, noffset)) { const char *node_name; int ret = 0; /* * Check subnode name, must be equal to "hash" or "signature". * Multiple hash nodes require unique unit node * names, e.g. hash@1, hash@2, signature@1, etc. */ node_name = fit_get_name(fit, noffset, NULL); if (!strncmp(node_name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) { ret = fit_image_process_hash(fit, image_name, noffset, data, size); } else if (IMAGE_ENABLE_SIGN && keydir && !strncmp(node_name, FIT_SIG_NODENAME, strlen(FIT_SIG_NODENAME))) { ret = fit_image_process_sig(keydir, keydest, fit, image_name, noffset, data, size, comment, require_keys); } if (ret) return ret; } return 0; }
static int cadence_spi_ofdata_to_platdata(struct udevice *bus) { struct cadence_spi_platdata *plat = bus->platdata; const void *blob = gd->fdt_blob; int node = bus->of_offset; int subnode; u32 data[4]; int ret; /* 2 base addresses are needed, lets get them from the DT */ ret = fdtdec_get_int_array(blob, node, "reg", data, ARRAY_SIZE(data)); if (ret) { printf("Error: Can't get base addresses (ret=%d)!\n", ret); return -ENODEV; } plat->regbase = (void *)data[0]; plat->ahbbase = (void *)data[2]; /* Use 500KHz as a suitable default */ plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 500000); /* All other paramters are embedded in the child node */ subnode = fdt_first_subnode(blob, node); if (subnode < 0) { printf("Error: subnode with SPI flash config missing!\n"); return -ENODEV; } /* Read other parameters from DT */ plat->page_size = fdtdec_get_int(blob, subnode, "page-size", 256); plat->block_size = fdtdec_get_int(blob, subnode, "block-size", 16); plat->tshsl_ns = fdtdec_get_int(blob, subnode, "tshsl-ns", 200); plat->tsd2d_ns = fdtdec_get_int(blob, subnode, "tsd2d-ns", 255); plat->tchsh_ns = fdtdec_get_int(blob, subnode, "tchsh-ns", 20); plat->tslch_ns = fdtdec_get_int(blob, subnode, "tslch-ns", 20); plat->sram_size = fdtdec_get_int(blob, node, "sram-size", 128); debug("%s: regbase=%p ahbbase=%p max-frequency=%d page-size=%d\n", __func__, plat->regbase, plat->ahbbase, plat->max_hz, plat->page_size); return 0; }
int ft_board_setup(void *fdt, bd_t *bd) { int offset, tmp, len; const struct fdt_property *prop; const char *cci_compatible = "arm,cci-400-ctrl-if"; #ifdef CONFIG_ARMV7_NONSEC if (!armv7_boot_nonsec()) return 0; #else return 0; #endif /* Booting in nonsec mode, disable CCI access */ offset = fdt_path_offset(fdt, "/cpus"); if (offset < 0) { printf("couldn't find /cpus\n"); return offset; } /* delete cci-control-port in each cpu node */ for (tmp = fdt_first_subnode(fdt, offset); tmp >= 0; tmp = fdt_next_subnode(fdt, tmp)) fdt_delprop(fdt, tmp, "cci-control-port"); /* disable all ace cci slave ports */ offset = fdt_node_offset_by_prop_value(fdt, offset, "compatible", cci_compatible, 20); while (offset > 0) { prop = fdt_get_property(fdt, offset, "interface-type", &len); if (!prop) continue; if (len < 4) continue; if (strcmp(prop->data, "ace")) continue; fdt_setprop_string(fdt, offset, "status", "disabled"); offset = fdt_node_offset_by_prop_value(fdt, offset, "compatible", cci_compatible, 20); } return 0; }
/** * We have a top-level GPIO device with no actual GPIOs. It has a child * device for each Exynos GPIO bank. */ static int gpio_exynos_bind(struct udevice *parent) { struct exynos_gpio_platdata *plat = parent->platdata; struct s5p_gpio_bank *bank, *base; const void *blob = gd->fdt_blob; int node; /* If this is a child device, there is nothing to do here */ if (plat) return 0; base = (struct s5p_gpio_bank *)fdtdec_get_addr(gd->fdt_blob, parent->of_offset, "reg"); for (node = fdt_first_subnode(blob, parent->of_offset), bank = base; node > 0; node = fdt_next_subnode(blob, node), bank++) { struct exynos_gpio_platdata *plat; struct udevice *dev; fdt_addr_t reg; int ret; if (!fdtdec_get_bool(blob, node, "gpio-controller")) continue; plat = calloc(1, sizeof(*plat)); if (!plat) return -ENOMEM; reg = fdtdec_get_addr(blob, node, "reg"); if (reg != FDT_ADDR_T_NONE) bank = (struct s5p_gpio_bank *)((ulong)base + reg); plat->bank = bank; plat->bank_name = fdt_get_name(blob, node, NULL); debug("dev at %p: %s\n", bank, plat->bank_name); ret = device_bind(parent, parent->driver, plat->bank_name, plat, -1, &dev); if (ret) return ret; dev->of_offset = node; } return 0; }
static uint32_t discover_processors(void) { #if defined(HAS_UBOOT) return QORIQ_CPU_COUNT; #elif defined(U_BOOT_USE_FDT) const void *fdt = bsp_fdt_get(); int cpus = fdt_path_offset(fdt, "/cpus"); int node = fdt_first_subnode(fdt, cpus); uint32_t cpu = 0; uintptr_t last = 0; uintptr_t begin = last - 1; while (node >= 0) { int len; fdt64_t *addr_fdt = (fdt64_t *) fdt_getprop(fdt, node, "cpu-release-addr", &len); if ( addr_fdt != NULL && cpu < RTEMS_ARRAY_SIZE(qoriq_start_spin_table_addr) ) { uintptr_t addr = (uintptr_t) fdt64_to_cpu(*addr_fdt); if (addr < begin) { begin = addr; } if (addr > last) { last = addr; } qoriq_start_spin_table_addr[cpu] = (qoriq_start_spin_table *) addr; ++cpu; } node = fdt_next_subnode(fdt, node); } return cpu * QORIQ_THREAD_COUNT; #endif }
/** * spl_fit_get_image_name(): By using the matching configuration subnode, * retrieve the name of an image, specified by a property name and an index * into that. * @fit: Pointer to the FDT blob. * @images: Offset of the /images subnode. * @type: Name of the property within the configuration subnode. * @index: Index into the list of strings in this property. * @outname: Name of the image * * Return: 0 on success, or a negative error number */ static int spl_fit_get_image_name(const void *fit, int images, const char *type, int index, char **outname) { const char *name, *str; __maybe_unused int node; int conf_node; int len, i; conf_node = fit_find_config_node(fit); if (conf_node < 0) { #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT printf("No matching DT out of these options:\n"); for (node = fdt_first_subnode(fit, conf_node); node >= 0; node = fdt_next_subnode(fit, node)) { name = fdt_getprop(fit, node, "description", &len); printf(" %s\n", name); } #endif return conf_node; } name = fdt_getprop(fit, conf_node, type, &len); if (!name) { debug("cannot find property '%s': %d\n", type, len); return -EINVAL; } str = name; for (i = 0; i < index; i++) { str = strchr(str, '\0') + 1; if (!str || (str - name >= len)) { debug("no string for index %d\n", index); return -E2BIG; } } *outname = (char *)str; return 0; }
/* Find a device by matching its compatible property */ static void parse_dtb_compatible_helper(const char *dtb, const char *compat, int node, void (*cb)(const char *dtb, int node, int parent)) { int parent = node; node = fdt_first_subnode(dtb, node); while(node >= 0) { const char *haystack = fdt_getprop(dtb, node, "compatible", NULL); if(compat) { if(strstr(haystack, compat)) { cb(dtb, node, parent); } } parse_dtb_compatible_helper(dtb, compat, node, cb); node = fdt_next_subnode(dtb, node); } }
static dt_node_t add_device_fdt(dt_node_t parent, void *fdt, int fdt_node, int depth) { const char *name = fdt_get_name(fdt, fdt_node, NULL); printf("%*cEnumerating \"%s\"\n", depth, ' ', name); dt_node_t n = dt_node_alloc(parent, name); if (!n) panic("Out of memory enumerating node \"%s\"\n", name); for (int propoff = fdt_first_property_offset(fdt, fdt_node); propoff >= 0; propoff = fdt_next_property_offset(fdt, propoff)) { int len; const struct fdt_property *fdt_prop = fdt_get_property_by_offset(fdt, propoff, &len); if (!fdt_prop) { panic("Error getting property of \"%s\": %s\n", name, fdt_strerror(len)); } const char *prop_name = fdt_string(fdt, fdt32_to_cpu(fdt_prop->nameoff)); printf("%*c \"%s\" = \"", depth, ' ', prop_name); print_dtval(fdt_prop->data, len); printf("\"\n"); if (!dt_node_set_property(n, prop_name, fdt_prop->data, len)) panic("Out of memory allocating \"%s\":\"%s\"", name, prop_name); } for (int suboff = fdt_first_subnode(fdt, fdt_node); suboff != -FDT_ERR_NOTFOUND; suboff = fdt_next_subnode(fdt, suboff)) { add_device_fdt(n, fdt, suboff, depth + 2); } return n; }
const char *dpl_get_connection_endpoint(void *blob, char *endpoint) { int connoffset = fdt_path_offset(blob, "/connections"), off; const char *s1, *s2; for (off = fdt_first_subnode(blob, connoffset); off >= 0; off = fdt_next_subnode(blob, off)) { s1 = fdt_stringlist_get(blob, off, "endpoint1", 0, NULL); s2 = fdt_stringlist_get(blob, off, "endpoint2", 0, NULL); if (!s1 || !s2) continue; if (strcmp(endpoint, s1) == 0) return s2; if (strcmp(endpoint, s2) == 0) return s1; } return NULL; }
static uint32_t discover_processors(void) { const void *fdt = bsp_fdt_get(); int cpus = fdt_path_offset(fdt, "/cpus"); int node = fdt_first_subnode(fdt, cpus); uint32_t cpu = 0; while (node >= 0 && cpu < RTEMS_ARRAY_SIZE(qoriq_start_spin_table_addr)) { int len; fdt64_t *addr_fdt = (fdt64_t *) fdt_getprop(fdt, node, "cpu-release-addr", &len); if (addr_fdt != NULL) { uintptr_t addr = (uintptr_t) fdt64_to_cpu(*addr_fdt); qoriq_start_spin_table_addr[cpu] = (qoriq_start_spin_table *) addr; } ++cpu; node = fdt_next_subnode(fdt, node); } return cpu * QORIQ_THREAD_COUNT; }
static int ti_musb_wrapper_bind(struct udevice *parent) { const void *fdt = gd->fdt_blob; int node; int ret; for (node = fdt_first_subnode(fdt, parent->of_offset); node > 0; node = fdt_next_subnode(fdt, node)) { struct udevice *dev; const char *name = fdt_get_name(fdt, node, NULL); enum usb_dr_mode dr_mode; struct driver *drv; if (strncmp(name, "usb@", 4)) continue; dr_mode = usb_get_dr_mode(node); switch (dr_mode) { case USB_DR_MODE_PERIPHERAL: /* Bind MUSB device */ break; case USB_DR_MODE_HOST: /* Bind MUSB host */ ret = device_bind_driver_to_node(parent, "ti-musb-host", name, node, &dev); if (ret) { error("musb - not able to bind usb host node\n"); return ret; } break; default: break; }; } return 0; }
static int cpu_x86_get_count(struct udevice *dev) { int node, cpu; int num = 0; node = fdt_path_offset(gd->fdt_blob, "/cpus"); if (node < 0) return -ENOENT; for (cpu = fdt_first_subnode(gd->fdt_blob, node); cpu >= 0; cpu = fdt_next_subnode(gd->fdt_blob, cpu)) { const char *device_type; device_type = fdt_getprop(gd->fdt_blob, cpu, "device_type", NULL); if (!device_type) continue; if (strcmp(device_type, "cpu") == 0) num++; } return num; }
int fit_list_configs(void *fit, int configs_offset) { int node; int count; const char *default_cfg = fdt_getprop(fit, configs_offset, "default", NULL); printf("\n\n Default configuration: %s\n", default_cfg); for(count = 0,node = fdt_first_subnode(fit, configs_offset); node >= 0; node = fdt_next_subnode(fit, node), count++) { printf("\n === Configuration (%d) - %s ===\n", count, fdt_get_name(fit, node, NULL)); const char *description = fdt_getprop(fit, node, "description", NULL); printf(" Description : %s\n", description); const char *kernel = fdt_getprop(fit, node, "kernel", NULL); printf(" Kernel : %s\n", kernel); const char *fpga = fdt_getprop(fit, node, "fpga", NULL); if(fpga) { const char *fpga_device = fdt_getprop(fit, node, "fpga_device", NULL); printf(" fpga : %s\n", fpga); printf(" fpga_device : %s\n", fpga_device); } } }
/** * at91_clk_sub_device_bind() - for the at91 clock driver * Recursively bind its children as clk devices. * * @return: 0 on success, or negative error code on failure */ int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name) { const void *fdt = gd->fdt_blob; int offset = dev_of_offset(dev); bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC); const char *name; int ret; for (offset = fdt_first_subnode(fdt, offset); offset > 0; offset = fdt_next_subnode(fdt, offset)) { if (pre_reloc_only && !fdt_getprop(fdt, offset, "u-boot,dm-pre-reloc", NULL)) continue; /* * If this node has "compatible" property, this is not * a clock sub-node, but a normal device. skip. */ fdt_get_property(fdt, offset, "compatible", &ret); if (ret >= 0) continue; if (ret != -FDT_ERR_NOTFOUND) return ret; name = fdt_get_name(fdt, offset, NULL); if (!name) return -EINVAL; ret = device_bind_driver_to_node(dev, drv_name, name, offset, NULL); if (ret) return ret; } return 0; }