summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2015-08-31 18:55:35 -0600
committerSimon Glass <sjg@chromium.org>2015-09-09 07:48:03 -0600
commit983c6ba227e192c79b1df82853d8bacd40e1e989 (patch)
treec2685a05573b12c7bbbb431399de140ba367b8ed /drivers
parent8270e3c12eefbbb785ae145835cb0349091e257a (diff)
downloadtalos-obmc-uboot-983c6ba227e192c79b1df82853d8bacd40e1e989.tar.gz
talos-obmc-uboot-983c6ba227e192c79b1df82853d8bacd40e1e989.zip
dm: pci: Allow a PCI bus to be found without an alias
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/pci-uclass.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index b25298fb5e..ea70853da2 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -20,16 +20,36 @@
DECLARE_GLOBAL_DATA_PTR;
+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;
- 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;
}
+
return dev_get_uclass_priv(bus);
}
@@ -128,7 +148,7 @@ int pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp)
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);
@@ -206,7 +226,7 @@ int pci_write_config(pci_dev_t bdf, int offset, unsigned long value,
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;
@@ -271,7 +291,7 @@ int pci_read_config(pci_dev_t bdf, int offset, unsigned long *valuep,
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;
OpenPOWER on IntegriCloud