Commit 13b06b78 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge branches 'pm-opp', 'pm-misc', 'pm-avs' and 'pm-tools'

* pm-opp:
  opp: Don't use IS_ERR on invalid supplies
  opp: Make dev_pm_opp_set_rate() handle freq = 0 to drop performance votes
  opp: Don't overwrite rounded clk rate
  opp: Allocate genpd_virt_devs from dev_pm_opp_attach_genpd()
  opp: Attach genpds to devices from within OPP core

* pm-misc:
  PM / clk: Remove error message on out-of-memory condition
  drivers: base: power: clock_ops: Use of_clk_get_parent_count()

* pm-avs:
  power: avs: smartreflex: no need to check return value of debugfs_create functions

* pm-tools:
  cpupower : frequency-set -r option misses the last cpu in related cpu list
  cpupower: correct spelling of interval
  Add README and update pm-graph and sleepgraph docs
  Update to pm-graph 5.4
  Update to pm-graph 5.3
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/pm_clock.h> #include <linux/pm_clock.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clkdev.h> #include <linux/clkdev.h>
#include <linux/of_clk.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/pm_domain.h> #include <linux/pm_domain.h>
...@@ -92,8 +93,6 @@ static int __pm_clk_add(struct device *dev, const char *con_id, ...@@ -92,8 +93,6 @@ static int __pm_clk_add(struct device *dev, const char *con_id,
if (con_id) { if (con_id) {
ce->con_id = kstrdup(con_id, GFP_KERNEL); ce->con_id = kstrdup(con_id, GFP_KERNEL);
if (!ce->con_id) { if (!ce->con_id) {
dev_err(dev,
"Not enough memory for clock connection ID.\n");
kfree(ce); kfree(ce);
return -ENOMEM; return -ENOMEM;
} }
...@@ -195,8 +194,7 @@ int of_pm_clk_add_clks(struct device *dev) ...@@ -195,8 +194,7 @@ int of_pm_clk_add_clks(struct device *dev)
if (!dev || !dev->of_node) if (!dev || !dev->of_node)
return -EINVAL; return -EINVAL;
count = of_count_phandle_with_args(dev->of_node, "clocks", count = of_clk_get_parent_count(dev->of_node);
"#clock-cells");
if (count <= 0) if (count <= 0)
return -ENODEV; return -ENODEV;
......
...@@ -682,7 +682,7 @@ static int _set_opp_custom(const struct opp_table *opp_table, ...@@ -682,7 +682,7 @@ static int _set_opp_custom(const struct opp_table *opp_table,
data->old_opp.rate = old_freq; data->old_opp.rate = old_freq;
size = sizeof(*old_supply) * opp_table->regulator_count; size = sizeof(*old_supply) * opp_table->regulator_count;
if (IS_ERR(old_supply)) if (!old_supply)
memset(data->old_opp.supplies, 0, size); memset(data->old_opp.supplies, 0, size);
else else
memcpy(data->old_opp.supplies, old_supply, size); memcpy(data->old_opp.supplies, old_supply, size);
...@@ -708,7 +708,7 @@ static int _set_required_opps(struct device *dev, ...@@ -708,7 +708,7 @@ static int _set_required_opps(struct device *dev,
/* Single genpd case */ /* Single genpd case */
if (!genpd_virt_devs) { if (!genpd_virt_devs) {
pstate = opp->required_opps[0]->pstate; pstate = likely(opp) ? opp->required_opps[0]->pstate : 0;
ret = dev_pm_genpd_set_performance_state(dev, pstate); ret = dev_pm_genpd_set_performance_state(dev, pstate);
if (ret) { if (ret) {
dev_err(dev, "Failed to set performance state of %s: %d (%d)\n", dev_err(dev, "Failed to set performance state of %s: %d (%d)\n",
...@@ -726,7 +726,7 @@ static int _set_required_opps(struct device *dev, ...@@ -726,7 +726,7 @@ static int _set_required_opps(struct device *dev,
mutex_lock(&opp_table->genpd_virt_dev_lock); mutex_lock(&opp_table->genpd_virt_dev_lock);
for (i = 0; i < opp_table->required_opp_count; i++) { for (i = 0; i < opp_table->required_opp_count; i++) {
pstate = opp->required_opps[i]->pstate; pstate = likely(opp) ? opp->required_opps[i]->pstate : 0;
if (!genpd_virt_devs[i]) if (!genpd_virt_devs[i])
continue; continue;
...@@ -748,29 +748,37 @@ static int _set_required_opps(struct device *dev, ...@@ -748,29 +748,37 @@ static int _set_required_opps(struct device *dev,
* @dev: device for which we do this operation * @dev: device for which we do this operation
* @target_freq: frequency to achieve * @target_freq: frequency to achieve
* *
* This configures the power-supplies and clock source to the levels specified * This configures the power-supplies to the levels specified by the OPP
* by the OPP corresponding to the target_freq. * corresponding to the target_freq, and programs the clock to a value <=
* target_freq, as rounded by clk_round_rate(). Device wanting to run at fmax
* provided by the opp, should have already rounded to the target OPP's
* frequency.
*/ */
int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
{ {
struct opp_table *opp_table; struct opp_table *opp_table;
unsigned long freq, old_freq; unsigned long freq, old_freq, temp_freq;
struct dev_pm_opp *old_opp, *opp; struct dev_pm_opp *old_opp, *opp;
struct clk *clk; struct clk *clk;
int ret; int ret;
if (unlikely(!target_freq)) {
dev_err(dev, "%s: Invalid target frequency %lu\n", __func__,
target_freq);
return -EINVAL;
}
opp_table = _find_opp_table(dev); opp_table = _find_opp_table(dev);
if (IS_ERR(opp_table)) { if (IS_ERR(opp_table)) {
dev_err(dev, "%s: device opp doesn't exist\n", __func__); dev_err(dev, "%s: device opp doesn't exist\n", __func__);
return PTR_ERR(opp_table); return PTR_ERR(opp_table);
} }
if (unlikely(!target_freq)) {
if (opp_table->required_opp_tables) {
ret = _set_required_opps(dev, opp_table, NULL);
} else {
dev_err(dev, "target frequency can't be 0\n");
ret = -EINVAL;
}
goto put_opp_table;
}
clk = opp_table->clk; clk = opp_table->clk;
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
dev_err(dev, "%s: No clock available for the device\n", dev_err(dev, "%s: No clock available for the device\n",
...@@ -793,13 +801,15 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) ...@@ -793,13 +801,15 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
goto put_opp_table; goto put_opp_table;
} }
old_opp = _find_freq_ceil(opp_table, &old_freq); temp_freq = old_freq;
old_opp = _find_freq_ceil(opp_table, &temp_freq);
if (IS_ERR(old_opp)) { if (IS_ERR(old_opp)) {
dev_err(dev, "%s: failed to find current OPP for freq %lu (%ld)\n", dev_err(dev, "%s: failed to find current OPP for freq %lu (%ld)\n",
__func__, old_freq, PTR_ERR(old_opp)); __func__, old_freq, PTR_ERR(old_opp));
} }
opp = _find_freq_ceil(opp_table, &freq); temp_freq = freq;
opp = _find_freq_ceil(opp_table, &temp_freq);
if (IS_ERR(opp)) { if (IS_ERR(opp)) {
ret = PTR_ERR(opp); ret = PTR_ERR(opp);
dev_err(dev, "%s: failed to find OPP for freq %lu (%d)\n", dev_err(dev, "%s: failed to find OPP for freq %lu (%d)\n",
...@@ -1741,91 +1751,137 @@ void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table) ...@@ -1741,91 +1751,137 @@ void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table)
} }
EXPORT_SYMBOL_GPL(dev_pm_opp_unregister_set_opp_helper); EXPORT_SYMBOL_GPL(dev_pm_opp_unregister_set_opp_helper);
static void _opp_detach_genpd(struct opp_table *opp_table)
{
int index;
for (index = 0; index < opp_table->required_opp_count; index++) {
if (!opp_table->genpd_virt_devs[index])
continue;
dev_pm_domain_detach(opp_table->genpd_virt_devs[index], false);
opp_table->genpd_virt_devs[index] = NULL;
}
kfree(opp_table->genpd_virt_devs);
opp_table->genpd_virt_devs = NULL;
}
/** /**
* dev_pm_opp_set_genpd_virt_dev - Set virtual genpd device for an index * dev_pm_opp_attach_genpd - Attach genpd(s) for the device and save virtual device pointer
* @dev: Consumer device for which the genpd device is getting set. * @dev: Consumer device for which the genpd is getting attached.
* @virt_dev: virtual genpd device. * @names: Null terminated array of pointers containing names of genpd to attach.
* @index: index.
* *
* Multiple generic power domains for a device are supported with the help of * Multiple generic power domains for a device are supported with the help of
* virtual genpd devices, which are created for each consumer device - genpd * virtual genpd devices, which are created for each consumer device - genpd
* pair. These are the device structures which are attached to the power domain * pair. These are the device structures which are attached to the power domain
* and are required by the OPP core to set the performance state of the genpd. * and are required by the OPP core to set the performance state of the genpd.
* The same API also works for the case where single genpd is available and so
* we don't need to support that separately.
* *
* This helper will normally be called by the consumer driver of the device * This helper will normally be called by the consumer driver of the device
* "dev", as only that has details of the genpd devices. * "dev", as only that has details of the genpd names.
* *
* This helper needs to be called once for each of those virtual devices, but * This helper needs to be called once with a list of all genpd to attach.
* only if multiple domains are available for a device. Otherwise the original * Otherwise the original device structure will be used instead by the OPP core.
* device structure will be used instead by the OPP core.
*/ */
struct opp_table *dev_pm_opp_set_genpd_virt_dev(struct device *dev, struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char **names)
struct device *virt_dev,
int index)
{ {
struct opp_table *opp_table; struct opp_table *opp_table;
struct device *virt_dev;
int index, ret = -EINVAL;
const char **name = names;
opp_table = dev_pm_opp_get_opp_table(dev); opp_table = dev_pm_opp_get_opp_table(dev);
if (!opp_table) if (!opp_table)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
/*
* If the genpd's OPP table isn't already initialized, parsing of the
* required-opps fail for dev. We should retry this after genpd's OPP
* table is added.
*/
if (!opp_table->required_opp_count) {
ret = -EPROBE_DEFER;
goto put_table;
}
mutex_lock(&opp_table->genpd_virt_dev_lock); mutex_lock(&opp_table->genpd_virt_dev_lock);
if (unlikely(!opp_table->genpd_virt_devs || opp_table->genpd_virt_devs = kcalloc(opp_table->required_opp_count,
index >= opp_table->required_opp_count || sizeof(*opp_table->genpd_virt_devs),
opp_table->genpd_virt_devs[index])) { GFP_KERNEL);
if (!opp_table->genpd_virt_devs)
goto unlock;
dev_err(dev, "Invalid request to set required device\n"); while (*name) {
dev_pm_opp_put_opp_table(opp_table); index = of_property_match_string(dev->of_node,
mutex_unlock(&opp_table->genpd_virt_dev_lock); "power-domain-names", *name);
if (index < 0) {
dev_err(dev, "Failed to find power domain: %s (%d)\n",
*name, index);
goto err;
}
return ERR_PTR(-EINVAL); if (index >= opp_table->required_opp_count) {
dev_err(dev, "Index can't be greater than required-opp-count - 1, %s (%d : %d)\n",
*name, opp_table->required_opp_count, index);
goto err;
}
if (opp_table->genpd_virt_devs[index]) {
dev_err(dev, "Genpd virtual device already set %s\n",
*name);
goto err;
}
virt_dev = dev_pm_domain_attach_by_name(dev, *name);
if (IS_ERR(virt_dev)) {
ret = PTR_ERR(virt_dev);
dev_err(dev, "Couldn't attach to pm_domain: %d\n", ret);
goto err;
} }
opp_table->genpd_virt_devs[index] = virt_dev; opp_table->genpd_virt_devs[index] = virt_dev;
name++;
}
mutex_unlock(&opp_table->genpd_virt_dev_lock); mutex_unlock(&opp_table->genpd_virt_dev_lock);
return opp_table; return opp_table;
err:
_opp_detach_genpd(opp_table);
unlock:
mutex_unlock(&opp_table->genpd_virt_dev_lock);
put_table:
dev_pm_opp_put_opp_table(opp_table);
return ERR_PTR(ret);
} }
EXPORT_SYMBOL_GPL(dev_pm_opp_attach_genpd);
/** /**
* dev_pm_opp_put_genpd_virt_dev() - Releases resources blocked for genpd device. * dev_pm_opp_detach_genpd() - Detach genpd(s) from the device.
* @opp_table: OPP table returned by dev_pm_opp_set_genpd_virt_dev(). * @opp_table: OPP table returned by dev_pm_opp_attach_genpd().
* @virt_dev: virtual genpd device. *
* * This detaches the genpd(s), resets the virtual device pointers, and puts the
* This releases the resource previously acquired with a call to * OPP table.
* dev_pm_opp_set_genpd_virt_dev(). The consumer driver shall call this helper
* if it doesn't want OPP core to update performance state of a power domain
* anymore.
*/ */
void dev_pm_opp_put_genpd_virt_dev(struct opp_table *opp_table, void dev_pm_opp_detach_genpd(struct opp_table *opp_table)
struct device *virt_dev)
{ {
int i;
/* /*
* Acquire genpd_virt_dev_lock to make sure virt_dev isn't getting * Acquire genpd_virt_dev_lock to make sure virt_dev isn't getting
* used in parallel. * used in parallel.
*/ */
mutex_lock(&opp_table->genpd_virt_dev_lock); mutex_lock(&opp_table->genpd_virt_dev_lock);
_opp_detach_genpd(opp_table);
for (i = 0; i < opp_table->required_opp_count; i++) {
if (opp_table->genpd_virt_devs[i] != virt_dev)
continue;
opp_table->genpd_virt_devs[i] = NULL;
dev_pm_opp_put_opp_table(opp_table);
/* Drop the vote */
dev_pm_genpd_set_performance_state(virt_dev, 0);
break;
}
mutex_unlock(&opp_table->genpd_virt_dev_lock); mutex_unlock(&opp_table->genpd_virt_dev_lock);
if (unlikely(i == opp_table->required_opp_count)) dev_pm_opp_put_opp_table(opp_table);
dev_err(virt_dev, "Failed to find required device entry\n");
} }
EXPORT_SYMBOL_GPL(dev_pm_opp_detach_genpd);
/** /**
* dev_pm_opp_xlate_performance_state() - Find required OPP's pstate for src_table. * dev_pm_opp_xlate_performance_state() - Find required OPP's pstate for src_table.
......
...@@ -138,7 +138,6 @@ static struct opp_table *_find_table_of_opp_np(struct device_node *opp_np) ...@@ -138,7 +138,6 @@ static struct opp_table *_find_table_of_opp_np(struct device_node *opp_np)
static void _opp_table_free_required_tables(struct opp_table *opp_table) static void _opp_table_free_required_tables(struct opp_table *opp_table)
{ {
struct opp_table **required_opp_tables = opp_table->required_opp_tables; struct opp_table **required_opp_tables = opp_table->required_opp_tables;
struct device **genpd_virt_devs = opp_table->genpd_virt_devs;
int i; int i;
if (!required_opp_tables) if (!required_opp_tables)
...@@ -152,10 +151,8 @@ static void _opp_table_free_required_tables(struct opp_table *opp_table) ...@@ -152,10 +151,8 @@ static void _opp_table_free_required_tables(struct opp_table *opp_table)
} }
kfree(required_opp_tables); kfree(required_opp_tables);
kfree(genpd_virt_devs);
opp_table->required_opp_count = 0; opp_table->required_opp_count = 0;
opp_table->genpd_virt_devs = NULL;
opp_table->required_opp_tables = NULL; opp_table->required_opp_tables = NULL;
} }
...@@ -168,9 +165,8 @@ static void _opp_table_alloc_required_tables(struct opp_table *opp_table, ...@@ -168,9 +165,8 @@ static void _opp_table_alloc_required_tables(struct opp_table *opp_table,
struct device_node *opp_np) struct device_node *opp_np)
{ {
struct opp_table **required_opp_tables; struct opp_table **required_opp_tables;
struct device **genpd_virt_devs = NULL;
struct device_node *required_np, *np; struct device_node *required_np, *np;
int count, count_pd, i; int count, i;
/* Traversing the first OPP node is all we need */ /* Traversing the first OPP node is all we need */
np = of_get_next_available_child(opp_np, NULL); np = of_get_next_available_child(opp_np, NULL);
...@@ -183,33 +179,11 @@ static void _opp_table_alloc_required_tables(struct opp_table *opp_table, ...@@ -183,33 +179,11 @@ static void _opp_table_alloc_required_tables(struct opp_table *opp_table,
if (!count) if (!count)
goto put_np; goto put_np;
/*
* Check the number of power-domains to know if we need to deal
* with virtual devices. In some cases we have devices with multiple
* power domains but with only one of them being scalable, hence
* 'count' could be 1, but we still have to deal with multiple genpds
* and virtual devices.
*/
count_pd = of_count_phandle_with_args(dev->of_node, "power-domains",
"#power-domain-cells");
if (!count_pd)
goto put_np;
if (count_pd > 1) {
genpd_virt_devs = kcalloc(count, sizeof(*genpd_virt_devs),
GFP_KERNEL);
if (!genpd_virt_devs)
goto put_np;
}
required_opp_tables = kcalloc(count, sizeof(*required_opp_tables), required_opp_tables = kcalloc(count, sizeof(*required_opp_tables),
GFP_KERNEL); GFP_KERNEL);
if (!required_opp_tables) { if (!required_opp_tables)
kfree(genpd_virt_devs);
goto put_np; goto put_np;
}
opp_table->genpd_virt_devs = genpd_virt_devs;
opp_table->required_opp_tables = required_opp_tables; opp_table->required_opp_tables = required_opp_tables;
opp_table->required_opp_count = count; opp_table->required_opp_count = count;
......
...@@ -899,38 +899,19 @@ static int omap_sr_probe(struct platform_device *pdev) ...@@ -899,38 +899,19 @@ static int omap_sr_probe(struct platform_device *pdev)
} }
dev_info(&pdev->dev, "%s: SmartReflex driver initialized\n", __func__); dev_info(&pdev->dev, "%s: SmartReflex driver initialized\n", __func__);
if (!sr_dbg_dir) { if (!sr_dbg_dir)
sr_dbg_dir = debugfs_create_dir("smartreflex", NULL); sr_dbg_dir = debugfs_create_dir("smartreflex", NULL);
if (IS_ERR_OR_NULL(sr_dbg_dir)) {
ret = PTR_ERR(sr_dbg_dir);
pr_err("%s:sr debugfs dir creation failed(%d)\n",
__func__, ret);
goto err_list_del;
}
}
sr_info->dbg_dir = debugfs_create_dir(sr_info->name, sr_dbg_dir); sr_info->dbg_dir = debugfs_create_dir(sr_info->name, sr_dbg_dir);
if (IS_ERR_OR_NULL(sr_info->dbg_dir)) {
dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n",
__func__);
ret = PTR_ERR(sr_info->dbg_dir);
goto err_debugfs;
}
(void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR, debugfs_create_file("autocomp", S_IRUGO | S_IWUSR, sr_info->dbg_dir,
sr_info->dbg_dir, (void *)sr_info, &pm_sr_fops); (void *)sr_info, &pm_sr_fops);
(void) debugfs_create_x32("errweight", S_IRUGO, sr_info->dbg_dir, debugfs_create_x32("errweight", S_IRUGO, sr_info->dbg_dir,
&sr_info->err_weight); &sr_info->err_weight);
(void) debugfs_create_x32("errmaxlimit", S_IRUGO, sr_info->dbg_dir, debugfs_create_x32("errmaxlimit", S_IRUGO, sr_info->dbg_dir,
&sr_info->err_maxlimit); &sr_info->err_maxlimit);
nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir); nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir);
if (IS_ERR_OR_NULL(nvalue_dir)) {
dev_err(&pdev->dev, "%s: Unable to create debugfs directory for n-values\n",
__func__);
ret = PTR_ERR(nvalue_dir);
goto err_debugfs;
}
if (sr_info->nvalue_count == 0 || !sr_info->nvalue_table) { if (sr_info->nvalue_count == 0 || !sr_info->nvalue_table) {
dev_warn(&pdev->dev, "%s: %s: No Voltage table for the corresponding vdd. Cannot create debugfs entries for n-values\n", dev_warn(&pdev->dev, "%s: %s: No Voltage table for the corresponding vdd. Cannot create debugfs entries for n-values\n",
...@@ -945,11 +926,11 @@ static int omap_sr_probe(struct platform_device *pdev) ...@@ -945,11 +926,11 @@ static int omap_sr_probe(struct platform_device *pdev)
snprintf(name, sizeof(name), "volt_%lu", snprintf(name, sizeof(name), "volt_%lu",
sr_info->nvalue_table[i].volt_nominal); sr_info->nvalue_table[i].volt_nominal);
(void) debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir, debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir,
&(sr_info->nvalue_table[i].nvalue)); &(sr_info->nvalue_table[i].nvalue));
snprintf(name, sizeof(name), "errminlimit_%lu", snprintf(name, sizeof(name), "errminlimit_%lu",
sr_info->nvalue_table[i].volt_nominal); sr_info->nvalue_table[i].volt_nominal);
(void) debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir, debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir,
&(sr_info->nvalue_table[i].errminlimit)); &(sr_info->nvalue_table[i].errminlimit));
} }
......
...@@ -128,8 +128,8 @@ struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char * name); ...@@ -128,8 +128,8 @@ struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char * name);
void dev_pm_opp_put_clkname(struct opp_table *opp_table); void dev_pm_opp_put_clkname(struct opp_table *opp_table);
struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data)); struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data));
void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table); void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table);
struct opp_table *dev_pm_opp_set_genpd_virt_dev(struct device *dev, struct device *virt_dev, int index); struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char **names);
void dev_pm_opp_put_genpd_virt_dev(struct opp_table *opp_table, struct device *virt_dev); void dev_pm_opp_detach_genpd(struct opp_table *opp_table);
int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate); int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate);
int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq); int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq);
int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask); int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask);
...@@ -292,12 +292,12 @@ static inline struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const ...@@ -292,12 +292,12 @@ static inline struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const
static inline void dev_pm_opp_put_clkname(struct opp_table *opp_table) {} static inline void dev_pm_opp_put_clkname(struct opp_table *opp_table) {}
static inline struct opp_table *dev_pm_opp_set_genpd_virt_dev(struct device *dev, struct device *virt_dev, int index) static inline struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char **names)
{ {
return ERR_PTR(-ENOTSUPP); return ERR_PTR(-ENOTSUPP);
} }
static inline void dev_pm_opp_put_genpd_virt_dev(struct opp_table *opp_table, struct device *virt_dev) {} static inline void dev_pm_opp_detach_genpd(struct opp_table *opp_table) {}
static inline int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate) static inline int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate)
{ {
......
...@@ -61,7 +61,7 @@ Only display specific monitors. Use the monitor string(s) provided by \-l option ...@@ -61,7 +61,7 @@ Only display specific monitors. Use the monitor string(s) provided by \-l option
.PP .PP
\-i seconds \-i seconds
.RS 4 .RS 4
Measure intervall. Measure interval.
.RE .RE
.PP .PP
\-c \-c
......
...@@ -98,7 +98,7 @@ msgstr "" ...@@ -98,7 +98,7 @@ msgstr ""
#: utils/idle_monitor/cpupower-monitor.c:74 #: utils/idle_monitor/cpupower-monitor.c:74
#, c-format #, c-format
msgid "\t -i: time intervall to measure for in seconds (default 1)\n" msgid "\t -i: time interval to measure for in seconds (default 1)\n"
msgstr "" msgstr ""
#: utils/idle_monitor/cpupower-monitor.c:75 #: utils/idle_monitor/cpupower-monitor.c:75
......
...@@ -95,7 +95,7 @@ msgstr "" ...@@ -95,7 +95,7 @@ msgstr ""
#: utils/idle_monitor/cpupower-monitor.c:74 #: utils/idle_monitor/cpupower-monitor.c:74
#, c-format #, c-format
msgid "\t -i: time intervall to measure for in seconds (default 1)\n" msgid "\t -i: time interval to measure for in seconds (default 1)\n"
msgstr "" msgstr ""
#: utils/idle_monitor/cpupower-monitor.c:75 #: utils/idle_monitor/cpupower-monitor.c:75
......
...@@ -95,7 +95,7 @@ msgstr "" ...@@ -95,7 +95,7 @@ msgstr ""
#: utils/idle_monitor/cpupower-monitor.c:74 #: utils/idle_monitor/cpupower-monitor.c:74
#, c-format #, c-format
msgid "\t -i: time intervall to measure for in seconds (default 1)\n" msgid "\t -i: time interval to measure for in seconds (default 1)\n"
msgstr "" msgstr ""
#: utils/idle_monitor/cpupower-monitor.c:75 #: utils/idle_monitor/cpupower-monitor.c:75
......
...@@ -95,7 +95,7 @@ msgstr "" ...@@ -95,7 +95,7 @@ msgstr ""
#: utils/idle_monitor/cpupower-monitor.c:74 #: utils/idle_monitor/cpupower-monitor.c:74
#, c-format #, c-format
msgid "\t -i: time intervall to measure for in seconds (default 1)\n" msgid "\t -i: time interval to measure for in seconds (default 1)\n"
msgstr "" msgstr ""
#: utils/idle_monitor/cpupower-monitor.c:75 #: utils/idle_monitor/cpupower-monitor.c:75
......
...@@ -93,7 +93,7 @@ msgstr "" ...@@ -93,7 +93,7 @@ msgstr ""
#: utils/idle_monitor/cpupower-monitor.c:74 #: utils/idle_monitor/cpupower-monitor.c:74
#, c-format #, c-format
msgid "\t -i: time intervall to measure for in seconds (default 1)\n" msgid "\t -i: time interval to measure for in seconds (default 1)\n"
msgstr "" msgstr ""
#: utils/idle_monitor/cpupower-monitor.c:75 #: utils/idle_monitor/cpupower-monitor.c:75
......
...@@ -305,6 +305,8 @@ int cmd_freq_set(int argc, char **argv) ...@@ -305,6 +305,8 @@ int cmd_freq_set(int argc, char **argv)
bitmask_setbit(cpus_chosen, cpus->cpu); bitmask_setbit(cpus_chosen, cpus->cpu);
cpus = cpus->next; cpus = cpus->next;
} }
/* Set the last cpu in related cpus list */
bitmask_setbit(cpus_chosen, cpus->cpu);
cpufreq_put_related_cpus(cpus); cpufreq_put_related_cpus(cpus);
} }
} }
......
This diff is collapsed.
...@@ -325,9 +325,9 @@ def parseKernelLog(): ...@@ -325,9 +325,9 @@ def parseKernelLog():
if(not sysvals.stamp['kernel']): if(not sysvals.stamp['kernel']):
sysvals.stamp['kernel'] = sysvals.kernelVersion(msg) sysvals.stamp['kernel'] = sysvals.kernelVersion(msg)
continue continue
m = re.match('.* setting system clock to (?P<t>.*) UTC.*', msg) m = re.match('.* setting system clock to (?P<d>[0-9\-]*)[ A-Z](?P<t>[0-9:]*) UTC.*', msg)
if(m): if(m):
bt = datetime.strptime(m.group('t'), '%Y-%m-%d %H:%M:%S') bt = datetime.strptime(m.group('d')+' '+m.group('t'), '%Y-%m-%d %H:%M:%S')
bt = bt - timedelta(seconds=int(ktime)) bt = bt - timedelta(seconds=int(ktime))
data.boottime = bt.strftime('%Y-%m-%d_%H:%M:%S') data.boottime = bt.strftime('%Y-%m-%d_%H:%M:%S')
sysvals.stamp['time'] = bt.strftime('%B %d %Y, %I:%M:%S %p') sysvals.stamp['time'] = bt.strftime('%B %d %Y, %I:%M:%S %p')
...@@ -348,7 +348,7 @@ def parseKernelLog(): ...@@ -348,7 +348,7 @@ def parseKernelLog():
data.newAction(phase, f, pid, start, ktime, int(r), int(t)) data.newAction(phase, f, pid, start, ktime, int(r), int(t))
del devtemp[f] del devtemp[f]
continue continue
if(re.match('^Freeing unused kernel memory.*', msg)): if(re.match('^Freeing unused kernel .*', msg)):
data.tUserMode = ktime data.tUserMode = ktime
data.dmesg['kernel']['end'] = ktime data.dmesg['kernel']['end'] = ktime
data.dmesg['user']['start'] = ktime data.dmesg['user']['start'] = ktime
...@@ -1008,7 +1008,7 @@ if __name__ == '__main__': ...@@ -1008,7 +1008,7 @@ if __name__ == '__main__':
updateKernelParams() updateKernelParams()
elif cmd == 'flistall': elif cmd == 'flistall':
for f in sysvals.getBootFtraceFilterFunctions(): for f in sysvals.getBootFtraceFilterFunctions():
print f print(f)
elif cmd == 'checkbl': elif cmd == 'checkbl':
sysvals.getBootLoader() sysvals.getBootLoader()
pprint('Boot Loader: %s\n%s' % (sysvals.bootloader, sysvals.blexec)) pprint('Boot Loader: %s\n%s' % (sysvals.bootloader, sysvals.blexec))
......
...@@ -98,12 +98,34 @@ postdelay: 0 ...@@ -98,12 +98,34 @@ postdelay: 0
# graph only devices longer than min in the timeline (default: 0.001 ms) # graph only devices longer than min in the timeline (default: 0.001 ms)
mindev: 0.001 mindev: 0.001
# Call Loop Max Gap (dev mode only)
# merge loops of the same call if each is less than maxgap apart (def: 100us)
callloop-maxgap: 0.0001
# Call Loop Max Length (dev mode only)
# merge loops of the same call if each is less than maxlen in length (def: 5ms)
callloop-maxlen: 0.005
# Override default timeline entries:
# Do not use the internal default functions for timeline entries (def: false)
# Set this to true if you intend to only use the ones defined in the config
override-timeline-functions: true
# Override default dev timeline entries:
# Do not use the internal default functions for dev timeline entries (def: false)
# Set this to true if you intend to only use the ones defined in the config
override-dev-timeline-functions: true
# ---- Debug Options ---- # ---- Debug Options ----
# Callgraph # Callgraph
# gather detailed ftrace callgraph data on all timeline events (default: false) # gather detailed ftrace callgraph data on all timeline events (default: false)
callgraph: false callgraph: false
# Max graph depth
# limit the callgraph trace to this depth (default: 0 = all)
maxdepth: 2
# Callgraph phase filter # Callgraph phase filter
# Only enable callgraphs for one phase, i.e. resume_noirq (default: all) # Only enable callgraphs for one phase, i.e. resume_noirq (default: all)
cgphase: suspend cgphase: suspend
...@@ -131,3 +153,7 @@ timeprec: 6 ...@@ -131,3 +153,7 @@ timeprec: 6
# Add kprobe functions to the timeline # Add kprobe functions to the timeline
# Add functions to the timeline from a text file (default: no-action) # Add functions to the timeline from a text file (default: no-action)
# fadd: file.txt # fadd: file.txt
# Ftrace buffer size
# Set trace buffer size to N kilo-bytes (default: all of free memory up to 3GB)
# bufsize: 1000
...@@ -53,6 +53,11 @@ disable rtcwake and require a user keypress to resume. ...@@ -53,6 +53,11 @@ disable rtcwake and require a user keypress to resume.
Add the dmesg and ftrace logs to the html output. They will be viewable by Add the dmesg and ftrace logs to the html output. They will be viewable by
clicking buttons in the timeline. clicking buttons in the timeline.
.TP .TP
\fB-turbostat\fR
Use turbostat to execute the command in freeze mode (default: disabled). This
will provide turbostat output in the log which will tell you which actual
power modes were entered.
.TP
\fB-result \fIfile\fR \fB-result \fIfile\fR
Export a results table to a text file for parsing. Export a results table to a text file for parsing.
.TP .TP
...@@ -121,6 +126,10 @@ be created in a new subdirectory with a summary page: suspend-xN-{date}-{time}. ...@@ -121,6 +126,10 @@ be created in a new subdirectory with a summary page: suspend-xN-{date}-{time}.
Use ftrace to create device callgraphs (default: disabled). This can produce Use ftrace to create device callgraphs (default: disabled). This can produce
very large outputs, i.e. 10MB - 100MB. very large outputs, i.e. 10MB - 100MB.
.TP .TP
\fB-ftop\fR
Use ftrace on the top level call: "suspend_devices_and_enter" only (default: disabled).
This option implies -f and creates a single callgraph covering all of suspend/resume.
.TP
\fB-maxdepth \fIlevel\fR \fB-maxdepth \fIlevel\fR
limit the callgraph trace depth to \fIlevel\fR (default: 0=all). This is limit the callgraph trace depth to \fIlevel\fR (default: 0=all). This is
the best way to limit the output size when using callgraphs via -f. the best way to limit the output size when using callgraphs via -f.
...@@ -138,8 +147,8 @@ which are barely visible in the timeline. ...@@ -138,8 +147,8 @@ which are barely visible in the timeline.
The value is a float: e.g. 0.001 represents 1 us. The value is a float: e.g. 0.001 represents 1 us.
.TP .TP
\fB-cgfilter \fI"func1,func2,..."\fR \fB-cgfilter \fI"func1,func2,..."\fR
Reduce callgraph output in the timeline by limiting it to a list of calls. The Reduce callgraph output in the timeline by limiting it certain devices. The
argument can be a single function name or a comma delimited list. argument can be a single device name or a comma delimited list.
(default: none) (default: none)
.TP .TP
\fB-cgskip \fIfile\fR \fB-cgskip \fIfile\fR
...@@ -183,6 +192,9 @@ Print out the contents of the ACPI Firmware Performance Data Table. ...@@ -183,6 +192,9 @@ Print out the contents of the ACPI Firmware Performance Data Table.
\fB-battery\fR \fB-battery\fR
Print out battery status and current charge. Print out battery status and current charge.
.TP .TP
\fB-wifi\fR
Print out wifi status and connection details.
.TP
\fB-xon/-xoff/-xstandby/-xsuspend\fR \fB-xon/-xoff/-xstandby/-xsuspend\fR
Test xset by attempting to switch the display to the given mode. This Test xset by attempting to switch the display to the given mode. This
is the same command which will be issued by \fB-display \fImode\fR. is the same command which will be issued by \fB-display \fImode\fR.
......
This diff is collapsed.
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