diff options
author | Greg Kroah-Hartman <greg@kroah.com> | 2014-12-24 13:01:40 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <greg@kroah.com> | 2015-01-02 13:05:42 -0800 |
commit | 12a5dfc9acf690504e7266a8f310702bc9e6872c (patch) | |
tree | e08322fe107b8caed9adb4f7a678ea582ea4727f /drivers/staging | |
parent | greybus: bundle: create GB_DEVICE_ID_BAD (diff) | |
download | linux-12a5dfc9acf690504e7266a8f310702bc9e6872c.tar.gz linux-12a5dfc9acf690504e7266a8f310702bc9e6872c.tar.bz2 linux-12a5dfc9acf690504e7266a8f310702bc9e6872c.zip |
greybus: protocol: add a module owner to a protocol
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>
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/greybus/protocol.c | 17 | ||||
-rw-r--r-- | drivers/staging/greybus/protocol.h | 6 |
2 files changed, 17 insertions, 6 deletions
diff --git a/drivers/staging/greybus/protocol.c b/drivers/staging/greybus/protocol.c index ee8ee3e15f8e..c6c0fd3ebea3 100644 --- a/drivers/staging/greybus/protocol.c +++ b/drivers/staging/greybus/protocol.c @@ -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) diff --git a/drivers/staging/greybus/protocol.h b/drivers/staging/greybus/protocol.h index e2555b75e334..62f024dd71bd 100644 --- a/drivers/staging/greybus/protocol.h +++ b/drivers/staging/greybus/protocol.h @@ -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); |