aboutsummaryrefslogtreecommitdiff
path: root/drivers/pci/pci-uclass.c
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2021-06-27 17:50:57 -0600
committerBin Meng <bmeng.cn@gmail.com>2021-07-15 19:49:50 +0800
commitf5cbb5c7cd24b5e674933bb381d854c02512d2d9 (patch)
tree00b101e293b3cff8ebf917787a4fccdea1ed5c7b /drivers/pci/pci-uclass.c
parente58f3a7d9b7e5961ca7e362bffd01a134ad3b831 (diff)
downloadu-boot-f5cbb5c7cd24b5e674933bb381d854c02512d2d9.zip
u-boot-f5cbb5c7cd24b5e674933bb381d854c02512d2d9.tar.gz
u-boot-f5cbb5c7cd24b5e674933bb381d854c02512d2d9.tar.bz2
x86: pci: Allow binding of some devices before relocation
At present only bridge devices are bound before relocation, to save space in pre-relocation memory. In some cases we do actually want to bind a device, e.g. because it provides the console UART. Add a devicetree binding to support this. Use the PCI_VENDEV() macro to encode the cell value. This is present in U-Boot but not used, so move it to the binding header-file. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Diffstat (limited to 'drivers/pci/pci-uclass.c')
-rw-r--r--drivers/pci/pci-uclass.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index 67838b9..fb12732 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -21,6 +21,7 @@
#if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP)
#include <asm/fsp/fsp_support.h>
#endif
+#include <dt-bindings/pci/pci.h>
#include <linux/delay.h>
#include "pci_internal.h"
@@ -682,6 +683,34 @@ static bool pci_match_one_id(const struct pci_device_id *id,
}
/**
+ * pci_need_device_pre_reloc() - Check if a device should be bound
+ *
+ * This checks a list of vendor/device-ID values indicating devices that should
+ * be bound before relocation.
+ *
+ * @bus: Bus to check
+ * @vendor: Vendor ID to check
+ * @device: Device ID to check
+ * @return true if the vendor/device is in the list, false if not
+ */
+static bool pci_need_device_pre_reloc(struct udevice *bus, uint vendor,
+ uint device)
+{
+ u32 vendev;
+ int index;
+
+ for (index = 0;
+ !dev_read_u32_index(bus, "u-boot,pci-pre-reloc", index,
+ &vendev);
+ index++) {
+ if (vendev == PCI_VENDEV(vendor, device))
+ return true;
+ }
+
+ return false;
+}
+
+/**
* pci_find_and_bind_driver() - Find and bind the right PCI driver
*
* This only looks at certain fields in the descriptor.
@@ -769,7 +798,9 @@ static int pci_find_and_bind_driver(struct udevice *parent,
* 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)
+ if (!(gd->flags & GD_FLG_RELOC) && !bridge &&
+ !pci_need_device_pre_reloc(parent, find_id->vendor,
+ find_id->device))
return log_msg_ret("notbr", -EPERM);
/* Bind a generic driver so that the device can be used */