diff --git a/drivers/staging/greybus/bundle.c b/drivers/staging/greybus/bundle.c index 93f80dc5a815..5ced992e17d4 100644 --- a/drivers/staging/greybus/bundle.c +++ b/drivers/staging/greybus/bundle.c @@ -140,7 +140,7 @@ void gb_bundle_destroy(struct gb_interface *intf) list_for_each_entry_safe(bundle, temp, &list, links) { list_del(&bundle->links); gb_bundle_connections_exit(bundle); - device_del(&bundle->dev); + device_unregister(&bundle->dev); } } diff --git a/drivers/staging/greybus/connection.c b/drivers/staging/greybus/connection.c index 102e1a4c6e74..5ec161b9b2f2 100644 --- a/drivers/staging/greybus/connection.c +++ b/drivers/staging/greybus/connection.c @@ -252,7 +252,7 @@ void gb_connection_destroy(struct gb_connection *connection) gb_connection_hd_cport_id_free(connection); gb_protocol_put(connection->protocol); - device_del(&connection->dev); + device_unregister(&connection->dev); } int gb_connection_init(struct gb_connection *connection) diff --git a/drivers/staging/greybus/interface.c b/drivers/staging/greybus/interface.c index b687908cfa16..122281f2cd2b 100644 --- a/drivers/staging/greybus/interface.c +++ b/drivers/staging/greybus/interface.c @@ -173,6 +173,8 @@ put_module: */ static void gb_interface_destroy(struct gb_interface *intf) { + struct gb_module *module; + if (WARN_ON(!intf)) return; @@ -184,10 +186,11 @@ static void gb_interface_destroy(struct gb_interface *intf) kfree(intf->product_string); kfree(intf->vendor_string); - put_device(&intf->module->dev); /* kref_put(module->hd); */ - device_del(&intf->dev); + module = intf->module; + device_unregister(&intf->dev); + gb_module_remove(module); } /** diff --git a/drivers/staging/greybus/module.c b/drivers/staging/greybus/module.c index 56a55fea107b..538182b60dd9 100644 --- a/drivers/staging/greybus/module.c +++ b/drivers/staging/greybus/module.c @@ -101,6 +101,7 @@ static struct gb_module *gb_module_create(struct greybus_host_device *hd, return NULL; module->module_id = module_id; + module->refcount = 1; module->dev.parent = hd->parent; module->dev.bus = &greybus_bus_type; module->dev.type = &greybus_module_type; @@ -127,9 +128,20 @@ struct gb_module *gb_module_find_or_create(struct greybus_host_device *hd, struct gb_module *module; module = gb_module_find(module_id); - if (module) + if (module) { + module->refcount++; return module; + } return gb_module_create(hd, module_id); } +void gb_module_remove(struct gb_module *module) +{ + if (!module) + return; + + if (!--module->refcount) + device_unregister(&module->dev); +} + diff --git a/drivers/staging/greybus/module.h b/drivers/staging/greybus/module.h index 75a8818de1c5..4f02e46301e1 100644 --- a/drivers/staging/greybus/module.h +++ b/drivers/staging/greybus/module.h @@ -13,6 +13,7 @@ struct gb_module { struct device dev; u8 module_id; /* Physical location within the Endo */ + u16 refcount; }; #define to_gb_module(d) container_of(d, struct gb_module, dev) @@ -21,6 +22,7 @@ struct greybus_host_device; /* Greybus "private" definitions */ struct gb_module *gb_module_find_or_create(struct greybus_host_device *hd, u8 module_id); +void gb_module_remove(struct gb_module *module); #endif /* __MODULE_H */