aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2012-09-17 22:25:35 -0700
committerYinghai Lu <yinghai@kernel.org>2012-09-17 22:25:35 -0700
commitaa23edc0cbca2eeed60eef1184fe386ff6db3e71 (patch)
tree56f0f0937aede19c01b288219654d62234f7ab29
parent06a747a001030f87bdc4131ee9be67de53935673 (diff)
downloadlinux-yinghai-aa23edc0cbca2eeed60eef1184fe386ff6db3e71.tar.gz
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>
-rw-r--r--arch/x86/include/asm/pci_x86.h1
-rw-r--r--arch/x86/pci/common.c3
-rw-r--r--arch/x86/pci/i386.c20
3 files changed, 17 insertions, 7 deletions
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index 73e8eeff22ee03..6edcf80d2708a0 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -35,6 +35,7 @@ do { \
#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 55837ce454a668..409033e2763f61 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -572,6 +572,9 @@ char * __init pcibios_setup(char *str)
} 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 07e2eab9ba921f..11b4e3b6e1275c 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -209,7 +209,9 @@ static void pcibios_allocate_bridge_resources(struct pci_dev *dev)
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 @@ static void pcibios_allocate_dev_resources(struct pci_dev *dev, int pass)
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) {