2011-12-01 06:02:05 +07:00
|
|
|
/*
|
|
|
|
* drivers/base/power/domain_governor.c - Governors for device PM domains.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
|
|
|
|
*
|
|
|
|
* This file is released under the GPLv2.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/pm_domain.h>
|
|
|
|
#include <linux/pm_qos.h>
|
2011-12-01 06:02:10 +07:00
|
|
|
#include <linux/hrtimer.h>
|
2011-12-01 06:02:05 +07:00
|
|
|
|
2012-04-30 03:54:17 +07:00
|
|
|
static int dev_update_qos_constraint(struct device *dev, void *data)
|
|
|
|
{
|
|
|
|
s64 *constraint_ns_p = data;
|
|
|
|
s32 constraint_ns = -1;
|
|
|
|
|
|
|
|
if (dev->power.subsys_data && dev->power.subsys_data->domain_data)
|
|
|
|
constraint_ns = dev_gpd_data(dev)->td.effective_constraint_ns;
|
|
|
|
|
|
|
|
if (constraint_ns < 0) {
|
|
|
|
constraint_ns = dev_pm_qos_read_value(dev);
|
|
|
|
constraint_ns *= NSEC_PER_USEC;
|
|
|
|
}
|
|
|
|
if (constraint_ns == 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* constraint_ns cannot be negative here, because the device has been
|
|
|
|
* suspended.
|
|
|
|
*/
|
|
|
|
if (constraint_ns < *constraint_ns_p || *constraint_ns_p == 0)
|
|
|
|
*constraint_ns_p = constraint_ns;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-12-01 06:02:05 +07:00
|
|
|
/**
|
2016-03-31 16:21:25 +07:00
|
|
|
* default_suspend_ok - Default PM domain governor routine to suspend devices.
|
2011-12-01 06:02:05 +07:00
|
|
|
* @dev: Device to check.
|
|
|
|
*/
|
2016-03-31 16:21:25 +07:00
|
|
|
static bool default_suspend_ok(struct device *dev)
|
2011-12-01 06:02:05 +07:00
|
|
|
{
|
|
|
|
struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
|
PM / Domains: Cache device stop and domain power off governor results, v3
The results of the default device stop and domain power off governor
functions for generic PM domains, default_stop_ok() and
default_power_down_ok(), depend only on the timing data of devices,
which are static, and on their PM QoS constraints. Thus, in theory,
these functions only need to carry out their computations, which may
be time consuming in general, when it is known that the PM QoS
constraint of at least one of the devices in question has changed.
Use the PM QoS notifiers of devices to implement that. First,
introduce new fields, constraint_changed and max_off_time_changed,
into struct gpd_timing_data and struct generic_pm_domain,
respectively, and register a PM QoS notifier function when adding
a device into a domain that will set those fields to 'true' whenever
the device's PM QoS constraint is modified. Second, make
default_stop_ok() and default_power_down_ok() use those fields to
decide whether or not to carry out their computations from scratch.
The device and PM domain hierarchies are taken into account in that
and the expense is that the changes of PM QoS constraints of
suspended devices will not be taken into account immediately, which
isn't guaranteed anyway in general.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2012-05-02 02:34:07 +07:00
|
|
|
unsigned long flags;
|
2012-04-30 03:54:17 +07:00
|
|
|
s64 constraint_ns;
|
2011-12-01 06:02:05 +07:00
|
|
|
|
|
|
|
dev_dbg(dev, "%s()\n", __func__);
|
|
|
|
|
PM / Domains: Cache device stop and domain power off governor results, v3
The results of the default device stop and domain power off governor
functions for generic PM domains, default_stop_ok() and
default_power_down_ok(), depend only on the timing data of devices,
which are static, and on their PM QoS constraints. Thus, in theory,
these functions only need to carry out their computations, which may
be time consuming in general, when it is known that the PM QoS
constraint of at least one of the devices in question has changed.
Use the PM QoS notifiers of devices to implement that. First,
introduce new fields, constraint_changed and max_off_time_changed,
into struct gpd_timing_data and struct generic_pm_domain,
respectively, and register a PM QoS notifier function when adding
a device into a domain that will set those fields to 'true' whenever
the device's PM QoS constraint is modified. Second, make
default_stop_ok() and default_power_down_ok() use those fields to
decide whether or not to carry out their computations from scratch.
The device and PM domain hierarchies are taken into account in that
and the expense is that the changes of PM QoS constraints of
suspended devices will not be taken into account immediately, which
isn't guaranteed anyway in general.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2012-05-02 02:34:07 +07:00
|
|
|
spin_lock_irqsave(&dev->power.lock, flags);
|
|
|
|
|
|
|
|
if (!td->constraint_changed) {
|
2016-03-31 16:21:25 +07:00
|
|
|
bool ret = td->cached_suspend_ok;
|
PM / Domains: Cache device stop and domain power off governor results, v3
The results of the default device stop and domain power off governor
functions for generic PM domains, default_stop_ok() and
default_power_down_ok(), depend only on the timing data of devices,
which are static, and on their PM QoS constraints. Thus, in theory,
these functions only need to carry out their computations, which may
be time consuming in general, when it is known that the PM QoS
constraint of at least one of the devices in question has changed.
Use the PM QoS notifiers of devices to implement that. First,
introduce new fields, constraint_changed and max_off_time_changed,
into struct gpd_timing_data and struct generic_pm_domain,
respectively, and register a PM QoS notifier function when adding
a device into a domain that will set those fields to 'true' whenever
the device's PM QoS constraint is modified. Second, make
default_stop_ok() and default_power_down_ok() use those fields to
decide whether or not to carry out their computations from scratch.
The device and PM domain hierarchies are taken into account in that
and the expense is that the changes of PM QoS constraints of
suspended devices will not be taken into account immediately, which
isn't guaranteed anyway in general.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2012-05-02 02:34:07 +07:00
|
|
|
|
|
|
|
spin_unlock_irqrestore(&dev->power.lock, flags);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
td->constraint_changed = false;
|
2016-03-31 16:21:25 +07:00
|
|
|
td->cached_suspend_ok = false;
|
PM / Domains: Cache device stop and domain power off governor results, v3
The results of the default device stop and domain power off governor
functions for generic PM domains, default_stop_ok() and
default_power_down_ok(), depend only on the timing data of devices,
which are static, and on their PM QoS constraints. Thus, in theory,
these functions only need to carry out their computations, which may
be time consuming in general, when it is known that the PM QoS
constraint of at least one of the devices in question has changed.
Use the PM QoS notifiers of devices to implement that. First,
introduce new fields, constraint_changed and max_off_time_changed,
into struct gpd_timing_data and struct generic_pm_domain,
respectively, and register a PM QoS notifier function when adding
a device into a domain that will set those fields to 'true' whenever
the device's PM QoS constraint is modified. Second, make
default_stop_ok() and default_power_down_ok() use those fields to
decide whether or not to carry out their computations from scratch.
The device and PM domain hierarchies are taken into account in that
and the expense is that the changes of PM QoS constraints of
suspended devices will not be taken into account immediately, which
isn't guaranteed anyway in general.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2012-05-02 02:34:07 +07:00
|
|
|
td->effective_constraint_ns = -1;
|
|
|
|
constraint_ns = __dev_pm_qos_read_value(dev);
|
|
|
|
|
|
|
|
spin_unlock_irqrestore(&dev->power.lock, flags);
|
|
|
|
|
2012-04-30 03:54:17 +07:00
|
|
|
if (constraint_ns < 0)
|
|
|
|
return false;
|
2011-12-01 06:02:05 +07:00
|
|
|
|
2012-04-30 03:54:17 +07:00
|
|
|
constraint_ns *= NSEC_PER_USEC;
|
|
|
|
/*
|
|
|
|
* We can walk the children without any additional locking, because
|
PM / Domains: Cache device stop and domain power off governor results, v3
The results of the default device stop and domain power off governor
functions for generic PM domains, default_stop_ok() and
default_power_down_ok(), depend only on the timing data of devices,
which are static, and on their PM QoS constraints. Thus, in theory,
these functions only need to carry out their computations, which may
be time consuming in general, when it is known that the PM QoS
constraint of at least one of the devices in question has changed.
Use the PM QoS notifiers of devices to implement that. First,
introduce new fields, constraint_changed and max_off_time_changed,
into struct gpd_timing_data and struct generic_pm_domain,
respectively, and register a PM QoS notifier function when adding
a device into a domain that will set those fields to 'true' whenever
the device's PM QoS constraint is modified. Second, make
default_stop_ok() and default_power_down_ok() use those fields to
decide whether or not to carry out their computations from scratch.
The device and PM domain hierarchies are taken into account in that
and the expense is that the changes of PM QoS constraints of
suspended devices will not be taken into account immediately, which
isn't guaranteed anyway in general.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2012-05-02 02:34:07 +07:00
|
|
|
* they all have been suspended at this point and their
|
|
|
|
* effective_constraint_ns fields won't be modified in parallel with us.
|
2012-04-30 03:54:17 +07:00
|
|
|
*/
|
|
|
|
if (!dev->power.ignore_children)
|
|
|
|
device_for_each_child(dev, &constraint_ns,
|
|
|
|
dev_update_qos_constraint);
|
|
|
|
|
|
|
|
if (constraint_ns > 0) {
|
2015-10-15 22:02:19 +07:00
|
|
|
constraint_ns -= td->suspend_latency_ns +
|
|
|
|
td->resume_latency_ns;
|
2012-04-30 03:54:17 +07:00
|
|
|
if (constraint_ns == 0)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
td->effective_constraint_ns = constraint_ns;
|
2016-03-31 16:21:25 +07:00
|
|
|
td->cached_suspend_ok = constraint_ns >= 0;
|
2015-10-13 21:10:28 +07:00
|
|
|
|
2012-04-30 03:54:17 +07:00
|
|
|
/*
|
|
|
|
* The children have been suspended already, so we don't need to take
|
2016-03-31 16:21:25 +07:00
|
|
|
* their suspend latencies into account here.
|
2012-04-30 03:54:17 +07:00
|
|
|
*/
|
2016-03-31 16:21:25 +07:00
|
|
|
return td->cached_suspend_ok;
|
2011-12-01 06:02:05 +07:00
|
|
|
}
|
|
|
|
|
2016-02-15 17:10:51 +07:00
|
|
|
static bool __default_power_down_ok(struct dev_pm_domain *pd,
|
|
|
|
unsigned int state)
|
2011-12-01 06:02:10 +07:00
|
|
|
{
|
|
|
|
struct generic_pm_domain *genpd = pd_to_genpd(pd);
|
|
|
|
struct gpd_link *link;
|
|
|
|
struct pm_domain_data *pdd;
|
2012-05-08 03:00:59 +07:00
|
|
|
s64 min_off_time_ns;
|
2011-12-01 06:02:10 +07:00
|
|
|
s64 off_on_time_ns;
|
|
|
|
|
2016-02-15 17:10:51 +07:00
|
|
|
off_on_time_ns = genpd->states[state].power_off_latency_ns +
|
|
|
|
genpd->states[state].power_on_latency_ns;
|
PM / Domains: Cache device stop and domain power off governor results, v3
The results of the default device stop and domain power off governor
functions for generic PM domains, default_stop_ok() and
default_power_down_ok(), depend only on the timing data of devices,
which are static, and on their PM QoS constraints. Thus, in theory,
these functions only need to carry out their computations, which may
be time consuming in general, when it is known that the PM QoS
constraint of at least one of the devices in question has changed.
Use the PM QoS notifiers of devices to implement that. First,
introduce new fields, constraint_changed and max_off_time_changed,
into struct gpd_timing_data and struct generic_pm_domain,
respectively, and register a PM QoS notifier function when adding
a device into a domain that will set those fields to 'true' whenever
the device's PM QoS constraint is modified. Second, make
default_stop_ok() and default_power_down_ok() use those fields to
decide whether or not to carry out their computations from scratch.
The device and PM domain hierarchies are taken into account in that
and the expense is that the changes of PM QoS constraints of
suspended devices will not be taken into account immediately, which
isn't guaranteed anyway in general.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2012-05-02 02:34:07 +07:00
|
|
|
|
2011-12-01 06:02:10 +07:00
|
|
|
|
2012-05-08 03:00:59 +07:00
|
|
|
min_off_time_ns = -1;
|
2011-12-01 06:02:10 +07:00
|
|
|
/*
|
|
|
|
* Check if subdomains can be off for enough time.
|
|
|
|
*
|
|
|
|
* All subdomains have been powered off already at this point.
|
|
|
|
*/
|
|
|
|
list_for_each_entry(link, &genpd->master_links, master_node) {
|
|
|
|
struct generic_pm_domain *sd = link->slave;
|
|
|
|
s64 sd_max_off_ns = sd->max_off_time_ns;
|
|
|
|
|
|
|
|
if (sd_max_off_ns < 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check if the subdomain is allowed to be off long enough for
|
|
|
|
* the current domain to turn off and on (that's how much time
|
|
|
|
* it will have to wait worst case).
|
|
|
|
*/
|
|
|
|
if (sd_max_off_ns <= off_on_time_ns)
|
|
|
|
return false;
|
2012-05-08 03:00:59 +07:00
|
|
|
|
|
|
|
if (min_off_time_ns > sd_max_off_ns || min_off_time_ns < 0)
|
|
|
|
min_off_time_ns = sd_max_off_ns;
|
2011-12-01 06:02:10 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check if the devices in the domain can be off enough time.
|
|
|
|
*/
|
|
|
|
list_for_each_entry(pdd, &genpd->dev_list, list_node) {
|
|
|
|
struct gpd_timing_data *td;
|
2012-04-30 03:54:30 +07:00
|
|
|
s64 constraint_ns;
|
2011-12-01 06:02:10 +07:00
|
|
|
|
2012-04-30 03:54:30 +07:00
|
|
|
/*
|
|
|
|
* Check if the device is allowed to be off long enough for the
|
|
|
|
* domain to turn off and on (that's how much time it will
|
|
|
|
* have to wait worst case).
|
|
|
|
*/
|
2011-12-01 06:02:10 +07:00
|
|
|
td = &to_gpd_data(pdd)->td;
|
2012-04-30 03:54:30 +07:00
|
|
|
constraint_ns = td->effective_constraint_ns;
|
2016-03-31 16:21:25 +07:00
|
|
|
/* default_suspend_ok() need not be called before us. */
|
2012-04-30 03:54:30 +07:00
|
|
|
if (constraint_ns < 0) {
|
|
|
|
constraint_ns = dev_pm_qos_read_value(pdd->dev);
|
|
|
|
constraint_ns *= NSEC_PER_USEC;
|
|
|
|
}
|
|
|
|
if (constraint_ns == 0)
|
|
|
|
continue;
|
2011-12-01 06:02:10 +07:00
|
|
|
|
|
|
|
/*
|
2012-04-30 03:54:30 +07:00
|
|
|
* constraint_ns cannot be negative here, because the device has
|
|
|
|
* been suspended.
|
2011-12-01 06:02:10 +07:00
|
|
|
*/
|
2012-04-30 03:54:30 +07:00
|
|
|
if (constraint_ns <= off_on_time_ns)
|
|
|
|
return false;
|
|
|
|
|
2012-05-08 03:00:59 +07:00
|
|
|
if (min_off_time_ns > constraint_ns || min_off_time_ns < 0)
|
|
|
|
min_off_time_ns = constraint_ns;
|
2011-12-01 06:02:10 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2012-04-30 03:54:30 +07:00
|
|
|
* If the computed minimum device off time is negative, there are no
|
|
|
|
* latency constraints, so the domain can spend arbitrary time in the
|
|
|
|
* "off" state.
|
2011-12-01 06:02:10 +07:00
|
|
|
*/
|
2012-05-08 03:00:59 +07:00
|
|
|
if (min_off_time_ns < 0)
|
2012-04-30 03:54:30 +07:00
|
|
|
return true;
|
2011-12-01 06:02:10 +07:00
|
|
|
|
|
|
|
/*
|
2012-05-08 03:00:59 +07:00
|
|
|
* The difference between the computed minimum subdomain or device off
|
|
|
|
* time and the time needed to turn the domain on is the maximum
|
|
|
|
* theoretical time this domain can spend in the "off" state.
|
2011-12-01 06:02:10 +07:00
|
|
|
*/
|
2016-02-15 17:10:51 +07:00
|
|
|
genpd->max_off_time_ns = min_off_time_ns -
|
|
|
|
genpd->states[state].power_on_latency_ns;
|
2011-12-01 06:02:10 +07:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-06-28 21:56:21 +07:00
|
|
|
/**
|
|
|
|
* default_power_down_ok - Default generic PM domain power off governor routine.
|
|
|
|
* @pd: PM domain to check.
|
|
|
|
*
|
|
|
|
* This routine must be executed under the PM domain's lock.
|
|
|
|
*/
|
2016-02-15 17:10:51 +07:00
|
|
|
static bool default_power_down_ok(struct dev_pm_domain *pd)
|
|
|
|
{
|
|
|
|
struct generic_pm_domain *genpd = pd_to_genpd(pd);
|
|
|
|
struct gpd_link *link;
|
|
|
|
|
|
|
|
if (!genpd->max_off_time_changed)
|
|
|
|
return genpd->cached_power_down_ok;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We have to invalidate the cached results for the masters, so
|
|
|
|
* use the observation that default_power_down_ok() is not
|
|
|
|
* going to be called for any master until this instance
|
|
|
|
* returns.
|
|
|
|
*/
|
|
|
|
list_for_each_entry(link, &genpd->slave_links, slave_node)
|
|
|
|
link->master->max_off_time_changed = true;
|
|
|
|
|
|
|
|
genpd->max_off_time_ns = -1;
|
|
|
|
genpd->max_off_time_changed = false;
|
|
|
|
genpd->cached_power_down_ok = true;
|
|
|
|
genpd->state_idx = genpd->state_count - 1;
|
|
|
|
|
|
|
|
/* Find a state to power down to, starting from the deepest. */
|
|
|
|
while (!__default_power_down_ok(pd, genpd->state_idx)) {
|
|
|
|
if (genpd->state_idx == 0) {
|
|
|
|
genpd->cached_power_down_ok = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
genpd->state_idx--;
|
|
|
|
}
|
|
|
|
|
|
|
|
return genpd->cached_power_down_ok;
|
|
|
|
}
|
|
|
|
|
2011-12-09 05:27:28 +07:00
|
|
|
static bool always_on_power_down_ok(struct dev_pm_domain *domain)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-01-14 06:39:36 +07:00
|
|
|
struct dev_power_governor simple_qos_governor = {
|
2016-03-31 16:21:25 +07:00
|
|
|
.suspend_ok = default_suspend_ok,
|
2012-01-14 06:39:36 +07:00
|
|
|
.power_down_ok = default_power_down_ok,
|
|
|
|
};
|
|
|
|
|
2011-12-09 05:27:28 +07:00
|
|
|
/**
|
|
|
|
* pm_genpd_gov_always_on - A governor implementing an always-on policy
|
|
|
|
*/
|
|
|
|
struct dev_power_governor pm_domain_always_on_gov = {
|
|
|
|
.power_down_ok = always_on_power_down_ok,
|
2016-03-31 16:21:25 +07:00
|
|
|
.suspend_ok = default_suspend_ok,
|
2011-12-09 05:27:28 +07:00
|
|
|
};
|