|
@@ -2924,6 +2924,40 @@ static void do_one_fixup_debug(void (*fn)(struct pci_dev *dev), struct pci_dev *
|
|
|
duration);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Some BIOS implementations leave the Intel GPU interrupts enabled,
|
|
|
+ * even though no one is handling them (f.e. i915 driver is never loaded).
|
|
|
+ * Additionally the interrupt destination is not set up properly
|
|
|
+ * and the interrupt ends up -somewhere-.
|
|
|
+ *
|
|
|
+ * These spurious interrupts are "sticky" and the kernel disables
|
|
|
+ * the (shared) interrupt line after 100.000+ generated interrupts.
|
|
|
+ *
|
|
|
+ * Fix it by disabling the still enabled interrupts.
|
|
|
+ * This resolves crashes often seen on monitor unplug.
|
|
|
+ */
|
|
|
+#define I915_DEIER_REG 0x4400c
|
|
|
+static void __devinit disable_igfx_irq(struct pci_dev *dev)
|
|
|
+{
|
|
|
+ void __iomem *regs = pci_iomap(dev, 0, 0);
|
|
|
+ if (regs == NULL) {
|
|
|
+ dev_warn(&dev->dev, "igfx quirk: Can't iomap PCI device\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Check if any interrupt line is still enabled */
|
|
|
+ if (readl(regs + I915_DEIER_REG) != 0) {
|
|
|
+ dev_warn(&dev->dev, "BIOS left Intel GPU interrupts enabled; "
|
|
|
+ "disabling\n");
|
|
|
+
|
|
|
+ writel(0, regs + I915_DEIER_REG);
|
|
|
+ }
|
|
|
+
|
|
|
+ pci_iounmap(dev, regs);
|
|
|
+}
|
|
|
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq);
|
|
|
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq);
|
|
|
+
|
|
|
static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
|
|
|
struct pci_fixup *end)
|
|
|
{
|