[PATCH v4 1/6] PCI: spacemit-k1: Add device data support
Inochi Amaoto <[email protected]> Thu, 9 Jul 2026 12:00:21 +0800
| Newsgroups | dev.linux.lists.spacemit,org.infradead.lists.linux-riscv,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pci |
|---|---|
| Message-ID | <[email protected]> |
To reuse the K1 PCIe driver logic for K3 PCIe controller, add device data to handle the K1 specific logic and make room for the incoming logic for K3. Signed-off-by: Inochi Amaoto <[email protected]> --- drivers/pci/controller/dwc/pcie-spacemit-k1.c | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-spacemit-k1.c b/drivers/pci/controller/dwc/pcie-spacemit-k1.c index be20a520255b..f6ae8ff3589a 100644 --- a/drivers/pci/controller/dwc/pcie-spacemit-k1.c +++ b/drivers/pci/controller/dwc/pcie-spacemit-k1.c @@ -49,8 +49,17 @@ #define PCIE_CONTROL_LOGIC 0x0004 #define PCIE_SOFT_RESET BIT(0) +struct k1_pcie; + +struct k1_pcie_device_data { + const struct dw_pcie_host_ops *host_ops; + const struct dw_pcie_ops *ops; + int (*parse_port)(struct k1_pcie *k1); +}; + struct k1_pcie { struct dw_pcie pci; + const struct k1_pcie_device_data *data; struct phy *phy; void __iomem *link; struct regmap *pmu; /* Errors ignored; MMIO-backed regmap */ @@ -278,14 +287,21 @@ static int k1_pcie_parse_port(struct k1_pcie *k1) static int k1_pcie_probe(struct platform_device *pdev) { + const struct k1_pcie_device_data *data; struct device *dev = &pdev->dev; struct k1_pcie *k1; int ret; + data = device_get_match_data(dev); + if (!data) + return -ENODEV; + k1 = devm_kzalloc(dev, sizeof(*k1), GFP_KERNEL); if (!k1) return -ENOMEM; + k1->data = data; + k1->pmu = syscon_regmap_lookup_by_phandle_args(dev_of_node(dev), SYSCON_APMU, 1, &k1->pmu_off); @@ -299,11 +315,11 @@ static int k1_pcie_probe(struct platform_device *pdev) "failed to map \"link\" registers\n"); k1->pci.dev = dev; - k1->pci.ops = &k1_pcie_ops; + k1->pci.ops = data->ops; k1->pci.pp.num_vectors = MAX_MSI_IRQS; dw_pcie_cap_set(&k1->pci, REQ_RES); - k1->pci.pp.ops = &k1_pcie_host_ops; + k1->pci.pp.ops = data->host_ops; /* Hold the PHY in reset until we start the link */ regmap_set_bits(k1->pmu, k1->pmu_off + PCIE_CLK_RESET_CONTROL, @@ -320,7 +336,7 @@ static int k1_pcie_probe(struct platform_device *pdev) platform_set_drvdata(pdev, k1); - ret = k1_pcie_parse_port(k1); + ret = data->parse_port(k1); if (ret) return dev_err_probe(dev, ret, "failed to parse root port\n"); @@ -338,8 +354,14 @@ static void k1_pcie_remove(struct platform_device *pdev) dw_pcie_host_deinit(&k1->pci.pp); } +static const struct k1_pcie_device_data k1_pcie_device_data = { + .host_ops = &k1_pcie_host_ops, + .ops = &k1_pcie_ops, + .parse_port = k1_pcie_parse_port, +}; + static const struct of_device_id k1_pcie_of_match_table[] = { - { .compatible = "spacemit,k1-pcie", }, + { .compatible = "spacemit,k1-pcie", .data = &k1_pcie_device_data}, { } }; -- 2.55.0