/* This call is synchronous, and may not be used in an interrupt context. Callers must own the device lock, so driver disconnect() entries don't need extra locking, but other call contexts may need to explicitly claim that lock.  */
void usb_driver_release_interface(struct usb_driver *driver, struct usb_interface *iface)
/* This call is synchronous, and may not be used in an interrupt context. Callers must own the device lock, so driver disconnect() entries don't need extra locking, but other call contexts may need to explicitly claim that lock.  */
void usb_driver_release_interface(struct usb_driver *driver, struct usb_interface *iface)
{
	struct device *dev = &iface->dev;
	if (!dev->driver || dev->driver != &driver->drvwrap.driver)
		return;
	if (iface->condition != USB_INTERFACE_BOUND)
		return;
	iface->condition = USB_INTERFACE_UNBINDING;
	if (device_is_registered(dev)) {
		device_release_driver(dev);
	} else {
		down(&dev->sem);
		usb_unbind_interface(dev);
		dev->driver = NULL;
		up(&dev->sem);
	}
}