Merge branch 'stable/xen.pm.bug-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen

* 'stable/xen.pm.bug-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen:
xen: use freeze/restore/thaw PM events for suspend/resume/chkpt
xen: xenbus PM events support

+30 -14
+8 -8
drivers/xen/manage.c
··· 61 xen_mm_unpin_all(); 62 } 63 64 - #ifdef CONFIG_PM_SLEEP 65 static int xen_suspend(void *data) 66 { 67 struct suspend_info *si = data; ··· 69 70 BUG_ON(!irqs_disabled()); 71 72 - err = sysdev_suspend(PMSG_SUSPEND); 73 if (err) { 74 printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n", 75 err); ··· 118 } 119 #endif 120 121 - err = dpm_suspend_start(PMSG_SUSPEND); 122 if (err) { 123 printk(KERN_ERR "xen suspend: dpm_suspend_start %d\n", err); 124 goto out_thaw; ··· 127 printk(KERN_DEBUG "suspending xenstore...\n"); 128 xs_suspend(); 129 130 - err = dpm_suspend_noirq(PMSG_SUSPEND); 131 if (err) { 132 printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err); 133 goto out_resume; ··· 147 148 err = stop_machine(xen_suspend, &si, cpumask_of(0)); 149 150 - dpm_resume_noirq(PMSG_RESUME); 151 152 if (err) { 153 printk(KERN_ERR "failed to start xen_suspend: %d\n", err); ··· 161 } else 162 xs_suspend_cancel(); 163 164 - dpm_resume_end(PMSG_RESUME); 165 166 /* Make sure timer events get retriggered on all CPUs */ 167 clock_was_set(); ··· 173 #endif 174 shutting_down = SHUTDOWN_INVALID; 175 } 176 - #endif /* CONFIG_PM_SLEEP */ 177 178 struct shutdown_handler { 179 const char *command; ··· 202 { "poweroff", do_poweroff }, 203 { "halt", do_poweroff }, 204 { "reboot", do_reboot }, 205 - #ifdef CONFIG_PM_SLEEP 206 { "suspend", do_suspend }, 207 #endif 208 {NULL, NULL},
··· 61 xen_mm_unpin_all(); 62 } 63 64 + #ifdef CONFIG_HIBERNATION 65 static int xen_suspend(void *data) 66 { 67 struct suspend_info *si = data; ··· 69 70 BUG_ON(!irqs_disabled()); 71 72 + err = sysdev_suspend(PMSG_FREEZE); 73 if (err) { 74 printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n", 75 err); ··· 118 } 119 #endif 120 121 + err = dpm_suspend_start(PMSG_FREEZE); 122 if (err) { 123 printk(KERN_ERR "xen suspend: dpm_suspend_start %d\n", err); 124 goto out_thaw; ··· 127 printk(KERN_DEBUG "suspending xenstore...\n"); 128 xs_suspend(); 129 130 + err = dpm_suspend_noirq(PMSG_FREEZE); 131 if (err) { 132 printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err); 133 goto out_resume; ··· 147 148 err = stop_machine(xen_suspend, &si, cpumask_of(0)); 149 150 + dpm_resume_noirq(si.cancelled ? PMSG_THAW : PMSG_RESTORE); 151 152 if (err) { 153 printk(KERN_ERR "failed to start xen_suspend: %d\n", err); ··· 161 } else 162 xs_suspend_cancel(); 163 164 + dpm_resume_end(si.cancelled ? PMSG_THAW : PMSG_RESTORE); 165 166 /* Make sure timer events get retriggered on all CPUs */ 167 clock_was_set(); ··· 173 #endif 174 shutting_down = SHUTDOWN_INVALID; 175 } 176 + #endif /* CONFIG_HIBERNATION */ 177 178 struct shutdown_handler { 179 const char *command; ··· 202 { "poweroff", do_poweroff }, 203 { "halt", do_poweroff }, 204 { "reboot", do_reboot }, 205 + #ifdef CONFIG_HIBERNATION 206 { "suspend", do_suspend }, 207 #endif 208 {NULL, NULL},
+10 -2
drivers/xen/xenbus/xenbus_probe.c
··· 577 } 578 EXPORT_SYMBOL_GPL(xenbus_dev_changed); 579 580 - int xenbus_dev_suspend(struct device *dev, pm_message_t state) 581 { 582 int err = 0; 583 struct xenbus_driver *drv; ··· 590 return 0; 591 drv = to_xenbus_driver(dev->driver); 592 if (drv->suspend) 593 - err = drv->suspend(xdev, state); 594 if (err) 595 printk(KERN_WARNING 596 "xenbus: suspend %s failed: %i\n", dev_name(dev), err); ··· 641 return 0; 642 } 643 EXPORT_SYMBOL_GPL(xenbus_dev_resume); 644 645 /* A flag to determine if xenstored is 'ready' (i.e. has started) */ 646 int xenstored_ready = 0;
··· 577 } 578 EXPORT_SYMBOL_GPL(xenbus_dev_changed); 579 580 + int xenbus_dev_suspend(struct device *dev) 581 { 582 int err = 0; 583 struct xenbus_driver *drv; ··· 590 return 0; 591 drv = to_xenbus_driver(dev->driver); 592 if (drv->suspend) 593 + err = drv->suspend(xdev); 594 if (err) 595 printk(KERN_WARNING 596 "xenbus: suspend %s failed: %i\n", dev_name(dev), err); ··· 641 return 0; 642 } 643 EXPORT_SYMBOL_GPL(xenbus_dev_resume); 644 + 645 + int xenbus_dev_cancel(struct device *dev) 646 + { 647 + /* Do nothing */ 648 + DPRINTK("cancel"); 649 + return 0; 650 + } 651 + EXPORT_SYMBOL_GPL(xenbus_dev_cancel); 652 653 /* A flag to determine if xenstored is 'ready' (i.e. has started) */ 654 int xenstored_ready = 0;
+2 -1
drivers/xen/xenbus/xenbus_probe.h
··· 64 65 extern void xenbus_dev_shutdown(struct device *_dev); 66 67 - extern int xenbus_dev_suspend(struct device *dev, pm_message_t state); 68 extern int xenbus_dev_resume(struct device *dev); 69 70 extern void xenbus_otherend_changed(struct xenbus_watch *watch, 71 const char **vec, unsigned int len,
··· 64 65 extern void xenbus_dev_shutdown(struct device *_dev); 66 67 + extern int xenbus_dev_suspend(struct device *dev); 68 extern int xenbus_dev_resume(struct device *dev); 69 + extern int xenbus_dev_cancel(struct device *dev); 70 71 extern void xenbus_otherend_changed(struct xenbus_watch *watch, 72 const char **vec, unsigned int len,
+9 -2
drivers/xen/xenbus/xenbus_probe_frontend.c
··· 85 __ATTR_NULL 86 }; 87 88 static struct xen_bus_type xenbus_frontend = { 89 .root = "device", 90 .levels = 2, /* device/type/<id> */ ··· 108 .shutdown = xenbus_dev_shutdown, 109 .dev_attrs = xenbus_frontend_dev_attrs, 110 111 - .suspend = xenbus_dev_suspend, 112 - .resume = xenbus_dev_resume, 113 }, 114 }; 115
··· 85 __ATTR_NULL 86 }; 87 88 + static const struct dev_pm_ops xenbus_pm_ops = { 89 + .suspend = xenbus_dev_suspend, 90 + .resume = xenbus_dev_resume, 91 + .freeze = xenbus_dev_suspend, 92 + .thaw = xenbus_dev_cancel, 93 + .restore = xenbus_dev_resume, 94 + }; 95 + 96 static struct xen_bus_type xenbus_frontend = { 97 .root = "device", 98 .levels = 2, /* device/type/<id> */ ··· 100 .shutdown = xenbus_dev_shutdown, 101 .dev_attrs = xenbus_frontend_dev_attrs, 102 103 + .pm = &xenbus_pm_ops, 104 }, 105 }; 106
+1 -1
include/xen/xenbus.h
··· 92 void (*otherend_changed)(struct xenbus_device *dev, 93 enum xenbus_state backend_state); 94 int (*remove)(struct xenbus_device *dev); 95 - int (*suspend)(struct xenbus_device *dev, pm_message_t state); 96 int (*resume)(struct xenbus_device *dev); 97 int (*uevent)(struct xenbus_device *, struct kobj_uevent_env *); 98 struct device_driver driver;
··· 92 void (*otherend_changed)(struct xenbus_device *dev, 93 enum xenbus_state backend_state); 94 int (*remove)(struct xenbus_device *dev); 95 + int (*suspend)(struct xenbus_device *dev); 96 int (*resume)(struct xenbus_device *dev); 97 int (*uevent)(struct xenbus_device *, struct kobj_uevent_env *); 98 struct device_driver driver;