Skip to content

Commit

Permalink
Merge branches 'pm-opp', 'pm-qos', 'acpi-pm', 'pm-domains' and 'pm-to…
Browse files Browse the repository at this point in the history
…ols'

* pm-opp:
  PM / OPP: Correct Documentation about library location
  opp: of: Support multiple suspend OPPs defined in DT
  dt-bindings: opp: Support multiple opp-suspend properties
  opp: core: add regulators enable and disable
  opp: Don't decrement uninitialized list_kref

* pm-qos:
  PM: QoS: Get rid of unused flags

* acpi-pm:
  ACPI: PM: Print debug messages on device power state changes

* pm-domains:
  PM / Domains: Verify PM domain type in dev_pm_genpd_set_performance_state()
  PM / Domains: Simplify genpd_lookup_dev()
  PM / Domains: Align in-parameter names for some genpd functions

* pm-tools:
  pm-graph: make setVal unbuffered again for python2 and python3
  cpupower: update German translation
  tools/power/cpupower: fix 64bit detection when cross-compiling
  cpupower: Add missing newline at end of file
  pm-graph v5.5
  • Loading branch information
rafaeljw committed Sep 17, 2019
6 parents 031f469 + e47bc75 + c3082a6 + ee8193e + 3ea4ca9 + e3e2ffd commit fc6763a
Show file tree
Hide file tree
Showing 19 changed files with 634 additions and 584 deletions.
4 changes: 2 additions & 2 deletions Documentation/devicetree/bindings/opp/opp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@ Optional properties:
frequency for a short duration of time limited by the device's power, current
and thermal limits.

- opp-suspend: Marks the OPP to be used during device suspend. Only one OPP in
the table should have this.
- opp-suspend: Marks the OPP to be used during device suspend. If multiple OPPs
in the table have this, the OPP with highest opp-hz will be used.

- opp-supported-hw: This enables us to select only a subset of OPPs from the
larger OPP table, based on what version of the hardware we are running on. We
Expand Down
2 changes: 1 addition & 1 deletion Documentation/power/opp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ We can represent these as three OPPs as the following {Hz, uV} tuples:
----------------------------------------

OPP library provides a set of helper functions to organize and query the OPP
information. The library is located in drivers/base/power/opp.c and the header
information. The library is located in drivers/opp/ directory and the header
is located in include/linux/pm_opp.h. OPP library can be enabled by enabling
CONFIG_PM_OPP from power management menuconfig menu. OPP library depends on
CONFIG_PM as certain SoCs such as Texas Instrument's OMAP framework allows to
Expand Down
5 changes: 2 additions & 3 deletions Documentation/power/pm_qos_interface.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ performance expectations by drivers, subsystems and user space applications on
one of the parameters.

Two different PM QoS frameworks are available:
1. PM QoS classes for cpu_dma_latency, network_latency, network_throughput,
memory_bandwidth.
1. PM QoS classes for cpu_dma_latency
2. the per-device PM QoS framework provides the API to manage the per-device latency
constraints and PM QoS flags.

Expand Down Expand Up @@ -79,7 +78,7 @@ cleanup of a process, the interface requires the process to register its
parameter requests in the following way:

To register the default pm_qos target for the specific parameter, the process
must open one of /dev/[cpu_dma_latency, network_latency, network_throughput]
must open /dev/cpu_dma_latency

As long as the device node is held open that process has a registered
request on the parameter.
Expand Down
4 changes: 4 additions & 0 deletions drivers/acpi/device_pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ int acpi_device_set_power(struct acpi_device *device, int state)
|| (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD))
return -EINVAL;

acpi_handle_debug(device->handle, "Power state change: %s -> %s\n",
acpi_power_state_string(device->power.state),
acpi_power_state_string(state));

/* Make sure this is a valid target state */

/* There is a special case for D0 addressed below. */
Expand Down
25 changes: 10 additions & 15 deletions drivers/base/power/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,29 +149,24 @@ static inline bool irq_safe_dev_in_no_sleep_domain(struct device *dev,
return ret;
}

static int genpd_runtime_suspend(struct device *dev);

/*
* Get the generic PM domain for a particular struct device.
* This validates the struct device pointer, the PM domain pointer,
* and checks that the PM domain pointer is a real generic PM domain.
* Any failure results in NULL being returned.
*/
static struct generic_pm_domain *genpd_lookup_dev(struct device *dev)
static struct generic_pm_domain *dev_to_genpd_safe(struct device *dev)
{
struct generic_pm_domain *genpd = NULL, *gpd;

if (IS_ERR_OR_NULL(dev) || IS_ERR_OR_NULL(dev->pm_domain))
return NULL;

mutex_lock(&gpd_list_lock);
list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
if (&gpd->domain == dev->pm_domain) {
genpd = gpd;
break;
}
}
mutex_unlock(&gpd_list_lock);
/* A genpd's always have its ->runtime_suspend() callback assigned. */
if (dev->pm_domain->ops.runtime_suspend == genpd_runtime_suspend)
return pd_to_genpd(dev->pm_domain);

return genpd;
return NULL;
}

/*
Expand Down Expand Up @@ -385,8 +380,8 @@ int dev_pm_genpd_set_performance_state(struct device *dev, unsigned int state)
unsigned int prev;
int ret;

genpd = dev_to_genpd(dev);
if (IS_ERR(genpd))
genpd = dev_to_genpd_safe(dev);
if (!genpd)
return -ENODEV;

if (unlikely(!genpd->set_performance_state))
Expand Down Expand Up @@ -1610,7 +1605,7 @@ static int genpd_remove_device(struct generic_pm_domain *genpd,
*/
int pm_genpd_remove_device(struct device *dev)
{
struct generic_pm_domain *genpd = genpd_lookup_dev(dev);
struct generic_pm_domain *genpd = dev_to_genpd_safe(dev);

if (!genpd)
return -EINVAL;
Expand Down
17 changes: 14 additions & 3 deletions drivers/opp/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -988,6 +988,7 @@ static struct opp_table *_allocate_opp_table(struct device *dev, int index)
BLOCKING_INIT_NOTIFIER_HEAD(&opp_table->head);
INIT_LIST_HEAD(&opp_table->opp_list);
kref_init(&opp_table->kref);
kref_init(&opp_table->list_kref);

/* Secure the device table modification */
list_add(&opp_table->node, &opp_tables);
Expand Down Expand Up @@ -1625,6 +1626,12 @@ struct opp_table *dev_pm_opp_set_regulators(struct device *dev,
goto free_regulators;
}

ret = regulator_enable(reg);
if (ret < 0) {
regulator_put(reg);
goto free_regulators;
}

opp_table->regulators[i] = reg;
}

Expand All @@ -1638,8 +1645,10 @@ struct opp_table *dev_pm_opp_set_regulators(struct device *dev,
return opp_table;

free_regulators:
while (i != 0)
regulator_put(opp_table->regulators[--i]);
while (i--) {
regulator_disable(opp_table->regulators[i]);
regulator_put(opp_table->regulators[i]);
}

kfree(opp_table->regulators);
opp_table->regulators = NULL;
Expand All @@ -1665,8 +1674,10 @@ void dev_pm_opp_put_regulators(struct opp_table *opp_table)
/* Make sure there are no concurrent readers while updating opp_table */
WARN_ON(!list_empty(&opp_table->opp_list));

for (i = opp_table->regulator_count - 1; i >= 0; i--)
for (i = opp_table->regulator_count - 1; i >= 0; i--) {
regulator_disable(opp_table->regulators[i]);
regulator_put(opp_table->regulators[i]);
}

_free_set_opp_data(opp_table);

Expand Down
30 changes: 10 additions & 20 deletions drivers/opp/of.c
Original file line number Diff line number Diff line change
Expand Up @@ -617,9 +617,12 @@ static struct dev_pm_opp *_opp_add_static_v2(struct opp_table *opp_table,
/* OPP to select on device suspend */
if (of_property_read_bool(np, "opp-suspend")) {
if (opp_table->suspend_opp) {
dev_warn(dev, "%s: Multiple suspend OPPs found (%lu %lu)\n",
__func__, opp_table->suspend_opp->rate,
new_opp->rate);
/* Pick the OPP with higher rate as suspend OPP */
if (new_opp->rate > opp_table->suspend_opp->rate) {
opp_table->suspend_opp->suspend = false;
new_opp->suspend = true;
opp_table->suspend_opp = new_opp;
}
} else {
new_opp->suspend = true;
opp_table->suspend_opp = new_opp;
Expand Down Expand Up @@ -662,8 +665,6 @@ static int _of_add_opp_table_v2(struct device *dev, struct opp_table *opp_table)
return 0;
}

kref_init(&opp_table->list_kref);

/* We have opp-table node now, iterate over it and add OPPs */
for_each_available_child_of_node(opp_table->np, np) {
opp = _opp_add_static_v2(opp_table, dev, np);
Expand All @@ -672,17 +673,15 @@ static int _of_add_opp_table_v2(struct device *dev, struct opp_table *opp_table)
dev_err(dev, "%s: Failed to add OPP, %d\n", __func__,
ret);
of_node_put(np);
goto put_list_kref;
return ret;
} else if (opp) {
count++;
}
}

/* There should be one of more OPP defined */
if (WARN_ON(!count)) {
ret = -ENOENT;
goto put_list_kref;
}
if (WARN_ON(!count))
return -ENOENT;

list_for_each_entry(opp, &opp_table->opp_list, node)
pstate_count += !!opp->pstate;
Expand All @@ -691,8 +690,7 @@ static int _of_add_opp_table_v2(struct device *dev, struct opp_table *opp_table)
if (pstate_count && pstate_count != count) {
dev_err(dev, "Not all nodes have performance state set (%d: %d)\n",
count, pstate_count);
ret = -ENOENT;
goto put_list_kref;
return -ENOENT;
}

if (pstate_count)
Expand All @@ -701,11 +699,6 @@ static int _of_add_opp_table_v2(struct device *dev, struct opp_table *opp_table)
opp_table->parsed_static_opps = true;

return 0;

put_list_kref:
_put_opp_list_kref(opp_table);

return ret;
}

/* Initializes OPP tables based on old-deprecated bindings */
Expand All @@ -731,8 +724,6 @@ static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table)
return -EINVAL;
}

kref_init(&opp_table->list_kref);

val = prop->value;
while (nr) {
unsigned long freq = be32_to_cpup(val++) * 1000;
Expand All @@ -742,7 +733,6 @@ static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table)
if (ret) {
dev_err(dev, "%s: Failed to add OPP %ld (%d)\n",
__func__, freq, ret);
_put_opp_list_kref(opp_table);
return ret;
}
nr -= 2;
Expand Down
16 changes: 8 additions & 8 deletions include/linux/pm_domain.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,9 @@ static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev)
int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev);
int pm_genpd_remove_device(struct device *dev);
int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
struct generic_pm_domain *new_subdomain);
struct generic_pm_domain *subdomain);
int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
struct generic_pm_domain *target);
struct generic_pm_domain *subdomain);
int pm_genpd_init(struct generic_pm_domain *genpd,
struct dev_power_governor *gov, bool is_off);
int pm_genpd_remove(struct generic_pm_domain *genpd);
Expand All @@ -226,12 +226,12 @@ static inline int pm_genpd_remove_device(struct device *dev)
return -ENOSYS;
}
static inline int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
struct generic_pm_domain *new_sd)
struct generic_pm_domain *subdomain)
{
return -ENOSYS;
}
static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
struct generic_pm_domain *target)
struct generic_pm_domain *subdomain)
{
return -ENOSYS;
}
Expand Down Expand Up @@ -282,8 +282,8 @@ int of_genpd_add_provider_onecell(struct device_node *np,
struct genpd_onecell_data *data);
void of_genpd_del_provider(struct device_node *np);
int of_genpd_add_device(struct of_phandle_args *args, struct device *dev);
int of_genpd_add_subdomain(struct of_phandle_args *parent,
struct of_phandle_args *new_subdomain);
int of_genpd_add_subdomain(struct of_phandle_args *parent_spec,
struct of_phandle_args *subdomain_spec);
struct generic_pm_domain *of_genpd_remove_last(struct device_node *np);
int of_genpd_parse_idle_states(struct device_node *dn,
struct genpd_power_state **states, int *n);
Expand Down Expand Up @@ -316,8 +316,8 @@ static inline int of_genpd_add_device(struct of_phandle_args *args,
return -ENODEV;
}

static inline int of_genpd_add_subdomain(struct of_phandle_args *parent,
struct of_phandle_args *new_subdomain)
static inline int of_genpd_add_subdomain(struct of_phandle_args *parent_spec,
struct of_phandle_args *subdomain_spec)
{
return -ENODEV;
}
Expand Down
6 changes: 0 additions & 6 deletions include/linux/pm_qos.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@
enum {
PM_QOS_RESERVED = 0,
PM_QOS_CPU_DMA_LATENCY,
PM_QOS_NETWORK_LATENCY,
PM_QOS_NETWORK_THROUGHPUT,
PM_QOS_MEMORY_BANDWIDTH,

/* insert new class ID */
PM_QOS_NUM_CLASSES,
Expand All @@ -33,9 +30,6 @@ enum pm_qos_flags_status {
#define PM_QOS_LATENCY_ANY_NS ((s64)PM_QOS_LATENCY_ANY * NSEC_PER_USEC)

#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
#define PM_QOS_NETWORK_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0
#define PM_QOS_MEMORY_BANDWIDTH_DEFAULT_VALUE 0
#define PM_QOS_RESUME_LATENCY_DEFAULT_VALUE PM_QOS_LATENCY_ANY
#define PM_QOS_RESUME_LATENCY_NO_CONSTRAINT PM_QOS_LATENCY_ANY
#define PM_QOS_RESUME_LATENCY_NO_CONSTRAINT_NS PM_QOS_LATENCY_ANY_NS
Expand Down
8 changes: 2 additions & 6 deletions include/trace/events/power.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,9 +379,7 @@ DECLARE_EVENT_CLASS(pm_qos_request,

TP_printk("pm_qos_class=%s value=%d",
__print_symbolic(__entry->pm_qos_class,
{ PM_QOS_CPU_DMA_LATENCY, "CPU_DMA_LATENCY" },
{ PM_QOS_NETWORK_LATENCY, "NETWORK_LATENCY" },
{ PM_QOS_NETWORK_THROUGHPUT, "NETWORK_THROUGHPUT" }),
{ PM_QOS_CPU_DMA_LATENCY, "CPU_DMA_LATENCY" }),
__entry->value)
);

Expand Down Expand Up @@ -426,9 +424,7 @@ TRACE_EVENT(pm_qos_update_request_timeout,

TP_printk("pm_qos_class=%s value=%d, timeout_us=%ld",
__print_symbolic(__entry->pm_qos_class,
{ PM_QOS_CPU_DMA_LATENCY, "CPU_DMA_LATENCY" },
{ PM_QOS_NETWORK_LATENCY, "NETWORK_LATENCY" },
{ PM_QOS_NETWORK_THROUGHPUT, "NETWORK_THROUGHPUT" }),
{ PM_QOS_CPU_DMA_LATENCY, "CPU_DMA_LATENCY" }),
__entry->value, __entry->timeout_us)
);

Expand Down
48 changes: 0 additions & 48 deletions kernel/power/qos.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,57 +78,9 @@ static struct pm_qos_object cpu_dma_pm_qos = {
.name = "cpu_dma_latency",
};

static BLOCKING_NOTIFIER_HEAD(network_lat_notifier);
static struct pm_qos_constraints network_lat_constraints = {
.list = PLIST_HEAD_INIT(network_lat_constraints.list),
.target_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE,
.default_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE,
.no_constraint_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE,
.type = PM_QOS_MIN,
.notifiers = &network_lat_notifier,
};
static struct pm_qos_object network_lat_pm_qos = {
.constraints = &network_lat_constraints,
.name = "network_latency",
};


static BLOCKING_NOTIFIER_HEAD(network_throughput_notifier);
static struct pm_qos_constraints network_tput_constraints = {
.list = PLIST_HEAD_INIT(network_tput_constraints.list),
.target_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE,
.default_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE,
.no_constraint_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE,
.type = PM_QOS_MAX,
.notifiers = &network_throughput_notifier,
};
static struct pm_qos_object network_throughput_pm_qos = {
.constraints = &network_tput_constraints,
.name = "network_throughput",
};


static BLOCKING_NOTIFIER_HEAD(memory_bandwidth_notifier);
static struct pm_qos_constraints memory_bw_constraints = {
.list = PLIST_HEAD_INIT(memory_bw_constraints.list),
.target_value = PM_QOS_MEMORY_BANDWIDTH_DEFAULT_VALUE,
.default_value = PM_QOS_MEMORY_BANDWIDTH_DEFAULT_VALUE,
.no_constraint_value = PM_QOS_MEMORY_BANDWIDTH_DEFAULT_VALUE,
.type = PM_QOS_SUM,
.notifiers = &memory_bandwidth_notifier,
};
static struct pm_qos_object memory_bandwidth_pm_qos = {
.constraints = &memory_bw_constraints,
.name = "memory_bandwidth",
};


static struct pm_qos_object *pm_qos_array[] = {
&null_pm_qos,
&cpu_dma_pm_qos,
&network_lat_pm_qos,
&network_throughput_pm_qos,
&memory_bandwidth_pm_qos,
};

static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf,
Expand Down
Loading

0 comments on commit fc6763a

Please sign in to comment.