void greybus_remove_hd(struct greybus_host_device *hd) { /* * Tear down all interfaces, modules, and the endo that is associated * with this host controller before freeing the memory associated with * the host controller. */ gb_interfaces_remove(hd); gb_endo_remove(hd->endo); /* Is the SVC still using the partially uninitialized connection ? */ if (hd->initial_svc_connection) { gb_connection_exit(hd->initial_svc_connection); gb_connection_destroy(hd->initial_svc_connection); } /* * Make sure there are no leftovers that can potentially corrupt sysfs. */ if (WARN_ON(!list_empty(&hd->connections))) gb_hd_connections_exit(hd); kref_put_mutex(&hd->kref, free_hd, &hd_mutex); }
/* * Tear down a previously set up connection. */ void gb_connection_destroy(struct gb_connection *connection) { struct ida *id_map; if (WARN_ON(!connection)) return; gb_connection_exit(connection); spin_lock_irq(&gb_connections_lock); list_del(&connection->bundle_links); list_del(&connection->hd_links); spin_unlock_irq(&gb_connections_lock); if (connection->protocol) gb_protocol_put(connection->protocol); connection->protocol = NULL; id_map = &connection->hd->cport_id_map; ida_simple_remove(id_map, connection->hd_cport_id); connection->hd_cport_id = CPORT_ID_BAD; device_unregister(&connection->dev); }