Power management and ACPI fixes for 3.10-rc3

- Additional CPU ID for the intel_pstate driver from Dirk Brandewie.
 
 - More cpufreq fixes related to ARM big.LITTLE support and locking from
   Viresh Kumar.
 
 - VIA C7 cpufreq build fix from Rafał Bilski.
 
 - ACPI power management fix making it possible to use device power
   states regardless of the CONFIG_PM setting from Rafael J. Wysocki.
 
 - New ACPI video blacklist item from Bastian Triller.
 
 /
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.19 (GNU/Linux)
 
 iQIcBAABAgAGBQJRoRZjAAoJEKhOf7ml8uNsv9wQAKAMs9J8k6XqgNPisFKetw+K
 hzCOsKFOpI0BQKFikgtWjhGre1SyNIRUvLXO7BHFHXYQW6cLvn1jAyJhvl+i4nvT
 eOa+vdGd6grWncbhIxeidoyk9hTZ6bdMWlTBvKUz5KpHzvp4YGC2jlvwFwqsJkpg
 nQ8Hcbrbhm4vz5h7EmrlYcELBNTi5LQtmnqlxtbn02GX75BFTpkCm5aLZWZNEUrE
 Hix8BhN41+hSy+K34ztHFlP5g/s/lIa9dOX1tewqSigkDB/qYYIt2lpdD2icOIOW
 qHAtvpZq8/fZOcoZ9KdFqKUjjbuKVavldb+YzGeTLQufOAwb4hgMRvAccdNFMHIW
 9tVkp2TcK6K7pAYlXtgEf25ka7ulLWDBd4C662gZfpi+oPKx2BI/6m7J4VoTULeb
 30hDMyZXrXWWvStwO05Pyno3W5lG+cn9jytc3hKkaFerb53NHcZHfb0Rih5NhDZD
 Ep09IuPE8fOT9KndY2kw/WwoZyJurYCbrgE+G1QyA+hsNPkNhPlGTxdL8vCqxM4K
 ZOaQQejpd1bXBSk8Koz8LRyQ38KJByvM64B0EDSP6BQUT+rlbkcvog1bJV+UdpbJ
 4TlhrAFlobhRFQBqlIbRqMXFPH31YSm7wVK1eK/gEqNZI935Kd17YSFf8yyi2yli
 vBlmPkiPEIJHysps+tvd
 =Srt8
 -----END PGP SIGNATURE-----

Merge tag 'pm+acpi-3.10-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull power management and ACPI fixes from Rafael Wysocki:

 - Additional CPU ID for the intel_pstate driver from Dirk Brandewie.

 - More cpufreq fixes related to ARM big.LITTLE support and locking from
   Viresh Kumar.

 - VIA C7 cpufreq build fix from Rafał Bilski.

 - ACPI power management fix making it possible to use device power
   states regardless of the CONFIG_PM setting from Rafael J Wysocki.

 - New ACPI video blacklist item from Bastian Triller.

* tag 'pm+acpi-3.10-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  ACPI / video: Add "Asus UL30A" to ACPI video detect blacklist
  cpufreq: arm_big_little_dt: Instantiate as platform_driver
  cpufreq: arm_big_little_dt: Register driver only if DT has valid data
  cpufreq / e_powersaver: Fix linker error when ACPI processor is a module
  cpufreq / intel_pstate: Add additional supported CPU ID
  cpufreq: Drop rwsem lock around CPUFREQ_GOV_POLICY_EXIT
  ACPI / PM: Allow device power states to be used for CONFIG_PM unset
This commit is contained in:
Linus Torvalds 2013-05-25 20:32:00 -07:00
commit 1aad08dc57
8 changed files with 144 additions and 137 deletions

View file

@ -272,7 +272,7 @@ config X86_LONGHAUL
config X86_E_POWERSAVER
tristate "VIA C7 Enhanced PowerSaver (DANGEROUS)"
select CPU_FREQ_TABLE
depends on X86_32
depends on X86_32 && ACPI_PROCESSOR
help
This adds the CPUFreq driver for VIA C7 processors. However, this driver
does not have any safeguards to prevent operating the CPU out of spec

View file

@ -19,70 +19,75 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/cpu.h>
#include <linux/cpufreq.h>
#include <linux/device.h>
#include <linux/export.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/opp.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/types.h>
#include "arm_big_little.h"
static int dt_init_opp_table(struct device *cpu_dev)
/* get cpu node with valid operating-points */
static struct device_node *get_cpu_node_with_valid_op(int cpu)
{
struct device_node *np, *parent;
int count = 0, ret;
parent = of_find_node_by_path("/cpus");
if (!parent) {
pr_err("failed to find OF /cpus\n");
return -ENOENT;
}
for_each_child_of_node(parent, np) {
if (count++ != cpu_dev->id)
continue;
if (!of_get_property(np, "operating-points", NULL)) {
ret = -ENODATA;
} else {
cpu_dev->of_node = np;
ret = of_init_opp_table(cpu_dev);
}
of_node_put(np);
of_node_put(parent);
return ret;
}
return -ENODEV;
}
static int dt_get_transition_latency(struct device *cpu_dev)
{
struct device_node *np, *parent;
u32 transition_latency = CPUFREQ_ETERNAL;
struct device_node *np = NULL, *parent;
int count = 0;
parent = of_find_node_by_path("/cpus");
if (!parent) {
pr_info("Failed to find OF /cpus. Use CPUFREQ_ETERNAL transition latency\n");
return CPUFREQ_ETERNAL;
pr_err("failed to find OF /cpus\n");
return NULL;
}
for_each_child_of_node(parent, np) {
if (count++ != cpu_dev->id)
if (count++ != cpu)
continue;
if (!of_get_property(np, "operating-points", NULL)) {
of_node_put(np);
np = NULL;
}
of_property_read_u32(np, "clock-latency", &transition_latency);
of_node_put(np);
of_node_put(parent);
return transition_latency;
break;
}
pr_info("clock-latency isn't found, use CPUFREQ_ETERNAL transition latency\n");
return CPUFREQ_ETERNAL;
of_node_put(parent);
return np;
}
static int dt_init_opp_table(struct device *cpu_dev)
{
struct device_node *np;
int ret;
np = get_cpu_node_with_valid_op(cpu_dev->id);
if (!np)
return -ENODATA;
cpu_dev->of_node = np;
ret = of_init_opp_table(cpu_dev);
of_node_put(np);
return ret;
}
static int dt_get_transition_latency(struct device *cpu_dev)
{
struct device_node *np;
u32 transition_latency = CPUFREQ_ETERNAL;
np = get_cpu_node_with_valid_op(cpu_dev->id);
if (!np)
return CPUFREQ_ETERNAL;
of_property_read_u32(np, "clock-latency", &transition_latency);
of_node_put(np);
pr_debug("%s: clock-latency: %d\n", __func__, transition_latency);
return transition_latency;
}
static struct cpufreq_arm_bL_ops dt_bL_ops = {
@ -91,17 +96,33 @@ static struct cpufreq_arm_bL_ops dt_bL_ops = {
.init_opp_table = dt_init_opp_table,
};
static int generic_bL_init(void)
static int generic_bL_probe(struct platform_device *pdev)
{
struct device_node *np;
np = get_cpu_node_with_valid_op(0);
if (!np)
return -ENODEV;
of_node_put(np);
return bL_cpufreq_register(&dt_bL_ops);
}
module_init(generic_bL_init);
static void generic_bL_exit(void)
static int generic_bL_remove(struct platform_device *pdev)
{
return bL_cpufreq_unregister(&dt_bL_ops);
bL_cpufreq_unregister(&dt_bL_ops);
return 0;
}
module_exit(generic_bL_exit);
static struct platform_driver generic_bL_platdrv = {
.driver = {
.name = "arm-bL-cpufreq-dt",
.owner = THIS_MODULE,
},
.probe = generic_bL_probe,
.remove = generic_bL_remove,
};
module_platform_driver(generic_bL_platdrv);
MODULE_AUTHOR("Viresh Kumar <[email protected]>");
MODULE_DESCRIPTION("Generic ARM big LITTLE cpufreq driver via DT");

View file

@ -1729,18 +1729,23 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
/* end old governor */
if (data->governor) {
__cpufreq_governor(data, CPUFREQ_GOV_STOP);
unlock_policy_rwsem_write(policy->cpu);
__cpufreq_governor(data,
CPUFREQ_GOV_POLICY_EXIT);
lock_policy_rwsem_write(policy->cpu);
}
/* start new governor */
data->governor = policy->governor;
if (!__cpufreq_governor(data, CPUFREQ_GOV_POLICY_INIT)) {
if (!__cpufreq_governor(data, CPUFREQ_GOV_START))
if (!__cpufreq_governor(data, CPUFREQ_GOV_START)) {
failed = 0;
else
} else {
unlock_policy_rwsem_write(policy->cpu);
__cpufreq_governor(data,
CPUFREQ_GOV_POLICY_EXIT);
lock_policy_rwsem_write(policy->cpu);
}
}
if (failed) {

View file

@ -521,6 +521,7 @@ static void intel_pstate_timer_func(unsigned long __data)
static const struct x86_cpu_id intel_pstate_cpu_ids[] = {
ICPU(0x2a, default_policy),
ICPU(0x2d, default_policy),
ICPU(0x3a, default_policy),
{}
};
MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids);