diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/pci-emul-uclass.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/drivers/pci/pci-emul-uclass.c b/drivers/pci/pci-emul-uclass.c index 3822758354..6b4efcea37 100644 --- a/drivers/pci/pci-emul-uclass.c +++ b/drivers/pci/pci-emul-uclass.c @@ -10,6 +10,7 @@ #include <linux/libfdt.h> #include <pci.h> #include <dm/lists.h> +#include <dm/uclass-internal.h> struct sandbox_pci_emul_priv { int dev_count; @@ -30,13 +31,14 @@ int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn, } *containerp = dev; - if (device_get_uclass_id(dev) == UCLASS_PCI_GENERIC) { - ret = device_find_first_child(dev, emulp); - if (ret) - return ret; - } else { + /* + * See commit 4345998ae9df, + * "pci: sandbox: Support dynamically binding device driver" + */ + ret = uclass_find_device_by_phandle(UCLASS_PCI_EMUL, dev, + "sandbox,emul", emulp); + if (ret && device_get_uclass_id(dev) != UCLASS_PCI_GENERIC) *emulp = dev; - } return *emulp ? 0 : -ENODEV; } @@ -68,3 +70,25 @@ UCLASS_DRIVER(pci_emul) = { .pre_remove = sandbox_pci_emul_pre_remove, .priv_auto_alloc_size = sizeof(struct sandbox_pci_emul_priv), }; + +/* + * This uclass is a child of the pci bus. Its platdata is not defined here so + * is defined by its parent, UCLASS_PCI, which uses struct pci_child_platdata. + * See per_child_platdata_auto_alloc_size in UCLASS_DRIVER(pci). + */ +UCLASS_DRIVER(pci_emul_parent) = { + .id = UCLASS_PCI_EMUL_PARENT, + .name = "pci_emul_parent", + .post_bind = dm_scan_fdt_dev, +}; + +static const struct udevice_id pci_emul_parent_ids[] = { + { .compatible = "sandbox,pci-emul-parent" }, + { } +}; + +U_BOOT_DRIVER(pci_emul_parent_drv) = { + .name = "pci_emul_parent_drv", + .id = UCLASS_PCI_EMUL_PARENT, + .of_match = pci_emul_parent_ids, +}; |