Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 375720
b: refs/heads/master
c: 49a9e43
h: refs/heads/master
v: v3
  • Loading branch information
Rafael J. Wysocki committed May 16, 2013
1 parent a21e26c commit 7f6c673
Show file tree
Hide file tree
Showing 19 changed files with 115 additions and 175 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7a26b53070f0099dfcfc9d499458de861c5c4859
refs/heads/master: 49a9e4315d40e1ba1d3258ea33f3948254038455
15 changes: 8 additions & 7 deletions trunk/Documentation/power/devices.txt
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ situations.
System Power Management Phases
------------------------------
Suspending or resuming the system is done in several phases. Different phases
are used for standby or memory sleep states ("suspend-to-RAM") and the
are used for freeze, standby, and memory sleep states ("suspend-to-RAM") and the
hibernation state ("suspend-to-disk"). Each phase involves executing callbacks
for every device before the next phase begins. Not all busses or classes
support all these callbacks and not all drivers use all the callbacks. The
Expand Down Expand Up @@ -309,7 +309,8 @@ execute the corresponding method from dev->driver->pm instead if there is one.

Entering System Suspend
-----------------------
When the system goes into the standby or memory sleep state, the phases are:
When the system goes into the freeze, standby or memory sleep state,
the phases are:

prepare, suspend, suspend_late, suspend_noirq.

Expand Down Expand Up @@ -368,7 +369,7 @@ the devices that were suspended.

Leaving System Suspend
----------------------
When resuming from standby or memory sleep, the phases are:
When resuming from freeze, standby or memory sleep, the phases are:

resume_noirq, resume_early, resume, complete.

Expand Down Expand Up @@ -433,8 +434,8 @@ the system log.

Entering Hibernation
--------------------
Hibernating the system is more complicated than putting it into the standby or
memory sleep state, because it involves creating and saving a system image.
Hibernating the system is more complicated than putting it into the other
sleep states, because it involves creating and saving a system image.
Therefore there are more phases for hibernation, with a different set of
callbacks. These phases always run after tasks have been frozen and memory has
been freed.
Expand Down Expand Up @@ -485,8 +486,8 @@ image forms an atomic snapshot of the system state.

At this point the system image is saved, and the devices then need to be
prepared for the upcoming system shutdown. This is much like suspending them
before putting the system into the standby or memory sleep state, and the phases
are similar.
before putting the system into the freeze, standby or memory sleep state,
and the phases are similar.

9. The prepare phase is discussed above.

Expand Down
4 changes: 2 additions & 2 deletions trunk/Documentation/power/interface.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ running. The interface exists in /sys/power/ directory (assuming sysfs
is mounted at /sys).

/sys/power/state controls system power state. Reading from this file
returns what states are supported, which is hard-coded to 'standby'
(Power-On Suspend), 'mem' (Suspend-to-RAM), and 'disk'
returns what states are supported, which is hard-coded to 'freeze',
'standby' (Power-On Suspend), 'mem' (Suspend-to-RAM), and 'disk'
(Suspend-to-Disk).

Writing to this file one of those strings causes the system to
Expand Down
6 changes: 4 additions & 2 deletions trunk/Documentation/power/notifiers.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ A suspend/hibernation notifier may be used for this purpose.
The subsystems or drivers having such needs can register suspend notifiers that
will be called upon the following events by the PM core:

PM_HIBERNATION_PREPARE The system is going to hibernate or suspend, tasks will
be frozen immediately.
PM_HIBERNATION_PREPARE The system is going to hibernate, tasks will be frozen
immediately. This is different from PM_SUSPEND_PREPARE
below because here we do additional work between notifiers
and drivers freezing.

PM_POST_HIBERNATION The system memory state has been restored from a
hibernation image or an error occurred during
Expand Down
30 changes: 17 additions & 13 deletions trunk/Documentation/power/states.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,26 @@
System Power Management States


The kernel supports three power management states generically, though
each is dependent on platform support code to implement the low-level
details for each state. This file describes each state, what they are
The kernel supports four power management states generically, though
one is generic and the other three are dependent on platform support
code to implement the low-level details for each state.
This file describes each state, what they are
commonly called, what ACPI state they map to, and what string to write
to /sys/power/state to enter that state

state: Freeze / Low-Power Idle
ACPI state: S0
String: "freeze"

This state is a generic, pure software, light-weight, low-power state.
It allows more energy to be saved relative to idle by freezing user
space and putting all I/O devices into low-power states (possibly
lower-power than available at run time), such that the processors can
spend more time in their idle states.
This state can be used for platforms without Standby/Suspend-to-RAM
support, or it can be used in addition to Suspend-to-RAM (memory sleep)
to provide reduced resume latency.


State: Standby / Power-On Suspend
ACPI State: S1
Expand All @@ -22,9 +36,6 @@ We try to put devices in a low-power state equivalent to D1, which
also offers low power savings, but low resume latency. Not all devices
support D1, and those that don't are left on.

A transition from Standby to the On state should take about 1-2
seconds.


State: Suspend-to-RAM
ACPI State: S3
Expand All @@ -42,9 +53,6 @@ transition back to the On state.
For at least ACPI, STR requires some minimal boot-strapping code to
resume the system from STR. This may be true on other platforms.

A transition from Suspend-to-RAM to the On state should take about
3-5 seconds.


State: Suspend-to-disk
ACPI State: S4
Expand Down Expand Up @@ -74,7 +82,3 @@ low-power state (like ACPI S4), or it may simply power down. Powering
down offers greater savings, and allows this mechanism to work on any
system. However, entering a real low-power state allows the user to
trigger wake up events (e.g. pressing a key or opening a laptop lid).

A transition from Suspend-to-Disk to the On state should take about 30
seconds, though it's typically a bit more with the current
implementation.
12 changes: 6 additions & 6 deletions trunk/drivers/base/power/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,24 +61,24 @@ EXPORT_SYMBOL_GPL(dev_pm_get_subsys_data);
int dev_pm_put_subsys_data(struct device *dev)
{
struct pm_subsys_data *psd;
int ret = 0;
int ret = 1;

spin_lock_irq(&dev->power.lock);

psd = dev_to_psd(dev);
if (!psd) {
ret = -EINVAL;
if (!psd)
goto out;
}

if (--psd->refcount == 0) {
dev->power.subsys_data = NULL;
kfree(psd);
ret = 1;
} else {
psd = NULL;
ret = 0;
}

out:
spin_unlock_irq(&dev->power.lock);
kfree(psd);

return ret;
}
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/cpufreq/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ config CPU_FREQ_STAT_DETAILS

choice
prompt "Default CPUFreq governor"
default CPU_FREQ_DEFAULT_GOV_USERSPACE if CPU_FREQ_SA1100 || CPU_FREQ_SA1110
default CPU_FREQ_DEFAULT_GOV_USERSPACE if ARM_SA1100_CPUFREQ || ARM_SA1110_CPUFREQ
default CPU_FREQ_DEFAULT_GOV_PERFORMANCE
help
This option sets which CPUFreq governor shall be loaded at
Expand Down
15 changes: 8 additions & 7 deletions trunk/drivers/cpufreq/Kconfig.arm
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@
#

config ARM_BIG_LITTLE_CPUFREQ
tristate
depends on ARM_CPU_TOPOLOGY
tristate "Generic ARM big LITTLE CPUfreq driver"
depends on ARM_CPU_TOPOLOGY && PM_OPP && HAVE_CLK
help
This enables the Generic CPUfreq driver for ARM big.LITTLE platforms.

config ARM_DT_BL_CPUFREQ
tristate "Generic ARM big LITTLE CPUfreq driver probed via DT"
select ARM_BIG_LITTLE_CPUFREQ
depends on OF && HAVE_CLK
tristate "Generic probing via DT for ARM big LITTLE CPUfreq driver"
depends on ARM_BIG_LITTLE_CPUFREQ && OF
help
This enables the Generic CPUfreq driver for ARM big.LITTLE platform.
This gets frequency tables from DT.
This enables probing via DT for Generic CPUfreq driver for ARM
big.LITTLE platform. This gets frequency tables from DT.

config ARM_EXYNOS_CPUFREQ
bool "SAMSUNG EXYNOS SoCs"
Expand Down
7 changes: 1 addition & 6 deletions trunk/drivers/cpufreq/arm_big_little.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,6 @@ static struct clk *clk[MAX_CLUSTERS];
static struct cpufreq_frequency_table *freq_table[MAX_CLUSTERS];
static atomic_t cluster_usage[MAX_CLUSTERS] = {ATOMIC_INIT(0), ATOMIC_INIT(0)};

static int cpu_to_cluster(int cpu)
{
return topology_physical_package_id(cpu);
}

static unsigned int bL_cpufreq_get(unsigned int cpu)
{
u32 cur_cluster = cpu_to_cluster(cpu);
Expand Down Expand Up @@ -192,7 +187,7 @@ static int bL_cpufreq_init(struct cpufreq_policy *policy)

cpumask_copy(policy->cpus, topology_core_cpumask(policy->cpu));

dev_info(cpu_dev, "CPU %d initialized\n", policy->cpu);
dev_info(cpu_dev, "%s: CPU %d initialized\n", __func__, policy->cpu);
return 0;
}

Expand Down
5 changes: 5 additions & 0 deletions trunk/drivers/cpufreq/arm_big_little.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ struct cpufreq_arm_bL_ops {
int (*init_opp_table)(struct device *cpu_dev);
};

static inline int cpu_to_cluster(int cpu)
{
return topology_physical_package_id(cpu);
}

int bL_cpufreq_register(struct cpufreq_arm_bL_ops *ops);
void bL_cpufreq_unregister(struct cpufreq_arm_bL_ops *ops);

Expand Down
9 changes: 5 additions & 4 deletions trunk/drivers/cpufreq/arm_big_little_dt.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ static int dt_get_transition_latency(struct device *cpu_dev)

parent = of_find_node_by_path("/cpus");
if (!parent) {
pr_err("failed to find OF /cpus\n");
return -ENOENT;
pr_info("Failed to find OF /cpus. Use CPUFREQ_ETERNAL transition latency\n");
return CPUFREQ_ETERNAL;
}

for_each_child_of_node(parent, np) {
Expand All @@ -78,10 +78,11 @@ static int dt_get_transition_latency(struct device *cpu_dev)
of_node_put(np);
of_node_put(parent);

return 0;
return transition_latency;
}

return -ENODEV;
pr_info("clock-latency isn't found, use CPUFREQ_ETERNAL transition latency\n");
return CPUFREQ_ETERNAL;
}

static struct cpufreq_arm_bL_ops dt_bL_ops = {
Expand Down
27 changes: 20 additions & 7 deletions trunk/drivers/cpufreq/cpufreq-cpu0.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,25 +189,36 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev)

if (!np) {
pr_err("failed to find cpu0 node\n");
return -ENOENT;
ret = -ENOENT;
goto out_put_parent;
}

cpu_dev = &pdev->dev;
cpu_dev->of_node = np;

cpu_reg = devm_regulator_get(cpu_dev, "cpu0");
if (IS_ERR(cpu_reg)) {
/*
* If cpu0 regulator supply node is present, but regulator is
* not yet registered, we should try defering probe.
*/
if (PTR_ERR(cpu_reg) == -EPROBE_DEFER) {
dev_err(cpu_dev, "cpu0 regulator not ready, retry\n");
ret = -EPROBE_DEFER;
goto out_put_node;
}
pr_warn("failed to get cpu0 regulator: %ld\n",
PTR_ERR(cpu_reg));
cpu_reg = NULL;
}

cpu_clk = devm_clk_get(cpu_dev, NULL);
if (IS_ERR(cpu_clk)) {
ret = PTR_ERR(cpu_clk);
pr_err("failed to get cpu0 clock: %d\n", ret);
goto out_put_node;
}

cpu_reg = devm_regulator_get(cpu_dev, "cpu0");
if (IS_ERR(cpu_reg)) {
pr_warn("failed to get cpu0 regulator\n");
cpu_reg = NULL;
}

ret = of_init_opp_table(cpu_dev);
if (ret) {
pr_err("failed to init OPP table: %d\n", ret);
Expand Down Expand Up @@ -264,6 +275,8 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev)
opp_free_cpufreq_table(cpu_dev, &freq_table);
out_put_node:
of_node_put(np);
out_put_parent:
of_node_put(parent);
return ret;
}

Expand Down
10 changes: 4 additions & 6 deletions trunk/drivers/cpufreq/cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -1075,14 +1075,14 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif
__func__, cpu_dev->id, cpu);
}

if ((cpus == 1) && (cpufreq_driver->target))
__cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT);

pr_debug("%s: removing link, cpu: %d\n", __func__, cpu);
cpufreq_cpu_put(data);

/* If cpu is last user of policy, free policy */
if (cpus == 1) {
if (cpufreq_driver->target)
__cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT);

lock_policy_rwsem_read(cpu);
kobj = &data->kobj;
cmp = &data->kobj_unregister;
Expand Down Expand Up @@ -1832,15 +1832,13 @@ static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
if (dev) {
switch (action) {
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
cpufreq_add_dev(dev, NULL);
break;
case CPU_DOWN_PREPARE:
case CPU_DOWN_PREPARE_FROZEN:
case CPU_UP_CANCELED_FROZEN:
__cpufreq_remove_dev(dev, NULL);
break;
case CPU_DOWN_FAILED:
case CPU_DOWN_FAILED_FROZEN:
cpufreq_add_dev(dev, NULL);
break;
}
Expand Down
11 changes: 7 additions & 4 deletions trunk/drivers/cpufreq/cpufreq_governor.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
if (have_governor_per_policy()) {
WARN_ON(dbs_data);
} else if (dbs_data) {
dbs_data->usage_count++;
policy->governor_data = dbs_data;
return 0;
}
Expand All @@ -266,6 +267,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
}

dbs_data->cdata = cdata;
dbs_data->usage_count = 1;
rc = cdata->init(dbs_data);
if (rc) {
pr_err("%s: POLICY_INIT: init() failed\n", __func__);
Expand Down Expand Up @@ -294,7 +296,8 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
set_sampling_rate(dbs_data, max(dbs_data->min_sampling_rate,
latency * LATENCY_MULTIPLIER));

if (dbs_data->cdata->governor == GOV_CONSERVATIVE) {
if ((cdata->governor == GOV_CONSERVATIVE) &&
(!policy->governor->initialized)) {
struct cs_ops *cs_ops = dbs_data->cdata->gov_ops;

cpufreq_register_notifier(cs_ops->notifier_block,
Expand All @@ -306,12 +309,12 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,

return 0;
case CPUFREQ_GOV_POLICY_EXIT:
if ((policy->governor->initialized == 1) ||
have_governor_per_policy()) {
if (!--dbs_data->usage_count) {
sysfs_remove_group(get_governor_parent_kobj(policy),
get_sysfs_attr(dbs_data));

if (dbs_data->cdata->governor == GOV_CONSERVATIVE) {
if ((dbs_data->cdata->governor == GOV_CONSERVATIVE) &&
(policy->governor->initialized == 1)) {
struct cs_ops *cs_ops = dbs_data->cdata->gov_ops;

cpufreq_unregister_notifier(cs_ops->notifier_block,
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/cpufreq/cpufreq_governor.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ struct common_dbs_data {
struct dbs_data {
struct common_dbs_data *cdata;
unsigned int min_sampling_rate;
int usage_count;
void *tuners;

/* dbs_mutex protects dbs_enable in governor start/stop */
Expand Down
Loading

0 comments on commit 7f6c673

Please sign in to comment.