thunderbolt: Split out margining from USB4 port
We are going to expand lane margining support for retimers too so split out the generic margining functionality out of being specific to USB4 ports. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
This commit is contained in:
parent
6d241fa001
commit
ec6f888ed0
@ -379,6 +379,7 @@ out_rpm_put:
|
||||
#if IS_ENABLED(CONFIG_USB4_DEBUGFS_MARGINING)
|
||||
/**
|
||||
* struct tb_margining - Lane margining support
|
||||
* @port: USB4 port through which the margining operations are run
|
||||
* @caps: Port lane margining capabilities
|
||||
* @results: Last lane margining results
|
||||
* @lanes: %0, %1 or %7 (all)
|
||||
@ -395,6 +396,7 @@ out_rpm_put:
|
||||
* right/high
|
||||
*/
|
||||
struct tb_margining {
|
||||
struct tb_port *port;
|
||||
u32 caps[2];
|
||||
u32 results[2];
|
||||
unsigned int lanes;
|
||||
@ -410,36 +412,38 @@ struct tb_margining {
|
||||
bool right_high;
|
||||
};
|
||||
|
||||
static bool supports_software(const struct usb4_port *usb4)
|
||||
static bool supports_software(const struct tb_margining *margining)
|
||||
{
|
||||
return usb4->margining->caps[0] & USB4_MARGIN_CAP_0_MODES_SW;
|
||||
return margining->caps[0] & USB4_MARGIN_CAP_0_MODES_SW;
|
||||
}
|
||||
|
||||
static bool supports_hardware(const struct usb4_port *usb4)
|
||||
static bool supports_hardware(const struct tb_margining *margining)
|
||||
{
|
||||
return usb4->margining->caps[0] & USB4_MARGIN_CAP_0_MODES_HW;
|
||||
return margining->caps[0] & USB4_MARGIN_CAP_0_MODES_HW;
|
||||
}
|
||||
|
||||
static bool both_lanes(const struct usb4_port *usb4)
|
||||
static bool both_lanes(const struct tb_margining *margining)
|
||||
{
|
||||
return usb4->margining->caps[0] & USB4_MARGIN_CAP_0_2_LANES;
|
||||
return margining->caps[0] & USB4_MARGIN_CAP_0_2_LANES;
|
||||
}
|
||||
|
||||
static unsigned int independent_voltage_margins(const struct usb4_port *usb4)
|
||||
static unsigned int
|
||||
independent_voltage_margins(const struct tb_margining *margining)
|
||||
{
|
||||
return (usb4->margining->caps[0] & USB4_MARGIN_CAP_0_VOLTAGE_INDP_MASK) >>
|
||||
return (margining->caps[0] & USB4_MARGIN_CAP_0_VOLTAGE_INDP_MASK) >>
|
||||
USB4_MARGIN_CAP_0_VOLTAGE_INDP_SHIFT;
|
||||
}
|
||||
|
||||
static bool supports_time(const struct usb4_port *usb4)
|
||||
static bool supports_time(const struct tb_margining *margining)
|
||||
{
|
||||
return usb4->margining->caps[0] & USB4_MARGIN_CAP_0_TIME;
|
||||
return margining->caps[0] & USB4_MARGIN_CAP_0_TIME;
|
||||
}
|
||||
|
||||
/* Only applicable if supports_time() returns true */
|
||||
static unsigned int independent_time_margins(const struct usb4_port *usb4)
|
||||
static unsigned int
|
||||
independent_time_margins(const struct tb_margining *margining)
|
||||
{
|
||||
return (usb4->margining->caps[1] & USB4_MARGIN_CAP_1_TIME_INDP_MASK) >>
|
||||
return (margining->caps[1] & USB4_MARGIN_CAP_1_TIME_INDP_MASK) >>
|
||||
USB4_MARGIN_CAP_1_TIME_INDP_SHIFT;
|
||||
}
|
||||
|
||||
@ -448,9 +452,8 @@ margining_ber_level_write(struct file *file, const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct seq_file *s = file->private_data;
|
||||
struct tb_port *port = s->private;
|
||||
struct usb4_port *usb4 = port->usb4;
|
||||
struct tb *tb = port->sw->tb;
|
||||
struct tb_margining *margining = s->private;
|
||||
struct tb *tb = margining->port->sw->tb;
|
||||
unsigned int val;
|
||||
int ret = 0;
|
||||
char *buf;
|
||||
@ -458,7 +461,7 @@ margining_ber_level_write(struct file *file, const char __user *user_buf,
|
||||
if (mutex_lock_interruptible(&tb->lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (usb4->margining->software) {
|
||||
if (margining->software) {
|
||||
ret = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
@ -475,13 +478,13 @@ margining_ber_level_write(struct file *file, const char __user *user_buf,
|
||||
if (ret)
|
||||
goto out_free;
|
||||
|
||||
if (val < usb4->margining->min_ber_level ||
|
||||
val > usb4->margining->max_ber_level) {
|
||||
if (val < margining->min_ber_level ||
|
||||
val > margining->max_ber_level) {
|
||||
ret = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
usb4->margining->ber_level = val;
|
||||
margining->ber_level = val;
|
||||
|
||||
out_free:
|
||||
free_page((unsigned long)buf);
|
||||
@ -501,52 +504,50 @@ static void ber_level_show(struct seq_file *s, unsigned int val)
|
||||
|
||||
static int margining_ber_level_show(struct seq_file *s, void *not_used)
|
||||
{
|
||||
struct tb_port *port = s->private;
|
||||
struct usb4_port *usb4 = port->usb4;
|
||||
const struct tb_margining *margining = s->private;
|
||||
|
||||
if (usb4->margining->software)
|
||||
if (margining->software)
|
||||
return -EINVAL;
|
||||
ber_level_show(s, usb4->margining->ber_level);
|
||||
ber_level_show(s, margining->ber_level);
|
||||
return 0;
|
||||
}
|
||||
DEBUGFS_ATTR_RW(margining_ber_level);
|
||||
|
||||
static int margining_caps_show(struct seq_file *s, void *not_used)
|
||||
{
|
||||
struct tb_port *port = s->private;
|
||||
struct usb4_port *usb4 = port->usb4;
|
||||
struct tb *tb = port->sw->tb;
|
||||
struct tb_margining *margining = s->private;
|
||||
struct tb *tb = margining->port->sw->tb;
|
||||
u32 cap0, cap1;
|
||||
|
||||
if (mutex_lock_interruptible(&tb->lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
/* Dump the raw caps first */
|
||||
cap0 = usb4->margining->caps[0];
|
||||
cap0 = margining->caps[0];
|
||||
seq_printf(s, "0x%08x\n", cap0);
|
||||
cap1 = usb4->margining->caps[1];
|
||||
cap1 = margining->caps[1];
|
||||
seq_printf(s, "0x%08x\n", cap1);
|
||||
|
||||
seq_printf(s, "# software margining: %s\n",
|
||||
supports_software(usb4) ? "yes" : "no");
|
||||
if (supports_hardware(usb4)) {
|
||||
supports_software(margining) ? "yes" : "no");
|
||||
if (supports_hardware(margining)) {
|
||||
seq_puts(s, "# hardware margining: yes\n");
|
||||
seq_puts(s, "# minimum BER level contour: ");
|
||||
ber_level_show(s, usb4->margining->min_ber_level);
|
||||
ber_level_show(s, margining->min_ber_level);
|
||||
seq_puts(s, "# maximum BER level contour: ");
|
||||
ber_level_show(s, usb4->margining->max_ber_level);
|
||||
ber_level_show(s, margining->max_ber_level);
|
||||
} else {
|
||||
seq_puts(s, "# hardware margining: no\n");
|
||||
}
|
||||
|
||||
seq_printf(s, "# both lanes simultaneously: %s\n",
|
||||
both_lanes(usb4) ? "yes" : "no");
|
||||
both_lanes(margining) ? "yes" : "no");
|
||||
seq_printf(s, "# voltage margin steps: %u\n",
|
||||
usb4->margining->voltage_steps);
|
||||
margining->voltage_steps);
|
||||
seq_printf(s, "# maximum voltage offset: %u mV\n",
|
||||
usb4->margining->max_voltage_offset);
|
||||
margining->max_voltage_offset);
|
||||
|
||||
switch (independent_voltage_margins(usb4)) {
|
||||
switch (independent_voltage_margins(margining)) {
|
||||
case USB4_MARGIN_CAP_0_VOLTAGE_MIN:
|
||||
seq_puts(s, "# returns minimum between high and low voltage margins\n");
|
||||
break;
|
||||
@ -558,12 +559,12 @@ static int margining_caps_show(struct seq_file *s, void *not_used)
|
||||
break;
|
||||
}
|
||||
|
||||
if (supports_time(usb4)) {
|
||||
if (supports_time(margining)) {
|
||||
seq_puts(s, "# time margining: yes\n");
|
||||
seq_printf(s, "# time margining is destructive: %s\n",
|
||||
cap1 & USB4_MARGIN_CAP_1_TIME_DESTR ? "yes" : "no");
|
||||
|
||||
switch (independent_time_margins(usb4)) {
|
||||
switch (independent_time_margins(margining)) {
|
||||
case USB4_MARGIN_CAP_1_TIME_MIN:
|
||||
seq_puts(s, "# returns minimum between left and right time margins\n");
|
||||
break;
|
||||
@ -576,9 +577,9 @@ static int margining_caps_show(struct seq_file *s, void *not_used)
|
||||
}
|
||||
|
||||
seq_printf(s, "# time margin steps: %u\n",
|
||||
usb4->margining->time_steps);
|
||||
margining->time_steps);
|
||||
seq_printf(s, "# maximum time offset: %u mUI\n",
|
||||
usb4->margining->max_time_offset);
|
||||
margining->max_time_offset);
|
||||
} else {
|
||||
seq_puts(s, "# time margining: no\n");
|
||||
}
|
||||
@ -593,9 +594,8 @@ margining_lanes_write(struct file *file, const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct seq_file *s = file->private_data;
|
||||
struct tb_port *port = s->private;
|
||||
struct usb4_port *usb4 = port->usb4;
|
||||
struct tb *tb = port->sw->tb;
|
||||
struct tb_margining *margining = s->private;
|
||||
struct tb *tb = margining->port->sw->tb;
|
||||
int ret = 0;
|
||||
char *buf;
|
||||
|
||||
@ -611,13 +611,13 @@ margining_lanes_write(struct file *file, const char __user *user_buf,
|
||||
}
|
||||
|
||||
if (!strcmp(buf, "0")) {
|
||||
usb4->margining->lanes = 0;
|
||||
margining->lanes = 0;
|
||||
} else if (!strcmp(buf, "1")) {
|
||||
usb4->margining->lanes = 1;
|
||||
margining->lanes = 1;
|
||||
} else if (!strcmp(buf, "all")) {
|
||||
/* Needs to be supported */
|
||||
if (both_lanes(usb4))
|
||||
usb4->margining->lanes = 7;
|
||||
if (both_lanes(margining))
|
||||
margining->lanes = 7;
|
||||
else
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
@ -633,16 +633,15 @@ out_free:
|
||||
|
||||
static int margining_lanes_show(struct seq_file *s, void *not_used)
|
||||
{
|
||||
struct tb_port *port = s->private;
|
||||
struct usb4_port *usb4 = port->usb4;
|
||||
struct tb *tb = port->sw->tb;
|
||||
struct tb_margining *margining = s->private;
|
||||
struct tb *tb = margining->port->sw->tb;
|
||||
unsigned int lanes;
|
||||
|
||||
if (mutex_lock_interruptible(&tb->lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
lanes = usb4->margining->lanes;
|
||||
if (both_lanes(usb4)) {
|
||||
lanes = margining->lanes;
|
||||
if (both_lanes(margining)) {
|
||||
if (!lanes)
|
||||
seq_puts(s, "[0] 1 all\n");
|
||||
else if (lanes == 1)
|
||||
@ -666,9 +665,8 @@ static ssize_t margining_mode_write(struct file *file,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct seq_file *s = file->private_data;
|
||||
struct tb_port *port = s->private;
|
||||
struct usb4_port *usb4 = port->usb4;
|
||||
struct tb *tb = port->sw->tb;
|
||||
struct tb_margining *margining = s->private;
|
||||
struct tb *tb = margining->port->sw->tb;
|
||||
int ret = 0;
|
||||
char *buf;
|
||||
|
||||
@ -684,13 +682,13 @@ static ssize_t margining_mode_write(struct file *file,
|
||||
}
|
||||
|
||||
if (!strcmp(buf, "software")) {
|
||||
if (supports_software(usb4))
|
||||
usb4->margining->software = true;
|
||||
if (supports_software(margining))
|
||||
margining->software = true;
|
||||
else
|
||||
ret = -EINVAL;
|
||||
} else if (!strcmp(buf, "hardware")) {
|
||||
if (supports_hardware(usb4))
|
||||
usb4->margining->software = false;
|
||||
if (supports_hardware(margining))
|
||||
margining->software = false;
|
||||
else
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
@ -706,23 +704,22 @@ out_free:
|
||||
|
||||
static int margining_mode_show(struct seq_file *s, void *not_used)
|
||||
{
|
||||
const struct tb_port *port = s->private;
|
||||
const struct usb4_port *usb4 = port->usb4;
|
||||
struct tb *tb = port->sw->tb;
|
||||
struct tb_margining *margining = s->private;
|
||||
struct tb *tb = margining->port->sw->tb;
|
||||
const char *space = "";
|
||||
|
||||
if (mutex_lock_interruptible(&tb->lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (supports_software(usb4)) {
|
||||
if (usb4->margining->software)
|
||||
if (supports_software(margining)) {
|
||||
if (margining->software)
|
||||
seq_puts(s, "[software]");
|
||||
else
|
||||
seq_puts(s, "software");
|
||||
space = " ";
|
||||
}
|
||||
if (supports_hardware(usb4)) {
|
||||
if (usb4->margining->software)
|
||||
if (supports_hardware(margining)) {
|
||||
if (margining->software)
|
||||
seq_printf(s, "%shardware", space);
|
||||
else
|
||||
seq_printf(s, "%s[hardware]", space);
|
||||
@ -737,10 +734,9 @@ DEBUGFS_ATTR_RW(margining_mode);
|
||||
|
||||
static int margining_run_write(void *data, u64 val)
|
||||
{
|
||||
struct tb_port *port = data;
|
||||
struct usb4_port *usb4 = port->usb4;
|
||||
struct tb_margining *margining = data;
|
||||
struct tb_port *port = margining->port;
|
||||
struct tb_switch *sw = port->sw;
|
||||
struct tb_margining *margining;
|
||||
struct tb_switch *down_sw;
|
||||
struct tb *tb = sw->tb;
|
||||
int ret, clx;
|
||||
@ -775,8 +771,6 @@ static int margining_run_write(void *data, u64 val)
|
||||
clx = ret;
|
||||
}
|
||||
|
||||
margining = usb4->margining;
|
||||
|
||||
if (margining->software) {
|
||||
tb_port_dbg(port, "running software %s lane margining for lanes %u\n",
|
||||
margining->time ? "time" : "voltage", margining->lanes);
|
||||
@ -817,16 +811,15 @@ static ssize_t margining_results_write(struct file *file,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct seq_file *s = file->private_data;
|
||||
struct tb_port *port = s->private;
|
||||
struct usb4_port *usb4 = port->usb4;
|
||||
struct tb *tb = port->sw->tb;
|
||||
struct tb_margining *margining = s->private;
|
||||
struct tb *tb = margining->port->sw->tb;
|
||||
|
||||
if (mutex_lock_interruptible(&tb->lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
/* Just clear the results */
|
||||
usb4->margining->results[0] = 0;
|
||||
usb4->margining->results[1] = 0;
|
||||
margining->results[0] = 0;
|
||||
margining->results[1] = 0;
|
||||
|
||||
mutex_unlock(&tb->lock);
|
||||
return count;
|
||||
@ -860,15 +853,12 @@ static void time_margin_show(struct seq_file *s,
|
||||
|
||||
static int margining_results_show(struct seq_file *s, void *not_used)
|
||||
{
|
||||
struct tb_port *port = s->private;
|
||||
struct usb4_port *usb4 = port->usb4;
|
||||
struct tb_margining *margining;
|
||||
struct tb *tb = port->sw->tb;
|
||||
struct tb_margining *margining = s->private;
|
||||
struct tb *tb = margining->port->sw->tb;
|
||||
|
||||
if (mutex_lock_interruptible(&tb->lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
margining = usb4->margining;
|
||||
/* Dump the raw results first */
|
||||
seq_printf(s, "0x%08x\n", margining->results[0]);
|
||||
/* Only the hardware margining has two result dwords */
|
||||
@ -930,9 +920,8 @@ static ssize_t margining_test_write(struct file *file,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct seq_file *s = file->private_data;
|
||||
struct tb_port *port = s->private;
|
||||
struct usb4_port *usb4 = port->usb4;
|
||||
struct tb *tb = port->sw->tb;
|
||||
struct tb_margining *margining = s->private;
|
||||
struct tb *tb = margining->port->sw->tb;
|
||||
int ret = 0;
|
||||
char *buf;
|
||||
|
||||
@ -947,10 +936,10 @@ static ssize_t margining_test_write(struct file *file,
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (!strcmp(buf, "time") && supports_time(usb4))
|
||||
usb4->margining->time = true;
|
||||
if (!strcmp(buf, "time") && supports_time(margining))
|
||||
margining->time = true;
|
||||
else if (!strcmp(buf, "voltage"))
|
||||
usb4->margining->time = false;
|
||||
margining->time = false;
|
||||
else
|
||||
ret = -EINVAL;
|
||||
|
||||
@ -963,15 +952,14 @@ out_free:
|
||||
|
||||
static int margining_test_show(struct seq_file *s, void *not_used)
|
||||
{
|
||||
struct tb_port *port = s->private;
|
||||
struct usb4_port *usb4 = port->usb4;
|
||||
struct tb *tb = port->sw->tb;
|
||||
struct tb_margining *margining = s->private;
|
||||
struct tb *tb = margining->port->sw->tb;
|
||||
|
||||
if (mutex_lock_interruptible(&tb->lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (supports_time(usb4)) {
|
||||
if (usb4->margining->time)
|
||||
if (supports_time(margining)) {
|
||||
if (margining->time)
|
||||
seq_puts(s, "voltage [time]\n");
|
||||
else
|
||||
seq_puts(s, "[voltage] time\n");
|
||||
@ -989,9 +977,8 @@ static ssize_t margining_margin_write(struct file *file,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct seq_file *s = file->private_data;
|
||||
struct tb_port *port = s->private;
|
||||
struct usb4_port *usb4 = port->usb4;
|
||||
struct tb *tb = port->sw->tb;
|
||||
struct tb_margining *margining = s->private;
|
||||
struct tb *tb = margining->port->sw->tb;
|
||||
int ret = 0;
|
||||
char *buf;
|
||||
|
||||
@ -1006,18 +993,18 @@ static ssize_t margining_margin_write(struct file *file,
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (usb4->margining->time) {
|
||||
if (margining->time) {
|
||||
if (!strcmp(buf, "left"))
|
||||
usb4->margining->right_high = false;
|
||||
margining->right_high = false;
|
||||
else if (!strcmp(buf, "right"))
|
||||
usb4->margining->right_high = true;
|
||||
margining->right_high = true;
|
||||
else
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
if (!strcmp(buf, "low"))
|
||||
usb4->margining->right_high = false;
|
||||
margining->right_high = false;
|
||||
else if (!strcmp(buf, "high"))
|
||||
usb4->margining->right_high = true;
|
||||
margining->right_high = true;
|
||||
else
|
||||
ret = -EINVAL;
|
||||
}
|
||||
@ -1031,20 +1018,19 @@ out_free:
|
||||
|
||||
static int margining_margin_show(struct seq_file *s, void *not_used)
|
||||
{
|
||||
struct tb_port *port = s->private;
|
||||
struct usb4_port *usb4 = port->usb4;
|
||||
struct tb *tb = port->sw->tb;
|
||||
struct tb_margining *margining = s->private;
|
||||
struct tb *tb = margining->port->sw->tb;
|
||||
|
||||
if (mutex_lock_interruptible(&tb->lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (usb4->margining->time) {
|
||||
if (usb4->margining->right_high)
|
||||
if (margining->time) {
|
||||
if (margining->right_high)
|
||||
seq_puts(s, "left [right]\n");
|
||||
else
|
||||
seq_puts(s, "[left] right\n");
|
||||
} else {
|
||||
if (usb4->margining->right_high)
|
||||
if (margining->right_high)
|
||||
seq_puts(s, "low [high]\n");
|
||||
else
|
||||
seq_puts(s, "[low] high\n");
|
||||
@ -1075,16 +1061,16 @@ static void margining_port_init(struct tb_port *port)
|
||||
if (!margining)
|
||||
return;
|
||||
|
||||
margining->port = port;
|
||||
|
||||
ret = usb4_port_margining_caps(port, margining->caps);
|
||||
if (ret) {
|
||||
kfree(margining);
|
||||
return;
|
||||
}
|
||||
|
||||
usb4->margining = margining;
|
||||
|
||||
/* Set the initial mode */
|
||||
if (supports_software(usb4))
|
||||
if (supports_software(margining))
|
||||
margining->software = true;
|
||||
|
||||
val = (margining->caps[0] & USB4_MARGIN_CAP_0_VOLTAGE_STEPS_MASK) >>
|
||||
@ -1094,7 +1080,7 @@ static void margining_port_init(struct tb_port *port)
|
||||
USB4_MARGIN_CAP_0_MAX_VOLTAGE_OFFSET_SHIFT;
|
||||
margining->max_voltage_offset = 74 + val * 2;
|
||||
|
||||
if (supports_time(usb4)) {
|
||||
if (supports_time(margining)) {
|
||||
val = (margining->caps[1] & USB4_MARGIN_CAP_1_TIME_STEPS_MASK) >>
|
||||
USB4_MARGIN_CAP_1_TIME_STEPS_SHIFT;
|
||||
margining->time_steps = val;
|
||||
@ -1108,7 +1094,7 @@ static void margining_port_init(struct tb_port *port)
|
||||
}
|
||||
|
||||
dir = debugfs_create_dir("margining", parent);
|
||||
if (supports_hardware(usb4)) {
|
||||
if (supports_hardware(margining)) {
|
||||
val = (margining->caps[1] & USB4_MARGIN_CAP_1_MIN_BER_MASK) >>
|
||||
USB4_MARGIN_CAP_1_MIN_BER_SHIFT;
|
||||
margining->min_ber_level = val;
|
||||
@ -1119,19 +1105,23 @@ static void margining_port_init(struct tb_port *port)
|
||||
/* Set the default to minimum */
|
||||
margining->ber_level = margining->min_ber_level;
|
||||
|
||||
debugfs_create_file("ber_level_contour", 0400, dir, port,
|
||||
debugfs_create_file("ber_level_contour", 0400, dir, margining,
|
||||
&margining_ber_level_fops);
|
||||
}
|
||||
debugfs_create_file("caps", 0400, dir, port, &margining_caps_fops);
|
||||
debugfs_create_file("lanes", 0600, dir, port, &margining_lanes_fops);
|
||||
debugfs_create_file("mode", 0600, dir, port, &margining_mode_fops);
|
||||
debugfs_create_file("run", 0600, dir, port, &margining_run_fops);
|
||||
debugfs_create_file("results", 0600, dir, port, &margining_results_fops);
|
||||
debugfs_create_file("test", 0600, dir, port, &margining_test_fops);
|
||||
if (independent_voltage_margins(usb4) == USB4_MARGIN_CAP_0_VOLTAGE_HL ||
|
||||
(supports_time(usb4) &&
|
||||
independent_time_margins(usb4) == USB4_MARGIN_CAP_1_TIME_LR))
|
||||
debugfs_create_file("margin", 0600, dir, port, &margining_margin_fops);
|
||||
debugfs_create_file("caps", 0400, dir, margining, &margining_caps_fops);
|
||||
debugfs_create_file("lanes", 0600, dir, margining, &margining_lanes_fops);
|
||||
debugfs_create_file("mode", 0600, dir, margining, &margining_mode_fops);
|
||||
debugfs_create_file("run", 0600, dir, margining, &margining_run_fops);
|
||||
debugfs_create_file("results", 0600, dir, margining,
|
||||
&margining_results_fops);
|
||||
debugfs_create_file("test", 0600, dir, margining, &margining_test_fops);
|
||||
if (independent_voltage_margins(margining) == USB4_MARGIN_CAP_0_VOLTAGE_HL ||
|
||||
(supports_time(margining) &&
|
||||
independent_time_margins(margining) == USB4_MARGIN_CAP_1_TIME_LR))
|
||||
debugfs_create_file("margin", 0600, dir, margining,
|
||||
&margining_margin_fops);
|
||||
|
||||
usb4->margining = margining;
|
||||
}
|
||||
|
||||
static void margining_port_remove(struct tb_port *port)
|
||||
|
Loading…
Reference in New Issue
Block a user