aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/tg3.c9
-rw-r--r--drivers/pci/msi.c18
-rw-r--r--drivers/pci/quirks.c24
-rw-r--r--include/linux/pci.h9
4 files changed, 45 insertions, 15 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 09440d783e65..cad519910767 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -7365,10 +7365,6 @@ static int tg3_open(struct net_device *dev)
7365 } else if (pci_enable_msi(tp->pdev) == 0) { 7365 } else if (pci_enable_msi(tp->pdev) == 0) {
7366 u32 msi_mode; 7366 u32 msi_mode;
7367 7367
7368 /* Hardware bug - MSI won't work if INTX disabled. */
7369 if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
7370 pci_intx(tp->pdev, 1);
7371
7372 msi_mode = tr32(MSGINT_MODE); 7368 msi_mode = tr32(MSGINT_MODE);
7373 tw32(MSGINT_MODE, msi_mode | MSGINT_MODE_ENABLE); 7369 tw32(MSGINT_MODE, msi_mode | MSGINT_MODE_ENABLE);
7374 tp->tg3_flags2 |= TG3_FLG2_USING_MSI; 7370 tp->tg3_flags2 |= TG3_FLG2_USING_MSI;
@@ -12681,11 +12677,6 @@ static int tg3_resume(struct pci_dev *pdev)
12681 if (err) 12677 if (err)
12682 return err; 12678 return err;
12683 12679
12684 /* Hardware bug - MSI won't work if INTX disabled. */
12685 if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) &&
12686 (tp->tg3_flags2 & TG3_FLG2_USING_MSI))
12687 pci_intx(tp->pdev, 1);
12688
12689 netif_device_attach(dev); 12680 netif_device_attach(dev);
12690 12681
12691 tg3_full_lock(tp, 0); 12682 tg3_full_lock(tp, 0);
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 87e01615053d..07c9f09c856d 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -224,6 +224,12 @@ static struct msi_desc* alloc_msi_entry(void)
224 return entry; 224 return entry;
225} 225}
226 226
227static void pci_intx_for_msi(struct pci_dev *dev, int enable)
228{
229 if (!(dev->dev_flags & PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG))
230 pci_intx(dev, enable);
231}
232
227#ifdef CONFIG_PM 233#ifdef CONFIG_PM
228static void __pci_restore_msi_state(struct pci_dev *dev) 234static void __pci_restore_msi_state(struct pci_dev *dev)
229{ 235{
@@ -237,7 +243,7 @@ static void __pci_restore_msi_state(struct pci_dev *dev)
237 entry = get_irq_msi(dev->irq); 243 entry = get_irq_msi(dev->irq);
238 pos = entry->msi_attrib.pos; 244 pos = entry->msi_attrib.pos;
239 245
240 pci_intx(dev, 0); /* disable intx */ 246 pci_intx_for_msi(dev, 0);
241 msi_set_enable(dev, 0); 247 msi_set_enable(dev, 0);
242 write_msi_msg(dev->irq, &entry->msg); 248 write_msi_msg(dev->irq, &entry->msg);
243 if (entry->msi_attrib.maskbit) 249 if (entry->msi_attrib.maskbit)
@@ -260,7 +266,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
260 return; 266 return;
261 267
262 /* route the table */ 268 /* route the table */
263 pci_intx(dev, 0); /* disable intx */ 269 pci_intx_for_msi(dev, 0);
264 msix_set_enable(dev, 0); 270 msix_set_enable(dev, 0);
265 271
266 list_for_each_entry(entry, &dev->msi_list, list) { 272 list_for_each_entry(entry, &dev->msi_list, list) {
@@ -343,7 +349,7 @@ static int msi_capability_init(struct pci_dev *dev)
343 } 349 }
344 350
345 /* Set MSI enabled bits */ 351 /* Set MSI enabled bits */
346 pci_intx(dev, 0); /* disable intx */ 352 pci_intx_for_msi(dev, 0);
347 msi_set_enable(dev, 1); 353 msi_set_enable(dev, 1);
348 dev->msi_enabled = 1; 354 dev->msi_enabled = 1;
349 355
@@ -433,7 +439,7 @@ static int msix_capability_init(struct pci_dev *dev,
433 i++; 439 i++;
434 } 440 }
435 /* Set MSI-X enabled bits */ 441 /* Set MSI-X enabled bits */
436 pci_intx(dev, 0); /* disable intx */ 442 pci_intx_for_msi(dev, 0);
437 msix_set_enable(dev, 1); 443 msix_set_enable(dev, 1);
438 dev->msix_enabled = 1; 444 dev->msix_enabled = 1;
439 445
@@ -528,7 +534,7 @@ void pci_disable_msi(struct pci_dev* dev)
528 return; 534 return;
529 535
530 msi_set_enable(dev, 0); 536 msi_set_enable(dev, 0);
531 pci_intx(dev, 1); /* enable intx */ 537 pci_intx_for_msi(dev, 1);
532 dev->msi_enabled = 0; 538 dev->msi_enabled = 0;
533 539
534 BUG_ON(list_empty(&dev->msi_list)); 540 BUG_ON(list_empty(&dev->msi_list));
@@ -640,7 +646,7 @@ void pci_disable_msix(struct pci_dev* dev)
640 return; 646 return;
641 647
642 msix_set_enable(dev, 0); 648 msix_set_enable(dev, 0);
643 pci_intx(dev, 1); /* enable intx */ 649 pci_intx_for_msi(dev, 1);
644 dev->msix_enabled = 0; 650 dev->msix_enabled = 0;
645 651
646 msix_free_all_irqs(dev); 652 msix_free_all_irqs(dev);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index f975f7fccb1d..9e8c7af0cc16 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1707,4 +1707,28 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
1707} 1707}
1708DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, 1708DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
1709 quirk_nvidia_ck804_msi_ht_cap); 1709 quirk_nvidia_ck804_msi_ht_cap);
1710
1711static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev)
1712{
1713 dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG;
1714}
1715DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,
1716 PCI_DEVICE_ID_TIGON3_5780,
1717 quirk_msi_intx_disable_bug);
1718DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,
1719 PCI_DEVICE_ID_TIGON3_5780S,
1720 quirk_msi_intx_disable_bug);
1721DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,
1722 PCI_DEVICE_ID_TIGON3_5714,
1723 quirk_msi_intx_disable_bug);
1724DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,
1725 PCI_DEVICE_ID_TIGON3_5714S,
1726 quirk_msi_intx_disable_bug);
1727DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,
1728 PCI_DEVICE_ID_TIGON3_5715,
1729 quirk_msi_intx_disable_bug);
1730DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,
1731 PCI_DEVICE_ID_TIGON3_5715S,
1732 quirk_msi_intx_disable_bug);
1733
1710#endif /* CONFIG_PCI_MSI */ 1734#endif /* CONFIG_PCI_MSI */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 5d2281f661f7..7c04f38e6ac3 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -109,6 +109,14 @@ enum pcie_reset_state {
109 pcie_hot_reset = (__force pcie_reset_state_t) 3 109 pcie_hot_reset = (__force pcie_reset_state_t) 3
110}; 110};
111 111
112typedef unsigned short __bitwise pci_dev_flags_t;
113enum pci_dev_flags {
114 /* INTX_DISABLE in PCI_COMMAND register disables MSI
115 * generation too.
116 */
117 PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG = (__force pci_dev_flags_t) 1,
118};
119
112typedef unsigned short __bitwise pci_bus_flags_t; 120typedef unsigned short __bitwise pci_bus_flags_t;
113enum pci_bus_flags { 121enum pci_bus_flags {
114 PCI_BUS_FLAGS_NO_MSI = (__force pci_bus_flags_t) 1, 122 PCI_BUS_FLAGS_NO_MSI = (__force pci_bus_flags_t) 1,
@@ -185,6 +193,7 @@ struct pci_dev {
185 unsigned int msix_enabled:1; 193 unsigned int msix_enabled:1;
186 unsigned int is_managed:1; 194 unsigned int is_managed:1;
187 unsigned int is_pcie:1; 195 unsigned int is_pcie:1;
196 pci_dev_flags_t dev_flags;
188 atomic_t enable_cnt; /* pci_enable_device has been called */ 197 atomic_t enable_cnt; /* pci_enable_device has been called */
189 198
190 u32 saved_config_space[16]; /* config space saved at suspend time */ 199 u32 saved_config_space[16]; /* config space saved at suspend time */