Skip to content

Commit df0383f

Browse files
saranyagopal1gregkh
authored andcommitted
usb: typec: ucsi: Add debugfs for ucsi commands
Add support for UCSI commands through the following debugfs: # /sys/kernel/debug/usb/ucsi/$UCSI_DEVICE/command # /sys/kernel/debug/usb/ucsi/$UCSI_DEVICE/response Eg: To execute UCSI GetCapabilities: # echo 0x6 > /sys/kernel/debug/usb/ucsi/<ucsi device>/command Then read the result, # cat /sys/kernel/debug/usb/ucsi/<ucsi device>/response 0x02000320000000020000ff0400000445 UCSI command will be written into the command file and the response for the command can be viewed under the response file. Reviewed-by: Andy Shevchenko <[email protected]> Signed-off-by: Saranya Gopal <[email protected]> Co-developed-by: Rajaram Regupathy <[email protected]> Signed-off-by: Rajaram Regupathy <[email protected]> Reviewed-by: Heikki Krogerus <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 3b563b9 commit df0383f

File tree

5 files changed

+141
-0
lines changed

5 files changed

+141
-0
lines changed

drivers/usb/typec/ucsi/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ config TYPEC_UCSI
44
tristate "USB Type-C Connector System Software Interface driver"
55
depends on !CPU_BIG_ENDIAN
66
depends on USB_ROLE_SWITCH || !USB_ROLE_SWITCH
7+
select USB_COMMON if DEBUG_FS
78
help
89
USB Type-C Connector System Software Interface (UCSI) is a
910
specification for an interface that allows the operating system to

drivers/usb/typec/ucsi/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ obj-$(CONFIG_TYPEC_UCSI) += typec_ucsi.o
55

66
typec_ucsi-y := ucsi.o
77

8+
typec_ucsi-$(CONFIG_DEBUG_FS) += debugfs.o
9+
810
typec_ucsi-$(CONFIG_TRACING) += trace.o
911

1012
ifneq ($(CONFIG_POWER_SUPPLY),)

drivers/usb/typec/ucsi/debugfs.c

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* UCSI debugfs interface
4+
*
5+
* Copyright (C) 2023 Intel Corporation
6+
*
7+
* Authors: Rajaram Regupathy <[email protected]>
8+
* Gopal Saranya <[email protected]>
9+
*/
10+
#include <linux/debugfs.h>
11+
#include <linux/slab.h>
12+
#include <linux/string.h>
13+
#include <linux/types.h>
14+
#include <linux/usb.h>
15+
16+
#include <asm/errno.h>
17+
18+
#include "ucsi.h"
19+
20+
static struct dentry *ucsi_debugfs_root;
21+
22+
static int ucsi_cmd(void *data, u64 val)
23+
{
24+
struct ucsi *ucsi = data;
25+
int ret;
26+
27+
memset(&ucsi->debugfs->response, 0, sizeof(ucsi->debugfs->response));
28+
ucsi->debugfs->status = 0;
29+
30+
switch (UCSI_COMMAND(val)) {
31+
case UCSI_SET_UOM:
32+
case UCSI_SET_UOR:
33+
case UCSI_SET_PDR:
34+
case UCSI_CONNECTOR_RESET:
35+
ret = ucsi_send_command(ucsi, val, NULL, 0);
36+
break;
37+
case UCSI_GET_CAPABILITY:
38+
case UCSI_GET_CONNECTOR_CAPABILITY:
39+
case UCSI_GET_ALTERNATE_MODES:
40+
case UCSI_GET_CURRENT_CAM:
41+
case UCSI_GET_PDOS:
42+
case UCSI_GET_CABLE_PROPERTY:
43+
case UCSI_GET_CONNECTOR_STATUS:
44+
ret = ucsi_send_command(ucsi, val,
45+
&ucsi->debugfs->response,
46+
sizeof(ucsi->debugfs->response));
47+
break;
48+
default:
49+
ret = -EOPNOTSUPP;
50+
}
51+
52+
if (ret < 0) {
53+
ucsi->debugfs->status = ret;
54+
return ret;
55+
}
56+
57+
return 0;
58+
}
59+
DEFINE_DEBUGFS_ATTRIBUTE(ucsi_cmd_fops, NULL, ucsi_cmd, "0x%llx\n");
60+
61+
static int ucsi_resp_show(struct seq_file *s, void *not_used)
62+
{
63+
struct ucsi *ucsi = s->private;
64+
65+
if (ucsi->debugfs->status)
66+
return ucsi->debugfs->status;
67+
68+
seq_printf(s, "0x%016llx%016llx\n", ucsi->debugfs->response.high,
69+
ucsi->debugfs->response.low);
70+
return 0;
71+
}
72+
DEFINE_SHOW_ATTRIBUTE(ucsi_resp);
73+
74+
void ucsi_debugfs_register(struct ucsi *ucsi)
75+
{
76+
ucsi->debugfs = kzalloc(sizeof(*ucsi->debugfs), GFP_KERNEL);
77+
if (!ucsi->debugfs)
78+
return;
79+
80+
ucsi->debugfs->dentry = debugfs_create_dir(dev_name(ucsi->dev), ucsi_debugfs_root);
81+
debugfs_create_file("command", 0200, ucsi->debugfs->dentry, ucsi, &ucsi_cmd_fops);
82+
debugfs_create_file("response", 0400, ucsi->debugfs->dentry, ucsi, &ucsi_resp_fops);
83+
}
84+
85+
void ucsi_debugfs_unregister(struct ucsi *ucsi)
86+
{
87+
debugfs_remove_recursive(ucsi->debugfs->dentry);
88+
kfree(ucsi->debugfs);
89+
}
90+
91+
void ucsi_debugfs_init(void)
92+
{
93+
ucsi_debugfs_root = debugfs_create_dir("ucsi", usb_debug_root);
94+
}
95+
96+
void ucsi_debugfs_exit(void)
97+
{
98+
debugfs_remove(ucsi_debugfs_root);
99+
}

drivers/usb/typec/ucsi/ucsi.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1530,6 +1530,7 @@ EXPORT_SYMBOL_GPL(ucsi_create);
15301530
*/
15311531
void ucsi_destroy(struct ucsi *ucsi)
15321532
{
1533+
ucsi_debugfs_unregister(ucsi);
15331534
kfree(ucsi);
15341535
}
15351536
EXPORT_SYMBOL_GPL(ucsi_destroy);
@@ -1552,6 +1553,7 @@ int ucsi_register(struct ucsi *ucsi)
15521553

15531554
queue_delayed_work(system_long_wq, &ucsi->work, 0);
15541555

1556+
ucsi_debugfs_register(ucsi);
15551557
return 0;
15561558
}
15571559
EXPORT_SYMBOL_GPL(ucsi_register);
@@ -1611,6 +1613,19 @@ void ucsi_unregister(struct ucsi *ucsi)
16111613
}
16121614
EXPORT_SYMBOL_GPL(ucsi_unregister);
16131615

1616+
static int __init ucsi_module_init(void)
1617+
{
1618+
ucsi_debugfs_init();
1619+
return 0;
1620+
}
1621+
module_init(ucsi_module_init);
1622+
1623+
static void __exit ucsi_module_exit(void)
1624+
{
1625+
ucsi_debugfs_exit();
1626+
}
1627+
module_exit(ucsi_module_exit);
1628+
16141629
MODULE_AUTHOR("Heikki Krogerus <[email protected]>");
16151630
MODULE_LICENSE("GPL v2");
16161631
MODULE_DESCRIPTION("USB Type-C Connector System Software Interface driver");

drivers/usb/typec/ucsi/ucsi.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
struct ucsi;
1717
struct ucsi_altmode;
18+
struct dentry;
1819

1920
/* UCSI offsets (Bytes) */
2021
#define UCSI_VERSION 0
@@ -277,6 +278,16 @@ struct ucsi_connector_status {
277278

278279
/* -------------------------------------------------------------------------- */
279280

281+
struct ucsi_debugfs_entry {
282+
u64 command;
283+
struct ucsi_data {
284+
u64 low;
285+
u64 high;
286+
} response;
287+
u32 status;
288+
struct dentry *dentry;
289+
};
290+
280291
struct ucsi {
281292
u16 version;
282293
struct device *dev;
@@ -286,6 +297,7 @@ struct ucsi {
286297

287298
struct ucsi_capability cap;
288299
struct ucsi_connector *connector;
300+
struct ucsi_debugfs_entry *debugfs;
289301

290302
struct work_struct resume_work;
291303
struct delayed_work work;
@@ -388,6 +400,18 @@ static inline void
388400
ucsi_displayport_remove_partner(struct typec_altmode *adev) { }
389401
#endif /* CONFIG_TYPEC_DP_ALTMODE */
390402

403+
#ifdef CONFIG_DEBUG_FS
404+
void ucsi_debugfs_init(void);
405+
void ucsi_debugfs_exit(void);
406+
void ucsi_debugfs_register(struct ucsi *ucsi);
407+
void ucsi_debugfs_unregister(struct ucsi *ucsi);
408+
#else
409+
static inline void ucsi_debugfs_init(void) { }
410+
static inline void ucsi_debugfs_exit(void) { }
411+
static inline void ucsi_debugfs_register(struct ucsi *ucsi) { }
412+
static inline void ucsi_debugfs_unregister(struct ucsi *ucsi) { }
413+
#endif /* CONFIG_DEBUG_FS */
414+
391415
/*
392416
* NVIDIA VirtualLink (svid 0x955) has two altmode. VirtualLink
393417
* DP mode with vdo=0x1 and NVIDIA test mode with vdo=0x3

0 commit comments

Comments
 (0)