diff mbox

[3/4] v4l: async: do not hold list_lock when re-probing devices

Message ID 20170730223158.14405-4-niklas.soderlund+renesas@ragnatech.se (mailing list archive)
State New, archived
Headers show

Commit Message

Niklas Söderlund July 30, 2017, 10:31 p.m. UTC
There is no good reason to hold the list_lock when re-probing the
devices and it prevents a clean implementation of subdevice notifiers.
Move the actual release of the devices outside of the loop which
requires the lock to be held.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/v4l2-core/v4l2-async.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)
diff mbox

Patch

diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index 67852f0f2d3000c9..d91ff0a33fd3eaff 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -206,7 +206,7 @@  void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
 	unsigned int notif_n_subdev = notifier->num_subdevs;
 	unsigned int n_subdev = min(notif_n_subdev, V4L2_MAX_SUBDEVS);
 	struct device **dev;
-	int i = 0;
+	int i, count = 0;
 
 	if (!notifier->v4l2_dev)
 		return;
@@ -223,27 +223,26 @@  void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
 	list_del(&notifier->list);
 
 	list_for_each_entry_safe(sd, tmp, &notifier->done, async_list) {
-		struct device *d;
-
-		d = get_device(sd->dev);
+		dev[count] = get_device(sd->dev);
+		count++;
 
 		if (notifier->unbind)
 			notifier->unbind(notifier, sd, sd->asd);
 
 		v4l2_async_cleanup(sd);
-
-		/* If we handled USB devices, we'd have to lock the parent too */
-		device_release_driver(d);
-
-		dev[i++] = d;
 	}
 
 	mutex_unlock(&list_lock);
 
+	for (i = 0; i < count; i++) {
+		/* If we handled USB devices, we'd have to lock the parent too */
+		device_release_driver(dev[i]);
+	}
+
 	/*
 	 * Call device_attach() to reprobe devices
 	 */
-	while (i--) {
+	for (i = 0; i < count; i++) {
 		struct device *d = dev[i];
 
 		if (d && device_attach(d) < 0) {