On Tue, Apr 01, 2025 at 10:17:03AM +0100, Marc Zyngier wrote: > pci_host_common_probe() is an extremely userful helper, as it > abstracts away most of the gunk that a "mostly-ECAM-compliant" > device driver needs. > > However, it is structured as a probe function, meaning that a lot > of the driver-specific setup has to happen in a .init() callback, > after the bridge and config space have been instantiated. > > This is a bit awkward, and results in a number of convolutions > that could be avoided if the host-common code was more like > a library. > > Introduce a pci_host_common_init() helper that does exactly that, > taking the platform device and a struct pci_ecam_op as parameters. > > This can then be called from the probe routine, and a lot of the > code that isn't relevant to PCI setup moved away from the .init() > callback. This also removes the dependency on the device match > data, which is an oddity. > > Reviewed-by: Rob Herring (Arm) <robh@xxxxxxxxxx> > Acked-by: Alyssa Rosenzweig <alyssa@xxxxxxxxxxxxx> > Tested-by: Janne Grunau <j@xxxxxxxxxx> > Signed-off-by: Marc Zyngier <maz@xxxxxxxxxx> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@xxxxxxxxxx> - Mani > --- > drivers/pci/controller/pci-host-common.c | 24 ++++++++++++++++-------- > include/linux/pci-ecam.h | 2 ++ > 2 files changed, 18 insertions(+), 8 deletions(-) > > diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c > index f441bfd6f96a8..466a1e6a7ffcd 100644 > --- a/drivers/pci/controller/pci-host-common.c > +++ b/drivers/pci/controller/pci-host-common.c > @@ -49,23 +49,17 @@ static struct pci_config_window *gen_pci_init(struct device *dev, > return cfg; > } > > -int pci_host_common_probe(struct platform_device *pdev) > +int pci_host_common_init(struct platform_device *pdev, > + const struct pci_ecam_ops *ops) > { > struct device *dev = &pdev->dev; > struct pci_host_bridge *bridge; > struct pci_config_window *cfg; > - const struct pci_ecam_ops *ops; > - > - ops = of_device_get_match_data(&pdev->dev); > - if (!ops) > - return -ENODEV; > > bridge = devm_pci_alloc_host_bridge(dev, 0); > if (!bridge) > return -ENOMEM; > > - platform_set_drvdata(pdev, bridge); > - > of_pci_check_probe_only(); > > /* Parse and map our Configuration Space windows */ > @@ -73,6 +67,8 @@ int pci_host_common_probe(struct platform_device *pdev) > if (IS_ERR(cfg)) > return PTR_ERR(cfg); > > + platform_set_drvdata(pdev, bridge); > + > bridge->sysdata = cfg; > bridge->ops = (struct pci_ops *)&ops->pci_ops; > bridge->enable_device = ops->enable_device; > @@ -81,6 +77,18 @@ int pci_host_common_probe(struct platform_device *pdev) > > return pci_host_probe(bridge); > } > +EXPORT_SYMBOL_GPL(pci_host_common_init); > + > +int pci_host_common_probe(struct platform_device *pdev) > +{ > + const struct pci_ecam_ops *ops; > + > + ops = of_device_get_match_data(&pdev->dev); > + if (!ops) > + return -ENODEV; > + > + return pci_host_common_init(pdev, ops); > +} > EXPORT_SYMBOL_GPL(pci_host_common_probe); > > void pci_host_common_remove(struct platform_device *pdev) > diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h > index 3a10f8cfc3ad5..bc2ca2c72ee23 100644 > --- a/include/linux/pci-ecam.h > +++ b/include/linux/pci-ecam.h > @@ -97,6 +97,8 @@ extern const struct pci_ecam_ops loongson_pci_ecam_ops; /* Loongson PCIe */ > #if IS_ENABLED(CONFIG_PCI_HOST_COMMON) > /* for DT-based PCI controllers that support ECAM */ > int pci_host_common_probe(struct platform_device *pdev); > +int pci_host_common_init(struct platform_device *pdev, > + const struct pci_ecam_ops *ops); > void pci_host_common_remove(struct platform_device *pdev); > #endif > #endif > -- > 2.39.2 > -- மணிவண்ணன் சதாசிவம்