Commit bddffa28 authored by Linus Torvalds's avatar Linus Torvalds

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
parents f41bfc94 bfde19c4
...@@ -162,6 +162,7 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = { ...@@ -162,6 +162,7 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
{ "80860F14", (unsigned long)&byt_sdio_dev_desc }, { "80860F14", (unsigned long)&byt_sdio_dev_desc },
{ "80860F41", (unsigned long)&byt_i2c_dev_desc }, { "80860F41", (unsigned long)&byt_i2c_dev_desc },
{ "INT33B2", }, { "INT33B2", },
{ "INT33FC", },
{ "INT3430", (unsigned long)&lpt_dev_desc }, { "INT3430", (unsigned long)&lpt_dev_desc },
{ "INT3431", (unsigned long)&lpt_dev_desc }, { "INT3431", (unsigned long)&lpt_dev_desc },
......
...@@ -828,6 +828,12 @@ static void cpufreq_init_policy(struct cpufreq_policy *policy) ...@@ -828,6 +828,12 @@ static void cpufreq_init_policy(struct cpufreq_policy *policy)
int ret = 0; int ret = 0;
memcpy(&new_policy, policy, sizeof(*policy)); 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 */ /* assure that the starting sequence is run in cpufreq_set_policy */
policy->governor = NULL; policy->governor = NULL;
...@@ -845,8 +851,7 @@ static void cpufreq_init_policy(struct cpufreq_policy *policy) ...@@ -845,8 +851,7 @@ static void cpufreq_init_policy(struct cpufreq_policy *policy)
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
unsigned int cpu, struct device *dev, unsigned int cpu, struct device *dev)
bool frozen)
{ {
int ret = 0; int ret = 0;
unsigned long flags; unsigned long flags;
...@@ -877,11 +882,7 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, ...@@ -877,11 +882,7 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
} }
} }
/* Don't touch sysfs links during light-weight init */ return sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
if (!frozen)
ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
return ret;
} }
#endif #endif
...@@ -926,6 +927,27 @@ static struct cpufreq_policy *cpufreq_policy_alloc(void) ...@@ -926,6 +927,27 @@ static struct cpufreq_policy *cpufreq_policy_alloc(void)
return NULL; 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) static void cpufreq_policy_free(struct cpufreq_policy *policy)
{ {
free_cpumask_var(policy->related_cpus); free_cpumask_var(policy->related_cpus);
...@@ -986,7 +1008,7 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, ...@@ -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) { list_for_each_entry(tpolicy, &cpufreq_policy_list, policy_list) {
if (cpumask_test_cpu(cpu, tpolicy->related_cpus)) { if (cpumask_test_cpu(cpu, tpolicy->related_cpus)) {
read_unlock_irqrestore(&cpufreq_driver_lock, flags); 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); up_read(&cpufreq_rwsem);
return ret; return ret;
} }
...@@ -1096,7 +1118,10 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, ...@@ -1096,7 +1118,10 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
if (cpufreq_driver->exit) if (cpufreq_driver->exit)
cpufreq_driver->exit(policy); cpufreq_driver->exit(policy);
err_set_policy_cpu: err_set_policy_cpu:
if (frozen)
cpufreq_policy_put_kobj(policy);
cpufreq_policy_free(policy); cpufreq_policy_free(policy);
nomem_out: nomem_out:
up_read(&cpufreq_rwsem); up_read(&cpufreq_rwsem);
...@@ -1118,7 +1143,7 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) ...@@ -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, 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; struct device *cpu_dev;
int ret; int ret;
...@@ -1126,10 +1151,6 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy, ...@@ -1126,10 +1151,6 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy,
/* first sibling now owns the new sysfs dir */ /* first sibling now owns the new sysfs dir */
cpu_dev = get_cpu_device(cpumask_any_but(policy->cpus, old_cpu)); 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"); sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
ret = kobject_move(&policy->kobj, &cpu_dev->kobj); ret = kobject_move(&policy->kobj, &cpu_dev->kobj);
if (ret) { if (ret) {
...@@ -1196,7 +1217,7 @@ static int __cpufreq_remove_dev_prepare(struct device *dev, ...@@ -1196,7 +1217,7 @@ static int __cpufreq_remove_dev_prepare(struct device *dev,
if (!frozen) if (!frozen)
sysfs_remove_link(&dev->kobj, "cpufreq"); sysfs_remove_link(&dev->kobj, "cpufreq");
} else if (cpus > 1) { } 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) { if (new_cpu >= 0) {
update_policy_cpu(policy, new_cpu); update_policy_cpu(policy, new_cpu);
...@@ -1218,8 +1239,6 @@ static int __cpufreq_remove_dev_finish(struct device *dev, ...@@ -1218,8 +1239,6 @@ static int __cpufreq_remove_dev_finish(struct device *dev,
int ret; int ret;
unsigned long flags; unsigned long flags;
struct cpufreq_policy *policy; struct cpufreq_policy *policy;
struct kobject *kobj;
struct completion *cmp;
read_lock_irqsave(&cpufreq_driver_lock, flags); read_lock_irqsave(&cpufreq_driver_lock, flags);
policy = per_cpu(cpufreq_cpu_data, cpu); policy = per_cpu(cpufreq_cpu_data, cpu);
...@@ -1249,22 +1268,8 @@ static int __cpufreq_remove_dev_finish(struct device *dev, ...@@ -1249,22 +1268,8 @@ static int __cpufreq_remove_dev_finish(struct device *dev,
} }
} }
if (!frozen) { if (!frozen)
down_read(&policy->rwsem); cpufreq_policy_put_kobj(policy);
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");
}
/* /*
* Perform the ->exit() even during light-weight tear-down, * Perform the ->exit() even during light-weight tear-down,
......
...@@ -512,6 +512,7 @@ static const struct dev_pm_ops byt_gpio_pm_ops = { ...@@ -512,6 +512,7 @@ static const struct dev_pm_ops byt_gpio_pm_ops = {
static const struct acpi_device_id byt_gpio_acpi_match[] = { static const struct acpi_device_id byt_gpio_acpi_match[] = {
{ "INT33B2", 0 }, { "INT33B2", 0 },
{ "INT33FC", 0 },
{ } { }
}; };
MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match); MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match);
......
...@@ -833,6 +833,11 @@ static int rapl_write_data_raw(struct rapl_domain *rd, ...@@ -833,6 +833,11 @@ static int rapl_write_data_raw(struct rapl_domain *rd,
return 0; 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) static int rapl_check_unit(struct rapl_package *rp, int cpu)
{ {
u64 msr_val; u64 msr_val;
...@@ -853,8 +858,11 @@ static int rapl_check_unit(struct rapl_package *rp, int cpu) ...@@ -853,8 +858,11 @@ static int rapl_check_unit(struct rapl_package *rp, int cpu)
* time unit: 1/time_unit_divisor Seconds * time unit: 1/time_unit_divisor Seconds
*/ */
value = (msr_val & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET; 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; value = (msr_val & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET;
rp->power_unit_divisor = 1 << value; rp->power_unit_divisor = 1 << value;
...@@ -941,6 +949,7 @@ static void package_power_limit_irq_restore(int package_id) ...@@ -941,6 +949,7 @@ static void package_power_limit_irq_restore(int package_id)
static const struct x86_cpu_id rapl_ids[] = { static const struct x86_cpu_id rapl_ids[] = {
{ X86_VENDOR_INTEL, 6, 0x2a},/* SNB */ { X86_VENDOR_INTEL, 6, 0x2a},/* SNB */
{ X86_VENDOR_INTEL, 6, 0x2d},/* SNB EP */ { X86_VENDOR_INTEL, 6, 0x2d},/* SNB EP */
{ X86_VENDOR_INTEL, 6, 0x37},/* VLV */
{ X86_VENDOR_INTEL, 6, 0x3a},/* IVB */ { X86_VENDOR_INTEL, 6, 0x3a},/* IVB */
{ X86_VENDOR_INTEL, 6, 0x45},/* HSW */ { X86_VENDOR_INTEL, 6, 0x45},/* HSW */
/* TODO: Add more CPU IDs after testing */ /* TODO: Add more CPU IDs after testing */
......
...@@ -81,6 +81,7 @@ void pm_vt_switch_unregister(struct device *dev) ...@@ -81,6 +81,7 @@ void pm_vt_switch_unregister(struct device *dev)
list_for_each_entry(tmp, &pm_vt_switch_list, head) { list_for_each_entry(tmp, &pm_vt_switch_list, head) {
if (tmp->dev == dev) { if (tmp->dev == dev) {
list_del(&tmp->head); list_del(&tmp->head);
kfree(tmp);
break; break;
} }
} }
......
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