1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * USB4 port device
4 *
5 * Copyright (C) 2021, Intel Corporation
6 * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
7 */
8
9 #include <linux/pm_runtime.h>
10 #include <linux/component.h>
11 #include <linux/property.h>
12
13 #include "tb.h"
14
connector_bind(struct device * dev,struct device * connector,void * data)15 static int connector_bind(struct device *dev, struct device *connector, void *data)
16 {
17 int ret;
18
19 ret = sysfs_create_link(&dev->kobj, &connector->kobj, "connector");
20 if (ret)
21 return ret;
22
23 ret = sysfs_create_link(&connector->kobj, &dev->kobj, dev_name(dev));
24 if (ret)
25 sysfs_remove_link(&dev->kobj, "connector");
26
27 return ret;
28 }
29
connector_unbind(struct device * dev,struct device * connector,void * data)30 static void connector_unbind(struct device *dev, struct device *connector, void *data)
31 {
32 sysfs_remove_link(&connector->kobj, dev_name(dev));
33 sysfs_remove_link(&dev->kobj, "connector");
34 }
35
36 static const struct component_ops connector_ops = {
37 .bind = connector_bind,
38 .unbind = connector_unbind,
39 };
40
link_show(struct device * dev,struct device_attribute * attr,char * buf)41 static ssize_t link_show(struct device *dev, struct device_attribute *attr,
42 char *buf)
43 {
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;
47 const char *link;
48
49 if (mutex_lock_interruptible(&tb->lock))
50 return -ERESTARTSYS;
51
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";
56 else if (port->xdomain)
57 link = port->xdomain->link_usb4 ? "usb4" : "tbt";
58 else
59 link = "none";
60
61 mutex_unlock(&tb->lock);
62
63 return sysfs_emit(buf, "%s\n", link);
64 }
65 static DEVICE_ATTR_RO(link);
66
67 static struct attribute *common_attrs[] = {
68 &dev_attr_link.attr,
69 NULL
70 };
71
72 static const struct attribute_group common_group = {
73 .attrs = common_attrs,
74 };
75
usb4_port_offline(struct usb4_port * usb4)76 static int usb4_port_offline(struct usb4_port *usb4)
77 {
78 struct tb_port *port = usb4->port;
79 int ret;
80
81 ret = tb_acpi_power_on_retimers(port);
82 if (ret)
83 return ret;
84
85 ret = usb4_port_router_offline(port);
86 if (ret) {
87 tb_acpi_power_off_retimers(port);
88 return ret;
89 }
90
91 ret = tb_retimer_scan(port, false);
92 if (ret) {
93 usb4_port_router_online(port);
94 tb_acpi_power_off_retimers(port);
95 }
96
97 return ret;
98 }
99
usb4_port_online(struct usb4_port * usb4)100 static void usb4_port_online(struct usb4_port *usb4)
101 {
102 struct tb_port *port = usb4->port;
103
104 usb4_port_router_online(port);
105 tb_acpi_power_off_retimers(port);
106 }
107
108 /**
109 * usb4_usb3_port_match() - Matches USB4 port device with USB 3.x port device
110 * @usb4_port_dev: USB4 port device
111 * @usb3_port_fwnode: USB 3.x port firmware node
112 *
113 * Checks if USB 3.x port @usb3_port_fwnode is tunneled through USB4 port @usb4_port_dev.
114 * Returns true if match is found, false otherwise.
115 *
116 * Function is designed to be used with component framework (component_match_add).
117 */
usb4_usb3_port_match(struct device * usb4_port_dev,const struct fwnode_handle * usb3_port_fwnode)118 bool usb4_usb3_port_match(struct device *usb4_port_dev,
119 const struct fwnode_handle *usb3_port_fwnode)
120 {
121 struct fwnode_handle *nhi_fwnode __free(fwnode_handle) = NULL;
122 struct usb4_port *usb4;
123 struct tb_switch *sw;
124 struct tb_nhi *nhi;
125 u8 usb4_port_num;
126 struct tb *tb;
127
128 usb4 = tb_to_usb4_port_device(usb4_port_dev);
129 if (!usb4)
130 return false;
131
132 sw = usb4->port->sw;
133 tb = sw->tb;
134 nhi = tb->nhi;
135
136 nhi_fwnode = fwnode_find_reference(usb3_port_fwnode, "usb4-host-interface", 0);
137 if (IS_ERR(nhi_fwnode))
138 return false;
139
140 /* Check if USB3 fwnode references same NHI where USB4 port resides */
141 if (!device_match_fwnode(&nhi->pdev->dev, nhi_fwnode))
142 return false;
143
144 if (fwnode_property_read_u8(usb3_port_fwnode, "usb4-port-number", &usb4_port_num))
145 return false;
146
147 return usb4_port_index(sw, usb4->port) == usb4_port_num;
148 }
149 EXPORT_SYMBOL_GPL(usb4_usb3_port_match);
150
offline_show(struct device * dev,struct device_attribute * attr,char * buf)151 static ssize_t offline_show(struct device *dev,
152 struct device_attribute *attr, char *buf)
153 {
154 struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
155
156 return sysfs_emit(buf, "%d\n", usb4->offline);
157 }
158
offline_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)159 static ssize_t offline_store(struct device *dev,
160 struct device_attribute *attr, const char *buf, size_t count)
161 {
162 struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
163 struct tb_port *port = usb4->port;
164 struct tb *tb = port->sw->tb;
165 bool val;
166 int ret;
167
168 ret = kstrtobool(buf, &val);
169 if (ret)
170 return ret;
171
172 pm_runtime_get_sync(&usb4->dev);
173
174 if (mutex_lock_interruptible(&tb->lock)) {
175 ret = -ERESTARTSYS;
176 goto out_rpm;
177 }
178
179 if (val == usb4->offline)
180 goto out_unlock;
181
182 /* Offline mode works only for ports that are not connected */
183 if (tb_port_has_remote(port)) {
184 ret = -EBUSY;
185 goto out_unlock;
186 }
187
188 if (val) {
189 ret = usb4_port_offline(usb4);
190 if (ret)
191 goto out_unlock;
192 } else {
193 usb4_port_online(usb4);
194 tb_retimer_remove_all(port);
195 }
196
197 usb4->offline = val;
198 tb_port_dbg(port, "%s offline mode\n", val ? "enter" : "exit");
199
200 out_unlock:
201 mutex_unlock(&tb->lock);
202 out_rpm:
203 pm_runtime_mark_last_busy(&usb4->dev);
204 pm_runtime_put_autosuspend(&usb4->dev);
205
206 return ret ? ret : count;
207 }
208 static DEVICE_ATTR_RW(offline);
209
rescan_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)210 static ssize_t rescan_store(struct device *dev,
211 struct device_attribute *attr, const char *buf, size_t count)
212 {
213 struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
214 struct tb_port *port = usb4->port;
215 struct tb *tb = port->sw->tb;
216 bool val;
217 int ret;
218
219 ret = kstrtobool(buf, &val);
220 if (ret)
221 return ret;
222
223 if (!val)
224 return count;
225
226 pm_runtime_get_sync(&usb4->dev);
227
228 if (mutex_lock_interruptible(&tb->lock)) {
229 ret = -ERESTARTSYS;
230 goto out_rpm;
231 }
232
233 /* Must be in offline mode already */
234 if (!usb4->offline) {
235 ret = -EINVAL;
236 goto out_unlock;
237 }
238
239 tb_retimer_remove_all(port);
240 ret = tb_retimer_scan(port, true);
241
242 out_unlock:
243 mutex_unlock(&tb->lock);
244 out_rpm:
245 pm_runtime_mark_last_busy(&usb4->dev);
246 pm_runtime_put_autosuspend(&usb4->dev);
247
248 return ret ? ret : count;
249 }
250 static DEVICE_ATTR_WO(rescan);
251
252 static struct attribute *service_attrs[] = {
253 &dev_attr_offline.attr,
254 &dev_attr_rescan.attr,
255 NULL
256 };
257
service_attr_is_visible(struct kobject * kobj,struct attribute * attr,int n)258 static umode_t service_attr_is_visible(struct kobject *kobj,
259 struct attribute *attr, int n)
260 {
261 struct device *dev = kobj_to_dev(kobj);
262 struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
263
264 /*
265 * Always need some platform help to cycle the modes so that
266 * retimers can be accessed through the sideband.
267 */
268 return usb4->can_offline ? attr->mode : 0;
269 }
270
271 static const struct attribute_group service_group = {
272 .attrs = service_attrs,
273 .is_visible = service_attr_is_visible,
274 };
275
276 static const struct attribute_group *usb4_port_device_groups[] = {
277 &common_group,
278 &service_group,
279 NULL
280 };
281
usb4_port_device_release(struct device * dev)282 static void usb4_port_device_release(struct device *dev)
283 {
284 struct usb4_port *usb4 = container_of(dev, struct usb4_port, dev);
285
286 kfree(usb4);
287 }
288
289 const struct device_type usb4_port_device_type = {
290 .name = "usb4_port",
291 .groups = usb4_port_device_groups,
292 .release = usb4_port_device_release,
293 };
294
295 /**
296 * usb4_port_device_add() - Add USB4 port device
297 * @port: Lane 0 adapter port to add the USB4 port
298 *
299 * Creates and registers a USB4 port device for @port. Returns the new
300 * USB4 port device pointer or ERR_PTR() in case of error.
301 */
usb4_port_device_add(struct tb_port * port)302 struct usb4_port *usb4_port_device_add(struct tb_port *port)
303 {
304 struct usb4_port *usb4;
305 int ret;
306
307 usb4 = kzalloc(sizeof(*usb4), GFP_KERNEL);
308 if (!usb4)
309 return ERR_PTR(-ENOMEM);
310
311 usb4->port = port;
312 usb4->dev.type = &usb4_port_device_type;
313 usb4->dev.parent = &port->sw->dev;
314 dev_set_name(&usb4->dev, "usb4_port%d", port->port);
315
316 ret = device_register(&usb4->dev);
317 if (ret) {
318 put_device(&usb4->dev);
319 return ERR_PTR(ret);
320 }
321
322 ret = component_add(&usb4->dev, &connector_ops);
323 if (ret) {
324 dev_err(&usb4->dev, "failed to add component\n");
325 device_unregister(&usb4->dev);
326 }
327
328 if (!tb_is_upstream_port(port))
329 device_set_wakeup_capable(&usb4->dev, true);
330
331 pm_runtime_no_callbacks(&usb4->dev);
332 pm_runtime_set_active(&usb4->dev);
333 pm_runtime_enable(&usb4->dev);
334 pm_runtime_set_autosuspend_delay(&usb4->dev, TB_AUTOSUSPEND_DELAY);
335 pm_runtime_mark_last_busy(&usb4->dev);
336 pm_runtime_use_autosuspend(&usb4->dev);
337
338 return usb4;
339 }
340
341 /**
342 * usb4_port_device_remove() - Removes USB4 port device
343 * @usb4: USB4 port device
344 *
345 * Unregisters the USB4 port device from the system. The device will be
346 * released when the last reference is dropped.
347 */
usb4_port_device_remove(struct usb4_port * usb4)348 void usb4_port_device_remove(struct usb4_port *usb4)
349 {
350 component_del(&usb4->dev, &connector_ops);
351 device_unregister(&usb4->dev);
352 }
353
354 /**
355 * usb4_port_device_resume() - Resumes USB4 port device
356 * @usb4: USB4 port device
357 *
358 * Used to resume USB4 port device after sleep state.
359 */
usb4_port_device_resume(struct usb4_port * usb4)360 int usb4_port_device_resume(struct usb4_port *usb4)
361 {
362 return usb4->offline ? usb4_port_offline(usb4) : 0;
363 }
364