xref: /linux/drivers/thunderbolt/usb4_port.c (revision c0c9379f235df33a12ceae94370ad80c5278324d)
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