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 
offline_show(struct device * dev,struct device_attribute * attr,char * buf)108 static ssize_t offline_show(struct device *dev,
109 	struct device_attribute *attr, char *buf)
110 {
111 	struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
112 
113 	return sysfs_emit(buf, "%d\n", usb4->offline);
114 }
115 
offline_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)116 static ssize_t offline_store(struct device *dev,
117 	struct device_attribute *attr, const char *buf, size_t count)
118 {
119 	struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
120 	struct tb_port *port = usb4->port;
121 	struct tb *tb = port->sw->tb;
122 	bool val;
123 	int ret;
124 
125 	ret = kstrtobool(buf, &val);
126 	if (ret)
127 		return ret;
128 
129 	pm_runtime_get_sync(&usb4->dev);
130 
131 	if (mutex_lock_interruptible(&tb->lock)) {
132 		ret = -ERESTARTSYS;
133 		goto out_rpm;
134 	}
135 
136 	if (val == usb4->offline)
137 		goto out_unlock;
138 
139 	/* Offline mode works only for ports that are not connected */
140 	if (tb_port_has_remote(port)) {
141 		ret = -EBUSY;
142 		goto out_unlock;
143 	}
144 
145 	if (val) {
146 		ret = usb4_port_offline(usb4);
147 		if (ret)
148 			goto out_unlock;
149 	} else {
150 		usb4_port_online(usb4);
151 		tb_retimer_remove_all(port);
152 	}
153 
154 	usb4->offline = val;
155 	tb_port_dbg(port, "%s offline mode\n", val ? "enter" : "exit");
156 
157 out_unlock:
158 	mutex_unlock(&tb->lock);
159 out_rpm:
160 	pm_runtime_mark_last_busy(&usb4->dev);
161 	pm_runtime_put_autosuspend(&usb4->dev);
162 
163 	return ret ? ret : count;
164 }
165 static DEVICE_ATTR_RW(offline);
166 
rescan_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)167 static ssize_t rescan_store(struct device *dev,
168 	struct device_attribute *attr, const char *buf, size_t count)
169 {
170 	struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
171 	struct tb_port *port = usb4->port;
172 	struct tb *tb = port->sw->tb;
173 	bool val;
174 	int ret;
175 
176 	ret = kstrtobool(buf, &val);
177 	if (ret)
178 		return ret;
179 
180 	if (!val)
181 		return count;
182 
183 	pm_runtime_get_sync(&usb4->dev);
184 
185 	if (mutex_lock_interruptible(&tb->lock)) {
186 		ret = -ERESTARTSYS;
187 		goto out_rpm;
188 	}
189 
190 	/* Must be in offline mode already */
191 	if (!usb4->offline) {
192 		ret = -EINVAL;
193 		goto out_unlock;
194 	}
195 
196 	tb_retimer_remove_all(port);
197 	ret = tb_retimer_scan(port, true);
198 
199 out_unlock:
200 	mutex_unlock(&tb->lock);
201 out_rpm:
202 	pm_runtime_mark_last_busy(&usb4->dev);
203 	pm_runtime_put_autosuspend(&usb4->dev);
204 
205 	return ret ? ret : count;
206 }
207 static DEVICE_ATTR_WO(rescan);
208 
209 static struct attribute *service_attrs[] = {
210 	&dev_attr_offline.attr,
211 	&dev_attr_rescan.attr,
212 	NULL
213 };
214 
service_attr_is_visible(struct kobject * kobj,struct attribute * attr,int n)215 static umode_t service_attr_is_visible(struct kobject *kobj,
216 				       struct attribute *attr, int n)
217 {
218 	struct device *dev = kobj_to_dev(kobj);
219 	struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
220 
221 	/*
222 	 * Always need some platform help to cycle the modes so that
223 	 * retimers can be accessed through the sideband.
224 	 */
225 	return usb4->can_offline ? attr->mode : 0;
226 }
227 
228 static const struct attribute_group service_group = {
229 	.attrs = service_attrs,
230 	.is_visible = service_attr_is_visible,
231 };
232 
233 static const struct attribute_group *usb4_port_device_groups[] = {
234 	&common_group,
235 	&service_group,
236 	NULL
237 };
238 
usb4_port_device_release(struct device * dev)239 static void usb4_port_device_release(struct device *dev)
240 {
241 	struct usb4_port *usb4 = container_of(dev, struct usb4_port, dev);
242 
243 	kfree(usb4);
244 }
245 
246 struct device_type usb4_port_device_type = {
247 	.name = "usb4_port",
248 	.groups = usb4_port_device_groups,
249 	.release = usb4_port_device_release,
250 };
251 
252 /**
253  * usb4_port_device_add() - Add USB4 port device
254  * @port: Lane 0 adapter port to add the USB4 port
255  *
256  * Creates and registers a USB4 port device for @port. Returns the new
257  * USB4 port device pointer or ERR_PTR() in case of error.
258  */
usb4_port_device_add(struct tb_port * port)259 struct usb4_port *usb4_port_device_add(struct tb_port *port)
260 {
261 	struct usb4_port *usb4;
262 	int ret;
263 
264 	usb4 = kzalloc(sizeof(*usb4), GFP_KERNEL);
265 	if (!usb4)
266 		return ERR_PTR(-ENOMEM);
267 
268 	usb4->port = port;
269 	usb4->dev.type = &usb4_port_device_type;
270 	usb4->dev.parent = &port->sw->dev;
271 	dev_set_name(&usb4->dev, "usb4_port%d", port->port);
272 
273 	ret = device_register(&usb4->dev);
274 	if (ret) {
275 		put_device(&usb4->dev);
276 		return ERR_PTR(ret);
277 	}
278 
279 	if (dev_fwnode(&usb4->dev)) {
280 		ret = component_add(&usb4->dev, &connector_ops);
281 		if (ret) {
282 			dev_err(&usb4->dev, "failed to add component\n");
283 			device_unregister(&usb4->dev);
284 		}
285 	}
286 
287 	pm_runtime_no_callbacks(&usb4->dev);
288 	pm_runtime_set_active(&usb4->dev);
289 	pm_runtime_enable(&usb4->dev);
290 	pm_runtime_set_autosuspend_delay(&usb4->dev, TB_AUTOSUSPEND_DELAY);
291 	pm_runtime_mark_last_busy(&usb4->dev);
292 	pm_runtime_use_autosuspend(&usb4->dev);
293 
294 	return usb4;
295 }
296 
297 /**
298  * usb4_port_device_remove() - Removes USB4 port device
299  * @usb4: USB4 port device
300  *
301  * Unregisters the USB4 port device from the system. The device will be
302  * released when the last reference is dropped.
303  */
usb4_port_device_remove(struct usb4_port * usb4)304 void usb4_port_device_remove(struct usb4_port *usb4)
305 {
306 	if (dev_fwnode(&usb4->dev))
307 		component_del(&usb4->dev, &connector_ops);
308 	device_unregister(&usb4->dev);
309 }
310 
311 /**
312  * usb4_port_device_resume() - Resumes USB4 port device
313  * @usb4: USB4 port device
314  *
315  * Used to resume USB4 port device after sleep state.
316  */
usb4_port_device_resume(struct usb4_port * usb4)317 int usb4_port_device_resume(struct usb4_port *usb4)
318 {
319 	return usb4->offline ? usb4_port_offline(usb4) : 0;
320 }
321