mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-18 17:54:13 +08:00
Merge branch 'suspend' into test
This commit is contained in:
commit
acd41d36e5
@ -78,19 +78,17 @@ acpi_set_firmware_waking_vector(acpi_physical_address physical_address)
|
|||||||
return_ACPI_STATUS(status);
|
return_ACPI_STATUS(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the vector */
|
/*
|
||||||
|
* According to the ACPI specification 2.0c and later, the 64-bit
|
||||||
|
* waking vector should be cleared and the 32-bit waking vector should
|
||||||
|
* be used, unless we want the wake-up code to be called by the BIOS in
|
||||||
|
* Protected Mode. Some systems (for example HP dv5-1004nr) are known
|
||||||
|
* to fail to resume if the 64-bit vector is used.
|
||||||
|
*/
|
||||||
|
if (facs->version >= 1)
|
||||||
|
facs->xfirmware_waking_vector = 0;
|
||||||
|
|
||||||
if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) {
|
facs->firmware_waking_vector = (u32)physical_address;
|
||||||
/*
|
|
||||||
* ACPI 1.0 FACS or short table or optional X_ field is zero
|
|
||||||
*/
|
|
||||||
facs->firmware_waking_vector = (u32) physical_address;
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* ACPI 2.0 FACS with valid X_ field
|
|
||||||
*/
|
|
||||||
facs->xfirmware_waking_vector = physical_address;
|
|
||||||
}
|
|
||||||
|
|
||||||
return_ACPI_STATUS(AE_OK);
|
return_ACPI_STATUS(AE_OK);
|
||||||
}
|
}
|
||||||
@ -134,20 +132,7 @@ acpi_get_firmware_waking_vector(acpi_physical_address * physical_address)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get the vector */
|
/* Get the vector */
|
||||||
|
*physical_address = (acpi_physical_address)facs->firmware_waking_vector;
|
||||||
if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) {
|
|
||||||
/*
|
|
||||||
* ACPI 1.0 FACS or short table or optional X_ field is zero
|
|
||||||
*/
|
|
||||||
*physical_address =
|
|
||||||
(acpi_physical_address) facs->firmware_waking_vector;
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* ACPI 2.0 FACS with valid X_ field
|
|
||||||
*/
|
|
||||||
*physical_address =
|
|
||||||
(acpi_physical_address) facs->xfirmware_waking_vector;
|
|
||||||
}
|
|
||||||
|
|
||||||
return_ACPI_STATUS(AE_OK);
|
return_ACPI_STATUS(AE_OK);
|
||||||
}
|
}
|
||||||
@ -627,6 +612,13 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
|
|||||||
}
|
}
|
||||||
/* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
|
/* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some BIOSes assume that WAK_STS will be cleared on resume and use
|
||||||
|
* it to determine whether the system is rebooting or resuming. Clear
|
||||||
|
* it for compatibility.
|
||||||
|
*/
|
||||||
|
acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
|
||||||
|
|
||||||
acpi_gbl_system_awake_and_running = TRUE;
|
acpi_gbl_system_awake_and_running = TRUE;
|
||||||
|
|
||||||
/* Enable power button */
|
/* Enable power button */
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include <linux/dmi.h>
|
#include <linux/dmi.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/suspend.h>
|
#include <linux/suspend.h>
|
||||||
|
#include <linux/reboot.h>
|
||||||
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
@ -25,6 +26,36 @@
|
|||||||
u8 sleep_states[ACPI_S_STATE_COUNT];
|
u8 sleep_states[ACPI_S_STATE_COUNT];
|
||||||
static u32 acpi_target_sleep_state = ACPI_STATE_S0;
|
static u32 acpi_target_sleep_state = ACPI_STATE_S0;
|
||||||
|
|
||||||
|
static void acpi_sleep_tts_switch(u32 acpi_state)
|
||||||
|
{
|
||||||
|
union acpi_object in_arg = { ACPI_TYPE_INTEGER };
|
||||||
|
struct acpi_object_list arg_list = { 1, &in_arg };
|
||||||
|
acpi_status status = AE_OK;
|
||||||
|
|
||||||
|
in_arg.integer.value = acpi_state;
|
||||||
|
status = acpi_evaluate_object(NULL, "\\_TTS", &arg_list, NULL);
|
||||||
|
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
|
||||||
|
/*
|
||||||
|
* OS can't evaluate the _TTS object correctly. Some warning
|
||||||
|
* message will be printed. But it won't break anything.
|
||||||
|
*/
|
||||||
|
printk(KERN_NOTICE "Failure in evaluating _TTS object\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tts_notify_reboot(struct notifier_block *this,
|
||||||
|
unsigned long code, void *x)
|
||||||
|
{
|
||||||
|
acpi_sleep_tts_switch(ACPI_STATE_S5);
|
||||||
|
return NOTIFY_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct notifier_block tts_notifier = {
|
||||||
|
.notifier_call = tts_notify_reboot,
|
||||||
|
.next = NULL,
|
||||||
|
.priority = 0,
|
||||||
|
};
|
||||||
|
|
||||||
static int acpi_sleep_prepare(u32 acpi_state)
|
static int acpi_sleep_prepare(u32 acpi_state)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_ACPI_SLEEP
|
#ifdef CONFIG_ACPI_SLEEP
|
||||||
@ -130,6 +161,7 @@ static void acpi_pm_end(void)
|
|||||||
* failing transition to a sleep state.
|
* failing transition to a sleep state.
|
||||||
*/
|
*/
|
||||||
acpi_target_sleep_state = ACPI_STATE_S0;
|
acpi_target_sleep_state = ACPI_STATE_S0;
|
||||||
|
acpi_sleep_tts_switch(acpi_target_sleep_state);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_ACPI_SLEEP */
|
#endif /* CONFIG_ACPI_SLEEP */
|
||||||
|
|
||||||
@ -154,6 +186,7 @@ static int acpi_suspend_begin(suspend_state_t pm_state)
|
|||||||
|
|
||||||
if (sleep_states[acpi_state]) {
|
if (sleep_states[acpi_state]) {
|
||||||
acpi_target_sleep_state = acpi_state;
|
acpi_target_sleep_state = acpi_state;
|
||||||
|
acpi_sleep_tts_switch(acpi_target_sleep_state);
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_ERR "ACPI does not support this state: %d\n",
|
printk(KERN_ERR "ACPI does not support this state: %d\n",
|
||||||
pm_state);
|
pm_state);
|
||||||
@ -199,6 +232,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If ACPI is not enabled by the BIOS, we need to enable it here. */
|
||||||
|
acpi_enable();
|
||||||
/* Reprogram control registers and execute _BFS */
|
/* Reprogram control registers and execute _BFS */
|
||||||
acpi_leave_sleep_state_prep(acpi_state);
|
acpi_leave_sleep_state_prep(acpi_state);
|
||||||
|
|
||||||
@ -295,6 +330,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
|
|||||||
DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"),
|
DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.callback = init_old_suspend_ordering,
|
||||||
|
.ident = "HP xw4600 Workstation",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"),
|
||||||
|
},
|
||||||
|
},
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
#endif /* CONFIG_SUSPEND */
|
#endif /* CONFIG_SUSPEND */
|
||||||
@ -312,6 +355,7 @@ void __init acpi_no_s4_hw_signature(void)
|
|||||||
static int acpi_hibernation_begin(void)
|
static int acpi_hibernation_begin(void)
|
||||||
{
|
{
|
||||||
acpi_target_sleep_state = ACPI_STATE_S4;
|
acpi_target_sleep_state = ACPI_STATE_S4;
|
||||||
|
acpi_sleep_tts_switch(acpi_target_sleep_state);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,7 +419,15 @@ static struct platform_hibernation_ops acpi_hibernation_ops = {
|
|||||||
*/
|
*/
|
||||||
static int acpi_hibernation_begin_old(void)
|
static int acpi_hibernation_begin_old(void)
|
||||||
{
|
{
|
||||||
int error = acpi_sleep_prepare(ACPI_STATE_S4);
|
int error;
|
||||||
|
/*
|
||||||
|
* The _TTS object should always be evaluated before the _PTS object.
|
||||||
|
* When the old_suspended_ordering is true, the _PTS object is
|
||||||
|
* evaluated in the acpi_sleep_prepare.
|
||||||
|
*/
|
||||||
|
acpi_sleep_tts_switch(ACPI_STATE_S4);
|
||||||
|
|
||||||
|
error = acpi_sleep_prepare(ACPI_STATE_S4);
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
acpi_target_sleep_state = ACPI_STATE_S4;
|
acpi_target_sleep_state = ACPI_STATE_S4;
|
||||||
@ -595,5 +647,10 @@ int __init acpi_sleep_init(void)
|
|||||||
pm_power_off = acpi_power_off;
|
pm_power_off = acpi_power_off;
|
||||||
}
|
}
|
||||||
printk(")\n");
|
printk(")\n");
|
||||||
|
/*
|
||||||
|
* Register the tts_notifier to reboot notifier list so that the _TTS
|
||||||
|
* object can also be evaluated when the system enters S5.
|
||||||
|
*/
|
||||||
|
register_reboot_notifier(&tts_notifier);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user