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);
}
}
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)
*/
static void gb_interface_destroy(struct gb_interface *intf)
{
+ struct gb_module *module;
+
if (WARN_ON(!intf))
return;
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);
}
/**
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;
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);
+}
+
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)
/* 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 */