Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <andriy.shevchenko@linux.intel.com>
Signed-off-by: Saranya Gopal <saranya.gopal@intel.com>
Co-developed-by: Rajaram Regupathy <rajaram.regupathy@intel.com>
Signed-off-by: Rajaram Regupathy <rajaram.regupathy@intel.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://lore.kernel.org/r/20230807105205.742819-1-saranya.gopal@intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Saranya Gopal and committed by
Greg Kroah-Hartman
df0383ff 3b563b90

+141
+1
drivers/usb/typec/ucsi/Kconfig
··· 4 4 tristate "USB Type-C Connector System Software Interface driver" 5 5 depends on !CPU_BIG_ENDIAN 6 6 depends on USB_ROLE_SWITCH || !USB_ROLE_SWITCH 7 + select USB_COMMON if DEBUG_FS 7 8 help 8 9 USB Type-C Connector System Software Interface (UCSI) is a 9 10 specification for an interface that allows the operating system to
+2
drivers/usb/typec/ucsi/Makefile
··· 5 5 6 6 typec_ucsi-y := ucsi.o 7 7 8 + typec_ucsi-$(CONFIG_DEBUG_FS) += debugfs.o 9 + 8 10 typec_ucsi-$(CONFIG_TRACING) += trace.o 9 11 10 12 ifneq ($(CONFIG_POWER_SUPPLY),)
+99
drivers/usb/typec/ucsi/debugfs.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * UCSI debugfs interface 4 + * 5 + * Copyright (C) 2023 Intel Corporation 6 + * 7 + * Authors: Rajaram Regupathy <rajaram.regupathy@intel.com> 8 + * Gopal Saranya <saranya.gopal@intel.com> 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 + }
+15
drivers/usb/typec/ucsi/ucsi.c
··· 1530 1530 */ 1531 1531 void ucsi_destroy(struct ucsi *ucsi) 1532 1532 { 1533 + ucsi_debugfs_unregister(ucsi); 1533 1534 kfree(ucsi); 1534 1535 } 1535 1536 EXPORT_SYMBOL_GPL(ucsi_destroy); ··· 1553 1552 1554 1553 queue_delayed_work(system_long_wq, &ucsi->work, 0); 1555 1554 1555 + ucsi_debugfs_register(ucsi); 1556 1556 return 0; 1557 1557 } 1558 1558 EXPORT_SYMBOL_GPL(ucsi_register); ··· 1612 1610 kfree(ucsi->connector); 1613 1611 } 1614 1612 EXPORT_SYMBOL_GPL(ucsi_unregister); 1613 + 1614 + static int __init ucsi_module_init(void) 1615 + { 1616 + ucsi_debugfs_init(); 1617 + return 0; 1618 + } 1619 + module_init(ucsi_module_init); 1620 + 1621 + static void __exit ucsi_module_exit(void) 1622 + { 1623 + ucsi_debugfs_exit(); 1624 + } 1625 + module_exit(ucsi_module_exit); 1615 1626 1616 1627 MODULE_AUTHOR("Heikki Krogerus <heikki.krogerus@linux.intel.com>"); 1617 1628 MODULE_LICENSE("GPL v2");
+24
drivers/usb/typec/ucsi/ucsi.h
··· 15 15 16 16 struct ucsi; 17 17 struct ucsi_altmode; 18 + struct dentry; 18 19 19 20 /* UCSI offsets (Bytes) */ 20 21 #define UCSI_VERSION 0 ··· 278 277 279 278 /* -------------------------------------------------------------------------- */ 280 279 280 + struct ucsi_debugfs_entry { 281 + u64 command; 282 + struct ucsi_data { 283 + u64 low; 284 + u64 high; 285 + } response; 286 + u32 status; 287 + struct dentry *dentry; 288 + }; 289 + 281 290 struct ucsi { 282 291 u16 version; 283 292 struct device *dev; ··· 297 286 298 287 struct ucsi_capability cap; 299 288 struct ucsi_connector *connector; 289 + struct ucsi_debugfs_entry *debugfs; 300 290 301 291 struct work_struct resume_work; 302 292 struct delayed_work work; ··· 399 387 static inline void 400 388 ucsi_displayport_remove_partner(struct typec_altmode *adev) { } 401 389 #endif /* CONFIG_TYPEC_DP_ALTMODE */ 390 + 391 + #ifdef CONFIG_DEBUG_FS 392 + void ucsi_debugfs_init(void); 393 + void ucsi_debugfs_exit(void); 394 + void ucsi_debugfs_register(struct ucsi *ucsi); 395 + void ucsi_debugfs_unregister(struct ucsi *ucsi); 396 + #else 397 + static inline void ucsi_debugfs_init(void) { } 398 + static inline void ucsi_debugfs_exit(void) { } 399 + static inline void ucsi_debugfs_register(struct ucsi *ucsi) { } 400 + static inline void ucsi_debugfs_unregister(struct ucsi *ucsi) { } 401 + #endif /* CONFIG_DEBUG_FS */ 402 402 403 403 /* 404 404 * NVIDIA VirtualLink (svid 0x955) has two altmode. VirtualLink