static int stm32_qspi_claim_bus(struct udevice *dev) { struct stm32_qspi_priv *priv = dev_get_priv(dev->parent); struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); if (slave_plat->cs >= STM32_QSPI_MAX_CHIP) return -ENODEV; if (priv->cs_used != slave_plat->cs) { struct stm32_qspi_flash *flash = &priv->flash[slave_plat->cs]; priv->cs_used = slave_plat->cs; if (flash->initialized) { /* Set the configuration: speed + cs */ writel(flash->cr, &priv->regs->cr); writel(flash->dcr, &priv->regs->dcr); } else { /* Set chip select */ clrsetbits_le32(&priv->regs->cr, STM32_QSPI_CR_FSEL, priv->cs_used ? STM32_QSPI_CR_FSEL : 0); /* Save the configuration: speed + cs */ flash->cr = readl(&priv->regs->cr); flash->dcr = readl(&priv->regs->dcr); flash->initialized = true; } } setbits_le32(&priv->regs->cr, STM32_QSPI_CR_EN); return 0; }
void usb_emul_reset(struct udevice *dev) { struct usb_dev_platdata *plat = dev_get_parent_platdata(dev); plat->devnum = 0; plat->configno = 0; }
pci_dev_t dm_pci_get_bdf(struct udevice *dev) { struct pci_child_platdata *pplat = dev_get_parent_platdata(dev); struct udevice *bus = dev->parent; return PCI_ADD_BUS(bus->seq, pplat->devfn); }
int dm_i2c_read(struct udevice *dev, uint offset, uint8_t *buffer, int len) { struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); struct udevice *bus = dev_get_parent(dev); struct dm_i2c_ops *ops = i2c_get_ops(bus); struct i2c_msg msg[2], *ptr; uint8_t offset_buf[I2C_MAX_OFFSET_LEN]; int msg_count; if (!ops->xfer) return -ENOSYS; if (chip->flags & DM_I2C_CHIP_RD_ADDRESS) return i2c_read_bytewise(dev, offset, buffer, len); ptr = msg; if (!i2c_setup_offset(chip, offset, offset_buf, ptr)) ptr++; if (len) { ptr->addr = chip->chip_addr; ptr->flags = chip->flags & DM_I2C_CHIP_10BIT ? I2C_M_TEN : 0; ptr->flags |= I2C_M_RD; ptr->len = len; ptr->buf = buffer; ptr++; } msg_count = ptr - msg; return ops->xfer(bus, msg, msg_count); }
static int i2c_read_bytewise(struct udevice *dev, uint offset, uint8_t *buffer, int len) { struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); struct udevice *bus = dev_get_parent(dev); struct dm_i2c_ops *ops = i2c_get_ops(bus); struct i2c_msg msg[2], *ptr; uint8_t offset_buf[I2C_MAX_OFFSET_LEN]; int ret; int i; for (i = 0; i < len; i++) { if (i2c_setup_offset(chip, offset + i, offset_buf, msg)) return -EINVAL; ptr = msg + 1; ptr->addr = chip->chip_addr; ptr->flags = msg->flags | I2C_M_RD; ptr->len = 1; ptr->buf = &buffer[i]; ptr++; ret = ops->xfer(bus, msg, ptr - msg); if (ret) return ret; } return 0; }
static int ti_qspi_claim_bus(struct udevice *dev) { struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); struct ti_qspi_priv *priv; struct udevice *bus; bus = dev->parent; priv = dev_get_priv(bus); if (slave_plat->cs > priv->num_cs) { debug("invalid qspi chip select\n"); return -EINVAL; } writel(MM_SWITCH, &priv->base->memswitch); if (priv->ctrl_mod_mmap) ti_qspi_ctrl_mode_mmap(priv->ctrl_mod_mmap, slave_plat->cs, true); writel(priv->dc, &priv->base->dc); writel(0, &priv->base->cmd); writel(0, &priv->base->data); priv->dc <<= slave_plat->cs * 8; writel(priv->dc, &priv->base->dc); return 0; }
static int rtl8169_eth_probe(struct udevice *dev) { struct pci_child_platdata *pplat = dev_get_parent_platdata(dev); struct rtl8169_private *priv = dev_get_priv(dev); struct eth_pdata *plat = dev_get_platdata(dev); u32 iobase; int region; int ret; debug("rtl8169: REALTEK RTL8169 @0x%x\n", iobase); switch (pplat->device) { case 0x8168: region = 2; break; default: region = 1; break; } dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0 + region * 4, &iobase); iobase &= ~0xf; priv->iobase = (int)dm_pci_mem_to_phys(dev, iobase); ret = rtl_init(priv->iobase, dev->name, plat->enetaddr); if (ret < 0) { printf(pr_fmt("failed to initialize card: %d\n"), ret); return ret; } return 0; }
static int qemu_cpu_fixup(void) { int ret; int cpu_num; int cpu_online; struct udevice *dev, *pdev; struct cpu_platdata *plat; char *cpu; /* first we need to find '/cpus' */ for (device_find_first_child(dm_root(), &pdev); pdev; device_find_next_child(&pdev)) { if (!strcmp(pdev->name, "cpus")) break; } if (!pdev) { printf("unable to find cpus device\n"); return -ENODEV; } /* calculate cpus that are already bound */ cpu_num = 0; for (uclass_find_first_device(UCLASS_CPU, &dev); dev; uclass_find_next_device(&dev)) { cpu_num++; } /* get actual cpu number */ cpu_online = qemu_fwcfg_online_cpus(); if (cpu_online < 0) { printf("unable to get online cpu number: %d\n", cpu_online); return cpu_online; } /* bind addtional cpus */ dev = NULL; for (; cpu_num < cpu_online; cpu_num++) { /* * allocate device name here as device_bind_driver() does * not copy device name, 8 bytes are enough for * sizeof("cpu@") + 3 digits cpu number + '\0' */ cpu = malloc(8); if (!cpu) { printf("unable to allocate device name\n"); return -ENOMEM; } sprintf(cpu, "cpu@%d", cpu_num); ret = device_bind_driver(pdev, "cpu_qemu", cpu, &dev); if (ret) { printf("binding cpu@%d failed: %d\n", cpu_num, ret); return ret; } plat = dev_get_parent_platdata(dev); plat->cpu_id = cpu_num; } return 0; }
int usb_emul_setup_device(struct udevice *dev, int maxpacketsize, struct usb_string *strings, void **desc_list) { struct usb_dev_platdata *plat = dev_get_parent_platdata(dev); struct usb_generic_descriptor **ptr; struct usb_config_descriptor *cdesc; int upto; plat->strings = strings; plat->desc_list = (struct usb_generic_descriptor **)desc_list; /* Fill in wTotalLength for each configuration descriptor */ ptr = plat->desc_list; for (cdesc = NULL, upto = 0; *ptr; upto += (*ptr)->bLength, ptr++) { debug(" - upto=%d, type=%d\n", upto, (*ptr)->bDescriptorType); if ((*ptr)->bDescriptorType == USB_DT_CONFIG) { if (cdesc) { cdesc->wTotalLength = upto; debug("%s: config %d length %d\n", __func__, cdesc->bConfigurationValue, cdesc->bLength); } cdesc = (struct usb_config_descriptor *)*ptr; upto = 0; } } if (cdesc) { cdesc->wTotalLength = upto; debug("%s: config %d length %d\n", __func__, cdesc->bConfigurationValue, cdesc->wTotalLength); } return 0; }
static int rockchip_spi_xfer(struct udevice *dev, unsigned int bitlen, const void *dout, void *din, unsigned long flags) { struct udevice *bus = dev->parent; struct rockchip_spi_priv *priv = dev_get_priv(bus); struct rockchip_spi *regs = priv->regs; struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); int len = bitlen >> 3; const u8 *out = dout; u8 *in = din; int toread, towrite; int ret; debug("%s: dout=%p, din=%p, len=%x, flags=%lx\n", __func__, dout, din, len, flags); if (DEBUG_RK_SPI) rkspi_dump_regs(regs); /* Assert CS before transfer */ if (flags & SPI_XFER_BEGIN) spi_cs_activate(dev, slave_plat->cs); while (len > 0) { int todo = min(len, 0xffff); rkspi_enable_chip(regs, false); writel(todo - 1, ®s->ctrlr1); rkspi_enable_chip(regs, true); toread = todo; towrite = todo; while (toread || towrite) { u32 status = readl(®s->sr); if (towrite && !(status & SR_TF_FULL)) { writel(out ? *out++ : 0, regs->txdr); towrite--; } if (toread && !(status & SR_RF_EMPT)) { u32 byte = readl(regs->rxdr); if (in) *in++ = byte; toread--; } } ret = rkspi_wait_till_not_busy(regs); if (ret) break; len -= todo; } /* Deassert CS after transfer */ if (flags & SPI_XFER_END) spi_cs_deactivate(dev, slave_plat->cs); rkspi_enable_chip(regs, false); return ret; }
int i2c_get_chip_flags(struct udevice *dev, uint *flagsp) { struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); *flagsp = chip->flags; return 0; }
static void atmel_spi_cs_deactivate(struct udevice *dev) { struct udevice *bus = dev_get_parent(dev); struct atmel_spi_priv *priv = dev_get_priv(bus); struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); u32 cs = slave_plat->cs; dm_gpio_set_value(&priv->cs_gpios[cs], 1); }
static int cpu_x86_baytrail_bind(struct udevice *dev) { struct cpu_platdata *plat = dev_get_parent_platdata(dev); plat->cpu_id = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "intel,apic-id", -1); return 0; }
static int spi_child_post_bind(struct udevice *dev) { struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev); if (!dev_of_valid(dev)) return 0; return spi_slave_ofdata_to_platdata(dev, plat); }
static int spi_child_post_bind(struct udevice *dev) { struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev); if (dev->of_offset == -1) return 0; return spi_slave_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, plat); }
static int pic32_spi_xfer(struct udevice *slave, unsigned int bitlen, const void *tx_buf, void *rx_buf, unsigned long flags) { struct dm_spi_slave_platdata *slave_plat; struct udevice *bus = slave->parent; struct pic32_spi_priv *priv; int len = bitlen / 8; int ret = 0; ulong tbase; priv = dev_get_priv(bus); slave_plat = dev_get_parent_platdata(slave); debug("spi_xfer: bus:%i cs:%i flags:%lx\n", bus->seq, slave_plat->cs, flags); debug("msg tx %p, rx %p submitted of %d byte(s)\n", tx_buf, rx_buf, len); /* assert cs */ if (flags & SPI_XFER_BEGIN) spi_cs_activate(priv); /* set current transfer information */ priv->tx = tx_buf; priv->rx = rx_buf; priv->tx_end = priv->tx + len; priv->rx_end = priv->rx + len; priv->len = len; /* transact by polling */ tbase = get_timer(0); for (;;) { priv->tx_fifo(priv); priv->rx_fifo(priv); /* received sufficient data */ if (priv->rx >= priv->rx_end) { ret = 0; break; } if (get_timer(tbase) > 5 * CONFIG_SYS_HZ) { printf("pic32_spi: error, xfer timedout.\n"); flags |= SPI_XFER_END; ret = -ETIMEDOUT; break; } } /* deassert cs */ if (flags & SPI_XFER_END) spi_cs_deactivate(priv); return ret; }
static int testbus_child_post_bind(struct udevice *dev) { struct dm_test_parent_platdata *plat; plat = dev_get_parent_platdata(dev); plat->bind_flag = 1; plat->uclass_bind_flag = 2; return 0; }
int i2c_set_chip_offset_len(struct udevice *dev, uint offset_len) { struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); if (offset_len > I2C_MAX_OFFSET_LEN) return -EINVAL; chip->offset_len = offset_len; return 0; }
int dm_i2c_write(struct udevice *dev, uint offset, const uint8_t *buffer, int len) { struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); struct udevice *bus = dev_get_parent(dev); struct dm_i2c_ops *ops = i2c_get_ops(bus); struct i2c_msg msg[1]; if (!ops->xfer) return -ENOSYS; if (chip->flags & DM_I2C_CHIP_WR_ADDRESS) return i2c_write_bytewise(dev, offset, buffer, len); /* * The simple approach would be to send two messages here: one to * set the offset and one to write the bytes. However some drivers * will not be expecting this, and some chips won't like how the * driver presents this on the I2C bus. * * The API does not support separate offset and data. We could extend * it with a flag indicating that there is data in the next message * that needs to be processed in the same transaction. We could * instead add an additional buffer to each message. For now, handle * this in the uclass since it isn't clear what the impact on drivers * would be with this extra complication. Unfortunately this means * copying the message. * * Use the stack for small messages, malloc() for larger ones. We * need to allow space for the offset (up to 4 bytes) and the message * itself. */ if (len < 64) { uint8_t buf[I2C_MAX_OFFSET_LEN + len]; i2c_setup_offset(chip, offset, buf, msg); msg->len += len; memcpy(buf + chip->offset_len, buffer, len); return ops->xfer(bus, msg, 1); } else { uint8_t *buf; int ret; buf = malloc(I2C_MAX_OFFSET_LEN + len); if (!buf) return -ENOMEM; i2c_setup_offset(chip, offset, buf, msg); msg->len += len; memcpy(buf + chip->offset_len, buffer, len); ret = ops->xfer(bus, msg, 1); free(buf); return ret; } }
int i2c_mux_select(struct udevice *dev) { struct i2c_mux_bus *plat = dev_get_parent_platdata(dev); struct udevice *mux = dev->parent; struct i2c_mux_ops *ops = i2c_mux_get_ops(mux); if (!ops->select) return -ENOSYS; return ops->select(mux, dev, plat->channel); }
int usb_emul_control(struct udevice *emul, struct usb_device *udev, unsigned long pipe, void *buffer, int length, struct devrequest *setup) { struct dm_usb_ops *ops = usb_get_emul_ops(emul); struct usb_dev_platdata *plat; int ret; /* We permit getting the descriptor before we are probed */ plat = dev_get_parent_platdata(emul); if (!ops->control) return -ENOSYS; debug("%s: dev=%s\n", __func__, emul->name); if (pipe == usb_rcvctrlpipe(udev, 0)) { switch (setup->request) { case USB_REQ_GET_DESCRIPTOR: { return usb_emul_get_descriptor(plat, setup->value, buffer, length); } default: ret = device_probe(emul); if (ret) return ret; return ops->control(emul, udev, pipe, buffer, length, setup); } } else if (pipe == usb_snddefctrl(udev)) { switch (setup->request) { case USB_REQ_SET_ADDRESS: debug(" ** set address %s %d\n", emul->name, setup->value); plat->devnum = setup->value; return 0; default: debug("requestsend =%x\n", setup->request); break; } } else if (pipe == usb_sndctrlpipe(udev, 0)) { switch (setup->request) { case USB_REQ_SET_CONFIGURATION: plat->configno = setup->value; return 0; default: ret = device_probe(emul); if (ret) return ret; return ops->control(emul, udev, pipe, buffer, length, setup); } } debug("pipe=%lx\n", pipe); return -EIO; }
static int i2c_child_post_bind(struct udevice *dev) { #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) struct dm_i2c_chip *plat = dev_get_parent_platdata(dev); if (!dev_of_valid(dev)) return 0; return i2c_chip_ofdata_to_platdata(dev, plat); #else return 0; #endif }
static int spi_flash_std_probe(struct udevice *dev) { struct spi_slave *slave = dev_get_parent_priv(dev); struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev); struct spi_flash *flash; flash = dev_get_uclass_priv(dev); flash->dev = dev; flash->spi = slave; debug("%s: slave=%p, cs=%d\n", __func__, slave, plat->cs); return spi_flash_probe_slave(flash); }
static int omap3_spi_set_wordlen(struct udevice *dev, unsigned int wordlen) { struct udevice *bus = dev->parent; struct omap3_spi_priv *priv = dev_get_priv(bus); struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); priv->cs = slave_plat->cs; priv->wordlen = wordlen; _omap3_spi_set_wordlen(priv); return 0; }
pci_dev_t pci_find_devices(struct pci_device_id *ids, int index) { struct pci_child_platdata *pplat; struct udevice *bus, *dev; if (pci_find_device_id(ids, index, &dev)) return -1; bus = dev->parent; pplat = dev_get_parent_platdata(dev); return PCI_ADD_BUS(bus->seq, pplat->devfn); }
/* Find out the mux channel number */ static int i2c_mux_child_post_bind(struct udevice *dev) { struct i2c_mux_bus *plat = dev_get_parent_platdata(dev); int channel; channel = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1); if (channel < 0) return -EINVAL; plat->channel = channel; return 0; }
static int omap3_spi_claim_bus(struct udevice *dev) { struct udevice *bus = dev->parent; struct omap3_spi_priv *priv = dev_get_priv(bus); struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); priv->cs = slave_plat->cs; priv->mode = slave_plat->mode; priv->freq = slave_plat->max_hz; _omap3_spi_claim_bus(priv); return 0; }
static int i2c_child_post_bind(struct udevice *dev) { #if CONFIG_IS_ENABLED(OF_CONTROL) struct dm_i2c_chip *plat = dev_get_parent_platdata(dev); if (dev->of_offset == -1) return 0; return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, plat); #else return 0; #endif }
static void atmel_spi_cs_deactivate(struct udevice *dev) { #ifdef CONFIG_DM_GPIO struct udevice *bus = dev_get_parent(dev); struct atmel_spi_priv *priv = dev_get_priv(bus); struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); u32 cs = slave_plat->cs; if (!dm_gpio_is_valid(&priv->cs_gpios[cs])) return; dm_gpio_set_value(&priv->cs_gpios[cs], 1); #endif }
unsigned long acpi_create_madt_lapics(unsigned long current) { struct udevice *dev; for (uclass_find_first_device(UCLASS_CPU, &dev); dev; uclass_find_next_device(&dev)) { struct cpu_platdata *plat = dev_get_parent_platdata(dev); current += acpi_create_madt_lapic( (struct acpi_madt_lapic *)current, plat->cpu_id, plat->cpu_id); } return current; }