Message ID | 1472561830-20932-3-git-send-email-thomas.petazzoni@free-electrons.com (mailing list archive) |
---|---|
State | New, archived |
Delegated to: | Bjorn Helgaas |
Headers | show |
On Tue, Aug 30, 2016 at 02:57:09PM +0200, Thomas Petazzoni wrote: > The Designware PCIe controllers have a built-in MSI controller, which is > already supported by the existing. However, in some situations, it might ^ driver. > be a better choice to use an external MSI controller, especially when it > provides a higher number of MSI interrupts than the built-in one. > > Therefore, this commit extends the pcie-designware driver to support the > "msi-parent" DT property, already used by other drivers. It contains a > phandle pointing to the external MSI controller to be used. > > Following this commit, the pcie-designware code supports three > possibilities, in this order: > > 1. If msi-parent is provided, then the MSI controller pointed by this ^ to > property is used. > if (IS_ENABLED(CONFIG_PCI_MSI)) { > - if (!pp->ops->msi_host_init) { > + if (of_find_property(pp->dev->of_node, "msi-parent", NULL)) { > + struct device_node *msi_node; > + > + msi_node = of_parse_phandle(pp->dev->of_node, > + "msi-parent", 0); > + if (!msi_node) > + return -ENODEV; > + > + msi = of_pci_find_msi_chip_by_node(msi_node); By this point, device tree tells us the external MSI controller should exist. So if we get a NULL here, should we not return -EPROBE_DIFFERED? Andrew -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 12afce1..1e18a85 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c @@ -437,6 +437,7 @@ int dw_pcie_host_init(struct pcie_port *pp) int i, ret; LIST_HEAD(res); struct resource_entry *win; + struct msi_controller *msi = NULL; cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config"); if (cfg_res) { @@ -525,10 +526,21 @@ int dw_pcie_host_init(struct pcie_port *pp) pp->lanes = 0; if (IS_ENABLED(CONFIG_PCI_MSI)) { - if (!pp->ops->msi_host_init) { + if (of_find_property(pp->dev->of_node, "msi-parent", NULL)) { + struct device_node *msi_node; + + msi_node = of_parse_phandle(pp->dev->of_node, + "msi-parent", 0); + if (!msi_node) + return -ENODEV; + + msi = of_pci_find_msi_chip_by_node(msi_node); + } else if (!pp->ops->msi_host_init) { + msi = &dw_pcie_msi_chip; + msi->dev = pp->dev; pp->irq_domain = irq_domain_add_linear(pp->dev->of_node, MAX_MSI_IRQS, &msi_domain_ops, - &dw_pcie_msi_chip); + msi); if (!pp->irq_domain) { dev_err(pp->dev, "irq domain init failed\n"); ret = -ENXIO; @@ -538,7 +550,9 @@ int dw_pcie_host_init(struct pcie_port *pp) for (i = 0; i < MAX_MSI_IRQS; i++) irq_create_mapping(pp->irq_domain, i); } else { - ret = pp->ops->msi_host_init(pp, &dw_pcie_msi_chip); + msi = &dw_pcie_msi_chip; + msi->dev = pp->dev; + ret = pp->ops->msi_host_init(pp, msi); if (ret < 0) goto error; } @@ -550,9 +564,7 @@ int dw_pcie_host_init(struct pcie_port *pp) pp->root_bus_nr = pp->busn->start; if (IS_ENABLED(CONFIG_PCI_MSI)) { bus = pci_scan_root_bus_msi(pp->dev, pp->root_bus_nr, - &dw_pcie_ops, pp, &res, - &dw_pcie_msi_chip); - dw_pcie_msi_chip.dev = pp->dev; + &dw_pcie_ops, pp, &res, msi); } else bus = pci_scan_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops, pp, &res);
The Designware PCIe controllers have a built-in MSI controller, which is already supported by the existing. However, in some situations, it might be a better choice to use an external MSI controller, especially when it provides a higher number of MSI interrupts than the built-in one. Therefore, this commit extends the pcie-designware driver to support the "msi-parent" DT property, already used by other drivers. It contains a phandle pointing to the external MSI controller to be used. Following this commit, the pcie-designware code supports three possibilities, in this order: 1. If msi-parent is provided, then the MSI controller pointed by this property is used. 2. Otherwise, and if no ->msi_host_init() function is provided by the platform-specific "glue", then the built-in MSI controller of the Designware controller is used. 3. Otherwise, the ->msi_host_init() function of the platform-specific "glue" is used to do some additional initialization, but it's still the built-in MSI controller that is used. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> --- drivers/pci/host/pcie-designware.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-)