From: Greg Kroah-Hartman Date: Wed, 24 Dec 2014 21:01:40 +0000 (-0800) Subject: greybus: protocol: add a module owner to a protocol X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=12a5dfc9acf690504e7266a8f310702bc9e6872c;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git 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 Reviewed-by: Alex Elder --- 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);