From 03e00e373cab981ad808271b2650700cfa0fbda6 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sun, 6 Apr 2025 14:49:20 -0400 Subject: [PATCH 01/16] tools/power turbostat: v2025.05.06 Support up to 8192 processors Add cpuidle governor debug telemetry, disabled by default Update default output to exclude cpuidle invocation counts Bug fixes Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index ab184f95cdaf..1b9fdc1a7ee8 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -9594,7 +9594,7 @@ int get_and_dump_counters(void) void print_version() { - fprintf(outf, "turbostat version 2025.02.02 - Len Brown \n"); + fprintf(outf, "turbostat version 2025.04.06 - Len Brown \n"); } #define COMMAND_LINE_SIZE 2048 -- 2.51.0 From 0efdedb3358aa78102967f242379686f94315830 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Thomas=20Wei=C3=9Fschuh?= Date: Wed, 2 Apr 2025 21:21:57 +0100 Subject: [PATCH 02/16] tools/include: make uapi/linux/types.h usable from assembly MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The "real" linux/types.h UAPI header gracefully degrades to a NOOP when included from assembly code. Mirror this behaviour in the tools/ variant. Test for __ASSEMBLER__ over __ASSEMBLY__ as the former is provided by the toolchain automatically. Reported-by: Mark Brown Closes: https://lore.kernel.org/lkml/af553c62-ca2f-4956-932c-dd6e3a126f58@sirena.org.uk/ Fixes: c9fbaa879508 ("selftests: vDSO: parse_vdso: Use UAPI headers instead of libc headers") Signed-off-by: Thomas Weißschuh Link: https://patch.msgid.link/20250321-uapi-consistency-v1-1-439070118dc0@linutronix.de Signed-off-by: Mark Brown Reviewed-by: Mark Brown Signed-off-by: Linus Torvalds --- tools/include/uapi/linux/types.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/include/uapi/linux/types.h b/tools/include/uapi/linux/types.h index 91fa51a9c31d..85aa327245c6 100644 --- a/tools/include/uapi/linux/types.h +++ b/tools/include/uapi/linux/types.h @@ -4,6 +4,8 @@ #include +#ifndef __ASSEMBLER__ + /* copied from linux:include/uapi/linux/types.h */ #define __bitwise typedef __u16 __bitwise __le16; @@ -20,4 +22,5 @@ typedef __u32 __bitwise __wsum; #define __aligned_be64 __be64 __attribute__((aligned(8))) #define __aligned_le64 __le64 __attribute__((aligned(8))) +#endif /* __ASSEMBLER__ */ #endif /* _UAPI_LINUX_TYPES_H */ -- 2.51.0 From 0af2f6be1b4281385b618cb86ad946eded089ac8 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 6 Apr 2025 13:11:33 -0700 Subject: [PATCH 03/16] Linux 6.15-rc1 --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index e55726a71d95..38689a0c3605 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 6 -PATCHLEVEL = 14 +PATCHLEVEL = 15 SUBLEVEL = 0 -EXTRAVERSION = +EXTRAVERSION = -rc1 NAME = Baby Opossum Posse # *DOCUMENTATION* -- 2.51.0 From 751bec089c4eed486578994abd2c5395f08d0302 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Tue, 1 Apr 2025 10:17:01 +0100 Subject: [PATCH 04/16] PCI: apple: Set only available ports up Iterating over disabled ports results in of_irq_parse_raw() parsing the wrong "interrupt-map" entries, as it takes the status of the node into account. This became apparent after disabling unused PCIe ports in the Apple Silicon device trees instead of deleting them. Switching from for_each_child_of_node_scoped() to for_each_available_child_of_node_scoped() solves this issue. Fixes: 1e33888fbe44 ("PCI: apple: Add initial hardware bring-up") Fixes: a0189fdfb73d ("arm64: dts: apple: t8103: Disable unused PCIe ports") Signed-off-by: Janne Grunau Signed-off-by: Alyssa Rosenzweig Signed-off-by: Marc Zyngier Signed-off-by: Manivannan Sadhasivam Tested-by: Janne Grunau Reviewed-by: Rob Herring (Arm) Reviewed-by: Manivannan Sadhasivam Acked-by: Alyssa Rosenzweig Cc: stable@vger.kernel.org Link: https://lore.kernel.org/asahi/20230214-apple_dts_pcie_disable_unused-v1-0-5ea0d3ddcde3@jannau.net/ Link: https://lore.kernel.org/asahi/1ea2107a-bb86-8c22-0bbc-82c453ab08ce@linaro.org/ Link: https://patch.msgid.link/20250401091713.2765724-2-maz@kernel.org --- drivers/pci/controller/pcie-apple.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c index 18e11b9a7f46..996cef8a2e17 100644 --- a/drivers/pci/controller/pcie-apple.c +++ b/drivers/pci/controller/pcie-apple.c @@ -754,7 +754,7 @@ static int apple_pcie_init(struct pci_config_window *cfg) if (ret) return ret; - for_each_child_of_node_scoped(dev->of_node, of_port) { + for_each_available_child_of_node_scoped(dev->of_node, of_port) { ret = apple_pcie_setup_port(pcie, of_port); if (ret) { dev_err(pcie->dev, "Port %pOF setup fail: %d\n", of_port, ret); -- 2.51.0 From 6b7f49be74758a60b760d6c19a48f65a23511dbe Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Tue, 1 Apr 2025 10:17:02 +0100 Subject: [PATCH 05/16] dt-bindings: pci: apple,pcie: Add t6020 compatible string t6020 adds some register ranges compared to t8103, so requires a new compatible as well as the new PHY registers. Thanks to Mark and Rob for their helpful suggestions in updating the binding. Suggested-by: Mark Kettenis Suggested-by: Rob Herring Signed-off-by: Alyssa Rosenzweig [maz: added PHY registers, constraints] Signed-off-by: Marc Zyngier Signed-off-by: Manivannan Sadhasivam Tested-by: Janne Grunau Reviewed-by: Rob Herring (Arm) Acked-by: Manivannan Sadhasivam Acked-by: Alyssa Rosenzweig Link: https://patch.msgid.link/20250401091713.2765724-3-maz@kernel.org --- .../devicetree/bindings/pci/apple,pcie.yaml | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/Documentation/devicetree/bindings/pci/apple,pcie.yaml b/Documentation/devicetree/bindings/pci/apple,pcie.yaml index c8775f9cb071..c0852be04f6d 100644 --- a/Documentation/devicetree/bindings/pci/apple,pcie.yaml +++ b/Documentation/devicetree/bindings/pci/apple,pcie.yaml @@ -17,6 +17,10 @@ description: | implements its root ports. But the ATU found on most DesignWare PCIe host bridges is absent. + On systems derived from T602x, the PHY registers are in a region + separate from the port registers. In that case, there is one PHY + register range per port register range. + All root ports share a single ECAM space, but separate GPIOs are used to take the PCI devices on those ports out of reset. Therefore the standard "reset-gpios" and "max-link-speed" properties appear on @@ -30,16 +34,18 @@ description: | properties: compatible: - items: - - enum: - - apple,t8103-pcie - - apple,t8112-pcie - - apple,t6000-pcie - - const: apple,pcie + oneOf: + - items: + - enum: + - apple,t8103-pcie + - apple,t8112-pcie + - apple,t6000-pcie + - const: apple,pcie + - const: apple,t6020-pcie reg: minItems: 3 - maxItems: 6 + maxItems: 10 reg-names: minItems: 3 @@ -50,6 +56,10 @@ properties: - const: port1 - const: port2 - const: port3 + - const: phy0 + - const: phy1 + - const: phy2 + - const: phy3 ranges: minItems: 2 @@ -98,6 +108,15 @@ allOf: maxItems: 5 interrupts: maxItems: 3 + - if: + properties: + compatible: + contains: + const: apple,t6020-pcie + then: + properties: + reg-names: + minItems: 10 examples: - | -- 2.51.0 From afc0a570bb6138713d74784a032e4eb5b7f919ca Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 1 Apr 2025 10:17:03 +0100 Subject: [PATCH 06/16] PCI: host-generic: Extract an ECAM bridge creation helper from pci_host_common_probe() pci_host_common_probe() is an extremely useful 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. Signed-off-by: Marc Zyngier [mani: fixed spelling mistakes] Signed-off-by: Manivannan Sadhasivam Tested-by: Janne Grunau Reviewed-by: Rob Herring (Arm) Reviewed-by: Manivannan Sadhasivam Acked-by: Alyssa Rosenzweig Link: https://patch.msgid.link/20250401091713.2765724-4-maz@kernel.org --- 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 f441bfd6f96a..466a1e6a7ffc 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 3a10f8cfc3ad..bc2ca2c72ee2 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.51.0 From 4900454b4f819e88e9c57ed93542bf9325d7e161 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 1 Apr 2025 10:17:04 +0100 Subject: [PATCH 07/16] PCI: ecam: Allow cfg->priv to be pre-populated from the root port device In order to decouple ecam config space creation from probing via pci_host_common_probe(), allow the private pointer to be populated via the device drvdata pointer. Crucially, this is set before calling ops->init(), allowing that particular callback to have access to probe data. This should have no impact on existing code which ignores the current value of cfg->priv. Signed-off-by: Marc Zyngier Signed-off-by: Manivannan Sadhasivam Tested-by: Janne Grunau Reviewed-by: Rob Herring (Arm) Reviewed-by: Manivannan Sadhasivam Acked-by: Alyssa Rosenzweig Link: https://patch.msgid.link/20250401091713.2765724-5-maz@kernel.org --- drivers/pci/ecam.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c index 260b7de2dbd5..2c5e6446e00e 100644 --- a/drivers/pci/ecam.c +++ b/drivers/pci/ecam.c @@ -84,6 +84,8 @@ struct pci_config_window *pci_ecam_create(struct device *dev, goto err_exit_iomap; } + cfg->priv = dev_get_drvdata(dev); + if (ops->init) { err = ops->init(cfg); if (err) -- 2.51.0 From 4785591f96c76534d9ccb7ec515ab4bc407f3191 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 1 Apr 2025 10:17:05 +0100 Subject: [PATCH 08/16] PCI: apple: Move over to standalone probing Now that we have the required infrastructure, split the Apple PCIe setup into two categories: - stuff that has to do with PCI setup stays in the .init() callback - stuff that is just driver gunk (such as MSI setup) goes into a probe routine, which will eventually call into the host-common code The result is a far more logical setup process. Signed-off-by: Marc Zyngier Signed-off-by: Manivannan Sadhasivam Tested-by: Janne Grunau Reviewed-by: Rob Herring (Arm) Reviewed-by: Manivannan Sadhasivam Acked-by: Alyssa Rosenzweig Link: https://patch.msgid.link/20250401091713.2765724-6-maz@kernel.org --- drivers/pci/controller/pcie-apple.c | 54 ++++++++++++++++------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c index 996cef8a2e17..6d7a95ab8b14 100644 --- a/drivers/pci/controller/pcie-apple.c +++ b/drivers/pci/controller/pcie-apple.c @@ -730,34 +730,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 platform_device *platform = to_platform_device(dev); - struct apple_pcie *pcie; int ret; - pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); - if (!pcie) - return -ENOMEM; - - pcie->dev = dev; - - mutex_init(&pcie->lock); - - pcie->base = devm_platform_ioremap_resource(platform, 1); - if (IS_ERR(pcie->base)) - return PTR_ERR(pcie->base); - - cfg->priv = pcie; - INIT_LIST_HEAD(&pcie->ports); - - ret = apple_msi_init(pcie); - if (ret) - return ret; - for_each_available_child_of_node_scoped(dev->of_node, of_port) { ret = apple_pcie_setup_port(pcie, of_port); if (ret) { - dev_err(pcie->dev, "Port %pOF setup fail: %d\n", of_port, ret); + dev_err(dev, "Port %pOF setup fail: %d\n", of_port, ret); return ret; } } @@ -776,14 +756,40 @@ 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 apple_pcie *pcie; + int ret; + + pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); + if (!pcie) + return -ENOMEM; + + pcie->dev = dev; + pcie->base = devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(pcie->base)) + return PTR_ERR(pcie->base); + + 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); +} + static const struct of_device_id apple_pcie_of_match[] = { - { .compatible = "apple,pcie", .data = &apple_pcie_cfg_ecam_ops }, + { .compatible = "apple,pcie" }, { } }; MODULE_DEVICE_TABLE(of, apple_pcie_of_match); static struct platform_driver apple_pcie_driver = { - .probe = pci_host_common_probe, + .probe = apple_pcie_probe, .driver = { .name = "pcie-apple", .of_match_table = apple_pcie_of_match, -- 2.51.0 From ed982862ce980c578c8c80917a69c8fa1c504b85 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 1 Apr 2025 10:17:06 +0100 Subject: [PATCH 09/16] PCI: apple: Dynamically allocate RID-to_SID bitmap As we move towards supporting SoCs with varying RID-to-SID mapping capabilities, turn the static SID tracking bitmap into a dynamically allocated one. The current allocation size is still the same, but that's about to change. Signed-off-by: Marc Zyngier Signed-off-by: Manivannan Sadhasivam Reviewed-by: Rob Herring (Arm) Tested-by: Janne Grunau Reviewed-by: Manivannan Sadhasivam Acked-by: Alyssa Rosenzweig Link: https://patch.msgid.link/20250401091713.2765724-7-maz@kernel.org --- drivers/pci/controller/pcie-apple.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c index 6d7a95ab8b14..8ac21d46c031 100644 --- a/drivers/pci/controller/pcie-apple.c +++ b/drivers/pci/controller/pcie-apple.c @@ -147,7 +147,7 @@ struct apple_pcie_port { void __iomem *base; struct irq_domain *domain; struct list_head entry; - DECLARE_BITMAP(sid_map, MAX_RID2SID); + unsigned long *sid_map; int sid_map_sz; int idx; }; @@ -524,6 +524,10 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie, if (!port) return -ENOMEM; + port->sid_map = devm_bitmap_zalloc(pcie->dev, MAX_RID2SID, GFP_KERNEL); + if (!port->sid_map) + return -ENOMEM; + ret = of_property_read_u32_index(np, "reg", 0, &idx); if (ret) return ret; -- 2.51.0 From 0411c90eee6fc97b30d3f5767e9cb82d4594faa1 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 1 Apr 2025 10:17:07 +0100 Subject: [PATCH 10/16] PCI: apple: Move away from INTMSK{SET,CLR} for INTx and private interrupts T602x seems to have dropped the rather useful SET/CLR accessors to the masking register. Instead, let's use the mask register directly, and wrap it with a brand new spinlock. No, this isn't moving in the right direction. Signed-off-by: Marc Zyngier Signed-off-by: Manivannan Sadhasivam Tested-by: Janne Grunau Reviewed-by: Rob Herring (Arm) Reviewed-by: Manivannan Sadhasivam Acked-by: Alyssa Rosenzweig Link: https://patch.msgid.link/20250401091713.2765724-8-maz@kernel.org --- drivers/pci/controller/pcie-apple.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c index 8ac21d46c031..152a65db3ff0 100644 --- a/drivers/pci/controller/pcie-apple.c +++ b/drivers/pci/controller/pcie-apple.c @@ -142,6 +142,7 @@ struct apple_pcie { }; struct apple_pcie_port { + raw_spinlock_t lock; struct apple_pcie *pcie; struct device_node *np; void __iomem *base; @@ -261,14 +262,16 @@ static void apple_port_irq_mask(struct irq_data *data) { struct apple_pcie_port *port = irq_data_get_irq_chip_data(data); - writel_relaxed(BIT(data->hwirq), port->base + PORT_INTMSKSET); + guard(raw_spinlock_irqsave)(&port->lock); + rmw_set(BIT(data->hwirq), port->base + PORT_INTMSK); } static void apple_port_irq_unmask(struct irq_data *data) { struct apple_pcie_port *port = irq_data_get_irq_chip_data(data); - writel_relaxed(BIT(data->hwirq), port->base + PORT_INTMSKCLR); + guard(raw_spinlock_irqsave)(&port->lock); + rmw_clear(BIT(data->hwirq), port->base + PORT_INTMSK); } static bool hwirq_is_intx(unsigned int hwirq) @@ -387,7 +390,7 @@ static int apple_pcie_port_setup_irq(struct apple_pcie_port *port) return -ENOMEM; /* Disable all interrupts */ - writel_relaxed(~0, port->base + PORT_INTMSKSET); + writel_relaxed(~0, port->base + PORT_INTMSK); writel_relaxed(~0, port->base + PORT_INTSTAT); irq_set_chained_handler_and_data(irq, apple_port_irq_handler, port); @@ -537,6 +540,8 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie, port->pcie = pcie; port->np = np; + raw_spin_lock_init(&port->lock); + port->base = devm_platform_ioremap_resource(platform, port->idx + 2); if (IS_ERR(port->base)) return PTR_ERR(port->base); -- 2.51.0 From 7fa9fbf39116b061f8a41cd84f1884c545f322c4 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Tue, 1 Apr 2025 10:17:08 +0100 Subject: [PATCH 11/16] PCI: apple: Fix missing OF node reference in apple_pcie_setup_port In the success path, we hang onto a reference to the node, so make sure to grab one. The caller iterator puts our borrowed reference when we return. Signed-off-by: Hector Martin Signed-off-by: Alyssa Rosenzweig Signed-off-by: Marc Zyngier Signed-off-by: Manivannan Sadhasivam Tested-by: Janne Grunau Reviewed-by: Rob Herring (Arm) Reviewed-by: Manivannan Sadhasivam Acked-by: Alyssa Rosenzweig Link: https://patch.msgid.link/20250401091713.2765724-9-maz@kernel.org --- drivers/pci/controller/pcie-apple.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c index 152a65db3ff0..cd02aa93a5c4 100644 --- a/drivers/pci/controller/pcie-apple.c +++ b/drivers/pci/controller/pcie-apple.c @@ -593,6 +593,9 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie, list_add_tail(&port->entry, &pcie->ports); init_completion(&pcie->event); + /* In the success path, we keep a reference to np around */ + of_node_get(np); + ret = apple_pcie_port_register_irqs(port); WARN_ON(ret); -- 2.51.0 From 80b31fbbcac4e4799fde34992b07d4f0692cfbb8 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Tue, 1 Apr 2025 10:17:09 +0100 Subject: [PATCH 12/16] PCI: apple: Move port PHY registers to their own reg items T602x PCIe cores move these registers around. Instead of hardcoding in another offset, let's move them into their own reg entries. This matches what Apple does on macOS device trees too. Maintains backwards compatibility with old DTs by using the old offsets. Note that we open code devm_platform_ioremap_resource_byname() to avoid error messages on older platforms with missing resources in the pcie node. ("pcie-apple 590000000.pcie: invalid resource (null)" on probe) Co-developed-by: Janne Grunau Signed-off-by: Janne Grunau Signed-off-by: Hector Martin Signed-off-by: Alyssa Rosenzweig Signed-off-by: Marc Zyngier Signed-off-by: Manivannan Sadhasivam Tested-by: Janne Grunau Reviewed-by: Rob Herring (Arm) Reviewed-by: Manivannan Sadhasivam Acked-by: Alyssa Rosenzweig Link: https://patch.msgid.link/20250401091713.2765724-10-maz@kernel.org --- drivers/pci/controller/pcie-apple.c | 55 +++++++++++++++++++---------- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c index cd02aa93a5c4..b8d9b07f35b5 100644 --- a/drivers/pci/controller/pcie-apple.c +++ b/drivers/pci/controller/pcie-apple.c @@ -39,14 +39,18 @@ #define CORE_RC_STAT_READY BIT(0) #define CORE_FABRIC_STAT 0x04000 #define CORE_FABRIC_STAT_MASK 0x001F001F -#define CORE_LANE_CFG(port) (0x84000 + 0x4000 * (port)) -#define CORE_LANE_CFG_REFCLK0REQ BIT(0) -#define CORE_LANE_CFG_REFCLK1REQ BIT(1) -#define CORE_LANE_CFG_REFCLK0ACK BIT(2) -#define CORE_LANE_CFG_REFCLK1ACK BIT(3) -#define CORE_LANE_CFG_REFCLKEN (BIT(9) | BIT(10)) -#define CORE_LANE_CTL(port) (0x84004 + 0x4000 * (port)) -#define CORE_LANE_CTL_CFGACC BIT(15) + +#define CORE_PHY_DEFAULT_BASE(port) (0x84000 + 0x4000 * (port)) + +#define PHY_LANE_CFG 0x00000 +#define PHY_LANE_CFG_REFCLK0REQ BIT(0) +#define PHY_LANE_CFG_REFCLK1REQ BIT(1) +#define PHY_LANE_CFG_REFCLK0ACK BIT(2) +#define PHY_LANE_CFG_REFCLK1ACK BIT(3) +#define PHY_LANE_CFG_REFCLKEN (BIT(9) | BIT(10)) +#define PHY_LANE_CFG_REFCLKCGEN (BIT(30) | BIT(31)) +#define PHY_LANE_CTL 0x00004 +#define PHY_LANE_CTL_CFGACC BIT(15) #define PORT_LTSSMCTL 0x00080 #define PORT_LTSSMCTL_START BIT(0) @@ -146,6 +150,7 @@ struct apple_pcie_port { struct apple_pcie *pcie; struct device_node *np; void __iomem *base; + void __iomem *phy; struct irq_domain *domain; struct list_head entry; unsigned long *sid_map; @@ -476,26 +481,26 @@ static int apple_pcie_setup_refclk(struct apple_pcie *pcie, if (res < 0) return res; - rmw_set(CORE_LANE_CTL_CFGACC, pcie->base + CORE_LANE_CTL(port->idx)); - rmw_set(CORE_LANE_CFG_REFCLK0REQ, pcie->base + CORE_LANE_CFG(port->idx)); + rmw_set(PHY_LANE_CTL_CFGACC, port->phy + PHY_LANE_CTL); + rmw_set(PHY_LANE_CFG_REFCLK0REQ, port->phy + PHY_LANE_CFG); - res = readl_relaxed_poll_timeout(pcie->base + CORE_LANE_CFG(port->idx), - stat, stat & CORE_LANE_CFG_REFCLK0ACK, + res = readl_relaxed_poll_timeout(port->phy + PHY_LANE_CFG, + stat, stat & PHY_LANE_CFG_REFCLK0ACK, 100, 50000); if (res < 0) return res; - rmw_set(CORE_LANE_CFG_REFCLK1REQ, pcie->base + CORE_LANE_CFG(port->idx)); - res = readl_relaxed_poll_timeout(pcie->base + CORE_LANE_CFG(port->idx), - stat, stat & CORE_LANE_CFG_REFCLK1ACK, + rmw_set(PHY_LANE_CFG_REFCLK1REQ, port->phy + PHY_LANE_CFG); + res = readl_relaxed_poll_timeout(port->phy + PHY_LANE_CFG, + stat, stat & PHY_LANE_CFG_REFCLK1ACK, 100, 50000); if (res < 0) return res; - rmw_clear(CORE_LANE_CTL_CFGACC, pcie->base + CORE_LANE_CTL(port->idx)); + rmw_clear(PHY_LANE_CTL_CFGACC, port->phy + PHY_LANE_CTL); - rmw_set(CORE_LANE_CFG_REFCLKEN, pcie->base + CORE_LANE_CFG(port->idx)); + rmw_set(PHY_LANE_CFG_REFCLKEN, port->phy + PHY_LANE_CFG); rmw_set(PORT_REFCLK_EN, port->base + PORT_REFCLK); return 0; @@ -515,6 +520,8 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie, struct platform_device *platform = to_platform_device(pcie->dev); struct apple_pcie_port *port; struct gpio_desc *reset; + struct resource *res; + char name[16]; u32 stat, idx; int ret, i; @@ -542,10 +549,22 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie, raw_spin_lock_init(&port->lock); - port->base = devm_platform_ioremap_resource(platform, port->idx + 2); + snprintf(name, sizeof(name), "port%d", port->idx); + res = platform_get_resource_byname(platform, IORESOURCE_MEM, name); + if (!res) + res = platform_get_resource(platform, IORESOURCE_MEM, port->idx + 2); + + port->base = devm_ioremap_resource(&platform->dev, res); if (IS_ERR(port->base)) return PTR_ERR(port->base); + snprintf(name, sizeof(name), "phy%d", port->idx); + res = platform_get_resource_byname(platform, IORESOURCE_MEM, name); + if (res) + port->phy = devm_ioremap_resource(&platform->dev, res); + else + port->phy = pcie->base + CORE_PHY_DEFAULT_BASE(port->idx); + rmw_set(PORT_APPCLK_EN, port->base + PORT_APPCLK); /* Assert PERST# before setting up the clock */ -- 2.51.0 From de9637c9f7827e0a2420bf1578758614530ac964 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Tue, 1 Apr 2025 10:17:10 +0100 Subject: [PATCH 13/16] PCI: apple: Drop poll for CORE_RC_PHYIF_STAT_REFCLK This is checking a core refclk in per-port setup which doesn't make a lot of sense, and the bootloader needs to have gone through this anyway. It doesn't work on T602x, so just drop it across the board. Signed-off-by: Hector Martin Signed-off-by: Alyssa Rosenzweig Signed-off-by: Marc Zyngier Signed-off-by: Manivannan Sadhasivam Tested-by: Janne Grunau Reviewed-by: Rob Herring (Arm) Reviewed-by: Manivannan Sadhasivam Acked-by: Alyssa Rosenzweig Link: https://patch.msgid.link/20250401091713.2765724-11-maz@kernel.org --- drivers/pci/controller/pcie-apple.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c index b8d9b07f35b5..a3ff225d54ce 100644 --- a/drivers/pci/controller/pcie-apple.c +++ b/drivers/pci/controller/pcie-apple.c @@ -475,12 +475,6 @@ static int apple_pcie_setup_refclk(struct apple_pcie *pcie, u32 stat; int res; - res = readl_relaxed_poll_timeout(pcie->base + CORE_RC_PHYIF_STAT, stat, - stat & CORE_RC_PHYIF_STAT_REFCLK, - 100, 50000); - if (res < 0) - return res; - rmw_set(PHY_LANE_CTL_CFGACC, port->phy + PHY_LANE_CTL); rmw_set(PHY_LANE_CFG_REFCLK0REQ, port->phy + PHY_LANE_CFG); -- 2.51.0 From 7334364f9de79a9a236dd0243ba574b8d2876e89 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Tue, 1 Apr 2025 10:17:11 +0100 Subject: [PATCH 14/16] PCI: apple: Use gpiod_set_value_cansleep in probe flow We're allowed to sleep here, so tell the GPIO core by using gpiod_set_value_cansleep instead of gpiod_set_value. Fixes: 1e33888fbe44 ("PCI: apple: Add initial hardware bring-up") Signed-off-by: Hector Martin Signed-off-by: Alyssa Rosenzweig Signed-off-by: Marc Zyngier Signed-off-by: Manivannan Sadhasivam Tested-by: Janne Grunau Reviewed-by: Rob Herring (Arm) Reviewed-by: Manivannan Sadhasivam Acked-by: Alyssa Rosenzweig Link: https://patch.msgid.link/20250401091713.2765724-12-maz@kernel.org --- drivers/pci/controller/pcie-apple.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c index a3ff225d54ce..eadce67e30c0 100644 --- a/drivers/pci/controller/pcie-apple.c +++ b/drivers/pci/controller/pcie-apple.c @@ -562,7 +562,7 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie, rmw_set(PORT_APPCLK_EN, port->base + PORT_APPCLK); /* Assert PERST# before setting up the clock */ - gpiod_set_value(reset, 1); + gpiod_set_value_cansleep(reset, 1); ret = apple_pcie_setup_refclk(pcie, port); if (ret < 0) @@ -573,7 +573,7 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie, /* Deassert PERST# */ rmw_set(PORT_PERST_OFF, port->base + PORT_PERST); - gpiod_set_value(reset, 0); + gpiod_set_value_cansleep(reset, 0); /* Wait for 100ms after PERST# deassertion (PCIe r5.0, 6.6.1) */ msleep(100); -- 2.51.0 From 3f1ccd6e85d7b57460efb71e73da91fbea48d98a Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Tue, 1 Apr 2025 10:17:12 +0100 Subject: [PATCH 15/16] PCI: apple: Abstract register offsets via a SoC-specific structure Newer versions of the Apple PCIe block have a bunch of small, but annoying differences. In order to embrace this diversity of implementations, move the currently hardcoded offsets into a hw_info structure. Future SoCs will provide their own structure describing the applicable offsets. Signed-off-by: Hector Martin Signed-off-by: Alyssa Rosenzweig [maz: split from original patch to only address T8103] Signed-off-by: Marc Zyngier Signed-off-by: Manivannan Sadhasivam Tested-by: Janne Grunau Reviewed-by: Rob Herring (Arm) Reviewed-by: Manivannan Sadhasivam Acked-by: Alyssa Rosenzweig Link: https://patch.msgid.link/20250401091713.2765724-13-maz@kernel.org --- drivers/pci/controller/pcie-apple.c | 89 +++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 17 deletions(-) diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c index eadce67e30c0..1ffab0c068e3 100644 --- a/drivers/pci/controller/pcie-apple.c +++ b/drivers/pci/controller/pcie-apple.c @@ -18,6 +18,7 @@ * Author: Marc Zyngier */ +#include #include #include #include @@ -29,6 +30,7 @@ #include #include +/* T8103 (original M1) and related SoCs */ #define CORE_RC_PHYIF_CTL 0x00024 #define CORE_RC_PHYIF_CTL_RUN BIT(0) #define CORE_RC_PHYIF_STAT 0x00028 @@ -104,7 +106,7 @@ #define PORT_REFCLK_CGDIS BIT(8) #define PORT_PERST 0x00814 #define PORT_PERST_OFF BIT(0) -#define PORT_RID2SID(i16) (0x00828 + 4 * (i16)) +#define PORT_RID2SID 0x00828 #define PORT_RID2SID_VALID BIT(31) #define PORT_RID2SID_SID_SHIFT 16 #define PORT_RID2SID_BUS_SHIFT 8 @@ -122,7 +124,8 @@ #define PORT_TUNSTAT_PERST_ACK_PEND BIT(1) #define PORT_PREFMEM_ENABLE 0x00994 -#define MAX_RID2SID 64 +#define PORT_MSIMAP_ENABLE BIT(31) +#define PORT_MSIMAP_TARGET GENMASK(7, 0) /* * The doorbell address is set to 0xfffff000, which by convention @@ -133,10 +136,33 @@ */ #define DOORBELL_ADDR CONFIG_PCIE_APPLE_MSI_DOORBELL_ADDR +struct hw_info { + u32 phy_lane_ctl; + u32 port_msiaddr; + u32 port_msiaddr_hi; + u32 port_refclk; + u32 port_perst; + u32 port_rid2sid; + u32 port_msimap; + u32 max_rid2sid; +}; + +static const struct hw_info t8103_hw = { + .phy_lane_ctl = PHY_LANE_CTL, + .port_msiaddr = PORT_MSIADDR, + .port_msiaddr_hi = 0, + .port_refclk = PORT_REFCLK, + .port_perst = PORT_PERST, + .port_rid2sid = PORT_RID2SID, + .port_msimap = 0, + .max_rid2sid = 64, +}; + struct apple_pcie { struct mutex lock; struct device *dev; void __iomem *base; + const struct hw_info *hw; struct irq_domain *domain; unsigned long *bitmap; struct list_head ports; @@ -380,7 +406,9 @@ static void apple_port_irq_handler(struct irq_desc *desc) static int apple_pcie_port_setup_irq(struct apple_pcie_port *port) { struct fwnode_handle *fwnode = &port->np->fwnode; + struct apple_pcie *pcie = port->pcie; unsigned int irq; + u32 val = 0; /* FIXME: consider moving each interrupt under each port */ irq = irq_of_parse_and_map(to_of_node(dev_fwnode(port->pcie->dev)), @@ -402,13 +430,23 @@ static int apple_pcie_port_setup_irq(struct apple_pcie_port *port) /* Configure MSI base address */ BUILD_BUG_ON(upper_32_bits(DOORBELL_ADDR)); - writel_relaxed(lower_32_bits(DOORBELL_ADDR), port->base + PORT_MSIADDR); + writel_relaxed(lower_32_bits(DOORBELL_ADDR), + port->base + pcie->hw->port_msiaddr); + if (pcie->hw->port_msiaddr_hi) + writel_relaxed(0, port->base + pcie->hw->port_msiaddr_hi); /* Enable MSIs, shared between all ports */ - writel_relaxed(0, port->base + PORT_MSIBASE); - writel_relaxed((ilog2(port->pcie->nvecs) << PORT_MSICFG_L2MSINUM_SHIFT) | - PORT_MSICFG_EN, port->base + PORT_MSICFG); + if (pcie->hw->port_msimap) { + for (int i = 0; i < pcie->nvecs; i++) + writel_relaxed(FIELD_PREP(PORT_MSIMAP_TARGET, i) | + PORT_MSIMAP_ENABLE, + port->base + pcie->hw->port_msimap + 4 * i); + } else { + writel_relaxed(0, port->base + PORT_MSIBASE); + val = ilog2(pcie->nvecs) << PORT_MSICFG_L2MSINUM_SHIFT; + } + writel_relaxed(val | PORT_MSICFG_EN, port->base + PORT_MSICFG); return 0; } @@ -475,7 +513,9 @@ static int apple_pcie_setup_refclk(struct apple_pcie *pcie, u32 stat; int res; - rmw_set(PHY_LANE_CTL_CFGACC, port->phy + PHY_LANE_CTL); + if (pcie->hw->phy_lane_ctl) + rmw_set(PHY_LANE_CTL_CFGACC, port->phy + pcie->hw->phy_lane_ctl); + rmw_set(PHY_LANE_CFG_REFCLK0REQ, port->phy + PHY_LANE_CFG); res = readl_relaxed_poll_timeout(port->phy + PHY_LANE_CFG, @@ -492,20 +532,28 @@ static int apple_pcie_setup_refclk(struct apple_pcie *pcie, if (res < 0) return res; - rmw_clear(PHY_LANE_CTL_CFGACC, port->phy + PHY_LANE_CTL); + if (pcie->hw->phy_lane_ctl) + rmw_clear(PHY_LANE_CTL_CFGACC, port->phy + pcie->hw->phy_lane_ctl); rmw_set(PHY_LANE_CFG_REFCLKEN, port->phy + PHY_LANE_CFG); - rmw_set(PORT_REFCLK_EN, port->base + PORT_REFCLK); + + if (pcie->hw->port_refclk) + rmw_set(PORT_REFCLK_EN, port->base + pcie->hw->port_refclk); return 0; } +static void __iomem *port_rid2sid_addr(struct apple_pcie_port *port, int idx) +{ + return port->base + port->pcie->hw->port_rid2sid + 4 * idx; +} + static u32 apple_pcie_rid2sid_write(struct apple_pcie_port *port, int idx, u32 val) { - writel_relaxed(val, port->base + PORT_RID2SID(idx)); + writel_relaxed(val, port_rid2sid_addr(port, idx)); /* Read back to ensure completion of the write */ - return readl_relaxed(port->base + PORT_RID2SID(idx)); + return readl_relaxed(port_rid2sid_addr(port, idx)); } static int apple_pcie_setup_port(struct apple_pcie *pcie, @@ -528,7 +576,7 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie, if (!port) return -ENOMEM; - port->sid_map = devm_bitmap_zalloc(pcie->dev, MAX_RID2SID, GFP_KERNEL); + port->sid_map = devm_bitmap_zalloc(pcie->dev, pcie->hw->max_rid2sid, GFP_KERNEL); if (!port->sid_map) return -ENOMEM; @@ -572,7 +620,7 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie, usleep_range(100, 200); /* Deassert PERST# */ - rmw_set(PORT_PERST_OFF, port->base + PORT_PERST); + rmw_set(PORT_PERST_OFF, port->base + pcie->hw->port_perst); gpiod_set_value_cansleep(reset, 0); /* Wait for 100ms after PERST# deassertion (PCIe r5.0, 6.6.1) */ @@ -585,7 +633,11 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie, return ret; } - rmw_clear(PORT_REFCLK_CGDIS, port->base + PORT_REFCLK); + if (pcie->hw->port_refclk) + rmw_clear(PORT_REFCLK_CGDIS, port->base + pcie->hw->port_refclk); + else + rmw_set(PHY_LANE_CFG_REFCLKCGEN, port->phy + PHY_LANE_CFG); + rmw_clear(PORT_APPCLK_CGDIS, port->base + PORT_APPCLK); ret = apple_pcie_port_setup_irq(port); @@ -593,7 +645,7 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie, return ret; /* Reset all RID/SID mappings, and check for RAZ/WI registers */ - for (i = 0; i < MAX_RID2SID; i++) { + for (i = 0; i < pcie->hw->max_rid2sid; i++) { if (apple_pcie_rid2sid_write(port, i, 0xbad1d) != 0xbad1d) break; apple_pcie_rid2sid_write(port, i, 0); @@ -741,7 +793,7 @@ static void apple_pcie_disable_device(struct pci_host_bridge *bridge, struct pci for_each_set_bit(idx, port->sid_map, port->sid_map_sz) { u32 val; - val = readl_relaxed(port->base + PORT_RID2SID(idx)); + val = readl_relaxed(port_rid2sid_addr(port, idx)); if ((val & 0xffff) == rid) { apple_pcie_rid2sid_write(port, idx, 0); bitmap_release_region(port->sid_map, idx, 0); @@ -792,6 +844,9 @@ static int apple_pcie_probe(struct platform_device *pdev) return -ENOMEM; pcie->dev = dev; + pcie->hw = of_device_get_match_data(dev); + if (!pcie->hw) + return -ENODEV; pcie->base = devm_platform_ioremap_resource(pdev, 1); if (IS_ERR(pcie->base)) return PTR_ERR(pcie->base); @@ -808,7 +863,7 @@ static int apple_pcie_probe(struct platform_device *pdev) } static const struct of_device_id apple_pcie_of_match[] = { - { .compatible = "apple,pcie" }, + { .compatible = "apple,pcie", .data = &t8103_hw }, { } }; MODULE_DEVICE_TABLE(of, apple_pcie_of_match); -- 2.51.0 From 4e639f11d6e06d9b33d29e0ae2c57b993b44ee48 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Tue, 1 Apr 2025 10:17:13 +0100 Subject: [PATCH 16/16] PCI: apple: Add T602x PCIe support This version of the hardware moved around a bunch of registers, so we avoid the old compatible for these and introduce register offset structures to handle the differences. Signed-off-by: Hector Martin Signed-off-by: Alyssa Rosenzweig Signed-off-by: Marc Zyngier Signed-off-by: Manivannan Sadhasivam Tested-by: Janne Grunau Reviewed-by: Rob Herring (Arm) Reviewed-by: Manivannan Sadhasivam Acked-by: Alyssa Rosenzweig Link: https://patch.msgid.link/20250401091713.2765724-14-maz@kernel.org --- drivers/pci/controller/pcie-apple.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c index 1ffab0c068e3..1211ca957c41 100644 --- a/drivers/pci/controller/pcie-apple.c +++ b/drivers/pci/controller/pcie-apple.c @@ -124,6 +124,13 @@ #define PORT_TUNSTAT_PERST_ACK_PEND BIT(1) #define PORT_PREFMEM_ENABLE 0x00994 +/* T602x (M2-pro and co) */ +#define PORT_T602X_MSIADDR 0x016c +#define PORT_T602X_MSIADDR_HI 0x0170 +#define PORT_T602X_PERST 0x082c +#define PORT_T602X_RID2SID 0x3000 +#define PORT_T602X_MSIMAP 0x3800 + #define PORT_MSIMAP_ENABLE BIT(31) #define PORT_MSIMAP_TARGET GENMASK(7, 0) @@ -158,6 +165,18 @@ static const struct hw_info t8103_hw = { .max_rid2sid = 64, }; +static const struct hw_info t602x_hw = { + .phy_lane_ctl = 0, + .port_msiaddr = PORT_T602X_MSIADDR, + .port_msiaddr_hi = PORT_T602X_MSIADDR_HI, + .port_refclk = 0, + .port_perst = PORT_T602X_PERST, + .port_rid2sid = PORT_T602X_RID2SID, + .port_msimap = PORT_T602X_MSIMAP, + /* 16 on t602x, guess for autodetect on future HW */ + .max_rid2sid = 512, +}; + struct apple_pcie { struct mutex lock; struct device *dev; @@ -425,6 +444,7 @@ static int apple_pcie_port_setup_irq(struct apple_pcie_port *port) /* Disable all interrupts */ writel_relaxed(~0, port->base + PORT_INTMSK); writel_relaxed(~0, port->base + PORT_INTSTAT); + writel_relaxed(~0, port->base + PORT_LINKCMDSTS); irq_set_chained_handler_and_data(irq, apple_port_irq_handler, port); @@ -863,6 +883,7 @@ static int apple_pcie_probe(struct platform_device *pdev) } static const struct of_device_id apple_pcie_of_match[] = { + { .compatible = "apple,t6020-pcie", .data = &t602x_hw }, { .compatible = "apple,pcie", .data = &t8103_hw }, { } }; -- 2.51.0