thunderbolt: Handle hotplug events
[cascardo/linux.git] / drivers / thunderbolt / tb.c
1 /*
2  * Thunderbolt Cactus Ridge driver - bus logic (NHI independent)
3  *
4  * Copyright (c) 2014 Andreas Noever <andreas.noever@gmail.com>
5  */
6
7 #include <linux/slab.h>
8 #include <linux/errno.h>
9 #include <linux/delay.h>
10
11 #include "tb.h"
12 #include "tb_regs.h"
13
14
15 /* enumeration & hot plug handling */
16
17
18 static void tb_scan_port(struct tb_port *port);
19
20 /**
21  * tb_scan_switch() - scan for and initialize downstream switches
22  */
23 static void tb_scan_switch(struct tb_switch *sw)
24 {
25         int i;
26         for (i = 1; i <= sw->config.max_port_number; i++)
27                 tb_scan_port(&sw->ports[i]);
28 }
29
30 /**
31  * tb_scan_port() - check for and initialize switches below port
32  */
33 static void tb_scan_port(struct tb_port *port)
34 {
35         struct tb_switch *sw;
36         if (tb_is_upstream_port(port))
37                 return;
38         if (port->config.type != TB_TYPE_PORT)
39                 return;
40         if (tb_wait_for_port(port, false) <= 0)
41                 return;
42         if (port->remote) {
43                 tb_port_WARN(port, "port already has a remote!\n");
44                 return;
45         }
46         sw = tb_switch_alloc(port->sw->tb, tb_downstream_route(port));
47         if (!sw)
48                 return;
49         port->remote = tb_upstream_port(sw);
50         tb_upstream_port(sw)->remote = port;
51         tb_scan_switch(sw);
52 }
53
54
55 /* hotplug handling */
56
57 struct tb_hotplug_event {
58         struct work_struct work;
59         struct tb *tb;
60         u64 route;
61         u8 port;
62         bool unplug;
63 };
64
65 /**
66  * tb_handle_hotplug() - handle hotplug event
67  *
68  * Executes on tb->wq.
69  */
70 static void tb_handle_hotplug(struct work_struct *work)
71 {
72         struct tb_hotplug_event *ev = container_of(work, typeof(*ev), work);
73         struct tb *tb = ev->tb;
74         struct tb_switch *sw;
75         struct tb_port *port;
76         mutex_lock(&tb->lock);
77         if (!tb->hotplug_active)
78                 goto out; /* during init, suspend or shutdown */
79
80         sw = get_switch_at_route(tb->root_switch, ev->route);
81         if (!sw) {
82                 tb_warn(tb,
83                         "hotplug event from non existent switch %llx:%x (unplug: %d)\n",
84                         ev->route, ev->port, ev->unplug);
85                 goto out;
86         }
87         if (ev->port > sw->config.max_port_number) {
88                 tb_warn(tb,
89                         "hotplug event from non existent port %llx:%x (unplug: %d)\n",
90                         ev->route, ev->port, ev->unplug);
91                 goto out;
92         }
93         port = &sw->ports[ev->port];
94         if (tb_is_upstream_port(port)) {
95                 tb_warn(tb,
96                         "hotplug event for upstream port %llx:%x (unplug: %d)\n",
97                         ev->route, ev->port, ev->unplug);
98                 goto out;
99         }
100         if (ev->unplug) {
101                 if (port->remote) {
102                         tb_port_info(port, "unplugged\n");
103                         tb_sw_set_unpplugged(port->remote->sw);
104                         tb_switch_free(port->remote->sw);
105                         port->remote = NULL;
106                 } else {
107                         tb_port_info(port,
108                                      "got unplug event for disconnected port, ignoring\n");
109                 }
110         } else if (port->remote) {
111                 tb_port_info(port,
112                              "got plug event for connected port, ignoring\n");
113         } else {
114                 tb_port_info(port, "hotplug: scanning\n");
115                 tb_scan_port(port);
116                 if (!port->remote) {
117                         tb_port_info(port, "hotplug: no switch found\n");
118                 } else if (port->remote->sw->config.depth > 1) {
119                         tb_sw_warn(port->remote->sw,
120                                    "hotplug: chaining not supported\n");
121                 }
122         }
123 out:
124         mutex_unlock(&tb->lock);
125         kfree(ev);
126 }
127
128 /**
129  * tb_schedule_hotplug_handler() - callback function for the control channel
130  *
131  * Delegates to tb_handle_hotplug.
132  */
133 static void tb_schedule_hotplug_handler(void *data, u64 route, u8 port,
134                                         bool unplug)
135 {
136         struct tb *tb = data;
137         struct tb_hotplug_event *ev = kmalloc(sizeof(*ev), GFP_KERNEL);
138         if (!ev)
139                 return;
140         INIT_WORK(&ev->work, tb_handle_hotplug);
141         ev->tb = tb;
142         ev->route = route;
143         ev->port = port;
144         ev->unplug = unplug;
145         queue_work(tb->wq, &ev->work);
146 }
147
148 /**
149  * thunderbolt_shutdown_and_free() - shutdown everything
150  *
151  * Free all switches and the config channel.
152  *
153  * Used in the error path of thunderbolt_alloc_and_start.
154  */
155 void thunderbolt_shutdown_and_free(struct tb *tb)
156 {
157         mutex_lock(&tb->lock);
158
159         if (tb->root_switch)
160                 tb_switch_free(tb->root_switch);
161         tb->root_switch = NULL;
162
163         if (tb->ctl) {
164                 tb_ctl_stop(tb->ctl);
165                 tb_ctl_free(tb->ctl);
166         }
167         tb->ctl = NULL;
168         tb->hotplug_active = false; /* signal tb_handle_hotplug to quit */
169
170         /* allow tb_handle_hotplug to acquire the lock */
171         mutex_unlock(&tb->lock);
172         if (tb->wq) {
173                 flush_workqueue(tb->wq);
174                 destroy_workqueue(tb->wq);
175                 tb->wq = NULL;
176         }
177         mutex_destroy(&tb->lock);
178         kfree(tb);
179 }
180
181 /**
182  * thunderbolt_alloc_and_start() - setup the thunderbolt bus
183  *
184  * Allocates a tb_cfg control channel, initializes the root switch, enables
185  * plug events and activates pci devices.
186  *
187  * Return: Returns NULL on error.
188  */
189 struct tb *thunderbolt_alloc_and_start(struct tb_nhi *nhi)
190 {
191         struct tb *tb;
192
193         BUILD_BUG_ON(sizeof(struct tb_regs_switch_header) != 5 * 4);
194         BUILD_BUG_ON(sizeof(struct tb_regs_port_header) != 8 * 4);
195         BUILD_BUG_ON(sizeof(struct tb_regs_hop) != 2 * 4);
196
197         tb = kzalloc(sizeof(*tb), GFP_KERNEL);
198         if (!tb)
199                 return NULL;
200
201         tb->nhi = nhi;
202         mutex_init(&tb->lock);
203         mutex_lock(&tb->lock);
204
205         tb->wq = alloc_ordered_workqueue("thunderbolt", 0);
206         if (!tb->wq)
207                 goto err_locked;
208
209         tb->ctl = tb_ctl_alloc(tb->nhi, tb_schedule_hotplug_handler, tb);
210         if (!tb->ctl)
211                 goto err_locked;
212         /*
213          * tb_schedule_hotplug_handler may be called as soon as the config
214          * channel is started. Thats why we have to hold the lock here.
215          */
216         tb_ctl_start(tb->ctl);
217
218         tb->root_switch = tb_switch_alloc(tb, 0);
219         if (!tb->root_switch)
220                 goto err_locked;
221
222         /* Full scan to discover devices added before the driver was loaded. */
223         tb_scan_switch(tb->root_switch);
224
225         /* Allow tb_handle_hotplug to progress events */
226         tb->hotplug_active = true;
227         mutex_unlock(&tb->lock);
228         return tb;
229
230 err_locked:
231         mutex_unlock(&tb->lock);
232         thunderbolt_shutdown_and_free(tb);
233         return NULL;
234 }
235