# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1215169199 -3600
# Node ID cdadea74443c93e77ce142a48819cf003abf6b73
# Parent c4134d1a3e3f8df10c7204595db9750311c5e68c
Set up an event channel to accept suspend requests.
This is much faster than going through xenstore.
Signed-off-by: Brendan Cullly <brendan@xxxxxxxxx>
---
drivers/xen/core/machine_reboot.c | 3 +++
drivers/xen/core/reboot.c | 38 ++++++++++++++++++++++++++++++++++++++
2 files changed, 41 insertions(+)
diff -r c4134d1a3e3f -r cdadea74443c drivers/xen/core/machine_reboot.c
--- a/drivers/xen/core/machine_reboot.c Thu Jul 03 13:40:02 2008 +0100
+++ b/drivers/xen/core/machine_reboot.c Fri Jul 04 11:59:59 2008 +0100
@@ -26,6 +26,8 @@ void (*pm_power_off)(void);
void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off);
+int setup_suspend_evtchn(void);
+
void machine_emergency_restart(void)
{
/* We really want to get pending console data out before we die. */
@@ -241,6 +243,7 @@ int __xen_suspend(int fast_suspend, void
if (!suspend_cancelled) {
xencons_resume();
xenbus_resume();
+ setup_suspend_evtchn();
} else {
xenbus_suspend_cancel();
}
diff -r c4134d1a3e3f -r cdadea74443c drivers/xen/core/reboot.c
--- a/drivers/xen/core/reboot.c Thu Jul 03 13:40:02 2008 +0100
+++ b/drivers/xen/core/reboot.c Fri Jul 04 11:59:59 2008 +0100
@@ -7,6 +7,7 @@
#include <linux/sysrq.h>
#include <asm/hypervisor.h>
#include <xen/xenbus.h>
+#include <xen/evtchn.h>
#include <linux/kmod.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
@@ -217,6 +218,36 @@ static struct xenbus_watch sysrq_watch =
.callback = sysrq_handler
};
+static irqreturn_t suspend_int(int irq, void* dev_id, struct pt_regs *ptregs)
+{
+ shutting_down = SHUTDOWN_SUSPEND;
+ schedule_work(&shutdown_work);
+
+ return IRQ_HANDLED;
+}
+
+int setup_suspend_evtchn(void)
+{
+ static int irq = -1;
+ int port;
+ char portstr[5]; /* 1024 max */
+
+ if (irq > 0)
+ unbind_from_irqhandler(irq, NULL);
+
+ irq = bind_listening_port_to_irqhandler(0, suspend_int, 0, "suspend",
+ NULL);
+ if (irq <= 0) {
+ return -1;
+ }
+ port = irq_to_evtchn_port(irq);
+ printk(KERN_INFO "suspend: event channel %d\n", port);
+ sprintf(portstr, "%d", port);
+ xenbus_write(XBT_NIL, "device/suspend", "event-channel", portstr);
+
+ return 0;
+}
+
static int setup_shutdown_watcher(void)
{
int err;
@@ -234,6 +265,13 @@ static int setup_shutdown_watcher(void)
err = register_xenbus_watch(&sysrq_watch);
if (err) {
printk(KERN_ERR "Failed to set sysrq watcher\n");
+ return err;
+ }
+
+ /* suspend event channel */
+ err = setup_suspend_evtchn();
+ if (err) {
+ printk(KERN_ERR "Failed to register suspend event channel\n");
return err;
}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|