Skip to content

Commit bbeac79

Browse files
authored
Fast resume
1 parent 5e38d4b commit bbeac79

File tree

2 files changed

+233
-0
lines changed

2 files changed

+233
-0
lines changed
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
From c9a88b70e1157e75b7de963bf7d2144c127a5037 Mon Sep 17 00:00:00 2001
2+
From: deqrocks <andre@negmaster.com>
3+
Date: Sun, 5 Apr 2026 13:36:54 +0200
4+
Subject: [PATCH] thunderbolt: add device links for integrated Apple T2 NHI
5+
6+
---
7+
drivers/thunderbolt/tb.c | 115 +++++++++++++++++++++++++++------------
8+
1 file changed, 80 insertions(+), 35 deletions(-)
9+
10+
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
11+
index 4f5f1dfc0..1b4ff0d9e 100644
12+
--- a/drivers/thunderbolt/tb.c
13+
+++ b/drivers/thunderbolt/tb.c
14+
@@ -9,6 +9,7 @@
15+
#include <linux/slab.h>
16+
#include <linux/errno.h>
17+
#include <linux/delay.h>
18+
+#include <linux/acpi.h>
19+
#include <linux/pm_runtime.h>
20+
#include <linux/platform_data/x86/apple.h>
21+
22+
@@ -3305,21 +3306,12 @@ static const struct tb_cm_ops tb_cm_ops = {
23+
static bool tb_apple_add_links(struct tb_nhi *nhi)
24+
{
25+
struct pci_dev *upstream, *pdev;
26+
+ struct acpi_device *adev;
27+
bool ret;
28+
29+
if (!x86_apple_machine)
30+
return false;
31+
32+
- switch (nhi->pdev->device) {
33+
- case PCI_DEVICE_ID_INTEL_LIGHT_RIDGE:
34+
- case PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C:
35+
- case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_NHI:
36+
- case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI:
37+
- break;
38+
- default:
39+
- return false;
40+
- }
41+
-
42+
upstream = pci_upstream_bridge(nhi->pdev);
43+
while (upstream) {
44+
if (!pci_is_pcie(upstream))
45+
@@ -3329,34 +3321,87 @@ static bool tb_apple_add_links(struct tb_nhi *nhi)
46+
upstream = pci_upstream_bridge(upstream);
47+
}
48+
49+
- if (!upstream)
50+
- return false;
51+
-
52+
- /*
53+
- * For each hotplug downstream port, create add device link
54+
- * back to NHI so that PCIe tunnels can be re-established after
55+
- * sleep.
56+
- */
57+
ret = false;
58+
- for_each_pci_bridge(pdev, upstream->subordinate) {
59+
- const struct device_link *link;
60+
61+
- if (!pci_is_pcie(pdev))
62+
- continue;
63+
- if (pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM ||
64+
- !pdev->is_pciehp)
65+
- continue;
66+
+ if (upstream) {
67+
+ /*
68+
+ * Discrete Thunderbolt controller (e.g. Light Ridge, Falcon
69+
+ * Ridge) behind a PCIe switch. Create device links for each
70+
+ * hotplug-capable downstream port under that switch.
71+
+ */
72+
+ for_each_pci_bridge(pdev, upstream->subordinate) {
73+
+ const struct device_link *link;
74+
75+
- link = device_link_add(&pdev->dev, &nhi->pdev->dev,
76+
- DL_FLAG_AUTOREMOVE_SUPPLIER |
77+
- DL_FLAG_PM_RUNTIME);
78+
- if (link) {
79+
- dev_dbg(&nhi->pdev->dev, "created link from %s\n",
80+
- dev_name(&pdev->dev));
81+
- ret = true;
82+
- } else {
83+
- dev_warn(&nhi->pdev->dev, "device link creation from %s failed\n",
84+
- dev_name(&pdev->dev));
85+
+ if (!pci_is_pcie(pdev))
86+
+ continue;
87+
+ if (pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM ||
88+
+ !pdev->is_pciehp)
89+
+ continue;
90+
+
91+
+ link = device_link_add(&pdev->dev, &nhi->pdev->dev,
92+
+ DL_FLAG_AUTOREMOVE_SUPPLIER |
93+
+ DL_FLAG_PM_RUNTIME);
94+
+ if (link) {
95+
+ dev_dbg(&nhi->pdev->dev, "created link from %s\n",
96+
+ dev_name(&pdev->dev));
97+
+ ret = true;
98+
+ } else {
99+
+ dev_warn(&nhi->pdev->dev,
100+
+ "device link creation from %s failed\n",
101+
+ dev_name(&pdev->dev));
102+
+ }
103+
+ }
104+
+ } else {
105+
+ unsigned int slot, func;
106+
+
107+
+ /*
108+
+ * Integrated Thunderbolt NHI on T2 Macs (2018-2020). The
109+
+ * NHI and its associated PCIe root ports all sit directly
110+
+ * on the root complex with no upstream port. Apple's ACPI
111+
+ * tables name Thunderbolt root ports as TRP0, TRP1, etc.
112+
+ * Find them and create device links back to the NHI so
113+
+ * that PCIe tunnels can be re-established after sleep.
114+
+ */
115+
+ for (slot = 0; slot < 32; slot++) {
116+
+ for (func = 0; func < 8; func++) {
117+
+ const struct device_link *link;
118+
+ const char *bid;
119+
+
120+
+ pdev = pci_get_slot(nhi->pdev->bus,
121+
+ PCI_DEVFN(slot, func));
122+
+ if (!pdev)
123+
+ continue;
124+
+
125+
+ if (!pci_is_pcie(pdev))
126+
+ goto put_pdev;
127+
+ if (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT)
128+
+ goto put_pdev;
129+
+
130+
+ adev = ACPI_COMPANION(&pdev->dev);
131+
+ if (!adev)
132+
+ goto put_pdev;
133+
+
134+
+ bid = acpi_device_bid(adev);
135+
+ if (!bid || strncmp(bid, "TRP", 3) != 0)
136+
+ goto put_pdev;
137+
+
138+
+ link = device_link_add(&pdev->dev, &nhi->pdev->dev,
139+
+ DL_FLAG_AUTOREMOVE_SUPPLIER |
140+
+ DL_FLAG_PM_RUNTIME);
141+
+ if (link) {
142+
+ dev_dbg(&nhi->pdev->dev,
143+
+ "created link from %s\n",
144+
+ dev_name(&pdev->dev));
145+
+ ret = true;
146+
+ } else {
147+
+ dev_warn(&nhi->pdev->dev,
148+
+ "device link creation from %s failed\n",
149+
+ dev_name(&pdev->dev));
150+
+ }
151+
+
152+
+put_pdev:
153+
+ pci_dev_put(pdev);
154+
+ }
155+
}
156+
}
157+
158+
--
159+
2.53.0
160+
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
From a388d392de31c53aacfcb8b375d1127046f42edd Mon Sep 17 00:00:00 2001
2+
From: deqrocks <andre@negmaster.com>
3+
Date: Mon, 6 Apr 2026 11:23:57 +0200
4+
Subject: [PATCH] PCI/portdrv: use INTx for Apple T2 Thunderbolt root port
5+
services
6+
7+
---
8+
drivers/pci/pcie/portdrv.c | 31 +++++++++++++++++++++++++++++++
9+
1 file changed, 31 insertions(+)
10+
11+
diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c
12+
index a0991da48..a2fc6c99f 100644
13+
--- a/drivers/pci/pcie/portdrv.c
14+
+++ b/drivers/pci/pcie/portdrv.c
15+
@@ -7,6 +7,7 @@
16+
*/
17+
18+
#include <linux/bitfield.h>
19+
+#include <linux/acpi.h>
20+
#include <linux/dmi.h>
21+
#include <linux/init.h>
22+
#include <linux/module.h>
23+
@@ -18,10 +19,37 @@
24+
#include <linux/string.h>
25+
#include <linux/slab.h>
26+
#include <linux/aer.h>
27+
+#include <linux/platform_data/x86/apple.h>
28+
29+
#include "../pci.h"
30+
#include "portdrv.h"
31+
32+
+static bool pcie_port_no_msi_on_apple_t2(struct pci_dev *dev)
33+
+{
34+
+ acpi_handle handle;
35+
+ struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
36+
+ char *name;
37+
+ bool ret = false;
38+
+
39+
+ if (!x86_apple_machine)
40+
+ return false;
41+
+ if (pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT)
42+
+ return false;
43+
+
44+
+ handle = ACPI_HANDLE(&dev->dev);
45+
+ if (!handle)
46+
+ return false;
47+
+
48+
+ if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buf))) {
49+
+ name = buf.pointer;
50+
+ if (name)
51+
+ ret = !strncmp(name, "TRP", 3);
52+
+ }
53+
+
54+
+ ACPI_FREE(buf.pointer);
55+
+ return ret;
56+
+}
57+
+
58+
/*
59+
* The PCIe Capability Interrupt Message Number (PCIe r3.1, sec 7.8.2) must
60+
* be one of the first 32 MSI-X entries. Per PCI r3.0, sec 6.8.3.1, MSI
61+
@@ -181,6 +209,9 @@ static int pcie_init_service_irqs(struct pci_dev *dev, int *irqs, int mask)
62+
for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
63+
irqs[i] = -1;
64+
65+
+ if (pcie_port_no_msi_on_apple_t2(dev))
66+
+ goto intx_irq;
67+
+
68+
/*
69+
* If we support PME but can't use MSI/MSI-X for it, we have to
70+
* fall back to INTx or other interrupts, e.g., a system shared
71+
--
72+
2.53.0
73+

0 commit comments

Comments
 (0)