aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2012-09-17 22:25:33 -0700
committerYinghai Lu <yinghai@kernel.org>2012-09-17 22:25:33 -0700
commit5f2d29510447220f5e770487838f907c978803c2 (patch)
treee4f4d27ff4ab2e2f01e9fb686cae5df27634e175
parentb72e0b86de15db007b31ea2b79a8a4ca873d8aa8 (diff)
downloadlinux-yinghai-5f2d29510447220f5e770487838f907c978803c2.tar.gz
PCI: Add pci=alloc_high support
add pci=alloc_high to enable/disable alloc_high for resource allcation. default to alloc high to disable. Signed-off-by: Yinghai Lu <yinghai@kernel.org>
-rw-r--r--Documentation/kernel-parameters.txt6
-rw-r--r--drivers/pci/bus.c10
-rw-r--r--drivers/pci/pci.c4
-rw-r--r--drivers/pci/pci.h3
4 files changed, 23 insertions, 0 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index ad7e2e5088c12..56065b06a1671 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2189,6 +2189,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
off: Turn realloc off
on: Turn realloc on
realloc same as realloc=on
+ alloc_high= Enable/disable allocating PCI resources above
+ 4G at first when allocating resource to PCI
+ devices that does not get assigned by BIOS.
+ off: Turn alloc_high off
+ on: Turn alloc_high on
+ alloc_high same as alloc_high=on
noari do not use PCIe ARI.
pcie_scan_all Scan all possible PCIe devices. Otherwise we
only look for one device below a PCIe downstream
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index b4aae0f086ccf..264c4522b75b1 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -98,6 +98,14 @@ void pci_bus_remove_resources(struct pci_bus *bus)
}
}
+static bool pci_alloc_high_enable = false;
+void __init pci_alloc_high_get_opt(char *str)
+{
+ if (!strncmp(str, "off", 3))
+ pci_alloc_high_enable = false;
+ else if (!strncmp(str, "on", 2))
+ pci_alloc_high_enable = true;
+}
/**
* pci_bus_alloc_resource - allocate a resource from a parent bus
* @bus: PCI bus
@@ -147,6 +155,8 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
start = 0;
end = MAX_RESOURCE;
+ if (!pci_alloc_high_enable)
+ goto again;
/*
* don't allocate too high if the pref mem doesn't
* support 64bit, also if this is a 64-bit mem
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 6b0a9aef1faa8..34d6da045f5c1 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3871,6 +3871,10 @@ static int __init pci_setup(char *str)
pci_realloc_get_opt(str + 8);
} else if (!strncmp(str, "realloc", 7)) {
pci_realloc_get_opt("on");
+ } else if (!strncmp(str, "alloc_high=", 11)) {
+ pci_alloc_high_get_opt(str + 11);
+ } else if (!strncmp(str, "alloc_high", 10)) {
+ pci_alloc_high_get_opt("on");
} else if (!strcmp(str, "nodomains")) {
pci_no_domains();
} else if (!strncmp(str, "noari", 5)) {
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 0697604c71b6c..d4e05b735370a 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -145,6 +145,7 @@ static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { }
#endif
void pci_realloc_get_opt(char *);
+void pci_alloc_high_get_opt(char *);
static inline int pci_no_d1d2(struct pci_dev *dev)
{
@@ -205,6 +206,8 @@ enum pci_bar_type {
#define PCI_MAX_ADDR_32 ((resource_size_t)0xffffffff)
+#define PCI_MAX_ADDR_32 ((resource_size_t)0xffffffff)
+
bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl,
int crs_timeout);
extern int pci_setup_device(struct pci_dev *dev);