/* Test that we can find a device by device tree offset */ static int dm_test_fdt_offset(struct unit_test_state *uts) { const void *blob = gd->fdt_blob; struct udevice *dev; int node; node = fdt_path_offset(blob, "/e-test"); ut_assert(node > 0); ut_assertok(uclass_get_device_by_of_offset(UCLASS_TEST_FDT, node, &dev)); ut_asserteq_str("e-test", dev->name); /* This node should not be bound */ node = fdt_path_offset(blob, "/junk"); ut_assert(node > 0); ut_asserteq(-ENODEV, uclass_get_device_by_of_offset(UCLASS_TEST_FDT, node, &dev)); /* This is not a top level node so should not be probed */ node = fdt_path_offset(blob, "/some-bus/c-test@5"); ut_assert(node > 0); ut_asserteq(-ENODEV, uclass_get_device_by_of_offset(UCLASS_TEST_FDT, node, &dev)); return 0; }
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"); }
static int pwm_regulator_ofdata_to_platdata(struct udevice *dev) { struct pwm_regulator_info *priv = dev_get_priv(dev); struct fdtdec_phandle_args args; const void *blob = gd->fdt_blob; int node = dev_of_offset(dev); int ret; ret = fdtdec_parse_phandle_with_args(blob, node, "pwms", "#pwm-cells", 0, 0, &args); if (ret) { debug("%s: Cannot get PWM phandle: ret=%d\n", __func__, ret); return ret; } priv->period_ns = args.args[1]; priv->polarity = args.args[2]; priv->init_voltage = fdtdec_get_int(blob, node, "regulator-init-microvolt", -1); if (priv->init_voltage < 0) { printf("Cannot find regulator pwm init_voltage\n"); return -EINVAL; } ret = uclass_get_device_by_of_offset(UCLASS_PWM, args.node, &priv->pwm); if (ret) { debug("%s: Cannot get PWM: ret=%d\n", __func__, ret); return ret; } return 0; }
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; }
int i2c_get_bus_num_fdt(int node) { struct udevice *bus; int ret; ret = uclass_get_device_by_of_offset(UCLASS_I2C, node, &bus); if (ret) return ret; return bus->seq; }
static int pwm_backlight_ofdata_to_platdata(struct udevice *dev) { struct pwm_backlight_priv *priv = dev_get_priv(dev); struct fdtdec_phandle_args args; const void *blob = gd->fdt_blob; int node = dev->of_offset; int index, ret, count, len; const u32 *cell; ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev, "power-supply", &priv->reg); if (ret) { debug("%s: Cannot get power supply: ret=%d\n", __func__, ret); return ret; } ret = gpio_request_by_name(dev, "enable-gpios", 0, &priv->enable, GPIOD_IS_OUT); if (ret) { debug("%s: Warning: cannot get enable GPIO: ret=%d\n", __func__, ret); if (ret != -ENOENT) return ret; } ret = fdtdec_parse_phandle_with_args(blob, node, "pwms", "#pwm-cells", 0, 0, &args); if (ret) { debug("%s: Cannot get PWM phandle: ret=%d\n", __func__, ret); return ret; } ret = uclass_get_device_by_of_offset(UCLASS_PWM, args.node, &priv->pwm); if (ret) { debug("%s: Cannot get PWM: ret=%d\n", __func__, ret); return ret; } priv->channel = args.args[0]; priv->period_ns = args.args[1]; index = fdtdec_get_int(blob, node, "default-brightness-level", 255); cell = fdt_getprop(blob, node, "brightness-levels", &len); count = len / sizeof(u32); if (cell && count > index) { priv->default_level = fdt32_to_cpu(cell[index]); priv->max_level = fdt32_to_cpu(cell[count - 1]); } else { priv->default_level = index; priv->max_level = 255; } return 0; }
/* Compatibility function - to be removed */ struct spi_slave *spi_setup_slave_fdt(const void *blob, int node, int bus_node) { struct udevice *bus, *dev; int ret; ret = uclass_get_device_by_of_offset(UCLASS_SPI, bus_node, &bus); if (ret) return NULL; ret = device_get_child_by_of_offset(bus, node, &dev); if (ret) return NULL; return dev_get_parent_priv(dev); }
/** * pinctrl_select_state_full() - full implementation of pinctrl_select_state * * @dev: peripheral device * @statename: state name, like "default" * @return: 0 on success, or negative error code on failure */ static int pinctrl_select_state_full(struct udevice *dev, const char *statename) { const void *fdt = gd->fdt_blob; int node = dev->of_offset; char propname[32]; /* long enough */ const fdt32_t *list; uint32_t phandle; int config_node; struct udevice *config; int state, size, i, ret; state = fdt_find_string(fdt, node, "pinctrl-names", statename); if (state < 0) { char *end; /* * If statename is not found in "pinctrl-names", * assume statename is just the integer state ID. */ state = simple_strtoul(statename, &end, 10); if (*end) return -EINVAL; } snprintf(propname, sizeof(propname), "pinctrl-%d", state); list = fdt_getprop(fdt, node, propname, &size); if (!list) return -EINVAL; size /= sizeof(*list); for (i = 0; i < size; i++) { phandle = fdt32_to_cpu(*list++); config_node = fdt_node_offset_by_phandle(fdt, phandle); if (config_node < 0) { dev_err(dev, "prop %s index %d invalid phandle\n", propname, i); return -EINVAL; } ret = uclass_get_device_by_of_offset(UCLASS_PINCONFIG, config_node, &config); if (ret) return ret; ret = pinctrl_config_one(config); if (ret) return ret; } return 0; }
static int _gpio_request_by_name_nodev(const void *blob, int node, const char *list_name, int index, struct gpio_desc *desc, int flags, bool add_index) { struct fdtdec_phandle_args args; int ret; desc->dev = NULL; desc->offset = 0; desc->flags = 0; ret = fdtdec_parse_phandle_with_args(blob, node, list_name, "#gpio-cells", 0, index, &args); if (ret) { debug("%s: fdtdec_parse_phandle_with_args failed\n", __func__); goto err; } ret = uclass_get_device_by_of_offset(UCLASS_GPIO, args.node, &desc->dev); if (ret) { debug("%s: uclass_get_device_by_of_offset failed\n", __func__); goto err; } ret = gpio_find_and_xlate(desc, &args); if (ret) { debug("%s: gpio_find_and_xlate failed\n", __func__); goto err; } ret = dm_gpio_requestf(desc, add_index ? "%s.%s%d" : "%s.%s", fdt_get_name(blob, node, NULL), list_name, index); if (ret) { debug("%s: dm_gpio_requestf failed\n", __func__); goto err; } ret = dm_gpio_set_dir_flags(desc, flags | desc->flags); if (ret) { debug("%s: dm_gpio_set_dir failed\n", __func__); goto err; } return 0; err: debug("%s: Node '%s', property '%s', failed to request GPIO index %d: %d\n", __func__, fdt_get_name(blob, node, NULL), list_name, index, ret); return ret; }
int reset_get_by_index(struct udevice *dev, int index, struct reset_ctl *reset_ctl) { struct fdtdec_phandle_args args; int ret; struct udevice *dev_reset; struct reset_ops *ops; debug("%s(dev=%p, index=%d, reset_ctl=%p)\n", __func__, dev, index, reset_ctl); ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset, "resets", "#reset-cells", 0, index, &args); if (ret) { debug("%s: fdtdec_parse_phandle_with_args failed: %d\n", __func__, ret); return ret; } ret = uclass_get_device_by_of_offset(UCLASS_RESET, args.node, &dev_reset); if (ret) { debug("%s: uclass_get_device_by_of_offset failed: %d\n", __func__, ret); return ret; } ops = reset_dev_ops(dev_reset); reset_ctl->dev = dev_reset; if (ops->of_xlate) ret = ops->of_xlate(reset_ctl, &args); else ret = reset_of_xlate_default(reset_ctl, &args); if (ret) { debug("of_xlate() failed: %d\n", ret); return ret; } ret = ops->request(reset_ctl); if (ret) { debug("ops->request() failed: %d\n", ret); return ret; } return 0; }
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 power_domain_get(struct udevice *dev, struct power_domain *power_domain) { struct fdtdec_phandle_args args; int ret; struct udevice *dev_power_domain; struct power_domain_ops *ops; debug("%s(dev=%p, power_domain=%p)\n", __func__, dev, power_domain); ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset, "power-domains", "#power-domain-cells", 0, 0, &args); if (ret) { debug("%s: fdtdec_parse_phandle_with_args failed: %d\n", __func__, ret); return ret; } ret = uclass_get_device_by_of_offset(UCLASS_POWER_DOMAIN, args.node, &dev_power_domain); if (ret) { debug("%s: uclass_get_device_by_of_offset failed: %d\n", __func__, ret); return ret; } ops = power_domain_dev_ops(dev_power_domain); power_domain->dev = dev_power_domain; if (ops->of_xlate) ret = ops->of_xlate(power_domain, &args); else ret = power_domain_of_xlate_default(power_domain, &args); if (ret) { debug("of_xlate() failed: %d\n", ret); return ret; } ret = ops->request(power_domain); if (ret) { debug("ops->request() failed: %d\n", ret); return ret; } return 0; }
int mbox_get_by_index(struct udevice *dev, int index, struct mbox_chan *chan) { struct fdtdec_phandle_args args; int ret; struct udevice *dev_mbox; struct mbox_ops *ops; debug("%s(dev=%p, index=%d, chan=%p)\n", __func__, dev, index, chan); ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset, "mboxes", "#mbox-cells", 0, index, &args); if (ret) { debug("%s: fdtdec_parse_phandle_with_args failed: %d\n", __func__, ret); return ret; } ret = uclass_get_device_by_of_offset(UCLASS_MAILBOX, args.node, &dev_mbox); if (ret) { debug("%s: uclass_get_device_by_of_offset failed: %d\n", __func__, ret); return ret; } ops = mbox_dev_ops(dev_mbox); chan->dev = dev_mbox; if (ops->of_xlate) ret = ops->of_xlate(chan, &args); else ret = mbox_of_xlate_default(chan, &args); if (ret) { debug("of_xlate() failed: %d\n", ret); return ret; } ret = ops->request(chan); if (ret) { debug("ops->request() failed: %d\n", ret); return ret; } return 0; }
static int serial_check_stdout(const void *blob, struct udevice **devp) { int node; /* 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, devp)) return 0; /* * If the console is not marked to be bound before relocation, bind it * anyway. */ if (node > 0 && !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node), devp)) { if (!device_probe(*devp)) return 0; } return -ENODEV; }
int notrace dm_timer_init(void) { __maybe_unused const void *blob = gd->fdt_blob; struct udevice *dev = NULL; int node = -ENOENT; int ret; if (gd->timer) return 0; #if !CONFIG_IS_ENABLED(OF_PLATDATA) /* Check for a chosen timer to be used for tick */ node = fdtdec_get_chosen_node(blob, "tick-timer"); #endif if (node < 0) { /* No chosen timer, trying first available timer */ ret = uclass_first_device_err(UCLASS_TIMER, &dev); if (ret) return ret; } else { if (uclass_get_device_by_of_offset(UCLASS_TIMER, node, &dev)) { /* * If the timer is not marked to be bound before * relocation, bind it anyway. */ if (node > 0 && !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node), &dev)) { ret = device_probe(dev); if (ret) return ret; } } } if (dev) { gd->timer = dev; return 0; } return -ENODEV; }
int clk_get_by_index(struct udevice *dev, int index, struct clk *clk) { int ret; struct fdtdec_phandle_args args; struct udevice *dev_clk; struct clk_ops *ops; debug("%s(dev=%p, index=%d, clk=%p)\n", __func__, dev, index, clk); assert(clk); ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev), "clocks", "#clock-cells", 0, index, &args); if (ret) { debug("%s: fdtdec_parse_phandle_with_args failed: err=%d\n", __func__, ret); return ret; } ret = uclass_get_device_by_of_offset(UCLASS_CLK, args.node, &dev_clk); if (ret) { debug("%s: uclass_get_device_by_of_offset failed: err=%d\n", __func__, ret); return ret; } clk->dev = dev_clk; ops = clk_dev_ops(dev_clk); if (ops->of_xlate) ret = ops->of_xlate(clk, &args); else ret = clk_of_xlate_default(clk, &args); if (ret) { debug("of_xlate() failed: %d\n", ret); return ret; } return clk_request(dev_clk, clk); }
int mrccache_get_region(struct udevice **devp, struct mrc_region *entry) { const void *blob = gd->fdt_blob; int node, mrc_node; u32 reg[2]; int ret; /* Find the flash chip within the SPI controller node */ node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH); if (node < 0) return -ENOENT; if (fdtdec_get_int_array(blob, node, "memory-map", reg, 2)) return -FDT_ERR_NOTFOUND; entry->base = reg[0]; /* 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_get_int_array(blob, mrc_node, "reg", reg, 2)) return -FDT_ERR_NOTFOUND; entry->offset = reg[0]; entry->length = reg[1]; if (devp) { 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 sti_sysreset_probe(struct udevice *dev) { struct sti_sysreset_priv *priv = dev_get_priv(dev); struct udevice *syscon; struct regmap *regmap; struct fdtdec_phandle_args syscfg_phandle; int ret; /* get corresponding syscon phandle */ ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev), "st,syscfg", NULL, 0, 0, &syscfg_phandle); if (ret < 0) { pr_err("Can't get syscfg phandle: %d\n", ret); return ret; } ret = uclass_get_device_by_of_offset(UCLASS_SYSCON, syscfg_phandle.node, &syscon); if (ret) { pr_err("%s: uclass_get_device_by_of_offset failed: %d\n", __func__, ret); return ret; } regmap = syscon_get_regmap(syscon); if (!regmap) { pr_err("unable to get regmap for %s\n", syscon->name); return -ENODEV; } priv->base = regmap->base; return 0; }
static int tegra_lcd_ofdata_to_platdata(struct udevice *dev) { struct tegra_lcd_priv *priv = dev_get_priv(dev); struct fdtdec_phandle_args args; const void *blob = gd->fdt_blob; int node = dev->of_offset; int front, back, ref; int panel_node; int rgb; int bpp, bit; int ret; priv->disp = (struct disp_ctlr *)dev_get_addr(dev); if (!priv->disp) { debug("%s: No display controller address\n", __func__); return -EINVAL; } rgb = fdt_subnode_offset(blob, node, "rgb"); panel_node = fdtdec_lookup_phandle(blob, rgb, "nvidia,panel"); if (panel_node < 0) { debug("%s: Cannot find panel information\n", __func__); return -EINVAL; } priv->width = fdtdec_get_int(blob, panel_node, "xres", -1); priv->height = fdtdec_get_int(blob, panel_node, "yres", -1); priv->pixel_clock = fdtdec_get_int(blob, panel_node, "clock", 0); if (!priv->pixel_clock || priv->width == -1 || priv->height == -1) { debug("%s: Pixel parameters missing\n", __func__); return -EINVAL; } back = fdtdec_get_int(blob, panel_node, "left-margin", -1); front = fdtdec_get_int(blob, panel_node, "right-margin", -1); ref = fdtdec_get_int(blob, panel_node, "hsync-len", -1); if ((back | front | ref) == -1) { debug("%s: Horizontal parameters missing\n", __func__); return -EINVAL; } /* Use a ref-to-sync of 1 always, and take this from the front porch */ priv->horiz_timing[FDT_LCD_TIMING_REF_TO_SYNC] = 1; priv->horiz_timing[FDT_LCD_TIMING_SYNC_WIDTH] = ref; priv->horiz_timing[FDT_LCD_TIMING_BACK_PORCH] = back; priv->horiz_timing[FDT_LCD_TIMING_FRONT_PORCH] = front - priv->horiz_timing[FDT_LCD_TIMING_REF_TO_SYNC]; debug_timing("horiz", priv->horiz_timing); back = fdtdec_get_int(blob, panel_node, "upper-margin", -1); front = fdtdec_get_int(blob, panel_node, "lower-margin", -1); ref = fdtdec_get_int(blob, panel_node, "vsync-len", -1); if ((back | front | ref) == -1) { debug("%s: Vertical parameters missing\n", __func__); return -EINVAL; } priv->vert_timing[FDT_LCD_TIMING_REF_TO_SYNC] = 1; priv->vert_timing[FDT_LCD_TIMING_SYNC_WIDTH] = ref; priv->vert_timing[FDT_LCD_TIMING_BACK_PORCH] = back; priv->vert_timing[FDT_LCD_TIMING_FRONT_PORCH] = front - priv->vert_timing[FDT_LCD_TIMING_REF_TO_SYNC]; debug_timing("vert", priv->vert_timing); bpp = fdtdec_get_int(blob, panel_node, "nvidia,bits-per-pixel", -1); bit = ffs(bpp) - 1; if (bpp == (1 << bit)) priv->log2_bpp = bit; else priv->log2_bpp = bpp; if (bpp == -1) { debug("%s: Pixel bpp parameters missing\n", __func__); return -EINVAL; } if (fdtdec_parse_phandle_with_args(blob, panel_node, "nvidia,pwm", "#pwm-cells", 0, 0, &args)) { debug("%s: Unable to decode PWM\n", __func__); return -EINVAL; } ret = uclass_get_device_by_of_offset(UCLASS_PWM, args.node, &priv->pwm); if (ret) { debug("%s: Unable to find PWM\n", __func__); return -EINVAL; } priv->pwm_channel = args.args[0]; priv->cache_type = fdtdec_get_int(blob, panel_node, "nvidia,cache-type", FDT_LCD_CACHE_WRITE_BACK_FLUSH); /* These GPIOs are all optional */ gpio_request_by_name_nodev(blob, panel_node, "nvidia,backlight-enable-gpios", 0, &priv->backlight_en, GPIOD_IS_OUT); gpio_request_by_name_nodev(blob, panel_node, "nvidia,lvds-shutdown-gpios", 0, &priv->lvds_shutdown, GPIOD_IS_OUT); gpio_request_by_name_nodev(blob, panel_node, "nvidia,backlight-vdd-gpios", 0, &priv->backlight_vdd, GPIOD_IS_OUT); gpio_request_by_name_nodev(blob, panel_node, "nvidia,panel-vdd-gpios", 0, &priv->panel_vdd, GPIOD_IS_OUT); if (fdtdec_get_int_array(blob, panel_node, "nvidia,panel-timings", priv->panel_timings, FDT_LCD_TIMINGS)) return -EINVAL; return 0; }
int board_usb_init(int index, enum usb_init_type init) { struct fdtdec_phandle_args args; struct udevice *dev; const void *blob = gd->fdt_blob; struct clk clk; struct phy phy; int node; int phy_provider; int ret; /* find the usb otg node */ node = fdt_node_offset_by_compatible(blob, -1, "snps,dwc2"); if (node < 0) { debug("Not found usb_otg device\n"); return -ENODEV; } if (!fdtdec_get_is_enabled(blob, node)) { debug("stm32 usbotg is disabled in the device tree\n"); return -ENODEV; } /* Enable clock */ ret = fdtdec_parse_phandle_with_args(blob, node, "clocks", "#clock-cells", 0, 0, &args); if (ret) { debug("usbotg has no clocks defined in the device tree\n"); return ret; } ret = uclass_get_device_by_of_offset(UCLASS_CLK, args.node, &dev); if (ret) return ret; if (args.args_count != 1) { debug("Can't find clock ID in the device tree\n"); return -ENODATA; } clk.dev = dev; clk.id = args.args[0]; ret = clk_enable(&clk); if (ret) { debug("Failed to enable usbotg clock\n"); return ret; } /* Reset */ ret = fdtdec_parse_phandle_with_args(blob, node, "resets", "#reset-cells", 0, 0, &args); if (ret) { debug("usbotg has no resets defined in the device tree\n"); goto clk_err; } ret = uclass_get_device_by_of_offset(UCLASS_RESET, args.node, &dev); if (ret || args.args_count != 1) goto clk_err; usbotg_reset.dev = dev; usbotg_reset.id = args.args[0]; reset_assert(&usbotg_reset); udelay(2); reset_deassert(&usbotg_reset); /* Get USB PHY */ ret = fdtdec_parse_phandle_with_args(blob, node, "phys", "#phy-cells", 0, 0, &args); if (!ret) { phy_provider = fdt_parent_offset(blob, args.node); ret = uclass_get_device_by_of_offset(UCLASS_PHY, phy_provider, &dev); if (ret) goto clk_err; phy.dev = dev; phy.id = fdtdec_get_uint(blob, args.node, "reg", -1); ret = generic_phy_power_on(&phy); if (ret) { debug("unable to power on the phy\n"); goto clk_err; } ret = generic_phy_init(&phy); if (ret) { debug("failed to init usb phy\n"); goto phy_power_err; } } /* Parse and store data needed for gadget */ stm32mp_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg"); if (stm32mp_otg_data.regs_otg == FDT_ADDR_T_NONE) { debug("usbotg: can't get base address\n"); ret = -ENODATA; goto phy_init_err; } stm32mp_otg_data.rx_fifo_sz = fdtdec_get_int(blob, node, "g-rx-fifo-size", 0); stm32mp_otg_data.np_tx_fifo_sz = fdtdec_get_int(blob, node, "g-np-tx-fifo-size", 0); stm32mp_otg_data.tx_fifo_sz = fdtdec_get_int(blob, node, "g-tx-fifo-size", 0); /* Enable voltage level detector */ if (!(fdtdec_parse_phandle_with_args(blob, node, "usb33d-supply", NULL, 0, 0, &args))) { if (!uclass_get_device_by_of_offset(UCLASS_REGULATOR, args.node, &dev)) { ret = regulator_set_enable(dev, true); if (ret) { debug("Failed to enable usb33d\n"); goto phy_init_err; } } } /* Enable vbus sensing */ setbits_le32(stm32mp_otg_data.regs_otg + STM32MP_GGPIO, STM32MP_GGPIO_VBUS_SENSING); return dwc2_udc_probe(&stm32mp_otg_data); phy_init_err: generic_phy_exit(&phy); phy_power_err: generic_phy_power_off(&phy); clk_err: clk_disable(&clk); return ret; }
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 }