[U-Boot] [PATCH v2 01/12] dm: pci: Support selected device/driver binding before relocation

Bin Meng bmeng.cn at gmail.com
Thu Aug 20 15:40:17 CEST 2015


On some platforms pci devices behind bridge need to be probed (eg:
a pci uart on recent x86 chipset) before relocation. But we won't
bind all devices found during the enumeration. Only devices whose
driver with DM_FLAG_PRE_RELOC set will be bound. Any other generic
devices except bridges won't be bound.

Signed-off-by: Bin Meng <bmeng.cn at gmail.com>
Acked-by: Simon Glass <sjg at chromium.org>

---

Changes in v2:
- Drop the following v1 patches:
  - dm: pci: Only allow serial device to be bound before relocation
  - drivers: serial: Add ns16550 compatible pci uart driver
  - drivers: serial: Remove special handling for pci uart in the ns16550 driver
  - x86: crownbay: Support Topcliff integrated pci uart devices
  - x86: queensbay: Call fsp_init_phase_pci() again

 drivers/pci/pci-uclass.c | 41 ++++++++++++++++++++++++++++++-----------
 1 file changed, 30 insertions(+), 11 deletions(-)

diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index 7d41d56..4160274 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -461,6 +461,7 @@ static int pci_find_and_bind_driver(struct udevice *parent,
 	int n_ents;
 	int ret;
 	char name[30], *str;
+	bool bridge;
 
 	*devp = NULL;
 
@@ -480,6 +481,17 @@ static int pci_find_and_bind_driver(struct udevice *parent,
 				continue;
 
 			drv = entry->driver;
+
+			/*
+			 * In the pre-relocation phase, we only bind devices
+			 * whose driver has the DM_FLAG_PRE_RELOC set, to save
+			 * precious memory space as on some platforms as that
+			 * space is pretty limited (ie: using Cache As RAM).
+			 */
+			if (!(gd->flags & GD_FLG_RELOC) &&
+			    !(drv->flags & DM_FLAG_PRE_RELOC))
+				return 0;
+
 			/*
 			 * We could pass the descriptor to the driver as
 			 * platdata (instead of NULL) and allow its bind()
@@ -499,14 +511,23 @@ static int pci_find_and_bind_driver(struct udevice *parent,
 		}
 	}
 
+	bridge = (find_id->class >> 8) == PCI_CLASS_BRIDGE_PCI;
+	/*
+	 * In the pre-relocation phase, we only bind bridge devices to save
+	 * precious memory space as on some platforms as that space is pretty
+	 * limited (ie: using Cache As RAM).
+	 */
+	if (!(gd->flags & GD_FLG_RELOC) && !bridge)
+		return 0;
+
 	/* Bind a generic driver so that the device can be used */
 	sprintf(name, "pci_%x:%x.%x", parent->seq, PCI_DEV(bdf),
 		PCI_FUNC(bdf));
 	str = strdup(name);
 	if (!str)
 		return -ENOMEM;
-	drv = (find_id->class >> 8) == PCI_CLASS_BRIDGE_PCI ? "pci_bridge_drv" :
-			"pci_generic_drv";
+	drv = bridge ? "pci_bridge_drv" : "pci_generic_drv";
+
 	ret = device_bind_driver(parent, drv, str, devp);
 	if (ret) {
 		debug("%s: Failed to bind generic driver: %d", __func__, ret);
@@ -589,11 +610,13 @@ int pci_bind_bus_devices(struct udevice *bus)
 			return ret;
 
 		/* Update the platform data */
-		pplat = dev_get_parent_platdata(dev);
-		pplat->devfn = PCI_MASK_BUS(bdf);
-		pplat->vendor = vendor;
-		pplat->device = device;
-		pplat->class = class;
+		if (dev) {
+			pplat = dev_get_parent_platdata(dev);
+			pplat->devfn = PCI_MASK_BUS(bdf);
+			pplat->vendor = vendor;
+			pplat->device = device;
+			pplat->class = class;
+		}
 	}
 
 	return 0;
@@ -717,10 +740,6 @@ static int pci_uclass_post_probe(struct udevice *bus)
 {
 	int ret;
 
-	/* Don't scan buses before relocation */
-	if (!(gd->flags & GD_FLG_RELOC))
-		return 0;
-
 	debug("%s: probing bus %d\n", __func__, bus->seq);
 	ret = pci_bind_bus_devices(bus);
 	if (ret)
-- 
1.8.2.1



More information about the U-Boot mailing list