* [PATCH v10 0/3] thunderbolt: Add device links for Apple T2
@ 2026-08-31 10:00 Mika Westerberg
2026-08-31 10:00 ` [PATCH v10 1/3] thunderbolt: Move tb_apple_add_links() to pci.c Mika Westerberg
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Mika Westerberg @ 2026-08-31 10:00 UTC (permalink / raw)
To: linux-usb
Cc: Yehezkel Bernat, Lukas Wunner, Andreas Noever, Atharva Tiwari,
Alexander Fischer, Andre Eikmeyer, Mika Westerberg
Hi all,
Original cover letter:
This series adds support for Device linking on Titan ridge, and Icelake,
which are used exclusively on Apple T2 machines.
I went and did some changes so wanted to check that these still work on the
Apple T2 systems. I dropped Tested-by from Alexander Fischer because these
are not anymore the same patches. I would appreciate if you could re-test
these and let me know if they still work or not.
The changes I did:
- Make ->add_links a NHI operation instead.
- Move the check to nhi.c instead after we have selected software CM.
- Split out add_link() helper that can be used both integrated and
discrete case.
- Link only the matching PCIe root ports to the NHI that actually tunnels
them. The previous version (v9) linked all four for each NHI so there
are duplicate links. Each NHI tunnels just up to 2 PCIe root ports in
Ice Lake.
v9 of the patch series can be found here:
https://lore.kernel.org/linux-usb/20260824184305.1234-1-atharvatiwarilinuxdev@gmail.com/
Atharva Tiwari (3):
thunderbolt: Move tb_apple_add_links() to pci.c
thunderbolt: Add device links for Apple machines with Titan Ridge
thunderbolt: Add device links for Apple systems with Ice Lake
drivers/thunderbolt/nhi.c | 34 +++++++++---
drivers/thunderbolt/nhi.h | 2 +
drivers/thunderbolt/pci.c | 113 ++++++++++++++++++++++++++++++++++++++
drivers/thunderbolt/tb.c | 78 --------------------------
4 files changed, 140 insertions(+), 87 deletions(-)
--
2.50.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v10 1/3] thunderbolt: Move tb_apple_add_links() to pci.c
2026-08-31 10:00 [PATCH v10 0/3] thunderbolt: Add device links for Apple T2 Mika Westerberg
@ 2026-08-31 10:00 ` Mika Westerberg
2026-08-31 10:00 ` [PATCH v10 2/3] thunderbolt: Add device links for Apple machines with Titan Ridge Mika Westerberg
2026-08-31 10:00 ` [PATCH v10 3/3] thunderbolt: Add device links for Apple systems with Ice Lake Mika Westerberg
2 siblings, 0 replies; 4+ messages in thread
From: Mika Westerberg @ 2026-08-31 10:00 UTC (permalink / raw)
To: linux-usb
Cc: Yehezkel Bernat, Lukas Wunner, Andreas Noever, Atharva Tiwari,
Alexander Fischer, Andre Eikmeyer, Mika Westerberg
From: Atharva Tiwari <atharvatiwarilinuxdev@gmail.com>
Due to historical reasons the software connection manager in tb.c
directly sets up the device link between the tunneled PCIe ports and the
NHI. Now as we are starting to support non-PCIe host interfaces as well
we are trying to keep the connection manager implementation agnostic of
the underlying host interface. For this reason move the device link
creation into pci.c and expose it through a new NHI operation that the
host interface code calls when it sets up the connection manager.
Suggested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Atharva Tiwari <atharvatiwarilinuxdev@gmail.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/thunderbolt/nhi.c | 34 ++++++++++++-----
drivers/thunderbolt/nhi.h | 2 +
drivers/thunderbolt/pci.c | 76 ++++++++++++++++++++++++++++++++++++++
drivers/thunderbolt/tb.c | 78 ---------------------------------------
4 files changed, 103 insertions(+), 87 deletions(-)
diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c
index d4d1efa2afa0..5827c498c628 100644
--- a/drivers/thunderbolt/nhi.c
+++ b/drivers/thunderbolt/nhi.c
@@ -1208,24 +1208,40 @@ void nhi_reset_interface(struct tb_nhi *nhi)
static struct tb *nhi_select_cm(struct tb_nhi *nhi)
{
+ bool linked = false;
struct tb *tb;
/*
* USB4 case is simple. If we got control of any of the
* capabilities, we use software CM.
*/
- if (tb_acpi_is_native())
- return tb_probe(nhi);
+ if (!tb_acpi_is_native()) {
+ /*
+ * Either firmware based CM is running (we did not get
+ * control from the firmware) or this is pre-USB4 PC so
+ * try first firmware CM and then fallback to software CM.
+ */
+ tb = icm_probe(nhi);
+ if (tb)
+ return tb;
+ }
- /*
- * Either firmware based CM is running (we did not get control
- * from the firmware) or this is pre-USB4 PC so try first
- * firmware CM and then fallback to software CM.
- */
- tb = icm_probe(nhi);
+ tb = tb_probe(nhi);
if (!tb)
- tb = tb_probe(nhi);
+ return NULL;
+ if (nhi->ops->add_links)
+ linked = nhi->ops->add_links(nhi);
+ if (!linked)
+ linked = tb_acpi_add_links(nhi);
+ /*
+ * Device links are needed to make sure we establish tunnels
+ * before protocol stacks are resumed so complain here if we
+ * found them missing.
+ */
+ if (!linked)
+ dev_warn(nhi->dev,
+ "device links to tunneled native ports are missing!\n");
return tb;
}
diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h
index f72d6b274501..b2e2e2c413b2 100644
--- a/drivers/thunderbolt/nhi.h
+++ b/drivers/thunderbolt/nhi.h
@@ -43,6 +43,7 @@ extern const struct dev_pm_ops nhi_pm_ops;
/**
* struct tb_nhi_ops - NHI specific optional operations
* @init: NHI specific initialization
+ * @add_links: Setup device links for tunneling native protocols
* @suspend_noirq: NHI specific suspend_noirq hook
* @resume_noirq: NHI specific resume_noirq hook
* @runtime_suspend: NHI specific runtime_suspend hook
@@ -58,6 +59,7 @@ extern const struct dev_pm_ops nhi_pm_ops;
*/
struct tb_nhi_ops {
int (*init)(struct tb_nhi *nhi);
+ bool (*add_links)(struct tb_nhi *nhi);
int (*suspend_noirq)(struct tb_nhi *nhi, bool wakeup);
int (*resume_noirq)(struct tb_nhi *nhi);
int (*runtime_suspend)(struct tb_nhi *nhi);
diff --git a/drivers/thunderbolt/pci.c b/drivers/thunderbolt/pci.c
index 99333729f3c2..c9c50004a6ac 100644
--- a/drivers/thunderbolt/pci.c
+++ b/drivers/thunderbolt/pci.c
@@ -18,6 +18,7 @@
#include <linux/property.h>
#include <linux/string_helpers.h>
#include <linux/suspend.h>
+#include <linux/platform_data/x86/apple.h>
#include "nhi.h"
#include "nhi_regs.h"
@@ -129,6 +130,80 @@ static void nhi_pci_check_iommu(struct tb_nhi_pci *nhi_pci)
str_enabled_disabled(port_ok));
}
+static bool add_link(struct tb_nhi *nhi, struct pci_dev *pdev)
+{
+ const struct device_link *link;
+
+ link = device_link_add(&pdev->dev, nhi->dev,
+ DL_FLAG_AUTOREMOVE_SUPPLIER |
+ DL_FLAG_PM_RUNTIME);
+ if (!link) {
+ dev_warn(nhi->dev, "device link creation from %s failed\n",
+ dev_name(&pdev->dev));
+ return false;
+ }
+
+ dev_dbg(nhi->dev, "created link from %s\n", dev_name(&pdev->dev));
+ return true;
+}
+
+/*
+ * During suspend the Thunderbolt controller is reset and all PCIe
+ * tunnels are lost. The NHI driver will try to reestablish all tunnels
+ * during resume. This adds device links between the tunneled PCIe
+ * downstream ports and the NHI so that the device core will make sure
+ * NHI is resumed first before the rest.
+ */
+static bool nhi_pci_add_links(struct tb_nhi *nhi)
+{
+ struct pci_dev *nhi_pdev = to_pci_dev(nhi->dev);
+ struct pci_dev *upstream, *pdev;
+ bool ret;
+
+ if (!x86_apple_machine)
+ return false;
+
+ switch (nhi_pdev->device) {
+ case PCI_DEVICE_ID_INTEL_LIGHT_RIDGE:
+ case PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C:
+ case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_NHI:
+ case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI:
+ break;
+ default:
+ return false;
+ }
+
+ upstream = pci_upstream_bridge(nhi_pdev);
+ while (upstream) {
+ if (!pci_is_pcie(upstream))
+ return false;
+ if (pci_pcie_type(upstream) == PCI_EXP_TYPE_UPSTREAM)
+ break;
+ upstream = pci_upstream_bridge(upstream);
+ }
+
+ if (!upstream)
+ return false;
+
+ /*
+ * For each hotplug downstream port, create add device link back
+ * to NHI so that PCIe tunnels can be re-established after
+ * sleep.
+ */
+ ret = false;
+ for_each_pci_bridge(pdev, upstream->subordinate) {
+ if (!pci_is_pcie(pdev))
+ continue;
+ if (pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM ||
+ !pdev->is_pciehp)
+ continue;
+
+ ret |= add_link(nhi, pdev);
+ }
+
+ return ret;
+}
+
static int nhi_pci_init_msi(struct tb_nhi *nhi)
{
struct tb_nhi_pci *nhi_pci = nhi_to_pci(nhi);
@@ -272,6 +347,7 @@ static bool nhi_pci_is_present(struct tb_nhi *nhi)
}
static const struct tb_nhi_ops pci_nhi_default_ops = {
+ .add_links = nhi_pci_add_links,
.pre_nvm_auth = nhi_pci_start_dma_port,
.post_nvm_auth = nhi_pci_complete_dma_port,
.request_ring_irq = nhi_pci_ring_request_msix,
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
index 47753a5c0f2e..7e39b067e5ff 100644
--- a/drivers/thunderbolt/tb.c
+++ b/drivers/thunderbolt/tb.c
@@ -10,7 +10,6 @@
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/pm_runtime.h>
-#include <linux/platform_data/x86/apple.h>
#include "tb.h"
#include "tb_regs.h"
@@ -3323,75 +3322,6 @@ static const struct tb_cm_ops tb_cm_ops = {
.disconnect_xdomain_paths = tb_disconnect_xdomain_paths,
};
-/*
- * During suspend the Thunderbolt controller is reset and all PCIe
- * tunnels are lost. The NHI driver will try to reestablish all tunnels
- * during resume. This adds device links between the tunneled PCIe
- * downstream ports and the NHI so that the device core will make sure
- * NHI is resumed first before the rest.
- */
-static bool tb_apple_add_links(struct tb_nhi *nhi)
-{
- struct pci_dev *nhi_pdev = to_pci_dev(nhi->dev);
- struct pci_dev *upstream, *pdev;
- bool ret;
-
- if (!x86_apple_machine)
- return false;
-
- switch (nhi_pdev->device) {
- case PCI_DEVICE_ID_INTEL_LIGHT_RIDGE:
- case PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C:
- case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_NHI:
- case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI:
- break;
- default:
- return false;
- }
-
- upstream = pci_upstream_bridge(nhi_pdev);
- while (upstream) {
- if (!pci_is_pcie(upstream))
- return false;
- if (pci_pcie_type(upstream) == PCI_EXP_TYPE_UPSTREAM)
- break;
- upstream = pci_upstream_bridge(upstream);
- }
-
- if (!upstream)
- return false;
-
- /*
- * For each hotplug downstream port, create add device link
- * back to NHI so that PCIe tunnels can be re-established after
- * sleep.
- */
- ret = false;
- for_each_pci_bridge(pdev, upstream->subordinate) {
- const struct device_link *link;
-
- if (!pci_is_pcie(pdev))
- continue;
- if (pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM ||
- !pdev->is_pciehp)
- continue;
-
- link = device_link_add(&pdev->dev, nhi->dev,
- DL_FLAG_AUTOREMOVE_SUPPLIER |
- DL_FLAG_PM_RUNTIME);
- if (link) {
- dev_dbg(nhi->dev, "created link from %s\n",
- dev_name(&pdev->dev));
- ret = true;
- } else {
- dev_warn(nhi->dev, "device link creation from %s failed\n",
- dev_name(&pdev->dev));
- }
- }
-
- return ret;
-}
-
struct tb *tb_probe(struct tb_nhi *nhi)
{
struct tb_cm *tcm;
@@ -3416,13 +3346,5 @@ struct tb *tb_probe(struct tb_nhi *nhi)
tb_dbg(tb, "using software connection manager\n");
- /*
- * Device links are needed to make sure we establish tunnels
- * before the PCIe/USB stack is resumed so complain here if we
- * found them missing.
- */
- if (!tb_apple_add_links(nhi) && !tb_acpi_add_links(nhi))
- tb_warn(tb, "device links to tunneled native ports are missing!\n");
-
return tb;
}
--
2.50.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v10 2/3] thunderbolt: Add device links for Apple machines with Titan Ridge
2026-08-31 10:00 [PATCH v10 0/3] thunderbolt: Add device links for Apple T2 Mika Westerberg
2026-08-31 10:00 ` [PATCH v10 1/3] thunderbolt: Move tb_apple_add_links() to pci.c Mika Westerberg
@ 2026-08-31 10:00 ` Mika Westerberg
2026-08-31 10:00 ` [PATCH v10 3/3] thunderbolt: Add device links for Apple systems with Ice Lake Mika Westerberg
2 siblings, 0 replies; 4+ messages in thread
From: Mika Westerberg @ 2026-08-31 10:00 UTC (permalink / raw)
To: linux-usb
Cc: Yehezkel Bernat, Lukas Wunner, Andreas Noever, Atharva Tiwari,
Alexander Fischer, Andre Eikmeyer, Mika Westerberg
From: Atharva Tiwari <atharvatiwarilinuxdev@gmail.com>
Add device links for Apple machines with the Titan Ridge thunderbolt
controller.
Signed-off-by: Atharva Tiwari <atharvatiwarilinuxdev@gmail.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/thunderbolt/pci.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/thunderbolt/pci.c b/drivers/thunderbolt/pci.c
index c9c50004a6ac..996a8ab3cfb7 100644
--- a/drivers/thunderbolt/pci.c
+++ b/drivers/thunderbolt/pci.c
@@ -168,6 +168,8 @@ static bool nhi_pci_add_links(struct tb_nhi *nhi)
case PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C:
case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_NHI:
case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI:
+ case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_NHI:
+ case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_NHI:
break;
default:
return false;
--
2.50.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v10 3/3] thunderbolt: Add device links for Apple systems with Ice Lake
2026-08-31 10:00 [PATCH v10 0/3] thunderbolt: Add device links for Apple T2 Mika Westerberg
2026-08-31 10:00 ` [PATCH v10 1/3] thunderbolt: Move tb_apple_add_links() to pci.c Mika Westerberg
2026-08-31 10:00 ` [PATCH v10 2/3] thunderbolt: Add device links for Apple machines with Titan Ridge Mika Westerberg
@ 2026-08-31 10:00 ` Mika Westerberg
2 siblings, 0 replies; 4+ messages in thread
From: Mika Westerberg @ 2026-08-31 10:00 UTC (permalink / raw)
To: linux-usb
Cc: Yehezkel Bernat, Lukas Wunner, Andreas Noever, Atharva Tiwari,
Alexander Fischer, Andre Eikmeyer, Mika Westerberg
From: Atharva Tiwari <atharvatiwarilinuxdev@gmail.com>
Ice Lake Thunderbolt NHI that are on some Macs. The NHI and its
associated PCIe Root Ports all sit directly on the Root Complex with no
upstream port. Identify the tunneled PCIe Root Ports by their PCI IDs
and create device links back to the NHI so that PCIe tunnels can be
re-established after sleep.
Co-developed-by: Andre Eikmeyer <andre@negmaster.com>
Signed-off-by: Andre Eikmeyer <andre@negmaster.com>
Signed-off-by: Atharva Tiwari <atharvatiwarilinuxdev@gmail.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/thunderbolt/pci.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/drivers/thunderbolt/pci.c b/drivers/thunderbolt/pci.c
index 996a8ab3cfb7..e40d4d6af071 100644
--- a/drivers/thunderbolt/pci.c
+++ b/drivers/thunderbolt/pci.c
@@ -521,6 +521,40 @@ static int icl_nhi_resume(struct tb_nhi *nhi)
return 0;
}
+static bool icl_nhi_add_links(struct tb_nhi *nhi)
+{
+ struct pci_dev *nhi_pdev = to_pci_dev(nhi->dev);
+ struct pci_bus *bus = nhi_pdev->bus;
+ struct pci_dev *pdev;
+ bool ret;
+
+ if (!x86_apple_machine)
+ return false;
+
+ /*
+ * On integrated controllers the tunneled PCIe root ports are
+ * directly under the host bridge.
+ */
+ if (!pci_is_root_bus(bus))
+ return false;
+
+ ret = false;
+ for_each_pci_bridge(pdev, bus) {
+ switch (nhi_pdev->device) {
+ case PCI_DEVICE_ID_INTEL_ICL_NHI0:
+ if (pdev->device == 0x8a1d || pdev->device == 0x8a1f)
+ ret |= add_link(nhi, pdev);
+ break;
+ case PCI_DEVICE_ID_INTEL_ICL_NHI1:
+ if (pdev->device == 0x8a21 || pdev->device == 0x8a23)
+ ret |= add_link(nhi, pdev);
+ break;
+ }
+ }
+
+ return ret;
+}
+
static void icl_nhi_shutdown(struct tb_nhi *nhi)
{
nhi_pci_release_irq(nhi);
@@ -530,6 +564,7 @@ static void icl_nhi_shutdown(struct tb_nhi *nhi)
static const struct tb_nhi_ops icl_nhi_ops = {
.init = icl_nhi_resume,
+ .add_links = icl_nhi_add_links,
.suspend_noirq = icl_nhi_suspend_noirq,
.resume_noirq = icl_nhi_resume,
.runtime_suspend = icl_nhi_suspend,
--
2.50.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-08-31 10:00 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-31 10:00 [PATCH v10 0/3] thunderbolt: Add device links for Apple T2 Mika Westerberg
2026-08-31 10:00 ` [PATCH v10 1/3] thunderbolt: Move tb_apple_add_links() to pci.c Mika Westerberg
2026-08-31 10:00 ` [PATCH v10 2/3] thunderbolt: Add device links for Apple machines with Titan Ridge Mika Westerberg
2026-08-31 10:00 ` [PATCH v10 3/3] thunderbolt: Add device links for Apple systems with Ice Lake Mika Westerberg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox