summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2014-02-14 13:48:16 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-03-06 22:06:22 -0800
commit3404ec304327ac92e8da2fd250c5aa7a81229fde (patch)
tree1684f895eed6c9c91f08ecdc6c3e2102588875eb
parent9984691beb0578d1211bb9b22292ea00789f9f5c (diff)
downloadlwn-3404ec304327ac92e8da2fd250c5aa7a81229fde.tar.gz
lwn-3404ec304327ac92e8da2fd250c5aa7a81229fde.zip
PCI: Enable INTx if BIOS left them disabled
commit 1f42db786b14a31bf807fc41ee5583a00c08fcb1 upstream. 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: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-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 07369f32e8bb..bde33336debc 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1120,6 +1120,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)
@@ -1129,6 +1131,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;
}