/* __device_release_driver() must be called with @dev->sem held. When called for a USB interface, @dev->parent->sem must be held as well.  */
static void __device_release_driver(struct device *dev)
/* __device_release_driver() must be called with @dev->sem held. When called for a USB interface, @dev->parent->sem must be held as well.  */
static void __device_release_driver(struct device *dev)
{
	struct device_driver *drv;
	drv = dev->driver;
	if (drv) {
		pm_runtime_get_noresume(dev);
		pm_runtime_barrier(dev);
		driver_sysfs_remove(dev);
		if (dev->bus)
			blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
						     BUS_NOTIFY_UNBIND_DRIVER,
						     dev);
		if (dev->bus && dev->bus->remove)
			dev->bus->remove(dev);
		else if (drv->remove)
			drv->remove(dev);
		devres_release_all(dev);
		dev->driver = NULL;
		klist_remove(&dev->p->knode_driver);
		if (dev->bus)
			blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
						     BUS_NOTIFY_UNBOUND_DRIVER,
						     dev);
		pm_runtime_put_sync(dev);
	}
}