1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2020, Intel Corporation
6 * Authors: Gil Fine <gil.fine@intel.com>
7 * Mika Westerberg <mika.westerberg@linux.intel.com>
10 #include <linux/debugfs.h>
11 #include <linux/pm_runtime.h>
12 #include <linux/uaccess.h>
16 #define PORT_CAP_PCIE_LEN 1
17 #define PORT_CAP_POWER_LEN 2
18 #define PORT_CAP_LANE_LEN 3
19 #define PORT_CAP_USB3_LEN 5
20 #define PORT_CAP_DP_LEN 8
21 #define PORT_CAP_TMU_LEN 8
22 #define PORT_CAP_BASIC_LEN 9
23 #define PORT_CAP_USB4_LEN 20
25 #define SWITCH_CAP_TMU_LEN 26
26 #define SWITCH_CAP_BASIC_LEN 27
30 #define COUNTER_SET_LEN 3
32 #define DEBUGFS_ATTR(__space, __write) \
33 static int __space ## _open(struct inode *inode, struct file *file) \
35 return single_open(file, __space ## _show, inode->i_private); \
38 static const struct file_operations __space ## _fops = { \
39 .owner = THIS_MODULE, \
40 .open = __space ## _open, \
41 .release = single_release, \
44 .llseek = seq_lseek, \
47 #define DEBUGFS_ATTR_RO(__space) \
48 DEBUGFS_ATTR(__space, NULL)
50 #define DEBUGFS_ATTR_RW(__space) \
51 DEBUGFS_ATTR(__space, __space ## _write)
53 static struct dentry
*tb_debugfs_root
;
55 static void *validate_and_copy_from_user(const void __user
*user_buf
,
62 return ERR_PTR(-EINVAL
);
64 if (!access_ok(user_buf
, *count
))
65 return ERR_PTR(-EFAULT
);
67 buf
= (void *)get_zeroed_page(GFP_KERNEL
);
69 return ERR_PTR(-ENOMEM
);
71 nbytes
= min_t(size_t, *count
, PAGE_SIZE
);
72 if (copy_from_user(buf
, user_buf
, nbytes
)) {
73 free_page((unsigned long)buf
);
74 return ERR_PTR(-EFAULT
);
81 static bool parse_line(char **line
, u32
*offs
, u32
*val
, int short_fmt_len
,
88 token
= strsep(line
, "\n");
93 * For Adapter/Router configuration space:
94 * Short format is: offset value\n
96 * Long format as produced from the read side:
97 * offset relative_offset cap_id vs_cap_id value\n
98 * v[0] v[1] v[2] v[3] v[4]
100 * For Counter configuration space:
101 * Short format is: offset\n
103 * Long format as produced from the read side:
104 * offset relative_offset counter_id value\n
105 * v[0] v[1] v[2] v[3]
107 ret
= sscanf(token
, "%i %i %i %i %i", &v
[0], &v
[1], &v
[2], &v
[3], &v
[4]);
108 /* In case of Counters, clear counter, "val" content is NA */
109 if (ret
== short_fmt_len
) {
111 *val
= v
[short_fmt_len
- 1];
113 } else if (ret
== long_fmt_len
) {
115 *val
= v
[long_fmt_len
- 1];
122 #if IS_ENABLED(CONFIG_USB4_DEBUGFS_WRITE)
123 static ssize_t
regs_write(struct tb_switch
*sw
, struct tb_port
*port
,
124 const char __user
*user_buf
, size_t count
,
127 struct tb
*tb
= sw
->tb
;
132 buf
= validate_and_copy_from_user(user_buf
, &count
);
136 pm_runtime_get_sync(&sw
->dev
);
138 if (mutex_lock_interruptible(&tb
->lock
)) {
143 /* User did hardware changes behind the driver's back */
144 add_taint(TAINT_USER
, LOCKDEP_STILL_OK
);
147 while (parse_line(&line
, &offset
, &val
, 2, 5)) {
149 ret
= tb_port_write(port
, &val
, TB_CFG_PORT
, offset
, 1);
151 ret
= tb_sw_write(sw
, &val
, TB_CFG_SWITCH
, offset
, 1);
156 mutex_unlock(&tb
->lock
);
159 pm_runtime_mark_last_busy(&sw
->dev
);
160 pm_runtime_put_autosuspend(&sw
->dev
);
161 free_page((unsigned long)buf
);
163 return ret
< 0 ? ret
: count
;
166 static ssize_t
port_regs_write(struct file
*file
, const char __user
*user_buf
,
167 size_t count
, loff_t
*ppos
)
169 struct seq_file
*s
= file
->private_data
;
170 struct tb_port
*port
= s
->private;
172 return regs_write(port
->sw
, port
, user_buf
, count
, ppos
);
175 static ssize_t
switch_regs_write(struct file
*file
, const char __user
*user_buf
,
176 size_t count
, loff_t
*ppos
)
178 struct seq_file
*s
= file
->private_data
;
179 struct tb_switch
*sw
= s
->private;
181 return regs_write(sw
, NULL
, user_buf
, count
, ppos
);
183 #define DEBUGFS_MODE 0600
185 #define port_regs_write NULL
186 #define switch_regs_write NULL
187 #define DEBUGFS_MODE 0400
190 static int port_clear_all_counters(struct tb_port
*port
)
195 buf
= kcalloc(COUNTER_SET_LEN
* port
->config
.max_counters
, sizeof(u32
),
200 ret
= tb_port_write(port
, buf
, TB_CFG_COUNTERS
, 0,
201 COUNTER_SET_LEN
* port
->config
.max_counters
);
207 static ssize_t
counters_write(struct file
*file
, const char __user
*user_buf
,
208 size_t count
, loff_t
*ppos
)
210 struct seq_file
*s
= file
->private_data
;
211 struct tb_port
*port
= s
->private;
212 struct tb_switch
*sw
= port
->sw
;
213 struct tb
*tb
= port
->sw
->tb
;
217 buf
= validate_and_copy_from_user(user_buf
, &count
);
221 pm_runtime_get_sync(&sw
->dev
);
223 if (mutex_lock_interruptible(&tb
->lock
)) {
228 /* If written delimiter only, clear all counters in one shot */
229 if (buf
[0] == '\n') {
230 ret
= port_clear_all_counters(port
);
236 while (parse_line(&line
, &offset
, &val
, 1, 4)) {
237 ret
= tb_port_write(port
, &val
, TB_CFG_COUNTERS
,
244 mutex_unlock(&tb
->lock
);
247 pm_runtime_mark_last_busy(&sw
->dev
);
248 pm_runtime_put_autosuspend(&sw
->dev
);
249 free_page((unsigned long)buf
);
251 return ret
< 0 ? ret
: count
;
254 static void cap_show(struct seq_file
*s
, struct tb_switch
*sw
,
255 struct tb_port
*port
, unsigned int cap
, u8 cap_id
,
256 u8 vsec_id
, int length
)
261 int i
, dwords
= min(length
, TB_MAX_CONFIG_RW_LENGTH
);
262 u32 data
[TB_MAX_CONFIG_RW_LENGTH
];
265 ret
= tb_port_read(port
, data
, TB_CFG_PORT
, cap
+ offset
,
268 ret
= tb_sw_read(sw
, data
, TB_CFG_SWITCH
, cap
+ offset
, dwords
);
270 seq_printf(s
, "0x%04x <not accessible>\n",
273 seq_printf(s
, "0x%04x ...\n", cap
+ offset
+ 1);
277 for (i
= 0; i
< dwords
; i
++) {
278 seq_printf(s
, "0x%04x %4d 0x%02x 0x%02x 0x%08x\n",
279 cap
+ offset
+ i
, offset
+ i
,
280 cap_id
, vsec_id
, data
[i
]);
288 static void port_cap_show(struct tb_port
*port
, struct seq_file
*s
,
291 struct tb_cap_any header
;
296 ret
= tb_port_read(port
, &header
, TB_CFG_PORT
, cap
, 1);
298 seq_printf(s
, "0x%04x <capability read failed>\n", cap
);
302 switch (header
.basic
.cap
) {
303 case TB_PORT_CAP_PHY
:
304 length
= PORT_CAP_LANE_LEN
;
307 case TB_PORT_CAP_TIME1
:
308 length
= PORT_CAP_TMU_LEN
;
311 case TB_PORT_CAP_POWER
:
312 length
= PORT_CAP_POWER_LEN
;
315 case TB_PORT_CAP_ADAP
:
316 if (tb_port_is_pcie_down(port
) || tb_port_is_pcie_up(port
)) {
317 length
= PORT_CAP_PCIE_LEN
;
318 } else if (tb_port_is_dpin(port
) || tb_port_is_dpout(port
)) {
319 length
= PORT_CAP_DP_LEN
;
320 } else if (tb_port_is_usb3_down(port
) ||
321 tb_port_is_usb3_up(port
)) {
322 length
= PORT_CAP_USB3_LEN
;
324 seq_printf(s
, "0x%04x <unsupported capability 0x%02x>\n",
325 cap
, header
.basic
.cap
);
330 case TB_PORT_CAP_VSE
:
331 if (!header
.extended_short
.length
) {
332 ret
= tb_port_read(port
, (u32
*)&header
+ 1, TB_CFG_PORT
,
335 seq_printf(s
, "0x%04x <capability read failed>\n",
339 length
= header
.extended_long
.length
;
340 vsec_id
= header
.extended_short
.vsec_id
;
342 length
= header
.extended_short
.length
;
343 vsec_id
= header
.extended_short
.vsec_id
;
345 * Ice Lake and Tiger Lake do not implement the
346 * full length of the capability, only first 32
347 * dwords so hard-code it here.
350 (tb_switch_is_ice_lake(port
->sw
) ||
351 tb_switch_is_tiger_lake(port
->sw
)))
356 case TB_PORT_CAP_USB4
:
357 length
= PORT_CAP_USB4_LEN
;
361 seq_printf(s
, "0x%04x <unsupported capability 0x%02x>\n",
362 cap
, header
.basic
.cap
);
366 cap_show(s
, NULL
, port
, cap
, header
.basic
.cap
, vsec_id
, length
);
369 static void port_caps_show(struct tb_port
*port
, struct seq_file
*s
)
373 cap
= tb_port_next_cap(port
, 0);
375 port_cap_show(port
, s
, cap
);
376 cap
= tb_port_next_cap(port
, cap
);
380 static int port_basic_regs_show(struct tb_port
*port
, struct seq_file
*s
)
382 u32 data
[PORT_CAP_BASIC_LEN
];
385 ret
= tb_port_read(port
, data
, TB_CFG_PORT
, 0, ARRAY_SIZE(data
));
389 for (i
= 0; i
< ARRAY_SIZE(data
); i
++)
390 seq_printf(s
, "0x%04x %4d 0x00 0x00 0x%08x\n", i
, i
, data
[i
]);
395 static int port_regs_show(struct seq_file
*s
, void *not_used
)
397 struct tb_port
*port
= s
->private;
398 struct tb_switch
*sw
= port
->sw
;
399 struct tb
*tb
= sw
->tb
;
402 pm_runtime_get_sync(&sw
->dev
);
404 if (mutex_lock_interruptible(&tb
->lock
)) {
409 seq_puts(s
, "# offset relative_offset cap_id vs_cap_id value\n");
411 ret
= port_basic_regs_show(port
, s
);
415 port_caps_show(port
, s
);
418 mutex_unlock(&tb
->lock
);
420 pm_runtime_mark_last_busy(&sw
->dev
);
421 pm_runtime_put_autosuspend(&sw
->dev
);
425 DEBUGFS_ATTR_RW(port_regs
);
427 static void switch_cap_show(struct tb_switch
*sw
, struct seq_file
*s
,
430 struct tb_cap_any header
;
434 ret
= tb_sw_read(sw
, &header
, TB_CFG_SWITCH
, cap
, 1);
436 seq_printf(s
, "0x%04x <capability read failed>\n", cap
);
440 if (header
.basic
.cap
== TB_SWITCH_CAP_VSE
) {
441 if (!header
.extended_short
.length
) {
442 ret
= tb_sw_read(sw
, (u32
*)&header
+ 1, TB_CFG_SWITCH
,
445 seq_printf(s
, "0x%04x <capability read failed>\n",
449 length
= header
.extended_long
.length
;
451 length
= header
.extended_short
.length
;
453 vsec_id
= header
.extended_short
.vsec_id
;
455 if (header
.basic
.cap
== TB_SWITCH_CAP_TMU
) {
456 length
= SWITCH_CAP_TMU_LEN
;
458 seq_printf(s
, "0x%04x <unknown capability 0x%02x>\n",
459 cap
, header
.basic
.cap
);
464 cap_show(s
, sw
, NULL
, cap
, header
.basic
.cap
, vsec_id
, length
);
467 static void switch_caps_show(struct tb_switch
*sw
, struct seq_file
*s
)
471 cap
= tb_switch_next_cap(sw
, 0);
473 switch_cap_show(sw
, s
, cap
);
474 cap
= tb_switch_next_cap(sw
, cap
);
478 static int switch_basic_regs_show(struct tb_switch
*sw
, struct seq_file
*s
)
480 u32 data
[SWITCH_CAP_BASIC_LEN
];
484 /* Only USB4 has the additional registers */
485 if (tb_switch_is_usb4(sw
))
486 dwords
= ARRAY_SIZE(data
);
490 ret
= tb_sw_read(sw
, data
, TB_CFG_SWITCH
, 0, dwords
);
494 for (i
= 0; i
< dwords
; i
++)
495 seq_printf(s
, "0x%04x %4d 0x00 0x00 0x%08x\n", i
, i
, data
[i
]);
500 static int switch_regs_show(struct seq_file
*s
, void *not_used
)
502 struct tb_switch
*sw
= s
->private;
503 struct tb
*tb
= sw
->tb
;
506 pm_runtime_get_sync(&sw
->dev
);
508 if (mutex_lock_interruptible(&tb
->lock
)) {
513 seq_puts(s
, "# offset relative_offset cap_id vs_cap_id value\n");
515 ret
= switch_basic_regs_show(sw
, s
);
519 switch_caps_show(sw
, s
);
522 mutex_unlock(&tb
->lock
);
524 pm_runtime_mark_last_busy(&sw
->dev
);
525 pm_runtime_put_autosuspend(&sw
->dev
);
529 DEBUGFS_ATTR_RW(switch_regs
);
531 static int path_show_one(struct tb_port
*port
, struct seq_file
*s
, int hopid
)
536 ret
= tb_port_read(port
, data
, TB_CFG_HOPS
, hopid
* PATH_LEN
,
539 seq_printf(s
, "0x%04x <not accessible>\n", hopid
* PATH_LEN
);
543 for (i
= 0; i
< ARRAY_SIZE(data
); i
++) {
544 seq_printf(s
, "0x%04x %4d 0x%02x 0x%08x\n",
545 hopid
* PATH_LEN
+ i
, i
, hopid
, data
[i
]);
551 static int path_show(struct seq_file
*s
, void *not_used
)
553 struct tb_port
*port
= s
->private;
554 struct tb_switch
*sw
= port
->sw
;
555 struct tb
*tb
= sw
->tb
;
556 int start
, i
, ret
= 0;
558 pm_runtime_get_sync(&sw
->dev
);
560 if (mutex_lock_interruptible(&tb
->lock
)) {
565 seq_puts(s
, "# offset relative_offset in_hop_id value\n");
567 /* NHI and lane adapters have entry for path 0 */
568 if (tb_port_is_null(port
) || tb_port_is_nhi(port
)) {
569 ret
= path_show_one(port
, s
, 0);
574 start
= tb_port_is_nhi(port
) ? 1 : TB_PATH_MIN_HOPID
;
576 for (i
= start
; i
<= port
->config
.max_in_hop_id
; i
++) {
577 ret
= path_show_one(port
, s
, i
);
583 mutex_unlock(&tb
->lock
);
585 pm_runtime_mark_last_busy(&sw
->dev
);
586 pm_runtime_put_autosuspend(&sw
->dev
);
590 DEBUGFS_ATTR_RO(path
);
592 static int counter_set_regs_show(struct tb_port
*port
, struct seq_file
*s
,
595 u32 data
[COUNTER_SET_LEN
];
598 ret
= tb_port_read(port
, data
, TB_CFG_COUNTERS
,
599 counter
* COUNTER_SET_LEN
, ARRAY_SIZE(data
));
601 seq_printf(s
, "0x%04x <not accessible>\n",
602 counter
* COUNTER_SET_LEN
);
606 for (i
= 0; i
< ARRAY_SIZE(data
); i
++) {
607 seq_printf(s
, "0x%04x %4d 0x%02x 0x%08x\n",
608 counter
* COUNTER_SET_LEN
+ i
, i
, counter
, data
[i
]);
614 static int counters_show(struct seq_file
*s
, void *not_used
)
616 struct tb_port
*port
= s
->private;
617 struct tb_switch
*sw
= port
->sw
;
618 struct tb
*tb
= sw
->tb
;
621 pm_runtime_get_sync(&sw
->dev
);
623 if (mutex_lock_interruptible(&tb
->lock
)) {
628 seq_puts(s
, "# offset relative_offset counter_id value\n");
630 for (i
= 0; i
< port
->config
.max_counters
; i
++) {
631 ret
= counter_set_regs_show(port
, s
, i
);
636 mutex_unlock(&tb
->lock
);
639 pm_runtime_mark_last_busy(&sw
->dev
);
640 pm_runtime_put_autosuspend(&sw
->dev
);
644 DEBUGFS_ATTR_RW(counters
);
647 * tb_switch_debugfs_init() - Add debugfs entries for router
648 * @sw: Pointer to the router
650 * Adds debugfs directories and files for given router.
652 void tb_switch_debugfs_init(struct tb_switch
*sw
)
654 struct dentry
*debugfs_dir
;
655 struct tb_port
*port
;
657 debugfs_dir
= debugfs_create_dir(dev_name(&sw
->dev
), tb_debugfs_root
);
658 sw
->debugfs_dir
= debugfs_dir
;
659 debugfs_create_file("regs", DEBUGFS_MODE
, debugfs_dir
, sw
,
662 tb_switch_for_each_port(sw
, port
) {
663 struct dentry
*debugfs_dir
;
668 if (port
->config
.type
== TB_TYPE_INACTIVE
)
671 snprintf(dir_name
, sizeof(dir_name
), "port%d", port
->port
);
672 debugfs_dir
= debugfs_create_dir(dir_name
, sw
->debugfs_dir
);
673 debugfs_create_file("regs", DEBUGFS_MODE
, debugfs_dir
,
674 port
, &port_regs_fops
);
675 debugfs_create_file("path", 0400, debugfs_dir
, port
,
677 if (port
->config
.counters_support
)
678 debugfs_create_file("counters", 0600, debugfs_dir
, port
,
684 * tb_switch_debugfs_remove() - Remove all router debugfs entries
685 * @sw: Pointer to the router
687 * Removes all previously added debugfs entries under this router.
689 void tb_switch_debugfs_remove(struct tb_switch
*sw
)
691 debugfs_remove_recursive(sw
->debugfs_dir
);
695 * tb_service_debugfs_init() - Add debugfs directory for service
696 * @svc: Thunderbolt service pointer
698 * Adds debugfs directory for service.
700 void tb_service_debugfs_init(struct tb_service
*svc
)
702 svc
->debugfs_dir
= debugfs_create_dir(dev_name(&svc
->dev
),
707 * tb_service_debugfs_remove() - Remove service debugfs directory
708 * @svc: Thunderbolt service pointer
710 * Removes the previously created debugfs directory for @svc.
712 void tb_service_debugfs_remove(struct tb_service
*svc
)
714 debugfs_remove_recursive(svc
->debugfs_dir
);
715 svc
->debugfs_dir
= NULL
;
718 void tb_debugfs_init(void)
720 tb_debugfs_root
= debugfs_create_dir("thunderbolt", NULL
);
723 void tb_debugfs_exit(void)
725 debugfs_remove_recursive(tb_debugfs_root
);