From 5dddb41692849594862473e4ddf57fb52e1249d6 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Mon, 18 Apr 2022 17:59:32 +0000 Subject: [PATCH] thunderbolt: Link USB4 ports to their USB Type-C connectors Creating a symlink pointing to the correct USB Type-C connector for the on-board USB4 ports when they are created. The link will be created only if the firmware is able to describe the connection between the port and its connector. Signed-off-by: Heikki Krogerus Signed-off-by: Won Chung Signed-off-by: Mika Westerberg --- Documentation/ABI/testing/sysfs-bus-thunderbolt | 10 +++++++ drivers/thunderbolt/usb4_port.c | 38 +++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-thunderbolt b/Documentation/ABI/testing/sysfs-bus-thunderbolt index b7e87f6..f7570c2 100644 --- a/Documentation/ABI/testing/sysfs-bus-thunderbolt +++ b/Documentation/ABI/testing/sysfs-bus-thunderbolt @@ -293,6 +293,16 @@ Contact: thunderbolt-software@lists.01.org Description: This contains XDomain service specific settings as bitmask. Format: %x +What: /sys/bus/thunderbolt/devices/usb4_portX/connector +Date: April 2022 +Contact: Heikki Krogerus +Description: + Symlink to the USB Type-C connector. This link is only + created when USB Type-C Connector Class is enabled, + and only if the system firmware is capable of + describing the connection between a port and its + connector. + What: /sys/bus/thunderbolt/devices/usb4_portX/link Date: Sep 2021 KernelVersion: v5.14 diff --git a/drivers/thunderbolt/usb4_port.c b/drivers/thunderbolt/usb4_port.c index 29e2a4f..6b02945 100644 --- a/drivers/thunderbolt/usb4_port.c +++ b/drivers/thunderbolt/usb4_port.c @@ -7,9 +7,37 @@ */ #include +#include +#include #include "tb.h" +static int connector_bind(struct device *dev, struct device *connector, void *data) +{ + int ret; + + ret = sysfs_create_link(&dev->kobj, &connector->kobj, "connector"); + if (ret) + return ret; + + ret = sysfs_create_link(&connector->kobj, &dev->kobj, dev_name(dev)); + if (ret) + sysfs_remove_link(&dev->kobj, "connector"); + + return ret; +} + +static void connector_unbind(struct device *dev, struct device *connector, void *data) +{ + sysfs_remove_link(&connector->kobj, dev_name(dev)); + sysfs_remove_link(&dev->kobj, "connector"); +} + +static const struct component_ops connector_ops = { + .bind = connector_bind, + .unbind = connector_unbind, +}; + static ssize_t link_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -246,6 +274,14 @@ struct usb4_port *usb4_port_device_add(struct tb_port *port) return ERR_PTR(ret); } + if (dev_fwnode(&usb4->dev)) { + ret = component_add(&usb4->dev, &connector_ops); + if (ret) { + dev_err(&usb4->dev, "failed to add component\n"); + device_unregister(&usb4->dev); + } + } + pm_runtime_no_callbacks(&usb4->dev); pm_runtime_set_active(&usb4->dev); pm_runtime_enable(&usb4->dev); @@ -265,6 +301,8 @@ struct usb4_port *usb4_port_device_add(struct tb_port *port) */ void usb4_port_device_remove(struct usb4_port *usb4) { + if (dev_fwnode(&usb4->dev)) + component_del(&usb4->dev, &connector_ops); device_unregister(&usb4->dev); } -- 2.7.4