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; |
