aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/ohci.c
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2010-06-05 06:31:25 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2010-06-09 13:42:18 -0400
commit262444eecce40950af19ea4d75a3dc03b3c07283 (patch)
tree87b465d2bdc2cc600807910d372e68ba668bda8a /drivers/firewire/ohci.c
parent148c7866c31d93f8c79366189075f5a26ad4556c (diff)
firewire: ohci: add MSI support
This patch adds support for message-signaled interrupts. Any native PCI-Express OHCI controller should support MSI, but most are just PCI cores behind a PCI-E/PCI bridge. The only chips that are known to claim to support MSI are the Lucent/Agere/LSI FW643 and the VIA VT6315, none of which I have been able to test. Due to the high level of trust I have in the competence of these and any future chip makers, I thought it a good idea to add a disable-MSI quirk. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Tested Agere FW643 rev 07 [11c1:5901] and JMicron JMB381 [197b:2380]. Added a quirks list entry for JMB38X since it kept its count of MSI events consistently at zero. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/ohci.c')
-rw-r--r--drivers/firewire/ohci.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 9743a405e69c..de5ff376231c 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -231,12 +231,14 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
231 231
232static char ohci_driver_name[] = KBUILD_MODNAME; 232static char ohci_driver_name[] = KBUILD_MODNAME;
233 233
234#define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380
234#define PCI_DEVICE_ID_TI_TSB12LV22 0x8009 235#define PCI_DEVICE_ID_TI_TSB12LV22 0x8009
235 236
236#define QUIRK_CYCLE_TIMER 1 237#define QUIRK_CYCLE_TIMER 1
237#define QUIRK_RESET_PACKET 2 238#define QUIRK_RESET_PACKET 2
238#define QUIRK_BE_HEADERS 4 239#define QUIRK_BE_HEADERS 4
239#define QUIRK_NO_1394A 8 240#define QUIRK_NO_1394A 8
241#define QUIRK_NO_MSI 16
240 242
241/* In case of multiple matches in ohci_quirks[], only the first one is used. */ 243/* In case of multiple matches in ohci_quirks[], only the first one is used. */
242static const struct { 244static const struct {
@@ -247,6 +249,7 @@ static const struct {
247 QUIRK_NO_1394A}, 249 QUIRK_NO_1394A},
248 {PCI_VENDOR_ID_TI, PCI_ANY_ID, QUIRK_RESET_PACKET}, 250 {PCI_VENDOR_ID_TI, PCI_ANY_ID, QUIRK_RESET_PACKET},
249 {PCI_VENDOR_ID_AL, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, 251 {PCI_VENDOR_ID_AL, PCI_ANY_ID, QUIRK_CYCLE_TIMER},
252 {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, QUIRK_NO_MSI},
250 {PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, 253 {PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER},
251 {PCI_VENDOR_ID_VIA, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, 254 {PCI_VENDOR_ID_VIA, PCI_ANY_ID, QUIRK_CYCLE_TIMER},
252 {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, QUIRK_BE_HEADERS}, 255 {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, QUIRK_BE_HEADERS},
@@ -260,6 +263,7 @@ MODULE_PARM_DESC(quirks, "Chip quirks (default = 0"
260 ", reset packet generation = " __stringify(QUIRK_RESET_PACKET) 263 ", reset packet generation = " __stringify(QUIRK_RESET_PACKET)
261 ", AR/selfID endianess = " __stringify(QUIRK_BE_HEADERS) 264 ", AR/selfID endianess = " __stringify(QUIRK_BE_HEADERS)
262 ", no 1394a enhancements = " __stringify(QUIRK_NO_1394A) 265 ", no 1394a enhancements = " __stringify(QUIRK_NO_1394A)
266 ", disable MSI = " __stringify(QUIRK_NO_MSI)
263 ")"); 267 ")");
264 268
265#define OHCI_PARAM_DEBUG_AT_AR 1 269#define OHCI_PARAM_DEBUG_AT_AR 1
@@ -1704,10 +1708,13 @@ static int ohci_enable(struct fw_card *card,
1704 1708
1705 reg_write(ohci, OHCI1394_AsReqFilterHiSet, 0x80000000); 1709 reg_write(ohci, OHCI1394_AsReqFilterHiSet, 0x80000000);
1706 1710
1711 if (!(ohci->quirks & QUIRK_NO_MSI))
1712 pci_enable_msi(dev);
1707 if (request_irq(dev->irq, irq_handler, 1713 if (request_irq(dev->irq, irq_handler,
1708 IRQF_SHARED, ohci_driver_name, ohci)) { 1714 pci_dev_msi_enabled(dev) ? 0 : IRQF_SHARED,
1709 fw_error("Failed to allocate shared interrupt %d.\n", 1715 ohci_driver_name, ohci)) {
1710 dev->irq); 1716 fw_error("Failed to allocate interrupt %d.\n", dev->irq);
1717 pci_disable_msi(dev);
1711 dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, 1718 dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE,
1712 ohci->config_rom, ohci->config_rom_bus); 1719 ohci->config_rom, ohci->config_rom_bus);
1713 return -EIO; 1720 return -EIO;
@@ -2622,6 +2629,7 @@ static void pci_remove(struct pci_dev *dev)
2622 context_release(&ohci->at_response_ctx); 2629 context_release(&ohci->at_response_ctx);
2623 kfree(ohci->it_context_list); 2630 kfree(ohci->it_context_list);
2624 kfree(ohci->ir_context_list); 2631 kfree(ohci->ir_context_list);
2632 pci_disable_msi(dev);
2625 pci_iounmap(dev, ohci->registers); 2633 pci_iounmap(dev, ohci->registers);
2626 pci_release_region(dev, 0); 2634 pci_release_region(dev, 0);
2627 pci_disable_device(dev); 2635 pci_disable_device(dev);
@@ -2639,6 +2647,7 @@ static int pci_suspend(struct pci_dev *dev, pm_message_t state)
2639 2647
2640 software_reset(ohci); 2648 software_reset(ohci);
2641 free_irq(dev->irq, ohci); 2649 free_irq(dev->irq, ohci);
2650 pci_disable_msi(dev);
2642 err = pci_save_state(dev); 2651 err = pci_save_state(dev);
2643 if (err) { 2652 if (err) {
2644 fw_error("pci_save_state failed\n"); 2653 fw_error("pci_save_state failed\n");