diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 8 | ||||
-rw-r--r-- | arch/ia64/include/asm/acpi.h | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/pci_x86.h | 1 | ||||
-rw-r--r-- | arch/x86/pci/acpi.c | 53 | ||||
-rw-r--r-- | arch/x86/pci/common.c | 3 | ||||
-rw-r--r-- | drivers/acpi/pci_root.c | 1 | ||||
-rw-r--r-- | include/acpi/acpi_drivers.h | 1 |
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 :) */ |
100 | static inline void disable_acpi(void) { } | 100 | static inline void disable_acpi(void) { } |
101 | static inline void pci_acpi_crs_quirks(void) { } | ||
101 | 102 | ||
102 | const char *acpi_get_sysname (void); | 103 | const char *acpi_get_sysname (void); |
103 | int acpi_request_vector (u32 int_type); | 104 | int 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 | ||
33 | extern unsigned int pci_probe; | 34 | extern unsigned int pci_probe; |
34 | extern unsigned long pirq_table_addr; | 35 | extern 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 | ||
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; |
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 | ||
105 | struct pci_bus *pci_acpi_scan_root(struct acpi_device *device, int domain, | 105 | struct pci_bus *pci_acpi_scan_root(struct acpi_device *device, int domain, |
106 | int bus); | 106 | int bus); |
107 | void pci_acpi_crs_quirks(void); | ||
107 | 108 | ||
108 | /* -------------------------------------------------------------------------- | 109 | /* -------------------------------------------------------------------------- |
109 | Processor | 110 | Processor |