]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
greybus: add device initialization
authorAlex Elder <elder@linaro.org>
Thu, 16 Oct 2014 11:35:35 +0000 (06:35 -0500)
committerGreg Kroah-Hartman <greg@kroah.com>
Fri, 17 Oct 2014 16:14:11 +0000 (18:14 +0200)
Set up the infrastructure for initializing connections based on
their protocol.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
drivers/staging/greybus/connection.c
drivers/staging/greybus/connection.h
drivers/staging/greybus/core.c
drivers/staging/greybus/greybus.h
drivers/staging/greybus/interface.c
drivers/staging/greybus/interface.h
drivers/staging/greybus/module.c
drivers/staging/greybus/module.h

index 740f491bf5fc1fa084fb89d2b58c3aea60eb6bcd..0143a4f6bd1263d9250ca9f1243359172655d3ef 100644 (file)
@@ -191,3 +191,27 @@ void gb_connection_err(struct gb_connection *connection, const char *fmt, ...)
 
        va_end(args);
 }
+
+/*
+ * XXX Protocols should have a set of function pointers:
+ *     ->init (called here, to initialize the device)
+ *     ->input_handler
+ *     ->exit (reverse of init)
+ */
+int gb_connection_init(struct gb_connection *connection)
+{
+       switch (connection->protocol) {
+       case GREYBUS_PROTOCOL_I2C:
+       case GREYBUS_PROTOCOL_CONTROL:
+       case GREYBUS_PROTOCOL_AP:
+       case GREYBUS_PROTOCOL_GPIO:
+       case GREYBUS_PROTOCOL_UART:
+       case GREYBUS_PROTOCOL_HID:
+       case GREYBUS_PROTOCOL_VENDOR:
+       default:
+               gb_connection_err(connection, "unimplemented protocol %u",
+                       (u32)connection->protocol);
+               break;
+       }
+       return -ENXIO;
+}
index 5862ce05933e6953112fefc155d02516b6a904be..bb22c52c2f019c1083f064f89af15a20e5211a07 100644 (file)
@@ -34,6 +34,8 @@ struct gb_connection *gb_connection_create(struct gb_interface *interface,
                                u16 cport_id, enum greybus_protocol protocol);
 void gb_connection_destroy(struct gb_connection *connection);
 
+int gb_connection_init(struct gb_connection *connection);
+
 struct gb_connection *gb_hd_connection_find(struct greybus_host_device *hd,
                                u16 cport_id);
 
index b5f666a6255e7050ee427153ff38426085d7facc..38f867db94111198f6bae05ef4f0a394aa5e6b61 100644 (file)
@@ -182,8 +182,11 @@ void gb_add_module(struct greybus_host_device *hd, u8 module_id,
        dev_set_name(&gmod->dev, "%d", module_id);
 
        retval = device_add(&gmod->dev);
-       if (!retval)
-               return;         /* Success */
+       if (retval)
+               goto error;
+
+       gb_module_interfaces_init(gmod);
+       return;
 error:
        gb_module_destroy(gmod);
 
@@ -253,7 +256,6 @@ void greybus_remove_hd(struct greybus_host_device *hd)
 }
 EXPORT_SYMBOL_GPL(greybus_remove_hd);
 
-
 static int __init gb_init(void)
 {
        int retval;
index 1970106d70a0cd4dd8da22fcfedb1c22650f81dc..d92ba5178cf158f021eb7072c9651c70e2963d1a 100644 (file)
@@ -265,6 +265,8 @@ void gb_deregister_cport_complete(u16 cport_id);
 
 extern const struct attribute_group *greybus_module_groups[];
 
+int gb_i2c_device_init(struct gb_connection *connection);
+
 int gb_tty_init(void);
 void gb_tty_exit(void);
 
index b9dd93093cc6e4e324e0dff9fd8df7e2297fb630..0c2fdd3f7ea267ff1f57a9975b8f0ea8a8a7003a 100644 (file)
@@ -57,3 +57,18 @@ void gb_interface_destroy(struct gb_interface *interface)
        /* kref_put(gmod); */
        kfree(interface);
 }
+
+int gb_interface_connections_init(struct gb_interface *interface)
+{
+       struct gb_connection *connection;
+       int ret = 0;
+
+       list_for_each_entry(connection, &interface->connections,
+                       interface_links) {
+               ret = gb_connection_init(connection);
+               if (ret)
+                       break;
+       }
+
+       return ret;
+}
index 9c9ffe7715a57694218df4f13ef113fe8ddc0029..1019a981f5f6eabf3e9d0a9c376c1023d41f033c 100644 (file)
@@ -22,4 +22,6 @@ struct gb_interface {
 struct gb_interface *gb_interface_create(struct gb_module *gmod, u8 module_id);
 void gb_interface_destroy(struct gb_interface *interface);
 
+int gb_interface_connections_init(struct gb_interface *interface);
+
 #endif /* __INTERFACE_H */
index 1970e7b01081ab1c83c43c1ff55a5017ae904dcb..699cd003e3673d4f5aec907d9847be06fc3e7965 100644 (file)
@@ -55,39 +55,52 @@ const struct greybus_module_id *gb_module_match_id(struct gb_module *gmod,
  */
 struct gb_module *gb_module_create(struct greybus_host_device *hd, u8 module_id)
 {
-       struct gb_module *module;
+       struct gb_module *gmod;
 
-       module = kzalloc(sizeof(*module), GFP_KERNEL);
-       if (!module)
+       gmod = kzalloc(sizeof(*gmod), GFP_KERNEL);
+       if (!gmod)
                return NULL;
 
-       module->hd = hd;                /* XXX refcount? */
-       module->module_id = module_id;
-       INIT_LIST_HEAD(&module->interfaces);
+       gmod->hd = hd;          /* XXX refcount? */
+       gmod->module_id = module_id;
+       INIT_LIST_HEAD(&gmod->interfaces);
 
        spin_lock_irq(&gb_modules_lock);
-       list_add_tail(&module->links, &hd->modules);
+       list_add_tail(&gmod->links, &hd->modules);
        spin_unlock_irq(&gb_modules_lock);
 
-       return module;
+       return gmod;
 }
 
 /*
  * Tear down a previously set up module.
  */
-void gb_module_destroy(struct gb_module *module)
+void gb_module_destroy(struct gb_module *gmod)
 {
-       if (WARN_ON(!module))
+       if (WARN_ON(!gmod))
                return;
 
-       kfree(module->product_string);
-       kfree(module->vendor_string);
+       kfree(gmod->product_string);
+       kfree(gmod->vendor_string);
 
        spin_lock_irq(&gb_modules_lock);
-       list_del(&module->links);
+       list_del(&gmod->links);
        spin_unlock_irq(&gb_modules_lock);
 
        /* kref_put(module->hd); */
 
-       kfree(module);
+       kfree(gmod);
+}
+
+void gb_module_interfaces_init(struct gb_module *gmod)
+{
+       struct gb_interface *interface;
+       int ret = 0;
+
+       list_for_each_entry(interface, &gmod->interfaces, links) {
+               ret = gb_interface_connections_init(interface);
+               if (ret)
+                       dev_err(gmod->hd->parent,
+                               "module interface init error %d\n", ret);
+       }
 }
index 7b01950fa36e7a876c869ec4e38f47bc74c8de8f..114f15750380ea16d65028fb1d04411cc6697541 100644 (file)
@@ -62,4 +62,6 @@ struct gb_module *gb_module_create(struct greybus_host_device *hd,
                                        u8 module_id);
 void gb_module_destroy(struct gb_module *module);
 
+void gb_module_interfaces_init(struct gb_module *gmod);
+
 #endif /* __MODULE_H */