Open CONFIG_ACPI_SLEEP in xenlinux, to enable ACPI based
power management. Basically, user can trigger power event
now by "echo *** > /sys/power/state". Also gear to pm
interface defined between xenlinux and Xen.
Signed-off-by Ke Yu <ke.yu@xxxxxxxxx>
Signed-off-by Kevin Tian <kevin.tian@xxxxxxxxx>
diff -r 0d3d91f87abd buildconfigs/linux-defconfig_xen_x86_32
--- a/buildconfigs/linux-defconfig_xen_x86_32 Tue Feb 13 16:40:58 2007
+0800
+++ b/buildconfigs/linux-defconfig_xen_x86_32 Tue Feb 13 16:40:59 2007
+0800
@@ -205,6 +205,9 @@ CONFIG_PM=y
# ACPI (Advanced Configuration and Power Interface) Support
#
CONFIG_ACPI=y
+CONFIG_ACPI_SLEEP=y
+ACPI_SLEEP_PROC_FS=y
+CONFIG_ACPI_SLEEP_PROC_SLEEP=y
CONFIG_ACPI_AC=m
CONFIG_ACPI_BATTERY=m
CONFIG_ACPI_BUTTON=m
diff -r 0d3d91f87abd linux-2.6-xen-sparse/arch/i386/Kconfig
--- a/linux-2.6-xen-sparse/arch/i386/Kconfig Tue Feb 13 16:40:58 2007
+0800
+++ b/linux-2.6-xen-sparse/arch/i386/Kconfig Tue Feb 13 16:40:59 2007
+0800
@@ -816,6 +816,11 @@ config HOTPLUG_CPU
Say Y here to experiment with turning CPUs off and on, and to
enable suspend on SMP systems. CPUs can be controlled through
/sys/devices/system/cpu.
+
+config SUSPEND_SMP
+ bool
+ depends on HOTPLUG_CPU && X86 && PM
+ default y
config COMPAT_VDSO
bool "Compat VDSO support"
diff -r 0d3d91f87abd linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c Tue Feb 13
16:40:58 2007 +0800
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c Tue Feb 13
16:40:59 2007 +0800
@@ -851,9 +851,9 @@ static int timer_resume(struct sys_devic
return 0;
}
+void time_resume(void);
static struct sysdev_class timer_sysclass = {
- .resume = timer_resume,
- .suspend = timer_suspend,
+ .resume = time_resume,
set_kset_name("timer"),
};
diff -r 0d3d91f87abd linux-2.6-xen-sparse/arch/i386/power/Makefile
--- a/linux-2.6-xen-sparse/arch/i386/power/Makefile Tue Feb 13
16:40:58 2007 +0800
+++ b/linux-2.6-xen-sparse/arch/i386/power/Makefile Tue Feb 13
16:40:59 2007 +0800
@@ -2,3 +2,8 @@ obj-$(CONFIG_SOFTWARE_SUSPEND) += cpu.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += cpu.o
obj-$(CONFIG_ACPI_SLEEP) += cpu.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
+
+ifdef CONFIG_XEN
+include $(srctree)/scripts/Makefile.xen
+obj-y := $(call cherrypickxen, $(obj-y))
+endif
diff -r 0d3d91f87abd linux-2.6-xen-sparse/arch/i386/power/cpu-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/power/cpu-xen.c Tue Feb 13
16:40:58 2007 +0800
+++ b/linux-2.6-xen-sparse/arch/i386/power/cpu-xen.c Tue Feb 13
16:40:59 2007 +0800
@@ -62,11 +62,12 @@ static void do_fpu_end(void)
static void fix_processor_context(void)
{
+#ifndef CONFIG_X86_NO_TSS
int cpu = smp_processor_id();
struct tss_struct * t = &per_cpu(init_tss, cpu);
set_tss_desc(cpu,t); /* This just modifies memory; should not
be necessary. But... This is necessary, because 386 hardware has concept
of busy TSS or some similar stupidity. */
-
+#endif
load_TR_desc(); /* This does ltr */
load_LDT(¤t->active_mm->context); /* This does lldt */
diff -r 0d3d91f87abd linux-2.6-xen-sparse/drivers/acpi/Kconfig
--- a/linux-2.6-xen-sparse/drivers/acpi/Kconfig Tue Feb 13 16:40:58 2007
+0800
+++ b/linux-2.6-xen-sparse/drivers/acpi/Kconfig Tue Feb 13 16:40:59 2007
+0800
@@ -45,7 +45,7 @@ if ACPI
config ACPI_SLEEP
bool "Sleep States"
- depends on X86 && (!SMP || SUSPEND_SMP) && !XEN
+ depends on X86 && (!SMP || SUSPEND_SMP)
depends on PM
default y
---help---
diff -r 0d3d91f87abd linux-2.6-xen-sparse/drivers/acpi/hardware/Makefile
--- a/linux-2.6-xen-sparse/drivers/acpi/hardware/Makefile Tue Feb
13 16:40:58 2007 +0800
+++ b/linux-2.6-xen-sparse/drivers/acpi/hardware/Makefile Tue Feb
13 16:40:59 2007 +0800
@@ -7,3 +7,8 @@ obj-$(ACPI_FUTURE_USAGE) += hwtimer.o
obj-$(ACPI_FUTURE_USAGE) += hwtimer.o
EXTRA_CFLAGS += $(ACPI_CFLAGS)
+
+ifdef CONFIG_XEN
+include $(srctree)/scripts/Makefile.xen
+obj-y := $(call cherrypickxen, $(obj-y))
+endif
diff -r 0d3d91f87abd
linux-2.6-xen-sparse/drivers/acpi/hardware/hwsleep-xen.c
--- a/linux-2.6-xen-sparse/drivers/acpi/hardware/hwsleep-xen.c Tue Feb
13 16:40:58 2007 +0800
+++ b/linux-2.6-xen-sparse/drivers/acpi/hardware/hwsleep-xen.c Tue Feb
13 16:49:22 2007 +0800
@@ -209,6 +209,34 @@ acpi_status acpi_enter_sleep_state_prep(
ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
+#ifdef CONFIG_XEN
+#include <asm/hypervisor.h>
+#include <xen/interface/platform.h>
+extern unsigned long acpi_video_flags;
+extern unsigned long saved_videomode;
+static acpi_status acpi_notify_xen_state(u8 sleep_state,
+ u32 pm1a_cnt, u32 pm1b_cnt)
+{
+ 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,
+ .sleep_state = sleep_state,
+ },
+ },
+ };
+
+#ifdef CONFIG_X86
+ op.u.enter_acpi_sleep.video_flags = acpi_video_flags;
+ op.u.enter_acpi_sleep.video_mode = saved_videomode;
+#endif
+
+ return HYPERVISOR_platform_op(&op);
+}
+#endif
/***********************************************************************
********
*
* FUNCTION: acpi_enter_sleep_state
@@ -304,6 +332,7 @@ acpi_status asmlinkage acpi_enter_sleep_
/* Write #1: fill in SLP_TYP data */
+#ifndef CONFIG_XEN
status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
ACPI_REGISTER_PM1A_CONTROL,
PM1Acontrol);
@@ -314,6 +343,10 @@ acpi_status asmlinkage acpi_enter_sleep_
status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
ACPI_REGISTER_PM1B_CONTROL,
PM1Bcontrol);
+#else
+ status = acpi_notify_xen_state(sleep_state,
+ PM1Acontrol, PM1Bcontrol);
+#endif
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -327,6 +360,7 @@ acpi_status asmlinkage acpi_enter_sleep_
ACPI_FLUSH_CPU_CACHE();
+#ifndef CONFIG_XEN
status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
ACPI_REGISTER_PM1A_CONTROL,
PM1Acontrol);
@@ -337,6 +371,10 @@ acpi_status asmlinkage acpi_enter_sleep_
status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
ACPI_REGISTER_PM1B_CONTROL,
PM1Bcontrol);
+#else
+ status = acpi_notify_xen_state(sleep_state,
+ PM1Acontrol, PM1Bcontrol);
+#endif
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
diff -r 0d3d91f87abd linux-2.6-xen-sparse/drivers/acpi/sleep/Makefile
--- a/linux-2.6-xen-sparse/drivers/acpi/sleep/Makefile Tue Feb 13
16:40:58 2007 +0800
+++ b/linux-2.6-xen-sparse/drivers/acpi/sleep/Makefile Tue Feb 13
16:40:59 2007 +0800
@@ -3,3 +3,8 @@ obj-$(CONFIG_ACPI_SLEEP_PROC_FS) += proc
obj-$(CONFIG_ACPI_SLEEP_PROC_FS) += proc.o
EXTRA_CFLAGS += $(ACPI_CFLAGS)
+
+ifdef CONFIG_XEN
+include $(srctree)/scripts/Makefile.xen
+obj-y := $(call cherrypickxen, $(obj-y))
+endif
diff -r 0d3d91f87abd linux-2.6-xen-sparse/drivers/acpi/sleep/main-xen.c
--- a/linux-2.6-xen-sparse/drivers/acpi/sleep/main-xen.c Tue Feb
13 16:40:58 2007 +0800
+++ b/linux-2.6-xen-sparse/drivers/acpi/sleep/main-xen.c Tue Feb
13 16:50:03 2007 +0800
@@ -75,12 +75,15 @@ static int acpi_pm_enter(suspend_state_t
ACPI_FLUSH_CPU_CACHE();
+#ifndef CONFIG_XEN
+ /* Covered by Xen */
/* Do arch specific saving of state. */
if (pm_state > PM_SUSPEND_STANDBY) {
int error = acpi_save_state_mem();
if (error)
return error;
}
+#endif
local_irq_save(flags);
acpi_enable_wakeup_device(acpi_state);
@@ -91,7 +94,14 @@ static int acpi_pm_enter(suspend_state_t
break;
case PM_SUSPEND_MEM:
+#ifdef CONFIG_XEN
+ /* XEN hyperviosr will save and restore CPU context
+ * and then we can skip low level housekeeping here.
+ */
+ acpi_enter_sleep_state(acpi_state);
+#else
do_suspend_lowlevel();
+#endif
break;
case PM_SUSPEND_DISK:
@@ -121,8 +131,10 @@ static int acpi_pm_enter(suspend_state_t
* And, in the case of the latter, the memory image should have
already
* been loaded from disk.
*/
+#ifndef CONFIG_XEN
if (pm_state > PM_SUSPEND_STANDBY)
acpi_restore_state_mem();
+#endif
return ACPI_SUCCESS(status) ? 0 : -EFAULT;
}
@@ -145,10 +157,12 @@ static int acpi_pm_finish(suspend_state_
/* reset firmware waking vector */
acpi_set_firmware_waking_vector((acpi_physical_address) 0);
+#ifndef CONFIG_XEN
if (init_8259A_after_S1) {
printk("Broken toshiba laptop -> kicking interrupts\n");
init_8259A(0);
}
+#endif
return 0;
}
@@ -199,6 +213,46 @@ static struct dmi_system_id __initdata a
},
{},
};
+
+#ifdef CONFIG_XEN
+#include <asm/hypervisor.h>
+#include <xen/interface/platform.h>
+/* Register sleep info to xen hypervisor which does real work later */
+static acpi_status acpi_register_sleep_info(void)
+{
+ struct xen_platform_op op;
+ acpi_status status;
+
+ if (acpi_gbl_FADT == NULL) {
+ printk(KERN_WARNING "%s: ACPI FADT not existed\n",
+ __FUNCTION__);
+ return AE_NO_ACPI_TABLES;
+ }
+
+ op.cmd = XENPF_set_acpi_sleep;
+ op.interface_version = XENPF_INTERFACE_VERSION;
+ op.u.set_acpi_sleep.pm1a_cnt_port =
+ (u16)acpi_gbl_FADT->xpm1a_cnt_blk.address;
+ op.u.set_acpi_sleep.pm1b_cnt_port =
+ (u16)acpi_gbl_FADT->xpm1b_cnt_blk.address;
+ op.u.set_acpi_sleep.pm1a_evt_port =
+ (u16)acpi_gbl_FADT->xpm1a_evt_blk.address;
+ op.u.set_acpi_sleep.pm1b_evt_port =
+ (u16)acpi_gbl_FADT->xpm1b_evt_blk.address;
+
+ status = HYPERVISOR_platform_op(&op);
+
+ if (ACPI_FAILURE(status)){
+ printk(KERN_WARNING "%s: Fail to register acpi sleep
info,"
+ "Xen sleep will not work\n",
__FUNCTION__);
+ return (status);
+ }
+
+ acpi_wakeup_address = (unsigned long)
+ op.u.set_acpi_sleep.xen_waking_vec;
+ return status;
+}
+#endif /* CONFIG_XEN */
static int __init acpi_sleep_init(void)
{
@@ -226,6 +280,10 @@ static int __init acpi_sleep_init(void)
printk(")\n");
pm_set_ops(&acpi_pm_ops);
+
+#ifdef CONFIG_XEN
+ acpi_register_sleep_info();
+#endif
return 0;
}
diff -r 0d3d91f87abd
linux-2.6-xen-sparse/drivers/acpi/sleep/poweroff-xen.c
--- a/linux-2.6-xen-sparse/drivers/acpi/sleep/poweroff-xen.c Tue Feb
13 16:40:58 2007 +0800
+++ b/linux-2.6-xen-sparse/drivers/acpi/sleep/poweroff-xen.c Tue Feb
13 16:40:59 2007 +0800
@@ -25,9 +25,14 @@ int acpi_sleep_prepare(u32 acpi_state)
if (!acpi_wakeup_address) {
return -EFAULT;
}
+#ifndef CONFIG_XEN
acpi_set_firmware_waking_vector((acpi_physical_address)
virt_to_phys((void *)
acpi_wakeup_address));
+#else
+ acpi_set_firmware_waking_vector((acpi_physical_address)
+ acpi_wakeup_address);
+#endif
}
ACPI_FLUSH_CPU_CACHE();
diff -r 0d3d91f87abd
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h
Tue Feb 13 16:40:58 2007 +0800
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h
Tue Feb 13 16:40:59 2007 +0800
@@ -402,6 +402,12 @@ HYPERVISOR_kexec_op(
return _hypercall2(int, kexec_op, op, args);
}
+static inline long
+HYPERVISOR_platform_op(
+ void* arg)
+{
+ return _hypercall1(long, platform_op, arg);
+}
#endif /* __HYPERCALL_H__ */
enable_linux_acpi_sleep.patch
Description: enable_linux_acpi_sleep.patch
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|