diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2018-01-14 19:34:17 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2018-01-14 19:34:17 -0500 |
commit | 46fa233acf875254668016204cb73136ec6bf71e (patch) | |
tree | 9d13e433d237fc15a20b431882483ae8630bccb4 | |
parent | 0026cef067d2962ed064b974e07f017233d5bd5a (diff) | |
parent | 17218e0092f8c7b7edce7ff08c8b23212eac7271 (diff) |
Merge generic power domains (genpd) material for v4.16 into pm-core
-rw-r--r-- | drivers/base/power/domain.c | 69 |
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) | |||
1032 | static int genpd_finish_suspend(struct device *dev, bool poweroff) | 1032 | static 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) | |||
1085 | static int genpd_resume_noirq(struct device *dev) | 1091 | static 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); |