diff options
Diffstat (limited to 'arch/x86/pci/acpi.c')
-rw-r--r-- | arch/x86/pci/acpi.c | 53 |
1 files changed, 47 insertions, 6 deletions
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 | ||
18 | static bool pci_use_crs = true; | ||
19 | |||
20 | static int __init set_use_crs(const struct dmi_system_id *id) | ||
21 | { | ||
22 | pci_use_crs = true; | ||
23 | return 0; | ||
24 | } | ||
25 | |||
26 | static 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 | |||
39 | void __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 | |||
18 | static acpi_status | 63 | static acpi_status |
19 | resource_to_addr(struct acpi_resource *resource, | 64 | resource_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; |