aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen/manage.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/xen/manage.c')
-rw-r--r--drivers/xen/manage.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index 10d03d7931c4..2ac4440e7b08 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -3,6 +3,7 @@
3 */ 3 */
4#include <linux/kernel.h> 4#include <linux/kernel.h>
5#include <linux/err.h> 5#include <linux/err.h>
6#include <linux/slab.h>
6#include <linux/reboot.h> 7#include <linux/reboot.h>
7#include <linux/sysrq.h> 8#include <linux/sysrq.h>
8#include <linux/stop_machine.h> 9#include <linux/stop_machine.h>
@@ -43,7 +44,6 @@ static int xen_suspend(void *data)
43 if (err) { 44 if (err) {
44 printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n", 45 printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n",
45 err); 46 err);
46 dpm_resume_noirq(PMSG_RESUME);
47 return err; 47 return err;
48 } 48 }
49 49
@@ -69,7 +69,6 @@ static int xen_suspend(void *data)
69 } 69 }
70 70
71 sysdev_resume(); 71 sysdev_resume();
72 dpm_resume_noirq(PMSG_RESUME);
73 72
74 return 0; 73 return 0;
75} 74}
@@ -81,6 +80,12 @@ static void do_suspend(void)
81 80
82 shutting_down = SHUTDOWN_SUSPEND; 81 shutting_down = SHUTDOWN_SUSPEND;
83 82
83 err = stop_machine_create();
84 if (err) {
85 printk(KERN_ERR "xen suspend: failed to setup stop_machine %d\n", err);
86 goto out;
87 }
88
84#ifdef CONFIG_PREEMPT 89#ifdef CONFIG_PREEMPT
85 /* If the kernel is preemptible, we need to freeze all the processes 90 /* If the kernel is preemptible, we need to freeze all the processes
86 to prevent them from being in the middle of a pagetable update 91 to prevent them from being in the middle of a pagetable update
@@ -88,14 +93,14 @@ static void do_suspend(void)
88 err = freeze_processes(); 93 err = freeze_processes();
89 if (err) { 94 if (err) {
90 printk(KERN_ERR "xen suspend: freeze failed %d\n", err); 95 printk(KERN_ERR "xen suspend: freeze failed %d\n", err);
91 return; 96 goto out_destroy_sm;
92 } 97 }
93#endif 98#endif
94 99
95 err = dpm_suspend_start(PMSG_SUSPEND); 100 err = dpm_suspend_start(PMSG_SUSPEND);
96 if (err) { 101 if (err) {
97 printk(KERN_ERR "xen suspend: dpm_suspend_start %d\n", err); 102 printk(KERN_ERR "xen suspend: dpm_suspend_start %d\n", err);
98 goto out; 103 goto out_thaw;
99 } 104 }
100 105
101 printk(KERN_DEBUG "suspending xenstore...\n"); 106 printk(KERN_DEBUG "suspending xenstore...\n");
@@ -104,32 +109,39 @@ static void do_suspend(void)
104 err = dpm_suspend_noirq(PMSG_SUSPEND); 109 err = dpm_suspend_noirq(PMSG_SUSPEND);
105 if (err) { 110 if (err) {
106 printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err); 111 printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err);
107 goto resume_devices; 112 goto out_resume;
108 } 113 }
109 114
110 err = stop_machine(xen_suspend, &cancelled, cpumask_of(0)); 115 err = stop_machine(xen_suspend, &cancelled, cpumask_of(0));
116
117 dpm_resume_noirq(PMSG_RESUME);
118
111 if (err) { 119 if (err) {
112 printk(KERN_ERR "failed to start xen_suspend: %d\n", err); 120 printk(KERN_ERR "failed to start xen_suspend: %d\n", err);
113 goto out; 121 cancelled = 1;
114 } 122 }
115 123
124out_resume:
116 if (!cancelled) { 125 if (!cancelled) {
117 xen_arch_resume(); 126 xen_arch_resume();
118 xs_resume(); 127 xs_resume();
119 } else 128 } else
120 xs_suspend_cancel(); 129 xs_suspend_cancel();
121 130
122 dpm_resume_noirq(PMSG_RESUME);
123
124resume_devices:
125 dpm_resume_end(PMSG_RESUME); 131 dpm_resume_end(PMSG_RESUME);
126 132
127 /* Make sure timer events get retriggered on all CPUs */ 133 /* Make sure timer events get retriggered on all CPUs */
128 clock_was_set(); 134 clock_was_set();
129out: 135
136out_thaw:
130#ifdef CONFIG_PREEMPT 137#ifdef CONFIG_PREEMPT
131 thaw_processes(); 138 thaw_processes();
139
140out_destroy_sm:
132#endif 141#endif
142 stop_machine_destroy();
143
144out:
133 shutting_down = SHUTDOWN_INVALID; 145 shutting_down = SHUTDOWN_INVALID;
134} 146}
135#endif /* CONFIG_PM_SLEEP */ 147#endif /* CONFIG_PM_SLEEP */