Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4bdb3550 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki Committed by Greg Kroah-Hartman
Browse files

driver core: Add a wrapper around __device_release_driver()



Add an internal wrapper around __device_release_driver() that will
acquire device locks and do the necessary checks before calling it.

The next patch will make use of it.

Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 7f847dd3
Loading
Loading
Loading
Loading
+18 −12
Original line number Original line Diff line number Diff line
@@ -811,6 +811,22 @@ static void __device_release_driver(struct device *dev)
	}
	}
}
}


static void device_release_driver_internal(struct device *dev,
					   struct device_driver *drv,
					   struct device *parent)
{
	if (parent)
		device_lock(parent);

	device_lock(dev);
	if (!drv || drv == dev->driver)
		__device_release_driver(dev);

	device_unlock(dev);
	if (parent)
		device_unlock(parent);
}

/**
/**
 * device_release_driver - manually detach device from driver.
 * device_release_driver - manually detach device from driver.
 * @dev: device.
 * @dev: device.
@@ -825,9 +841,7 @@ void device_release_driver(struct device *dev)
	 * within their ->remove callback for the same device, they
	 * within their ->remove callback for the same device, they
	 * will deadlock right here.
	 * will deadlock right here.
	 */
	 */
	device_lock(dev);
	device_release_driver_internal(dev, NULL, NULL);
	__device_release_driver(dev);
	device_unlock(dev);
}
}
EXPORT_SYMBOL_GPL(device_release_driver);
EXPORT_SYMBOL_GPL(device_release_driver);


@@ -852,15 +866,7 @@ void driver_detach(struct device_driver *drv)
		dev = dev_prv->device;
		dev = dev_prv->device;
		get_device(dev);
		get_device(dev);
		spin_unlock(&drv->p->klist_devices.k_lock);
		spin_unlock(&drv->p->klist_devices.k_lock);

		device_release_driver_internal(dev, drv, dev->parent);
		if (dev->parent)	/* Needed for USB */
			device_lock(dev->parent);
		device_lock(dev);
		if (dev->driver == drv)
			__device_release_driver(dev);
		device_unlock(dev);
		if (dev->parent)
			device_unlock(dev->parent);
		put_device(dev);
		put_device(dev);
	}
	}
}
}