dm: pci: Use the correct hose when configuring devices
authorSimon Glass <sjg@chromium.org>
Sun, 7 Jun 2015 14:50:40 +0000 (08:50 -0600)
committerSimon Glass <sjg@chromium.org>
Wed, 15 Jul 2015 00:03:17 +0000 (18:03 -0600)
Only the PCI controller has access to the PCI region information. Make sure
to use the controller (rather than any attached bridges) when configuring
devices.

This corrects a failure to scan and configure devices when driver model is
enabled for PCI.

Also add a comment to explain the problem.

Signed-off-by: Simon Glass <sjg@chromium.org>
drivers/pci/pci-uclass.c
drivers/pci/pci_common.c
include/pci.h

index de8750546699e0a66a5d70d9652184d1c5ba448b..41d19cb37a936170d34e9e714be0ddea6b287194 100644 (file)
@@ -296,6 +296,7 @@ int pci_auto_config_devices(struct udevice *bus)
             !ret && dev;
             ret = device_find_next_child(&dev)) {
                struct pci_child_platdata *pplat;
+               struct pci_controller *ctlr_hose;
 
                pplat = dev_get_parent_platdata(dev);
                unsigned int max_bus;
@@ -303,7 +304,10 @@ int pci_auto_config_devices(struct udevice *bus)
 
                bdf = PCI_ADD_BUS(bus->seq, pplat->devfn);
                debug("%s: device %s\n", __func__, dev->name);
-               max_bus = pciauto_config_device(hose, bdf);
+
+               /* The root controller has the region information */
+               ctlr_hose = hose->ctlr->uclass_priv;
+               max_bus = pciauto_config_device(ctlr_hose, bdf);
                sub_bus = max(sub_bus, max_bus);
        }
        debug("%s: done\n", __func__);
index b9ff23f35bc8627650994c0e573adbe9c63eff14..f67c9c7b2fbf57a680f989f50312788e6ff89016 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <errno.h>
 #include <pci.h>
 #include <asm/io.h>
@@ -221,6 +222,11 @@ phys_addr_t pci_hose_bus_to_phys(struct pci_controller *hose,
                return phys_addr;
        }
 
+#ifdef CONFIG_DM_PCI
+       /* The root controller has the region information */
+       hose = hose->ctlr->uclass_priv;
+#endif
+
        /*
         * if PCI_REGION_MEM is set we do a two pass search with preference
         * on matches that don't have PCI_REGION_SYS_MEMORY set
index 07b1e9a4f54ace148ee72061348c203beb5e81a0..3af511b38de969c542a9b60d5ea75d961d7f5a0f 100644 (file)
@@ -513,6 +513,16 @@ struct pci_controller {
 
        int indirect_type;
 
+       /*
+        * TODO(sjg@chromium.org): With driver model we use struct
+        * pci_controller for both the controller and any bridge devices
+        * attached to it. But there is only one region list and it is in the
+        * top-level controller.
+        *
+        * This could be changed so that struct pci_controller is only used
+        * for PCI controllers and a separate UCLASS (or perhaps
+        * UCLASS_PCI_GENERIC) is used for bridges.
+        */
        struct pci_region regions[MAX_PCI_REGIONS];
        int region_count;