You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
thunderbolt: Add debugfs interface
This adds debugfs interface that can be used for debugging possible issues in hardware/software. It exposes router and adapter config spaces through files like this: /sys/kernel/debug/thunderbolt/<DEVICE>/regs /sys/kernel/debug/thunderbolt/<DEVICE>/<PORT1>/regs /sys/kernel/debug/thunderbolt/<DEVICE>/<PORT1>/path /sys/kernel/debug/thunderbolt/<DEVICE>/<PORT1>/counters /sys/kernel/debug/thunderbolt/<DEVICE>/<PORT2>/regs /sys/kernel/debug/thunderbolt/<DEVICE>/<PORT2>/path /sys/kernel/debug/thunderbolt/<DEVICE>/<PORT2>/counters ... The "regs" is either the router or port configuration space register dump. The "path" is the port path configuration space and "counters" is the optional counters configuration space. These files contains one register per line so it should be easy to use normal filtering tools to find the registers of interest if needed. The router and adapter regs file becomes writable when CONFIG_USB4_DEBUGFS_WRITE is enabled (which is not supposed to be done in production systems) and in this case the developer can write "offset value" lines there to modify the hardware directly. For convenience this also supports the long format the read side produces (but ignores the additional fields). The counters file can be written even when CONFIG_USB4_DEBUGFS_WRITE is not enabled and it is only used to clear the counter values. Signed-off-by: Gil Fine <gil.fine@intel.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Mika Westerberg
parent
fa1653d99c
commit
54e418106c
@@ -16,6 +16,16 @@ menuconfig USB4
|
||||
To compile this driver a module, choose M here. The module will be
|
||||
called thunderbolt.
|
||||
|
||||
config USB4_DEBUGFS_WRITE
|
||||
bool "Enable write by debugfs to configuration spaces (DANGEROUS)"
|
||||
depends on USB4
|
||||
help
|
||||
Enables writing to device configuration registers through
|
||||
debugfs interface.
|
||||
|
||||
Only enable this if you know what you are doing! Never enable
|
||||
this for production systems or distro kernels.
|
||||
|
||||
config USB4_KUNIT_TEST
|
||||
bool "KUnit tests"
|
||||
depends on KUNIT=y
|
||||
|
||||
@@ -5,5 +5,6 @@ thunderbolt-objs += domain.o dma_port.o icm.o property.o xdomain.o lc.o tmu.o us
|
||||
thunderbolt-objs += nvm.o retimer.o quirks.o
|
||||
|
||||
thunderbolt-${CONFIG_ACPI} += acpi.o
|
||||
thunderbolt-$(CONFIG_DEBUG_FS) += debugfs.o
|
||||
|
||||
obj-${CONFIG_USB4_KUNIT_TEST} += test.o
|
||||
|
||||
700
drivers/thunderbolt/debugfs.c
Normal file
700
drivers/thunderbolt/debugfs.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -800,12 +800,20 @@ int tb_domain_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
tb_debugfs_init();
|
||||
ret = tb_xdomain_init();
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_debugfs;
|
||||
ret = bus_register(&tb_bus_type);
|
||||
if (ret)
|
||||
tb_xdomain_exit();
|
||||
goto err_xdomain;
|
||||
|
||||
return 0;
|
||||
|
||||
err_xdomain:
|
||||
tb_xdomain_exit();
|
||||
err_debugfs:
|
||||
tb_debugfs_exit();
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -816,4 +824,5 @@ void tb_domain_exit(void)
|
||||
ida_destroy(&tb_domain_ida);
|
||||
tb_nvm_exit();
|
||||
tb_xdomain_exit();
|
||||
tb_debugfs_exit();
|
||||
}
|
||||
|
||||
@@ -2517,6 +2517,7 @@ int tb_switch_add(struct tb_switch *sw)
|
||||
pm_request_autosuspend(&sw->dev);
|
||||
}
|
||||
|
||||
tb_switch_debugfs_init(sw);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2532,6 +2533,8 @@ void tb_switch_remove(struct tb_switch *sw)
|
||||
{
|
||||
struct tb_port *port;
|
||||
|
||||
tb_switch_debugfs_remove(sw);
|
||||
|
||||
if (sw->rpm) {
|
||||
pm_runtime_get_sync(&sw->dev);
|
||||
pm_runtime_disable(&sw->dev);
|
||||
|
||||
@@ -125,6 +125,7 @@ struct tb_switch_tmu {
|
||||
* @rpm: The switch supports runtime PM
|
||||
* @authorized: Whether the switch is authorized by user or policy
|
||||
* @security_level: Switch supported security level
|
||||
* @debugfs_dir: Pointer to the debugfs structure
|
||||
* @key: Contains the key used to challenge the device or %NULL if not
|
||||
* supported. Size of the key is %TB_SWITCH_KEY_SIZE.
|
||||
* @connection_id: Connection ID used with ICM messaging
|
||||
@@ -166,6 +167,7 @@ struct tb_switch {
|
||||
bool rpm;
|
||||
unsigned int authorized;
|
||||
enum tb_security_level security_level;
|
||||
struct dentry *debugfs_dir;
|
||||
u8 *key;
|
||||
u8 connection_id;
|
||||
u8 connection_key;
|
||||
@@ -1010,4 +1012,16 @@ void tb_acpi_add_links(struct tb_nhi *nhi);
|
||||
static inline void tb_acpi_add_links(struct tb_nhi *nhi) { }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
void tb_debugfs_init(void);
|
||||
void tb_debugfs_exit(void);
|
||||
void tb_switch_debugfs_init(struct tb_switch *sw);
|
||||
void tb_switch_debugfs_remove(struct tb_switch *sw);
|
||||
#else
|
||||
static inline void tb_debugfs_init(void) { }
|
||||
static inline void tb_debugfs_exit(void) { }
|
||||
static inline void tb_switch_debugfs_init(struct tb_switch *sw) { }
|
||||
static inline void tb_switch_debugfs_remove(struct tb_switch *sw) { }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -39,6 +39,7 @@ enum tb_switch_vse_cap {
|
||||
|
||||
enum tb_port_cap {
|
||||
TB_PORT_CAP_PHY = 0x01,
|
||||
TB_PORT_CAP_POWER = 0x02,
|
||||
TB_PORT_CAP_TIME1 = 0x03,
|
||||
TB_PORT_CAP_ADAP = 0x04,
|
||||
TB_PORT_CAP_VSE = 0x05,
|
||||
@@ -252,7 +253,8 @@ struct tb_regs_port_header {
|
||||
/* DWORD 1 */
|
||||
u32 first_cap_offset:8;
|
||||
u32 max_counters:11;
|
||||
u32 __unknown1:5;
|
||||
u32 counters_support:1;
|
||||
u32 __unknown1:4;
|
||||
u32 revision:8;
|
||||
/* DWORD 2 */
|
||||
enum tb_port_type type:24;
|
||||
|
||||
Reference in New Issue
Block a user