mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-19 05:31:32 +00:00
dm: pci: Support selected device/driver binding before relocation
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@gmail.com> Acked-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
f86f0c1897
commit
08fc7b8fac
1 changed files with 30 additions and 11 deletions
|
@ -461,6 +461,7 @@ static int pci_find_and_bind_driver(struct udevice *parent,
|
||||||
int n_ents;
|
int n_ents;
|
||||||
int ret;
|
int ret;
|
||||||
char name[30], *str;
|
char name[30], *str;
|
||||||
|
bool bridge;
|
||||||
|
|
||||||
*devp = NULL;
|
*devp = NULL;
|
||||||
|
|
||||||
|
@ -480,6 +481,17 @@ static int pci_find_and_bind_driver(struct udevice *parent,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
drv = entry->driver;
|
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
|
* We could pass the descriptor to the driver as
|
||||||
* platdata (instead of NULL) and allow its bind()
|
* 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 */
|
/* Bind a generic driver so that the device can be used */
|
||||||
sprintf(name, "pci_%x:%x.%x", parent->seq, PCI_DEV(bdf),
|
sprintf(name, "pci_%x:%x.%x", parent->seq, PCI_DEV(bdf),
|
||||||
PCI_FUNC(bdf));
|
PCI_FUNC(bdf));
|
||||||
str = strdup(name);
|
str = strdup(name);
|
||||||
if (!str)
|
if (!str)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
drv = (find_id->class >> 8) == PCI_CLASS_BRIDGE_PCI ? "pci_bridge_drv" :
|
drv = bridge ? "pci_bridge_drv" : "pci_generic_drv";
|
||||||
"pci_generic_drv";
|
|
||||||
ret = device_bind_driver(parent, drv, str, devp);
|
ret = device_bind_driver(parent, drv, str, devp);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
debug("%s: Failed to bind generic driver: %d", __func__, 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;
|
return ret;
|
||||||
|
|
||||||
/* Update the platform data */
|
/* Update the platform data */
|
||||||
pplat = dev_get_parent_platdata(dev);
|
if (dev) {
|
||||||
pplat->devfn = PCI_MASK_BUS(bdf);
|
pplat = dev_get_parent_platdata(dev);
|
||||||
pplat->vendor = vendor;
|
pplat->devfn = PCI_MASK_BUS(bdf);
|
||||||
pplat->device = device;
|
pplat->vendor = vendor;
|
||||||
pplat->class = class;
|
pplat->device = device;
|
||||||
|
pplat->class = class;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -717,10 +740,6 @@ static int pci_uclass_post_probe(struct udevice *bus)
|
||||||
{
|
{
|
||||||
int ret;
|
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);
|
debug("%s: probing bus %d\n", __func__, bus->seq);
|
||||||
ret = pci_bind_bus_devices(bus);
|
ret = pci_bind_bus_devices(bus);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
Loading…
Add table
Reference in a new issue