]> Gentwo Git Trees - linux/.git/commitdiff
PCI: host-generic: Move bridge allocation outside of pci_host_common_init()
authorMarc Zyngier <maz@kernel.org>
Tue, 25 Nov 2025 10:27:26 +0000 (10:27 +0000)
committerManivannan Sadhasivam <mani@kernel.org>
Tue, 25 Nov 2025 14:09:42 +0000 (19:39 +0530)
Having the host bridge allocation inside pci_host_common_init() results
in a lot of complexity in the pcie-apple driver (the only direct user
of this function outside of core PCI code).

It forces the allocation of driver-specific tracking structures outside
of the bridge allocation, which in turn requires it to use inefficient
data structures to match the bridge and the private structure as needed.

Instead, let the bridge structure be passed to pci_host_common_init(),
allowing the driver to allocate it together with the private data,
as it is usually intended. The driver can then retrieve the bridge
via the owning device attached to the PCI config window structure.
This allows the pcie-apple driver to be significantly simplified.

Both core and driver code are changed in one go to avoid going via
a transitional interface.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
Reviewed-by: Radu Rendec <rrendec@redhat.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Manivannan Sadhasivam <mani@kernel.org>
Cc: Rob Herring <robh@kernel.org>
Cc: Krzysztof WilczyƄski <kwilczynski@kernel.org>
Cc: Lorenzo Pieralisi <lpieralisi@kernel.org>
Link: https://lore.kernel.org/r/86jyzms036.wl-maz@kernel.org
Link: https://patch.msgid.link/20251125102726.865617-1-maz@kernel.org
drivers/pci/controller/pci-host-common.c
drivers/pci/controller/pci-host-common.h
drivers/pci/controller/pcie-apple.c

index 810d1c8de24e93081a9f07137359c32ed1d2db94..c473e7c03bacad2de07c798768f99652443431e0 100644 (file)
@@ -53,16 +53,12 @@ struct pci_config_window *pci_host_common_ecam_create(struct device *dev,
 EXPORT_SYMBOL_GPL(pci_host_common_ecam_create);
 
 int pci_host_common_init(struct platform_device *pdev,
+                        struct pci_host_bridge *bridge,
                         const struct pci_ecam_ops *ops)
 {
        struct device *dev = &pdev->dev;
-       struct pci_host_bridge *bridge;
        struct pci_config_window *cfg;
 
-       bridge = devm_pci_alloc_host_bridge(dev, 0);
-       if (!bridge)
-               return -ENOMEM;
-
        of_pci_check_probe_only();
 
        platform_set_drvdata(pdev, bridge);
@@ -85,12 +81,17 @@ EXPORT_SYMBOL_GPL(pci_host_common_init);
 int pci_host_common_probe(struct platform_device *pdev)
 {
        const struct pci_ecam_ops *ops;
+       struct pci_host_bridge *bridge;
 
        ops = of_device_get_match_data(&pdev->dev);
        if (!ops)
                return -ENODEV;
 
-       return pci_host_common_init(pdev, ops);
+       bridge = devm_pci_alloc_host_bridge(&pdev->dev, 0);
+       if (!bridge)
+               return -ENOMEM;
+
+       return pci_host_common_init(pdev, bridge, ops);
 }
 EXPORT_SYMBOL_GPL(pci_host_common_probe);
 
index 51c35ec0cf37df4c149cd848038284f38e6abfb0..b5075d4bd7eb31fbf1dc946ef1a6afd5afb5b3c6 100644 (file)
@@ -14,6 +14,7 @@ struct pci_ecam_ops;
 
 int pci_host_common_probe(struct platform_device *pdev);
 int pci_host_common_init(struct platform_device *pdev,
+                        struct pci_host_bridge *bridge,
                         const struct pci_ecam_ops *ops);
 void pci_host_common_remove(struct platform_device *pdev);
 
index 0380d300adca6f32752fcc274bdaa70f21ac420c..2d92fc79f6ddfa36e561ac0c109feec9eac7bee5 100644 (file)
@@ -187,7 +187,6 @@ struct apple_pcie {
        const struct hw_info    *hw;
        unsigned long           *bitmap;
        struct list_head        ports;
-       struct list_head        entry;
        struct completion       event;
        struct irq_fwspec       fwspec;
        u32                     nvecs;
@@ -206,9 +205,6 @@ struct apple_pcie_port {
        int                     idx;
 };
 
-static LIST_HEAD(pcie_list);
-static DEFINE_MUTEX(pcie_list_lock);
-
 static void rmw_set(u32 set, void __iomem *addr)
 {
        writel_relaxed(readl_relaxed(addr) | set, addr);
@@ -724,32 +720,9 @@ static int apple_msi_init(struct apple_pcie *pcie)
        return 0;
 }
 
-static void apple_pcie_register(struct apple_pcie *pcie)
-{
-       guard(mutex)(&pcie_list_lock);
-
-       list_add_tail(&pcie->entry, &pcie_list);
-}
-
-static void apple_pcie_unregister(struct apple_pcie *pcie)
-{
-       guard(mutex)(&pcie_list_lock);
-
-       list_del(&pcie->entry);
-}
-
 static struct apple_pcie *apple_pcie_lookup(struct device *dev)
 {
-       struct apple_pcie *pcie;
-
-       guard(mutex)(&pcie_list_lock);
-
-       list_for_each_entry(pcie, &pcie_list, entry) {
-               if (pcie->dev == dev)
-                       return pcie;
-       }
-
-       return NULL;
+       return pci_host_bridge_priv(dev_get_drvdata(dev));
 }
 
 static struct apple_pcie_port *apple_pcie_get_port(struct pci_dev *pdev)
@@ -875,13 +848,15 @@ static const struct pci_ecam_ops apple_pcie_cfg_ecam_ops = {
 static int apple_pcie_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
+       struct pci_host_bridge *bridge;
        struct apple_pcie *pcie;
        int ret;
 
-       pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
-       if (!pcie)
+       bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
+       if (!bridge)
                return -ENOMEM;
 
+       pcie = pci_host_bridge_priv(bridge);
        pcie->dev = dev;
        pcie->hw = of_device_get_match_data(dev);
        if (!pcie->hw)
@@ -897,13 +872,7 @@ static int apple_pcie_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
-       apple_pcie_register(pcie);
-
-       ret = pci_host_common_init(pdev, &apple_pcie_cfg_ecam_ops);
-       if (ret)
-               apple_pcie_unregister(pcie);
-
-       return ret;
+       return pci_host_common_init(pdev, bridge, &apple_pcie_cfg_ecam_ops);
 }
 
 static const struct of_device_id apple_pcie_of_match[] = {