md: change daemon_sleep to be in 'jiffies' rather than 'seconds'.
[safe/jmp/linux-2.6] / drivers / xen / manage.c
index ba85fa2..c499793 100644 (file)
@@ -31,17 +31,23 @@ enum shutdown_state {
 /* Ignore multiple shutdown requests. */
 static enum shutdown_state shutting_down = SHUTDOWN_INVALID;
 
+#ifdef CONFIG_PM_SLEEP
 static int xen_suspend(void *data)
 {
        int *cancelled = data;
+       int err;
 
        BUG_ON(!irqs_disabled());
 
-       load_cr3(swapper_pg_dir);
+       err = sysdev_suspend(PMSG_SUSPEND);
+       if (err) {
+               printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n",
+                       err);
+               return err;
+       }
 
        xen_mm_pin_all();
        gnttab_suspend();
-       xen_time_suspend();
        xen_pre_suspend();
 
        /*
@@ -52,15 +58,17 @@ static int xen_suspend(void *data)
        *cancelled = HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
 
        xen_post_suspend(*cancelled);
-       xen_time_resume();
        gnttab_resume();
        xen_mm_unpin_all();
 
        if (!*cancelled) {
                xen_irq_resume();
                xen_console_resume();
+               xen_timer_resume();
        }
 
+       sysdev_resume();
+
        return 0;
 }
 
@@ -71,6 +79,12 @@ static void do_suspend(void)
 
        shutting_down = SHUTDOWN_SUSPEND;
 
+       err = stop_machine_create();
+       if (err) {
+               printk(KERN_ERR "xen suspend: failed to setup stop_machine %d\n", err);
+               goto out;
+       }
+
 #ifdef CONFIG_PREEMPT
        /* If the kernel is preemptible, we need to freeze all the processes
           to prevent them from being in the middle of a pagetable update
@@ -78,40 +92,58 @@ static void do_suspend(void)
        err = freeze_processes();
        if (err) {
                printk(KERN_ERR "xen suspend: freeze failed %d\n", err);
-               return;
+               goto out_destroy_sm;
        }
 #endif
 
-       err = device_suspend(PMSG_SUSPEND);
+       err = dpm_suspend_start(PMSG_SUSPEND);
        if (err) {
-               printk(KERN_ERR "xen suspend: device_suspend %d\n", err);
-               goto out;
+               printk(KERN_ERR "xen suspend: dpm_suspend_start %d\n", err);
+               goto out_thaw;
+       }
+
+       err = dpm_suspend_noirq(PMSG_SUSPEND);
+       if (err) {
+               printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err);
+               goto out_resume;
        }
 
-       printk("suspending xenbus...\n");
-       /* XXX use normal device tree? */
-       xenbus_suspend();
+       printk(KERN_DEBUG "suspending xenstore...\n");
+       xs_suspend();
+
+       err = stop_machine(xen_suspend, &cancelled, cpumask_of(0));
+
+       dpm_resume_noirq(PMSG_RESUME);
 
-       err = stop_machine_run(xen_suspend, &cancelled, 0);
        if (err) {
                printk(KERN_ERR "failed to start xen_suspend: %d\n", err);
-               goto out;
+               cancelled = 1;
        }
 
-       if (!cancelled)
-               xenbus_resume();
-       else
-               xenbus_suspend_cancel();
+       if (!cancelled) {
+               xen_arch_resume();
+               xs_resume();
+       } else
+               xs_suspend_cancel();
 
-       device_resume();
+out_resume:
+       dpm_resume_end(PMSG_RESUME);
 
+       /* Make sure timer events get retriggered on all CPUs */
+       clock_was_set();
 
-out:
+out_thaw:
 #ifdef CONFIG_PREEMPT
        thaw_processes();
+
+out_destroy_sm:
 #endif
+       stop_machine_destroy();
+
+out:
        shutting_down = SHUTDOWN_INVALID;
 }
+#endif /* CONFIG_PM_SLEEP */
 
 static void shutdown_handler(struct xenbus_watch *watch,
                             const char **vec, unsigned int len)