]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
greybus: register preallocated protocols
authorAlex Elder <elder@linaro.org>
Wed, 5 Nov 2014 22:12:53 +0000 (16:12 -0600)
committerGreg Kroah-Hartman <greg@kroah.com>
Wed, 5 Nov 2014 22:23:50 +0000 (14:23 -0800)
Set up protocol structures as static objects in each protocol source
file.  Pass the address of that in--rather than the protocol id and
version information--to the protocol registration routine.  Call a
central routine to register all our pre-defined protocols.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
drivers/staging/greybus/battery-gb.c
drivers/staging/greybus/core.c
drivers/staging/greybus/gpio-gb.c
drivers/staging/greybus/greybus_manifest.h
drivers/staging/greybus/i2c-gb.c
drivers/staging/greybus/protocol.c
drivers/staging/greybus/protocol.h
drivers/staging/greybus/sdio-gb.c
drivers/staging/greybus/uart-gb.c

index 28c0d0b9aefeaa4664bb328d3cd43f8ccb013a2b..457daf700543bc980a4fbff0f516379f3436f325 100644 (file)
@@ -404,3 +404,19 @@ struct gb_connection_handler gb_battery_connection_handler = {
        .connection_init        = gb_battery_connection_init,
        .connection_exit        = gb_battery_connection_exit,
 };
+
+static struct gb_protocol battery_protocol = {
+       .id                     = GREYBUS_PROTOCOL_BATTERY,
+       .major                  = 0,
+       .minor                  = 1,
+};
+
+bool gb_battery_protocol_init(void)
+{
+       return gb_protocol_register(&battery_protocol);
+}
+
+void gb_battery_protocol_exit(void)
+{
+       gb_protocol_deregister(&battery_protocol);
+}
index 252d131c3ae85b78bd18da87e8261df97e64dc34..1d05c35a1b603c52af73091ef66bac65021df9b5 100644 (file)
@@ -277,17 +277,23 @@ static int __init gb_init(void)
                goto error_operation;
        }
 
-       return 0;
+       if (!gb_protocol_init()) {
+               /* This only fails for duplicate protocol registration */
+               retval = -EEXIST;
+               pr_err("gb_protocol_init failed\n");
+               goto error_protocol;
+       }
 
+       return 0;       /* Success */
+
+error_protocol:
+       gb_operation_exit();
 error_operation:
        gb_gbuf_exit();
-
 error_gbuf:
        gb_ap_exit();
-
 error_ap:
        bus_unregister(&greybus_bus_type);
-
 error_bus:
        gb_debugfs_cleanup();
 
index df7dbae85d6396667dab91f8c5526d54f1814ee3..242b91a99d22377163b22d33b9f362b5c3aa459a 100644 (file)
@@ -796,3 +796,19 @@ struct gb_connection_handler gb_gpio_connection_handler = {
        .connection_init        = gb_gpio_connection_init,
        .connection_exit        = gb_gpio_connection_exit,
 };
+
+static struct gb_protocol gpio_protocol = {
+       .id                     = GREYBUS_PROTOCOL_GPIO,
+       .major                  = 0,
+       .minor                  = 1,
+};
+
+bool gb_gpio_protocol_init(void)
+{
+       return gb_protocol_register(&gpio_protocol);
+}
+
+void gb_gpio_protocol_exit(void)
+{
+       gb_protocol_deregister(&gpio_protocol);
+}
index c6988ce2818a88f18286642e2e3c29e4c8f2a477..844ab8a745b0c3d1ec55f491bf268e9743ee0e06 100644 (file)
@@ -30,6 +30,7 @@ enum greybus_protocol {
        GREYBUS_PROTOCOL_I2C            = 0x03,
        GREYBUS_PROTOCOL_UART           = 0x04,
        GREYBUS_PROTOCOL_HID            = 0x05,
+       GREYBUS_PROTOCOL_SDIO           = 0x06,
        GREYBUS_PROTOCOL_BATTERY        = 0x08,
        GREYBUS_PROTOCOL_LED            = 0x0e,
                /* ... */
index b26464a14b32c3f725d23965a5c4829c9c32b411..c8fae17d4b7783a390ff87dede7413d3cb1e0c31 100644 (file)
@@ -522,3 +522,19 @@ struct gb_connection_handler gb_i2c_connection_handler = {
        .connection_init        = gb_i2c_connection_init,
        .connection_exit        = gb_i2c_connection_exit,
 };
+
+static struct gb_protocol i2c_protocol = {
+       .id                     = GREYBUS_PROTOCOL_I2C,
+       .major                  = 0,
+       .minor                  = 1,
+};
+
+bool gb_i2c_protocol_init(void)
+{
+       return gb_protocol_register(&i2c_protocol);
+}
+
+void gb_i2c_protocol_exit(void)
+{
+       gb_protocol_deregister(&i2c_protocol);
+}
index 6fec32eea76d549079e28c83d142581c3cf79845..93e0af3c6b4e5563e9e0881d0ad3a36e502ebf6a 100644 (file)
@@ -39,18 +39,12 @@ static struct gb_protocol *_gb_protocol_find(u8 id, u8 major, u8 minor)
 }
 
 /* Returns true if protocol was succesfully registered, false otherwise */
-bool gb_protocol_register(u8 id, u8 major, u8 minor)
+bool gb_protocol_register(struct gb_protocol *protocol)
 {
-       struct gb_protocol *protocol;
        struct gb_protocol *existing;
-
-       /* Initialize it speculatively */
-       protocol = kzalloc(sizeof(*protocol), GFP_KERNEL);
-       if (!protocol)
-               return false;
-       protocol->id = id;
-       protocol->major = major;
-       protocol->minor = minor;
+       u8 id = protocol->id;
+       u8 major = protocol->major;
+       u8 minor = protocol->minor;
 
        /*
         * The protocols list is sorted first by protocol id (low to
@@ -79,7 +73,6 @@ bool gb_protocol_register(u8 id, u8 major, u8 minor)
 
                /* A matching protocol has already been registered */
                spin_unlock_irq(&gb_protocols_lock);
-               kfree(protocol);
 
                return false;
        }
@@ -94,7 +87,17 @@ bool gb_protocol_register(u8 id, u8 major, u8 minor)
        return true;
 }
 
-/* Returns true if successful, false otherwise */
+/*
+ * De-register a previously registered protocol.
+ *
+ * XXX Currently this fails (and reports an error to the caller) if
+ * XXX the protocol is currently in use.  We may want to forcefully
+ * XXX kill off a protocol and all its active users at some point.
+ * XXX But I think that's better handled by quescing modules that
+ * XXX have users and having those users drop their reference.
+ *
+ * Returns true if successful, false otherwise.
+ */
 bool gb_protocol_deregister(struct gb_protocol *protocol)
 {
        u8 protocol_count = 0;
@@ -108,7 +111,6 @@ bool gb_protocol_deregister(struct gb_protocol *protocol)
                        list_del(&protocol->links);
        }
        spin_unlock_irq(&gb_protocols_lock);
-       kfree(protocol);
 
        return protocol && !protocol_count;
 }
@@ -158,3 +160,39 @@ void gb_protocol_put(struct gb_protocol *protocol)
                pr_err("protocol id %hhu version %hhu.%hhu not found\n",
                        protocol->id, major, minor);
 }
+
+bool gb_protocol_init(void)
+{
+       bool ret = true;
+
+       if (!gb_battery_protocol_init()) {
+               pr_err("error initializing battery protocol\n");
+               ret = false;
+       }
+       if (!gb_gpio_protocol_init()) {
+               pr_err("error initializing gpio protocol\n");
+               ret = false;
+       }
+       if (!gb_i2c_protocol_init()) {
+               pr_err("error initializing i2c protocol\n");
+               ret = false;
+       }
+       if (!gb_uart_protocol_init()) {
+               pr_err("error initializing uart protocol\n");
+               ret = false;
+       }
+       if (!gb_sdio_protocol_init()) {
+               pr_err("error initializing sdio protocol\n");
+               ret = false;
+       }
+       return ret;
+}
+
+void gb_protocol_exit(void)
+{
+       gb_sdio_protocol_exit();
+       gb_uart_protocol_exit();
+       gb_i2c_protocol_exit();
+       gb_gpio_protocol_exit();
+       gb_battery_protocol_exit();
+}
index aa7b5548e8a82c923739c60b7c241354c675801b..c2adfdca8bf785470c2f9e42fe1909546deaa900 100644 (file)
@@ -25,10 +25,33 @@ struct gb_protocol {
        struct list_head        links;          /* global list */
 };
 
-bool gb_protocol_register(u8 id, u8 major, u8 minor);
+bool gb_protocol_register(struct gb_protocol *protocol);
 bool gb_protocol_deregister(struct gb_protocol *protocol);
 
 struct gb_protocol *gb_protocol_get(u8 id, u8 major, u8 minor);
 void gb_protocol_put(struct gb_protocol *protocol);
 
+/*
+ * These are defined in their respective protocol source files.
+ * Declared here for now.  They could be added via modules, or maybe
+ * just use initcalls (which level?).
+ */
+extern bool gb_battery_protocol_init(void);
+extern void gb_battery_protocol_exit(void);
+
+extern bool gb_gpio_protocol_init(void);
+extern void gb_gpio_protocol_exit(void);
+
+extern bool gb_i2c_protocol_init(void);
+extern void gb_i2c_protocol_exit(void);
+
+extern bool gb_uart_protocol_init(void);
+extern void gb_uart_protocol_exit(void);
+
+extern bool gb_sdio_protocol_init(void);
+extern void gb_sdio_protocol_exit(void);
+
+bool gb_protocol_init(void);
+void gb_protocol_exit(void);
+
 #endif /* __PROTOCOL_H */
index 30caba8d0fa5a18d294df43970ca4f877619fd98..8fbfbca37c48d824397401c8de0075a3769c597e 100644 (file)
@@ -81,3 +81,19 @@ struct gb_connection_handler gb_sdio_connection_handler = {
        .connection_init        = gb_sdio_connection_init,
        .connection_exit        = gb_sdio_connection_exit,
 };
+
+static struct gb_protocol sdio_protocol = {
+       .id                     = GREYBUS_PROTOCOL_SDIO,
+       .major                  = 0,
+       .minor                  = 1,
+};
+
+bool gb_sdio_protocol_init(void)
+{
+       return gb_protocol_register(&sdio_protocol);
+}
+
+void gb_sdio_protocol_exit(void)
+{
+       gb_protocol_deregister(&sdio_protocol);
+}
index b52d9e11f5366a65d4fbfe8707a16828f4867e9f..5596644e952b8583cfc242279a8d756d60c4cd9e 100644 (file)
@@ -524,3 +524,19 @@ struct gb_connection_handler gb_uart_connection_handler = {
        .connection_init        = gb_uart_connection_init,
        .connection_exit        = gb_uart_connection_exit,
 };
+
+static struct gb_protocol uart_protocol = {
+       .id                     = GREYBUS_PROTOCOL_UART,
+       .major                  = 0,
+       .minor                  = 1,
+};
+
+bool gb_uart_protocol_init(void)
+{
+       return gb_protocol_register(&uart_protocol);
+}
+
+void gb_uart_protocol_exit(void)
+{
+       gb_protocol_deregister(&uart_protocol);
+}