]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
thunderbolt: Add support for ConfigFS
authorMika Westerberg <mika.westerberg@linux.intel.com>
Tue, 12 Aug 2025 10:53:49 +0000 (13:53 +0300)
committerMika Westerberg <mika.westerberg@linux.intel.com>
Tue, 19 May 2026 12:20:18 +0000 (14:20 +0200)
This adds ConfigFS support to USB4/Thunderbolt bus. By itself this just
creates the subsystem but it exposes functions that can be used to
register groups under it.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
drivers/thunderbolt/Kconfig
drivers/thunderbolt/Makefile
drivers/thunderbolt/configfs.c [new file with mode: 0644]
drivers/thunderbolt/domain.c
drivers/thunderbolt/tb.h
include/linux/thunderbolt.h

index db3b0bef48f4c30be6b27e11a2ff9d1ba072c3fe..9b4aaa456e323e6eb694f056a9cbf85cba31e140 100644 (file)
@@ -18,6 +18,10 @@ menuconfig USB4
 
 if USB4
 
+config USB4_CONFIGFS
+       def_tristate USB4
+       depends on CONFIGFS_FS && !(USB4=y && CONFIGFS_FS=m)
+
 config USB4_DEBUGFS_WRITE
        bool "Enable write by debugfs to configuration spaces (DANGEROUS)"
        help
index b44b32dcb8322612c1851b34efc9ef7fe837b02c..d5b367dfda1eddb8127188d69a17f5bbac22091b 100644 (file)
@@ -7,6 +7,7 @@ thunderbolt-objs += usb4_port.o nvm.o retimer.o quirks.o clx.o
 
 thunderbolt-${CONFIG_ACPI} += acpi.o
 thunderbolt-$(CONFIG_DEBUG_FS) += debugfs.o
+thunderbolt-$(CONFIG_USB4_CONFIGFS) += configfs.o
 thunderbolt-${CONFIG_USB4_KUNIT_TEST} += test.o
 CFLAGS_test.o += $(DISABLE_STRUCTLEAK_PLUGIN)
 
diff --git a/drivers/thunderbolt/configfs.c b/drivers/thunderbolt/configfs.c
new file mode 100644 (file)
index 0000000..dc6bc36
--- /dev/null
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ConfigFS support
+ *
+ * Copyright (C) 2026, Intel Corporation
+ * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
+ */
+
+#include <linux/configfs.h>
+#include <linux/export.h>
+
+#include "tb.h"
+
+static const struct config_item_type tb_root_group_type = {
+       .ct_owner = THIS_MODULE,
+};
+
+static struct configfs_subsystem tb_configfs = {
+       .su_group = {
+               .cg_item = {
+                       .ci_namebuf = "thunderbolt",
+                       .ci_type = &tb_root_group_type,
+               },
+       },
+};
+
+/**
+ * tb_configfs_register_group() - Register Thunderbolt ConfigFS group
+ * @group: Group to register.
+ *
+ * Registers the new @group under Thunderbolt subsystem ConfigFS.
+ *
+ * Return: 0% in case of success, negative errno otherwise.
+ */
+int tb_configfs_register_group(struct config_group *group)
+{
+       return configfs_register_group(&tb_configfs.su_group, group);
+}
+EXPORT_SYMBOL_GPL(tb_configfs_register_group);
+
+/**
+ * tb_configfs_unregister_group() - Unregister previously registered group
+ * @group: Group to unregister.
+ */
+void tb_configfs_unregister_group(struct config_group *group)
+{
+       configfs_unregister_group(group);
+}
+EXPORT_SYMBOL_GPL(tb_configfs_unregister_group);
+
+int tb_configfs_init(void)
+{
+       config_group_init(&tb_configfs.su_group);
+       mutex_init(&tb_configfs.su_mutex);
+       return configfs_register_subsystem(&tb_configfs);
+}
+
+void tb_configfs_exit(void)
+{
+       configfs_unregister_subsystem(&tb_configfs);
+}
index d83719a37b4c1f53308f8b6df9ac86d9a3fcdde2..b381f184340ec5178425497831f77dd9fc9a0db8 100644 (file)
@@ -887,6 +887,7 @@ int tb_domain_init(void)
 {
        int ret;
 
+       tb_configfs_init();
        tb_debugfs_init();
        tb_acpi_init();
 
@@ -916,4 +917,5 @@ void tb_domain_exit(void)
        tb_xdomain_exit();
        tb_acpi_exit();
        tb_debugfs_exit();
+       tb_configfs_exit();
 }
index 229b9e7961fba8613168e3db5fb685f4779cfb0f..e60f1bc3764e7a7f5a83d59058d14478a675ab94 100644 (file)
@@ -1558,4 +1558,12 @@ static inline void tb_retimer_debugfs_init(struct tb_retimer *rt) { }
 static inline void tb_retimer_debugfs_remove(struct tb_retimer *rt) { }
 #endif
 
+#if IS_REACHABLE(CONFIG_CONFIGFS_FS)
+int tb_configfs_init(void);
+void tb_configfs_exit(void);
+#else
+static inline int tb_configfs_init(void) { return 0; }
+static inline void tb_configfs_exit(void) { }
+#endif
+
 #endif
index 9c5cb5e4f23d3afc94e01431fb96c372fa54e191..0be9b298e692c9fad2f56f1ad3f11b8d4a29259e 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/types.h>
 
+struct config_group;
 struct fwnode_handle;
 struct device;
 
@@ -727,6 +728,11 @@ static inline struct device *tb_ring_dma_device(struct tb_ring *ring)
 bool usb4_usb3_port_match(struct device *usb4_port_dev,
                          const struct fwnode_handle *usb3_port_fwnode);
 
+#if IS_REACHABLE(CONFIG_CONFIGFS_FS)
+int tb_configfs_register_group(struct config_group *group);
+void tb_configfs_unregister_group(struct config_group *group);
+#endif
+
 #else /* CONFIG_USB4 */
 static inline bool usb4_usb3_port_match(struct device *usb4_port_dev,
                                        const struct fwnode_handle *usb3_port_fwnode)