At present, until a PCI bus is probed, it cannot be found by its sequence
number unless it has an alias. This is the same with any device.
However with PCI this is more annoying than usual, since bus 0 is always the
same device.
Add a function that tries a little harder to locate PCI bus 0. This means
that PCI enumeration will happen automatically on the first access.
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
+static int pci_get_bus(int busnum, struct udevice **busp)
+{
+ int ret;
+
+ ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, busp);
+
+ /* Since buses may not be numbered yet try a little harder with bus 0 */
+ if (ret == -ENODEV) {
+ ret = uclass_first_device(UCLASS_PCI, busp);
+ if (ret)
+ return ret;
+ else if (!*busp)
+ return -ENODEV;
+ ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, busp);
+ }
+
+ return ret;
+}
+
struct pci_controller *pci_bus_to_hose(int busnum)
{
struct udevice *bus;
int ret;
struct pci_controller *pci_bus_to_hose(int busnum)
{
struct udevice *bus;
int ret;
- ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, &bus);
+ ret = pci_get_bus(busnum, &bus);
if (ret) {
debug("%s: Cannot get bus %d: ret=%d\n", __func__, busnum, ret);
return NULL;
}
if (ret) {
debug("%s: Cannot get bus %d: ret=%d\n", __func__, busnum, ret);
return NULL;
}
return dev_get_uclass_priv(bus);
}
return dev_get_uclass_priv(bus);
}
struct udevice *bus;
int ret;
struct udevice *bus;
int ret;
- ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus);
+ ret = pci_get_bus(PCI_BUS(bdf), &bus);
if (ret)
return ret;
return pci_bus_find_devfn(bus, PCI_MASK_BUS(bdf), devp);
if (ret)
return ret;
return pci_bus_find_devfn(bus, PCI_MASK_BUS(bdf), devp);
struct udevice *bus;
int ret;
struct udevice *bus;
int ret;
- ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus);
+ ret = pci_get_bus(PCI_BUS(bdf), &bus);
struct udevice *bus;
int ret;
struct udevice *bus;
int ret;
- ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus);
+ ret = pci_get_bus(PCI_BUS(bdf), &bus);