Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6

* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6:
  ACPI / Sleep: Allow the NVS saving to be skipped during suspend to RAM
  ACPI: create "processor.bm_check_disable" boot param
  ACPI: skip checking BM_STS if the BIOS doesn't ask for it
  ACPI: fix unused function warning
  ACPI: processor: fix processor_physically_present on UP
  ACPI video: fix string mismatch for Sony SR290 laptop
  ACPI battery: don't invoke power_supply_changed twice when battery is hot-added
  ACPI: handle systems which asynchoronously enable ACPI mode
This commit is contained in:
Linus Torvalds 2010-07-26 08:10:00 -07:00
Родитель 24b1442d01 0e1cf38889
Коммит dbbe4649d6
12 изменённых файлов: 74 добавлений и 36 удалений

Просмотреть файл

@ -647,3 +647,10 @@ Who: Stefan Richter <stefanr@s5r6.in-berlin.de>
---------------------------- ----------------------------
What: The acpi_sleep=s4_nonvs command line option
When: 2.6.37
Files: arch/x86/kernel/acpi/sleep.c
Why: superseded by acpi_sleep=nonvs
Who: Rafael J. Wysocki <rjw@sisk.pl>
----------------------------

Просмотреть файл

@ -254,8 +254,8 @@ and is between 256 and 4096 characters. It is defined in the file
control method, with respect to putting devices into control method, with respect to putting devices into
low power states, to be enforced (the ACPI 2.0 ordering low power states, to be enforced (the ACPI 2.0 ordering
of _PTS is used by default). of _PTS is used by default).
s4_nonvs prevents the kernel from saving/restoring the nonvs prevents the kernel from saving/restoring the
ACPI NVS memory during hibernation. ACPI NVS memory during suspend/hibernation and resume.
sci_force_enable causes the kernel to set SCI_EN directly sci_force_enable causes the kernel to set SCI_EN directly
on resume from S1/S3 (which is against the ACPI spec, on resume from S1/S3 (which is against the ACPI spec,
but some broken systems don't work without it). but some broken systems don't work without it).

Просмотреть файл

@ -145,6 +145,15 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu,
percpu_entry->states[cx->index].eax = cx->address; percpu_entry->states[cx->index].eax = cx->address;
percpu_entry->states[cx->index].ecx = MWAIT_ECX_INTERRUPT_BREAK; percpu_entry->states[cx->index].ecx = MWAIT_ECX_INTERRUPT_BREAK;
} }
/*
* For _CST FFH on Intel, if GAS.access_size bit 1 is cleared,
* then we should skip checking BM_STS for this C-state.
* ref: "Intel Processor Vendor-Specific ACPI Interface Specification"
*/
if ((c->x86_vendor == X86_VENDOR_INTEL) && !(reg->access_size & 0x2))
cx->bm_sts_skip = 1;
return retval; return retval;
} }
EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe); EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe);

Просмотреть файл

@ -157,9 +157,14 @@ static int __init acpi_sleep_setup(char *str)
#ifdef CONFIG_HIBERNATION #ifdef CONFIG_HIBERNATION
if (strncmp(str, "s4_nohwsig", 10) == 0) if (strncmp(str, "s4_nohwsig", 10) == 0)
acpi_no_s4_hw_signature(); acpi_no_s4_hw_signature();
if (strncmp(str, "s4_nonvs", 8) == 0) if (strncmp(str, "s4_nonvs", 8) == 0) {
acpi_s4_no_nvs(); pr_warning("ACPI: acpi_sleep=s4_nonvs is deprecated, "
"please use acpi_sleep=nonvs instead");
acpi_nvs_nosave();
}
#endif #endif
if (strncmp(str, "nonvs", 5) == 0)
acpi_nvs_nosave();
if (strncmp(str, "old_ordering", 12) == 0) if (strncmp(str, "old_ordering", 12) == 0)
acpi_old_suspend_ordering(); acpi_old_suspend_ordering();
str = strchr(str, ','); str = strchr(str, ',');

Просмотреть файл

@ -70,6 +70,7 @@ acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
acpi_status acpi_enable(void) acpi_status acpi_enable(void)
{ {
acpi_status status; acpi_status status;
int retry;
ACPI_FUNCTION_TRACE(acpi_enable); ACPI_FUNCTION_TRACE(acpi_enable);
@ -98,16 +99,18 @@ acpi_status acpi_enable(void)
/* Sanity check that transition succeeded */ /* Sanity check that transition succeeded */
if (acpi_hw_get_mode() != ACPI_SYS_MODE_ACPI) { for (retry = 0; retry < 30000; ++retry) {
ACPI_ERROR((AE_INFO, if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
"Hardware did not enter ACPI mode")); if (retry != 0)
return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); ACPI_WARNING((AE_INFO,
"Platform took > %d00 usec to enter ACPI mode", retry));
return_ACPI_STATUS(AE_OK);
}
acpi_os_stall(100); /* 100 usec */
} }
ACPI_DEBUG_PRINT((ACPI_DB_INIT, ACPI_ERROR((AE_INFO, "Hardware did not enter ACPI mode"));
"Transition to ACPI mode successful\n")); return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
return_ACPI_STATUS(AE_OK);
} }
ACPI_EXPORT_SYMBOL(acpi_enable) ACPI_EXPORT_SYMBOL(acpi_enable)

Просмотреть файл

@ -868,9 +868,15 @@ static void acpi_battery_remove_fs(struct acpi_device *device)
static void acpi_battery_notify(struct acpi_device *device, u32 event) static void acpi_battery_notify(struct acpi_device *device, u32 event)
{ {
struct acpi_battery *battery = acpi_driver_data(device); struct acpi_battery *battery = acpi_driver_data(device);
#ifdef CONFIG_ACPI_SYSFS_POWER
struct device *old;
#endif
if (!battery) if (!battery)
return; return;
#ifdef CONFIG_ACPI_SYSFS_POWER
old = battery->bat.dev;
#endif
acpi_battery_update(battery); acpi_battery_update(battery);
acpi_bus_generate_proc_event(device, event, acpi_bus_generate_proc_event(device, event,
acpi_battery_present(battery)); acpi_battery_present(battery));
@ -879,7 +885,7 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event)
acpi_battery_present(battery)); acpi_battery_present(battery));
#ifdef CONFIG_ACPI_SYSFS_POWER #ifdef CONFIG_ACPI_SYSFS_POWER
/* acpi_battery_update could remove power_supply object */ /* acpi_battery_update could remove power_supply object */
if (battery->bat.dev) if (old && battery->bat.dev)
power_supply_changed(&battery->bat); power_supply_changed(&battery->bat);
#endif #endif
} }

Просмотреть файл

@ -214,7 +214,7 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
.ident = "Sony VGN-SR290J", .ident = "Sony VGN-SR290J",
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, "Sony VGN-SR290J"), DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR290J"),
}, },
}, },
{ {

Просмотреть файл

@ -223,7 +223,7 @@ static bool processor_physically_present(acpi_handle handle)
type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0; type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
cpuid = acpi_get_cpuid(handle, type, acpi_id); cpuid = acpi_get_cpuid(handle, type, acpi_id);
if (cpuid == -1) if ((cpuid == -1) && (num_possible_cpus() > 1))
return false; return false;
return true; return true;

Просмотреть файл

@ -76,14 +76,19 @@ static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER;
module_param(max_cstate, uint, 0000); module_param(max_cstate, uint, 0000);
static unsigned int nocst __read_mostly; static unsigned int nocst __read_mostly;
module_param(nocst, uint, 0000); module_param(nocst, uint, 0000);
static int bm_check_disable __read_mostly;
module_param(bm_check_disable, uint, 0000);
static unsigned int latency_factor __read_mostly = 2; static unsigned int latency_factor __read_mostly = 2;
module_param(latency_factor, uint, 0644); module_param(latency_factor, uint, 0644);
#ifdef CONFIG_ACPI_PROCFS
static u64 us_to_pm_timer_ticks(s64 t) static u64 us_to_pm_timer_ticks(s64 t)
{ {
return div64_u64(t * PM_TIMER_FREQUENCY, 1000000); return div64_u64(t * PM_TIMER_FREQUENCY, 1000000);
} }
#endif
/* /*
* IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
* For now disable this. Probably a bug somewhere else. * For now disable this. Probably a bug somewhere else.
@ -763,6 +768,9 @@ static int acpi_idle_bm_check(void)
{ {
u32 bm_status = 0; u32 bm_status = 0;
if (bm_check_disable)
return 0;
acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
if (bm_status) if (bm_status)
acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
@ -947,7 +955,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
if (acpi_idle_suspend) if (acpi_idle_suspend)
return(acpi_idle_enter_c1(dev, state)); return(acpi_idle_enter_c1(dev, state));
if (acpi_idle_bm_check()) { if (!cx->bm_sts_skip && acpi_idle_bm_check()) {
if (dev->safe_state) { if (dev->safe_state) {
dev->last_state = dev->safe_state; dev->last_state = dev->safe_state;
return dev->safe_state->enter(dev, dev->safe_state); return dev->safe_state->enter(dev, dev->safe_state);

Просмотреть файл

@ -81,6 +81,20 @@ static int acpi_sleep_prepare(u32 acpi_state)
#ifdef CONFIG_ACPI_SLEEP #ifdef CONFIG_ACPI_SLEEP
static u32 acpi_target_sleep_state = ACPI_STATE_S0; static u32 acpi_target_sleep_state = ACPI_STATE_S0;
/*
* The ACPI specification wants us to save NVS memory regions during hibernation
* and to restore them during the subsequent resume. Windows does that also for
* suspend to RAM. However, it is known that this mechanism does not work on
* all machines, so we allow the user to disable it with the help of the
* 'acpi_sleep=nonvs' kernel command line option.
*/
static bool nvs_nosave;
void __init acpi_nvs_nosave(void)
{
nvs_nosave = true;
}
/* /*
* ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the
* user to request that behavior by using the 'acpi_old_suspend_ordering' * user to request that behavior by using the 'acpi_old_suspend_ordering'
@ -197,8 +211,7 @@ static int acpi_suspend_begin(suspend_state_t pm_state)
u32 acpi_state = acpi_suspend_states[pm_state]; u32 acpi_state = acpi_suspend_states[pm_state];
int error = 0; int error = 0;
error = suspend_nvs_alloc(); error = nvs_nosave ? 0 : suspend_nvs_alloc();
if (error) if (error)
return error; return error;
@ -388,20 +401,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
#endif /* CONFIG_SUSPEND */ #endif /* CONFIG_SUSPEND */
#ifdef CONFIG_HIBERNATION #ifdef CONFIG_HIBERNATION
/*
* The ACPI specification wants us to save NVS memory regions during hibernation
* and to restore them during the subsequent resume. However, it is not certain
* if this mechanism is going to work on all machines, so we allow the user to
* disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line
* option.
*/
static bool s4_no_nvs;
void __init acpi_s4_no_nvs(void)
{
s4_no_nvs = true;
}
static unsigned long s4_hardware_signature; static unsigned long s4_hardware_signature;
static struct acpi_table_facs *facs; static struct acpi_table_facs *facs;
static bool nosigcheck; static bool nosigcheck;
@ -415,7 +414,7 @@ static int acpi_hibernation_begin(void)
{ {
int error; int error;
error = s4_no_nvs ? 0 : suspend_nvs_alloc(); error = nvs_nosave ? 0 : suspend_nvs_alloc();
if (!error) { if (!error) {
acpi_target_sleep_state = ACPI_STATE_S4; acpi_target_sleep_state = ACPI_STATE_S4;
acpi_sleep_tts_switch(acpi_target_sleep_state); acpi_sleep_tts_switch(acpi_target_sleep_state);
@ -510,7 +509,7 @@ static int acpi_hibernation_begin_old(void)
error = acpi_sleep_prepare(ACPI_STATE_S4); error = acpi_sleep_prepare(ACPI_STATE_S4);
if (!error) { if (!error) {
if (!s4_no_nvs) if (!nvs_nosave)
error = suspend_nvs_alloc(); error = suspend_nvs_alloc();
if (!error) if (!error)
acpi_target_sleep_state = ACPI_STATE_S4; acpi_target_sleep_state = ACPI_STATE_S4;

Просмотреть файл

@ -48,7 +48,7 @@ struct acpi_power_register {
u8 space_id; u8 space_id;
u8 bit_width; u8 bit_width;
u8 bit_offset; u8 bit_offset;
u8 reserved; u8 access_size;
u64 address; u64 address;
} __attribute__ ((packed)); } __attribute__ ((packed));
@ -63,6 +63,7 @@ struct acpi_processor_cx {
u32 power; u32 power;
u32 usage; u32 usage;
u64 time; u64 time;
u8 bm_sts_skip;
char desc[ACPI_CX_DESC_LEN]; char desc[ACPI_CX_DESC_LEN];
}; };

Просмотреть файл

@ -253,7 +253,7 @@ int acpi_resources_are_enforced(void);
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
void __init acpi_no_s4_hw_signature(void); void __init acpi_no_s4_hw_signature(void);
void __init acpi_old_suspend_ordering(void); void __init acpi_old_suspend_ordering(void);
void __init acpi_s4_no_nvs(void); void __init acpi_nvs_nosave(void);
#endif /* CONFIG_PM_SLEEP */ #endif /* CONFIG_PM_SLEEP */
struct acpi_osc_context { struct acpi_osc_context {