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; }
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; }
int soc_clk_ctl(const char *name, ulong *rate, enum clk_ctl_ops ctl) { int ret; ulong mhz_rate, priv_rate; struct clk clk; /* Dummy fmeas device, just to be able to use standard clk_* api */ struct udevice fmeas = { .name = "clk-fmeas", .node = ofnode_path("/clk-fmeas"), }; ret = clk_get_by_name(&fmeas, name, &clk); if (ret) { pr_err("clock '%s' not found, err=%d\n", name, ret); return ret; } if (ctl & CLK_ON) { ret = clk_enable(&clk); if (ret && ret != -ENOSYS && ret != -ENOTSUPP) return ret; } if ((ctl & CLK_SET) && rate) { priv_rate = ctl & CLK_MHZ ? (*rate) * HZ_IN_MHZ : *rate; ret = clk_set_rate(&clk, priv_rate); if (ret) return ret; } if (ctl & CLK_OFF) { ret = clk_disable(&clk); if (ret) { pr_err("clock '%s' can't be disabled, err=%d\n", name, ret); return ret; } } priv_rate = clk_get_rate(&clk); clk_free(&clk); mhz_rate = ceil(priv_rate, HZ_IN_MHZ); if (ctl & CLK_MHZ) priv_rate = mhz_rate; if ((ctl & CLK_GET) && rate) *rate = priv_rate; if ((ctl & CLK_PRINT) && (ctl & CLK_MHZ)) printf("HSDK: clock '%s' rate %lu MHz\n", name, priv_rate); else if (ctl & CLK_PRINT) printf("HSDK: clock '%s' rate %lu Hz\n", name, priv_rate); else debug("HSDK: clock '%s' rate %lu MHz\n", name, mhz_rate); 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 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; }
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); }