forked from Minki/linux
ACPI and power management fixes and new device IDs for 3.13-rc6
- Fix for a cpufreq regression causing stale sysfs files to be left behind during system resume if cpufreq_add_dev() fails for one or more CPUs from Viresh Kumar. - Fix for a bug in cpufreq causing CONFIG_CPU_FREQ_DEFAULT_* to be ignored when the intel_pstate driver is used from Jason Baron. - System suspend fix for a memory leak in pm_vt_switch_unregister() that forgot to release objects after removing them from pm_vt_switch_list. From Masami Ichikawa. - Intel Valley View device ID and energy unit encoding update for the (recently added) Intel RAPL (Running Average Power Limit) driver from Jacob Pan. - Intel Bay Trail SoC GPIO and ACPI device IDs for the Low Power Subsystem (LPSS) ACPI driver from Paul Drews. / -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iQIcBAABCAAGBQJSvh9MAAoJEILEb/54YlRxfJoQAJFzcqXlYsROgPSlYVEG0F80 Cop0MbYC/gr8XNiLXWGIRVVYHbxMNeAPk5vUPZg4E9L6cOeazwjFtnRB/Av3FpVo XReYHpLbJXJ3VaVyJiw0tCHp/Ukw8Ds0VcURi8RdcrQdkmyXPtbfWcrE+7GmuA2z jnZOJviws+mTnxdEHtaml2iZMM5jwvUmUeh3iytc8zOC3QR4I7cLkKnYNTrQatqZ qYxu5e9VAKuTXBv7BeNHiViakKhoWPx0S3nKofoiOG5hGwg49HGVlJ3pH9CCfIli jA1NpXOGyKzYLJv2fJPtgxQ+l7Mb8wu9hGbPJWaUI3MRa9vIxNok6qzYwAQcfCWD p4iugfsaatyKbBSBu+mntczCM7wsl2+/gH3gWfDySRpxq8G9At1dduO9GMeD/pDi QhYlFl0obR05F6R0hlkk2Pahx+5x5nub7dM2+8Oh+r8k6TlkFRg+BKe21MJGz/45 BHBmJkNkLpdUNKT2GhaQK6rhc5TSln3eYGjYDRRhRmV6/4US/hI1MtY6HYg2uWbk J3xiMcUXAY/0DzC1zDzvwr4Cc+WRdNXbZGKmmhyc+fxEmjZZVGanfmqC0JFV3gni 32v1krQA8v3KANz2xjvnNwNLQzSypgVOHihUbPN34FGaE7fxp6PWqxwhRD6RyywK gtIHNSZ0mKnmIR6oxq1a =vQDX -----END PGP SIGNATURE----- Merge tag 'pm+acpi-3.13-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull ACPI and power management fixes and new device IDs from Rafael Wysocki: - Fix for a cpufreq regression causing stale sysfs files to be left behind during system resume if cpufreq_add_dev() fails for one or more CPUs from Viresh Kumar. - Fix for a bug in cpufreq causing CONFIG_CPU_FREQ_DEFAULT_* to be ignored when the intel_pstate driver is used from Jason Baron. - System suspend fix for a memory leak in pm_vt_switch_unregister() that forgot to release objects after removing them from pm_vt_switch_list. From Masami Ichikawa. - Intel Valley View device ID and energy unit encoding update for the (recently added) Intel RAPL (Running Average Power Limit) driver from Jacob Pan. - Intel Bay Trail SoC GPIO and ACPI device IDs for the Low Power Subsystem (LPSS) ACPI driver from Paul Drews. * tag 'pm+acpi-3.13-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: powercap / RAPL: add support for ValleyView Soc PM / sleep: Fix memory leak in pm_vt_switch_unregister(). cpufreq: Use CONFIG_CPU_FREQ_DEFAULT_* to set initial policy for setpolicy drivers cpufreq: remove sysfs files for CPUs which failed to come back after resume ACPI: Add BayTrail SoC GPIO and LPSS ACPI IDs
This commit is contained in:
commit
bddffa28dc
@ -162,6 +162,7 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
|
||||
{ "80860F14", (unsigned long)&byt_sdio_dev_desc },
|
||||
{ "80860F41", (unsigned long)&byt_i2c_dev_desc },
|
||||
{ "INT33B2", },
|
||||
{ "INT33FC", },
|
||||
|
||||
{ "INT3430", (unsigned long)&lpt_dev_desc },
|
||||
{ "INT3431", (unsigned long)&lpt_dev_desc },
|
||||
|
@ -828,6 +828,12 @@ static void cpufreq_init_policy(struct cpufreq_policy *policy)
|
||||
int ret = 0;
|
||||
|
||||
memcpy(&new_policy, policy, sizeof(*policy));
|
||||
|
||||
/* Use the default policy if its valid. */
|
||||
if (cpufreq_driver->setpolicy)
|
||||
cpufreq_parse_governor(policy->governor->name,
|
||||
&new_policy.policy, NULL);
|
||||
|
||||
/* assure that the starting sequence is run in cpufreq_set_policy */
|
||||
policy->governor = NULL;
|
||||
|
||||
@ -845,8 +851,7 @@ static void cpufreq_init_policy(struct cpufreq_policy *policy)
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
|
||||
unsigned int cpu, struct device *dev,
|
||||
bool frozen)
|
||||
unsigned int cpu, struct device *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned long flags;
|
||||
@ -877,11 +882,7 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't touch sysfs links during light-weight init */
|
||||
if (!frozen)
|
||||
ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
|
||||
|
||||
return ret;
|
||||
return sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -926,6 +927,27 @@ err_free_policy:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void cpufreq_policy_put_kobj(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct kobject *kobj;
|
||||
struct completion *cmp;
|
||||
|
||||
down_read(&policy->rwsem);
|
||||
kobj = &policy->kobj;
|
||||
cmp = &policy->kobj_unregister;
|
||||
up_read(&policy->rwsem);
|
||||
kobject_put(kobj);
|
||||
|
||||
/*
|
||||
* We need to make sure that the underlying kobj is
|
||||
* actually not referenced anymore by anybody before we
|
||||
* proceed with unloading.
|
||||
*/
|
||||
pr_debug("waiting for dropping of refcount\n");
|
||||
wait_for_completion(cmp);
|
||||
pr_debug("wait complete\n");
|
||||
}
|
||||
|
||||
static void cpufreq_policy_free(struct cpufreq_policy *policy)
|
||||
{
|
||||
free_cpumask_var(policy->related_cpus);
|
||||
@ -986,7 +1008,7 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
|
||||
list_for_each_entry(tpolicy, &cpufreq_policy_list, policy_list) {
|
||||
if (cpumask_test_cpu(cpu, tpolicy->related_cpus)) {
|
||||
read_unlock_irqrestore(&cpufreq_driver_lock, flags);
|
||||
ret = cpufreq_add_policy_cpu(tpolicy, cpu, dev, frozen);
|
||||
ret = cpufreq_add_policy_cpu(tpolicy, cpu, dev);
|
||||
up_read(&cpufreq_rwsem);
|
||||
return ret;
|
||||
}
|
||||
@ -1096,7 +1118,10 @@ err_get_freq:
|
||||
if (cpufreq_driver->exit)
|
||||
cpufreq_driver->exit(policy);
|
||||
err_set_policy_cpu:
|
||||
if (frozen)
|
||||
cpufreq_policy_put_kobj(policy);
|
||||
cpufreq_policy_free(policy);
|
||||
|
||||
nomem_out:
|
||||
up_read(&cpufreq_rwsem);
|
||||
|
||||
@ -1118,7 +1143,7 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
|
||||
}
|
||||
|
||||
static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy,
|
||||
unsigned int old_cpu, bool frozen)
|
||||
unsigned int old_cpu)
|
||||
{
|
||||
struct device *cpu_dev;
|
||||
int ret;
|
||||
@ -1126,10 +1151,6 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy,
|
||||
/* first sibling now owns the new sysfs dir */
|
||||
cpu_dev = get_cpu_device(cpumask_any_but(policy->cpus, old_cpu));
|
||||
|
||||
/* Don't touch sysfs files during light-weight tear-down */
|
||||
if (frozen)
|
||||
return cpu_dev->id;
|
||||
|
||||
sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
|
||||
ret = kobject_move(&policy->kobj, &cpu_dev->kobj);
|
||||
if (ret) {
|
||||
@ -1196,7 +1217,7 @@ static int __cpufreq_remove_dev_prepare(struct device *dev,
|
||||
if (!frozen)
|
||||
sysfs_remove_link(&dev->kobj, "cpufreq");
|
||||
} else if (cpus > 1) {
|
||||
new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu, frozen);
|
||||
new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu);
|
||||
if (new_cpu >= 0) {
|
||||
update_policy_cpu(policy, new_cpu);
|
||||
|
||||
@ -1218,8 +1239,6 @@ static int __cpufreq_remove_dev_finish(struct device *dev,
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
struct cpufreq_policy *policy;
|
||||
struct kobject *kobj;
|
||||
struct completion *cmp;
|
||||
|
||||
read_lock_irqsave(&cpufreq_driver_lock, flags);
|
||||
policy = per_cpu(cpufreq_cpu_data, cpu);
|
||||
@ -1249,22 +1268,8 @@ static int __cpufreq_remove_dev_finish(struct device *dev,
|
||||
}
|
||||
}
|
||||
|
||||
if (!frozen) {
|
||||
down_read(&policy->rwsem);
|
||||
kobj = &policy->kobj;
|
||||
cmp = &policy->kobj_unregister;
|
||||
up_read(&policy->rwsem);
|
||||
kobject_put(kobj);
|
||||
|
||||
/*
|
||||
* We need to make sure that the underlying kobj is
|
||||
* actually not referenced anymore by anybody before we
|
||||
* proceed with unloading.
|
||||
*/
|
||||
pr_debug("waiting for dropping of refcount\n");
|
||||
wait_for_completion(cmp);
|
||||
pr_debug("wait complete\n");
|
||||
}
|
||||
if (!frozen)
|
||||
cpufreq_policy_put_kobj(policy);
|
||||
|
||||
/*
|
||||
* Perform the ->exit() even during light-weight tear-down,
|
||||
|
@ -512,6 +512,7 @@ static const struct dev_pm_ops byt_gpio_pm_ops = {
|
||||
|
||||
static const struct acpi_device_id byt_gpio_acpi_match[] = {
|
||||
{ "INT33B2", 0 },
|
||||
{ "INT33FC", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match);
|
||||
|
@ -833,6 +833,11 @@ static int rapl_write_data_raw(struct rapl_domain *rd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct x86_cpu_id energy_unit_quirk_ids[] = {
|
||||
{ X86_VENDOR_INTEL, 6, 0x37},/* VLV */
|
||||
{}
|
||||
};
|
||||
|
||||
static int rapl_check_unit(struct rapl_package *rp, int cpu)
|
||||
{
|
||||
u64 msr_val;
|
||||
@ -853,8 +858,11 @@ static int rapl_check_unit(struct rapl_package *rp, int cpu)
|
||||
* time unit: 1/time_unit_divisor Seconds
|
||||
*/
|
||||
value = (msr_val & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET;
|
||||
rp->energy_unit_divisor = 1 << value;
|
||||
|
||||
/* some CPUs have different way to calculate energy unit */
|
||||
if (x86_match_cpu(energy_unit_quirk_ids))
|
||||
rp->energy_unit_divisor = 1000000 / (1 << value);
|
||||
else
|
||||
rp->energy_unit_divisor = 1 << value;
|
||||
|
||||
value = (msr_val & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET;
|
||||
rp->power_unit_divisor = 1 << value;
|
||||
@ -941,6 +949,7 @@ static void package_power_limit_irq_restore(int package_id)
|
||||
static const struct x86_cpu_id rapl_ids[] = {
|
||||
{ X86_VENDOR_INTEL, 6, 0x2a},/* SNB */
|
||||
{ X86_VENDOR_INTEL, 6, 0x2d},/* SNB EP */
|
||||
{ X86_VENDOR_INTEL, 6, 0x37},/* VLV */
|
||||
{ X86_VENDOR_INTEL, 6, 0x3a},/* IVB */
|
||||
{ X86_VENDOR_INTEL, 6, 0x45},/* HSW */
|
||||
/* TODO: Add more CPU IDs after testing */
|
||||
|
@ -81,6 +81,7 @@ void pm_vt_switch_unregister(struct device *dev)
|
||||
list_for_each_entry(tmp, &pm_vt_switch_list, head) {
|
||||
if (tmp->dev == dev) {
|
||||
list_del(&tmp->head);
|
||||
kfree(tmp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user