]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
greybus: legacy: add legacy-protocol bundle driver
authorJohan Hovold <johan@hovoldconsulting.com>
Tue, 19 Jan 2016 11:50:59 +0000 (12:50 +0100)
committerGreg Kroah-Hartman <gregkh@google.com>
Tue, 19 Jan 2016 20:12:40 +0000 (12:12 -0800)
Add the first Greybus bundle driver that will be used when transitioning
from legacy Greybus protocols to bundle drivers.

The legacy-protocol driver initially binds to all current bundle classes.

In order to avoid having to update current module-loading scripts, keep
this driver internal to greybus core at least until modalias support is
added. Note that this prevents unloading any protocol drivers without
first tearing down the host device due to a circular module dependency.

Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/Makefile
drivers/staging/greybus/bundle.c
drivers/staging/greybus/connection.c
drivers/staging/greybus/core.c
drivers/staging/greybus/interface.c
drivers/staging/greybus/legacy.c [new file with mode: 0644]
drivers/staging/greybus/legacy.h [new file with mode: 0644]

index b1272cbd55ee4f3f46cdbee04b83de3f7cc241af..1e24509bdb4db982ab31dc0233c21a021c49b370 100644 (file)
@@ -9,7 +9,8 @@ greybus-y :=    core.o          \
                control.o       \
                svc.o           \
                firmware.o      \
-               operation.o
+               operation.o     \
+               legacy.o
 
 gb-phy-y :=    gpbridge.o      \
                sdio.o  \
index fb775ff1895d60267cb81f83dbdba48c1023b21f..ec52bdecb5c1d3e146e31de6c1547cddc0598e7b 100644 (file)
@@ -152,21 +152,11 @@ int gb_bundle_add(struct gb_bundle *bundle)
        return 0;
 }
 
-static void gb_bundle_connections_exit(struct gb_bundle *bundle)
-{
-       struct gb_connection *connection;
-
-       list_for_each_entry(connection, &bundle->connections, bundle_links)
-               gb_connection_exit(connection);
-}
-
 /*
  * Tear down a previously set up bundle.
  */
 void gb_bundle_destroy(struct gb_bundle *bundle)
 {
-       gb_bundle_connections_exit(bundle);
-
        if (device_is_registered(&bundle->dev))
                device_del(&bundle->dev);
 
index 6295d28a4be49a575352afe4bcadbd6e1d828ce5..21e6eb52c43788a8d8237430b18dfecc9e4d59a4 100644 (file)
@@ -464,6 +464,7 @@ int gb_connection_init(struct gb_connection *connection)
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(gb_connection_init);
 
 void gb_connection_exit(struct gb_connection *connection)
 {
@@ -482,6 +483,7 @@ void gb_connection_exit(struct gb_connection *connection)
 
        gb_connection_unbind_protocol(connection);
 }
+EXPORT_SYMBOL_GPL(gb_connection_exit);
 
 /*
  * Tear down a previously set up connection.
index 0e2f99df6cfa6fd49c41d71d7ba82785b9b3faa1..28f48d79b0055212f72b6a267f32a726b4a7b302 100644 (file)
@@ -12,6 +12,7 @@
 #define CREATE_TRACE_POINTS
 #include "greybus.h"
 #include "greybus_trace.h"
+#include "legacy.h"
 
 EXPORT_TRACEPOINT_SYMBOL_GPL(gb_host_device_send);
 EXPORT_TRACEPOINT_SYMBOL_GPL(gb_host_device_recv);
@@ -240,8 +241,16 @@ static int __init gb_init(void)
                goto error_firmware;
        }
 
+       retval = gb_legacy_init();
+       if (retval) {
+               pr_err("gb_legacy_init failed\n");
+               goto error_legacy;
+       }
+
        return 0;       /* Success */
 
+error_legacy:
+       gb_firmware_protocol_exit();
 error_firmware:
        gb_svc_protocol_exit();
 error_svc:
@@ -261,6 +270,7 @@ module_init(gb_init);
 
 static void __exit gb_exit(void)
 {
+       gb_legacy_exit();
        gb_firmware_protocol_exit();
        gb_svc_protocol_exit();
        gb_control_protocol_exit();
index edac2383e492a2471fd34fdc19549d4603b53c51..c3453502ae226a7a9be0ceecdfc09a4e31032622 100644 (file)
@@ -183,7 +183,6 @@ void gb_interfaces_remove(struct gb_host_device *hd)
 int gb_interface_init(struct gb_interface *intf, u8 device_id)
 {
        struct gb_bundle *bundle, *tmp;
-       struct gb_connection *connection;
        int ret, size;
        void *manifest;
 
@@ -242,15 +241,6 @@ int gb_interface_init(struct gb_interface *intf, u8 device_id)
                        gb_bundle_destroy(bundle);
                        continue;
                }
-
-               list_for_each_entry(connection, &bundle->connections,
-                                                       bundle_links) {
-                       ret = gb_connection_init(connection);
-                       if (ret)
-                               break;
-               }
-               if (ret)
-                       gb_bundle_destroy(bundle);
        }
 
        ret = 0;
diff --git a/drivers/staging/greybus/legacy.c b/drivers/staging/greybus/legacy.c
new file mode 100644 (file)
index 0000000..26a7d1a
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Greybus legacy-protocol driver
+ *
+ * Copyright 2015 Google Inc.
+ * Copyright 2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include "greybus.h"
+#include "legacy.h"
+
+static int legacy_probe(struct gb_bundle *bundle,
+                       const struct greybus_bundle_id *id)
+{
+       struct gb_connection *connection;
+       int ret;
+
+       dev_dbg(&bundle->dev, "%s - bundle class = 0x%02x\n", __func__,
+                       bundle->class);
+
+       list_for_each_entry(connection, &bundle->connections, bundle_links) {
+               dev_dbg(&bundle->dev, "enabling connection %s\n",
+                               connection->name);
+
+               ret = gb_connection_init(connection);
+               if (ret)
+                       goto err_connections_disable;
+       }
+
+       return 0;
+
+err_connections_disable:
+       list_for_each_entry_reverse(connection, &bundle->connections,
+                                                       bundle_links) {
+               gb_connection_exit(connection);
+       }
+
+       return ret;
+}
+
+static void legacy_disconnect(struct gb_bundle *bundle)
+{
+       struct gb_connection *connection;
+
+       dev_dbg(&bundle->dev, "%s - bundle class = 0x%02x\n", __func__,
+                       bundle->class);
+
+       list_for_each_entry_reverse(connection, &bundle->connections,
+                                                       bundle_links) {
+               gb_connection_exit(connection);
+       }
+}
+
+static const struct greybus_bundle_id legacy_id_table[] = {
+       { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_GPIO) },
+       { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_I2C) },
+       { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_UART) },
+       { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_HID) },
+       { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_USB) },
+       { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_SDIO) },
+       { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_POWER_SUPPLY) },
+       { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_PWM) },
+       { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_SPI) },
+       { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_DISPLAY) },
+       { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_CAMERA) },
+       { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_SENSOR) },
+       { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_LIGHTS) },
+       { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_VIBRATOR) },
+       { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_LOOPBACK) },
+       { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_AUDIO_MGMT) },
+       { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_AUDIO_DATA) },
+       { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_SVC) },
+       { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_FIRMWARE) },
+       { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_RAW) },
+       { }
+};
+MODULE_DEVICE_TABLE(greybus, legacy_id_table);
+
+static struct greybus_driver legacy_driver = {
+       .name           = "legacy",
+       .probe          = legacy_probe,
+       .disconnect     = legacy_disconnect,
+       .id_table       = legacy_id_table,
+};
+
+int gb_legacy_init(void)
+{
+       return greybus_register(&legacy_driver);
+}
+
+void gb_legacy_exit(void)
+{
+       greybus_deregister(&legacy_driver);
+}
diff --git a/drivers/staging/greybus/legacy.h b/drivers/staging/greybus/legacy.h
new file mode 100644 (file)
index 0000000..2177f6a
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Greybus legacy-protocol driver
+ *
+ * Copyright 2015 Google Inc.
+ * Copyright 2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#ifndef __LEGACY_H
+#define __LEGACY_H
+
+int gb_legacy_init(void);
+void gb_legacy_exit(void);
+
+#endif /* __LEGACY_H */