diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2014-04-14 17:35:21 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2014-04-25 13:09:04 -0400 |
commit | 44c8bdbe32aa51fe673c7a86b1e8f45b952d7759 (patch) | |
tree | 026e94f536852f5a8dce7a8192e14ed22bf2113d | |
parent | 4e4ba9441fb431f3996de2454522342e0b1d9263 (diff) |
x86/PCI: Mark ATI SBx00 HPET BAR as IORESOURCE_PCI_FIXED
Bodo reported that on the Asrock M3A UCC, v3.12.6 hangs during boot unless
he uses "pci=nocrs". This regression was caused by 7bc5e3f2be32 ("x86/PCI:
use host bridge _CRS info by default on 2008 and newer machines"), which
appeared in v2.6.34.
The reason is that the HPET address appears in a PCI device BAR, and this
address is not contained in any of the host bridge windows. Linux moves
the PCI BAR into a window, but the original address was published via the
HPET table and an ACPI device, so changing the BAR is a bad idea. Here's
the dmesg info:
ACPI: HPET id: 0x43538301 base: 0xfed00000
pci_root PNP0A03:00: host bridge window [mem 0xd0000000-0xdfffffff]
pci_root PNP0A03:00: host bridge window [mem 0xf0000000-0xfebfffff]
pci 0000:00:14.0: [1002:4385] type 0 class 0x000c05
pci 0000:00:14.0: reg 14: [mem 0xfed00000-0xfed003ff]
hpet0: at MMIO 0xfed00000, IRQs 2, 8, 0, 0
pnp 00:06: Plug and Play ACPI device, IDs PNP0103 (active)
pnp 00:06: [mem 0xfed00000-0xfed003ff]
When we notice the BAR is not in a host bridge window, we try to move it,
but that causes a hang shortly thereafter:
pci 0000:00:14.0: no compatible bridge window for [mem 0xfed00000-0xfed003ff]
pci 0000:00:14.0: BAR 1: assigned [mem 0xf0000000-0xf00003ff]
This patch marks the BAR as IORESOURCE_PCI_FIXED to prevent Linux from
moving it. This depends on a previous patch ("x86/PCI: Don't try to move
IORESOURCE_PCI_FIXED resources") to check for this flag when
pci_claim_resource() fails.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=68591
Reported-and-tested-by: Bodo Eggert <7eggert@gmx.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r-- | arch/x86/pci/fixup.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index 94ae9ae9574f..ef334a003f3c 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/dmi.h> | 6 | #include <linux/dmi.h> |
7 | #include <linux/pci.h> | 7 | #include <linux/pci.h> |
8 | #include <linux/vgaarb.h> | 8 | #include <linux/vgaarb.h> |
9 | #include <asm/hpet.h> | ||
9 | #include <asm/pci_x86.h> | 10 | #include <asm/pci_x86.h> |
10 | 11 | ||
11 | static void pci_fixup_i450nx(struct pci_dev *d) | 12 | static void pci_fixup_i450nx(struct pci_dev *d) |
@@ -526,6 +527,19 @@ static void sb600_disable_hpet_bar(struct pci_dev *dev) | |||
526 | } | 527 | } |
527 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x4385, sb600_disable_hpet_bar); | 528 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x4385, sb600_disable_hpet_bar); |
528 | 529 | ||
530 | #ifdef CONFIG_HPET_TIMER | ||
531 | static void sb600_hpet_quirk(struct pci_dev *dev) | ||
532 | { | ||
533 | struct resource *r = &dev->resource[1]; | ||
534 | |||
535 | if (r->flags & IORESOURCE_MEM && r->start == hpet_address) { | ||
536 | r->flags |= IORESOURCE_PCI_FIXED; | ||
537 | dev_info(&dev->dev, "reg 0x14 contains HPET; making it immovable\n"); | ||
538 | } | ||
539 | } | ||
540 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, 0x4385, sb600_hpet_quirk); | ||
541 | #endif | ||
542 | |||
529 | /* | 543 | /* |
530 | * Twinhead H12Y needs us to block out a region otherwise we map devices | 544 | * Twinhead H12Y needs us to block out a region otherwise we map devices |
531 | * there and any access kills the box. | 545 | * there and any access kills the box. |