Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit acd41d36 authored by Len Brown's avatar Len Brown
Browse files

Merge branch 'suspend' into test

parents 4dff4e7f 4fb507b6
Loading
Loading
Loading
Loading
+18 −26
Original line number Diff line number Diff line
@@ -78,19 +78,17 @@ acpi_set_firmware_waking_vector(acpi_physical_address physical_address)
		return_ACPI_STATUS(status);
	}

	/* Set the vector */

	if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) {
	/*
		 * ACPI 1.0 FACS or short table or optional X_ field is zero
	 * 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;

	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);
}
@@ -134,20 +132,7 @@ acpi_get_firmware_waking_vector(acpi_physical_address * physical_address)
	}

	/* Get the 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;
	}
	*physical_address = (acpi_physical_address)facs->firmware_waking_vector;

	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? */

	/*
	 * 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;

	/* Enable power button */
+58 −1
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include <linux/dmi.h>
#include <linux/device.h>
#include <linux/suspend.h>
#include <linux/reboot.h>

#include <asm/io.h>

@@ -25,6 +26,36 @@
u8 sleep_states[ACPI_S_STATE_COUNT];
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)
{
#ifdef CONFIG_ACPI_SLEEP
@@ -130,6 +161,7 @@ static void acpi_pm_end(void)
	 * failing transition to a sleep state.
	 */
	acpi_target_sleep_state = ACPI_STATE_S0;
	acpi_sleep_tts_switch(acpi_target_sleep_state);
}
#endif /* CONFIG_ACPI_SLEEP */

@@ -154,6 +186,7 @@ static int acpi_suspend_begin(suspend_state_t pm_state)

	if (sleep_states[acpi_state]) {
		acpi_target_sleep_state = acpi_state;
		acpi_sleep_tts_switch(acpi_target_sleep_state);
	} else {
		printk(KERN_ERR "ACPI does not support this state: %d\n",
			pm_state);
@@ -199,6 +232,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
		break;
	}

	/* If ACPI is not enabled by the BIOS, we need to enable it here. */
	acpi_enable();
	/* Reprogram control registers and execute _BFS */
	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)"),
		},
	},
	{
	.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 */
@@ -312,6 +355,7 @@ void __init acpi_no_s4_hw_signature(void)
static int acpi_hibernation_begin(void)
{
	acpi_target_sleep_state = ACPI_STATE_S4;
	acpi_sleep_tts_switch(acpi_target_sleep_state);
	return 0;
}

@@ -375,7 +419,15 @@ static struct platform_hibernation_ops acpi_hibernation_ops = {
 */
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)
		acpi_target_sleep_state = ACPI_STATE_S4;
@@ -595,5 +647,10 @@ int __init acpi_sleep_init(void)
		pm_power_off = acpi_power_off;
	}
	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;
}