Skip to content

Commit ddef08d

Browse files
rafaeljwLee Jones
authored and
Lee Jones
committed
Driver core: wakeup the parent device before trying probe
If the parent is still suspended when driver probe is attempted, the result may be failure. For example, if the parent is a PCI MFD device that has been suspended when we try to probe our device, any register reads will return 0xffffffff. To fix the problem, making sure the parent is always awake before attempting driver probe. Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Lee Jones <lee.jones@linaro.org>
1 parent 712e960 commit ddef08d

File tree

1 file changed

+20
-0
lines changed

1 file changed

+20
-0
lines changed

drivers/base/dd.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,8 @@ EXPORT_SYMBOL_GPL(wait_for_device_probe);
399399
*
400400
* This function must be called with @dev lock held. When called for a
401401
* USB interface, @dev->parent lock must be held as well.
402+
*
403+
* If the device has a parent, runtime-resume the parent before driver probing.
402404
*/
403405
int driver_probe_device(struct device_driver *drv, struct device *dev)
404406
{
@@ -410,10 +412,16 @@ int driver_probe_device(struct device_driver *drv, struct device *dev)
410412
pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
411413
drv->bus->name, __func__, dev_name(dev), drv->name);
412414

415+
if (dev->parent)
416+
pm_runtime_get_sync(dev->parent);
417+
413418
pm_runtime_barrier(dev);
414419
ret = really_probe(dev, drv);
415420
pm_request_idle(dev);
416421

422+
if (dev->parent)
423+
pm_runtime_put(dev->parent);
424+
417425
return ret;
418426
}
419427

@@ -507,11 +515,17 @@ static void __device_attach_async_helper(void *_dev, async_cookie_t cookie)
507515

508516
device_lock(dev);
509517

518+
if (dev->parent)
519+
pm_runtime_get_sync(dev->parent);
520+
510521
bus_for_each_drv(dev->bus, NULL, &data, __device_attach_driver);
511522
dev_dbg(dev, "async probe completed\n");
512523

513524
pm_request_idle(dev);
514525

526+
if (dev->parent)
527+
pm_runtime_put(dev->parent);
528+
515529
device_unlock(dev);
516530

517531
put_device(dev);
@@ -541,6 +555,9 @@ static int __device_attach(struct device *dev, bool allow_async)
541555
.want_async = false,
542556
};
543557

558+
if (dev->parent)
559+
pm_runtime_get_sync(dev->parent);
560+
544561
ret = bus_for_each_drv(dev->bus, NULL, &data,
545562
__device_attach_driver);
546563
if (!ret && allow_async && data.have_async) {
@@ -557,6 +574,9 @@ static int __device_attach(struct device *dev, bool allow_async)
557574
} else {
558575
pm_request_idle(dev);
559576
}
577+
578+
if (dev->parent)
579+
pm_runtime_put(dev->parent);
560580
}
561581
out_unlock:
562582
device_unlock(dev);

0 commit comments

Comments
 (0)