aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/xen/acpi.c41
-rw-r--r--include/xen/acpi.h8
-rw-r--r--include/xen/interface/platform.h7
3 files changed, 38 insertions, 18 deletions
diff --git a/drivers/xen/acpi.c b/drivers/xen/acpi.c
index 119d42a2bf57..90307c0b630c 100644
--- a/drivers/xen/acpi.c
+++ b/drivers/xen/acpi.c
@@ -35,28 +35,43 @@
35#include <asm/xen/hypercall.h> 35#include <asm/xen/hypercall.h>
36#include <asm/xen/hypervisor.h> 36#include <asm/xen/hypervisor.h>
37 37
38int xen_acpi_notify_hypervisor_state(u8 sleep_state, 38static int xen_acpi_notify_hypervisor_state(u8 sleep_state,
39 u32 pm1a_cnt, u32 pm1b_cnt) 39 u32 val_a, u32 val_b,
40 bool extended)
40{ 41{
42 unsigned int bits = extended ? 8 : 16;
43
41 struct xen_platform_op op = { 44 struct xen_platform_op op = {
42 .cmd = XENPF_enter_acpi_sleep, 45 .cmd = XENPF_enter_acpi_sleep,
43 .interface_version = XENPF_INTERFACE_VERSION, 46 .interface_version = XENPF_INTERFACE_VERSION,
44 .u = { 47 .u.enter_acpi_sleep = {
45 .enter_acpi_sleep = { 48 .val_a = (u16)val_a,
46 .pm1a_cnt_val = (u16)pm1a_cnt, 49 .val_b = (u16)val_b,
47 .pm1b_cnt_val = (u16)pm1b_cnt, 50 .sleep_state = sleep_state,
48 .sleep_state = sleep_state, 51 .flags = extended ? XENPF_ACPI_SLEEP_EXTENDED : 0,
49 },
50 }, 52 },
51 }; 53 };
52 54
53 if ((pm1a_cnt & 0xffff0000) || (pm1b_cnt & 0xffff0000)) { 55 if (WARN((val_a & (~0 << bits)) || (val_b & (~0 << bits)),
54 WARN(1, "Using more than 16bits of PM1A/B 0x%x/0x%x!" 56 "Using more than %u bits of sleep control values %#x/%#x!"
55 "Email xen-devel@lists.xensource.com Thank you.\n", \ 57 "Email xen-devel@lists.xen.org - Thank you.\n", \
56 pm1a_cnt, pm1b_cnt); 58 bits, val_a, val_b))
57 return -1; 59 return -1;
58 }
59 60
60 HYPERVISOR_dom0_op(&op); 61 HYPERVISOR_dom0_op(&op);
61 return 1; 62 return 1;
62} 63}
64
65int xen_acpi_notify_hypervisor_sleep(u8 sleep_state,
66 u32 pm1a_cnt, u32 pm1b_cnt)
67{
68 return xen_acpi_notify_hypervisor_state(sleep_state, pm1a_cnt,
69 pm1b_cnt, false);
70}
71
72int xen_acpi_notify_hypervisor_extended_sleep(u8 sleep_state,
73 u32 val_a, u32 val_b)
74{
75 return xen_acpi_notify_hypervisor_state(sleep_state, val_a,
76 val_b, true);
77}
diff --git a/include/xen/acpi.h b/include/xen/acpi.h
index 46aa3d1c1654..4ddd7dc4a61e 100644
--- a/include/xen/acpi.h
+++ b/include/xen/acpi.h
@@ -75,8 +75,10 @@ static inline int xen_acpi_get_pxm(acpi_handle h)
75 return -ENXIO; 75 return -ENXIO;
76} 76}
77 77
78int xen_acpi_notify_hypervisor_state(u8 sleep_state, 78int xen_acpi_notify_hypervisor_sleep(u8 sleep_state,
79 u32 pm1a_cnt, u32 pm1b_cnd); 79 u32 pm1a_cnt, u32 pm1b_cnd);
80int xen_acpi_notify_hypervisor_extended_sleep(u8 sleep_state,
81 u32 val_a, u32 val_b);
80 82
81static inline int xen_acpi_suspend_lowlevel(void) 83static inline int xen_acpi_suspend_lowlevel(void)
82{ 84{
@@ -93,7 +95,9 @@ static inline void xen_acpi_sleep_register(void)
93{ 95{
94 if (xen_initial_domain()) { 96 if (xen_initial_domain()) {
95 acpi_os_set_prepare_sleep( 97 acpi_os_set_prepare_sleep(
96 &xen_acpi_notify_hypervisor_state); 98 &xen_acpi_notify_hypervisor_sleep);
99 acpi_os_set_prepare_extended_sleep(
100 &xen_acpi_notify_hypervisor_extended_sleep);
97 101
98 acpi_suspend_lowlevel = xen_acpi_suspend_lowlevel; 102 acpi_suspend_lowlevel = xen_acpi_suspend_lowlevel;
99 } 103 }
diff --git a/include/xen/interface/platform.h b/include/xen/interface/platform.h
index c57d5f67f702..f1331e3e7271 100644
--- a/include/xen/interface/platform.h
+++ b/include/xen/interface/platform.h
@@ -152,10 +152,11 @@ DEFINE_GUEST_HANDLE_STRUCT(xenpf_firmware_info_t);
152#define XENPF_enter_acpi_sleep 51 152#define XENPF_enter_acpi_sleep 51
153struct xenpf_enter_acpi_sleep { 153struct xenpf_enter_acpi_sleep {
154 /* IN variables */ 154 /* IN variables */
155 uint16_t pm1a_cnt_val; /* PM1a control value. */ 155 uint16_t val_a; /* PM1a control / sleep type A. */
156 uint16_t pm1b_cnt_val; /* PM1b control value. */ 156 uint16_t val_b; /* PM1b control / sleep type B. */
157 uint32_t sleep_state; /* Which state to enter (Sn). */ 157 uint32_t sleep_state; /* Which state to enter (Sn). */
158 uint32_t flags; /* Must be zero. */ 158#define XENPF_ACPI_SLEEP_EXTENDED 0x00000001
159 uint32_t flags; /* XENPF_ACPI_SLEEP_*. */
159}; 160};
160DEFINE_GUEST_HANDLE_STRUCT(xenpf_enter_acpi_sleep_t); 161DEFINE_GUEST_HANDLE_STRUCT(xenpf_enter_acpi_sleep_t);
161 162