aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/msi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/msi.c')
-rw-r--r--drivers/pci/msi.c100
1 files changed, 51 insertions, 49 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 362773247fbf..d9f06fbfa0bf 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -75,22 +75,17 @@ void arch_teardown_msi_irqs(struct pci_dev *dev)
75} 75}
76#endif 76#endif
77 77
78static void __msi_set_enable(struct pci_dev *dev, int pos, int enable) 78static void msi_set_enable(struct pci_dev *dev, int pos, int enable)
79{ 79{
80 u16 control; 80 u16 control;
81 81
82 if (pos) { 82 BUG_ON(!pos);
83 pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
84 control &= ~PCI_MSI_FLAGS_ENABLE;
85 if (enable)
86 control |= PCI_MSI_FLAGS_ENABLE;
87 pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control);
88 }
89}
90 83
91static void msi_set_enable(struct pci_dev *dev, int enable) 84 pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
92{ 85 control &= ~PCI_MSI_FLAGS_ENABLE;
93 __msi_set_enable(dev, pci_find_capability(dev, PCI_CAP_ID_MSI), enable); 86 if (enable)
87 control |= PCI_MSI_FLAGS_ENABLE;
88 pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control);
94} 89}
95 90
96static void msix_set_enable(struct pci_dev *dev, int enable) 91static void msix_set_enable(struct pci_dev *dev, int enable)
@@ -131,9 +126,6 @@ static inline __attribute_const__ u32 msi_enabled_mask(u16 control)
131 * mask all MSI interrupts by clearing the MSI enable bit does not work 126 * mask all MSI interrupts by clearing the MSI enable bit does not work
132 * reliably as devices without an INTx disable bit will then generate a 127 * reliably as devices without an INTx disable bit will then generate a
133 * level IRQ which will never be cleared. 128 * level IRQ which will never be cleared.
134 *
135 * Returns 1 if it succeeded in masking the interrupt and 0 if the device
136 * doesn't support MSI masking.
137 */ 129 */
138static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag) 130static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
139{ 131{
@@ -303,7 +295,7 @@ static void __pci_restore_msi_state(struct pci_dev *dev)
303 pos = entry->msi_attrib.pos; 295 pos = entry->msi_attrib.pos;
304 296
305 pci_intx_for_msi(dev, 0); 297 pci_intx_for_msi(dev, 0);
306 msi_set_enable(dev, 0); 298 msi_set_enable(dev, pos, 0);
307 write_msi_msg(dev->irq, &entry->msg); 299 write_msi_msg(dev->irq, &entry->msg);
308 300
309 pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); 301 pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
@@ -321,22 +313,22 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
321 313
322 if (!dev->msix_enabled) 314 if (!dev->msix_enabled)
323 return; 315 return;
316 BUG_ON(list_empty(&dev->msi_list));
317 entry = list_entry(dev->msi_list.next, struct msi_desc, list);
318 pos = entry->msi_attrib.pos;
319 pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control);
324 320
325 /* route the table */ 321 /* route the table */
326 pci_intx_for_msi(dev, 0); 322 pci_intx_for_msi(dev, 0);
327 msix_set_enable(dev, 0); 323 control |= PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL;
324 pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
328 325
329 list_for_each_entry(entry, &dev->msi_list, list) { 326 list_for_each_entry(entry, &dev->msi_list, list) {
330 write_msi_msg(entry->irq, &entry->msg); 327 write_msi_msg(entry->irq, &entry->msg);
331 msix_mask_irq(entry, entry->masked); 328 msix_mask_irq(entry, entry->masked);
332 } 329 }
333 330
334 BUG_ON(list_empty(&dev->msi_list));
335 entry = list_entry(dev->msi_list.next, struct msi_desc, list);
336 pos = entry->msi_attrib.pos;
337 pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control);
338 control &= ~PCI_MSIX_FLAGS_MASKALL; 331 control &= ~PCI_MSIX_FLAGS_MASKALL;
339 control |= PCI_MSIX_FLAGS_ENABLE;
340 pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); 332 pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
341} 333}
342 334
@@ -365,9 +357,9 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
365 u16 control; 357 u16 control;
366 unsigned mask; 358 unsigned mask;
367 359
368 msi_set_enable(dev, 0); /* Ensure msi is disabled as I set it up */
369
370 pos = pci_find_capability(dev, PCI_CAP_ID_MSI); 360 pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
361 msi_set_enable(dev, pos, 0); /* Disable MSI during set up */
362
371 pci_read_config_word(dev, msi_control_reg(pos), &control); 363 pci_read_config_word(dev, msi_control_reg(pos), &control);
372 /* MSI Entry Initialization */ 364 /* MSI Entry Initialization */
373 entry = alloc_msi_entry(dev); 365 entry = alloc_msi_entry(dev);
@@ -381,7 +373,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
381 entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ 373 entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */
382 entry->msi_attrib.pos = pos; 374 entry->msi_attrib.pos = pos;
383 375
384 entry->mask_pos = msi_mask_bits_reg(pos, entry->msi_attrib.is_64); 376 entry->mask_pos = msi_mask_reg(pos, entry->msi_attrib.is_64);
385 /* All MSIs are unmasked by default, Mask them all */ 377 /* All MSIs are unmasked by default, Mask them all */
386 if (entry->msi_attrib.maskbit) 378 if (entry->msi_attrib.maskbit)
387 pci_read_config_dword(dev, entry->mask_pos, &entry->masked); 379 pci_read_config_dword(dev, entry->mask_pos, &entry->masked);
@@ -399,7 +391,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
399 391
400 /* Set MSI enabled bits */ 392 /* Set MSI enabled bits */
401 pci_intx_for_msi(dev, 0); 393 pci_intx_for_msi(dev, 0);
402 msi_set_enable(dev, 1); 394 msi_set_enable(dev, pos, 1);
403 dev->msi_enabled = 1; 395 dev->msi_enabled = 1;
404 396
405 dev->irq = entry->irq; 397 dev->irq = entry->irq;
@@ -427,11 +419,14 @@ static int msix_capability_init(struct pci_dev *dev,
427 u8 bir; 419 u8 bir;
428 void __iomem *base; 420 void __iomem *base;
429 421
430 msix_set_enable(dev, 0);/* Ensure msix is disabled as I set it up */
431
432 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); 422 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
423 pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control);
424
425 /* Ensure MSI-X is disabled while it is set up */
426 control &= ~PCI_MSIX_FLAGS_ENABLE;
427 pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
428
433 /* Request & Map MSI-X table region */ 429 /* Request & Map MSI-X table region */
434 pci_read_config_word(dev, msi_control_reg(pos), &control);
435 nr_entries = multi_msix_capable(control); 430 nr_entries = multi_msix_capable(control);
436 431
437 pci_read_config_dword(dev, msix_table_offset_reg(pos), &table_offset); 432 pci_read_config_dword(dev, msix_table_offset_reg(pos), &table_offset);
@@ -442,7 +437,6 @@ static int msix_capability_init(struct pci_dev *dev,
442 if (base == NULL) 437 if (base == NULL)
443 return -ENOMEM; 438 return -ENOMEM;
444 439
445 /* MSI-X Table Initialization */
446 for (i = 0; i < nvec; i++) { 440 for (i = 0; i < nvec; i++) {
447 entry = alloc_msi_entry(dev); 441 entry = alloc_msi_entry(dev);
448 if (!entry) 442 if (!entry)
@@ -455,7 +449,6 @@ static int msix_capability_init(struct pci_dev *dev,
455 entry->msi_attrib.default_irq = dev->irq; 449 entry->msi_attrib.default_irq = dev->irq;
456 entry->msi_attrib.pos = pos; 450 entry->msi_attrib.pos = pos;
457 entry->mask_base = base; 451 entry->mask_base = base;
458 msix_mask_irq(entry, 1);
459 452
460 list_add_tail(&entry->list, &dev->msi_list); 453 list_add_tail(&entry->list, &dev->msi_list);
461 } 454 }
@@ -480,22 +473,31 @@ static int msix_capability_init(struct pci_dev *dev,
480 return ret; 473 return ret;
481 } 474 }
482 475
476 /*
477 * Some devices require MSI-X to be enabled before we can touch the
478 * MSI-X registers. We need to mask all the vectors to prevent
479 * interrupts coming in before they're fully set up.
480 */
481 control |= PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE;
482 pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
483
483 i = 0; 484 i = 0;
484 list_for_each_entry(entry, &dev->msi_list, list) { 485 list_for_each_entry(entry, &dev->msi_list, list) {
485 entries[i].vector = entry->irq; 486 entries[i].vector = entry->irq;
486 set_irq_msi(entry->irq, entry); 487 set_irq_msi(entry->irq, entry);
488 j = entries[i].entry;
489 entry->masked = readl(base + j * PCI_MSIX_ENTRY_SIZE +
490 PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
491 msix_mask_irq(entry, 1);
487 i++; 492 i++;
488 } 493 }
489 /* Set MSI-X enabled bits */ 494
495 /* Set MSI-X enabled bits and unmask the function */
490 pci_intx_for_msi(dev, 0); 496 pci_intx_for_msi(dev, 0);
491 msix_set_enable(dev, 1);
492 dev->msix_enabled = 1; 497 dev->msix_enabled = 1;
493 498
494 list_for_each_entry(entry, &dev->msi_list, list) { 499 control &= ~PCI_MSIX_FLAGS_MASKALL;
495 int vector = entry->msi_attrib.entry_nr; 500 pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
496 entry->masked = readl(base + vector * PCI_MSIX_ENTRY_SIZE +
497 PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
498 }
499 501
500 return 0; 502 return 0;
501} 503}
@@ -596,17 +598,20 @@ void pci_msi_shutdown(struct pci_dev *dev)
596 struct msi_desc *desc; 598 struct msi_desc *desc;
597 u32 mask; 599 u32 mask;
598 u16 ctrl; 600 u16 ctrl;
601 unsigned pos;
599 602
600 if (!pci_msi_enable || !dev || !dev->msi_enabled) 603 if (!pci_msi_enable || !dev || !dev->msi_enabled)
601 return; 604 return;
602 605
603 msi_set_enable(dev, 0); 606 BUG_ON(list_empty(&dev->msi_list));
607 desc = list_first_entry(&dev->msi_list, struct msi_desc, list);
608 pos = desc->msi_attrib.pos;
609
610 msi_set_enable(dev, pos, 0);
604 pci_intx_for_msi(dev, 1); 611 pci_intx_for_msi(dev, 1);
605 dev->msi_enabled = 0; 612 dev->msi_enabled = 0;
606 613
607 BUG_ON(list_empty(&dev->msi_list)); 614 pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &ctrl);
608 desc = list_first_entry(&dev->msi_list, struct msi_desc, list);
609 pci_read_config_word(dev, desc->msi_attrib.pos + PCI_MSI_FLAGS, &ctrl);
610 mask = msi_capable_mask(ctrl); 615 mask = msi_capable_mask(ctrl);
611 msi_mask_irq(desc, mask, ~mask); 616 msi_mask_irq(desc, mask, ~mask);
612 617
@@ -648,10 +653,7 @@ static int msi_free_irqs(struct pci_dev* dev)
648 653
649 list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) { 654 list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) {
650 if (entry->msi_attrib.is_msix) { 655 if (entry->msi_attrib.is_msix) {
651 writel(1, entry->mask_base + entry->msi_attrib.entry_nr 656 msix_mask_irq(entry, 1);
652 * PCI_MSIX_ENTRY_SIZE
653 + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
654
655 if (list_is_last(&entry->list, &dev->msi_list)) 657 if (list_is_last(&entry->list, &dev->msi_list))
656 iounmap(entry->mask_base); 658 iounmap(entry->mask_base);
657 } 659 }
@@ -691,8 +693,8 @@ int pci_msix_table_size(struct pci_dev *dev)
691 * indicates the successful configuration of MSI-X capability structure 693 * indicates the successful configuration of MSI-X capability structure
692 * with new allocated MSI-X irqs. A return of < 0 indicates a failure. 694 * with new allocated MSI-X irqs. A return of < 0 indicates a failure.
693 * Or a return of > 0 indicates that driver request is exceeding the number 695 * Or a return of > 0 indicates that driver request is exceeding the number
694 * of irqs available. Driver should use the returned value to re-send 696 * of irqs or MSI-X vectors available. Driver should use the returned value to
695 * its request. 697 * re-send its request.
696 **/ 698 **/
697int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) 699int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
698{ 700{
@@ -708,7 +710,7 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
708 710
709 nr_entries = pci_msix_table_size(dev); 711 nr_entries = pci_msix_table_size(dev);
710 if (nvec > nr_entries) 712 if (nvec > nr_entries)
711 return -EINVAL; 713 return nr_entries;
712 714
713 /* Check for any invalid entries */ 715 /* Check for any invalid entries */
714 for (i = 0; i < nvec; i++) { 716 for (i = 0; i < nvec; i++) {