]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/staging/greybus/interface.c
greybus: interface: drop the control bundle
[karo-tx-linux.git] / drivers / staging / greybus / interface.c
index f9fd479bfd8bb035875f6a269a0efc088840722a..9ff7464b84592d94ac94b54524317e0fbb73efbf 100644 (file)
@@ -16,22 +16,20 @@ static ssize_t field##_show(struct device *dev,                             \
                            char *buf)                                  \
 {                                                                      \
        struct gb_interface *intf = to_gb_interface(dev);               \
-       return sprintf(buf, "%"#type"\n", intf->field);                 \
+       return scnprintf(buf, PAGE_SIZE, "%"#type"\n", intf->field);    \
 }                                                                      \
 static DEVICE_ATTR_RO(field)
 
-gb_interface_attr(device_id, d);
-gb_interface_attr(vendor, x);
-gb_interface_attr(product, x);
-gb_interface_attr(unique_id, llX);
+gb_interface_attr(interface_id, u);
+gb_interface_attr(vendor_id, x);
+gb_interface_attr(product_id, x);
 gb_interface_attr(vendor_string, s);
 gb_interface_attr(product_string, s);
 
 static struct attribute *interface_attrs[] = {
-       &dev_attr_device_id.attr,
-       &dev_attr_vendor.attr,
-       &dev_attr_product.attr,
-       &dev_attr_unique_id.attr,
+       &dev_attr_interface_id.attr,
+       &dev_attr_vendor_id.attr,
+       &dev_attr_product_id.attr,
        &dev_attr_vendor_string.attr,
        &dev_attr_product_string.attr,
        NULL,
@@ -44,7 +42,7 @@ static DEFINE_SPINLOCK(gb_interfaces_lock);
 
 // FIXME, odds are you don't want to call this function, rework the caller to
 // not need it please.
-struct gb_interface *gb_interface_find(struct greybus_host_device *hd,
+struct gb_interface *gb_interface_find(struct gb_host_device *hd,
                                       u8 interface_id)
 {
        struct gb_interface *intf;
@@ -60,6 +58,9 @@ static void gb_interface_release(struct device *dev)
 {
        struct gb_interface *intf = to_gb_interface(dev);
 
+       kfree(intf->product_string);
+       kfree(intf->vendor_string);
+
        kfree(intf);
 }
 
@@ -69,28 +70,7 @@ struct device_type greybus_interface_type = {
 };
 
 /*
- * Create kernel structures corresponding to a bundle and connection for
- * managing control CPort. Also initialize the bundle, which will request SVC to
- * set route and will initialize the control protocol for this connection.
- */
-static int gb_create_control_connection(struct gb_interface *intf)
-{
-       struct gb_bundle *bundle;
-
-       bundle = gb_bundle_create(intf, GB_CONTROL_BUNDLE_ID,
-                                 GREYBUS_CLASS_CONTROL);
-       if (!bundle)
-               return -EINVAL;
-
-       if (!gb_connection_create(bundle, GB_CONTROL_CPORT_ID,
-                                 GREYBUS_PROTOCOL_CONTROL))
-               return -EINVAL;
-
-       return 0;
-}
-
-/*
- * A Greybus module represents a user-replicable component on an Ara
+ * A Greybus module represents a user-replaceable component on an Ara
  * phone.  An interface is the physical connection on that module.  A
  * module may have more than one interface.
  *
@@ -101,30 +81,17 @@ static int gb_create_control_connection(struct gb_interface *intf)
  * Returns a pointer to the new interfce or a null pointer if a
  * failure occurs due to memory exhaustion.
  */
-struct gb_interface *gb_interface_create(struct greybus_host_device *hd,
+struct gb_interface *gb_interface_create(struct gb_host_device *hd,
                                         u8 interface_id)
 {
-       struct gb_module *module;
        struct gb_interface *intf;
        int retval;
 
-       intf = gb_interface_find(hd, interface_id);
-       if (intf) {
-               dev_err(hd->parent, "Duplicate interface with interface-id: %d will not be created\n",
-                       interface_id);
-               return NULL;
-       }
-
-       module = gb_module_find(hd, endo_get_module_id(hd->endo, interface_id));
-       if (!module)
-               return NULL;
-
        intf = kzalloc(sizeof(*intf), GFP_KERNEL);
        if (!intf)
-               goto put_module;
+               return NULL;
 
        intf->hd = hd;          /* XXX refcount? */
-       intf->module = module;
        intf->interface_id = interface_id;
        INIT_LIST_HEAD(&intf->bundles);
        INIT_LIST_HEAD(&intf->manifest_descs);
@@ -132,18 +99,17 @@ struct gb_interface *gb_interface_create(struct greybus_host_device *hd,
        /* Invalid device id to start with */
        intf->device_id = GB_DEVICE_ID_BAD;
 
-       intf->dev.parent = &module->dev;
+       intf->dev.parent = &hd->dev;
        intf->dev.bus = &greybus_bus_type;
        intf->dev.type = &greybus_interface_type;
        intf->dev.groups = interface_groups;
-       intf->dev.dma_mask = hd->parent->dma_mask;
+       intf->dev.dma_mask = hd->dev.dma_mask;
        device_initialize(&intf->dev);
-       dev_set_name(&intf->dev, "%s:%d", dev_name(&module->dev), interface_id);
+       dev_set_name(&intf->dev, "%d-%d", hd->bus_id, interface_id);
 
        retval = device_add(&intf->dev);
        if (retval) {
-               pr_err("failed to add interface device for id 0x%02hhx\n",
-                      interface_id);
+               pr_err("failed to add interface %u\n", interface_id);
                goto free_intf;
        }
 
@@ -155,18 +121,14 @@ struct gb_interface *gb_interface_create(struct greybus_host_device *hd,
 
 free_intf:
        put_device(&intf->dev);
-       kfree(intf);
-put_module:
-       put_device(&module->dev);
        return NULL;
 }
 
 /*
- * Tear down a previously set up module.
+ * Tear down a previously set up interface.
  */
-static void gb_interface_destroy(struct gb_interface *intf)
+void gb_interface_remove(struct gb_interface *intf)
 {
-       struct gb_module *module;
        struct gb_bundle *bundle;
        struct gb_bundle *next;
 
@@ -180,16 +142,22 @@ static void gb_interface_destroy(struct gb_interface *intf)
        list_for_each_entry_safe(bundle, next, &intf->bundles, links)
                gb_bundle_destroy(bundle);
 
-       kfree(intf->product_string);
-       kfree(intf->vendor_string);
+       if (intf->control)
+               gb_connection_destroy(intf->control->connection);
 
-       module = intf->module;
        device_unregister(&intf->dev);
-       put_device(&module->dev);
+}
+
+void gb_interfaces_remove(struct gb_host_device *hd)
+{
+       struct gb_interface *intf, *temp;
+
+       list_for_each_entry_safe(intf, temp, &hd->interfaces, links)
+               gb_interface_remove(intf);
 }
 
 /**
- * gb_interface_add
+ * gb_interface_init
  *
  * Create connection for control CPort and then request/parse manifest.
  * Finally initialize all the bundles to set routes via SVC and initialize all
@@ -197,16 +165,19 @@ static void gb_interface_destroy(struct gb_interface *intf)
  */
 int gb_interface_init(struct gb_interface *intf, u8 device_id)
 {
+       struct gb_connection *connection;
        int ret, size;
        void *manifest;
 
        intf->device_id = device_id;
 
        /* Establish control CPort connection */
-       ret = gb_create_control_connection(intf);
-       if (ret) {
-               dev_err(&intf->dev, "Failed to create control CPort connection (%d)\n", ret);
-               return ret;
+       connection = gb_connection_create_dynamic(intf, NULL,
+                                               GB_CONTROL_CPORT_ID,
+                                               GREYBUS_PROTOCOL_CONTROL);
+       if (!connection) {
+               dev_err(&intf->dev, "failed to create control connection\n");
+               return -ENOMEM;
        }
 
        /* Get manifest size using control protocol on CPort */
@@ -254,22 +225,3 @@ free_manifest:
        kfree(manifest);
        return ret;
 }
-
-void gb_interface_remove(struct greybus_host_device *hd, u8 interface_id)
-{
-       struct gb_interface *intf = gb_interface_find(hd, interface_id);
-
-       if (intf)
-               gb_interface_destroy(intf);
-       else
-               dev_err(hd->parent, "interface id %d not found\n",
-                       interface_id);
-}
-
-void gb_interfaces_remove(struct greybus_host_device *hd)
-{
-       struct gb_interface *intf, *temp;
-
-       list_for_each_entry_safe(intf, temp, &hd->interfaces, links)
-               gb_interface_destroy(intf);
-}