diff options
| author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-11-17 19:21:39 -0500 |
|---|---|---|
| committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-11-17 19:21:39 -0500 |
| commit | 2e015da0d5f756c1b8a06158700238022671168b (patch) | |
| tree | 69078c28231a4b5f5ce4cf3dda9c73174fcc4ff7 /drivers/base | |
| parent | fc14f9c1272f62c3e8d01300f52467c0d9af50f9 (diff) | |
| parent | 00e7c295968d74f4dbb00aef8334fafe788e3c89 (diff) | |
Merge back 'pm-domains' material for 3.19-rc1.
Diffstat (limited to 'drivers/base')
| -rw-r--r-- | drivers/base/power/domain.c | 105 |
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 | ||
| 154 | static 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 | |||
| 181 | static 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 | */ |
| 782 | static bool pm_genpd_present(struct generic_pm_domain *genpd) | 804 | static 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 | } |
