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>
13 static ssize_t link_show(struct device *dev, struct device_attribute *attr,
16 struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
17 struct tb_port *port = usb4->port;
18 struct tb *tb = port->sw->tb;
21 if (mutex_lock_interruptible(&tb->lock))
24 if (tb_is_upstream_port(port))
25 link = port->sw->link_usb4 ? "usb4" : "tbt";
26 else if (tb_port_has_remote(port))
27 link = port->remote->sw->link_usb4 ? "usb4" : "tbt";
31 mutex_unlock(&tb->lock);
33 return sysfs_emit(buf, "%s\n", link);
35 static DEVICE_ATTR_RO(link);
37 static struct attribute *common_attrs[] = {
42 static const struct attribute_group common_group = {
43 .attrs = common_attrs,
46 static int usb4_port_offline(struct usb4_port *usb4)
48 struct tb_port *port = usb4->port;
51 ret = tb_acpi_power_on_retimers(port);
55 ret = usb4_port_router_offline(port);
57 tb_acpi_power_off_retimers(port);
61 ret = tb_retimer_scan(port, false);
63 usb4_port_router_online(port);
64 tb_acpi_power_off_retimers(port);
70 static void usb4_port_online(struct usb4_port *usb4)
72 struct tb_port *port = usb4->port;
74 usb4_port_router_online(port);
75 tb_acpi_power_off_retimers(port);
78 static ssize_t offline_show(struct device *dev,
79 struct device_attribute *attr, char *buf)
81 struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
83 return sysfs_emit(buf, "%d\n", usb4->offline);
86 static ssize_t offline_store(struct device *dev,
87 struct device_attribute *attr, const char *buf, size_t count)
89 struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
90 struct tb_port *port = usb4->port;
91 struct tb *tb = port->sw->tb;
95 ret = kstrtobool(buf, &val);
99 pm_runtime_get_sync(&usb4->dev);
101 if (mutex_lock_interruptible(&tb->lock)) {
106 if (val == usb4->offline)
109 /* Offline mode works only for ports that are not connected */
110 if (tb_port_has_remote(port)) {
116 ret = usb4_port_offline(usb4);
120 usb4_port_online(usb4);
121 tb_retimer_remove_all(port);
125 tb_port_dbg(port, "%s offline mode\n", val ? "enter" : "exit");
128 mutex_unlock(&tb->lock);
130 pm_runtime_mark_last_busy(&usb4->dev);
131 pm_runtime_put_autosuspend(&usb4->dev);
133 return ret ? ret : count;
135 static DEVICE_ATTR_RW(offline);
137 static ssize_t rescan_store(struct device *dev,
138 struct device_attribute *attr, const char *buf, size_t count)
140 struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
141 struct tb_port *port = usb4->port;
142 struct tb *tb = port->sw->tb;
146 ret = kstrtobool(buf, &val);
153 pm_runtime_get_sync(&usb4->dev);
155 if (mutex_lock_interruptible(&tb->lock)) {
160 /* Must be in offline mode already */
161 if (!usb4->offline) {
166 tb_retimer_remove_all(port);
167 ret = tb_retimer_scan(port, true);
170 mutex_unlock(&tb->lock);
172 pm_runtime_mark_last_busy(&usb4->dev);
173 pm_runtime_put_autosuspend(&usb4->dev);
175 return ret ? ret : count;
177 static DEVICE_ATTR_WO(rescan);
179 static struct attribute *service_attrs[] = {
180 &dev_attr_offline.attr,
181 &dev_attr_rescan.attr,
185 static umode_t service_attr_is_visible(struct kobject *kobj,
186 struct attribute *attr, int n)
188 struct device *dev = kobj_to_dev(kobj);
189 struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
192 * Always need some platform help to cycle the modes so that
193 * retimers can be accessed through the sideband.
195 return usb4->can_offline ? attr->mode : 0;
198 static const struct attribute_group service_group = {
199 .attrs = service_attrs,
200 .is_visible = service_attr_is_visible,
203 static const struct attribute_group *usb4_port_device_groups[] = {
209 static void usb4_port_device_release(struct device *dev)
211 struct usb4_port *usb4 = container_of(dev, struct usb4_port, dev);
216 struct device_type usb4_port_device_type = {
218 .groups = usb4_port_device_groups,
219 .release = usb4_port_device_release,
223 * usb4_port_device_add() - Add USB4 port device
224 * @port: Lane 0 adapter port to add the USB4 port
226 * Creates and registers a USB4 port device for @port. Returns the new
227 * USB4 port device pointer or ERR_PTR() in case of error.
229 struct usb4_port *usb4_port_device_add(struct tb_port *port)
231 struct usb4_port *usb4;
234 usb4 = kzalloc(sizeof(*usb4), GFP_KERNEL);
236 return ERR_PTR(-ENOMEM);
239 usb4->dev.type = &usb4_port_device_type;
240 usb4->dev.parent = &port->sw->dev;
241 dev_set_name(&usb4->dev, "usb4_port%d", port->port);
243 ret = device_register(&usb4->dev);
245 put_device(&usb4->dev);
249 pm_runtime_no_callbacks(&usb4->dev);
250 pm_runtime_set_active(&usb4->dev);
251 pm_runtime_enable(&usb4->dev);
252 pm_runtime_set_autosuspend_delay(&usb4->dev, TB_AUTOSUSPEND_DELAY);
253 pm_runtime_mark_last_busy(&usb4->dev);
254 pm_runtime_use_autosuspend(&usb4->dev);
260 * usb4_port_device_remove() - Removes USB4 port device
261 * @usb4: USB4 port device
263 * Unregisters the USB4 port device from the system. The device will be
264 * released when the last reference is dropped.
266 void usb4_port_device_remove(struct usb4_port *usb4)
268 device_unregister(&usb4->dev);
272 * usb4_port_device_resume() - Resumes USB4 port device
273 * @usb4: USB4 port device
275 * Used to resume USB4 port device after sleep state.
277 int usb4_port_device_resume(struct usb4_port *usb4)
279 return usb4->offline ? usb4_port_offline(usb4) : 0;