mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-28 16:52:18 +00:00
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt.git
This commit is contained in:
commit
02f8f5ccba
@ -168,6 +168,13 @@ static bool parse_line(char **line, u32 *offs, u32 *val, int short_fmt_len,
|
|||||||
* offset relative_offset cap_id vs_cap_id value\n
|
* offset relative_offset cap_id vs_cap_id value\n
|
||||||
* v[0] v[1] v[2] v[3] v[4]
|
* v[0] v[1] v[2] v[3] v[4]
|
||||||
*
|
*
|
||||||
|
* For Path configuration space:
|
||||||
|
* Short format is: offset value\n
|
||||||
|
* v[0] v[1]
|
||||||
|
* Long format as produced from the read side:
|
||||||
|
* offset relative_offset in_hop_id value\n
|
||||||
|
* v[0] v[1] v[2] v[3]
|
||||||
|
*
|
||||||
* For Counter configuration space:
|
* For Counter configuration space:
|
||||||
* Short format is: offset\n
|
* Short format is: offset\n
|
||||||
* v[0]
|
* v[0]
|
||||||
@ -191,14 +198,33 @@ static bool parse_line(char **line, u32 *offs, u32 *val, int short_fmt_len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_USB4_DEBUGFS_WRITE)
|
#if IS_ENABLED(CONFIG_USB4_DEBUGFS_WRITE)
|
||||||
static ssize_t regs_write(struct tb_switch *sw, struct tb_port *port,
|
/*
|
||||||
const char __user *user_buf, size_t count,
|
* Path registers need to be written in double word pairs and they both must be
|
||||||
loff_t *ppos)
|
* read before written. This writes one double word in patch config space
|
||||||
|
* following the spec flow.
|
||||||
|
*/
|
||||||
|
static int path_write_one(struct tb_port *port, u32 val, u32 offset)
|
||||||
{
|
{
|
||||||
|
u32 index = offset % PATH_LEN;
|
||||||
|
u32 offs = offset - index;
|
||||||
|
u32 data[PATH_LEN];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = tb_port_read(port, data, TB_CFG_HOPS, offs, PATH_LEN);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
data[index] = val;
|
||||||
|
return tb_port_write(port, data, TB_CFG_HOPS, offs, PATH_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t regs_write(struct tb_switch *sw, struct tb_port *port,
|
||||||
|
enum tb_cfg_space space, const char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
int long_fmt_len, ret = 0;
|
||||||
struct tb *tb = sw->tb;
|
struct tb *tb = sw->tb;
|
||||||
char *line, *buf;
|
char *line, *buf;
|
||||||
u32 val, offset;
|
u32 val, offset;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
buf = validate_and_copy_from_user(user_buf, &count);
|
buf = validate_and_copy_from_user(user_buf, &count);
|
||||||
if (IS_ERR(buf))
|
if (IS_ERR(buf))
|
||||||
@ -214,12 +240,21 @@ static ssize_t regs_write(struct tb_switch *sw, struct tb_port *port,
|
|||||||
/* User did hardware changes behind the driver's back */
|
/* User did hardware changes behind the driver's back */
|
||||||
add_taint(TAINT_USER, LOCKDEP_STILL_OK);
|
add_taint(TAINT_USER, LOCKDEP_STILL_OK);
|
||||||
|
|
||||||
|
if (space == TB_CFG_HOPS)
|
||||||
|
long_fmt_len = 4;
|
||||||
|
else
|
||||||
|
long_fmt_len = 5;
|
||||||
|
|
||||||
line = buf;
|
line = buf;
|
||||||
while (parse_line(&line, &offset, &val, 2, 5)) {
|
while (parse_line(&line, &offset, &val, 2, long_fmt_len)) {
|
||||||
if (port)
|
if (port) {
|
||||||
ret = tb_port_write(port, &val, TB_CFG_PORT, offset, 1);
|
if (space == TB_CFG_HOPS)
|
||||||
else
|
ret = path_write_one(port, val, offset);
|
||||||
|
else
|
||||||
|
ret = tb_port_write(port, &val, space, offset, 1);
|
||||||
|
} else {
|
||||||
ret = tb_sw_write(sw, &val, TB_CFG_SWITCH, offset, 1);
|
ret = tb_sw_write(sw, &val, TB_CFG_SWITCH, offset, 1);
|
||||||
|
}
|
||||||
if (ret)
|
if (ret)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -240,7 +275,16 @@ static ssize_t port_regs_write(struct file *file, const char __user *user_buf,
|
|||||||
struct seq_file *s = file->private_data;
|
struct seq_file *s = file->private_data;
|
||||||
struct tb_port *port = s->private;
|
struct tb_port *port = s->private;
|
||||||
|
|
||||||
return regs_write(port->sw, port, user_buf, count, ppos);
|
return regs_write(port->sw, port, TB_CFG_PORT, user_buf, count, ppos);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t path_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;
|
||||||
|
|
||||||
|
return regs_write(port->sw, port, TB_CFG_HOPS, user_buf, count, ppos);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t switch_regs_write(struct file *file, const char __user *user_buf,
|
static ssize_t switch_regs_write(struct file *file, const char __user *user_buf,
|
||||||
@ -249,7 +293,7 @@ static ssize_t switch_regs_write(struct file *file, const char __user *user_buf,
|
|||||||
struct seq_file *s = file->private_data;
|
struct seq_file *s = file->private_data;
|
||||||
struct tb_switch *sw = s->private;
|
struct tb_switch *sw = s->private;
|
||||||
|
|
||||||
return regs_write(sw, NULL, user_buf, count, ppos);
|
return regs_write(sw, NULL, TB_CFG_SWITCH, user_buf, count, ppos);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool parse_sb_line(char **line, u8 *reg, u8 *data, size_t data_size,
|
static bool parse_sb_line(char **line, u8 *reg, u8 *data, size_t data_size,
|
||||||
@ -401,6 +445,7 @@ static ssize_t retimer_sb_regs_write(struct file *file,
|
|||||||
#define DEBUGFS_MODE 0600
|
#define DEBUGFS_MODE 0600
|
||||||
#else
|
#else
|
||||||
#define port_regs_write NULL
|
#define port_regs_write NULL
|
||||||
|
#define path_write NULL
|
||||||
#define switch_regs_write NULL
|
#define switch_regs_write NULL
|
||||||
#define port_sb_regs_write NULL
|
#define port_sb_regs_write NULL
|
||||||
#define retimer_sb_regs_write NULL
|
#define retimer_sb_regs_write NULL
|
||||||
@ -2243,7 +2288,7 @@ static int path_show(struct seq_file *s, void *not_used)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
DEBUGFS_ATTR_RO(path);
|
DEBUGFS_ATTR_RW(path);
|
||||||
|
|
||||||
static int counter_set_regs_show(struct tb_port *port, struct seq_file *s,
|
static int counter_set_regs_show(struct tb_port *port, struct seq_file *s,
|
||||||
int counter)
|
int counter)
|
||||||
|
Loading…
Reference in New Issue
Block a user