static int check_reserved(const struct gpio_desc *desc, const char *func) { struct gpio_dev_priv *uc_priv; if (!dm_gpio_is_valid(desc)) return -ENOENT; uc_priv = dev_get_uclass_priv(desc->dev); if (!uc_priv->name[desc->offset]) { printf("%s: %s: error: gpio %s%d not reserved\n", desc->dev->name, func, uc_priv->bank_name ? uc_priv->bank_name : "", desc->offset); return -EBUSY; } return 0; }
static int ich6_gpio_probe(struct udevice *dev) { struct ich6_bank_platdata *plat = dev_get_platdata(dev); struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); struct ich6_bank_priv *bank = dev_get_priv(dev); struct udevice *pinctrl; /* Set up pin control if available */ syscon_get_by_driver_data(X86_SYSCON_PINCONF, &pinctrl); uc_priv->gpio_count = GPIO_PER_BANK; uc_priv->bank_name = plat->bank_name; bank->use_sel = plat->base_addr; bank->io_sel = plat->base_addr + 4; bank->lvl = plat->base_addr + 8; return 0; }
static int sdhci_cdns_probe(struct udevice *dev) { DECLARE_GLOBAL_DATA_PTR; struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct sdhci_cdns_plat *plat = dev_get_platdata(dev); struct sdhci_host *host = dev_get_priv(dev); fdt_addr_t base; int ret; base = devfdt_get_addr(dev); if (base == FDT_ADDR_T_NONE) return -EINVAL; plat->hrs_addr = devm_ioremap(dev, base, SZ_1K); if (!plat->hrs_addr) return -ENOMEM; host->name = dev->name; host->ioaddr = plat->hrs_addr + SDHCI_CDNS_SRS_BASE; host->ops = &sdhci_cdns_ops; host->quirks |= SDHCI_QUIRK_WAIT_SEND_CMD; sdhci_cdns_mmc_ops = sdhci_ops; #ifdef MMC_SUPPORTS_TUNING sdhci_cdns_mmc_ops.execute_tuning = sdhci_cdns_execute_tuning; #endif ret = mmc_of_parse(dev, &plat->cfg); if (ret) return ret; ret = sdhci_cdns_phy_init(plat, gd->fdt_blob, dev_of_offset(dev)); if (ret) return ret; ret = sdhci_setup_cfg(&plat->cfg, host, 0, 0); if (ret) return ret; upriv->mmc = &plat->mmc; host->mmc = &plat->mmc; host->mmc->priv = host; return sdhci_probe(dev); }
static int ich6_gpio_probe(struct udevice *dev) { struct ich6_bank_platdata *plat = dev_get_platdata(dev); struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); struct ich6_bank_priv *bank = dev_get_priv(dev); if (gd->arch.gpio_map) { setup_pch_gpios(plat->base_addr, gd->arch.gpio_map); gd->arch.gpio_map = NULL; } uc_priv->gpio_count = GPIO_PER_BANK; uc_priv->bank_name = plat->bank_name; bank->use_sel = plat->base_addr; bank->io_sel = plat->base_addr + 4; bank->lvl = plat->base_addr + 8; return 0; }
static int uniphier_gpio_probe(struct udevice *dev) { struct uniphier_gpio_priv *priv = dev_get_priv(dev); struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); fdt_addr_t addr; addr = devfdt_get_addr(dev); if (addr == FDT_ADDR_T_NONE) return -EINVAL; priv->regs = devm_ioremap(dev, addr, SZ_512); if (!priv->regs) return -ENOMEM; uc_priv->gpio_count = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), "ngpios", 0); return 0; }
static int i2c_mux_bus_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs) { struct udevice *mux = dev->parent; struct i2c_mux *priv = dev_get_uclass_priv(mux); struct dm_i2c_ops *ops = i2c_get_ops(priv->i2c_bus); int ret, ret2; debug("%s: %s, bus %s\n", __func__, dev->name, priv->i2c_bus->name); if (!ops->xfer) return -ENOSYS; ret = i2c_mux_select(dev); if (ret) return ret; ret = ops->xfer(priv->i2c_bus, msg, nmsgs); ret2 = i2c_mux_deselect(dev); return ret ? ret : ret2; }
int video_bridge_set_active(struct udevice *dev, bool active) { struct video_bridge_priv *uc_priv = dev_get_uclass_priv(dev); int ret; debug("%s: %d\n", __func__, active); ret = dm_gpio_set_value(&uc_priv->sleep, !active); if (ret) return ret; if (active) { ret = dm_gpio_set_value(&uc_priv->reset, true); if (ret) return ret; udelay(10); ret = dm_gpio_set_value(&uc_priv->reset, false); } return ret; }
static int i2c_mux_bus_probe(struct udevice *dev, uint chip_addr, uint chip_flags) { struct udevice *mux = dev->parent; struct i2c_mux *priv = dev_get_uclass_priv(mux); struct dm_i2c_ops *ops = i2c_get_ops(priv->i2c_bus); int ret, ret2; debug("%s: %s, bus %s\n", __func__, dev->name, priv->i2c_bus->name); if (!ops->probe_chip) return -ENOSYS; ret = i2c_mux_select(dev); if (ret) return ret; ret = ops->probe_chip(priv->i2c_bus, chip_addr, chip_flags); ret2 = i2c_mux_deselect(dev); return ret ? ret : ret2; }
static int omap_hsmmc_probe(struct udevice *dev) { struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct omap_hsmmc_data *priv = dev_get_priv(dev); struct mmc_config *cfg; struct mmc *mmc; cfg = &priv->cfg; cfg->name = "OMAP SD/MMC"; cfg->ops = &omap_hsmmc_ops; mmc = mmc_create(cfg, priv); if (mmc == NULL) return -1; upriv->mmc = mmc; return 0; }
int _dm_gpio_free(struct udevice *dev, uint offset) { struct gpio_dev_priv *uc_priv; int ret; uc_priv = dev_get_uclass_priv(dev); if (!uc_priv->name[offset]) return -ENXIO; if (gpio_get_ops(dev)->free) { ret = gpio_get_ops(dev)->free(dev, offset); if (ret) return ret; } free(uc_priv->name[offset]); uc_priv->name[offset] = NULL; return 0; }
static int console_normal_set_row(struct udevice *dev, uint row, int clr) { struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); void *line; int pixels = VIDEO_FONT_HEIGHT * vid_priv->line_length; int i; line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * vid_priv->line_length; switch (vid_priv->bpix) { #ifdef CONFIG_VIDEO_BPP8 case VIDEO_BPP8: { uint8_t *dst = line; for (i = 0; i < pixels; i++) *dst++ = clr; break; } #endif #ifdef CONFIG_VIDEO_BPP16 case VIDEO_BPP16: { uint16_t *dst = line; for (i = 0; i < pixels; i++) *dst++ = clr; break; } #endif #ifdef CONFIG_VIDEO_BPP32 case VIDEO_BPP32: { uint32_t *dst = line; for (i = 0; i < pixels; i++) *dst++ = clr; break; } #endif default: return -ENOSYS; } return 0; }
static int sandbox_sdl_probe(struct udevice *dev) { struct sandbox_sdl_plat *plat = dev_get_platdata(dev); struct video_priv *uc_priv = dev_get_uclass_priv(dev); int ret; ret = sandbox_sdl_init_display(plat->xres, plat->yres, plat->bpix); if (ret) { puts("LCD init failed\n"); return ret; } uc_priv->xsize = plat->xres; uc_priv->ysize = plat->yres; uc_priv->bpix = plat->bpix; uc_priv->rot = plat->rot; uc_priv->vidconsole_drv_name = plat->vidconsole_drv_name; uc_priv->font_size = plat->font_size; return 0; }
/** * compress_frame_buffer() - Compress the frame buffer and return its size * * We want to write tests which perform operations on the video console and * check that the frame buffer ends up with the correct contents. But it is * painful to store 'known good' images for comparison with the frame * buffer. As an alternative, we can compress the frame buffer and check the * size of the compressed data. This provides a pretty good level of * certainty and the resulting tests need only check a single value. * * @dev: Video device * @return compressed size of the frame buffer, or -ve on error */ static int compress_frame_buffer(struct udevice *dev) { struct video_priv *priv = dev_get_uclass_priv(dev); uint destlen; void *dest; int ret; destlen = priv->fb_size; dest = malloc(priv->fb_size); if (!dest) return -ENOMEM; ret = BZ2_bzBuffToBuffCompress(dest, &destlen, priv->fb, priv->fb_size, 3, 0, 0); free(dest); if (ret) return ret; return destlen; }
int dm_i2c_set_bus_speed(struct udevice *bus, unsigned int speed) { struct dm_i2c_ops *ops = i2c_get_ops(bus); struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus); int ret; /* * If we have a method, call it. If not then the driver probably wants * to deal with speed changes on the next transfer. It can easily read * the current speed from this uclass */ if (ops->set_bus_speed) { ret = ops->set_bus_speed(bus, speed); if (ret) return ret; } i2c->speed_hz = speed; return 0; }
static int rockchip_gpio_probe(struct udevice *dev) { struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); struct rockchip_gpio_priv *priv = dev_get_priv(dev); char *end; int ret; priv->regs = dev_read_addr_ptr(dev); ret = uclass_first_device_err(UCLASS_PINCTRL, &priv->pinctrl); if (ret) return ret; uc_priv->gpio_count = ROCKCHIP_GPIOS_PER_BANK; end = strrchr(dev->name, '@'); priv->bank = trailing_strtoln(dev->name, end); priv->name[0] = 'A' + priv->bank; uc_priv->bank_name = priv->name; return 0; }
int musb_usb_probe(struct udevice *dev) { struct musb_host_data *host = dev_get_priv(dev); struct usb_bus_priv *priv = dev_get_uclass_priv(dev); int ret; priv->desc_before_addr = true; if (!host->host) { host->host = musb_init_controller(&musb_plat, NULL, (void *)SUNXI_USB0_BASE); if (!host->host) return -EIO; } ret = musb_lowlevel_init(host); if (ret == 0) printf("MUSB OTG\n"); return ret; }
static int arasan_sdhci_probe(struct udevice *dev) { struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct sdhci_host *host = dev_get_priv(dev); host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_BROKEN_R1B; #ifdef CONFIG_ZYNQ_HISPD_BROKEN host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT; #endif host->version = sdhci_readw(host, SDHCI_HOST_VERSION); add_sdhci(host, CONFIG_ZYNQ_SDHCI_MAX_FREQ, CONFIG_ZYNQ_SDHCI_MIN_FREQ); upriv->mmc = host->mmc; return 0; }
static int timer_pre_probe(struct udevice *dev) { #if !CONFIG_IS_ENABLED(OF_PLATDATA) struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); struct clk timer_clk; int err; ulong ret; err = clk_get_by_index(dev, 0, &timer_clk); if (!err) { ret = clk_get_rate(&timer_clk); if (IS_ERR_VALUE(ret)) return ret; uc_priv->clock_rate = ret; } else uc_priv->clock_rate = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "clock-frequency", 0); #endif return 0; }
static int atmel_hlcdc_probe(struct udevice *dev) { struct video_priv *uc_priv = dev_get_uclass_priv(dev); struct atmel_hlcdc_priv *priv = dev_get_priv(dev); int ret; ret = at91_hlcdc_enable_clk(dev); if (ret) return ret; atmel_hlcdc_init(dev); uc_priv->xsize = priv->timing.hactive.typ; uc_priv->ysize = priv->timing.vactive.typ; uc_priv->bpix = priv->vl_bpix; /* Enable flushing if we enabled dcache */ video_set_flush_dcache(dev, true); return 0; }
/** * 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; }
static int ti_musb_host_probe(struct udevice *dev) { struct musb_host_data *host = dev_get_priv(dev); struct ti_musb_platdata *platdata = dev_get_platdata(dev); struct usb_bus_priv *priv = dev_get_uclass_priv(dev); struct omap_musb_board_data *otg_board_data; int ret; priv->desc_before_addr = true; otg_board_data = &platdata->otg_board_data; host->host = musb_init_controller(&platdata->plat, (struct device *)otg_board_data, platdata->base); if (!host->host) return -EIO; ret = musb_lowlevel_init(host); return ret; }
int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize) { struct dm_gpio_ops *ops = gpio_get_ops(dev); struct gpio_dev_priv *priv; char *str = buf; int func; int ret; int len; BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function)); *buf = 0; priv = dev_get_uclass_priv(dev); ret = gpio_get_raw_function(dev, offset, NULL); if (ret < 0) return ret; func = ret; len = snprintf(str, buffsize, "%s%d: %s", priv->bank_name ? priv->bank_name : "", offset, gpio_function[func]); if (func == GPIOF_INPUT || func == GPIOF_OUTPUT || func == GPIOF_UNUSED) { const char *label; bool used; ret = ops->get_value(dev, offset); if (ret < 0) return ret; used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED; snprintf(str + len, buffsize - len, ": %d [%c]%s%s", ret, used ? 'x' : ' ', used ? " " : "", label ? label : ""); } return 0; }
int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc) { struct gpio_dev_priv *uc_priv = NULL; struct udevice *dev; ulong offset; int numeric; int ret; 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_get_uclass_priv(dev); if (numeric != -1) { offset = numeric - uc_priv->gpio_base; /* Allow GPIOs to be numbered from 0 */ if (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; desc->dev = dev; desc->offset = offset; return 0; }
static int broadwell_gpio_probe(struct udevice *dev) { struct broadwell_bank_platdata *plat = dev_get_platdata(dev); struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); struct broadwell_bank_priv *priv = dev_get_priv(dev); struct udevice *pinctrl; int ret; /* Set up pin control if available */ ret = syscon_get_by_driver_data(X86_SYSCON_PINCONF, &pinctrl); debug("%s, pinctrl=%p, ret=%d\n", __func__, pinctrl, ret); uc_priv->gpio_count = GPIO_PER_BANK; uc_priv->bank_name = plat->bank_name; priv->regs = (struct pch_lp_gpio_regs *)(uintptr_t)plat->base_addr; priv->bank = plat->bank; priv->offset = priv->bank * 32; debug("%s: probe done, regs %p, bank %d\n", __func__, priv->regs, priv->bank); return 0; }
static int syscon_pre_probe(struct udevice *dev) { struct syscon_uc_info *priv = dev_get_uclass_priv(dev); /* Special case for PCI devices, which don't have a regmap */ if (device_get_uclass_id(dev->parent) == UCLASS_PCI) return 0; /* * With OF_PLATDATA we really have no way of knowing the format of * the device-specific platform data. So we assume that it starts with * a 'reg' member, and this holds a single address and size. Drivers * using OF_PLATDATA will need to ensure that this is true. */ #if CONFIG_IS_ENABLED(OF_PLATDATA) struct syscon_base_platdata *plat = dev_get_platdata(dev); return regmap_init_mem_platdata(dev, plat->reg, ARRAY_SIZE(plat->reg), &priv->regmap); #else return regmap_init_mem(dev_ofnode(dev), &priv->regmap); #endif }
int gpio_lookup_name(const char *name, struct udevice **devp, unsigned int *offsetp, unsigned int *gpiop) { struct gpio_desc desc; int ret; if (devp) *devp = NULL; ret = dm_gpio_lookup_name(name, &desc); if (ret) return ret; if (devp) *devp = desc.dev; if (offsetp) *offsetp = desc.offset; if (gpiop) { struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc.dev); *gpiop = uc_priv->gpio_base + desc.offset; } return 0; }
/* We need to renumber the GPIOs when any driver is probed/removed */ static int gpio_renumber(struct udevice *removed_dev) { struct gpio_dev_priv *uc_priv; struct udevice *dev; struct uclass *uc; unsigned base; int ret; ret = uclass_get(UCLASS_GPIO, &uc); if (ret) return ret; /* Ensure that we have a base for each bank */ base = 0; uclass_foreach_dev(dev, uc) { if (device_active(dev) && dev != removed_dev) { uc_priv = dev_get_uclass_priv(dev); uc_priv->gpio_base = base; base += uc_priv->gpio_count; } } return 0; }
static int tegra124_lcd_init(struct udevice *dev, void *lcdbase, enum video_log2_bpp l2bpp) { struct video_priv *uc_priv = dev_get_uclass_priv(dev); struct display_timing timing; int ret; clock_set_up_plldp(); clock_start_periph_pll(PERIPH_ID_HOST1X, CLOCK_ID_PERIPH, 408000000); clock_enable(PERIPH_ID_HOST1X); clock_enable(PERIPH_ID_DISP1); clock_enable(PERIPH_ID_PWM); clock_enable(PERIPH_ID_DPAUX); clock_enable(PERIPH_ID_SOR0); udelay(2); reset_set_enable(PERIPH_ID_HOST1X, 0); reset_set_enable(PERIPH_ID_DISP1, 0); reset_set_enable(PERIPH_ID_PWM, 0); reset_set_enable(PERIPH_ID_DPAUX, 0); reset_set_enable(PERIPH_ID_SOR0, 0); ret = display_init(dev, lcdbase, 1 << l2bpp, &timing); if (ret) return ret; uc_priv->xsize = roundup(timing.hactive.typ, 16); uc_priv->ysize = timing.vactive.typ; uc_priv->bpix = l2bpp; video_set_flush_dcache(dev, 1); debug("%s: done\n", __func__); return 0; }
int dm_gpio_request(struct gpio_desc *desc, const char *label) { struct udevice *dev = desc->dev; struct gpio_dev_priv *uc_priv; char *str; int ret; uc_priv = dev_get_uclass_priv(dev); if (uc_priv->name[desc->offset]) return -EBUSY; str = strdup(label); if (!str) return -ENOMEM; if (gpio_get_ops(dev)->request) { ret = gpio_get_ops(dev)->request(dev, desc->offset, label); if (ret) { free(str); return ret; } } uc_priv->name[desc->offset] = str; return 0; }
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; }