diff mbox

[v4,3/8] Driver core: wakeup the parent device before trying probe

Message ID 1434362256-239992-4-git-send-email-andriy.shevchenko@linux.intel.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Andy Shevchenko June 15, 2015, 9:57 a.m. UTC
From: "Rafael J. Wysocki" <rjw@rjwysocki.net>

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 <rjw@rjwysocki.net>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/base/dd.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

Comments

Rafael J. Wysocki June 15, 2015, 11:50 a.m. UTC | #1
On Mon, Jun 15, 2015 at 11:57 AM, Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
> From: "Rafael J. Wysocki" <rjw@rjwysocki.net>
>
> 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 <rjw@rjwysocki.net>

Please use my Intel sign-off with this one:

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
>  drivers/base/dd.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
>
> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
> index e843fdb..c4c1eaf 100644
> --- a/drivers/base/dd.c
> +++ b/drivers/base/dd.c
> @@ -399,6 +399,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)
>  {
> @@ -410,10 +412,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;
>  }
>
> @@ -459,8 +467,14 @@ int device_attach(struct device *dev)
>                         ret = 0;
>                 }
>         } else {
> +               if (dev->parent)
> +                       pm_runtime_get_sync(dev->parent);
> +
>                 ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
>                 pm_request_idle(dev);
> +
> +               if (dev->parent)
> +                       pm_runtime_put(dev->parent);
>         }
>  out_unlock:
>         device_unlock(dev);
> --
> 2.1.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index e843fdb..c4c1eaf 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -399,6 +399,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)
 {
@@ -410,10 +412,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;
 }
 
@@ -459,8 +467,14 @@  int device_attach(struct device *dev)
 			ret = 0;
 		}
 	} else {
+		if (dev->parent)
+			pm_runtime_get_sync(dev->parent);
+
 		ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
 		pm_request_idle(dev);
+
+		if (dev->parent)
+			pm_runtime_put(dev->parent);
 	}
 out_unlock:
 	device_unlock(dev);