MSI: Simplify BUG() handling in msi_remove_pci_irq_vectors() part 2
[powerpc.git] / drivers / pci / msi.c
index 435c195..91fed54 100644 (file)
@@ -68,6 +68,29 @@ static void msix_set_enable(struct pci_dev *dev, int enable)
        }
 }
 
+static void msix_flush_writes(unsigned int irq)
+{
+       struct msi_desc *entry;
+
+       entry = get_irq_msi(irq);
+       BUG_ON(!entry || !entry->dev);
+       switch (entry->msi_attrib.type) {
+       case PCI_CAP_ID_MSI:
+               /* nothing to do */
+               break;
+       case PCI_CAP_ID_MSIX:
+       {
+               int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
+                       PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET;
+               readl(entry->mask_base + offset);
+               break;
+       }
+       default:
+               BUG();
+               break;
+       }
+}
+
 static void msi_set_mask_bit(unsigned int irq, int flag)
 {
        struct msi_desc *entry;
@@ -187,11 +210,13 @@ void write_msi_msg(unsigned int irq, struct msi_msg *msg)
 void mask_msi_irq(unsigned int irq)
 {
        msi_set_mask_bit(irq, 1);
+       msix_flush_writes(irq);
 }
 
 void unmask_msi_irq(unsigned int irq)
 {
        msi_set_mask_bit(irq, 0);
+       msix_flush_writes(irq);
 }
 
 static int msi_free_irq(struct pci_dev* dev, int irq);
@@ -547,18 +572,15 @@ void pci_disable_msi(struct pci_dev* dev)
        if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) {
                return;
        }
-       if (irq_has_action(dev->first_msi_irq)) {
-               printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without "
-                      "free_irq() on MSI irq %d\n",
-                      pci_name(dev), dev->first_msi_irq);
-               BUG_ON(irq_has_action(dev->first_msi_irq));
-       } else {
-               default_irq = entry->msi_attrib.default_irq;
-               msi_free_irq(dev, dev->first_msi_irq);
 
-               /* Restore dev->irq to its default pin-assertion irq */
-               dev->irq = default_irq;
-       }
+       BUG_ON(irq_has_action(dev->first_msi_irq));
+
+       default_irq = entry->msi_attrib.default_irq;
+       msi_free_irq(dev, dev->first_msi_irq);
+
+       /* Restore dev->irq to its default pin-assertion irq */
+       dev->irq = default_irq;
+
        dev->first_msi_irq = 0;
 }
 
@@ -654,7 +676,7 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
 
 void pci_disable_msix(struct pci_dev* dev)
 {
-       int irq, head, tail = 0, warning = 0;
+       int irq, head, tail = 0;
 
        if (!pci_msi_enable)
                return;
@@ -671,19 +693,14 @@ void pci_disable_msix(struct pci_dev* dev)
        irq = head = dev->first_msi_irq;
        while (head != tail) {
                tail = get_irq_msi(irq)->link.tail;
-               if (irq_has_action(irq))
-                       warning = 1;
-               else if (irq != head)   /* Release MSI-X irq */
+
+               BUG_ON(irq_has_action(irq));
+
+               if (irq != head)        /* Release MSI-X irq */
                        msi_free_irq(dev, irq);
                irq = tail;
        }
        msi_free_irq(dev, irq);
-       if (warning) {
-               printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without "
-                       "free_irq() on all MSI-X irqs\n",
-                       pci_name(dev));
-               BUG_ON(warning > 0);
-       }
        dev->first_msi_irq = 0;
 }
 
@@ -702,36 +719,25 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
                return;
 
        if (dev->msi_enabled) {
-               if (irq_has_action(dev->first_msi_irq)) {
-                       printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
-                              "called without free_irq() on MSI irq %d\n",
-                              pci_name(dev), dev->first_msi_irq);
-                       BUG_ON(irq_has_action(dev->first_msi_irq));
-               } else /* Release MSI irq assigned to this device */
-                       msi_free_irq(dev, dev->first_msi_irq);
+               BUG_ON(irq_has_action(dev->first_msi_irq));
+               msi_free_irq(dev, dev->first_msi_irq);
        }
        if (dev->msix_enabled) {
-               int irq, head, tail = 0, warning = 0;
+               int irq, head, tail = 0;
                void __iomem *base = NULL;
 
                irq = head = dev->first_msi_irq;
                while (head != tail) {
                        tail = get_irq_msi(irq)->link.tail;
                        base = get_irq_msi(irq)->mask_base;
-                       if (irq_has_action(irq))
-                               warning = 1;
-                       else if (irq != head) /* Release MSI-X irq */
+
+                       BUG_ON(irq_has_action(irq));
+
+                       if (irq != head) /* Release MSI-X irq */
                                msi_free_irq(dev, irq);
                        irq = tail;
                }
                msi_free_irq(dev, irq);
-               if (warning) {
-                       iounmap(base);
-                       printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
-                              "called without free_irq() on all MSI-X irqs\n",
-                              pci_name(dev));
-                       BUG_ON(warning > 0);
-               }
        }
 }