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