aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/dd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/dd.c')
-rw-r--r--drivers/base/dd.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index dcb8a6e48692..e3bbed8a617c 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -85,8 +85,20 @@ static void deferred_probe_work_func(struct work_struct *work)
85 * manipulate the deferred list 85 * manipulate the deferred list
86 */ 86 */
87 mutex_unlock(&deferred_probe_mutex); 87 mutex_unlock(&deferred_probe_mutex);
88
89 /*
90 * Force the device to the end of the dpm_list since
91 * the PM code assumes that the order we add things to
92 * the list is a good order for suspend but deferred
93 * probe makes that very unsafe.
94 */
95 device_pm_lock();
96 device_pm_move_last(dev);
97 device_pm_unlock();
98
88 dev_dbg(dev, "Retrying from deferred list\n"); 99 dev_dbg(dev, "Retrying from deferred list\n");
89 bus_probe_device(dev); 100 bus_probe_device(dev);
101
90 mutex_lock(&deferred_probe_mutex); 102 mutex_lock(&deferred_probe_mutex);
91 103
92 put_device(dev); 104 put_device(dev);
@@ -283,6 +295,7 @@ probe_failed:
283 devres_release_all(dev); 295 devres_release_all(dev);
284 driver_sysfs_remove(dev); 296 driver_sysfs_remove(dev);
285 dev->driver = NULL; 297 dev->driver = NULL;
298 dev_set_drvdata(dev, NULL);
286 299
287 if (ret == -EPROBE_DEFER) { 300 if (ret == -EPROBE_DEFER) {
288 /* Driver requested deferred probing */ 301 /* Driver requested deferred probing */
@@ -356,10 +369,9 @@ int driver_probe_device(struct device_driver *drv, struct device *dev)
356 pr_debug("bus: '%s': %s: matched device %s with driver %s\n", 369 pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
357 drv->bus->name, __func__, dev_name(dev), drv->name); 370 drv->bus->name, __func__, dev_name(dev), drv->name);
358 371
359 pm_runtime_get_noresume(dev);
360 pm_runtime_barrier(dev); 372 pm_runtime_barrier(dev);
361 ret = really_probe(dev, drv); 373 ret = really_probe(dev, drv);
362 pm_runtime_put_sync(dev); 374 pm_runtime_idle(dev);
363 375
364 return ret; 376 return ret;
365} 377}
@@ -406,9 +418,8 @@ int device_attach(struct device *dev)
406 ret = 0; 418 ret = 0;
407 } 419 }
408 } else { 420 } else {
409 pm_runtime_get_noresume(dev);
410 ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); 421 ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
411 pm_runtime_put_sync(dev); 422 pm_runtime_idle(dev);
412 } 423 }
413out_unlock: 424out_unlock:
414 device_unlock(dev); 425 device_unlock(dev);
@@ -487,6 +498,7 @@ static void __device_release_driver(struct device *dev)
487 drv->remove(dev); 498 drv->remove(dev);
488 devres_release_all(dev); 499 devres_release_all(dev);
489 dev->driver = NULL; 500 dev->driver = NULL;
501 dev_set_drvdata(dev, NULL);
490 klist_remove(&dev->p->knode_driver); 502 klist_remove(&dev->p->knode_driver);
491 if (dev->bus) 503 if (dev->bus)
492 blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 504 blocking_notifier_call_chain(&dev->bus->p->bus_notifier,