]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/powerpc/platforms/pseries/msi.c
Merge branches 'topic/asoc', 'topic/misc-fixes', 'topic/ps3-csbits' and 'topic/stagin...
[karo-tx-linux.git] / arch / powerpc / platforms / pseries / msi.c
index 9c3bcfe3fe6a055ae8fedc2663633dda9016d8a8..f15222bbe136a1020de443d3ff6c434c152c8d4b 100644 (file)
@@ -70,11 +70,15 @@ static int rtas_change_msi(struct pci_dn *pdn, u32 func, u32 num_irqs)
                seq_num = rtas_ret[1];
        } while (rtas_busy_delay(rc));
 
-       if (rc == 0) /* Success */
-               rc = rtas_ret[0];
+       /*
+        * If the RTAS call succeeded, check the number of irqs is actually
+        * what we asked for. If not, return an error.
+        */
+       if (rc == 0 && rtas_ret[0] != num_irqs)
+               rc = -ENOSPC;
 
-       pr_debug("rtas_msi: ibm,change_msi(func=%d,num=%d) = (%d)\n",
-                func, num_irqs, rc);
+       pr_debug("rtas_msi: ibm,change_msi(func=%d,num=%d), got %d rc = %d\n",
+                func, num_irqs, rtas_ret[0], rc);
 
        return rc;
 }
@@ -87,7 +91,7 @@ static void rtas_disable_msi(struct pci_dev *pdev)
        if (!pdn)
                return;
 
-       if (rtas_change_msi(pdn, RTAS_CHANGE_FN, 0) != 0)
+       if (rtas_change_msi(pdn, RTAS_CHANGE_FN, 0))
                pr_debug("rtas_msi: Setting MSIs to 0 failed!\n");
 }
 
@@ -167,6 +171,7 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
        struct pci_dn *pdn;
        int hwirq, virq, i, rc;
        struct msi_desc *entry;
+       struct msi_msg msg;
 
        pdn = get_pdn(pdev);
        if (!pdn)
@@ -180,14 +185,14 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
        if (type == PCI_CAP_ID_MSI) {
                rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec);
 
-               if (rc != nvec) {
+               if (rc) {
                        pr_debug("rtas_msi: trying the old firmware call.\n");
                        rc = rtas_change_msi(pdn, RTAS_CHANGE_FN, nvec);
                }
        } else
                rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec);
 
-       if (rc != nvec) {
+       if (rc) {
                pr_debug("rtas_msi: rtas_change_msi() failed\n");
                return rc;
        }
@@ -209,6 +214,11 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
 
                dev_dbg(&pdev->dev, "rtas_msi: allocated virq %d\n", virq);
                set_irq_msi(virq, entry);
+
+               /* Read config space back so we can restore after reset */
+               read_msi_msg(virq, &msg);
+               entry->msg = msg;
+
                unmask_msi_irq(virq);
        }