aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2018-01-14 19:34:17 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2018-01-14 19:34:17 -0500
commit46fa233acf875254668016204cb73136ec6bf71e (patch)
tree9d13e433d237fc15a20b431882483ae8630bccb4
parent0026cef067d2962ed064b974e07f017233d5bd5a (diff)
parent17218e0092f8c7b7edce7ff08c8b23212eac7271 (diff)
Merge generic power domains (genpd) material for v4.16 into pm-core
-rw-r--r--drivers/base/power/domain.c69
1 files changed, 33 insertions, 36 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 0c80bea05bcb..528b24149bc7 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1032,15 +1032,12 @@ static int genpd_prepare(struct device *dev)
1032static int genpd_finish_suspend(struct device *dev, bool poweroff) 1032static int genpd_finish_suspend(struct device *dev, bool poweroff)
1033{ 1033{
1034 struct generic_pm_domain *genpd; 1034 struct generic_pm_domain *genpd;
1035 int ret; 1035 int ret = 0;
1036 1036
1037 genpd = dev_to_genpd(dev); 1037 genpd = dev_to_genpd(dev);
1038 if (IS_ERR(genpd)) 1038 if (IS_ERR(genpd))
1039 return -EINVAL; 1039 return -EINVAL;
1040 1040
1041 if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd))
1042 return 0;
1043
1044 if (poweroff) 1041 if (poweroff)
1045 ret = pm_generic_poweroff_noirq(dev); 1042 ret = pm_generic_poweroff_noirq(dev);
1046 else 1043 else
@@ -1048,10 +1045,19 @@ static int genpd_finish_suspend(struct device *dev, bool poweroff)
1048 if (ret) 1045 if (ret)
1049 return ret; 1046 return ret;
1050 1047
1051 if (genpd->dev_ops.stop && genpd->dev_ops.start) { 1048 if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd))
1052 ret = pm_runtime_force_suspend(dev); 1049 return 0;
1053 if (ret) 1050
1051 if (genpd->dev_ops.stop && genpd->dev_ops.start &&
1052 !pm_runtime_status_suspended(dev)) {
1053 ret = genpd_stop_dev(genpd, dev);
1054 if (ret) {
1055 if (poweroff)
1056 pm_generic_restore_noirq(dev);
1057 else
1058 pm_generic_resume_noirq(dev);
1054 return ret; 1059 return ret;
1060 }
1055 } 1061 }
1056 1062
1057 genpd_lock(genpd); 1063 genpd_lock(genpd);
@@ -1085,7 +1091,7 @@ static int genpd_suspend_noirq(struct device *dev)
1085static int genpd_resume_noirq(struct device *dev) 1091static int genpd_resume_noirq(struct device *dev)
1086{ 1092{
1087 struct generic_pm_domain *genpd; 1093 struct generic_pm_domain *genpd;
1088 int ret = 0; 1094 int ret;
1089 1095
1090 dev_dbg(dev, "%s()\n", __func__); 1096 dev_dbg(dev, "%s()\n", __func__);
1091 1097
@@ -1094,21 +1100,21 @@ static int genpd_resume_noirq(struct device *dev)
1094 return -EINVAL; 1100 return -EINVAL;
1095 1101
1096 if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd)) 1102 if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd))
1097 return 0; 1103 return pm_generic_resume_noirq(dev);
1098 1104
1099 genpd_lock(genpd); 1105 genpd_lock(genpd);
1100 genpd_sync_power_on(genpd, true, 0); 1106 genpd_sync_power_on(genpd, true, 0);
1101 genpd->suspended_count--; 1107 genpd->suspended_count--;
1102 genpd_unlock(genpd); 1108 genpd_unlock(genpd);
1103 1109
1104 if (genpd->dev_ops.stop && genpd->dev_ops.start) 1110 if (genpd->dev_ops.stop && genpd->dev_ops.start &&
1105 ret = pm_runtime_force_resume(dev); 1111 !pm_runtime_status_suspended(dev)) {
1106 1112 ret = genpd_start_dev(genpd, dev);
1107 ret = pm_generic_resume_noirq(dev); 1113 if (ret)
1108 if (ret) 1114 return ret;
1109 return ret; 1115 }
1110 1116
1111 return ret; 1117 return pm_generic_resume_noirq(dev);
1112} 1118}
1113 1119
1114/** 1120/**
@@ -1135,8 +1141,9 @@ static int genpd_freeze_noirq(struct device *dev)
1135 if (ret) 1141 if (ret)
1136 return ret; 1142 return ret;
1137 1143
1138 if (genpd->dev_ops.stop && genpd->dev_ops.start) 1144 if (genpd->dev_ops.stop && genpd->dev_ops.start &&
1139 ret = pm_runtime_force_suspend(dev); 1145 !pm_runtime_status_suspended(dev))
1146 ret = genpd_stop_dev(genpd, dev);
1140 1147
1141 return ret; 1148 return ret;
1142} 1149}
@@ -1159,8 +1166,9 @@ static int genpd_thaw_noirq(struct device *dev)
1159 if (IS_ERR(genpd)) 1166 if (IS_ERR(genpd))
1160 return -EINVAL; 1167 return -EINVAL;
1161 1168
1162 if (genpd->dev_ops.stop && genpd->dev_ops.start) { 1169 if (genpd->dev_ops.stop && genpd->dev_ops.start &&
1163 ret = pm_runtime_force_resume(dev); 1170 !pm_runtime_status_suspended(dev)) {
1171 ret = genpd_start_dev(genpd, dev);
1164 if (ret) 1172 if (ret)
1165 return ret; 1173 return ret;
1166 } 1174 }
@@ -1217,8 +1225,9 @@ static int genpd_restore_noirq(struct device *dev)
1217 genpd_sync_power_on(genpd, true, 0); 1225 genpd_sync_power_on(genpd, true, 0);
1218 genpd_unlock(genpd); 1226 genpd_unlock(genpd);
1219 1227
1220 if (genpd->dev_ops.stop && genpd->dev_ops.start) { 1228 if (genpd->dev_ops.stop && genpd->dev_ops.start &&
1221 ret = pm_runtime_force_resume(dev); 1229 !pm_runtime_status_suspended(dev)) {
1230 ret = genpd_start_dev(genpd, dev);
1222 if (ret) 1231 if (ret)
1223 return ret; 1232 return ret;
1224 } 1233 }
@@ -2199,20 +2208,8 @@ int genpd_dev_pm_attach(struct device *dev)
2199 2208
2200 ret = of_parse_phandle_with_args(dev->of_node, "power-domains", 2209 ret = of_parse_phandle_with_args(dev->of_node, "power-domains",
2201 "#power-domain-cells", 0, &pd_args); 2210 "#power-domain-cells", 0, &pd_args);
2202 if (ret < 0) { 2211 if (ret < 0)
2203 if (ret != -ENOENT) 2212 return ret;
2204 return ret;
2205
2206 /*
2207 * Try legacy Samsung-specific bindings
2208 * (for backwards compatibility of DT ABI)
2209 */
2210 pd_args.args_count = 0;
2211 pd_args.np = of_parse_phandle(dev->of_node,
2212 "samsung,power-domain", 0);
2213 if (!pd_args.np)
2214 return -ENOENT;
2215 }
2216 2213
2217 mutex_lock(&gpd_list_lock); 2214 mutex_lock(&gpd_list_lock);
2218 pd = genpd_get_from_provider(&pd_args); 2215 pd = genpd_get_from_provider(&pd_args);