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