aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/msi.c74
1 files changed, 31 insertions, 43 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index bdd2ca9df41f..a7f2a014046b 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -272,7 +272,30 @@ void write_msi_msg(unsigned int irq, struct msi_msg *msg)
272 write_msi_msg_desc(desc, msg); 272 write_msi_msg_desc(desc, msg);
273} 273}
274 274
275static int msi_free_irqs(struct pci_dev* dev); 275static void free_msi_irqs(struct pci_dev *dev)
276{
277 struct msi_desc *entry, *tmp;
278
279 list_for_each_entry(entry, &dev->msi_list, list) {
280 int i, nvec;
281 if (!entry->irq)
282 continue;
283 nvec = 1 << entry->msi_attrib.multiple;
284 for (i = 0; i < nvec; i++)
285 BUG_ON(irq_has_action(entry->irq + i));
286 }
287
288 arch_teardown_msi_irqs(dev);
289
290 list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) {
291 if (entry->msi_attrib.is_msix) {
292 if (list_is_last(&entry->list, &dev->msi_list))
293 iounmap(entry->mask_base);
294 }
295 list_del(&entry->list);
296 kfree(entry);
297 }
298}
276 299
277static struct msi_desc *alloc_msi_entry(struct pci_dev *dev) 300static struct msi_desc *alloc_msi_entry(struct pci_dev *dev)
278{ 301{
@@ -396,7 +419,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
396 ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI); 419 ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI);
397 if (ret) { 420 if (ret) {
398 msi_mask_irq(entry, mask, ~mask); 421 msi_mask_irq(entry, mask, ~mask);
399 msi_free_irqs(dev); 422 free_msi_irqs(dev);
400 return ret; 423 return ret;
401 } 424 }
402 425
@@ -454,7 +477,7 @@ static int msix_capability_init(struct pci_dev *dev,
454 if (!i) 477 if (!i)
455 iounmap(base); 478 iounmap(base);
456 else 479 else
457 msi_free_irqs(dev); 480 free_msi_irqs(dev);
458 /* No enough memory. Don't try again */ 481 /* No enough memory. Don't try again */
459 return -ENOMEM; 482 return -ENOMEM;
460 } 483 }
@@ -486,7 +509,7 @@ static int msix_capability_init(struct pci_dev *dev,
486 } 509 }
487 510
488 if (ret) { 511 if (ret) {
489 msi_free_irqs(dev); 512 free_msi_irqs(dev);
490 return ret; 513 return ret;
491 } 514 }
492 515
@@ -644,37 +667,10 @@ void pci_disable_msi(struct pci_dev* dev)
644 return; 667 return;
645 668
646 pci_msi_shutdown(dev); 669 pci_msi_shutdown(dev);
647 msi_free_irqs(dev); 670 free_msi_irqs(dev);
648} 671}
649EXPORT_SYMBOL(pci_disable_msi); 672EXPORT_SYMBOL(pci_disable_msi);
650 673
651static int msi_free_irqs(struct pci_dev* dev)
652{
653 struct msi_desc *entry, *tmp;
654
655 list_for_each_entry(entry, &dev->msi_list, list) {
656 int i, nvec;
657 if (!entry->irq)
658 continue;
659 nvec = 1 << entry->msi_attrib.multiple;
660 for (i = 0; i < nvec; i++)
661 BUG_ON(irq_has_action(entry->irq + i));
662 }
663
664 arch_teardown_msi_irqs(dev);
665
666 list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) {
667 if (entry->msi_attrib.is_msix) {
668 if (list_is_last(&entry->list, &dev->msi_list))
669 iounmap(entry->mask_base);
670 }
671 list_del(&entry->list);
672 kfree(entry);
673 }
674
675 return 0;
676}
677
678/** 674/**
679 * pci_msix_table_size - return the number of device's MSI-X table entries 675 * pci_msix_table_size - return the number of device's MSI-X table entries
680 * @dev: pointer to the pci_dev data structure of MSI-X device function 676 * @dev: pointer to the pci_dev data structure of MSI-X device function
@@ -745,11 +741,6 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
745} 741}
746EXPORT_SYMBOL(pci_enable_msix); 742EXPORT_SYMBOL(pci_enable_msix);
747 743
748static void msix_free_all_irqs(struct pci_dev *dev)
749{
750 msi_free_irqs(dev);
751}
752
753void pci_msix_shutdown(struct pci_dev* dev) 744void pci_msix_shutdown(struct pci_dev* dev)
754{ 745{
755 struct msi_desc *entry; 746 struct msi_desc *entry;
@@ -774,7 +765,7 @@ void pci_disable_msix(struct pci_dev* dev)
774 return; 765 return;
775 766
776 pci_msix_shutdown(dev); 767 pci_msix_shutdown(dev);
777 msix_free_all_irqs(dev); 768 free_msi_irqs(dev);
778} 769}
779EXPORT_SYMBOL(pci_disable_msix); 770EXPORT_SYMBOL(pci_disable_msix);
780 771
@@ -792,11 +783,8 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
792 if (!pci_msi_enable || !dev) 783 if (!pci_msi_enable || !dev)
793 return; 784 return;
794 785
795 if (dev->msi_enabled) 786 if (dev->msi_enabled || dev->msix_enabled)
796 msi_free_irqs(dev); 787 free_msi_irqs(dev);
797
798 if (dev->msix_enabled)
799 msix_free_all_irqs(dev);
800} 788}
801 789
802void pci_no_msi(void) 790void pci_no_msi(void)