blob: 0c2fdd3f7ea267ff1f57a9975b8f0ea8a8a7003a [file] [log] [blame]
Alex Elder8c12cde2014-10-01 21:54:12 -05001/*
2 * Greybus interfaces
3 *
4 * Copyright 2014 Google Inc.
5 *
6 * Released under the GPLv2 only.
7 */
8
9#include "greybus.h"
10
11/* XXX This could be per-host device or per-module */
12static DEFINE_SPINLOCK(gb_interfaces_lock);
13
14/*
15 * A Greybus interface represents a UniPro device present on a
16 * module. For Project Ara, each active Interface Block on a module
17 * implements a UniPro device, and therefore a Greybus interface. A
18 * Greybus module has at least one interface, but can have two (or
19 * even more).
20 *
21 * Create a gb_interface structure to represent a discovered
22 * interface. Returns a pointer to the new interface or a null
23 * pointer if a failure occurs due to memory exhaustion.
24 */
25struct gb_interface *
26gb_interface_create(struct gb_module *gmod, u8 interface_id)
27{
28 struct gb_interface *interface;
29
30 interface = kzalloc(sizeof(*interface), GFP_KERNEL);
31 if (!interface)
32 return NULL;
33
34 interface->gmod = gmod; /* XXX refcount? */
Alex Elder63cc9322014-10-02 12:30:02 -050035 interface->id = interface_id;
Alex Elder748e1232014-10-03 14:14:22 -050036 INIT_LIST_HEAD(&interface->connections);
Alex Elder8c12cde2014-10-01 21:54:12 -050037
38 spin_lock_irq(&gb_interfaces_lock);
39 list_add_tail(&interface->links, &gmod->interfaces);
40 spin_unlock_irq(&gb_interfaces_lock);
41
42 return interface;
43}
44
45/*
46 * Tear down a previously set up interface.
47 */
48void gb_interface_destroy(struct gb_interface *interface)
49{
50 if (WARN_ON(!interface))
51 return;
52
53 spin_lock_irq(&gb_interfaces_lock);
54 list_del(&interface->links);
55 spin_unlock_irq(&gb_interfaces_lock);
56
57 /* kref_put(gmod); */
58 kfree(interface);
59}
Alex Elder574341c2014-10-16 06:35:35 -050060
61int gb_interface_connections_init(struct gb_interface *interface)
62{
63 struct gb_connection *connection;
64 int ret = 0;
65
66 list_for_each_entry(connection, &interface->connections,
67 interface_links) {
68 ret = gb_connection_init(connection);
69 if (ret)
70 break;
71 }
72
73 return ret;
74}