diff options
Diffstat (limited to 'arch/x86/pci/acpi.c')
-rw-r--r-- | arch/x86/pci/acpi.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index e4695985f9de..d93963340c3c 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
@@ -325,6 +325,26 @@ static void release_pci_root_info(struct pci_host_bridge *bridge) | |||
325 | kfree(info); | 325 | kfree(info); |
326 | } | 326 | } |
327 | 327 | ||
328 | /* | ||
329 | * An IO port or MMIO resource assigned to a PCI host bridge may be | ||
330 | * consumed by the host bridge itself or available to its child | ||
331 | * bus/devices. The ACPI specification defines a bit (Producer/Consumer) | ||
332 | * to tell whether the resource is consumed by the host bridge itself, | ||
333 | * but firmware hasn't used that bit consistently, so we can't rely on it. | ||
334 | * | ||
335 | * On x86 and IA64 platforms, all IO port and MMIO resources are assumed | ||
336 | * to be available to child bus/devices except one special case: | ||
337 | * IO port [0xCF8-0xCFF] is consumed by the host bridge itself | ||
338 | * to access PCI configuration space. | ||
339 | * | ||
340 | * So explicitly filter out PCI CFG IO ports[0xCF8-0xCFF]. | ||
341 | */ | ||
342 | static bool resource_is_pcicfg_ioport(struct resource *res) | ||
343 | { | ||
344 | return (res->flags & IORESOURCE_IO) && | ||
345 | res->start == 0xCF8 && res->end == 0xCFF; | ||
346 | } | ||
347 | |||
328 | static void probe_pci_root_info(struct pci_root_info *info, | 348 | static void probe_pci_root_info(struct pci_root_info *info, |
329 | struct acpi_device *device, | 349 | struct acpi_device *device, |
330 | int busnum, int domain, | 350 | int busnum, int domain, |
@@ -346,8 +366,8 @@ static void probe_pci_root_info(struct pci_root_info *info, | |||
346 | "no IO and memory resources present in _CRS\n"); | 366 | "no IO and memory resources present in _CRS\n"); |
347 | else | 367 | else |
348 | resource_list_for_each_entry_safe(entry, tmp, list) { | 368 | resource_list_for_each_entry_safe(entry, tmp, list) { |
349 | if ((entry->res->flags & IORESOURCE_WINDOW) == 0 || | 369 | if ((entry->res->flags & IORESOURCE_DISABLED) || |
350 | (entry->res->flags & IORESOURCE_DISABLED)) | 370 | resource_is_pcicfg_ioport(entry->res)) |
351 | resource_list_destroy_entry(entry); | 371 | resource_list_destroy_entry(entry); |
352 | else | 372 | else |
353 | entry->res->name = info->name; | 373 | entry->res->name = info->name; |