aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/controller/dwc/pcie-designware-host.c
diff options
context:
space:
mode:
authorRob Herring <robh@kernel.org>2020-11-05 15:11:52 -0600
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2020-11-19 10:51:41 +0000
commitf78f02638af5941eb45a402fa52c0edf4ac0f507 (patch)
tree5f5a6588d4e9ded840ca743fd4092be68ba29b26 /drivers/pci/controller/dwc/pcie-designware-host.c
parentPCI: dwc: Move MSI interrupt setup into DWC common code (diff)
downloadlinux-dev-f78f02638af5941eb45a402fa52c0edf4ac0f507.tar.xz
linux-dev-f78f02638af5941eb45a402fa52c0edf4ac0f507.zip
PCI: dwc: Rework MSI initialization
There are 3 possible MSI implementations for the DWC host. The first is using the built-in DWC MSI controller. The 2nd is a custom MSI controller as part of the PCI host (keystone only). The 3rd is an external MSI controller (typically GICv3 ITS). Currently, the last 2 are distinguished with a .msi_host_init() hook with the 3rd option using an empty function. However we can detect the 3rd case with the presence of 'msi-parent' or 'msi-map' properties, so let's do that instead and remove the empty functions. Link: https://lore.kernel.org/r/20201105211159.1814485-10-robh@kernel.org Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Rob Herring <robh@kernel.org> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Acked-by: Jingoo Han <jingoohan1@gmail.com> Cc: Murali Karicheri <m-karicheri2@ti.com> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Cc: Bjorn Helgaas <bhelgaas@google.com> Cc: Minghuan Lian <minghuan.Lian@nxp.com> Cc: Mingkai Hu <mingkai.hu@nxp.com> Cc: Roy Zang <roy.zang@nxp.com> Cc: Gustavo Pimentel <gustavo.pimentel@synopsys.com> Cc: linuxppc-dev@lists.ozlabs.org
Diffstat (limited to 'drivers/pci/controller/dwc/pcie-designware-host.c')
-rw-r--r--drivers/pci/controller/dwc/pcie-designware-host.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index 95deef0eaadf..9b952639d020 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -365,6 +365,10 @@ int dw_pcie_host_init(struct pcie_port *pp)
pci->link_gen = of_pci_get_max_link_speed(np);
if (pci_msi_enabled()) {
+ pp->has_msi_ctrl = !(pp->ops->msi_host_init ||
+ of_property_read_bool(np, "msi-parent") ||
+ of_property_read_bool(np, "msi-map"));
+
if (!pp->num_vectors) {
pp->num_vectors = MSI_DEF_NUM_VECTORS;
} else if (pp->num_vectors > MAX_MSI_IRQS) {
@@ -372,7 +376,11 @@ int dw_pcie_host_init(struct pcie_port *pp)
return -EINVAL;
}
- if (!pp->ops->msi_host_init) {
+ if (pp->ops->msi_host_init) {
+ ret = pp->ops->msi_host_init(pp);
+ if (ret < 0)
+ return ret;
+ } else if (pp->has_msi_ctrl) {
if (!pp->msi_irq) {
pp->msi_irq = platform_get_irq_byname_optional(pdev, "msi");
if (pp->msi_irq < 0) {
@@ -402,10 +410,6 @@ int dw_pcie_host_init(struct pcie_port *pp)
pp->msi_data = 0;
goto err_free_msi;
}
- } else {
- ret = pp->ops->msi_host_init(pp);
- if (ret < 0)
- return ret;
}
}
@@ -426,7 +430,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
return 0;
err_free_msi:
- if (pci_msi_enabled() && !pp->ops->msi_host_init)
+ if (pp->has_msi_ctrl)
dw_pcie_free_msi(pp);
return ret;
}
@@ -436,7 +440,7 @@ void dw_pcie_host_deinit(struct pcie_port *pp)
{
pci_stop_root_bus(pp->bridge->bus);
pci_remove_root_bus(pp->bridge->bus);
- if (pci_msi_enabled() && !pp->ops->msi_host_init)
+ if (pp->has_msi_ctrl)
dw_pcie_free_msi(pp);
}
EXPORT_SYMBOL_GPL(dw_pcie_host_deinit);
@@ -544,7 +548,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
dw_pcie_setup(pci);
- if (pci_msi_enabled() && !pp->ops->msi_host_init) {
+ if (pp->has_msi_ctrl) {
num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL;
/* Initialize IRQ Status array */