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@xxxxxxxxxxxx> --- drivers/media/v4l2-core/v4l2-async.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) 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(¬ifier->list); list_for_each_entry_safe(sd, tmp, ¬ifier->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) { -- 2.13.1