Merge tag 'u-boot-imx-20191009' of https://gitlab.denx.de/u-boot/custodians/u-boot-imx
[oweals/u-boot.git] / drivers / pci / pci-emul-uclass.c
index e9d2f4979329fda88c9b92b9d4f137bd6f78b742..0dcf937d9a67bc28a562e6496d3c5cbb68935416 100644 (file)
@@ -11,7 +11,7 @@
 #include <pci.h>
 #include <dm/lists.h>
 
-struct sandbox_pci_priv {
+struct sandbox_pci_emul_priv {
        int dev_count;
 };
 
@@ -30,20 +30,41 @@ 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_get_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;
 }
 
+uint sandbox_pci_read_bar(u32 barval, int type, uint size)
+{
+       u32 result;
+
+       result = barval;
+       if (result == 0xffffffff) {
+               if (type == PCI_BASE_ADDRESS_SPACE_IO) {
+                       result = (~(size - 1) &
+                               PCI_BASE_ADDRESS_IO_MASK) |
+                               PCI_BASE_ADDRESS_SPACE_IO;
+               } else {
+                       result = (~(size - 1) &
+                               PCI_BASE_ADDRESS_MEM_MASK) |
+                               PCI_BASE_ADDRESS_MEM_TYPE_32;
+               }
+       }
+
+       return result;
+}
+
 static int sandbox_pci_emul_post_probe(struct udevice *dev)
 {
-       struct sandbox_pci_priv *priv = dev->uclass->priv;
+       struct sandbox_pci_emul_priv *priv = dev->uclass->priv;
 
        priv->dev_count++;
        sandbox_set_enable_pci_map(true);
@@ -53,7 +74,7 @@ static int sandbox_pci_emul_post_probe(struct udevice *dev)
 
 static int sandbox_pci_emul_pre_remove(struct udevice *dev)
 {
-       struct sandbox_pci_priv *priv = dev->uclass->priv;
+       struct sandbox_pci_emul_priv *priv = dev->uclass->priv;
 
        priv->dev_count--;
        sandbox_set_enable_pci_map(priv->dev_count > 0);
@@ -66,5 +87,27 @@ UCLASS_DRIVER(pci_emul) = {
        .name           = "pci_emul",
        .post_probe     = sandbox_pci_emul_post_probe,
        .pre_remove     = sandbox_pci_emul_pre_remove,
-       .priv_auto_alloc_size   = sizeof(struct sandbox_pci_priv),
+       .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,
 };