--- drivers/base/power/main.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) Index: linux-pm/drivers/base/power/main.c =================================================================== --- linux-pm.orig/drivers/base/power/main.c +++ linux-pm/drivers/base/power/main.c @@ -127,6 +127,8 @@ void device_pm_unlock(void) */ void device_pm_add(struct device *dev) { + struct device *ancestor; + /* Skip PM setup/initialization. */ if (device_pm_not_required(dev)) return; @@ -134,12 +136,20 @@ void device_pm_add(struct device *dev) pr_debug("Adding info for %s:%s\n", dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); device_pm_check_callbacks(dev); + mutex_lock(&dpm_list_mtx); - if (dev->parent && dev->parent->power.is_prepared) - dev_warn(dev, "parent %s should not be sleeping\n", - dev_name(dev->parent)); + + ancestor = dev->parent; + while (ancestor && ancestor->power.no_pm_callbacks) + ancestor = ancestor->parent; + + if (ancestor && ancestor->power.is_prepared) + dev_warn(dev, "ancestor %s should not be sleeping\n", + dev_name(ancestor)); + list_add_tail(&dev->power.entry, &dpm_list); dev->power.in_dpm_list = true; + mutex_unlock(&dpm_list_mtx); }