Commit dfca53fb authored by Linus Torvalds's avatar Linus Torvalds

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

Pull ACPI and power management fixes from Rafael J Wysocki:

 - Fix for a recent cpufreq regression related to acpi-cpufreq and
   suspend/resume from Viresh Kumar.

 - cpufreq stats reference counting fix from Viresh Kumar.

 - intel_pstate driver fixes from Dirk Brandewie and Konrad Rzeszutek
   Wilk.

 - New ACPI suspend blacklist entry for Sony Vaio VGN-FW21M from Fabio
   Valentini.

 - ACPI Platform Error Interface (APEI) fix from Chen Gong.

 - PCI root bridge hotplug locking fix from Yinghai Lu.

* tag 'pm+acpi-3.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  PCI / ACPI: hold acpi_scan_lock during root bus hotplug
  ACPI / APEI: fix error status check condition for CPER
  ACPI / PM: fix suspend and resume on Sony Vaio VGN-FW21M
  cpufreq: acpi-cpufreq: Don't set policy->related_cpus from .init()
  cpufreq: stats: do cpufreq_cpu_put() corresponding to cpufreq_cpu_get()
  intel-pstate: Use #defines instead of hard-coded values.
  cpufreq / intel_pstate: Fix calculation of current frequency
  cpufreq / intel_pstate: Add function to check that all MSRs are valid
parents 8b1e54c4 6125c2be
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#define SNB_C1_AUTO_UNDEMOTE (1UL << 27) #define SNB_C1_AUTO_UNDEMOTE (1UL << 27)
#define SNB_C3_AUTO_UNDEMOTE (1UL << 28) #define SNB_C3_AUTO_UNDEMOTE (1UL << 28)
#define MSR_PLATFORM_INFO 0x000000ce
#define MSR_MTRRcap 0x000000fe #define MSR_MTRRcap 0x000000fe
#define MSR_IA32_BBL_CR_CTL 0x00000119 #define MSR_IA32_BBL_CR_CTL 0x00000119
#define MSR_IA32_BBL_CR_CTL3 0x0000011e #define MSR_IA32_BBL_CR_CTL3 0x0000011e
......
...@@ -405,7 +405,7 @@ int apei_estatus_check(const struct acpi_hest_generic_status *estatus) ...@@ -405,7 +405,7 @@ int apei_estatus_check(const struct acpi_hest_generic_status *estatus)
return rc; return rc;
data_len = estatus->data_length; data_len = estatus->data_length;
gdata = (struct acpi_hest_generic_data *)(estatus + 1); gdata = (struct acpi_hest_generic_data *)(estatus + 1);
while (data_len > sizeof(*gdata)) { while (data_len >= sizeof(*gdata)) {
gedata_len = gdata->error_data_length; gedata_len = gdata->error_data_length;
if (gedata_len > data_len - sizeof(*gdata)) if (gedata_len > data_len - sizeof(*gdata))
return -EINVAL; return -EINVAL;
......
...@@ -646,6 +646,7 @@ static void handle_root_bridge_insertion(acpi_handle handle) ...@@ -646,6 +646,7 @@ static void handle_root_bridge_insertion(acpi_handle handle)
static void handle_root_bridge_removal(struct acpi_device *device) static void handle_root_bridge_removal(struct acpi_device *device)
{ {
acpi_status status;
struct acpi_eject_event *ej_event; struct acpi_eject_event *ej_event;
ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
...@@ -661,7 +662,9 @@ static void handle_root_bridge_removal(struct acpi_device *device) ...@@ -661,7 +662,9 @@ static void handle_root_bridge_removal(struct acpi_device *device)
ej_event->device = device; ej_event->device = device;
ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
acpi_bus_hot_remove_device(ej_event); status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, ej_event);
if (ACPI_FAILURE(status))
kfree(ej_event);
} }
static void _handle_hotplug_event_root(struct work_struct *work) static void _handle_hotplug_event_root(struct work_struct *work)
...@@ -676,8 +679,9 @@ static void _handle_hotplug_event_root(struct work_struct *work) ...@@ -676,8 +679,9 @@ static void _handle_hotplug_event_root(struct work_struct *work)
handle = hp_work->handle; handle = hp_work->handle;
type = hp_work->type; type = hp_work->type;
root = acpi_pci_find_root(handle); acpi_scan_lock_acquire();
root = acpi_pci_find_root(handle);
acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
switch (type) { switch (type) {
...@@ -711,6 +715,7 @@ static void _handle_hotplug_event_root(struct work_struct *work) ...@@ -711,6 +715,7 @@ static void _handle_hotplug_event_root(struct work_struct *work)
break; break;
} }
acpi_scan_lock_release();
kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ kfree(hp_work); /* allocated in handle_hotplug_event_bridge */
kfree(buffer.pointer); kfree(buffer.pointer);
} }
......
...@@ -193,6 +193,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { ...@@ -193,6 +193,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
}, },
{ {
.callback = init_nvs_nosave, .callback = init_nvs_nosave,
.ident = "Sony Vaio VGN-FW21M",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW21M"),
},
},
{
.callback = init_nvs_nosave,
.ident = "Sony Vaio VPCEB17FX", .ident = "Sony Vaio VPCEB17FX",
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
......
...@@ -730,7 +730,6 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) ...@@ -730,7 +730,6 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) { policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
cpumask_copy(policy->cpus, perf->shared_cpu_map); cpumask_copy(policy->cpus, perf->shared_cpu_map);
} }
cpumask_copy(policy->related_cpus, perf->shared_cpu_map);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
dmi_check_system(sw_any_bug_dmi_table); dmi_check_system(sw_any_bug_dmi_table);
...@@ -742,7 +741,6 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) ...@@ -742,7 +741,6 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
if (check_amd_hwpstate_cpu(cpu) && !acpi_pstate_strict) { if (check_amd_hwpstate_cpu(cpu) && !acpi_pstate_strict) {
cpumask_clear(policy->cpus); cpumask_clear(policy->cpus);
cpumask_set_cpu(cpu, policy->cpus); cpumask_set_cpu(cpu, policy->cpus);
cpumask_copy(policy->related_cpus, cpu_sibling_mask(cpu));
policy->shared_type = CPUFREQ_SHARED_TYPE_HW; policy->shared_type = CPUFREQ_SHARED_TYPE_HW;
pr_info_once(PFX "overriding BIOS provided _PSD data\n"); pr_info_once(PFX "overriding BIOS provided _PSD data\n");
} }
......
...@@ -180,14 +180,18 @@ static void cpufreq_stats_free_sysfs(unsigned int cpu) ...@@ -180,14 +180,18 @@ static void cpufreq_stats_free_sysfs(unsigned int cpu)
{ {
struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
if (!cpufreq_frequency_get_table(cpu)) if (!policy)
return; return;
if (policy && !policy_is_shared(policy)) { if (!cpufreq_frequency_get_table(cpu))
goto put_ref;
if (!policy_is_shared(policy)) {
pr_debug("%s: Free sysfs stat\n", __func__); pr_debug("%s: Free sysfs stat\n", __func__);
sysfs_remove_group(&policy->kobj, &stats_attr_group); sysfs_remove_group(&policy->kobj, &stats_attr_group);
} }
if (policy)
put_ref:
cpufreq_cpu_put(policy); cpufreq_cpu_put(policy);
} }
......
...@@ -358,14 +358,14 @@ static void intel_pstate_sysfs_expose_params(void) ...@@ -358,14 +358,14 @@ static void intel_pstate_sysfs_expose_params(void)
static int intel_pstate_min_pstate(void) static int intel_pstate_min_pstate(void)
{ {
u64 value; u64 value;
rdmsrl(0xCE, value); rdmsrl(MSR_PLATFORM_INFO, value);
return (value >> 40) & 0xFF; return (value >> 40) & 0xFF;
} }
static int intel_pstate_max_pstate(void) static int intel_pstate_max_pstate(void)
{ {
u64 value; u64 value;
rdmsrl(0xCE, value); rdmsrl(MSR_PLATFORM_INFO, value);
return (value >> 8) & 0xFF; return (value >> 8) & 0xFF;
} }
...@@ -373,7 +373,7 @@ static int intel_pstate_turbo_pstate(void) ...@@ -373,7 +373,7 @@ static int intel_pstate_turbo_pstate(void)
{ {
u64 value; u64 value;
int nont, ret; int nont, ret;
rdmsrl(0x1AD, value); rdmsrl(MSR_NHM_TURBO_RATIO_LIMIT, value);
nont = intel_pstate_max_pstate(); nont = intel_pstate_max_pstate();
ret = ((value) & 255); ret = ((value) & 255);
if (ret <= nont) if (ret <= nont)
...@@ -454,7 +454,7 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu, ...@@ -454,7 +454,7 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu,
sample->idletime_us * 100, sample->idletime_us * 100,
sample->duration_us); sample->duration_us);
core_pct = div64_u64(sample->aperf * 100, sample->mperf); core_pct = div64_u64(sample->aperf * 100, sample->mperf);
sample->freq = cpu->pstate.turbo_pstate * core_pct * 1000; sample->freq = cpu->pstate.max_pstate * core_pct * 1000;
sample->core_pct_busy = div_s64((sample->pstate_pct_busy * core_pct), sample->core_pct_busy = div_s64((sample->pstate_pct_busy * core_pct),
100); 100);
...@@ -752,6 +752,29 @@ static struct cpufreq_driver intel_pstate_driver = { ...@@ -752,6 +752,29 @@ static struct cpufreq_driver intel_pstate_driver = {
static int __initdata no_load; static int __initdata no_load;
static int intel_pstate_msrs_not_valid(void)
{
/* Check that all the msr's we are using are valid. */
u64 aperf, mperf, tmp;
rdmsrl(MSR_IA32_APERF, aperf);
rdmsrl(MSR_IA32_MPERF, mperf);
if (!intel_pstate_min_pstate() ||
!intel_pstate_max_pstate() ||
!intel_pstate_turbo_pstate())
return -ENODEV;
rdmsrl(MSR_IA32_APERF, tmp);
if (!(tmp - aperf))
return -ENODEV;
rdmsrl(MSR_IA32_MPERF, tmp);
if (!(tmp - mperf))
return -ENODEV;
return 0;
}
static int __init intel_pstate_init(void) static int __init intel_pstate_init(void)
{ {
int cpu, rc = 0; int cpu, rc = 0;
...@@ -764,6 +787,9 @@ static int __init intel_pstate_init(void) ...@@ -764,6 +787,9 @@ static int __init intel_pstate_init(void)
if (!id) if (!id)
return -ENODEV; return -ENODEV;
if (intel_pstate_msrs_not_valid())
return -ENODEV;
pr_info("Intel P-state driver initializing.\n"); pr_info("Intel P-state driver initializing.\n");
all_cpu_data = vmalloc(sizeof(void *) * num_possible_cpus()); all_cpu_data = vmalloc(sizeof(void *) * num_possible_cpus());
......
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