PCI, x86: Add pci=pref_bar to realloc pref bars
So could reallocate 64bit pref mem above 4g.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index 0126f10..600bd6f 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -35,6 +35,7 @@
#define PCI_NOASSIGN_ROMS 0x80000
#define PCI_ROOT_NO_CRS 0x100000
#define PCI_NOASSIGN_BARS 0x200000
+#define PCI_ASSIGN_PREF_BARS 0x400000
extern unsigned int pci_probe;
extern unsigned long pirq_table_addr;
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 7e65128..852d1a7 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -576,6 +576,9 @@
} else if (!strcmp(str, "assign-busses")) {
pci_probe |= PCI_ASSIGN_ALL_BUSSES;
return NULL;
+ } else if (!strcmp(str, "pref_bar")) {
+ pci_probe |= PCI_ASSIGN_PREF_BARS;
+ return NULL;
} else if (!strcmp(str, "use_crs")) {
pci_probe |= PCI_USE__CRS;
return NULL;
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 6fbd5f2..301f712 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -209,7 +209,9 @@
for_each_pci_resource(dev, r, idx, PCI_BRIDGE_RES) {
if (!r->flags)
continue;
- if (!r->start || pci_claim_resource(dev, idx) < 0) {
+ if (((r->flags & IORESOURCE_PREFETCH) &&
+ (pci_probe & PCI_ASSIGN_PREF_BARS)) ||
+ !r->start || pci_claim_resource(dev, idx) < 0) {
/*
* Something is wrong with the region.
* Invalidate the resource to prevent
@@ -250,15 +252,19 @@
else
disabled = !(command & PCI_COMMAND_MEMORY);
if (pass == disabled) {
+ if ((r->flags & IORESOURCE_PREFETCH) &&
+ (pci_probe & PCI_ASSIGN_PREF_BARS))
+ goto clear_start;
dev_dbg(&dev->dev,
"BAR %d: reserving %pr (d=%d, p=%d)\n",
idx, r, disabled, pass);
- if (pci_claim_resource(dev, idx) < 0) {
- /* We'll assign a new address later */
- pcibios_save_fw_addr(dev, idx, r->start);
- r->end -= r->start;
- r->start = 0;
- }
+ if (!pci_claim_resource(dev, idx))
+ continue;
+clear_start:
+ /* We'll assign a new address later */
+ pcibios_save_fw_addr(dev, idx, r->start);
+ r->end -= r->start;
+ r->start = 0;
}
}
if (!pass) {