/* driver_detach - detach driver from all devices it controls. @drv: driver.  */
void driver_detach(struct device_driver *drv)
/* driver_detach - detach driver from all devices it controls. @drv: driver.  */
void driver_detach(struct device_driver *drv)
{
	struct device_private *dev_prv;
	struct device *dev;
	for (;;) {
		spin_lock(&drv->p->klist_devices.k_lock);
		if (list_empty(&drv->p->klist_devices.k_list)) {
			spin_unlock(&drv->p->klist_devices.k_lock);
			break;
		}
		dev_prv = list_entry(drv->p->klist_devices.k_list.prev,
				     struct device_private,
				     knode_driver.n_node);
		dev = dev_prv->device;
		get_device(dev);
		spin_unlock(&drv->p->klist_devices.k_lock);
		if (dev->parent)
			down(&dev->parent->sem);
		down(&dev->sem);
		if (dev->driver == drv)
			__device_release_driver(dev);
		up(&dev->sem);
		if (dev->parent)
			up(&dev->parent->sem);
		put_device(dev);
	}
}