/** * The BPMP exposes multiple different services. We create a sub-device for * each separate type of service, since each device must be of the appropriate * UCLASS. */ static int tegra186_bpmp_bind(struct udevice *dev) { int ret; struct udevice *child; debug("%s(dev=%p)\n", __func__, dev); ret = device_bind_driver_to_node(dev, "tegra186_clk", "tegra186_clk", dev_of_offset(dev), &child); if (ret) return ret; ret = device_bind_driver_to_node(dev, "tegra186_reset", "tegra186_reset", dev_of_offset(dev), &child); if (ret) return ret; ret = device_bind_driver_to_node(dev, "tegra186_power_domain", "tegra186_power_domain", dev_of_offset(dev), &child); if (ret) return ret; ret = dm_scan_fdt_dev(dev); if (ret) return ret; return 0; }
static int ks2_eth_bind_slaves(struct udevice *dev, int gbe, int *gbe_0) { const void *fdt = gd->fdt_blob; struct udevice *sl_dev; int interfaces; int sec_slave; int slave; int ret; char *slave_name; interfaces = fdt_subnode_offset(fdt, gbe, "interfaces"); fdt_for_each_subnode(fdt, slave, interfaces) { int slave_no; slave_no = fdtdec_get_int(fdt, slave, "slave-port", -ENOENT); if (slave_no == -ENOENT) continue; if (slave_no == 0) { /* This is the current eth device */ *gbe_0 = slave; } else { /* Slave devices to be registered */ slave_name = malloc(20); snprintf(slave_name, 20, "netcp@slave-%d", slave_no); ret = device_bind_driver_to_node(dev, "eth_ks2_sl", slave_name, slave, &sl_dev); if (ret) { error("ks2_net - not able to bind slave interfaces\n"); return ret; } } }
static int led_gpio_bind(struct udevice *parent) { struct udevice *dev; ofnode node; int ret; dev_for_each_subnode(node, parent) { struct led_uc_plat *uc_plat; const char *label; label = ofnode_read_string(node, "label"); if (!label) { debug("%s: node %s has no label\n", __func__, ofnode_get_name(node)); return -EINVAL; } ret = device_bind_driver_to_node(parent, "gpio_led", ofnode_get_name(node), node, &dev); if (ret) return ret; uc_plat = dev_get_uclass_platdata(dev); uc_plat->label = label; } return 0; }
/* Find the I2C buses selected by this mux */ static int i2c_mux_post_bind(struct udevice *mux) { const void *blob = gd->fdt_blob; int ret; int offset; debug("%s: %s\n", __func__, mux->name); /* * There is no compatible string in the sub-nodes, so we must manually * bind these */ for (offset = fdt_first_subnode(blob, mux->of_offset); offset > 0; offset = fdt_next_subnode(blob, offset)) { struct udevice *dev; const char *name; name = fdt_get_name(blob, offset, NULL); ret = device_bind_driver_to_node(mux, "i2c_mux_bus_drv", name, offset, &dev); debug(" - bind ret=%d, %s\n", ret, dev ? dev->name : NULL); if (ret) return ret; } return 0; }
static int syscon_probe_by_ofnode(ofnode node, struct udevice **devp) { struct udevice *dev, *parent; int ret; /* found node with "syscon" compatible, not bounded to SYSCON UCLASS */ if (!ofnode_device_is_compatible(node, "syscon")) { dev_dbg(dev, "invalid compatible for syscon device\n"); return -EINVAL; } /* bound to driver with same ofnode or to root if not found */ if (device_find_global_by_ofnode(node, &parent)) parent = dm_root(); /* force bound to syscon class */ ret = device_bind_driver_to_node(parent, "syscon", ofnode_get_name(node), node, &dev); if (ret) { dev_dbg(dev, "unable to bound syscon device\n"); return ret; } ret = device_probe(dev); if (ret) { dev_dbg(dev, "unable to probe syscon device\n"); return ret; } *devp = dev; return 0; }
static int led_gpio_bind(struct udevice *parent) { const void *blob = gd->fdt_blob; struct udevice *dev; int node; int ret; for (node = fdt_first_subnode(blob, dev_of_offset(parent)); node > 0; node = fdt_next_subnode(blob, node)) { struct led_uclass_plat *uc_plat; const char *label; label = fdt_getprop(blob, node, "label", NULL); if (!label) { debug("%s: node %s has no label\n", __func__, fdt_get_name(blob, node, NULL)); return -EINVAL; } ret = device_bind_driver_to_node(parent, "gpio_led", fdt_get_name(blob, node, NULL), node, &dev); if (ret) return ret; uc_plat = dev_get_uclass_platdata(dev); uc_plat->label = label; } return 0; }
static int stm32_rcc_bind(struct udevice *dev) { int ret; struct udevice *child; debug("%s(dev=%p)\n", __func__, dev); ret = device_bind_driver_to_node(dev, "stm32h7_rcc_clock", "stm32h7_rcc_clock", dev_ofnode(dev), &child); if (ret) return ret; return device_bind_driver_to_node(dev, "stm32_rcc_reset", "stm32_rcc_reset", dev_ofnode(dev), &child); }
static int uclass_cpu_init(struct uclass *uc) { struct udevice *dev; int node; int ret; node = fdt_path_offset(gd->fdt_blob, "/cpus"); if (node < 0) return 0; ret = device_bind_driver_to_node(dm_root(), "cpu_bus", "cpus", node, &dev); return ret; }
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; }
fdt_for_each_subnode(fdt, slave, sec_slave) { int slave_no; slave_no = fdtdec_get_int(fdt, slave, "slave-port", -ENOENT); if (slave_no == -ENOENT) continue; /* Slave devices to be registered */ slave_name = malloc(20); snprintf(slave_name, 20, "netcp@slave-%d", slave_no); ret = device_bind_driver_to_node(dev, "eth_ks2_sl", slave_name, slave, &sl_dev); if (ret) { error("ks2_net - not able to bind slave interfaces\n"); return ret; } }
int rockchip_reset_bind(struct udevice *pdev, u32 reg_offset, u32 reg_number) { struct udevice *rst_dev; struct rockchip_reset_priv *priv; int ret; ret = device_bind_driver_to_node(pdev, "rockchip_reset", "reset", dev_ofnode(pdev), &rst_dev); if (ret) { debug("Warning: No rockchip reset driver: ret=%d\n", ret); return ret; } priv = malloc(sizeof(struct rockchip_reset_priv)); priv->reset_reg_offset = reg_offset; priv->reset_reg_num = reg_number; rst_dev->priv = priv; return 0; }
/** * pinconfig_post_bind() - post binding for PINCONFIG uclass * Recursively bind its children as pinconfig devices. * * @dev: pinconfig device * @return: 0 on success, or negative error code on failure */ static int pinconfig_post_bind(struct udevice *dev) { bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC); const char *name; ofnode node; int ret; if (!dev_of_valid(dev)) return 0; dev_for_each_subnode(node, dev) { if (pre_reloc_only && !ofnode_pre_reloc(node)) continue; /* * If this node has "compatible" property, this is not * a pin configuration node, but a normal device. skip. */ ofnode_get_property(node, "compatible", &ret); if (ret >= 0) continue; /* If this node has "gpio-controller" property, skip */ if (ofnode_read_bool(node, "gpio-controller")) continue; if (ret != -FDT_ERR_NOTFOUND) return ret; name = ofnode_get_name(node); if (!name) return -EINVAL; ret = device_bind_driver_to_node(dev, "pinconfig", name, node, NULL); if (ret) return ret; } return 0; }
static int ti_musb_wrapper_bind(struct udevice *parent) { const void *fdt = gd->fdt_blob; int node; int ret; for (node = fdt_first_subnode(fdt, parent->of_offset); node > 0; node = fdt_next_subnode(fdt, node)) { struct udevice *dev; const char *name = fdt_get_name(fdt, node, NULL); enum usb_dr_mode dr_mode; struct driver *drv; if (strncmp(name, "usb@", 4)) continue; dr_mode = usb_get_dr_mode(node); switch (dr_mode) { case USB_DR_MODE_PERIPHERAL: /* Bind MUSB device */ break; case USB_DR_MODE_HOST: /* Bind MUSB host */ ret = device_bind_driver_to_node(parent, "ti-musb-host", name, node, &dev); if (ret) { error("musb - not able to bind usb host node\n"); return ret; } break; default: break; }; } return 0; }
/** * at91_clk_sub_device_bind() - for the at91 clock driver * Recursively bind its children as clk devices. * * @return: 0 on success, or negative error code on failure */ int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name) { const void *fdt = gd->fdt_blob; int offset = dev_of_offset(dev); bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC); const char *name; int ret; for (offset = fdt_first_subnode(fdt, offset); offset > 0; offset = fdt_next_subnode(fdt, offset)) { if (pre_reloc_only && !fdt_getprop(fdt, offset, "u-boot,dm-pre-reloc", NULL)) continue; /* * If this node has "compatible" property, this is not * a clock sub-node, but a normal device. skip. */ fdt_get_property(fdt, offset, "compatible", &ret); if (ret >= 0) continue; if (ret != -FDT_ERR_NOTFOUND) return ret; name = fdt_get_name(fdt, offset, NULL); if (!name) return -EINVAL; ret = device_bind_driver_to_node(dev, drv_name, name, offset, NULL); if (ret) return ret; } return 0; }
int device_bind_driver(struct udevice *parent, const char *drv_name, const char *dev_name, struct udevice **devp) { return device_bind_driver_to_node(parent, drv_name, dev_name, -1, devp); }