* [PATCH 0/4] add support platform nhi driver
@ 2026-10-30 8:25 Chunfeng Yun
2026-10-30 8:25 ` [PATCH 1/4] thunderbolt: add " Chunfeng Yun
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Chunfeng Yun @ 2026-10-30 8:25 UTC (permalink / raw)
To: Mika Westerberg
Cc: Andreas Noever, Yehezkel Bernat, Matthias Brugger,
Greg Kroah-Hartman, AngeloGioacchino Del Regno, linux-kernel,
linux-usb, linux-arm-kernel, linux-mediatek, Chunfeng Yun
This patch series introduces support for platform bus-based USB4/Thunderbolt
Host Interface (NHI) controllers on embedded SoCs, along with two fixes/
improvements in the Thunderbolt core connection manager.
Historically, the Thunderbolt NHI driver has assumed a PCI bus binding
(pci.c), with tb_domain_init()/exit() tightly coupled to the PCI module
lifecycle. Modern ARM64 SoCs integrate the USB4 NHI controller directly
onto the platform bus, described via Device Tree or ACPI.
This series decouples the core domain initialization from the PCI driver
and adds a dedicated platform driver (plat.c) supporting standard platform
probing, OF/ACPI device tables, runtime PM, and an optional dedicated
out-of-band wakeup IRQ.
Additionally, this series resolves two issues observed during runtime PM
and link training:
1. Premature link-up timeout when bringing up USB3 adapters on links with
multiple retimers.
2. Kernel warnings when authorizing/de-authorizing PCIe tunnels on switches
that have been marked unplugged or lost during suspend.
Patches in this series:
======================
Patch 1: thunderbolt: add platform nhi driver
Decouples tb_domain_init()/exit() using subsys_initcall() and adds plat.c
to support memory-mapped NHI host controllers on the platform bus with
Device Tree (CONFIG_OF) and ACPI (CONFIG_ACPI) match tables.
Patch 2: thunderbolt: add support optional dedicated wakeup irq
Adds support for an optional dedicated wakeup interrupt for platform NHI
controllers using dev_pm_set_dedicated_wake_irq(), allowing out-of-band
wake-up lines from SoC power management units during low-power states.
Patch 3: thunderbolt: improve usb3 adapter link up timeout value
Increases tb_wait_for_port() timeout from 1.0s to 2.5s. In the USB4 spec,
Phase 5 (Link Equalization) alone is permitted up to 1000 ms. When factoring
in Phase 3/4 and retimer transaction delays across multiple retimers, link
training can legitimately take 1.2s to 1.5s+. The previous 1.0s timeout
caused premature aborts and disconnects upon wakeup.
Patch 4: thunderbolt: fix pcie tunnel create/destroy core dump
Checks sw->is_unplugged in tb_switch_set_authorized(), tb_disconnect_pci(),
and tb_tunnel_pci(). When de-authorizing an unplugged/lost switch via sysfs,
this prevents redundant lookups and eliminates false-positive
WARN_ON(!tunnel) stack traces when tunnels have already been destroyed.
Testing:
========
Tested on ARM64 platform hardware with USB4 hubs and downstream PCIe/USB3
devices across plug/unplug, system suspend/resume, and runtime PM transitions,
the kernel boots from UEFI/ACPI.
Chunfeng Yun (4):
thunderbolt: add platform nhi driver
thunderbolt: add support optional dedicated wakeup irq
thunderbolt: improve usb3 adapter link up timeout value
thunderbolt: prevent pcie tunnel activation/teardown warnings
drivers/thunderbolt/Makefile | 2 +-
drivers/thunderbolt/domain.c | 10 +-
drivers/thunderbolt/nhi.c | 2 +
drivers/thunderbolt/nhi.h | 1 -
drivers/thunderbolt/pci.c | 26 +-----
drivers/thunderbolt/plat.c | 171 +++++++++++++++++++++++++++++++++++
drivers/thunderbolt/switch.c | 8 +-
drivers/thunderbolt/tb.c | 7 ++
drivers/thunderbolt/tb.h | 2 -
include/linux/thunderbolt.h | 2 +
10 files changed, 200 insertions(+), 31 deletions(-)
create mode 100644 drivers/thunderbolt/plat.c
--
2.43.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/4] thunderbolt: add platform nhi driver
2026-10-30 8:25 [PATCH 0/4] add support platform nhi driver Chunfeng Yun
@ 2026-10-30 8:25 ` Chunfeng Yun
2026-10-30 8:47 ` Mika Westerberg
2026-10-30 8:25 ` [PATCH 2/4] thunderbolt: add support optional dedicated wakeup irq Chunfeng Yun
` (2 subsequent siblings)
3 siblings, 1 reply; 9+ messages in thread
From: Chunfeng Yun @ 2026-10-30 8:25 UTC (permalink / raw)
To: Mika Westerberg
Cc: Andreas Noever, Yehezkel Bernat, Matthias Brugger,
Greg Kroah-Hartman, AngeloGioacchino Del Regno, linux-kernel,
linux-usb, linux-arm-kernel, linux-mediatek, Chunfeng Yun
Add a new file plat.c to register platform NHI driver for MediaTek
mt8901/mt8992 SoCs.
Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
---
drivers/thunderbolt/Makefile | 2 +-
drivers/thunderbolt/domain.c | 10 ++-
drivers/thunderbolt/nhi.c | 2 +
drivers/thunderbolt/nhi.h | 1 -
drivers/thunderbolt/pci.c | 26 +-----
drivers/thunderbolt/plat.c | 155 +++++++++++++++++++++++++++++++++++
drivers/thunderbolt/tb.h | 2 -
include/linux/thunderbolt.h | 1 +
8 files changed, 169 insertions(+), 30 deletions(-)
create mode 100644 drivers/thunderbolt/plat.c
diff --git a/drivers/thunderbolt/Makefile b/drivers/thunderbolt/Makefile
index beb054c3126b..9c941682f3d6 100644
--- a/drivers/thunderbolt/Makefile
+++ b/drivers/thunderbolt/Makefile
@@ -3,7 +3,7 @@ ccflags-y := -I$(src)
obj-${CONFIG_USB4} := thunderbolt.o
thunderbolt-objs := nhi.o ctl.o tb.o switch.o cap.o pci.o path.o tunnel.o eeprom.o
thunderbolt-objs += domain.o dma_port.o icm.o property.o xdomain.o lc.o tmu.o usb4.o
-thunderbolt-objs += usb4_port.o nvm.o retimer.o quirks.o clx.o
+thunderbolt-objs += usb4_port.o nvm.o retimer.o quirks.o clx.o plat.o
thunderbolt-${CONFIG_ACPI} += acpi.o
thunderbolt-$(CONFIG_DEBUG_FS) += debugfs.o
diff --git a/drivers/thunderbolt/domain.c b/drivers/thunderbolt/domain.c
index 24611f05b3cd..bec7e6ebc4a8 100644
--- a/drivers/thunderbolt/domain.c
+++ b/drivers/thunderbolt/domain.c
@@ -881,7 +881,7 @@ int tb_domain_unregister_unplugged_xdomains(struct tb *tb)
return ctx.n;
}
-int tb_domain_init(void)
+static int __init tb_domain_init(void)
{
int ret;
@@ -907,7 +907,7 @@ int tb_domain_init(void)
return ret;
}
-void tb_domain_exit(void)
+static void __exit tb_domain_exit(void)
{
bus_unregister(&tb_bus_type);
ida_destroy(&tb_domain_ida);
@@ -917,3 +917,9 @@ void tb_domain_exit(void)
tb_debugfs_exit();
tb_configfs_exit();
}
+
+subsys_initcall(tb_domain_init);
+module_exit(tb_domain_exit);
+
+MODULE_DESCRIPTION("Thunderbolt/USB4 domain driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c
index e99a3fcc4a29..c0f9f1855e8f 100644
--- a/drivers/thunderbolt/nhi.c
+++ b/drivers/thunderbolt/nhi.c
@@ -1379,8 +1379,10 @@ int nhi_probe(struct tb_nhi *nhi)
device_wakeup_enable(dev);
pm_runtime_allow(dev);
+ device_enable_async_suspend(dev);
pm_runtime_set_autosuspend_delay(dev, TB_AUTOSUSPEND_DELAY);
pm_runtime_use_autosuspend(dev);
+ pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
return 0;
diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h
index 88af9ab9fde7..37c11de167ad 100644
--- a/drivers/thunderbolt/nhi.h
+++ b/drivers/thunderbolt/nhi.h
@@ -29,7 +29,6 @@ enum nhi_mailbox_cmd {
int nhi_mailbox_cmd(struct tb_nhi *nhi, enum nhi_mailbox_cmd cmd, u32 data);
enum nhi_fw_mode nhi_mailbox_mode(struct tb_nhi *nhi);
-void nhi_enable_int_throttling(struct tb_nhi *nhi);
void nhi_disable_interrupts(struct tb_nhi *nhi);
void nhi_interrupt_work(struct work_struct *work);
irqreturn_t nhi_msi(int irq, void *data);
diff --git a/drivers/thunderbolt/pci.c b/drivers/thunderbolt/pci.c
index 4408229d8ac7..91d236300703 100644
--- a/drivers/thunderbolt/pci.c
+++ b/drivers/thunderbolt/pci.c
@@ -715,7 +715,7 @@ static struct pci_device_id nhi_ids[] = {
};
MODULE_DEVICE_TABLE(pci, nhi_ids);
-MODULE_DESCRIPTION("Thunderbolt/USB4 core driver");
+MODULE_DESCRIPTION("Thunderbolt/USB4 PCI host interface driver");
MODULE_LICENSE("GPL");
static struct pci_driver nhi_driver = {
@@ -727,26 +727,4 @@ static struct pci_driver nhi_driver = {
.driver.pm = &nhi_pm_ops,
};
-static int __init nhi_init(void)
-{
- int ret;
-
- ret = tb_domain_init();
- if (ret)
- return ret;
-
- ret = pci_register_driver(&nhi_driver);
- if (ret)
- tb_domain_exit();
-
- return ret;
-}
-
-static void __exit nhi_unload(void)
-{
- pci_unregister_driver(&nhi_driver);
- tb_domain_exit();
-}
-
-rootfs_initcall(nhi_init);
-module_exit(nhi_unload);
+module_pci_driver(nhi_driver);
diff --git a/drivers/thunderbolt/plat.c b/drivers/thunderbolt/plat.c
new file mode 100644
index 000000000000..85a00cd391d4
--- /dev/null
+++ b/drivers/thunderbolt/plat.c
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Thunderbolt driver - NHI driver (Platform bus specific implementation)
+ *
+ * Author: Chunfeng Yun <chunfeng.yun@mediatek.com>
+ */
+
+#include <linux/acpi.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+
+#include "nhi.h"
+#include "tb.h"
+
+static int nhi_plat_init(struct tb_nhi *nhi)
+{
+ /*
+ * avoid device link fail for pcie tunnel
+ */
+ pm_runtime_set_active(nhi->dev);
+ pm_runtime_get_noresume(nhi->dev);
+ devm_pm_runtime_enable(nhi->dev);
+
+ return 0;
+}
+
+static irqreturn_t nhi_plat_isr(int irq, void *data)
+{
+ struct tb_nhi *nhi = data;
+ schedule_work(&nhi->interrupt_work);
+ return IRQ_HANDLED;
+}
+
+static int nhi_plat_init_irq(struct tb_nhi *nhi)
+{
+ int ret;
+
+ INIT_WORK(&nhi->interrupt_work, nhi_interrupt_work);
+
+ ret = devm_request_irq(nhi->dev, nhi->irq, nhi_plat_isr, IRQF_NO_SUSPEND,
+ dev_name(nhi->dev), nhi);
+ if (ret)
+ return dev_err_probe(nhi->dev, ret, "request irq failed\n");
+
+ return 0;
+}
+
+static void nhi_plat_exit(struct tb_nhi *nhi)
+{
+ devm_free_irq(nhi->dev, nhi->irq, nhi);
+ flush_work(&nhi->interrupt_work);
+
+ pm_runtime_put_noidle(nhi->dev);
+ pm_runtime_disable(nhi->dev);
+ pm_runtime_set_suspended(nhi->dev);
+}
+
+static const struct tb_nhi_ops nhi_plat_default_ops = {
+ .init = nhi_plat_init,
+ .shutdown = nhi_plat_exit,
+ .init_interrupts = nhi_plat_init_irq,
+};
+
+static int nhi_plat_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct tb_nhi *nhi;
+
+ nhi = devm_kzalloc(dev, sizeof(*nhi), GFP_KERNEL);
+ if (!nhi)
+ return -ENOMEM;
+
+ nhi->dev = dev;
+ nhi->ops = &nhi_plat_default_ops;
+
+ nhi->iobase = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(nhi->iobase))
+ return PTR_ERR(nhi->iobase);
+
+ nhi->irq = platform_get_irq(pdev, 0);
+ if (nhi->irq < 0)
+ return dev_err_probe(dev, nhi->irq, "get irq failed\n");
+
+ return nhi_probe(nhi);
+}
+
+static void nhi_plat_do_remove(struct platform_device *pdev, bool reset)
+{
+ struct device *dev = &pdev->dev;
+ struct tb *tb = platform_get_drvdata(pdev);
+ struct tb_nhi *nhi = tb->nhi;
+
+ /*
+ * On system shutdown/reboot force a host router reset so the
+ * CM asserts DPR on connected tbt3 devices before the router tree
+ * is removed (see tb_stop()).
+ */
+ if (reset)
+ nhi->host_reset = true;
+
+ pm_runtime_get_sync(dev);
+ pm_runtime_dont_use_autosuspend(dev);
+
+ tb_domain_remove(tb);
+ wait_for_completion(&nhi->domain_released);
+ nhi_shutdown(nhi);
+}
+
+static void nhi_plat_remove(struct platform_device *pdev)
+{
+ nhi_plat_do_remove(pdev, false);
+}
+
+static void nhi_plat_shutdown(struct platform_device *pdev)
+{
+ nhi_plat_do_remove(pdev, true);
+}
+
+
+#ifdef CONFIG_OF
+static const struct of_device_id nhi_plat_of_match[] = {
+ { .compatible = "thunderbolt-platform" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, nhi_plat_of_match);
+#endif
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id nhi_plat_acpi_match[] = {
+ { "ACPI0015", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, nhi_plat_acpi_match);
+#endif
+
+static struct platform_driver nhi_plat_driver = {
+ .probe = nhi_plat_probe,
+ .remove = nhi_plat_remove,
+ .shutdown = nhi_plat_shutdown,
+ .driver = {
+ .name = "thunderbolt",
+ .of_match_table = of_match_ptr(nhi_plat_of_match),
+ .acpi_match_table = ACPI_PTR(nhi_plat_acpi_match),
+ .pm = &nhi_pm_ops,
+ },
+};
+
+module_platform_driver(nhi_plat_driver);
+MODULE_ALIAS("platform:thunderbolt");
+MODULE_DESCRIPTION("Thunderbolt/USB4 platform host interface driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index e86845762e22..6dfdc47e05d2 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -768,8 +768,6 @@ extern const struct device_type tb_retimer_type;
extern const struct device_type tb_switch_type;
extern const struct device_type usb4_port_device_type;
-int tb_domain_init(void);
-void tb_domain_exit(void);
int tb_xdomain_init(void);
void tb_xdomain_exit(void);
diff --git a/include/linux/thunderbolt.h b/include/linux/thunderbolt.h
index 57502da29080..212c8fea6571 100644
--- a/include/linux/thunderbolt.h
+++ b/include/linux/thunderbolt.h
@@ -532,6 +532,7 @@ struct tb_nhi {
u32 *interrupt_mask;
bool going_away;
bool iommu_dma_protection;
+ int irq;
struct work_struct interrupt_work;
u32 hop_count;
unsigned long quirks;
--
2.43.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/4] thunderbolt: add support optional dedicated wakeup irq
2026-10-30 8:25 [PATCH 0/4] add support platform nhi driver Chunfeng Yun
2026-10-30 8:25 ` [PATCH 1/4] thunderbolt: add " Chunfeng Yun
@ 2026-10-30 8:25 ` Chunfeng Yun
2026-10-30 8:48 ` Mika Westerberg
2026-10-30 8:25 ` [PATCH 3/4] thunderbolt: improve usb3 adapter link up timeout value Chunfeng Yun
2026-10-30 8:25 ` [PATCH 4/4] thunderbolt: prevent pcie tunnel activation/teardown warnings Chunfeng Yun
3 siblings, 1 reply; 9+ messages in thread
From: Chunfeng Yun @ 2026-10-30 8:25 UTC (permalink / raw)
To: Mika Westerberg
Cc: Andreas Noever, Yehezkel Bernat, Matthias Brugger,
Greg Kroah-Hartman, AngeloGioacchino Del Regno, linux-kernel,
linux-usb, linux-arm-kernel, linux-mediatek, Chunfeng Yun
There is a dedicated wakeup irq on nvidia n1/n2 SoCs.
Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
---
drivers/thunderbolt/plat.c | 16 ++++++++++++++++
include/linux/thunderbolt.h | 1 +
2 files changed, 17 insertions(+)
diff --git a/drivers/thunderbolt/plat.c b/drivers/thunderbolt/plat.c
index 85a00cd391d4..8d83b484d942 100644
--- a/drivers/thunderbolt/plat.c
+++ b/drivers/thunderbolt/plat.c
@@ -11,6 +11,7 @@
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/pm_wakeirq.h>
#include <linux/slab.h>
#include "nhi.h"
@@ -46,6 +47,15 @@ static int nhi_plat_init_irq(struct tb_nhi *nhi)
if (ret)
return dev_err_probe(nhi->dev, ret, "request irq failed\n");
+ if (nhi->wake_irq) {
+ ret = dev_pm_set_dedicated_wake_irq(nhi->dev, nhi->wake_irq);
+ if (ret) {
+ dev_err_probe(nhi->dev, ret, "set wake irq %d failed\n", nhi->wake_irq);
+ return ret;
+ }
+ dev_info(nhi->dev, "wake irq %d\n", nhi->wake_irq);
+ }
+
return 0;
}
@@ -53,6 +63,7 @@ static void nhi_plat_exit(struct tb_nhi *nhi)
{
devm_free_irq(nhi->dev, nhi->irq, nhi);
flush_work(&nhi->interrupt_work);
+ dev_pm_clear_wake_irq(nhi->dev);
pm_runtime_put_noidle(nhi->dev);
pm_runtime_disable(nhi->dev);
@@ -85,6 +96,11 @@ static int nhi_plat_probe(struct platform_device *pdev)
if (nhi->irq < 0)
return dev_err_probe(dev, nhi->irq, "get irq failed\n");
+ /* ignore error */
+ nhi->wake_irq = platform_get_irq_optional(pdev, 1);
+ if (nhi->wake_irq < 0)
+ nhi->wake_irq = 0;
+
return nhi_probe(nhi);
}
diff --git a/include/linux/thunderbolt.h b/include/linux/thunderbolt.h
index 212c8fea6571..06b90d452ee2 100644
--- a/include/linux/thunderbolt.h
+++ b/include/linux/thunderbolt.h
@@ -533,6 +533,7 @@ struct tb_nhi {
bool going_away;
bool iommu_dma_protection;
int irq;
+ int wake_irq;
struct work_struct interrupt_work;
u32 hop_count;
unsigned long quirks;
--
2.43.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 3/4] thunderbolt: improve usb3 adapter link up timeout value
2026-10-30 8:25 [PATCH 0/4] add support platform nhi driver Chunfeng Yun
2026-10-30 8:25 ` [PATCH 1/4] thunderbolt: add " Chunfeng Yun
2026-10-30 8:25 ` [PATCH 2/4] thunderbolt: add support optional dedicated wakeup irq Chunfeng Yun
@ 2026-10-30 8:25 ` Chunfeng Yun
2026-10-30 8:50 ` Mika Westerberg
2026-10-30 8:25 ` [PATCH 4/4] thunderbolt: prevent pcie tunnel activation/teardown warnings Chunfeng Yun
3 siblings, 1 reply; 9+ messages in thread
From: Chunfeng Yun @ 2026-10-30 8:25 UTC (permalink / raw)
To: Mika Westerberg
Cc: Andreas Noever, Yehezkel Bernat, Matthias Brugger,
Greg Kroah-Hartman, AngeloGioacchino Del Regno, linux-kernel,
linux-usb, linux-arm-kernel, linux-mediatek, Chunfeng Yun
when plug into a usb3 device into usb4 hub's DFP to trigger usb4
driver wakeup, encounter usb3 link up timeout issue, then cause
usb3 hub disconnect:
usb4_hi NVDA8100:00: 0:1: failed to reach state TB_PORT_UP. Ignoring port...
usb4_hi NVDA8100:00: 0:1: lost during suspend, disconnecting
usb4_hi NVDA8100:00: 0:4 <-> 1:20 (USB3): deactivating
usb4_hi NVDA8100:00: deactivating USB3 Down path from 0:4 to 1:20
usb4_hi NVDA8100:00: deactivating USB3 Up path from 1:20 to 0:4
...
thunderbolt 0-1: device disconnected
usb 2-1: USB disconnect, device number 10
Completes link training at ~1.48s and transitions to TB_PORT_UP after
change the timeout to 2.5s:
In the USB4 spec, Phase 5 (Link Equalization) alone is allowed up to
1000 ms. When add tPhase3 (100 ms), tPhase4 (100 ms), and retimer
transaction delays (tCmdResponse = 50 ms), the physical link is
allowed by spec to take 1200 ms to 1500 ms+ to complete initialization.
here are two retimers in the link, if more retimers add it, need more
time
Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
---
drivers/thunderbolt/switch.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index d22d8db8f890..e7ee9639c54c 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -500,8 +500,9 @@ int tb_port_state(struct tb_port *port)
*/
int tb_wait_for_port(struct tb_port *port, bool wait_if_unplugged)
{
- int retries = 10;
+ int retries = 25;
int state;
+
if (!port->cap_phy) {
tb_port_WARN(port, "does not have PHY\n");
return -EINVAL;
--
2.43.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 4/4] thunderbolt: prevent pcie tunnel activation/teardown warnings
2026-10-30 8:25 [PATCH 0/4] add support platform nhi driver Chunfeng Yun
` (2 preceding siblings ...)
2026-10-30 8:25 ` [PATCH 3/4] thunderbolt: improve usb3 adapter link up timeout value Chunfeng Yun
@ 2026-10-30 8:25 ` Chunfeng Yun
2026-10-30 8:56 ` Mika Westerberg
3 siblings, 1 reply; 9+ messages in thread
From: Chunfeng Yun @ 2026-10-30 8:25 UTC (permalink / raw)
To: Mika Westerberg
Cc: Andreas Noever, Yehezkel Bernat, Matthias Brugger,
Greg Kroah-Hartman, AngeloGioacchino Del Regno, linux-kernel,
linux-usb, linux-arm-kernel, linux-mediatek, Chunfeng Yun
When usb4 enter sleep mode, echo 1 to authorized of sysfile,
will wakeup usb4 driver, but fail to create pcie tunnel, cause
the warning due to a race condition between switch disconnect
during resume and user authorization
When usb4 enter sleep mode, echo 0 to authorized of sysfile,
will wakeup usb4 driver, but fail to disconnect pcie due to
the PCIe tunnel had already been torn down and freed if the port
is fail to resume:
The check prevents a redundant lookup and eliminates the warning
Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
---
drivers/thunderbolt/switch.c | 5 +++++
drivers/thunderbolt/tb.c | 7 +++++++
2 files changed, 12 insertions(+)
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index e7ee9639c54c..7902172f4e99 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -1849,6 +1849,11 @@ static int tb_switch_set_authorized(struct tb_switch *sw, unsigned int val)
if (!!sw->authorized == !!val)
goto unlock;
+ if (sw->is_unplugged) {
+ ret = -ENODEV;
+ goto unlock;
+ }
+
switch (val) {
/* Disapprove switch */
case 0:
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
index 57c11ba13459..69310622d786 100644
--- a/drivers/thunderbolt/tb.c
+++ b/drivers/thunderbolt/tb.c
@@ -2266,6 +2266,10 @@ static int tb_disconnect_pci(struct tb *tb, struct tb_switch *sw)
struct tb_tunnel *tunnel;
struct tb_port *up;
+ /* If the switch has already been unplugged, tunnels are already freed */
+ if (sw->is_unplugged)
+ return 0;
+
up = tb_switch_find_port(sw, TB_TYPE_PCIE_UP);
if (WARN_ON(!up))
return -ENODEV;
@@ -2288,6 +2292,9 @@ static int tb_tunnel_pci(struct tb *tb, struct tb_switch *sw)
struct tb_cm *tcm = tb_priv(tb);
struct tb_tunnel *tunnel;
+ if (sw->is_unplugged)
+ return -ENODEV;
+
up = tb_switch_find_port(sw, TB_TYPE_PCIE_UP);
if (!up)
return 0;
--
2.43.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/4] thunderbolt: add platform nhi driver
2026-10-30 8:25 ` [PATCH 1/4] thunderbolt: add " Chunfeng Yun
@ 2026-10-30 8:47 ` Mika Westerberg
0 siblings, 0 replies; 9+ messages in thread
From: Mika Westerberg @ 2026-10-30 8:47 UTC (permalink / raw)
To: Chunfeng Yun
Cc: Mika Westerberg, Andreas Noever, Yehezkel Bernat,
Matthias Brugger, Greg Kroah-Hartman, AngeloGioacchino Del Regno,
linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek,
Konrad Dybcio, Sven Peter
Hi,
Adding Konrad and Sven because they are also working towards the same goal
to get non-PCIe "platform" hosts supported.
On Fri, Oct 30, 2026 at 04:25:36PM +0800, Chunfeng Yun wrote:
> Add a new file plat.c to register platform NHI driver for MediaTek
> mt8901/mt8992 SoCs.
>
> Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
> ---
> drivers/thunderbolt/Makefile | 2 +-
> drivers/thunderbolt/domain.c | 10 ++-
> drivers/thunderbolt/nhi.c | 2 +
> drivers/thunderbolt/nhi.h | 1 -
> drivers/thunderbolt/pci.c | 26 +-----
> drivers/thunderbolt/plat.c | 155 +++++++++++++++++++++++++++++++++++
Call it platform.c
> drivers/thunderbolt/tb.h | 2 -
> include/linux/thunderbolt.h | 1 +
> 8 files changed, 169 insertions(+), 30 deletions(-)
> create mode 100644 drivers/thunderbolt/plat.c
>
> diff --git a/drivers/thunderbolt/Makefile b/drivers/thunderbolt/Makefile
> index beb054c3126b..9c941682f3d6 100644
> --- a/drivers/thunderbolt/Makefile
> +++ b/drivers/thunderbolt/Makefile
> @@ -3,7 +3,7 @@ ccflags-y := -I$(src)
> obj-${CONFIG_USB4} := thunderbolt.o
> thunderbolt-objs := nhi.o ctl.o tb.o switch.o cap.o pci.o path.o tunnel.o eeprom.o
> thunderbolt-objs += domain.o dma_port.o icm.o property.o xdomain.o lc.o tmu.o usb4.o
> -thunderbolt-objs += usb4_port.o nvm.o retimer.o quirks.o clx.o
> +thunderbolt-objs += usb4_port.o nvm.o retimer.o quirks.o clx.o plat.o
>
> thunderbolt-${CONFIG_ACPI} += acpi.o
> thunderbolt-$(CONFIG_DEBUG_FS) += debugfs.o
> diff --git a/drivers/thunderbolt/domain.c b/drivers/thunderbolt/domain.c
> index 24611f05b3cd..bec7e6ebc4a8 100644
> --- a/drivers/thunderbolt/domain.c
> +++ b/drivers/thunderbolt/domain.c
> @@ -881,7 +881,7 @@ int tb_domain_unregister_unplugged_xdomains(struct tb *tb)
> return ctx.n;
> }
>
> -int tb_domain_init(void)
> +static int __init tb_domain_init(void)
> {
> int ret;
>
> @@ -907,7 +907,7 @@ int tb_domain_init(void)
> return ret;
> }
>
> -void tb_domain_exit(void)
> +static void __exit tb_domain_exit(void)
> {
> bus_unregister(&tb_bus_type);
> ida_destroy(&tb_domain_ida);
> @@ -917,3 +917,9 @@ void tb_domain_exit(void)
> tb_debugfs_exit();
> tb_configfs_exit();
> }
> +
> +subsys_initcall(tb_domain_init);
> +module_exit(tb_domain_exit);
> +
> +MODULE_DESCRIPTION("Thunderbolt/USB4 domain driver");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c
> index e99a3fcc4a29..c0f9f1855e8f 100644
> --- a/drivers/thunderbolt/nhi.c
> +++ b/drivers/thunderbolt/nhi.c
> @@ -1379,8 +1379,10 @@ int nhi_probe(struct tb_nhi *nhi)
> device_wakeup_enable(dev);
>
> pm_runtime_allow(dev);
> + device_enable_async_suspend(dev);
Why you add this?
> pm_runtime_set_autosuspend_delay(dev, TB_AUTOSUSPEND_DELAY);
> pm_runtime_use_autosuspend(dev);
> + pm_runtime_mark_last_busy(dev);
and this
> pm_runtime_put_autosuspend(dev);
>
> return 0;
> diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h
> index 88af9ab9fde7..37c11de167ad 100644
> --- a/drivers/thunderbolt/nhi.h
> +++ b/drivers/thunderbolt/nhi.h
> @@ -29,7 +29,6 @@ enum nhi_mailbox_cmd {
>
> int nhi_mailbox_cmd(struct tb_nhi *nhi, enum nhi_mailbox_cmd cmd, u32 data);
> enum nhi_fw_mode nhi_mailbox_mode(struct tb_nhi *nhi);
> -void nhi_enable_int_throttling(struct tb_nhi *nhi);
> void nhi_disable_interrupts(struct tb_nhi *nhi);
> void nhi_interrupt_work(struct work_struct *work);
> irqreturn_t nhi_msi(int irq, void *data);
> diff --git a/drivers/thunderbolt/pci.c b/drivers/thunderbolt/pci.c
> index 4408229d8ac7..91d236300703 100644
> --- a/drivers/thunderbolt/pci.c
> +++ b/drivers/thunderbolt/pci.c
> @@ -715,7 +715,7 @@ static struct pci_device_id nhi_ids[] = {
> };
>
> MODULE_DEVICE_TABLE(pci, nhi_ids);
> -MODULE_DESCRIPTION("Thunderbolt/USB4 core driver");
> +MODULE_DESCRIPTION("Thunderbolt/USB4 PCI host interface driver");
> MODULE_LICENSE("GPL");
>
> static struct pci_driver nhi_driver = {
> @@ -727,26 +727,4 @@ static struct pci_driver nhi_driver = {
> .driver.pm = &nhi_pm_ops,
> };
>
> -static int __init nhi_init(void)
> -{
> - int ret;
> -
> - ret = tb_domain_init();
> - if (ret)
> - return ret;
> -
> - ret = pci_register_driver(&nhi_driver);
> - if (ret)
> - tb_domain_exit();
> -
> - return ret;
> -}
> -
> -static void __exit nhi_unload(void)
> -{
> - pci_unregister_driver(&nhi_driver);
> - tb_domain_exit();
> -}
> -
> -rootfs_initcall(nhi_init);
> -module_exit(nhi_unload);
> +module_pci_driver(nhi_driver);
> diff --git a/drivers/thunderbolt/plat.c b/drivers/thunderbolt/plat.c
> new file mode 100644
> index 000000000000..85a00cd391d4
> --- /dev/null
> +++ b/drivers/thunderbolt/plat.c
> @@ -0,0 +1,155 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Thunderbolt driver - NHI driver (Platform bus specific implementation)
> + *
> + * Author: Chunfeng Yun <chunfeng.yun@mediatek.com>
> + */
> +
> +#include <linux/acpi.h>
> +#include <linux/interrupt.h>
> +#include <linux/errno.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/slab.h>
> +
> +#include "nhi.h"
> +#include "tb.h"
> +
> +static int nhi_plat_init(struct tb_nhi *nhi)
nhi_platform_
> +{
> + /*
> + * avoid device link fail for pcie tunnel
> + */
What's this? And the comment style is not the expected.
> + pm_runtime_set_active(nhi->dev);
> + pm_runtime_get_noresume(nhi->dev);
> + devm_pm_runtime_enable(nhi->dev);
This means we never runtime suspend? Then this is not good.
> +
> + return 0;
> +}
> +
> +static irqreturn_t nhi_plat_isr(int irq, void *data)
> +{
> + struct tb_nhi *nhi = data;
Did you run checkpatch.pl against this? If not please do.
> + schedule_work(&nhi->interrupt_work);
> + return IRQ_HANDLED;
> +}
> +
> +static int nhi_plat_init_irq(struct tb_nhi *nhi)
> +{
> + int ret;
> +
> + INIT_WORK(&nhi->interrupt_work, nhi_interrupt_work);
> +
> + ret = devm_request_irq(nhi->dev, nhi->irq, nhi_plat_isr, IRQF_NO_SUSPEND,
> + dev_name(nhi->dev), nhi);
> + if (ret)
> + return dev_err_probe(nhi->dev, ret, "request irq failed\n");
> +
> + return 0;
> +}
> +
> +static void nhi_plat_exit(struct tb_nhi *nhi)
> +{
> + devm_free_irq(nhi->dev, nhi->irq, nhi);
> + flush_work(&nhi->interrupt_work);
> +
> + pm_runtime_put_noidle(nhi->dev);
> + pm_runtime_disable(nhi->dev);
> + pm_runtime_set_suspended(nhi->dev);
> +}
> +
> +static const struct tb_nhi_ops nhi_plat_default_ops = {
> + .init = nhi_plat_init,
> + .shutdown = nhi_plat_exit,
> + .init_interrupts = nhi_plat_init_irq,
> +};
> +
> +static int nhi_plat_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct tb_nhi *nhi;
> +
> + nhi = devm_kzalloc(dev, sizeof(*nhi), GFP_KERNEL);
> + if (!nhi)
> + return -ENOMEM;
> +
> + nhi->dev = dev;
> + nhi->ops = &nhi_plat_default_ops;
> +
> + nhi->iobase = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(nhi->iobase))
> + return PTR_ERR(nhi->iobase);
> +
> + nhi->irq = platform_get_irq(pdev, 0);
> + if (nhi->irq < 0)
> + return dev_err_probe(dev, nhi->irq, "get irq failed\n");
> +
> + return nhi_probe(nhi);
> +}
> +
> +static void nhi_plat_do_remove(struct platform_device *pdev, bool reset)
> +{
> + struct device *dev = &pdev->dev;
> + struct tb *tb = platform_get_drvdata(pdev);
> + struct tb_nhi *nhi = tb->nhi;
> +
> + /*
> + * On system shutdown/reboot force a host router reset so the
> + * CM asserts DPR on connected tbt3 devices before the router tree
> + * is removed (see tb_stop()).
> + */
> + if (reset)
> + nhi->host_reset = true;
> +
> + pm_runtime_get_sync(dev);
> + pm_runtime_dont_use_autosuspend(dev);
> +
> + tb_domain_remove(tb);
> + wait_for_completion(&nhi->domain_released);
> + nhi_shutdown(nhi);
> +}
> +
> +static void nhi_plat_remove(struct platform_device *pdev)
> +{
> + nhi_plat_do_remove(pdev, false);
> +}
> +
> +static void nhi_plat_shutdown(struct platform_device *pdev)
> +{
> + nhi_plat_do_remove(pdev, true);
> +}
> +
> +
> +#ifdef CONFIG_OF
> +static const struct of_device_id nhi_plat_of_match[] = {
> + { .compatible = "thunderbolt-platform" },
Not sure if this is correct? Should this have mediatek,... ?
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, nhi_plat_of_match);
> +#endif
> +
> +#ifdef CONFIG_ACPI
> +static const struct acpi_device_id nhi_plat_acpi_match[] = {
> + { "ACPI0015", 0 },
Same here, where is this ID defined in the ACPI spec?
> + { }
> +};
> +MODULE_DEVICE_TABLE(acpi, nhi_plat_acpi_match);
> +#endif
> +
> +static struct platform_driver nhi_plat_driver = {
> + .probe = nhi_plat_probe,
> + .remove = nhi_plat_remove,
> + .shutdown = nhi_plat_shutdown,
> + .driver = {
> + .name = "thunderbolt",
> + .of_match_table = of_match_ptr(nhi_plat_of_match),
> + .acpi_match_table = ACPI_PTR(nhi_plat_acpi_match),
> + .pm = &nhi_pm_ops,
> + },
> +};
> +
> +module_platform_driver(nhi_plat_driver);
> +MODULE_ALIAS("platform:thunderbolt");
> +MODULE_DESCRIPTION("Thunderbolt/USB4 platform host interface driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
> index e86845762e22..6dfdc47e05d2 100644
> --- a/drivers/thunderbolt/tb.h
> +++ b/drivers/thunderbolt/tb.h
> @@ -768,8 +768,6 @@ extern const struct device_type tb_retimer_type;
> extern const struct device_type tb_switch_type;
> extern const struct device_type usb4_port_device_type;
>
> -int tb_domain_init(void);
> -void tb_domain_exit(void);
> int tb_xdomain_init(void);
> void tb_xdomain_exit(void);
>
> diff --git a/include/linux/thunderbolt.h b/include/linux/thunderbolt.h
> index 57502da29080..212c8fea6571 100644
> --- a/include/linux/thunderbolt.h
> +++ b/include/linux/thunderbolt.h
> @@ -532,6 +532,7 @@ struct tb_nhi {
> u32 *interrupt_mask;
> bool going_away;
> bool iommu_dma_protection;
> + int irq;
You are missing kernel-doc.
> struct work_struct interrupt_work;
> u32 hop_count;
> unsigned long quirks;
> --
> 2.43.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/4] thunderbolt: add support optional dedicated wakeup irq
2026-10-30 8:25 ` [PATCH 2/4] thunderbolt: add support optional dedicated wakeup irq Chunfeng Yun
@ 2026-10-30 8:48 ` Mika Westerberg
0 siblings, 0 replies; 9+ messages in thread
From: Mika Westerberg @ 2026-10-30 8:48 UTC (permalink / raw)
To: Chunfeng Yun
Cc: Mika Westerberg, Andreas Noever, Yehezkel Bernat,
Matthias Brugger, Greg Kroah-Hartman, AngeloGioacchino Del Regno,
linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek
On Fri, Oct 30, 2026 at 04:25:37PM +0800, Chunfeng Yun wrote:
> There is a dedicated wakeup irq on nvidia n1/n2 SoCs.
Okay but why it is needed? Can you add this to the commit message?
And why you did not add it already in the first commit that added the
platform driver there anyway?
>
> Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
> ---
> drivers/thunderbolt/plat.c | 16 ++++++++++++++++
> include/linux/thunderbolt.h | 1 +
> 2 files changed, 17 insertions(+)
>
> diff --git a/drivers/thunderbolt/plat.c b/drivers/thunderbolt/plat.c
> index 85a00cd391d4..8d83b484d942 100644
> --- a/drivers/thunderbolt/plat.c
> +++ b/drivers/thunderbolt/plat.c
> @@ -11,6 +11,7 @@
> #include <linux/of.h>
> #include <linux/platform_device.h>
> #include <linux/pm_runtime.h>
> +#include <linux/pm_wakeirq.h>
> #include <linux/slab.h>
>
> #include "nhi.h"
> @@ -46,6 +47,15 @@ static int nhi_plat_init_irq(struct tb_nhi *nhi)
> if (ret)
> return dev_err_probe(nhi->dev, ret, "request irq failed\n");
>
> + if (nhi->wake_irq) {
> + ret = dev_pm_set_dedicated_wake_irq(nhi->dev, nhi->wake_irq);
> + if (ret) {
> + dev_err_probe(nhi->dev, ret, "set wake irq %d failed\n", nhi->wake_irq);
> + return ret;
> + }
> + dev_info(nhi->dev, "wake irq %d\n", nhi->wake_irq);
> + }
> +
> return 0;
> }
>
> @@ -53,6 +63,7 @@ static void nhi_plat_exit(struct tb_nhi *nhi)
> {
> devm_free_irq(nhi->dev, nhi->irq, nhi);
> flush_work(&nhi->interrupt_work);
> + dev_pm_clear_wake_irq(nhi->dev);
>
> pm_runtime_put_noidle(nhi->dev);
> pm_runtime_disable(nhi->dev);
> @@ -85,6 +96,11 @@ static int nhi_plat_probe(struct platform_device *pdev)
> if (nhi->irq < 0)
> return dev_err_probe(dev, nhi->irq, "get irq failed\n");
>
> + /* ignore error */
> + nhi->wake_irq = platform_get_irq_optional(pdev, 1);
> + if (nhi->wake_irq < 0)
> + nhi->wake_irq = 0;
> +
> return nhi_probe(nhi);
> }
>
> diff --git a/include/linux/thunderbolt.h b/include/linux/thunderbolt.h
> index 212c8fea6571..06b90d452ee2 100644
> --- a/include/linux/thunderbolt.h
> +++ b/include/linux/thunderbolt.h
> @@ -533,6 +533,7 @@ struct tb_nhi {
> bool going_away;
> bool iommu_dma_protection;
> int irq;
> + int wake_irq;
> struct work_struct interrupt_work;
> u32 hop_count;
> unsigned long quirks;
> --
> 2.43.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/4] thunderbolt: improve usb3 adapter link up timeout value
2026-10-30 8:25 ` [PATCH 3/4] thunderbolt: improve usb3 adapter link up timeout value Chunfeng Yun
@ 2026-10-30 8:50 ` Mika Westerberg
0 siblings, 0 replies; 9+ messages in thread
From: Mika Westerberg @ 2026-10-30 8:50 UTC (permalink / raw)
To: Chunfeng Yun
Cc: Mika Westerberg, Andreas Noever, Yehezkel Bernat,
Matthias Brugger, Greg Kroah-Hartman, AngeloGioacchino Del Regno,
linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek
On Fri, Oct 30, 2026 at 04:25:38PM +0800, Chunfeng Yun wrote:
> when plug into a usb3 device into usb4 hub's DFP to trigger usb4
USB 3 device into USB4 hub's downstream facing port to ...
> driver wakeup, encounter usb3 link up timeout issue, then cause
> usb3 hub disconnect:
>
> usb4_hi NVDA8100:00: 0:1: failed to reach state TB_PORT_UP. Ignoring port...
> usb4_hi NVDA8100:00: 0:1: lost during suspend, disconnecting
> usb4_hi NVDA8100:00: 0:4 <-> 1:20 (USB3): deactivating
> usb4_hi NVDA8100:00: deactivating USB3 Down path from 0:4 to 1:20
> usb4_hi NVDA8100:00: deactivating USB3 Up path from 1:20 to 0:4
> ...
> thunderbolt 0-1: device disconnected
> usb 2-1: USB disconnect, device number 10
>
> Completes link training at ~1.48s and transitions to TB_PORT_UP after
> change the timeout to 2.5s:
>
> In the USB4 spec, Phase 5 (Link Equalization) alone is allowed up to
> 1000 ms. When add tPhase3 (100 ms), tPhase4 (100 ms), and retimer
> transaction delays (tCmdResponse = 50 ms), the physical link is
> allowed by spec to take 1200 ms to 1500 ms+ to complete initialization.
>
> here are two retimers in the link, if more retimers add it, need more
> time
>
> Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
> ---
> drivers/thunderbolt/switch.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
> index d22d8db8f890..e7ee9639c54c 100644
> --- a/drivers/thunderbolt/switch.c
> +++ b/drivers/thunderbolt/switch.c
> @@ -500,8 +500,9 @@ int tb_port_state(struct tb_port *port)
> */
> int tb_wait_for_port(struct tb_port *port, bool wait_if_unplugged)
> {
> - int retries = 10;
> + int retries = 25;
> int state;
> +
This is unrelated change.
> if (!port->cap_phy) {
> tb_port_WARN(port, "does not have PHY\n");
> return -EINVAL;
> --
> 2.43.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 4/4] thunderbolt: prevent pcie tunnel activation/teardown warnings
2026-10-30 8:25 ` [PATCH 4/4] thunderbolt: prevent pcie tunnel activation/teardown warnings Chunfeng Yun
@ 2026-10-30 8:56 ` Mika Westerberg
0 siblings, 0 replies; 9+ messages in thread
From: Mika Westerberg @ 2026-10-30 8:56 UTC (permalink / raw)
To: Chunfeng Yun
Cc: Mika Westerberg, Andreas Noever, Yehezkel Bernat,
Matthias Brugger, Greg Kroah-Hartman, AngeloGioacchino Del Regno,
linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek
On Fri, Oct 30, 2026 at 04:25:39PM +0800, Chunfeng Yun wrote:
> When usb4 enter sleep mode, echo 1 to authorized of sysfile,
> will wakeup usb4 driver, but fail to create pcie tunnel, cause
> the warning due to a race condition between switch disconnect
It's router
> during resume and user authorization
>
> When usb4 enter sleep mode, echo 0 to authorized of sysfile,
> will wakeup usb4 driver, but fail to disconnect pcie due to
> the PCIe tunnel had already been torn down and freed if the port
> is fail to resume:
So this is runtime resume when there is no PCIe tunnel yet, the device is
unplugged and the userspace is at the same time writing to the "authorized"
attribute?
Then the PCIe tunnel creation fails as expected.
What warning you are trying to silence?
>
> The check prevents a redundant lookup and eliminates the warning
>
> Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
> ---
> drivers/thunderbolt/switch.c | 5 +++++
> drivers/thunderbolt/tb.c | 7 +++++++
> 2 files changed, 12 insertions(+)
>
> diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
> index e7ee9639c54c..7902172f4e99 100644
> --- a/drivers/thunderbolt/switch.c
> +++ b/drivers/thunderbolt/switch.c
> @@ -1849,6 +1849,11 @@ static int tb_switch_set_authorized(struct tb_switch *sw, unsigned int val)
> if (!!sw->authorized == !!val)
> goto unlock;
>
> + if (sw->is_unplugged) {
> + ret = -ENODEV;
> + goto unlock;
> + }
> +
> switch (val) {
> /* Disapprove switch */
> case 0:
> diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
> index 57c11ba13459..69310622d786 100644
> --- a/drivers/thunderbolt/tb.c
> +++ b/drivers/thunderbolt/tb.c
> @@ -2266,6 +2266,10 @@ static int tb_disconnect_pci(struct tb *tb, struct tb_switch *sw)
> struct tb_tunnel *tunnel;
> struct tb_port *up;
>
> + /* If the switch has already been unplugged, tunnels are already freed */
> + if (sw->is_unplugged)
> + return 0;
> +
> up = tb_switch_find_port(sw, TB_TYPE_PCIE_UP);
> if (WARN_ON(!up))
> return -ENODEV;
> @@ -2288,6 +2292,9 @@ static int tb_tunnel_pci(struct tb *tb, struct tb_switch *sw)
> struct tb_cm *tcm = tb_priv(tb);
> struct tb_tunnel *tunnel;
>
> + if (sw->is_unplugged)
> + return -ENODEV;
> +
> up = tb_switch_find_port(sw, TB_TYPE_PCIE_UP);
> if (!up)
> return 0;
> --
> 2.43.0
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-10-30 8:56 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-30 8:25 [PATCH 0/4] add support platform nhi driver Chunfeng Yun
2026-10-30 8:25 ` [PATCH 1/4] thunderbolt: add " Chunfeng Yun
2026-10-30 8:47 ` Mika Westerberg
2026-10-30 8:25 ` [PATCH 2/4] thunderbolt: add support optional dedicated wakeup irq Chunfeng Yun
2026-10-30 8:48 ` Mika Westerberg
2026-10-30 8:25 ` [PATCH 3/4] thunderbolt: improve usb3 adapter link up timeout value Chunfeng Yun
2026-10-30 8:50 ` Mika Westerberg
2026-10-30 8:25 ` [PATCH 4/4] thunderbolt: prevent pcie tunnel activation/teardown warnings Chunfeng Yun
2026-10-30 8:56 ` Mika Westerberg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®