aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-11-17 19:21:39 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-11-17 19:21:39 -0500
commit2e015da0d5f756c1b8a06158700238022671168b (patch)
tree69078c28231a4b5f5ce4cf3dda9c73174fcc4ff7 /drivers/base
parentfc14f9c1272f62c3e8d01300f52467c0d9af50f9 (diff)
parent00e7c295968d74f4dbb00aef8334fafe788e3c89 (diff)
Merge back 'pm-domains' material for 3.19-rc1.
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/power/domain.c105
1 files changed, 62 insertions, 43 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index fb83d4acd400..3989eb63d538 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -151,6 +151,59 @@ static void genpd_recalc_cpu_exit_latency(struct generic_pm_domain *genpd)
151 genpd->cpuidle_data->idle_state->exit_latency = usecs64; 151 genpd->cpuidle_data->idle_state->exit_latency = usecs64;
152} 152}
153 153
154static int genpd_power_on(struct generic_pm_domain *genpd)
155{
156 ktime_t time_start;
157 s64 elapsed_ns;
158 int ret;
159
160 if (!genpd->power_on)
161 return 0;
162
163 time_start = ktime_get();
164 ret = genpd->power_on(genpd);
165 if (ret)
166 return ret;
167
168 elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
169 if (elapsed_ns <= genpd->power_on_latency_ns)
170 return ret;
171
172 genpd->power_on_latency_ns = elapsed_ns;
173 genpd->max_off_time_changed = true;
174 genpd_recalc_cpu_exit_latency(genpd);
175 pr_warn("%s: Power-%s latency exceeded, new value %lld ns\n",
176 genpd->name, "on", elapsed_ns);
177
178 return ret;
179}
180
181static int genpd_power_off(struct generic_pm_domain *genpd)
182{
183 ktime_t time_start;
184 s64 elapsed_ns;
185 int ret;
186
187 if (!genpd->power_off)
188 return 0;
189
190 time_start = ktime_get();
191 ret = genpd->power_off(genpd);
192 if (ret == -EBUSY)
193 return ret;
194
195 elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
196 if (elapsed_ns <= genpd->power_off_latency_ns)
197 return ret;
198
199 genpd->power_off_latency_ns = elapsed_ns;
200 genpd->max_off_time_changed = true;
201 pr_warn("%s: Power-%s latency exceeded, new value %lld ns\n",
202 genpd->name, "off", elapsed_ns);
203
204 return ret;
205}
206
154/** 207/**
155 * __pm_genpd_poweron - Restore power to a given PM domain and its masters. 208 * __pm_genpd_poweron - Restore power to a given PM domain and its masters.
156 * @genpd: PM domain to power up. 209 * @genpd: PM domain to power up.
@@ -222,25 +275,9 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd)
222 } 275 }
223 } 276 }
224 277
225 if (genpd->power_on) { 278 ret = genpd_power_on(genpd);
226 ktime_t time_start = ktime_get(); 279 if (ret)
227 s64 elapsed_ns; 280 goto err;
228
229 ret = genpd->power_on(genpd);
230 if (ret)
231 goto err;
232
233 elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
234 if (elapsed_ns > genpd->power_on_latency_ns) {
235 genpd->power_on_latency_ns = elapsed_ns;
236 genpd->max_off_time_changed = true;
237 genpd_recalc_cpu_exit_latency(genpd);
238 if (genpd->name)
239 pr_warning("%s: Power-on latency exceeded, "
240 "new value %lld ns\n", genpd->name,
241 elapsed_ns);
242 }
243 }
244 281
245 out: 282 out:
246 genpd_set_active(genpd); 283 genpd_set_active(genpd);
@@ -544,16 +581,11 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
544 } 581 }
545 582
546 if (genpd->power_off) { 583 if (genpd->power_off) {
547 ktime_t time_start;
548 s64 elapsed_ns;
549
550 if (atomic_read(&genpd->sd_count) > 0) { 584 if (atomic_read(&genpd->sd_count) > 0) {
551 ret = -EBUSY; 585 ret = -EBUSY;
552 goto out; 586 goto out;
553 } 587 }
554 588
555 time_start = ktime_get();
556
557 /* 589 /*
558 * If sd_count > 0 at this point, one of the subdomains hasn't 590 * If sd_count > 0 at this point, one of the subdomains hasn't
559 * managed to call pm_genpd_poweron() for the master yet after 591 * managed to call pm_genpd_poweron() for the master yet after
@@ -562,21 +594,11 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
562 * the pm_genpd_poweron() restore power for us (this shouldn't 594 * the pm_genpd_poweron() restore power for us (this shouldn't
563 * happen very often). 595 * happen very often).
564 */ 596 */
565 ret = genpd->power_off(genpd); 597 ret = genpd_power_off(genpd);
566 if (ret == -EBUSY) { 598 if (ret == -EBUSY) {
567 genpd_set_active(genpd); 599 genpd_set_active(genpd);
568 goto out; 600 goto out;
569 } 601 }
570
571 elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
572 if (elapsed_ns > genpd->power_off_latency_ns) {
573 genpd->power_off_latency_ns = elapsed_ns;
574 genpd->max_off_time_changed = true;
575 if (genpd->name)
576 pr_warning("%s: Power-off latency exceeded, "
577 "new value %lld ns\n", genpd->name,
578 elapsed_ns);
579 }
580 } 602 }
581 603
582 genpd->status = GPD_STATE_POWER_OFF; 604 genpd->status = GPD_STATE_POWER_OFF;
@@ -779,9 +801,9 @@ static inline void genpd_power_off_work_fn(struct work_struct *work) {}
779 * pm_genpd_present - Check if the given PM domain has been initialized. 801 * pm_genpd_present - Check if the given PM domain has been initialized.
780 * @genpd: PM domain to check. 802 * @genpd: PM domain to check.
781 */ 803 */
782static bool pm_genpd_present(struct generic_pm_domain *genpd) 804static bool pm_genpd_present(const struct generic_pm_domain *genpd)
783{ 805{
784 struct generic_pm_domain *gpd; 806 const struct generic_pm_domain *gpd;
785 807
786 if (IS_ERR_OR_NULL(genpd)) 808 if (IS_ERR_OR_NULL(genpd))
787 return false; 809 return false;
@@ -822,8 +844,7 @@ static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd)
822 || atomic_read(&genpd->sd_count) > 0) 844 || atomic_read(&genpd->sd_count) > 0)
823 return; 845 return;
824 846
825 if (genpd->power_off) 847 genpd_power_off(genpd);
826 genpd->power_off(genpd);
827 848
828 genpd->status = GPD_STATE_POWER_OFF; 849 genpd->status = GPD_STATE_POWER_OFF;
829 850
@@ -854,8 +875,7 @@ static void pm_genpd_sync_poweron(struct generic_pm_domain *genpd)
854 genpd_sd_counter_inc(link->master); 875 genpd_sd_counter_inc(link->master);
855 } 876 }
856 877
857 if (genpd->power_on) 878 genpd_power_on(genpd);
858 genpd->power_on(genpd);
859 879
860 genpd->status = GPD_STATE_ACTIVE; 880 genpd->status = GPD_STATE_ACTIVE;
861} 881}
@@ -1277,8 +1297,7 @@ static int pm_genpd_restore_noirq(struct device *dev)
1277 * If the domain was off before the hibernation, make 1297 * If the domain was off before the hibernation, make
1278 * sure it will be off going forward. 1298 * sure it will be off going forward.
1279 */ 1299 */
1280 if (genpd->power_off) 1300 genpd_power_off(genpd);
1281 genpd->power_off(genpd);
1282 1301
1283 return 0; 1302 return 0;
1284 } 1303 }