[PATCH 2/4] x86/PCI: Mark HPET BAR as IORESOURCE_PCI_FIXED

From: Bjorn Helgaas
Date: Fri Apr 25 2014 - 13:17:56 EST


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:

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]

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-by: Bodo Eggert <7eggert@xxxxxx>
Signed-off-by: Bjorn Helgaas <bhelgaas@xxxxxxxxxx>
---
arch/x86/pci/fixup.c | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
index 94ae9ae9574f..d4359f9d74b6 100644
--- a/arch/x86/pci/fixup.c
+++ b/arch/x86/pci/fixup.c
@@ -6,6 +6,7 @@
#include <linux/dmi.h>
#include <linux/pci.h>
#include <linux/vgaarb.h>
+#include <asm/hpet.h>
#include <asm/pci_x86.h>

static void pci_fixup_i450nx(struct pci_dev *d)
@@ -526,6 +527,17 @@ static void sb600_disable_hpet_bar(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x4385, sb600_disable_hpet_bar);

+static void sb600_hpet_quirk(struct pci_dev *dev)
+{
+ struct resource *r = &dev->resource[0];
+
+ if (r->flags & IORESOURCE_MEM && r->start == hpet_address) {
+ r->flags |= IORESOURCE_PCI_FIXED;
+ dev_info(&dev->dev, "reg 0x10 contains HPET; making it immovable\n");
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, 0x4385, sb600_hpet_quirk);
+
/*
* Twinhead H12Y needs us to block out a region otherwise we map devices
* there and any access kills the box.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/