brintos

brintos / linux-shallow public Read only

0
0
Text · 56.0 KiB · 350310b Raw
2274 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Debugfs interface4 *5 * Copyright (C) 2020, Intel Corporation6 * Authors: Gil Fine <gil.fine@intel.com>7 *	    Mika Westerberg <mika.westerberg@linux.intel.com>8 */9 10#include <linux/bitfield.h>11#include <linux/debugfs.h>12#include <linux/delay.h>13#include <linux/pm_runtime.h>14#include <linux/uaccess.h>15 16#include "tb.h"17#include "sb_regs.h"18 19#define PORT_CAP_V1_PCIE_LEN	120#define PORT_CAP_V2_PCIE_LEN	221#define PORT_CAP_POWER_LEN	222#define PORT_CAP_LANE_LEN	323#define PORT_CAP_USB3_LEN	524#define PORT_CAP_DP_V1_LEN	925#define PORT_CAP_DP_V2_LEN	1426#define PORT_CAP_TMU_V1_LEN	827#define PORT_CAP_TMU_V2_LEN	1028#define PORT_CAP_BASIC_LEN	929#define PORT_CAP_USB4_LEN	2030 31#define SWITCH_CAP_TMU_LEN	2632#define SWITCH_CAP_BASIC_LEN	2733 34#define PATH_LEN		235 36#define COUNTER_SET_LEN		337 38/*39 * USB4 spec doesn't specify dwell range, the range of 100 ms to 500 ms40 * probed to give good results.41 */42#define MIN_DWELL_TIME		100 /* ms */43#define MAX_DWELL_TIME		500 /* ms */44#define DWELL_SAMPLE_INTERVAL	1045 46/* Sideband registers and their sizes as defined in the USB4 spec */47struct sb_reg {48	unsigned int reg;49	unsigned int size;50};51 52#define SB_MAX_SIZE		6453 54/* Sideband registers for router */55static const struct sb_reg port_sb_regs[] = {56	{ USB4_SB_VENDOR_ID, 4 },57	{ USB4_SB_PRODUCT_ID, 4 },58	{ USB4_SB_DEBUG_CONF, 4 },59	{ USB4_SB_DEBUG, 54 },60	{ USB4_SB_LRD_TUNING, 4 },61	{ USB4_SB_OPCODE, 4 },62	{ USB4_SB_METADATA, 4 },63	{ USB4_SB_LINK_CONF, 3 },64	{ USB4_SB_GEN23_TXFFE, 4 },65	{ USB4_SB_GEN4_TXFFE, 4 },66	{ USB4_SB_VERSION, 4 },67	{ USB4_SB_DATA, 64 },68};69 70/* Sideband registers for retimer */71static const struct sb_reg retimer_sb_regs[] = {72	{ USB4_SB_VENDOR_ID, 4 },73	{ USB4_SB_PRODUCT_ID, 4 },74	{ USB4_SB_FW_VERSION, 4 },75	{ USB4_SB_LRD_TUNING, 4 },76	{ USB4_SB_OPCODE, 4 },77	{ USB4_SB_METADATA, 4 },78	{ USB4_SB_GEN23_TXFFE, 4 },79	{ USB4_SB_GEN4_TXFFE, 4 },80	{ USB4_SB_VERSION, 4 },81	{ USB4_SB_DATA, 64 },82};83 84#define DEBUGFS_ATTR(__space, __write)					\85static int __space ## _open(struct inode *inode, struct file *file)	\86{									\87	return single_open(file, __space ## _show, inode->i_private);	\88}									\89									\90static const struct file_operations __space ## _fops = {		\91	.owner = THIS_MODULE,						\92	.open = __space ## _open,					\93	.release = single_release,					\94	.read  = seq_read,						\95	.write = __write,						\96	.llseek = seq_lseek,						\97}98 99#define DEBUGFS_ATTR_RO(__space)					\100	DEBUGFS_ATTR(__space, NULL)101 102#define DEBUGFS_ATTR_RW(__space)					\103	DEBUGFS_ATTR(__space, __space ## _write)104 105static struct dentry *tb_debugfs_root;106 107static void *validate_and_copy_from_user(const void __user *user_buf,108					 size_t *count)109{110	size_t nbytes;111	void *buf;112 113	if (!*count)114		return ERR_PTR(-EINVAL);115 116	if (!access_ok(user_buf, *count))117		return ERR_PTR(-EFAULT);118 119	buf = (void *)get_zeroed_page(GFP_KERNEL);120	if (!buf)121		return ERR_PTR(-ENOMEM);122 123	nbytes = min_t(size_t, *count, PAGE_SIZE);124	if (copy_from_user(buf, user_buf, nbytes)) {125		free_page((unsigned long)buf);126		return ERR_PTR(-EFAULT);127	}128 129	*count = nbytes;130	return buf;131}132 133static bool parse_line(char **line, u32 *offs, u32 *val, int short_fmt_len,134		       int long_fmt_len)135{136	char *token;137	u32 v[5];138	int ret;139 140	token = strsep(line, "\n");141	if (!token)142		return false;143 144	/*145	 * For Adapter/Router configuration space:146	 * Short format is: offset value\n147	 *		    v[0]   v[1]148	 * Long format as produced from the read side:149	 * offset relative_offset cap_id vs_cap_id value\n150	 * v[0]   v[1]            v[2]   v[3]      v[4]151	 *152	 * For Counter configuration space:153	 * Short format is: offset\n154	 *		    v[0]155	 * Long format as produced from the read side:156	 * offset relative_offset counter_id value\n157	 * v[0]   v[1]            v[2]       v[3]158	 */159	ret = sscanf(token, "%i %i %i %i %i", &v[0], &v[1], &v[2], &v[3], &v[4]);160	/* In case of Counters, clear counter, "val" content is NA */161	if (ret == short_fmt_len) {162		*offs = v[0];163		*val = v[short_fmt_len - 1];164		return true;165	} else if (ret == long_fmt_len) {166		*offs = v[0];167		*val = v[long_fmt_len - 1];168		return true;169	}170 171	return false;172}173 174#if IS_ENABLED(CONFIG_USB4_DEBUGFS_WRITE)175static ssize_t regs_write(struct tb_switch *sw, struct tb_port *port,176			  const char __user *user_buf, size_t count,177			  loff_t *ppos)178{179	struct tb *tb = sw->tb;180	char *line, *buf;181	u32 val, offset;182	int ret = 0;183 184	buf = validate_and_copy_from_user(user_buf, &count);185	if (IS_ERR(buf))186		return PTR_ERR(buf);187 188	pm_runtime_get_sync(&sw->dev);189 190	if (mutex_lock_interruptible(&tb->lock)) {191		ret = -ERESTARTSYS;192		goto out;193	}194 195	/* User did hardware changes behind the driver's back */196	add_taint(TAINT_USER, LOCKDEP_STILL_OK);197 198	line = buf;199	while (parse_line(&line, &offset, &val, 2, 5)) {200		if (port)201			ret = tb_port_write(port, &val, TB_CFG_PORT, offset, 1);202		else203			ret = tb_sw_write(sw, &val, TB_CFG_SWITCH, offset, 1);204		if (ret)205			break;206	}207 208	mutex_unlock(&tb->lock);209 210out:211	pm_runtime_mark_last_busy(&sw->dev);212	pm_runtime_put_autosuspend(&sw->dev);213	free_page((unsigned long)buf);214 215	return ret < 0 ? ret : count;216}217 218static ssize_t port_regs_write(struct file *file, const char __user *user_buf,219			       size_t count, loff_t *ppos)220{221	struct seq_file *s = file->private_data;222	struct tb_port *port = s->private;223 224	return regs_write(port->sw, port, user_buf, count, ppos);225}226 227static ssize_t switch_regs_write(struct file *file, const char __user *user_buf,228				 size_t count, loff_t *ppos)229{230	struct seq_file *s = file->private_data;231	struct tb_switch *sw = s->private;232 233	return regs_write(sw, NULL, user_buf, count, ppos);234}235 236static bool parse_sb_line(char **line, u8 *reg, u8 *data, size_t data_size,237			  size_t *bytes_read)238{239	char *field, *token;240	int i;241 242	token = strsep(line, "\n");243	if (!token)244		return false;245 246	/* Parse the register first */247	field = strsep(&token, " ");248	if (!field)249		return false;250	if (kstrtou8(field, 0, reg))251		return false;252 253	/* Then the values for the register, up to data_size */254	for (i = 0; i < data_size; i++) {255		field = strsep(&token, " ");256		if (!field)257			break;258		if (kstrtou8(field, 0, &data[i]))259			return false;260	}261 262	*bytes_read = i;263	return true;264}265 266static ssize_t sb_regs_write(struct tb_port *port, const struct sb_reg *sb_regs,267			     size_t size, enum usb4_sb_target target, u8 index,268			     char *buf, size_t count, loff_t *ppos)269{270	u8 reg, data[SB_MAX_SIZE];271	size_t bytes_read;272	char *line = buf;273 274	/* User did hardware changes behind the driver's back */275	add_taint(TAINT_USER, LOCKDEP_STILL_OK);276 277	/*278	 * For sideband registers we accept:279	 * reg b0 b1 b2...\n280	 *281	 * Here "reg" is the byte offset of the sideband register and "b0"..282	 * are the byte values. There can be less byte values than the register283	 * size. The leftovers will not be overwritten.284	 */285	while (parse_sb_line(&line, &reg, data, ARRAY_SIZE(data), &bytes_read)) {286		const struct sb_reg *sb_reg;287		int ret;288 289		/* At least one byte must be passed */290		if (bytes_read < 1)291			return -EINVAL;292 293		/* Find the register */294		sb_reg = NULL;295		for (int i = 0; i < size; i++) {296			if (sb_regs[i].reg == reg) {297				sb_reg = &sb_regs[i];298				break;299			}300		}301 302		if (!sb_reg)303			return -EINVAL;304 305		if (bytes_read > sb_regs->size)306			return -E2BIG;307 308		ret = usb4_port_sb_write(port, target, index, sb_reg->reg, data,309					 bytes_read);310		if (ret)311			return ret;312	}313 314	return 0;315}316 317static ssize_t port_sb_regs_write(struct file *file, const char __user *user_buf,318				  size_t count, loff_t *ppos)319{320	struct seq_file *s = file->private_data;321	struct tb_port *port = s->private;322	struct tb_switch *sw = port->sw;323	struct tb *tb = sw->tb;324	char *buf;325	int ret;326 327	buf = validate_and_copy_from_user(user_buf, &count);328	if (IS_ERR(buf))329		return PTR_ERR(buf);330 331	pm_runtime_get_sync(&sw->dev);332 333	if (mutex_lock_interruptible(&tb->lock)) {334		ret = -ERESTARTSYS;335		goto out;336	}337 338	ret = sb_regs_write(port, port_sb_regs, ARRAY_SIZE(port_sb_regs),339			    USB4_SB_TARGET_ROUTER, 0, buf, count, ppos);340 341	mutex_unlock(&tb->lock);342out:343	pm_runtime_mark_last_busy(&sw->dev);344	pm_runtime_put_autosuspend(&sw->dev);345	free_page((unsigned long)buf);346 347	return ret < 0 ? ret : count;348}349 350static ssize_t retimer_sb_regs_write(struct file *file,351				     const char __user *user_buf,352				     size_t count, loff_t *ppos)353{354	struct seq_file *s = file->private_data;355	struct tb_retimer *rt = s->private;356	struct tb *tb = rt->tb;357	char *buf;358	int ret;359 360	buf = validate_and_copy_from_user(user_buf, &count);361	if (IS_ERR(buf))362		return PTR_ERR(buf);363 364	pm_runtime_get_sync(&rt->dev);365 366	if (mutex_lock_interruptible(&tb->lock)) {367		ret = -ERESTARTSYS;368		goto out;369	}370 371	ret = sb_regs_write(rt->port, retimer_sb_regs, ARRAY_SIZE(retimer_sb_regs),372			    USB4_SB_TARGET_RETIMER, rt->index, buf, count, ppos);373 374	mutex_unlock(&tb->lock);375out:376	pm_runtime_mark_last_busy(&rt->dev);377	pm_runtime_put_autosuspend(&rt->dev);378	free_page((unsigned long)buf);379 380	return ret < 0 ? ret : count;381}382#define DEBUGFS_MODE		0600383#else384#define port_regs_write		NULL385#define switch_regs_write	NULL386#define port_sb_regs_write	NULL387#define retimer_sb_regs_write	NULL388#define DEBUGFS_MODE		0400389#endif390 391#if IS_ENABLED(CONFIG_USB4_DEBUGFS_MARGINING)392/**393 * struct tb_margining - Lane margining support394 * @port: USB4 port through which the margining operations are run395 * @target: Sideband target396 * @index: Retimer index if taget is %USB4_SB_TARGET_RETIMER397 * @dev: Pointer to the device that is the target (USB4 port or retimer)398 * @caps: Port lane margining capabilities399 * @results: Last lane margining results400 * @lanes: %0, %1 or %7 (all)401 * @min_ber_level: Minimum supported BER level contour value402 * @max_ber_level: Maximum supported BER level contour value403 * @ber_level: Current BER level contour value404 * @voltage_steps: Number of mandatory voltage steps405 * @max_voltage_offset: Maximum mandatory voltage offset (in mV)406 * @voltage_steps_optional_range: Number of voltage steps for optional range407 * @max_voltage_offset_optional_range: Maximum voltage offset for the optional408 *					range (in mV).409 * @time_steps: Number of time margin steps410 * @max_time_offset: Maximum time margin offset (in mUI)411 * @voltage_time_offset: Offset for voltage / time for software margining412 * @dwell_time: Dwell time for software margining (in ms)413 * @error_counter: Error counter operation for software margining414 * @optional_voltage_offset_range: Enable optional extended voltage range415 * @software: %true if software margining is used instead of hardware416 * @time: %true if time margining is used instead of voltage417 * @right_high: %false if left/low margin test is performed, %true if418 *		right/high419 */420struct tb_margining {421	struct tb_port *port;422	enum usb4_sb_target target;423	u8 index;424	struct device *dev;425	u32 caps[2];426	u32 results[2];427	unsigned int lanes;428	unsigned int min_ber_level;429	unsigned int max_ber_level;430	unsigned int ber_level;431	unsigned int voltage_steps;432	unsigned int max_voltage_offset;433	unsigned int voltage_steps_optional_range;434	unsigned int max_voltage_offset_optional_range;435	unsigned int time_steps;436	unsigned int max_time_offset;437	unsigned int voltage_time_offset;438	unsigned int dwell_time;439	enum usb4_margin_sw_error_counter error_counter;440	bool optional_voltage_offset_range;441	bool software;442	bool time;443	bool right_high;444};445 446static int margining_modify_error_counter(struct tb_margining *margining,447	u32 lanes, enum usb4_margin_sw_error_counter error_counter)448{449	struct usb4_port_margining_params params = { 0 };450	struct tb_port *port = margining->port;451	u32 result;452 453	if (error_counter != USB4_MARGIN_SW_ERROR_COUNTER_CLEAR &&454	    error_counter != USB4_MARGIN_SW_ERROR_COUNTER_STOP)455		return -EOPNOTSUPP;456 457	params.error_counter = error_counter;458	params.lanes = lanes;459 460	return usb4_port_sw_margin(port, margining->target, margining->index,461				   &params, &result);462}463 464static bool supports_software(const struct tb_margining *margining)465{466	return margining->caps[0] & USB4_MARGIN_CAP_0_MODES_SW;467}468 469static bool supports_hardware(const struct tb_margining *margining)470{471	return margining->caps[0] & USB4_MARGIN_CAP_0_MODES_HW;472}473 474static bool both_lanes(const struct tb_margining *margining)475{476	return margining->caps[0] & USB4_MARGIN_CAP_0_2_LANES;477}478 479static unsigned int480independent_voltage_margins(const struct tb_margining *margining)481{482	return FIELD_GET(USB4_MARGIN_CAP_0_VOLTAGE_INDP_MASK, margining->caps[0]);483}484 485static bool supports_time(const struct tb_margining *margining)486{487	return margining->caps[0] & USB4_MARGIN_CAP_0_TIME;488}489 490/* Only applicable if supports_time() returns true */491static unsigned int492independent_time_margins(const struct tb_margining *margining)493{494	return FIELD_GET(USB4_MARGIN_CAP_1_TIME_INDP_MASK, margining->caps[1]);495}496 497static bool498supports_optional_voltage_offset_range(const struct tb_margining *margining)499{500	return margining->caps[0] & USB4_MARGIN_CAP_0_OPT_VOLTAGE_SUPPORT;501}502 503static ssize_t504margining_ber_level_write(struct file *file, const char __user *user_buf,505			   size_t count, loff_t *ppos)506{507	struct seq_file *s = file->private_data;508	struct tb_margining *margining = s->private;509	struct tb *tb = margining->port->sw->tb;510	unsigned int val;511	int ret = 0;512	char *buf;513 514	if (mutex_lock_interruptible(&tb->lock))515		return -ERESTARTSYS;516 517	if (margining->software) {518		ret = -EINVAL;519		goto out_unlock;520	}521 522	buf = validate_and_copy_from_user(user_buf, &count);523	if (IS_ERR(buf)) {524		ret = PTR_ERR(buf);525		goto out_unlock;526	}527 528	buf[count - 1] = '\0';529 530	ret = kstrtouint(buf, 10, &val);531	if (ret)532		goto out_free;533 534	if (val < margining->min_ber_level ||535	    val > margining->max_ber_level) {536		ret = -EINVAL;537		goto out_free;538	}539 540	margining->ber_level = val;541 542out_free:543	free_page((unsigned long)buf);544out_unlock:545	mutex_unlock(&tb->lock);546 547	return ret < 0 ? ret : count;548}549 550static void ber_level_show(struct seq_file *s, unsigned int val)551{552	if (val % 2)553		seq_printf(s, "3 * 1e%d (%u)\n", -12 + (val + 1) / 2, val);554	else555		seq_printf(s, "1e%d (%u)\n", -12 + val / 2, val);556}557 558static int margining_ber_level_show(struct seq_file *s, void *not_used)559{560	const struct tb_margining *margining = s->private;561 562	if (margining->software)563		return -EINVAL;564	ber_level_show(s, margining->ber_level);565	return 0;566}567DEBUGFS_ATTR_RW(margining_ber_level);568 569static int margining_caps_show(struct seq_file *s, void *not_used)570{571	struct tb_margining *margining = s->private;572	struct tb *tb = margining->port->sw->tb;573	u32 cap0, cap1;574 575	if (mutex_lock_interruptible(&tb->lock))576		return -ERESTARTSYS;577 578	/* Dump the raw caps first */579	cap0 = margining->caps[0];580	seq_printf(s, "0x%08x\n", cap0);581	cap1 = margining->caps[1];582	seq_printf(s, "0x%08x\n", cap1);583 584	seq_printf(s, "# software margining: %s\n",585		   supports_software(margining) ? "yes" : "no");586	if (supports_hardware(margining)) {587		seq_puts(s, "# hardware margining: yes\n");588		seq_puts(s, "# minimum BER level contour: ");589		ber_level_show(s, margining->min_ber_level);590		seq_puts(s, "# maximum BER level contour: ");591		ber_level_show(s, margining->max_ber_level);592	} else {593		seq_puts(s, "# hardware margining: no\n");594	}595 596	seq_printf(s, "# both lanes simultaneously: %s\n",597		  both_lanes(margining) ? "yes" : "no");598	seq_printf(s, "# voltage margin steps: %u\n",599		   margining->voltage_steps);600	seq_printf(s, "# maximum voltage offset: %u mV\n",601		   margining->max_voltage_offset);602	seq_printf(s, "# optional voltage offset range support: %s\n",603		   str_yes_no(supports_optional_voltage_offset_range(margining)));604	if (supports_optional_voltage_offset_range(margining)) {605		seq_printf(s, "# voltage margin steps, optional range: %u\n",606			   margining->voltage_steps_optional_range);607		seq_printf(s, "# maximum voltage offset, optional range: %u mV\n",608			   margining->max_voltage_offset_optional_range);609	}610 611	switch (independent_voltage_margins(margining)) {612	case USB4_MARGIN_CAP_0_VOLTAGE_MIN:613		seq_puts(s, "# returns minimum between high and low voltage margins\n");614		break;615	case USB4_MARGIN_CAP_0_VOLTAGE_HL:616		seq_puts(s, "# returns high or low voltage margin\n");617		break;618	case USB4_MARGIN_CAP_0_VOLTAGE_BOTH:619		seq_puts(s, "# returns both high and low margins\n");620		break;621	}622 623	if (supports_time(margining)) {624		seq_puts(s, "# time margining: yes\n");625		seq_printf(s, "# time margining is destructive: %s\n",626			   cap1 & USB4_MARGIN_CAP_1_TIME_DESTR ? "yes" : "no");627 628		switch (independent_time_margins(margining)) {629		case USB4_MARGIN_CAP_1_TIME_MIN:630			seq_puts(s, "# returns minimum between left and right time margins\n");631			break;632		case USB4_MARGIN_CAP_1_TIME_LR:633			seq_puts(s, "# returns left or right margin\n");634			break;635		case USB4_MARGIN_CAP_1_TIME_BOTH:636			seq_puts(s, "# returns both left and right margins\n");637			break;638		}639 640		seq_printf(s, "# time margin steps: %u\n",641			   margining->time_steps);642		seq_printf(s, "# maximum time offset: %u mUI\n",643			   margining->max_time_offset);644	} else {645		seq_puts(s, "# time margining: no\n");646	}647 648	mutex_unlock(&tb->lock);649	return 0;650}651DEBUGFS_ATTR_RO(margining_caps);652 653static ssize_t654margining_lanes_write(struct file *file, const char __user *user_buf,655		      size_t count, loff_t *ppos)656{657	struct seq_file *s = file->private_data;658	struct tb_margining *margining = s->private;659	struct tb *tb = margining->port->sw->tb;660	int ret = 0;661	char *buf;662 663	buf = validate_and_copy_from_user(user_buf, &count);664	if (IS_ERR(buf))665		return PTR_ERR(buf);666 667	buf[count - 1] = '\0';668 669	if (mutex_lock_interruptible(&tb->lock)) {670		ret = -ERESTARTSYS;671		goto out_free;672	}673 674	if (!strcmp(buf, "0")) {675		margining->lanes = 0;676	} else if (!strcmp(buf, "1")) {677		margining->lanes = 1;678	} else if (!strcmp(buf, "all")) {679		/* Needs to be supported */680		if (both_lanes(margining))681			margining->lanes = 7;682		else683			ret = -EINVAL;684	} else {685		ret = -EINVAL;686	}687 688	mutex_unlock(&tb->lock);689 690out_free:691	free_page((unsigned long)buf);692	return ret < 0 ? ret : count;693}694 695static int margining_lanes_show(struct seq_file *s, void *not_used)696{697	struct tb_margining *margining = s->private;698	struct tb *tb = margining->port->sw->tb;699	unsigned int lanes;700 701	if (mutex_lock_interruptible(&tb->lock))702		return -ERESTARTSYS;703 704	lanes = margining->lanes;705	if (both_lanes(margining)) {706		if (!lanes)707			seq_puts(s, "[0] 1 all\n");708		else if (lanes == 1)709			seq_puts(s, "0 [1] all\n");710		else711			seq_puts(s, "0 1 [all]\n");712	} else {713		if (!lanes)714			seq_puts(s, "[0] 1\n");715		else716			seq_puts(s, "0 [1]\n");717	}718 719	mutex_unlock(&tb->lock);720	return 0;721}722DEBUGFS_ATTR_RW(margining_lanes);723 724static ssize_t725margining_voltage_time_offset_write(struct file *file,726				    const char __user *user_buf,727				    size_t count, loff_t *ppos)728{729	struct seq_file *s = file->private_data;730	struct tb_margining *margining = s->private;731	struct tb *tb = margining->port->sw->tb;732	unsigned int max_margin;733	unsigned int val;734	int ret;735 736	ret = kstrtouint_from_user(user_buf, count, 10, &val);737	if (ret)738		return ret;739 740	scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &tb->lock) {741		if (!margining->software)742			return -EOPNOTSUPP;743 744		if (margining->time)745			max_margin = margining->time_steps;746		else747			if (margining->optional_voltage_offset_range)748				max_margin = margining->voltage_steps_optional_range;749			else750				max_margin = margining->voltage_steps;751 752		margining->voltage_time_offset = clamp(val, 0, max_margin);753	}754 755	return count;756}757 758static int margining_voltage_time_offset_show(struct seq_file *s,759					      void *not_used)760{761	const struct tb_margining *margining = s->private;762	struct tb *tb = margining->port->sw->tb;763 764	scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &tb->lock) {765		if (!margining->software)766			return -EOPNOTSUPP;767 768		seq_printf(s, "%d\n", margining->voltage_time_offset);769	}770 771	return 0;772}773DEBUGFS_ATTR_RW(margining_voltage_time_offset);774 775static ssize_t776margining_error_counter_write(struct file *file, const char __user *user_buf,777			      size_t count, loff_t *ppos)778{779	enum usb4_margin_sw_error_counter error_counter;780	struct seq_file *s = file->private_data;781	struct tb_margining *margining = s->private;782	struct tb *tb = margining->port->sw->tb;783	char *buf;784 785	buf = validate_and_copy_from_user(user_buf, &count);786	if (IS_ERR(buf))787		return PTR_ERR(buf);788 789	buf[count - 1] = '\0';790 791	if (!strcmp(buf, "nop"))792		error_counter = USB4_MARGIN_SW_ERROR_COUNTER_NOP;793	else if (!strcmp(buf, "clear"))794		error_counter = USB4_MARGIN_SW_ERROR_COUNTER_CLEAR;795	else if (!strcmp(buf, "start"))796		error_counter = USB4_MARGIN_SW_ERROR_COUNTER_START;797	else if (!strcmp(buf, "stop"))798		error_counter = USB4_MARGIN_SW_ERROR_COUNTER_STOP;799	else800		return -EINVAL;801 802	scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &tb->lock) {803		if (!margining->software)804			return -EOPNOTSUPP;805 806		margining->error_counter = error_counter;807	}808 809	return count;810}811 812static int margining_error_counter_show(struct seq_file *s, void *not_used)813{814	const struct tb_margining *margining = s->private;815	struct tb *tb = margining->port->sw->tb;816 817	scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &tb->lock) {818		if (!margining->software)819			return -EOPNOTSUPP;820 821		switch (margining->error_counter) {822		case USB4_MARGIN_SW_ERROR_COUNTER_NOP:823			seq_puts(s, "[nop] clear start stop\n");824			break;825		case USB4_MARGIN_SW_ERROR_COUNTER_CLEAR:826			seq_puts(s, "nop [clear] start stop\n");827			break;828		case USB4_MARGIN_SW_ERROR_COUNTER_START:829			seq_puts(s, "nop clear [start] stop\n");830			break;831		case USB4_MARGIN_SW_ERROR_COUNTER_STOP:832			seq_puts(s, "nop clear start [stop]\n");833			break;834		}835	}836 837	return 0;838}839DEBUGFS_ATTR_RW(margining_error_counter);840 841static ssize_t842margining_dwell_time_write(struct file *file, const char __user *user_buf,843			   size_t count, loff_t *ppos)844{845	struct seq_file *s = file->private_data;846	struct tb_margining *margining = s->private;847	struct tb *tb = margining->port->sw->tb;848	unsigned int val;849	int ret;850 851	ret = kstrtouint_from_user(user_buf, count, 10, &val);852	if (ret)853		return ret;854 855	scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &tb->lock) {856		if (!margining->software)857			return -EOPNOTSUPP;858 859		margining->dwell_time = clamp(val, MIN_DWELL_TIME, MAX_DWELL_TIME);860	}861 862	return count;863}864 865static int margining_dwell_time_show(struct seq_file *s, void *not_used)866{867	struct tb_margining *margining = s->private;868	struct tb *tb = margining->port->sw->tb;869 870	scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &tb->lock) {871		if (!margining->software)872			return -EOPNOTSUPP;873 874		seq_printf(s, "%d\n", margining->dwell_time);875	}876 877	return 0;878}879DEBUGFS_ATTR_RW(margining_dwell_time);880 881static ssize_t882margining_optional_voltage_offset_write(struct file *file, const char __user *user_buf,883					size_t count, loff_t *ppos)884{885	struct seq_file *s = file->private_data;886	struct tb_margining *margining = s->private;887	struct tb *tb = margining->port->sw->tb;888	bool val;889	int ret;890 891	ret = kstrtobool_from_user(user_buf, count, &val);892	if (ret)893		return ret;894 895	scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &tb->lock) {896		margining->optional_voltage_offset_range = val;897	}898 899	return count;900}901 902static int margining_optional_voltage_offset_show(struct seq_file *s,903						  void *not_used)904{905	struct tb_margining *margining = s->private;906	struct tb *tb = margining->port->sw->tb;907 908	scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &tb->lock) {909		seq_printf(s, "%u\n", margining->optional_voltage_offset_range);910	}911 912	return 0;913}914DEBUGFS_ATTR_RW(margining_optional_voltage_offset);915 916static ssize_t margining_mode_write(struct file *file,917				   const char __user *user_buf,918				   size_t count, loff_t *ppos)919{920	struct seq_file *s = file->private_data;921	struct tb_margining *margining = s->private;922	struct tb *tb = margining->port->sw->tb;923	int ret = 0;924	char *buf;925 926	buf = validate_and_copy_from_user(user_buf, &count);927	if (IS_ERR(buf))928		return PTR_ERR(buf);929 930	buf[count - 1] = '\0';931 932	if (mutex_lock_interruptible(&tb->lock)) {933		ret = -ERESTARTSYS;934		goto out_free;935	}936 937	if (!strcmp(buf, "software")) {938		if (supports_software(margining))939			margining->software = true;940		else941			ret = -EINVAL;942	} else if (!strcmp(buf, "hardware")) {943		if (supports_hardware(margining))944			margining->software = false;945		else946			ret = -EINVAL;947	} else {948		ret = -EINVAL;949	}950 951	mutex_unlock(&tb->lock);952 953out_free:954	free_page((unsigned long)buf);955	return ret ? ret : count;956}957 958static int margining_mode_show(struct seq_file *s, void *not_used)959{960	struct tb_margining *margining = s->private;961	struct tb *tb = margining->port->sw->tb;962	const char *space = "";963 964	if (mutex_lock_interruptible(&tb->lock))965		return -ERESTARTSYS;966 967	if (supports_software(margining)) {968		if (margining->software)969			seq_puts(s, "[software]");970		else971			seq_puts(s, "software");972		space = " ";973	}974	if (supports_hardware(margining)) {975		if (margining->software)976			seq_printf(s, "%shardware", space);977		else978			seq_printf(s, "%s[hardware]", space);979	}980 981	mutex_unlock(&tb->lock);982 983	seq_puts(s, "\n");984	return 0;985}986DEBUGFS_ATTR_RW(margining_mode);987 988static int margining_run_sw(struct tb_margining *margining,989			    struct usb4_port_margining_params *params)990{991	u32 nsamples = margining->dwell_time / DWELL_SAMPLE_INTERVAL;992	int ret, i;993 994	ret = usb4_port_sw_margin(margining->port, margining->target, margining->index,995				  params, margining->results);996	if (ret)997		goto out_stop;998 999	for (i = 0; i <= nsamples; i++) {1000		u32 errors = 0;1001 1002		ret = usb4_port_sw_margin_errors(margining->port, margining->target,1003						 margining->index, &margining->results[1]);1004		if (ret)1005			break;1006 1007		if (margining->lanes == USB4_MARGIN_SW_LANE_0)1008			errors = FIELD_GET(USB4_MARGIN_SW_ERR_COUNTER_LANE_0_MASK,1009					   margining->results[1]);1010		else if (margining->lanes == USB4_MARGIN_SW_LANE_1)1011			errors = FIELD_GET(USB4_MARGIN_SW_ERR_COUNTER_LANE_1_MASK,1012					   margining->results[1]);1013		else if (margining->lanes == USB4_MARGIN_SW_ALL_LANES)1014			errors = margining->results[1];1015 1016		/* Any errors stop the test */1017		if (errors)1018			break;1019 1020		fsleep(DWELL_SAMPLE_INTERVAL * USEC_PER_MSEC);1021	}1022 1023out_stop:1024	/*1025	 * Stop the counters but don't clear them to allow the1026	 * different error counter configurations.1027	 */1028	margining_modify_error_counter(margining, margining->lanes,1029				       USB4_MARGIN_SW_ERROR_COUNTER_STOP);1030	return ret;1031}1032 1033static int margining_run_write(void *data, u64 val)1034{1035	struct tb_margining *margining = data;1036	struct tb_port *port = margining->port;1037	struct device *dev = margining->dev;1038	struct tb_switch *sw = port->sw;1039	struct tb_switch *down_sw;1040	struct tb *tb = sw->tb;1041	int ret, clx;1042 1043	if (val != 1)1044		return -EINVAL;1045 1046	pm_runtime_get_sync(dev);1047 1048	if (mutex_lock_interruptible(&tb->lock)) {1049		ret = -ERESTARTSYS;1050		goto out_rpm_put;1051	}1052 1053	if (tb_is_upstream_port(port))1054		down_sw = sw;1055	else if (port->remote)1056		down_sw = port->remote->sw;1057	else1058		down_sw = NULL;1059 1060	if (down_sw) {1061		/*1062		 * CL states may interfere with lane margining so1063		 * disable them temporarily now.1064		 */1065		ret = tb_switch_clx_disable(down_sw);1066		if (ret < 0) {1067			tb_sw_warn(down_sw, "failed to disable CL states\n");1068			goto out_unlock;1069		}1070		clx = ret;1071	}1072 1073	/* Clear the results */1074	memset(margining->results, 0, sizeof(margining->results));1075 1076	if (margining->software) {1077		struct usb4_port_margining_params params = {1078			.error_counter = USB4_MARGIN_SW_ERROR_COUNTER_CLEAR,1079			.lanes = margining->lanes,1080			.time = margining->time,1081			.voltage_time_offset = margining->voltage_time_offset,1082			.right_high = margining->right_high,1083			.optional_voltage_offset_range = margining->optional_voltage_offset_range,1084		};1085 1086		tb_port_dbg(port,1087			    "running software %s lane margining for %s lanes %u\n",1088			    margining->time ? "time" : "voltage", dev_name(dev),1089			    margining->lanes);1090 1091		ret = margining_run_sw(margining, &params);1092	} else {1093		struct usb4_port_margining_params params = {1094			.ber_level = margining->ber_level,1095			.lanes = margining->lanes,1096			.time = margining->time,1097			.right_high = margining->right_high,1098			.optional_voltage_offset_range = margining->optional_voltage_offset_range,1099		};1100 1101		tb_port_dbg(port,1102			    "running hardware %s lane margining for %s lanes %u\n",1103			    margining->time ? "time" : "voltage", dev_name(dev),1104			    margining->lanes);1105 1106		ret = usb4_port_hw_margin(port, margining->target, margining->index, &params,1107					  margining->results);1108	}1109 1110	if (down_sw)1111		tb_switch_clx_enable(down_sw, clx);1112out_unlock:1113	mutex_unlock(&tb->lock);1114out_rpm_put:1115	pm_runtime_mark_last_busy(dev);1116	pm_runtime_put_autosuspend(dev);1117 1118	return ret;1119}1120DEFINE_DEBUGFS_ATTRIBUTE(margining_run_fops, NULL, margining_run_write,1121			 "%llu\n");1122 1123static ssize_t margining_results_write(struct file *file,1124				       const char __user *user_buf,1125				       size_t count, loff_t *ppos)1126{1127	struct seq_file *s = file->private_data;1128	struct tb_margining *margining = s->private;1129	struct tb *tb = margining->port->sw->tb;1130 1131	if (mutex_lock_interruptible(&tb->lock))1132		return -ERESTARTSYS;1133 1134	/* Just clear the results */1135	margining->results[0] = 0;1136	margining->results[1] = 0;1137 1138	if (margining->software) {1139		/* Clear the error counters */1140		margining_modify_error_counter(margining,1141					       USB4_MARGIN_SW_ALL_LANES,1142					       USB4_MARGIN_SW_ERROR_COUNTER_CLEAR);1143	}1144 1145	mutex_unlock(&tb->lock);1146	return count;1147}1148 1149static void voltage_margin_show(struct seq_file *s,1150				const struct tb_margining *margining, u8 val)1151{1152	unsigned int tmp, voltage;1153 1154	tmp = FIELD_GET(USB4_MARGIN_HW_RES_1_MARGIN_MASK, val);1155	voltage = tmp * margining->max_voltage_offset / margining->voltage_steps;1156	seq_printf(s, "%u mV (%u)", voltage, tmp);1157	if (val & USB4_MARGIN_HW_RES_1_EXCEEDS)1158		seq_puts(s, " exceeds maximum");1159	seq_puts(s, "\n");1160	if (margining->optional_voltage_offset_range)1161		seq_puts(s, " optional voltage offset range enabled\n");1162}1163 1164static void time_margin_show(struct seq_file *s,1165			     const struct tb_margining *margining, u8 val)1166{1167	unsigned int tmp, interval;1168 1169	tmp = FIELD_GET(USB4_MARGIN_HW_RES_1_MARGIN_MASK, val);1170	interval = tmp * margining->max_time_offset / margining->time_steps;1171	seq_printf(s, "%u mUI (%u)", interval, tmp);1172	if (val & USB4_MARGIN_HW_RES_1_EXCEEDS)1173		seq_puts(s, " exceeds maximum");1174	seq_puts(s, "\n");1175}1176 1177static int margining_results_show(struct seq_file *s, void *not_used)1178{1179	struct tb_margining *margining = s->private;1180	struct tb *tb = margining->port->sw->tb;1181 1182	if (mutex_lock_interruptible(&tb->lock))1183		return -ERESTARTSYS;1184 1185	/* Dump the raw results first */1186	seq_printf(s, "0x%08x\n", margining->results[0]);1187	/* Only the hardware margining has two result dwords */1188	if (!margining->software) {1189		unsigned int val;1190 1191		seq_printf(s, "0x%08x\n", margining->results[1]);1192 1193		if (margining->time) {1194			if (!margining->lanes || margining->lanes == 7) {1195				val = margining->results[1];1196				seq_puts(s, "# lane 0 right time margin: ");1197				time_margin_show(s, margining, val);1198				val = margining->results[1] >>1199					USB4_MARGIN_HW_RES_1_L0_LL_MARGIN_SHIFT;1200				seq_puts(s, "# lane 0 left time margin: ");1201				time_margin_show(s, margining, val);1202			}1203			if (margining->lanes == 1 || margining->lanes == 7) {1204				val = margining->results[1] >>1205					USB4_MARGIN_HW_RES_1_L1_RH_MARGIN_SHIFT;1206				seq_puts(s, "# lane 1 right time margin: ");1207				time_margin_show(s, margining, val);1208				val = margining->results[1] >>1209					USB4_MARGIN_HW_RES_1_L1_LL_MARGIN_SHIFT;1210				seq_puts(s, "# lane 1 left time margin: ");1211				time_margin_show(s, margining, val);1212			}1213		} else {1214			if (!margining->lanes || margining->lanes == 7) {1215				val = margining->results[1];1216				seq_puts(s, "# lane 0 high voltage margin: ");1217				voltage_margin_show(s, margining, val);1218				val = margining->results[1] >>1219					USB4_MARGIN_HW_RES_1_L0_LL_MARGIN_SHIFT;1220				seq_puts(s, "# lane 0 low voltage margin: ");1221				voltage_margin_show(s, margining, val);1222			}1223			if (margining->lanes == 1 || margining->lanes == 7) {1224				val = margining->results[1] >>1225					USB4_MARGIN_HW_RES_1_L1_RH_MARGIN_SHIFT;1226				seq_puts(s, "# lane 1 high voltage margin: ");1227				voltage_margin_show(s, margining, val);1228				val = margining->results[1] >>1229					USB4_MARGIN_HW_RES_1_L1_LL_MARGIN_SHIFT;1230				seq_puts(s, "# lane 1 low voltage margin: ");1231				voltage_margin_show(s, margining, val);1232			}1233		}1234	} else {1235		u32 lane_errors, result;1236 1237		seq_printf(s, "0x%08x\n", margining->results[1]);1238		result = FIELD_GET(USB4_MARGIN_SW_LANES_MASK, margining->results[0]);1239 1240		if (result == USB4_MARGIN_SW_LANE_0 ||1241		    result == USB4_MARGIN_SW_ALL_LANES) {1242			lane_errors = FIELD_GET(USB4_MARGIN_SW_ERR_COUNTER_LANE_0_MASK,1243						margining->results[1]);1244			seq_printf(s, "# lane 0 errors: %u\n", lane_errors);1245		}1246		if (result == USB4_MARGIN_SW_LANE_1 ||1247		    result == USB4_MARGIN_SW_ALL_LANES) {1248			lane_errors = FIELD_GET(USB4_MARGIN_SW_ERR_COUNTER_LANE_1_MASK,1249						margining->results[1]);1250			seq_printf(s, "# lane 1 errors: %u\n", lane_errors);1251		}1252	}1253 1254	mutex_unlock(&tb->lock);1255	return 0;1256}1257DEBUGFS_ATTR_RW(margining_results);1258 1259static ssize_t margining_test_write(struct file *file,1260				    const char __user *user_buf,1261				    size_t count, loff_t *ppos)1262{1263	struct seq_file *s = file->private_data;1264	struct tb_margining *margining = s->private;1265	struct tb *tb = margining->port->sw->tb;1266	int ret = 0;1267	char *buf;1268 1269	buf = validate_and_copy_from_user(user_buf, &count);1270	if (IS_ERR(buf))1271		return PTR_ERR(buf);1272 1273	buf[count - 1] = '\0';1274 1275	if (mutex_lock_interruptible(&tb->lock)) {1276		ret = -ERESTARTSYS;1277		goto out_free;1278	}1279 1280	if (!strcmp(buf, "time") && supports_time(margining))1281		margining->time = true;1282	else if (!strcmp(buf, "voltage"))1283		margining->time = false;1284	else1285		ret = -EINVAL;1286 1287	mutex_unlock(&tb->lock);1288 1289out_free:1290	free_page((unsigned long)buf);1291	return ret ? ret : count;1292}1293 1294static int margining_test_show(struct seq_file *s, void *not_used)1295{1296	struct tb_margining *margining = s->private;1297	struct tb *tb = margining->port->sw->tb;1298 1299	if (mutex_lock_interruptible(&tb->lock))1300		return -ERESTARTSYS;1301 1302	if (supports_time(margining)) {1303		if (margining->time)1304			seq_puts(s, "voltage [time]\n");1305		else1306			seq_puts(s, "[voltage] time\n");1307	} else {1308		seq_puts(s, "[voltage]\n");1309	}1310 1311	mutex_unlock(&tb->lock);1312	return 0;1313}1314DEBUGFS_ATTR_RW(margining_test);1315 1316static ssize_t margining_margin_write(struct file *file,1317				    const char __user *user_buf,1318				    size_t count, loff_t *ppos)1319{1320	struct seq_file *s = file->private_data;1321	struct tb_margining *margining = s->private;1322	struct tb *tb = margining->port->sw->tb;1323	int ret = 0;1324	char *buf;1325 1326	buf = validate_and_copy_from_user(user_buf, &count);1327	if (IS_ERR(buf))1328		return PTR_ERR(buf);1329 1330	buf[count - 1] = '\0';1331 1332	if (mutex_lock_interruptible(&tb->lock)) {1333		ret = -ERESTARTSYS;1334		goto out_free;1335	}1336 1337	if (margining->time) {1338		if (!strcmp(buf, "left"))1339			margining->right_high = false;1340		else if (!strcmp(buf, "right"))1341			margining->right_high = true;1342		else1343			ret = -EINVAL;1344	} else {1345		if (!strcmp(buf, "low"))1346			margining->right_high = false;1347		else if (!strcmp(buf, "high"))1348			margining->right_high = true;1349		else1350			ret = -EINVAL;1351	}1352 1353	mutex_unlock(&tb->lock);1354 1355out_free:1356	free_page((unsigned long)buf);1357	return ret ? ret : count;1358}1359 1360static int margining_margin_show(struct seq_file *s, void *not_used)1361{1362	struct tb_margining *margining = s->private;1363	struct tb *tb = margining->port->sw->tb;1364 1365	if (mutex_lock_interruptible(&tb->lock))1366		return -ERESTARTSYS;1367 1368	if (margining->time) {1369		if (margining->right_high)1370			seq_puts(s, "left [right]\n");1371		else1372			seq_puts(s, "[left] right\n");1373	} else {1374		if (margining->right_high)1375			seq_puts(s, "low [high]\n");1376		else1377			seq_puts(s, "[low] high\n");1378	}1379 1380	mutex_unlock(&tb->lock);1381	return 0;1382}1383DEBUGFS_ATTR_RW(margining_margin);1384 1385static struct tb_margining *margining_alloc(struct tb_port *port,1386					    struct device *dev,1387					    enum usb4_sb_target target,1388					    u8 index, struct dentry *parent)1389{1390	struct tb_margining *margining;1391	struct dentry *dir;1392	unsigned int val;1393	int ret;1394 1395	margining = kzalloc(sizeof(*margining), GFP_KERNEL);1396	if (!margining)1397		return NULL;1398 1399	margining->port = port;1400	margining->target = target;1401	margining->index = index;1402	margining->dev = dev;1403 1404	ret = usb4_port_margining_caps(port, target, index, margining->caps);1405	if (ret) {1406		kfree(margining);1407		return NULL;1408	}1409 1410	/* Set the initial mode */1411	if (supports_software(margining))1412		margining->software = true;1413 1414	val = FIELD_GET(USB4_MARGIN_CAP_0_VOLTAGE_STEPS_MASK, margining->caps[0]);1415	margining->voltage_steps = val;1416	val = FIELD_GET(USB4_MARGIN_CAP_0_MAX_VOLTAGE_OFFSET_MASK, margining->caps[0]);1417	margining->max_voltage_offset = 74 + val * 2;1418 1419	if (supports_optional_voltage_offset_range(margining)) {1420		val = FIELD_GET(USB4_MARGIN_CAP_0_VOLT_STEPS_OPT_MASK,1421				margining->caps[0]);1422		margining->voltage_steps_optional_range = val;1423		val = FIELD_GET(USB4_MARGIN_CAP_1_MAX_VOLT_OFS_OPT_MASK,1424				margining->caps[1]);1425		margining->max_voltage_offset_optional_range = 74 + val * 2;1426	}1427 1428	if (supports_time(margining)) {1429		val = FIELD_GET(USB4_MARGIN_CAP_1_TIME_STEPS_MASK, margining->caps[1]);1430		margining->time_steps = val;1431		val = FIELD_GET(USB4_MARGIN_CAP_1_TIME_OFFSET_MASK, margining->caps[1]);1432		/*1433		 * Store it as mUI (milli Unit Interval) because we want1434		 * to keep it as integer.1435		 */1436		margining->max_time_offset = 200 + 10 * val;1437	}1438 1439	dir = debugfs_create_dir("margining", parent);1440	if (supports_hardware(margining)) {1441		val = FIELD_GET(USB4_MARGIN_CAP_1_MIN_BER_MASK, margining->caps[1]);1442		margining->min_ber_level = val;1443		val = FIELD_GET(USB4_MARGIN_CAP_1_MAX_BER_MASK, margining->caps[1]);1444		margining->max_ber_level = val;1445 1446		/* Set the default to minimum */1447		margining->ber_level = margining->min_ber_level;1448 1449		debugfs_create_file("ber_level_contour", 0400, dir, margining,1450				    &margining_ber_level_fops);1451	}1452	debugfs_create_file("caps", 0400, dir, margining, &margining_caps_fops);1453	debugfs_create_file("lanes", 0600, dir, margining, &margining_lanes_fops);1454	debugfs_create_file("mode", 0600, dir, margining, &margining_mode_fops);1455	debugfs_create_file("run", 0600, dir, margining, &margining_run_fops);1456	debugfs_create_file("results", 0600, dir, margining,1457			    &margining_results_fops);1458	debugfs_create_file("test", 0600, dir, margining, &margining_test_fops);1459	if (independent_voltage_margins(margining) == USB4_MARGIN_CAP_0_VOLTAGE_HL ||1460	    (supports_time(margining) &&1461	     independent_time_margins(margining) == USB4_MARGIN_CAP_1_TIME_LR))1462		debugfs_create_file("margin", 0600, dir, margining,1463				    &margining_margin_fops);1464 1465	margining->error_counter = USB4_MARGIN_SW_ERROR_COUNTER_CLEAR;1466	margining->dwell_time = MIN_DWELL_TIME;1467 1468	if (supports_optional_voltage_offset_range(margining))1469		debugfs_create_file("optional_voltage_offset", DEBUGFS_MODE, dir, margining,1470				    &margining_optional_voltage_offset_fops);1471 1472	if (supports_software(margining)) {1473		debugfs_create_file("voltage_time_offset", DEBUGFS_MODE, dir, margining,1474				    &margining_voltage_time_offset_fops);1475		debugfs_create_file("error_counter", DEBUGFS_MODE, dir, margining,1476				    &margining_error_counter_fops);1477		debugfs_create_file("dwell_time", DEBUGFS_MODE, dir, margining,1478				    &margining_dwell_time_fops);1479	}1480	return margining;1481}1482 1483static void margining_port_init(struct tb_port *port)1484{1485	struct dentry *parent;1486	char dir_name[10];1487 1488	if (!port->usb4)1489		return;1490 1491	snprintf(dir_name, sizeof(dir_name), "port%d", port->port);1492	parent = debugfs_lookup(dir_name, port->sw->debugfs_dir);1493	port->usb4->margining = margining_alloc(port, &port->usb4->dev,1494						USB4_SB_TARGET_ROUTER, 0,1495						parent);1496}1497 1498static void margining_port_remove(struct tb_port *port)1499{1500	struct dentry *parent;1501	char dir_name[10];1502 1503	if (!port->usb4)1504		return;1505 1506	snprintf(dir_name, sizeof(dir_name), "port%d", port->port);1507	parent = debugfs_lookup(dir_name, port->sw->debugfs_dir);1508	if (parent)1509		debugfs_lookup_and_remove("margining", parent);1510 1511	kfree(port->usb4->margining);1512	port->usb4->margining = NULL;1513}1514 1515static void margining_switch_init(struct tb_switch *sw)1516{1517	struct tb_port *upstream, *downstream;1518	struct tb_switch *parent_sw;1519	u64 route = tb_route(sw);1520 1521	if (!route)1522		return;1523 1524	upstream = tb_upstream_port(sw);1525	parent_sw = tb_switch_parent(sw);1526	downstream = tb_port_at(route, parent_sw);1527 1528	margining_port_init(downstream);1529	margining_port_init(upstream);1530}1531 1532static void margining_switch_remove(struct tb_switch *sw)1533{1534	struct tb_port *upstream, *downstream;1535	struct tb_switch *parent_sw;1536	u64 route = tb_route(sw);1537 1538	if (!route)1539		return;1540 1541	upstream = tb_upstream_port(sw);1542	parent_sw = tb_switch_parent(sw);1543	downstream = tb_port_at(route, parent_sw);1544 1545	margining_port_remove(upstream);1546	margining_port_remove(downstream);1547}1548 1549static void margining_xdomain_init(struct tb_xdomain *xd)1550{1551	struct tb_switch *parent_sw;1552	struct tb_port *downstream;1553 1554	parent_sw = tb_xdomain_parent(xd);1555	downstream = tb_port_at(xd->route, parent_sw);1556 1557	margining_port_init(downstream);1558}1559 1560static void margining_xdomain_remove(struct tb_xdomain *xd)1561{1562	struct tb_switch *parent_sw;1563	struct tb_port *downstream;1564 1565	parent_sw = tb_xdomain_parent(xd);1566	downstream = tb_port_at(xd->route, parent_sw);1567	margining_port_remove(downstream);1568}1569 1570static void margining_retimer_init(struct tb_retimer *rt, struct dentry *debugfs_dir)1571{1572	rt->margining = margining_alloc(rt->port, &rt->dev,1573					USB4_SB_TARGET_RETIMER, rt->index,1574					debugfs_dir);1575}1576 1577static void margining_retimer_remove(struct tb_retimer *rt)1578{1579	kfree(rt->margining);1580	rt->margining = NULL;1581}1582#else1583static inline void margining_switch_init(struct tb_switch *sw) { }1584static inline void margining_switch_remove(struct tb_switch *sw) { }1585static inline void margining_xdomain_init(struct tb_xdomain *xd) { }1586static inline void margining_xdomain_remove(struct tb_xdomain *xd) { }1587static inline void margining_retimer_init(struct tb_retimer *rt,1588					  struct dentry *debugfs_dir) { }1589static inline void margining_retimer_remove(struct tb_retimer *rt) { }1590#endif1591 1592static int port_clear_all_counters(struct tb_port *port)1593{1594	u32 *buf;1595	int ret;1596 1597	buf = kcalloc(COUNTER_SET_LEN * port->config.max_counters, sizeof(u32),1598		      GFP_KERNEL);1599	if (!buf)1600		return -ENOMEM;1601 1602	ret = tb_port_write(port, buf, TB_CFG_COUNTERS, 0,1603			    COUNTER_SET_LEN * port->config.max_counters);1604	kfree(buf);1605 1606	return ret;1607}1608 1609static ssize_t counters_write(struct file *file, const char __user *user_buf,1610			      size_t count, loff_t *ppos)1611{1612	struct seq_file *s = file->private_data;1613	struct tb_port *port = s->private;1614	struct tb_switch *sw = port->sw;1615	struct tb *tb = port->sw->tb;1616	char *buf;1617	int ret;1618 1619	buf = validate_and_copy_from_user(user_buf, &count);1620	if (IS_ERR(buf))1621		return PTR_ERR(buf);1622 1623	pm_runtime_get_sync(&sw->dev);1624 1625	if (mutex_lock_interruptible(&tb->lock)) {1626		ret = -ERESTARTSYS;1627		goto out;1628	}1629 1630	/* If written delimiter only, clear all counters in one shot */1631	if (buf[0] == '\n') {1632		ret = port_clear_all_counters(port);1633	} else  {1634		char *line = buf;1635		u32 val, offset;1636 1637		ret = -EINVAL;1638		while (parse_line(&line, &offset, &val, 1, 4)) {1639			ret = tb_port_write(port, &val, TB_CFG_COUNTERS,1640					    offset, 1);1641			if (ret)1642				break;1643		}1644	}1645 1646	mutex_unlock(&tb->lock);1647 1648out:1649	pm_runtime_mark_last_busy(&sw->dev);1650	pm_runtime_put_autosuspend(&sw->dev);1651	free_page((unsigned long)buf);1652 1653	return ret < 0 ? ret : count;1654}1655 1656static void cap_show_by_dw(struct seq_file *s, struct tb_switch *sw,1657			   struct tb_port *port, unsigned int cap,1658			   unsigned int offset, u8 cap_id, u8 vsec_id,1659			   int dwords)1660{1661	int i, ret;1662	u32 data;1663 1664	for (i = 0; i < dwords; i++) {1665		if (port)1666			ret = tb_port_read(port, &data, TB_CFG_PORT, cap + offset + i, 1);1667		else1668			ret = tb_sw_read(sw, &data, TB_CFG_SWITCH, cap + offset + i, 1);1669		if (ret) {1670			seq_printf(s, "0x%04x <not accessible>\n", cap + offset + i);1671			continue;1672		}1673 1674		seq_printf(s, "0x%04x %4d 0x%02x 0x%02x 0x%08x\n", cap + offset + i,1675			   offset + i, cap_id, vsec_id, data);1676	}1677}1678 1679static void cap_show(struct seq_file *s, struct tb_switch *sw,1680		     struct tb_port *port, unsigned int cap, u8 cap_id,1681		     u8 vsec_id, int length)1682{1683	int ret, offset = 0;1684 1685	while (length > 0) {1686		int i, dwords = min(length, TB_MAX_CONFIG_RW_LENGTH);1687		u32 data[TB_MAX_CONFIG_RW_LENGTH];1688 1689		if (port)1690			ret = tb_port_read(port, data, TB_CFG_PORT, cap + offset,1691					   dwords);1692		else1693			ret = tb_sw_read(sw, data, TB_CFG_SWITCH, cap + offset, dwords);1694		if (ret) {1695			cap_show_by_dw(s, sw, port, cap, offset, cap_id, vsec_id, length);1696			return;1697		}1698 1699		for (i = 0; i < dwords; i++) {1700			seq_printf(s, "0x%04x %4d 0x%02x 0x%02x 0x%08x\n",1701				   cap + offset + i, offset + i,1702				   cap_id, vsec_id, data[i]);1703		}1704 1705		length -= dwords;1706		offset += dwords;1707	}1708}1709 1710static void port_cap_show(struct tb_port *port, struct seq_file *s,1711			  unsigned int cap)1712{1713	struct tb_cap_any header;1714	u8 vsec_id = 0;1715	size_t length;1716	int ret;1717 1718	ret = tb_port_read(port, &header, TB_CFG_PORT, cap, 1);1719	if (ret) {1720		seq_printf(s, "0x%04x <capability read failed>\n", cap);1721		return;1722	}1723 1724	switch (header.basic.cap) {1725	case TB_PORT_CAP_PHY:1726		length = PORT_CAP_LANE_LEN;1727		break;1728 1729	case TB_PORT_CAP_TIME1:1730		if (usb4_switch_version(port->sw) < 2)1731			length = PORT_CAP_TMU_V1_LEN;1732		else1733			length = PORT_CAP_TMU_V2_LEN;1734		break;1735 1736	case TB_PORT_CAP_POWER:1737		length = PORT_CAP_POWER_LEN;1738		break;1739 1740	case TB_PORT_CAP_ADAP:1741		if (tb_port_is_pcie_down(port) || tb_port_is_pcie_up(port)) {1742			if (usb4_switch_version(port->sw) < 2)1743				length = PORT_CAP_V1_PCIE_LEN;1744			else1745				length = PORT_CAP_V2_PCIE_LEN;1746		} else if (tb_port_is_dpin(port)) {1747			if (usb4_switch_version(port->sw) < 2)1748				length = PORT_CAP_DP_V1_LEN;1749			else1750				length = PORT_CAP_DP_V2_LEN;1751		} else if (tb_port_is_dpout(port)) {1752			length = PORT_CAP_DP_V1_LEN;1753		} else if (tb_port_is_usb3_down(port) ||1754			   tb_port_is_usb3_up(port)) {1755			length = PORT_CAP_USB3_LEN;1756		} else {1757			seq_printf(s, "0x%04x <unsupported capability 0x%02x>\n",1758				   cap, header.basic.cap);1759			return;1760		}1761		break;1762 1763	case TB_PORT_CAP_VSE:1764		if (!header.extended_short.length) {1765			ret = tb_port_read(port, (u32 *)&header + 1, TB_CFG_PORT,1766					   cap + 1, 1);1767			if (ret) {1768				seq_printf(s, "0x%04x <capability read failed>\n",1769					   cap + 1);1770				return;1771			}1772			length = header.extended_long.length;1773			vsec_id = header.extended_short.vsec_id;1774		} else {1775			length = header.extended_short.length;1776			vsec_id = header.extended_short.vsec_id;1777		}1778		break;1779 1780	case TB_PORT_CAP_USB4:1781		length = PORT_CAP_USB4_LEN;1782		break;1783 1784	default:1785		seq_printf(s, "0x%04x <unsupported capability 0x%02x>\n",1786			   cap, header.basic.cap);1787		return;1788	}1789 1790	cap_show(s, NULL, port, cap, header.basic.cap, vsec_id, length);1791}1792 1793static void port_caps_show(struct tb_port *port, struct seq_file *s)1794{1795	int cap;1796 1797	cap = tb_port_next_cap(port, 0);1798	while (cap > 0) {1799		port_cap_show(port, s, cap);1800		cap = tb_port_next_cap(port, cap);1801	}1802}1803 1804static int port_basic_regs_show(struct tb_port *port, struct seq_file *s)1805{1806	u32 data[PORT_CAP_BASIC_LEN];1807	int ret, i;1808 1809	ret = tb_port_read(port, data, TB_CFG_PORT, 0, ARRAY_SIZE(data));1810	if (ret)1811		return ret;1812 1813	for (i = 0; i < ARRAY_SIZE(data); i++)1814		seq_printf(s, "0x%04x %4d 0x00 0x00 0x%08x\n", i, i, data[i]);1815 1816	return 0;1817}1818 1819static int port_regs_show(struct seq_file *s, void *not_used)1820{1821	struct tb_port *port = s->private;1822	struct tb_switch *sw = port->sw;1823	struct tb *tb = sw->tb;1824	int ret;1825 1826	pm_runtime_get_sync(&sw->dev);1827 1828	if (mutex_lock_interruptible(&tb->lock)) {1829		ret = -ERESTARTSYS;1830		goto out_rpm_put;1831	}1832 1833	seq_puts(s, "# offset relative_offset cap_id vs_cap_id value\n");1834 1835	ret = port_basic_regs_show(port, s);1836	if (ret)1837		goto out_unlock;1838 1839	port_caps_show(port, s);1840 1841out_unlock:1842	mutex_unlock(&tb->lock);1843out_rpm_put:1844	pm_runtime_mark_last_busy(&sw->dev);1845	pm_runtime_put_autosuspend(&sw->dev);1846 1847	return ret;1848}1849DEBUGFS_ATTR_RW(port_regs);1850 1851static void switch_cap_show(struct tb_switch *sw, struct seq_file *s,1852			    unsigned int cap)1853{1854	struct tb_cap_any header;1855	int ret, length;1856	u8 vsec_id = 0;1857 1858	ret = tb_sw_read(sw, &header, TB_CFG_SWITCH, cap, 1);1859	if (ret) {1860		seq_printf(s, "0x%04x <capability read failed>\n", cap);1861		return;1862	}1863 1864	if (header.basic.cap == TB_SWITCH_CAP_VSE) {1865		if (!header.extended_short.length) {1866			ret = tb_sw_read(sw, (u32 *)&header + 1, TB_CFG_SWITCH,1867					 cap + 1, 1);1868			if (ret) {1869				seq_printf(s, "0x%04x <capability read failed>\n",1870					   cap + 1);1871				return;1872			}1873			length = header.extended_long.length;1874		} else {1875			length = header.extended_short.length;1876		}1877		vsec_id = header.extended_short.vsec_id;1878	} else {1879		if (header.basic.cap == TB_SWITCH_CAP_TMU) {1880			length = SWITCH_CAP_TMU_LEN;1881		} else  {1882			seq_printf(s, "0x%04x <unknown capability 0x%02x>\n",1883				   cap, header.basic.cap);1884			return;1885		}1886	}1887 1888	cap_show(s, sw, NULL, cap, header.basic.cap, vsec_id, length);1889}1890 1891static void switch_caps_show(struct tb_switch *sw, struct seq_file *s)1892{1893	int cap;1894 1895	cap = tb_switch_next_cap(sw, 0);1896	while (cap > 0) {1897		switch_cap_show(sw, s, cap);1898		cap = tb_switch_next_cap(sw, cap);1899	}1900}1901 1902static int switch_basic_regs_show(struct tb_switch *sw, struct seq_file *s)1903{1904	u32 data[SWITCH_CAP_BASIC_LEN];1905	size_t dwords;1906	int ret, i;1907 1908	/* Only USB4 has the additional registers */1909	if (tb_switch_is_usb4(sw))1910		dwords = ARRAY_SIZE(data);1911	else1912		dwords = 5;1913 1914	ret = tb_sw_read(sw, data, TB_CFG_SWITCH, 0, dwords);1915	if (ret)1916		return ret;1917 1918	for (i = 0; i < dwords; i++)1919		seq_printf(s, "0x%04x %4d 0x00 0x00 0x%08x\n", i, i, data[i]);1920 1921	return 0;1922}1923 1924static int switch_regs_show(struct seq_file *s, void *not_used)1925{1926	struct tb_switch *sw = s->private;1927	struct tb *tb = sw->tb;1928	int ret;1929 1930	pm_runtime_get_sync(&sw->dev);1931 1932	if (mutex_lock_interruptible(&tb->lock)) {1933		ret = -ERESTARTSYS;1934		goto out_rpm_put;1935	}1936 1937	seq_puts(s, "# offset relative_offset cap_id vs_cap_id value\n");1938 1939	ret = switch_basic_regs_show(sw, s);1940	if (ret)1941		goto out_unlock;1942 1943	switch_caps_show(sw, s);1944 1945out_unlock:1946	mutex_unlock(&tb->lock);1947out_rpm_put:1948	pm_runtime_mark_last_busy(&sw->dev);1949	pm_runtime_put_autosuspend(&sw->dev);1950 1951	return ret;1952}1953DEBUGFS_ATTR_RW(switch_regs);1954 1955static int path_show_one(struct tb_port *port, struct seq_file *s, int hopid)1956{1957	u32 data[PATH_LEN];1958	int ret, i;1959 1960	ret = tb_port_read(port, data, TB_CFG_HOPS, hopid * PATH_LEN,1961			   ARRAY_SIZE(data));1962	if (ret) {1963		seq_printf(s, "0x%04x <not accessible>\n", hopid * PATH_LEN);1964		return ret;1965	}1966 1967	for (i = 0; i < ARRAY_SIZE(data); i++) {1968		seq_printf(s, "0x%04x %4d 0x%02x 0x%08x\n",1969			   hopid * PATH_LEN + i, i, hopid, data[i]);1970	}1971 1972	return 0;1973}1974 1975static int path_show(struct seq_file *s, void *not_used)1976{1977	struct tb_port *port = s->private;1978	struct tb_switch *sw = port->sw;1979	struct tb *tb = sw->tb;1980	int start, i, ret = 0;1981 1982	pm_runtime_get_sync(&sw->dev);1983 1984	if (mutex_lock_interruptible(&tb->lock)) {1985		ret = -ERESTARTSYS;1986		goto out_rpm_put;1987	}1988 1989	seq_puts(s, "# offset relative_offset in_hop_id value\n");1990 1991	/* NHI and lane adapters have entry for path 0 */1992	if (tb_port_is_null(port) || tb_port_is_nhi(port)) {1993		ret = path_show_one(port, s, 0);1994		if (ret)1995			goto out_unlock;1996	}1997 1998	start = tb_port_is_nhi(port) ? 1 : TB_PATH_MIN_HOPID;1999 2000	for (i = start; i <= port->config.max_in_hop_id; i++) {2001		ret = path_show_one(port, s, i);2002		if (ret)2003			break;2004	}2005 2006out_unlock:2007	mutex_unlock(&tb->lock);2008out_rpm_put:2009	pm_runtime_mark_last_busy(&sw->dev);2010	pm_runtime_put_autosuspend(&sw->dev);2011 2012	return ret;2013}2014DEBUGFS_ATTR_RO(path);2015 2016static int counter_set_regs_show(struct tb_port *port, struct seq_file *s,2017				 int counter)2018{2019	u32 data[COUNTER_SET_LEN];2020	int ret, i;2021 2022	ret = tb_port_read(port, data, TB_CFG_COUNTERS,2023			   counter * COUNTER_SET_LEN, ARRAY_SIZE(data));2024	if (ret) {2025		seq_printf(s, "0x%04x <not accessible>\n",2026			   counter * COUNTER_SET_LEN);2027		return ret;2028	}2029 2030	for (i = 0; i < ARRAY_SIZE(data); i++) {2031		seq_printf(s, "0x%04x %4d 0x%02x 0x%08x\n",2032			   counter * COUNTER_SET_LEN + i, i, counter, data[i]);2033	}2034 2035	return 0;2036}2037 2038static int counters_show(struct seq_file *s, void *not_used)2039{2040	struct tb_port *port = s->private;2041	struct tb_switch *sw = port->sw;2042	struct tb *tb = sw->tb;2043	int i, ret = 0;2044 2045	pm_runtime_get_sync(&sw->dev);2046 2047	if (mutex_lock_interruptible(&tb->lock)) {2048		ret = -ERESTARTSYS;2049		goto out;2050	}2051 2052	seq_puts(s, "# offset relative_offset counter_id value\n");2053 2054	for (i = 0; i < port->config.max_counters; i++) {2055		ret = counter_set_regs_show(port, s, i);2056		if (ret)2057			break;2058	}2059 2060	mutex_unlock(&tb->lock);2061 2062out:2063	pm_runtime_mark_last_busy(&sw->dev);2064	pm_runtime_put_autosuspend(&sw->dev);2065 2066	return ret;2067}2068DEBUGFS_ATTR_RW(counters);2069 2070static int sb_regs_show(struct tb_port *port, const struct sb_reg *sb_regs,2071			size_t size, enum usb4_sb_target target, u8 index,2072			struct seq_file *s)2073{2074	int ret, i;2075 2076	seq_puts(s, "# register value\n");2077 2078	for (i = 0; i < size; i++) {2079		const struct sb_reg *regs = &sb_regs[i];2080		u8 data[64];2081		int j;2082 2083		memset(data, 0, sizeof(data));2084		ret = usb4_port_sb_read(port, target, index, regs->reg, data,2085					regs->size);2086		if (ret)2087			return ret;2088 2089		seq_printf(s, "0x%02x", regs->reg);2090		for (j = 0; j < regs->size; j++)2091			seq_printf(s, " 0x%02x", data[j]);2092		seq_puts(s, "\n");2093	}2094 2095	return 0;2096}2097 2098static int port_sb_regs_show(struct seq_file *s, void *not_used)2099{2100	struct tb_port *port = s->private;2101	struct tb_switch *sw = port->sw;2102	struct tb *tb = sw->tb;2103	int ret;2104 2105	pm_runtime_get_sync(&sw->dev);2106 2107	if (mutex_lock_interruptible(&tb->lock)) {2108		ret = -ERESTARTSYS;2109		goto out_rpm_put;2110	}2111 2112	ret = sb_regs_show(port, port_sb_regs, ARRAY_SIZE(port_sb_regs),2113			   USB4_SB_TARGET_ROUTER, 0, s);2114 2115	mutex_unlock(&tb->lock);2116out_rpm_put:2117	pm_runtime_mark_last_busy(&sw->dev);2118	pm_runtime_put_autosuspend(&sw->dev);2119 2120	return ret;2121}2122DEBUGFS_ATTR_RW(port_sb_regs);2123 2124/**2125 * tb_switch_debugfs_init() - Add debugfs entries for router2126 * @sw: Pointer to the router2127 *2128 * Adds debugfs directories and files for given router.2129 */2130void tb_switch_debugfs_init(struct tb_switch *sw)2131{2132	struct dentry *debugfs_dir;2133	struct tb_port *port;2134 2135	debugfs_dir = debugfs_create_dir(dev_name(&sw->dev), tb_debugfs_root);2136	sw->debugfs_dir = debugfs_dir;2137	debugfs_create_file("regs", DEBUGFS_MODE, debugfs_dir, sw,2138			    &switch_regs_fops);2139 2140	tb_switch_for_each_port(sw, port) {2141		struct dentry *debugfs_dir;2142		char dir_name[10];2143 2144		if (port->disabled)2145			continue;2146		if (port->config.type == TB_TYPE_INACTIVE)2147			continue;2148 2149		snprintf(dir_name, sizeof(dir_name), "port%d", port->port);2150		debugfs_dir = debugfs_create_dir(dir_name, sw->debugfs_dir);2151		debugfs_create_file("regs", DEBUGFS_MODE, debugfs_dir,2152				    port, &port_regs_fops);2153		debugfs_create_file("path", 0400, debugfs_dir, port,2154				    &path_fops);2155		if (port->config.counters_support)2156			debugfs_create_file("counters", 0600, debugfs_dir, port,2157					    &counters_fops);2158		if (port->usb4)2159			debugfs_create_file("sb_regs", DEBUGFS_MODE, debugfs_dir,2160					    port, &port_sb_regs_fops);2161	}2162 2163	margining_switch_init(sw);2164}2165 2166/**2167 * tb_switch_debugfs_remove() - Remove all router debugfs entries2168 * @sw: Pointer to the router2169 *2170 * Removes all previously added debugfs entries under this router.2171 */2172void tb_switch_debugfs_remove(struct tb_switch *sw)2173{2174	margining_switch_remove(sw);2175	debugfs_remove_recursive(sw->debugfs_dir);2176}2177 2178void tb_xdomain_debugfs_init(struct tb_xdomain *xd)2179{2180	margining_xdomain_init(xd);2181}2182 2183void tb_xdomain_debugfs_remove(struct tb_xdomain *xd)2184{2185	margining_xdomain_remove(xd);2186}2187 2188/**2189 * tb_service_debugfs_init() - Add debugfs directory for service2190 * @svc: Thunderbolt service pointer2191 *2192 * Adds debugfs directory for service.2193 */2194void tb_service_debugfs_init(struct tb_service *svc)2195{2196	svc->debugfs_dir = debugfs_create_dir(dev_name(&svc->dev),2197					      tb_debugfs_root);2198}2199 2200/**2201 * tb_service_debugfs_remove() - Remove service debugfs directory2202 * @svc: Thunderbolt service pointer2203 *2204 * Removes the previously created debugfs directory for @svc.2205 */2206void tb_service_debugfs_remove(struct tb_service *svc)2207{2208	debugfs_remove_recursive(svc->debugfs_dir);2209	svc->debugfs_dir = NULL;2210}2211 2212static int retimer_sb_regs_show(struct seq_file *s, void *not_used)2213{2214	struct tb_retimer *rt = s->private;2215	struct tb *tb = rt->tb;2216	int ret;2217 2218	pm_runtime_get_sync(&rt->dev);2219 2220	if (mutex_lock_interruptible(&tb->lock)) {2221		ret = -ERESTARTSYS;2222		goto out_rpm_put;2223	}2224 2225	ret = sb_regs_show(rt->port, retimer_sb_regs, ARRAY_SIZE(retimer_sb_regs),2226			   USB4_SB_TARGET_RETIMER, rt->index, s);2227 2228	mutex_unlock(&tb->lock);2229out_rpm_put:2230	pm_runtime_mark_last_busy(&rt->dev);2231	pm_runtime_put_autosuspend(&rt->dev);2232 2233	return ret;2234}2235DEBUGFS_ATTR_RW(retimer_sb_regs);2236 2237/**2238 * tb_retimer_debugfs_init() - Add debugfs directory for retimer2239 * @rt: Pointer to retimer structure2240 *2241 * Adds and populates retimer debugfs directory.2242 */2243void tb_retimer_debugfs_init(struct tb_retimer *rt)2244{2245	struct dentry *debugfs_dir;2246 2247	debugfs_dir = debugfs_create_dir(dev_name(&rt->dev), tb_debugfs_root);2248	debugfs_create_file("sb_regs", DEBUGFS_MODE, debugfs_dir, rt,2249			    &retimer_sb_regs_fops);2250	margining_retimer_init(rt, debugfs_dir);2251}2252 2253/**2254 * tb_retimer_debugfs_remove() - Remove retimer debugfs directory2255 * @rt: Pointer to retimer structure2256 *2257 * Removes the retimer debugfs directory along with its contents.2258 */2259void tb_retimer_debugfs_remove(struct tb_retimer *rt)2260{2261	debugfs_lookup_and_remove(dev_name(&rt->dev), tb_debugfs_root);2262	margining_retimer_remove(rt);2263}2264 2265void tb_debugfs_init(void)2266{2267	tb_debugfs_root = debugfs_create_dir("thunderbolt", NULL);2268}2269 2270void tb_debugfs_exit(void)2271{2272	debugfs_remove_recursive(tb_debugfs_root);2273}2274