From 142587887e28e8f71bbb3bb7eacdf7f2d7f8a10b Mon Sep 17 00:00:00 2001 From: Thomas Jarosch Date: Wed, 7 Dec 2011 22:08:11 +0100 Subject: [PATCH] --- yaml --- r: 294720 b: refs/heads/master c: f67fd55fa96f7d7295b43ffbc4a97d8f55e473aa h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/pci/quirks.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 05da2b97a5c2..fdcaa1ce8a14 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 3209874a1da2c51c7325e601d9634189ee178ad6 +refs/heads/master: f67fd55fa96f7d7295b43ffbc4a97d8f55e473aa diff --git a/trunk/drivers/pci/quirks.c b/trunk/drivers/pci/quirks.c index f5d09f4066f3..fb544d6d29f6 100644 --- a/trunk/drivers/pci/quirks.c +++ b/trunk/drivers/pci/quirks.c @@ -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) {