int dm_uninit(void) { device_remove(dm_root()); device_unbind(dm_root()); 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 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; }
/* Get ready for testing */ static int dm_test_init(struct dm_test_state *dms) { memset(dms, '\0', sizeof(*dms)); gd->dm_root = NULL; memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count)); ut_assertok(dm_init()); dms->root = dm_root(); return 0; }
/* * Create a block device for a handle * * @handle handle * @interface block io protocol * @return 0 = success */ static int efi_bl_bind(efi_handle_t handle, void *interface) { struct udevice *bdev, *parent = dm_root(); int ret, devnum; char *name; struct efi_object *obj = efi_search_obj(handle); struct efi_block_io *io = interface; int disks; struct efi_blk_priv *priv; EFI_PRINT("%s: handle %p, interface %p\n", __func__, handle, io); if (!obj) return -ENOENT; devnum = blk_find_max_devnum(IF_TYPE_EFI); if (devnum == -ENODEV) devnum = 0; else if (devnum < 0) return devnum; name = calloc(1, 18); /* strlen("efiblk#2147483648") + 1 */ if (!name) return -ENOMEM; sprintf(name, "efiblk#%d", devnum); /* Create driver model udevice for the EFI block io device */ ret = blk_create_device(parent, "efi_blk", name, IF_TYPE_EFI, devnum, io->media->block_size, (lbaint_t)io->media->last_block, &bdev); if (ret) return ret; if (!bdev) return -ENOENT; /* Allocate priv */ ret = device_probe(bdev); if (ret) return ret; EFI_PRINT("%s: block device '%s' created\n", __func__, bdev->name); priv = bdev->priv; priv->handle = handle; priv->io = interface; ret = blk_prepare_device(bdev); /* Create handles for the partions of the block device */ disks = efi_bl_bind_partitions(handle, bdev); EFI_PRINT("Found %d partitions\n", disks); return 0; }
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; }
int axp_gpio_init(void) { struct udevice *dev; int ret; ret = pmic_bus_init(); if (ret) return ret; /* There is no devicetree support for the axp yet, so bind directly */ ret = device_bind_driver(dm_root(), "gpio_axp", "AXP-gpio", &dev); if (ret) return ret; return 0; }
void sunxi_musb_board_init(void) { #ifdef CONFIG_USB_MUSB_HOST struct udevice *dev; /* * Bind the driver directly for now as musb linux kernel support is * still pending upstream so our dts files do not have the necessary * nodes yet. TODO: Remove this as soon as the dts nodes are in place * and bind by compatible instead. */ device_bind_driver(dm_root(), "sunxi-musb", "sunxi-musb", &dev); #else musb_register(&musb_plat, NULL, (void *)SUNXI_USB0_BASE); #endif }
/* Get ready for testing */ static int dm_test_init(struct unit_test_state *uts, bool of_live) { struct dm_test_state *dms = uts->priv; memset(dms, '\0', sizeof(*dms)); gd->dm_root = NULL; memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count)); state_reset_for_test(state_get_current()); #ifdef CONFIG_OF_LIVE /* Determine whether to make the live tree available */ gd->of_root = of_live ? uts->of_root : NULL; #endif ut_assertok(dm_init(of_live)); dms->root = dm_root(); return 0; }