Commit 2e015da0 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge back 'pm-domains' material for 3.19-rc1.

parents fc14f9c1 00e7c295
...@@ -151,6 +151,59 @@ static void genpd_recalc_cpu_exit_latency(struct generic_pm_domain *genpd) ...@@ -151,6 +151,59 @@ static void genpd_recalc_cpu_exit_latency(struct generic_pm_domain *genpd)
genpd->cpuidle_data->idle_state->exit_latency = usecs64; genpd->cpuidle_data->idle_state->exit_latency = usecs64;
} }
static int genpd_power_on(struct generic_pm_domain *genpd)
{
ktime_t time_start;
s64 elapsed_ns;
int ret;
if (!genpd->power_on)
return 0;
time_start = ktime_get();
ret = genpd->power_on(genpd);
if (ret)
return ret;
elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
if (elapsed_ns <= genpd->power_on_latency_ns)
return ret;
genpd->power_on_latency_ns = elapsed_ns;
genpd->max_off_time_changed = true;
genpd_recalc_cpu_exit_latency(genpd);
pr_warn("%s: Power-%s latency exceeded, new value %lld ns\n",
genpd->name, "on", elapsed_ns);
return ret;
}
static int genpd_power_off(struct generic_pm_domain *genpd)
{
ktime_t time_start;
s64 elapsed_ns;
int ret;
if (!genpd->power_off)
return 0;
time_start = ktime_get();
ret = genpd->power_off(genpd);
if (ret == -EBUSY)
return ret;
elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
if (elapsed_ns <= genpd->power_off_latency_ns)
return ret;
genpd->power_off_latency_ns = elapsed_ns;
genpd->max_off_time_changed = true;
pr_warn("%s: Power-%s latency exceeded, new value %lld ns\n",
genpd->name, "off", elapsed_ns);
return ret;
}
/** /**
* __pm_genpd_poweron - Restore power to a given PM domain and its masters. * __pm_genpd_poweron - Restore power to a given PM domain and its masters.
* @genpd: PM domain to power up. * @genpd: PM domain to power up.
...@@ -222,25 +275,9 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd) ...@@ -222,25 +275,9 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd)
} }
} }
if (genpd->power_on) { ret = genpd_power_on(genpd);
ktime_t time_start = ktime_get(); if (ret)
s64 elapsed_ns; goto err;
ret = genpd->power_on(genpd);
if (ret)
goto err;
elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
if (elapsed_ns > genpd->power_on_latency_ns) {
genpd->power_on_latency_ns = elapsed_ns;
genpd->max_off_time_changed = true;
genpd_recalc_cpu_exit_latency(genpd);
if (genpd->name)
pr_warning("%s: Power-on latency exceeded, "
"new value %lld ns\n", genpd->name,
elapsed_ns);
}
}
out: out:
genpd_set_active(genpd); genpd_set_active(genpd);
...@@ -544,16 +581,11 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd) ...@@ -544,16 +581,11 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
} }
if (genpd->power_off) { if (genpd->power_off) {
ktime_t time_start;
s64 elapsed_ns;
if (atomic_read(&genpd->sd_count) > 0) { if (atomic_read(&genpd->sd_count) > 0) {
ret = -EBUSY; ret = -EBUSY;
goto out; goto out;
} }
time_start = ktime_get();
/* /*
* If sd_count > 0 at this point, one of the subdomains hasn't * If sd_count > 0 at this point, one of the subdomains hasn't
* managed to call pm_genpd_poweron() for the master yet after * 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,21 +594,11 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
* the pm_genpd_poweron() restore power for us (this shouldn't * the pm_genpd_poweron() restore power for us (this shouldn't
* happen very often). * happen very often).
*/ */
ret = genpd->power_off(genpd); ret = genpd_power_off(genpd);
if (ret == -EBUSY) { if (ret == -EBUSY) {
genpd_set_active(genpd); genpd_set_active(genpd);
goto out; goto out;
} }
elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
if (elapsed_ns > genpd->power_off_latency_ns) {
genpd->power_off_latency_ns = elapsed_ns;
genpd->max_off_time_changed = true;
if (genpd->name)
pr_warning("%s: Power-off latency exceeded, "
"new value %lld ns\n", genpd->name,
elapsed_ns);
}
} }
genpd->status = GPD_STATE_POWER_OFF; genpd->status = GPD_STATE_POWER_OFF;
...@@ -779,9 +801,9 @@ static inline void genpd_power_off_work_fn(struct work_struct *work) {} ...@@ -779,9 +801,9 @@ static inline void genpd_power_off_work_fn(struct work_struct *work) {}
* pm_genpd_present - Check if the given PM domain has been initialized. * pm_genpd_present - Check if the given PM domain has been initialized.
* @genpd: PM domain to check. * @genpd: PM domain to check.
*/ */
static bool pm_genpd_present(struct generic_pm_domain *genpd) static bool pm_genpd_present(const struct generic_pm_domain *genpd)
{ {
struct generic_pm_domain *gpd; const struct generic_pm_domain *gpd;
if (IS_ERR_OR_NULL(genpd)) if (IS_ERR_OR_NULL(genpd))
return false; return false;
...@@ -822,8 +844,7 @@ static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd) ...@@ -822,8 +844,7 @@ static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd)
|| atomic_read(&genpd->sd_count) > 0) || atomic_read(&genpd->sd_count) > 0)
return; return;
if (genpd->power_off) genpd_power_off(genpd);
genpd->power_off(genpd);
genpd->status = GPD_STATE_POWER_OFF; genpd->status = GPD_STATE_POWER_OFF;
...@@ -854,8 +875,7 @@ static void pm_genpd_sync_poweron(struct generic_pm_domain *genpd) ...@@ -854,8 +875,7 @@ static void pm_genpd_sync_poweron(struct generic_pm_domain *genpd)
genpd_sd_counter_inc(link->master); genpd_sd_counter_inc(link->master);
} }
if (genpd->power_on) genpd_power_on(genpd);
genpd->power_on(genpd);
genpd->status = GPD_STATE_ACTIVE; genpd->status = GPD_STATE_ACTIVE;
} }
...@@ -1277,8 +1297,7 @@ static int pm_genpd_restore_noirq(struct device *dev) ...@@ -1277,8 +1297,7 @@ static int pm_genpd_restore_noirq(struct device *dev)
* If the domain was off before the hibernation, make * If the domain was off before the hibernation, make
* sure it will be off going forward. * sure it will be off going forward.
*/ */
if (genpd->power_off) genpd_power_off(genpd);
genpd->power_off(genpd);
return 0; return 0;
} }
......
...@@ -538,11 +538,7 @@ enum rpm_request { ...@@ -538,11 +538,7 @@ enum rpm_request {
}; };
struct wakeup_source; struct wakeup_source;
struct pm_domain_data;
struct pm_domain_data {
struct list_head list_node;
struct device *dev;
};
struct pm_subsys_data { struct pm_subsys_data {
spinlock_t lock; spinlock_t lock;
......
...@@ -100,6 +100,11 @@ struct gpd_timing_data { ...@@ -100,6 +100,11 @@ struct gpd_timing_data {
bool cached_stop_ok; bool cached_stop_ok;
}; };
struct pm_domain_data {
struct list_head list_node;
struct device *dev;
};
struct generic_pm_domain_data { struct generic_pm_domain_data {
struct pm_domain_data base; struct pm_domain_data base;
struct gpd_timing_data td; struct gpd_timing_data td;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment