diff options
Diffstat (limited to 'drivers/acpi')
| -rw-r--r-- | drivers/acpi/acpica/evxfevnt.c | 19 | ||||
| -rw-r--r-- | drivers/acpi/battery.c | 8 | ||||
| -rw-r--r-- | drivers/acpi/blacklist.c | 2 | ||||
| -rw-r--r-- | drivers/acpi/processor_core.c | 2 | ||||
| -rw-r--r-- | drivers/acpi/processor_idle.c | 10 | ||||
| -rw-r--r-- | drivers/acpi/sleep.c | 35 |
6 files changed, 46 insertions, 30 deletions
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index d97b8dce1668..18b3f1468b7d 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c | |||
| @@ -70,6 +70,7 @@ acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
| 70 | acpi_status acpi_enable(void) | 70 | acpi_status acpi_enable(void) |
| 71 | { | 71 | { |
| 72 | acpi_status status; | 72 | acpi_status status; |
| 73 | int retry; | ||
| 73 | 74 | ||
| 74 | ACPI_FUNCTION_TRACE(acpi_enable); | 75 | ACPI_FUNCTION_TRACE(acpi_enable); |
| 75 | 76 | ||
| @@ -98,16 +99,18 @@ acpi_status acpi_enable(void) | |||
| 98 | 99 | ||
| 99 | /* Sanity check that transition succeeded */ | 100 | /* Sanity check that transition succeeded */ |
| 100 | 101 | ||
| 101 | if (acpi_hw_get_mode() != ACPI_SYS_MODE_ACPI) { | 102 | for (retry = 0; retry < 30000; ++retry) { |
| 102 | ACPI_ERROR((AE_INFO, | 103 | if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { |
| 103 | "Hardware did not enter ACPI mode")); | 104 | if (retry != 0) |
| 104 | return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); | 105 | ACPI_WARNING((AE_INFO, |
| 106 | "Platform took > %d00 usec to enter ACPI mode", retry)); | ||
| 107 | return_ACPI_STATUS(AE_OK); | ||
| 108 | } | ||
| 109 | acpi_os_stall(100); /* 100 usec */ | ||
| 105 | } | 110 | } |
| 106 | 111 | ||
| 107 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, | 112 | ACPI_ERROR((AE_INFO, "Hardware did not enter ACPI mode")); |
| 108 | "Transition to ACPI mode successful\n")); | 113 | return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); |
| 109 | |||
| 110 | return_ACPI_STATUS(AE_OK); | ||
| 111 | } | 114 | } |
| 112 | 115 | ||
| 113 | ACPI_EXPORT_SYMBOL(acpi_enable) | 116 | ACPI_EXPORT_SYMBOL(acpi_enable) |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 3026e3fa83ef..dc58402b0a17 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
| @@ -868,9 +868,15 @@ static void acpi_battery_remove_fs(struct acpi_device *device) | |||
| 868 | static void acpi_battery_notify(struct acpi_device *device, u32 event) | 868 | static void acpi_battery_notify(struct acpi_device *device, u32 event) |
| 869 | { | 869 | { |
| 870 | struct acpi_battery *battery = acpi_driver_data(device); | 870 | struct acpi_battery *battery = acpi_driver_data(device); |
| 871 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
| 872 | struct device *old; | ||
| 873 | #endif | ||
| 871 | 874 | ||
| 872 | if (!battery) | 875 | if (!battery) |
| 873 | return; | 876 | return; |
| 877 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
| 878 | old = battery->bat.dev; | ||
| 879 | #endif | ||
| 874 | acpi_battery_update(battery); | 880 | acpi_battery_update(battery); |
| 875 | acpi_bus_generate_proc_event(device, event, | 881 | acpi_bus_generate_proc_event(device, event, |
| 876 | acpi_battery_present(battery)); | 882 | acpi_battery_present(battery)); |
| @@ -879,7 +885,7 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event) | |||
| 879 | acpi_battery_present(battery)); | 885 | acpi_battery_present(battery)); |
| 880 | #ifdef CONFIG_ACPI_SYSFS_POWER | 886 | #ifdef CONFIG_ACPI_SYSFS_POWER |
| 881 | /* acpi_battery_update could remove power_supply object */ | 887 | /* acpi_battery_update could remove power_supply object */ |
| 882 | if (battery->bat.dev) | 888 | if (old && battery->bat.dev) |
| 883 | power_supply_changed(&battery->bat); | 889 | power_supply_changed(&battery->bat); |
| 884 | #endif | 890 | #endif |
| 885 | } | 891 | } |
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 01381be05e96..2bb28b9d91c4 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
| @@ -214,7 +214,7 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
| 214 | .ident = "Sony VGN-SR290J", | 214 | .ident = "Sony VGN-SR290J", |
| 215 | .matches = { | 215 | .matches = { |
| 216 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | 216 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), |
| 217 | DMI_MATCH(DMI_PRODUCT_NAME, "Sony VGN-SR290J"), | 217 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR290J"), |
| 218 | }, | 218 | }, |
| 219 | }, | 219 | }, |
| 220 | { | 220 | { |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 51284351418f..e9699aaed109 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
| @@ -223,7 +223,7 @@ static bool processor_physically_present(acpi_handle handle) | |||
| 223 | type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0; | 223 | type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0; |
| 224 | cpuid = acpi_get_cpuid(handle, type, acpi_id); | 224 | cpuid = acpi_get_cpuid(handle, type, acpi_id); |
| 225 | 225 | ||
| 226 | if (cpuid == -1) | 226 | if ((cpuid == -1) && (num_possible_cpus() > 1)) |
| 227 | return false; | 227 | return false; |
| 228 | 228 | ||
| 229 | return true; | 229 | return true; |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index b1b385692f46..e9a8026d39f0 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
| @@ -76,14 +76,19 @@ static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER; | |||
| 76 | module_param(max_cstate, uint, 0000); | 76 | module_param(max_cstate, uint, 0000); |
| 77 | static unsigned int nocst __read_mostly; | 77 | static unsigned int nocst __read_mostly; |
| 78 | module_param(nocst, uint, 0000); | 78 | module_param(nocst, uint, 0000); |
| 79 | static int bm_check_disable __read_mostly; | ||
| 80 | module_param(bm_check_disable, uint, 0000); | ||
| 79 | 81 | ||
| 80 | static unsigned int latency_factor __read_mostly = 2; | 82 | static unsigned int latency_factor __read_mostly = 2; |
| 81 | module_param(latency_factor, uint, 0644); | 83 | module_param(latency_factor, uint, 0644); |
| 82 | 84 | ||
| 85 | #ifdef CONFIG_ACPI_PROCFS | ||
| 83 | static u64 us_to_pm_timer_ticks(s64 t) | 86 | static u64 us_to_pm_timer_ticks(s64 t) |
| 84 | { | 87 | { |
| 85 | return div64_u64(t * PM_TIMER_FREQUENCY, 1000000); | 88 | return div64_u64(t * PM_TIMER_FREQUENCY, 1000000); |
| 86 | } | 89 | } |
| 90 | #endif | ||
| 91 | |||
| 87 | /* | 92 | /* |
| 88 | * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. | 93 | * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. |
| 89 | * For now disable this. Probably a bug somewhere else. | 94 | * For now disable this. Probably a bug somewhere else. |
| @@ -763,6 +768,9 @@ static int acpi_idle_bm_check(void) | |||
| 763 | { | 768 | { |
| 764 | u32 bm_status = 0; | 769 | u32 bm_status = 0; |
| 765 | 770 | ||
| 771 | if (bm_check_disable) | ||
| 772 | return 0; | ||
| 773 | |||
| 766 | acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); | 774 | acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); |
| 767 | if (bm_status) | 775 | if (bm_status) |
| 768 | acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); | 776 | acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); |
| @@ -947,7 +955,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
| 947 | if (acpi_idle_suspend) | 955 | if (acpi_idle_suspend) |
| 948 | return(acpi_idle_enter_c1(dev, state)); | 956 | return(acpi_idle_enter_c1(dev, state)); |
| 949 | 957 | ||
| 950 | if (acpi_idle_bm_check()) { | 958 | if (!cx->bm_sts_skip && acpi_idle_bm_check()) { |
| 951 | if (dev->safe_state) { | 959 | if (dev->safe_state) { |
| 952 | dev->last_state = dev->safe_state; | 960 | dev->last_state = dev->safe_state; |
| 953 | return dev->safe_state->enter(dev, dev->safe_state); | 961 | return dev->safe_state->enter(dev, dev->safe_state); |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 5b7c52e4a00f..2862c781b372 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
| @@ -82,6 +82,20 @@ static int acpi_sleep_prepare(u32 acpi_state) | |||
| 82 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | 82 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; |
| 83 | 83 | ||
| 84 | /* | 84 | /* |
| 85 | * The ACPI specification wants us to save NVS memory regions during hibernation | ||
| 86 | * and to restore them during the subsequent resume. Windows does that also for | ||
| 87 | * suspend to RAM. However, it is known that this mechanism does not work on | ||
| 88 | * all machines, so we allow the user to disable it with the help of the | ||
| 89 | * 'acpi_sleep=nonvs' kernel command line option. | ||
| 90 | */ | ||
| 91 | static bool nvs_nosave; | ||
| 92 | |||
| 93 | void __init acpi_nvs_nosave(void) | ||
| 94 | { | ||
| 95 | nvs_nosave = true; | ||
| 96 | } | ||
| 97 | |||
| 98 | /* | ||
| 85 | * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the | 99 | * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the |
| 86 | * user to request that behavior by using the 'acpi_old_suspend_ordering' | 100 | * user to request that behavior by using the 'acpi_old_suspend_ordering' |
| 87 | * kernel command line option that causes the following variable to be set. | 101 | * kernel command line option that causes the following variable to be set. |
| @@ -197,8 +211,7 @@ static int acpi_suspend_begin(suspend_state_t pm_state) | |||
| 197 | u32 acpi_state = acpi_suspend_states[pm_state]; | 211 | u32 acpi_state = acpi_suspend_states[pm_state]; |
| 198 | int error = 0; | 212 | int error = 0; |
| 199 | 213 | ||
| 200 | error = suspend_nvs_alloc(); | 214 | error = nvs_nosave ? 0 : suspend_nvs_alloc(); |
| 201 | |||
| 202 | if (error) | 215 | if (error) |
| 203 | return error; | 216 | return error; |
| 204 | 217 | ||
| @@ -388,20 +401,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
| 388 | #endif /* CONFIG_SUSPEND */ | 401 | #endif /* CONFIG_SUSPEND */ |
| 389 | 402 | ||
| 390 | #ifdef CONFIG_HIBERNATION | 403 | #ifdef CONFIG_HIBERNATION |
| 391 | /* | ||
| 392 | * The ACPI specification wants us to save NVS memory regions during hibernation | ||
| 393 | * and to restore them during the subsequent resume. However, it is not certain | ||
| 394 | * if this mechanism is going to work on all machines, so we allow the user to | ||
| 395 | * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line | ||
| 396 | * option. | ||
| 397 | */ | ||
| 398 | static bool s4_no_nvs; | ||
| 399 | |||
| 400 | void __init acpi_s4_no_nvs(void) | ||
| 401 | { | ||
| 402 | s4_no_nvs = true; | ||
| 403 | } | ||
| 404 | |||
| 405 | static unsigned long s4_hardware_signature; | 404 | static unsigned long s4_hardware_signature; |
| 406 | static struct acpi_table_facs *facs; | 405 | static struct acpi_table_facs *facs; |
| 407 | static bool nosigcheck; | 406 | static bool nosigcheck; |
| @@ -415,7 +414,7 @@ static int acpi_hibernation_begin(void) | |||
| 415 | { | 414 | { |
| 416 | int error; | 415 | int error; |
| 417 | 416 | ||
| 418 | error = s4_no_nvs ? 0 : suspend_nvs_alloc(); | 417 | error = nvs_nosave ? 0 : suspend_nvs_alloc(); |
| 419 | if (!error) { | 418 | if (!error) { |
| 420 | acpi_target_sleep_state = ACPI_STATE_S4; | 419 | acpi_target_sleep_state = ACPI_STATE_S4; |
| 421 | acpi_sleep_tts_switch(acpi_target_sleep_state); | 420 | acpi_sleep_tts_switch(acpi_target_sleep_state); |
| @@ -510,7 +509,7 @@ static int acpi_hibernation_begin_old(void) | |||
| 510 | error = acpi_sleep_prepare(ACPI_STATE_S4); | 509 | error = acpi_sleep_prepare(ACPI_STATE_S4); |
| 511 | 510 | ||
| 512 | if (!error) { | 511 | if (!error) { |
| 513 | if (!s4_no_nvs) | 512 | if (!nvs_nosave) |
| 514 | error = suspend_nvs_alloc(); | 513 | error = suspend_nvs_alloc(); |
| 515 | if (!error) | 514 | if (!error) |
| 516 | acpi_target_sleep_state = ACPI_STATE_S4; | 515 | acpi_target_sleep_state = ACPI_STATE_S4; |
