greybus: protocol: add a module owner to a protocol
authorGreg Kroah-Hartman <greg@kroah.com>
Wed, 24 Dec 2014 21:01:40 +0000 (13:01 -0800)
committerGreg Kroah-Hartman <greg@kroah.com>
Fri, 2 Jan 2015 21:05:42 +0000 (13:05 -0800)
Now that protocols can be in a module, we need to reference count them
to lock them into memory so they can't be removed while in use.  So add
a module owner structure, and have it automatically be assigned when
registering the protocol.

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

index ee8ee3e..c6c0fd3 100644 (file)
@@ -39,13 +39,15 @@ static struct gb_protocol *_gb_protocol_find(u8 id, u8 major, u8 minor)
        return NULL;
 }
 
-int gb_protocol_register(struct gb_protocol *protocol)
+int __gb_protocol_register(struct gb_protocol *protocol, struct module *module)
 {
        struct gb_protocol *existing;
        u8 id = protocol->id;
        u8 major = protocol->major;
        u8 minor = protocol->minor;
 
+       protocol->owner = module;
+
        /*
         * The protocols list is sorted first by protocol id (low to
         * high), then by major version (high to low), and finally
@@ -92,7 +94,7 @@ int gb_protocol_register(struct gb_protocol *protocol)
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(gb_protocol_register);
+EXPORT_SYMBOL_GPL(__gb_protocol_register);
 
 /*
  * De-register a previously registered protocol.
@@ -135,9 +137,13 @@ struct gb_protocol *gb_protocol_get(u8 id, u8 major, u8 minor)
        spin_lock_irq(&gb_protocols_lock);
        protocol = _gb_protocol_find(id, major, minor);
        if (protocol) {
-               protocol_count = protocol->count;
-               if (protocol_count != U8_MAX)
-                       protocol->count++;
+               if (!try_module_get(protocol->owner)) {
+                       protocol = NULL;
+               } else {
+                       protocol_count = protocol->count;
+                       if (protocol_count != U8_MAX)
+                               protocol->count++;
+               }
        }
        spin_unlock_irq(&gb_protocols_lock);
 
@@ -163,6 +169,7 @@ void gb_protocol_put(struct gb_protocol *protocol)
                protocol_count = protocol->count;
                if (protocol_count)
                        protocol->count--;
+               module_put(protocol->owner);
        }
        spin_unlock_irq(&gb_protocols_lock);
        if (protocol)
index e2555b7..62f024d 100644 (file)
@@ -34,11 +34,15 @@ struct gb_protocol {
        gb_connection_init_t    connection_init;
        gb_connection_exit_t    connection_exit;
        gb_request_recv_t       request_recv;
+       struct module           *owner;
 };
 
-int gb_protocol_register(struct gb_protocol *protocol);
+int __gb_protocol_register(struct gb_protocol *protocol, struct module *module);
 int gb_protocol_deregister(struct gb_protocol *protocol);
 
+#define gb_protocol_register(protocol) \
+       __gb_protocol_register(protocol, THIS_MODULE)
+
 struct gb_protocol *gb_protocol_get(u8 id, u8 major, u8 minor);
 void gb_protocol_put(struct gb_protocol *protocol);