* [PATCH] thunderbolt: Make PCIe NHI support opt-in
@ 2026-09-15 17:04 Konrad Dybcio
2026-09-16 7:11 ` Greg KH
2026-09-16 7:59 ` Mika Westerberg
0 siblings, 2 replies; 6+ messages in thread
From: Konrad Dybcio @ 2026-09-15 17:04 UTC (permalink / raw)
To: Andreas Noever, Mika Westerberg, Yehezkel Bernat
Cc: linux-usb, linux-kernel, usb4-upstream, Raghavendra Thoorpu,
Konrad Dybcio
From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
With more implementations coming in, one may desire not to enable
support for the PCIe-attached NHIs. Allow it to be built as a module
atop the framework.
Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
---
The diff came out a little messy.. compile-tested with CONFIG_PCI=n and
tested USB4_PCIE=m/=y on a NUC with an Alpine Ridge controller
---
drivers/thunderbolt/Kconfig | 11 ++++++++++-
drivers/thunderbolt/Makefile | 7 +++++--
drivers/thunderbolt/ctl.c | 6 +++++-
drivers/thunderbolt/domain.c | 14 ++++++++++++--
drivers/thunderbolt/nhi.c | 18 +++++++++++-------
drivers/thunderbolt/nhi.h | 2 ++
drivers/thunderbolt/pci.c | 39 ++++++++++++++-------------------------
drivers/thunderbolt/switch.c | 9 +++++++++
drivers/thunderbolt/tb.h | 2 --
drivers/thunderbolt/tunnel.c | 1 +
drivers/thunderbolt/xdomain.c | 5 +++++
11 files changed, 74 insertions(+), 40 deletions(-)
diff --git a/drivers/thunderbolt/Kconfig b/drivers/thunderbolt/Kconfig
index 294b3227a545..81fca3bfcdd7 100644
--- a/drivers/thunderbolt/Kconfig
+++ b/drivers/thunderbolt/Kconfig
@@ -1,7 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
menuconfig USB4
tristate "Unified support for USB4 and Thunderbolt"
- depends on PCI
select APPLE_PROPERTIES if EFI_STUB && X86
select CRC32
select CRYPTO_LIB_SHA256
@@ -18,6 +17,16 @@ menuconfig USB4
if USB4
+config USB4_PCIE
+ depends on PCI
+ tristate "Support for PCIe-attached USB4 and Thunderbolt controllers"
+ help
+ Say Y here to add support for the USB4 and Thunderbolt host
+ routers attached over the PCIe bus, commonly found on x86 PCs.
+
+ To compile this driver a module, choose M here. The module will be
+ called thunderbolt_pcie.
+
config USB4_CONFIGFS
def_tristate USB4
depends on CONFIGFS_FS && !(USB4=y && CONFIGFS_FS=m)
diff --git a/drivers/thunderbolt/Makefile b/drivers/thunderbolt/Makefile
index beb054c3126b..fc808c6b23e6 100644
--- a/drivers/thunderbolt/Makefile
+++ b/drivers/thunderbolt/Makefile
@@ -1,10 +1,13 @@
# SPDX-License-Identifier: GPL-2.0-only
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 := nhi.o ctl.o tb.o switch.o cap.o path.o tunnel.o eeprom.o
+thunderbolt-objs += domain.o dma_port.o property.o xdomain.o lc.o tmu.o usb4.o
thunderbolt-objs += usb4_port.o nvm.o retimer.o quirks.o clx.o
+obj-${CONFIG_USB4_PCIE} += thunderbolt_pcie.o
+thunderbolt_pcie-y := pci.o icm.o
+
thunderbolt-${CONFIG_ACPI} += acpi.o
thunderbolt-$(CONFIG_DEBUG_FS) += debugfs.o
thunderbolt-$(CONFIG_USB4_CONFIGFS) += configfs.o
diff --git a/drivers/thunderbolt/ctl.c b/drivers/thunderbolt/ctl.c
index 965988b18608..96717a0a94b1 100644
--- a/drivers/thunderbolt/ctl.c
+++ b/drivers/thunderbolt/ctl.c
@@ -9,7 +9,6 @@
#include <linux/crc32.h>
#include <linux/delay.h>
#include <linux/slab.h>
-#include <linux/pci.h>
#include <linux/dmapool.h>
#include <linux/workqueue.h>
@@ -96,6 +95,7 @@ struct tb_cfg_request *tb_cfg_request_alloc(void)
return req;
}
+EXPORT_SYMBOL_GPL(tb_cfg_request_alloc);
/**
* tb_cfg_request_get() - Increase refcount of a request
@@ -128,6 +128,7 @@ void tb_cfg_request_put(struct tb_cfg_request *req)
kref_put(&req->kref, tb_cfg_request_destroy);
mutex_unlock(&tb_cfg_request_lock);
}
+EXPORT_SYMBOL_GPL(tb_cfg_request_put);
static int tb_cfg_request_enqueue(struct tb_ctl *ctl,
struct tb_cfg_request *req)
@@ -575,6 +576,7 @@ int tb_cfg_request(struct tb_ctl *ctl, struct tb_cfg_request *req,
tb_cfg_request_dequeue(req);
return ret;
}
+EXPORT_SYMBOL_GPL(tb_cfg_request);
/**
* tb_cfg_request_cancel() - Cancel a control request
@@ -634,6 +636,7 @@ struct tb_cfg_result tb_cfg_request_sync(struct tb_ctl *ctl,
return req->result;
}
+EXPORT_SYMBOL_GPL(tb_cfg_request_sync);
/* public interface, alloc/start/stop/free */
@@ -1009,6 +1012,7 @@ struct tb_cfg_result tb_cfg_read_raw(struct tb_ctl *ctl, void *buffer,
memcpy(buffer, &reply.data, 4 * length);
return res;
}
+EXPORT_SYMBOL_GPL(tb_cfg_read_raw);
/**
* tb_cfg_write_raw() - write from buffer into config space
diff --git a/drivers/thunderbolt/domain.c b/drivers/thunderbolt/domain.c
index 12c88509a54f..1c76fd8151ca 100644
--- a/drivers/thunderbolt/domain.c
+++ b/drivers/thunderbolt/domain.c
@@ -313,6 +313,7 @@ const struct bus_type tb_bus_type = {
.remove = tb_service_remove,
.shutdown = tb_service_shutdown,
};
+EXPORT_SYMBOL_GPL(tb_bus_type);
static void tb_domain_release(struct device *dev)
{
@@ -421,6 +422,7 @@ struct tb *tb_domain_alloc(struct tb_nhi *nhi, int timeout_msec, size_t privsize
return NULL;
}
+EXPORT_SYMBOL_GPL(tb_domain_alloc);
/**
* tb_domain_add() - Add domain to the system
@@ -514,6 +516,7 @@ void tb_domain_remove(struct tb *tb)
device_unregister(&tb->dev);
}
+EXPORT_SYMBOL_GPL(tb_domain_remove);
/**
* tb_domain_suspend_noirq() - Suspend a domain
@@ -904,8 +907,9 @@ int tb_domain_unregister_unplugged_xdomains(struct tb *tb)
return ctx.n;
}
+EXPORT_SYMBOL_GPL(tb_domain_unregister_unplugged_xdomains);
-int tb_domain_init(void)
+static int __init tb_domain_init(void)
{
int ret;
@@ -931,7 +935,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);
@@ -941,3 +945,9 @@ void tb_domain_exit(void)
tb_debugfs_exit();
tb_configfs_exit();
}
+
+postcore_initcall(tb_domain_init);
+module_exit(tb_domain_exit);
+
+MODULE_DESCRIPTION("Thunderbolt/USB4 core driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c
index 020db5a1f029..9b1165b2a484 100644
--- a/drivers/thunderbolt/nhi.c
+++ b/drivers/thunderbolt/nhi.c
@@ -548,6 +548,7 @@ irqreturn_t ring_msix(int irq, void *data)
return IRQ_HANDLED;
}
+EXPORT_SYMBOL_GPL(ring_msix);
static int nhi_alloc_hop(struct tb_nhi *nhi, struct tb_ring *ring)
{
@@ -1001,6 +1002,7 @@ int nhi_mailbox_cmd(struct tb_nhi *nhi, enum nhi_mailbox_cmd cmd, u32 data)
return 0;
}
+EXPORT_SYMBOL_GPL(nhi_mailbox_cmd);
/**
* nhi_mailbox_mode() - Return current firmware operation mode
@@ -1021,6 +1023,7 @@ enum nhi_fw_mode nhi_mailbox_mode(struct tb_nhi *nhi)
return (enum nhi_fw_mode)val;
}
+EXPORT_SYMBOL_GPL(nhi_mailbox_mode);
void nhi_interrupt_work(struct work_struct *work)
{
@@ -1071,6 +1074,7 @@ void nhi_interrupt_work(struct work_struct *work)
}
spin_unlock_irq(&nhi->lock);
}
+EXPORT_SYMBOL_GPL(nhi_interrupt_work);
irqreturn_t nhi_msi(int irq, void *data)
{
@@ -1078,6 +1082,7 @@ irqreturn_t nhi_msi(int irq, void *data)
schedule_work(&nhi->interrupt_work);
return IRQ_HANDLED;
}
+EXPORT_SYMBOL_GPL(nhi_msi);
static int __nhi_suspend_noirq(struct device *dev, bool wakeup)
{
@@ -1235,6 +1240,7 @@ void nhi_shutdown(struct tb_nhi *nhi)
if (nhi->ops->shutdown)
nhi->ops->shutdown(nhi);
}
+EXPORT_SYMBOL_GPL(nhi_shutdown);
static void nhi_reset(struct tb_nhi *nhi)
{
@@ -1292,6 +1298,7 @@ void nhi_reset_interface(struct tb_nhi *nhi)
/* Wait for tHIReset (10 ms) to complete */
usleep_range(10000, 20000);
}
+EXPORT_SYMBOL_GPL(nhi_reset_interface);
static struct tb *nhi_select_cm(struct tb_nhi *nhi)
{
@@ -1302,13 +1309,8 @@ static struct tb *nhi_select_cm(struct tb_nhi *nhi)
* USB4 case is simple. If we got control of any of the
* capabilities, we use software CM.
*/
- 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_acpi_is_native() && nhi->ops->select_cm) {
+ tb = nhi->ops->select_cm(nhi);
if (tb)
return tb;
}
@@ -1411,6 +1413,7 @@ int nhi_probe(struct tb_nhi *nhi)
return 0;
}
+EXPORT_SYMBOL_GPL(nhi_probe);
/*
* The tunneled pci bridges are siblings of us. Use resume_noirq to reenable
@@ -1433,3 +1436,4 @@ const struct dev_pm_ops nhi_pm_ops = {
.runtime_suspend = nhi_runtime_suspend,
.runtime_resume = nhi_runtime_resume,
};
+EXPORT_SYMBOL_GPL(nhi_pm_ops);
diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h
index b2e2e2c413b2..475ee8615edf 100644
--- a/drivers/thunderbolt/nhi.h
+++ b/drivers/thunderbolt/nhi.h
@@ -56,6 +56,7 @@ extern const struct dev_pm_ops nhi_pm_ops;
* @is_present: Whether the device is currently present on the parent bus
* @init_interrupts: NHI specific interrupt initialization hook
* @reset_interface: Resets the host interface
+ * @select_cm: optional hook to select a custom CM
*/
struct tb_nhi_ops {
int (*init)(struct tb_nhi *nhi);
@@ -72,6 +73,7 @@ struct tb_nhi_ops {
bool (*is_present)(struct tb_nhi *nhi);
int (*init_interrupts)(struct tb_nhi *nhi);
void (*reset_interface)(struct tb_nhi *nhi);
+ struct tb * (*select_cm)(struct tb_nhi *nhi);
};
/*
diff --git a/drivers/thunderbolt/pci.c b/drivers/thunderbolt/pci.c
index e40d4d6af071..f215ef7aa336 100644
--- a/drivers/thunderbolt/pci.c
+++ b/drivers/thunderbolt/pci.c
@@ -348,6 +348,16 @@ static bool nhi_pci_is_present(struct tb_nhi *nhi)
return pci_device_is_present(to_pci_dev(nhi->dev));
}
+static struct tb *nhi_pci_select_cm(struct tb_nhi *nhi)
+{
+ /*
+ * Either the firmware-based CM is running (we did not get
+ * control from the firmware) or this is a pre-USB4 PC, so
+ * first try using the firmware CM and then fallback to software CM.
+ */
+ return icm_probe(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,
@@ -358,6 +368,7 @@ static const struct tb_nhi_ops pci_nhi_default_ops = {
.is_present = nhi_pci_is_present,
.init_interrupts = nhi_pci_init_msi,
.reset_interface = nhi_reset_interface,
+ .select_cm = nhi_pci_select_cm,
};
/* Ice Lake specific NHI operations */
@@ -577,6 +588,7 @@ static const struct tb_nhi_ops icl_nhi_ops = {
.is_present = nhi_pci_is_present,
.init_interrupts = nhi_pci_init_msi,
.reset_interface = nhi_reset_interface,
+ .select_cm = nhi_pci_select_cm,
};
static int nhi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -738,7 +750,7 @@ static struct pci_device_id nhi_ids[] = {
};
MODULE_DEVICE_TABLE(pci, nhi_ids);
-MODULE_DESCRIPTION("Thunderbolt/USB4 core driver");
+MODULE_DESCRIPTION("PCIe-attached Thunderbolt/USB4 host interface driver");
MODULE_LICENSE("GPL");
static struct pci_driver nhi_driver = {
@@ -749,27 +761,4 @@ static struct pci_driver nhi_driver = {
.shutdown = nhi_pci_shutdown,
.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/switch.c b/drivers/thunderbolt/switch.c
index d22d8db8f890..7ff3da79da76 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -2396,6 +2396,7 @@ const struct device_type tb_switch_type = {
.uevent = tb_switch_uevent,
.pm = &tb_switch_pm_ops,
};
+EXPORT_SYMBOL_GPL(tb_switch_type);
static int tb_switch_get_generation(struct tb_switch *sw)
{
@@ -2571,6 +2572,7 @@ struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent,
return ERR_PTR(ret);
}
+EXPORT_SYMBOL_GPL(tb_switch_alloc);
/**
* tb_switch_alloc_safe_mode() - allocate a switch that is in safe mode
@@ -2610,6 +2612,7 @@ tb_switch_alloc_safe_mode(struct tb *tb, struct device *parent, u64 route)
return sw;
}
+EXPORT_SYMBOL_GPL(tb_switch_alloc_safe_mode);
/**
* tb_switch_configure() - Uploads configuration to the switch
@@ -3438,6 +3441,7 @@ int tb_switch_add(struct tb_switch *sw)
return ret;
}
+EXPORT_SYMBOL_GPL(tb_switch_add);
/**
* tb_switch_remove() - Remove and release a switch
@@ -3483,6 +3487,7 @@ void tb_switch_remove(struct tb_switch *sw)
dev_info(&sw->dev, "device disconnected\n");
device_unregister(&sw->dev);
}
+EXPORT_SYMBOL_GPL(tb_switch_remove);
/**
* tb_sw_set_unplugged() - set is_unplugged on switch and downstream switches
@@ -3828,6 +3833,7 @@ struct tb_switch *tb_switch_find_by_link_depth(struct tb *tb, u8 link, u8 depth)
return NULL;
}
+EXPORT_SYMBOL_GPL(tb_switch_find_by_link_depth);
/**
* tb_switch_find_by_uuid() - Find switch by UUID
@@ -3854,6 +3860,7 @@ struct tb_switch *tb_switch_find_by_uuid(struct tb *tb, const uuid_t *uuid)
return NULL;
}
+EXPORT_SYMBOL_GPL(tb_switch_find_by_uuid);
/**
* tb_switch_find_by_route() - Find switch by route string
@@ -3883,6 +3890,7 @@ struct tb_switch *tb_switch_find_by_route(struct tb *tb, u64 route)
return NULL;
}
+EXPORT_SYMBOL_GPL(tb_switch_find_by_route);
/**
* tb_switch_find_port() - return the first port of @type on @sw or NULL
@@ -3903,6 +3911,7 @@ struct tb_port *tb_switch_find_port(struct tb_switch *sw,
return NULL;
}
+EXPORT_SYMBOL_GPL(tb_switch_find_port);
/*
* Can be used for read/write a specified PCIe bridge for any Thunderbolt 3
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index c112954ce3fd..12dad4097a8f 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/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c
index ffd2d04b3bfa..fdaff55baead 100644
--- a/drivers/thunderbolt/tunnel.c
+++ b/drivers/thunderbolt/tunnel.c
@@ -273,6 +273,7 @@ void tb_tunnel_event(struct tb *tb, enum tb_tunnel_event event,
kfree(envp[1]);
kfree(envp[0]);
}
+EXPORT_SYMBOL_GPL(tb_tunnel_event);
static inline void tb_tunnel_set_active(struct tb_tunnel *tunnel, bool active)
{
diff --git a/drivers/thunderbolt/xdomain.c b/drivers/thunderbolt/xdomain.c
index b187a60663f5..af82b86a0348 100644
--- a/drivers/thunderbolt/xdomain.c
+++ b/drivers/thunderbolt/xdomain.c
@@ -86,6 +86,7 @@ bool tb_is_xdomain_enabled(void)
{
return tb_xdomain_enabled && tb_acpi_is_xdomain_allowed();
}
+EXPORT_SYMBOL_GPL(tb_is_xdomain_enabled);
static bool tb_xdomain_match(const struct tb_cfg_request *req,
const struct ctl_pkg *pkg)
@@ -2196,6 +2197,7 @@ struct tb_xdomain *tb_xdomain_alloc(struct tb *tb, struct device *parent,
return NULL;
}
+EXPORT_SYMBOL_GPL(tb_xdomain_alloc);
/**
* tb_xdomain_add() - Add XDomain to the bus
@@ -2211,6 +2213,7 @@ void tb_xdomain_add(struct tb_xdomain *xd)
/* Start exchanging properties with the other host */
start_handshake(xd);
}
+EXPORT_SYMBOL_GPL(tb_xdomain_add);
static int unregister_service(struct device *dev, void *data)
{
@@ -2270,6 +2273,7 @@ void tb_xdomain_unregister(struct tb_xdomain *xd)
dev_info(&xd->dev, "host disconnected\n");
device_unregister(&xd->dev);
}
+EXPORT_SYMBOL_GPL(tb_xdomain_remove);
/**
* tb_xdomain_lane_bonding_enable() - Enable lane bonding on XDomain
@@ -2593,6 +2597,7 @@ struct tb_xdomain *tb_xdomain_find_by_link_depth(struct tb *tb, u8 link,
xd = switch_find_xdomain(tb->root_switch, &lookup);
return tb_xdomain_get(xd);
}
+EXPORT_SYMBOL_GPL(tb_xdomain_find_by_link_depth);
/**
* tb_xdomain_find_by_route() - Find an XDomain by route string
---
base-commit: 1a1de54f7369cd2b5bac0f265910e60ad3a6b4c3
change-id: 20260915-topic-tbt_pcie_optional-2af6de7e47f3
Best regards,
--
Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] thunderbolt: Make PCIe NHI support opt-in
2026-09-15 17:04 [PATCH] thunderbolt: Make PCIe NHI support opt-in Konrad Dybcio
@ 2026-09-16 7:11 ` Greg KH
2026-09-16 8:08 ` Konrad Dybcio
2026-09-16 7:59 ` Mika Westerberg
1 sibling, 1 reply; 6+ messages in thread
From: Greg KH @ 2026-09-16 7:11 UTC (permalink / raw)
To: Konrad Dybcio
Cc: Andreas Noever, Mika Westerberg, Yehezkel Bernat, linux-usb,
linux-kernel, usb4-upstream, Raghavendra Thoorpu, Konrad Dybcio
On Tue, Sep 15, 2026 at 07:04:10PM +0200, Konrad Dybcio wrote:
> From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
>
> With more implementations coming in, one may desire not to enable
> support for the PCIe-attached NHIs. Allow it to be built as a module
> atop the framework.
>
> Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Why would you not want this? Can hardware not provide this for some
platforms? I thought it was part of the spec...
thanks,
greg k-h
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] thunderbolt: Make PCIe NHI support opt-in
2026-09-15 17:04 [PATCH] thunderbolt: Make PCIe NHI support opt-in Konrad Dybcio
2026-09-16 7:11 ` Greg KH
@ 2026-09-16 7:59 ` Mika Westerberg
2026-09-16 16:10 ` Konrad Dybcio
1 sibling, 1 reply; 6+ messages in thread
From: Mika Westerberg @ 2026-09-16 7:59 UTC (permalink / raw)
To: Konrad Dybcio
Cc: Andreas Noever, Mika Westerberg, Yehezkel Bernat, linux-usb,
linux-kernel, usb4-upstream, Raghavendra Thoorpu, Konrad Dybcio
Hi,
On Tue, Sep 15, 2026 at 07:04:10PM +0200, Konrad Dybcio wrote:
> From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
>
> With more implementations coming in, one may desire not to enable
> support for the PCIe-attached NHIs. Allow it to be built as a module
> atop the framework.
Is it so that Qualcomm platform does not support PCIe tunneling at all
then?
> Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
> ---
> The diff came out a little messy.. compile-tested with CONFIG_PCI=n and
> tested USB4_PCIE=m/=y on a NUC with an Alpine Ridge controller
> ---
> drivers/thunderbolt/Kconfig | 11 ++++++++++-
> drivers/thunderbolt/Makefile | 7 +++++--
> drivers/thunderbolt/ctl.c | 6 +++++-
> drivers/thunderbolt/domain.c | 14 ++++++++++++--
> drivers/thunderbolt/nhi.c | 18 +++++++++++-------
> drivers/thunderbolt/nhi.h | 2 ++
> drivers/thunderbolt/pci.c | 39 ++++++++++++++-------------------------
> drivers/thunderbolt/switch.c | 9 +++++++++
> drivers/thunderbolt/tb.h | 2 --
> drivers/thunderbolt/tunnel.c | 1 +
> drivers/thunderbolt/xdomain.c | 5 +++++
> 11 files changed, 74 insertions(+), 40 deletions(-)
>
> diff --git a/drivers/thunderbolt/Kconfig b/drivers/thunderbolt/Kconfig
> index 294b3227a545..81fca3bfcdd7 100644
> --- a/drivers/thunderbolt/Kconfig
> +++ b/drivers/thunderbolt/Kconfig
> @@ -1,7 +1,6 @@
> # SPDX-License-Identifier: GPL-2.0-only
> menuconfig USB4
> tristate "Unified support for USB4 and Thunderbolt"
> - depends on PCI
> select APPLE_PROPERTIES if EFI_STUB && X86
> select CRC32
> select CRYPTO_LIB_SHA256
> @@ -18,6 +17,16 @@ menuconfig USB4
>
> if USB4
>
> +config USB4_PCIE
> + depends on PCI
> + tristate "Support for PCIe-attached USB4 and Thunderbolt controllers"
I think USB4_PCI and so on.
> + help
> + Say Y here to add support for the USB4 and Thunderbolt host
> + routers attached over the PCIe bus, commonly found on x86 PCs.
> +
> + To compile this driver a module, choose M here. The module will be
> + called thunderbolt_pcie.
thunderbolt_pci
> +
> config USB4_CONFIGFS
> def_tristate USB4
> depends on CONFIGFS_FS && !(USB4=y && CONFIGFS_FS=m)
> diff --git a/drivers/thunderbolt/Makefile b/drivers/thunderbolt/Makefile
> index beb054c3126b..fc808c6b23e6 100644
> --- a/drivers/thunderbolt/Makefile
> +++ b/drivers/thunderbolt/Makefile
> @@ -1,10 +1,13 @@
> # SPDX-License-Identifier: GPL-2.0-only
> 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 := nhi.o ctl.o tb.o switch.o cap.o path.o tunnel.o eeprom.o
> +thunderbolt-objs += domain.o dma_port.o property.o xdomain.o lc.o tmu.o usb4.o
> thunderbolt-objs += usb4_port.o nvm.o retimer.o quirks.o clx.o
>
> +obj-${CONFIG_USB4_PCIE} += thunderbolt_pcie.o
> +thunderbolt_pcie-y := pci.o icm.o
> +
> thunderbolt-${CONFIG_ACPI} += acpi.o
> thunderbolt-$(CONFIG_DEBUG_FS) += debugfs.o
> thunderbolt-$(CONFIG_USB4_CONFIGFS) += configfs.o
> diff --git a/drivers/thunderbolt/ctl.c b/drivers/thunderbolt/ctl.c
> index 965988b18608..96717a0a94b1 100644
> --- a/drivers/thunderbolt/ctl.c
> +++ b/drivers/thunderbolt/ctl.c
> @@ -9,7 +9,6 @@
> #include <linux/crc32.h>
> #include <linux/delay.h>
> #include <linux/slab.h>
> -#include <linux/pci.h>
> #include <linux/dmapool.h>
> #include <linux/workqueue.h>
>
> @@ -96,6 +95,7 @@ struct tb_cfg_request *tb_cfg_request_alloc(void)
>
> return req;
> }
> +EXPORT_SYMBOL_GPL(tb_cfg_request_alloc);
>
> /**
> * tb_cfg_request_get() - Increase refcount of a request
> @@ -128,6 +128,7 @@ void tb_cfg_request_put(struct tb_cfg_request *req)
> kref_put(&req->kref, tb_cfg_request_destroy);
> mutex_unlock(&tb_cfg_request_lock);
> }
> +EXPORT_SYMBOL_GPL(tb_cfg_request_put);
>
> static int tb_cfg_request_enqueue(struct tb_ctl *ctl,
> struct tb_cfg_request *req)
> @@ -575,6 +576,7 @@ int tb_cfg_request(struct tb_ctl *ctl, struct tb_cfg_request *req,
> tb_cfg_request_dequeue(req);
> return ret;
> }
> +EXPORT_SYMBOL_GPL(tb_cfg_request);
>
> /**
> * tb_cfg_request_cancel() - Cancel a control request
> @@ -634,6 +636,7 @@ struct tb_cfg_result tb_cfg_request_sync(struct tb_ctl *ctl,
>
> return req->result;
> }
> +EXPORT_SYMBOL_GPL(tb_cfg_request_sync);
>
> /* public interface, alloc/start/stop/free */
>
> @@ -1009,6 +1012,7 @@ struct tb_cfg_result tb_cfg_read_raw(struct tb_ctl *ctl, void *buffer,
> memcpy(buffer, &reply.data, 4 * length);
> return res;
> }
> +EXPORT_SYMBOL_GPL(tb_cfg_read_raw);
>
> /**
> * tb_cfg_write_raw() - write from buffer into config space
> diff --git a/drivers/thunderbolt/domain.c b/drivers/thunderbolt/domain.c
> index 12c88509a54f..1c76fd8151ca 100644
> --- a/drivers/thunderbolt/domain.c
> +++ b/drivers/thunderbolt/domain.c
> @@ -313,6 +313,7 @@ const struct bus_type tb_bus_type = {
> .remove = tb_service_remove,
> .shutdown = tb_service_shutdown,
> };
> +EXPORT_SYMBOL_GPL(tb_bus_type);
>
> static void tb_domain_release(struct device *dev)
> {
> @@ -421,6 +422,7 @@ struct tb *tb_domain_alloc(struct tb_nhi *nhi, int timeout_msec, size_t privsize
>
> return NULL;
> }
> +EXPORT_SYMBOL_GPL(tb_domain_alloc);
>
> /**
> * tb_domain_add() - Add domain to the system
> @@ -514,6 +516,7 @@ void tb_domain_remove(struct tb *tb)
>
> device_unregister(&tb->dev);
> }
> +EXPORT_SYMBOL_GPL(tb_domain_remove);
>
> /**
> * tb_domain_suspend_noirq() - Suspend a domain
> @@ -904,8 +907,9 @@ int tb_domain_unregister_unplugged_xdomains(struct tb *tb)
>
> return ctx.n;
> }
> +EXPORT_SYMBOL_GPL(tb_domain_unregister_unplugged_xdomains);
>
> -int tb_domain_init(void)
> +static int __init tb_domain_init(void)
> {
> int ret;
>
> @@ -931,7 +935,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);
> @@ -941,3 +945,9 @@ void tb_domain_exit(void)
> tb_debugfs_exit();
> tb_configfs_exit();
> }
> +
> +postcore_initcall(tb_domain_init);
> +module_exit(tb_domain_exit);
> +
> +MODULE_DESCRIPTION("Thunderbolt/USB4 core driver");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c
> index 020db5a1f029..9b1165b2a484 100644
> --- a/drivers/thunderbolt/nhi.c
> +++ b/drivers/thunderbolt/nhi.c
> @@ -548,6 +548,7 @@ irqreturn_t ring_msix(int irq, void *data)
>
> return IRQ_HANDLED;
> }
> +EXPORT_SYMBOL_GPL(ring_msix);
We need to think what is going to be exported and how. For example here
ring_msix is pretty common name so if nothing else it needs to be properly
namespaced and that should be the first patch in the series.
Secondly I think it would be good to have this whole thing as part of a
patch series that adds the Qualcomm controller support so we have an
explanation there why we are doing all this.
>
> static int nhi_alloc_hop(struct tb_nhi *nhi, struct tb_ring *ring)
> {
> @@ -1001,6 +1002,7 @@ int nhi_mailbox_cmd(struct tb_nhi *nhi, enum nhi_mailbox_cmd cmd, u32 data)
>
> return 0;
> }
> +EXPORT_SYMBOL_GPL(nhi_mailbox_cmd);
>
> /**
> * nhi_mailbox_mode() - Return current firmware operation mode
> @@ -1021,6 +1023,7 @@ enum nhi_fw_mode nhi_mailbox_mode(struct tb_nhi *nhi)
>
> return (enum nhi_fw_mode)val;
> }
> +EXPORT_SYMBOL_GPL(nhi_mailbox_mode);
We really need to think what should be exported and what not. This for
example I think we can move inside pci.c because there is really no user
outside of Intel PCIe based systems for these.
Ideally export the minimal.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] thunderbolt: Make PCIe NHI support opt-in
2026-09-16 7:11 ` Greg KH
@ 2026-09-16 8:08 ` Konrad Dybcio
0 siblings, 0 replies; 6+ messages in thread
From: Konrad Dybcio @ 2026-09-16 8:08 UTC (permalink / raw)
To: Greg KH, Konrad Dybcio
Cc: Andreas Noever, Mika Westerberg, Yehezkel Bernat, linux-usb,
linux-kernel, usb4-upstream, Raghavendra Thoorpu
On 9/16/26 9:11 AM, Greg KH wrote:
> On Tue, Sep 15, 2026 at 07:04:10PM +0200, Konrad Dybcio wrote:
>> From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
>>
>> With more implementations coming in, one may desire not to enable
>> support for the PCIe-attached NHIs. Allow it to be built as a module
>> atop the framework.
>>
>> Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
>
> Why would you not want this? Can hardware not provide this for some
> platforms? I thought it was part of the spec...
This is about the host interface/controller being attached over
something else than PCIe, not opting out of building support
PCIe-over-USB4 tunneling (I believe that's what you interpreted
it as)
On (at least) Qualcomm and Apple Silicon, the on-SoC controller
is an MMIO device, the ASi driver is in review and the Qualcomm
one is soon to be.
Konrad
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] thunderbolt: Make PCIe NHI support opt-in
2026-09-16 7:59 ` Mika Westerberg
@ 2026-09-16 16:10 ` Konrad Dybcio
2026-09-17 4:13 ` Mika Westerberg
0 siblings, 1 reply; 6+ messages in thread
From: Konrad Dybcio @ 2026-09-16 16:10 UTC (permalink / raw)
To: Mika Westerberg, Konrad Dybcio
Cc: Andreas Noever, Mika Westerberg, Yehezkel Bernat, linux-usb,
linux-kernel, usb4-upstream, Raghavendra Thoorpu
On 9/16/26 9:59 AM, Mika Westerberg wrote:
> Hi,
>
> On Tue, Sep 15, 2026 at 07:04:10PM +0200, Konrad Dybcio wrote:
>> From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
>>
>> With more implementations coming in, one may desire not to enable
>> support for the PCIe-attached NHIs. Allow it to be built as a module
>> atop the framework.
>
> Is it so that Qualcomm platform does not support PCIe tunneling at all
> then?
No, this is about letting one opt out of building in support for
PCIe-attached NHIs - tunneling stays intact and our hw
indeed supports it.
The PCI NHI driver (which this patch makes optional) binds host
interfaces. TBT PCIe bridges (e.g. PCI 8086:15d3) on connected devices
with PCIe ports are handled by the pcieport driver.
[...]
>> +config USB4_PCIE
>> + depends on PCI
>> + tristate "Support for PCIe-attached USB4 and Thunderbolt controllers"
>
> I think USB4_PCI and so on.
>
>> + help
>> + Say Y here to add support for the USB4 and Thunderbolt host
>> + routers attached over the PCIe bus, commonly found on x86 PCs.
>> +
>> + To compile this driver a module, choose M here. The module will be
>> + called thunderbolt_pcie.
>
> thunderbolt_pci
ack
[...]
>> --- a/drivers/thunderbolt/nhi.c
>> +++ b/drivers/thunderbolt/nhi.c
>> @@ -548,6 +548,7 @@ irqreturn_t ring_msix(int irq, void *data)
>>
>> return IRQ_HANDLED;
>> }
>> +EXPORT_SYMBOL_GPL(ring_msix);
>
> We need to think what is going to be exported and how. For example here
> ring_msix is pretty common name so if nothing else it needs to be properly
> namespaced and that should be the first patch in the series.
Right, maybe EXPORT_SYMBOL_FOR_MODULES would be more fitting..
> Secondly I think it would be good to have this whole thing as part of a
> patch series that adds the Qualcomm controller support so we have an
> explanation there why we are doing all this.
This change isn't really necessary and my reasoning here was to
let the user decide if support for this specific kind of controllers
should be built, just like CONFIG_I2C is separate from the dozens of
implementations.
Konrad
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] thunderbolt: Make PCIe NHI support opt-in
2026-09-16 16:10 ` Konrad Dybcio
@ 2026-09-17 4:13 ` Mika Westerberg
0 siblings, 0 replies; 6+ messages in thread
From: Mika Westerberg @ 2026-09-17 4:13 UTC (permalink / raw)
To: Konrad Dybcio
Cc: Konrad Dybcio, Andreas Noever, Mika Westerberg, Yehezkel Bernat,
linux-usb, linux-kernel, usb4-upstream, Raghavendra Thoorpu
Hi,
On Wed, Sep 16, 2026 at 06:10:59PM +0200, Konrad Dybcio wrote:
> On 9/16/26 9:59 AM, Mika Westerberg wrote:
> > Hi,
> >
> > On Tue, Sep 15, 2026 at 07:04:10PM +0200, Konrad Dybcio wrote:
> >> From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
> >>
> >> With more implementations coming in, one may desire not to enable
> >> support for the PCIe-attached NHIs. Allow it to be built as a module
> >> atop the framework.
> >
> > Is it so that Qualcomm platform does not support PCIe tunneling at all
> > then?
>
>
> No, this is about letting one opt out of building in support for
> PCIe-attached NHIs - tunneling stays intact and our hw
> indeed supports it.
>
> The PCI NHI driver (which this patch makes optional) binds host
> interfaces. TBT PCIe bridges (e.g. PCI 8086:15d3) on connected devices
> with PCIe ports are handled by the pcieport driver.
Yes okay "typically" they go hand-in-hand and that's why I wanted to check.
So you have a PCIe root complex that then exposes the tunneling root ports
as well, got it.
> [...]
>
> >> +config USB4_PCIE
> >> + depends on PCI
> >> + tristate "Support for PCIe-attached USB4 and Thunderbolt controllers"
> >
> > I think USB4_PCI and so on.
> >
> >> + help
> >> + Say Y here to add support for the USB4 and Thunderbolt host
> >> + routers attached over the PCIe bus, commonly found on x86 PCs.
> >> +
> >> + To compile this driver a module, choose M here. The module will be
> >> + called thunderbolt_pcie.
> >
> > thunderbolt_pci
>
> ack
>
> [...]
>
> >> --- a/drivers/thunderbolt/nhi.c
> >> +++ b/drivers/thunderbolt/nhi.c
> >> @@ -548,6 +548,7 @@ irqreturn_t ring_msix(int irq, void *data)
> >>
> >> return IRQ_HANDLED;
> >> }
> >> +EXPORT_SYMBOL_GPL(ring_msix);
> >
> > We need to think what is going to be exported and how. For example here
> > ring_msix is pretty common name so if nothing else it needs to be properly
> > namespaced and that should be the first patch in the series.
>
> Right, maybe EXPORT_SYMBOL_FOR_MODULES would be more fitting..
That or namespace like tb_ring_msix (this one requires probably rename
patch first but may end up looking more consistent wrt naming).
> > Secondly I think it would be good to have this whole thing as part of a
> > patch series that adds the Qualcomm controller support so we have an
> > explanation there why we are doing all this.
>
> This change isn't really necessary and my reasoning here was to
> let the user decide if support for this specific kind of controllers
> should be built, just like CONFIG_I2C is separate from the dozens of
> implementations.
Yes but there is really no other option at the moment so it does not make
sense to provide yet another selection to the user IMHO. Once we have the
thunderbolt_platform (and thunderbolt_apple) then thunderbolt_pci makes
more sense.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-09-17 4:13 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-15 17:04 [PATCH] thunderbolt: Make PCIe NHI support opt-in Konrad Dybcio
2026-09-16 7:11 ` Greg KH
2026-09-16 8:08 ` Konrad Dybcio
2026-09-16 7:59 ` Mika Westerberg
2026-09-16 16:10 ` Konrad Dybcio
2026-09-17 4:13 ` 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®