]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/base/dd.c
Merge branch 'ras-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[karo-tx-linux.git] / drivers / base / dd.c
index cc2b1d4801fd52c5117495fd10e2e48f0656d4a0..a641cf3ccad691e76d9665e9defab4ef04e9af4f 100644 (file)
@@ -322,6 +322,8 @@ static int really_probe(struct device *dev, struct device_driver *drv)
                        goto probe_failed;
        }
 
+       pinctrl_init_done(dev);
+
        if (dev->pm_domain && dev->pm_domain->sync)
                dev->pm_domain->sync(dev);
 
@@ -407,6 +409,8 @@ EXPORT_SYMBOL_GPL(wait_for_device_probe);
  *
  * This function must be called with @dev lock held.  When called for a
  * USB interface, @dev->parent lock must be held as well.
+ *
+ * If the device has a parent, runtime-resume the parent before driver probing.
  */
 int driver_probe_device(struct device_driver *drv, struct device *dev)
 {
@@ -418,10 +422,16 @@ int driver_probe_device(struct device_driver *drv, struct device *dev)
        pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
                 drv->bus->name, __func__, dev_name(dev), drv->name);
 
+       if (dev->parent)
+               pm_runtime_get_sync(dev->parent);
+
        pm_runtime_barrier(dev);
        ret = really_probe(dev, drv);
        pm_request_idle(dev);
 
+       if (dev->parent)
+               pm_runtime_put(dev->parent);
+
        return ret;
 }
 
@@ -515,11 +525,17 @@ static void __device_attach_async_helper(void *_dev, async_cookie_t cookie)
 
        device_lock(dev);
 
+       if (dev->parent)
+               pm_runtime_get_sync(dev->parent);
+
        bus_for_each_drv(dev->bus, NULL, &data, __device_attach_driver);
        dev_dbg(dev, "async probe completed\n");
 
        pm_request_idle(dev);
 
+       if (dev->parent)
+               pm_runtime_put(dev->parent);
+
        device_unlock(dev);
 
        put_device(dev);
@@ -549,6 +565,9 @@ static int __device_attach(struct device *dev, bool allow_async)
                        .want_async = false,
                };
 
+               if (dev->parent)
+                       pm_runtime_get_sync(dev->parent);
+
                ret = bus_for_each_drv(dev->bus, NULL, &data,
                                        __device_attach_driver);
                if (!ret && allow_async && data.have_async) {
@@ -565,6 +584,9 @@ static int __device_attach(struct device *dev, bool allow_async)
                } else {
                        pm_request_idle(dev);
                }
+
+               if (dev->parent)
+                       pm_runtime_put(dev->parent);
        }
 out_unlock:
        device_unlock(dev);