Browse Source

Merge generic power domains (genpd) material for v4.16 into pm-core

Rafael J. Wysocki 7 years ago
parent
commit
46fa233acf
1 changed files with 33 additions and 36 deletions
  1. 33 36
      drivers/base/power/domain.c

+ 33 - 36
drivers/base/power/domain.c

@@ -1032,15 +1032,12 @@ static int genpd_prepare(struct device *dev)
 static int genpd_finish_suspend(struct device *dev, bool poweroff)
 static int genpd_finish_suspend(struct device *dev, bool poweroff)
 {
 {
 	struct generic_pm_domain *genpd;
 	struct generic_pm_domain *genpd;
-	int ret;
+	int ret = 0;
 
 
 	genpd = dev_to_genpd(dev);
 	genpd = dev_to_genpd(dev);
 	if (IS_ERR(genpd))
 	if (IS_ERR(genpd))
 		return -EINVAL;
 		return -EINVAL;
 
 
-	if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd))
-		return 0;
-
 	if (poweroff)
 	if (poweroff)
 		ret = pm_generic_poweroff_noirq(dev);
 		ret = pm_generic_poweroff_noirq(dev);
 	else
 	else
@@ -1048,10 +1045,19 @@ static int genpd_finish_suspend(struct device *dev, bool poweroff)
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
-	if (genpd->dev_ops.stop && genpd->dev_ops.start) {
-		ret = pm_runtime_force_suspend(dev);
-		if (ret)
+	if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd))
+		return 0;
+
+	if (genpd->dev_ops.stop && genpd->dev_ops.start &&
+	    !pm_runtime_status_suspended(dev)) {
+		ret = genpd_stop_dev(genpd, dev);
+		if (ret) {
+			if (poweroff)
+				pm_generic_restore_noirq(dev);
+			else
+				pm_generic_resume_noirq(dev);
 			return ret;
 			return ret;
+		}
 	}
 	}
 
 
 	genpd_lock(genpd);
 	genpd_lock(genpd);
@@ -1085,7 +1091,7 @@ static int genpd_suspend_noirq(struct device *dev)
 static int genpd_resume_noirq(struct device *dev)
 static int genpd_resume_noirq(struct device *dev)
 {
 {
 	struct generic_pm_domain *genpd;
 	struct generic_pm_domain *genpd;
-	int ret = 0;
+	int ret;
 
 
 	dev_dbg(dev, "%s()\n", __func__);
 	dev_dbg(dev, "%s()\n", __func__);
 
 
@@ -1094,21 +1100,21 @@ static int genpd_resume_noirq(struct device *dev)
 		return -EINVAL;
 		return -EINVAL;
 
 
 	if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd))
 	if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd))
-		return 0;
+		return pm_generic_resume_noirq(dev);
 
 
 	genpd_lock(genpd);
 	genpd_lock(genpd);
 	genpd_sync_power_on(genpd, true, 0);
 	genpd_sync_power_on(genpd, true, 0);
 	genpd->suspended_count--;
 	genpd->suspended_count--;
 	genpd_unlock(genpd);
 	genpd_unlock(genpd);
 
 
-	if (genpd->dev_ops.stop && genpd->dev_ops.start)
-		ret = pm_runtime_force_resume(dev);
-
-	ret = pm_generic_resume_noirq(dev);
-	if (ret)
-		return ret;
+	if (genpd->dev_ops.stop && genpd->dev_ops.start &&
+	    !pm_runtime_status_suspended(dev)) {
+		ret = genpd_start_dev(genpd, dev);
+		if (ret)
+			return ret;
+	}
 
 
-	return ret;
+	return pm_generic_resume_noirq(dev);
 }
 }
 
 
 /**
 /**
@@ -1135,8 +1141,9 @@ static int genpd_freeze_noirq(struct device *dev)
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
-	if (genpd->dev_ops.stop && genpd->dev_ops.start)
-		ret = pm_runtime_force_suspend(dev);
+	if (genpd->dev_ops.stop && genpd->dev_ops.start &&
+	    !pm_runtime_status_suspended(dev))
+		ret = genpd_stop_dev(genpd, dev);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -1159,8 +1166,9 @@ static int genpd_thaw_noirq(struct device *dev)
 	if (IS_ERR(genpd))
 	if (IS_ERR(genpd))
 		return -EINVAL;
 		return -EINVAL;
 
 
-	if (genpd->dev_ops.stop && genpd->dev_ops.start) {
-		ret = pm_runtime_force_resume(dev);
+	if (genpd->dev_ops.stop && genpd->dev_ops.start &&
+	    !pm_runtime_status_suspended(dev)) {
+		ret = genpd_start_dev(genpd, dev);
 		if (ret)
 		if (ret)
 			return ret;
 			return ret;
 	}
 	}
@@ -1217,8 +1225,9 @@ static int genpd_restore_noirq(struct device *dev)
 	genpd_sync_power_on(genpd, true, 0);
 	genpd_sync_power_on(genpd, true, 0);
 	genpd_unlock(genpd);
 	genpd_unlock(genpd);
 
 
-	if (genpd->dev_ops.stop && genpd->dev_ops.start) {
-		ret = pm_runtime_force_resume(dev);
+	if (genpd->dev_ops.stop && genpd->dev_ops.start &&
+	    !pm_runtime_status_suspended(dev)) {
+		ret = genpd_start_dev(genpd, dev);
 		if (ret)
 		if (ret)
 			return ret;
 			return ret;
 	}
 	}
@@ -2199,20 +2208,8 @@ int genpd_dev_pm_attach(struct device *dev)
 
 
 	ret = of_parse_phandle_with_args(dev->of_node, "power-domains",
 	ret = of_parse_phandle_with_args(dev->of_node, "power-domains",
 					"#power-domain-cells", 0, &pd_args);
 					"#power-domain-cells", 0, &pd_args);
-	if (ret < 0) {
-		if (ret != -ENOENT)
-			return ret;
-
-		/*
-		 * Try legacy Samsung-specific bindings
-		 * (for backwards compatibility of DT ABI)
-		 */
-		pd_args.args_count = 0;
-		pd_args.np = of_parse_phandle(dev->of_node,
-						"samsung,power-domain", 0);
-		if (!pd_args.np)
-			return -ENOENT;
-	}
+	if (ret < 0)
+		return ret;
 
 
 	mutex_lock(&gpd_list_lock);
 	mutex_lock(&gpd_list_lock);
 	pd = genpd_get_from_provider(&pd_args);
 	pd = genpd_get_from_provider(&pd_args);