aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/quirks.c
diff options
context:
space:
mode:
authorThomas Jarosch <thomas.jarosch@intra2net.com>2011-12-07 16:08:11 -0500
committerJesse Barnes <jbarnes@virtuousgeek.org>2012-02-14 11:45:26 -0500
commitf67fd55fa96f7d7295b43ffbc4a97d8f55e473aa (patch)
tree93f18189c8b1d944e2433d9bfb70a1f67b4148a5 /drivers/pci/quirks.c
parent3209874a1da2c51c7325e601d9634189ee178ad6 (diff)
PCI: Add quirk for still enabled interrupts on Intel Sandy Bridge GPUs
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. Tested on the following boards: - Intel DH61CR: Affected - Intel DH67BL: Affected - Intel S1200KP server board: Affected - Asus P8H61-M LE: Affected, but system does not crash. Probably the IRQ ends up somewhere unnoticed. According to reports on the net, the Intel DH61WW board is also affected. Many thanks to Jesse Barnes from Intel for helping with the register configuration and to Intel in general for providing public hardware documentation. Signed-off-by: Thomas Jarosch <thomas.jarosch@intra2net.com> Tested-by: Charlie Suffin <charlie.suffin@stratus.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci/quirks.c')
-rw-r--r--drivers/pci/quirks.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index f5d09f4066f3..fb544d6d29f6 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2924,6 +2924,40 @@ static void do_one_fixup_debug(void (*fn)(struct pci_dev *dev), struct pci_dev *
2924 duration); 2924 duration);
2925} 2925}
2926 2926
2927/*
2928 * Some BIOS implementations leave the Intel GPU interrupts enabled,
2929 * even though no one is handling them (f.e. i915 driver is never loaded).
2930 * Additionally the interrupt destination is not set up properly
2931 * and the interrupt ends up -somewhere-.
2932 *
2933 * These spurious interrupts are "sticky" and the kernel disables
2934 * the (shared) interrupt line after 100.000+ generated interrupts.
2935 *
2936 * Fix it by disabling the still enabled interrupts.
2937 * This resolves crashes often seen on monitor unplug.
2938 */
2939#define I915_DEIER_REG 0x4400c
2940static void __devinit disable_igfx_irq(struct pci_dev *dev)
2941{
2942 void __iomem *regs = pci_iomap(dev, 0, 0);
2943 if (regs == NULL) {
2944 dev_warn(&dev->dev, "igfx quirk: Can't iomap PCI device\n");
2945 return;
2946 }
2947
2948 /* Check if any interrupt line is still enabled */
2949 if (readl(regs + I915_DEIER_REG) != 0) {
2950 dev_warn(&dev->dev, "BIOS left Intel GPU interrupts enabled; "
2951 "disabling\n");
2952
2953 writel(0, regs + I915_DEIER_REG);
2954 }
2955
2956 pci_iounmap(dev, regs);
2957}
2958DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq);
2959DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq);
2960
2927static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, 2961static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
2928 struct pci_fixup *end) 2962 struct pci_fixup *end)
2929{ 2963{