diff options
author | Jean Delvare <jdelvare@suse.de> | 2014-11-12 10:25:37 +0100 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2014-11-12 16:26:41 +0100 |
commit | aeb8a3d16ae0faceeae77adde2d3f9f2b199f4d9 (patch) | |
tree | 7ab95cb3f0ca822ebf8f95b3a2c0b54b24ae1310 /drivers/i2c | |
parent | i2c: i801: Fallback to polling if request_irq() fails (diff) | |
download | linux-aeb8a3d16ae0faceeae77adde2d3f9f2b199f4d9.tar.xz linux-aeb8a3d16ae0faceeae77adde2d3f9f2b199f4d9.zip |
i2c: i801: Check if interrupts are disabled
There is a control bit in the PCI configuration space which disables
interrupts. If this bit is set, the driver should not try to make use
of interrupts, it won't receive any.
Signed-off-by: Jean Delvare <jdelvare@suse.de>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-i801.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index a6f3bc38fbe5..3f1f30313cd7 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -109,12 +109,16 @@ /* PCI Address Constants */ #define SMBBAR 4 +#define SMBPCICTL 0x004 #define SMBPCISTS 0x006 #define SMBHSTCFG 0x040 /* Host status bits for SMBPCISTS */ #define SMBPCISTS_INTS 0x08 +/* Control bits for SMBPCICTL */ +#define SMBPCICTL_INTDIS 0x0400 + /* Host configuration bits for SMBHSTCFG */ #define SMBHSTCFG_HST_EN 1 #define SMBHSTCFG_SMB_SMI_EN 2 @@ -1232,6 +1236,22 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) priv->adapter.timeout = HZ / 5; if (priv->features & FEATURE_IRQ) { + u16 pcictl, pcists; + + /* Complain if an interrupt is already pending */ + pci_read_config_word(priv->pci_dev, SMBPCISTS, &pcists); + if (pcists & SMBPCISTS_INTS) + dev_warn(&dev->dev, "An interrupt is pending!\n"); + + /* Check if interrupts have been disabled */ + pci_read_config_word(priv->pci_dev, SMBPCICTL, &pcictl); + if (pcictl & SMBPCICTL_INTDIS) { + dev_info(&dev->dev, "Interrupts are disabled\n"); + priv->features &= ~FEATURE_IRQ; + } + } + + if (priv->features & FEATURE_IRQ) { init_waitqueue_head(&priv->waitq); err = request_irq(dev->irq, i801_isr, IRQF_SHARED, |