2 * Greybus interface code
4 * Copyright 2014 Google Inc.
5 * Copyright 2014 Linaro Ltd.
7 * Released under the GPLv2 only.
12 /* interface sysfs attributes */
13 #define gb_interface_attr(field, type) \
14 static ssize_t field##_show(struct device *dev, \
15 struct device_attribute *attr, \
18 struct gb_interface *intf = to_gb_interface(dev); \
19 return scnprintf(buf, PAGE_SIZE, "%"#type"\n", intf->field); \
21 static DEVICE_ATTR_RO(field)
23 gb_interface_attr(device_id, d);
24 gb_interface_attr(vendor, x);
25 gb_interface_attr(product, x);
26 gb_interface_attr(unique_id, llX);
27 gb_interface_attr(vendor_string, s);
28 gb_interface_attr(product_string, s);
30 static struct attribute *interface_attrs[] = {
31 &dev_attr_device_id.attr,
32 &dev_attr_vendor.attr,
33 &dev_attr_product.attr,
34 &dev_attr_unique_id.attr,
35 &dev_attr_vendor_string.attr,
36 &dev_attr_product_string.attr,
39 ATTRIBUTE_GROUPS(interface);
42 /* XXX This could be per-host device */
43 static DEFINE_SPINLOCK(gb_interfaces_lock);
45 // FIXME, odds are you don't want to call this function, rework the caller to
46 // not need it please.
47 struct gb_interface *gb_interface_find(struct gb_host_device *hd,
50 struct gb_interface *intf;
52 list_for_each_entry(intf, &hd->interfaces, links)
53 if (intf->interface_id == interface_id)
59 static void gb_interface_release(struct device *dev)
61 struct gb_interface *intf = to_gb_interface(dev);
63 kfree(intf->product_string);
64 kfree(intf->vendor_string);
69 struct device_type greybus_interface_type = {
70 .name = "greybus_interface",
71 .release = gb_interface_release,
75 * Create kernel structures corresponding to a bundle and connection for
76 * managing control/svc CPort.
78 int gb_create_bundle_connection(struct gb_interface *intf, u8 class)
80 struct gb_bundle *bundle;
81 u32 ida_start, ida_end;
82 u8 bundle_id, protocol_id;
85 if (class == GREYBUS_CLASS_CONTROL) {
86 protocol_id = GREYBUS_PROTOCOL_CONTROL;
87 bundle_id = GB_CONTROL_BUNDLE_ID;
88 cport_id = GB_CONTROL_CPORT_ID;
90 ida_end = intf->hd->num_cports - 1;
91 } else if (class == GREYBUS_CLASS_SVC) {
92 protocol_id = GREYBUS_PROTOCOL_SVC;
93 bundle_id = GB_SVC_BUNDLE_ID;
94 cport_id = GB_SVC_CPORT_ID;
95 ida_start = GB_SVC_CPORT_ID;
96 ida_end = GB_SVC_CPORT_ID + 1;
102 bundle = gb_bundle_create(intf, bundle_id, class);
106 if (!gb_connection_create_range(bundle->intf->hd, bundle, &bundle->dev,
107 cport_id, protocol_id, ida_start,
115 * A Greybus module represents a user-replaceable component on an Ara
116 * phone. An interface is the physical connection on that module. A
117 * module may have more than one interface.
119 * Create a gb_interface structure to represent a discovered interface.
120 * The position of interface within the Endo is encoded in "interface_id"
123 * Returns a pointer to the new interfce or a null pointer if a
124 * failure occurs due to memory exhaustion.
126 struct gb_interface *gb_interface_create(struct gb_host_device *hd,
129 struct gb_module *module;
130 struct gb_interface *intf;
133 module = gb_module_find(hd, endo_get_module_id(hd->endo, interface_id));
137 intf = kzalloc(sizeof(*intf), GFP_KERNEL);
141 intf->hd = hd; /* XXX refcount? */
142 intf->module = module;
143 intf->interface_id = interface_id;
144 INIT_LIST_HEAD(&intf->bundles);
145 INIT_LIST_HEAD(&intf->manifest_descs);
147 /* Invalid device id to start with */
148 intf->device_id = GB_DEVICE_ID_BAD;
150 intf->dev.parent = &module->dev;
151 intf->dev.bus = &greybus_bus_type;
152 intf->dev.type = &greybus_interface_type;
153 intf->dev.groups = interface_groups;
154 intf->dev.dma_mask = hd->parent->dma_mask;
155 device_initialize(&intf->dev);
156 dev_set_name(&intf->dev, "%s:%d", dev_name(&module->dev), interface_id);
158 retval = device_add(&intf->dev);
160 pr_err("failed to add interface device for id 0x%02hhx\n",
165 spin_lock_irq(&gb_interfaces_lock);
166 list_add(&intf->links, &hd->interfaces);
167 spin_unlock_irq(&gb_interfaces_lock);
172 put_device(&intf->dev);
174 put_device(&module->dev);
179 * Tear down a previously set up module.
181 void gb_interface_remove(struct gb_interface *intf)
183 struct gb_module *module;
184 struct gb_bundle *bundle;
185 struct gb_bundle *next;
190 spin_lock_irq(&gb_interfaces_lock);
191 list_del(&intf->links);
192 spin_unlock_irq(&gb_interfaces_lock);
194 list_for_each_entry_safe(bundle, next, &intf->bundles, links)
195 gb_bundle_destroy(bundle);
197 module = intf->module;
198 device_unregister(&intf->dev);
199 put_device(&module->dev);
202 void gb_interfaces_remove(struct gb_host_device *hd)
204 struct gb_interface *intf, *temp;
206 list_for_each_entry_safe(intf, temp, &hd->interfaces, links)
207 gb_interface_remove(intf);
213 * Create connection for control CPort and then request/parse manifest.
214 * Finally initialize all the bundles to set routes via SVC and initialize all
217 int gb_interface_init(struct gb_interface *intf, u8 device_id)
222 intf->device_id = device_id;
224 /* Establish control CPort connection */
225 ret = gb_create_bundle_connection(intf, GREYBUS_CLASS_CONTROL);
227 dev_err(&intf->dev, "Failed to create control CPort connection (%d)\n", ret);
231 /* Get manifest size using control protocol on CPort */
232 size = gb_control_get_manifest_size_operation(intf);
234 dev_err(&intf->dev, "%s: Failed to get manifest size (%d)\n",
242 manifest = kmalloc(size, GFP_KERNEL);
246 /* Get manifest using control protocol on CPort */
247 ret = gb_control_get_manifest_operation(intf, manifest, size);
249 dev_err(&intf->dev, "%s: Failed to get manifest\n", __func__);
254 * Parse the manifest and build up our data structures representing
257 if (!gb_manifest_parse(intf, manifest, size)) {
258 dev_err(&intf->dev, "%s: Failed to parse manifest\n", __func__);
265 * We've successfully parsed the manifest. Now we need to
266 * allocate CPort Id's for connecting to the CPorts found on
267 * other modules. For each of these, establish a connection
268 * between the local and remote CPorts (including
269 * configuring the switch to allow them to communicate).