MLK-17731 PCI: dwc: implement MSI-X support
authorRichard Zhu <hongxing.zhu@nxp.com>
Fri, 2 Mar 2018 09:24:05 +0000 (17:24 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Tue, 20 Mar 2018 19:56:39 +0000 (14:56 -0500)
The DWC MSI controller does not support different MSI-X target addresses
and does not allow to route individual IRQs to different CPUs. Aside
from those shortcomings it is able to support MSI-X just fine.

Some devices like the Intel i210 network controller depend on MSI-X to
be available to enable all hardware features, so even a feature limited
implementation of MSI-X on the host side is useful.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
drivers/pci/host/pcie-designware.c

index 0765eaf..b27d85b 100644 (file)
@@ -426,9 +426,6 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
        int irq, pos;
        struct pcie_port *pp = pdev->bus->sysdata;
 
-       if (desc->msi_attrib.is_msix)
-               return -EINVAL;
-
        irq = assign_irq(1, desc, &pos);
        if (irq < 0)
                return irq;
@@ -446,9 +443,20 @@ static int dw_msi_setup_irqs(struct msi_controller *chip, struct pci_dev *pdev,
        struct msi_desc *desc;
        struct pcie_port *pp = pdev->bus->sysdata;
 
-       /* MSI-X interrupts are not supported */
-       if (type == PCI_CAP_ID_MSIX)
-               return -EINVAL;
+       if (type == PCI_CAP_ID_MSIX) {
+               if ((MAX_MSI_IRQS - bitmap_weight(pp->msi_irq_in_use,
+                                                 MAX_MSI_IRQS)) < nvec)
+                       return -ENOSPC;
+
+               for_each_pci_msi_entry(desc, pdev) {
+                       int ret = dw_msi_setup_irq(chip, pdev, desc);
+
+                       if (ret)
+                               return ret;
+               }
+
+               return 0;
+       }
 
        WARN_ON(!list_is_singular(&pdev->dev.msi_list));
        desc = list_entry(pdev->dev.msi_list.next, struct msi_desc, list);