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 
11 #include "tb.h"
12 
link_show(struct device * dev,struct device_attribute * attr,char * buf)13 static ssize_t link_show(struct device *dev, struct device_attribute *attr,
14 			 char *buf)
15 {
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;
19 	const char *link;
20 
21 	if (mutex_lock_interruptible(&tb->lock))
22 		return -ERESTARTSYS;
23 
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";
28 	else
29 		link = "none";
30 
31 	mutex_unlock(&tb->lock);
32 
33 	return sysfs_emit(buf, "%s\n", link);
34 }
35 static DEVICE_ATTR_RO(link);
36 
37 static struct attribute *common_attrs[] = {
38 	&dev_attr_link.attr,
39 	NULL
40 };
41 
42 static const struct attribute_group common_group = {
43 	.attrs = common_attrs,
44 };
45 
usb4_port_offline(struct usb4_port * usb4)46 static int usb4_port_offline(struct usb4_port *usb4)
47 {
48 	struct tb_port *port = usb4->port;
49 	int ret;
50 
51 	ret = tb_acpi_power_on_retimers(port);
52 	if (ret)
53 		return ret;
54 
55 	ret = usb4_port_router_offline(port);
56 	if (ret) {
57 		tb_acpi_power_off_retimers(port);
58 		return ret;
59 	}
60 
61 	ret = tb_retimer_scan(port, false);
62 	if (ret) {
63 		usb4_port_router_online(port);
64 		tb_acpi_power_off_retimers(port);
65 	}
66 
67 	return ret;
68 }
69 
usb4_port_online(struct usb4_port * usb4)70 static void usb4_port_online(struct usb4_port *usb4)
71 {
72 	struct tb_port *port = usb4->port;
73 
74 	usb4_port_router_online(port);
75 	tb_acpi_power_off_retimers(port);
76 }
77 
offline_show(struct device * dev,struct device_attribute * attr,char * buf)78 static ssize_t offline_show(struct device *dev,
79 	struct device_attribute *attr, char *buf)
80 {
81 	struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
82 
83 	return sysfs_emit(buf, "%d\n", usb4->offline);
84 }
85 
offline_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)86 static ssize_t offline_store(struct device *dev,
87 	struct device_attribute *attr, const char *buf, size_t count)
88 {
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;
92 	bool val;
93 	int ret;
94 
95 	ret = kstrtobool(buf, &val);
96 	if (ret)
97 		return ret;
98 
99 	pm_runtime_get_sync(&usb4->dev);
100 
101 	if (mutex_lock_interruptible(&tb->lock)) {
102 		ret = -ERESTARTSYS;
103 		goto out_rpm;
104 	}
105 
106 	if (val == usb4->offline)
107 		goto out_unlock;
108 
109 	/* Offline mode works only for ports that are not connected */
110 	if (tb_port_has_remote(port)) {
111 		ret = -EBUSY;
112 		goto out_unlock;
113 	}
114 
115 	if (val) {
116 		ret = usb4_port_offline(usb4);
117 		if (ret)
118 			goto out_unlock;
119 	} else {
120 		usb4_port_online(usb4);
121 		tb_retimer_remove_all(port);
122 	}
123 
124 	usb4->offline = val;
125 	tb_port_dbg(port, "%s offline mode\n", val ? "enter" : "exit");
126 
127 out_unlock:
128 	mutex_unlock(&tb->lock);
129 out_rpm:
130 	pm_runtime_mark_last_busy(&usb4->dev);
131 	pm_runtime_put_autosuspend(&usb4->dev);
132 
133 	return ret ? ret : count;
134 }
135 static DEVICE_ATTR_RW(offline);
136 
rescan_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)137 static ssize_t rescan_store(struct device *dev,
138 	struct device_attribute *attr, const char *buf, size_t count)
139 {
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;
143 	bool val;
144 	int ret;
145 
146 	ret = kstrtobool(buf, &val);
147 	if (ret)
148 		return ret;
149 
150 	if (!val)
151 		return count;
152 
153 	pm_runtime_get_sync(&usb4->dev);
154 
155 	if (mutex_lock_interruptible(&tb->lock)) {
156 		ret = -ERESTARTSYS;
157 		goto out_rpm;
158 	}
159 
160 	/* Must be in offline mode already */
161 	if (!usb4->offline) {
162 		ret = -EINVAL;
163 		goto out_unlock;
164 	}
165 
166 	tb_retimer_remove_all(port);
167 	ret = tb_retimer_scan(port, true);
168 
169 out_unlock:
170 	mutex_unlock(&tb->lock);
171 out_rpm:
172 	pm_runtime_mark_last_busy(&usb4->dev);
173 	pm_runtime_put_autosuspend(&usb4->dev);
174 
175 	return ret ? ret : count;
176 }
177 static DEVICE_ATTR_WO(rescan);
178 
179 static struct attribute *service_attrs[] = {
180 	&dev_attr_offline.attr,
181 	&dev_attr_rescan.attr,
182 	NULL
183 };
184 
service_attr_is_visible(struct kobject * kobj,struct attribute * attr,int n)185 static umode_t service_attr_is_visible(struct kobject *kobj,
186 				       struct attribute *attr, int n)
187 {
188 	struct device *dev = kobj_to_dev(kobj);
189 	struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
190 
191 	/*
192 	 * Always need some platform help to cycle the modes so that
193 	 * retimers can be accessed through the sideband.
194 	 */
195 	return usb4->can_offline ? attr->mode : 0;
196 }
197 
198 static const struct attribute_group service_group = {
199 	.attrs = service_attrs,
200 	.is_visible = service_attr_is_visible,
201 };
202 
203 static const struct attribute_group *usb4_port_device_groups[] = {
204 	&common_group,
205 	&service_group,
206 	NULL
207 };
208 
usb4_port_device_release(struct device * dev)209 static void usb4_port_device_release(struct device *dev)
210 {
211 	struct usb4_port *usb4 = container_of(dev, struct usb4_port, dev);
212 
213 	kfree(usb4);
214 }
215 
216 struct device_type usb4_port_device_type = {
217 	.name = "usb4_port",
218 	.groups = usb4_port_device_groups,
219 	.release = usb4_port_device_release,
220 };
221 
222 /**
223  * usb4_port_device_add() - Add USB4 port device
224  * @port: Lane 0 adapter port to add the USB4 port
225  *
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.
228  */
usb4_port_device_add(struct tb_port * port)229 struct usb4_port *usb4_port_device_add(struct tb_port *port)
230 {
231 	struct usb4_port *usb4;
232 	int ret;
233 
234 	usb4 = kzalloc(sizeof(*usb4), GFP_KERNEL);
235 	if (!usb4)
236 		return ERR_PTR(-ENOMEM);
237 
238 	usb4->port = port;
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);
242 
243 	ret = device_register(&usb4->dev);
244 	if (ret) {
245 		put_device(&usb4->dev);
246 		return ERR_PTR(ret);
247 	}
248 
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);
255 
256 	return usb4;
257 }
258 
259 /**
260  * usb4_port_device_remove() - Removes USB4 port device
261  * @usb4: USB4 port device
262  *
263  * Unregisters the USB4 port device from the system. The device will be
264  * released when the last reference is dropped.
265  */
usb4_port_device_remove(struct usb4_port * usb4)266 void usb4_port_device_remove(struct usb4_port *usb4)
267 {
268 	device_unregister(&usb4->dev);
269 }
270 
271 /**
272  * usb4_port_device_resume() - Resumes USB4 port device
273  * @usb4: USB4 port device
274  *
275  * Used to resume USB4 port device after sleep state.
276  */
usb4_port_device_resume(struct usb4_port * usb4)277 int usb4_port_device_resume(struct usb4_port *usb4)
278 {
279 	return usb4->offline ? usb4_port_offline(usb4) : 0;
280 }
281