greybus: connection: add latency tag enable/disable callbacks
[cascardo/linux.git] / drivers / staging / greybus / connection.c
1 /*
2  * Greybus connections
3  *
4  * Copyright 2014 Google Inc.
5  * Copyright 2014 Linaro Ltd.
6  *
7  * Released under the GPLv2 only.
8  */
9
10 #include <linux/workqueue.h>
11
12 #include "greybus.h"
13
14 #define GB_CONNECTION_TS_KFIFO_ELEMENTS 2
15 #define GB_CONNECTION_TS_KFIFO_LEN \
16         (GB_CONNECTION_TS_KFIFO_ELEMENTS * sizeof(struct timeval))
17
18 static DEFINE_SPINLOCK(gb_connections_lock);
19
20 /* This is only used at initialization time; no locking is required. */
21 static struct gb_connection *
22 gb_connection_intf_find(struct gb_interface *intf, u16 cport_id)
23 {
24         struct greybus_host_device *hd = intf->hd;
25         struct gb_connection *connection;
26
27         list_for_each_entry(connection, &hd->connections, hd_links)
28                 if (connection->bundle->intf == intf &&
29                                 connection->intf_cport_id == cport_id)
30                         return connection;
31         return NULL;
32 }
33
34 static struct gb_connection *
35 gb_connection_hd_find(struct greybus_host_device *hd, u16 cport_id)
36 {
37         struct gb_connection *connection;
38         unsigned long flags;
39
40         spin_lock_irqsave(&gb_connections_lock, flags);
41         list_for_each_entry(connection, &hd->connections, hd_links)
42                 if (connection->hd_cport_id == cport_id)
43                         goto found;
44         connection = NULL;
45 found:
46         spin_unlock_irqrestore(&gb_connections_lock, flags);
47
48         return connection;
49 }
50
51 /*
52  * Callback from the host driver to let us know that data has been
53  * received on the bundle.
54  */
55 void greybus_data_rcvd(struct greybus_host_device *hd, u16 cport_id,
56                         u8 *data, size_t length)
57 {
58         struct gb_connection *connection;
59
60         connection = gb_connection_hd_find(hd, cport_id);
61         if (!connection) {
62                 dev_err(hd->parent,
63                         "nonexistent connection (%zu bytes dropped)\n", length);
64                 return;
65         }
66         gb_connection_recv(connection, data, length);
67 }
68 EXPORT_SYMBOL_GPL(greybus_data_rcvd);
69
70 static ssize_t state_show(struct device *dev, struct device_attribute *attr,
71                           char *buf)
72 {
73         struct gb_connection *connection = to_gb_connection(dev);
74         enum gb_connection_state state;
75
76         spin_lock_irq(&connection->lock);
77         state = connection->state;
78         spin_unlock_irq(&connection->lock);
79
80         return sprintf(buf, "%d\n", state);
81 }
82 static DEVICE_ATTR_RO(state);
83
84 static ssize_t
85 protocol_id_show(struct device *dev, struct device_attribute *attr, char *buf)
86 {
87         struct gb_connection *connection = to_gb_connection(dev);
88
89         if (connection->protocol)
90                 return sprintf(buf, "%d\n", connection->protocol->id);
91         else
92                 return -EINVAL;
93 }
94 static DEVICE_ATTR_RO(protocol_id);
95
96 static ssize_t
97 ap_cport_id_show(struct device *dev, struct device_attribute *attr, char *buf)
98 {
99         struct gb_connection *connection = to_gb_connection(dev);
100         return sprintf(buf, "%hu\n", connection->hd_cport_id);
101 }
102 static DEVICE_ATTR_RO(ap_cport_id);
103
104 static struct attribute *connection_attrs[] = {
105         &dev_attr_state.attr,
106         &dev_attr_protocol_id.attr,
107         &dev_attr_ap_cport_id.attr,
108         NULL,
109 };
110
111 ATTRIBUTE_GROUPS(connection);
112
113 static void gb_connection_release(struct device *dev)
114 {
115         struct gb_connection *connection = to_gb_connection(dev);
116
117         destroy_workqueue(connection->wq);
118         kfree(connection);
119 }
120
121 struct device_type greybus_connection_type = {
122         .name =         "greybus_connection",
123         .release =      gb_connection_release,
124 };
125
126
127 int svc_update_connection(struct gb_interface *intf,
128                           struct gb_connection *connection)
129 {
130         struct gb_bundle *bundle;
131
132         bundle = gb_bundle_create(intf, GB_SVC_BUNDLE_ID, GREYBUS_CLASS_SVC);
133         if (!bundle)
134                 return -EINVAL;
135
136         device_del(&connection->dev);
137         connection->bundle = bundle;
138         connection->dev.parent = &bundle->dev;
139         dev_set_name(&connection->dev, "%s:%d", dev_name(&bundle->dev),
140                      GB_SVC_CPORT_ID);
141
142         WARN_ON(device_add(&connection->dev));
143
144         spin_lock_irq(&gb_connections_lock);
145         list_add(&connection->bundle_links, &bundle->connections);
146         spin_unlock_irq(&gb_connections_lock);
147
148         return 0;
149 }
150
151 /*
152  * Set up a Greybus connection, representing the bidirectional link
153  * between a CPort on a (local) Greybus host device and a CPort on
154  * another Greybus module.
155  *
156  * A connection also maintains the state of operations sent over the
157  * connection.
158  *
159  * Returns a pointer to the new connection if successful, or a null
160  * pointer otherwise.
161  */
162 struct gb_connection *
163 gb_connection_create_range(struct greybus_host_device *hd,
164                            struct gb_bundle *bundle, struct device *parent,
165                            u16 cport_id, u8 protocol_id, u32 ida_start,
166                            u32 ida_end)
167 {
168         struct gb_connection *connection;
169         struct ida *id_map = &hd->cport_id_map;
170         int hd_cport_id;
171         int retval;
172         u8 major = 0;
173         u8 minor = 1;
174
175         /*
176          * If a manifest tries to reuse a cport, reject it.  We
177          * initialize connections serially so we don't need to worry
178          * about holding the connection lock.
179          */
180         if (bundle && gb_connection_intf_find(bundle->intf, cport_id)) {
181                 dev_err(parent, "cport 0x%04hx already connected\n", cport_id);
182                 return NULL;
183         }
184
185         hd_cport_id = ida_simple_get(id_map, ida_start, ida_end, GFP_KERNEL);
186         if (hd_cport_id < 0)
187                 return NULL;
188
189         connection = kzalloc(sizeof(*connection), GFP_KERNEL);
190         if (!connection)
191                 goto err_remove_ida;
192
193         connection->hd_cport_id = hd_cport_id;
194         connection->intf_cport_id = cport_id;
195         connection->hd = hd;
196
197         connection->protocol_id = protocol_id;
198         connection->major = major;
199         connection->minor = minor;
200
201         connection->bundle = bundle;
202         connection->state = GB_CONNECTION_STATE_DISABLED;
203
204         atomic_set(&connection->op_cycle, 0);
205         spin_lock_init(&connection->lock);
206         INIT_LIST_HEAD(&connection->operations);
207
208         connection->wq = alloc_workqueue("%s:%d", WQ_UNBOUND, 1,
209                                          dev_name(parent), cport_id);
210         if (!connection->wq)
211                 goto err_free_connection;
212
213         connection->dev.parent = parent;
214         connection->dev.bus = &greybus_bus_type;
215         connection->dev.type = &greybus_connection_type;
216         connection->dev.groups = connection_groups;
217         device_initialize(&connection->dev);
218         dev_set_name(&connection->dev, "%s:%d",
219                      dev_name(parent), cport_id);
220
221         retval = device_add(&connection->dev);
222         if (retval) {
223                 connection->hd_cport_id = CPORT_ID_BAD;
224                 put_device(&connection->dev);
225
226                 dev_err(parent, "failed to register connection to cport %04hx: %d\n",
227                                 cport_id, retval);
228
229                 goto err_remove_ida;
230         }
231
232         spin_lock_irq(&gb_connections_lock);
233         list_add(&connection->hd_links, &hd->connections);
234
235         if (bundle)
236                 list_add(&connection->bundle_links, &bundle->connections);
237         else
238                 INIT_LIST_HEAD(&connection->bundle_links);
239
240         spin_unlock_irq(&gb_connections_lock);
241
242         retval = gb_connection_bind_protocol(connection);
243         if (retval) {
244                 dev_err(&connection->dev, "failed to bind protocol: %d\n",
245                         retval);
246                 gb_connection_destroy(connection);
247                 return NULL;
248         }
249
250         return connection;
251
252 err_free_connection:
253         kfree(connection);
254 err_remove_ida:
255         ida_simple_remove(id_map, hd_cport_id);
256
257         return NULL;
258 }
259
260 static int gb_connection_hd_cport_enable(struct gb_connection *connection)
261 {
262         struct greybus_host_device *hd = connection->hd;
263         int ret;
264
265         if (!hd->driver->cport_enable)
266                 return 0;
267
268         ret = hd->driver->cport_enable(hd, connection->hd_cport_id);
269         if (ret) {
270                 dev_err(&connection->dev,
271                                 "failed to enable host cport: %d\n", ret);
272                 return ret;
273         }
274
275         return 0;
276 }
277
278 static void gb_connection_hd_cport_disable(struct gb_connection *connection)
279 {
280         struct greybus_host_device *hd = connection->hd;
281
282         if (!hd->driver->cport_disable)
283                 return;
284
285         hd->driver->cport_disable(hd, connection->hd_cport_id);
286 }
287
288 struct gb_connection *gb_connection_create(struct gb_bundle *bundle,
289                                 u16 cport_id, u8 protocol_id)
290 {
291         return gb_connection_create_range(bundle->intf->hd, bundle,
292                                           &bundle->dev, cport_id, protocol_id,
293                                           0, bundle->intf->hd->num_cports - 1);
294 }
295
296 /*
297  * Cancel all active operations on a connection.
298  *
299  * Should only be called during connection tear down.
300  */
301 static void gb_connection_cancel_operations(struct gb_connection *connection,
302                                                 int errno)
303 {
304         struct gb_operation *operation;
305
306         spin_lock_irq(&connection->lock);
307         while (!list_empty(&connection->operations)) {
308                 operation = list_last_entry(&connection->operations,
309                                                 struct gb_operation, links);
310                 gb_operation_get(operation);
311                 spin_unlock_irq(&connection->lock);
312
313                 if (gb_operation_is_incoming(operation))
314                         gb_operation_cancel_incoming(operation, errno);
315                 else
316                         gb_operation_cancel(operation, errno);
317
318                 gb_operation_put(operation);
319
320                 spin_lock_irq(&connection->lock);
321         }
322         spin_unlock_irq(&connection->lock);
323 }
324
325 /*
326  * Request the SVC to create a connection from AP's cport to interface's
327  * cport.
328  */
329 static int
330 gb_connection_svc_connection_create(struct gb_connection *connection)
331 {
332         struct greybus_host_device *hd = connection->hd;
333         struct gb_protocol *protocol = connection->protocol;
334         struct gb_interface *intf;
335         int ret;
336
337         if (protocol->flags & GB_PROTOCOL_SKIP_SVC_CONNECTION)
338                 return 0;
339
340         intf = connection->bundle->intf;
341         ret = gb_svc_connection_create(hd->svc,
342                         hd->endo->ap_intf_id,
343                         connection->hd_cport_id,
344                         intf->interface_id,
345                         connection->intf_cport_id,
346                         intf->boot_over_unipro);
347         if (ret) {
348                 dev_err(&connection->dev,
349                                 "failed to create svc connection: %d\n", ret);
350                 return ret;
351         }
352
353         return 0;
354 }
355
356 static void
357 gb_connection_svc_connection_destroy(struct gb_connection *connection)
358 {
359         if (connection->protocol->flags & GB_PROTOCOL_SKIP_SVC_CONNECTION)
360                 return;
361
362         gb_svc_connection_destroy(connection->hd->svc,
363                                   connection->hd->endo->ap_intf_id,
364                                   connection->hd_cport_id,
365                                   connection->bundle->intf->interface_id,
366                                   connection->intf_cport_id);
367 }
368
369 /* Inform Interface about active CPorts */
370 static int gb_connection_control_connected(struct gb_connection *connection)
371 {
372         struct gb_protocol *protocol = connection->protocol;
373         struct gb_control *control;
374         u16 cport_id = connection->intf_cport_id;
375         int ret;
376
377         if (protocol->flags & GB_PROTOCOL_SKIP_CONTROL_CONNECTED)
378                 return 0;
379
380         control = connection->bundle->intf->control;
381
382         ret = gb_control_connected_operation(control, cport_id);
383         if (ret) {
384                 dev_err(&connection->dev,
385                                 "failed to connect cport: %d\n", ret);
386                 return ret;
387         }
388
389         return 0;
390 }
391
392 /* Inform Interface about inactive CPorts */
393 static void
394 gb_connection_control_disconnected(struct gb_connection *connection)
395 {
396         struct gb_protocol *protocol = connection->protocol;
397         struct gb_control *control;
398         u16 cport_id = connection->intf_cport_id;
399         int ret;
400
401         if (protocol->flags & GB_PROTOCOL_SKIP_CONTROL_DISCONNECTED)
402                 return;
403
404         control = connection->bundle->intf->control;
405
406         ret = gb_control_disconnected_operation(control, cport_id);
407         if (ret) {
408                 dev_warn(&connection->dev,
409                                 "failed to disconnect cport: %d\n", ret);
410         }
411 }
412
413 /*
414  * Request protocol version supported by the module. We don't need to do
415  * this for SVC as that is initiated by the SVC.
416  */
417 static int gb_connection_protocol_get_version(struct gb_connection *connection)
418 {
419         struct gb_protocol *protocol = connection->protocol;
420         int ret;
421
422         if (protocol->flags & GB_PROTOCOL_SKIP_VERSION)
423                 return 0;
424
425         ret = gb_protocol_get_version(connection);
426         if (ret) {
427                 dev_err(&connection->dev,
428                                 "failed to get protocol version: %d\n", ret);
429                 return ret;
430         }
431
432         return 0;
433 }
434
435 static int gb_connection_init(struct gb_connection *connection)
436 {
437         struct gb_protocol *protocol = connection->protocol;
438         int ret;
439
440         ret = gb_connection_hd_cport_enable(connection);
441         if (ret)
442                 return ret;
443
444         ret = gb_connection_svc_connection_create(connection);
445         if (ret)
446                 goto err_hd_cport_disable;
447
448         ret = gb_connection_control_connected(connection);
449         if (ret)
450                 goto err_svc_destroy;
451
452         /* Need to enable the connection to initialize it */
453         spin_lock_irq(&connection->lock);
454         connection->state = GB_CONNECTION_STATE_ENABLED;
455         spin_unlock_irq(&connection->lock);
456
457         ret = gb_connection_protocol_get_version(connection);
458         if (ret)
459                 goto err_disconnect;
460
461         ret = protocol->connection_init(connection);
462         if (ret)
463                 goto err_disconnect;
464
465         return 0;
466
467 err_disconnect:
468         spin_lock_irq(&connection->lock);
469         connection->state = GB_CONNECTION_STATE_ERROR;
470         spin_unlock_irq(&connection->lock);
471
472         gb_connection_control_disconnected(connection);
473 err_svc_destroy:
474         gb_connection_svc_connection_destroy(connection);
475 err_hd_cport_disable:
476         gb_connection_hd_cport_disable(connection);
477
478         return ret;
479 }
480
481 static void gb_connection_exit(struct gb_connection *connection)
482 {
483         if (!connection->protocol)
484                 return;
485
486         spin_lock_irq(&connection->lock);
487         if (connection->state != GB_CONNECTION_STATE_ENABLED) {
488                 spin_unlock_irq(&connection->lock);
489                 return;
490         }
491         connection->state = GB_CONNECTION_STATE_DESTROYING;
492         spin_unlock_irq(&connection->lock);
493
494         gb_connection_cancel_operations(connection, -ESHUTDOWN);
495
496         connection->protocol->connection_exit(connection);
497         gb_connection_control_disconnected(connection);
498         gb_connection_svc_connection_destroy(connection);
499         gb_connection_hd_cport_disable(connection);
500 }
501
502 /*
503  * Tear down a previously set up connection.
504  */
505 void gb_connection_destroy(struct gb_connection *connection)
506 {
507         struct ida *id_map;
508
509         if (WARN_ON(!connection))
510                 return;
511
512         gb_connection_exit(connection);
513
514         spin_lock_irq(&gb_connections_lock);
515         list_del(&connection->bundle_links);
516         list_del(&connection->hd_links);
517         spin_unlock_irq(&gb_connections_lock);
518
519         if (connection->protocol)
520                 gb_protocol_put(connection->protocol);
521         connection->protocol = NULL;
522
523         id_map = &connection->hd->cport_id_map;
524         ida_simple_remove(id_map, connection->hd_cport_id);
525         connection->hd_cport_id = CPORT_ID_BAD;
526
527         device_unregister(&connection->dev);
528 }
529
530 void gb_connection_latency_tag_enable(struct gb_connection *connection)
531 {
532         struct greybus_host_device *hd = connection->hd;
533         int ret;
534
535         if (!hd->driver->latency_tag_enable)
536                 return;
537
538         ret = hd->driver->latency_tag_enable(hd, connection->hd_cport_id);
539         if (ret) {
540                 dev_err(&connection->dev,
541                         "failed to enable latency tag: %d\n", ret);
542         }
543 }
544 EXPORT_SYMBOL_GPL(gb_connection_latency_tag_enable);
545
546 void gb_connection_latency_tag_disable(struct gb_connection *connection)
547 {
548         struct greybus_host_device *hd = connection->hd;
549         int ret;
550
551         if (!hd->driver->latency_tag_disable)
552                 return;
553
554         ret = hd->driver->latency_tag_disable(hd, connection->hd_cport_id);
555         if (ret) {
556                 dev_err(&connection->dev,
557                         "failed to disable latency tag: %d\n", ret);
558         }
559 }
560 EXPORT_SYMBOL_GPL(gb_connection_latency_tag_disable);
561
562 void gb_hd_connections_exit(struct greybus_host_device *hd)
563 {
564         struct gb_connection *connection;
565
566         list_for_each_entry(connection, &hd->connections, hd_links)
567                 gb_connection_destroy(connection);
568 }
569
570 int gb_connection_bind_protocol(struct gb_connection *connection)
571 {
572         struct gb_protocol *protocol;
573         int ret;
574
575         /* If we already have a protocol bound here, just return */
576         if (connection->protocol)
577                 return 0;
578
579         protocol = gb_protocol_get(connection->protocol_id,
580                                    connection->major,
581                                    connection->minor);
582         if (!protocol) {
583                 dev_warn(&connection->dev,
584                                 "protocol 0x%02hhx version %hhu.%hhu not found\n",
585                                 connection->protocol_id,
586                                 connection->major, connection->minor);
587                 return 0;
588         }
589         connection->protocol = protocol;
590
591         /*
592          * If we have a valid device_id for the interface block, then we have an
593          * active device, so bring up the connection at the same time.
594          */
595         if ((!connection->bundle &&
596              protocol->flags & GB_PROTOCOL_NO_BUNDLE) ||
597             connection->bundle->intf->device_id != GB_DEVICE_ID_BAD) {
598                 ret = gb_connection_init(connection);
599                 if (ret) {
600                         gb_protocol_put(protocol);
601                         connection->protocol = NULL;
602                         return ret;
603                 }
604         }
605
606         return 0;
607 }