ACPI and power management fixes for 3.9-rc5
- 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. / -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iQIcBAABAgAGBQJRVETOAAoJEKhOf7ml8uNs30kP/3GsKWacHsaIPdhIiHQC3f91 HMLabrW7NE7ldrOoXzj1lTHsIc1TQHm722vyI+aF061HErfkF8Jkdi5rkIai8VMq IJXe4CtwuuCi0SeKQsV9ymiQanTrgsP/AlGV5x/KM/As8dvAVW/1+Ln/gXAnH0IJ /Onqf3eA4NBw/1Hjg7AGHGeCmOlDHvcetHF7eX4MaiYZHEwuy/a7jswH4aNOjwgx GZtbrnwUO6OtDKv6ie//1EbP753VrkHDtK3jzIy2lUA5YyLmr0XOTvy4uQh2n/r7 tVTqsVoNZNA4En0YUspfsWwBruUic3ra9qVTrJqn7Fzymyr+TgyCQQzSUGrOGy2a wY0vwMAwm1dMwAsZWPhnui6aqvu0bbg0u7sxCZQs8WapdtjxPdD7iIhRk2YU4wOZ omtejW0thUIwEmHWgBPo9rFvfZmxy9hb044UfhkLI9xBmuTVrDb/HqeVPA767ZoO k7IVg1DG4Ye6xboCIILfluoUAsc3DvkHpCIvWVujK3pF5j/M9ptt3d8eXDFIzmWD J6tm9ARkQoUPRAs6751cG1N0nP++ZlErYseU/h6eXoC0rkeC/WbGyxIumii4xJhg Gs6GGeM8OgQ/7Fat68kA2Z7jriY+MTteLbq1Sl3PBlfdURaceOXkTIVrxXo33Itq jQiEKa1CbJDi6OBKog8K =0bjZ -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
dfca53fb16
7 changed files with 55 additions and 13 deletions
|
@ -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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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[] = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.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)
|
||||||
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)
|
||||||
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,15 +180,19 @@ 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)
|
|
||||||
cpufreq_cpu_put(policy);
|
put_ref:
|
||||||
|
cpufreq_cpu_put(policy);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cpufreq_stats_create_table(struct cpufreq_policy *policy,
|
static int cpufreq_stats_create_table(struct cpufreq_policy *policy,
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
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,
|
||||||
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 = {
|
||||||
|
|
||||||
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)
|
||||||
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());
|
||||||
|
|
Loading…
Add table
Reference in a new issue