diff --git a/drivers/base/dd.c b/drivers/base/dd.c index d76cd97a98b6ba..a90224eab2b242 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -51,6 +51,7 @@ static DEFINE_MUTEX(deferred_probe_mutex); static LIST_HEAD(deferred_probe_pending_list); static LIST_HEAD(deferred_probe_active_list); +static struct workqueue_struct *deferred_wq; static atomic_t deferred_trigger_count = ATOMIC_INIT(0); /* @@ -174,7 +175,7 @@ static void driver_deferred_probe_trigger(void) * Kick the re-probe thread. It may already be scheduled, but it is * safe to kick it again. */ - schedule_work(&deferred_probe_work); + queue_work(deferred_wq, &deferred_probe_work); } /** @@ -210,10 +211,14 @@ void device_unblock_probing(void) */ static int deferred_probe_initcall(void) { + deferred_wq = create_singlethread_workqueue("deferwq"); + if (WARN_ON(!deferred_wq)) + return -ENOMEM; + driver_deferred_probe_enable = true; driver_deferred_probe_trigger(); /* Sort as many dependencies as possible before exiting initcalls */ - flush_work(&deferred_probe_work); + flush_workqueue(deferred_wq); return 0; } late_initcall(deferred_probe_initcall); @@ -477,7 +482,8 @@ int driver_probe_done(void) void wait_for_device_probe(void) { /* wait for the deferred probe workqueue to finish */ - flush_work(&deferred_probe_work); + if (driver_deferred_probe_enable) + flush_workqueue(deferred_wq); /* wait for the known devices to complete their probing */ wait_event(probe_waitqueue, atomic_read(&probe_count) == 0);