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

Commit 4b319f29 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branch 'acpi-sleep'

* acpi-sleep:
  x86 / tboot / ACPI: Fail extended mode reduced hardware sleep
  xen / ACPI: notify xen when reduced hardware sleep is available
  ACPI / sleep: Introduce acpi_os_prepare_extended_sleep() for extended sleep path
parents 0ad4c9a9 01c6a6af
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -301,6 +301,15 @@ static int tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control)
	return 0;
}

static int tboot_extended_sleep(u8 sleep_state, u32 val_a, u32 val_b)
{
	if (!tboot_enabled())
		return 0;

	pr_warning("tboot is not able to suspend on platforms with reduced hardware sleep (ACPIv5)");
	return -ENODEV;
}

static atomic_t ap_wfs_count;

static int tboot_wait_for_aps(int num_aps)
@@ -422,6 +431,7 @@ static __init int tboot_late_init(void)
#endif

	acpi_os_set_prepare_sleep(&tboot_sleep);
	acpi_os_set_prepare_extended_sleep(&tboot_extended_sleep);
	return 0;
}

+9 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
 */

#include <acpi/acpi.h>
#include <linux/acpi.h>
#include "accommon.h"

#define _COMPONENT          ACPI_HARDWARE
@@ -128,6 +129,14 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state)

	ACPI_FLUSH_CPU_CACHE();

	status = acpi_os_prepare_extended_sleep(sleep_state,
						acpi_gbl_sleep_type_a,
						acpi_gbl_sleep_type_b);
	if (ACPI_SKIP(status))
		return_ACPI_STATUS(AE_OK);
	if (ACPI_FAILURE(status))
		return_ACPI_STATUS(status);

	/*
	 * Set the SLP_TYP and SLP_EN bits.
	 *
+24 −0
Original line number Diff line number Diff line
@@ -79,6 +79,8 @@ extern char line_buf[80];

static int (*__acpi_os_prepare_sleep)(u8 sleep_state, u32 pm1a_ctrl,
				      u32 pm1b_ctrl);
static int (*__acpi_os_prepare_extended_sleep)(u8 sleep_state, u32 val_a,
				      u32 val_b);

static acpi_osd_handler acpi_irq_handler;
static void *acpi_irq_context;
@@ -1779,6 +1781,28 @@ void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
	__acpi_os_prepare_sleep = func;
}

acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state, u32 val_a,
				  u32 val_b)
{
	int rc = 0;
	if (__acpi_os_prepare_extended_sleep)
		rc = __acpi_os_prepare_extended_sleep(sleep_state,
					     val_a, val_b);
	if (rc < 0)
		return AE_ERROR;
	else if (rc > 0)
		return AE_CTRL_SKIP;

	return AE_OK;
}

void acpi_os_set_prepare_extended_sleep(int (*func)(u8 sleep_state,
			       u32 val_a, u32 val_b))
{
	__acpi_os_prepare_extended_sleep = func;
}


void alloc_acpi_hp_work(acpi_handle handle, u32 type, void *context,
			void (*func)(struct work_struct *work))
{
+28 −13
Original line number Diff line number Diff line
@@ -35,28 +35,43 @@
#include <asm/xen/hypercall.h>
#include <asm/xen/hypervisor.h>

int xen_acpi_notify_hypervisor_state(u8 sleep_state,
				     u32 pm1a_cnt, u32 pm1b_cnt)
static int xen_acpi_notify_hypervisor_state(u8 sleep_state,
					    u32 val_a, u32 val_b,
					    bool extended)
{
	unsigned int bits = extended ? 8 : 16;

	struct xen_platform_op op = {
		.cmd = XENPF_enter_acpi_sleep,
		.interface_version = XENPF_INTERFACE_VERSION,
		.u = {
			.enter_acpi_sleep = {
				.pm1a_cnt_val = (u16)pm1a_cnt,
				.pm1b_cnt_val = (u16)pm1b_cnt,
		.u.enter_acpi_sleep = {
			.val_a = (u16)val_a,
			.val_b = (u16)val_b,
			.sleep_state = sleep_state,
			},
			.flags = extended ? XENPF_ACPI_SLEEP_EXTENDED : 0,
		},
	};

	if ((pm1a_cnt & 0xffff0000) || (pm1b_cnt & 0xffff0000)) {
		WARN(1, "Using more than 16bits of PM1A/B 0x%x/0x%x!"
		     "Email xen-devel@lists.xensource.com  Thank you.\n", \
		     pm1a_cnt, pm1b_cnt);
	if (WARN((val_a & (~0 << bits)) || (val_b & (~0 << bits)),
		 "Using more than %u bits of sleep control values %#x/%#x!"
		 "Email xen-devel@lists.xen.org - Thank you.\n", \
		 bits, val_a, val_b))
		return -1;
	}

	HYPERVISOR_dom0_op(&op);
	return 1;
}

int xen_acpi_notify_hypervisor_sleep(u8 sleep_state,
				     u32 pm1a_cnt, u32 pm1b_cnt)
{
	return xen_acpi_notify_hypervisor_state(sleep_state, pm1a_cnt,
						pm1b_cnt, false);
}

int xen_acpi_notify_hypervisor_extended_sleep(u8 sleep_state,
				     u32 val_a, u32 val_b)
{
	return xen_acpi_notify_hypervisor_state(sleep_state, val_a,
						val_b, true);
}
+7 −0
Original line number Diff line number Diff line
@@ -481,6 +481,13 @@ void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,

acpi_status acpi_os_prepare_sleep(u8 sleep_state,
				  u32 pm1a_control, u32 pm1b_control);

void acpi_os_set_prepare_extended_sleep(int (*func)(u8 sleep_state,
				        u32 val_a,  u32 val_b));

acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state,
					   u32 val_a, u32 val_b);

#ifdef CONFIG_X86
void arch_reserve_mem_area(acpi_physical_address addr, size_t size);
#else
Loading