1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2021, Intel Corporation
6 * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
9 #include <linux/pm_runtime.h>
10 #include <linux/component.h>
11 #include <linux/property.h>
15 static int connector_bind(struct device *dev, struct device *connector, void *data)
19 ret = sysfs_create_link(&dev->kobj, &connector->kobj, "connector");
23 ret = sysfs_create_link(&connector->kobj, &dev->kobj, dev_name(dev));
25 sysfs_remove_link(&dev->kobj, "connector");
30 static void connector_unbind(struct device *dev, struct device *connector, void *data)
32 sysfs_remove_link(&connector->kobj, dev_name(dev));
33 sysfs_remove_link(&dev->kobj, "connector");
36 static const struct component_ops connector_ops = {
37 .bind = connector_bind,
38 .unbind = connector_unbind,
41 static ssize_t link_show(struct device *dev, struct device_attribute *attr,
44 struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
45 struct tb_port *port = usb4->port;
46 struct tb *tb = port->sw->tb;
49 if (mutex_lock_interruptible(&tb->lock))
52 if (tb_is_upstream_port(port))
53 link = port->sw->link_usb4 ? "usb4" : "tbt";
54 else if (tb_port_has_remote(port))
55 link = port->remote->sw->link_usb4 ? "usb4" : "tbt";
59 mutex_unlock(&tb->lock);
61 return sysfs_emit(buf, "%s\n", link);
63 static DEVICE_ATTR_RO(link);
65 static struct attribute *common_attrs[] = {
70 static const struct attribute_group common_group = {
71 .attrs = common_attrs,
74 static int usb4_port_offline(struct usb4_port *usb4)
76 struct tb_port *port = usb4->port;
79 ret = tb_acpi_power_on_retimers(port);
83 ret = usb4_port_router_offline(port);
85 tb_acpi_power_off_retimers(port);
89 ret = tb_retimer_scan(port, false);
91 usb4_port_router_online(port);
92 tb_acpi_power_off_retimers(port);
98 static void usb4_port_online(struct usb4_port *usb4)
100 struct tb_port *port = usb4->port;
102 usb4_port_router_online(port);
103 tb_acpi_power_off_retimers(port);
106 static ssize_t offline_show(struct device *dev,
107 struct device_attribute *attr, char *buf)
109 struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
111 return sysfs_emit(buf, "%d\n", usb4->offline);
114 static ssize_t offline_store(struct device *dev,
115 struct device_attribute *attr, const char *buf, size_t count)
117 struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
118 struct tb_port *port = usb4->port;
119 struct tb *tb = port->sw->tb;
123 ret = kstrtobool(buf, &val);
127 pm_runtime_get_sync(&usb4->dev);
129 if (mutex_lock_interruptible(&tb->lock)) {
134 if (val == usb4->offline)
137 /* Offline mode works only for ports that are not connected */
138 if (tb_port_has_remote(port)) {
144 ret = usb4_port_offline(usb4);
148 usb4_port_online(usb4);
149 tb_retimer_remove_all(port);
153 tb_port_dbg(port, "%s offline mode\n", val ? "enter" : "exit");
156 mutex_unlock(&tb->lock);
158 pm_runtime_mark_last_busy(&usb4->dev);
159 pm_runtime_put_autosuspend(&usb4->dev);
161 return ret ? ret : count;
163 static DEVICE_ATTR_RW(offline);
165 static ssize_t rescan_store(struct device *dev,
166 struct device_attribute *attr, const char *buf, size_t count)
168 struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
169 struct tb_port *port = usb4->port;
170 struct tb *tb = port->sw->tb;
174 ret = kstrtobool(buf, &val);
181 pm_runtime_get_sync(&usb4->dev);
183 if (mutex_lock_interruptible(&tb->lock)) {
188 /* Must be in offline mode already */
189 if (!usb4->offline) {
194 tb_retimer_remove_all(port);
195 ret = tb_retimer_scan(port, true);
198 mutex_unlock(&tb->lock);
200 pm_runtime_mark_last_busy(&usb4->dev);
201 pm_runtime_put_autosuspend(&usb4->dev);
203 return ret ? ret : count;
205 static DEVICE_ATTR_WO(rescan);
207 static struct attribute *service_attrs[] = {
208 &dev_attr_offline.attr,
209 &dev_attr_rescan.attr,
213 static umode_t service_attr_is_visible(struct kobject *kobj,
214 struct attribute *attr, int n)
216 struct device *dev = kobj_to_dev(kobj);
217 struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
220 * Always need some platform help to cycle the modes so that
221 * retimers can be accessed through the sideband.
223 return usb4->can_offline ? attr->mode : 0;
226 static const struct attribute_group service_group = {
227 .attrs = service_attrs,
228 .is_visible = service_attr_is_visible,
231 static const struct attribute_group *usb4_port_device_groups[] = {
237 static void usb4_port_device_release(struct device *dev)
239 struct usb4_port *usb4 = container_of(dev, struct usb4_port, dev);
244 struct device_type usb4_port_device_type = {
246 .groups = usb4_port_device_groups,
247 .release = usb4_port_device_release,
251 * usb4_port_device_add() - Add USB4 port device
252 * @port: Lane 0 adapter port to add the USB4 port
254 * Creates and registers a USB4 port device for @port. Returns the new
255 * USB4 port device pointer or ERR_PTR() in case of error.
257 struct usb4_port *usb4_port_device_add(struct tb_port *port)
259 struct usb4_port *usb4;
262 usb4 = kzalloc(sizeof(*usb4), GFP_KERNEL);
264 return ERR_PTR(-ENOMEM);
267 usb4->dev.type = &usb4_port_device_type;
268 usb4->dev.parent = &port->sw->dev;
269 dev_set_name(&usb4->dev, "usb4_port%d", port->port);
271 ret = device_register(&usb4->dev);
273 put_device(&usb4->dev);
277 if (dev_fwnode(&usb4->dev)) {
278 ret = component_add(&usb4->dev, &connector_ops);
280 dev_err(&usb4->dev, "failed to add component\n");
281 device_unregister(&usb4->dev);
285 pm_runtime_no_callbacks(&usb4->dev);
286 pm_runtime_set_active(&usb4->dev);
287 pm_runtime_enable(&usb4->dev);
288 pm_runtime_set_autosuspend_delay(&usb4->dev, TB_AUTOSUSPEND_DELAY);
289 pm_runtime_mark_last_busy(&usb4->dev);
290 pm_runtime_use_autosuspend(&usb4->dev);
296 * usb4_port_device_remove() - Removes USB4 port device
297 * @usb4: USB4 port device
299 * Unregisters the USB4 port device from the system. The device will be
300 * released when the last reference is dropped.
302 void usb4_port_device_remove(struct usb4_port *usb4)
304 if (dev_fwnode(&usb4->dev))
305 component_del(&usb4->dev, &connector_ops);
306 device_unregister(&usb4->dev);
310 * usb4_port_device_resume() - Resumes USB4 port device
311 * @usb4: USB4 port device
313 * Used to resume USB4 port device after sleep state.
315 int usb4_port_device_resume(struct usb4_port *usb4)
317 return usb4->offline ? usb4_port_offline(usb4) : 0;