aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/controller/dwc/pci-imx6.c
diff options
context:
space:
mode:
authorRichard Zhu <hongxing.zhu@nxp.com>2018-12-20 23:33:38 -0500
committerBjorn Helgaas <bhelgaas@google.com>2019-01-01 20:16:48 -0500
commit75cb8d20c112aba70f23d98e3f8d0a38ace16006 (patch)
treea1a44c1cce124a214520432dcd18995e0e1e61fb /drivers/pci/controller/dwc/pci-imx6.c
parent651022382c7f8da46cb4872a545ee1da6d097d2a (diff)
PCI: imx: Enable MSI from downstream components
The MSI Enable bit in the MSI Capability (PCIe r4.0, sec 7.7.1.2) controls whether a Function can request service using MSI. i.MX6 Root Ports implement the MSI Capability and may use MSI to request service for events like PME, hotplug, AER, etc. In addition, on i.MX6, the MSI Enable bit controls delivery of MSI interrupts from components below the Root Port. Prior to f3fdfc4ac3a2 ("PCI: Remove host driver Kconfig selection of CONFIG_PCIEPORTBUS"), enabling CONFIG_PCI_IMX6 automatically also enabled CONFIG_PCIEPORTBUS, and when portdrv claimed the Root Ports, it set the MSI Enable bit so it could use PME, hotplug, AER, etc. As a side effect, that also enabled delivery of MSI interrupts from downstream components. The imx6q-pcie driver itself does not depend on portdrv, so set MSI Enable in imx6q-pcie so MSI from downstream components works even if nobody uses MSI for the Root Port events. Fixes: f3fdfc4ac3a2 ("PCI: Remove host driver Kconfig selection of CONFIG_PCIEPORTBUS") Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Tested-by: Sven Van Asbroeck <TheSven73@googlemail.com> Tested-by: Trent Piepho <tpiepho@impinj.com> Reviewed-by: Lucas Stach <l.stach@pengutronix.de> Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Diffstat (limited to 'drivers/pci/controller/dwc/pci-imx6.c')
-rw-r--r--drivers/pci/controller/dwc/pci-imx6.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 2cbef2d7c207..bd02760257e5 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -67,6 +67,7 @@ struct imx6_pcie {
67#define PHY_PLL_LOCK_WAIT_USLEEP_MAX 200 67#define PHY_PLL_LOCK_WAIT_USLEEP_MAX 200
68 68
69/* PCIe Root Complex registers (memory-mapped) */ 69/* PCIe Root Complex registers (memory-mapped) */
70#define PCIE_RC_IMX6_MSI_CAP 0x50
70#define PCIE_RC_LCR 0x7c 71#define PCIE_RC_LCR 0x7c
71#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1 0x1 72#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1 0x1
72#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2 0x2 73#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2 0x2
@@ -848,6 +849,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
848 struct resource *dbi_base; 849 struct resource *dbi_base;
849 struct device_node *node = dev->of_node; 850 struct device_node *node = dev->of_node;
850 int ret; 851 int ret;
852 u16 val;
851 853
852 imx6_pcie = devm_kzalloc(dev, sizeof(*imx6_pcie), GFP_KERNEL); 854 imx6_pcie = devm_kzalloc(dev, sizeof(*imx6_pcie), GFP_KERNEL);
853 if (!imx6_pcie) 855 if (!imx6_pcie)
@@ -989,6 +991,14 @@ static int imx6_pcie_probe(struct platform_device *pdev)
989 if (ret < 0) 991 if (ret < 0)
990 return ret; 992 return ret;
991 993
994 if (pci_msi_enabled()) {
995 val = dw_pcie_readw_dbi(pci, PCIE_RC_IMX6_MSI_CAP +
996 PCI_MSI_FLAGS);
997 val |= PCI_MSI_FLAGS_ENABLE;
998 dw_pcie_writew_dbi(pci, PCIE_RC_IMX6_MSI_CAP + PCI_MSI_FLAGS,
999 val);
1000 }
1001
992 return 0; 1002 return 0;
993} 1003}
994 1004