提交 cff539b1 编写于 作者: L Linus Torvalds

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

Pull ACPI and power management fixes from Rafael Wysocki:

 - Recent commits modifying the lists of C-states in the intel_idle
   driver introduced bugs leading to crashes on some systems.  Two fixes
   from Jiang Liu.

 - The ACPI AC driver should receive all types of notifications, but
   recent change made it ignore some of them.  Fix from Alexander Mezin.

 - intel_pstate's validity checks for MSRs it depends on are not
   sufficient to catch the lack of support in nested KVM setups, so they
   are extended to cover that case.  From Dirk Brandewie.

 - NEC LZ750/LS has a botched up _BIX method in its ACPI tables, so our
   ACPI battery driver needs a quirk for it.  From Lan Tianyu.

 - The tpm_ppi driver sometimes leaks memory allocated by
   acpi_get_name().  Fix from Jiang Liu.

* tag 'pm+acpi-3.13-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  intel_idle: close avn_cstates array with correct marker
  Revert "intel_idle: mark states tables with __initdata tag"
  ACPI / Battery: Add a _BIX quirk for NEC LZ750/LS
  intel_pstate: Add X86_FEATURE_APERFMPERF to cpu match parameters.
  ACPI / TPM: fix memory leak when walking ACPI namespace
  ACPI / AC: change notification handler type to ACPI_ALL_NOTIFY
...@@ -207,7 +207,7 @@ static int acpi_ac_probe(struct platform_device *pdev) ...@@ -207,7 +207,7 @@ static int acpi_ac_probe(struct platform_device *pdev)
goto end; goto end;
result = acpi_install_notify_handler(ACPI_HANDLE(&pdev->dev), result = acpi_install_notify_handler(ACPI_HANDLE(&pdev->dev),
ACPI_DEVICE_NOTIFY, acpi_ac_notify_handler, ac); ACPI_ALL_NOTIFY, acpi_ac_notify_handler, ac);
if (result) { if (result) {
power_supply_unregister(&ac->charger); power_supply_unregister(&ac->charger);
goto end; goto end;
...@@ -255,7 +255,7 @@ static int acpi_ac_remove(struct platform_device *pdev) ...@@ -255,7 +255,7 @@ static int acpi_ac_remove(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
acpi_remove_notify_handler(ACPI_HANDLE(&pdev->dev), acpi_remove_notify_handler(ACPI_HANDLE(&pdev->dev),
ACPI_DEVICE_NOTIFY, acpi_ac_notify_handler); ACPI_ALL_NOTIFY, acpi_ac_notify_handler);
ac = platform_get_drvdata(pdev); ac = platform_get_drvdata(pdev);
if (ac->charger.dev) if (ac->charger.dev)
......
...@@ -62,6 +62,7 @@ MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>"); ...@@ -62,6 +62,7 @@ MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>");
MODULE_DESCRIPTION("ACPI Battery Driver"); MODULE_DESCRIPTION("ACPI Battery Driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static int battery_bix_broken_package;
static unsigned int cache_time = 1000; static unsigned int cache_time = 1000;
module_param(cache_time, uint, 0644); module_param(cache_time, uint, 0644);
MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
...@@ -416,7 +417,12 @@ static int acpi_battery_get_info(struct acpi_battery *battery) ...@@ -416,7 +417,12 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s", name)); ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s", name));
return -ENODEV; return -ENODEV;
} }
if (test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags))
if (battery_bix_broken_package)
result = extract_package(battery, buffer.pointer,
extended_info_offsets + 1,
ARRAY_SIZE(extended_info_offsets) - 1);
else if (test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags))
result = extract_package(battery, buffer.pointer, result = extract_package(battery, buffer.pointer,
extended_info_offsets, extended_info_offsets,
ARRAY_SIZE(extended_info_offsets)); ARRAY_SIZE(extended_info_offsets));
...@@ -754,6 +760,17 @@ static int battery_notify(struct notifier_block *nb, ...@@ -754,6 +760,17 @@ static int battery_notify(struct notifier_block *nb,
return 0; return 0;
} }
static struct dmi_system_id bat_dmi_table[] = {
{
.ident = "NEC LZ750/LS",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "NEC"),
DMI_MATCH(DMI_PRODUCT_NAME, "PC-LZ750LS"),
},
},
{},
};
static int acpi_battery_add(struct acpi_device *device) static int acpi_battery_add(struct acpi_device *device)
{ {
int result = 0; int result = 0;
...@@ -846,6 +863,9 @@ static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie) ...@@ -846,6 +863,9 @@ static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
{ {
if (acpi_disabled) if (acpi_disabled)
return; return;
if (dmi_check_system(bat_dmi_table))
battery_bix_broken_package = 1;
acpi_bus_register_driver(&acpi_battery_driver); acpi_bus_register_driver(&acpi_battery_driver);
} }
......
...@@ -27,15 +27,18 @@ static char *tpm_device_name = "TPM"; ...@@ -27,15 +27,18 @@ static char *tpm_device_name = "TPM";
static acpi_status ppi_callback(acpi_handle handle, u32 level, void *context, static acpi_status ppi_callback(acpi_handle handle, u32 level, void *context,
void **return_value) void **return_value)
{ {
acpi_status status; acpi_status status = AE_OK;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
if (strstr(buffer.pointer, context) != NULL) { if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer))) {
*return_value = handle; if (strstr(buffer.pointer, context) != NULL) {
*return_value = handle;
status = AE_CTRL_TERMINATE;
}
kfree(buffer.pointer); kfree(buffer.pointer);
return AE_CTRL_TERMINATE;
} }
return AE_OK;
return status;
} }
static inline void ppi_assign_params(union acpi_object params[4], static inline void ppi_assign_params(union acpi_object params[4],
......
...@@ -581,7 +581,8 @@ static void intel_pstate_timer_func(unsigned long __data) ...@@ -581,7 +581,8 @@ static void intel_pstate_timer_func(unsigned long __data)
} }
#define ICPU(model, policy) \ #define ICPU(model, policy) \
{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&policy } { X86_VENDOR_INTEL, 6, model, X86_FEATURE_APERFMPERF,\
(unsigned long)&policy }
static const struct x86_cpu_id intel_pstate_cpu_ids[] = { static const struct x86_cpu_id intel_pstate_cpu_ids[] = {
ICPU(0x2a, core_params), ICPU(0x2a, core_params),
......
...@@ -123,7 +123,7 @@ static struct cpuidle_state *cpuidle_state_table; ...@@ -123,7 +123,7 @@ static struct cpuidle_state *cpuidle_state_table;
* which is also the index into the MWAIT hint array. * which is also the index into the MWAIT hint array.
* Thus C0 is a dummy. * Thus C0 is a dummy.
*/ */
static struct cpuidle_state nehalem_cstates[] __initdata = { static struct cpuidle_state nehalem_cstates[] = {
{ {
.name = "C1-NHM", .name = "C1-NHM",
.desc = "MWAIT 0x00", .desc = "MWAIT 0x00",
...@@ -156,7 +156,7 @@ static struct cpuidle_state nehalem_cstates[] __initdata = { ...@@ -156,7 +156,7 @@ static struct cpuidle_state nehalem_cstates[] __initdata = {
.enter = NULL } .enter = NULL }
}; };
static struct cpuidle_state snb_cstates[] __initdata = { static struct cpuidle_state snb_cstates[] = {
{ {
.name = "C1-SNB", .name = "C1-SNB",
.desc = "MWAIT 0x00", .desc = "MWAIT 0x00",
...@@ -196,7 +196,7 @@ static struct cpuidle_state snb_cstates[] __initdata = { ...@@ -196,7 +196,7 @@ static struct cpuidle_state snb_cstates[] __initdata = {
.enter = NULL } .enter = NULL }
}; };
static struct cpuidle_state ivb_cstates[] __initdata = { static struct cpuidle_state ivb_cstates[] = {
{ {
.name = "C1-IVB", .name = "C1-IVB",
.desc = "MWAIT 0x00", .desc = "MWAIT 0x00",
...@@ -236,7 +236,7 @@ static struct cpuidle_state ivb_cstates[] __initdata = { ...@@ -236,7 +236,7 @@ static struct cpuidle_state ivb_cstates[] __initdata = {
.enter = NULL } .enter = NULL }
}; };
static struct cpuidle_state hsw_cstates[] __initdata = { static struct cpuidle_state hsw_cstates[] = {
{ {
.name = "C1-HSW", .name = "C1-HSW",
.desc = "MWAIT 0x00", .desc = "MWAIT 0x00",
...@@ -297,7 +297,7 @@ static struct cpuidle_state hsw_cstates[] __initdata = { ...@@ -297,7 +297,7 @@ static struct cpuidle_state hsw_cstates[] __initdata = {
.enter = NULL } .enter = NULL }
}; };
static struct cpuidle_state atom_cstates[] __initdata = { static struct cpuidle_state atom_cstates[] = {
{ {
.name = "C1E-ATM", .name = "C1E-ATM",
.desc = "MWAIT 0x00", .desc = "MWAIT 0x00",
...@@ -329,7 +329,7 @@ static struct cpuidle_state atom_cstates[] __initdata = { ...@@ -329,7 +329,7 @@ static struct cpuidle_state atom_cstates[] __initdata = {
{ {
.enter = NULL } .enter = NULL }
}; };
static struct cpuidle_state avn_cstates[] __initdata = { static struct cpuidle_state avn_cstates[] = {
{ {
.name = "C1-AVN", .name = "C1-AVN",
.desc = "MWAIT 0x00", .desc = "MWAIT 0x00",
...@@ -344,6 +344,8 @@ static struct cpuidle_state avn_cstates[] __initdata = { ...@@ -344,6 +344,8 @@ static struct cpuidle_state avn_cstates[] __initdata = {
.exit_latency = 15, .exit_latency = 15,
.target_residency = 45, .target_residency = 45,
.enter = &intel_idle }, .enter = &intel_idle },
{
.enter = NULL }
}; };
/** /**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册