summaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2014-02-14 13:48:16 -0700
committerBjorn Helgaas <bhelgaas@google.com>2014-02-14 13:48:16 -0700
commit1f42db786b14a31bf807fc41ee5583a00c08fcb1 (patch)
treebde4516fa52a89b94935f118acbe48ee6d40ade2 /drivers/pci
parent3ce4e860e578f843db36a1f7357ba00aeaa7610f (diff)
downloadlinux-1f42db786b14a31bf807fc41ee5583a00c08fcb1.tar.bz2
PCI: Enable INTx if BIOS left them disabled
Some firmware leaves the Interrupt Disable bit set even if the device uses INTx interrupts. Clear Interrupt Disable so we get those interrupts. Based on the report mentioned below, if the user selects the "EHCI only" option in the Intel Baytrail BIOS, the EHCI device is handed off to the OS with the PCI_COMMAND_INTX_DISABLE bit set. Link: http://lkml.kernel.org/r/20140114181721.GC12126@xanatos Link: https://bugzilla.kernel.org/show_bug.cgi?id=70601 Reported-by: Chris Cheng <chris.cheng@atrustcorp.com> Reported-and-tested-by: Jamie Chen <jamie.chen@intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> CC: stable@vger.kernel.org CC: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/pci.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 1febe90831b4..6b05f6134b68 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1181,6 +1181,8 @@ EXPORT_SYMBOL_GPL(pci_load_and_free_saved_state);
static int do_pci_enable_device(struct pci_dev *dev, int bars)
{
int err;
+ u16 cmd;
+ u8 pin;
err = pci_set_power_state(dev, PCI_D0);
if (err < 0 && err != -EIO)
@@ -1190,6 +1192,14 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars)
return err;
pci_fixup_device(pci_fixup_enable, dev);
+ pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+ if (pin) {
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ if (cmd & PCI_COMMAND_INTX_DISABLE)
+ pci_write_config_word(dev, PCI_COMMAND,
+ cmd & ~PCI_COMMAND_INTX_DISABLE);
+ }
+
return 0;
}