diff options
author | Ben Guthro <benjamin.guthro@citrix.com> | 2013-07-30 08:24:54 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-07-31 08:22:35 -0400 |
commit | be6b25d15f5e67bc49b90ed55feb1dd947f4df2c (patch) | |
tree | 1de57c5826b46527732ad02acddc42b018076dfd | |
parent | d6b47b122473885abc882e337ac2d321bbcfb378 (diff) |
xen / ACPI: notify xen when reduced hardware sleep is available
Use the acpi_os_prepare_extended_sleep() callback to notify xen
to make use of the reduced hardware sleep functionality
The xen hypervisor change underlying this is commit 62d1a69
("ACPI: support v5 (reduced HW) sleep interface") on the master
branch of git://xenbits.xen.org/xen.git.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Ben Guthro <benjamin.guthro@citrix.com>
Acked-by: Konrad Wilk <konrad.wilk@oracle.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/xen/acpi.c | 41 | ||||
-rw-r--r-- | include/xen/acpi.h | 8 | ||||
-rw-r--r-- | include/xen/interface/platform.h | 7 |
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 | ||
38 | int xen_acpi_notify_hypervisor_state(u8 sleep_state, | 38 | static 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 | |||
65 | int 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 | |||
72 | int 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 | ||
78 | int xen_acpi_notify_hypervisor_state(u8 sleep_state, | 78 | int xen_acpi_notify_hypervisor_sleep(u8 sleep_state, |
79 | u32 pm1a_cnt, u32 pm1b_cnd); | 79 | u32 pm1a_cnt, u32 pm1b_cnd); |
80 | int xen_acpi_notify_hypervisor_extended_sleep(u8 sleep_state, | ||
81 | u32 val_a, u32 val_b); | ||
80 | 82 | ||
81 | static inline int xen_acpi_suspend_lowlevel(void) | 83 | static 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 |
153 | struct xenpf_enter_acpi_sleep { | 153 | struct 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 | }; |
160 | DEFINE_GUEST_HANDLE_STRUCT(xenpf_enter_acpi_sleep_t); | 161 | DEFINE_GUEST_HANDLE_STRUCT(xenpf_enter_acpi_sleep_t); |
161 | 162 | ||