summaryrefslogtreecommitdiffstats
path: root/drivers/pci/quirks.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2011-01-06 18:24:07 +0900
committerPaul Mundt <lethal@linux-sh.org>2011-01-06 18:24:07 +0900
commitf862f904d357dc0d3612347a8dbabe6fae037fbb (patch)
treed7f5c2d5f85fd9e1cfc36beae904dc4f9cca04a3 /drivers/pci/quirks.c
parent6f09e41d704fe0bc9157a5357480751d39361d01 (diff)
parent3c0eee3fe6a3a1c745379547c7e7c904aa64f6d5 (diff)
downloadlinux-f862f904d357dc0d3612347a8dbabe6fae037fbb.tar.bz2
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6 into sh-latest
Conflicts: arch/sh/kernel/cpu/sh2a/clock-sh7201.c Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/pci/quirks.c')
-rw-r--r--drivers/pci/quirks.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 6f9350cabbd5..53a786fd0d40 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2329,6 +2329,9 @@ static void __devinit nvbridge_check_legacy_irq_routing(struct pci_dev *dev)
{
u32 cfg;
+ if (!pci_find_capability(dev, PCI_CAP_ID_HT))
+ return;
+
pci_read_config_dword(dev, 0x74, &cfg);
if (cfg & ((1 << 2) | (1 << 15))) {
@@ -2764,6 +2767,29 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_m
DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
#endif /*CONFIG_MMC_RICOH_MMC*/
+#if defined(CONFIG_DMAR) || defined(CONFIG_INTR_REMAP)
+#define VTUNCERRMSK_REG 0x1ac
+#define VTD_MSK_SPEC_ERRORS (1 << 31)
+/*
+ * This is a quirk for masking vt-d spec defined errors to platform error
+ * handling logic. With out this, platforms using Intel 7500, 5500 chipsets
+ * (and the derivative chipsets like X58 etc) seem to generate NMI/SMI (based
+ * on the RAS config settings of the platform) when a vt-d fault happens.
+ * The resulting SMI caused the system to hang.
+ *
+ * VT-d spec related errors are already handled by the VT-d OS code, so no
+ * need to report the same error through other channels.
+ */
+static void vtd_mask_spec_errors(struct pci_dev *dev)
+{
+ u32 word;
+
+ pci_read_config_dword(dev, VTUNCERRMSK_REG, &word);
+ pci_write_config_dword(dev, VTUNCERRMSK_REG, word | VTD_MSK_SPEC_ERRORS);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x342e, vtd_mask_spec_errors);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x3c28, vtd_mask_spec_errors);
+#endif
static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
struct pci_fixup *end)