int ofnode_decode_memory_region(ofnode config_node, const char *mem_type, const char *suffix, fdt_addr_t *basep, fdt_size_t *sizep) { char prop_name[50]; const char *mem; fdt_size_t size, offset_size; fdt_addr_t base, offset; ofnode node; if (!ofnode_valid(config_node)) { config_node = ofnode_path("/config"); if (!ofnode_valid(config_node)) { debug("%s: Cannot find /config node\n", __func__); return -ENOENT; } } if (!suffix) suffix = ""; snprintf(prop_name, sizeof(prop_name), "%s-memory%s", mem_type, suffix); mem = ofnode_read_string(config_node, prop_name); if (!mem) { debug("%s: No memory type for '%s', using /memory\n", __func__, prop_name); mem = "/memory"; } node = ofnode_path(mem); if (!ofnode_valid(node)) { debug("%s: Failed to find node '%s'\n", __func__, mem); return -ENOENT; } /* * Not strictly correct - the memory may have multiple banks. We just * use the first */ if (ofnode_decode_region(node, "reg", &base, &size)) { debug("%s: Failed to decode memory region %s\n", __func__, mem); return -EINVAL; } snprintf(prop_name, sizeof(prop_name), "%s-offset%s", mem_type, suffix); if (ofnode_decode_region(config_node, prop_name, &offset, &offset_size)) { debug("%s: Failed to decode memory region '%s'\n", __func__, prop_name); return -EINVAL; } *basep = base + offset; *sizep = offset_size; return 0; }
struct regmap *syscon_regmap_lookup_by_phandle(struct udevice *dev, const char *name) { struct udevice *syscon; struct regmap *r; u32 phandle; ofnode node; int err; err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, name, &syscon); if (err) { /* found node with "syscon" compatible, not bounded to SYSCON */ err = ofnode_read_u32(dev_ofnode(dev), name, &phandle); if (err) return ERR_PTR(err); node = ofnode_get_by_phandle(phandle); if (!ofnode_valid(node)) { dev_dbg(dev, "unable to find syscon device\n"); return ERR_PTR(-EINVAL); } err = syscon_probe_by_ofnode(node, &syscon); if (err) return ERR_PTR(-ENODEV); } r = syscon_get_regmap(syscon); if (!r) { dev_dbg(dev, "unable to find regmap\n"); return ERR_PTR(-ENODEV); } return r; }
static int fs_loader_ofdata_to_platdata(struct udevice *dev) { const char *fs_loader_path; u32 phandlepart[2]; fs_loader_path = ofnode_get_chosen_prop("firmware-loader"); if (fs_loader_path) { ofnode fs_loader_node; fs_loader_node = ofnode_path(fs_loader_path); if (ofnode_valid(fs_loader_node)) { struct device_platdata *plat; plat = dev->platdata; if (!ofnode_read_u32_array(fs_loader_node, "phandlepart", phandlepart, 2)) { plat->phandlepart.phandle = phandlepart[0]; plat->phandlepart.partition = phandlepart[1]; } plat->mtdpart = (char *)ofnode_read_string( fs_loader_node, "mtdpart"); plat->ubivol = (char *)ofnode_read_string( fs_loader_node, "ubivol"); } } return 0; }
/* Base test of register maps */ static int dm_test_regmap_base(struct unit_test_state *uts) { struct udevice *dev; struct regmap *map; ofnode node; int i; ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev)); map = syscon_get_regmap(dev); ut_assertok_ptr(map); ut_asserteq(1, map->range_count); ut_asserteq(0x10, map->ranges[0].start); ut_asserteq(4, map->ranges[0].size); ut_asserteq(0x10, map_to_sysmem(regmap_get_range(map, 0))); ut_assertok(uclass_get_device(UCLASS_SYSCON, 1, &dev)); map = syscon_get_regmap(dev); ut_assertok_ptr(map); ut_asserteq(4, map->range_count); ut_asserteq(0x20, map->ranges[0].start); for (i = 0; i < 4; i++) { const unsigned long addr = 0x20 + 8 * i; ut_asserteq(addr, map->ranges[i].start); ut_asserteq(5 + i, map->ranges[i].size); ut_asserteq(addr, map_to_sysmem(regmap_get_range(map, i))); } /* Check that we can't pretend a different device is a syscon */ ut_assertok(uclass_get_device(UCLASS_I2C, 0, &dev)); map = syscon_get_regmap(dev); ut_asserteq_ptr(ERR_PTR(-ENOEXEC), map); /* A different device can be a syscon by using Linux-compat API */ node = ofnode_path("/syscon@2"); ut_assert(ofnode_valid(node)); map = syscon_node_to_regmap(node); ut_assertok_ptr(map); ut_asserteq(4, map->range_count); ut_asserteq(0x40, map->ranges[0].start); for (i = 0; i < 4; i++) { const unsigned long addr = 0x40 + 8 * i; ut_asserteq(addr, map->ranges[i].start); ut_asserteq(5 + i, map->ranges[i].size); ut_asserteq(addr, map_to_sysmem(regmap_get_range(map, i))); } return 0; }
static int gpio_dwapb_bind(struct udevice *dev) { struct gpio_dwapb_platdata *plat = dev_get_platdata(dev); struct udevice *subdev; fdt_addr_t base; int ret, bank = 0; ofnode node; /* If this is a child device, there is nothing to do here */ if (plat) return 0; base = dev_read_addr(dev); if (base == FDT_ADDR_T_NONE) { debug("Can't get the GPIO register base address\n"); return -ENXIO; } for (node = dev_read_first_subnode(dev); ofnode_valid(node); node = dev_read_next_subnode(node)) { if (!ofnode_read_bool(node, "gpio-controller")) continue; plat = devm_kcalloc(dev, 1, sizeof(*plat), GFP_KERNEL); if (!plat) return -ENOMEM; plat->base = base; plat->bank = bank; plat->pins = ofnode_read_u32_default(node, "snps,nr-gpios", 0); if (ofnode_read_string_index(node, "bank-name", 0, &plat->name)) { /* * Fall back to node name. This means accessing pins * via bank name won't work. */ plat->name = ofnode_get_name(node); } ret = device_bind(dev, dev->driver, plat->name, plat, -1, &subdev); if (ret) return ret; dev->node = node; bank++; } return 0; }
static int uclass_cpu_init(struct uclass *uc) { struct udevice *dev; ofnode node; int ret; node = ofnode_path("/cpus"); if (!ofnode_valid(node)) return 0; ret = device_bind_driver_to_node(dm_root(), "cpu_bus", "cpus", node, &dev); return ret; }
int pinctrl_select_state(struct udevice *dev, const char *statename) { /* * Some device which is logical like mmc.blk, do not have * a valid ofnode. */ if (!ofnode_valid(dev->node)) return 0; /* * Try full-implemented pinctrl first. * If it fails or is not implemented, try simple one. */ if (pinctrl_select_state_full(dev, statename)) return pinctrl_select_state_simple(dev); return 0; }
static int pmic_tps65910_bind(struct udevice *dev) { ofnode regulators_node; int children; regulators_node = dev_read_subnode(dev, "regulators"); if (!ofnode_valid(regulators_node)) { debug("%s regulators subnode not found\n", dev->name); return -EINVAL; } children = pmic_bind_children(dev, regulators_node, pmic_children_info); if (!children) debug("%s has no children (regulators)\n", dev->name); return 0; }
static int lp873x_bind(struct udevice *dev) { ofnode regulators_node; int children; regulators_node = dev_read_subnode(dev, "regulators"); if (!ofnode_valid(regulators_node)) { debug("%s: %s regulators subnode not found!", __func__, dev->name); return -ENXIO; } children = pmic_bind_children(dev, regulators_node, pmic_children_info); if (!children) printf("%s: %s - no child found\n", __func__, dev->name); /* Always return success for this device */ return 0; }
static int s2mps11_probe(struct udevice *dev) { ofnode regulators_node; int children; regulators_node = dev_read_subnode(dev, "voltage-regulators"); if (!ofnode_valid(regulators_node)) { debug("%s: %s regulators subnode not found!", __func__, dev->name); return -ENXIO; } debug("%s: '%s' - found regulators subnode\n", __func__, dev->name); children = pmic_bind_children(dev, regulators_node, pmic_children_info); if (!children) debug("%s: %s - no child found\n", __func__, dev->name); return 0; }
static int stpmu1_bind(struct udevice *dev) { #ifndef CONFIG_SPL_BUILD ofnode regulators_node; int children; regulators_node = dev_read_subnode(dev, "regulators"); if (!ofnode_valid(regulators_node)) { dev_dbg(dev, "regulators subnode not found!"); return -ENXIO; } dev_dbg(dev, "found regulators subnode\n"); children = pmic_bind_children(dev, regulators_node, stpmu1_children_info); if (!children) dev_dbg(dev, "no child found\n"); #endif /* CONFIG_SPL_BUILD */ return 0; }
static int s5m8767_bind(struct udevice *dev) { int children; ofnode node; node = dev_read_subnode(dev, "regulators"); if (!ofnode_valid(node)) { debug("%s: %s regulators subnode not found!", __func__, dev->name); return -ENXIO; } debug("%s: '%s' - found regulators subnode\n", __func__, dev->name); children = pmic_bind_children(dev, node, pmic_children_info); if (!children) debug("%s: %s - no child found\n", __func__, dev->name); /* Always return success for this device */ return 0; }
static int max77686_bind(struct udevice *dev) { ofnode regulators_node; int children; regulators_node = dev_read_subnode(dev, "voltage-regulators"); if (!ofnode_valid(regulators_node)) { debug("%s: %s regulators subnode not found!\n", __func__, dev->name); return -ENXIO; } debug("%s: '%s' - found regulators subnode\n", __func__, dev->name); children = pmic_bind_children(dev, regulators_node, pmic_children_info); if (!children) debug("%s: %s - no child found\n", __func__, dev->name); /* Always return success for this device */ return 0; }
static void rk3399_force_power_on_reset(void) { ofnode node; struct gpio_desc sysreset_gpio; debug("%s: trying to force a power-on reset\n", __func__); node = ofnode_path("/config"); if (!ofnode_valid(node)) { debug("%s: no /config node?\n", __func__); return; } if (gpio_request_by_name_nodev(node, "sysreset-gpio", 0, &sysreset_gpio, GPIOD_IS_OUT)) { debug("%s: could not find a /config/sysreset-gpio\n", __func__); return; } dm_gpio_set_value(&sysreset_gpio, 1); }
int cros_ec_decode_ec_flash(struct udevice *dev, struct fdt_cros_ec *config) { ofnode flash_node, node; flash_node = dev_read_subnode(dev, "flash"); if (!ofnode_valid(flash_node)) { debug("Failed to find flash node\n"); return -1; } if (ofnode_read_fmap_entry(flash_node, &config->flash)) { debug("Failed to decode flash node in chrome-ec\n"); return -1; } config->flash_erase_value = ofnode_read_s32_default(flash_node, "erase-value", -1); ofnode_for_each_subnode(node, flash_node) { const char *name = ofnode_get_name(node); 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_ACTIVE; } 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 (ofnode_read_fmap_entry(node, &config->region[region])) { debug("Failed to decode flash region in chrome-ec'\n"); return -1; } } return 0; }