Skip to content

Commit

Permalink
PCI: apple: Add tracking of probed root ports
Browse files Browse the repository at this point in the history
The apple driver relies on being able to directly find the matching root
port structure from the platform device that represents this port.

A previous hack stashed a pointer to the root port structure in the config
window private pointer, but that ended up relying on assumptions that break
other drivers.

Instead, bite the bullet and track the association as part of the driver
itself as a list of probed root ports.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://patch.msgid.link/20250625111806.4153773-3-maz@kernel.org
  • Loading branch information
Marc Zyngier authored and Bjorn Helgaas committed Jun 30, 2025
1 parent 19272b3 commit 643c0c9
Showing 1 changed file with 49 additions and 4 deletions.
53 changes: 49 additions & 4 deletions drivers/pci/controller/pcie-apple.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ 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;
Expand All @@ -205,6 +206,9 @@ 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);
Expand Down Expand Up @@ -720,13 +724,45 @@ 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;
}

static struct apple_pcie_port *apple_pcie_get_port(struct pci_dev *pdev)
{
struct pci_config_window *cfg = pdev->sysdata;
struct apple_pcie *pcie = cfg->priv;
struct apple_pcie *pcie;
struct pci_dev *port_pdev;
struct apple_pcie_port *port;

pcie = apple_pcie_lookup(cfg->parent);
if (WARN_ON(!pcie))
return NULL;

/* Find the root port this device is on */
port_pdev = pcie_find_root_port(pdev);

Expand Down Expand Up @@ -806,10 +842,14 @@ static void apple_pcie_disable_device(struct pci_host_bridge *bridge, struct pci

static int apple_pcie_init(struct pci_config_window *cfg)
{
struct apple_pcie *pcie = cfg->priv;
struct device *dev = cfg->parent;
struct apple_pcie *pcie;
int ret;

pcie = apple_pcie_lookup(dev);
if (WARN_ON(!pcie))
return -ENOENT;

for_each_available_child_of_node_scoped(dev->of_node, of_port) {
ret = apple_pcie_setup_port(pcie, of_port);
if (ret) {
Expand Down Expand Up @@ -852,13 +892,18 @@ static int apple_pcie_probe(struct platform_device *pdev)

mutex_init(&pcie->lock);
INIT_LIST_HEAD(&pcie->ports);
dev_set_drvdata(dev, pcie);

ret = apple_msi_init(pcie);
if (ret)
return ret;

return pci_host_common_init(pdev, &apple_pcie_cfg_ecam_ops);
apple_pcie_register(pcie);

ret = pci_host_common_init(pdev, &apple_pcie_cfg_ecam_ops);
if (ret)
apple_pcie_unregister(pcie);

return ret;
}

static const struct of_device_id apple_pcie_of_match[] = {
Expand Down

0 comments on commit 643c0c9

Please sign in to comment.