aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt8
-rw-r--r--arch/ia64/include/asm/acpi.h1
-rw-r--r--arch/x86/include/asm/pci_x86.h1
-rw-r--r--arch/x86/pci/acpi.c53
-rw-r--r--arch/x86/pci/common.c3
-rw-r--r--drivers/acpi/pci_root.c1
-rw-r--r--include/acpi/acpi_drivers.h1
7 files changed, 60 insertions, 8 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 516225a864f9..3e69c1c4f508 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1948,8 +1948,12 @@ and is between 256 and 4096 characters. It is defined in the file
1948 IRQ routing is enabled. 1948 IRQ routing is enabled.
1949 noacpi [X86] Do not use ACPI for IRQ routing 1949 noacpi [X86] Do not use ACPI for IRQ routing
1950 or for PCI scanning. 1950 or for PCI scanning.
1951 use_crs [X86] Use _CRS for PCI resource 1951 use_crs [X86] Use PCI host bridge window information
1952 allocation. 1952 from ACPI. On BIOSes from 2008 or later, this
1953 is enabled by default. If you need to use this,
1954 please report a bug.
1955 nocrs [X86] Ignore PCI host bridge windows from ACPI.
1956 If you need to use this, please report a bug.
1953 routeirq Do IRQ routing for all PCI devices. 1957 routeirq Do IRQ routing for all PCI devices.
1954 This is normally done in pci_enable_device(), 1958 This is normally done in pci_enable_device(),
1955 so this option is a temporary workaround 1959 so this option is a temporary workaround
diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h
index e97b255d97bc..93997bd5edc3 100644
--- a/arch/ia64/include/asm/acpi.h
+++ b/arch/ia64/include/asm/acpi.h
@@ -98,6 +98,7 @@ ia64_acpi_release_global_lock (unsigned int *lock)
98#endif 98#endif
99#define acpi_processor_cstate_check(x) (x) /* no idle limits on IA64 :) */ 99#define acpi_processor_cstate_check(x) (x) /* no idle limits on IA64 :) */
100static inline void disable_acpi(void) { } 100static inline void disable_acpi(void) { }
101static inline void pci_acpi_crs_quirks(void) { }
101 102
102const char *acpi_get_sysname (void); 103const char *acpi_get_sysname (void);
103int acpi_request_vector (u32 int_type); 104int acpi_request_vector (u32 int_type);
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index b4bf9a942ed0..05b58ccb2e82 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -29,6 +29,7 @@
29#define PCI_CHECK_ENABLE_AMD_MMCONF 0x20000 29#define PCI_CHECK_ENABLE_AMD_MMCONF 0x20000
30#define PCI_HAS_IO_ECS 0x40000 30#define PCI_HAS_IO_ECS 0x40000
31#define PCI_NOASSIGN_ROMS 0x80000 31#define PCI_NOASSIGN_ROMS 0x80000
32#define PCI_ROOT_NO_CRS 0x100000
32 33
33extern unsigned int pci_probe; 34extern unsigned int pci_probe;
34extern unsigned long pirq_table_addr; 35extern unsigned long pirq_table_addr;
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index a2f8cdb8c1d5..5f11ff6f5389 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -15,6 +15,51 @@ struct pci_root_info {
15 int busnum; 15 int busnum;
16}; 16};
17 17
18static bool pci_use_crs = true;
19
20static int __init set_use_crs(const struct dmi_system_id *id)
21{
22 pci_use_crs = true;
23 return 0;
24}
25
26static const struct dmi_system_id pci_use_crs_table[] __initconst = {
27 /* http://bugzilla.kernel.org/show_bug.cgi?id=14183 */
28 {
29 .callback = set_use_crs,
30 .ident = "IBM System x3800",
31 .matches = {
32 DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
33 DMI_MATCH(DMI_PRODUCT_NAME, "x3800"),
34 },
35 },
36 {}
37};
38
39void __init pci_acpi_crs_quirks(void)
40{
41 int year;
42
43 if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year < 2008)
44 pci_use_crs = false;
45
46 dmi_check_system(pci_use_crs_table);
47
48 /*
49 * If the user specifies "pci=use_crs" or "pci=nocrs" explicitly, that
50 * takes precedence over anything we figured out above.
51 */
52 if (pci_probe & PCI_ROOT_NO_CRS)
53 pci_use_crs = false;
54 else if (pci_probe & PCI_USE__CRS)
55 pci_use_crs = true;
56
57 printk(KERN_INFO "PCI: %s host bridge windows from ACPI; "
58 "if necessary, use \"pci=%s\" and report a bug\n",
59 pci_use_crs ? "Using" : "Ignoring",
60 pci_use_crs ? "nocrs" : "use_crs");
61}
62
18static acpi_status 63static acpi_status
19resource_to_addr(struct acpi_resource *resource, 64resource_to_addr(struct acpi_resource *resource,
20 struct acpi_resource_address64 *addr) 65 struct acpi_resource_address64 *addr)
@@ -106,7 +151,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
106 res->child = NULL; 151 res->child = NULL;
107 align_resource(info->bridge, res); 152 align_resource(info->bridge, res);
108 153
109 if (!(pci_probe & PCI_USE__CRS)) { 154 if (!pci_use_crs) {
110 dev_printk(KERN_DEBUG, &info->bridge->dev, 155 dev_printk(KERN_DEBUG, &info->bridge->dev,
111 "host bridge window %pR (ignored)\n", res); 156 "host bridge window %pR (ignored)\n", res);
112 return AE_OK; 157 return AE_OK;
@@ -137,12 +182,8 @@ get_current_resources(struct acpi_device *device, int busnum,
137 struct pci_root_info info; 182 struct pci_root_info info;
138 size_t size; 183 size_t size;
139 184
140 if (pci_probe & PCI_USE__CRS) 185 if (pci_use_crs)
141 pci_bus_remove_resources(bus); 186 pci_bus_remove_resources(bus);
142 else
143 dev_info(&device->dev,
144 "ignoring host bridge windows from ACPI; "
145 "boot with \"pci=use_crs\" to use them\n");
146 187
147 info.bridge = device; 188 info.bridge = device;
148 info.bus = bus; 189 info.bus = bus;
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index d2552c68e94d..3736176acaab 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -520,6 +520,9 @@ char * __devinit pcibios_setup(char *str)
520 } else if (!strcmp(str, "use_crs")) { 520 } else if (!strcmp(str, "use_crs")) {
521 pci_probe |= PCI_USE__CRS; 521 pci_probe |= PCI_USE__CRS;
522 return NULL; 522 return NULL;
523 } else if (!strcmp(str, "nocrs")) {
524 pci_probe |= PCI_ROOT_NO_CRS;
525 return NULL;
523 } else if (!strcmp(str, "earlydump")) { 526 } else if (!strcmp(str, "earlydump")) {
524 pci_early_dump_regs = 1; 527 pci_early_dump_regs = 1;
525 return NULL; 528 return NULL;
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 9cd8bedb1e5a..d724736d56c8 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -566,6 +566,7 @@ static int __init acpi_pci_root_init(void)
566 if (acpi_pci_disabled) 566 if (acpi_pci_disabled)
567 return 0; 567 return 0;
568 568
569 pci_acpi_crs_quirks();
569 if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0) 570 if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0)
570 return -ENODEV; 571 return -ENODEV;
571 572
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index f4906f6568d4..3a4767c01c5f 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -104,6 +104,7 @@ int acpi_pci_bind_root(struct acpi_device *device);
104 104
105struct pci_bus *pci_acpi_scan_root(struct acpi_device *device, int domain, 105struct pci_bus *pci_acpi_scan_root(struct acpi_device *device, int domain,
106 int bus); 106 int bus);
107void pci_acpi_crs_quirks(void);
107 108
108/* -------------------------------------------------------------------------- 109/* --------------------------------------------------------------------------
109 Processor 110 Processor